diff --git a/Console/Console_VS2005.vcproj b/Console/Console_VS2005.vcproj
new file mode 100644
index 00000000..b579ea18
--- /dev/null
+++ b/Console/Console_VS2005.vcproj
@@ -0,0 +1,679 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Console/Console_VS2008.vcproj b/Console/Console_VS2008.vcproj
index d658acbc..539399c0 100644
--- a/Console/Console_VS2008.vcproj
+++ b/Console/Console_VS2008.vcproj
@@ -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"
>
@@ -149,7 +149,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"
>
@@ -214,7 +214,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"
>
diff --git a/Console/Console_VS2010.vcxproj b/Console/Console_VS2010.vcxproj
new file mode 100644
index 00000000..98557bce
--- /dev/null
+++ b/Console/Console_VS2010.vcxproj
@@ -0,0 +1,227 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}
+ Win32Proj
+ Console
+ Console
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Console/Console_VS2010.vcxproj.filters b/Console/Console_VS2010.vcxproj.filters
new file mode 100644
index 00000000..e7559662
--- /dev/null
+++ b/Console/Console_VS2010.vcxproj.filters
@@ -0,0 +1,45 @@
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ {abfafc0c-c637-4524-960d-bddcb96d0913}
+
+
+ {680812ee-68a6-4c84-a9aa-615d9523b3b1}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Credits.cpp b/Credits.cpp
index 4bd2c003..9bb0866c 100644
--- a/Credits.cpp
+++ b/Credits.cpp
@@ -1575,13 +1575,7 @@ UINT32 GetAndHandleCreditCodeFromCodeString( STR16 pzCode )
{
return( CRDT_FLAG__END_SECTION );
}
-
- //else its an error
- else
- {
- Assert( 0 );
- }
-
+
return( CRDT_NODE_NONE );
}
diff --git a/Editor/Editor Callbacks.cpp b/Editor/Editor Callbacks.cpp
index 8fc198d8..fa8d6517 100644
--- a/Editor/Editor Callbacks.cpp
+++ b/Editor/Editor Callbacks.cpp
@@ -33,6 +33,8 @@
#include "EditorMapInfo.h"
#endif
+#include "LoadScreen.h"
+
extern SOLDIERINITNODE *gpSelected;
extern SCHEDULENODE gCurrSchedule;
extern void ExtractAndUpdateMercSchedule();
@@ -648,8 +650,17 @@ void BtnChangeTilesetCallback(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
{
- btn->uiFlags |= BUTTON_CLICKED_ON;
- iEditorToolbarState = TBAR_MODE_CHANGE_TILESET;
+ // WANNE: Check if map has been saved when we have a new map that has not been saved before!
+ if (fNewMapSaved)
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ iEditorToolbarState = TBAR_MODE_CHANGE_TILESET;
+ }
+ else
+ {
+ swprintf(gzErrorCatchString, L"Before changing tilesets you have to save the new map!");
+ InitErrorCatchDialog();
+ }
}
}
diff --git a/Editor/Editor Taskbar Creation.cpp b/Editor/Editor Taskbar Creation.cpp
index 7f5f3526..eed584ec 100644
--- a/Editor/Editor Taskbar Creation.cpp
+++ b/Editor/Editor Taskbar Creation.cpp
@@ -708,7 +708,7 @@ void InitEditorOptionsToolbar()
//dnl ch33 160909
iEditorButton[OPTIONS_VANILLA_MODE] =
CreateCheckBoxButton(iScreenWidthOffset+71, SCREEN_HEIGHT-119, "EDITOR//smcheckbox.sti", MSYS_PRIORITY_NORMAL, VanillaModeCallback);
- SetButtonFastHelpText(iEditorButton[OPTIONS_VANILLA_MODE],L"Set save map as v1.12");
+ SetButtonFastHelpText(iEditorButton[OPTIONS_VANILLA_MODE],L"When checked, the map will be saved in original JA2 format (Version: 5.00 / 25)");
}
void InitEditorTerrainToolbar()
diff --git a/Editor/Editor Taskbar Utils.cpp b/Editor/Editor Taskbar Utils.cpp
index d3d031ab..f69d7ac7 100644
--- a/Editor/Editor Taskbar Utils.cpp
+++ b/Editor/Editor Taskbar Utils.cpp
@@ -906,7 +906,7 @@ void RenderEditorInfo( )
switch( iCurrentTaskbar )
{
case TASK_OPTIONS:
- mprintf(iScreenWidthOffset+71+15, SCREEN_HEIGHT-117, L"v1.12");//dnl ch33 160909
+ mprintf(iScreenWidthOffset+71+15, SCREEN_HEIGHT-117, L"Save map in original JA2 map format (Version: 5.00 / 25)");//dnl ch33 160909
if( !gfWorldLoaded || giCurrentTilesetID < 0 )
mprintf( iScreenWidthOffset + 260, 2 * iScreenHeightOffset + 445, L"No map currently loaded." );
else
diff --git a/Editor/EditorItems.cpp b/Editor/EditorItems.cpp
index e472828a..42a500c5 100644
--- a/Editor/EditorItems.cpp
+++ b/Editor/EditorItems.cpp
@@ -45,7 +45,7 @@
#include "InterfaceItemImages.h"
#endif
-#include "VFS/Tools/Log.h"
+#include
#define NUMBER_TRIGGERS 27
#define PRESSURE_ACTION_ID (NUMBER_TRIGGERS - 1)
@@ -557,10 +557,10 @@ void InitEditorItemsInfo(UINT32 uiItemType)
}
else
{
- static CLog& editorLog = *CLog::create(L"EditorItems.log");
+ static vfs::Log& editorLog = *vfs::Log::create(L"EditorItems.log");
editorLog << L"Tried to access item ["
<< item->ubGraphicNum << L"/" << hVObject->usNumberOfObjects
- << L"]" << CLog::ENDL;
+ << L"]" << vfs::Log::endl;
}
}
usCounter++;
diff --git a/Editor/EditorMapInfo.cpp b/Editor/EditorMapInfo.cpp
index 029c4e74..8c0ebb58 100644
--- a/Editor/EditorMapInfo.cpp
+++ b/Editor/EditorMapInfo.cpp
@@ -141,7 +141,7 @@ void SetupTextInputForMapInfo()
swprintf( str, L"%d", gExitGrid.ubGotoSectorZ );
AddTextInputField( iScreenWidthOffset + 338, 2 * iScreenHeightOffset + 383, 30, 18, MSYS_PRIORITY_NORMAL, str, 1, INPUTTYPE_NUMERICSTRICT );
swprintf( str, L"%d", gExitGrid.usGridNo );
- AddTextInputField( iScreenWidthOffset + 338, 2 * iScreenHeightOffset + 403, 40, 18, MSYS_PRIORITY_NORMAL, str, 5, INPUTTYPE_NUMERICSTRICT );
+ AddTextInputField( iScreenWidthOffset + 338, 2 * iScreenHeightOffset + 403, 45, 18, MSYS_PRIORITY_NORMAL, str, 6, INPUTTYPE_NUMERICSTRICT );
}
void UpdateMapInfo()
@@ -183,8 +183,8 @@ void UpdateMapInfo()
mprintf( iScreenWidthOffset + 368, 2 * iScreenHeightOffset + 372, L"Sector" );
mprintf( iScreenWidthOffset + 368, 2 * iScreenHeightOffset + 383, L"Destination");
mprintf( iScreenWidthOffset + 368, 2 * iScreenHeightOffset + 392, L"Bsmt. Level" );
- mprintf( iScreenWidthOffset + 378, 2 * iScreenHeightOffset + 403, L"Dest." );
- mprintf( iScreenWidthOffset + 378, 2 * iScreenHeightOffset + 412, L"GridNo" );
+ mprintf( iScreenWidthOffset + 383, 2 * iScreenHeightOffset + 403, L"Dest." );
+ mprintf( iScreenWidthOffset + 383, 2 * iScreenHeightOffset + 412, L"GridNo" );
SetFontForeground( FONT_RED );
}
diff --git a/Editor/EditorMercs.cpp b/Editor/EditorMercs.cpp
index 9142b3e3..fca45019 100644
--- a/Editor/EditorMercs.cpp
+++ b/Editor/EditorMercs.cpp
@@ -77,6 +77,11 @@ extern void GetSoldierAboveGuyPositions( SOLDIERTYPE *pSoldier, INT16 *psX, INT1
// SANMONA_ARMS_GROUP,
// ANGELS_GROUP,
// NUM_CIV_GROUPS
+
+CHAR16 gszCivGroupNames[ NUM_CIV_GROUPS ][ 128 ];
+
+
+/*
CHAR16 gszCivGroupNames[ NUM_CIV_GROUPS ][ 20 ] =
{
L"NONE",
@@ -102,7 +107,7 @@ CHAR16 gszCivGroupNames[ NUM_CIV_GROUPS ][ 20 ] =
L"UNUSED18",
L"UNUSED19",
};
-
+*/
//--------------------------------------------------
// SCHEDULE_ACTION_NONE,
@@ -311,6 +316,27 @@ extern SOLDIERCREATE_STRUCT gSaveBufferDetailedPlacement;
//void CopyMercPlacement(); // moved to header (jonathanl)
//void PasteMercPlacement(); // moved to header (jonathanl)
+
+//legion2 jazz
+
+wchar_t *GetGrupaString( SOLDIERTYPE *pSoldier ) //Legion 2
+{
+ INT32 cnt, cntStart,par;
+
+ cntStart = 0;
+ for ( cnt = cntStart; cnt < NUM_CIV_GROUPS; cnt ++ )
+ {
+ if (pSoldier->ubCivilianGroup == cnt)
+ {
+ par = cnt;
+ }
+
+ }
+ return gszCivGroupNames[ par ];
+}
+//------------
+
+
void GameInitEditorMercsInfo()
{
INT32 i;
@@ -3106,7 +3132,7 @@ void RenderMercStrings()
SOLDIERTYPE *pSoldier;
INT16 sXPos, sYPos;
INT16 sX, sY;
- STR16 pStr;
+ STR16 pStr, pStr2;
SOLDIERINITNODE *curr;
CHAR16 str[50];
@@ -3154,6 +3180,24 @@ void RenderMercStrings()
mprintf( sX, sY, str );
}
sYPos += 10;
+
+
+ if (pSoldier->bTeam == CIV_TEAM )
+ {
+ //legion2
+ pStr2 = GetGrupaString( pSoldier );
+
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW ); //FONT_MCOLOR_WHITE
+ FindFontCenterCoordinates( sXPos, sYPos, 80, 1, pStr2, TINYFONT1, &sX, &sY );
+ if( sY < (2 * iScreenHeightOffset + 352 ))
+ {
+ gprintfdirty( sX, sY, pStr2 );
+ mprintf( sX, sY, pStr2 );
+ }
+ sYPos += 10;
+ }
+
}
else
{
@@ -3180,6 +3224,25 @@ void RenderMercStrings()
mprintf( sX, sY, str );
}
sYPos += 10;
+
+ //legion
+ if (pSoldier->bTeam == CIV_TEAM ) //(pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == CREATURE_TEAM || pSoldier->bTeam == MILITIA_TEAM)
+ {
+ //legion 2
+ pStr2 = GetGrupaString( pSoldier );
+
+ //SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW ); //FONT_MCOLOR_WHITE
+ FindFontCenterCoordinates( sXPos, sYPos, 80, 1, pStr2, TINYFONT1, &sX, &sY );
+ if( sY < (2 * iScreenHeightOffset + 352 ))
+ {
+ gprintfdirty( sX, sY, pStr2 );
+ mprintf( sX, sY, pStr2 );
+ }
+ sYPos += 10;
+ }
+
}
if( curr->pBasicPlacement->bOrders == RNDPTPATROL || curr->pBasicPlacement->bOrders == POINTPATROL )
{ //make sure the placement has at least one waypoint.
@@ -3302,7 +3365,7 @@ void CancelCurrentScheduleAction()
void RegisterCurrentScheduleAction( INT32 iMapIndex )
{
- CHAR16 str[6];
+ CHAR16 str[10];
MarkWorldDirty();
swprintf( str, L"%d", iMapIndex );
if( gfUseScheduleData2 )
diff --git a/Editor/Editor_VS2005.vcproj b/Editor/Editor_VS2005.vcproj
new file mode 100644
index 00000000..090d57ee
--- /dev/null
+++ b/Editor/Editor_VS2005.vcproj
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Editor/Editor_VS2008.vcproj b/Editor/Editor_VS2008.vcproj
index a06031ed..efd16c40 100644
--- a/Editor/Editor_VS2008.vcproj
+++ b/Editor/Editor_VS2008.vcproj
@@ -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"
>
@@ -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"
>
diff --git a/Editor/Editor_VS2010.vcxproj b/Editor/Editor_VS2010.vcxproj
new file mode 100644
index 00000000..28a36a00
--- /dev/null
+++ b/Editor/Editor_VS2010.vcxproj
@@ -0,0 +1,265 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {23EA0500-038A-4EB8-B753-0C709B25470D}
+ Win32Proj
+ Editor
+ Editor
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Editor/Editor_VS2010.vcxproj.filters b/Editor/Editor_VS2010.vcxproj.filters
new file mode 100644
index 00000000..ca9d84a6
--- /dev/null
+++ b/Editor/Editor_VS2010.vcxproj.filters
@@ -0,0 +1,171 @@
+
+
+
+
+ {1305164a-0ad7-4d96-af15-765647f97f27}
+
+
+ {02bb6629-3e96-4c7d-931f-fb1ec12b8ef5}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Editor/Item Statistics.cpp b/Editor/Item Statistics.cpp
index a1db49cf..731c82e8 100644
--- a/Editor/Item Statistics.cpp
+++ b/Editor/Item Statistics.cpp
@@ -671,7 +671,7 @@ void SetupGunGUI()
//for a particular weapon. Show only the ones that we can apply to this gun.
yp = 2 * iScreenHeightOffset + 383;
guiAttachmentButton[ SILENCER_ATTACHMENT_BUTTON ] = -1;
- if( ValidAttachment( SILENCER, gpItem->usItem ) )
+ if( ValidAttachment( SILENCER, gpItem ) )
{
guiAttachmentButton[ SILENCER_ATTACHMENT_BUTTON ] =
CreateTextButton( L"SILENCER", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -684,7 +684,7 @@ void SetupGunGUI()
}
}
guiAttachmentButton[ SNIPERSCOPE_ATTACHMENT_BUTTON ] = -1;
- if( ValidAttachment( SNIPERSCOPE, gpItem->usItem ) )
+ if( ValidAttachment( SNIPERSCOPE, gpItem ) )
{
guiAttachmentButton[ SNIPERSCOPE_ATTACHMENT_BUTTON ] =
CreateTextButton( L"SNIPERSCOPE", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -697,7 +697,7 @@ void SetupGunGUI()
}
}
guiAttachmentButton[ LASERSCOPE_ATTACHMENT_BUTTON ] = -1;
- if( ValidAttachment( LASERSCOPE, gpItem->usItem ) )
+ if( ValidAttachment( LASERSCOPE, gpItem ) )
{
guiAttachmentButton[ LASERSCOPE_ATTACHMENT_BUTTON ] =
CreateTextButton( L"LASERSCOPE", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -710,7 +710,7 @@ void SetupGunGUI()
}
}
guiAttachmentButton[ BIPOD_ATTACHMENT_BUTTON ] = -1;
- if( ValidAttachment( BIPOD, gpItem->usItem ) )
+ if( ValidAttachment( BIPOD, gpItem ) )
{
guiAttachmentButton[ BIPOD_ATTACHMENT_BUTTON ] =
CreateTextButton( L"BIPOD", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -723,7 +723,7 @@ void SetupGunGUI()
}
}
guiAttachmentButton[ DUCKBILL_ATTACHMENT_BUTTON ] = -1;
- if( ValidAttachment( DUCKBILL, gpItem->usItem ) )
+ if( ValidAttachment( DUCKBILL, gpItem ) )
{
guiAttachmentButton[ DUCKBILL_ATTACHMENT_BUTTON ] =
CreateTextButton( L"DUCKBILL", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -736,7 +736,7 @@ void SetupGunGUI()
}
}
guiAttachmentButton[ GLAUNCHER_ATTACHMENT_BUTTON ] = -1;
- if( ValidAttachment( UNDER_GLAUNCHER, gpItem->usItem ) )
+ if( ValidAttachment( UNDER_GLAUNCHER, gpItem ) )
{
guiAttachmentButton[ GLAUNCHER_ATTACHMENT_BUTTON ] =
CreateTextButton( L"G-LAUNCHER", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -855,7 +855,7 @@ void SetupArmourGUI()
}
guiCeramicPlatesButton = -1;
- if( ValidAttachment( CERAMIC_PLATES, gpItem->usItem ) )
+ if( ValidAttachment( CERAMIC_PLATES, gpItem ) )
{
guiCeramicPlatesButton =
CreateTextButton( L"CERAMIC PLATES", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
@@ -1012,7 +1012,7 @@ void SetupExplosivesGUI()
yp = 375;
gfDetonator = FALSE;
guiDetonatorButton = -1;
- if( ValidAttachment( DETONATOR, gpItem->usItem ) )
+ if( ValidAttachment( DETONATOR, gpItem ) )
{
guiDetonatorButton =
CreateTextButton( L"DETONATOR", SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
diff --git a/Editor/LoadScreen.cpp b/Editor/LoadScreen.cpp
index b7372720..b7acf76c 100644
--- a/Editor/LoadScreen.cpp
+++ b/Editor/LoadScreen.cpp
@@ -43,9 +43,11 @@
#include "Item Statistics.h"
#include "Scheduling.h"
#include "MessageBoxScreen.h"
- #include "VFS/vfs.h"//dnl ch37 110909
+ #include //dnl ch37 110909
#endif
+INT16 gsMouseWheelDeltaValue;
+
//===========================================================================
BOOLEAN gfErrorCatch = FALSE;
@@ -190,7 +192,7 @@ void LoadSaveScreenEntry()
vfs::CVirtualProfile::FileIterator fit = prof->files(L"MAPS/*");
while(!fit.end())
{
- utf8string fname = fit.value()->getName().c_str();
+ vfs::String fname = fit.value()->getName().c_str();
memset(&FileInfo, 0, sizeof(GETFILESTRUCT));
strcpy(FileInfo.zFileName, fname.utf8().c_str());
FileInfo.uiFileSize = fname.length();
@@ -1013,8 +1015,7 @@ UINT32 ProcessFileIO()
return(EDIT_SCREEN);
}
gbCurrentFileIOStatus = IOSTATUS_NONE;
- utf8string msg = utf8string(" Error saving ") + ubNewFilename + utf8string(" file. Try another filename? ");
- CreateMessageBox((STR16)msg.c_wcs().c_str());
+ CreateMessageBox((STR16)(_BS(L" Error saving ") << (const char*)ubNewFilename << L" file. Try another filename? " << _BS::wget).c_str() );
return(guiCurrentScreen);
}
if( gfShowPits )
@@ -1035,6 +1036,9 @@ UINT32 ProcessFileIO()
InitErrorCatchDialog();
return EDIT_SCREEN;
}
+
+ fNewMapSaved = TRUE;
+
return EDIT_SCREEN;
case INITIATE_MAP_LOAD: //draw load message
SaveFontSettings();
@@ -1056,8 +1060,7 @@ UINT32 ProcessFileIO()
gbCurrentFileIOStatus = IOSTATUS_NONE;
gfGlobalError = FALSE;
gfLoadError = TRUE;
- utf8string msg = utf8string(" Error loading ") + ubNewFilename + utf8string(" file. Try another filename? ");
- CreateMessageBox((STR16)msg.c_wcs().c_str());
+ CreateMessageBox((STR16)(_BS(L" Error loading ") << (const char*)ubNewFilename << L" file. Try another filename? " << _BS::wget).c_str());
return(guiCurrentScreen);
}
//ADB these are NOT set yet! but they need to be, duh
diff --git a/Editor/LoadScreen.h b/Editor/LoadScreen.h
index 90c24dae..2958a605 100644
--- a/Editor/LoadScreen.h
+++ b/Editor/LoadScreen.h
@@ -42,6 +42,8 @@ BOOLEAN ValidMapFileName(STR16 szFilename);
BOOLEAN ExternalLoadMap(STR16 szFilename);
BOOLEAN ExternalSaveMap(STR16 szFilename);
+void InitErrorCatchDialog();
+
extern BOOLEAN gfErrorCatch;
extern CHAR16 gzErrorCatchString[ 256 ];
diff --git a/Editor/Sector Summary.cpp b/Editor/Sector Summary.cpp
index 9ea6fe33..4f38c493 100644
--- a/Editor/Sector Summary.cpp
+++ b/Editor/Sector Summary.cpp
@@ -39,10 +39,11 @@
#include "Soldier Create.h"
#include "GameVersion.h"
#include "Campaign Types.h"
+ #include "GameSettings.h"
#endif
-#include "VFS/vfs.h"
-#include "VFS/vfs_file_raii.h"
+#include
+#include
extern BOOLEAN gfOverheadMapDirty;
@@ -416,9 +417,10 @@ void CreateSummaryWindow()
if( gfAutoLoadA9 )
{
gfAutoLoadA9++;
- gsSelSectorX = 9;
- gsSelSectorY = 1;
- gpCurrentSectorSummary = gpSectorSummary[ 8 ][ 0 ][ 0 ];
+ gsSelSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;//9;
+ gsSelSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;//1;
+ //gpCurrentSectorSummary = gpSectorSummary[ 8 ][ 0 ][ 0 ];
+ gpCurrentSectorSummary = gpSectorSummary[ gGameExternalOptions.ubDefaultArrivalSectorX - 1 ][ gGameExternalOptions.ubDefaultArrivalSectorY - 1 ][ 0 ];
ButtonList[ iSummaryButton[ SUMMARY_LOAD ] ]->uiFlags |= BUTTON_CLICKED_ON;
}
}
@@ -761,6 +763,7 @@ void RenderItemDetails()
pItem = &gpWorldItemsSummaryArray[ i ].object;
uiExistChance += (100 - gpWorldItemsSummaryArray[ i ].ubNonExistChance) * pItem->ubNumberOfObjects;
uiStatus += (*pItem)[0]->data.objectStatus;
+ uiQuantity += pItem->ubNumberOfObjects;
}
}
}
@@ -1965,7 +1968,7 @@ void CreateGlobalSummary()
vfs::COpenWriteFile wfile(L"DevInfo\\readme.txt",true,true);
std::string str = "This information is used in conjunction with the editor.\n";
str += "This directory or it's contents shouldn't be included with final release.\n";
- TRYCATCH_RETHROW( wfile.file().write(str.c_str(), str.length()), L"" );
+ SGP_TRYCATCH_RETHROW( wfile->write(str.c_str(), str.length()), L"" );
#endif
// Snap: Restore the data directory once we are finished.
@@ -2155,6 +2158,8 @@ void SummaryLoadMapCallback( GUI_BUTTON *btn, INT32 reason )
SetFontForeground( FONT_LTKHAKI );
SetFontShadow( FONT_NEARBLACK );
+ fNewMapSaved = TRUE;
+
//swprintf( str, L"Loading map: %s...", gszDisplayName );
//mprintf( MAP_LEFT, MAP_BOTTOM+100, str );
//InvalidateRegion( MAP_LEFT, MAP_BOTTOM+100, MAP_LEFT+150, MAP_BOTTOM+110 );
@@ -2640,11 +2645,11 @@ void GenerateSummaryList()
vfs::COpenWriteFile wfile(L"DevInfo/readme.txt",true,true);
std::string str = "This information is used in conjunction with the editor.\n";
str += "This directory or it's contents shouldn't be included with final release.\n";
- TRYCATCH_RETHROW( wfile.file().write(str.c_str(), str.length()), L"");
+ SGP_TRYCATCH_RETHROW( wfile->write(str.c_str(), str.length()), L"");
}
- catch(CBasicException &ex)
+ catch(std::exception &ex)
{
- RETHROWEXCEPTION(L"Could not create readme.txt",&ex);
+ SGP_RETHROW(L"Could not create readme.txt", ex);
}
#endif
}
@@ -3220,6 +3225,9 @@ void SetupItemDetailsMode( BOOLEAN fAllowRecursion )
OBJECTTYPE *pItem;
UINT16 usPEnemyIndex, usNEnemyIndex;
+ SUMMARYFILE *s = gpCurrentSectorSummary;
+ MAPCREATE_STRUCT *m = &gpCurrentSectorSummary->MapInfo;
+
//Clear memory for all the item summaries loaded
if( gpWorldItemsSummaryArray )
{
@@ -3291,7 +3299,7 @@ void SetupItemDetailsMode( BOOLEAN fAllowRecursion )
gusWorldItemsSummaryArraySize = gpCurrentSectorSummary->usNumItems;
for (unsigned int x = 0; x < uiNumItems; ++x)
{
- gpWorldItemsSummaryArray[x].Load(hfile);
+ gpWorldItemsSummaryArray[x].Load(hfile, s->dMajorMapVersion, m->ubMapVersion);
}
//NOW, do the enemy's items!
diff --git a/Editor/edit_sys.cpp b/Editor/edit_sys.cpp
index 34ef96e8..c5877cba 100644
--- a/Editor/edit_sys.cpp
+++ b/Editor/edit_sys.cpp
@@ -365,8 +365,9 @@ void PasteSingleWallCommon( INT32 iMapIndex )
// TEMP STUFF FOR ONROOF THINGS!
if ( (usUseObjIndex >= FIRSTONROOF) && (usUseObjIndex <= SECONDONROOF ) )
{
+ // WANNE: Disabled the next line, because if makes placing sandbags on rooftops impossible!
//dnl Remove all onroof things before placing new one to avoid stacking problems of same element
- RemoveAllOnRoofsOfTypeRange( iMapIndex, FIRSTONROOF, SECONDONROOF );
+ //RemoveAllOnRoofsOfTypeRange( iMapIndex, FIRSTONROOF, SECONDONROOF );
// Add to onroof section!
AddOnRoofToTail( iMapIndex, (UINT16)(gTileTypeStartIndex[ usUseObjIndex ] + usUseIndex) );
diff --git a/Editor/editscreen.cpp b/Editor/editscreen.cpp
index efa73a4e..b2e49663 100644
--- a/Editor/editscreen.cpp
+++ b/Editor/editscreen.cpp
@@ -214,6 +214,7 @@ BOOLEAN gfRealGunNut = TRUE;
INT16 sGridX, sGridY;
INT32 iMapIndex;
BOOLEAN fNewMap = FALSE;
+BOOLEAN fNewMapSaved = TRUE;
INT32 iPrevDrawMode = DRAW_MODE_NOTHING;
UINT16 PrevCurrentPaste = FIRSTTEXTURE;
@@ -297,7 +298,8 @@ BOOLEAN EditModeInit( void )
//dnl after multiplayer stuff was implemeted, editor goes to assertion when you leave editor mode, because InitGameOption() is not called anymore from InitializeGame()
is_networked = FALSE;
- InitGameOptions();
+ //InitGameOptions();
+ GameInitOptionsScreenInit();
ResetCustomFileSectorSummary();//dnl ch30 150909
@@ -375,6 +377,7 @@ BOOLEAN EditModeInit( void )
gfEditMode = TRUE;
fNewMap = FALSE;
+ fNewMapSaved = TRUE;
gfEditingDoor = FALSE;
@@ -2483,6 +2486,8 @@ void CreateNewMap()
ResetCustomFileSectorSummary();//dnl ch30 150909
SetRenderCenter(WORLD_COLS/2, WORLD_ROWS/2);//dnl ch43 280909
InitRenderParams(gMapInformation.ubRestrictedScrollID);//dnl ch54 101009
+
+ fNewMapSaved = FALSE;
}
diff --git a/Editor/editscreen.h b/Editor/editscreen.h
index 162dd07c..858a2b58 100644
--- a/Editor/editscreen.h
+++ b/Editor/editscreen.h
@@ -14,6 +14,9 @@ extern GUI_BUTTON *gpPersistantButton;
extern UINT16 GenericButtonFillColors[40];
+// WANNE: 05.10.2010
+extern BOOLEAN fNewMapSaved;
+
void DisplayWayPoints(void);
BOOLEAN CheckForSlantRoofs( void );
diff --git a/Editor/selectwin.cpp b/Editor/selectwin.cpp
index c4f6d0cb..728646a6 100644
--- a/Editor/selectwin.cpp
+++ b/Editor/selectwin.cpp
@@ -185,36 +185,36 @@ void CreateJA2SelectionWindow( INT16 sWhat )
DisableEditorTaskbar( );
// Load up the button images
- iButtonIcons[ CANCEL_ICON ] = LoadGenericButtonIcon( "EDITOR//bigX.sti" );
- iButtonIcons[ UP_ICON ] = LoadGenericButtonIcon( "EDITOR//lgUpArrow.sti" );
- iButtonIcons[ DOWN_ICON ] = LoadGenericButtonIcon( "EDITOR//lgDownArrow.sti" );
- iButtonIcons[ OK_ICON ] = LoadGenericButtonIcon( "EDITOR//checkmark.sti" );
+ iButtonIcons[ SEL_WIN_CANCEL_ICON ] = LoadGenericButtonIcon( "EDITOR//bigX.sti" );
+ iButtonIcons[ SEL_WIN_UP_ICON ] = LoadGenericButtonIcon( "EDITOR//lgUpArrow.sti" );
+ iButtonIcons[ SEL_WIN_DOWN_ICON ] = LoadGenericButtonIcon( "EDITOR//lgDownArrow.sti" );
+ iButtonIcons[ SEL_WIN_OK_ICON ] = LoadGenericButtonIcon( "EDITOR//checkmark.sti" );
iSelectWin = CreateHotSpot(0, 0, 600, 360, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, SelWinClkCallback);
- iCancelWin = CreateIconButton((INT16)iButtonIcons[CANCEL_ICON], 0,
+ iCancelWin = CreateIconButton((INT16)iButtonIcons[SEL_WIN_CANCEL_ICON], 0,
BUTTON_USE_DEFAULT, 600, 40,
40, 40, BUTTON_TOGGLE,
MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, CnclClkCallback);
SetButtonFastHelpText(iCancelWin,L"Cancel selections");
- iOkWin = CreateIconButton((INT16)iButtonIcons[OK_ICON], 0,
+ iOkWin = CreateIconButton((INT16)iButtonIcons[SEL_WIN_OK_ICON], 0,
BUTTON_USE_DEFAULT, 600, 0,
40, 40, BUTTON_TOGGLE,
MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, OkClkCallback);
SetButtonFastHelpText(iOkWin,L"Accept selections");
- iScrollUp = CreateIconButton((INT16)iButtonIcons[UP_ICON], 0,
+ iScrollUp = CreateIconButton((INT16)iButtonIcons[SEL_WIN_UP_ICON], 0,
BUTTON_USE_DEFAULT, 600, 80,
40, 160, BUTTON_NO_TOGGLE,
MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, UpClkCallback);
SetButtonFastHelpText(iScrollUp,L"Scroll window up");
- iScrollDown = CreateIconButton((INT16)iButtonIcons[DOWN_ICON], 0,
+ iScrollDown = CreateIconButton((INT16)iButtonIcons[SEL_WIN_DOWN_ICON], 0,
BUTTON_USE_DEFAULT, 600, 240,
40, 160, BUTTON_NO_TOGGLE,
MSYS_PRIORITY_HIGH,
diff --git a/Editor/selectwin.h b/Editor/selectwin.h
index fe02e8aa..7d9c8981 100644
--- a/Editor/selectwin.h
+++ b/Editor/selectwin.h
@@ -10,10 +10,10 @@
#include "mousesystem.h"
#include "Button System.h"
-#define CANCEL_ICON 0
-#define UP_ICON 1
-#define DOWN_ICON 2
-#define OK_ICON 3
+#define SEL_WIN_CANCEL_ICON 0
+#define SEL_WIN_UP_ICON 1
+#define SEL_WIN_DOWN_ICON 2
+#define SEL_WIN_OK_ICON 3
extern INT32 iButtonIcons[4];
extern INT32 iSelectWin,iCancelWin,iScrollUp,iScrollDown;
diff --git a/Fade Screen.cpp b/Fade Screen.cpp
index ee6e21b9..9e7d930f 100644
--- a/Fade Screen.cpp
+++ b/Fade Screen.cpp
@@ -30,7 +30,8 @@ INT32 giX1, giX2, giY1, giY2;
INT16 gsFadeRealCount;
BOOLEAN gfFadeInVideo;
-UINT32 uiOldMusicMode;
+// unused
+//UINT32 uiOldMusicMode;
FADE_FUNCTION gFadeFunction = NULL;
@@ -154,7 +155,8 @@ void BeginFade( UINT32 uiExitScreen, INT8 bFadeValue, INT8 bType, UINT32 uiDelay
gfFadeIn = FALSE;
gfFadeInVideo = TRUE;
- uiOldMusicMode = uiMusicHandle;
+ // unused
+ //uiOldMusicMode = uiMusicHandle;
// Calculate step;
diff --git a/GameInitOptionsScreen.cpp b/GameInitOptionsScreen.cpp
index 5dacb4c4..041c5ce7 100644
--- a/GameInitOptionsScreen.cpp
+++ b/GameInitOptionsScreen.cpp
@@ -28,65 +28,122 @@
#include "connect.h"
#include "saveloadscreen.h"
+#include
+#include
+#include
+#include
+
+//////////////////////////////////////////////////////////////
+// SANDRO - the start-new-game screen has been changed a lot
+//////////////////////////////////////////////////////////////
+
////////////////////////////////////////////
//
// Global Defines
//
///////////////////////////////////////////
-#define GIO_TITLE_FONT FONT14ARIAL//FONT16ARIAL
-#define GIO_TITLE_COLOR FONT_MCOLOR_WHITE
+#define GIO_TITLE_FONT FONT14ARIAL
+#define GIO_TITLE_COLOR FONT_MCOLOR_WHITE
-#define GIO_TOGGLE_TEXT_FONT FONT12ARIAL//FONT16ARIAL
-#define GIO_TOGGLE_TEXT_COLOR FONT_MCOLOR_WHITE
+#define GIO_TOGGLE_TEXT_FONT FONT10ARIAL
+#define GIO_TOGGLE_TEXT_COLOR FONT_MCOLOR_WHITE
//buttons
-#define GIO_BTN_OK_X iScreenWidthOffset + ((320 - 115) / 2)
-#define GIO_BTN_OK_Y iScreenHeightOffset + 435
-#define GIO_CANCEL_X iScreenWidthOffset + 320 + 143
+#define GIO_CANCEL_X iScreenWidthOffset + ((320 - 115) / 2)
+
+#define GIO_BTN_START_X iScreenWidthOffset + 320 + 105
+#define GIO_BTN_START_Y iScreenHeightOffset + 435
+
//main title
-#define GIO_MAIN_TITLE_X 0
+#define GIO_MAIN_TITLE_X 0
#define GIO_MAIN_TITLE_Y iScreenHeightOffset + 10
#define GIO_MAIN_TITLE_WIDTH SCREEN_WIDTH
//radio box locations
-#define GIO_GAP_BN_SETTINGS 35
-#define GIO_OFFSET_TO_TEXT 30
-#define GIO_OFFSET_TO_TOGGLE_BOX 250
-#define GIO_OFFSET_TO_TOGGLE_BOX_Y 9
+#define GIO_GAP_BN_SETTINGS 35
+#define GIO_OFFSET_TO_TEXT 36
+#define GIO_OFFSET_TO_TOGGLE_BOX 180
+#define GIO_OFFSET_TO_TOGGLE_BOX_Y 9
-#define GIO_DIF_SETTINGS_X iScreenWidthOffset + 20
-#define GIO_DIF_SETTINGS_Y iScreenHeightOffset + 75
-#define GIO_DIF_SETTINGS_WIDTH GIO_OFFSET_TO_TOGGLE_BOX - GIO_OFFSET_TO_TEXT
+#define GIO_TITLE_DISTANCE 30 // higher means closer
+
+#define GIO_DIF_SETTING_X iScreenWidthOffset + 48
+#define GIO_DIF_SETTING_Y iScreenHeightOffset + 55
+#define GIO_DIF_SETTING_WIDTH GIO_OFFSET_TO_TOGGLE_BOX - GIO_OFFSET_TO_TEXT
+
+#define GIO_IMP_SETTING_X GIO_DIF_SETTING_X
+#define GIO_IMP_SETTING_Y GIO_DIF_SETTING_Y + 63
+#define GIO_IMP_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+// old/new traits
+#define GIO_TRAITS_SETTING_X GIO_DIF_SETTING_X + 36
+#define GIO_TRAITS_SETTING_Y GIO_IMP_SETTING_Y + 52
+#define GIO_TRAITS_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
// Madd
-#define GIO_GAME_SETTINGS_X GIO_DIF_SETTINGS_X
-#define GIO_GAME_SETTINGS_Y GIO_GUN_SETTINGS_Y
-#define GIO_GAME_SETTINGS_WIDTH GIO_DIF_SETTINGS_WIDTH
+#define GIO_GAME_SETTING_X GIO_TRAITS_SETTING_X
+#define GIO_GAME_SETTING_Y GIO_TRAITS_SETTING_Y + 67
+#define GIO_GAME_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
-#define GIO_GUN_SETTINGS_X GIO_BR_SETTING_X
-#define GIO_GUN_SETTINGS_Y iScreenHeightOffset + 242
-#define GIO_GUN_SETTINGS_WIDTH GIO_DIF_SETTINGS_WIDTH
+#define GIO_IRON_MAN_SETTING_X GIO_TRAITS_SETTING_X
+#define GIO_IRON_MAN_SETTING_Y GIO_GAME_SETTING_Y + 67
+#define GIO_IRON_MAN_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_TERRORISTS_SETTING_X GIO_TRAITS_SETTING_X
+#define GIO_TERRORISTS_SETTING_Y GIO_IRON_MAN_SETTING_Y + 67
+#define GIO_TERRORISTS_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_BR_SETTING_X iScreenWidthOffset + 370
+#define GIO_BR_SETTING_Y GIO_DIF_SETTING_Y
+#define GIO_BR_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_PROGRESS_SETTING_X GIO_BR_SETTING_X
+#define GIO_PROGRESS_SETTING_Y GIO_BR_SETTING_Y + 63
+#define GIO_PROGRESS_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_INV_SETTING_X GIO_PROGRESS_SETTING_X
+#define GIO_INV_SETTING_Y GIO_PROGRESS_SETTING_Y + 63
+#define GIO_INV_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_DROPALL_SETTING_X GIO_INV_SETTING_X + 36
+#define GIO_DROPALL_SETTING_Y GIO_INV_SETTING_Y + 56
+#define GIO_DROPALL_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_GUN_SETTING_X GIO_DROPALL_SETTING_X
+#define GIO_GUN_SETTING_Y GIO_DROPALL_SETTING_Y + 67
+#define GIO_GUN_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_CACHES_SETTING_X GIO_GUN_SETTING_X
+#define GIO_CACHES_SETTING_Y GIO_GUN_SETTING_Y + 67
+#define GIO_CACHES_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+#define GIO_TIMED_TURN_SETTING_X GIO_GUN_SETTING_X
+#define GIO_TIMED_TURN_SETTING_Y GIO_IRON_MAN_SETTING_Y
+#define GIO_TIMED_TURN_SETTING_WIDTH GIO_DIF_SETTING_WIDTH
+
+// INI File
+#define JA2SP_INI_FILENAME "ja2_sp.ini"
+
+// INI Section
+#define JA2SP_INI_INITIAL_SECTION "JA2 Singleplayer Initial Settings"
+
+// INI Properties
+#define JA2SP_DIFFICULTY_LEVEL "DIFFICULTY_LEVEL"
+#define JA2SP_BOBBY_RAY_SELECTION "BOBBY_RAY_SELECTION"
+#define JA2SP_MAX_IMP_CHARACTERS "MAX_IMP_CHARACTERS"
+#define JA2SP_PROGRESS_SPEED_OF_ITEM_CHOICES "PROGRESS_SPEED_OF_ITEM_CHOICES"
+#define JA2SP_SKILL_TRAITS "SKILL_TRAITS"
+#define JA2SP_INVENTORY_ATTACHMENTS "INVENTORY_ATTACHMENTS"
+#define JA2SP_GAME_STYLE "GAME_STYLE"
+#define JA2SP_ENEMIES_DROP_ALL_ITEMS "ENEMIES_DROP_ALL_ITEMS"
+#define JA2SP_EXTRA_DIFFICULTY "EXTRA_DIFFICULTY"
+#define JA2SP_AVAILABLE_ARSENAL "AVAILABLE_ARSENAL"
+#define JA2SP_NUMBER_OF_TERRORISTS "NUMBER_OF_TERRORISTS"
+#define JA2SP_SECRET_WEAPON_CACHES "SECRET_WEAPON_CACHES"
-#define GIO_TIMED_TURN_SETTING_X GIO_GUN_SETTINGS_X
-#define GIO_TIMED_TURN_SETTING_Y GIO_IRON_MAN_SETTING_Y//hayden
-#define GIO_TIMED_TURN_SETTING_WIDTH GIO_DIF_SETTINGS_WIDTH
-
-
-// Madd
-#define GIO_BR_SETTING_X iScreenWidthOffset + 340
-#define GIO_BR_SETTING_Y GIO_DIF_SETTINGS_Y
-#define GIO_BR_SETTING_WIDTH GIO_DIF_SETTINGS_WIDTH
-#define GIO_IRON_MAN_SETTING_X iScreenWidthOffset + 20
-#define GIO_IRON_MAN_SETTING_Y iScreenHeightOffset + 355
-#define GIO_IRON_MAN_SETTING_WIDTH GIO_DIF_SETTINGS_WIDTH
-
-// CHRISL:
-#define GIO_INV_SETTING_X iScreenWidthOffset + 340
-#define GIO_INV_SETTING_Y GIO_IRON_MAN_SETTING_Y
-#define GIO_INV_SETTING_WIDTH GIO_DIF_SETTINGS_WIDTH
//Difficulty settings
enum
@@ -95,29 +152,44 @@ enum
GIO_DIFF_MED,
GIO_DIFF_HARD,
GIO_DIFF_INSANE,
+
NUM_DIFF_SETTINGS,
};
+enum
+{
+ GIO_TRAITS_OLD,
+ GIO_TRAITS_NEW,
+
+ NUM_TRAIT_OPTIONS,
+};
+
// Game Settings options
enum
{
GIO_REALISTIC,
- GIO_SCI_FI,
- //GIO_PLATINUM,
+ GIO_SCI_FI,
NUM_GAME_STYLES,
};
-// Gun options
+// Iron man mode
enum
{
- GIO_REDUCED_GUNS,
- GIO_GUN_NUT,
+ GIO_CAN_SAVE,
+ GIO_IRON_MAN,
- NUM_GUN_OPTIONS,
+ NUM_SAVE_OPTIONS,
+};
+
+enum
+{
+ GIO_TERRORISTS_RANDOM,
+ GIO_TERRORISTS_ALL,
+
+ NUM_TERRORISTS_OPTIONS,
};
-// Madd
// BR options
enum
{
@@ -129,38 +201,63 @@ enum
NUM_BR_OPTIONS,
};
-// CHRISL: New inventory options
+enum
+{
+ GIO_PROGRESS_VERY_SLOW,
+ GIO_PROGRESS_SLOW,
+ GIO_PROGRESS_NORMAL,
+ GIO_PROGRESS_FAST,
+ GIO_PROGRESS_VERY_FAST,
+
+ NUM_PROGRESS_OPTIONS,
+};
+
+// New inventory options
enum
{
GIO_INV_OLD,
GIO_INV_NEW,
+ GIO_INV_NEW_NAS, // WANNE: Added NAS to the start new game screen
NUM_INV_OPTIONS,
};
-// JA2Gold: no more timed turns setting
+enum
+{
+ GIO_DROPALL_OFF,
+ GIO_DROPALL_ON,
+
+ NUM_DROPALL_OPTIONS,
+};
+
+// Gun options
+enum
+{
+ GIO_REDUCED_GUNS,
+ GIO_GUN_NUT,
+
+ NUM_GUN_OPTIONS,
+};
+
+enum
+{
+ GIO_CACHES_RANDOM,
+ GIO_CACHES_ALL,
+
+ NUM_CACHES_OPTIONS,
+};
-//enum for the timed turns setting
+// Timed turns setting (Multiplayer exclusive)
enum
{
GIO_NO_TIMED_TURNS,
GIO_TIMED_TURNS,
GIO_NUM_TIMED_TURN_OPTIONS,
-};//hayden : re-enabled
-
-
-// Iron man mode
-
-enum
-{
- GIO_CAN_SAVE,
- GIO_IRON_MAN,
-
- NUM_SAVE_OPTIONS,
};
+
//enum for different states of game
enum
{
@@ -182,27 +279,22 @@ BOOLEAN gfGIOScreenExit = FALSE;
BOOLEAN gfReRenderGIOScreen=TRUE;
BOOLEAN gfGIOButtonsAllocated = FALSE;
-UINT8 gubGameOptionScreenHandler=GIO_NOTHING;
+UINT8 gubGameOptionScreenHandler=GIO_NOTHING;
UINT32 gubGIOExitScreen = GAME_INIT_OPTIONS_SCREEN;
UINT32 guiGIOMainBackGroundImage;
+INT32 giGioMessageBox = -1;
-INT32 giGioMessageBox = -1;
-//BOOLEAN gfExitGioDueToMessageBox=FALSE;
+INT8 iCurrentDifficulty;
+INT8 iCurrentBRSetting;
+INT8 iCurrentIMPNumberSetting;
+INT8 iCurrentProgressSetting;
+INT8 iCurrentInventorySetting;
-//UINT8 gubDifficultySettings[ NUM_DIFF_SETTINGS ];
-//UINT8 gubGameSettings[ NUM_GAME_STYLES ];
-//UINT8 gubGunSettings[ NUM_GUN_OPTIONS ];
-
-//extern INT32 gp16PointArial;
-
-
-// CHRISL: checkbox to toggle INV selection
-UINT32 guiINVOptionToggles[ NUM_INV_OPTIONS ];
-void BtnINVOptionTogglesCallback(GUI_BUTTON *btn,INT32 reason);
+UINT32 guiGIOSMALLFRAME;
// Done Button
void BtnGIODoneCallback(GUI_BUTTON *btn,INT32 reason);
@@ -219,34 +311,75 @@ void MPBtnGIOCancelCallback(GUI_BUTTON *btn,INT32 reason);
UINT32 MPguiGIOCancelButton;
INT32 MPgiGIOCancelBtnImage;
+UINT32 giGIODifficultyButton[ 2 ];
+INT32 giGIODifficultyButtonImage[ 2 ];
+void BtnGIODifficultySelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnGIODifficultySelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
-//checkbox to toggle the Diff level
-UINT32 guiDifficultySettingsToggles[ NUM_DIFF_SETTINGS ];
-void BtnDifficultyTogglesCallback(GUI_BUTTON *btn,INT32 reason);
+UINT32 giGIOIMPNumberButton[ 2 ];
+INT32 giGIOIMPNumberButtonImage[ 2 ];
+void BtnGIOIMPNumberSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnGIOIMPNumberSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+UINT32 giGIOBRSettingButton[ 2 ];
+INT32 giGIOBRSettingButtonImage[ 2 ];
+void BtnGIOBRSettingLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnGIOBRSettingRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+UINT32 giGIOProgressSettingButton[ 2 ];
+INT32 giGIOProgressSettingButtonImage[ 2 ];
+void BtnGIOProgressSettingLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnGIOProgressSettingRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+UINT32 giGIOInventorySettingButton [ 2 ];
+INT32 giGIOInventorySettingButtonImage [ 2 ];
+void BtnGIOInventorySettingLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnGIOInventorySettingRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+UINT32 guiTraitsOptionTogglesImage[ NUM_TRAIT_OPTIONS ];
+UINT32 guiTraitsOptionToggles[ NUM_TRAIT_OPTIONS ];
+void BtnGIOOldTraitsCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIONewTraitsCallback(GUI_BUTTON *btn,INT32 reason);
+void NewTraitsNotPossibleMessageBoxCallBack( UINT8 bExitValue );
//checkbox to toggle Game style
+UINT32 guiGameStyleTogglesImage[ NUM_GAME_STYLES ];
UINT32 guiGameStyleToggles[ NUM_GAME_STYLES ];
-void BtnGameStyleTogglesCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIORealisticStyleCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIOScifiStyleCallback(GUI_BUTTON *btn,INT32 reason);
+
+//checkbox to toggle Save style
+UINT32 guiGameSaveTogglesImage[ NUM_SAVE_OPTIONS ];
+UINT32 guiGameSaveToggles[ NUM_SAVE_OPTIONS ];
+void BtnGIOIronManOffCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIOIronManOnCallback(GUI_BUTTON *btn,INT32 reason);
+
+UINT32 guiTerroristsOptionTogglesImage[ NUM_TERRORISTS_OPTIONS ];
+UINT32 guiTerroristsOptionToggles[ NUM_TERRORISTS_OPTIONS ];
+void BtnGIOTerroristsRandomCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIOTerroristsAllCallback(GUI_BUTTON *btn,INT32 reason);
+
+UINT32 guiDropAllOptionTogglesImage[ NUM_DROPALL_OPTIONS ];
+UINT32 guiDropAllOptionToggles[ NUM_DROPALL_OPTIONS ];
+void BtnGIODropAllOffCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIODropAllOnCallback(GUI_BUTTON *btn,INT32 reason);
//checkbox to toggle Gun options
+UINT32 guiGunOptionTogglesImage[ NUM_GUN_OPTIONS ];
UINT32 guiGunOptionToggles[ NUM_GUN_OPTIONS ];
-void BtnGunOptionsTogglesCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIOGunSettingReducedCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIOGunSettingToGCallback(GUI_BUTTON *btn,INT32 reason);
+
+UINT32 guiWeaponCachesOptionTogglesImage[ NUM_CACHES_OPTIONS ];
+UINT32 guiWeaponCachesOptionToggles[ NUM_CACHES_OPTIONS ];
+void BtnGIOWeaponCachesRandomCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnGIOWeaponCachesAllCallback(GUI_BUTTON *btn,INT32 reason);
+
-// JA2Gold: no more timed turns setting
-//hayden : re-enabled
-//checkbox to toggle Timed turn option on or off
UINT32 guiTimedTurnToggles[ GIO_NUM_TIMED_TURN_OPTIONS ];
void BtnTimedTurnsTogglesCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox to toggle Save style
-UINT32 guiGameSaveToggles[ NUM_SAVE_OPTIONS ];
-void BtnGameSaveTogglesCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox to toggle BR selection
-UINT32 guiBROptionToggles[ NUM_BR_OPTIONS ];
-void BtnBROptionTogglesCallback(GUI_BUTTON *btn,INT32 reason);
-
+void RenderGIOSmallSelectionFrame(INT16 sX, INT16 sY);
////////////////////////////////////////////
//
@@ -265,24 +398,131 @@ UINT8 GetCurrentGunButtonSetting();
// JA2Gold: added save (iron man) button setting
UINT8 GetCurrentGameSaveButtonSetting();
UINT8 GetCurrentGameStyleButtonSetting();
-UINT8 GetCurrentDifficultyButtonSetting();
-void RestoreGIOButtonBackGrounds();
-void DoneFadeOutForExitGameInitOptionScreen( void );
-void DoneFadeInForExitGameInitOptionScreen( void );
-// JA2Gold: no more timed turns setting
-UINT8 GetCurrentTimedTurnsButtonSetting();//hayden : re-enabled
-BOOLEAN DoGioMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback );
-void DisplayMessageToUserAboutGameDifficulty();
-void ConfirmGioDifSettingMessageBoxCallBack( UINT8 bExitValue );
-BOOLEAN DisplayMessageToUserAboutIronManMode();
-void ConfirmGioIronManMessageBoxCallBack( UINT8 bExitValue );
+// SANDRO - added following
+UINT8 GetCurrentTraitsOptionButtonSetting();
+UINT8 GetCurrentDropAllButtonSetting();
+UINT8 GetCurrentTerroristsButtonSetting();
+UINT8 GetCurrentWeaponCachesButtonSetting();
+
+void DoneFadeOutForExitGameInitOptionScreen( void );
+void DoneFadeInForExitGameInitOptionScreen( void );
+UINT8 GetCurrentTimedTurnsButtonSetting();
+BOOLEAN DoGioMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback );
+void DisplayMessageToUserAboutGameDifficulty();
+void ConfirmGioDifSettingMessageBoxCallBack( UINT8 bExitValue );
+BOOLEAN DisplayMessageToUserAboutIronManMode();
+BOOLEAN DisplayMessageToUserAboutOIVandNASincompatibility();
+void ConfirmGioIronManMessageBoxCallBack( UINT8 bExitValue );
+
+BOOLEAN SpIniExists()
+{
+ BOOLEAN exists = TRUE;
+
+ if(!getVFS()->fileExists(JA2SP_INI_FILENAME))
+ exists = FALSE;
+
+ return exists;
+}
UINT32 GameInitOptionsScreenInit( void )
{
- return( 1 );
-}
+ memset( &gGameOptions, 0, sizeof( GAME_OPTIONS ) );
+ // WANNE: Read initial game settings from ja2_sp.ini
+ vfs::PropertyContainer props;
+
+ if (SpIniExists())
+ props.initFromIniFile(JA2SP_INI_FILENAME);
+
+ // Difficulty Level (Default: Experienced = 1)
+ gGameOptions.ubDifficultyLevel = ((UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_DIFFICULTY_LEVEL, 1)) + 1;
+
+ // Bobby Ray's Selection (Default: Great = 1)
+ UINT8 ubBobbyRay = (UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_BOBBY_RAY_SELECTION, 1);
+ switch (ubBobbyRay)
+ {
+ // Normal
+ case 0:
+ gGameOptions.ubBobbyRay = BR_GOOD;
+ break;
+ // Great
+ case 1:
+ gGameOptions.ubBobbyRay = BR_GREAT;
+ break;
+ // Excellent
+ case 2:
+ gGameOptions.ubBobbyRay = BR_EXCELLENT;
+ break;
+ // Awesome
+ case 3:
+ gGameOptions.ubBobbyRay = BR_AWESOME;
+ break;
+ }
+
+ // Max. IMP Characters
+ UINT8 maxIMPCharacterCount = (UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_MAX_IMP_CHARACTERS, 1);
+ gGameOptions.ubMaxIMPCharacters = min( (gGameExternalOptions.iIMPMaleCharacterCount + gGameExternalOptions.iIMPFemaleCharacterCount), ( max( 1, maxIMPCharacterCount) ));
+
+ // Progress Speed of Item Choices (Default: Normal)
+ gGameOptions.ubProgressSpeedOfItemsChoices = (UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_PROGRESS_SPEED_OF_ITEM_CHOICES, ITEM_PROGRESS_NORMAL);
+
+ // Skill Traits
+ UINT8 ubTraitSystem = (UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_SKILL_TRAITS, 1);
+ if (!gGameExternalOptions.fReadProfileDataFromXML)
+ ubTraitSystem = 0;
+
+ gGameOptions.fNewTraitSystem = ubTraitSystem;
+
+ // Inventory Attachments (Default: New/New = 2)
+ UINT8 ubInventoryAttachmentSystem = (UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_INVENTORY_ATTACHMENTS, 2);
+
+ // NIV is not allowed
+ if (!IsNIVModeValid(true))
+ ubInventoryAttachmentSystem = 0;
+
+ switch (ubInventoryAttachmentSystem)
+ {
+ // Old / Old
+ case 0:
+ gGameOptions.ubInventorySystem = INVENTORY_OLD;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_OLD;
+ break;
+ // New / Old
+ case 1:
+ gGameOptions.ubInventorySystem = INVENTORY_NEW;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_OLD;
+ break;
+ // New / New
+ case 2:
+ gGameOptions.ubInventorySystem = INVENTORY_NEW;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_NEW;
+ break;
+ }
+
+ // Game Style (Default: Realistic = 0)
+ gGameOptions.ubGameStyle = (UINT8)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_GAME_STYLE, STYLE_REALISTIC);
+
+ // Enemies Drop All Items (Default: Off = 0)
+ gGameOptions.fEnemiesDropAllItems = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_ENEMIES_DROP_ALL_ITEMS, 0);
+
+ // Extra Difficulty (Default: Save Anytime = 0)
+ gGameOptions.fIronManMode = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_EXTRA_DIFFICULTY, 0);
+
+ // Available Arsenal (Default: Tons of Guns = 1)
+ gGameOptions.fGunNut = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_AVAILABLE_ARSENAL, 1);
+
+ // Number of Terrorists (Default: Random = 0)
+ gGameOptions.fEnableAllTerrorists = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_NUMBER_OF_TERRORISTS, 0);
+
+ // Secret Weapon Caches (Default: Random = 0)
+ gGameOptions.fEnableAllWeaponCaches = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_SECRET_WEAPON_CACHES, 0);
+
+ gGameOptions.fAirStrikes = FALSE;
+ gGameOptions.fTurnTimeLimit = FALSE;
+
+ return (1);
+}
UINT32 GameInitOptionsScreenHandle( void )
{
@@ -290,7 +530,7 @@ UINT32 GameInitOptionsScreenHandle( void )
if( gfGIOScreenEntry )
{
-// PauseGame();
+ GameInitOptionsScreenInit();
EnterGIOScreen();
gfGIOScreenEntry = FALSE;
@@ -300,18 +540,12 @@ UINT32 GameInitOptionsScreenHandle( void )
GetGIOScreenUserInput();
-
HandleGIOScreen();
// render buttons marked dirty
MarkButtonsDirty( );
RenderButtons( );
- // render help
-// RenderFastHelp( );
-// RenderButtonsFastHelp( );
-
-
ExecuteBaseDirtyRectQueue();
EndFrameBufferRender();
@@ -353,10 +587,8 @@ UINT32 GameInitOptionsScreenShutdown( void )
BOOLEAN EnterGIOScreen()
{
- VOBJECT_DESC VObjectDesc;
- UINT16 cnt;
- UINT16 usPosY;
-
+ VOBJECT_DESC VObjectDesc, VObjectDesc2;
+
if( gfGIOButtonsAllocated )
return( TRUE );
@@ -380,13 +612,17 @@ BOOLEAN EnterGIOScreen()
CHECKF(AddVideoObject(&VObjectDesc, &guiGIOMainBackGroundImage ));
+ VObjectDesc2.fCreateFlags=VOBJECT_CREATE_FROMFILE;
+ FilenameForBPP("INTERFACE\\GIOSmallFrame.sti", VObjectDesc2.ImageFile);
+ CHECKF(AddVideoObject(&VObjectDesc2, &guiGIOSMALLFRAME));
+
//Ok button
giGIODoneBtnImage = LoadButtonImage("INTERFACE\\PreferencesButtons.sti", -1,0,-1,2,-1 );
- guiGIODoneButton = CreateIconAndTextButton( giGIODoneBtnImage, gzGIOScreenText[GIO_OK_TEXT], OPT_BUTTON_FONT,
+ guiGIODoneButton = CreateIconAndTextButton( giGIODoneBtnImage, gzGIOScreenText[GIO_START_TEXT], OPT_BUTTON_FONT,
OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW,
OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW,
TEXT_CJUSTIFIED,
- GIO_BTN_OK_X, GIO_BTN_OK_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ GIO_BTN_START_X, GIO_BTN_START_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, BtnGIODoneCallback);
SpecifyButtonSoundScheme( guiGIODoneButton, BUTTON_SOUND_SCHEME_BIGSWITCH3 );
@@ -398,188 +634,364 @@ BOOLEAN EnterGIOScreen()
OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW,
OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW,
TEXT_CJUSTIFIED,
- GIO_CANCEL_X, GIO_BTN_OK_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ GIO_CANCEL_X, GIO_BTN_START_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
DEFAULT_MOVE_CALLBACK, BtnGIOCancelCallback );
SpecifyButtonSoundScheme( guiGIOCancelButton, BUTTON_SOUND_SCHEME_BIGSWITCH3 );
- //MP button
- if(is_networked)
- {
- MPgiGIOCancelBtnImage = UseLoadedButtonImage( giGIODoneBtnImage, -1,1,-1,3,-1 );
- MPguiGIOCancelButton = CreateIconAndTextButton( giGIOCancelBtnImage, gzGIOScreenText[GIO_LOAD_MP_GAME], OPT_BUTTON_FONT,
- OPT_BUTTON_ON_COLOR, DEFAULT_SHADOW,
- OPT_BUTTON_OFF_COLOR, DEFAULT_SHADOW,
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DIFFICULTY SETTING
+
+ giGIODifficultyButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giGIODifficultyButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giGIODifficultyButton[ 0 ] = QuickCreateButton( giGIODifficultyButtonImage[ 0 ], GIO_DIF_SETTING_X + 39, GIO_DIF_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnGIODifficultySelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giGIODifficultyButton[ 1 ] = QuickCreateButton( giGIODifficultyButtonImage[ 1 ], GIO_DIF_SETTING_X + 158, GIO_DIF_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnGIODifficultySelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giGIODifficultyButton[0],0, 0 );
+ MSYS_SetBtnUserData(giGIODifficultyButton[1],0, 1 );
+
+ iCurrentDifficulty = max( 0, gGameOptions.ubDifficultyLevel - 1);
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MAX IMP NUMBER SETTING
+
+ giGIOIMPNumberButtonImage[ 0 ]= UseLoadedButtonImage( giGIODifficultyButtonImage[ 0 ],-1,0,-1,1,-1 );
+ giGIOIMPNumberButtonImage[ 1 ]= UseLoadedButtonImage( giGIODifficultyButtonImage[ 1 ],-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giGIOIMPNumberButton[ 0 ] = QuickCreateButton( giGIOIMPNumberButtonImage[ 0 ], GIO_IMP_SETTING_X + 39, GIO_IMP_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnGIOIMPNumberSelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giGIOIMPNumberButton[ 1 ] = QuickCreateButton( giGIOIMPNumberButtonImage[ 1 ], GIO_IMP_SETTING_X + 158, GIO_IMP_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnGIOIMPNumberSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giGIOIMPNumberButton[0],0, 0 );
+ MSYS_SetBtnUserData(giGIOIMPNumberButton[1],0, 1 );
+
+ iCurrentIMPNumberSetting = gGameOptions.ubMaxIMPCharacters;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // OLD/NEW TARITS SETTING
+
+ guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiTraitsOptionToggles[ GIO_TRAITS_OLD ] = CreateIconAndTextButton( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], gzGIOScreenText[ GIO_TRAITS_OLD_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
TEXT_CJUSTIFIED,
- GIO_CANCEL_X-180, GIO_BTN_OK_Y, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
- DEFAULT_MOVE_CALLBACK, MPBtnGIOCancelCallback );
- SpecifyButtonSoundScheme( guiGIOCancelButton, BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ (GIO_TRAITS_SETTING_X + 74), (GIO_TRAITS_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOOldTraitsCallback);
- }
- //
- //Check box to toggle Difficulty settings
- //
- usPosY = GIO_DIF_SETTINGS_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
+ guiTraitsOptionTogglesImage[ GIO_TRAITS_NEW ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiTraitsOptionToggles[ GIO_TRAITS_NEW ] = CreateIconAndTextButton( guiTraitsOptionTogglesImage[ GIO_TRAITS_NEW ], gzGIOScreenText[ GIO_TRAITS_NEW_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_TRAITS_SETTING_X), (GIO_TRAITS_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIONewTraitsCallback );
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
-
- else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
- ButtonList[ guiDifficultySettingsToggles[ GIO_DIFF_MED ] ]->uiFlags |= BUTTON_CLICKED_ON;
-
- else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
- ButtonList[ guiDifficultySettingsToggles[ GIO_DIFF_HARD ] ]->uiFlags |= BUTTON_CLICKED_ON;
-
- else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
- ButtonList[ guiDifficultySettingsToggles[ GIO_DIFF_INSANE ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ SpecifyButtonSoundScheme( guiTraitsOptionToggles[ GIO_TRAITS_OLD ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiTraitsOptionToggles[ GIO_TRAITS_NEW ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiTraitsOptionToggles[ GIO_TRAITS_OLD ],0, 0 );
+ MSYS_SetBtnUserData(guiTraitsOptionToggles[ GIO_TRAITS_NEW ],0, 1 );
+ if( gGameOptions.fNewTraitSystem )
+ ButtonList[ guiTraitsOptionToggles[ GIO_TRAITS_NEW ] ]->uiFlags |= BUTTON_CLICKED_ON;
else
- ButtonList[ guiDifficultySettingsToggles[ GIO_DIFF_MED ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ ButtonList[ guiTraitsOptionToggles[ GIO_TRAITS_OLD ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GAME SETTING ( realistic, sci fi )
- //
- //Check box to toggle Game settings ( realistic, sci fi )
- //
+ guiGameStyleTogglesImage[ GIO_REALISTIC ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiGameStyleToggles[ GIO_REALISTIC ] = CreateIconAndTextButton( guiGameStyleTogglesImage[ GIO_REALISTIC ], gzGIOScreenText[ GIO_REALISTIC_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_GAME_SETTING_X + 74), (GIO_GAME_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIORealisticStyleCallback);
- usPosY = GIO_GAME_SETTINGS_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
- else // if(gGameOptions.ubGameStyle == STYLE_REALISTIC)
- ButtonList[ guiGameStyleToggles[ GIO_REALISTIC ] ]->uiFlags |= BUTTON_CLICKED_ON;
-// else
-// ButtonList[ guiGameStyleToggles[ GIO_PLATINUM ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiGameStyleToggles[ GIO_REALISTIC ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // IRON MAN SETTING
+
+ guiGameSaveTogglesImage[ GIO_CAN_SAVE ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiGameSaveToggles[ GIO_CAN_SAVE ] = CreateIconAndTextButton( guiGameSaveTogglesImage[ GIO_CAN_SAVE ], gzGIOScreenText[ GIO_SAVE_ANYWHERE_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_IRON_MAN_SETTING_X), (GIO_IRON_MAN_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOIronManOffCallback);
+
+ guiGameSaveTogglesImage[ GIO_IRON_MAN ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiGameSaveToggles[ GIO_IRON_MAN ] = CreateIconAndTextButton( guiGameSaveTogglesImage[ GIO_IRON_MAN ], gzGIOScreenText[ GIO_IRON_MAN_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_IRON_MAN_SETTING_X + 74), (GIO_IRON_MAN_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOIronManOnCallback );
+
+ SpecifyButtonSoundScheme( guiGameSaveToggles[ GIO_CAN_SAVE ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiGameSaveToggles[ GIO_IRON_MAN ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiGameSaveToggles[ GIO_CAN_SAVE ],0, 0 );
+ MSYS_SetBtnUserData(guiGameSaveToggles[ GIO_IRON_MAN ],0, 1 );
+
+ if( gGameOptions.fIronManMode )
+ ButtonList[ guiGameSaveToggles[ GIO_IRON_MAN ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiGameSaveToggles[ GIO_CAN_SAVE ] ]->uiFlags |= BUTTON_CLICKED_ON;
- // Madd
- usPosY = GIO_BR_SETTING_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiTerroristsOptionToggles[ GIO_TERRORISTS_RANDOM ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BOBBY RAY SETTING
+
+ giGIOBRSettingButtonImage[ 0 ]= UseLoadedButtonImage( giGIODifficultyButtonImage[ 0 ], -1,0,-1,1,-1 );
+ giGIOBRSettingButtonImage[ 1 ]= UseLoadedButtonImage( giGIODifficultyButtonImage[ 1 ], -1,2,-1,3,-1 );
+
+ // left button - decrement BR level
+ giGIOBRSettingButton[ 0 ] = QuickCreateButton( giGIOBRSettingButtonImage[ 0 ], GIO_BR_SETTING_X + 39, GIO_BR_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnGIOBRSettingLeftCallback );
+
+ // right button - increment BR level
+ giGIOBRSettingButton[ 1 ] = QuickCreateButton( giGIOBRSettingButtonImage[ 1 ], GIO_BR_SETTING_X + 158, GIO_BR_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnGIOBRSettingRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giGIOBRSettingButton[0],0, 0 );
+ MSYS_SetBtnUserData(giGIOBRSettingButton[1],0, 1 );
+
+ // set initial value
+ switch ( gGameOptions.ubBobbyRay )
{
case BR_GOOD:
- ButtonList[ guiBROptionToggles[ GIO_BR_GOOD ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ iCurrentBRSetting = GIO_BR_GOOD;
break;
case BR_GREAT:
- ButtonList[ guiBROptionToggles[ GIO_BR_GREAT ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ iCurrentBRSetting = GIO_BR_GREAT;
break;
case BR_EXCELLENT:
- ButtonList[ guiBROptionToggles[ GIO_BR_EXCELLENT ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ iCurrentBRSetting = GIO_BR_EXCELLENT;
break;
case BR_AWESOME:
- ButtonList[ guiBROptionToggles[ GIO_BR_AWESOME ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ iCurrentBRSetting = GIO_BR_AWESOME;
+ break;
+ default:
+ iCurrentBRSetting = GIO_BR_GOOD; // optimistically assume, we have selected the normal one
break;
}
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // ITEM PROGRESS SETTING
+
+ giGIOProgressSettingButtonImage[ 0 ]= UseLoadedButtonImage( giGIODifficultyButtonImage[ 0 ], -1,0,-1,1,-1 );
+ giGIOProgressSettingButtonImage[ 1 ]= UseLoadedButtonImage( giGIODifficultyButtonImage[ 1 ], -1,2,-1,3,-1 );
- // CHRISL: New inventory options
- if (!is_networked)
- {
- if(IsNIVModeValid() == TRUE){
- usPosY = GIO_INV_SETTING_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
+ iCurrentInventorySetting = GIO_INV_OLD;
break;
case INVENTORY_NEW:
- ButtonList[ guiINVOptionToggles[ GIO_INV_NEW ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ iCurrentInventorySetting = GIO_INV_NEW;
break;
}
}
}
- // JA2Gold: iron man buttons
- usPosY = GIO_IRON_MAN_SETTING_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
+ guiDropAllOptionTogglesImage[ GIO_DROPALL_OFF ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiDropAllOptionToggles[ GIO_DROPALL_OFF ] = CreateIconAndTextButton( guiDropAllOptionTogglesImage[ GIO_DROPALL_OFF ], gzGIOScreenText[ GIO_DROPALL_OFF_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_DROPALL_SETTING_X), (GIO_DROPALL_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIODropAllOffCallback);
+
+ guiDropAllOptionTogglesImage[ GIO_DROPALL_ON ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiDropAllOptionToggles[ GIO_DROPALL_ON ] = CreateIconAndTextButton( guiDropAllOptionTogglesImage[ GIO_DROPALL_ON ], gzGIOScreenText[ GIO_DROPALL_ON_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_DROPALL_SETTING_X + 74), (GIO_DROPALL_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIODropAllOnCallback );
+
+ SpecifyButtonSoundScheme( guiDropAllOptionToggles[ GIO_DROPALL_OFF ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiDropAllOptionToggles[ GIO_DROPALL_ON ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiDropAllOptionToggles[ GIO_DROPALL_OFF ],0, 0 );
+ MSYS_SetBtnUserData(guiDropAllOptionToggles[ GIO_DROPALL_ON ],0, 1 );
+
+ if( gGameOptions.fEnemiesDropAllItems )
+ ButtonList[ guiDropAllOptionToggles[ GIO_DROPALL_ON ] ]->uiFlags |= BUTTON_CLICKED_ON;
else
- ButtonList[ guiGameSaveToggles[ GIO_CAN_SAVE ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ ButtonList[ guiDropAllOptionToggles[ GIO_DROPALL_OFF ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GUN SETTING
+ guiGunOptionTogglesImage[ GIO_REDUCED_GUNS ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiGunOptionToggles[ GIO_REDUCED_GUNS ] = CreateIconAndTextButton( guiGunOptionTogglesImage[ GIO_REDUCED_GUNS ], gzGIOScreenText[ GIO_REDUCED_GUNS_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_GUN_SETTING_X + 74), (GIO_GUN_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOGunSettingReducedCallback);
- //
- // Check box to toggle Gun options
- //
+ guiGunOptionTogglesImage[ GIO_GUN_NUT ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiGunOptionToggles[ GIO_GUN_NUT ] = CreateIconAndTextButton( guiGunOptionTogglesImage[ GIO_GUN_NUT ], gzGIOScreenText[ GIO_GUN_NUT_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_GUN_SETTING_X), (GIO_GUN_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOGunSettingToGCallback );
- usPosY = GIO_GUN_SETTINGS_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
else
ButtonList[ guiGunOptionToggles[ GIO_REDUCED_GUNS ] ]->uiFlags |= BUTTON_CLICKED_ON;
-// JA2 Gold: no more timed turns
- //
- // Check box to toggle the timed turn option
- //
-/*
- usPosY = GIO_TIMED_TURN_SETTING_Y - GIO_OFFSET_TO_TOGGLE_BOX_Y;
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WEAPON CACHES SETTING
+
+ guiWeaponCachesOptionTogglesImage[ GIO_CACHES_RANDOM ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiWeaponCachesOptionToggles[ GIO_CACHES_RANDOM ] = CreateIconAndTextButton( guiWeaponCachesOptionTogglesImage[ GIO_CACHES_RANDOM ], gzGIOScreenText[ GIO_CACHES_RANDOM_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_CACHES_SETTING_X), (GIO_CACHES_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOWeaponCachesRandomCallback);
+
+ guiWeaponCachesOptionTogglesImage[ GIO_CACHES_ALL ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiWeaponCachesOptionToggles[ GIO_CACHES_ALL ] = CreateIconAndTextButton( guiWeaponCachesOptionTogglesImage[ GIO_CACHES_ALL ], gzGIOScreenText[ GIO_CACHES_ALL_TEXT ], GIO_TOGGLE_TEXT_FONT,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ GIO_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (GIO_CACHES_SETTING_X + 74), (GIO_CACHES_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnGIOWeaponCachesAllCallback );
+
+ SpecifyButtonSoundScheme( guiWeaponCachesOptionToggles[ GIO_CACHES_RANDOM ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiWeaponCachesOptionToggles[ GIO_CACHES_ALL ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiWeaponCachesOptionToggles[ GIO_CACHES_RANDOM ],0, 0 );
+ MSYS_SetBtnUserData(guiWeaponCachesOptionToggles[ GIO_CACHES_ALL ],0, 1 );
+
+ if( gGameOptions.fEnableAllWeaponCaches )
+ ButtonList[ guiWeaponCachesOptionToggles[ GIO_CACHES_ALL ] ]->uiFlags |= BUTTON_CLICKED_ON;
else
- ButtonList[ guiTimedTurnToggles[ GIO_NO_TIMED_TURNS ] ]->uiFlags |= BUTTON_CLICKED_ON;
-*/
-
+ ButtonList[ guiWeaponCachesOptionToggles[ GIO_CACHES_RANDOM ] ]->uiFlags |= BUTTON_CLICKED_ON;
//Reset the exit screen
@@ -595,6 +1007,679 @@ BOOLEAN EnterGIOScreen()
return( TRUE );
}
+void BtnGIODifficultySelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentDifficulty > 0 )
+ {
+ PlayButtonSound( giGIODifficultyButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentDifficulty--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIODifficultyButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentDifficulty > 0 )
+ {
+ PlayButtonSound( giGIODifficultyButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentDifficulty--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIODifficultyButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIODifficultySelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentDifficulty < 3 )
+ {
+ PlayButtonSound( giGIODifficultyButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentDifficulty++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIODifficultyButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentDifficulty < 3 )
+ {
+ PlayButtonSound( giGIODifficultyButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentDifficulty++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIODifficultyButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOBRSettingLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentBRSetting > 0 )
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentBRSetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentBRSetting > 0 )
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentBRSetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOBRSettingRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentBRSetting < 3 )
+ {
+ PlayButtonSound( giGIOBRSettingButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentBRSetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOBRSettingButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentBRSetting < 3 )
+ {
+ PlayButtonSound( giGIOBRSettingButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentBRSetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOBRSettingButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOIMPNumberSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentIMPNumberSetting > 1 )
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentIMPNumberSetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentIMPNumberSetting > 1 )
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentIMPNumberSetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOBRSettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOIMPNumberSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentIMPNumberSetting < (gGameExternalOptions.iIMPMaleCharacterCount + gGameExternalOptions.iIMPFemaleCharacterCount) )
+ {
+ PlayButtonSound( giGIOIMPNumberButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentIMPNumberSetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOIMPNumberButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentIMPNumberSetting < (gGameExternalOptions.iIMPMaleCharacterCount + gGameExternalOptions.iIMPFemaleCharacterCount) )
+ {
+ PlayButtonSound( giGIOIMPNumberButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentIMPNumberSetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOIMPNumberButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOInventorySettingLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentInventorySetting > GIO_INV_OLD )
+ {
+ PlayButtonSound( giGIOInventorySettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentInventorySetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOInventorySettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentInventorySetting > GIO_INV_OLD )
+ {
+ PlayButtonSound( giGIOInventorySettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentInventorySetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOInventorySettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOInventorySettingRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentInventorySetting < GIO_INV_NEW_NAS )
+ {
+ PlayButtonSound( giGIOIMPNumberButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentInventorySetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOInventorySettingButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentInventorySetting < GIO_INV_NEW_NAS )
+ {
+ PlayButtonSound( giGIOInventorySettingButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentInventorySetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOInventorySettingButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOProgressSettingLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentProgressSetting > 0 )
+ {
+ PlayButtonSound( giGIOProgressSettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentProgressSetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOProgressSettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentProgressSetting > 0 )
+ {
+ PlayButtonSound( giGIOProgressSettingButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentProgressSetting--;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOProgressSettingButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOProgressSettingRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
+ {
+ if ( iCurrentProgressSetting < GIO_PROGRESS_VERY_FAST )
+ {
+ PlayButtonSound( giGIOProgressSettingButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentProgressSetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOProgressSettingButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ if ( iCurrentProgressSetting < GIO_PROGRESS_VERY_FAST )
+ {
+ PlayButtonSound( giGIOProgressSettingButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iCurrentProgressSetting++;
+ gfReRenderGIOScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giGIOProgressSettingButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnGIOOldTraitsCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_TRAITS_SETTING_X), (GIO_TRAITS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiTraitsOptionToggles[ GIO_TRAITS_NEW ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiTraitsOptionToggles[ GIO_TRAITS_OLD ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIONewTraitsCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ if (!gGameExternalOptions.fReadProfileDataFromXML)
+ {
+ PlayButtonSound( guiTraitsOptionToggles[ GIO_TRAITS_NEW ], BUTTON_SOUND_DISABLED_CLICK );
+
+ DoGioMessageBox( MSG_BOX_BASIC_STYLE, zGioNewTraitsImpossibleText[0], GAME_INIT_OPTIONS_SCREEN, MSG_BOX_FLAG_OK, NewTraitsNotPossibleMessageBoxCallBack );
+ }
+ else
+ {
+ RestoreExternBackgroundRect( (GIO_TRAITS_SETTING_X), (GIO_TRAITS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiTraitsOptionToggles[ GIO_TRAITS_OLD ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiTraitsOptionToggles[ GIO_TRAITS_NEW ], BUTTON_SOUND_CLICKED_ON );
+ }
+ }
+}
+
+void NewTraitsNotPossibleMessageBoxCallBack( UINT8 bExitValue )
+{
+ /*if( bExitValue == MSG_BOX_RETURN_YES )
+ {
+ gubGameOptionScreenHandler = GIO_NOTHING;
+ }*/
+}
+
+void BtnGIORealisticStyleCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_GAME_SETTING_X), (GIO_GAME_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiGameStyleToggles[ GIO_SCI_FI ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiGameStyleToggles[ GIO_REALISTIC ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIOScifiStyleCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_GAME_SETTING_X), (GIO_GAME_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiGameStyleToggles[ GIO_REALISTIC ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiGameStyleToggles[ GIO_SCI_FI ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnGIOIronManOffCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_IRON_MAN_SETTING_X), (GIO_IRON_MAN_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiGameSaveToggles[ GIO_IRON_MAN ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiGameStyleToggles[ GIO_CAN_SAVE ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIOIronManOnCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_IRON_MAN_SETTING_X), (GIO_IRON_MAN_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiGameSaveToggles[ GIO_CAN_SAVE ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiGameStyleToggles[ GIO_IRON_MAN ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnGIOTerroristsRandomCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_TERRORISTS_SETTING_X), (GIO_TERRORISTS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiTerroristsOptionToggles[ GIO_TERRORISTS_ALL ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiTerroristsOptionToggles[ GIO_TERRORISTS_RANDOM ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIOTerroristsAllCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_TERRORISTS_SETTING_X), (GIO_TERRORISTS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiTerroristsOptionToggles[ GIO_TERRORISTS_RANDOM ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiTerroristsOptionToggles[ GIO_TERRORISTS_ALL ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnGIODropAllOffCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_DROPALL_SETTING_X), (GIO_DROPALL_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiDropAllOptionToggles[ GIO_DROPALL_ON ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiDropAllOptionToggles[ GIO_DROPALL_OFF ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIODropAllOnCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_DROPALL_SETTING_X), (GIO_DROPALL_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiDropAllOptionToggles[ GIO_DROPALL_OFF ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiDropAllOptionToggles[ GIO_DROPALL_ON ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnGIOGunSettingReducedCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_GUN_SETTING_X), (GIO_GUN_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiGunOptionToggles[ GIO_GUN_NUT ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiGunOptionToggles[ GIO_REDUCED_GUNS ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIOGunSettingToGCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_GUN_SETTING_X), (GIO_GUN_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiGunOptionToggles[ GIO_REDUCED_GUNS ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiGunOptionToggles[ GIO_GUN_NUT ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnGIOWeaponCachesRandomCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_CACHES_SETTING_X), (GIO_CACHES_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiWeaponCachesOptionToggles[ GIO_CACHES_ALL ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiWeaponCachesOptionToggles[ GIO_CACHES_RANDOM ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnGIOWeaponCachesAllCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (GIO_CACHES_SETTING_X), (GIO_CACHES_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiWeaponCachesOptionToggles[ GIO_CACHES_RANDOM ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiWeaponCachesOptionToggles[ GIO_CACHES_ALL ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
BOOLEAN ExitGIOScreen()
{
@@ -606,55 +1691,96 @@ BOOLEAN ExitGIOScreen()
//Delete the main options screen background
DeleteVideoObjectFromIndex( guiGIOMainBackGroundImage );
- if(is_networked)
- {
- RemoveButton( MPguiGIOCancelButton );
- UnloadButtonImage( MPgiGIOCancelBtnImage );
- }
+ DeleteVideoObjectFromIndex( guiGIOSMALLFRAME );
+ // Destroy Basic buttons
RemoveButton( guiGIOCancelButton );
RemoveButton( guiGIODoneButton );
-
-
UnloadButtonImage( giGIOCancelBtnImage );
UnloadButtonImage( giGIODoneBtnImage );
+ // Destroy Difficulty setting buttons
+ RemoveButton( giGIODifficultyButton[0] );
+ RemoveButton( giGIODifficultyButton[1] );
+ UnloadButtonImage( giGIODifficultyButtonImage[0] );
+ UnloadButtonImage( giGIODifficultyButtonImage[1] );
- //Check box to toggle Difficulty settings
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-//Madd
-void BtnBROptionTogglesCallback( GUI_BUTTON *btn, INT32 reason )
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- /*UINT8 ubButton = (UINT8)*/MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-// CHRISL:
-void BtnINVOptionTogglesCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- /*UINT8 ubButton = (UINT8)*/MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnGameStyleTogglesCallback( GUI_BUTTON *btn, INT32 reason )
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- /*UINT8 ubButton = (UINT8)*/MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnGameSaveTogglesCallback( GUI_BUTTON *btn, INT32 reason )
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
-// UINT8 ubButton = (UINT8)MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnGunOptionsTogglesCallback( GUI_BUTTON *btn, INT32 reason )
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- /*UINT8 ubButton = (UINT8)*/MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-// JA2Gold: no more timed turns setting
-
-void BtnTimedTurnsTogglesCallback( GUI_BUTTON *btn, INT32 reason )//hayden : re-enabled
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- UINT8 ubButton = (UINT8)MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-
-
-
-
void BtnGIODoneCallback(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
@@ -1195,26 +1970,17 @@ void BtnGIODoneCallback(GUI_BUTTON *btn,INT32 reason)
{
btn->uiFlags &= (~BUTTON_CLICKED_ON );
- if(!is_networked)
- {
//if the user doesnt have IRON MAN mode selected
if( !DisplayMessageToUserAboutIronManMode() )
{
//Confirm the difficulty setting
DisplayMessageToUserAboutGameDifficulty();
}
- }
- else
- {
- gubGameOptionScreenHandler = GIO_EXIT;
- }
-
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
}
}
-
void BtnGIOCancelCallback(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
@@ -1232,10 +1998,6 @@ void BtnGIOCancelCallback(GUI_BUTTON *btn,INT32 reason)
}
}
-
-
-
-
void MPBtnGIOCancelCallback(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
@@ -1247,72 +2009,19 @@ void MPBtnGIOCancelCallback(GUI_BUTTON *btn,INT32 reason)
{
btn->uiFlags &= (~BUTTON_CLICKED_ON );
- //gubGameOptionScreenHandler = GIO_CANCEL;
-
- //// Select the game which is to be restored
- //guiPreviousOptionScreen = guiCurrentScreen;
- //guiMainMenuExitScreen = SAVE_LOAD_SCREEN;
- //gbHandledMainMenu = 0;
- //gfSaveGame = FALSE;
- //gfMainMenuScreenExit = TRUE;
-
- /* guiPreviousOptionScreen = guiCurrentScreen;
- SetPendingNewScreen( SAVE_LOAD_SCREEN );
- gubGameOptionScreenHandler = GIO_EXIT;
-
- gubGIOExitScreen = MAINMENU_SCREEN;
- gfGIOScreenExit = TRUE;
- fInterfacePanelDirty = DIRTYLEVEL2;*/
-
- gubGameOptionScreenHandler = MP_LOAD;
-
-
+ gubGameOptionScreenHandler = MP_LOAD;
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
}
}
-
-UINT8 GetCurrentDifficultyButtonSetting()
+UINT8 GetCurrentTraitsOptionButtonSetting()
{
UINT8 cnt;
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- return( cnt );
- }
- }
-
- return( 0 );
-}
-
-
-
-//Madd
-UINT8 GetCurrentBROptionButtonSetting()
-{
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- return( cnt );
- }
- }
- return( 0 );
-}
-
-// CHRISL:
-UINT8 GetCurrentINVOptionButtonSetting()
-{
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ if( ButtonList[ guiTraitsOptionToggles[ cnt ] ]->uiFlags & BUTTON_CLICKED_ON )
{
return( cnt );
}
@@ -1334,7 +2043,47 @@ UINT8 GetCurrentGameStyleButtonSetting()
return( 0 );
}
+UINT8 GetCurrentGameSaveButtonSetting()
+{
+ UINT8 cnt;
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+UINT8 GetCurrentTerroristsButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+UINT8 GetCurrentDropAllButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
UINT8 GetCurrentGunButtonSetting()
{
@@ -1350,7 +2099,19 @@ UINT8 GetCurrentGunButtonSetting()
return( 0 );
}
-// JA2 Gold: no timed turns
+UINT8 GetCurrentWeaponCachesButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
UINT8 GetCurrentTimedTurnsButtonSetting()
{
@@ -1365,116 +2126,20 @@ UINT8 GetCurrentTimedTurnsButtonSetting()
}
return( 0 );
}
-//hayden : re-enabled
-
-UINT8 GetCurrentGameSaveButtonSetting()
-{
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- return( cnt );
- }
- }
- return( 0 );
-}
-
-
-
-void RestoreGIOButtonBackGrounds()
-{
- UINT8 cnt;
- UINT16 usPosY;
-
-
- usPosY = GIO_DIF_SETTINGS_Y-GIO_OFFSET_TO_TOGGLE_BOX_Y;
- //Check box to toggle Difficulty settings
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
}
}
+
+void RenderGIOSmallSelectionFrame(INT16 sX, INT16 sY)
+{
+
+ HVOBJECT hHandle;
+
+ // get the video object
+ GetVideoObject(&hHandle, guiGIOSMALLFRAME);
+
+ // blt to sX, sY relative to upper left corner
+ BltVideoObject(FRAME_BUFFER, hHandle, 0, sX, sY , VO_BLT_SRCTRANSPARENCY,NULL);
+
+ return;
+}
\ No newline at end of file
diff --git a/GameInitOptionsScreen.h b/GameInitOptionsScreen.h
index 32a6c212..6300cc8a 100644
--- a/GameInitOptionsScreen.h
+++ b/GameInitOptionsScreen.h
@@ -6,7 +6,7 @@ UINT32 GameInitOptionsScreenInit( void );
UINT32 GameInitOptionsScreenHandle( void );
UINT32 GameInitOptionsScreenShutdown( void );
-
+BOOLEAN SpIniExists();
#endif
diff --git a/GameSettings.cpp b/GameSettings.cpp
index ae301778..6a3561ea 100644
--- a/GameSettings.cpp
+++ b/GameSettings.cpp
@@ -39,10 +39,11 @@
#include "Text.h"
#include "connect.h"
+#include "sgp_logger.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_file_raii.h"
-#include "VFS/File/vfs_file.h"
+#include
+#include
+#include
#define GAME_SETTINGS_FILE "Ja2_Settings.INI"
@@ -52,12 +53,19 @@
#define AP_BP_CONSTANTS_FILE "APBPConstants.ini"
+#define STOMP_SETTINGS_FILE "Skills_Settings.ini" // SANDRO - file for STOMP
+
+// HEADROCK HAM 4: This file contains all the settings required to tweak the new Shooting Mechanism. There's lots of them.
+#define CTH_COEFFICIENTS_FILE "CTHConstants.ini"
+
#define CD_ROOT_DIR "DATA\\"
GAME_SETTINGS gGameSettings;
GAME_OPTIONS gGameOptions;
// Snap: Options read from an INI file in the default of custom Data directory
GAME_EXTERNAL_OPTIONS gGameExternalOptions;
+SKILL_TRAIT_VALUES gSkillTraitValues; // SANDRO - added this one
+CTH_CONSTANTS gGameCTHConstants; // HEADROCK HAM 4: CTH constants
extern SGPFILENAME gCheckFilenames[];
extern CHAR8 gzErrorMsg[256];
@@ -80,6 +88,16 @@ bool UsingNewInventorySystem()
return (gGameOptions.ubInventorySystem == INVENTORY_NEW);
}
+bool UsingNewAttachmentSystem()
+{
+ return (gGameOptions.ubAttachmentSystem == ATTACHMENT_NEW);
+}
+
+bool UsingNewCTHSystem()
+{
+ return (gGameExternalOptions.fUseNCTH == TRUE);
+}
+
std::string StringToLower(std::string strToConvert)
{//change each element of the string to lower case
for(unsigned int i=0;igetProfileStack()->getProfile(L"v1.13") != NULL)
{
- return TRUE;
+ isValid = TRUE;
}
- return FALSE;
-#endif
+ else
+ isValid = FALSE;
+
+ // Also check the resolution if needed.
+ if(checkRes == true && iResolution == 0)
+ isValid = FALSE;
+
+ return isValid;
}
BOOLEAN LoadGameSettings()
-{
+{
try
{
CIniReader iniReader(GAME_SETTINGS_FILE, TRUE); // force path even for non existing files
- gGameSettings.bLastSavedGameSlot = iniReader.ReadInteger("JA2 Game Settings","bLastSavedGameSlot" , -1 , -1 , NUM_SAVE_GAMES );
+ gGameSettings.bLastSavedGameSlot = iniReader.ReadInteger("JA2 Game Settings","bLastSavedGameSlot" , -1 , -1 , NUM_SLOT );
gGameSettings.ubMusicVolumeSetting = iniReader.ReadInteger("JA2 Game Settings","ubMusicVolumeSetting" , MIDVOLUME , 0 , HIGHVOLUME );
gGameSettings.ubSoundEffectsVolume = iniReader.ReadInteger("JA2 Game Settings","ubSoundEffectsVolume" , MIDVOLUME , 0 , HIGHVOLUME );
gGameSettings.ubSpeechVolume = iniReader.ReadInteger("JA2 Game Settings","ubSpeechVolume" , MIDVOLUME , 0 , HIGHVOLUME );
@@ -146,22 +162,25 @@ BOOLEAN LoadGameSettings()
gGameSettings.fOptions[TOPTION_3D_CURSOR] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_3D_CURSOR" , FALSE );
gGameSettings.fOptions[TOPTION_CTH_CURSOR] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_CTH_CURSOR" , TRUE );
gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_GL_BURST_CURSOR" , TRUE );
- gGameSettings.fOptions[TOPTION_DROP_ALL] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_DROP_ALL" , FALSE );
- gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_GL_HIGH_ANGLE" , FALSE );
- gGameSettings.fOptions[TOPTION_AIM_LEVEL_RESTRICTION] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_AIM_LEVEL_RESTRICTION" , TRUE );
+ gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALLOW_TAUNTS" , TRUE ); // changed from drop all - SANDRO
+ gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_GL_HIGH_ANGLE" , FALSE );
+ gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALLOW_REAL_TIME_SNEAK" , FALSE ); // Changed from aim levels restriction - SANDRO
gGameSettings.fOptions[TOPTION_SPACE_SELECTS_NEXT_SQUAD] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SPACE_SELECTS_NEXT_SQUAD" , TRUE );
gGameSettings.fOptions[TOPTION_SHOW_ITEM_SHADOW] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SHOW_ITEM_SHADOW" , TRUE );
gGameSettings.fOptions[TOPTION_SHOW_WEAPON_RANGE_IN_TILES] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SHOW_WEAPON_RANGE_IN_TILES" , TRUE );
gGameSettings.fOptions[TOPTION_TRACERS_FOR_SINGLE_FIRE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_TRACERS_FOR_SINGLE_FIRE" , FALSE );
gGameSettings.fOptions[TOPTION_RAIN_SOUND] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_RAIN_SOUND" , TRUE );
gGameSettings.fOptions[TOPTION_ALLOW_CROWS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALLOW_CROWS" , TRUE );
- gGameSettings.fOptions[TOPTION_ALLOW_SOLDIER_TOOLTIPS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALLOW_SOLDIER_TOOLTIPS" , TRUE ); // Changed from random IMP personality - SANDRO
+ gGameSettings.fOptions[TOPTION_ALLOW_SOLDIER_TOOLTIPS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALLOW_SOLDIER_TOOLTIPS" , TRUE );
gGameSettings.fOptions[TOPTION_USE_AUTO_SAVE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_USE_AUTO_SAVE" , FALSE );
gGameSettings.fOptions[TOPTION_SILENT_SKYRIDER] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_SILENT_SKYRIDER" , FALSE );
gGameSettings.fOptions[TOPTION_LOW_CPU_USAGE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_LOW_CPU_USAGE" , FALSE );
gGameSettings.fOptions[TOPTION_ENHANCED_DESC_BOX] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ENHANCED_DESC_BOX" , FALSE );
gGameSettings.fOptions[TOPTION_TOGGLE_TURN_MODE] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_TOGGLE_TURN_MODE" , FALSE );
gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_STAT_PROGRESS_BARS" , FALSE ); // HEADROCK HAM 3.6: Progress Bars
+ gGameSettings.fOptions[TOPTION_REPORT_MISS_MARGIN] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_REPORT_MISS_MARGIN" , FALSE ); // HEADROCK HAM 4: Shot offset report
+ gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALT_MAP_COLOR" , FALSE ); // HEADROCK HAM 4: Strategic Map Colors
+ gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_ALTERNATE_BULLET_GRAPHICS" , FALSE );
gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_HEADER] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_CHEAT_MODE_OPTIONS_HEADER" , FALSE );
gGameSettings.fOptions[TOPTION_FORCE_BOBBY_RAY_SHIPMENTS] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_FORCE_BOBBY_RAY_SHIPMENTS" , FALSE );
gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_END] = iniReader.ReadBoolean("JA2 Game Settings","TOPTION_CHEAT_MODE_OPTIONS_END" , FALSE );
@@ -187,7 +206,7 @@ BOOLEAN LoadGameSettings()
//
//Do checking to make sure the settings are valid
//
- if( gGameSettings.bLastSavedGameSlot < 0 || gGameSettings.bLastSavedGameSlot >= NUM_SAVE_GAMES )
+ if( gGameSettings.bLastSavedGameSlot < 0 || gGameSettings.bLastSavedGameSlot >= NUM_SLOT )
gGameSettings.bLastSavedGameSlot = -1;
if( gGameSettings.ubMusicVolumeSetting > HIGHVOLUME )
@@ -229,7 +248,7 @@ BOOLEAN LoadGameSettings()
return( TRUE );
}
- catch(CBasicException &ex)
+ catch(vfs::Exception)
{
// file does not exist, InitGamesettings() and then return.
// InitGamesettings() will also call SaveGameSettings().
@@ -246,19 +265,6 @@ BOOLEAN SaveGameSettings()
gGameSettings.ubSpeechVolume = (UINT8)GetSpeechVolume( );
gGameSettings.ubMusicVolumeSetting = (UINT8)MusicGetVolume( );
-#ifndef USE_VFS
- char gameSettingsFilePath[MAX_PATH];
- FILE *file_pointer;
-
- sprintf(gameSettingsFilePath, "%s\\%s", gCustomDataCat.GetRootDir().c_str(), GAME_SETTINGS_FILE);
- fopen_s( &file_pointer, gameSettingsFilePath, "w" );
- if( !file_pointer )
- {
- //?fclose( file_pointer );
- return FALSE;
- }
-#endif
-
std::stringstream settings;
const char endl[] = "\r\n";
settings << ";******************************************************************************************************************************" << endl;
@@ -325,22 +331,25 @@ BOOLEAN SaveGameSettings()
settings << "TOPTION_3D_CURSOR = " << (gGameSettings.fOptions[TOPTION_3D_CURSOR] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_CTH_CURSOR = " << (gGameSettings.fOptions[TOPTION_CTH_CURSOR] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_GL_BURST_CURSOR = " << (gGameSettings.fOptions[TOPTION_GL_BURST_CURSOR] ? "TRUE" : "FALSE" ) << endl;
- settings << "TOPTION_DROP_ALL = " << (gGameSettings.fOptions[TOPTION_DROP_ALL] ? "TRUE" : "FALSE" ) << endl;
+ settings << "TOPTION_ALLOW_TAUNTS = " << (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] ? "TRUE" : "FALSE" ) << endl; // changed from drop all - SANDRO
settings << "TOPTION_GL_HIGH_ANGLE = " << (gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] ? "TRUE" : "FALSE" ) << endl;
- settings << "TOPTION_AIM_LEVEL_RESTRICTION = " << (gGameSettings.fOptions[TOPTION_AIM_LEVEL_RESTRICTION] ? "TRUE" : "FALSE" ) << endl;
+ settings << "TOPTION_ALLOW_REAL_TIME_SNEAK = " << (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] ? "TRUE" : "FALSE" ) << endl; // changed from restrict aim levels - SANDRO
settings << "TOPTION_SPACE_SELECTS_NEXT_SQUAD = " << (gGameSettings.fOptions[TOPTION_SPACE_SELECTS_NEXT_SQUAD] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_SHOW_ITEM_SHADOW = " << (gGameSettings.fOptions[TOPTION_SHOW_ITEM_SHADOW] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_SHOW_WEAPON_RANGE_IN_TILES = " << (gGameSettings.fOptions[TOPTION_SHOW_WEAPON_RANGE_IN_TILES] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_TRACERS_FOR_SINGLE_FIRE = " << (gGameSettings.fOptions[TOPTION_TRACERS_FOR_SINGLE_FIRE] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_RAIN_SOUND = " << (gGameSettings.fOptions[TOPTION_RAIN_SOUND] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_ALLOW_CROWS = " << (gGameSettings.fOptions[TOPTION_ALLOW_CROWS] ? "TRUE" : "FALSE" ) << endl;
- settings << "TOPTION_ALLOW_SOLDIER_TOOLTIPS = " << (gGameSettings.fOptions[TOPTION_ALLOW_SOLDIER_TOOLTIPS] ? "TRUE" : "FALSE" ) << endl; // changed from random IMP personality - SANDRO
+ settings << "TOPTION_ALLOW_SOLDIER_TOOLTIPS = " << (gGameSettings.fOptions[TOPTION_ALLOW_SOLDIER_TOOLTIPS] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_USE_AUTO_SAVE = " << (gGameSettings.fOptions[TOPTION_USE_AUTO_SAVE] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_SILENT_SKYRIDER = " << (gGameSettings.fOptions[TOPTION_SILENT_SKYRIDER] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_LOW_CPU_USAGE = " << (gGameSettings.fOptions[TOPTION_LOW_CPU_USAGE] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_ENHANCED_DESC_BOX = " << (gGameSettings.fOptions[TOPTION_ENHANCED_DESC_BOX] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_TOGGLE_TURN_MODE = " << (gGameSettings.fOptions[TOPTION_TOGGLE_TURN_MODE] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_STAT_PROGRESS_BARS = " << (gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] ? "TRUE" : "FALSE" ) << endl; // HEADROCK HAM 3.6: Progress Bars
+ settings << "TOPTION_REPORT_MISS_MARGIN = " << (gGameSettings.fOptions[TOPTION_REPORT_MISS_MARGIN] ? "TRUE" : "FALSE" ) << endl; // HEADROCK HAM 4: Shot offset report
+ settings << "TOPTION_ALT_MAP_COLOR = " << (gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR] ? "TRUE" : "FALSE" ) << endl; // HEADROCK HAM 4: Alt Map Colors
+ settings << "TOPTION_ALTERNATE_BULLET_GRAPHICS = " << (gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_CHEAT_MODE_OPTIONS_HEADER = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_HEADER] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_FORCE_BOBBY_RAY_SHIPMENTS = " << (gGameSettings.fOptions[TOPTION_FORCE_BOBBY_RAY_SHIPMENTS] ? "TRUE" : "FALSE" ) << endl;
settings << "TOPTION_CHEAT_MODE_OPTIONS_END = " << (gGameSettings.fOptions[TOPTION_CHEAT_MODE_OPTIONS_END] ? "TRUE" : "FALSE" ) << endl;
@@ -362,26 +371,21 @@ BOOLEAN SaveGameSettings()
settings << "TOPTION_TRACKING_MODE = " << (gGameSettings.fOptions[TOPTION_TRACKING_MODE] ? "TRUE" : "FALSE" ) << endl;
settings << "NUM_ALL_GAME_OPTIONS = " << (gGameSettings.fOptions[NUM_ALL_GAME_OPTIONS] ? "TRUE" : "FALSE" ) << endl;
-#ifndef USE_VFS
- fprintf_s (file_pointer , settings.str().c_str());
- fclose( file_pointer );
-#else
try
{
vfs::COpenWriteFile wfile(GAME_SETTINGS_FILE,true,true);
- wfile.file().write(settings.str().c_str(), settings.str().length());
+ wfile->write(settings.str().c_str(), settings.str().length());
}
- catch(CBasicException& ex)
+ catch(vfs::Exception& ex)
{
- logException(ex);
+ SGP_WARNING(ex.what());
vfs::CFile file(GAME_SETTINGS_FILE);
if(file.openWrite(true,true))
{
vfs::COpenWriteFile wfile( vfs::tWritableFile::cast(&file));
- TRYCATCH_RETHROW(file.write(settings.str().c_str(), settings.str().length()),L"");
+ SGP_TRYCATCH_RETHROW(file.write(settings.str().c_str(), settings.str().length()),L"");
}
}
-#endif
return( TRUE );
@@ -428,9 +432,9 @@ void InitGameSettings()
//Madd:
gGameSettings.fOptions[ TOPTION_GL_BURST_CURSOR ] = TRUE;
- gGameSettings.fOptions[ TOPTION_DROP_ALL ] = FALSE;
+ gGameSettings.fOptions[ TOPTION_ALLOW_TAUNTS ] = TRUE; // changed - SANDRO
gGameSettings.fOptions[ TOPTION_GL_HIGH_ANGLE ] = FALSE;
- gGameSettings.fOptions[ TOPTION_AIM_LEVEL_RESTRICTION ] = TRUE;
+ gGameSettings.fOptions[ TOPTION_ALLOW_REAL_TIME_SNEAK ] = FALSE; // changed - SANDRO
//lalien
gGameSettings.fOptions[ TOPTION_SPACE_SELECTS_NEXT_SQUAD ] = TRUE;
@@ -439,7 +443,7 @@ void InitGameSettings()
gGameSettings.fOptions[ TOPTION_TRACERS_FOR_SINGLE_FIRE ] = FALSE;
gGameSettings.fOptions[ TOPTION_RAIN_SOUND ] = TRUE;
gGameSettings.fOptions[ TOPTION_ALLOW_CROWS ] = TRUE;
- gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] = TRUE; // changed - SANDRO
+ gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] = TRUE;
gGameSettings.fOptions[ TOPTION_USE_AUTO_SAVE ] = FALSE;
gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] = FALSE;
gGameSettings.fOptions[ TOPTION_LOW_CPU_USAGE ] = FALSE;
@@ -451,6 +455,13 @@ void InitGameSettings()
// HEADROCK HAM 3.6:
gGameSettings.fOptions[ TOPTION_STAT_PROGRESS_BARS ] = FALSE;
+ // HEADROCK HAM 4:
+ gGameSettings.fOptions[ TOPTION_ALT_MAP_COLOR ] = FALSE;
+
+ gGameSettings.fOptions[ TOPTION_ALTERNATE_BULLET_GRAPHICS ] = FALSE;
+
+ gGameSettings.fOptions[ TOPTION_REPORT_MISS_MARGIN ] = FALSE;
+
// arynn: Cheat/Debug Menu
gGameSettings.fOptions[ TOPTION_CHEAT_MODE_OPTIONS_HEADER ] = FALSE;
gGameSettings.fOptions[ TOPTION_FORCE_BOBBY_RAY_SHIPMENTS ] = FALSE; // force all pending Bobby Ray shipments
@@ -492,7 +503,7 @@ void InitGameOptions()
memset( &gGameOptions, 0, sizeof( GAME_OPTIONS ) );
//Init the game options
-
+
if (is_networked)
gGameOptions.ubBobbyRay = BR_AWESOME;// hayden, was BR_GOOD;
else
@@ -508,10 +519,16 @@ void InitGameOptions()
gGameOptions.ubDifficultyLevel = DIF_LEVEL_MEDIUM;
//CHRISL: override default inventory mode when in low res
- if(IsNIVModeValid() == FALSE)
+ if(IsNIVModeValid(true) == FALSE)
+ {
gGameOptions.ubInventorySystem = INVENTORY_OLD;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_OLD;
+ }
else
+ {
gGameOptions.ubInventorySystem = INVENTORY_NEW;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_OLD;
+ }
if (is_networked)
gGameOptions.fTurnTimeLimit = TRUE;//hayden
@@ -519,6 +536,19 @@ void InitGameOptions()
gGameOptions.fTurnTimeLimit = FALSE;
gGameOptions.fIronManMode = FALSE;
+
+ // following added by SANDRO
+ gGameOptions.ubMaxIMPCharacters = (gGameExternalOptions.iIMPMaleCharacterCount + gGameExternalOptions.iIMPFemaleCharacterCount);
+
+ if (gGameExternalOptions.fReadProfileDataFromXML)
+ gGameOptions.fNewTraitSystem = TRUE;
+ else
+ gGameOptions.fNewTraitSystem = FALSE;
+
+ gGameOptions.ubProgressSpeedOfItemsChoices = ITEM_PROGRESS_NORMAL;
+ gGameOptions.fEnableAllTerrorists = FALSE;
+ gGameOptions.fEnemiesDropAllItems = FALSE;
+ gGameOptions.fEnableAllWeaponCaches = FALSE;
}
@@ -545,16 +575,6 @@ void LoadGameExternalOptions()
//Kaiden: Setting Ja2_Options.ini file to be read
CIniReader iniReader(GAME_EXTERNAL_OPTIONS_FILE);
-
- // WANNE: FILE TRANSFER: We disable reading from ja2_options.ini until we get file transfer working
- if(is_networked)
- {
-#ifndef USE_VFS
- //memset(&iniReader, 0, sizeof (CIniReader) );//disable ini in mp (taking default values)
- iniReader.Clear();
-#endif
- }
-
//################# System Limit Settings #################
// WDS - make number of mercenaries, etc. be configurable. Note: Changing one of these can render savegames unloadable.
@@ -574,7 +594,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.fUseDifficultyBasedProfDat = iniReader.ReadBoolean("Data File Settings", "USE_DIFFICULTY_BASED_PROF_DAT", TRUE);
// HEADROCK PROFEX/3.6: Activate this to read Profile data from MercProfiles.XML and MercOpinions.XML
- gGameExternalOptions.fReadProfileDataFromXML = iniReader.ReadBoolean("Data File Settings","READ_PROFILE_DATA_FROM_XML", FALSE);
+ gGameExternalOptions.fReadProfileDataFromXML = iniReader.ReadBoolean("Data File Settings","READ_PROFILE_DATA_FROM_XML", TRUE);
// HEADROCK PROFEX/3.6: Activate this to write Profile data to MercProfiles Out.XML and MercOpinions Out.XML. This can be used to convert PROF.DAT to XML format.
gGameExternalOptions.fWriteProfileDataToXML = iniReader.ReadBoolean("Data File Settings","WRITE_PROFILE_DATA_TO_XML", FALSE);
@@ -585,7 +605,8 @@ void LoadGameExternalOptions()
//################# Merc Recruitment Settings #################
// WDS: Allow flexible numbers of IMPs of each sex
- gGameExternalOptions.iMaxIMPCharacters = iniReader.ReadInteger("Recruitment Settings","MAX_IMP_CHARACTERS",1, 1, NUM_PROFILES);
+ // SANDRO - moved to the game itself
+ //gGameExternalOptions.iMaxIMPCharacters = iniReader.ReadInteger("Recruitment Settings","MAX_IMP_CHARACTERS",1, 1, NUM_PROFILES);
gGameExternalOptions.iIMPMaleCharacterCount = iniReader.ReadInteger("Recruitment Settings","IMP_MALE_CHARACTER_COUNT", COUNT_STANDARD_MALE_SLOTS, 1, NUM_PROFILES);
gGameExternalOptions.iIMPFemaleCharacterCount = iniReader.ReadInteger("Recruitment Settings","IMP_FEMALE_CHARACTER_COUNT", COUNT_STANDARD_FEMALE_SLOTS, 1, NUM_PROFILES);
@@ -646,19 +667,62 @@ void LoadGameExternalOptions()
}
gGameExternalOptions.iaIMPSlots[gGameExternalOptions.iIMPFemaleCharacterCount+gGameExternalOptions.iIMPMaleCharacterCount+1] = -1;
+ // silversurfer: read early recruitment options 1=immediately (control Omerta), 2=early (control 1, 2, 3 towns including Omerta)
+ // 3=normal (control 3, 4, 5 towns including Omerta), 4=after liberating Omerta and solving the "Deliver Food Quest" for Miguel
+ gGameExternalOptions.ubEarlyRebelsRecruitment[0] = iniReader.ReadInteger("Recruitment Settings","EARLY_REBELS_RECRUITMENT", 3, 1, 4);
+ switch (gGameExternalOptions.ubEarlyRebelsRecruitment[0])
+ {
+ case 2:
+ {
+ gGameExternalOptions.ubEarlyRebelsRecruitment[1] = 1; // FACT_PLAYER_OWNS_2_TOWNS_INCLUDING_OMERTA
+ gGameExternalOptions.ubEarlyRebelsRecruitment[2] = 2; // FACT_PLAYER_OWNS_3_TOWNS_INCLUDING_OMERTA
+ gGameExternalOptions.ubEarlyRebelsRecruitment[3] = 3; // FACT_PLAYER_OWNS_4_TOWNS_INCLUDING_OMERTA
+ break;
+ }
+ case 3:
+ {
+ gGameExternalOptions.ubEarlyRebelsRecruitment[1] = 3; // FACT_PLAYER_OWNS_2_TOWNS_INCLUDING_OMERTA
+ gGameExternalOptions.ubEarlyRebelsRecruitment[2] = 4; // FACT_PLAYER_OWNS_3_TOWNS_INCLUDING_OMERTA
+ gGameExternalOptions.ubEarlyRebelsRecruitment[3] = 5; // FACT_PLAYER_OWNS_4_TOWNS_INCLUDING_OMERTA
+ break;
+ }
+ case 4:
+ {
+ gGameExternalOptions.ubEarlyRebelsRecruitment[1] = 3; // FACT_PLAYER_OWNS_2_TOWNS_INCLUDING_OMERTA
+ gGameExternalOptions.ubEarlyRebelsRecruitment[2] = 4; // FACT_PLAYER_OWNS_3_TOWNS_INCLUDING_OMERTA
+ gGameExternalOptions.ubEarlyRebelsRecruitment[3] = 5; // FACT_PLAYER_OWNS_4_TOWNS_INCLUDING_OMERTA
+ break;
+ }
+ default:
+ break;
+ }
+
//I.M.P Character generation
- gGameExternalOptions.iStartAttribute = iniReader.ReadInteger("Recruitment Settings","IMP_INITIAL_ATTRIBUTES",55, 1, 100);
- gGameExternalOptions.iImpAttributePoints = iniReader.ReadInteger("Recruitment Settings","IMP_INITIAL_POINTS",40, 1, 100);
+ // SANDRO - some changes here
+ gGameExternalOptions.iIMPProfileCost = iniReader.ReadInteger("Recruitment Settings","IMP_PROFILE_COST",3000, 0, 50000);
+ gGameExternalOptions.fDynamicIMPProfileCost = iniReader.ReadBoolean("Recruitment Settings","DYNAMIC_IMP_PROFILE_COST",FALSE);
+ gGameExternalOptions.iImpAttributePoints = iniReader.ReadInteger("Recruitment Settings","IMP_INITIAL_POINTS",500, 1, 5000);
gGameExternalOptions.iMinAttribute = iniReader.ReadInteger("Recruitment Settings","IMP_MIN_ATTRIBUTE",35, 1, 99);
gGameExternalOptions.iMaxZeroBonus = iniReader.ReadInteger("Recruitment Settings","IMP_BONUS_POINTS_FOR_ZERO_ATTRIBUTE",15, 0, 100);
+ // if attribute points set too low...
+ if ( gGameExternalOptions.iImpAttributePoints < ((gGameExternalOptions.iMinAttribute * 5) + (gGameExternalOptions.iMaxZeroBonus * 5)) )
+ {
+ gGameExternalOptions.iImpAttributePoints = ((gGameExternalOptions.iMinAttribute * 5) + (gGameExternalOptions.iMaxZeroBonus * 5));
+ }
+
gGameExternalOptions.iMaxAttribute = iniReader.ReadInteger("Recruitment Settings","IMP_MAX_ATTRIBUTE",90, gGameExternalOptions.iMinAttribute+1, 100);
gGameExternalOptions.iIMPStartingLevelCostMultiplier = iniReader.ReadInteger("Recruitment Settings","IMP_STARTING_LEVEL_COST_MULTIPLIER", 5, 0, 100);
gGameExternalOptions.iBonusPointsForDisability = iniReader.ReadInteger("Recruitment Settings","IMP_BONUS_POINTS_FOR_DISABILITY",20, 0, 500);
gGameExternalOptions.iBonusPointsPerSkillNotTaken = iniReader.ReadInteger("Recruitment Settings","IMP_BONUS_POINTS_PER_SKILL_NOT_TAKEN",25, 0, 500);
-
+ // DBrot: Expert choices
+ gGameExternalOptions.fExpertsGetDifferentChoices = iniReader.ReadBoolean("Recruitment Settings","EXPERTS_GET_DIFFERENT_CHOICES",FALSE);
//Merc settings
- gGameExternalOptions.fMercDayOne = iniReader.ReadBoolean("Recruitment Settings","MERC_WEBSITE_IMMEDIATELY_AVAILABLE",FALSE);
- gGameExternalOptions.fAllMercsAvailable = iniReader.ReadBoolean("Recruitment Settings","MERC_WEBSITE_ALL_MERCS_AVAILABLE",FALSE);
+ gGameExternalOptions.fMercDayOne = iniReader.ReadBoolean("Recruitment Settings","MERC_WEBSITE_IMMEDIATELY_AVAILABLE",FALSE);
+ gGameExternalOptions.fAllMercsAvailable = iniReader.ReadBoolean("Recruitment Settings","MERC_WEBSITE_ALL_MERCS_AVAILABLE",FALSE);
+ //tais: mercs can go on assignment; 0 = default behaviour, 1 = all mercs available at start, 2 = no mercs go on other assignments... period!
+ gGameExternalOptions.fMercsOnAssignment = iniReader.ReadInteger("Recruitment Settings","MERCS_CAN_BE_ON_ASSIGNMENT",0,0,2);
+
+
//Merc Death Settings:
gGameExternalOptions.gfMercsDieOnAssignment = iniReader.ReadBoolean("Recruitment Settings","MERCS_CAN_DIE_ON_ASSIGNMENT",TRUE);
@@ -701,6 +765,9 @@ void LoadGameExternalOptions()
gGameExternalOptions.usHelicopterBaseCostPerGreenTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_BASE_COST_PER_GREEN_TILE", 100, 0, 60000);
gGameExternalOptions.usHelicopterBaseCostPerRedTile = iniReader.ReadInteger("Financial Settings","HELICOPTER_BASE_COST_PER_RED_TILE", 1000, 0, 60000);
+ //tais: percentage that the merc's salary rises when he/she levels up
+ gGameExternalOptions.gMercLevelUpSalaryIncreasePercentage = (FLOAT)iniReader.ReadInteger("Financial Settings","MERC_LEVEL_UP_SALARY_INCREASE_PERCENTAGE",25, 0, 1000);
+
//################# Troubleshooting Settings #################
gGameExternalOptions.gubDeadLockDelay = (UINT8) iniReader.ReadInteger("Troubleshooting Settings","DEAD_LOCK_DELAY",15, 5, 50);
@@ -721,12 +788,20 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("Graphics Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE);
+ //tais: enable/disable New Starting Gear Interface (0 = disabled, classic style; 1 = enabled, new 21 item view and up to 5 gearkit selection)
+ gGameExternalOptions.gfUseNewStartingGearInterface = iniReader.ReadBoolean("Graphics Settings","USE_NEW_STARTING_GEAR_INTERFACE", FALSE);
+
+ // WANNE: Moved to options screen
//afp - use a different graphic for bullets?
- gGameExternalOptions.gbBulletTracer = iniReader.ReadBoolean("Graphics Settings","ALTERNATE_BULLET_GRAPHICS",FALSE);
+ //gGameExternalOptions.gbBulletTracer = iniReader.ReadBoolean("Graphics Settings","ALTERNATE_BULLET_GRAPHICS",FALSE);
// Are enemy females restricted to Blackshirts only?
gGameExternalOptions.fRestrictFemaleEnemiesExceptElite = iniReader.ReadBoolean("Graphics Settings","RESTRICT_FEMALE_ENEMIES_EXCEPT_ELITE",FALSE);
+ // *** ddd - BEGIN
+ // New setting to allow thin progressbar
+ gGameExternalOptions.fSmallSizeProgressbar = iniReader.ReadBoolean("Graphics Settings", "SMALL_SIZE_PB", FALSE);
+ // *** ddd - END
//################# Sound Settings #################
@@ -751,6 +826,11 @@ void LoadGameExternalOptions()
// WDS - Automatically flag mines
gGameExternalOptions.automaticallyFlagMines = iniReader.ReadBoolean("Tactical Interface Settings","AUTOMATICALLY_FLAG_MINES_WHEN_SPOTTED", FALSE);
+ // silversurfer: don't play quote when mine spotted?
+ gGameExternalOptions.fMineSpottedNoTalk = iniReader.ReadBoolean("Tactical Interface Settings","MINES_SPOTTED_NO_TALK", FALSE);
+
+ //DBrot: Stand up after battle?
+ gGameExternalOptions.fStandUpAfterBattle = iniReader.ReadBoolean("Tactical Interface Settings","STAND_UP_AFTER_BATTLE", TRUE);
// Tactical militia command
gGameExternalOptions.fAllowTacticalMilitiaCommand = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_TACTICAL_MILITIA_COMMAND",0);
@@ -781,8 +861,13 @@ void LoadGameExternalOptions()
break;
}
- // HEADROCK HAM 3.6: If activated, the game does not switch focus to a merc who spots an enemy in real-time mode. This fixes issues with Real-Time Sneak.
- gGameExternalOptions.fNoAutoFocusChangeInRealtimeSneak = iniReader.ReadBoolean("Tactical Interface Settings","NO_AUTO_FOCUS_CHANGE_IN_REALTIME_SNEAK", FALSE);
+ //legion by Jazz
+ gGameExternalOptions.fShowTacticalFaceGear = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_TACTICAL_FACE_GEAR",FALSE);
+ gGameExternalOptions.fShowTacticalFaceIcons = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_TACTICAL_FACE_ICONS",FALSE);
+ gGameExternalOptions.bTacticalFaceIconStyle = iniReader.ReadInteger("Tactical Interface Settings","TACTICAL_FACE_ICON_STYLE", 0, 0, 3);
+
+ // Camo portraits by Jazz
+ gGameExternalOptions.fShowCamouflageFaces = iniReader.ReadBoolean("Tactical Interface Settings","SHOW_CAMOUFLAGE_FACES", FALSE);
//################# Tactical Difficulty Settings #################
@@ -794,6 +879,21 @@ void LoadGameExternalOptions()
gGameExternalOptions.iPlayerAPBonus = (INT8) iniReader.ReadInteger("Tactical Difficulty Settings","PLAYER_AP_BONUS",0,__max(-APBPConstants[AP_MINIMUM],-128),127);
+ // Percentage bonus to total enemy CtH on every hit - applies during tactical combat only
+ gGameExternalOptions.sEnemyAdminCtHBonusPercent = iniReader.ReadInteger("Tactical Difficulty Settings", "ADMIN_CTH_BONUS_PERCENT", 0, -100, 500);
+ gGameExternalOptions.sEnemyRegularCtHBonusPercent = iniReader.ReadInteger("Tactical Difficulty Settings", "REGULAR_CTH_BONUS_PERCENT", 0, -100, 500);
+ gGameExternalOptions.sEnemyEliteCtHBonusPercent = iniReader.ReadInteger("Tactical Difficulty Settings", "ELITE_CTH_BONUS_PERCENT", 10, -100, 500);
+
+ // Damage the enemz suffer is reduced by this percentage - applies during tactical combat only
+ gGameExternalOptions.sEnemyAdminDamageResistance = iniReader.ReadInteger("Tactical Difficulty Settings", "ADMIN_DAMAGE_RESISTANCE", 0, -50, 95);
+ gGameExternalOptions.sEnemyRegularDamageResistance = iniReader.ReadInteger("Tactical Difficulty Settings", "REGULAR_DAMAGE_RESISTANCE", 0, -50, 95);
+ gGameExternalOptions.sEnemyEliteDamageResistance = iniReader.ReadInteger("Tactical Difficulty Settings", "ELITE_DAMAGE_RESISTANCE", 0, -50, 95);
+
+ // SANDRO - Function to assign traits to enemy soldiers or militia
+ gGameExternalOptions.fAssignTraitsToEnemy = iniReader.ReadBoolean("Tactical Difficulty Settings", "ASSIGN_SKILL_TRAITS_TO_ENEMY", FALSE);
+ gGameExternalOptions.fAssignTraitsToMilitia = iniReader.ReadBoolean("Tactical Difficulty Settings", "ASSIGN_SKILL_TRAITS_TO_MILITIA", FALSE);
+ gGameExternalOptions.bAssignedTraitsRarity = iniReader.ReadInteger("Tactical Difficulty Settings", "ASSIGNED_SKILL_TRAITS_RARITY ", 0, -100, 100);
+
// HEADROCK HAM B2.8: At "1", Militia will drop their equipment similar to enemies, IF killed by non-player character. At "2" they drop whenever killed.
gGameExternalOptions.ubMilitiaDropEquipment = iniReader.ReadInteger("Tactical Difficulty Settings","MILITIA_DROP_EQUIPMENT", 0, 0, 2 );
@@ -811,13 +911,17 @@ void LoadGameExternalOptions()
gGameExternalOptions.usLevelSubpointsToImprove = iniReader.ReadInteger("Tactical Difficulty Settings","LEVEL_SUBPOINTS_TO_IMPROVE", 350, 1, 6500);
// Alternate algorithm for choosing equipment level. Mostly disregards soldier's class and puts less emphasis on distance from Sector P3.
- gGameExternalOptions.fSlowProgressForEnemyItemsChoice = iniReader.ReadBoolean("Tactical Difficulty Settings", "SLOW_PROGRESS_FOR_ENEMY_ITEMS_CHOICE", TRUE);
+ // SANDRO - moved into the game
+ //gGameExternalOptions.fSlowProgressForEnemyItemsChoice = iniReader.ReadBoolean("Tactical Difficulty Settings", "SLOW_PROGRESS_FOR_ENEMY_ITEMS_CHOICE", TRUE);
// The_Bob - real time sneaking code 01/06/09
// Suport disabling real time sneaking via external .ini file
- gGameExternalOptions.fAllowRealTimeSneak = iniReader.ReadBoolean("Tactical Difficulty Settings","ALLOW_REAL_TIME_SNEAK", FALSE);
+ // SANDRO - revisited and moved to preferences
+ // gGameExternalOptions.fAllowRealTimeSneak = iniReader.ReadBoolean("Tactical Difficulty Settings","ALLOW_REAL_TIME_SNEAK", FALSE);
// Silence the RT sneaking messages
gGameExternalOptions.fQuietRealTimeSneak = iniReader.ReadBoolean("Tactical Difficulty Settings","QUIET_REAL_TIME_SNEAK", FALSE);
+ // HEADROCK HAM 3.6: If activated, the game does not switch focus to a merc who spots an enemy in real-time mode. This fixes issues with Real-Time Sneak.
+ gGameExternalOptions.fNoAutoFocusChangeInRealtimeSneak = iniReader.ReadBoolean("Tactical Difficulty Settings","NO_AUTO_FOCUS_CHANGE_IN_REALTIME_SNEAK", FALSE);
// HEADROCK HAM 3.2: If activated, reinforcements (militia/enemy) arrive in the battle with 0 APs. This makes them less of a diablo-ex-machina. 0 = Diabled. 2 = Enemies. 3 = Militia. 1 = both
gGameExternalOptions.ubReinforcementsFirstTurnFreeze = iniReader.ReadInteger("Tactical Difficulty Settings","REINFORCEMENTS_ARRIVE_WITH_ZERO_AP", 0, 0, 3);
@@ -825,15 +929,24 @@ void LoadGameExternalOptions()
// HEADROCK HAM 3.6: Militia can now place blue flags when they spot a landmine.
gGameExternalOptions.fMilitiaPlaceBlueFlags = iniReader.ReadBoolean("Tactical Difficulty Settings","MILITIA_CAN_PLACE_FLAGS_ON_MINES", FALSE);
- // WANNE: Added INI file Option for enemy ambushes, so we also have the option to play vanilla ja2 ambush settings
- gGameExternalOptions.fEnableChanceOfEnemyAmbushesOnInsaneDifficult = iniReader.ReadBoolean("Tactical Difficulty Settings", "ENABLE_CHANCE_OF_ENEMY_AMBUSHES_ON_INSANE_DIFFICULT", TRUE);
-
// HEADROCK HAM 3.6: Non-Combat Bodytypes shouldn't become hostile
gGameExternalOptions.fCanTrueCiviliansBecomeHostile = iniReader.ReadBoolean("Tactical Difficulty Settings","CAN_TRUE_CIVILIANS_BECOME_HOSTILE", TRUE);
// HEADROCK HAM 3.6: Militia become hostile when attacked. 0 = No. 1 = If killed. 2 = If attacked (JA2 Default)
gGameExternalOptions.ubCanMilitiaBecomeHostile = iniReader.ReadInteger("Tactical Difficulty Settings","CAN_MILITIA_BECOME_HOSTILE", 2, 0, 2);
+ // SANDRO - Mercs stronger during autoresolve setting
+ gGameExternalOptions.sMercsAutoresolveOffenseBonus = iniReader.ReadInteger("Tactical Difficulty Settings", "MERCS_OFFENSE_IN_AUTORESOLVE_BATTLES_BONUS",15, -100, 500);
+ gGameExternalOptions.sMercsAutoresolveDeffenseBonus = iniReader.ReadInteger("Tactical Difficulty Settings", "MERCS_DEFFENSE_IN_AUTORESOLVE_BATTLES_BONUS",30, -100, 500);
+
+ // WANNE: Added INI file Option for enemy ambushes, so we also have the option to play vanilla ja2 ambush settings
+ // SANDRO - changed this so on any difficulty there is a chance to beambushed. Hoever this chance is calculated differently to not lead to instant load game like before
+ gGameExternalOptions.fEnableChanceOfEnemyAmbushes = iniReader.ReadBoolean("Tactical Difficulty Settings", "ENABLE_CHANCE_OF_ENEMY_AMBUSHES", TRUE);
+ gGameExternalOptions.bChanceModifierEnemyAmbushes = iniReader.ReadInteger("Tactical Difficulty Settings","ENEMY_AMBUSHES_CHANCE_MODIFIER ", 0, -100, 100);
+
+ // SANDRO - Special NPCs strength increased by percent
+ gGameExternalOptions.usSpecialNPCStronger = iniReader.ReadInteger("Tactical Difficulty Settings", "SPECIAL_NPCS_STRONGER",0, 0, 200);
+
//################# Tactical Vision Settings #################
@@ -844,7 +957,6 @@ void LoadGameExternalOptions()
gGameExternalOptions.gfAllowLimitedVision = iniReader.ReadBoolean("Tactical Vision Settings","ALLOW_TUNNEL_VISION",0);
-
//################# Tactical Tooltip Settings #################
// ShadoWarrior: Tooltip changes (start)
@@ -859,6 +971,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.fEnableSoldierTooltipAttitude = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_ATTITUDE", TRUE);
gGameExternalOptions.fEnableSoldierTooltipActionPoints = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_ACTIONPOINTS", TRUE);
gGameExternalOptions.fEnableSoldierTooltipHealth = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_HEALTH", TRUE);
+ gGameExternalOptions.fEnableSoldierTooltipTraits = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_TRAITS", TRUE); // added by SANDRO
gGameExternalOptions.fEnableSoldierTooltipHelmet = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_HELMET", TRUE);
gGameExternalOptions.fEnableSoldierTooltipVest = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_VEST", TRUE);
gGameExternalOptions.fEnableSoldierTooltipLeggings = iniReader.ReadBoolean("Tactical Tooltip Settings", "SOLDIER_TOOLTIP_DISPLAY_LEGGINGS", TRUE);
@@ -880,6 +993,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.ubUDTModifier = (UINT8) iniReader.ReadInteger("Tactical Tooltip Settings", "DYNAMIC_TOOLTIP_RANGE_MODIFIER", 50);
gGameExternalOptions.gfAllowUDTDetail = iniReader.ReadBoolean("Tactical Tooltip Settings","ALLOW_DYNAMIC_TOOLTIP_DETAIL_LEVEL",0);
+
//################# Tactical Gameplay Settings ##################
// HEADROCK HAM B1: Set minimum and maximum CTH
@@ -899,30 +1013,121 @@ void LoadGameExternalOptions()
// HEADROCK HAM B2.5: Realistic tracers - CTH increased by this amount whenever a tracer is fired. 0 = off.
gGameExternalOptions.ubCTHBumpPerTracer = iniReader.ReadInteger("Tactical Gameplay Settings","CTH_BUMP_PER_TRACER", 30, 0, 100 );
+ // CHRISL: Exeternalize the minimum range at which tracers can improve autofire hit chance
+ gGameExternalOptions.ubMinRangeTracerEffect = iniReader.ReadInteger("Tactical Gameplay Settings","MIN_RANGE_FOR_TRACER", 10);
+
// HEADROCK HAM 3.5: Limit bonus from tracers based on range to target. This is a multiplier factor - higher means harder to aim with tracers.
gGameExternalOptions.ubRangeDifficultyAimingWithTracers = iniReader.ReadInteger("Tactical Gameplay Settings","RANGE_EFFECT_ON_MAX_TRACER_CTH_BONUS", 3, 1, 10);
// HEADROCK HAM B2.6: Increased aiming costs?
gGameExternalOptions.fIncreasedAimingCost = iniReader.ReadBoolean("Tactical Gameplay Settings","INCREASE_AIMING_COSTS", FALSE);
+ // CHRISL: Converts the AutoFireToHitBonus value to a percentage for CTH calculations
+ gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier = iniReader.ReadInteger("Tactical Gameplay Settings","AUTOFIRE_TOHIT_BONUS_MULTIPLIER", 0, 0, 10);
+
// HEADROCK HAM 3.1: Divisor for the AP-to-Ready cost charge on first aiming click, when extra aiming costs are enabled. 0 = No ready-time-based charge.
gGameExternalOptions.ubFirstAimReadyCostDivisor = iniReader.ReadInteger("Tactical Gameplay Settings","FIRST_AIM_READY_COST_DIVISOR", 0, 0, 255);
+ // SANDRO - moved this here from preferences and renamed to actually match its effect
+ gGameExternalOptions.fAimLevelRestriction = iniReader.ReadBoolean("Tactical Gameplay Settings","ALLOW_EXTRA_AIM_LEVELS", TRUE);
+
// HEADROCK HAM B2.6: Dynamically determine Max-Aiming based also on weapon, bipod, etc?
gGameExternalOptions.fDynamicAimingTime = iniReader.ReadBoolean("Tactical Gameplay Settings","DYNAMIC_AIMING_LIMITS", FALSE);
+ // allow old behaviour
+ gGameExternalOptions.fAimLevelsDependOnDistance = iniReader.ReadBoolean("Tactical Gameplay Settings", "AIM_LEVELS_DEPEND_ON_DISTANCE", TRUE);
+
+ //WarmSteel - These determine in which group each scope belongs. Needed for dynamic aiming limits.
+ gGameExternalOptions.sVeryHighPowerScope = iniReader.ReadInteger("Tactical Gameplay Settings","VERY_HIGH_POWER_SCOPE_AIM_THRESHOLD", 18, 0, 255);
+ gGameExternalOptions.sHighPowerScope = iniReader.ReadInteger("Tactical Gameplay Settings","HIGH_POWER_SCOPE_AIM_THRESHOLD", 13, 0, 255);
+ gGameExternalOptions.sMediumPowerScope = iniReader.ReadInteger("Tactical Gameplay Settings","MEDIUM_POWER_SCOPE_AIM_THRESHOLD", 8, 0, 255);
+
// HEADROCK HAM B2.6: Controls how much effect target movement has on aiming
gGameExternalOptions.iMovementEffectOnAiming = (float)iniReader.ReadDouble("Tactical Gameplay Settings","CTH_PENALTY_FOR_TARGET_MOVEMENT", 1.5, 0.0, 255.0);
// HEADROCK HAM 3.3: Externalized maximum possible penalty for hitting a moving target. JA2 Default = 30.
gGameExternalOptions.usMaxCTHPenaltyForMovingTarget = iniReader.ReadInteger("Tactical Gameplay Settings","MAX_CTH_PENALTY_FOR_TARGET_MOVEMENT", 30, 0, 300);
+ // CHRISL: HAM4-NCTH
+ gGameExternalOptions.fUseNCTH = iniReader.ReadBoolean("Tactical Gameplay Settings", "USE_NCTH", FALSE, false);
+
// HEADROCK HAM 3.2: Critical Headshots may cause blindness. Rolls 1 to X change of being blinded. 0 = disabled.
- gGameExternalOptions.ubChanceBlindedByHeadshot = iniReader.ReadInteger("Tactical Gameplay Settings","CHANCE_BLINDED_BY_HEADSHOT", 0, 0, 10);
+ gGameExternalOptions.ubChanceBlindedByHeadshot = iniReader.ReadInteger("Tactical Gameplay Settings","CHANCE_BLINDED_BY_HEADSHOT", 0, 0, 100);
// HEADROCK HAM 3.2: Critical Legshots cause additional AP loss
gGameExternalOptions.fCriticalLegshotCausesAPLoss = iniReader.ReadBoolean("Tactical Gameplay Settings","CRITICAL_LEGSHOT_CAUSES_AP_LOSS", FALSE);
+ //legion by Jazz
+ gGameExternalOptions.fCanJumpThroughWindows = iniReader.ReadBoolean("Tactical Gameplay Settings","CAN_JUMP_THROUGH_WINDOWS", FALSE);
+ gGameExternalOptions.fCanClimbOnWalls = iniReader.ReadBoolean("Tactical Gameplay Settings","CAN_CLIMB_ON_WALLS", FALSE);
+
+ //legion by Jazz
+ gGameExternalOptions.fIndividualHiddenPersonNames = iniReader.ReadBoolean("Tactical Gameplay Settings","INDIVIDUAL_HIDDEN_PERSON_NAMES", FALSE);
+
+ //Enemy Names by Jazz
+ gGameExternalOptions.fEnemyNames = iniReader.ReadBoolean("Tactical Gameplay Settings","INDIVIDUAL_ENEMY_NAMES",FALSE);
+
+ //Civ Names by Jazz
+ gGameExternalOptions.fCivGroupName = iniReader.ReadBoolean("Tactical Gameplay Settings","INDIVIDUAL_CIVILIAN_NAMES",FALSE);
+
+ //Enemy Rank by Jazz
+ gGameExternalOptions.fEnemyRank = iniReader.ReadBoolean("Tactical Gameplay Settings","INDIVIDUAL_ENEMY_RANK",FALSE);
+
+ // *** ddd - BEGIN
+ gGameExternalOptions.fExtMouseKeyEnabled = iniReader.ReadBoolean("Tactical Interface Settings", "ENABLE_EXT_MOUSE_KEYS", FALSE);
+
+ // New setting to change stamina
+ gGameExternalOptions.uStaminaHit = iniReader.ReadInteger("Tactical Interface Settings", "STAMINA_HIT", 10000);
+
+ // Alternative system for aiming - progressive method depending on marksmash of Merc
+ gGameExternalOptions.bAltAimEnabled = iniReader.ReadBoolean("Tactical Interface Settings","ALT_AIMING_ENABLED",FALSE);
+
+ // Use aimed burst
+ gGameExternalOptions.bAimedBurstEnabled = iniReader.ReadBoolean("Tactical Interface Settings","USE_AIMED_BURST",FALSE);
+
+ // Penalcy for aimed burst
+ gGameExternalOptions.uAimedBurstPenalty = iniReader.ReadInteger("Tactical Interface Settings","AIMING_BURST_PENALTY",2);
+
+ // We could see all what can see militia
+ gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa = iniReader.ReadBoolean("Tactical Interface Settings","WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA",TRUE);
+
+ // Gun supressor can deterioration
+ gGameExternalOptions.bAllowWearSuppressor = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_WEAR_SUPPRESSOR",FALSE);
+
+ // Civils don't make too much actions (for faster civils turn)
+ gGameExternalOptions.bLazyCivilians = iniReader.ReadBoolean("Tactical Interface Settings","ALLOW_LAZY_CIVILIANS",FALSE);
+
+ // Chance to Say Annoying Phrase (you can just turn of it by button in game)
+ gGameExternalOptions.iChanceSayAnnoyingPhrase = iniReader.ReadInteger("Tactical Interface Settings","CHANCE_SAY_ANNOYING_PHRASE",100);
+
+ // New enemy AI for night battles
+ gGameExternalOptions.bNewTacticalAIBehavior = iniReader.ReadBoolean("Tactical Interface Settings","NEW_AI_TACTICAL",FALSE);
+
+ // Heahshot penalty
+ gGameExternalOptions.uShotHeadPenalty = iniReader.ReadFloat("Tactical Interface Settings","SHOT_HEAD_PENALTY",3,0,100);
+
+ // Modifer of damage for HEADSHOT
+ gGameExternalOptions.fShotHeadDivisor = iniReader.ReadFloat("Tactical Interface Settings","SHOT_HEAD_DIVISOR",1.5,1,10);
+
+ // Penalty for fire when you don't see enemy (when you see enemy because his see militya or ather merc)
+ gGameExternalOptions.iPenaltyShootUnSeen = iniReader.ReadInteger("Tactical Interface Settings","SHOOT_UNSEEN_PENALTY",0,0,255);
+
+ // CtH/2 if the target are out of gun range or invisible for this merc
+ gGameExternalOptions.fOutOfGunRangeOrSight = iniReader.ReadFloat("Tactical Interface Settings","OUT_OF_SIGHT_OR_GUN_RANGE",2,1,100);
+ // *** ddd - END
+
+ // SANDRO - Improved camo applying and camo can be removed
+ gGameExternalOptions.fCamoRemoving = iniReader.ReadBoolean("Tactical Gameplay Settings", "CAMO_REMOVING", TRUE);
+
+ // SANDRO - Enhanced close combat system
+ gGameExternalOptions.fEnhancedCloseCombatSystem = iniReader.ReadBoolean("Tactical Gameplay Settings", "ENHANCED_CLOSE_COMBAT_SYSTEM", FALSE);
+
+ // SANDRO - give special Exp for completing quests
+ gGameExternalOptions.usAwardSpecialExpForQuests = iniReader.ReadInteger("Tactical Gameplay Settings", "AWARD_SPECIAL_EXP_POINTS_FOR_COMPLETING_QUESTS", 100, 0, 5000);
+
+ //tais: soldiers always wear any armour..
+ gGameExternalOptions.fSoldiersWearAnyArmour = iniReader.ReadBoolean("Tactical Gameplay Settings", "SOLDIERS_ALWAYS_WEAR_ANY_ARMOR", FALSE);
+
//################# Tactical Cover System Settings ##################
// CPT: Cover System Settings
@@ -930,9 +1135,9 @@ void LoadGameExternalOptions()
gGameExternalOptions.ubStealthEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_STEALTH_EFFECTIVENESS", 50, 0, 100);
gGameExternalOptions.ubCamouflageEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_CAMOUFLAGE_EFFECTIVENESS", 50, 0, 100);
gGameExternalOptions.ubStanceEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_STANCE_EFFECTIVENESS", 10, 0, 100);
- gGameExternalOptions.ubLBEEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_LBE_EFFECTIVENESS", 50, 0, 100);
- gGameExternalOptions.ubMovementEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_MOVEMENT_EFFECTIVENESS", 50, 0, 100);
- gGameExternalOptions.ubTreeCoverEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_TREE_EFFECTIVENESS", 50, 0, 100);
+ gGameExternalOptions.ubLBEEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_LBE_EFFECTIVENESS", 20, 0, 100);
+ gGameExternalOptions.ubMovementEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_MOVEMENT_EFFECTIVENESS", 20, 0, 100);
+ gGameExternalOptions.ubTreeCoverEffectiveness = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_TREE_EFFECTIVENESS", 20, 0, 100);
gGameExternalOptions.ubCoverDisplayUpdateWait = iniReader.ReadInteger("Tactical Cover System Settings", "COVER_SYSTEM_UPDATE_DELAY", 500, -1, 10000);
//################# Tactical Suppression Fire Settings ##################
@@ -1099,7 +1304,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.fEnableCrepitus = iniReader.ReadBoolean("Strategic Event Settings", "ENABLE_CREPITUS", TRUE);
// HEADROCK HAM 3.1: Select which mine will run out. 0 = no mine. 1 = San Mona (unused), 2 = Drassen, 3 = Alma, 4 = Cambria, 5 = Chitzena, 6 = Grumm.
- gGameExternalOptions.bWhichMineRunsOut = iniReader.ReadInteger("Strategic Event Settings","WHICH_MINE_SHUTS_DOWN", -1, -1, 6);
+ gGameExternalOptions.bWhichMineRunsOut = iniReader.ReadInteger("Strategic Event Settings","WHICH_MINE_SHUTS_DOWN", -1, -1, 256);
//################# Strategic Gameplay Settings ##################
@@ -1109,8 +1314,9 @@ void LoadGameExternalOptions()
// Allow reinforcements only between City sectors?
gGameExternalOptions.gfAllowReinforcementsOnlyInCity = iniReader.ReadBoolean("Strategic Gameplay Settings","ALLOW_REINFORCEMENTS_ONLY_IN_CITIES",FALSE);
- gGameExternalOptions.fEnableAllTerrorists = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_TERRORISTS", FALSE);
- gGameExternalOptions.fEnableAllWeaponCaches = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_WEAPON_CACHES", FALSE);
+ // SANDRO - moved into the game start screen
+ //gGameExternalOptions.fEnableAllTerrorists = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_TERRORISTS", FALSE);
+ //gGameExternalOptions.fEnableAllWeaponCaches = iniReader.ReadBoolean("Strategic Gameplay Settings", "ENABLE_ALL_WEAPON_CACHES", FALSE);
// Kaiden: Vehicle Inventory change - Added INI file Option VEHICLE_INVENTORY
gGameExternalOptions.fVehicleInventory = iniReader.ReadBoolean("Strategic Gameplay Settings", "VEHICLE_INVENTORY", TRUE);
@@ -1129,6 +1335,11 @@ void LoadGameExternalOptions()
// HEADROCK HAM 3.6: Controls how important the character's stats are, in insuring he/she gets better results (or smaller damage) from using facilities. The higher this is, the more dangerous all facilities are.
gGameExternalOptions.ubFacilityDangerRate = iniReader.ReadInteger("Strategic Gameplay Settings","FACILITY_DANGER_RATE", 50, 0, 100);
+ // 2Points: Use new repair algorithm (Items are priorized based on type and damage to item, starting from equipped weapons, going to armor, then inventory)
+ gGameExternalOptions.fAdditionalRepairMode = iniReader.ReadBoolean("Strategic Gameplay Settings", "ADDITIONAL_REPAIR_MODE", FALSE);
+
+ // CHRISL: Determine how Skyrider should handle landing in enemy occupied sectors
+ gGameExternalOptions.ubSkyriderHotLZ = iniReader.ReadInteger("Strategic Gameplay Settings", "ALLOW_SKYRIDER_HOT_LZ", 0);
//################# Bobby Ray Settings ##################
@@ -1149,6 +1360,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.iExplosivesDamageModifier = iniReader.ReadInteger("Item Property Settings","EXPLOSIVES_DAMAGE_MODIFIER",100, 0, 1000);
gGameExternalOptions.iMeleeDamageModifier = iniReader.ReadInteger("Item Property Settings","MELEE_DAMAGE_MODIFIER",100, 0, 1000);
gGameExternalOptions.iGunDamageModifier = iniReader.ReadInteger("Item Property Settings","GUN_DAMAGE_MODIFIER",100, 0, 1000);
+ gGameExternalOptions.iGunRangeModifier = iniReader.ReadInteger("Item Property Settings","GUN_RANGE_MODIFIER",100, 0, 1000);
// Enables the "Coverage" value of armor items.
gGameExternalOptions.fEnableArmorCoverage = iniReader.ReadBoolean("Item Property Settings", "ENABLE_ARMOR_COVERAGE", FALSE); // ShadoWarrior for Captain J's armor coverage
@@ -1164,7 +1376,10 @@ void LoadGameExternalOptions()
// HEADROCK HAM 3.2: Set a divisor for the CtH of Mortar weapons.
gGameExternalOptions.ubMortarCTHDivisor = iniReader.ReadInteger("Item Property Settings","MORTAR_CTH_DIVISOR", 1, 1, 255);
-
+ // WarmSteel: NAS
+ gGameExternalOptions.fUseDefaultSlots = iniReader.ReadBoolean("Item Property Settings","USE_DEFAULT_SLOTS_WHEN_MISSING",FALSE);
+ gGameExternalOptions.usAttachmentDropRate = iniReader.ReadInteger("Item Property Settings","ATTACHMENT_DROP_RATE",10, 0, 100);
+ gGameExternalOptions.iMaxEnemyAttachments = iniReader.ReadInteger("Item Property Settings","MAX_ENEMY_ATTACHMENTS",6, 2, MAX_ATTACHMENTS);
//################# Strategic Enemy AI Settings ##################
@@ -1319,12 +1534,43 @@ void LoadGameExternalOptions()
gGameExternalOptions.fAllowMobileReinforceSAM = iniReader.ReadBoolean("Mobile Militia Movement Settings","ALLOW_MOBILE_MILITIA_REINFORCE_SAM_GARRISONS", FALSE);
+ // SANDRO - added several bonuses for militia
+ //################# Militia Strength Settings ##################
+
+ // These applies for autoresolve only
+ gGameExternalOptions.sGreenMilitiaAutoresolveStrength = iniReader.ReadInteger("Militia Strength Settings", "GREEN_MILITIA_AUTORESOLVE_STRENGTH_BONUS", 0, -100, 500);
+ gGameExternalOptions.sRegularMilitiaAutoresolveStrength = iniReader.ReadInteger("Militia Strength Settings", "REGULAR_MILITIA_AUTORESOLVE_STRENGTH_BONUS", 0, -100, 500);
+ gGameExternalOptions.sVeteranMilitiaAutoresolveStrength = iniReader.ReadInteger("Militia Strength Settings", "VETERAN_MILITIA_AUTORESOLVE_STRENGTH_BONUS", 10, -100, 500);
+
+ // Flat bonus to militia APs - applies during tactical combat only
+ gGameExternalOptions.bGreenMilitiaAPsBonus = iniReader.ReadInteger("Militia Strength Settings", "GREEN_MILITIA_APS_BONUS", 0, -75, 75);
+ gGameExternalOptions.bRegularMilitiaAPsBonus = iniReader.ReadInteger("Militia Strength Settings", "REGULAR_MILITIA_APS_BONUS", 0, -75, 75);
+ gGameExternalOptions.bVeteranMilitiaAPsBonus = iniReader.ReadInteger("Militia Strength Settings", "VETERAN_MILITIA_APS_BONUS", 5, -75, 75);
+
+ // Percentage bonus to total militia CtH on every hit - applies during tactical combat only
+ gGameExternalOptions.sGreenMilitiaCtHBonusPercent = iniReader.ReadInteger("Militia Strength Settings", "GREEN_MILITIA_CTH_BONUS_PERCENT", 0, -100, 500);
+ gGameExternalOptions.sRegularMilitiaCtHBonusPercent = iniReader.ReadInteger("Militia Strength Settings", "REGULAR_MILITIA_CTH_BONUS_PERCENT", 0, -100, 500);
+ gGameExternalOptions.sVeteranMilitiaCtHBonusPercent = iniReader.ReadInteger("Militia Strength Settings", "VETERAN_MILITIA_CTH_BONUS_PERCENT", 10, -100, 500);
+
+ // Damage the militia suffer is reduced by this percentage - applies during tactical combat only
+ gGameExternalOptions.bGreenMilitiaDamageResistance = iniReader.ReadInteger("Militia Strength Settings", "GREEN_MILITIA_DAMAGE_RESISTANCE", 0, -50, 95);
+ gGameExternalOptions.bRegularMilitiaDamageResistance = iniReader.ReadInteger("Militia Strength Settings", "REGULAR_MILITIA_DAMAGE_RESISTANCE", 0, -50, 95);
+ gGameExternalOptions.bVeteranMilitiaDamageResistance = iniReader.ReadInteger("Militia Strength Settings", "VETERAN_MILITIA_DAMAGE_RESISTANCE", 0, -50, 95);
+
+ // Modifier increasing militia equipment quality on creation - applies during tactical combat only
+ gGameExternalOptions.bGreenMilitiaEquipmentQualityModifier = iniReader.ReadInteger("Militia Strength Settings", "GREEN_MILITIA_EQUIPMENT_QUALITY_MODIFIER", 0, -5, 10);
+ gGameExternalOptions.bRegularMilitiaEquipmentQualityModifier = iniReader.ReadInteger("Militia Strength Settings", "REGULAR_MILITIA_EQUIPMENT_QUALITY_MODIFIER", 0, -5, 10);
+ gGameExternalOptions.bVeteranMilitiaEquipmentQualityModifier = iniReader.ReadInteger("Militia Strength Settings", "VETERAN_MILITIA_EQUIPMENT_QUALITY_MODIFIER", 1, -5, 10);
+
+
//################# Shopkeeper Inventory Settings ##################
// WDS - Improve Tony's and Devin's inventory like BR's
gGameExternalOptions.tonyUsesBRSetting = iniReader.ReadBoolean("Shopkeeper Inventory Settings","TONY_USES_BOBBY_RAYS_SETTING", FALSE);
gGameExternalOptions.devinUsesBRSetting = iniReader.ReadBoolean("Shopkeeper Inventory Settings","DEVIN_USES_BOBBY_RAYS_SETTING", FALSE);
+ // chance that Tony will be in his office - silversurfer/SANDRO
+ gGameExternalOptions.ubChanceTonyAvailable = iniReader.ReadInteger("Shopkeeper Inventory Settings","CHANCE_TONY_AVAILABLE", 80, 0, 100);
//################# Strategic Assignment Settings ##################
@@ -1358,7 +1604,7 @@ void LoadGameExternalOptions()
gGameExternalOptions.ubHighActivityLevel = iniReader.ReadInteger("Strategic Assignment Settings","NATURAL_HEALING_SPEED_DIVISOR_AT_HIGH_ACTIVITY_LEVEL",12, 1, 100);
gGameExternalOptions.ubDoctoringRateDivisor = iniReader.ReadInteger("Strategic Assignment Settings","DOCTORING_RATE_DIVISOR",2400, 1200, 24000);
- gGameExternalOptions.ubHospitalHealingRate = iniReader.ReadInteger("Strategic Assignment Settings","HOSPITAL_HEALING_RATE",5, 1, 10);
+ gGameExternalOptions.ubHospitalHealingRate = iniReader.ReadInteger("Strategic Assignment Settings","HOSPITAL_HEALING_RATE",5, 1, 12);
gGameExternalOptions.ubBaseMedicalSkillToDealWithEmergency = iniReader.ReadInteger("Strategic Assignment Settings","BASE_MEDICAL_SKILL_TO_DEAL_WITH_EMERGENCY",20, 0, 100);
gGameExternalOptions.ubMultiplierForDifferenceInLifeValueForEmergency = iniReader.ReadInteger("Strategic Assignment Settings","MULTIPLIER_FOR_DIFFERENCE_IN_LIFE_VALUE_FOR_EMERGENCY",4, 1, 10);
gGameExternalOptions.ubPointCostPerHealthBelowOkLife = iniReader.ReadInteger("Strategic Assignment Settings","POINT_COST_PER_HEALTH_BELOW_OKLIFE",2, 1, 5);//OKLIFE = 15
@@ -1366,19 +1612,274 @@ void LoadGameExternalOptions()
////////// REPAIR //////////
gGameExternalOptions.ubRepairCostPerJam = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_POINT_COST_TO_FIX_WEAPON_JAM",2, 1, 10);
- gGameExternalOptions.ubRepairRateDivisor = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_RATE_DIVISOR",2500, 1250, 25000);
+ gGameExternalOptions.ubRepairRateDivisor = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_RATE_DIVISOR",2500, 500, 25000);
gGameExternalOptions.ubAssignmentUnitsPerDay = iniReader.ReadInteger("Strategic Assignment Settings","REPAIR_SESSIONS_PER_DAY",24, 1, 96);
-
- // WANNE: This is just a debug setting. Only in debug version we should check if propert is set in the ja2_options.ini,
+
+ //SaveGame slot by Jazz
+ // WANNE: No need to make it external to switch between old/new. We always use the new save/load screen with more save slots
+ //gGameExternalOptions.fSaveGameSlot = iniReader.ReadBoolean("Extension","SAVE_GAMES_SLOT",FALSE);
+ gGameExternalOptions.fSaveGameSlot = TRUE;
+
+ // WANNE: This is just a debug setting. Only in debug version we set that property to TRUE.
// In Release version this should always be set to FALSE
- //dnl ch51 081009 JA2 Debug Settings
+ // dnl ch51 081009 JA2 Debug Settings
#ifdef _DEBUG
gGameExternalOptions.fEnableInventoryPoolQ = TRUE;
#else
gGameExternalOptions.fEnableInventoryPoolQ = FALSE;
-#endif
+#endif
}
+
+// SANDRO - externalization of all skill trait values and STOMP settings into separate file
+void LoadSkillTraitsExternalSettings()
+{
+ CIniReader iniReader(STOMP_SETTINGS_FILE);
+
+ gSkillTraitValues.ubMaxNumberOfTraits = iniReader.ReadInteger("Generic Traits Settings","MAX_NUMBER_OF_TRAITS", 3, 2, 30);
+ gSkillTraitValues.ubNumberOfMajorTraitsAllowed = iniReader.ReadInteger("Generic Traits Settings","NUMBER_OF_MAJOR_TRAITS_ALLOWED", 2, 2, 20);
+
+ // GENERIC SETTINGS
+ gSkillTraitValues.bCtHModifierAssaultRifles = iniReader.ReadInteger("Generic Traits Settings","ASSAULT_RIFLES_CTH_MODIFIER", -5, -100, 100);
+ gSkillTraitValues.bCtHModifierSniperRifles = iniReader.ReadInteger("Generic Traits Settings","SNIPER_RIFLES_CTH_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bCtHModifierRifles = iniReader.ReadInteger("Generic Traits Settings","RIFLES_CTH_MODIFIER", -5, -100, 100);
+ gSkillTraitValues.bCtHModifierSMGs = iniReader.ReadInteger("Generic Traits Settings","SMGS_CTH_MODIFIER", -5, -100, 100);
+ gSkillTraitValues.bCtHModifierLMGs = iniReader.ReadInteger("Generic Traits Settings","LMGS_CTH_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bCtHModifierShotguns = iniReader.ReadInteger("Generic Traits Settings","SHOTGUNS_CTH_MODIFIER", -5, -100, 100);
+ gSkillTraitValues.bCtHModifierPistols = iniReader.ReadInteger("Generic Traits Settings","PISTOLS_CTH_MODIFIER", -5, -100, 100);
+ gSkillTraitValues.bCtHModifierMachinePistols = iniReader.ReadInteger("Generic Traits Settings","MACHINE_PISTOLS_CTH_MODIFIER", -5, -100, 100);
+ gSkillTraitValues.bCtHModifierRocketLaunchers = iniReader.ReadInteger("Generic Traits Settings","ROCKET_LAUNCHERS_CTH_MODIFIER", -25, -100, 100);
+ gSkillTraitValues.bCtHModifierGrenadeLaunchers = iniReader.ReadInteger("Generic Traits Settings","GRENADE_LAUNCHERS_CTH_MODIFIER", -25, -100, 100);
+ gSkillTraitValues.sCtHModifierMortar = iniReader.ReadInteger("Generic Traits Settings","MORTAR_CTH_MODIFIER", -60, -500, 500);
+ gSkillTraitValues.bCtHModifierThrowingKnives = iniReader.ReadInteger("Generic Traits Settings","THROWING_KNIVES_CTH_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bCtHModifierThrowingGrenades = iniReader.ReadInteger("Generic Traits Settings","THROWING_GRENADES_CTH_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bCtHModifierHtHAttack = iniReader.ReadInteger("Generic Traits Settings","HTH_ATTACK_CTH_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bModifierDodgeHtHChance = iniReader.ReadInteger("Generic Traits Settings","CHANCE_TO_DODGE_HTH_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bCtHModifierKnifeAttack = iniReader.ReadInteger("Generic Traits Settings","KNIFE_ATTACK_CTH_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bModifierDodgeKnifeChance = iniReader.ReadInteger("Generic Traits Settings","CHANCE_TO_DODGE_KNIFE_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bCtHModifierRobot = iniReader.ReadInteger("Generic Traits Settings","ROBOT_CTH_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.ubCtHPenaltyDualShot = iniReader.ReadInteger("Generic Traits Settings","DUAL_SHOT_CTH_PENALTY", 25, 0, 100);
+ gSkillTraitValues.bPercentModifierHtHBreathLoss = iniReader.ReadInteger("Generic Traits Settings","PERCENT_BREATH_LOSS_ON_HTH_ATTACK_MODIFIER", -25, -100, 100);
+ gSkillTraitValues.bPercentModifierBladesBreathLoss = iniReader.ReadInteger("Generic Traits Settings","PERCENT_BREATH_LOSS_ON_KNIFE_ATTACK_MODIFIER", -25, -100, 100);
+ gSkillTraitValues.bPercentModifierBluntBreathLoss = iniReader.ReadInteger("Generic Traits Settings","PERCENT_BREATH_LOSS_ON_BLUNT_MELEE_ATTACK_MODIFIER", -40, -100, 100);
+ gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches = iniReader.ReadInteger("Generic Traits Settings","MODIFIER_FOR_APS_ADDED_ON_AIMED_HTH_ATTACKS", 3, 1, 10);
+ gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes = iniReader.ReadInteger("Generic Traits Settings","MODIFIER_FOR_APS_ADDED_ON_AIMED_BLADE_ATTACKS", 3, 1, 10);
+ gSkillTraitValues.bSpeedModifierDoctoring = iniReader.ReadInteger("Generic Traits Settings","DOCTORING_SPEED_MODIFIER", -40, -100, 100);
+ gSkillTraitValues.bSpeedModifierBandaging = iniReader.ReadInteger("Generic Traits Settings","BANDAGING_SPEED_MODIFIER", -30, -100, 100);
+ gSkillTraitValues.bSpeedModifierRepairing = iniReader.ReadInteger("Generic Traits Settings","REPAIRING_SPEED_MODIFIER", -20, -100, 100);
+ gSkillTraitValues.bSpeedModifierTrainingMilitia = iniReader.ReadInteger("Generic Traits Settings","TRAIN_MILITIA_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bSpeedModifierTeachingOthers = iniReader.ReadInteger("Generic Traits Settings","TEACHING_OTHERS_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bCheckModifierLockpicking = iniReader.ReadInteger("Generic Traits Settings","LOCKPICKING_CHECK_MODIFIER", -10, -100, 100);
+ gSkillTraitValues.bCheckModifierAttachDetonators = iniReader.ReadInteger("Generic Traits Settings","ATTACHING_DETONATORS_CHECK_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bCheckModifierSetExplosives = iniReader.ReadInteger("Generic Traits Settings","SET_EXPLOSIVES_CHECK_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bCheckModifierDisarmExplosiveTraps = iniReader.ReadInteger("Generic Traits Settings","DISARM_EXPLOSIVE_TRAPS_CHECK_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bCheckModifierDisarmElectronicTraps = iniReader.ReadInteger("Generic Traits Settings","DISARM_ELECTRONIC_TRAPS_CHECK_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bCheckModifierAttachSpecialItems = iniReader.ReadInteger("Generic Traits Settings","ATTACH_SPECIAL_ITEMS_CHECK_MODIFIER", -15, -100, 100);
+ gSkillTraitValues.bTanksDamageResistanceModifier = iniReader.ReadInteger("Generic Traits Settings","TANKS_DAMAGE_RESISTANCE_MODIFIER", 40, -100, 95);
+ gSkillTraitValues.ubDamageNeededToLoseStats = iniReader.ReadInteger("Generic Traits Settings","DAMAGE_NEEDED_TO_LOSE_STATS", 15, 0, 100);
+
+ // AUTO WEAPONS
+ gSkillTraitValues.ubAWBonusCtHAssaultRifles = iniReader.ReadInteger("Auto Weapons","BONUS_CTH_ASSAULT_RIFLES", 5, 0, 100);
+ gSkillTraitValues.ubAWBonusCtHSMGs = iniReader.ReadInteger("Auto Weapons","BONUS_CTH_SMGS", 5, 0, 100);
+ gSkillTraitValues.ubAWBonusCtHLMGs = iniReader.ReadInteger("Auto Weapons","BONUS_CTH_LMGS", 5, 0, 100);
+ gSkillTraitValues.ubAWAutoFirePenaltyReduction = iniReader.ReadInteger("Auto Weapons","AUTOFIRE_PENALTY_REDUCTION", 40, 0, 100);
+ gSkillTraitValues.ubAWUnwantedBulletsReduction = iniReader.ReadInteger("Auto Weapons","UNWANTED_BULLETS_REDUCTION", 4, 0, 40);
+ gSkillTraitValues.ubAWFiringSpeedBonusLMGs = iniReader.ReadInteger("Auto Weapons","FIRING_SPEED_BONUS_LMGS", 10, 0, 45);
+ gSkillTraitValues.ubAWPercentReadyLMGReduction = iniReader.ReadInteger("Auto Weapons","PERCENT_AP_READY_LMG_REDUCTION", 10, 0, 45);
+
+ // HEAVY WEAPONS
+ gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction = iniReader.ReadInteger("Heavy Weapons","GRENADE_LAUNCHERS_FIRE_AP_REDUCTION", 20, 0, 45);
+ gSkillTraitValues.ubHWRocketLaunchersAPsReduction = iniReader.ReadInteger("Heavy Weapons","ROCKET_LAUNCHERS_FIRE_AP_REDUCTION", 20, 0, 45);
+ gSkillTraitValues.ubHWBonusCtHGrenadeLaunchers = iniReader.ReadInteger("Heavy Weapons","BONUS_CTH_GRENADE_LAUNCHERS", 25, 0, 100);
+ gSkillTraitValues.ubHWBonusCtHRocketLaunchers = iniReader.ReadInteger("Heavy Weapons","BONUS_CTH_ROCKET_LAUNCHERS", 25, 0, 100);
+ gSkillTraitValues.ubHWMortarAPsReduction = iniReader.ReadInteger("Heavy Weapons","MORTAR_FIRE_AP_REDUCTION", 10, 0, 45);
+ gSkillTraitValues.ubHWMortarCtHPenaltyReduction = iniReader.ReadInteger("Heavy Weapons","MORTAR_CTH_PENALTY_REDUCTION", 50, 0, 100);
+ gSkillTraitValues.ubHWDamageTanksBonusPercent = iniReader.ReadInteger("Heavy Weapons","DAMAGE_TO_TANKS_PERCENT_BONUS", 30, 0, 200);
+ gSkillTraitValues.ubHWDamageBonusPercentForHW = iniReader.ReadInteger("Heavy Weapons","HW_DAMAGE_PERCENT_BONUS", 15, 0, 100);
+
+ // SNIPER
+ gSkillTraitValues.ubSNBonusCtHRifles = iniReader.ReadInteger("Sniper","BONUS_CTH_RIFLES", 5, 0, 100);
+ gSkillTraitValues.ubSNBonusCtHSniperRifles = iniReader.ReadInteger("Sniper","BONUS_CTH_SNIPER_RIFLES", 10, 0, 100);
+ gSkillTraitValues.ubSNEffRangeToTargetReduction = iniReader.ReadInteger("Sniper","EFFECTIVE_RANGE_TO_TARGET_REDUCTION", 5, 0, 45);
+ gSkillTraitValues.ubSNAimingBonusPerClick = iniReader.ReadInteger("Sniper","AIMING_BONUS_PER_CLICK_RIFLES", 10, 0, 50);
+ gSkillTraitValues.ubSNDamageBonusPerClick = iniReader.ReadInteger("Sniper","GUN_DAMAGE_BONUS_PER_CLICK", 5, 0, 50);
+ gSkillTraitValues.ubSNDamageBonusFromNumClicks = iniReader.ReadInteger("Sniper","GUN_DAMAGE_BONUS_FROM_NUM_CLICKS", 4, 0, 8);
+ gSkillTraitValues.ubSNChamberRoundAPsReduction = iniReader.ReadInteger("Sniper","CHAMBER_ROUND_APS_REDUCTION", 25, 0, 45);
+ gSkillTraitValues.ubSNAimClicksAdded = iniReader.ReadInteger("Sniper","POSSIBLE_AIM_CLICK_ADDED_RIFLES", 1, 0, 3);
+
+ // RANGER
+ gSkillTraitValues.ubRABonusCtHRifles = iniReader.ReadInteger("Ranger","BONUS_CTH_RIFLES", 5, 0, 100);
+ gSkillTraitValues.ubRABonusCtHShotguns = iniReader.ReadInteger("Ranger","BONUS_CTH_SHOTGUNS", 10, 0, 100);
+ gSkillTraitValues.ubRAPumpShotgunsAPsReduction = iniReader.ReadInteger("Ranger","PUMP_SHOTGUNS_APS_REDUCTION", 25, 0, 45);
+ gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot = iniReader.ReadInteger("Ranger","GROUP_TIME_SPENT_FOR_TRAVELLING_BY_FOOT_REDUCTION", 20, 0, 100);
+ gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle = iniReader.ReadInteger("Ranger","GROUP_TIME_SPENT_FOR_TRAVELLING_IN_VEHICLE_REDUCTION", 10, 0, 100);
+ gSkillTraitValues.ubRAMaxBonusesToTravelSpeed = iniReader.ReadInteger("Ranger","MAX_STACKABLE_LESS_TRAVEL_TIME_BONUSES", 2, 0, 20);
+ gSkillTraitValues.ubRABreathForTravellingReduction = iniReader.ReadInteger("Ranger","ENERGY_SPENT_TRAVEL_REDUCTION", 30, 0, 100);
+ gSkillTraitValues.ubRAWeatherPenaltiesReduction = iniReader.ReadInteger("Ranger","WEATHER_PENALTIES_REDUCTION", 50, 0, 100);
+ //gSkillTraitValues.ubRACamoEffectivenessBonus = iniReader.ReadInteger("Ranger","CAMO_EFFECTIVENESS_BONUS_PERCENT", 10, 0, 100);
+ gSkillTraitValues.ubRACamoWornountSpeedReduction = iniReader.ReadInteger("Ranger","CAMO_WORNOUT_SPEED_REDUCTION", 50, 0, 100);
+
+ // GUNSLINGER
+ gSkillTraitValues.ubGSFiringSpeedBonusPistols = iniReader.ReadInteger("Gunslinger","FIRING_SPEED_BONUS_PISTOLS", 15, 0, 45);
+ gSkillTraitValues.ubGSEffectiveRangeBonusPistols = iniReader.ReadInteger("Gunslinger","FEFFECTIVE_RANGE_BONUS_PISTOLS", 10, 0, 100);
+ gSkillTraitValues.ubGSBonusCtHPistols = iniReader.ReadInteger("Gunslinger","BONUS_CTH_PISTOLS", 10, 0, 100);
+ gSkillTraitValues.ubGSBonusCtHMachinePistols = iniReader.ReadInteger("Gunslinger","BONUS_CTH_MACHINE_PISTOLS", 5, 0, 100);
+ gSkillTraitValues.ubGSCtHMPExcludeAuto = iniReader.ReadBoolean("Gunslinger","CTH_MP_EXCLUDE_AUTOFIRE", TRUE);
+ gSkillTraitValues.ubGSAimingBonusPerClick = iniReader.ReadInteger("Gunslinger","AIMING_BONUS_PER_CLICK_HANDGUNS", 5, 0, 100);
+ gSkillTraitValues.ubGSPercentReadyPistolsReduction = iniReader.ReadInteger("Gunslinger","PERCENT_AP_READY_PISTOLS_REDUCTION", 15, 0, 50);
+ gSkillTraitValues.ubGSRealoadSpeedHandgunsBonus = iniReader.ReadInteger("Gunslinger","RELOAD_SPEED_HANDGUNS_BONUS", 25, 0, 45);
+ gSkillTraitValues.ubGSAimClicksAdded = iniReader.ReadInteger("Gunslinger","POSSIBLE_AIM_CLICK_ADDED_HANDGUNS", 1, 0, 3);
+
+ // MARTIAL ARTS
+ gSkillTraitValues.ubMAPunchAPsReduction = iniReader.ReadInteger("Martial Arts","PUNCH_APS_REDUCTION", 15, 0, 50);
+ gSkillTraitValues.ubMABonusCtHBareHands = iniReader.ReadInteger("Martial Arts","BONUS_CTH_BARE_HANDS", 30, 0, 100);
+ gSkillTraitValues.ubMABonusCtHBrassKnuckles = iniReader.ReadInteger("Martial Arts","BONUS_CTH_KNUCKLES", 25, 0, 100);
+ gSkillTraitValues.ubMABonusDamageHandToHand = iniReader.ReadInteger("Martial Arts","BONUS_HTH_DAMAGE", 30, 0, 250);
+ gSkillTraitValues.ubMABonusBreathDamageHandToHand = iniReader.ReadInteger("Martial Arts","BONUS_HTH_BREATH_DAMAGE", 30, 0, 250);
+ gSkillTraitValues.usMALostBreathRegainPenalty = iniReader.ReadInteger("Martial Arts","LOST_BREATH_REGAIN_PENALTY", 50, 0, 10000);
+ gSkillTraitValues.usMAAimedPunchDamageBonus = iniReader.ReadInteger("Martial Arts","AIMED_PUNCH_DAMAGE_BONUS", 75, 0, 3000);
+ gSkillTraitValues.bMAAimedPunchCtHModifier = iniReader.ReadInteger("Martial Arts","AIMED_PUNCH_CTH_MODIFIER", 0, -100, 100);
+ gSkillTraitValues.ubMAChanceToDodgeHtH = iniReader.ReadInteger("Martial Arts","BONUS_CHANCE_TO_DODGE_HTH", 35, 0, 250);
+ gSkillTraitValues.ubMAOnTopCTDHtHBareHanded = iniReader.ReadInteger("Martial Arts","ONTOP_BONUS_CTD_HTH_WITH_BARE_HANDS", 5, 0, 250);
+ gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles = iniReader.ReadInteger("Martial Arts","ONTOP_BONUS_CTD_HTH_WITH_KNUCKLES", 0, 0, 250);
+ gSkillTraitValues.ubMAChanceToDodgeMelee = iniReader.ReadInteger("Martial Arts","BONUS_CHANCE_TO_DODGE_MELEE", 20, 0, 250);
+ gSkillTraitValues.ubMAReducedAPsToSteal = iniReader.ReadInteger("Martial Arts","APS_TO_STEAL_WEAPON_REDUCTION", 25, 0, 50);
+ gSkillTraitValues.ubMAAPsChangeStanceReduction = iniReader.ReadInteger("Martial Arts","APS_CHANGE_STANCE_REDUCTION", 25, 0, 100);
+ gSkillTraitValues.ubMAApsTurnAroundReduction = iniReader.ReadInteger("Martial Arts","APS_TURN_AROUND_REDUCTION", 25, 0, 100);
+ gSkillTraitValues.ubMAAPsClimbOrJumpReduction = iniReader.ReadInteger("Martial Arts","APS_CLIMB_OR_JUMP_REDUCTION", 25, 0, 100);
+ gSkillTraitValues.ubMAChanceToCkickDoors = iniReader.ReadInteger("Martial Arts","CHANCE_KICK_DOORS_BONUS", 25, 0, 250);
+ gSkillTraitValues.fPermitExtraAnimationsOnlyToMA = iniReader.ReadBoolean("Martial Arts","PERMIT_EXTRA_ANIMATIONS_TO_EXPERT_MARTIAL_ARTS_ONLY", TRUE);
+
+ // SQUADLEADER
+ gSkillTraitValues.usSLRadiusNormal = iniReader.ReadInteger("Squadleader","BONUSES_RADIUS_NORMAL", 10, 2, 1000);
+ gSkillTraitValues.usSLRadiusExtendedEar = iniReader.ReadInteger("Squadleader","BONUSES_RADIUS_EXTENDED_EAR", 20, 2, 1000);
+ if( gSkillTraitValues.usSLRadiusExtendedEar < gSkillTraitValues.usSLRadiusNormal ) { gSkillTraitValues.usSLRadiusExtendedEar = gSkillTraitValues.usSLRadiusNormal; }
+ gSkillTraitValues.ubSLMaxBonuses = iniReader.ReadInteger("Squadleader","MAX_STACKABLE_BONUSES", 3, 1, 30);
+ gSkillTraitValues.ubSLBonusAPsPercent = iniReader.ReadInteger("Squadleader","BONUS_APS_PERCENT_IN_RADIUS", 5, 0, 100);
+ gSkillTraitValues.ubSLEffectiveLevelInRadius = iniReader.ReadInteger("Squadleader","EFFECTIVE_LEVEL_OF_OTHERS_IN_RADIUS", 1, 0, 10);
+ gSkillTraitValues.ubSLEffectiveLevelAsStandby = iniReader.ReadInteger("Squadleader","EFFECTIVE_LEVEL_AS_STANDBY", 1, 0, 10);
+ gSkillTraitValues.ubSLOverallSuppresionBonusPercent = iniReader.ReadInteger("Squadleader","OVERALL_SUPRESSION_BONUS_PERCENT", 20, 0, 100);
+ gSkillTraitValues.ubSLMoraleGainBonus = iniReader.ReadInteger("Squadleader","MORALE_GAIN_BONUS", 1, 0, 20);
+ gSkillTraitValues.ubSLMoraleLossReduction = iniReader.ReadInteger("Squadleader","MORALE_LOSS_REDUCTION", 1, 0, 20);
+ gSkillTraitValues.ubSLFearResistance = iniReader.ReadInteger("Squadleader","SL_FEAR_RESISTANCE", 50, 0, 100);
+ gSkillTraitValues.ubSLDeathMoralelossMultiplier = iniReader.ReadInteger("Squadleader","SL_DEATH_MORALE_LOSS_MULTIPLIER", 1, 0, 10);
+
+ // TECHNICIAN
+ gSkillTraitValues.usTERepairSpeedBonus = iniReader.ReadInteger("Technician","REPAIR_SPEED_BONUS_PERCENT", 25, 0, 1000);
+ gSkillTraitValues.usTELockpickingBonus = iniReader.ReadInteger("Technician","LOCKPICKING_BONUS", 30, 0, 1000);
+ gSkillTraitValues.usTEDisarmElTrapBonus = iniReader.ReadInteger("Technician","DISARMING_ELECTRONIC_TRAPS_BONUS", 40, 0, 1000);
+ gSkillTraitValues.usTEAttachingItemsBonus = iniReader.ReadInteger("Technician","COMBINING_ITEMS_BONUS", 40, 0, 1000);
+ gSkillTraitValues.ubTEUnjamGunBonus = iniReader.ReadInteger("Technician","UNJAMMING_GUN_BONUS", 20, 0, 250);
+ gSkillTraitValues.ubTERepairElectronicsPenaltyReduction = iniReader.ReadInteger("Technician","REPAIR_ELECTRONICS_PENALTY_REDUCTION", 50, 0, 100);
+ gSkillTraitValues.ubTEChanceToDetectTrapsBonus = iniReader.ReadInteger("Technician","EFFECTIVE_LEVEL_TO_FIND_TRAPS_BONUS", 2, 0, 10);
+ gSkillTraitValues.ubTECtHControlledRobotBonus = iniReader.ReadInteger("Technician","ROBOT_CTH_BONUS", 10, 0, 100);
+ gSkillTraitValues.ubTETraitsNumToRepairRobot = iniReader.ReadInteger("Technician","NUMBER_TRAITS_TO_BE_ABLE_TO_REPAIR_THE_ROBOT", 1, 0, 2);
+ gSkillTraitValues.ubTERepairRobotPenaltyReduction = iniReader.ReadInteger("Technician","REPAIR_SPEED_ROBOT_PENALTY_REDUCTION", 30, 0, 100);
+ if (gSkillTraitValues.ubTETraitsNumToRepairRobot == 2) {gSkillTraitValues.ubTERepairRobotPenaltyReduction /= 2; }
+
+ // DOCTOR
+ gSkillTraitValues.ubDONumberTraitsNeededForSurgery = iniReader.ReadInteger("Doctor","NUMBER_OF_TRAITS_NEEDED_FOR_SURGERY", 1, 0, 2);
+ gSkillTraitValues.ubDOSurgeryHealPercentBase = iniReader.ReadInteger("Doctor","BASE_PERCENT_SURGERY_HEAL", 10, 0, 100);
+ gSkillTraitValues.ubDOSurgeryHealPercentOnTop = iniReader.ReadInteger("Doctor","ONTOP_PERCENT_SURGERY_HEAL_PER_TRAIT", 20, 0, 100);
+ gSkillTraitValues.usDOSurgeryMedBagConsumption = iniReader.ReadInteger("Doctor","MEDICAL_BAG_CONSUMPTION_BY_SURGERY", 100, 0, 1000);
+ gSkillTraitValues.usDOSurgeryMaxBreathLoss = iniReader.ReadInteger("Doctor","MAX_ENERGY_LOSS_FOR_LIFE_HEALED", 100, 0, 500);
+ gSkillTraitValues.usDORepairStatsRateBasic = iniReader.ReadInteger("Doctor","REPAIR_STATS_RATE_BASIC", 20, 0, 1000);
+ gSkillTraitValues.usDORepairStatsRateOnTop = iniReader.ReadInteger("Doctor","REPAIR_STATS_RATE_ONTOP", 40, 0, 1000);
+ gSkillTraitValues.ubDORepStPenaltyIfAlsoHealing = iniReader.ReadInteger("Doctor","REPAIR_STATS_RATE_REDUCTION_IF_ALSO_HEALING", 50, 0, 100);
+ gSkillTraitValues.ubDOHealingPenaltyIfAlsoStatRepair = iniReader.ReadInteger("Doctor","HEALING_RATE_REDUCTION_IF_ALSO_REPAIRING_STATS", 50, 0, 100);
+ gSkillTraitValues.fDORepStShouldThrowMessage = iniReader.ReadBoolean("Doctor","SHOW_MESSAGE_ABOUT_STATS_REGAINED", TRUE );
+ gSkillTraitValues.usDODoctorAssignmentBonus = iniReader.ReadInteger("Doctor","DOCTOR_ASSIGNMENT_BONUS_PERCENT", 25, 0, 500);
+ gSkillTraitValues.ubDOBandagingSpeedPercent = iniReader.ReadInteger("Doctor","BANDAGING_SPEED_PERCENT", 30, 0, 250);
+ gSkillTraitValues.ubDONaturalRegenBonus = iniReader.ReadInteger("Doctor","NATURAL_REGENERATION_IN_SECTOR_BONUS", 10, 0, 250);
+ gSkillTraitValues.ubDOMaxRegenBonuses = iniReader.ReadInteger("Doctor","MAX_NATURAL_REGEN_BONUSES", 4, 1, 50);
+
+ // AMBIDEXTROUS
+ gSkillTraitValues.ubAMPenaltyDoubleReduction = iniReader.ReadInteger("Ambidextrous","PENALTY_TO_SHOOT_DOUBLE_GUNS_REDUCTION", 100, 0, 100);
+ gSkillTraitValues.ubAMReloadSpeedMagazines = iniReader.ReadInteger("Ambidextrous","RELOAD_SPEED_WITH_MAGAZINE_BONUS", 20, 0, 90);
+ gSkillTraitValues.ubAMReloadSpeedLoose = iniReader.ReadInteger("Ambidextrous","RELOAD_SPEED_WITH_LOOSE_ROUNDS_BONUS", 33, 0, 90);
+ gSkillTraitValues.ubAMPickItemsAPsReduction = iniReader.ReadInteger("Ambidextrous","PICK_ITEM_AP_REDUCTION", 33, 0, 90);
+ gSkillTraitValues.ubAMWorkBackpackAPsReduction = iniReader.ReadInteger("Ambidextrous","WORK_BACKPACK_AP_REDUCTION", 33, 0, 90);
+ gSkillTraitValues.ubAMHandleDoorsAPsReduction = iniReader.ReadInteger("Ambidextrous","HANDLE_DOORS_AP_REDUCTION", 33, 0, 90);
+ gSkillTraitValues.ubAMHandleBombsAPsReduction = iniReader.ReadInteger("Ambidextrous","HANDLE_BOMBS_AP_REDUCTION", 33, 0, 90);
+ gSkillTraitValues.ubAMAttachingItemsAPsReduction = iniReader.ReadInteger("Ambidextrous","ATTACH_ITEMS_AP_REDUCTION", 33, 0, 90);
+
+ // MELEE
+ gSkillTraitValues.ubMEBladesAPsReduction = iniReader.ReadInteger("Melee","BLADE_ATTACK_APS_REDUCTION", 20, 0, 100);
+ gSkillTraitValues.ubMECtHBladesBonus = iniReader.ReadInteger("Melee","CTH_BLADES_BONUS", 40, 0, 100);
+ gSkillTraitValues.ubMECtHBluntBonus = iniReader.ReadInteger("Melee","CTH_BLUNT_WEAPONS_BONUS", 30, 0, 200);
+ gSkillTraitValues.ubMEDamageBonusBlades = iniReader.ReadInteger("Melee","DAMAGE_BONUS_BLADES", 30, 0, 250);
+ gSkillTraitValues.ubMEDamageBonusBlunt = iniReader.ReadInteger("Melee","DAMAGE_BONUS_BLUNT_WEAPONS", 30, 0, 250);
+ gSkillTraitValues.usMEAimedMeleeAttackDamageBonus = iniReader.ReadInteger("Melee","AIMED_MELEE_ATTACK_DAMAGE_BONUS", 50, 0, 1000);
+ gSkillTraitValues.ubMEDodgeBladesBonus = iniReader.ReadInteger("Melee","BONUS_CHANCE_TO_DODGE_BLADES", 30, 0, 200);
+ gSkillTraitValues.ubMECtDBladesOnTopWithBladeInHands = iniReader.ReadInteger("Melee","ONTOP_CHANCE_TO_DODGE_BLADES_WITH_BLADE", 20, 0, 200);
+ gSkillTraitValues.ubMEDodgeBluntBonus = iniReader.ReadInteger("Melee","BONUS_CHANCE_TO_DODGE_BLUNT_WEAPONS", 20, 0, 200);
+ gSkillTraitValues.ubMECtDBluntOnTopWithBladeInHands = iniReader.ReadInteger("Melee","ONTOP_CHANCE_TO_DODGE_BLUNT_WITH_BLADE", 10, 0, 200);
+
+ // THROWING
+ gSkillTraitValues.ubTHBladesAPsReduction = iniReader.ReadInteger("Throwing","THROW_BLADE_APS_REDUCTION", 20, 0, 90);
+ gSkillTraitValues.ubTHBladesMaxRange = iniReader.ReadInteger("Throwing","TH_BLADES_RANGE_BONUS", 15, 0, 200);
+ gSkillTraitValues.ubTHBladesCtHBonus = iniReader.ReadInteger("Throwing","TH_BLADES_CTH_BONUS", 25, 0, 100);
+ gSkillTraitValues.ubTHBladesCtHBonusPerClick = iniReader.ReadInteger("Throwing","TH_BLADES_CTH_BONUS_PER_AIM_CLICK", 5, 0, 100);
+ gSkillTraitValues.ubTHBladesDamageBonus = iniReader.ReadInteger("Throwing","TH_BLADES_DAMAGE_BONUS", 20, 0, 250);
+ gSkillTraitValues.ubTHBladesDamageBonusPerClick = iniReader.ReadInteger("Throwing","TH_BLADES_DAMAGE_BONUS_PER_AIM_CLICK", 10, 0, 100);
+ gSkillTraitValues.ubTHBladesSilentCriticalHitChance = iniReader.ReadInteger("Throwing","TH_BLADES_SILENT_CRITICAL_HIT_CHANCE", 20, 0, 100);
+ gSkillTraitValues.ubTHBladesCriticalHitMultiplierBonus = iniReader.ReadInteger("Throwing","SILENT_CRITICAL_HIT_MULTIPLIER_BONUS", 1, 0, 50);
+ gSkillTraitValues.ubTHBladesAimClicksAdded = iniReader.ReadInteger("Throwing","POSSIBLE_AIM_CLICK_ADDED_TH_KNIVES", 1, 0, 5);
+
+ // NIGHT OPS
+ gSkillTraitValues.ubNOeSightRangeBonusInDark = iniReader.ReadInteger("Night Ops","SIGHT_RANGE_BONUS_IN_DARK", 1, 0, 100);
+ gSkillTraitValues.ubNOHearingRangeBonus = iniReader.ReadInteger("Night Ops","BASIC_HEARING_RANGE_BONUS", 1, 0, 100);
+ gSkillTraitValues.ubNOHearingRangeBonusInDark = iniReader.ReadInteger("Night Ops","ONTOP_HEARING_RANGE_BONUS_IN_DARK", 2, 0, 100);
+ gSkillTraitValues.ubNOIterruptsBonusInDark = iniReader.ReadInteger("Night Ops","INTERRUPTS_BONUS_IN_DARK", 2, 0, 10);
+ gSkillTraitValues.ubNONeedForSleepReduction = iniReader.ReadInteger("Night Ops","NEED_FOR_SLEEP_REDUCTION", 3, 0, 10);
+
+ // STEALTHY
+ gSkillTraitValues.ubSTStealthModeSpeedBonus = iniReader.ReadInteger("Stealthy","STEALTH_MODE_SPEED_BONUS", 50, 0, 100);
+ gSkillTraitValues.ubSTBonusToMoveQuietly = iniReader.ReadInteger("Stealthy","BONUS_TO_MOVE_STEALTHILY", 40, 0, 250);
+ gSkillTraitValues.ubSTStealthBonus = iniReader.ReadInteger("Stealthy","STEALTH_BONUS", 25, 0, 200);
+ gSkillTraitValues.ubSTStealthPenaltyForMovingReduction = iniReader.ReadInteger("Stealthy","CHANCE_TO_BE_SPOTTED_FOR_MOVING_REDUCTION", 25, 0, 100);
+
+ // ATHLETICS
+ gSkillTraitValues.ubATAPsMovementReduction = iniReader.ReadInteger("Athletics","APS_NEED_FOR_MOVEMENT_REDUCTION", 33, 0, 90);
+ gSkillTraitValues.ubATBPsMovementReduction = iniReader.ReadInteger("Athletics","BPS_SPENT_FOR_MOVEMENT_REDUCTION", 33, 0, 90);
+
+ // BODYBUILDING
+ gSkillTraitValues.ubBBDamageResistance = iniReader.ReadInteger("Bodybuilding","DAMAGE_RESISTANCE", 20, 0, 90);
+ gSkillTraitValues.ubBBCarryWeightBonus = iniReader.ReadInteger("Bodybuilding","CARRY_WEIGHT_BONUS", 30, 0, 250);
+ gSkillTraitValues.ubBBBreathLossForHtHImpactReduction = iniReader.ReadInteger("Bodybuilding","BREATH_LOSS_FOR_HTH_HIT_REDUCTION", 50, 0, 100);
+ gSkillTraitValues.usBBIncreasedNeededDamageToFallDown = iniReader.ReadInteger("Bodybuilding","INCREASE_DAMAGE_NEEDED_TO_FALL_DOWN_IF_HIT_TO_LEGS", 100, 0, 500);
+
+ // DEMOLITIONS
+ gSkillTraitValues.ubDEAPsNeededToThrowGrenadesReduction = iniReader.ReadInteger("Demolitions","APS_NEEDED_TO_THROW_GRENADES_REDUCTION", 25, 0, 90);
+ gSkillTraitValues.ubDEMaxRangeToThrowGrenades = iniReader.ReadInteger("Demolitions","MAX_RANGE_TO_THROW_GRENADES", 20, 0, 250);
+ gSkillTraitValues.ubDECtHWhenThrowingGrenades = iniReader.ReadInteger("Demolitions","CTH_WHEN_THROWING_GRENADES", 30, 0, 100);
+ gSkillTraitValues.ubDEDamageOfBombsAndMines = iniReader.ReadInteger("Demolitions","DAMAGE_OF_PLACED_BOMBS_AND_MINES", 25, 0, 250);
+ gSkillTraitValues.ubDEAttachDetonatorCheckBonus = iniReader.ReadInteger("Demolitions","ATTACH_DETONATOR_CHECK_BONUS", 50, 0, 250);
+ gSkillTraitValues.ubDEPlantAndRemoveBombCheckBonus = iniReader.ReadInteger("Demolitions","PLANT_AND_REMOVE_BOMBS_AND_MINES_BONUS", 50, 0, 250);
+ gSkillTraitValues.ubDEPlacedBombLevelBonus = iniReader.ReadInteger("Demolitions","PLACED_BOMBS_AND_MINES_DETECTION_DIFFICULTY_BONUS", 5, 0, 15);
+ gSkillTraitValues.ubDEShapedChargeDamageMultiplier = iniReader.ReadInteger("Demolitions","SHAPED_CHARGE_DAMAGE_MULTIPLIER", 3, 1, 50);
+
+ // TEACHING
+ gSkillTraitValues.ubTGBonusToTrainMilitia = iniReader.ReadInteger("Teaching","BONUS_TO_TRAIN_MILITIA", 40, 0, 250);
+ gSkillTraitValues.ubTGEffectiveLDRToTrainMilitia = iniReader.ReadInteger("Teaching","EFFECTIVE_LEADERSHIP_FOR_MILITIA_TRAINING", 40, 0, 250);
+ gSkillTraitValues.ubTGBonusToTeachOtherMercs = iniReader.ReadInteger("Teaching","BONUS_TO_TEACH_OTHER_MERCS", 40, 0, 250);
+ gSkillTraitValues.ubTGEffectiveSkillValueForTeaching = iniReader.ReadInteger("Teaching","EFFECTIVE_SKILL_VALUE_TO_TEACH_OTHERS_BONUS", 25, 0, 100);
+ gSkillTraitValues.ubTGBonusOnPractising = iniReader.ReadInteger("Teaching","BONUS_ON_PRACTISING", 25, 0, 250);
+
+ // SCOUTING
+ gSkillTraitValues.ubSCSightRangebonusWithScopes = iniReader.ReadInteger("Scouting","SIGHT_RANGE_INCREASED_WITH_SCOPES", 10, 0, 250);
+ gSkillTraitValues.usSCSightRangebonusWithBinoculars = iniReader.ReadInteger("Scouting","SIGHT_RANGE_INCREASED_WITH_BINOCULARS", 40, 0, 1000);
+ gSkillTraitValues.ubSCTunnelVisionReducedWithBinoculars = iniReader.ReadInteger("Scouting","TUNNEL_VISION_REDUCED_WITH_BINOCULARS", 20, 0, 250);
+ gSkillTraitValues.fSCCanDetectEnemyPresenseAround = iniReader.ReadBoolean("Scouting","CAN_DETECT_ENEMY_PRESENSE_IN_SECTORS_AROUND", TRUE);
+ gSkillTraitValues.fSCCanDetermineEnemyNumbersAround = iniReader.ReadBoolean("Scouting","CAN_DETERMINE_ENEMY_NUMBERS_IN_SECTORS_AROUND", TRUE);
+ gSkillTraitValues.fSCDetectionInDiagonalSectors = iniReader.ReadBoolean("Scouting","ALLOW_DETECTION_IN_DIAGONAL_SECTORS", TRUE);
+ gSkillTraitValues.fSCPreventsTheEnemyToAmbushMercs = iniReader.ReadBoolean("Scouting","PREVENTS_ENEMY_AMBUSHES", TRUE);
+ gSkillTraitValues.fSCPreventsBloodcatsAmbushes = iniReader.ReadBoolean("Scouting","PREVENTS_BLOODCATS_AMBUSHES", TRUE);
+ gSkillTraitValues.fSCThrowMessageIfAmbushPrevented = iniReader.ReadBoolean("Scouting","SHOW_MESSAGE_IF_AMBUSH_PREVENTED", TRUE);
+
+}
+
+
INT16 DynamicAdjustAPConstants(INT16 iniReadValue, INT16 iniDefaultValue, BOOLEAN reverse)
{
//CHRISL: This function will dynamically adjust all the APBPConstant values based on the AP_MAXIMUM value. This way
@@ -1404,10 +1905,10 @@ void LoadGameAPBPConstants()
//CHRISL: To allow for dynamic settings, we need to switch AP_MAXIMUM and AP_MINIMUM so that only the max value needs
// to be changed to effect the entire system. This will require a change in the ENUM so that we can use a loop to
// modify the remaining values.
- APBPConstants[AP_MAXIMUM] = iniReader.ReadInteger("APConstants","AP_MAXIMUM",100);
+ APBPConstants[AP_MAXIMUM] = iniReader.ReadInteger("APConstants","AP_MAXIMUM",100, 25, 250);
//CHRISL: Once we've loaded the AP_MAXIMUM value, we can use it to modifiy all the remaining values
- APBPConstants[AP_MINIMUM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_MINIMUM",40),40);
+ APBPConstants[AP_MINIMUM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_MINIMUM",40, 10, 100),40);
APBPConstants[AP_MONSTER_MAXIMUM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_MONSTER_MAXIMUM",160),160);
APBPConstants[AP_VEHICLE_MAXIMUM] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_VEHICLE_MAXIMUM",200),200);
APBPConstants[MAX_AP_CARRIED] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","MAX_AP_CARRIED",20),20);
@@ -1545,12 +2046,12 @@ void LoadGameAPBPConstants()
APBPConstants[BP_GET_WOUNDED] = iniReader.ReadInteger("BPConstants","BP_GET_WOUNDED",50);
APBPConstants[BP_FALL_DOWN] = iniReader.ReadInteger("BPConstants","BP_FALL_DOWN",250);
APBPConstants[BP_OPEN_DOOR] = iniReader.ReadInteger("BPConstants","BP_OPEN_DOOR",30);
- APBPConstants[BP_PICKLOCK] = iniReader.ReadInteger("BPConstants","BP_PICKLOCK",-250);
- APBPConstants[BP_EXAMINE_DOOR] = iniReader.ReadInteger("BPConstants","BP_EXAMINE_DOOR",-250);
+ APBPConstants[BP_PICKLOCK] = iniReader.ReadInteger("BPConstants","BP_PICKLOCK",50);
+ APBPConstants[BP_EXAMINE_DOOR] = iniReader.ReadInteger("BPConstants","BP_EXAMINE_DOOR",20);
APBPConstants[BP_BOOT_DOOR] = iniReader.ReadInteger("BPConstants","BP_BOOT_DOOR",200);
APBPConstants[BP_USE_CROWBAR] = iniReader.ReadInteger("BPConstants","BP_USE_CROWBAR",350);
APBPConstants[BP_UNLOCK_DOOR] = iniReader.ReadInteger("BPConstants","BP_UNLOCK_DOOR",50);
- APBPConstants[BP_EXPLODE_DOOR] = iniReader.ReadInteger("BPConstants","BP_EXPLODE_DOOR",-250);
+ APBPConstants[BP_EXPLODE_DOOR] = iniReader.ReadInteger("BPConstants","BP_EXPLODE_DOOR",40);
APBPConstants[BP_UNTRAP_DOOR] = iniReader.ReadInteger("BPConstants","BP_UNTRAP_DOOR",150);
APBPConstants[BP_LOCK_DOOR] = iniReader.ReadInteger("BPConstants","BP_LOCK_DOOR",50);
APBPConstants[BP_USEWIRECUTTERS] = iniReader.ReadInteger("BPConstants","BP_USEWIRECUTTERS",200);
@@ -1561,11 +2062,144 @@ void LoadGameAPBPConstants()
APBPConstants[BP_BACK_PACK] = iniReader.ReadInteger("APConstants","BP_JUMP_OVER",50);
APBPConstants[BP_WORK_ZIPPER] = iniReader.ReadInteger("APConstants","BP_WORK_ZIPPER",250);
APBPConstants[BP_UNJAM] = iniReader.ReadInteger("APConstants","BP_WORK_ZIPPER",0);
+
+ APBPConstants[AP_JUMPWINDOW] = DynamicAdjustAPConstants(iniReader.ReadInteger("APConstants","AP_JUMPWINDOW",40),40);
SetupMaxActionPointsAnimation();
#undef ReadInteger
}
+// HEADROCK HAM 4: Read the various coefficients for the new CTH and Shooting systems from an INI file.
+void LoadCTHConstants()
+{
+
+ //Kaiden: Setting Ja2_Options.ini file to be read
+ CIniReader iniReader(CTH_COEFFICIENTS_FILE);
+
+ gGameCTHConstants.NORMAL_SHOOTING_DISTANCE = iniReader.ReadInteger("General","NORMAL_SHOOTING_DISTANCE",100, 1, 10000);
+ gGameCTHConstants.DEGREES_MAXIMUM_APERTURE = iniReader.ReadFloat("General", "DEGREES_MAXIMUM_APERTURE", 15.0, 0.0, 22.5);
+ gGameCTHConstants.GRAVITY_COEFFICIENT = iniReader.ReadFloat("General", "GRAVITY_COEFFICIENT", 2.0, 0.001f, 100.0);
+ gGameCTHConstants.VERTICAL_BIAS = iniReader.ReadFloat("General", "VERTICAL_BIAS", 1.0f, 0.01f, 2.0f);
+ gGameCTHConstants.SCOPE_RANGE_MULTIPLIER = iniReader.ReadFloat("General", "SCOPE_RANGE_MULTIPLIER", 0.7f, 0.5f, 1.5f);
+
+ ////////////////////////////////////////////////////////////
+ // Coefficients for factors affecting Base CTH
+ ////////////////////////////////////////////////////////////
+
+ gGameCTHConstants.BASE_EXP = iniReader.ReadFloat("Base CTH","BASE_EXP",3.0, 0.0, 100.0);
+ gGameCTHConstants.BASE_MARKS = iniReader.ReadFloat("Base CTH","BASE_MARKS",1.0, 0.0, 100.0);
+ gGameCTHConstants.BASE_WIS = iniReader.ReadFloat("Base CTH","BASE_WIS",1.0, 0.0, 100.0);
+ gGameCTHConstants.BASE_DEX = iniReader.ReadFloat("Base CTH","BASE_DEX",1.0, 0.0, 100.0);
+
+ gGameCTHConstants.BASE_LOW_MORALE = iniReader.ReadFloat("Base CTH","BASE_LOW_MORALE",-1.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_HIGH_MORALE = iniReader.ReadFloat("Base CTH","BASE_HIGH_MORALE",2.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_PSYCHO = iniReader.ReadFloat("Base CTH","BASE_PSYCHO",-3.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_SHOOTING_UPWARDS = iniReader.ReadFloat("Base CTH","BASE_SHOOTING_UPWARDS",-15.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_INJURY = iniReader.ReadFloat("Base CTH","BASE_INJURY",-30.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DRUNK[0] = iniReader.ReadFloat("Base CTH","BASE_DRUNK_TIPSY",-5.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DRUNK[1] = iniReader.ReadFloat("Base CTH","BASE_DRUNK",-20.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DRUNK[2] = iniReader.ReadFloat("Base CTH","BASE_DRUNK_WASTED",-50.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DRUNK[3] = iniReader.ReadFloat("Base CTH","BASE_DRUNK_HUNGOVER",-10.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_FATIGUE = iniReader.ReadFloat("Base CTH","BASE_FATIGUE",-15.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_SAME_TARGET = iniReader.ReadFloat("Base CTH","BASE_SAME_TARGET",5.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_GASSED = iniReader.ReadFloat("Base CTH","BASE_GASSED",-15.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_BEING_BANDAGED = iniReader.ReadFloat("Base CTH","BASE_BEING_BANDAGED",-5.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_SHOCK = iniReader.ReadFloat("Base CTH","BASE_SHOCK",-150.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_AGILE_TARGET = iniReader.ReadFloat("Base CTH","BASE_AGILE_TARGET",-5.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_TARGET_INVISIBLE = iniReader.ReadFloat("Base CTH","BASE_TARGET_INVISIBLE",-100.0, -1000.0, 1000.0);
+
+ gGameCTHConstants.BASE_DRAW_COST = iniReader.ReadFloat("Base CTH","BASE_DRAW_COST",-2.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_TWO_GUNS = iniReader.ReadFloat("Base CTH","BASE_TWO_GUNS",3.5, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_ONE_HANDED = iniReader.ReadFloat("Base CTH","BASE_ONE_HANDED",2.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_CROUCHING_STANCE = iniReader.ReadFloat("Base CTH","BASE_CROUCHING_STANCE",2.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_PRONE_STANCE = iniReader.ReadFloat("Base CTH","BASE_PRONE_STANCE",3.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_HEAVY_WEAPON = iniReader.ReadFloat("Base CTH","BASE_HEAVY_WEAPON",2.0, -1000.0, 1000.0);
+
+ gGameCTHConstants.BASE_DIFFICULTY[0] = -100.0;
+ gGameCTHConstants.BASE_DIFFICULTY[1] = iniReader.ReadFloat("Base CTH","BASE_DIFFICULTY_NOVICE",-30.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DIFFICULTY[2] = iniReader.ReadFloat("Base CTH","BASE_DIFFICULTY_EXPERIENCED",0.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DIFFICULTY[3] = iniReader.ReadFloat("Base CTH","BASE_DIFFICULTY_EXPERT",20.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DIFFICULTY[4] = iniReader.ReadFloat("Base CTH","BASE_DIFFICULTY_INSANE",50.0, -1000.0, 1000.0);
+ gGameCTHConstants.BASE_DIFFICULTY[5] = 100.0;
+
+ ////////////////////////////////////////////////////////////
+ // Coefficients for factors affecting Aiming CTH
+ ////////////////////////////////////////////////////////////
+
+ gGameCTHConstants.AIM_EXP = iniReader.ReadFloat("Aiming CTH","AIM_EXP",1.0, 0.0, 100.0);
+ gGameCTHConstants.AIM_MARKS = iniReader.ReadFloat("Aiming CTH","AIM_MARKS",3.0, 0.0, 100.0);
+ gGameCTHConstants.AIM_WIS = iniReader.ReadFloat("Aiming CTH","AIM_WIS",1.0, 0.0, 100.0);
+ gGameCTHConstants.AIM_DEX = iniReader.ReadFloat("Aiming CTH","AIM_DEX",2.0, 0.0, 100.0);
+
+ gGameCTHConstants.AIM_TOO_CLOSE_SCOPE = iniReader.ReadFloat("Aiming CTH","AIM_TOO_CLOSE_SCOPE",-4.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_GUN_CONDITION = iniReader.ReadFloat("Aiming CTH","AIM_GUN_CONDITION",-2.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_LOW_MORALE = iniReader.ReadFloat("Aiming CTH","AIM_LOW_MORALE",-2.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_HIGH_MORALE = iniReader.ReadFloat("Aiming CTH","AIM_HIGH_MORALE",1.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_PSYCHO = iniReader.ReadFloat("Aiming CTH","AIM_PSYCHO",-5.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_VISIBILITY = iniReader.ReadFloat("Aiming CTH","AIM_VISIBILITY",-1.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_SHOOTING_UPWARDS = iniReader.ReadFloat("Aiming CTH","AIM_SHOOTING_UPWARDS",-20.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_INJURY = iniReader.ReadFloat("Aiming CTH","AIM_INJURY",-60.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DRUNK[0] = iniReader.ReadFloat("Aiming CTH","AIM_DRUNK_TIPSY",-10.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DRUNK[1] = iniReader.ReadFloat("Aiming CTH","AIM_DRUNK",-40.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DRUNK[2] = iniReader.ReadFloat("Aiming CTH","AIM_DRUNK_WASTED",-90.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DRUNK[3] = iniReader.ReadFloat("Aiming CTH","AIM_DRUNK_HUNGOVER",-15.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_FATIGUE = iniReader.ReadFloat("Aiming CTH","AIM_FATIGUE",-40.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_GASSED = iniReader.ReadFloat("Aiming CTH","AIM_GASSED",-80.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_BEING_BANDAGED = iniReader.ReadFloat("Aiming CTH","AIM_BEING_BANDAGED",-20.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_SHOCK = iniReader.ReadFloat("Aiming CTH","AIM_SHOCK",-150.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_TARGET_INVISIBLE = iniReader.ReadFloat("Aiming CTH","AIM_TARGET_INVISIBLE",-50.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_SNIPER_SKILL = iniReader.ReadFloat("Aiming CTH","AIM_SNIPER_SKILL",25.0, -100.0, 100.0);
+
+ gGameCTHConstants.AIM_DRAW_COST = iniReader.ReadFloat("Aiming CTH","AIM_DRAW_COST",-2.5, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_STANDING_STANCE = iniReader.ReadFloat("Aiming CTH","AIM_STANDING_STANCE",2.5, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_CROUCHING_STANCE = iniReader.ReadFloat("Aiming CTH","AIM_CROUCHING_STANCE",1.5, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_PRONE_STANCE = iniReader.ReadFloat("Aiming CTH","AIM_PRONE_STANCE",1.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_TWO_GUNS = iniReader.ReadFloat("Aiming CTH","AIM_TWO_GUNS",4.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_ONE_HANDED = iniReader.ReadFloat("Aiming CTH","AIM_ONE_HANDED",2.5, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_HEAVY_WEAPON = iniReader.ReadFloat("Aiming CTH","AIM_HEAVY_WEAPON",2.0, -1000.0, 1000.0);
+
+ gGameCTHConstants.AIM_DIFFICULTY[0] = -100.0;
+ gGameCTHConstants.AIM_DIFFICULTY[1] = iniReader.ReadFloat("Aiming CTH","AIM_DIFFICULTY_NOVICE",-30.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DIFFICULTY[2] = iniReader.ReadFloat("Aiming CTH","AIM_DIFFICULTY_EXPERIENCED",0.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DIFFICULTY[3] = iniReader.ReadFloat("Aiming CTH","AIM_DIFFICULTY_EXPERT",20.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DIFFICULTY[4] = iniReader.ReadFloat("Aiming CTH","AIM_DIFFICULTY_INSANE",50.0, -1000.0, 1000.0);
+ gGameCTHConstants.AIM_DIFFICULTY[5] = 100.0;
+
+ ////////////////////////////////////////////////////////////
+ // Coefficients for factors affecting the Shooting Mechanism
+ ////////////////////////////////////////////////////////////
+
+ gGameCTHConstants.MOVEMENT_MRK = iniReader.ReadFloat("Shooting Mechanism","MOVEMENT_MRK",3.0, 0.0, 100.0);
+ gGameCTHConstants.MOVEMENT_WIS = iniReader.ReadFloat("Shooting Mechanism","MOVEMENT_WIS",2.0, 0.0, 100.0);
+ gGameCTHConstants.MOVEMENT_DEX = iniReader.ReadFloat("Shooting Mechanism","MOVEMENT_DEX",1.0, 0.0, 100.0);
+ gGameCTHConstants.MOVEMENT_EXP_LEVEL = iniReader.ReadFloat("Shooting Mechanism","MOVEMENT_EXP_LEVEL",2.0, 0.0, 100.0);
+ gGameCTHConstants.MOVEMENT_TRACKING_DIFFICULTY = iniReader.ReadInteger("Shooting Mechanism","MOVEMENT_TRACKING_DIFFICULTY",20, 0, 1000);
+ gGameCTHConstants.MOVEMENT_PENALTY_PER_TILE = iniReader.ReadFloat("Shooting Mechanism","MOVEMENT_PENALTY_PER_TILE",1.0, 0.0, 10.0);
+
+ gGameCTHConstants.PRE_RECOIL_WIS = iniReader.ReadFloat("Shooting Mechanism","PRE_RECOIL_WIS",2.0, 0.0, 100.0);
+ gGameCTHConstants.PRE_RECOIL_EXP_LEVEL = iniReader.ReadFloat("Shooting Mechanism","PRE_RECOIL_EXP_LEVEL",3.0, 0.0, 100.0);
+ gGameCTHConstants.PRE_RECOIL_AUTO_WEAPONS_SKILL = iniReader.ReadFloat("Shooting Mechanism","PRE_RECOIL_AUTO_WEAPONS_SKILL",2.0, 1.0, 100.0);
+
+ gGameCTHConstants.RECOIL_MAX_COUNTER_STR = iniReader.ReadFloat("Shooting Mechanism","RECOIL_MAX_COUNTER_STR",3.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_MAX_COUNTER_AGI = iniReader.ReadFloat("Shooting Mechanism","RECOIL_MAX_COUNTER_AGI",1.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_MAX_COUNTER_EXP_LEVEL = iniReader.ReadFloat("Shooting Mechanism","RECOIL_MAX_COUNTER_EXP_LEVEL",1.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_MAX_COUNTER_FORCE = iniReader.ReadFloat("Shooting Mechanism","RECOIL_MAX_COUNTER_FORCE",5.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_MIN_ERROR = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_MIN",1.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_DEX = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_DEX",3.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_WIS = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_WIS",1.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_AGI = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_AGI",1.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_EXP_LEVEL = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_EXP_LEVEL",2.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_AUTO_WEAPONS_DIVISOR = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_AUTO_WEAPONS_DIVISOR",2.0, 1.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_ACCURACY_TRACER_BONUS = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_ACCURACY_TRACER_BONUS",10.0, -1000.0, 1000.0);
+ gGameCTHConstants.RECOIL_COUNTER_FREQUENCY_AGI = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_FREQUENCY_AGI",3.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_FREQUENCY_EXP_LEVEL = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_FREQUENCY_EXP_LEVEL",2.0, 0.0, 100.0);
+ gGameCTHConstants.RECOIL_COUNTER_FREQUENCY_AUTO_WEAPONS_DIVISOR = iniReader.ReadFloat("Shooting Mechanism","RECOIL_COUNTER_FREQUENCY_AUTO_WEAPONS_DIVISOR",2.0, -1000.0, 1000.0);
+
+ gGameCTHConstants.MAX_BULLET_DEV = iniReader.ReadFloat("Shooting Mechanism","MAX_BULLET_DEV ",10.0, -1000.0, 1000.0);
+
+
+}
+
void FreeGameExternalOptions()
{
if (gGameExternalOptions.iaIMPSlots != NULL) // OJW - 20081129 - Fix memory leak when calling LoadGameExternalOptions twice
diff --git a/GameSettings.h b/GameSettings.h
index 30a4bdb2..be92359b 100644
--- a/GameSettings.h
+++ b/GameSettings.h
@@ -38,9 +38,9 @@ enum
//Madd:
TOPTION_GL_BURST_CURSOR,
- TOPTION_DROP_ALL,
+ TOPTION_ALLOW_TAUNTS, // changed from drop all - SANDRO
TOPTION_GL_HIGH_ANGLE,
- TOPTION_AIM_LEVEL_RESTRICTION,
+ TOPTION_ALLOW_REAL_TIME_SNEAK, // changed from aim levels restriction - SANDRO
//lalien
TOPTION_SPACE_SELECTS_NEXT_SQUAD,
@@ -49,7 +49,7 @@ enum
TOPTION_TRACERS_FOR_SINGLE_FIRE,
TOPTION_RAIN_SOUND,
TOPTION_ALLOW_CROWS,
- TOPTION_ALLOW_SOLDIER_TOOLTIPS, // Changed from TOPTION_USE_RANDOM_PERSONALITY - SANDRO
+ TOPTION_ALLOW_SOLDIER_TOOLTIPS,
TOPTION_USE_AUTO_SAVE,
TOPTION_SILENT_SKYRIDER,
TOPTION_LOW_CPU_USAGE,
@@ -61,6 +61,15 @@ enum
// HEADROCK HAM 3.6:
TOPTION_STAT_PROGRESS_BARS,
+ // HEADROCK HAM 4:
+ TOPTION_REPORT_MISS_MARGIN,
+
+ // HEADROCK HAM 4:
+ TOPTION_ALT_MAP_COLOR,
+
+ // WANNE: Moved alternate bullets graphics (tracers) to options
+ TOPTION_ALTERNATE_BULLET_GRAPHICS,
+
// arynn: Debug/Cheat
TOPTION_CHEAT_MODE_OPTIONS_HEADER,
TOPTION_FORCE_BOBBY_RAY_SHIPMENTS, // force all pending Bobby Ray shipments
@@ -113,7 +122,13 @@ typedef struct
enum
{
INVENTORY_OLD = 0,
- INVENTORY_NEW = 1
+ INVENTORY_NEW = 1,
+};
+
+enum
+{
+ ATTACHMENT_OLD = 0,
+ ATTACHMENT_NEW = 1,
};
@@ -144,6 +159,16 @@ enum
BR_AWESOME = 10,
};
+// Added by SANDRO
+enum
+{
+ ITEM_PROGRESS_VERY_SLOW = 0,
+ ITEM_PROGRESS_SLOW,
+ ITEM_PROGRESS_NORMAL,
+ ITEM_PROGRESS_FAST,
+ ITEM_PROGRESS_VERY_FAST,
+};
+
typedef struct
{
BOOLEAN fGunNut;
@@ -154,11 +179,21 @@ typedef struct
BOOLEAN fIronManMode;
UINT8 ubBobbyRay;
UINT8 ubInventorySystem;
- UINT8 ubFiller[6];
+ UINT8 ubAttachmentSystem;
+ // SANDRO - added variables
+ UINT8 ubMaxIMPCharacters;
+ BOOLEAN fNewTraitSystem;
+ BOOLEAN fEnableAllTerrorists;
+ BOOLEAN fEnemiesDropAllItems;
+ UINT8 ubProgressSpeedOfItemsChoices;
+ BOOLEAN fEnableAllWeaponCaches;
+ //UINT8 ubFiller[];
} GAME_OPTIONS;
bool UsingNewInventorySystem();
+bool UsingNewAttachmentSystem();
+bool UsingNewCTHSystem();
BOOLEAN IsNIVModeValid(bool checkRes = true);
// Snap: Options read from an INI file in the default of custom Data directory
@@ -178,19 +213,20 @@ typedef struct
// WDS: Allow flexible numbers of IMPs of each sex
INT32 iIMPMaleCharacterCount; // Count of how many there are
INT32 iIMPFemaleCharacterCount;
- INT32 iMaxIMPCharacters; // Limit of how many to allow
+ //INT32 iMaxIMPCharacters; // Limit of how many to allow
//
// iaIMPSlots is an array of the slots (in prof.dat) to use for IMPs.
//
INT32 *iaIMPSlots;
+ // SANDRO was here - some changes done
+ INT32 iIMPProfileCost;
+ BOOLEAN fDynamicIMPProfileCost;
INT32 iMinAttribute;
INT32 iMaxAttribute;
INT32 iImpAttributePoints;
INT32 iMaxZeroBonus;
- INT32 iStartAttribute;
- // These 3 added - SANDRO
INT32 iIMPStartingLevelCostMultiplier;
INT32 iBonusPointsForDisability;
INT32 iBonusPointsPerSkillNotTaken;
@@ -225,22 +261,49 @@ typedef struct
BOOLEAN fMercDayOne;
BOOLEAN fAllMercsAvailable;
-
- //BOOLEAN fPers_att;
-
- // These 2 removed - SANDRO
- //INT8 iCustomPersonality;
- //INT8 iCustomAttitude;
+
+ // tais: Any AIM merc on assignment?
+ UINT8 fMercsOnAssignment;
+ // tais: Soldiers wear any armour
+ UINT8 fSoldiersWearAnyArmour;
INT8 iEasyAPBonus;
INT8 iExperiencedAPBonus;
INT8 iExpertAPBonus;
INT8 iInsaneAPBonus;
INT8 iPlayerAPBonus;
+
+ ////////////////////////////////////
+ // added by SANDRO
+ INT16 sEnemyAdminCtHBonusPercent;
+ INT16 sEnemyRegularCtHBonusPercent;
+ INT16 sEnemyEliteCtHBonusPercent;
+
+ INT8 sEnemyAdminDamageResistance;
+ INT8 sEnemyRegularDamageResistance;
+ INT8 sEnemyEliteDamageResistance;
+
+ BOOLEAN fAssignTraitsToEnemy;
+ BOOLEAN fAssignTraitsToMilitia;
+ INT8 bAssignedTraitsRarity;
+
+ BOOLEAN fCamoRemoving;
+ BOOLEAN fEnhancedCloseCombatSystem;
+
+ UINT16 usAwardSpecialExpForQuests;
+ ////////////////////////////////////
+
// Kaiden: Vehicle Inventory change - Added for INI Option
BOOLEAN fVehicleInventory;
- BOOLEAN fEnableChanceOfEnemyAmbushesOnInsaneDifficult;
+ ///////////////////////////////////////
+ // changed/added these - SANDRO
+ UINT8 sMercsAutoresolveOffenseBonus;
+ UINT8 sMercsAutoresolveDeffenseBonus;
+ BOOLEAN fEnableChanceOfEnemyAmbushes;
+ INT8 bChanceModifierEnemyAmbushes;
+ UINT8 usSpecialNPCStronger;
+ ///////////////////////////////////////
// System settings
UINT8 gubDeadLockDelay;
@@ -285,7 +348,22 @@ typedef struct
//UINT32 guiMaxMilitiaSquadSize;
//UINT32 guiMaxMilitiaSquadSizeBattle;
- //BOOLEAN gfAllowSoldierToolTips; // moved to prefereces - SANDRO
+ // SANDRO - added some variables
+ INT16 sGreenMilitiaAutoresolveStrength;
+ INT16 sRegularMilitiaAutoresolveStrength;
+ INT16 sVeteranMilitiaAutoresolveStrength;
+ INT8 bGreenMilitiaAPsBonus;
+ INT8 bRegularMilitiaAPsBonus;
+ INT8 bVeteranMilitiaAPsBonus;
+ INT16 sGreenMilitiaCtHBonusPercent;
+ INT16 sRegularMilitiaCtHBonusPercent;
+ INT16 sVeteranMilitiaCtHBonusPercent;
+ INT8 bGreenMilitiaDamageResistance;
+ INT8 bRegularMilitiaDamageResistance;
+ INT8 bVeteranMilitiaDamageResistance;
+ INT8 bGreenMilitiaEquipmentQualityModifier;
+ INT8 bRegularMilitiaEquipmentQualityModifier;
+ INT8 bVeteranMilitiaEquipmentQualityModifier;
// WDS - Improve Tony's and Devin's inventory like BR's
BOOLEAN tonyUsesBRSetting;
@@ -335,9 +413,6 @@ typedef struct
UINT32 ubGameProgressMinimum;
INT32 bGameProgressModifier;
- // WDS - Advanced start
- //UINT32 ubIMPStartingLevel; // removed - SANDRO
-
// Event settings
UINT32 ubGameProgressStartMadlabQuest;
UINT32 ubGameProgressMikeAvailable;
@@ -357,6 +432,7 @@ typedef struct
INT32 iExplosivesDamageModifier;
INT32 iGunDamageModifier;
+ INT32 iGunRangeModifier;
INT32 iMeleeDamageModifier;
UINT32 ubEasyEnemyStartingAlertLevel;
@@ -414,6 +490,10 @@ typedef struct
BOOLEAN gfUseExternalLoadscreens;
+ //tais: nsgi
+ BOOLEAN gfUseNewStartingGearInterface;
+ // DBrot: Seperate Starting items for Experts
+ BOOLEAN fExpertsGetDifferentChoices;
BOOLEAN gfUseAutoSave;
//Merc Assignment settings
@@ -448,8 +528,9 @@ typedef struct
//Misc settings
BOOLEAN fAmmoDynamicWeight; //Pulmu
BOOLEAN fEnableCrepitus;
- BOOLEAN fEnableAllWeaponCaches;
- BOOLEAN fEnableAllTerrorists;
+ // SANDRO was here - removed these two
+ //BOOLEAN fEnableAllWeaponCaches;
+ //BOOLEAN fEnableAllTerrorists;
BOOLEAN gfRevealItems;
BOOLEAN fEnableArmorCoverage; // ShadoWarrior for Captain J's armor coverage
@@ -465,6 +546,7 @@ typedef struct
BOOLEAN fEnableSoldierTooltipAttitude;
BOOLEAN fEnableSoldierTooltipActionPoints;
BOOLEAN fEnableSoldierTooltipHealth;
+ BOOLEAN fEnableSoldierTooltipTraits; // added by SANDRO
BOOLEAN fEnableSoldierTooltipHelmet;
BOOLEAN fEnableSoldierTooltipVest;
BOOLEAN fEnableSoldierTooltipLeggings;
@@ -495,8 +577,8 @@ typedef struct
// Lesh: slow enemy items choice progress
BOOLEAN fSlowProgressForEnemyItemsChoice;
-//afp - use bullet tracers
-BOOLEAN gbBulletTracer;
+ //afp - use bullet tracers
+ BOOLEAN gbBulletTracer;
// CHRISL: option to allow Slay to remain as a hired PC
BOOLEAN fEnableSlayForever;
@@ -510,10 +592,42 @@ BOOLEAN gbBulletTracer;
// HEADROCK: Enhanced Item Description Box ON/OFF
// WANNE: Changed from BOOLEAN to INT32!
INT32 iEnhancedDescriptionBox;
+
+ //WarmSteel - New Attachment System?
+ BOOLEAN fUseDefaultSlots;
+ UINT32 usAttachmentDropRate;
+ INT16 iMaxEnemyAttachments;
+ //** ddd
+ //enable ext mouse key
+ BOOLEAN fExtMouseKeyEnabled;
+ // for small progress bar
+ BOOLEAN fSmallSizeProgressbar;
+ // stamina multiplier (for all weapons eg knife fist gun
+ INT32 uStaminaHit;
+ //enable ext mouse key
+ BOOLEAN bAltAimEnabled;
+ BOOLEAN bAimedBurstEnabled;
+ INT16 uAimedBurstPenalty;
+ BOOLEAN bWeSeeWhatMilitiaSeesAndViceVersa;
+ BOOLEAN bAllowWearSuppressor;
+ BOOLEAN bLazyCivilians;
+ INT16 iChanceSayAnnoyingPhrase;
+ BOOLEAN bNewTacticalAIBehavior;
+ FLOAT uShotHeadPenalty;
+ FLOAT fShotHeadDivisor;
+ INT16 iPenaltyShootUnSeen;
+
+ FLOAT fOutOfGunRangeOrSight;
// WANNE: Always use "prof.dat".
BOOLEAN fUseDifficultyBasedProfDat;
+ // 2Points: Use new repair algorithm
+ BOOLEAN fAdditionalRepairMode;
+
+ // CHRISL: Skyrider and enemy occupied sectors
+ UINT8 ubSkyriderHotLZ;
+
// CPT: Cover System Settings
UINT8 ubStealthTraitCoverValue;
UINT8 ubStealthEffectiveness;
@@ -566,12 +680,26 @@ BOOLEAN gbBulletTracer;
// HEADROCK HAM B2.5: Realistic tracers - CTH increased by this amount whenever a tracer is fired. 0 = off.
UINT8 ubCTHBumpPerTracer;
+ // CHRISL: Exeternalize the minimum range at which tracers can improve autofire hit chance
+ UINT16 ubMinRangeTracerEffect;
+
// HEADROCK HAM B2.6: Increased aiming costs?
BOOLEAN fIncreasedAimingCost;
+ // added by SANDRO
+ BOOLEAN fAimLevelRestriction;
+
// HEADROCK HAM B2.6: Dynamically determine Max-Aiming based also on weapon, bipod, etc?
BOOLEAN fDynamicAimingTime;
+ // allow old behaviour
+ BOOLEAN fAimLevelsDependOnDistance;
+
+ //WarmSteel - These determine in which group each scope belongs. Needed for dynamic aiming limits.
+ INT16 sVeryHighPowerScope;
+ INT16 sHighPowerScope;
+ INT16 sMediumPowerScope;
+
// HEADROCK HAM B2.6: Controls how much effect target movement has on aiming
FLOAT iMovementEffectOnAiming;
@@ -661,6 +789,9 @@ BOOLEAN gbBulletTracer;
// HEADROCK HAM 3: If enabled, tooltipping over Bobby Ray's weapons will show a list of possible attachments to those weapons.
BOOLEAN fBobbyRayTooltipsShowAttachments;
+ // CHRISL: Converts the AutoFireToHitBonus value to a percentage for CTH calculations
+ UINT8 ubFlatAFTHBtoPrecentMultiplier;
+
// HEADROCK HAM 3.1: Divisor for the AP-to-Ready cost charge on first aiming click, when extra aiming costs are enabled. 0 = No ready-time-based charge.
UINT8 ubFirstAimReadyCostDivisor;
@@ -706,6 +837,9 @@ BOOLEAN gbBulletTracer;
// HEADROCK HAM 3.3: Externalized maximum possible penalty for hitting a moving target. JA2 Default = 30.
UINT16 usMaxCTHPenaltyForMovingTarget;
+ // CHRISL: HAM4-NCTH
+ BOOLEAN fUseNCTH;
+
// HEADROCK HAM 3.3: Increases tolerance while moving.
UINT8 ubTilesMovedPerBonusTolerancePoint;
@@ -800,15 +934,388 @@ BOOLEAN gbBulletTracer;
// HEADROCK HAM 3.6: If activated, the game does not switch focus to a merc who spots an enemy in real-time mode. This fixes issues with Real-Time Sneak.
BOOLEAN fNoAutoFocusChangeInRealtimeSneak;
+ UINT8 ubEarlyRebelsRecruitment[4]; // early recruitment of Miguel and Carlos
+ // silversurfer: don't play quote when merc spots a mine? TRUE = shut up! FALSE = tell me that you found a mine!
+ BOOLEAN fMineSpottedNoTalk;
+
// The_Bob - real time sneaking code 01/06/09
// Suport disabling/silencing real time sneaking via external .ini file
- BOOLEAN fAllowRealTimeSneak;
+ //BOOLEAN fAllowRealTimeSneak; // SANDRO - moved to preferences
BOOLEAN fQuietRealTimeSneak;
-//dnl ch51 081009 JA2 Debug Settings
- BOOLEAN fEnableInventoryPoolQ;
+ //legion by Jazz
+ BOOLEAN fCanJumpThroughWindows;
+ BOOLEAN fCanClimbOnWalls;
+
+ //legion by Jazz
+ BOOLEAN fIndividualHiddenPersonNames;
+
+ //SAveGame Slot by Jazz
+ BOOLEAN fSaveGameSlot;
+
+ //dnl ch51 081009 JA2 Debug Settings
+ BOOLEAN fEnableInventoryPoolQ;
+
+ //legion by Jazz
+ BOOLEAN fShowTacticalFaceGear; //legion 2
+ BOOLEAN fShowTacticalFaceIcons; //legion 2
+ INT8 bTacticalFaceIconStyle;
+
+ //Enemy Names Group Legion 2 by Jazz
+ BOOLEAN fEnemyNames;
+
+ //Civ Names Group Legion 2 by Jazz
+ BOOLEAN fCivGroupName;
+
+ //Enemy Rank Legion 2 by Jazz
+ BOOLEAN fEnemyRank;
+
+ BOOLEAN fShowCamouflageFaces;
+
+ FLOAT gMercLevelUpSalaryIncreasePercentage;
+
+ UINT8 ubChanceTonyAvailable; // silversurfer/SANDRO
+
+ BOOLEAN fStandUpAfterBattle;
} GAME_EXTERNAL_OPTIONS;
+typedef struct
+{
+ UINT8 ubMaxNumberOfTraits;
+ UINT8 ubNumberOfMajorTraitsAllowed;
+
+ // GENERIC SETTINGS
+ INT8 bCtHModifierAssaultRifles;
+ INT8 bCtHModifierSniperRifles;
+ INT8 bCtHModifierRifles;
+ INT8 bCtHModifierSMGs;
+ INT8 bCtHModifierLMGs;
+ INT8 bCtHModifierShotguns;
+ INT8 bCtHModifierPistols;
+ INT8 bCtHModifierMachinePistols;
+ INT8 bCtHModifierRocketLaunchers;
+ INT8 bCtHModifierGrenadeLaunchers;
+ INT16 sCtHModifierMortar;
+ INT8 bCtHModifierThrowingKnives;
+ INT8 bCtHModifierThrowingGrenades;
+ INT8 bCtHModifierHtHAttack;
+ INT8 bModifierDodgeHtHChance;
+ INT8 bCtHModifierKnifeAttack;
+ INT8 bModifierDodgeKnifeChance;
+ INT8 bCtHModifierRobot;
+ UINT8 ubCtHPenaltyDualShot;
+ INT8 bPercentModifierHtHBreathLoss;
+ INT8 bPercentModifierBladesBreathLoss;
+ INT8 bPercentModifierBluntBreathLoss;
+ UINT8 ubModifierForAPsAddedOnAimedPunches;
+ UINT8 ubModifierForAPsAddedOnAimedBladedAttackes;
+ INT8 bSpeedModifierDoctoring;
+ INT8 bSpeedModifierBandaging;
+ INT8 bSpeedModifierRepairing;
+ INT8 bSpeedModifierTrainingMilitia;
+ INT8 bSpeedModifierTeachingOthers;
+ INT8 bCheckModifierLockpicking;
+ INT8 bCheckModifierAttachDetonators;
+ INT8 bCheckModifierSetExplosives;
+ INT8 bCheckModifierDisarmExplosiveTraps;
+ INT8 bCheckModifierDisarmElectronicTraps;
+ INT8 bCheckModifierAttachSpecialItems;
+ INT8 bTanksDamageResistanceModifier;
+ UINT8 ubDamageNeededToLoseStats;
+
+ // AUTO WEAPONS
+ UINT8 ubAWBonusCtHAssaultRifles;
+ UINT8 ubAWBonusCtHSMGs;
+ UINT8 ubAWBonusCtHLMGs;
+ UINT8 ubAWAutoFirePenaltyReduction;
+ UINT8 ubAWUnwantedBulletsReduction;
+ UINT8 ubAWFiringSpeedBonusLMGs;
+ UINT8 ubAWPercentReadyLMGReduction;
+
+ // HEAVY WEAPONS
+ UINT8 ubHWGrenadeLaunchersAPsReduction;
+ UINT8 ubHWRocketLaunchersAPsReduction;
+ UINT8 ubHWBonusCtHGrenadeLaunchers;
+ UINT8 ubHWBonusCtHRocketLaunchers;
+ UINT8 ubHWMortarAPsReduction;
+ UINT8 ubHWMortarCtHPenaltyReduction;
+ UINT8 ubHWDamageTanksBonusPercent;
+ UINT8 ubHWDamageBonusPercentForHW;
+
+ // SNIPER
+ UINT8 ubSNBonusCtHRifles;
+ UINT8 ubSNBonusCtHSniperRifles;
+ UINT8 ubSNEffRangeToTargetReduction;
+ UINT8 ubSNAimingBonusPerClick;
+ UINT8 ubSNDamageBonusPerClick;
+ UINT8 ubSNDamageBonusFromNumClicks;
+ UINT8 ubSNChamberRoundAPsReduction;
+ UINT8 ubSNAimClicksAdded;
+
+ // RANGER
+ UINT8 ubRABonusCtHRifles;
+ UINT8 ubRABonusCtHShotguns;
+ UINT8 ubRAPumpShotgunsAPsReduction;
+ UINT8 ubRAGroupTimeSpentForTravellingFoot;
+ UINT8 ubRAGroupTimeSpentForTravellingVehicle;
+ UINT8 ubRAMaxBonusesToTravelSpeed;
+ UINT8 ubRABreathForTravellingReduction;
+ UINT8 ubRAWeatherPenaltiesReduction;
+ //UINT8 ubRACamoEffectivenessBonus;
+ UINT8 ubRACamoWornountSpeedReduction;
+
+ // GUNSLINGER
+ UINT8 ubGSFiringSpeedBonusPistols;
+ UINT8 ubGSEffectiveRangeBonusPistols;
+ UINT8 ubGSBonusCtHPistols;
+ UINT8 ubGSBonusCtHMachinePistols;
+ UINT8 ubGSCtHMPExcludeAuto;
+ UINT8 ubGSAimingBonusPerClick;
+ UINT8 ubGSPercentReadyPistolsReduction;
+ UINT8 ubGSRealoadSpeedHandgunsBonus;
+ UINT8 ubGSAimClicksAdded;
+
+ // MARTIAL ARTS
+ UINT8 ubMABonusCtHBareHands;
+ UINT8 ubMABonusCtHBrassKnuckles;
+ UINT8 ubMAPunchAPsReduction;
+ UINT8 ubMABonusDamageHandToHand;
+ UINT8 ubMABonusBreathDamageHandToHand;
+ UINT16 usMALostBreathRegainPenalty;
+ UINT16 usMAAimedPunchDamageBonus;
+ INT8 bMAAimedPunchCtHModifier;
+ UINT8 ubMAChanceToDodgeHtH;
+ UINT8 ubMAOnTopCTDHtHBareHanded;
+ UINT8 ubMAOnTopCTDHtHBrassKnuckles;
+ UINT8 ubMAChanceToDodgeMelee;
+ UINT8 ubMAReducedAPsToSteal;
+ UINT8 ubMAAPsChangeStanceReduction;
+ UINT8 ubMAApsTurnAroundReduction;
+ UINT8 ubMAAPsClimbOrJumpReduction;
+ UINT8 ubMAChanceToCkickDoors;
+ BOOLEAN fPermitExtraAnimationsOnlyToMA;
+
+ // SQUADLEADER
+ UINT16 usSLRadiusNormal;
+ UINT16 usSLRadiusExtendedEar;
+ UINT8 ubSLMaxBonuses;
+ UINT8 ubSLBonusAPsPercent;
+ UINT8 ubSLEffectiveLevelInRadius;
+ UINT8 ubSLEffectiveLevelAsStandby;
+ UINT8 ubSLOverallSuppresionBonusPercent;
+ UINT8 ubSLMoraleGainBonus;
+ UINT8 ubSLMoraleLossReduction;
+ UINT8 ubSLFearResistance;
+ UINT8 ubSLDeathMoralelossMultiplier;
+
+ // TECHNICIAN
+ UINT16 usTERepairSpeedBonus;
+ UINT16 usTELockpickingBonus;
+ UINT16 usTEDisarmElTrapBonus;
+ UINT16 usTEAttachingItemsBonus;
+ UINT8 ubTEUnjamGunBonus;
+ UINT8 ubTERepairElectronicsPenaltyReduction;
+ UINT8 ubTEChanceToDetectTrapsBonus;
+ UINT8 ubTECtHControlledRobotBonus;
+ UINT8 ubTERepairRobotPenaltyReduction;
+ UINT8 ubTETraitsNumToRepairRobot;
+
+ // DOCTOR
+ UINT8 ubDONumberTraitsNeededForSurgery;
+ UINT8 ubDOSurgeryHealPercentBase;
+ UINT8 ubDOSurgeryHealPercentOnTop;
+ UINT16 usDOSurgeryMedBagConsumption;
+ UINT16 usDOSurgeryMaxBreathLoss;
+ UINT16 usDORepairStatsRateBasic;
+ UINT16 usDORepairStatsRateOnTop;
+ UINT8 ubDORepStPenaltyIfAlsoHealing;
+ UINT8 ubDOHealingPenaltyIfAlsoStatRepair;
+ BOOLEAN fDORepStShouldThrowMessage;
+ UINT8 ubDOBandagingSpeedPercent;
+ UINT16 usDODoctorAssignmentBonus;
+ UINT8 ubDONaturalRegenBonus;
+ UINT8 ubDOMaxRegenBonuses;
+
+ // AMBIDEXTROUS
+ UINT8 ubAMPenaltyDoubleReduction;
+ UINT8 ubAMReloadSpeedMagazines;
+ UINT8 ubAMReloadSpeedLoose;
+ UINT8 ubAMPickItemsAPsReduction;
+ UINT8 ubAMWorkBackpackAPsReduction;
+ UINT8 ubAMHandleDoorsAPsReduction;
+ UINT8 ubAMHandleBombsAPsReduction;
+ UINT8 ubAMAttachingItemsAPsReduction;
+
+ // MELEE
+ UINT8 ubMEBladesAPsReduction;
+ UINT8 ubMECtHBladesBonus;
+ UINT8 ubMECtHBluntBonus;
+ UINT8 ubMEDamageBonusBlades;
+ UINT8 ubMEDamageBonusBlunt;
+ UINT16 usMEAimedMeleeAttackDamageBonus;
+ UINT8 ubMEDodgeBladesBonus;
+ UINT8 ubMECtDBladesOnTopWithBladeInHands;
+ UINT8 ubMEDodgeBluntBonus;
+ UINT8 ubMECtDBluntOnTopWithBladeInHands;
+
+ // THROWING
+ UINT8 ubTHBladesAPsReduction;
+ UINT8 ubTHBladesMaxRange;
+ UINT8 ubTHBladesCtHBonus;
+ UINT8 ubTHBladesCtHBonusPerClick;
+ UINT8 ubTHBladesDamageBonus;
+ UINT8 ubTHBladesDamageBonusPerClick;
+ UINT8 ubTHBladesSilentCriticalHitChance;
+ UINT8 ubTHBladesCriticalHitMultiplierBonus;
+ UINT8 ubTHBladesAimClicksAdded;
+
+ // NIGHT OPS
+ UINT8 ubNOeSightRangeBonusInDark;
+ UINT8 ubNOHearingRangeBonus;
+ UINT8 ubNOHearingRangeBonusInDark;
+ UINT8 ubNOIterruptsBonusInDark;
+ UINT8 ubNONeedForSleepReduction;
+
+ // STEALTHY
+ UINT8 ubSTStealthModeSpeedBonus;
+ UINT8 ubSTBonusToMoveQuietly;
+ UINT8 ubSTStealthBonus;
+ UINT8 ubSTStealthPenaltyForMovingReduction;
+
+ // ATHLETICS
+ UINT8 ubATAPsMovementReduction;
+ UINT8 ubATBPsMovementReduction;
+
+ // BODYBUILDING
+ UINT8 ubBBDamageResistance;
+ UINT8 ubBBCarryWeightBonus;
+ UINT8 ubBBBreathLossForHtHImpactReduction;
+ UINT16 usBBIncreasedNeededDamageToFallDown;
+
+ // DEMOLITIONS
+ UINT8 ubDEAPsNeededToThrowGrenadesReduction;
+ UINT8 ubDEMaxRangeToThrowGrenades;
+ UINT8 ubDECtHWhenThrowingGrenades;
+ UINT8 ubDEDamageOfBombsAndMines;
+ UINT8 ubDEAttachDetonatorCheckBonus;
+ UINT8 ubDEPlantAndRemoveBombCheckBonus;
+ UINT8 ubDEPlacedBombLevelBonus;
+ UINT8 ubDEShapedChargeDamageMultiplier;
+
+ // TEACHING
+ UINT8 ubTGBonusToTrainMilitia;
+ UINT8 ubTGEffectiveLDRToTrainMilitia;
+ UINT8 ubTGBonusToTeachOtherMercs;
+ UINT8 ubTGEffectiveSkillValueForTeaching;
+ UINT8 ubTGBonusOnPractising;
+
+ // SCOUTING
+ UINT8 ubSCSightRangebonusWithScopes;
+ UINT16 usSCSightRangebonusWithBinoculars;
+ UINT8 ubSCTunnelVisionReducedWithBinoculars;
+ BOOLEAN fSCCanDetectEnemyPresenseAround;
+ BOOLEAN fSCCanDetermineEnemyNumbersAround;
+ BOOLEAN fSCDetectionInDiagonalSectors;
+ BOOLEAN fSCPreventsTheEnemyToAmbushMercs;
+ BOOLEAN fSCPreventsBloodcatsAmbushes;
+ BOOLEAN fSCThrowMessageIfAmbushPrevented;
+
+} SKILL_TRAIT_VALUES;
+
+// HEADROCK HAM 4: Constants used as coefficients by the various parts of the new CTH system.
+typedef struct
+{
+ UINT32 NORMAL_SHOOTING_DISTANCE; // Distance at which 1x magnification is 100% effective. This is a major component of the entire shooting mechanism.
+ FLOAT DEGREES_MAXIMUM_APERTURE; // Maximum possible aperture for a 100% muzzle sway shot. Decrease to make all shots more accurate.
+ FLOAT GRAVITY_COEFFICIENT; // Changes the way gravity works in the game. Higher values mean bullets don't drop as quickly after reaching max range.
+ FLOAT VERTICAL_BIAS; // This float can be used to reduce the chance of missing too far upwards or downwards (compared to left/right).
+ FLOAT SCOPE_RANGE_MULTIPLIER; // Adjusts the minimum effective range of scopes
+
+ FLOAT BASE_EXP; // Importance of Experience for BASE CTH
+ FLOAT BASE_MARKS; // Importance of Marksmanship for BASE CTH
+ FLOAT BASE_WIS; // Importance of Wisdom for BASE CTH
+ FLOAT BASE_DEX; // Importance of Dexterity for BASE CTH
+
+ FLOAT BASE_LOW_MORALE; // Applied gradually when morale is below 50.
+ FLOAT BASE_HIGH_MORALE; // Applied gradually when morale is above 50.
+ FLOAT BASE_PSYCHO; // Applied for each level of PSYCHO trait
+ FLOAT BASE_SHOOTING_UPWARDS; // Applied gradually for shooting at a higher target. Decreases with distance.
+ FLOAT BASE_INJURY; // Applied gradually for injuries
+ FLOAT BASE_DRUNK[4]; // Applied for drunkness levels
+ FLOAT BASE_FATIGUE; // Applied gradually for fatigue
+ FLOAT BASE_SAME_TARGET; // Applied for shooting at the same target again
+ FLOAT BASE_GASSED; // Applied for shooting while breathing gas
+ FLOAT BASE_BEING_BANDAGED; // Applied for shooting while being bandaged
+ FLOAT BASE_SHOCK; // Applied gradually for shock points
+ FLOAT BASE_AGILE_TARGET; // Applied gradually for agile or experienced target
+ FLOAT BASE_TARGET_INVISIBLE; // Applied for shooting at a target you can't see
+ FLOAT BASE_DRAW_COST; // Applied per 1 AP of the weapon's Ready Cost, under 100AP.
+ FLOAT BASE_TWO_GUNS; // Gun Difficulty Multiplier for shooting two guns
+ FLOAT BASE_ONE_HANDED; // Gun Difficulty Multiplier for shooting a pistol with one hand.
+ FLOAT BASE_CROUCHING_STANCE; // Gun Difficulty Multiplier for shooting from a crouched stance
+ FLOAT BASE_PRONE_STANCE; // Gun Difficulty Multiplier for shooting from a prone stance
+ FLOAT BASE_HEAVY_WEAPON; // Gun Difficulty Multiplier for shooting a launcher
+ FLOAT BASE_DIFFICULTY[6]; // Applied for game difficulty
+
+ FLOAT AIM_EXP; // Importance of Experience for AIMING CTH
+ FLOAT AIM_MARKS; // Importance of Marksmanship for AIMING CTH
+ FLOAT AIM_WIS; // Importance of Wisdom for AIMING CTH
+ FLOAT AIM_DEX; // Importance of Dexterity for AIMING CTH
+
+ FLOAT AIM_TOO_CLOSE_SCOPE; // Applied per tile closer than the scope's minimum range.
+ FLOAT AIM_GUN_CONDITION; // Applied per point of condition below 50.
+ FLOAT AIM_LOW_MORALE; // Applied gradually when morale is below 50.
+ FLOAT AIM_HIGH_MORALE; // Applied gradually when morale is above 50.
+ FLOAT AIM_PSYCHO; // Applied for each level of PSYCHO trait
+ FLOAT AIM_VISIBILITY; // Applied for bad visibility
+ FLOAT AIM_SHOOTING_UPWARDS; // Applied gradually for shooting at a higher target. Decreases with distance.
+ FLOAT AIM_INJURY; // Applied gradually for injuries
+ FLOAT AIM_DRUNK[4]; // Applied for drunkness levels
+ FLOAT AIM_FATIGUE; // Applied gradually for fatigue
+ FLOAT AIM_GASSED; // Applied for shooting while breathing gas
+ FLOAT AIM_BEING_BANDAGED; // Applied for shooting while being bandaged
+ FLOAT AIM_SHOCK; // Applied gradually for shock points
+ FLOAT AIM_TARGET_INVISIBLE; // Applied for shooting at a target you can't see
+ FLOAT AIM_SNIPER_SKILL; // Applied as percentage bonus to CTH cap, once per each level.
+ FLOAT AIM_DRAW_COST; // Applied per 1 AP of the weapon's Ready Cost, under 100AP.
+ FLOAT AIM_STANDING_STANCE; // Gun Difficulty multiplier for shooting a heavy gun when standing
+ FLOAT AIM_CROUCHING_STANCE; // Gun Difficulty multiplier for shooting a heavy gun from a crouched stance
+ FLOAT AIM_PRONE_STANCE; // Gun Difficulty multiplier for shooting a heavy gun when prone, before bipod bonuses
+ FLOAT AIM_TWO_GUNS; // Gun Difficulty multiplier for shooting two guns (halved for each Ambidextrous level)
+ FLOAT AIM_ONE_HANDED; // Gun Difficulty multiplier for firing a pistol with one hand.
+ FLOAT AIM_HEAVY_WEAPON; // Gun Difficulty multiplier for shooting a launcher (halved for each Heavy Weapons level)
+ FLOAT AIM_DIFFICULTY[6]; // Applied for game difficulty
+
+ FLOAT MOVEMENT_MRK;
+ FLOAT MOVEMENT_WIS;
+ FLOAT MOVEMENT_DEX;
+ FLOAT MOVEMENT_EXP_LEVEL;
+ UINT32 MOVEMENT_TRACKING_DIFFICULTY;
+ FLOAT MOVEMENT_PENALTY_PER_TILE;
+
+ FLOAT PRE_RECOIL_WIS;
+ FLOAT PRE_RECOIL_EXP_LEVEL;
+ FLOAT PRE_RECOIL_AUTO_WEAPONS_SKILL;
+
+ FLOAT RECOIL_MAX_COUNTER_STR;
+ FLOAT RECOIL_MAX_COUNTER_AGI;
+ FLOAT RECOIL_MAX_COUNTER_EXP_LEVEL;
+ FLOAT RECOIL_MAX_COUNTER_FORCE;
+ FLOAT RECOIL_COUNTER_ACCURACY_MIN_ERROR;
+ FLOAT RECOIL_COUNTER_ACCURACY_DEX;
+ FLOAT RECOIL_COUNTER_ACCURACY_WIS;
+ FLOAT RECOIL_COUNTER_ACCURACY_AGI;
+ FLOAT RECOIL_COUNTER_ACCURACY_EXP_LEVEL;
+ FLOAT RECOIL_COUNTER_ACCURACY_AUTO_WEAPONS_DIVISOR;
+ FLOAT RECOIL_COUNTER_ACCURACY_TRACER_BONUS;
+ FLOAT RECOIL_COUNTER_FREQUENCY_AGI;
+ FLOAT RECOIL_COUNTER_FREQUENCY_EXP_LEVEL;
+ FLOAT RECOIL_COUNTER_FREQUENCY_AUTO_WEAPONS_DIVISOR;
+
+ FLOAT MAX_BULLET_DEV;
+
+} CTH_CONSTANTS;
+
//This structure will contain general Ja2 settings NOT individual game settings.
extern GAME_SETTINGS gGameSettings;
@@ -818,6 +1325,11 @@ extern GAME_OPTIONS gGameOptions;
// Snap: Options read from an INI file in the default of custom Data directory
extern GAME_EXTERNAL_OPTIONS gGameExternalOptions;
+extern SKILL_TRAIT_VALUES gSkillTraitValues; // SANDRO - added this one
+
+// HEADROCK HAM 4: CTH constants read from a separate INI file
+extern CTH_CONSTANTS gGameCTHConstants;
+
// WDS - Automatically try to save when an assertion failure occurs
extern bool alreadySaving;
@@ -825,7 +1337,10 @@ BOOLEAN SaveGameSettings();
BOOLEAN LoadGameSettings();
// Snap: Read options from an INI file in the default of custom Data directory
void LoadGameExternalOptions();
+void LoadSkillTraitsExternalSettings(); // SANDRO - added this one
void LoadGameAPBPConstants();
+// HEADROCK HAM 4: Read CTH/Shooting coefficients from file
+void LoadCTHConstants();
void FreeGameExternalOptions();
void InitGameOptions();
diff --git a/GameVersion.cpp b/GameVersion.cpp
index c9b4ab7b..d2e14fc4 100644
--- a/GameVersion.cpp
+++ b/GameVersion.cpp
@@ -13,13 +13,11 @@
#ifdef JA2EDITOR
//MAP EDITOR BUILD VERSION
-CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.3356" };
-
+CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.4063" };
#elif defined JA2BETAVERSION
//BETA/TEST BUILD VERSION
-CHAR16 zVersionLabel[256] = { L"Debug v1.13.3356" };
-
+CHAR16 zVersionLabel[256] = { L"Debug v1.13.4063" };
#elif defined CRIPPLED_VERSION
//RELEASE BUILD VERSION s
@@ -28,11 +26,10 @@ CHAR16 zVersionLabel[256] = { L"Beta v. 0.98" };
#else
//RELEASE BUILD VERSION
- CHAR16 zVersionLabel[256] = { L"Release v1.13.3356" };
-
+ CHAR16 zVersionLabel[256] = { L"Release v1.13.4063" };
#endif
-CHAR8 czVersionNumber[16] = { "Build 10.03.13" }; //YY.MM.DD
+CHAR8 czVersionNumber[16] = { "Build 11.01.18" }; //YY.MM.DD
CHAR16 zTrackingNumber[16] = { L"Z" };
diff --git a/GameVersion.h b/GameVersion.h
index 36a74c70..feed7b3c 100644
--- a/GameVersion.h
+++ b/GameVersion.h
@@ -20,10 +20,21 @@ extern CHAR16 zTrackingNumber[16];
//
// Keeps track of the saved game version. Increment the saved game version whenever
// you will invalidate the saved game file
-#define SAVE_GAME_VERSION 107 //106 //105 //104 //103 //102 //101 //100 // 99
+#define SAVE_GAME_VERSION 117 //114 //113 //112 //111 //110 //109 //108 //107 //106 //105 //104 //103 //102 //101 //100 // 99
-#define CURRENT_SAVEGAME_DATATYPE_VERSION 107
-#define BIG_MAPS_PROJECT_SAVEGAME_DATATYPE_CHANGE 107 // Before this, we did not had big maps project
+#define CURRENT_SAVEGAME_DATATYPE_VERSION 116
+
+#define NCTH_DATATYPE_CHANGE 117 // Before this, we did not have HAM 4.0 NCTH
+#define NEW_GENERAL_SAVE_INFO_DATA 116 // Before this, we did not have HAM 4.0 general info
+#define IMP_TRAIT_EXPERT_ITEMS_CHANGE 115 // Before this, we did not have additional expert items defined in IMPItemChoices.xml
+#define LUA_SAVEGAME_CHANGE 114 // Before this, we did not have additional lua script files (e.g: Intro.lua, ...)
+#define STOMP12_SAVEGAME_DATATYPE_CHANGE2 113 // Before this, STOMP did not allow to have up to 30 traits
+#define NAS_SAVEGAME_DATATYPE_CHANGE 112 // Before this, NAS settings (ON/OFF) was not saved to the savegame
+#define STOMP12_SAVEGAME_DATATYPE_CHANGE 111 // Before this, STOMP v1.2 was not included in the source
+#define BUGFIX_NPC_DATA_FOR_BIG_MAPS 110 // Before this, we had a bug in the NPC Data for Big Maps (this fix was introduced in the Closed Beta)
+#define STRATEGIC_MINES_DATATYPE_CHANGE 109 // Before this, we did not have strategic mines initialization via lua script
+#define HIDE_NPC_NAMES_FOR_UNKNOWN_PERSONS 108 // Before this, we did not have hiding of npc names for unknown persons included (by jazz)
+#define BIG_MAPS_PROJECT_SAVEGAME_DATATYPE_CHANGE 107 // Before this, we did not have big maps project
#define AIRPORT_SAVEGAME_DATATYPE_CHANGE 106 // Before this, we did not have airport externalized
#define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes
#define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system
diff --git a/Init.cpp b/Init.cpp
index effbde29..7cfa8040 100644
--- a/Init.cpp
+++ b/Init.cpp
@@ -60,10 +60,22 @@
#include "Vehicles.h"
#include "Multilingual Text Code Generator.h"
#include "editscreen.h"
+ #include "Arms Dealer Init.h"
#endif
#include "MPXmlTeams.hpp"
+#include "Strategic Mines LUA.h"
+#include "UndergroundInit.h"
+#include "lua_state.h"
+#include "Interface.h"
+#include "Strategic Town Loyalty.h"
+#include "Soldier Profile.h"
+#include "aim.h"
+
+#include "Civ Quotes.h"
#include "Sector Summary.h"
+#include "LuaInitNPCs.h"
+
extern INT16 APBPConstants[TOTAL_APBP_VALUES] = {0};
extern INT16 gubMaxActionPoints[28];//MAXBODYTYPES = 28... JUST GETTING IT TO WORK NOW. GOTTHARD 7/2/08
extern BOOLEAN GetCDromDriveLetter( STR8 pString );
@@ -123,34 +135,62 @@ static void AddLanguagePrefix(STR fileName, const STR language)
memmove( fileComponent, language, strlen( language) );
}
-static void AddLanguagePrefix(STR fileName)
+static const STR GetLanguagePrefix()
{
+#ifdef ENGLISH
+ return "";
+#endif
#ifdef GERMAN
- AddLanguagePrefix( fileName, GERMAN_PREFIX);
+ return GERMAN_PREFIX;
#endif
#ifdef RUSSIAN
- AddLanguagePrefix( fileName, RUSSIAN_PREFIX);
+ return RUSSIAN_PREFIX;
#endif
#ifdef DUTCH
- AddLanguagePrefix( fileName, DUTCH_PREFIX);
+ return DUTCH_PREFIX;
#endif
#ifdef POLISH
- AddLanguagePrefix( fileName, POLISH_PREFIX);
+ return POLISH_PREFIX;
#endif
#ifdef FRENCH
- AddLanguagePrefix( fileName, FRENCH_PREFIX);
+ return FRENCH_PREFIX;
#endif
#ifdef ITALIAN
- AddLanguagePrefix( fileName, ITALIAN_PREFIX);
+ return ITALIAN_PREFIX;
#endif
#ifdef TAIWANESE
- AddLanguagePrefix( fileName, TAIWANESE_PREFIX);
+ return TAIWANESE_PREFIX;
#endif
#ifdef CHINESE
- AddLanguagePrefix( fileName, CHINESE_PREFIX);
+ return CHINESE_PREFIX;
#endif
}
+static void AddLanguagePrefix(STR fileName)
+{
+ AddLanguagePrefix( fileName, GetLanguagePrefix());
+}
+
+void ResetEmptyRPCFaceSlots()
+{
+ //legion by jazz (load small faces from rpcs)
+ // reset empty slots with "-1"
+ for (UINT8 i = 0; i < 200; i++)
+ {
+ if (i == 0 &&
+ gRPCSmallFaceValues[i].bEyesX == 0 && gRPCSmallFaceValues[i].bEyesY == 0 &&
+ gRPCSmallFaceValues[i].bMouthX == 0 && gRPCSmallFaceValues[i].bMouthY == 0 &&
+ gRPCSmallFaceValues[i].FaceIndex == 0 && gRPCSmallFaceValues[i].uiIndex == 0)
+ {
+ gRPCSmallFaceValues[i].uiIndex = -1; // -1 -> 65535
+ }
+ else if (i > 0 && gRPCSmallFaceValues[i].uiIndex == 0)
+ {
+ gRPCSmallFaceValues[i].uiIndex = -1; // -1 -> 65535
+ }
+ }
+}
+
BOOLEAN LoadExternalGameplayData(STR directoryName)
{
char fileName[MAX_PATH];
@@ -167,27 +207,27 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcpy(fileName, directoryName);
strcat(fileName, ENEMYMISCDROPSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInEnemyMiscDropsStats(gEnemyMiscDrops, fileName), ENEMYMISCDROPSFILENAME);
+ SGP_THROW_IFFALSE(ReadInEnemyMiscDropsStats(gEnemyMiscDrops, fileName), ENEMYMISCDROPSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ENEMYEXPLOSIVEDROPSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInEnemyExplosiveDropsStats(gEnemyExplosiveDrops, fileName),ENEMYEXPLOSIVEDROPSFILENAME);
+ SGP_THROW_IFFALSE(ReadInEnemyExplosiveDropsStats(gEnemyExplosiveDrops, fileName),ENEMYEXPLOSIVEDROPSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ENEMYWEAPONDROPSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInEnemyWeaponDropsStats(gEnemyWeaponDrops, fileName),ENEMYWEAPONDROPSFILENAME);
+ SGP_THROW_IFFALSE(ReadInEnemyWeaponDropsStats(gEnemyWeaponDrops, fileName),ENEMYWEAPONDROPSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ENEMYAMMODROPSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInEnemyAmmoDropsStats(gEnemyAmmoDrops, fileName),ENEMYAMMODROPSFILENAME);
+ SGP_THROW_IFFALSE(ReadInEnemyAmmoDropsStats(gEnemyAmmoDrops, fileName),ENEMYAMMODROPSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ENEMYARMOURDROPSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInEnemyArmourDropsStats(gEnemyArmourDrops, fileName),ENEMYARMOURDROPSFILENAME);
+ SGP_THROW_IFFALSE(ReadInEnemyArmourDropsStats(gEnemyArmourDrops, fileName),ENEMYARMOURDROPSFILENAME);
// WANNE: Enemy drops - end
// WANNE: Sector Loadscreens [2007-05-18]
@@ -197,7 +237,7 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
if ( FileExists(fileName) )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInSectorLoadscreensStats(gSectorLoadscreens, fileName),SECTORLOADSCREENSFILENAME);
+ SGP_THROW_IFFALSE(ReadInSectorLoadscreensStats(gSectorLoadscreens, fileName),SECTORLOADSCREENSFILENAME);
}
else
{
@@ -209,7 +249,7 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcpy(fileName, directoryName);
strcat(fileName, AMMOTYPESFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInAmmoTypeStats(fileName),AMMOTYPESFILENAME);
+ SGP_THROW_IFFALSE(ReadInAmmoTypeStats(fileName),AMMOTYPESFILENAME);
//Madd: Simple Localization
//Read in the correct ammostring file for the given language
@@ -245,7 +285,7 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
//CHRISL: If we fail to load, try loading just the default english
strcpy(fileName, directoryName);
strcat(fileName, AMMOFILENAME);
- THROWIFFALSE(!ReadInAmmoStats(fileName),AMMOFILENAME);
+ SGP_THROW_IFFALSE(!ReadInAmmoStats(fileName),AMMOFILENAME);
}
@@ -253,13 +293,13 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcpy(fileName, directoryName);
strcat(fileName, BURSTSOUNDSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInBurstSoundArray(fileName),BURSTSOUNDSFILENAME);
+ SGP_THROW_IFFALSE(ReadInBurstSoundArray(fileName),BURSTSOUNDSFILENAME);
// Lesh: end
strcpy(fileName, directoryName);
strcat(fileName, ITEMSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInItemStats(fileName,FALSE),ITEMSFILENAME);
+ SGP_THROW_IFFALSE(ReadInItemStats(fileName,FALSE),ITEMSFILENAME);
//Madd: Simple localization
// The idea here is that we can have a separate xml file that's named differently
@@ -286,57 +326,57 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcpy(fileName, directoryName);
strcat(fileName, SOUNDSFILENAME);
- THROWIFFALSE(ReadInSoundArray(fileName),SOUNDSFILENAME);
+ SGP_THROW_IFFALSE(ReadInSoundArray(fileName),SOUNDSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, MAGAZINESFILENAME);
- THROWIFFALSE(ReadInMagazineStats(fileName),MAGAZINESFILENAME);
+ SGP_THROW_IFFALSE(ReadInMagazineStats(fileName),MAGAZINESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ATTACHMENTSFILENAME);
- THROWIFFALSE(ReadInAttachmentStats(fileName),ATTACHMENTSFILENAME);
+ SGP_THROW_IFFALSE(ReadInAttachmentStats(fileName),ATTACHMENTSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ATTACHMENTINFOFILENAME);
- THROWIFFALSE(ReadInAttachmentInfoStats(fileName),ATTACHMENTINFOFILENAME);
+ SGP_THROW_IFFALSE(ReadInAttachmentInfoStats(fileName),ATTACHMENTINFOFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, LAUNCHABLESFILENAME);
- THROWIFFALSE(ReadInLaunchableStats(fileName),LAUNCHABLESFILENAME);
+ SGP_THROW_IFFALSE(ReadInLaunchableStats(fileName),LAUNCHABLESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, COMPATIBLEFACEITEMSFILENAME);
- THROWIFFALSE(ReadInCompatibleFaceItemStats(fileName),COMPATIBLEFACEITEMSFILENAME);
+ SGP_THROW_IFFALSE(ReadInCompatibleFaceItemStats(fileName),COMPATIBLEFACEITEMSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, MERGESFILENAME);
- THROWIFFALSE(ReadInMergeStats(fileName),MERGESFILENAME);
+ SGP_THROW_IFFALSE(ReadInMergeStats(fileName),MERGESFILENAME);
//if(!WriteMergeStats())
// return FALSE;
strcpy(fileName, directoryName);
strcat(fileName, ATTACHMENTCOMBOMERGESFILENAME);
- THROWIFFALSE(ReadInAttachmentComboMergeStats(fileName),ATTACHMENTCOMBOMERGESFILENAME);
+ SGP_THROW_IFFALSE(ReadInAttachmentComboMergeStats(fileName),ATTACHMENTCOMBOMERGESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, EXPLOSIVESFILENAME);
- THROWIFFALSE(ReadInExplosiveStats(fileName),EXPLOSIVESFILENAME);
+ SGP_THROW_IFFALSE(ReadInExplosiveStats(fileName),EXPLOSIVESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ARMOURSFILENAME);
- THROWIFFALSE(ReadInArmourStats(fileName),ARMOURSFILENAME);
+ SGP_THROW_IFFALSE(ReadInArmourStats(fileName),ARMOURSFILENAME);
// CHRISL:
strcpy(fileName, directoryName);
strcat(fileName, LOADBEARINGEQUIPMENTFILENAME);
- THROWIFFALSE(ReadInlbeStats(fileName),LOADBEARINGEQUIPMENTFILENAME);
+ SGP_THROW_IFFALSE(ReadInlbeStats(fileName),LOADBEARINGEQUIPMENTFILENAME);
// CHRISL:
LBEPocketType.clear();
strcpy(fileName, directoryName);
strcat(fileName, LBEPOCKETFILENAME);
- THROWIFFALSE(ReadInLBEPocketStats(fileName,FALSE),LBEPOCKETFILENAME);
+ SGP_THROW_IFFALSE(ReadInLBEPocketStats(fileName,FALSE),LBEPOCKETFILENAME);
//CHRISL: Simple localization
// Same setup as what Madd used for items.xml
@@ -354,108 +394,117 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
// CHRISL:
strcpy(fileName, directoryName);
strcat(fileName, MERCSTARTINGGEARFILENAME);
- THROWIFFALSE(ReadInMercStartingGearStats(fileName),MERCSTARTINGGEARFILENAME);
+ SGP_THROW_IFFALSE(ReadInMercStartingGearStats(fileName),MERCSTARTINGGEARFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, WEAPONSFILENAME);
- THROWIFFALSE(ReadInWeaponStats(fileName),WEAPONSFILENAME);
+ SGP_THROW_IFFALSE(ReadInWeaponStats(fileName),WEAPONSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, INCOMPATIBLEATTACHMENTSFILENAME);
- THROWIFFALSE(ReadInIncompatibleAttachmentStats(fileName),INCOMPATIBLEATTACHMENTSFILENAME);
+ SGP_THROW_IFFALSE(ReadInIncompatibleAttachmentStats(fileName),INCOMPATIBLEATTACHMENTSFILENAME);
+
+ //WarmSteel - Attachment slots related xml's
+ strcpy(fileName, directoryName);
+ strcat(fileName, ATTACHMENTSLOTSFILENAME);
+ SGP_THROW_IFFALSE(ReadInAttachmentSlotsStats(fileName),ATTACHMENTSLOTSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ENEMYGUNCHOICESFILENAME);
- THROWIFFALSE(ReadInExtendedArmyGunChoicesStats (fileName),ENEMYGUNCHOICESFILENAME);
+ SGP_THROW_IFFALSE(ReadInExtendedArmyGunChoicesStats (fileName),ENEMYGUNCHOICESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ENEMYITEMCHOICESFILENAME);
- THROWIFFALSE(ReadInArmyItemChoicesStats(fileName),ENEMYITEMCHOICESFILENAME);
+ SGP_THROW_IFFALSE(ReadInArmyItemChoicesStats(fileName),ENEMYITEMCHOICESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, IMPITEMCHOICESFILENAME);
- THROWIFFALSE(ReadInIMPItemChoicesStats(fileName),IMPITEMCHOICESFILENAME);
+ SGP_THROW_IFFALSE(ReadInIMPItemChoicesStats(fileName),IMPITEMCHOICESFILENAME);
+
+ std::copy(DefaultarmsDealerInfo,
+ DefaultarmsDealerInfo + sizeof(DefaultarmsDealerInfo)/sizeof(*DefaultarmsDealerInfo),
+ armsDealerInfo.begin());
strcpy(fileName, directoryName);
strcat(fileName, TONYINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gTonyInventory,fileName),TONYINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gTonyInventory,fileName),TONYINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, DEVININVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gDevinInventory,fileName),DEVININVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gDevinInventory,fileName),DEVININVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, FRANZINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gFranzInventory,fileName),FRANZINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gFranzInventory,fileName),FRANZINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, KEITHINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gKeithInventory,fileName),KEITHINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gKeithInventory,fileName),KEITHINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, SAMINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gSamInventory,fileName),SAMINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gSamInventory,fileName),SAMINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, JAKEINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gJakeInventory,fileName),JAKEINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gJakeInventory,fileName),JAKEINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, HOWARDINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gHowardInventory,fileName),HOWARDINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gHowardInventory,fileName),HOWARDINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, GABBYINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gGabbyInventory,fileName),GABBYINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gGabbyInventory,fileName),GABBYINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, FRANKINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gFrankInventory,fileName),FRANKINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gFrankInventory,fileName),FRANKINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ELGININVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gElginInventory,fileName),ELGININVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gElginInventory,fileName),ELGININVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, MANNYINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gMannyInventory,fileName),MANNYINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gMannyInventory,fileName),MANNYINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, HERVEINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gHerveInventory,fileName),HERVEINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gHerveInventory,fileName),HERVEINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, PETERINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gPeterInventory,fileName),PETERINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gPeterInventory,fileName),PETERINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ALBERTOINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gAlbertoInventory,fileName),ALBERTOINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gAlbertoInventory,fileName),ALBERTOINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, CARLOINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gCarloInventory,fileName),CARLOINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gCarloInventory,fileName),CARLOINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, MICKEYINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gMickyInventory,fileName),MICKEYINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gMickyInventory,fileName),MICKEYINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ARNIEINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gArnieInventory,fileName),ARNIEINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gArnieInventory,fileName),ARNIEINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, PERKOINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gPerkoInventory,fileName),PERKOINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gPerkoInventory,fileName),PERKOINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, FREDOINVENTORYFILENAME);
- THROWIFFALSE(ReadInInventoryStats(gFredoInventory,fileName),FREDOINVENTORYFILENAME);
+ SGP_THROW_IFFALSE(ReadInInventoryStats(gFredoInventory,fileName),FREDOINVENTORYFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, CITYTABLEFILENAME);
- THROWIFFALSE(ReadInMapStructure(fileName, FALSE),CITYTABLEFILENAME);
+ SGP_THROW_IFFALSE(ReadInMapStructure(fileName, FALSE),CITYTABLEFILENAME);
#ifndef ENGLISH
AddLanguagePrefix(fileName);
@@ -474,113 +523,365 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
// Lesh: load altsectors list
strcpy(fileName, directoryName);
strcat(fileName, ALTSECTORSFILENAME);
- THROWIFFALSE(ReadInAltSectors(fileName),ALTSECTORSFILENAME);
+ SGP_THROW_IFFALSE(ReadInAltSectors(fileName),ALTSECTORSFILENAME);
// Lesh: load samsites - must be after cities.xml
strcpy(fileName, directoryName);
strcat(fileName, SAMSITESFILENAME);
- THROWIFFALSE(ReadInSAMInfo(fileName),SAMSITESFILENAME);
+ SGP_THROW_IFFALSE(ReadInSAMInfo(fileName),SAMSITESFILENAME);
// Lesh: army externalization
strcpy(fileName, directoryName);
strcat(fileName, GARRISONFILENAME);
- THROWIFFALSE(ReadInGarrisonInfo(fileName),GARRISONFILENAME);
+ SGP_THROW_IFFALSE(ReadInGarrisonInfo(fileName),GARRISONFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, PATROLFILENAME);
- THROWIFFALSE(ReadInPatrolInfo(fileName),PATROLFILENAME);
+ SGP_THROW_IFFALSE(ReadInPatrolInfo(fileName),PATROLFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, COMPOSITIONFILENAME);
- THROWIFFALSE(ReadInArmyCompositionInfo(fileName),COMPOSITIONFILENAME);
+ SGP_THROW_IFFALSE(ReadInArmyCompositionInfo(fileName),COMPOSITIONFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, EXPLOSIONDATAFILENAME);
- THROWIFFALSE(ReadInExplosionDataStats(fileName),EXPLOSIONDATAFILENAME);
+ SGP_THROW_IFFALSE(ReadInExplosionDataStats(fileName),EXPLOSIONDATAFILENAME);
// Kaiden: Read in Restricted Sectors for Mobile Militia
strcpy(fileName, directoryName);
strcat(fileName, ROAMINGMILITIAFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInRoamingInfo(fileName),ROAMINGMILITIAFILENAME);
+ SGP_THROW_IFFALSE(ReadInRoamingInfo(fileName),ROAMINGMILITIAFILENAME);
// Dealtar: Read in shipping destinations and delivery methods
gPostalService.Clear();
strcpy(fileName, directoryName);
strcat(fileName, SHIPPINGDESTINATIONSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInShippingDestinations(fileName, FALSE),SHIPPINGDESTINATIONSFILENAME);
+ SGP_THROW_IFFALSE(ReadInShippingDestinations(fileName, FALSE),SHIPPINGDESTINATIONSFILENAME);
#ifndef ENGLISH
AddLanguagePrefix(fileName);
if ( FileExists(fileName) )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInShippingDestinations(fileName, TRUE),SHIPPINGDESTINATIONSFILENAME);
+ SGP_THROW_IFFALSE(ReadInShippingDestinations(fileName, TRUE),SHIPPINGDESTINATIONSFILENAME);
}
#endif
strcpy(fileName, directoryName);
strcat(fileName, DELIVERYMETHODSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInDeliveryMethods(fileName),DELIVERYMETHODSFILENAME);
+ SGP_THROW_IFFALSE(ReadInDeliveryMethods(fileName),DELIVERYMETHODSFILENAME);
// HEADROCK HAM 3.5: Read in facility types
strcpy(fileName, directoryName);
strcat(fileName, FACILITYTYPESFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInFacilityTypes(fileName), FACILITYTYPESFILENAME);
+ SGP_THROW_IFFALSE(ReadInFacilityTypes(fileName,FALSE), FACILITYTYPESFILENAME);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInFacilityTypes(fileName,TRUE))
+ return FALSE;
+ }
+#endif
// HEADROCK HAM 3.4: Read in facility locations
strcpy(fileName, directoryName);
strcat(fileName, SECTORFACILITIESFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInSectorFacilities(fileName), SECTORFACILITIESFILENAME);
+ SGP_THROW_IFFALSE(ReadInSectorFacilities(fileName), SECTORFACILITIESFILENAME);
// HEADROCK HAM 3.4: Read in dynamic roaming restrictions
strcpy(fileName, directoryName);
strcat(fileName, DYNAMICROAMINGFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInDynamicRoamingRestrictions(fileName), DYNAMICROAMINGFILENAME);
+ SGP_THROW_IFFALSE(ReadInDynamicRoamingRestrictions(fileName), DYNAMICROAMINGFILENAME);
// HEADROCK HAM 3.6: Read in customized sector names
strcpy(fileName, directoryName);
strcat(fileName, SECTORNAMESFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInSectorNames(fileName), SECTORNAMESFILENAME);
+ SGP_THROW_IFFALSE(ReadInSectorNames(fileName,FALSE,0), SECTORNAMESFILENAME);
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInSectorNames(fileName,TRUE,0))
+ return FALSE;
+ }
+#endif
+
+ // moved to lua
+ //strcpy(fileName, directoryName);
+ //strcat(fileName, SECTORLEVEL1NAMESFILENAME);
+ //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ //SGP_THROW_IFFALSE(ReadInSectorNames(fileName,FALSE,1), SECTORLEVEL1NAMESFILENAME);
+ //
+ //#ifndef ENGLISH
+ //AddLanguagePrefix(fileName);
+ //if ( FileExists(fileName) )
+ //{
+ // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ // if(!ReadInSectorNames(fileName,TRUE,1))
+ // return FALSE;
+ //}
+ //#endif
+
+ //strcpy(fileName, directoryName);
+ //strcat(fileName, SECTORLEVEL2NAMESFILENAME);
+ //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ //SGP_THROW_IFFALSE(ReadInSectorNames(fileName,FALSE,2), SECTORLEVEL2NAMESFILENAME);
+ //
+ //#ifndef ENGLISH
+ //AddLanguagePrefix(fileName);
+ //if ( FileExists(fileName) )
+ //{
+ // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ // if(!ReadInSectorNames(fileName,TRUE,2))
+ // return FALSE;
+ //}
+ //#endif
+
+ //strcpy(fileName, directoryName);
+ //strcat(fileName, SECTORLEVEL3NAMESFILENAME);
+ //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ //SGP_THROW_IFFALSE(ReadInSectorNames(fileName,FALSE,3), SECTORLEVEL3NAMESFILENAME);
+ //
+ //#ifndef ENGLISH
+ //AddLanguagePrefix(fileName);
+ //if ( FileExists(fileName) )
+ //{
+ // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ // if(!ReadInSectorNames(fileName,TRUE,3))
+ // return FALSE;
+ //}
+ //#endif
+
+ // code duplication?
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInSectorNames(fileName,TRUE,0))
+ return FALSE;
+ }
+#endif
+
+ // WANNE: Why do we need it. It should also run without that file!!
+ // SANDRO - always initialize those files, we need it on game start
if (gGameExternalOptions.fReadProfileDataFromXML)
{
// HEADROCK PROFEX: Read in Merc Profile data to replace PROF.DAT data
strcpy(fileName, directoryName);
strcat(fileName, MERCPROFILESFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInMercProfiles(fileName), MERCPROFILESFILENAME);
+ SGP_THROW_IFFALSE(ReadInMercProfiles(fileName, FALSE), MERCPROFILESFILENAME);
+
+ #ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInMercProfiles(fileName,TRUE))
+ return FALSE;
+ }
+ #endif
// HEADROCK PROFEX: Read in Merc Opinion data to replace PROF.DAT data
strcpy(fileName, directoryName);
strcat(fileName, MERCOPINIONSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInMercOpinions(fileName), MERCOPINIONSFILENAME);
+ SGP_THROW_IFFALSE(ReadInMercOpinions(fileName), MERCOPINIONSFILENAME);
}
// HEADROCK HAM 3.6: Read in customized Bloodcat Placements
strcpy(fileName, directoryName);
strcat(fileName, BLOODCATPLACEMENTSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInBloodcatPlacements(fileName), BLOODCATPLACEMENTSFILENAME);
+ SGP_THROW_IFFALSE(ReadInBloodcatPlacements(fileName), BLOODCATPLACEMENTSFILENAME);
// HEADROCK HAM 3.6: Read in customized Uniform Colors
strcpy(fileName, directoryName);
strcat(fileName, UNIFORMCOLORSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
- THROWIFFALSE(ReadInUniforms(fileName), UNIFORMCOLORSFILENAME);
+ SGP_THROW_IFFALSE(ReadInUniforms(fileName), UNIFORMCOLORSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, MULTIPLAYERTEAMSFILENAME);
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
mpTeams.ReadInMPTeams(fileName);
+ //legion by jazz (load small faces from rpcs)
+ strcpy(fileName, directoryName);
+ strcat(fileName, RPCFACESSMALLFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInSmallFacesStats(gRPCSmallFaceValues,fileName), RPCFACESSMALLFILENAME);
+ ResetEmptyRPCFaceSlots();
+
+ //Hidden Names by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, HIDDENNAMESFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInHiddenNamesStats(zHiddenNames,fileName), HIDDENNAMESFILENAME);
+
+
+
+ if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
+ {
+ // Enemy Names Group by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYNAMESFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInEnemyNames(fileName,FALSE), ENEMYNAMESFILENAME);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyNames(fileName,TRUE))
+ return FALSE;
+ }
+#endif
+ }
+
+
+ if (gGameExternalOptions.fCivGroupName == TRUE)
+ {
+ // Civ Names Group by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, CIVGROUPNAMESFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInCivGroupNamesStats(fileName,FALSE), CIVGROUPNAMESFILENAME);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInCivGroupNamesStats(fileName,TRUE))
+ return FALSE;
+ }
+#endif
+ }
+
+
+ // Sender Name List by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, SENDERNAMELISTFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInSenderNameList(fileName,FALSE), SENDERNAMELISTFILENAME);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInSenderNameList(fileName,TRUE))
+ return FALSE;
+ }
+#endif
+
+ if (gGameExternalOptions.fEnemyNames == FALSE && gGameExternalOptions.fEnemyRank == TRUE)
+ {
+ // Enemy Rank by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, ENEMYRANKFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInEnemyRank(fileName,FALSE), ENEMYRANKFILENAME);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInEnemyRank(fileName,TRUE))
+ return FALSE;
+ }
+#endif
+ }
+
+ // IMP Portraits List by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, IMPPORTRAITS);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInIMPPortraits(fileName,FALSE), IMPPORTRAITS);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInIMPPortraits(fileName,TRUE))
+ return FALSE;
+ }
+#endif
+
+ LoadIMPPortraitsTEMP();
+
+ //Sound profile by jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, SOUNDPROFILE);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInSoundProfile(fileName), SOUNDPROFILE);
+
+ //Random stats by jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, RANDOMSTATS);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInRandomStats(fileName), RANDOMSTATS);
+ //new profiles by Jazz
+ strcpy(fileName, directoryName);
+ strcat(fileName, MERCAVAILABILITY);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInMercAvailability(fileName,FALSE), MERCAVAILABILITY);
+
+#ifndef ENGLISH
+ AddLanguagePrefix(fileName);
+ if ( FileExists(fileName) )
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ if(!ReadInMercAvailability(fileName,TRUE))
+ return FALSE;
+ }
+#endif
+ UINT32 i;
+ for(i=0; i
+
+#include "Luaglobal.h"
+#include "LuaInitNPCs.h"
+#include "XML.h"
+
+BOOLEAN Style_JA = TRUE;
+extern INT8 Test = 0;
+
+UINT32 iStringToUseLua = -1;
+// BF
+class VideoPlayer
+{
+public:
+ enum VideoType
+ {
+ VT_NONE = 0,
+ VT_SMK = 1,
+ VT_BINK = 2,
+ };
+ VideoPlayer(UINT32 type) : _type(type), _smk(NULL), _bink(NULL), _current(VT_NONE)
+ {
+ }
+ void Initialize()
+ {
+ if(_type & VT_SMK)
+ {
+ SmkInitialize( ghWindow, SCREEN_WIDTH, SCREEN_HEIGHT);
+ }
+ if(_type & VT_BINK)
+ {
+ BinkInitialize(ghWindow, SCREEN_WIDTH, SCREEN_HEIGHT);
+ }
+ }
+ void Shutdown()
+ {
+ if(_type & VT_SMK)
+ {
+ SmkShutdown();
+ }
+ if(_type & VT_BINK)
+ {
+ BinkShutdownVideo();
+ }
+ }
+
+ bool isValid()
+ {
+ if( (_current == VT_SMK && _smk && !_bink) || (_current == VT_BINK && !_smk && _bink) )
+ {
+ return true;
+ }
+ return false;
+ }
+
+ bool isPlaying()
+ {
+ if( _current == VT_SMK && _smk && !_bink )
+ {
+ return SmkPollFlics() != 0;
+ }
+ else if(_current == VT_BINK && !_smk && _bink)
+ {
+ return BinkPollFlics() != 0;
+ }
+ else if(_current == VT_NONE && !_smk && !_bink)
+ {
+ return false;
+ }
+ SGP_THROW(L"Invalid Video Player state!");
+ }
+
+ void stopVideo()
+ {
+ if(_current == VT_SMK && _smk && !_bink)
+ {
+ SmkCloseFlic(_smk);
+ _smk = NULL;
+ }
+ else if(_current == VT_BINK && !_smk && _bink)
+ {
+ BinkCloseFlic(_bink);
+ _bink = NULL;
+ }
+ _current = VT_NONE;
+ }
+
+ bool startVideo(std::string const& filename)
+ {
+ if(isPlaying())
+ {
+ return false;
+ }
+
+ /// check file extension
+ std::string ext;
+ std::string::size_type pos = filename.find_last_of(".");
+ if(pos != std::string::npos)
+ {
+ ext = filename.substr(pos, filename.size() - pos);
+ }
+ if(vfs::StrCmp::Equal(ext, ".smk"))
+ {
+ return startSmkVideo(filename);
+ }
+ else if(vfs::StrCmp::Equal(ext, ".bik"))
+ {
+ return startBinkVideo(filename);
+ }
+ else if(ext.empty())
+ {
+ // try .bik first
+ if(!startBinkVideo(filename + ".bik"))
+ {
+ return startSmkVideo(filename + ".smk");
+ }
+ return true;
+ }
+ else
+ {
+ SGP_INFO(L"Unknown video file format");
+ }
+ return false;
+ }
+private:
+ bool startSmkVideo(std::string const& filename)
+ {
+ _smk = SmkPlayFlic( filename.c_str(), (SCREEN_WIDTH-640)/2, (SCREEN_HEIGHT-480)/2, TRUE );
+ if(_smk)
+ {
+ _current = VT_SMK;
+ return true;
+ }
+ return false;
+ }
+ bool startBinkVideo(std::string const& filename)
+ {
+ _bink = BinkPlayFlic( filename.c_str(), (SCREEN_WIDTH-640)/2, (SCREEN_HEIGHT-480)/2, BINK_FLIC_AUTOCLOSE | BINK_FLIC_CENTER_VERTICAL);
+ if(_bink)
+ {
+ _current = VT_BINK;
+ return true;
+ }
+ return false;
+ }
+private:
+ UINT32 _type;
+ SMKFLIC* _smk;
+ BINKFLIC* _bink;
+ VideoType _current;
+};
+
+static VideoPlayer s_VP(VideoPlayer::VT_SMK | VideoPlayer::VT_BINK);
extern STR16 gzIntroScreen[];
extern HVSURFACE ghFrameBuffer;
@@ -54,37 +209,37 @@ UINT32 guiIntroExitScreen = INTRO_SCREEN;
extern BOOLEAN gfDoneWithSplashScreen;
-SMKFLIC *gpSmackFlic = NULL;
-
-#define SMKINTRO_FIRST_VIDEO 255
-#define SMKINTRO_NO_VIDEO -1
+//BF SMKFLIC *gpSmackFlic = NULL;
//enums for the various smacker files
-enum
+enum EGameVideos
{
- SMKINTRO_REBEL_CRDT,
- SMKINTRO_OMERTA,
- SMKINTRO_PRAGUE_CRDT,
- SMKINTRO_PRAGUE,
+ INTRO_NO_VIDEO = -1,
+ INTRO_REBEL_CRDT = 0,
+ INTRO_OMERTA,
+ INTRO_PRAGUE_CRDT,
+ INTRO_PRAGUE,
//there are no more videos shown for the begining
- SMKINTRO_END_END_SPEECH_MIGUEL,
- SMKINTRO_END_END_SPEECH_NO_MIGUEL,
- SMKINTRO_END_HELI_FLYBY,
- SMKINTRO_END_SKYRIDER_HELICOPTER,
- SMKINTRO_END_NOSKYRIDER_HELICOPTER,
+ INTRO_END_END_SPEECH_MIGUEL,
+ INTRO_END_END_SPEECH_NO_MIGUEL,
+ INTRO_END_HELI_FLYBY,
+ INTRO_END_SKYRIDER_HELICOPTER,
+ INTRO_END_NOSKYRIDER_HELICOPTER,
- SMKINTRO_SPLASH_SCREEN,
- SMKINTRO_SPLASH_TALONSOFT,
+ INTRO_SPLASH_SCREEN,
+ INTRO_SPLASH_TALONSOFT,
//there are no more videos shown for the endgame
- SMKINTRO_LAST_END_GAME,
+ INTRO_LAST_END_GAME,
+
+ INTRO_FIRST_VIDEO = 255
};
-INT32 giCurrentIntroBeingPlayed = SMKINTRO_NO_VIDEO;
-
+EGameVideos giCurrentIntroBeingPlayed = INTRO_NO_VIDEO;
+/*
CHAR *gpzSmackerFileNames[] =
{
//begining of the game
@@ -104,7 +259,9 @@ CHAR *gpzSmackerFileNames[] =
"INTRO\\SplashScreen.smk",
"INTRO\\TalonSoftid_endhold.smk",
};
-
+*/
+typedef std::map VideoFileNames_t;
+static VideoFileNames_t s_VFN;
//enums used for when the intro screen can come up, either begining game intro, or end game cinematic
INT8 gbIntroScreenMode=-1;
@@ -112,15 +269,15 @@ INT8 gbIntroScreenMode=-1;
extern void CDromEjectionErrorMessageBoxCallBack( UINT8 bExitValue );
-void GetIntroScreenUserInput();
-BOOLEAN EnterIntroScreen();
-void RenderIntroScreen();
-void ExitIntroScreen();
-void HandleIntroScreen();
-void PrepareToExitIntroScreen();
-INT32 GetNextIntroVideo( UINT32 uiCurrentVideo );
-void StartPlayingIntroFlic( INT32 iIndexOfFlicToPlay );
-void DisplaySirtechSplashScreen();
+void GetIntroScreenUserInput();
+BOOLEAN EnterIntroScreen();
+void RenderIntroScreen();
+void ExitIntroScreen();
+void HandleIntroScreen();
+void PrepareToExitIntroScreen();
+EGameVideos GetNextIntroVideo( EGameVideos uiCurrentVideo );
+void StartPlayingIntroFlic( EGameVideos iIndexOfFlicToPlay );
+void DisplaySirtechSplashScreen();
//ppp
@@ -131,6 +288,24 @@ UINT32 IntroScreenInit( void )
//Set so next time we come in, we can set up
gfIntroScreenEntry = TRUE;
+ CIniReader inireader("IntroVideos.ini");
+ s_VFN[INTRO_REBEL_CRDT] = inireader.ReadString("INTRO_BEGINNING","INTRO_REBEL_CRDT","INTRO\\Rebel_cr");
+ s_VFN[INTRO_OMERTA] = inireader.ReadString("INTRO_BEGINNING","INTRO_OMERTA","INTRO\\Omerta");
+ s_VFN[INTRO_PRAGUE_CRDT] = inireader.ReadString("INTRO_BEGINNING","INTRO_PRAGUE_CRDT","INTRO\\Prague_cr");
+ s_VFN[INTRO_PRAGUE] = inireader.ReadString("INTRO_BEGINNING","INTRO_PRAGUE","INTRO\\Prague");
+
+ //there are no more videos shown for the begining
+ s_VFN[INTRO_END_END_SPEECH_MIGUEL] = inireader.ReadString("INTRO_ENDING","INTRO_END_END_SPEECH_MIGUEL","INTRO\\Throne_Mig");
+ s_VFN[INTRO_END_END_SPEECH_NO_MIGUEL] = inireader.ReadString("INTRO_ENDING","INTRO_END_END_SPEECH_NO_MIGUEL","INTRO\\Throne_NoMig");
+ s_VFN[INTRO_END_HELI_FLYBY] = inireader.ReadString("INTRO_ENDING","INTRO_END_HELI_FLYBY","INTRO\\Heli_FlyBy");
+ s_VFN[INTRO_END_SKYRIDER_HELICOPTER] = inireader.ReadString("INTRO_ENDING","INTRO_END_SKYRIDER_HELICOPTER","INTRO\\Heli_Sky");
+ s_VFN[INTRO_END_NOSKYRIDER_HELICOPTER] = inireader.ReadString("INTRO_ENDING","INTRO_END_NOSKYRIDER_HELICOPTER","INTRO\\Heli_NoSky");
+
+ s_VFN[INTRO_SPLASH_SCREEN] = inireader.ReadString("INTRO_SPLASH","INTRO_SPLASH_SCREEN","INTRO\\SplashScreen");
+ s_VFN[INTRO_SPLASH_TALONSOFT] = inireader.ReadString("INTRO_SPLASH","INTRO_SPLASH_TALONSOFT","INTRO\\TalonSoftid_endhold");
+
+ //there are no more videos shown for the endgame
+
return( 1 );
}
@@ -176,11 +351,11 @@ UINT32 IntroScreenHandle( void )
BOOLEAN EnterIntroScreen()
{
- INT32 iFirstVideoID = -1;
+
+Test = 0;
ClearMainMenu();
-
SetCurrentCursorFromDatabase( VIDEO_NO_CURSOR );
// Don't play music....
@@ -193,28 +368,11 @@ BOOLEAN EnterIntroScreen()
return( TRUE );
}
-//#ifdef JA2BETAVERSION
-// if( FileExists( "..\\NoIntro.txt" ) )
-// {
-// PrepareToExitIntroScreen();
-// return( TRUE );
-// }
-//#endif
-#ifndef USE_VFS
- //if the library doesnt exist, exit
- if( !IsLibraryOpened( LIBRARY_INTRO ) )
- {
- PrepareToExitIntroScreen();
- return( TRUE );
- }
-#endif
-
- //initialize smacker
- SmkInitialize( ghWindow, SCREEN_WIDTH, SCREEN_HEIGHT);
-
+ //initialize video player
+ s_VP.Initialize();
//get the index opf the first video to watch
- iFirstVideoID = GetNextIntroVideo( SMKINTRO_FIRST_VIDEO );
+ EGameVideos iFirstVideoID = GetNextIntroVideo( INTRO_FIRST_VIDEO );
if( iFirstVideoID != -1 )
{
@@ -239,29 +397,23 @@ void RenderIntroScreen()
void ExitIntroScreen()
{
-
- //shutdown smaker
- SmkShutdown();
+ //shutdown video player
+ s_VP.Shutdown();
}
void HandleIntroScreen()
{
- BOOLEAN fFlicStillPlaying = FALSE;
-
//if we are exiting this screen, this frame, dont update the screen
if( gfIntroScreenExit )
return;
-
- //handle smaker each frame
- fFlicStillPlaying = SmkPollFlics();
+ //handle video in each frame
+ BOOLEAN fFlicStillPlaying = s_VP.isPlaying();
//if the flic is not playing
if( !fFlicStillPlaying )
{
- INT32 iNextVideoToPlay = -1;
-
- iNextVideoToPlay = GetNextIntroVideo( giCurrentIntroBeingPlayed );
+ EGameVideos iNextVideoToPlay = GetNextIntroVideo( giCurrentIntroBeingPlayed );
if( iNextVideoToPlay != -1 )
{
@@ -270,7 +422,7 @@ void HandleIntroScreen()
else
{
PrepareToExitIntroScreen();
- giCurrentIntroBeingPlayed = -1;
+ giCurrentIntroBeingPlayed = INTRO_NO_VIDEO;
}
}
@@ -279,12 +431,11 @@ void HandleIntroScreen()
-void GetIntroScreenUserInput()
+void GetIntroScreenUserInput()
{
InputAtom Event;
POINT MousePos;
-
GetCursorPos(&MousePos);
ScreenToClient(ghWindow, &MousePos); // In window coords!
@@ -292,7 +443,7 @@ void GetIntroScreenUserInput()
{
// HOOK INTO MOUSE HOOKS
switch( Event.usEvent)
- {
+ {
case LEFT_BUTTON_DOWN:
MouseSystemHook(LEFT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown);
break;
@@ -313,16 +464,16 @@ void GetIntroScreenUserInput()
break;
}
-
if( Event.usEvent == KEY_UP )
{
switch( Event.usParam )
{
case ESC:
+ s_VP.stopVideo();
PrepareToExitIntroScreen();
break;
case SPACE:
- SmkCloseFlic( gpSmackFlic );
+ s_VP.stopVideo();
break;
#ifdef JA2TESTVERSION
@@ -343,15 +494,18 @@ void GetIntroScreenUserInput()
if( gfLeftButtonState || gfRightButtonState )
{
//advance to the next flic
- SmkCloseFlic( gpSmackFlic );
+ s_VP.stopVideo();
}
}
void PrepareToExitIntroScreen()
{
+#ifdef LUA_INTRO
+ LuaIntro(0, 0, 0, 0);
+#else
//if its the intro at the begining of the game
- if( gbIntroScreenMode == INTRO_BEGINING )
+ if( gbIntroScreenMode == INTRO_BEGINNING )
{
//go to the init screen
guiIntroExitScreen = INIT_SCREEN;
@@ -374,110 +528,121 @@ void PrepareToExitIntroScreen()
}
gfIntroScreenExit = TRUE;
+#endif
}
-INT32 GetNextIntroVideo( UINT32 uiCurrentVideo )
+EGameVideos GetNextIntroVideo( EGameVideos uiCurrentVideo )
{
- INT32 iStringToUse = -1;
-
+ EGameVideos iStringToUse = INTRO_NO_VIDEO;
+#ifdef LUA_INTRO
+ switch( Test )
+ {
+ case 0:
+ LuaIntro(1, uiCurrentVideo, 0, 0);
+ iStringToUse = (EGameVideos)iStringToUseLua;
+ //Test = 1;
+ break;
+ }
+#else
//switch on whether it is the beginging or the end game video
switch( gbIntroScreenMode )
{
//the video at the begining of the game
- case INTRO_BEGINING:
+ case INTRO_BEGINNING:
{
switch( uiCurrentVideo )
{
- case SMKINTRO_FIRST_VIDEO:
- iStringToUse = SMKINTRO_REBEL_CRDT;
+ case INTRO_FIRST_VIDEO:
+ iStringToUse = INTRO_REBEL_CRDT;
break;
- case SMKINTRO_REBEL_CRDT:
- iStringToUse = SMKINTRO_OMERTA;
+ case INTRO_REBEL_CRDT:
+ iStringToUse = INTRO_OMERTA;
break;
- case SMKINTRO_OMERTA:
- iStringToUse = SMKINTRO_PRAGUE_CRDT;
+ case INTRO_OMERTA:
+ iStringToUse = INTRO_PRAGUE_CRDT;
break;
- case SMKINTRO_PRAGUE_CRDT:
- iStringToUse = SMKINTRO_PRAGUE;
+ case INTRO_PRAGUE_CRDT:
+ iStringToUse = INTRO_PRAGUE;
break;
- case SMKINTRO_PRAGUE:
- iStringToUse = -1;
+ case INTRO_PRAGUE:
+ iStringToUse = INTRO_NO_VIDEO;
break;
-// case SMKINTRO_LAST_INTRO:
+// case INTRO_LAST_INTRO:
// iStringToUse = -1;
// break;
}
+ break;
}
- break;
//end game
case INTRO_ENDING:
{
switch( uiCurrentVideo )
{
- case SMKINTRO_FIRST_VIDEO:
+ case INTRO_FIRST_VIDEO:
+ {
//if Miguel is dead, play the flic with out him in it
if( gMercProfiles[ MIGUEL ].bMercStatus == MERC_IS_DEAD )
- iStringToUse = SMKINTRO_END_END_SPEECH_NO_MIGUEL;
+ iStringToUse = INTRO_END_END_SPEECH_NO_MIGUEL;
else
- iStringToUse = SMKINTRO_END_END_SPEECH_MIGUEL;
+ iStringToUse = INTRO_END_END_SPEECH_MIGUEL;
break;
-
- case SMKINTRO_END_END_SPEECH_MIGUEL:
- case SMKINTRO_END_END_SPEECH_NO_MIGUEL:
- iStringToUse = SMKINTRO_END_HELI_FLYBY;
+ }
+ case INTRO_END_END_SPEECH_MIGUEL:
+ case INTRO_END_END_SPEECH_NO_MIGUEL:
+ {
+ iStringToUse = INTRO_END_HELI_FLYBY;
break;
-
+ }
//if SkyRider is dead, play the flic without him
- case SMKINTRO_END_HELI_FLYBY:
+ case INTRO_END_HELI_FLYBY:
+ {
if( gMercProfiles[ SKYRIDER ].bMercStatus == MERC_IS_DEAD )
- iStringToUse = SMKINTRO_END_NOSKYRIDER_HELICOPTER;
+ iStringToUse = INTRO_END_NOSKYRIDER_HELICOPTER;
else
- iStringToUse = SMKINTRO_END_SKYRIDER_HELICOPTER;
+ iStringToUse = INTRO_END_SKYRIDER_HELICOPTER;
break;
+ }
}
+ break;
}
- break;
case INTRO_SPLASH:
switch( uiCurrentVideo )
{
- case SMKINTRO_FIRST_VIDEO:
- iStringToUse = SMKINTRO_SPLASH_SCREEN;
+ case INTRO_FIRST_VIDEO:
+ iStringToUse = INTRO_SPLASH_SCREEN;
break;
- case SMKINTRO_SPLASH_SCREEN:
+ case INTRO_SPLASH_SCREEN:
//iStringToUse = SMKINTRO_SPLASH_TALONSOFT;
break;
}
break;
}
+#endif
return( iStringToUse );
}
-void StartPlayingIntroFlic( INT32 iIndexOfFlicToPlay )
+void StartPlayingIntroFlic( EGameVideos iIndexOfFlicToPlay )
{
-
if( iIndexOfFlicToPlay != -1 )
{
+ giCurrentIntroBeingPlayed = iIndexOfFlicToPlay;
//start playing a flic
- gpSmackFlic = SmkPlayFlic( gpzSmackerFileNames[ iIndexOfFlicToPlay ], (SCREEN_WIDTH-640)/2, (SCREEN_HEIGHT-480)/2, TRUE );
-
- if( gpSmackFlic != NULL )
+ if(s_VP.startVideo( s_VFN[iIndexOfFlicToPlay] ))
{
- giCurrentIntroBeingPlayed = iIndexOfFlicToPlay;
- }
- else
- {
- //do a check
+ if(!s_VP.isValid())
+ {
+ //do a check
#ifdef JA2BETAVERSION
- PrepareToExitIntroScreen();
+ PrepareToExitIntroScreen();
#else
-
- DoScreenIndependantMessageBox( gzIntroScreen[INTRO_TXT__CANT_FIND_INTRO], MSG_BOX_FLAG_OK, CDromEjectionErrorMessageBoxCallBack );
+ DoScreenIndependantMessageBox( gzIntroScreen[INTRO_TXT__CANT_FIND_INTRO], MSG_BOX_FLAG_OK, CDromEjectionErrorMessageBoxCallBack );
#endif
+ }
}
}
}
@@ -485,9 +650,12 @@ void StartPlayingIntroFlic( INT32 iIndexOfFlicToPlay )
void SetIntroType( INT8 bIntroType )
{
- if( bIntroType == INTRO_BEGINING )
+#ifdef LUA_INTRO
+ LuaIntro(2, 0, bIntroType, 0);
+#else
+ if( bIntroType == INTRO_BEGINNING )
{
- gbIntroScreenMode = INTRO_BEGINING;
+ gbIntroScreenMode = INTRO_BEGINNING;
}
else if( bIntroType == INTRO_ENDING )
{
@@ -497,58 +665,53 @@ void SetIntroType( INT8 bIntroType )
{
gbIntroScreenMode = INTRO_SPLASH;
}
+#endif
}
void DisplaySirtechSplashScreen()
{
- HVOBJECT hPixHandle;
- VOBJECT_DESC VObjectDesc;
- UINT32 uiLogoID;
-
- UINT32 uiDestPitchBYTES;
- UINT8 *pDestBuf;
-
-
// CLEAR THE FRAME BUFFER
- pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
+ UINT32 uiDestPitchBYTES;
+ UINT8* pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
memset(pDestBuf, 0, SCREEN_HEIGHT * uiDestPitchBYTES );
UnLockVideoSurface( FRAME_BUFFER );
-
+ VOBJECT_DESC VObjectDesc;
memset( &VObjectDesc, 0, sizeof( VOBJECT_DESC ) );
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\SirtechSplash.sti", VObjectDesc.ImageFile);
-
// FilenameForBPP("INTERFACE\\TShold.sti", VObjectDesc.ImageFile);
+
+ UINT32 uiLogoID;
if( !AddVideoObject(&VObjectDesc, &uiLogoID) )
{
FilenameForBPP("GERMAN\\SPLASH_GERMAN.sti", VObjectDesc.ImageFile);
- if( !AddVideoObject(&VObjectDesc, &uiLogoID) )
- {
- /*
- * This is the place, where most non english coders stranding.
- * Don't hesitate, don't give up!
- * I'll now tell You what You made wrong
- * (2006-10-10, Sergeant_Kolja)
- */
- #ifdef _DEBUG
- # if defined(ENGLISH)
- AssertMsg( 0, String( "Wheter English nor German works. May be You built English - but have only German or other foreign Disk?" ) );
- # elif defined(GERMAN)
- AssertMsg( 0, String( "Weder Englisch noch Deutsch geht. Deutsche Version kompiliert und mit englischer CDs gestartet? Das geht nicht!" ) );
- # endif
- #endif
- AssertMsg( 0, String( "Failed to load %s", VObjectDesc.ImageFile ) );
- return;
- }
+ if( !AddVideoObject(&VObjectDesc, &uiLogoID) )
+ {
+ /*
+ * This is the place, where most non english coders stranding.
+ * Don't hesitate, don't give up!
+ * I'll now tell You what You made wrong
+ * (2006-10-10, Sergeant_Kolja)
+ */
+ #ifdef _DEBUG
+ # if defined(ENGLISH)
+ AssertMsg( 0, String( "Wheter English nor German works. May be You built English - but have only German or other foreign Disk?" ) );
+ # elif defined(GERMAN)
+ AssertMsg( 0, String( "Weder Englisch noch Deutsch geht. Deutsche Version kompiliert und mit englischer CDs gestartet? Das geht nicht!" ) );
+ # endif
+ #endif
+ AssertMsg( 0, String( "Failed to load %s", VObjectDesc.ImageFile ) );
+ return;
+ }
}
+ HVOBJECT hPixHandle;
GetVideoObject(&hPixHandle, uiLogoID);
BltVideoObject(FRAME_BUFFER, hPixHandle, 0,(SCREEN_WIDTH-640)/2, (SCREEN_HEIGHT-480)/2, VO_BLT_SRCTRANSPARENCY,NULL);
DeleteVideoObjectFromIndex(uiLogoID);
-
InvalidateScreen();
RefreshScreen( NULL );
}
diff --git a/Intro.h b/Intro.h
index 15a5fd09..f2bfc56e 100644
--- a/Intro.h
+++ b/Intro.h
@@ -9,9 +9,9 @@ UINT32 IntroScreenInit( void );
//enums used for when the intro screen can come up, used with 'gbIntroScreenMode'
-enum
+enum EIntroType
{
- INTRO_BEGINING, //set when viewing the intro at the begining of the game
+ INTRO_BEGINNING, //set when viewing the intro at the begining of the game
INTRO_ENDING, //set when viewing the end game video.
INTRO_SPLASH,
@@ -22,5 +22,9 @@ extern UINT32 guiSmackerSurface;
void SetIntroType( INT8 bIntroType );
+extern void DisplaySirtechSplashScreen();
+extern UINT32 guiIntroExitScreen;
+extern BOOLEAN gfIntroScreenExit;
+extern INT8 gbIntroScreenMode;
#endif
\ No newline at end of file
diff --git a/JA2 Splash.cpp b/JA2 Splash.cpp
index a933de6f..8debb31a 100644
--- a/JA2 Splash.cpp
+++ b/JA2 Splash.cpp
@@ -24,39 +24,39 @@ void InitJA2SplashScreen()
UINT32 uiLogoID = 0;
HVSURFACE hVSurface; // unused jonathanl // lalien reenabled for international versions
VSURFACE_DESC VSurfaceDesc; //unused jonathanl // lalien reenabled for international versions
- #ifdef JA2TESTVERSION
- INT32 i = 0;
+# ifdef JA2TESTVERSION
+ INT32 i = 0;
+
+ memset( &VSurfaceDesc, 0, sizeof( VSURFACE_DESC ) );
+ VSurfaceDesc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE;
+ sprintf( VSurfaceDesc.ImageFile, "LOADSCREENS\\Notification.sti" );
+ if( !AddVideoSurface( &VSurfaceDesc, &uiLogoID ) )
+ {
+ //AssertMsg( 0, String( "Failed to load %s", VSurfaceDesc.ImageFile ) );
+ return;
+ }
+ GetVideoSurface(&hVSurface, uiLogoID );
+ //BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, 0, 0, 0, NULL );
+ BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, iScreenWidthOffset, iScreenHeightOffset, 0, NULL );
+ DeleteVideoSurfaceFromIndex( uiLogoID );
+
+
+ InvalidateScreen();
+ RefreshScreen( NULL );
+
+ guiSplashStartTime = GetJA2Clock();
+ while( i < 60 * 15 )//guiSplashStartTime + 15000 > GetJA2Clock() )
+ {
+ //Allow the user to pick his bum.
+ InvalidateScreen();
+ RefreshScreen( NULL );
+ i++;
+ }
+# endif // JA2TESTVERSION
memset( &VSurfaceDesc, 0, sizeof( VSURFACE_DESC ) );
VSurfaceDesc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE;
- sprintf( VSurfaceDesc.ImageFile, "LOADSCREENS\\Notification.sti" );
- if( !AddVideoSurface( &VSurfaceDesc, &uiLogoID ) )
- {
- //AssertMsg( 0, String( "Failed to load %s", VSurfaceDesc.ImageFile ) );
- return;
- }
- GetVideoSurface(&hVSurface, uiLogoID );
- //BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, 0, 0, 0, NULL );
- BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, iScreenWidthOffset, iScreenHeightOffset, 0, NULL );
- DeleteVideoSurfaceFromIndex( uiLogoID );
-
-
- InvalidateScreen();
- RefreshScreen( NULL );
-
- guiSplashStartTime = GetJA2Clock();
- while( i < 60 * 15 )//guiSplashStartTime + 15000 > GetJA2Clock() )
- {
- //Allow the user to pick his bum.
- InvalidateScreen();
- RefreshScreen( NULL );
- i++;
- }
-#endif
-
- memset( &VSurfaceDesc, 0, sizeof( VSURFACE_DESC ) );
- VSurfaceDesc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE;
- GetMLGFilename( VSurfaceDesc.ImageFile, MLG_SPLASH );
+ GetMLGFilename( VSurfaceDesc.ImageFile, MLG_SPLASH );
try
{
if( !AddVideoSurface( &VSurfaceDesc, &uiLogoID ) )
@@ -65,15 +65,15 @@ void InitJA2SplashScreen()
return;
}
}
- catch(CBasicException &ex)
+ catch(std::exception &ex)
{
- RETHROWEXCEPTION(L"Failed loading splash screen", &ex);
+ SGP_RETHROW(L"Failed loading splash screen", ex);
}
- GetVideoSurface( &hVSurface, uiLogoID );
- BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, iScreenWidthOffset, iScreenHeightOffset, 0, NULL );
- DeleteVideoSurfaceFromIndex( uiLogoID );
- #endif
+ GetVideoSurface( &hVSurface, uiLogoID );
+ BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, iScreenWidthOffset, iScreenHeightOffset, 0, NULL );
+ DeleteVideoSurfaceFromIndex( uiLogoID );
+#endif // ENGLISH
InvalidateScreen();
RefreshScreen( NULL );
diff --git a/Language Defines.h b/Language Defines.h
index 179fce0d..e69af8d2 100644
--- a/Language Defines.h
+++ b/Language Defines.h
@@ -37,7 +37,11 @@
#endif
-
+//**ddd direct link libraries
+#pragma comment (lib, "user32.lib")
+#pragma comment (lib, "gdi32.lib")
+#pragma comment (lib, "advapi32.lib")
+#pragma comment (lib, "shell32.lib")
/* ====================================================================
* Regardless of if we did it Workspace wide or by uncommenting above,
diff --git a/Laptop/AimFacialIndex.cpp b/Laptop/AimFacialIndex.cpp
index 1874c481..8085cd03 100644
--- a/Laptop/AimFacialIndex.cpp
+++ b/Laptop/AimFacialIndex.cpp
@@ -23,12 +23,15 @@ extern UINT8 gbCurrentIndex;
UINT32 guiMugShotBorder;
-UINT32 guiAimFiFace[ MAX_NUMBER_MERCS ];
+UINT32 guiAimFiFace[ NUM_PROFILES ]; //MAX_NUMBER_MERCS
+BOOLEAN gAimProfiles[ NUM_PROFILES ];
+#define AIM_FI_NUM_MUGSHOTS_X 8
+#define AIM_FI_NUM_MUGSHOTS_Y 5
-#define AIM_FI_NUM_MUHSHOTS_X 8
-#define AIM_FI_NUM_MUHSHOTS_Y 5
+UINT8 START_MERC =0;
+UINT8 END_MERC =0;
#define AIM_FI_PORTRAIT_WIDTH 52
#define AIM_FI_PORTRAIT_HEIGHT 48
@@ -46,6 +49,9 @@ UINT32 guiAimFiFace[ MAX_NUMBER_MERCS ];
#define AIM_FI_MEMBER_TEXT_X IMAGE_OFFSET_X + 155
#define AIM_FI_MEMBER_TEXT_Y AIM_SYMBOL_Y + AIM_SYMBOL_SIZE_Y + 1
#define AIM_FI_MEMBER_TEXT_WIDTH 190
+//tais: nsgi, move member text up
+#define AIM_FI_MEMBER_TEXT_Y_NSGI AIM_SYMBOL_SMALL_Y + 35
+
#define AIM_FI_AWAY_TEXT_OFFSET_X 3
#define AIM_FI_AWAY_TEXT_OFFSET_Y 23//3//36
@@ -55,7 +61,7 @@ UINT32 guiAimFiFace[ MAX_NUMBER_MERCS ];
//Mouse Regions
//Face regions
-MOUSE_REGION gMercFaceMouseRegions[ MAX_NUMBER_MERCS ];
+MOUSE_REGION gMercFaceMouseRegions[ NUM_PROFILES ]; //MAX_NUMBER_MERCS
void SelectMercFaceRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void SelectMercFaceMoveRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason );
@@ -66,12 +72,74 @@ void SelectScreenRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason );
BOOLEAN DrawMercsFaceToScreen(UINT8 ubMercID, UINT16 usPosX, UINT16 usPosY, UINT8 ubImage);
+//New profiles
+INT32 guiPreviousNewProfilesNextButtonImage;
+void BtnNewProfilesButtonCallback(GUI_BUTTON *btn,INT32 reason);
+
+INT32 PAGE_BUTTON;
void GameInitAimFacialIndex()
{
}
+/// Calculates the needed string for the page button based on number of mercs
+/// and currently displayed page.
+static STR16 GetPageButtonText()
+{
+ const int MERCS_PER_PAGE = AIM_FI_NUM_MUGSHOTS_X * AIM_FI_NUM_MUGSHOTS_Y;
+
+ int baseTextIndex;
+ // Display three pages of mercs (strings from gszAimPages[2] to gszAimPages[4])
+ if (MAX_NUMBER_MERCS > MERCS_PER_PAGE * 2)
+ baseTextIndex = 2;
+ // Display two pages of mercs (strings from gszAimPages[0] to gszAimPages[1])
+ else if (MAX_NUMBER_MERCS > MERCS_PER_PAGE)
+ {
+ Assert(START_MERC < MERCS_PER_PAGE * 2);
+ baseTextIndex = 0;
+ }
+ // Display one page of mercs (string gszAimPages[5])
+ else
+ {
+ Assert(START_MERC < MERCS_PER_PAGE);
+ baseTextIndex = 5;
+ }
+
+ int currentPage = START_MERC / MERCS_PER_PAGE;
+ int stringIndex = baseTextIndex + currentPage;
+ return gszAimPages[ stringIndex ];
+}
+
+void BtnNewProfilesButtonCallback(GUI_BUTTON *btn,INT32 reason)
+{
+UINT32 i;
+
+ for(i=0; i 80 )
+ START_MERC = 80;
+ else
+ START_MERC = 0;
+ }
+ else
+ {
+ START_MERC = 0;
+ }
+
+ ExitAimFacialIndex();
+ EnterAimFacialIndex();
+}
+
BOOLEAN EnterAimFacialIndex()
{
VOBJECT_DESC VObjectDesc;
@@ -79,41 +147,66 @@ BOOLEAN EnterAimFacialIndex()
UINT16 usPosX, usPosY, x,y;
STR sFaceLoc = "FACES\\";
char sTemp[100];
+
+ UINT8 p = 0;
+
+ for(i=0; i 40 )
+ {
+ ShowButton( PAGE_BUTTON );
+ }
+ else
+ {
+ HideButton( PAGE_BUTTON );
+ }
DrawAimDefaults();
@@ -175,21 +286,25 @@ BOOLEAN RenderAimFacialIndex()
else
swprintf(sString, AimFiText[ AIM_FI_AIM_MEMBERS_SORTED_DESCENDING ], AimFiText[gubCurrentSortMode] );
- DrawTextToScreen(sString, AIM_FI_MEMBER_TEXT_X, AIM_FI_MEMBER_TEXT_Y, AIM_FI_MEMBER_TEXT_WIDTH, AIM_MAINTITLE_FONT, AIM_MAINTITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
-
+ if(gGameExternalOptions.gfUseNewStartingGearInterface) DrawTextToScreen(sString, AIM_FI_MEMBER_TEXT_X, AIM_FI_MEMBER_TEXT_Y_NSGI, AIM_FI_MEMBER_TEXT_WIDTH, AIM_MAINTITLE_FONT, AIM_MAINTITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ else DrawTextToScreen(sString, AIM_FI_MEMBER_TEXT_X, AIM_FI_MEMBER_TEXT_Y, AIM_FI_MEMBER_TEXT_WIDTH, AIM_MAINTITLE_FONT, AIM_MAINTITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+
//Draw the mug shot border and face
usPosX = AIM_FI_FIRST_MUGSHOT_X;
usPosY = AIM_FI_FIRST_MUGSHOT_Y;
i=0;
- for(y=0; yuiFlags &= (~BUTTON_CLICKED_ON );
@@ -277,6 +401,8 @@ void SelectMercFaceMoveRegionCallBack(MOUSE_REGION * pRegion, INT32 reason )
DrawMercsFaceToScreen(ubMercNum, usPosX, usPosY, 0);
InvalidateRegion(pRegion->RegionTopLeftX, pRegion->RegionTopLeftY, pRegion->RegionBottomRightX, pRegion->RegionBottomRightY);
}
+
+ }
}
BOOLEAN DrawMercsFaceToScreen(UINT8 ubMercID, UINT16 usPosX, UINT16 usPosY, UINT8 ubImage)
@@ -285,7 +411,10 @@ BOOLEAN DrawMercsFaceToScreen(UINT8 ubMercID, UINT16 usPosX, UINT16 usPosY, UINT
HVOBJECT hFaceHandle;
SOLDIERTYPE *pSoldier=NULL;
- pSoldier = FindSoldierByProfileID( AimMercArray[ubMercID], TRUE );
+ //pSoldier = FindSoldierByProfileID( AimMercArray[ubMercID], TRUE );
+ pSoldier = FindSoldierByProfileID( gAimAvailability[AimMercArray[ubMercID + START_MERC]].ProfilId, TRUE );
+
+
//Blt the portrait background
@@ -296,7 +425,8 @@ BOOLEAN DrawMercsFaceToScreen(UINT8 ubMercID, UINT16 usPosX, UINT16 usPosY, UINT
GetVideoObject(&hFaceHandle, guiAimFiFace[ubMercID]);
BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,usPosX+AIM_FI_FACE_OFFSET, usPosY+AIM_FI_FACE_OFFSET, VO_BLT_SRCTRANSPARENCY,NULL);
- if( IsMercDead( AimMercArray[ubMercID] ) )
+ //if( IsMercDead( AimMercArray[ubMercID] ) )
+ if( IsMercDead( gAimAvailability[AimMercArray[ubMercID + START_MERC]].ProfilId ) )
{
//get the face object
GetVideoObject(&hFaceHandle, guiAimFiFace[ubMercID]);
@@ -315,7 +445,8 @@ BOOLEAN DrawMercsFaceToScreen(UINT8 ubMercID, UINT16 usPosX, UINT16 usPosY, UINT
}
//else if the merc is currently a POW or, the merc was fired as a pow
- else if( gMercProfiles[ AimMercArray[ubMercID] ].bMercStatus == MERC_FIRED_AS_A_POW || ( pSoldier && pSoldier->bAssignment == ASSIGNMENT_POW ) )
+ //else if( gMercProfiles[ AimMercArray[ubMercID] ].bMercStatus == MERC_FIRED_AS_A_POW || ( pSoldier && pSoldier->bAssignment == ASSIGNMENT_POW ) )
+ else if( gMercProfiles[ gAimAvailability[AimMercArray[ubMercID + START_MERC]].ProfilId ].bMercStatus == MERC_FIRED_AS_A_POW || ( pSoldier && pSoldier->bAssignment == ASSIGNMENT_POW ) )
{
ShadowVideoSurfaceRect( FRAME_BUFFER, usPosX+AIM_FI_FACE_OFFSET, usPosY+AIM_FI_FACE_OFFSET, usPosX + 48+AIM_FI_FACE_OFFSET, usPosY + 43+AIM_FI_FACE_OFFSET);
DrawTextToScreen( pPOWStrings[0], (UINT16)(usPosX+AIM_FI_AWAY_TEXT_OFFSET_X), (UINT16)(usPosY+AIM_FI_AWAY_TEXT_OFFSET_Y), AIM_FI_AWAY_TEXT_OFFSET_WIDTH, FONT10ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
@@ -329,7 +460,8 @@ BOOLEAN DrawMercsFaceToScreen(UINT8 ubMercID, UINT16 usPosX, UINT16 usPosY, UINT
}
//if the merc is away, shadow his/her face and blit 'away' over top
- else if( !IsMercHireable( AimMercArray[ubMercID] ) )
+ //else if( !IsMercHireable( AimMercArray[ubMercID] ) )
+ else if( !IsMercHireable( gAimAvailability[AimMercArray[ubMercID + START_MERC ]].ProfilId ) )
{
ShadowVideoSurfaceRect( FRAME_BUFFER, usPosX+AIM_FI_FACE_OFFSET, usPosY+AIM_FI_FACE_OFFSET, usPosX + 48+AIM_FI_FACE_OFFSET, usPosY + 43+AIM_FI_FACE_OFFSET);
DrawTextToScreen( AimFiText[AIM_FI_DEAD+1], (UINT16)(usPosX+AIM_FI_AWAY_TEXT_OFFSET_X), (UINT16)(usPosY+AIM_FI_AWAY_TEXT_OFFSET_Y), AIM_FI_AWAY_TEXT_OFFSET_WIDTH, FONT10ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
diff --git a/Laptop/AimFacialIndex.h b/Laptop/AimFacialIndex.h
index 9bd4ae3b..02097374 100644
--- a/Laptop/AimFacialIndex.h
+++ b/Laptop/AimFacialIndex.h
@@ -4,6 +4,11 @@
#define AIM_FI_LEFT_CLICK_TEXT_X (SCREEN_WIDTH - 640) / 2 + 116
#define AIM_FI_LEFT_CLICK_TEXT_Y (SCREEN_HEIGHT - 480) / 2 + 35 + LAPTOP_SCREEN_WEB_DELTA_Y
+//tais: nsgi, left click text moved a bit to create space for small logo
+#define AIM_FI_LEFT_CLICK_TEXT_X_NSGI (SCREEN_WIDTH - 640) / 2 + 200
+#define AIM_FI_LEFT_CLICK_TEXT_Y_NSGI (SCREEN_HEIGHT - 480) / 2 + 35 + LAPTOP_SCREEN_WEB_DELTA_Y
+
+
#define AIM_FI_CLICK_DESC_TEXT_Y_OFFSET 16
#define AIM_FI_RIGHT_CLICK_TEXT_X (SCREEN_WIDTH - 640) / 2 + 500
@@ -22,6 +27,8 @@ BOOLEAN RenderAimFacialIndex();
BOOLEAN DisplayAimFIMugShot();
+extern UINT8 START_MERC;
+
#endif
diff --git a/Laptop/AimHistory.cpp b/Laptop/AimHistory.cpp
index 267bf82d..8f737d5b 100644
--- a/Laptop/AimHistory.cpp
+++ b/Laptop/AimHistory.cpp
@@ -11,7 +11,7 @@
#include "Text.h"
#endif
-
+#include "LocalizedStrings.h"
// Defines
@@ -171,7 +171,6 @@ void HandleAimHistory()
void RenderAimHistory()
{
CHAR16 sText[400];
- UINT32 uiStartLoc=0;
UINT16 usPosY;
DrawAimDefaults();
@@ -210,8 +209,15 @@ void RenderAimHistory()
// display coloniel Mohanned...
usPosY = AIM_HISTORY_PARAGRAPH_Y + (GetFontHeight(AIM_HISTORY_TEXT_FONT) + 2)* 5 + LAPTOP_SCREEN_WEB_DELTA_Y;
- uiStartLoc = AIM_HISTORY_LINE_SIZE * COLONEL_MOHANNED;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * COLONEL_MOHANNED;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", COLONEL_MOHANNED, sText, 400);
+ }
DisplayWrappedString(AIM_HISTORY_PARAGRAPH_X, iScreenHeightOffset + 210+LAPTOP_SCREEN_WEB_DELTA_Y, AIM_HISTORY_PARAGRAPH_WIDTH, 2, AIM_HISTORY_TEXT_FONT, AIM_HISTORY_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED);
break;
@@ -220,13 +226,27 @@ void RenderAimHistory()
DisplayAimHistoryParagraph(INCORPORATION, 2);
// display dunn and bradbord...
- uiStartLoc = AIM_HISTORY_LINE_SIZE * DUNN_AND_BRADROAD;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * DUNN_AND_BRADROAD;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", DUNN_AND_BRADROAD, sText, 400);
+ }
DisplayWrappedString(AIM_HISTORY_PARAGRAPH_X, iScreenHeightOffset + 270+LAPTOP_SCREEN_WEB_DELTA_Y, AIM_HISTORY_PARAGRAPH_WIDTH, 2, AIM_HISTORY_TEXT_FONT, AIM_HISTORY_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED);
//AIM_HISTORY_PARAGRAPH_Y
- uiStartLoc = AIM_HISTORY_LINE_SIZE * INCORPORATION_3;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * INCORPORATION_3;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", INCORPORATION_3, sText, 400);
+ }
DisplayWrappedString(AIM_HISTORY_PARAGRAPH_X, iScreenHeightOffset + 290+LAPTOP_SCREEN_WEB_DELTA_Y, AIM_HISTORY_PARAGRAPH_WIDTH, 2, AIM_HISTORY_TEXT_FONT, AIM_HISTORY_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
break;
}
@@ -360,21 +380,34 @@ void SelectHistoryMenuButtonsRegionCallBack(MOUSE_REGION * pRegion, INT32 iReaso
BOOLEAN DisplayAimHistoryParagraph(UINT8 ubPageNum, UINT8 ubNumParagraphs)
{
CHAR16 sText[400];
- UINT32 uiStartLoc=0;
UINT16 usPosY=0;
UINT16 usNumPixels=0;
//title
- uiStartLoc = AIM_HISTORY_LINE_SIZE * ubPageNum;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * ubPageNum;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", ubPageNum, sText, 400);
+ }
DrawTextToScreen(sText, AIM_HISTORY_PARAGRAPH_X, AIM_HISTORY_SUBTITLE_Y, 0, AIM_HISTORY_PARAGRAPH_TITLE_FONT, AIM_HISTORY_PARAGRAPH_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
if(ubNumParagraphs >= 1)
{
usPosY = AIM_HISTORY_PARAGRAPH_Y;
//1st paragraph
- uiStartLoc = AIM_HISTORY_LINE_SIZE * (ubPageNum + 1 );
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * (ubPageNum + 1 );
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", ubPageNum+1, sText, 400);
+ }
usNumPixels = DisplayWrappedString(AIM_HISTORY_PARAGRAPH_X, usPosY, AIM_HISTORY_PARAGRAPH_WIDTH, 2, AIM_HISTORY_TEXT_FONT, AIM_HISTORY_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
}
@@ -382,8 +415,15 @@ BOOLEAN DisplayAimHistoryParagraph(UINT8 ubPageNum, UINT8 ubNumParagraphs)
{
//2nd paragraph
usPosY += usNumPixels + AIM_HISTORY_SPACE_BETWEEN_PARAGRAPHS;
- uiStartLoc = AIM_HISTORY_LINE_SIZE * (ubPageNum + 2 );
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * (ubPageNum + 2 );
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", ubPageNum+2, sText, 400);
+ }
DisplayWrappedString(AIM_HISTORY_PARAGRAPH_X, usPosY, AIM_HISTORY_PARAGRAPH_WIDTH, 2, AIM_HISTORY_TEXT_FONT, AIM_HISTORY_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
}
@@ -391,9 +431,15 @@ BOOLEAN DisplayAimHistoryParagraph(UINT8 ubPageNum, UINT8 ubNumParagraphs)
{
//3rd paragraph
usPosY += usNumPixels + AIM_HISTORY_SPACE_BETWEEN_PARAGRAPHS;
-
- uiStartLoc = AIM_HISTORY_LINE_SIZE * (ubPageNum + 3 );
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * (ubPageNum + 3 );
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", ubPageNum+3, sText, 400);
+ }
DisplayWrappedString(AIM_HISTORY_PARAGRAPH_X, usPosY, AIM_HISTORY_PARAGRAPH_WIDTH, 2, AIM_HISTORY_TEXT_FONT, AIM_HISTORY_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
}
@@ -404,19 +450,18 @@ BOOLEAN DisplayAimHistoryParagraph(UINT8 ubPageNum, UINT8 ubNumParagraphs)
BOOLEAN InitTocMenu()
{
- UINT16 i, usPosY;
- UINT16 usHeight;
- UINT16 usWidth=0;
- UINT32 uiStartLoc=0;
- CHAR16 sText[400];
- UINT8 ubLocInFile[]=
- {IN_THE_BEGINNING,
- THE_ISLAND_METAVIRA,
- GUS_TARBALLS,
- WORD_FROM_FOUNDER,
- INCORPORATION};
+ UINT16 i, usPosY;
+ UINT16 usHeight;
+ UINT16 usWidth=0;
+ CHAR16 sText[400];
+ UINT8 ubLocInFile[] = {
+ IN_THE_BEGINNING,
+ THE_ISLAND_METAVIRA,
+ GUS_TARBALLS,
+ WORD_FROM_FOUNDER,
+ INCORPORATION};
- HVOBJECT hContentButtonHandle;
+ HVOBJECT hContentButtonHandle;
GetVideoObject(&hContentButtonHandle, guiContentButton);
@@ -424,9 +469,15 @@ BOOLEAN InitTocMenu()
usPosY = AIM_HISTORY_CONTENTBUTTON_Y;
for(i=0; i 2 )
+ //if medical deposit is required
+ if( gMercProfiles[gbCurrentSoldier].bMedicalDeposit )
{
- DisplayWrappedString( AIM_MEDICAL_DEPOSIT_X, (UINT16)(AIM_MEDICAL_DEPOSIT_Y - GetFontHeight( AIM_FONT12ARIAL ) ), AIM_MEDICAL_DEPOSIT_WIDTH, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ CHAR16 zTemp[40];
+ CHAR16 sMedicalString[40];
+
+ // Display the medical cost
+ swprintf( zTemp, L"%d", gMercProfiles[ gbCurrentSoldier ].sMedicalDepositAmount );
+ InsertCommasForDollarFigure( zTemp );
+ InsertDollarSignInToString( zTemp );
+
+ swprintf( sMedicalString, L"%s %s", zTemp, CharacterInfo[AIM_MEMBER_MEDICAL_DEPOSIT_REQ] );
+
+ // If the string will be displayed in more then 2 lines, recenter the string
+ if( ( DisplayWrappedString( 0, 0, AIM_MEDICAL_DEPOSIT_WIDTH_NSGI, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT ) / GetFontHeight( AIM_FONT12ARIAL ) ) > 2 )
+ {
+ DisplayWrappedString( AIM_MEDICAL_DEPOSIT_X_NSGI, (UINT16)(AIM_MEDICAL_DEPOSIT_Y_NSGI - GetFontHeight( AIM_FONT12ARIAL ) ), AIM_MEDICAL_DEPOSIT_WIDTH_NSGI, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ }
+ else
+ DisplayWrappedString(AIM_MEDICAL_DEPOSIT_X_NSGI, AIM_MEDICAL_DEPOSIT_Y_NSGI, AIM_MEDICAL_DEPOSIT_WIDTH_NSGI, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ }
+ if(!g_bUseXML_Strings)
+ {
+ // LoadMercBioInfo( gbCurrentSoldier, MercInfoString, AdditionalInfoString);
+ if (gbCurrentSoldierBio != 255)
+ LoadMercBioInfo( gbCurrentSoldierBio, MercInfoString, AdditionalInfoString);
+ else
+ {
+ MercInfoString[0] = 0;
+ AdditionalInfoString[0] = 0;
+ }
}
else
- DisplayWrappedString(AIM_MEDICAL_DEPOSIT_X, AIM_MEDICAL_DEPOSIT_Y, AIM_MEDICAL_DEPOSIT_WIDTH, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ {
+ Loc::GetString(Loc::AIM_BIOGRAPHY, L"Bio", gbCurrentSoldier, MercInfoString, SIZE_MERC_BIO_INFO);
+ Loc::GetString(Loc::AIM_BIOGRAPHY, L"Add", gbCurrentSoldier, AdditionalInfoString, SIZE_MERC_BIO_INFO);
+ }
+ if( MercInfoString[0] != 0)
+ {
+ DisplayWrappedString(AIM_MERC_INFO_X_NSGI, AIM_MERC_INFO_Y_NSGI, AIM_MERC_INFO_WIDTH_NSGI, 2, AIM_M_FONT_DYNAMIC_TEXT, AIM_FONT_MCOLOR_WHITE, MercInfoString, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ }
+ if( AdditionalInfoString[0] != 0)
+ {
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_ADDTNL_INFO], AIM_MERC_ADD_X_NSGI, AIM_MERC_ADD_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayWrappedString(AIM_MERC_ADD_INFO_X_NSGI, AIM_MERC_ADD_INFO_Y_NSGI, AIM_MERC_INFO_WIDTH_NSGI, 2, AIM_M_FONT_DYNAMIC_TEXT, AIM_FONT_MCOLOR_WHITE, AdditionalInfoString, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ }
}
-
- LoadMercBioInfo( gbCurrentSoldier, MercInfoString, AdditionalInfoString);
- if( MercInfoString[0] != 0)
+ else
{
- DisplayWrappedString(AIM_MERC_INFO_X, AIM_MERC_INFO_Y, AIM_MERC_INFO_WIDTH, 2, AIM_M_FONT_DYNAMIC_TEXT, AIM_FONT_MCOLOR_WHITE, MercInfoString, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- }
- if( AdditionalInfoString[0] != 0)
- {
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_ADDTNL_INFO], AIM_MERC_ADD_X, AIM_MERC_ADD_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayWrappedString(AIM_MERC_ADD_INFO_X, AIM_MERC_ADD_INFO_Y, AIM_MERC_INFO_WIDTH, 2, AIM_M_FONT_DYNAMIC_TEXT, AIM_FONT_MCOLOR_WHITE, AdditionalInfoString, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- }
+ //Display the salaries
+ DrawMoneyToScreen(gMercProfiles[gbCurrentSoldier].sSalary, FEE_WIDTH, FEE_X, HEALTH_Y, AIM_M_NUMBER_FONT, AIM_M_COLOR_DYNAMIC_TEXT );
+ DrawMoneyToScreen(gMercProfiles[gbCurrentSoldier].uiWeeklySalary, FEE_WIDTH, FEE_X, AGILITY_Y, AIM_M_NUMBER_FONT, AIM_M_COLOR_DYNAMIC_TEXT );
+ DrawMoneyToScreen(gMercProfiles[gbCurrentSoldier].uiBiWeeklySalary, FEE_WIDTH, FEE_X, DEXTERITY_Y, AIM_M_NUMBER_FONT, AIM_M_COLOR_DYNAMIC_TEXT );
+ //if medical deposit is required
+ if( gMercProfiles[gbCurrentSoldier].bMedicalDeposit )
+ {
+ CHAR16 zTemp[40];
+ CHAR16 sMedicalString[40];
+
+ // Display the medical cost
+ swprintf( zTemp, L"%d", gMercProfiles[ gbCurrentSoldier ].sMedicalDepositAmount );
+ InsertCommasForDollarFigure( zTemp );
+ InsertDollarSignInToString( zTemp );
+
+ swprintf( sMedicalString, L"%s %s", zTemp, CharacterInfo[AIM_MEMBER_MEDICAL_DEPOSIT_REQ] );
+
+ // If the string will be displayed in more then 2 lines, recenter the string
+ if( ( DisplayWrappedString( 0, 0, AIM_MEDICAL_DEPOSIT_WIDTH, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT ) / GetFontHeight( AIM_FONT12ARIAL ) ) > 2 )
+ {
+ DisplayWrappedString( AIM_MEDICAL_DEPOSIT_X, (UINT16)(AIM_MEDICAL_DEPOSIT_Y - GetFontHeight( AIM_FONT12ARIAL ) ), AIM_MEDICAL_DEPOSIT_WIDTH, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ }
+ else
+ DisplayWrappedString(AIM_MEDICAL_DEPOSIT_X, AIM_MEDICAL_DEPOSIT_Y, AIM_MEDICAL_DEPOSIT_WIDTH, 2, AIM_FONT12ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, sMedicalString, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ }
+ if(!g_bUseXML_Strings)
+ {
+// LoadMercBioInfo( gbCurrentSoldier, MercInfoString, AdditionalInfoString);
+
+ if (gbCurrentSoldierBio != 255)
+ LoadMercBioInfo( gbCurrentSoldierBio, MercInfoString, AdditionalInfoString);
+ else
+ {
+ MercInfoString[0] = 0;
+ AdditionalInfoString[0] = 0;
+ }
+
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_BIOGRAPHY, L"Bio", gbCurrentSoldier, MercInfoString, SIZE_MERC_BIO_INFO);
+ Loc::GetString(Loc::AIM_BIOGRAPHY, L"Add", gbCurrentSoldier, AdditionalInfoString, SIZE_MERC_BIO_INFO);
+ }
+ if( MercInfoString[0] != 0)
+ {
+ DisplayWrappedString(AIM_MERC_INFO_X, AIM_MERC_INFO_Y, AIM_MERC_INFO_WIDTH, 2, AIM_M_FONT_DYNAMIC_TEXT, AIM_FONT_MCOLOR_WHITE, MercInfoString, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ }
+ if( AdditionalInfoString[0] != 0)
+ {
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_ADDTNL_INFO], AIM_MERC_ADD_X, AIM_MERC_ADD_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayWrappedString(AIM_MERC_ADD_INFO_X, AIM_MERC_ADD_INFO_Y, AIM_MERC_INFO_WIDTH, 2, AIM_M_FONT_DYNAMIC_TEXT, AIM_FONT_MCOLOR_WHITE, AdditionalInfoString, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ }
+ }
return(TRUE);
}
@@ -1214,94 +1558,186 @@ BOOLEAN LoadMercBioInfo(UINT8 ubIndex, STR16 pInfoString, STR16 pAddInfo)
BOOLEAN DisplayMercsInventory(UINT8 ubMercID)
{
- UINT8 i;
- INT16 PosX, PosY, sCenX, sCenY;
+ UINT8 i;
+ INT16 PosX, PosY, sCenX, sCenY;
UINT16 usItem;
INVTYPE *pItem;
HVOBJECT hVObject;
UINT32 usHeight, usWidth;
- ETRLEObject *pTrav;
+ ETRLEObject *pTrav;
CHAR16 gzItemName[ SIZE_ITEM_NAME ];
- UINT8 ubItemCount=0;
-// UINT16 gzTempItemName[ SIZE_ITEM_INFO ];
-
+ UINT8 ubItemCount=0;
+ UINT8 ubColumnCount=0;
//if the mercs inventory has already been purchased, dont display the inventory
if( gMercProfiles[ ubMercID ].ubMiscFlags & PROFILE_MISC_FLAG_ALREADY_USED_ITEMS )
return( TRUE );
- UINT16 wnameY = AIM_MEMBER_WEAPON_NAME_Y;
- PosX = WEAPONBOX_X+3; // + 3 ( 1 to take care of the shadow, +2 to get past the weapon box border )
-
- PosY = WEAPONBOX_Y;
- if(is_networked && guiCurrentLaptopMode == LAPTOP_MODE_MERC_FILES)
- {
- PosY-=30;
- wnameY-=30;
-
- }
-
-
- for(i=0; iubGraphicNum;
- if(usGraphicNum < hVObject->usNumberOfObjects)
+ //tais: disable Weaponbox Mouseregions to stop crashing when changing kit selection and hovering over item
+ //tooltips for weaponbox
+ for(i=0;ipETRLEObject[ usGraphicNum ] );
+ //increase the item count
+ ubItemCount++;
+ ubColumnCount++;
+
+ pItem = &Item[ usItem ];
+ GetVideoObject( &hVObject, GetInterfaceGraphicForItem( pItem ) );
+ UINT16 usGraphicNum = g_bUsePngItemImages ? 0 : pItem->ubGraphicNum;
+
+ if(usGraphicNum < hVObject->usNumberOfObjects)
+ {
+ pTrav = &(hVObject->pETRLEObject[ usGraphicNum ] );
+ }
+ else
+ {
+ SGP_THROW(_BS(L"Number of images in VObject [") << hVObject->usNumberOfObjects
+ << L"] is smaller than the requested index [" << (int)pItem->ubGraphicNum << L"]" << _BS::wget);
+ }
+
+ usHeight = (UINT32)pTrav->usHeight;
+ usWidth = (UINT32)pTrav->usWidth;
+
+ sCenX = PosX + ( abs( WEAPONBOX_SIZE_X_NSGI - 3 - (int)usWidth ) / 2 ) - pTrav->sOffsetX;
+ sCenY = PosY + ( abs( WEAPONBOX_SIZE_Y_NSGI - (int)usHeight ) / 2 ) - pTrav->sOffsetY;
+
+ //blt the shadow of the item
+ if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ])
+ BltVideoObjectOutlineShadowFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX-2, sCenY+2);
+
+ //blt the item
+ BltVideoObjectOutlineFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX, sCenY, 0, FALSE );
+
+ //if there are more then 1 piece of equipment in the current slot, display how many there are
+ if( gMercProfiles[ubMercID].bInvNumber[ i ] > 1 )
+ {
+ CHAR16 zTempStr[ 32 ];
+
+ swprintf( zTempStr, L"x%d", gMercProfiles[ ubMercID ].bInvNumber[ i ] );
+
+ DrawTextToScreen( zTempStr, (UINT16)(PosX-1), (UINT16)(PosY+20), AIM_MEMBER_WEAPON_NAME_WIDTH, AIM_M_FONT_DYNAMIC_TEXT, AIM_M_WEAPON_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED );
+ }
+
+ wcscpy( gzItemName, ShortItemNames[ usItem ] );
+ SetRegionFastHelpText( &(gWeaponboxFasthelpRegion[ubItemCount-1]), gzItemName );
+ SetRegionHelpEndCallback( &(gWeaponboxFasthelpRegion[ubItemCount-1]), HelpTextDoneCallback );
+ MSYS_EnableRegion( &gWeaponboxFasthelpRegion[ubItemCount-1] );
+
+ // WANNE: In a multiplayer game also display the items name on the MERC website
+ if (is_networked && guiCurrentLaptopMode == LAPTOP_MODE_MERC_FILES)
+ {
+ //if this will only be a single line, center it in the box
+ if( ( DisplayWrappedString( (UINT16)(PosX-1), wnameY, AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT ) / GetFontHeight( AIM_M_WEAPON_TEXT_FONT ) ) == 1 )
+ DisplayWrappedString( (UINT16)(PosX-1), (UINT16)(wnameY+GetFontHeight( AIM_M_WEAPON_TEXT_FONT )/2), AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ else
+ DisplayWrappedString( (UINT16)(PosX-1), wnameY, AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+ if(ubColumnCount == WEAPONBOX_COLUMNS)
+ {
+ PosX = WEAPONBOX_X_NSGI+3;
+ PosY += WEAPONBOX_SIZE_Y_NSGI;
+ ubColumnCount = 0;
+ }
+ else
+ {
+ PosX += WEAPONBOX_SIZE_X_NSGI;
+ }
}
- else
+ }
+ }
+ else
+ {
+ UINT16 wnameY = AIM_MEMBER_WEAPON_NAME_Y;
+ PosX = WEAPONBOX_X+3; // + 3 ( 1 to take care of the shadow, +2 to get past the weapon box border )
+ PosY = WEAPONBOX_Y;
+ if(is_networked && guiCurrentLaptopMode == LAPTOP_MODE_MERC_FILES)
+ {
+ PosX+=20;
+ PosY-=28;
+ wnameY-=28;
+ }
+
+ for(i=0; iusNumberOfObjects
- << L"] is smaller than the requested index [" << (int)pItem->ubGraphicNum << L"]";
- THROWEXCEPTION(wss.str().c_str());
+ //increase the item count
+ ubItemCount++;
+
+ pItem = &Item[ usItem ];
+ GetVideoObject( &hVObject, GetInterfaceGraphicForItem( pItem ) );
+ UINT16 usGraphicNum = g_bUsePngItemImages ? 0 : pItem->ubGraphicNum;
+ if(usGraphicNum < hVObject->usNumberOfObjects)
+ {
+ pTrav = &(hVObject->pETRLEObject[ usGraphicNum ] );
+ }
+ else
+ {
+ std::wstringstream wss;
+ wss << L"Number of images in VObject [" << hVObject->usNumberOfObjects
+ << L"] is smaller than the requested index [" << (int)pItem->ubGraphicNum << L"]";
+ SGP_THROW(wss.str().c_str());
+ }
+
+ usHeight = (UINT32)pTrav->usHeight;
+ usWidth = (UINT32)pTrav->usWidth;
+
+ sCenX = PosX + ( abs( WEAPONBOX_SIZE_X - 3 - (int)usWidth ) / 2 ) - pTrav->sOffsetX;
+ sCenY = PosY + ( abs( WEAPONBOX_SIZE_Y - (int)usHeight ) / 2 ) - pTrav->sOffsetY;
+
+ //blt the shadow of the item
+ if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ])
+ BltVideoObjectOutlineShadowFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX-2, sCenY+2);
+
+ //blt the item
+ BltVideoObjectOutlineFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX, sCenY, 0, FALSE );
+
+ //if there are more then 1 piece of equipment in the current slot, display how many there are
+ if( gMercProfiles[ubMercID].bInvNumber[ i ] > 1 )
+ {
+ CHAR16 zTempStr[ 32 ];
+
+ swprintf( zTempStr, L"x%d", gMercProfiles[ ubMercID ].bInvNumber[ i ] );
+
+ DrawTextToScreen( zTempStr, (UINT16)(PosX-1), (UINT16)(PosY+20), AIM_MEMBER_WEAPON_NAME_WIDTH, AIM_M_FONT_DYNAMIC_TEXT, AIM_M_WEAPON_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED );
+ }
+
+ wcscpy( gzItemName, ShortItemNames[ usItem ] );
+
+ //if this will only be a single line, center it in the box
+ if( ( DisplayWrappedString( (UINT16)(PosX-1), wnameY, AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT ) / GetFontHeight( AIM_M_WEAPON_TEXT_FONT ) ) == 1 )
+ DisplayWrappedString( (UINT16)(PosX-1), (UINT16)(wnameY+GetFontHeight( AIM_M_WEAPON_TEXT_FONT )/2), AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ else
+ DisplayWrappedString( (UINT16)(PosX-1), wnameY, AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+
+ PosX += WEAPONBOX_SIZE_X;
}
-
- usHeight = (UINT32)pTrav->usHeight;
- usWidth = (UINT32)pTrav->usWidth;
-
- sCenX = PosX + ( abs( WEAPONBOX_SIZE_X - 3 - usWidth ) / 2 ) - pTrav->sOffsetX;
- sCenY = PosY + ( abs( WEAPONBOX_SIZE_Y - usHeight ) / 2 ) - pTrav->sOffsetY;
-
- //blt the shadow of the item
- if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ]) BltVideoObjectOutlineShadowFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX-2, sCenY+2);
- //blt the item
- BltVideoObjectOutlineFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX, sCenY, 0, FALSE );
-
-
- //if there are more then 1 piece of equipment in the current slot, display how many there are
- if( gMercProfiles[ubMercID].bInvNumber[ i ] > 1 )
- {
- CHAR16 zTempStr[ 32 ];
-// UINT16 usWidthOfNumber;
-
- swprintf( zTempStr, L"x%d", gMercProfiles[ ubMercID ].bInvNumber[ i ] );
-
- DrawTextToScreen( zTempStr, (UINT16)(PosX-1), (UINT16)(PosY+20), AIM_MEMBER_WEAPON_NAME_WIDTH, AIM_M_FONT_DYNAMIC_TEXT, AIM_M_WEAPON_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED );
- }
- else
- {
- }
-
- wcscpy( gzItemName, ShortItemNames[ usItem ] );
-
- //if this will only be a single line, center it in the box
- if( ( DisplayWrappedString( (UINT16)(PosX-1), wnameY, AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT ) / GetFontHeight( AIM_M_WEAPON_TEXT_FONT ) ) == 1 )
- DisplayWrappedString( (UINT16)(PosX-1), (UINT16)(wnameY+GetFontHeight( AIM_M_WEAPON_TEXT_FONT )/2), AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
- else
- DisplayWrappedString( (UINT16)(PosX-1), wnameY, AIM_MEMBER_WEAPON_NAME_WIDTH, 2, AIM_M_WEAPON_TEXT_FONT, AIM_M_WEAPON_TEXT_COLOR, gzItemName, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
-
- PosX += WEAPONBOX_SIZE_X;
}
}
@@ -1309,10 +1745,168 @@ BOOLEAN DisplayMercsInventory(UINT8 ubMercID)
}
+//tais: nsgi, kit selection button callbacks one to five
+void BtnWeaponboxSelectOneButtonCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+ //tais: handle selected kit
+ WeaponKitSelectionUpdate(0);
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ gfRedrawScreen = TRUE;
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+ gubVideoConferencingMode = AIM_VIDEO_NOT_DISPLAYED_MODE;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ }
+ if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+}
+
+void BtnWeaponboxSelectTwoButtonCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+ //tais: handle selected kit
+ WeaponKitSelectionUpdate(1);
+
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ gfRedrawScreen = TRUE;
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+
+ gubVideoConferencingMode = AIM_VIDEO_NOT_DISPLAYED_MODE;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ }
+ if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+}
+void BtnWeaponboxSelectThreeButtonCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+ //tais: handle selected kit
+ WeaponKitSelectionUpdate(2);
+
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ gfRedrawScreen = TRUE;
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+
+ gubVideoConferencingMode = AIM_VIDEO_NOT_DISPLAYED_MODE;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ }
+ if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+}
+void BtnWeaponboxSelectFourButtonCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+
+ //tais: handle selected kit
+ WeaponKitSelectionUpdate(3);
+
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ gfRedrawScreen = TRUE;
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+
+ gubVideoConferencingMode = AIM_VIDEO_NOT_DISPLAYED_MODE;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ }
+ if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+}
+void BtnWeaponboxSelectFiveButtonCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+
+ //tais: handle selected kit
+ WeaponKitSelectionUpdate(4);
+
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ gfRedrawScreen = TRUE;
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+
+ gubVideoConferencingMode = AIM_VIDEO_NOT_DISPLAYED_MODE;
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+ }
+ if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE)
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ }
+}
void BtnPreviousButtonCallback(GUI_BUTTON *btn,INT32 reason)
{
+
+BOOLEAN Stop = FALSE;
+
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags |= BUTTON_CLICKED_ON;
@@ -1333,7 +1927,9 @@ void BtnPreviousButtonCallback(GUI_BUTTON *btn,INT32 reason)
gfRedrawScreen = TRUE;
- gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+ gbCurrentSoldierBio = gAimAvailability[AimMercArray[gbCurrentIndex]].AimBio;
gubVideoConferencingMode = AIM_VIDEO_NOT_DISPLAYED_MODE;
InvalidateRegion(btn->Area.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
@@ -1382,6 +1978,9 @@ void BtnContactButtonCallback(GUI_BUTTON *btn,INT32 reason)
void BtnNextButtonCallback(GUI_BUTTON *btn,INT32 reason)
{
+
+BOOLEAN Stop = FALSE;
+
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
btn->uiFlags |= BUTTON_CLICKED_ON;
@@ -1394,12 +1993,15 @@ void BtnNextButtonCallback(GUI_BUTTON *btn,INT32 reason)
btn->uiFlags &= (~BUTTON_CLICKED_ON );
InitCreateDeleteAimPopUpBox(AIM_POPUP_DELETE, NULL, NULL, 0, 0, 0);
- if( gbCurrentIndex < MAX_NUMBER_MERCS-1 )
+ if( gbCurrentIndex < MAX_NUMBER_MERCS -1 )
gbCurrentIndex++;
else
gbCurrentIndex = 0;
- gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+// gbCurrentSoldier = AimMercArray[gbCurrentIndex];
+ gbCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
+
+ gbCurrentSoldierBio = gAimAvailability[AimMercArray[gbCurrentIndex]].AimBio;
gfRedrawScreen = TRUE;
@@ -1430,7 +2032,8 @@ BOOLEAN DisplayMercsFace()
// Portrait Frame
GetVideoObject(&hPortraitHandle, guiPortrait);
- BltVideoObject(FRAME_BUFFER, hPortraitHandle, 0,PORTRAIT_X, PORTRAIT_Y, VO_BLT_SRCTRANSPARENCY,NULL);
+ if(gGameExternalOptions.gfUseNewStartingGearInterface) BltVideoObject(FRAME_BUFFER, hPortraitHandle, 0,PORTRAIT_X_NSGI, PORTRAIT_Y_NSGI, VO_BLT_SRCTRANSPARENCY,NULL);
+ else BltVideoObject(FRAME_BUFFER, hPortraitHandle, 0,PORTRAIT_X, PORTRAIT_Y, VO_BLT_SRCTRANSPARENCY,NULL);
// load the Face graphic and add it
if (gGameExternalOptions.fReadProfileDataFromXML)
@@ -1446,51 +2049,100 @@ BOOLEAN DisplayMercsFace()
FilenameForBPP(sTemp, VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiFace));
- //Blt face to screen
- GetVideoObject(&hFaceHandle, guiFace);
- BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,FACE_X, FACE_Y, VO_BLT_SRCTRANSPARENCY,NULL);
-
- //if the merc is dead
- if( IsMercDead( gbCurrentSoldier ) )
+ if(gGameExternalOptions.gfUseNewStartingGearInterface)
{
- //shade the face red, (to signif that he is dead)
- hFaceHandle->pShades[ 0 ] = Create16BPPPaletteShaded( hFaceHandle->pPaletteEntry, DEAD_MERC_COLOR_RED, DEAD_MERC_COLOR_GREEN, DEAD_MERC_COLOR_BLUE, TRUE );
-
- //get the face object
- GetVideoObject(&hFaceHandle, guiFace);
-
- //set the red pallete to the face
- SetObjectHandleShade( guiFace, 0 );
-
//Blt face to screen
+ GetVideoObject(&hFaceHandle, guiFace);
+ BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,FACE_X_NSGI, FACE_Y_NSGI, VO_BLT_SRCTRANSPARENCY,NULL);
+
+ //if the merc is dead
+ if( IsMercDead( gbCurrentSoldier ) )
+ {
+ //shade the face red, (to signif that he is dead)
+ hFaceHandle->pShades[ 0 ] = Create16BPPPaletteShaded( hFaceHandle->pPaletteEntry, DEAD_MERC_COLOR_RED, DEAD_MERC_COLOR_GREEN, DEAD_MERC_COLOR_BLUE, TRUE );
+
+ //get the face object
+ GetVideoObject(&hFaceHandle, guiFace);
+
+ //set the red pallete to the face
+ SetObjectHandleShade( guiFace, 0 );
+
+ //Blt face to screen
+ BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,FACE_X_NSGI, FACE_Y_NSGI, VO_BLT_SRCTRANSPARENCY,NULL);
+
+ //if the merc is dead, display it
+ DrawTextToScreen(AimPopUpText[AIM_MEMBER_DEAD], FACE_X_NSGI+1, FACE_Y_NSGI+107, FACE_WIDTH_NSGI, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+ //else if the merc is currently a POW or, the merc was fired as a pow
+ else if( gMercProfiles[ gbCurrentSoldier ].bMercStatus == MERC_FIRED_AS_A_POW || ( pSoldier && pSoldier->bAssignment == ASSIGNMENT_POW ) )
+ {
+ ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X_NSGI, FACE_Y_NSGI, FACE_X_NSGI + FACE_WIDTH_NSGI, FACE_Y_NSGI + FACE_HEIGHT_NSGI);
+ DrawTextToScreen( pPOWStrings[0], FACE_X_NSGI+1, FACE_Y_NSGI+107, FACE_WIDTH_NSGI, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+
+ //else if the merc has already been hired
+ else if( FindSoldierByProfileID( gbCurrentSoldier, TRUE ) )
+ {
+ ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X_NSGI, FACE_Y_NSGI, FACE_X_NSGI + FACE_WIDTH_NSGI, FACE_Y_NSGI + FACE_HEIGHT_NSGI);
+ DrawTextToScreen( MercInfo[MERC_FILES_ALREADY_HIRED], FACE_X_NSGI+1, FACE_Y_NSGI+107, FACE_WIDTH_NSGI, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+ else if( !IsMercHireable( gbCurrentSoldier ) )
+ {
+ //else if the merc has a text file and the merc is not away
+ ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X_NSGI, FACE_Y_NSGI, FACE_X_NSGI + FACE_WIDTH_NSGI, FACE_Y_NSGI + FACE_HEIGHT_NSGI);
+ DrawTextToScreen(AimPopUpText[AIM_MEMBER_ON_ASSIGNMENT], FACE_X_NSGI+1, FACE_Y_NSGI+107, FACE_WIDTH_NSGI, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+ }
+ else
+ {
+ //Blt face to screen
+ GetVideoObject(&hFaceHandle, guiFace);
BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,FACE_X, FACE_Y, VO_BLT_SRCTRANSPARENCY,NULL);
- //if the merc is dead, display it
- DrawTextToScreen(AimPopUpText[AIM_MEMBER_DEAD], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ //if the merc is dead
+ if( IsMercDead( gbCurrentSoldier ) )
+ {
+ //shade the face red, (to signif that he is dead)
+ hFaceHandle->pShades[ 0 ] = Create16BPPPaletteShaded( hFaceHandle->pPaletteEntry, DEAD_MERC_COLOR_RED, DEAD_MERC_COLOR_GREEN, DEAD_MERC_COLOR_BLUE, TRUE );
+
+ //get the face object
+ GetVideoObject(&hFaceHandle, guiFace);
+
+ //set the red pallete to the face
+ SetObjectHandleShade( guiFace, 0 );
+
+ //Blt face to screen
+ BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,FACE_X, FACE_Y, VO_BLT_SRCTRANSPARENCY,NULL);
+
+ //if the merc is dead, display it
+ DrawTextToScreen(AimPopUpText[AIM_MEMBER_DEAD], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+ //else if the merc is currently a POW or, the merc was fired as a pow
+ else if( gMercProfiles[ gbCurrentSoldier ].bMercStatus == MERC_FIRED_AS_A_POW || ( pSoldier && pSoldier->bAssignment == ASSIGNMENT_POW ) )
+ {
+ ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X, FACE_Y, FACE_X + FACE_WIDTH, FACE_Y + FACE_HEIGHT);
+ DrawTextToScreen( pPOWStrings[0], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+
+ //else if the merc has already been hired
+ else if( FindSoldierByProfileID( gbCurrentSoldier, TRUE ) )
+ {
+ ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X, FACE_Y, FACE_X + FACE_WIDTH, FACE_Y + FACE_HEIGHT);
+ DrawTextToScreen( MercInfo[MERC_FILES_ALREADY_HIRED], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+
+ else if( !IsMercHireable( gbCurrentSoldier ) )
+ {
+ //else if the merc has a text file and the merc is not away
+ ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X, FACE_Y, FACE_X + FACE_WIDTH, FACE_Y + FACE_HEIGHT);
+ DrawTextToScreen(AimPopUpText[AIM_MEMBER_ON_ASSIGNMENT], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
}
-
- //else if the merc is currently a POW or, the merc was fired as a pow
- else if( gMercProfiles[ gbCurrentSoldier ].bMercStatus == MERC_FIRED_AS_A_POW || ( pSoldier && pSoldier->bAssignment == ASSIGNMENT_POW ) )
- {
- ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X, FACE_Y, FACE_X + FACE_WIDTH, FACE_Y + FACE_HEIGHT);
- DrawTextToScreen( pPOWStrings[0], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
- }
-
-
- //else if the merc has already been hired
- else if( FindSoldierByProfileID( gbCurrentSoldier, TRUE ) )
- {
- ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X, FACE_Y, FACE_X + FACE_WIDTH, FACE_Y + FACE_HEIGHT);
- DrawTextToScreen( MercInfo[MERC_FILES_ALREADY_HIRED], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
- }
-
- else if( !IsMercHireable( gbCurrentSoldier ) )
- {
- //else if the merc has a text file and the merc is not away
- ShadowVideoSurfaceRect( FRAME_BUFFER, FACE_X, FACE_Y, FACE_X + FACE_WIDTH, FACE_Y + FACE_HEIGHT);
- DrawTextToScreen(AimPopUpText[AIM_MEMBER_ON_ASSIGNMENT], FACE_X+1, FACE_Y+107, FACE_WIDTH, FONT14ARIAL, 145, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
- }
-
DeleteVideoObjectFromIndex(guiFace);
return( TRUE );
@@ -1500,91 +2152,180 @@ BOOLEAN DisplayMercsFace()
void DisplayMercStats()
{
UINT8 ubColor;
+ if(gGameExternalOptions.gfUseNewStartingGearInterface)
+ {
+ //
+ // Display all the static text
+ //
- //
- // Display all the static text
- //
+ //First column in stats box. Health, Agility, dexterity, strength, leadership, wisdom
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_HEALTH], STATS_FIRST_COL_NSGI, HEALTH_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL_NSGI, HEALTH_Y_NSGI, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_HEALTH]);
- //First column in stats box. Health, Agility, dexterity, strength, leadership, wisdom
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_HEALTH], STATS_FIRST_COL, HEALTH_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_FIRST_COL, HEALTH_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_HEALTH]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_AGILITY], STATS_FIRST_COL_NSGI, AGILITY_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL_NSGI, AGILITY_Y_NSGI, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_AGILITY]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_AGILITY], STATS_FIRST_COL, AGILITY_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_FIRST_COL, AGILITY_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_AGILITY]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_DEXTERITY], STATS_FIRST_COL_NSGI, DEXTERITY_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL_NSGI, DEXTERITY_Y_NSGI, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_DEXTERITY]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_DEXTERITY], STATS_FIRST_COL, DEXTERITY_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_FIRST_COL, DEXTERITY_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_DEXTERITY]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_STRENGTH], STATS_FIRST_COL_NSGI, STRENGTH_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL_NSGI, STRENGTH_Y_NSGI, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_STRENGTH]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_STRENGTH], STATS_FIRST_COL, STRENGTH_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_FIRST_COL, STRENGTH_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_STRENGTH]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_LEADERSHIP], STATS_FIRST_COL_NSGI, LEADERSHIP_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL_NSGI, LEADERSHIP_Y_NSGI, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_LEADERSHIP]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_LEADERSHIP], STATS_FIRST_COL, LEADERSHIP_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_FIRST_COL, LEADERSHIP_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_LEADERSHIP]);
-
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_WISDOM], STATS_FIRST_COL, WISDOM_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_FIRST_COL, WISDOM_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_WISDOM]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_WISDOM], STATS_FIRST_COL_NSGI, WISDOM_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL_NSGI, WISDOM_Y_NSGI, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_WISDOM]);
- //Second column in stats box. Exp.Level, Markmanship, mechanical, explosive, medical
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_EXP_LEVEL], STATS_SECOND_COL, EXPLEVEL_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- DisplayDots(STATS_SECOND_COL, EXPLEVEL_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_EXP_LEVEL]);
+ //Second column in stats box. Exp.Level, Markmanship, mechanical, explosive, medical
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_EXP_LEVEL], STATS_SECOND_COL_NSGI, EXPLEVEL_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL_NSGI, EXPLEVEL_Y_NSGI, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_EXP_LEVEL]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_MARKSMANSHIP], STATS_SECOND_COL, MARKSMAN_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT , FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- DisplayDots(STATS_SECOND_COL, MARKSMAN_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MARKSMANSHIP]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_MARKSMANSHIP], STATS_SECOND_COL_NSGI, MARKSMAN_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT , FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_SECOND_COL_NSGI, MARKSMAN_Y_NSGI, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MARKSMANSHIP]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_MECHANICAL], STATS_SECOND_COL, MECHANAICAL_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- DisplayDots(STATS_SECOND_COL, MECHANAICAL_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MECHANICAL]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_MECHANICAL], STATS_SECOND_COL_NSGI, MECHANAICAL_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL_NSGI, MECHANAICAL_Y_NSGI, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MECHANICAL]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_EXPLOSIVE], STATS_SECOND_COL, EXPLOSIVE_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- DisplayDots(STATS_SECOND_COL, EXPLOSIVE_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_EXPLOSIVE]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_EXPLOSIVE], STATS_SECOND_COL_NSGI, EXPLOSIVE_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL_NSGI, EXPLOSIVE_Y_NSGI, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_EXPLOSIVE]);
- DrawTextToScreen(CharacterInfo[AIM_MEMBER_MEDICAL], STATS_SECOND_COL, MEDICAL_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- DisplayDots(STATS_SECOND_COL, MEDICAL_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MEDICAL]);
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_MEDICAL], STATS_SECOND_COL_NSGI, MEDICAL_Y_NSGI, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL_NSGI, MEDICAL_Y_NSGI, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MEDICAL]);
- //
- // Display all the Merc dynamic stat info
- //
+ //
+ // Display all the Merc dynamic stat info
+ //
- //Name
- DrawTextToScreen(gMercProfiles[gbCurrentSoldier].zName, NAME_X, NAME_Y, 0, FONT14ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ //Name
+ DrawTextToScreen(gMercProfiles[gbCurrentSoldier].zName, NAME_X_NSGI, NAME_Y_NSGI, 0, FONT14ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- // Numbers for above. Health, Agility, dexterity, strength, leadership, wisdom
+ // Numbers for above. Health, Agility, dexterity, strength, leadership, wisdom
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bLife );
- DrawNumeralsToScreen( gMercProfiles[gbCurrentSoldier].bLife, 3, STATS_FIRST_NUM, HEALTH_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bLife );
+ DrawNumeralsToScreen( gMercProfiles[gbCurrentSoldier].bLife, 3, STATS_FIRST_NUM_NSGI, HEALTH_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bAgility );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bAgility, 3, STATS_FIRST_NUM, AGILITY_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bAgility );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bAgility, 3, STATS_FIRST_NUM_NSGI, AGILITY_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bDexterity );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bDexterity, 3, STATS_FIRST_NUM, DEXTERITY_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bDexterity );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bDexterity, 3, STATS_FIRST_NUM_NSGI, DEXTERITY_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bStrength );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bStrength, 3, STATS_FIRST_NUM, STRENGTH_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bStrength );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bStrength, 3, STATS_FIRST_NUM_NSGI, STRENGTH_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bLeadership );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bLeadership, 3, STATS_FIRST_NUM, LEADERSHIP_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bLeadership );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bLeadership, 3, STATS_FIRST_NUM_NSGI, LEADERSHIP_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bWisdom );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bWisdom, 3, STATS_FIRST_NUM, WISDOM_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bWisdom );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bWisdom, 3, STATS_FIRST_NUM_NSGI, WISDOM_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- //Second column in stats box. Exp.Level, Markmanship, mechanical, explosive, medical
+ //Second column in stats box. Exp.Level, Markmanship, mechanical, explosive, medical
-// ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bExpLevel );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bExpLevel, 3, STATS_SECOND_NUM, EXPLEVEL_Y, AIM_M_NUMBER_FONT, FONT_MCOLOR_WHITE );
+ // ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bExpLevel );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bExpLevel, 3, STATS_SECOND_NUM_NSGI, EXPLEVEL_Y_NSGI, AIM_M_NUMBER_FONT, FONT_MCOLOR_WHITE );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMarksmanship );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMarksmanship, 3, STATS_SECOND_NUM, MARKSMAN_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMarksmanship );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMarksmanship, 3, STATS_SECOND_NUM_NSGI, MARKSMAN_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMechanical );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMechanical, 3, STATS_SECOND_NUM, MECHANAICAL_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMechanical );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMechanical, 3, STATS_SECOND_NUM_NSGI, MECHANAICAL_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bExplosive );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bExplosive, 3, STATS_SECOND_NUM, EXPLOSIVE_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bExplosive );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bExplosive, 3, STATS_SECOND_NUM_NSGI, EXPLOSIVE_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
- ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMedical );
- DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMedical, 3, STATS_SECOND_NUM, MEDICAL_Y, AIM_M_NUMBER_FONT, ubColor );
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMedical );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMedical, 3, STATS_SECOND_NUM_NSGI, MEDICAL_Y_NSGI, AIM_M_NUMBER_FONT, ubColor );
+ }
+ else
+ {
+ //
+ // Display all the static text
+ //
+
+ //First column in stats box. Health, Agility, dexterity, strength, leadership, wisdom
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_HEALTH], STATS_FIRST_COL, HEALTH_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL, HEALTH_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_HEALTH]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_AGILITY], STATS_FIRST_COL, AGILITY_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL, AGILITY_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_AGILITY]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_DEXTERITY], STATS_FIRST_COL, DEXTERITY_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL, DEXTERITY_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_DEXTERITY]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_STRENGTH], STATS_FIRST_COL, STRENGTH_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL, STRENGTH_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_STRENGTH]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_LEADERSHIP], STATS_FIRST_COL, LEADERSHIP_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL, LEADERSHIP_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_LEADERSHIP]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_WISDOM], STATS_FIRST_COL, WISDOM_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_FIRST_COL, WISDOM_Y, FIRST_COLUMN_DOT, CharacterInfo[AIM_MEMBER_WISDOM]);
+
+
+ //Second column in stats box. Exp.Level, Markmanship, mechanical, explosive, medical
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_EXP_LEVEL], STATS_SECOND_COL, EXPLEVEL_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL, EXPLEVEL_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_EXP_LEVEL]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_MARKSMANSHIP], STATS_SECOND_COL, MARKSMAN_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT , FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ DisplayDots(STATS_SECOND_COL, MARKSMAN_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MARKSMANSHIP]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_MECHANICAL], STATS_SECOND_COL, MECHANAICAL_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL, MECHANAICAL_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MECHANICAL]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_EXPLOSIVE], STATS_SECOND_COL, EXPLOSIVE_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL, EXPLOSIVE_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_EXPLOSIVE]);
+
+ DrawTextToScreen(CharacterInfo[AIM_MEMBER_MEDICAL], STATS_SECOND_COL, MEDICAL_Y, 0, AIM_M_FONT_STATIC_TEXT, AIM_M_COLOR_STATIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayDots(STATS_SECOND_COL, MEDICAL_Y, SECOND_COLUMN_DOT, CharacterInfo[AIM_MEMBER_MEDICAL]);
+
+
+ //
+ // Display all the Merc dynamic stat info
+ //
+
+ //Name
+ DrawTextToScreen(gMercProfiles[gbCurrentSoldier].zName, NAME_X, NAME_Y, 0, FONT14ARIAL, AIM_M_COLOR_DYNAMIC_TEXT, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+
+ // Numbers for above. Health, Agility, dexterity, strength, leadership, wisdom
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bLife );
+ DrawNumeralsToScreen( gMercProfiles[gbCurrentSoldier].bLife, 3, STATS_FIRST_NUM, HEALTH_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bAgility );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bAgility, 3, STATS_FIRST_NUM, AGILITY_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bDexterity );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bDexterity, 3, STATS_FIRST_NUM, DEXTERITY_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bStrength );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bStrength, 3, STATS_FIRST_NUM, STRENGTH_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bLeadership );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bLeadership, 3, STATS_FIRST_NUM, LEADERSHIP_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bWisdom );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bWisdom, 3, STATS_FIRST_NUM, WISDOM_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ //Second column in stats box. Exp.Level, Markmanship, mechanical, explosive, medical
+
+ // ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bExpLevel );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bExpLevel, 3, STATS_SECOND_NUM, EXPLEVEL_Y, AIM_M_NUMBER_FONT, FONT_MCOLOR_WHITE );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMarksmanship );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMarksmanship, 3, STATS_SECOND_NUM, MARKSMAN_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMechanical );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMechanical, 3, STATS_SECOND_NUM, MECHANAICAL_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bExplosive );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bExplosive, 3, STATS_SECOND_NUM, EXPLOSIVE_Y, AIM_M_NUMBER_FONT, ubColor );
+
+ ubColor = GetStatColor( gMercProfiles[gbCurrentSoldier].bMedical );
+ DrawNumeralsToScreen(gMercProfiles[gbCurrentSoldier].bMedical, 3, STATS_SECOND_NUM, MEDICAL_Y, AIM_M_NUMBER_FONT, ubColor );
+ }
}
UINT8 GetStatColor( INT8 bStat )
@@ -1695,7 +2436,8 @@ if (LaptopSaveInfo.iCurrentBalance == 4500001) {
unsigned hired = 0;
while (hired < gGameExternalOptions.ubGameMaximumNumberOfPlayerMercs) {
if (AimMemberHireMerc()) {
- giIdOfLastHiredMerc = AimMercArray[gbCurrentIndex];
+// giIdOfLastHiredMerc = AimMercArray[gbCurrentIndex];
+ giIdOfLastHiredMerc = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
++hired;
}
++gbCurrentIndex;
@@ -1739,7 +2481,8 @@ if (LaptopSaveInfo.iCurrentBalance == 4500001) {
SpecifyDisabledButtonStyle( giBuyEquipmentButton[0], DISABLED_STYLE_NONE );
SpecifyDisabledButtonStyle( giBuyEquipmentButton[1], DISABLED_STYLE_NONE );
- giIdOfLastHiredMerc = AimMercArray[gbCurrentIndex];
+// giIdOfLastHiredMerc = AimMercArray[gbCurrentIndex];
+ giIdOfLastHiredMerc = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
}
}
/*
@@ -1773,7 +2516,8 @@ if (LaptopSaveInfo.iCurrentBalance == 4500001) {
INT8 AimMemberHireMerc()
{
MERC_HIRE_STRUCT HireMercStruct;
- UINT8 ubCurrentSoldier = AimMercArray[gbCurrentIndex];
+// UINT8 ubCurrentSoldier = AimMercArray[gbCurrentIndex];
+ UINT8 ubCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
INT8 bReturnCode;
INT16 sSoldierID=0;
INT8 bTypeOfContract=0;
@@ -1809,6 +2553,7 @@ INT8 AimMemberHireMerc()
//if the players is buyibng the equipment
if( gfBuyEquipment )
{
+ gMercProfiles[ ubCurrentSoldier ].usOptionalGearCost = 0;
gMercProfiles[ ubCurrentSoldier ].ubMiscFlags |= PROFILE_MISC_FLAG_ALREADY_USED_ITEMS;
}
@@ -3368,7 +4113,7 @@ BOOLEAN InitDeleteVideoConferencePopUp( )
if( gMercProfiles[gbCurrentSoldier].usOptionalGearCost == 0 )
DisableButton( giBuyEquipmentButton[1] );
- if(!ALLOW_EQUIP && is_networked)
+ if(!cAllowMercEquipment && is_networked)
{
gfBuyEquipment = FALSE;
DisableButton( giBuyEquipmentButton[0] );
@@ -4201,7 +4946,8 @@ BOOLEAN QuickHireMerc()
{
INT8 bReturnCode;
MERC_HIRE_STRUCT HireMercStruct;
- UINT8 ubCurrentSoldier = AimMercArray[gbCurrentIndex];
+// UINT8 ubCurrentSoldier = AimMercArray[gbCurrentIndex];
+ UINT8 ubCurrentSoldier = gAimAvailability[AimMercArray[gbCurrentIndex]].ProfilId;
giContractAmount = 0;
@@ -4498,17 +5244,248 @@ void DisplayPopUpBoxExplainingMercArrivalLocationAndTimeCallBack( UINT8 bExitVal
void DisplayAimMemberClickOnFaceHelpText()
{
- //display the 'left and right click' onscreen help msg
- DrawTextToScreen( AimMemberText[0], AIM_FI_LEFT_CLICK_TEXT_X, AIM_FI_LEFT_CLICK_TEXT_Y, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_TITLE_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
- DrawTextToScreen( AimMemberText[1], AIM_FI_LEFT_CLICK_TEXT_X, AIM_FI_LEFT_CLICK_TEXT_Y+AIM_FI_CLICK_DESC_TEXT_Y_OFFSET, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
-
+ if(gGameExternalOptions.gfUseNewStartingGearInterface)
+ {
+ //display the 'left click' onscreen help msg a bit to the right
+ DrawTextToScreen( AimMemberText[0], AIM_FI_LEFT_CLICK_TEXT_X_NSGI, AIM_FI_LEFT_CLICK_TEXT_Y_NSGI, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_TITLE_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DrawTextToScreen( AimMemberText[1], AIM_FI_LEFT_CLICK_TEXT_X_NSGI, AIM_FI_LEFT_CLICK_TEXT_Y_NSGI+AIM_FI_CLICK_DESC_TEXT_Y_OFFSET, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+ else
+ {
+ //display the 'left click' onscreen help msg
+ DrawTextToScreen( AimMemberText[0], AIM_FI_LEFT_CLICK_TEXT_X, AIM_FI_LEFT_CLICK_TEXT_Y, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_TITLE_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DrawTextToScreen( AimMemberText[1], AIM_FI_LEFT_CLICK_TEXT_X, AIM_FI_LEFT_CLICK_TEXT_Y+AIM_FI_CLICK_DESC_TEXT_Y_OFFSET, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+ //display the 'right click' onscreen help msg
DrawTextToScreen( AimMemberText[2], AIM_FI_RIGHT_CLICK_TEXT_X, AIM_FI_LEFT_CLICK_TEXT_Y, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_TITLE_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
DrawTextToScreen( AimMemberText[3], AIM_FI_RIGHT_CLICK_TEXT_X, AIM_FI_LEFT_CLICK_TEXT_Y+AIM_FI_CLICK_DESC_TEXT_Y_OFFSET, AIM_FI_CLICK_TEXT_WIDTH, AIM_FI_HELP_FONT, AIM_FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
}
+void CreateWeaponBoxMouseRegions()
+{
+ UINT16 i, x, uiPosX, uiPosY;
+ UINT16 itemcounter = 0;
+ //tais: Weaponbox Mouseregions
+ for(i=0; i 1) {
+ if(buttonEnabled[0] == TRUE) ShowButton(giWeaponboxSelectionButtonOne);
+ if(buttonEnabled[1] == TRUE) ShowButton(giWeaponboxSelectionButtonTwo);
+ if(buttonEnabled[2] == TRUE) ShowButton(giWeaponboxSelectionButtonThree);
+ if(buttonEnabled[3] == TRUE) ShowButton(giWeaponboxSelectionButtonFour);
+ if(buttonEnabled[4] == TRUE) ShowButton(giWeaponboxSelectionButtonFive);
+ }
+ }
+ }
+}
+
+void WeaponKitSelectionUpdate(UINT8 selectedInventory = 0)
+{
+ UINT32 uiLoop;
+ INT16 usItem;
+ if(UsingNewInventorySystem() == true){
+ // Start by resetting all profile inventory values to 0
+ gMercProfiles[gbCurrentSoldier].clearInventory();
+ gMercProfiles[gbCurrentSoldier].ubInvUndroppable = 0;
+ // Next, go through and assign everything but lbe gear
+ for(uiLoop=INV_START_POS; uiLoop 5)
+ gMercProfiles[gbCurrentSoldier].bInvNumber[uiLoop] = gMercProfileGear[gbCurrentSoldier][selectedInventory].iNumber[uiLoop];
+ else
+ gMercProfiles[gbCurrentSoldier].bInvNumber[uiLoop] = 1;
+ }
+ }
+ // Last, go through and assign LBE items. Only needed for new inventory system
+ if((UsingNewInventorySystem() == true))
+ {
+ for(uiLoop=0; uiLoop<5; uiLoop++)
+ {
+ UINT32 uiLoop2 = uiLoop + VESTPOCKPOS;
+ if(gMercProfileGear[gbCurrentSoldier][selectedInventory].lbe[uiLoop] != NONE){
+ gMercProfiles[gbCurrentSoldier].inv[uiLoop2] = gMercProfileGear[gbCurrentSoldier][selectedInventory].lbe[uiLoop];
+ gMercProfiles[gbCurrentSoldier].bInvStatus[uiLoop2] = gMercProfileGear[gbCurrentSoldier][selectedInventory].lStatus[uiLoop];
+ gMercProfiles[gbCurrentSoldier].bInvNumber[uiLoop2] = 1;
+ }
+ }
+ }
+ }
+ gMercProfiles[gbCurrentSoldier].bMainGunAttractiveness = -1;
+ gMercProfiles[gbCurrentSoldier].bArmourAttractiveness = -1;
+
+ for ( uiLoop = 0; uiLoop < gMercProfiles[gbCurrentSoldier].inv.size(); uiLoop++ )
+ {
+ usItem = gMercProfiles[gbCurrentSoldier].inv[ uiLoop ];
+
+ if ( usItem != NOTHING )
+ {
+ // Check if it's a gun
+ if ( Item[ usItem ].usItemClass & IC_GUN )
+ {
+ gMercProfiles[gbCurrentSoldier].bMainGunAttractiveness = Weapon[ usItem ].ubDeadliness;
+ }
+
+ // If it's armour
+ if ( Item[ usItem ].usItemClass & IC_ARMOUR )
+ {
+ gMercProfiles[gbCurrentSoldier].bArmourAttractiveness = min(128,Armour[ Item[ usItem ].ubClassIndex ].ubProtection);
+ }
+ }
+ }
+ gMercProfiles[ gbCurrentSoldier ].usOptionalGearCost = 0;
+ UINT16 tempGearCost = 0;
+ for ( uiLoop = 0; uiLoop< gMercProfiles[ gbCurrentSoldier ].inv.size(); uiLoop++ )
+ {
+ if ( gMercProfiles[ gbCurrentSoldier ].inv[ uiLoop ] != NOTHING )
+ {
+ //get the item
+ usItem = gMercProfiles[ gbCurrentSoldier ].inv[ uiLoop ];
+
+ //add the cost
+ tempGearCost += Item[ usItem ].usPrice;
+ }
+ }
+ //tais: added optional price modifier for gearkits, reads the xml tag mPriceMod from MercStartingGear.xml
+ if(gMercProfileGear[gbCurrentSoldier][selectedInventory].PriceModifier != 0 &&
+ gMercProfileGear[gbCurrentSoldier][selectedInventory].PriceModifier <= 200 &&
+ gMercProfileGear[gbCurrentSoldier][selectedInventory].PriceModifier >= -100)
+ {
+ FLOAT mod;
+ mod = (FLOAT) (gMercProfileGear[gbCurrentSoldier][selectedInventory].PriceModifier + 100) / 100;
+ gMercProfiles[ gbCurrentSoldier ].usOptionalGearCost = (UINT16)(tempGearCost * mod);
+ }
+ else
+ {
+ gMercProfiles[ gbCurrentSoldier ].usOptionalGearCost = tempGearCost;
+ }
+}
diff --git a/Laptop/AimPolicies.cpp b/Laptop/AimPolicies.cpp
index 5f7c912f..2fa45060 100644
--- a/Laptop/AimPolicies.cpp
+++ b/Laptop/AimPolicies.cpp
@@ -9,8 +9,11 @@
#include "WordWrap.h"
#include "Encrypted File.h"
#include "Text.h"
+ #include "GameSettings.h"
#endif
+#include "LocalizedStrings.h"
+
#define NUM_AIM_POLICY_PAGES 11
#define NUM_AIM_POLICY_TOC_BUTTONS 9
#define AIMPOLICYFILE "BINARYDATA\\AimPol.edt"
@@ -38,6 +41,9 @@
#define AIM_POLICY_TITLE_Y AIM_SYMBOL_Y + AIM_SYMBOL_SIZE_Y + 11
#define AIM_POLICY_TITLE_WIDTH AIM_SYMBOL_WIDTH
+//tais: nsgi, move title up
+#define AIM_POLICY_TITLE_Y_NSGI AIM_SYMBOL_Y + 35
+
#define AIM_POLICY_TITLE_STATEMENT_WIDTH 300
#define AIM_POLICY_TITLE_STATEMENT_X IMAGE_OFFSET_X + (500 - AIM_POLICY_TITLE_STATEMENT_WIDTH) / 2 +5//80
#define AIM_POLICY_TITLE_STATEMENT_Y AIM_SYMBOL_Y + AIM_SYMBOL_SIZE_Y + 75
@@ -456,21 +462,20 @@ BOOLEAN ExitAimPolicyMenuBar(void)
BOOLEAN DrawAimPolicyMenu()
{
- UINT16 i, usPosY;
- UINT16 usHeight;
- UINT32 uiStartLoc=0;
- CHAR16 sText[400];
- HVOBJECT hContentButtonHandle;
- UINT8 ubLocInFile[]=
- { DEFINITIONS,
- LENGTH_OF_ENGAGEMENT,
- LOCATION_0F_ENGAGEMENT,
- CONTRACT_EXTENSIONS,
- TERMS_OF_PAYMENT,
- TERMS_OF_ENGAGEMENT,
- ENGAGEMENT_TERMINATION,
- EQUIPMENT_AND_INVENTORY,
- POLICY_MEDICAL};
+ UINT16 i, usPosY;
+ UINT16 usHeight;
+ CHAR16 sText[400];
+ HVOBJECT hContentButtonHandle;
+ UINT8 ubLocInFile[]= {
+ DEFINITIONS,
+ LENGTH_OF_ENGAGEMENT,
+ LOCATION_0F_ENGAGEMENT,
+ CONTRACT_EXTENSIONS,
+ TERMS_OF_PAYMENT,
+ TERMS_OF_ENGAGEMENT,
+ ENGAGEMENT_TERMINATION,
+ EQUIPMENT_AND_INVENTORY,
+ POLICY_MEDICAL};
GetVideoObject(&hContentButtonHandle, guiContentButton);
@@ -478,10 +483,16 @@ BOOLEAN DrawAimPolicyMenu()
usPosY = AIM_POLICY_TOC_Y;
for(i=0; iArea.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
+ ///////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Added ability to scroll forward 5 pages instead of one.
+ // This is done by holding down SHIFT while clicking.
+ //
+
//if previous screen
if( bNewValue == BOBBYR_PREVIOUS_PAGE)
{
if( gubCurPage > 0 )
- gubCurPage--;
+ {
+ if (_KeyDown( 16 ) ) // SHIFT
+ {
+ gubCurPage = __max(gubCurPage - 5, 0);
+ }
+ else
+ {
+ gubCurPage--;
+ }
+ }
}
//else next screen
else
{
if( gubCurPage < gubNumPages-1 )
- gubCurPage++;
+ {
+ if (_KeyDown( 16 ) ) // SHIFT
+ {
+ gubCurPage = __min(gubNumPages, gubCurPage+5);
+ }
+ else
+ {
+ gubCurPage++;
+ }
+ }
}
@@ -1736,10 +1763,11 @@ BOOLEAN DisplayAmmoInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16
BOOLEAN DisplayBigItemImage(UINT16 usIndex, UINT16 PosY)
{
- INT16 PosX, sCenX, sCenY;
- UINT32 usHeight, usWidth;
+ INT16 PosX, sCenX, sCenY;
+ UINT32 usHeight, usWidth;
+ INT32 sOffsetX, sOffsetY;
ETRLEObject *pTrav;
- INVTYPE *pItem;
+ INVTYPE *pItem;
UINT32 uiImage;
HVOBJECT hPixHandle;
@@ -1749,20 +1777,43 @@ BOOLEAN DisplayBigItemImage(UINT16 usIndex, UINT16 PosY)
LoadTileGraphicForItem(pItem, &uiImage);
GetVideoObject(&hPixHandle, uiImage);
- pTrav = &(hPixHandle->pETRLEObject[0]);
- //center picture in frame
- usHeight = (UINT32)pTrav->usHeight;
- usWidth = (UINT32)pTrav->usWidth;
+ if(hPixHandle->ubBitDepth == 8)
+ {
+ pTrav = &(hPixHandle->pETRLEObject[ 0 ] );
+
+ //center picture in frame
+ usHeight = (UINT32)pTrav->usHeight;
+ usWidth = (UINT32)pTrav->usWidth;
+ sOffsetX = (INT32)pTrav->sOffsetX;
+ sOffsetY = (INT32)pTrav->sOffsetY;
+ }
+ else if(hPixHandle->ubBitDepth == 16 && hPixHandle->p16BPPObject)
+ {
+ usHeight = hPixHandle->p16BPPObject->usHeight;
+ usWidth = hPixHandle->p16BPPObject->usWidth;
+ sOffsetX = hPixHandle->p16BPPObject->sOffsetX;
+ sOffsetY = hPixHandle->p16BPPObject->sOffsetY;
+ }
+ else if(hPixHandle->ubBitDepth == 32)
+ {
+ usHeight = hPixHandle->p16BPPObject->usHeight;
+ usWidth = hPixHandle->p16BPPObject->usWidth;
+ sOffsetX = hPixHandle->p16BPPObject->sOffsetX;
+ sOffsetY = hPixHandle->p16BPPObject->sOffsetY;
+ }
+
// sCenX = PosX + ( abs( BOBBYR_GRID_PIC_WIDTH - usWidth ) / 2 );
// sCenY = PosY + 8;
- sCenX = PosX + ( abs( BOBBYR_GRID_PIC_WIDTH - usWidth ) / 2 ) - pTrav->sOffsetX;
+ sCenX = PosX + ( abs( BOBBYR_GRID_PIC_WIDTH - (int)usWidth ) / 2 ) - sOffsetX;
sCenY = PosY + 8;
//blt the shadow of the item
- if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ]) BltVideoObjectOutlineShadowFromIndex( FRAME_BUFFER, uiImage, 0, sCenX-2, sCenY+2);//pItem->ubGraphicNum
-
+ if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ])
+ {
+ BltVideoObjectOutlineShadowFromIndex( FRAME_BUFFER, uiImage, 0, sCenX-2, sCenY+2);//pItem->ubGraphicNum
+ }
BltVideoObject(FRAME_BUFFER, hPixHandle, 0, sCenX, sCenY, VO_BLT_SRCTRANSPARENCY,NULL);
DeleteVideoObjectFromIndex(uiImage);
@@ -1923,9 +1974,13 @@ UINT16 DisplayDamage(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
UINT16 DisplayRange(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
{
CHAR16 sTemp[20];
+ UINT16 gunRange = 0;
DrawTextToScreen(BobbyRText[BOBBYR_GUNS_RANGE], BOBBYR_ITEM_WEIGHT_TEXT_X, (UINT16)usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- swprintf(sTemp, L"%3d %s", Weapon[ usIndex ].usRange, pMessageStrings[ MSG_METER_ABBREVIATION ] );
+
+ gunRange = (UINT16)GetModifiedGunRange( usIndex);
+
+ swprintf(sTemp, L"%3d %s", gunRange, pMessageStrings[ MSG_METER_ABBREVIATION ] );
DrawTextToScreen(sTemp, BOBBYR_ITEM_WEIGHT_NUM_X, (UINT16)usPosY, BOBBYR_ITEM_WEIGHT_NUM_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, RIGHT_JUSTIFIED);
usPosY += usFontHeight + 2;
return(usPosY);
@@ -2417,6 +2472,7 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum
//UINT16 gunDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier );
UINT16 gunDamage = (UINT16)GetModifiedGunDamage( Weapon[ pItemNumbers[ i ] ].ubImpact );
UINT16 readyAPs = (UINT16)(( Weapon[ pItemNumbers[ i ] ].ubReadyTime * (100 - Item[ pItemNumbers[ i ] ].percentreadytimeapreduction)) / 100);
+ UINT16 gunRange = (UINT16)GetModifiedGunRange(pItemNumbers[ i ]);
//Calculate AP's
CHAR16 apStr[20];
@@ -2504,18 +2560,48 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum
wcscat( attachStr, attachStr3 );
}
}
+
+ //Sum up default attachments.
+ BOOLEAN fFoundDefault = FALSE;
+ swprintf( attachStr2, L"" );
+ swprintf( attachStr3, L"" );
+ for(UINT8 cnt = 0; cnt < MAX_DEFAULT_ATTACHMENTS; cnt++){
+ if(Item[pItemNumbers[ i ]].defaultattachments[cnt] != 0){
+ if (wcslen( attachStr ) + wcslen(attachStr3) + wcslen(Item[ Item[pItemNumbers[ i ]].defaultattachments[cnt] ].szItemName) > 3800)
+ {
+ // End list early to avoid stack overflow
+ wcscat( attachStr3, L"\n..." );
+ break;
+ }
+ fFoundDefault = TRUE;
+ swprintf( attachStr2, L"\n%s", Item[ Item[pItemNumbers[ i ]].defaultattachments[cnt] ].szItemName );
+ wcscat( attachStr3, attachStr2 );
+ } else {
+ //If we found an empty entry, we can assume the rest will be empty too.
+ break;
+ }
+ }
+ if(fFoundDefault){
+ //Found at least one default attachment, write it to the attachment string.
+ CHAR16 defaultStr[50];
+ swprintf( defaultStr, L"\n \n%s", gWeaponStatsDesc[ 17 ] );
+ wcscat( attachStr, defaultStr );
+ wcscat( attachStr, attachStr3 );
+ }
+
// HEADROCK HAM 3: Added last string (attachStr), for display of the possible attachment list.
// If the feature is deactivated, the attachStr will simply be empty at this point
// (remember? we emptied it earlier!).
+ INT8 accuracy = (UsingNewCTHSystem()==true?Weapon[ pItemNumbers[ i ] ].nAccuracy:Weapon[ pItemNumbers[ i ] ].bAccuracy);
swprintf( pStr, L"%s (%s)\n%s %d\n%s %d\n%s %d\n%s (%d) %s\n%s %1.1f %s%s",
ItemNames[ pItemNumbers[ i ] ],
AmmoCaliber[ Weapon[ pItemNumbers[ i ] ].ubCalibre ],
gWeaponStatsDesc[ 9 ], //Accuracy String
- Weapon[ pItemNumbers[ i ] ].bAccuracy, //Accuracy
+ accuracy, //Accuracy
gWeaponStatsDesc[ 11 ], //Damage String
gunDamage, //Gun damage
gWeaponStatsDesc[ 10 ], //Range String
- gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? Weapon[ pItemNumbers[ i ] ].usRange/10 : Weapon[ pItemNumbers[ i ] ].usRange, //Gun Range
+ gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? gunRange/10 : gunRange, //Gun Range
gWeaponStatsDesc[ 6 ], //AP String
readyAPs,
apStr, //AP's
@@ -2571,16 +2657,18 @@ void CreateMouseRegionForBigImage( UINT16 usPosY, UINT8 ubCount, INT16 *pItemNum
{
// HEADROCK HAM 3.6: Can now take a negative modifier.
UINT16 gunDamage = (UINT16)GetModifiedGunDamage( Weapon[ pItemNumbers[ i ] ].ubImpact );
+ UINT16 usRange = (UINT16)GetModifiedGunRange(pItemNumbers[ i ]);
+ INT8 accuracy = (UsingNewCTHSystem()==true?Weapon[ pItemNumbers[ i ] ].nAccuracy:Weapon[ pItemNumbers[ i ] ].bAccuracy);
//UINT16 gunDamage = (UINT16)( Weapon[ pItemNumbers[ i ] ].ubImpact + ( (double) Weapon[ pItemNumbers[ i ] ].ubImpact / 100) * gGameExternalOptions.ubGunDamageMultiplier );
swprintf( pStr, L"%s\n%s %d\n%s %d\n%s %d\n%s %s\n%s %1.1f %s",
ItemNames[ pItemNumbers[ i ] ],
gWeaponStatsDesc[ 9 ], //Accuracy String
- Weapon[ pItemNumbers[ i ] ].bAccuracy, //Accuracy
+ accuracy, //Accuracy
gWeaponStatsDesc[ 11 ], //Damage String
gunDamage, //Gun damage
gWeaponStatsDesc[ 10 ], //Range String
- gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? Weapon[ pItemNumbers[ i ] ].usRange/10 : Weapon[ pItemNumbers[ i ] ].usRange, //Gun Range
+ gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? usRange/10 : usRange, //Gun Range
gWeaponStatsDesc[ 6 ], //AP String
//apStr, //AP's
L"- / - / -",
@@ -2764,7 +2852,11 @@ void SelectBigImageRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
{
UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
- PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
+ // HEADROCK HAM 4: Purchase all at once.
+ if (_KeyDown( 16 ) ) // SHIFT
+ PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum], TRUE );
+ else
+ PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum], FALSE );
fReDrawScreenFlag = TRUE;
fPausedReDrawScreenFlag = TRUE;
@@ -2773,7 +2865,11 @@ void SelectBigImageRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
{
UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
- UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
+ // HEADROCK HAM 4: Unpurchase all at once.
+ if (_KeyDown( 16 ) ) // SHIFT
+ UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum], TRUE );
+ else
+ UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum], FALSE );
fReDrawScreenFlag = TRUE;
fPausedReDrawScreenFlag = TRUE;
}
@@ -2781,7 +2877,7 @@ void SelectBigImageRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
{
UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
- PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
+ PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum], FALSE );
fReDrawScreenFlag = TRUE;
fPausedReDrawScreenFlag = TRUE;
}
@@ -2789,7 +2885,7 @@ void SelectBigImageRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
{
UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
- UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
+ UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum], FALSE );
fReDrawScreenFlag = TRUE;
fPausedReDrawScreenFlag = TRUE;
}
@@ -2797,7 +2893,7 @@ void SelectBigImageRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
-void PurchaseBobbyRayItem(UINT16 usItemNumber)
+void PurchaseBobbyRayItem(UINT16 usItemNumber, BOOLEAN fAllItems )
{
UINT8 ubPurchaseNumber;
@@ -2816,8 +2912,10 @@ void PurchaseBobbyRayItem(UINT16 usItemNumber)
if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED )
{
+ UINT8 ubNumItems = fAllItems ? LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].ubQtyOnHand : 1;
+
BobbyRayPurchases[ ubPurchaseNumber ].usItemIndex = LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].usItemIndex;
- BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = 1;
+ BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = ubNumItems;
BobbyRayPurchases[ ubPurchaseNumber ].bItemQuality = LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].ubItemQuality;
BobbyRayPurchases[ ubPurchaseNumber ].usBobbyItemIndex = usItemNumber;
BobbyRayPurchases[ ubPurchaseNumber ].fUsed = TRUE;
@@ -2832,8 +2930,10 @@ void PurchaseBobbyRayItem(UINT16 usItemNumber)
// Else If the item is already purchased increment purchase amount. Only if ordering less then the max amount!
else
{
- if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased <= BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE)
- BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased++;
+ UINT8 ubNumItems = fAllItems ? LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].ubQtyOnHand - BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased : 1;
+
+ if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased <= BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE - (ubNumItems-1))
+ BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased += ubNumItems;
}
}
else
@@ -2858,8 +2958,10 @@ void PurchaseBobbyRayItem(UINT16 usItemNumber)
if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED )
{
+ UINT8 ubNumItems = fAllItems ? LaptopSaveInfo.BobbyRayInventory[ usItemNumber ].ubQtyOnHand : 1;
+
BobbyRayPurchases[ ubPurchaseNumber ].usItemIndex = LaptopSaveInfo.BobbyRayInventory[ usItemNumber ].usItemIndex;
- BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = 1;
+ BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = ubNumItems;
BobbyRayPurchases[ ubPurchaseNumber ].bItemQuality = 100;
BobbyRayPurchases[ ubPurchaseNumber ].usBobbyItemIndex = usItemNumber;
BobbyRayPurchases[ ubPurchaseNumber ].fUsed = FALSE;
@@ -2873,8 +2975,10 @@ void PurchaseBobbyRayItem(UINT16 usItemNumber)
// Else If the item is already purchased increment purchase amount. Only if ordering less then the max amount!
else
{
- if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased <= BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE)
- BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased++;
+ UINT8 ubNumItems = fAllItems ? LaptopSaveInfo.BobbyRayInventory[ usItemNumber ].ubQtyOnHand - BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased : 1;
+
+ if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased <= BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE - (ubNumItems-1))
+ BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased += ubNumItems;
}
}
else
@@ -2916,7 +3020,7 @@ UINT8 GetNextPurchaseNumber()
-void UnPurchaseBobbyRayItem(UINT16 usItemNumber)
+void UnPurchaseBobbyRayItem(UINT16 usItemNumber, BOOLEAN fAllItems )
{
UINT8 ubPurchaseNumber;
@@ -2924,7 +3028,7 @@ void UnPurchaseBobbyRayItem(UINT16 usItemNumber)
if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED )
{
- if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased > 1)
+ if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased > 1 && !fAllItems)
BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased--;
else
{
diff --git a/Laptop/BobbyRMailOrder.cpp b/Laptop/BobbyRMailOrder.cpp
index e3823c40..179b9f4d 100644
--- a/Laptop/BobbyRMailOrder.cpp
+++ b/Laptop/BobbyRMailOrder.cpp
@@ -31,6 +31,7 @@
#include "Strategic Event Handler.h"
#include "connect.h"
+/*
typedef struct
{
STR16 *psCityLoc;
@@ -38,8 +39,9 @@ typedef struct
UINT16 us2DaysService;
UINT16 usStandardService;
} BobbyROrderLocationStruct;
+*/
-
+/*
BobbyROrderLocationStruct BobbyROrderLocations[]=
{
{ &pDeliveryLocationStrings[0], 20, 15, 10 },
@@ -60,6 +62,7 @@ BobbyROrderLocationStruct BobbyROrderLocations[]=
{ &pDeliveryLocationStrings[15], 100, 55, 30 },
{ &pDeliveryLocationStrings[16], 45, 30, 20 },
};
+*/
//drop down menu
enum
@@ -829,7 +832,10 @@ void BtnBobbyRAcceptOrderCallback(GUI_BUTTON *btn,INT32 reason)
else
{
//else pop up a confirmation box
- swprintf( zTemp, BobbyROrderFormText[BOBBYR_CONFIRM_DEST], *BobbyROrderLocations[gbSelectedCity].psCityLoc );
+ //swprintf( zTemp, BobbyROrderFormText[BOBBYR_CONFIRM_DEST], *BobbyROrderLocations[gbSelectedCity].psCityLoc );
+
+ // WANNE: Replaced hard coded town names with the externalized ones (from ShippingDestination.xml).
+ swprintf( zTemp, BobbyROrderFormText[BOBBYR_CONFIRM_DEST], gDestinationTable[gbSelectedCity]->wstrName.c_str() );
DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, zTemp, LAPTOP_SCREEN, MSG_BOX_FLAG_YESNO, ConfirmBobbyRPurchaseMessageBoxCallBack );
}
@@ -1433,10 +1439,12 @@ BOOLEAN CreateDestroyBobbyRDropDown( UINT8 ubDropDownAction )
//display the name on the title bar
ColorFillVideoSurfaceArea( FRAME_BUFFER, BOBBYR_SHIPPING_LOC_AREA_L_X, BOBBYR_SHIPPING_LOC_AREA_T_Y, BOBBYR_SHIPPING_LOC_AREA_L_X+175, BOBBYR_SHIPPING_LOC_AREA_T_Y+BOBBYR_DROP_DOWN_HEIGHT, Get16BPPColor( FROMRGB( 0, 0, 0 ) ) );
+ /*
if( gbSelectedCity == -1 )
DrawTextToScreen( BobbyROrderFormText[BOBBYR_SELECT_DEST], BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, BOBBYR_SHIPPING_LOC_AREA_T_Y+3, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_DROP_DOWN_SELEC_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- else
+ else
DrawTextToScreen( *(BobbyROrderLocations[gbSelectedCity].psCityLoc), BOBBYR_CITY_START_LOCATION_X+BOBBYR_CITY_NAME_OFFSET, BOBBYR_SHIPPING_LOC_AREA_T_Y+3, 0, BOBBYR_DROPDOWN_FONT, BOBBYR_ORDER_DROP_DOWN_SELEC_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ */
//disable the r\close regiuon
MSYS_DisableRegion(&gSelectedCloseDropDownRegion);
diff --git a/Laptop/CharProfile.cpp b/Laptop/CharProfile.cpp
index 00c799b9..a50c796e 100644
--- a/Laptop/CharProfile.cpp
+++ b/Laptop/CharProfile.cpp
@@ -25,11 +25,12 @@
#include "IMP Confirm.h"
#include "messageboxscreen.h"
#include "LaptopSave.h"
- // These 4 added - SANDRO
+ // These 5 added - SANDRO
#include "IMP Character and Disability Entrance.h"
#include "IMP Character Trait.h"
#include "IMP Disability Trait.h"
#include "IMP Color Choosing.h"
+ #include "IMP Minor Trait.h"
#endif
@@ -67,6 +68,7 @@ CHAR16 pNickName[ 32 ];
// skills
INT32 iSkillA = 0;
INT32 iSkillB = 0;
+INT32 iSkillC = 0; // added third skill - SANDRO
// personality
INT32 iPersonality = 0;
@@ -255,7 +257,7 @@ void HandleCharProfile()
case( IMP_CONFIRM ):
HandleIMPConfirm( );
break;
- // These 4 added - SANDRO
+ // These 5 added - SANDRO
case( IMP_CHARACTER_AND_DISABILITY_ENTRANCE ):
HandleIMPCharacterAndDisabilityEntrance( );
break;
@@ -268,6 +270,9 @@ void HandleCharProfile()
case( IMP_COLOR_CHOICE_PAGE ):
HandleIMPColorChoice( );
break;
+ case( IMP_MINOR_TRAITS_PAGE ):
+ HandleIMPMinorTrait( );
+ break;
}
return;
@@ -328,7 +333,7 @@ void RenderCharProfile()
case( IMP_CONFIRM ):
RenderIMPConfirm( );
break;
- // These 4 added - SANDRO
+ // These 5 added - SANDRO
case( IMP_CHARACTER_AND_DISABILITY_ENTRANCE ):
RenderIMPCharacterAndDisabilityEntrance( );
break;
@@ -341,6 +346,9 @@ void RenderCharProfile()
case( IMP_COLOR_CHOICE_PAGE ):
RenderIMPColorChoice( );
break;
+ case( IMP_MINOR_TRAITS_PAGE ):
+ RenderIMPMinorTrait( );
+ break;
}
// render title bar
@@ -425,7 +433,7 @@ void ExitOldIMPMode( void )
case( IMP_CONFIRM ):
ExitIMPConfirm( );
break;
- // These 4 added - SANDRO
+ // These 5 added - SANDRO
case( IMP_CHARACTER_AND_DISABILITY_ENTRANCE ):
DestroyIMPButtons( );
ExitIMPCharacterAndDisabilityEntrance( );
@@ -442,6 +450,10 @@ void ExitOldIMPMode( void )
DestroyIMPButtons( );
ExitIMPColorChoice( );
break;
+ case( IMP_MINOR_TRAITS_PAGE ):
+ DestroyIMPButtons( );
+ ExitIMPMinorTrait( );
+ break;
}
return;
@@ -508,7 +520,7 @@ void EnterNewIMPMode( void )
case( IMP_CONFIRM ):
EnterIMPConfirm( );
break;
- // These 4 added - SANDRO
+ // These 5 added - SANDRO
case( IMP_CHARACTER_AND_DISABILITY_ENTRANCE ):
CreateIMPButtons( );
EnterIMPCharacterAndDisabilityEntrance( );
@@ -525,6 +537,10 @@ void EnterNewIMPMode( void )
CreateIMPButtons( );
EnterIMPColorChoice( );
break;
+ case( IMP_MINOR_TRAITS_PAGE ):
+ CreateIMPButtons( );
+ EnterIMPMinorTrait( );
+ break;
}
@@ -552,6 +568,7 @@ void ResetCharacterStats( void )
// skills
iSkillA = 0;
iSkillB = 0;
+ iSkillC = 0; // SANDRO - added third skill
// personality
iPersonality = 0;
@@ -614,8 +631,9 @@ void LoadImpGraphics( void )
LoadAvgMercIndentFrame( );
LoadAboutUsIndentFrame( );
- LoadAttribStartingLevelFrame( ); // Added by SANDRO
- LoadColorChoiceFrame( ); // Added by SANDRO
+ // Added by SANDRO
+ LoadAttribStartingLevelFrame( );
+ LoadColorChoiceFrame( );
return;
@@ -666,9 +684,10 @@ void RemoveImpGraphics( void )
DeleteAttrib2IndentFrame( );
DeleteAvgMercIndentFrame( );
DeleteAboutUsIndentFrame( );
-
- DeleteAttribStartingLevelFrame( ); // Added by SANDRO
- DeleteColorChoiceFrame( ); // Added by SANDRO
+
+ // Added by SANDRO
+ DeleteAttribStartingLevelFrame( );
+ DeleteColorChoiceFrame( );
return;
}
diff --git a/Laptop/CharProfile.h b/Laptop/CharProfile.h
index e884dd59..f569b217 100644
--- a/Laptop/CharProfile.h
+++ b/Laptop/CharProfile.h
@@ -38,6 +38,7 @@ extern CHAR16 pNickName[];
// skills
extern INT32 iSkillA;
extern INT32 iSkillB;
+extern INT32 iSkillC; // Added by SANDRO
// persoanlity
extern INT32 iPersonality;
@@ -78,11 +79,12 @@ enum{
IMP_VOICE,
IMP_ABOUT_US,
IMP_CONFIRM,
- // These 4 added - SANDRO
+ // These 5 added - SANDRO
IMP_CHARACTER_AND_DISABILITY_ENTRANCE,
IMP_CHARACTER_PAGE,
IMP_DISABILITY_PAGE,
IMP_COLOR_CHOICE_PAGE,
+ IMP_MINOR_TRAITS_PAGE,
IMP_NUM_PAGES,
};
diff --git a/Laptop/IMP Attribute Selection.cpp b/Laptop/IMP Attribute Selection.cpp
index 89500489..0a0d84fa 100644
--- a/Laptop/IMP Attribute Selection.cpp
+++ b/Laptop/IMP Attribute Selection.cpp
@@ -23,7 +23,10 @@
#include "IMP Compile Character.h"
#include "text.h"
#include "GameSettings.h"
- #include "IMP Disability Trait.h" // Added this one - SANDRO
+ // Added these 3 - SANDRO
+ #include "IMP Disability Trait.h"
+ #include "IMP Color Choosing.h"
+ #include "IMP Minor Trait.h"
#endif
@@ -84,6 +87,19 @@ INT32 iCurrentMechanical = 0;
INT32 iCurrentMedical = 0;
INT32 iCurrentExplosives = 0;
+INT32 iStrengthMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iAgilityMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iDexterityMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iHealthMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iLeaderShipMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iWisdomMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iMarkmanshipMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iMechanicalMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iMedicalMinimum = gGameExternalOptions.iMinAttribute;
+INT32 iExplosivesMinimum = gGameExternalOptions.iMinAttribute;
+
+
+
// which stat is message about stat at zero about
INT32 iCurrentStatAtZero = 0;
@@ -460,36 +476,36 @@ void ProcessAttributes( void )
INT32 iMaxAttribute = gGameExternalOptions.iMaxAttribute;
// strength
- if( iCurrentStrength <= iMinAttribute )
+ if( iCurrentStrength <= iStrengthMinimum )
{
- iCurrentStrength = iMinAttribute;
+ iCurrentStrength = iStrengthMinimum;
// disable button too
}
// dex
- if( iCurrentDexterity <= iMinAttribute )
+ if( iCurrentDexterity <= iDexterityMinimum )
{
- iCurrentDexterity = iMinAttribute;
+ iCurrentDexterity = iDexterityMinimum;
// disable button too
}
// agility
- if( iCurrentAgility <= iMinAttribute )
+ if( iCurrentAgility <= iAgilityMinimum )
{
- iCurrentAgility = iMinAttribute;
+ iCurrentAgility = iAgilityMinimum;
// disable button too
}
// wisdom
- if( iCurrentWisdom <= iMinAttribute )
+ if( iCurrentWisdom <= iWisdomMinimum )
{
- iCurrentWisdom = iMinAttribute;
+ iCurrentWisdom = iWisdomMinimum;
// disable button too
@@ -504,9 +520,9 @@ void ProcessAttributes( void )
//}
// health
- if( iCurrentHealth <= iMinAttribute )
+ if( iCurrentHealth <= iHealthMinimum )
{
- iCurrentHealth = iMinAttribute;
+ iCurrentHealth = iHealthMinimum;
// disable button too
}
@@ -668,7 +684,7 @@ UINT8 IncrementStat( INT32 iStatToIncrement )
{
if( DoWeHaveThisManyBonusPoints( iMaxZeroBonus ) == TRUE )
{
- iCurrentLeaderShip+=iMinAttribute;
+ iCurrentLeaderShip+=iLeaderShipMinimum;
iCurrentBonusPoints-=iMaxZeroBonus;
fSkillAtZeroWarning = FALSE;
}
@@ -696,7 +712,7 @@ UINT8 IncrementStat( INT32 iStatToIncrement )
{
if( DoWeHaveThisManyBonusPoints( iMaxZeroBonus ) == TRUE )
{
- iCurrentMarkmanship+=iMinAttribute;
+ iCurrentMarkmanship+=iMarkmanshipMinimum;
iCurrentBonusPoints-=iMaxZeroBonus;
fSkillAtZeroWarning = FALSE;
}
@@ -724,7 +740,7 @@ UINT8 IncrementStat( INT32 iStatToIncrement )
{
if( DoWeHaveThisManyBonusPoints( iMaxZeroBonus ) == TRUE )
{
- iCurrentMechanical+=iMinAttribute;
+ iCurrentMechanical+=iMechanicalMinimum;
iCurrentBonusPoints-=iMaxZeroBonus;
fSkillAtZeroWarning = FALSE;
}
@@ -752,7 +768,7 @@ UINT8 IncrementStat( INT32 iStatToIncrement )
{
if( DoWeHaveThisManyBonusPoints( iMaxZeroBonus ) == TRUE )
{
- iCurrentMedical+=iMinAttribute;
+ iCurrentMedical+=iMedicalMinimum;
iCurrentBonusPoints-=iMaxZeroBonus;
fSkillAtZeroWarning = FALSE;
}
@@ -780,7 +796,7 @@ UINT8 IncrementStat( INT32 iStatToIncrement )
{
if( DoWeHaveThisManyBonusPoints( iMaxZeroBonus ) == TRUE )
{
- iCurrentExplosives+=iMinAttribute;
+ iCurrentExplosives+=iExplosivesMinimum;
iCurrentBonusPoints-=iMaxZeroBonus;
fSkillAtZeroWarning = FALSE;
}
@@ -821,23 +837,23 @@ UINT8 DecrementStat( INT32 iStatToDecrement )
switch( iStatToDecrement )
{
case( STRENGTH_ATTRIBUTE ):
- if( iCurrentStrength > iMinAttribute )
+ if( iCurrentStrength > iStrengthMinimum )
{
// ok to decrement
iCurrentStrength--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
else
{
return( SLIDER_OUT_OF_RANGE );
}
break;
- case( DEXTERITY_ATTRIBUTE ):
- if( iCurrentDexterity > iMinAttribute )
+ case( DEXTERITY_ATTRIBUTE ):
+ if( iCurrentDexterity > iDexterityMinimum )
{
// ok to decrement
iCurrentDexterity--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
else
{
@@ -845,23 +861,23 @@ UINT8 DecrementStat( INT32 iStatToDecrement )
}
break;
case( AGILITY_ATTRIBUTE ):
- if( iCurrentAgility > iMinAttribute )
+ if( iCurrentAgility > iAgilityMinimum )
{
// ok to decrement
iCurrentAgility--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
else
{
return( SLIDER_OUT_OF_RANGE );
}
break;
- case( WISDOM_ATTRIBUTE ):
- if( iCurrentWisdom > iMinAttribute )
+ case( WISDOM_ATTRIBUTE ):
+ if( iCurrentWisdom > iWisdomMinimum )
{
// ok to decrement
iCurrentWisdom--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
else
{
@@ -869,91 +885,106 @@ UINT8 DecrementStat( INT32 iStatToDecrement )
}
break;
case( LEADERSHIP_ATTRIBUTE ):
- if( iCurrentLeaderShip > iMinAttribute )
+ if( iCurrentLeaderShip > iLeaderShipMinimum )
{
// ok to decrement
iCurrentLeaderShip--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
//Kaiden: Leadership couldn't be set to zero fixed below:
- else if( iCurrentLeaderShip == iMinAttribute)
+ else if( iCurrentLeaderShip == iLeaderShipMinimum)
{
- // ok to decrement
- iCurrentLeaderShip-=iMinAttribute;
- iCurrentBonusPoints+=iMaxZeroBonus;
- fSkillAtZeroWarning = TRUE;
+ if (LeadershipRequiredDueToMajorSkills() == 0 && LeaderShipRequiredAdjustmentForMinorTraits( 0 ) == 0 )
+ {
+ // ok to decrement
+ iCurrentLeaderShip-=iLeaderShipMinimum;
+ iCurrentBonusPoints+=iMaxZeroBonus;
+ fSkillAtZeroWarning = TRUE;
+ }
}
break;
case( HEALTH_ATTRIBUTE ):
- if( iCurrentHealth > iMinAttribute )
+ if( iCurrentHealth > iHealthMinimum )
{
// ok to decrement
iCurrentHealth--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
else
{
return( SLIDER_OUT_OF_RANGE );
}
break;
- case( MARKSMANSHIP_SKILL ):
- if( iCurrentMarkmanship > iMinAttribute )
+ case( MARKSMANSHIP_SKILL ):
+ if( iCurrentMarkmanship > iMarkmanshipMinimum )
{
// ok to decrement
iCurrentMarkmanship--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
- else if( iCurrentMarkmanship == iMinAttribute)
+ else if( iCurrentMarkmanship == iMarkmanshipMinimum)
{
- // ok to decrement
- iCurrentMarkmanship-=iMinAttribute;
- iCurrentBonusPoints+=iMaxZeroBonus;
- fSkillAtZeroWarning = TRUE;
+ if (MarksmanshipRequiredDueToMajorSkills() == 0 && MarksmanshipRequiredAdjustmentForMinorTraits( 0 ) == 0 )
+ {
+ // ok to decrement
+ iCurrentMarkmanship-=iMarkmanshipMinimum;
+ iCurrentBonusPoints+=iMaxZeroBonus;
+ fSkillAtZeroWarning = TRUE;
+ }
}
break;
case( MEDICAL_SKILL ):
- if( iCurrentMedical > iMinAttribute )
+ if( iCurrentMedical > iMedicalMinimum )
{
// ok to decrement
iCurrentMedical--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
- else if( iCurrentMedical == iMinAttribute)
+ else if( iCurrentMedical == iMedicalMinimum)
{
- // ok to decrement
- iCurrentMedical-=iMinAttribute;
- iCurrentBonusPoints+=iMaxZeroBonus;
- fSkillAtZeroWarning = TRUE;
+ if (MedicalRequiredDueToMajorSkills() == 0 && MedicalRequiredAdjustmentForMinorTraits( 0 ) == 0 )
+ {
+ // ok to decrement
+ iCurrentMedical-=iMedicalMinimum;
+ iCurrentBonusPoints+=iMaxZeroBonus;
+ fSkillAtZeroWarning = TRUE;
+ }
}
break;
case( MECHANICAL_SKILL ):
- if( iCurrentMechanical > iMinAttribute )
+ if( iCurrentMechanical > iMechanicalMinimum )
{
// ok to decrement
iCurrentMechanical--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
- else if( iCurrentMechanical == iMinAttribute)
+ else if( iCurrentMechanical == iMechanicalMinimum)
{
- // ok to decrement
- iCurrentMechanical-=iMinAttribute;
- iCurrentBonusPoints+=iMaxZeroBonus;
- fSkillAtZeroWarning = TRUE;
+ if (MechanicalRequiredDueToMajorSkills() == 0 && MechanicalRequiredAdjustmentForMinorTraits( 0 ) == 0 )
+ {
+ // ok to decrement
+ iCurrentMechanical-=iMechanicalMinimum;
+ iCurrentBonusPoints+=iMaxZeroBonus;
+ fSkillAtZeroWarning = TRUE;
+ }
}
break;
case( EXPLOSIVE_SKILL ):
- if( iCurrentExplosives > iMinAttribute )
+ if( iCurrentExplosives > iExplosivesMinimum )
{
// ok to decrement
iCurrentExplosives--;
- iCurrentBonusPoints++;
+ iCurrentBonusPoints++;
}
- else if( iCurrentExplosives == iMinAttribute)
+ else if( iCurrentExplosives == iExplosivesMinimum)
{
- // ok to decrement
- iCurrentExplosives-=iMinAttribute;
- iCurrentBonusPoints+=iMaxZeroBonus;
- fSkillAtZeroWarning = TRUE;
+ if (ExplosivesRequiredDueToMajorSkills() == 0 && ExplosivesRequiredAdjustmentForMinorTraits( 0 ) == 0 )
+ {
+ // ok to decrement
+ iCurrentExplosives-=iExplosivesMinimum;
+ iCurrentBonusPoints+=iMaxZeroBonus;
+ fSkillAtZeroWarning = TRUE;
+ }
}
break;
@@ -1563,7 +1594,9 @@ void CreateSliderBarMouseRegions( void )
INT16 sX = 0;
// set the starting X
- sX = DetermineNewPosition( gGameExternalOptions.iStartAttribute - iMinAttribute );
+ // SANDRO - some changes in attribute points distribution method
+ //sX = DetermineNewPosition( gGameExternalOptions.iStartAttribute - iMinAttribute );
+ sX = DetermineNewPosition( 0 );
for( iCounter = 0; iCounter < 10; iCounter++ )
{
@@ -1882,59 +1915,190 @@ INT32 GetCurrentAttributeValue( INT32 iAttribute )
void SetAttributes( void )
{
- INT8 bExtraPoints = 0;
-/*
- // set attributes and skills based on what is in charprofile.c
-
- // attributes
- iCurrentStrength = iStrength + iAddStrength;
- iCurrentDexterity = iDexterity + iAddDexterity;
- iCurrentHealth = iHealth + iAddHealth;
- iCurrentLeaderShip = iLeadership + iAddLeadership;
- iCurrentWisdom = iWisdom + iAddWisdom;
- iCurrentAgility = iAgility + iAddAgility;
-
- // skills
- iCurrentMarkmanship = iMarksmanship + iAddMarksmanship;
- iCurrentMechanical = iMechanical + iAddMechanical;
- iCurrentMedical = iMedical + iAddMedical;
- iCurrentExplosives = iExplosives + iAddExplosives;
-
- // reset bonus pts
- iCurrentBonusPoints = 40;
-*/
+ INT32 iExtraPoints = 0;
// added externilized multiplier for starting level - SADNRO
iLevelCostMultiplier = gGameExternalOptions.iIMPStartingLevelCostMultiplier;
- iCurrentStrength = gGameExternalOptions.iStartAttribute;
- iCurrentDexterity = gGameExternalOptions.iStartAttribute;
- iCurrentHealth = gGameExternalOptions.iStartAttribute;
- iCurrentLeaderShip = gGameExternalOptions.iStartAttribute;
- iCurrentWisdom = gGameExternalOptions.iStartAttribute;
- iCurrentAgility = gGameExternalOptions.iStartAttribute;
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - determine minimum attribute values due to chosen traits
- // skills
- iCurrentMarkmanship = gGameExternalOptions.iStartAttribute;
- iCurrentMechanical = gGameExternalOptions.iStartAttribute;
- iCurrentMedical = gGameExternalOptions.iStartAttribute;
- iCurrentExplosives = gGameExternalOptions.iStartAttribute;
-
-
- // reset bonus pts
- //iCurrentBonusPoints = 40;
- iCurrentBonusPoints = gGameExternalOptions.iImpAttributePoints;
-
-
- //Determine if the player has any extra points
- bExtraPoints += iPlayersAttributePointsBonusForDisabilitySelected(); // Added attribute bonus for chosen disability - SANDRO
- bExtraPoints += DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection();
-
- if( bExtraPoints > 0 )
+ // For new trait system only though
+ if ( gGameOptions.fNewTraitSystem )
{
- iCurrentBonusPoints += bExtraPoints;
- }
+ // reset bonus pts
+ iCurrentBonusPoints = gGameExternalOptions.iImpAttributePoints;
+ //Determine if the player has any extra points
+ iExtraPoints += iPlayersAttributePointsBonusForDisabilitySelected();
+ iExtraPoints += DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection();
+ if( iExtraPoints > 0 )
+ iCurrentBonusPoints += iExtraPoints;
+
+ // Get Strength minimum
+ iStrengthMinimum = StrengthRequiredDueToMajorSkills();
+ if ( iStrengthMinimum < gGameExternalOptions.iMinAttribute )
+ iStrengthMinimum = gGameExternalOptions.iMinAttribute;
+
+ iStrengthMinimum += StrengthRequiredAdjustmentForMinorTraits( iStrengthMinimum );
+
+ // hehehe, make the alternative weapon holding anim requiring a big strength
+ if ( bBadAssSelected() && iStrengthMinimum < 80 )
+ iStrengthMinimum = 80;
+
+ if ( iStrengthMinimum > gGameExternalOptions.iMaxAttribute )
+ iStrengthMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentStrength = iStrengthMinimum;
+ iCurrentBonusPoints -= iStrengthMinimum;
+
+ // Get Agility minimum
+ iAgilityMinimum = AgilityRequiredDueToMajorSkills();
+ if ( iAgilityMinimum < gGameExternalOptions.iMinAttribute )
+ iAgilityMinimum = gGameExternalOptions.iMinAttribute;
+
+ iAgilityMinimum += AgilityRequiredAdjustmentForMinorTraits( iAgilityMinimum );
+
+ if ( iAgilityMinimum > gGameExternalOptions.iMaxAttribute )
+ iAgilityMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentAgility = iAgilityMinimum;
+ iCurrentBonusPoints -= iAgilityMinimum;
+
+ // Get Dexterity minimum
+ iDexterityMinimum = DexterityRequiredDueToMajorSkills();
+ if ( iDexterityMinimum < gGameExternalOptions.iMinAttribute )
+ iDexterityMinimum = gGameExternalOptions.iMinAttribute;
+
+ iDexterityMinimum += DexterityRequiredAdjustmentForMinorTraits( iDexterityMinimum );
+
+ if ( iDexterityMinimum > gGameExternalOptions.iMaxAttribute )
+ iDexterityMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentDexterity = iDexterityMinimum;
+ iCurrentBonusPoints -= iDexterityMinimum;
+
+ // Get Health minimum
+ iHealthMinimum = HealthRequiredDueToMajorSkills();
+ if ( iHealthMinimum <= 0 )
+ iHealthMinimum = gGameExternalOptions.iMinAttribute;
+
+ iHealthMinimum += HealthRequiredAdjustmentForMinorTraits( iHealthMinimum );
+
+ if ( iHealthMinimum > gGameExternalOptions.iMaxAttribute )
+ iHealthMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentHealth = iHealthMinimum;
+ iCurrentBonusPoints -= iHealthMinimum;
+
+ // Get Leadership minimum
+ iLeaderShipMinimum = LeadershipRequiredDueToMajorSkills();
+ if ( iLeaderShipMinimum < gGameExternalOptions.iMinAttribute )
+ iLeaderShipMinimum = gGameExternalOptions.iMinAttribute;
+
+ iLeaderShipMinimum += LeaderShipRequiredAdjustmentForMinorTraits( iLeaderShipMinimum );
+
+ if ( iLeaderShipMinimum > gGameExternalOptions.iMaxAttribute )
+ iLeaderShipMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentLeaderShip = iLeaderShipMinimum;
+ iCurrentBonusPoints -= (iLeaderShipMinimum - gGameExternalOptions.iMinAttribute + gGameExternalOptions.iMaxZeroBonus);
+
+ // Get Wisdom minimum
+ iWisdomMinimum = WisdomRequiredDueToMajorSkills();
+ if ( iWisdomMinimum < gGameExternalOptions.iMinAttribute )
+ iWisdomMinimum = gGameExternalOptions.iMinAttribute;
+
+ iWisdomMinimum += WisdomRequiredAdjustmentForMinorTraits( iWisdomMinimum );
+
+ if ( iWisdomMinimum > gGameExternalOptions.iMaxAttribute )
+ iWisdomMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentWisdom = iWisdomMinimum;
+ iCurrentBonusPoints -= iWisdomMinimum;
+
+ // Get Marksmanship minimum
+ iMarkmanshipMinimum = MarksmanshipRequiredDueToMajorSkills();
+ if ( iMarkmanshipMinimum < gGameExternalOptions.iMinAttribute )
+ iMarkmanshipMinimum = gGameExternalOptions.iMinAttribute;
+
+ iMarkmanshipMinimum += MarksmanshipRequiredAdjustmentForMinorTraits( iMarkmanshipMinimum );
+
+ if ( iMarkmanshipMinimum > gGameExternalOptions.iMaxAttribute )
+ iMarkmanshipMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentMarkmanship = iMarkmanshipMinimum;
+ iCurrentBonusPoints -= (iMarkmanshipMinimum - gGameExternalOptions.iMinAttribute + gGameExternalOptions.iMaxZeroBonus);
+
+ // Get Mechanical minimum
+ iMechanicalMinimum = MechanicalRequiredDueToMajorSkills();
+ if ( iMechanicalMinimum < gGameExternalOptions.iMinAttribute )
+ iMechanicalMinimum = gGameExternalOptions.iMinAttribute;
+
+ iMechanicalMinimum += MechanicalRequiredAdjustmentForMinorTraits( iMechanicalMinimum );
+
+ if ( iMechanicalMinimum > gGameExternalOptions.iMaxAttribute )
+ iMechanicalMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentMechanical = iMechanicalMinimum;
+ iCurrentBonusPoints -= (iMechanicalMinimum - gGameExternalOptions.iMinAttribute + gGameExternalOptions.iMaxZeroBonus);
+
+ // Get Medical minimum
+ iMedicalMinimum = MedicalRequiredDueToMajorSkills();
+ if ( iMedicalMinimum < gGameExternalOptions.iMinAttribute )
+ iMedicalMinimum = gGameExternalOptions.iMinAttribute;
+
+ iMedicalMinimum += MedicalRequiredAdjustmentForMinorTraits( iMedicalMinimum );
+
+ if ( iMedicalMinimum > gGameExternalOptions.iMaxAttribute )
+ iMedicalMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentMedical = iMedicalMinimum;
+ iCurrentBonusPoints -= (iMedicalMinimum - gGameExternalOptions.iMinAttribute + gGameExternalOptions.iMaxZeroBonus);
+
+ // Get Explosives minimum
+ iExplosivesMinimum = ExplosivesRequiredDueToMajorSkills();
+ if ( iExplosivesMinimum < gGameExternalOptions.iMinAttribute )
+ iExplosivesMinimum = gGameExternalOptions.iMinAttribute;
+
+ iExplosivesMinimum += ExplosivesRequiredAdjustmentForMinorTraits( iExplosivesMinimum );
+
+ if ( iExplosivesMinimum > gGameExternalOptions.iMaxAttribute )
+ iExplosivesMinimum = gGameExternalOptions.iMaxAttribute;
+
+ iCurrentExplosives = iExplosivesMinimum;
+ iCurrentBonusPoints -= (iExplosivesMinimum - gGameExternalOptions.iMinAttribute + gGameExternalOptions.iMaxZeroBonus);
+
+
+ // if we exceeded points available, just give us zero points, but keep the attribute minimums untouched
+ if ( iCurrentBonusPoints < 0 )
+ iCurrentBonusPoints = 0;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ else // ORIGINAL
+ {
+ iCurrentBonusPoints = gGameExternalOptions.iImpAttributePoints;
+
+ //Determine if the player has any extra points
+ iExtraPoints += iPlayersAttributePointsBonusForDisabilitySelected();
+ iExtraPoints += DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection();
+ if( iExtraPoints > 0 )
+ iCurrentBonusPoints += iExtraPoints;
+
+ iCurrentStrength = gGameExternalOptions.iMinAttribute;
+ iCurrentDexterity = gGameExternalOptions.iMinAttribute;
+ iCurrentHealth = gGameExternalOptions.iMinAttribute;
+ iCurrentLeaderShip = gGameExternalOptions.iMinAttribute;
+ iCurrentWisdom = gGameExternalOptions.iMinAttribute;
+ iCurrentAgility = gGameExternalOptions.iMinAttribute;
+ iCurrentMarkmanship = gGameExternalOptions.iMinAttribute;
+ iCurrentMechanical = gGameExternalOptions.iMinAttribute;
+ iCurrentMedical = gGameExternalOptions.iMinAttribute;
+ iCurrentExplosives = gGameExternalOptions.iMinAttribute;
+
+ iCurrentBonusPoints -= ((5 * gGameExternalOptions.iMinAttribute) + (5 * gGameExternalOptions.iMaxZeroBonus));
+ }
+ ////////////////////////////////////////////////////
ResetIncrementCharacterAttributes( );
diff --git a/Laptop/IMP Begin Screen.cpp b/Laptop/IMP Begin Screen.cpp
index b71aaa55..58094185 100644
--- a/Laptop/IMP Begin Screen.cpp
+++ b/Laptop/IMP Begin Screen.cpp
@@ -32,7 +32,7 @@
#include "LaptopSave.h"
#endif
-#include "VFS/Tools/ParserTools.h"
+#include
#define FULL_NAME_CURSOR_Y LAPTOP_SCREEN_WEB_UL_Y + 138
#define NICK_NAME_CURSOR_Y LAPTOP_SCREEN_WEB_UL_Y + 195
@@ -1299,9 +1299,9 @@ BOOLEAN CheckCharacterInputForEgg( void )
iMechanical = 0;
iExplosives = 99;
iMedical = 0;
- iSkillA = AMBIDEXT;
- iSkillB = AUTO_WEAPS;
- iPersonality = NO_PERSONALITYTRAIT;
+ iSkillA = AMBIDEXT_OT;
+ iSkillB = AUTO_WEAPS_OT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_ASSHOLE;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1324,9 +1324,9 @@ BOOLEAN CheckCharacterInputForEgg( void )
iMechanical = 40;
iExplosives = 25;
iMedical = 60;
- iSkillA = MARTIALARTS;
- iSkillB = AUTO_WEAPS;
- iPersonality = NO_PERSONALITYTRAIT;
+ iSkillA = MARTIALARTS_OT;
+ iSkillB = AUTO_WEAPS_OT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_FRIENDLY;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1349,9 +1349,9 @@ BOOLEAN CheckCharacterInputForEgg( void )
iMechanical = 100;
iExplosives = 100;
iMedical = 100;
- iSkillA = MARTIALARTS;
- iSkillB = AUTO_WEAPS;
- iPersonality = NO_PERSONALITYTRAIT;
+ iSkillA = MARTIALARTS_OT;
+ iSkillB = AUTO_WEAPS_OT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_FRIENDLY;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 2;
@@ -1376,10 +1376,10 @@ BOOLEAN CheckCharacterInputForEgg( void )
iExplosives = 99;
iMedical = 75;
- iSkillA = STEALTHY;
- iSkillB = MARTIALARTS;
+ iSkillA = STEALTHY_OT;
+ iSkillB = MARTIALARTS_OT;
- iPersonality = NO_PERSONALITYTRAIT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_AGGRESSIVE;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1404,10 +1404,10 @@ BOOLEAN CheckCharacterInputForEgg( void )
iExplosives = 0;
iMedical = 99;
- iSkillA = AUTO_WEAPS;
- iSkillB = AMBIDEXT;
+ iSkillA = AUTO_WEAPS_OT;
+ iSkillB = AMBIDEXT_OT;
- iPersonality = NO_PERSONALITYTRAIT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_ARROGANT;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1432,10 +1432,10 @@ BOOLEAN CheckCharacterInputForEgg( void )
iExplosives = 99;
iMedical = 35;
- iSkillA = AUTO_WEAPS;
- iSkillB = MARTIALARTS;
+ iSkillA = AUTO_WEAPS_OT;
+ iSkillB = MARTIALARTS_OT;
- iPersonality = NO_PERSONALITYTRAIT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_AGGRESSIVE;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1460,10 +1460,10 @@ BOOLEAN CheckCharacterInputForEgg( void )
iExplosives = 99;
iMedical = 0;
- iSkillA = AUTO_WEAPS;
- iSkillB = MARTIALARTS;
+ iSkillA = AUTO_WEAPS_OT;
+ iSkillB = MARTIALARTS_OT;
- iPersonality = NO_PERSONALITYTRAIT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_LONER;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1486,8 +1486,8 @@ BOOLEAN CheckCharacterInputForEgg( void )
iMechanical = 0;
iExplosives = 99;
iMedical = 0;
- iSkillA = AMBIDEXT;
- iSkillB = AUTO_WEAPS;
+ iSkillA = AMBIDEXT_OT;
+ iSkillB = AUTO_WEAPS_OT;
iPersonality = PSYCHO;
iAttitude = ATT_ASSHOLE;
iCurrentImpPage = IMP_FINISH;
@@ -1542,10 +1542,10 @@ BOOLEAN CheckCharacterInputForEgg( void )
iExplosives = 99;
iMedical = 60;
- iSkillA = ELECTRONICS;
- iSkillB = LOCKPICKING;
+ iSkillA = ELECTRONICS_OT;
+ iSkillB = LOCKPICKING_OT;
- iPersonality = NO_PERSONALITYTRAIT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_LONER;
iCurrentImpPage = IMP_FINISH;
// LaptopSaveInfo.iCurrentVoice = 1;
@@ -1575,7 +1575,7 @@ BOOLEAN CheckCharacterInputForEgg( void )
iSkillA = 0;
iSkillB = 0;
- iPersonality = NO_PERSONALITYTRAIT;
+ iPersonality = NO_DISABILITY;
iAttitude = ATT_LONER;
iCurrentImpPage = IMP_FINISH;
LaptopSaveInfo.iIMPIndex = 54;
diff --git a/Laptop/IMP Character Trait.cpp b/Laptop/IMP Character Trait.cpp
index 98f83a42..16b0e98c 100644
--- a/Laptop/IMP Character Trait.cpp
+++ b/Laptop/IMP Character Trait.cpp
@@ -19,6 +19,7 @@
#include "CharProfile.h"
#include "soldier profile type.h"
#include "IMP Compile Character.h"
+ #include "GameSettings.h"
#endif
@@ -33,13 +34,6 @@
#define IMP_CHARACTER_TRAIT__FONT FONT12ARIAL
#define IMP_CHARACTER_TRAIT__COLOR FONT_MCOLOR_WHITE
-enum
-{
- IMP_CHARACTER_TRAIT__TITLE_TEXT=IMP_CHARACTER_TRAITS_NUMBER,
-};
-
-
-
#define IMP_CHARACTER_1ST_COLUMN_START_X ( LAPTOP_SCREEN_UL_X + 15 )
#define IMP_CHARACTER_1ST_COLUMN_START_Y ( LAPTOP_SCREEN_WEB_UL_Y + 40 )
@@ -48,7 +42,7 @@ enum
#define IMP_CHARACTER_TRAIT__SPACE_BTN_BUTTONS 38
-#define IMP_CHARACTER_TRAIT_NUMBER_TO_START_2ND_COLUMN 5
+//#define IMP_CHARACTER_TRAIT_NUMBER_TO_START_2ND_COLUMN 5
#define IMP_CHARACTER_TRAIT__TEXT_OFFSET_X 65
#define IMP_CHARACTER_TRAIT__TEXT_OFFSET_Y 12
@@ -69,11 +63,11 @@ enum
BOOLEAN gfIST_Redraw2=FALSE;
-BOOLEAN gfCharacterTraitQuestions[ IMP_CHARACTER_TRAITS_NUMBER ];
+BOOLEAN gfCharacterTraitQuestions[ 15 ];
// these are the buttons for the questions
-INT32 giIMPCharacterTraitAnswerButton[ IMP_CHARACTER_TRAITS_NUMBER ];
-INT32 giIMPCharacterTraitAnswerButtonImage[ IMP_CHARACTER_TRAITS_NUMBER ];
+INT32 giIMPCharacterTraitAnswerButton[ 15 ];
+INT32 giIMPCharacterTraitAnswerButtonImage[ 15 ];
// this is the Done buttons
INT32 giIMPCharacterTraitFinsihButton;
@@ -82,6 +76,8 @@ INT32 giIMPCharacterTraitFinsihButtonImage;
//image handle
UINT32 guiIST_GreyGoldBox2;
+MOUSE_REGION gMR_CharacterTraitHelpTextRegions[IMP_NUMBER_CHARACTER_TRAITS];
+
//*******************************************************************
//
// Function Prototypes
@@ -100,6 +96,7 @@ void IMPCharacterTraitDisplayCharacterTraits();
//void HandleLastSelectedCharacterTraits( INT8 bNewTrait );
BOOLEAN CameBackToCharacterTraitPageButNotFinished();
//ppp
+void AssignCharacterTraitHelpText( UINT8 ubNumber );
//*******************************************************************
//
@@ -111,7 +108,7 @@ BOOLEAN CameBackToCharacterTraitPageButNotFinished();
void EnterIMPCharacterTrait( void )
{
-// UINT32 uiCnt;
+// UINT32 ubCnt;
VOBJECT_DESC VObjectDesc;
//add the skill trait buttons
@@ -144,11 +141,36 @@ void EnterIMPCharacterTrait( void )
if( iCurrentProfileMode != IMP__FINISH )
{
//Have the NONE trait initially selected
- gfCharacterTraitQuestions[ IMP_CHARACTER_TRAIT_NORMAL ] = TRUE;
+ gfCharacterTraitQuestions[ 0 ] = TRUE;
}
HandleCharacterTraitButtonStates( );
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ // add regions for help texts
+ UINT16 usPosX = IMP_CHARACTER_1ST_COLUMN_START_X + 62;
+ UINT16 usPosY = IMP_CHARACTER_1ST_COLUMN_START_Y + 8;
+ for( UINT8 ubCnt=0; ubCnt<(gGameOptions.fNewTraitSystem ? IMP_NUMBER_CHARACTER_TRAITS : IMP_NUMBER_ATTITUDES); ubCnt++ )
+ {
+ MSYS_DefineRegion( &gMR_CharacterTraitHelpTextRegions[ubCnt], ( usPosX ), ( usPosY ),
+ (usPosX + 156), ( usPosY + 17), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gMR_CharacterTraitHelpTextRegions[ubCnt] );
+
+ //Determine the next x location
+ if( ubCnt < (gGameOptions.fNewTraitSystem ? 6 : 5) )
+ usPosX = IMP_CHARACTER_1ST_COLUMN_START_X + 62;
+ else
+ usPosX = IMP_CHARACTER_2ND_COLUMN_START_X + 62;
+
+ //Determine the next Y location
+ if( ubCnt == (gGameOptions.fNewTraitSystem ? 6 : 5) )
+ usPosY = IMP_CHARACTER_2ND_COLUMN_START_Y + 8;
+ else
+ usPosY += IMP_CHARACTER_TRAIT__SPACE_BTN_BUTTONS;
+ }
+ }
}
@@ -158,7 +180,10 @@ void RenderIMPCharacterTrait( void )
RenderProfileBackGround();
//Display the title
- DrawTextToScreen( gzIMPCharacterTraitText[IMP_CHARACTER_TRAITS_NUMBER], LAPTOP_SCREEN_UL_X - 111, iScreenHeightOffset + 53, ( LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X ), FONT14ARIAL, FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ if ( gGameOptions.fNewTraitSystem )
+ DrawTextToScreen( gzIMPCharacterTraitText[IMP_NUMBER_CHARACTER_TRAITS], LAPTOP_SCREEN_UL_X - 111, iScreenHeightOffset + 53, ( LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X ), FONT14ARIAL, FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ else
+ DrawTextToScreen( gzIMPAttitudesText[IMP_NUMBER_ATTITUDES], LAPTOP_SCREEN_UL_X - 111, iScreenHeightOffset + 53, ( LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X ), FONT14ARIAL, FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
IMPCharacterTraitDisplayCharacterTraits();
}
@@ -171,7 +196,7 @@ void ExitIMPCharacterTrait( void )
DeleteVideoObjectFromIndex( guiIST_GreyGoldBox2 );
//remove the skill buttons
- for(iCnt = 0; iCnt < IMP_CHARACTER_TRAITS_NUMBER; iCnt++)
+ for(iCnt = 0; iCnt < (gGameOptions.fNewTraitSystem ? IMP_NUMBER_CHARACTER_TRAITS : IMP_NUMBER_ATTITUDES); iCnt++)
{
//if there is a button allocated
if( giIMPCharacterTraitAnswerButton[iCnt] != -1 )
@@ -179,6 +204,9 @@ void ExitIMPCharacterTrait( void )
RemoveButton(giIMPCharacterTraitAnswerButton[ iCnt ] );
UnloadButtonImage(giIMPCharacterTraitAnswerButtonImage[ iCnt ] );
}
+
+ if ( gGameOptions.fNewTraitSystem )
+ MSYS_RemoveRegion( &gMR_CharacterTraitHelpTextRegions[iCnt] );
}
RemoveButton( giIMPCharacterTraitFinsihButton );
@@ -205,7 +233,7 @@ void AddImpCharacterTraitButtons()
usPosX = IMP_CHARACTER_1ST_COLUMN_START_X;
usPosY = IMP_CHARACTER_1ST_COLUMN_START_Y;
- for(iCnt = 0; iCnt < IMP_CHARACTER_TRAITS_NUMBER; iCnt++)
+ for(iCnt = 0; iCnt < (gGameOptions.fNewTraitSystem ? IMP_NUMBER_CHARACTER_TRAITS : IMP_NUMBER_ATTITUDES) ; iCnt++)
{
//reset
giIMPCharacterTraitAnswerButton[iCnt] = -1;
@@ -233,13 +261,13 @@ void AddImpCharacterTraitButtons()
//ButtonList[ giIMPCharacterTraitAnswerButton[ iCnt ] ]->ubSoundSchemeID = 0;
//Determine the next x location
- if( iCnt < IMP_CHARACTER_TRAIT_NUMBER_TO_START_2ND_COLUMN )
+ if( iCnt < (gGameOptions.fNewTraitSystem ? 6 : 5) )
usPosX = IMP_CHARACTER_1ST_COLUMN_START_X;
else
usPosX = IMP_CHARACTER_2ND_COLUMN_START_X;
//Determine the next Y location
- if( iCnt == IMP_CHARACTER_TRAIT_NUMBER_TO_START_2ND_COLUMN )
+ if( iCnt == (gGameOptions.fNewTraitSystem ? 6 : 5) )
usPosY = IMP_CHARACTER_2ND_COLUMN_START_Y;
else
usPosY += IMP_CHARACTER_TRAIT__SPACE_BTN_BUTTONS;
@@ -265,7 +293,7 @@ void BtnIMPCharacterTraitAnswerCallback(GUI_BUTTON *btn,INT32 reason)
void HandleIMPCharacterTraitAnswers( UINT32 uiSkillPressed )
{
- UINT32 uiCnt;
+ INT8 bCnt;
//if we are DONE and are just reviewing
if( iCurrentProfileMode == IMP__FINISH )
@@ -274,13 +302,13 @@ void HandleIMPCharacterTraitAnswers( UINT32 uiSkillPressed )
}
//reset all other buttons
- for( uiCnt=0; uiCnt IMP_CHARACTER_TRAITS_NUMBER )
+ if( uiSkillPressed > (UINT32)(gGameOptions.fNewTraitSystem ? IMP_NUMBER_CHARACTER_TRAITS : IMP_NUMBER_ATTITUDES) )
{
Assert( 0 );
return;
@@ -315,26 +343,26 @@ void HandleIMPCharacterTraitAnswers( UINT32 uiSkillPressed )
void HandleCharacterTraitButtonStates( )
{
- UINT32 uiCnt;
+ INT8 bCnt;
- for( uiCnt=0; uiCntuiFlags |= BUTTON_CLICKED_ON;
+ ButtonList[ giIMPCharacterTraitAnswerButton[ bCnt ] ]->uiFlags |= BUTTON_CLICKED_ON;
}
else
{
- ButtonList[ giIMPCharacterTraitAnswerButton[ uiCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ ButtonList[ giIMPCharacterTraitAnswerButton[ bCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
}
}
}
void IMPCharacterTraitDisplayCharacterTraits()
{
- UINT32 uiCnt;
+ INT8 bCnt;
UINT16 usPosX, usPosY;
UINT16 usBoxPosX, usBoxPosY;
HVOBJECT hImageHandle;
@@ -345,13 +373,13 @@ void IMPCharacterTraitDisplayCharacterTraits()
usPosX = IMP_CHARACTER_1ST_COLUMN_START_X + IMP_CHARACTER_TRAIT__TEXT_OFFSET_X;
usPosY = IMP_CHARACTER_1ST_COLUMN_START_Y + IMP_CHARACTER_TRAIT__TEXT_OFFSET_Y;
- for( uiCnt=0; uiCnt iHighestHits )
- {
- iHighestHits = __max( iHighestHits, iAttitudeHits[ iCounter ] );
- iNumAttitudesWithHighestHits = 1;
- }
- else if ( iAttitudeHits[ iCounter ] == iHighestHits )
- {
- iNumAttitudesWithHighestHits++;
- }
- }
- }
-
- // roll dice
- iDiceValue = Random( iNumAttitudesWithHighestHits + 1 );
-
- // find attitude
- for ( iCounter = 0; iCounter < NUM_ATTITUDES; iCounter++ )
- {
- if ( iAttitudeHits[ iCounter ] == iHighestHits )
- {
- if ( iCounter2 == iDiceValue )
- {
- // this is it!
- iAttitude = iCounter2;
- break;
- }
- else
- {
- // one of the next attitudes...
- iCounter2++;
- }
- }
- }
- }
- else
- {
- iAttitude = gGameExternalOptions.iCustomAttitude;
- }*/
-
- // Chosen by ourselves - SANDRO
iAttitude = iChosenCharacterTrait();
}
@@ -382,7 +310,7 @@ void ClearAllSkillsList( void )
{
INT32 iLoop;
- for ( iLoop = 0; iLoop < iLastElementInSkillsList; iLoop++ )
+ for ( iLoop = 0; iLoop < ATTITUDE_LIST_SIZE; iLoop++ ) // SANDRO - better clear everything to be sure
{
SkillsList[ iLoop ] = 0;
}
@@ -445,132 +373,113 @@ void ValidateSkillsList( void )
if ( pProfile->bMechanical == 0 )
{
// without mechanical, electronics is useless
- iIndex = FindSkillInSkillsList( ELECTRONICS );
- if ( iIndex != -1 )
+ // Electronics/Technician check - SANDRO
+ if ( gGameOptions.fNewTraitSystem )
{
- pProfile->bMechanical = 1;
+ iIndex = FindSkillInSkillsList( TECHNICIAN_NT );
+ if ( iIndex != -1 )
+ pProfile->bMechanical = 1;
}
+ else
+ {
+ iIndex = FindSkillInSkillsList( ELECTRONICS_OT );
+ if ( iIndex != -1 )
+ pProfile->bMechanical = 1;
+
+ iIndex = FindSkillInSkillsList( LOCKPICKING_OT );
+ if ( iIndex != -1 )
+ pProfile->bMechanical = 1;
+ }
+
}
- // Kaiden using UB's code, lockpicking can't be removed from the list "yet".
- // special check for lockpicking
- //iValue = pProfile->bMechanical;
- //iValue = ( iValue * pProfile->bWisdom ) / 100;
- //iValue = ( iValue * pProfile->bDexterity ) / 100;
- //if ( iValue + gbSkillTraitBonus[ LOCKPICKING ] < 50 )
- //{
- // // not good enough for lockpicking!
- //
- // // so is lockpicking
- // iIndex = FindSkillInSkillsList( LOCKPICKING );
- // while ( iIndex != -1 )
- // {
- // RemoveSkillFromSkillsList( iIndex );
- // iIndex = FindSkillInSkillsList( LOCKPICKING );
- // }
- //}
+ // SANDRO - added to give 1 medical skill to doctors
+ if ( pProfile->bMedical == 0 && gGameOptions.fNewTraitSystem )
+ {
+ // without medical, Doctor trait is useless
+ iIndex = FindSkillInSkillsList( DOCTOR_NT );
+ if ( iIndex != -1 )
+ pProfile->bMedical = 1;
+ }
+
+ // SANDRO - added to give 1 explosive skill to dmolitions
+ if ( pProfile->bExplosive == 0 && gGameOptions.fNewTraitSystem )
+ {
+ iIndex = FindSkillInSkillsList( DEMOLITIONS_NT );
+ if ( iIndex != -1 )
+ pProfile->bExplosive = 1;
+ }
+
+ // SANDRO - added to give 1 Leadership skill to Squadleaders
+ if ( pProfile->bLeadership == 0 && gGameOptions.fNewTraitSystem )
+ {
+ // without medical, Doctor trait is useless
+ iIndex = FindSkillInSkillsList( SQUADLEADER_NT );
+ if ( iIndex != -1 )
+ pProfile->bLeadership = 1;
+ }
if ( pProfile->bMarksmanship == 0 )
{
// without marksmanship, the following traits are useless:
- // auto weapons, heavy weapons
- iIndex = FindSkillInSkillsList( AUTO_WEAPS );
- if( iIndex != -1 )
+ // auto weapons, heavy weapons, sniper, ranger, gunslinger
+
+ if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
{
- //RemoveSkillFromSkillsList( iIndex );
- //iIndex = FindSkillInSkillsList( AUTO_WEAPS );
- pProfile->bMarksmanship = 1;
+ iIndex = FindSkillInSkillsList( AUTO_WEAPONS_NT );
+ if( iIndex != -1 )
+ pProfile->bMarksmanship = 1;
+
+ iIndex = FindSkillInSkillsList( HEAVY_WEAPONS_NT );
+ if( iIndex != -1 )
+ pProfile->bMarksmanship = 1;
+
+ iIndex = FindSkillInSkillsList( SNIPER_NT );
+ if( iIndex != -1 )
+ pProfile->bMarksmanship = 1;
+
+ iIndex = FindSkillInSkillsList( RANGER_NT );
+ if( iIndex != -1 )
+ pProfile->bMarksmanship = 1;
+
+ iIndex = FindSkillInSkillsList( GUNSLINGER_NT );
+ if( iIndex != -1 )
+ pProfile->bMarksmanship = 1;
}
- // so is lockpicking
- iIndex = FindSkillInSkillsList( HEAVY_WEAPS );
- if( iIndex != -1 )
+ else
{
- //RemoveSkillFromSkillsList( iIndex );
- //iIndex = FindSkillInSkillsList( HEAVY_WEAPS );
- pProfile->bMarksmanship = 1;
+ iIndex = FindSkillInSkillsList( AUTO_WEAPS_OT );
+ if( iIndex != -1 )
+ {
+ //RemoveSkillFromSkillsList( iIndex );
+ //iIndex = FindSkillInSkillsList( AUTO_WEAPS_OT );
+ pProfile->bMarksmanship = 1;
+ }
+ iIndex = FindSkillInSkillsList( HEAVY_WEAPS_OT );
+ if( iIndex != -1 )
+ {
+ //RemoveSkillFromSkillsList( iIndex );
+ //iIndex = FindSkillInSkillsList( HEAVY_WEAPONS_NT );
+ pProfile->bMarksmanship = 1;
+ }
}
}
}
void CreatePlayerSkills( void )
{
-
- // this function will 'roll a die' and decide if any attitude does exists
- INT32 iDiceValue = 0;
-
ValidateSkillsList();
-/* Kaiden - Commented out in UB to skip the whole random skill thing
- // roll dice
- iDiceValue = Random( iLastElementInSkillsList );
- // set attitude
- iSkillA = SkillsList[ iDiceValue ];
-
- // second dice value
- iDiceValue = Random( iLastElementInSkillsList );
-
- iSkillB = SkillsList[ iDiceValue ];
-*/
-
- // Kaiden: This section was added in it's place:
+ // Kaiden: This section was added in it's place:
+ // SANDRO - Note: this is actually used only for old trait system
if( iLastElementInSkillsList > 0 )
{
- // set attitude
iSkillA = SkillsList[ 0 ];
}
-
if( iLastElementInSkillsList > 1 )
{
iSkillB = SkillsList[ 1 ];
}
- else
- {
- iSkillB = SkillsList[ 0 ];
- }
-
- // allow expert level for generated merc so you CAN have two of the same
- // but there is no such thing as expert level for electronics
-
-
- while ( iSkillA == iSkillB && ( iSkillB == ELECTRONICS || iSkillB == AMBIDEXT ) )
- {
- // remove electronics as an option and roll again
- RemoveSkillFromSkillsList( iDiceValue );
- if ( iLastElementInSkillsList == 0 )
- {
- // ok, only one trait!
- iSkillB = NO_SKILLTRAIT;
- break;
- }
- else
- {
- iDiceValue = Random( iLastElementInSkillsList );
- iSkillB = SkillsList[ iDiceValue ];
- }
- }
-
- /*
- // are the same,
- // reroll until different, or until ATTITUDE_LIST_SIZE times
- iSkillB = Random( iLastElementInSkillsList + 1 );
-
- while( (iSkillA == iSkillB ) && ( iCounter < HOW_MANY_ROLLS_FOR_SAME_SKILL_CHECK ) )
- {
- // increment counter
- iCounter++;
-
- // next random
- iSkillB = Random( iLastElementInSkillsList + 1 );
-
- }
- if( iCounter == ATTITUDE_LIST_SIZE )
- {
- iSkillB = NO_SKILLTRAIT;
- }
- return;
-
-
- */
}
@@ -604,82 +513,15 @@ void AddAPersonalityToPersonalityList( INT8 bPersonlity )
void CreatePlayerPersonality( void )
{
+ // DELETED UNUSED PART OF THE CODE - SANDRO
- // Kaiden: Added for optional Mercenary personalities and attitudes
- // We don't need this - SANDRO
- /*if(gGameSettings.fOptions[TOPTION_USE_RANDOM_PERSONALITY] == TRUE)
- {
- // Kaiden: More chances for Psycho and Normal.
- AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
- AddAPersonalityToPersonalityList( PSYCHO );
- AddAPersonalityToPersonalityList( FORGETFUL );
- AddAPersonalityToPersonalityList( NERVOUS );
- AddAPersonalityToPersonalityList( HEAT_INTOLERANT );
- AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
- AddAPersonalityToPersonalityList( PSYCHO );
- AddAPersonalityToPersonalityList( CLAUSTROPHOBIC );
- AddAPersonalityToPersonalityList( NONSWIMMER );
- AddAPersonalityToPersonalityList( FEAR_OF_INSECTS );
- AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
- AddAPersonalityToPersonalityList( PSYCHO );
- AddAPersonalityToPersonalityList( FORGETFUL );
- AddAPersonalityToPersonalityList( NERVOUS );
- AddAPersonalityToPersonalityList( HEAT_INTOLERANT );
- AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
- AddAPersonalityToPersonalityList( PSYCHO );
- AddAPersonalityToPersonalityList( CLAUSTROPHOBIC );
- AddAPersonalityToPersonalityList( NONSWIMMER );
- AddAPersonalityToPersonalityList( FEAR_OF_INSECTS );
-
-
- INT32 iDiceValue = 0;
- INT32 iCounter = 0;
- INT32 iCounter2 = 0;
-
- // Kaiden: Roll dice 20 times just to be on the safe side
- // was getting too many repeats. Will end up scrapping
- // rand() later anyway so will worry about fixing it then.
- for (iCounter2 = 0; iCounter2 < 20; iCounter2++)
- {
- iDiceValue = Random( iLastElementInPersonalityList + 1 );
- }
-
- // Kaiden two chances to avoid a normal personality. As IMP
- // says, They check it twice just to make sure :p
- for( iCounter = 0; iCounter < iLastElementInPersonalityList; iCounter++ )
- {
-
- DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("iDiceValue = %d",iDiceValue));
-
- if( PersonalityList[ iDiceValue ] == NO_PERSONALITYTRAIT )
- {
- //Kaiden: Roll one more time for good measure:
- iDiceValue = Random( iLastElementInPersonalityList + 1 );
- }
- }
- DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("And our Personality is... = %d",PersonalityList[ iDiceValue ]));
- iPersonality = PersonalityList[ iDiceValue ];
- }
- else
- {
- iPersonality = gGameExternalOptions.iCustomPersonality;
- }*/
-
- // Chosen by ourselves - SANDRO
iPersonality = iChosenDisabilityTrait();
-
return;
-
}
-
void CreatePlayersPersonalitySkillsAndAttitude( void )
{
-
-
-
-
// creates personality, skills and attitudes from curretly built list
// personality
@@ -731,12 +573,52 @@ void ResetIncrementCharacterAttributes( void )
void SelectMercFace( void )
{
+/*
+UINT32 cnt;
+
+ for ( cnt = 0; cnt < MAX_NEW_IMP_PORTRAITS; cnt++ )
+ {
+ sFacePositions[ cnt ][ 0 ] = 0;
+ sFacePositions[ cnt ][ 1 ] = 0;
+ sFacePositions[ cnt ][ 2 ] = 0;
+ sFacePositions[ cnt ][ 3 ] = 0;
+ }
+ */
// this procedure will select the approriate face for the merc and save offsets
// grab face filename
// strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubUnusedFaceFileName , pPlayerSelectedFaceFileNames[ iPortraitNumber ]);
+
+ if( fCharacterIsMale )
+ {
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubFaceIndex = 200 + ( UINT8 )iPortraitNumber;
+
+ // eyes
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usEyesX = sFacePositions[ gIMPMaleValues[iPortraitNumber].uiEyeXPositions ][ 0 ];
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usEyesY = sFacePositions[ gIMPMaleValues[iPortraitNumber].uiEyeYPositions ][ 1 ];
+
+ // mouth
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthX = sFacePositions[ gIMPMaleValues[iPortraitNumber].uiMouthXPositions ][ 2 ];
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthY = sFacePositions[ gIMPMaleValues[iPortraitNumber].uiMouthYPositions ][ 3 ];
+ }
+ else
+ {
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubFaceIndex = 200 + ( UINT8 )iPortraitNumber;
+
+ // eyes
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usEyesX = sFacePositions[ gIMPFemaleValues[iPortraitNumber].uiEyeXPositions ][ 0 ];
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usEyesY = sFacePositions[ gIMPFemaleValues[iPortraitNumber].uiEyeYPositions ][ 1 ];
+
+ // mouth
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthX = sFacePositions[ gIMPFemaleValues[iPortraitNumber].uiMouthXPositions ][ 2 ];
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthY = sFacePositions[ gIMPFemaleValues[iPortraitNumber].uiMouthYPositions ][ 3 ];
+
+
+ }
+
// now the offsets
+ /*
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubFaceIndex = 200 + ( UINT8 )iPortraitNumber;
// eyes
@@ -746,7 +628,7 @@ void SelectMercFace( void )
// mouth
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthX = sFacePositions[ iPortraitNumber ][ 2 ];
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthY = sFacePositions[ iPortraitNumber ][ 3 ];
-
+ */
// set merc skins and hair color
SetMercSkinAndHairColors( );
return;
@@ -754,40 +636,7 @@ void SelectMercFace( void )
void SetMercSkinAndHairColors( void )
{
- // We don't need this - SANDRO
- /*enum{ PINKSKIN, TANSKIN, DARKSKIN, BLACKSKIN, NUMSKINS };
- enum{ BROWNHEAD, BLACKHEAD, //black skin (only this line )
- WHITEHEAD, //dark skin (this line plus all above)
- BLONDHEAD, REDHEAD, //pink/tan skin (this line plus all above )
- NUMHEADS
- };
-
- enum
- {
- WHITEVEST,
- GYELLOWSHIRT,
- YELLOWVEST,
- GREYVEST,
- BROWNVEST,
- PURPLESHIRT,
- BLUEVEST,
- JEANVEST,
- GREENVEST,
- REDVEST,
- BLACKSHIRT,
- NUMSHIRTS
- };//shirts
-
- enum
- {
- BLUEPANTS,
- BLACKPANTS,
- JEANPANTS,
- TANPANTS,
- BEIGEPANTS,
- GREENPANTS,
- NUMPANTS
- };//pants*/
+ // DELETED UNUSED PART OF THE CODE - SANDRO
// skin strings
STR sSkinStrings[]={
@@ -832,117 +681,8 @@ void SetMercSkinAndHairColors( void )
"GREENPANTS",
};//pants
- // We don't need this - SANDRO
- // given the portrait number, set the merc's skin and hair color
- /*INT16 sSkinColor = 0, sHairColor = 0, sShirtColor, sPantColor;
+ // DELETED UNUSED PART OF THE CODE - SANDRO
- switch( iPortraitNumber )
- {
- case( 0 ):
- sSkinColor = BLACKSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = JEANVEST;
- sPantColor = JEANPANTS;
- break;
- case( 1 ):
- sSkinColor = TANSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = BROWNVEST;
- sPantColor = TANPANTS;
- break;
- case( 2 ):
- sSkinColor = TANSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = WHITEVEST;
- sPantColor = BLUEPANTS;
- break;
- case( 3 ):
- sSkinColor = DARKSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = WHITEVEST;
- sPantColor = BLACKPANTS;
- break;
- case( 4 ):
- sSkinColor = TANSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = GREYVEST;
- sPantColor = GREENPANTS;
- break;
- case( 5 ):
- sSkinColor = DARKSKIN;
- sHairColor = BLACKHEAD;
- sShirtColor = GREYVEST;
- sPantColor = BLACKPANTS;
- break;
- case( 6 ):
- sSkinColor = TANSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = BROWNVEST;
- sPantColor = BLUEPANTS;
- break;
- case( 7 ):
- sSkinColor = TANSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = BLACKSHIRT;
- sPantColor = BLACKPANTS;
- break;
- case( 8 ):
- sSkinColor = TANSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = BROWNVEST;
- sPantColor = TANPANTS;
- break;
- case( 9 ):
- sSkinColor = PINKSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = BROWNVEST;
- sPantColor = BEIGEPANTS;
- break;
- case( 10 ):
- sSkinColor = TANSKIN;
- sHairColor = BLACKHEAD;
- sShirtColor = BROWNVEST;
- sPantColor = BLACKPANTS;
- break;
- case( 11 ):
- sSkinColor = TANSKIN;
- sHairColor = BLACKHEAD;
- sShirtColor = BLACKSHIRT;
- sPantColor = BLACKPANTS;
- break;
- case( 12 ):
- sSkinColor = PINKSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = WHITEVEST;
- sPantColor = GREENPANTS;
- break;
- case( 13 ):
- sSkinColor = BLACKSKIN;
- sHairColor = BROWNHEAD;
- sShirtColor = GREYVEST;
- sPantColor = BLACKPANTS;
- break;
- case( 14 ):
- sSkinColor = TANSKIN;
- sHairColor = REDHEAD;
- sShirtColor = WHITEVEST;
- sPantColor = JEANPANTS;
- break;
- case( 15 ):
- sSkinColor = TANSKIN;
- sHairColor = BLONDHEAD;
- sShirtColor = BROWNVEST;
- sPantColor = GREENPANTS;
- break;
- }
-
- // now set them
- strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].HAIR, sHairStrings[ sHairColor ] );
- strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].SKIN, sSkinStrings[ sSkinColor ] );
- strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].PANTS, sPantStrings[ sPantColor ] );
- strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].VEST, sShirtStrings[ sShirtColor ] );*/
-
- // Cosen colors by ourselves - SANDRO
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].HAIR, sHairStrings[ iChosenHair() ] );
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].SKIN, sSkinStrings[ iChosenSkin() ] );
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].PANTS, sPantStrings[ iChosenPants() ] );
@@ -957,9 +697,12 @@ void HandleMercStatsForChangesInFace( )
return;
}
- //add the skills to the skills list
+ //add the skills (major) to the skills list
AddSelectedSkillsToSkillsList();
+ if ( gGameOptions.fNewTraitSystem ) // SANDRO - add also minor traits
+ AddSelectedMinorTraitsToSkillsList();
+
// now figure out skills
CreatePlayerSkills();
@@ -969,60 +712,56 @@ void HandleMercStatsForChangesInFace( )
// male
// big or regular
// Madd - don't override the skills - override the body type instead
- if( ShouldThisMercHaveABigBody() && iSkillA != MARTIALARTS && iSkillB != MARTIALARTS )
+ // this should not happen any more, we don't even offer the martial arts to big mercs - SANDRO
+ //if( ShouldThisMercHaveABigBody() && iSkillA != MARTIALARTS_OT && iSkillB != MARTIALARTS_OT )
+ if( ShouldThisMercHaveABigBody() ) // still added a safety check - SANDRO
{
- gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = BIGMALE;
+ if (!gGameOptions.fNewTraitSystem) // SANDRO - traits
+ {
+ if (iSkillA == MARTIALARTS_OT )
+ iSkillA = HANDTOHAND_OT;
+ if (iSkillB == MARTIALARTS_OT )
+ iSkillB = HANDTOHAND_OT;
+ }
- //if( iSkillA == MARTIALARTS )
- //{
- // iSkillA = HANDTOHAND;
- //}
- //if( iSkillB == MARTIALARTS )
- //{
- // iSkillB = HANDTOHAND;
- //}
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = BIGMALE;
}
else
{
- gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = REGMALE;
- }
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = REGMALE;
+ }
}
else
{
- // female
- gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = REGFEMALE;
+ // female
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = REGFEMALE;
- if( iSkillA == MARTIALARTS )
+ if (!gGameOptions.fNewTraitSystem) // SANDRO - traits
{
- iSkillA = HANDTOHAND;
- }
- if( iSkillB == MARTIALARTS )
- {
- iSkillB = HANDTOHAND;
+ if( iSkillA == MARTIALARTS_OT )
+ iSkillA = HANDTOHAND_OT;
+ if( iSkillB == MARTIALARTS_OT )
+ iSkillB = HANDTOHAND_OT;
}
}
-
- // skill trait
- gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTrait = ( INT8 )iSkillA;
- gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTrait2 = ( INT8 )iSkillB;
-
+ if (gGameOptions.fNewTraitSystem)
+ {
+ for ( UINT8 ubCnt = 0; ubCnt < gSkillTraitValues.ubMaxNumberOfTraits; ubCnt++ )
+ {
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTraits[ ubCnt ] = ( INT8 )SkillsList[ ubCnt ];
+ }
+ }
+ else
+ {
+ // skill trait
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTraits[0] = ( INT8 )iSkillA;
+ gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTraits[1] = ( INT8 )iSkillB;
+ }
}
BOOLEAN ShouldThisMercHaveABigBody( void )
{
- // should this merc be a big body type
- // Madd - don't limit it by portrait
- //if ( ( iPortraitNumber == 0 ) || ( iPortraitNumber == 6 ) || ( iPortraitNumber == 7 ) )
- //{
- // if ( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bStrength >= 75 )
- // {
- // return( TRUE );
- // }
- //}
-
- //return( FALSE );
-
// We can now choose this ourselves - SANDRO
return( bBigBodySelected() );
}
diff --git a/Laptop/IMP Compile Character.h b/Laptop/IMP Compile Character.h
index c6647b10..d3487817 100644
--- a/Laptop/IMP Compile Character.h
+++ b/Laptop/IMP Compile Character.h
@@ -2,8 +2,8 @@
#define __IMP_COMPILE_H
#define PLAYER_GENERATED_CHARACTER_ID 51
-#define ATTITUDE_LIST_SIZE 20
-#define NUMBER_OF_PLAYER_PORTRAITS 16
+#define ATTITUDE_LIST_SIZE 30
+#define NUMBER_OF_PLAYER_PORTRAITS 50 //16
void AddAnAttitudeToAttitudeList( INT8 bAttitude );
void CreatePlayerAttitude( void );
diff --git a/Laptop/IMP Confirm.cpp b/Laptop/IMP Confirm.cpp
index 81e508fa..189c319b 100644
--- a/Laptop/IMP Confirm.cpp
+++ b/Laptop/IMP Confirm.cpp
@@ -34,9 +34,13 @@
#include "weapons.h"
#include "Random.h"
#include "GameVersion.h"
+ #include "faces.h"
#include "GameSettings.h"
#endif
+#include
+#include
+
// Changed by ADB (rev 1513) to resolve IMPs created prior to structural changes
//#define IMP_FILENAME_SUFFIX ".dat"
#define OLD_IMP_FILENAME_SUFFIX ".dat"
@@ -60,6 +64,13 @@ void GiveIMPItems( MERCPROFILESTRUCT *pProfile, INT8 abilityValue, UINT8 typeInd
UINT32 giIMPConfirmButton[ 2 ];
UINT32 giIMPConfirmButtonImage[ 2 ];
BOOLEAN fNoAlreadySelected = FALSE;
+
+IMP_FACE_VALUES gIMPFaceValues[200];
+
+IMP_FEMALE_VALUES gIMPFemaleValues[200];
+IMP_MALE_VALUES gIMPMaleValues[200];
+
+/*
UINT16 uiEyeXPositions[ ]={
8,
9,
@@ -137,7 +148,7 @@ UINT16 uiMouthYPositions[]={
24, //214
26,
};
-
+*/
BOOLEAN fLoadingCharacterForPreviousImpProfile = FALSE;
void CreateConfirmButtons( void );
@@ -271,8 +282,23 @@ BOOLEAN AddCharacterToPlayersTeam( void )
HireMercStruct.ubInsertionCode = INSERTION_CODE_ARRIVING_GAME;
HireMercStruct.uiTimeTillMercArrives = GetMercArrivalTimeOfDay( );
- SetProfileFaceData( HireMercStruct.ubProfileID , ( UINT8 ) ( 200 + iPortraitNumber ), uiEyeXPositions[ iPortraitNumber ], uiEyeYPositions[ iPortraitNumber ], uiMouthXPositions[ iPortraitNumber ], uiMouthYPositions[ iPortraitNumber ] );
-
+
+ if( fCharacterIsMale )
+ {
+ if ( gIMPMaleValues[ iPortraitNumber ].PortraitId !=0 )
+ {
+ SetProfileFaceData( HireMercStruct.ubProfileID , (UINT8)(gIMPMaleValues[ iPortraitNumber ].PortraitId), gIMPMaleValues[ iPortraitNumber ].uiEyeXPositions, gIMPMaleValues[ iPortraitNumber ].uiEyeYPositions, gIMPMaleValues[ iPortraitNumber ].uiMouthXPositions, gIMPMaleValues[ iPortraitNumber ].uiMouthYPositions );
+ }
+ }
+ else
+ {
+ if ( gIMPFemaleValues[ iPortraitNumber ].PortraitId !=0 )
+ {
+ SetProfileFaceData( HireMercStruct.ubProfileID , (UINT8)(gIMPFemaleValues[ iPortraitNumber ].PortraitId), gIMPFemaleValues[ iPortraitNumber ].uiEyeXPositions, gIMPFemaleValues[ iPortraitNumber ].uiEyeYPositions, gIMPFemaleValues[ iPortraitNumber ].uiMouthXPositions, gIMPFemaleValues[ iPortraitNumber ].uiMouthYPositions );
+ }
+ }
+
+
//if we succesfully hired the merc
if( !HireMerc( &HireMercStruct ) )
{
@@ -310,18 +336,23 @@ void BtnIMPConfirmYes(GUI_BUTTON *btn,INT32 reason)
return;
}
*/
- if( LaptopSaveInfo.iCurrentBalance < COST_OF_PROFILE )
+ // SANDRO - changed to find the actual profile cost
+ //if( LaptopSaveInfo.iCurrentBalance < COST_OF_PROFILE )
+ if( LaptopSaveInfo.iCurrentBalance < iGetProfileCost() )
{
// not enough
- return;
+ return;
}
// line moved by CJC Nov 28 2002 to AFTER the check for money
LaptopSaveInfo.fIMPCompletedFlag = TRUE;
// charge the player
- AddTransactionToPlayersBook(IMP_PROFILE, (UINT8)(LaptopSaveInfo.iIMPIndex), GetWorldTotalMin( ), - ( COST_OF_PROFILE ) );
- AddHistoryToPlayersLog( HISTORY_CHARACTER_GENERATED, 0,GetWorldTotalMin( ), -1, -1 );
+ // SANDRO - changed to find the actual profile cost
+ //AddTransactionToPlayersBook(IMP_PROFILE, (UINT8)(LaptopSaveInfo.iIMPIndex), GetWorldTotalMin( ), - ( COST_OF_PROFILE ) );
+ AddTransactionToPlayersBook(IMP_PROFILE, (UINT8)(LaptopSaveInfo.iIMPIndex), GetWorldTotalMin( ), - ( iGetProfileCost() ) );
+
+ AddHistoryToPlayersLog( HISTORY_CHARACTER_GENERATED, 0,GetWorldTotalMin( ), -1, -1 );
AddCharacterToPlayersTeam( );
// write the created imp merc
@@ -426,9 +457,11 @@ void BtnIMPConfirmNo( GUI_BUTTON *btn,INT32 reason )
}
*/
-
-#define PROFILE_HAS_SKILL_TRAIT( p, t ) ((p->bSkillTrait == t) || (p->bSkillTrait2 == t))
-
+// SANDRO - improved this function
+//#define PROFILE_HAS_SKILL_TRAIT( p, t ) ( gGameOptions.fNewTraitSystem ? ((p->bSkillTrait == t) || (p->bSkillTrait2 == t) || (p->bSkillTrait3 == t)) : ((p->bSkillTrait == t) || (p->bSkillTrait2 == t)))
+#define PROFILE_HAS_SKILL_TRAIT( p, t ) ( ProfileHasSkillTrait( p, t ) > 0 )
+// DBrot: need a check for experts
+#define PROFILE_HAS_EXPERT_TRAIT( p, t ) ( ProfileHasSkillTrait( p, t ) > 1 )
//CHRISL: New function to handle proper distribution of starting gear
void DistributeInitialGear(MERCPROFILESTRUCT *pProfile)
{
@@ -560,101 +593,26 @@ void DistributeInitialGear(MERCPROFILESTRUCT *pProfile)
}
}
-
void GiveItemsToPC( UINT8 ubProfileId )
{
MERCPROFILESTRUCT *pProfile;
-
// gives starting items to merc
// NOTE: Any guns should probably be from those available in regular gun set
pProfile = &(gMercProfiles[ubProfileId]);
-
// STANDARD EQUIPMENT
+ // SANDRO - obsolete code deleted
GiveIMPItems(pProfile, 100, IMP_DEFAULT);
GiveIMPRandomItems(pProfile, IMP_RANDOMDEFAULT);
-
- // kevlar vest, leggings, & helmet
-// MakeProfileInvItemThisSlot(pProfile, VESTPOS, FLAK_JACKET, 100, 1);
-
GiveIMPItems (pProfile,pProfile->bWisdom,IMP_WISDOM);
-
-
- //if ( PreRandom( 100 ) < (UINT32) pProfile->bWisdom )
- //{
- // MakeProfileInvItemThisSlot(pProfile, HELMETPOS, STEEL_HELMET, 100, 1);
- //}
-
- // canteen
-// MakeProfileInvItemThisSlot(pProfile, SMALLPOCK4POS, CANTEEN, 100, 1);
-
GiveIMPItems (pProfile,pProfile->bMarksmanship,IMP_MARKSMANSHIP);
-
-
- //Give ANY imp the calico
-// MakeProfileInvItemThisSlot( pProfile, HANDPOS, M950, 100, 1);
-
-
-
- //No ammo clip MakeProfileInvItemThisSlot( pProfile, SMALLPOCK1POS, CLIP9_30, 100, 2);
-
- /*
- Ja25 IMP only gets 1 gun now
-
-
-
-
- if (pProfile->bMarksmanship >= 80)
- {
- // good shooters get a better & matching ammo
- MakeProfileInvItemThisSlot( pProfile, HANDPOS, MP5K, 100, 1);
- MakeProfileInvItemThisSlot( pProfile, SMALLPOCK1POS, CLIP9_30, 100, 2);
- }
- else
- {
- // Automatic pistol, with matching ammo
- MakeProfileInvItemThisSlot( pProfile, HANDPOS, BERETTA_93R, 100, 1 );
- MakeProfileInvItemThisSlot( pProfile, SMALLPOCK1POS, CLIP9_15, 100, 3 );
- }
- */
-
- // OPTIONAL EQUIPMENT: depends on skills & special skills
-
GiveIMPItems (pProfile,pProfile->bMedical,IMP_MEDICAL);
-
- //if (pProfile->bMedical >= 60)
- //{
- // // strong medics get full medic kit
- // MakeProfileInvItemAnySlot(pProfile, MEDICKIT, 100, 1);
- //}
- //else
- //if (pProfile->bMedical >= 30)
- //{
- // // passable medics get first aid kit
- // MakeProfileInvItemAnySlot(pProfile, FIRSTAIDKIT, 100, 1);
- //}
-
GiveIMPItems (pProfile,pProfile->bMechanical,IMP_MECHANICAL);
-
- //if (pProfile->bMechanical >= 50)
- //{
- // // mechanics get toolkit
- // MakeProfileInvItemAnySlot(pProfile, TOOLKIT, 100, 1);
- //}
-
GiveIMPItems (pProfile,pProfile->bExplosive,IMP_EXPLOSIVE);
-
- //if (pProfile->bExplosive >= 50)
- //{
- // // loonies get TNT & Detonator
- //MakeProfileInvItemAnySlot(pProfile, TNT, 100, 1);
- //MakeProfileInvItemAnySlot(pProfile, DETONATOR, 100, 1);
- //}
-
GiveIMPItems (pProfile,pProfile->bAgility,IMP_AGILITY);
GiveIMPItems (pProfile,pProfile->bDexterity,IMP_DEXTERITY);
GiveIMPItems (pProfile,pProfile->bStrength,IMP_STRENGTH);
@@ -662,89 +620,309 @@ void GiveItemsToPC( UINT8 ubProfileId )
GiveIMPItems (pProfile,pProfile->bLeadership,IMP_LEADERSHIP);
// check for special skills
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, LOCKPICKING) && ( iMechanical ) )
+ /////////////////////////////////////////////////////////////////////
+ // Check for new traits - SANDRO
+ // DBrot: experts get other stuff
+ if ( gGameOptions.fNewTraitSystem )
{
- //MakeProfileInvItemAnySlot(pProfile, LOCKSMITHKIT, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_LOCKPICKING);
+ // MAJOR TRAITS
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AUTO_WEAPONS_NT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, AUTO_WEAPONS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_AUTO_WEAPONS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_AUTO_WEAPONS);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, HEAVY_WEAPONS_NT ))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, HEAVY_WEAPONS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_HEAVY_WEAPONS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_HEAVY_WEAPONS);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SNIPER_NT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, SNIPER_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_SNIPER_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_SNIPER);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, RANGER_NT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, RANGER_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_RANGER_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_RANGER);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, GUNSLINGER_NT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, GUNSLINGER_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_GUNSLINGER_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_GUNSLINGER);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, MARTIAL_ARTS_NT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, MARTIAL_ARTS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_MARTIAL_ARTS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_MARTIAL_ARTS);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SQUADLEADER_NT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, SQUADLEADER_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_SQUADLEADER_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_SQUADLEADER);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, TECHNICIAN_NT) && ( iMechanical ) )
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, TECHNICIAN_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_TECHNICIAN_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_TECHNICIAN);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, DOCTOR_NT ))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, DOCTOR_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_DOCTOR_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_DOCTOR);
+ }
+ }
+ // MINOR TRAITS
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AMBIDEXTROUS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_AMBIDEXTROUS);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, MELEE_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_MELEE);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, THROWING_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_THROWING);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, NIGHT_OPS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_NIGHT_OPS);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, STEALTHY_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_STEALTHY);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, ATHLETICS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_ATHLETICS);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, BODYBUILDING_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_BODYBUILDING);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, DEMOLITIONS_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_DEMOLITIONS);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, TEACHING_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_TEACHING);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, SCOUTING_NT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_SCOUTING);
+ }
+
}
+ else
+ {
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, LOCKPICKING_OT) && ( iMechanical ) )
+ {
+ //MakeProfileInvItemAnySlot(pProfile, LOCKSMITHKIT, 100, 1);
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, LOCKPICKING_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_LOCKPICKING_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_LOCKPICKING);
+ }
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, ELECTRONICS_OT) && ( iMechanical ) )
+ {
+ //MakeProfileInvItemAnySlot(pProfile, METALDETECTOR, 100, 1);
+ GiveIMPRandomItems(pProfile,IMP_ELECTRONICS);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, CAMOUFLAGED_OT)) // TODO: Madd - other camouflage types, once we figure out a way to enable more traits
+ {
+ //MakeProfileInvItemAnySlot(pProfile, CAMOUFLAGEKIT, 100, 1);
+ GiveIMPRandomItems(pProfile,IMP_CAMOUFLAGED);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AMBIDEXT_OT))
+ {
+ //MakeProfileInvItemAnySlot(pProfile, M950, 100, 1);
+ GiveIMPRandomItems(pProfile,IMP_AMBIDEXTROUS);
+ }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, NIGHTOPS_OT))
+ {
+// MakeProfileInvItemAnySlot(pProfile, SILENCER, 100, 2);
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, NIGHTOPS_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_NIGHT_OPS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_NIGHT_OPS);
+ }
+ }
+
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, HANDTOHAND_OT))
+ {
+ //MakeProfileInvItemAnySlot(pProfile, BRASS_KNUCKLES, 100, 1);
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, HANDTOHAND_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_MARTIAL_ARTS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_MARTIAL_ARTS);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, HANDTOHAND))
- {
- //MakeProfileInvItemAnySlot(pProfile, BRASS_KNUCKLES, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_HTH);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, THROWING_OT))
+ {
+// MakeProfileInvItemAnySlot(pProfile, THROWING_KNIFE, 100, 1);
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, THROWING_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_THROWING_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_THROWING);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, ELECTRONICS) && ( iMechanical ) )
- {
- //MakeProfileInvItemAnySlot(pProfile, METALDETECTOR, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_ELECTRONICS);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, STEALTHY_OT))
+ {
+// MakeProfileInvItemAnySlot(pProfile, SILENCER, 100, 1);
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, STEALTHY_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_STEALTHY_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_STEALTHY);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, NIGHTOPS))
- {
-// MakeProfileInvItemAnySlot(pProfile, SILENCER, 100, 2);
- GiveIMPRandomItems(pProfile,IMP_NIGHTOPS);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, KNIFING_OT))
+ {
+// MakeProfileInvItemAnySlot(pProfile, COMBAT_KNIFE, 100, 1);
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, KNIFING_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_MELEE_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_MELEE);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, THROWING))
- {
-// MakeProfileInvItemAnySlot(pProfile, THROWING_KNIFE, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_THROWING);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, MARTIALARTS_OT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, MARTIALARTS_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_MARTIAL_ARTS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_MARTIAL_ARTS);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, STEALTHY))
- {
-// MakeProfileInvItemAnySlot(pProfile, SILENCER, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_STEALTHY);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, PROF_SNIPER_OT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, PROF_SNIPER_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_SNIPER_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_SNIPER);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, KNIFING))
- {
-// MakeProfileInvItemAnySlot(pProfile, COMBAT_KNIFE, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_KNIFING);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, TEACHING_OT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, TEACHING_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_TEACHING_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_TEACHING);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, CAMOUFLAGED)) // TODO: Madd - other camouflage types, once we figure out a way to enable more traits
- {
-// MakeProfileInvItemAnySlot(pProfile, CAMOUFLAGEKIT, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_CAMOUFLAGED);
- }
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, AUTO_WEAPS_OT))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, AUTO_WEAPS_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_AUTO_WEAPONS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_AUTO_WEAPONS);
+ }
+ }
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, AMBIDEXT))
- {
-// MakeProfileInvItemAnySlot(pProfile, M950, 100, 1);
- GiveIMPRandomItems(pProfile,IMP_AMBIDEXTROUS);
- }
-
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, MARTIALARTS))
- {
- GiveIMPRandomItems(pProfile,IMP_MARTIALARTS);
- }
-
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, PROF_SNIPER))
- {
- GiveIMPRandomItems(pProfile,IMP_PROF_SNIPER);
- }
-
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, TEACHING))
- {
- GiveIMPRandomItems(pProfile,IMP_TEACHING);
- }
-
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, AUTO_WEAPS))
- {
- GiveIMPRandomItems(pProfile,IMP_AUTOWEAPONS);
- }
-
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, HEAVY_WEAPS ))
- {
- GiveIMPRandomItems(pProfile,IMP_HEAVYWEAPONS);
- }
-
- if (PROFILE_HAS_SKILL_TRAIT(pProfile, THIEF ))
- {
- GiveIMPRandomItems(pProfile,IMP_THIEF);
+ if (PROFILE_HAS_SKILL_TRAIT(ubProfileId, HEAVY_WEAPS_OT ))
+ {
+ if( gGameExternalOptions.fExpertsGetDifferentChoices && PROFILE_HAS_EXPERT_TRAIT(ubProfileId, HEAVY_WEAPS_OT))
+ {
+ GiveIMPRandomItems(pProfile,IMP_HEAVY_WEAPONS_EXP);
+ }
+ else
+ {
+ GiveIMPRandomItems(pProfile, IMP_HEAVY_WEAPONS);
+ }
+ }
}
+ /////////////////////////////////////////////////////////////////////
// CHRISL: Now that all items have been issued, distribute them into appropriate pockets, starting with the largest items
DistributeInitialGear(pProfile);
@@ -871,7 +1049,8 @@ INT32 SpecificFreePocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHow
{
if(LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo!=0)
{
- if((pProfile->inv[BPACKPOCKPOS]!=NONE && LoadBearingEquipment[Item[pProfile->inv[BPACKPOCKPOS]].ubClassIndex].lbeCombo==LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo) || pProfile->inv[BPACKPOCKPOS]==NONE)
+ //DBrot: changed to bitwise comparison
+ if((pProfile->inv[BPACKPOCKPOS]!=NONE && (LoadBearingEquipment[Item[pProfile->inv[BPACKPOCKPOS]].ubClassIndex].lbeCombo & LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo)) || pProfile->inv[BPACKPOCKPOS]==NONE)
return CPACKPOCKPOS;
}
else if(pProfile->inv[BPACKPOCKPOS]==NONE)
@@ -884,7 +1063,8 @@ INT32 SpecificFreePocket(MERCPROFILESTRUCT *pProfile, UINT16 usItem, UINT8 ubHow
{
if(LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo!=0)
{
- if((pProfile->inv[CPACKPOCKPOS]!=NONE && LoadBearingEquipment[Item[pProfile->inv[CPACKPOCKPOS]].ubClassIndex].lbeCombo==LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo) || pProfile->inv[CPACKPOCKPOS]==NONE)
+ //DBrot: changed to bitwise comparison
+ if((pProfile->inv[CPACKPOCKPOS]!=NONE && (LoadBearingEquipment[Item[pProfile->inv[CPACKPOCKPOS]].ubClassIndex].lbeCombo & LoadBearingEquipment[Item[usItem].ubClassIndex].lbeCombo)) || pProfile->inv[CPACKPOCKPOS]==NONE)
return BPACKPOCKPOS;
}
else if(pProfile->inv[CPACKPOCKPOS]==NONE)
@@ -1117,8 +1297,6 @@ INT32 AnyFreeBigEnoughPocket(MERCPROFILESTRUCT *pProfile, INVNODE *tInv)
return(-1);
}
-#include "VFS/vfs.h"
-#include "VFS/vfs_settings.h"
void WriteOutCurrentImpCharacter( INT32 iProfileId )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("WriteOutCurrentImpCharacter: IMP.dat"));
@@ -1145,11 +1323,11 @@ void WriteOutCurrentImpCharacter( INT32 iProfileId )
char zFileName[32];
if(vfs::Settings::getUseUnicode())
{
- strncpy(zFileName, utf8string::as_utf8(gMercProfiles[iProfileId].zNickname,10).c_str(), 32);
+ strncpy(zFileName, vfs::String::as_utf8(gMercProfiles[iProfileId].zNickname,10).c_str(), 32);
}
else
{
- utf8string::narrow(gMercProfiles[iProfileId].zNickname, 10, zFileName, 32);
+ vfs::String::narrow(gMercProfiles[iProfileId].zNickname, 10, zFileName, 32);
}
#endif
@@ -1339,20 +1517,31 @@ BOOLEAN LoadImpCharacter( STR nickName )
//CHRISL: At this point, we need to resort profile inventory so that NewInv items don't accidentally appear in OldInv
DistributeInitialGear(&gMercProfiles[iProfileId]);
- if( LaptopSaveInfo.iCurrentBalance < COST_OF_PROFILE )
+ // Changed to find actual IMP cost - SANDRO
+ if( LaptopSaveInfo.iCurrentBalance < iGetProfileCost() )
{
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 3 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
// not enough
return FALSE;
}
+
+ //new camo face
+ if ( gGameExternalOptions.fShowCamouflageFaces == TRUE )
+ {
+ gCamoFace[iProfileId].gCamoface = TRUE;
+ gCamoFace[iProfileId].gUrbanCamoface = FALSE;
+ gCamoFace[iProfileId].gDesertCamoface = FALSE;
+ gCamoFace[iProfileId].gSnowCamoface = FALSE;
+ }
// charge the player
// is the character male?
fCharacterIsMale = ( gMercProfiles[ iProfileId ].bSex == MALE );
fLoadingCharacterForPreviousImpProfile = TRUE;
- AddTransactionToPlayersBook(IMP_PROFILE,0, GetWorldTotalMin( ), - ( COST_OF_PROFILE ) );
+ // Changed to find actual IMP cost - SANDRO
+ AddTransactionToPlayersBook(IMP_PROFILE,0, GetWorldTotalMin( ), - ( iGetProfileCost() ) );
AddHistoryToPlayersLog( HISTORY_CHARACTER_GENERATED, 0,GetWorldTotalMin( ), -1, -1 );
LaptopSaveInfo.iIMPIndex = iProfileId;
AddCharacterToPlayersTeam( );
@@ -1383,38 +1572,86 @@ BOOLEAN LoadImpCharacter( STR nickName )
void ResetIMPCharactersEyesAndMouthOffsets( UINT8 ubMercProfileID )
{
// ATE: Check boundary conditions!
- if( ( ( gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ) > 16 ) || ( ubMercProfileID >= PROF_HUMMER ) )
+ if( ( ( gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ) > MAX_NEW_IMP_PORTRAITS ) || ( ubMercProfileID >= PROF_HUMMER ) ) // 16
{
return;
}
+ /*
+ gMercProfiles[ ubMercProfileID ].usEyesX = gIMPFaceValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiEyeXPositions;
+ gMercProfiles[ ubMercProfileID ].usEyesY = gIMPFaceValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiEyeYPositions;
- gMercProfiles[ ubMercProfileID ].usEyesX = uiEyeXPositions[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ];
- gMercProfiles[ ubMercProfileID ].usEyesY = uiEyeYPositions[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ];
+ gMercProfiles[ ubMercProfileID ].usMouthX = gIMPFaceValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiMouthXPositions;
+ gMercProfiles[ ubMercProfileID ].usMouthY = gIMPFaceValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiMouthYPositions;
+ */
+
+ if( gMercProfiles[ ubMercProfileID ].bSex == 0 )
+ {
+ gMercProfiles[ ubMercProfileID ].usEyesX = gIMPMaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiEyeXPositions;
+ gMercProfiles[ ubMercProfileID ].usEyesY = gIMPMaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiEyeYPositions;
- gMercProfiles[ ubMercProfileID ].usMouthX = uiMouthXPositions[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ];
- gMercProfiles[ ubMercProfileID ].usMouthY = uiMouthYPositions[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ];
+ gMercProfiles[ ubMercProfileID ].usMouthX = gIMPMaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiMouthXPositions;
+ gMercProfiles[ ubMercProfileID ].usMouthY = gIMPMaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiMouthYPositions;
+ }
+ else
+ {
+ gMercProfiles[ ubMercProfileID ].usEyesX = gIMPFemaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiEyeXPositions;
+ gMercProfiles[ ubMercProfileID ].usEyesY = gIMPFemaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiEyeYPositions;
+
+ gMercProfiles[ ubMercProfileID ].usMouthX = gIMPFemaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiMouthXPositions;
+ gMercProfiles[ ubMercProfileID ].usMouthY = gIMPFemaleValues[ gMercProfiles[ ubMercProfileID ].ubFaceIndex - 200 ].uiMouthYPositions;
+ }
+
}
void GiveIMPRandomItems( MERCPROFILESTRUCT *pProfile, UINT8 typeIndex )
{
+ /////////////////////////////////////////////////////////////////////
+ // SANDRO - I've changed this formula a bit, <- me too - silversurfer
+ // now it should not take the same choice twice
+ /////////////////////////////////////////////////////////////////////
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPRandomItems: typeIndex = %d",typeIndex ));
UINT16 usItem = 0;
INT32 iChoice;
+ UINT8 ubValidChoices = 0;
+ UINT8 ubNumChoices = gIMPItemChoices[ typeIndex ].ubChoices;
+ UINT8 ubNumItemsToGive = 0;
+ BOOLEAN ubItemsGiven[ 50 ]={FALSE};
- if ( gIMPItemChoices[ typeIndex ].ubChoices <= 0 )
- return;
-
- for ( int i=0; i < gIMPItemChoices[typeIndex].ubNumItems ;i++ )
+ // check how many legal items are in the choices list, this is to prevent infinite loop
+ for ( UINT8 cnt=0; cnt < ubNumChoices; cnt++ )
{
+ usItem = gIMPItemChoices[ typeIndex ].bItemNo[ cnt ];
+ if ( ItemIsLegal(usItem) )
+ ubValidChoices++;
+ }
+
+ // if no valid items found, bail out
+ if ( ubValidChoices <= 0 )
+ return;
+
+ // define how many items we get
+ if ( ubValidChoices < gIMPItemChoices[typeIndex].ubNumItems )
+ // if there are less legal items than the number we should get, we only get the number of legal items
+ ubNumItemsToGive = ubValidChoices;
+ else
+ // give us the maximum possible
+ ubNumItemsToGive = gIMPItemChoices[typeIndex].ubNumItems;
+
+ for ( int i=0; i < ubNumItemsToGive ;i++ )
+ {
+ usItem = 0;
while (usItem == 0 )
{
- iChoice = Random(gIMPItemChoices[ typeIndex ].ubChoices);
- usItem = gIMPItemChoices[ typeIndex ].bItemNo[ iChoice ];
- if (!ItemIsLegal(usItem))
- usItem=0;
+ iChoice = Random( ubNumChoices );
+ usItem = gIMPItemChoices[ typeIndex ].bItemNo[ iChoice ];
+ // is this legal and we don't have it already?
+ if (ItemIsLegal(usItem) && !ubItemsGiven[iChoice] )
+ ubItemsGiven[iChoice] = TRUE;
+ else
+ usItem=0;
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("GiveIMPRandomItems: typeIndex = %d, usItem = %d ",typeIndex, usItem ));
if ( usItem > 0 )
@@ -1491,5 +1728,23 @@ void GiveIMPItems( MERCPROFILESTRUCT *pProfile, INT8 abilityValue, UINT8 typeInd
}
+// SANDRO - Function to determine actual cost of profile
+INT32 iGetProfileCost()
+{
+ if (gGameExternalOptions.fDynamicIMPProfileCost)
+ {
+ INT32 iIMPProfileCost;
+
+ iIMPProfileCost = gGameExternalOptions.iIMPProfileCost * CountFilledIMPSlots(-1);
+
+ if (iIMPProfileCost >= gGameExternalOptions.iIMPProfileCost)
+ return(iIMPProfileCost);
+ else
+ return(gGameExternalOptions.iIMPProfileCost);
+ }
+ else
+ return(gGameExternalOptions.iIMPProfileCost);
+}
+
diff --git a/Laptop/IMP Confirm.h b/Laptop/IMP Confirm.h
index b1aeaead..2bba2a9d 100644
--- a/Laptop/IMP Confirm.h
+++ b/Laptop/IMP Confirm.h
@@ -6,6 +6,76 @@ void RenderIMPConfirm( void );
void ExitIMPConfirm( void );
void HandleIMPConfirm( void );
+#define MAX_NEW_IMP_PORTRAITS 50
+
+typedef struct
+{
+ UINT16 uiEyeXPositions;
+ UINT16 uiEyeYPositions;
+ UINT16 uiMouthXPositions;
+ UINT16 uiMouthYPositions;
+ UINT16 uiIndex;
+ UINT16 FaceIndex;
+ UINT16 PortraitId;
+ BOOLEAN bSex;
+ INT32 iCurrentSkin;
+ INT32 iCurrentHair;
+ INT32 iCurrentShirt;
+ INT32 iCurrentPants;
+ BOOLEAN bBigBody;
+ BOOLEAN bBadAss;
+
+} IMP_FACE_VALUES;
+
+extern IMP_FACE_VALUES gIMPFaceValues[200];
+
+
+typedef struct
+{
+ UINT16 uiIndexIMP;
+ BOOLEAN Enabled;
+
+ UINT16 uiEyeXPositions;
+ UINT16 uiEyeYPositions;
+ UINT16 uiMouthXPositions;
+ UINT16 uiMouthYPositions;
+ UINT16 uiIndex;
+ UINT16 FaceIndex;
+ UINT16 PortraitId;
+ BOOLEAN bSex;
+ INT32 iCurrentSkin;
+ INT32 iCurrentHair;
+ INT32 iCurrentShirt;
+ INT32 iCurrentPants;
+ BOOLEAN bBigBody;
+ BOOLEAN bBadAss;
+
+} IMP_MALE_VALUES;
+
+typedef struct
+{
+ UINT16 uiIndexIMP;
+ BOOLEAN Enabled;
+
+ UINT16 uiEyeXPositions;
+ UINT16 uiEyeYPositions;
+ UINT16 uiMouthXPositions;
+ UINT16 uiMouthYPositions;
+ UINT16 uiIndex;
+ UINT16 FaceIndex;
+ UINT16 PortraitId;
+ BOOLEAN bSex;
+ INT32 iCurrentSkin;
+ INT32 iCurrentHair;
+ INT32 iCurrentShirt;
+ INT32 iCurrentPants;
+ BOOLEAN bBigBody;
+ BOOLEAN bBadAss;
+} IMP_FEMALE_VALUES;
+
+extern IMP_FEMALE_VALUES gIMPFemaleValues[200];
+extern IMP_MALE_VALUES gIMPMaleValues[200];
+
BOOLEAN AddCharacterToPlayersTeam( void );
BOOLEAN LoadImpCharacter( STR fileName );
void WriteOutCurrentImpCharacter( INT32 iProfileId );
@@ -15,5 +85,7 @@ void ResetIMPCharactersEyesAndMouthOffsets( UINT8 ubMercProfileID );
BOOLEAN ImpExists ( STR fileName );
+INT32 iGetProfileCost( void ); // added by SANDRO
+
#endif
diff --git a/Laptop/IMP Disability Trait.cpp b/Laptop/IMP Disability Trait.cpp
index 48ce631d..3b85ddea 100644
--- a/Laptop/IMP Disability Trait.cpp
+++ b/Laptop/IMP Disability Trait.cpp
@@ -78,6 +78,8 @@ INT32 giIMPDisabilityTraitFinsihButtonImage;
//image handle
UINT32 guiIST_GreyGoldBox3;
+MOUSE_REGION gMR_DisabilityHelpTextRegions[ IMP_DISABILITIES_NUMBER ];
+
//*******************************************************************
//
// Function Prototypes
@@ -93,6 +95,7 @@ void IMPDisabilityTraitDisplayDisabilityTraits();
BOOLEAN CameBackToDisabilityTraitPageButNotFinished();
+void AssignDisabilityHelpText( UINT8 ubNumber );
//*******************************************************************
//
@@ -141,7 +144,18 @@ void EnterIMPDisabilityTrait( void )
}
HandleDisabilityTraitButtonStates( );
-
+
+ // add regions for help texts
+ UINT16 usPosY = IMP_DISABILITY_COLUMN_START_Y + 8;
+ for( UINT8 ubCnt=0; ubCntubSoundSchemeID = 0;
+ //ButtonList[ giIMPDisabilityTraitAnswerButton[ ubCnt ] ]->ubSoundSchemeID = 0;
//Determine the next x location
- //if( iCnt < IMP_DISABILITY_TRAIT_NUMBER_TO_START_2ND_COLUMN )
+ //if( ubCnt < IMP_DISABILITY_TRAIT_NUMBER_TO_START_2ND_COLUMN )
usPosX = IMP_DISABILITY_COLUMN_START_X;
//else
// usPosX = IMP_DISABILITY_2ND_COLUMN_START_X;
//Determine the next Y location
- //if( iCnt == IMP_DISABILITY_TRAIT_NUMBER_TO_START_2ND_COLUMN )
+ //if( ubCnt == IMP_DISABILITY_TRAIT_NUMBER_TO_START_2ND_COLUMN )
// usPosY = IMP_DISABILITY_2ND_COLUMN_START_Y;
//else
usPosY += IMP_DISABILITY_TRAIT__SPACE_BTN_BUTTONS;
@@ -258,7 +274,7 @@ void BtnIMPDisabilityTraitAnswerCallback(GUI_BUTTON *btn,INT32 reason)
void HandleIMPDisabilityTraitAnswers( UINT32 uiSkillPressed )
{
- UINT32 uiCnt;
+ UINT8 ubCnt;
//if we are DONE and are just reviewing
if( iCurrentProfileMode == IMP__FINISH )
@@ -267,9 +283,9 @@ void HandleIMPDisabilityTraitAnswers( UINT32 uiSkillPressed )
}
//reset all other buttons
- for( uiCnt=0; uiCntuiFlags |= BUTTON_CLICKED_ON;
+ ButtonList[ giIMPDisabilityTraitAnswerButton[ ubCnt ] ]->uiFlags |= BUTTON_CLICKED_ON;
}
else
{
- ButtonList[ giIMPDisabilityTraitAnswerButton[ uiCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ ButtonList[ giIMPDisabilityTraitAnswerButton[ ubCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
}
}
}
void IMPDisabilityTraitDisplayDisabilityTraits()
{
- UINT32 uiCnt;
+ UINT8 ubCnt;
UINT16 usPosX, usPosY;
UINT16 usBoxPosX, usBoxPosY;
HVOBJECT hImageHandle;
@@ -342,13 +357,13 @@ void IMPDisabilityTraitDisplayDisabilityTraits()
usPosX = IMP_DISABILITY_COLUMN_START_X + IMP_DISABILITY_TRAIT__TEXT_OFFSET_X;
usPosY = IMP_DISABILITY_COLUMN_START_Y + IMP_DISABILITY_TRAIT__TEXT_OFFSET_Y;
- for( uiCnt=0; uiCntuiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+// btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ INT32 iMinorTrait = MSYS_GetBtnUserData( btn, 0 );
+
+ HandleIMPMinorTraitAnswers( iMinorTrait );
+ }
+}
+
+void HandleIMPMinorTraitAnswers( UINT32 uiSkillPressed )
+{
+ UINT32 uiCnt;
+
+ //if we are DONE and are just reviewing
+ if( iCurrentProfileMode == IMP__FINISH )
+ {
+ return;
+ }
+
+ //make sure its a valid skill
+ if( uiSkillPressed > IMP_SKILL_TRAITS_NEW_NUMBER_MINOR_SKILLS )
+ {
+ Assert( 0 );
+ return;
+ }
+
+ //if its allready set
+ if( gfMinorTraitQuestions[ uiSkillPressed ] && uiSkillPressed != IMP_SKILL_TRAITS_NEW_MINOR_NONE )
+ {
+ gfMinorTraitQuestions[ uiSkillPressed ] = FALSE;
+
+ BOOLEAN fNoSkillSelected = TRUE;
+ for ( uiCnt=0; uiCnt<(IMP_SKILL_TRAITS_NEW_MINOR_NONE); uiCnt++ )
+ {
+ if ( gfMinorTraitQuestions[ uiCnt ] == TRUE )
+ fNoSkillSelected = FALSE;
+ }
+ if ( fNoSkillSelected )
+ {
+ // select NONE button
+ gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_MINOR_NONE ] = TRUE;
+ }
+ }
+ else
+ {
+ //if we are to reset all the buttons
+ if( CountNumMinorTraitsSelected( FALSE ) >= NumAvailableMinorTraits() )
+ {
+ // try to remove the last selected minor trait
+ if ( gfMinorTraitQuestions[ GetLastSelectedMinorTrait() ] > 0 )
+ {
+ gfMinorTraitQuestions[ GetLastSelectedMinorTrait() ] = FALSE;
+
+ // remove this one from list
+ HandleLastSelectedMinorTrait( -1 );
+ }
+ // if there is none, remove all for sure
+ else
+ {
+ //loop through all the skill and reset them
+ for( uiCnt=0; uiCntuiFlags |= BUTTON_CLICKED_ON;
+ }
+ else
+ {
+ ButtonList[ giIMPMinorTraitAnswerButton[ uiCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ }
+ }
+}
+
+void IMPMinorTraitDisplaySkills()
+{
+ UINT32 uiCnt;
+ UINT16 usPosX, usPosY;
+ UINT16 usBoxPosX, usBoxPosY;
+ HVOBJECT hImageHandle;
+
+ //Display the title
+ DrawTextToScreen( gzIMPSkillTraitsTextNewMinor[ IMP_SKILL_TRAITS_NEW_NUMBER_MINOR_SKILLS ], IMP_MINOR_TRAIT__TITLE_X, IMP_MINOR_TRAIT__TITLE_Y, IMP_MINOR_TRAIT__TITLE_WIDTH, IMP_MINOR_TRAIT__TITLE_FONT, IMP_MINOR_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+
+ // Stats
+ GetVideoObject(&hImageHandle, guiIMT_GreyGoldBox );
+
+ usPosX = IMP_MINOR_TRAIT__LEFT_COLUMN_START_X + IMP_MINOR_TRAIT__TEXT_OFFSET_X;
+ usPosY = IMP_MINOR_TRAIT__LEFT_COLUMN_START_Y + IMP_MINOR_TRAIT__TEXT_OFFSET_Y;
+
+ for( uiCnt=0; uiCntuiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ //if we are just reviewing the page
+ if( iCurrentProfileMode == IMP__FINISH )
+ {
+ //go back tot he done screen
+ iCurrentImpPage = IMP_FINISH;
+ }
+ else
+ {
+ iCurrentImpPage = IMP_MAIN_PAGE;
+
+ if( CameBackToMinorTraitPageButNotFinished() )
+ {
+ }
+ else
+ {
+ //We are finished on this page
+ iCurrentProfileMode = IMP__ATTRIBUTES;
+ }
+ }
+ }
+}
+
+BOOLEAN CameBackToMinorTraitPageButNotFinished()
+{
+ //if we are in a page that comes after this one
+ if( iCurrentProfileMode == IMP__ATTRIBUTES )
+ {
+ return( TRUE );
+ }
+ else
+ {
+ return( FALSE );
+ }
+}
+
+INT8 CountNumMinorTraitsSelected( BOOLEAN fIncludeNoneSkill )
+{
+ UINT32 uiCnt;
+ INT8 iNumberSkills=0;
+
+ for( uiCnt=0; uiCnt < IMP_SKILL_TRAITS_NEW_NUMBER_MINOR_SKILLS; uiCnt++ )
+ {
+ if( !fIncludeNoneSkill && uiCnt == IMP_SKILL_TRAITS_NEW_MINOR_NONE )
+ continue;
+ //if the skill is selected ( ie depressed )
+ else if( gfMinorTraitQuestions[ uiCnt ] )
+ {
+ iNumberSkills++;
+ }
+ }
+
+ return( iNumberSkills );
+}
+
+INT8 NumAvailableMinorTraits()
+{
+ INT8 bNumMinorTraits=0;
+ INT8 bNumMajorTraits=0;
+
+ //Count the number of skills selected
+ bNumMajorTraits = CountNumSkillTraitsSelected( FALSE );
+
+ bNumMinorTraits = gSkillTraitValues.ubMaxNumberOfTraits - bNumMajorTraits;
+
+ bNumMinorTraits = max( 1, bNumMinorTraits );
+
+ //if ( bNumMajorTraits == 0 )
+ // bNumMinorTraits = 3;
+ //else if ( bNumMajorTraits == 1 )
+ // bNumMinorTraits = 2;
+ //else if ( bNumMajorTraits == 2 )
+ // bNumMinorTraits = 1;
+ //else
+ //{
+ // Assert( 0 );
+ // bNumMinorTraits = 0;
+ //}
+
+ return(bNumMinorTraits);
+}
+
+
+void AddSelectedMinorTraitsToSkillsList()
+{
+ UINT32 uiCnt;
+
+ // if we have somehow reached beyond available traits, try to fix it by removing the last one selected
+ if ( NumAvailableMinorTraits() < CountNumMinorTraitsSelected( FALSE ) )
+ {
+ if (gfMinorTraitQuestions[ GetLastSelectedMinorTrait() ] == TRUE )
+ gfMinorTraitQuestions[ GetLastSelectedMinorTrait() ] = FALSE;
+ }
+ // if still something is wrong, remove them all
+ if ( NumAvailableMinorTraits() < CountNumMinorTraitsSelected( FALSE ) )
+ {
+ for( uiCnt=0; uiCnt=0; iCnt-- )
+ {
+ if ( gbLastSelectedMinorTrait[ iCnt ] > 0 )
+ {
+ gbLastSelectedMinorTrait[ iCnt ] = 0;
+ break;
+ }
+ }
+
+ }
+ else
+ {
+ for( iCnt=0; iCnt<9; iCnt++ )
+ {
+ gbLastSelectedMinorTrait[ (iCnt + 1) ] = gbLastSelectedMinorTrait[ iCnt ];
+ }
+ gbLastSelectedMinorTrait[ 0 ] = bNewTrait;
+ }
+
+ // here in "gbLastSelectedMinorTrait[ 0 ]" must always be the oldest minor trait selected
+ // this is indeed pretty sh*tty code
+ /*if( bNewTrait == IMP_SKILL_TRAITS_NEW_MINOR_NONE )
+ {
+ gbLastSelectedMinorTrait[ 0 ] = -1;
+ gbLastSelectedMinorTrait[ 1 ] = -1;
+ gbLastSelectedMinorTrait[ 2 ] = -1;
+ return;
+ }
+
+ if( gfMinorTraitQuestions[ gbLastSelectedMinorTrait[ 0 ] ] == FALSE )
+ gbLastSelectedMinorTrait[ 0 ] = -1;
+ if( gfMinorTraitQuestions[ gbLastSelectedMinorTrait[ 1 ] ] == FALSE )
+ gbLastSelectedMinorTrait[ 1 ] = -1;
+ if( gfMinorTraitQuestions[ gbLastSelectedMinorTrait[ 2 ] ] == FALSE )
+ gbLastSelectedMinorTrait[ 2 ] = -1;
+
+ if( gbLastSelectedMinorTrait[ 0 ] == -1 )
+ {
+ if( gbLastSelectedMinorTrait[ 1 ] != -1 )
+ gbLastSelectedMinorTrait[ 0 ] = gbLastSelectedMinorTrait[ 1 ];
+ else if( gbLastSelectedMinorTrait[ 2 ] != -1 )
+ gbLastSelectedMinorTrait[ 0 ] = gbLastSelectedMinorTrait[ 2 ];
+ }
+ else if( gbLastSelectedMinorTrait[ 1 ] == -1 && gbLastSelectedMinorTrait[ 2 ] != -1 )
+ {
+ gbLastSelectedMinorTrait[ 1 ] = gbLastSelectedMinorTrait[ 2 ];
+ }
+
+ if( NumAvailableMinorTraits() == 1 )
+ {
+ gbLastSelectedMinorTrait[ 0 ] = bNewTrait;
+ }
+ else if( NumAvailableMinorTraits() == 2 )
+ {
+ if( gbLastSelectedMinorTrait[ 0 ] == -1 )
+ {
+ gbLastSelectedMinorTrait[ 0 ] = bNewTrait;
+ }
+ else if( gbLastSelectedMinorTrait[ 1 ] == -1 )
+ {
+ gbLastSelectedMinorTrait[ 1 ] = bNewTrait;
+ }
+ else
+ {
+ gbLastSelectedMinorTrait[ 0 ] = gbLastSelectedMinorTrait[ 1 ];
+ gbLastSelectedMinorTrait[ 1 ] = bNewTrait;
+ }
+ }
+ else if( NumAvailableMinorTraits() == 3 )
+ {
+ if( gbLastSelectedMinorTrait[ 0 ] == -1 )
+ {
+ gbLastSelectedMinorTrait[ 0 ] = bNewTrait;
+ }
+ else if( gbLastSelectedMinorTrait[ 1 ] == -1 )
+ {
+ gbLastSelectedMinorTrait[ 1 ] = bNewTrait;
+ }
+ else if( gbLastSelectedMinorTrait[ 2 ] == -1 )
+ {
+ gbLastSelectedMinorTrait[ 2 ] = bNewTrait;
+ }
+ else
+ {
+ gbLastSelectedMinorTrait[ 0 ] = gbLastSelectedMinorTrait[ 1 ];
+ gbLastSelectedMinorTrait[ 1 ] = gbLastSelectedMinorTrait[ 2 ];
+ gbLastSelectedMinorTrait[ 2 ] = bNewTrait;
+ }
+ }
+ else
+ {
+ Assert( 0 );
+ gbLastSelectedMinorTrait[ 0 ] = bNewTrait;
+ }*/
+}
+
+INT8 GetLastSelectedMinorTrait( void )
+{
+ INT16 iCnt;
+
+ for( iCnt=9; iCnt>=0; iCnt-- )
+ {
+ if ( gbLastSelectedMinorTrait[ iCnt ] > 0 )
+ {
+ return ( gbLastSelectedMinorTrait[ iCnt ] );
+ break;
+ }
+ }
+ return ( 0 );
+}
+
+UINT8 StrengthRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_MELEE ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+ return( 0 );
+}
+UINT8 DexterityRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_AMBIDEXTROUS ] && gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_THROWING ] )
+ {
+ // 70 is minimum if having both, +20 is addition to other preset requirements
+ if( (iInitialValue + 20) < 70 )
+ {
+ // if less than minimum, add how much we need
+ return ( 70 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 20 );
+ }
+ }
+ else if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_AMBIDEXTROUS ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+ else if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_THROWING ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+
+ return( 0 );
+}
+UINT8 AgilityRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_ATHLETICS ] && gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_STEALTHY ] )
+ {
+ // 70 is minimum if having both, +20 is addition to other preset requirements
+ if( (iInitialValue + 20) < 70 )
+ {
+ // if less than minimum, add how much we need
+ return ( 70 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 20 );
+ }
+ }
+ else if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_ATHLETICS ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+ else if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_STEALTHY ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+
+ return( 0 );
+}
+UINT8 HealthRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_BODYBUILDING ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+
+ return( 0 );
+}
+UINT8 WisdomRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_NIGHT_OPS ] && gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_SCOUTING ] )
+ {
+ // 70 is minimum if having both, +20 is addition to other preset requirements
+ if( (iInitialValue + 20) < 70 )
+ {
+ // if less than minimum, add how much we need
+ return ( 70 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 20 );
+ }
+ }
+ else if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_NIGHT_OPS ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+ else if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_SCOUTING ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 60 )
+ {
+ // if less than minimum, add how much we need
+ return ( 60 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+
+ return( 0 );
+}
+UINT8 LeaderShipRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_TEACHING ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 45 )
+ {
+ // if less than minimum, add how much we need
+ return ( 45 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+
+ return( 0 );
+}
+UINT8 MarksmanshipRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ // nothing here
+ return( 0 );
+}
+UINT8 MechanicalRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ // nothing here
+ return( 0 );
+}
+UINT8 MedicalRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ // nothing here
+ return( 0 );
+}
+UINT8 ExplosivesRequiredAdjustmentForMinorTraits( INT32 iInitialValue )
+{
+ if ( gfMinorTraitQuestions[ IMP_SKILL_TRAITS_NEW_DEMOLITIONS ] )
+ {
+ // 60 is minimum, +10 is addition to other preset requirements
+ if( (iInitialValue + 10) < 45 )
+ {
+ // if less than minimum, add how much we need
+ return ( 45 - iInitialValue );
+ }
+ else
+ {
+ // otherwise just add 10 on top
+ return ( 10 );
+ }
+ }
+
+ return( 0 );
+}
+
+void AssignMinorTraitHelpText( UINT8 ubNumber )
+{
+ CHAR16 apStr[ 5000 ];
+ CHAR16 atStr[ 1500 ];
+
+ switch( ubNumber )
+ {
+ case IMP_SKILL_TRAITS_NEW_AMBIDEXTROUS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubAMPenaltyDoubleReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[0], gSkillTraitValues.ubAMPenaltyDoubleReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMReloadSpeedMagazines != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[1], gSkillTraitValues.ubAMReloadSpeedMagazines, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMReloadSpeedLoose != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[2], gSkillTraitValues.ubAMReloadSpeedLoose, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMPickItemsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[3], gSkillTraitValues.ubAMPickItemsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMWorkBackpackAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[4], gSkillTraitValues.ubAMWorkBackpackAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMHandleDoorsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[5], gSkillTraitValues.ubAMHandleDoorsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMHandleBombsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[6], gSkillTraitValues.ubAMHandleBombsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMAttachingItemsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[7], gSkillTraitValues.ubAMAttachingItemsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_MELEE:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubMEBladesAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[0], gSkillTraitValues.ubMEBladesAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtHBladesBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[1], gSkillTraitValues.ubMECtHBladesBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtHBluntBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[2], gSkillTraitValues.ubMECtHBluntBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDamageBonusBlades != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[3], gSkillTraitValues.ubMEDamageBonusBlades, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDamageBonusBlunt != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[4], gSkillTraitValues.ubMEDamageBonusBlunt, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usMEAimedMeleeAttackDamageBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[5], gSkillTraitValues.usMEAimedMeleeAttackDamageBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDodgeBladesBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[6], gSkillTraitValues.ubMEDodgeBladesBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtDBladesOnTopWithBladeInHands != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[7], gSkillTraitValues.ubMECtDBladesOnTopWithBladeInHands, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDodgeBluntBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[8], gSkillTraitValues.ubMEDodgeBluntBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtDBluntOnTopWithBladeInHands != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[9], gSkillTraitValues.ubMECtDBluntOnTopWithBladeInHands, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_THROWING:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubTHBladesAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[0], gSkillTraitValues.ubTHBladesAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesMaxRange != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[1], gSkillTraitValues.ubTHBladesMaxRange, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesCtHBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[2], gSkillTraitValues.ubTHBladesCtHBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesCtHBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[3], gSkillTraitValues.ubTHBladesCtHBonusPerClick, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesDamageBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[4], gSkillTraitValues.ubTHBladesDamageBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesDamageBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[5], gSkillTraitValues.ubTHBladesDamageBonusPerClick, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesSilentCriticalHitChance != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[6], gSkillTraitValues.ubTHBladesSilentCriticalHitChance, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesCriticalHitMultiplierBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[7], gSkillTraitValues.ubTHBladesCriticalHitMultiplierBonus);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesAimClicksAdded != 0 )
+ {
+ if( gSkillTraitValues.ubTHBladesAimClicksAdded == 1 )
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[8], gSkillTraitValues.ubTHBladesAimClicksAdded );
+ else
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[9], gSkillTraitValues.ubTHBladesAimClicksAdded );
+
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_NIGHT_OPS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubNOeSightRangeBonusInDark != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[0], gSkillTraitValues.ubNOeSightRangeBonusInDark, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNOHearingRangeBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[1], gSkillTraitValues.ubNOHearingRangeBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNOHearingRangeBonusInDark != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[2], gSkillTraitValues.ubNOHearingRangeBonusInDark, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNOIterruptsBonusInDark != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[3], gSkillTraitValues.ubNOIterruptsBonusInDark, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNONeedForSleepReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[4], gSkillTraitValues.ubNONeedForSleepReduction);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_STEALTHY:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSTStealthModeSpeedBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[0], gSkillTraitValues.ubSTStealthModeSpeedBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSTBonusToMoveQuietly != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[1], gSkillTraitValues.ubSTBonusToMoveQuietly, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSTStealthBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[2], gSkillTraitValues.ubSTStealthBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSTStealthPenaltyForMovingReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[3], gSkillTraitValues.ubSTStealthPenaltyForMovingReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_ATHLETICS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubATAPsMovementReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAthletics[0], gSkillTraitValues.ubATAPsMovementReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubATBPsMovementReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAthletics[1], gSkillTraitValues.ubATBPsMovementReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_BODYBUILDING:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubBBDamageResistance != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[0], gSkillTraitValues.ubBBDamageResistance, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubBBCarryWeightBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[1], gSkillTraitValues.ubBBCarryWeightBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubBBBreathLossForHtHImpactReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[2], gSkillTraitValues.ubBBBreathLossForHtHImpactReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usBBIncreasedNeededDamageToFallDown != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[3], gSkillTraitValues.usBBIncreasedNeededDamageToFallDown, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_DEMOLITIONS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubDEAPsNeededToThrowGrenadesReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[0], gSkillTraitValues.ubDEAPsNeededToThrowGrenadesReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEMaxRangeToThrowGrenades != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[1], gSkillTraitValues.ubDEMaxRangeToThrowGrenades, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDECtHWhenThrowingGrenades != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[2], gSkillTraitValues.ubDECtHWhenThrowingGrenades, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEDamageOfBombsAndMines != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[3], gSkillTraitValues.ubDEDamageOfBombsAndMines, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEAttachDetonatorCheckBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[4], gSkillTraitValues.ubDEAttachDetonatorCheckBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEPlantAndRemoveBombCheckBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[5], gSkillTraitValues.ubDEPlantAndRemoveBombCheckBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEPlacedBombLevelBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[6], gSkillTraitValues.ubDEPlacedBombLevelBonus);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEShapedChargeDamageMultiplier != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[7], gSkillTraitValues.ubDEShapedChargeDamageMultiplier);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_TEACHING:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubTGBonusToTrainMilitia != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[0], gSkillTraitValues.ubTGBonusToTrainMilitia, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGEffectiveLDRToTrainMilitia != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[1], gSkillTraitValues.ubTGEffectiveLDRToTrainMilitia, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGBonusToTeachOtherMercs != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[2], gSkillTraitValues.ubTGBonusToTeachOtherMercs, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGEffectiveSkillValueForTeaching != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[3], gSkillTraitValues.ubTGEffectiveSkillValueForTeaching);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGBonusOnPractising != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[4], gSkillTraitValues.ubTGBonusOnPractising, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_SCOUTING:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSCSightRangebonusWithScopes != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[0], gSkillTraitValues.ubSCSightRangebonusWithScopes, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usSCSightRangebonusWithBinoculars != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[1], gSkillTraitValues.usSCSightRangebonusWithBinoculars, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSCTunnelVisionReducedWithBinoculars != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[2], gSkillTraitValues.ubSCTunnelVisionReducedWithBinoculars, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.fSCCanDetectEnemyPresenseAround )
+ {
+ if( gSkillTraitValues.fSCCanDetermineEnemyNumbersAround )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[3]);
+ wcscat( apStr, atStr );
+ }
+ else
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[4]);
+ wcscat( apStr, atStr );
+ }
+ }
+ if( gSkillTraitValues.fSCPreventsTheEnemyToAmbushMercs )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[5]);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.fSCPreventsBloodcatsAmbushes )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[6]);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_MINOR_NONE:
+ {
+ swprintf( apStr, gzIMPMinorTraitsHelpTextsNone[0] );
+ break;
+ }
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gMR_MinorTraitHelpTextRegions[ubNumber]), apStr );
+ SetRegionHelpEndCallback( &gMR_MinorTraitHelpTextRegions[ubNumber], MSYS_NO_CALLBACK );
+
+ return;
+}
\ No newline at end of file
diff --git a/Laptop/IMP Minor Trait.h b/Laptop/IMP Minor Trait.h
new file mode 100644
index 00000000..f99267fc
--- /dev/null
+++ b/Laptop/IMP Minor Trait.h
@@ -0,0 +1,44 @@
+#ifndef __IMP_MINOR_TRAIT__H_
+#define __IMP_MINOR_TRAIT__H_
+
+#include "Types.h"
+
+void EnterIMPMinorTrait( void );
+void RenderIMPMinorTrait( void );
+void ExitIMPMinorTrait( void );
+void HandleIMPMinorTrait( void );
+
+enum
+{
+ // minor traits
+ IMP_SKILL_TRAITS_NEW_AMBIDEXTROUS,
+ IMP_SKILL_TRAITS_NEW_MELEE,
+ IMP_SKILL_TRAITS_NEW_THROWING,
+ IMP_SKILL_TRAITS_NEW_NIGHT_OPS,
+ IMP_SKILL_TRAITS_NEW_STEALTHY,
+ IMP_SKILL_TRAITS_NEW_ATHLETICS,
+ IMP_SKILL_TRAITS_NEW_BODYBUILDING,
+ IMP_SKILL_TRAITS_NEW_DEMOLITIONS,
+ IMP_SKILL_TRAITS_NEW_TEACHING,
+ IMP_SKILL_TRAITS_NEW_SCOUTING,
+ //////
+ IMP_SKILL_TRAITS_NEW_MINOR_NONE,
+ IMP_SKILL_TRAITS_NEW_NUMBER_MINOR_SKILLS,
+};
+
+void AddSelectedMinorTraitsToSkillsList();
+
+INT8 CountNumMinorTraitsSelected( BOOLEAN fIncludeNoneSkill );
+
+UINT8 StrengthRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 DexterityRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 AgilityRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 HealthRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 WisdomRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 LeaderShipRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 MarksmanshipRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 MechanicalRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 MedicalRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+UINT8 ExplosivesRequiredAdjustmentForMinorTraits( INT32 iInitialValue );
+
+#endif
diff --git a/Laptop/IMP Personality Entrance.h b/Laptop/IMP Personality Entrance.h
index dc82d663..6e0a9d83 100644
--- a/Laptop/IMP Personality Entrance.h
+++ b/Laptop/IMP Personality Entrance.h
@@ -7,4 +7,6 @@ void RenderIMPPersonalityEntrance( void );
void ExitIMPPersonalityEntrance( void );
void HandleIMPPersonalityEntrance( void );
+STR16 pSkillTraitBeginIMPStrings[];
+
#endif
\ No newline at end of file
diff --git a/Laptop/IMP Personality Quiz.cpp b/Laptop/IMP Personality Quiz.cpp
index 8d381ffe..3a27cb5d 100644
--- a/Laptop/IMP Personality Quiz.cpp
+++ b/Laptop/IMP Personality Quiz.cpp
@@ -21,6 +21,7 @@
#include "english.h"
#endif
+
// Kaiden this line was commented before I screwed with it
//extern struct POINT;
@@ -207,10 +208,10 @@ void CreateIMPPersonalityQuizButtons( void )
// ths Done button
giIMPPersonalityQuizButtonImage[0]= LoadButtonImage( "LAPTOP\\button_7.sti" ,-1,0,-1,1,-1 );
-/* giIMPPersonalityQuizButton[0] = QuickCreateButton( giIMPPersonalityQuizButtonImage[0], LAPTOP_SCREEN_UL_X + ( 197 ), LAPTOP_SCREEN_WEB_UL_Y + ( 310 ),
- BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
- BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPPersonalityQuizAnswerConfirmCallback);
-*/
+// giIMPPersonalityQuizButton[0] = QuickCreateButton( giIMPPersonalityQuizButtonImage[0], LAPTOP_SCREEN_UL_X + ( 197 ), LAPTOP_SCREEN_WEB_UL_Y + ( 310 ),
+// BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+// BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPPersonalityQuizAnswerConfirmCallback);
+//
giIMPPersonalityQuizButton[0] = CreateIconAndTextButton( giIMPPersonalityQuizButtonImage[0], pImpButtonText[ 8 ], FONT12ARIAL,
FONT_WHITE, DEFAULT_SHADOW,
FONT_WHITE, DEFAULT_SHADOW,
@@ -221,10 +222,10 @@ void CreateIMPPersonalityQuizButtons( void )
// start over
giIMPPersonalityQuizButtonImage[ 1 ]= LoadButtonImage( "LAPTOP\\button_5.sti" ,-1,0,-1,1,-1 );
- /* giIMPPersonalityQuizButton[ 1 ] = QuickCreateButton( giIMPPersonalityQuizButtonImage[1], LAPTOP_SCREEN_UL_X + ( BTN_FIRST_COLUMN_X ), LAPTOP_SCREEN_WEB_UL_Y + ( 310 ),
- BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
- BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPPersonalityQuizStartOverCallback);
-*/
+ // giIMPPersonalityQuizButton[ 1 ] = QuickCreateButton( giIMPPersonalityQuizButtonImage[1], LAPTOP_SCREEN_UL_X + ( BTN_FIRST_COLUMN_X ), LAPTOP_SCREEN_WEB_UL_Y + ( 310 ),
+// BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+// BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPPersonalityQuizStartOverCallback);
+//
giIMPPersonalityQuizButton[ 1 ] = CreateIconAndTextButton( giIMPPersonalityQuizButtonImage[ 1 ], pImpButtonText[ 7 ], FONT12ARIAL,
FONT_WHITE, DEFAULT_SHADOW,
@@ -1024,12 +1025,12 @@ void CompileQuestionsInStatsAndWhatNot( void )
if( fCharacterIsMale )
{
// Martial arts
- AddSkillToSkillList( MARTIALARTS );
+ AddSkillToSkillList( MARTIALARTS_OT );
}
else
{
// for women, ambidexterious
- AddSkillToSkillList( AMBIDEXT );
+ AddSkillToSkillList( AMBIDEXT_OT );
}
break;
case( 1 ):
@@ -1037,15 +1038,15 @@ void CompileQuestionsInStatsAndWhatNot( void )
break;
case( 2 ):
// hand to hand
- AddSkillToSkillList( HANDTOHAND );
+ AddSkillToSkillList( HANDTOHAND_OT );
break;
case( 3 ):
// lock picking
- AddSkillToSkillList( LOCKPICKING );
+ AddSkillToSkillList( LOCKPICKING_OT );
break;
case( 4 ):
// throwing
- AddSkillToSkillList( THROWING );
+ AddSkillToSkillList( THROWING_OT );
break;
case( 5 ):
// optimist
@@ -1058,10 +1059,10 @@ void CompileQuestionsInStatsAndWhatNot( void )
{
case( 0 ):
// teaching
- AddSkillToSkillList( TEACHING );
+ AddSkillToSkillList( TEACHING_OT );
break;
case( 1 ):
- AddSkillToSkillList( STEALTHY );
+ AddSkillToSkillList( STEALTHY_OT );
break;
case( 2 ):
// psycho
@@ -1077,14 +1078,14 @@ void CompileQuestionsInStatsAndWhatNot( void )
{
case( 0 ):
// lock picking
- AddSkillToSkillList( LOCKPICKING );
+ AddSkillToSkillList( LOCKPICKING_OT );
break;
case( 1 ):
// arrogant
AddAnAttitudeToAttitudeList( ATT_ARROGANT );
break;
case( 2 ):
- AddSkillToSkillList( STEALTHY );
+ AddSkillToSkillList( STEALTHY_OT );
break;
case( 3 ):
// normal
@@ -1098,7 +1099,7 @@ void CompileQuestionsInStatsAndWhatNot( void )
{
case( 0 ):
// automatic weapons
- AddSkillToSkillList( AUTO_WEAPS );
+ AddSkillToSkillList( AUTO_WEAPS_OT );
break;
case( 1 ):
// friendly
@@ -1146,7 +1147,7 @@ void CompileQuestionsInStatsAndWhatNot( void )
AddAnAttitudeToAttitudeList( ATT_COWARD );
break;
case( 1 ):
- AddSkillToSkillList( NIGHTOPS );
+ AddSkillToSkillList( NIGHTOPS_OT );
break;
case( 2 ):
// dont like boxes much
@@ -1165,14 +1166,14 @@ void CompileQuestionsInStatsAndWhatNot( void )
{
case( 0 ):
// electronics
- AddSkillToSkillList( ELECTRONICS );
+ AddSkillToSkillList( ELECTRONICS_OT );
break;
case( 1 ):
//knifing
- AddSkillToSkillList( KNIFING );
+ AddSkillToSkillList( KNIFING_OT );
break;
case( 2 ):
- AddSkillToSkillList( NIGHTOPS );
+ AddSkillToSkillList( NIGHTOPS_OT );
break;
case( 3 ):
// none
@@ -1184,7 +1185,7 @@ void CompileQuestionsInStatsAndWhatNot( void )
{
case( 0 ):
// ambidexterous
- AddSkillToSkillList( AMBIDEXT );
+ AddSkillToSkillList( AMBIDEXT_OT );
break;
case( 1 ):
// none
@@ -1247,7 +1248,7 @@ void CompileQuestionsInStatsAndWhatNot( void )
break;
case( 1 ):
// teaching
- AddSkillToSkillList( TEACHING );
+ AddSkillToSkillList( TEACHING_OT );
break;
case( 2 ):
// aggressive
@@ -1269,32 +1270,32 @@ void CompileQuestionsInStatsAndWhatNot( void )
if( fCharacterIsMale )
{
// Martial arts
- AddSkillToSkillList( MARTIALARTS );
+ AddSkillToSkillList( MARTIALARTS_OT );
}
else
{
// for women, ambidexterious
- AddSkillToSkillList( AMBIDEXT );
+ AddSkillToSkillList( AMBIDEXT_OT );
}
break;
case( 1 ):
//knifing
- AddSkillToSkillList( KNIFING );
+ AddSkillToSkillList( KNIFING_OT );
break;
case( 2 ):
// none
break;
case( 3 ):
// automatic weapons
- AddSkillToSkillList( AUTO_WEAPS );
+ AddSkillToSkillList( AUTO_WEAPS_OT );
break;
case( 4 ):
// hand to hand
- AddSkillToSkillList( HANDTOHAND );
+ AddSkillToSkillList( HANDTOHAND_OT );
break;
case( 5 ):
// electronics
- AddSkillToSkillList( ELECTRONICS );
+ AddSkillToSkillList( ELECTRONICS_OT );
break;
case( 6 ):
// ashole
@@ -1350,11 +1351,11 @@ void CompileQuestionsInStatsAndWhatNot( void )
{
case( 0 ):
// throwing
- AddSkillToSkillList( THROWING );
+ AddSkillToSkillList( THROWING_OT );
break;
case( 1 ):
// ambidexterous
- AddSkillToSkillList( AMBIDEXT );
+ AddSkillToSkillList( AMBIDEXT_OT );
break;
case( 3 ):
// none
@@ -1622,71 +1623,71 @@ void HandleIMPQuizKeyBoard( void )
// HOOK INTO MOUSE HOOKS
- /*
- if( (InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam >= '1' ) && ( InputEvent.usParam <= '9') )
- {
- if( ( UINT16 )( iNumberOfPersonaButtons ) >= InputEvent.usParam - '0' )
- {
+ //
+ //if( (InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam >= '1' ) && ( InputEvent.usParam <= '9') )
+ //{
+ // if( ( UINT16 )( iNumberOfPersonaButtons ) >= InputEvent.usParam - '0' )
+ // {
// reset buttons
- ResetQuizAnswerButtons( );
+ // ResetQuizAnswerButtons( );
// ok, check to see if button was disabled, if so, re enable
- CheckStateOfTheConfirmButton( );
+ // CheckStateOfTheConfirmButton( );
// toggle this button on
- ButtonList[ giIMPPersonalityQuizAnswerButton[ InputEvent.usParam - '1' ] ]->uiFlags |= (BUTTON_CLICKED_ON);
+ // ButtonList[ giIMPPersonalityQuizAnswerButton[ InputEvent.usParam - '1' ] ]->uiFlags |= (BUTTON_CLICKED_ON);
- iCurrentAnswer = InputEvent.usParam - '1';
+ // iCurrentAnswer = InputEvent.usParam - '1';
- PrintImpText( );
+ // PrintImpText( );
// the current and last question numbers
- PrintQuizQuestionNumber( );
+ // PrintQuizQuestionNumber( );
- fReDrawCharProfile = TRUE;
- fSkipFrame = TRUE;
- }
- }
- else if( ( iCurrentAnswer != -1 ) && ( InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == ENTER ) )
- {
+ // fReDrawCharProfile = TRUE;
+ // fSkipFrame = TRUE;
+ // }
+// }
+// else if( ( iCurrentAnswer != -1 ) && ( InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == ENTER ) )
+// {
// reset all the buttons
- ResetQuizAnswerButtons( );
+// ResetQuizAnswerButtons( );
// copy the answer into the list
- iQuizAnswerList[ giCurrentPersonalityQuizQuestion ] = iCurrentAnswer;
+// iQuizAnswerList[ giCurrentPersonalityQuizQuestion ] = iCurrentAnswer;
// reset answer for next question
- iCurrentAnswer = -1;
+// iCurrentAnswer = -1;
// next question, JOHNNY!
- giCurrentPersonalityQuizQuestion++;
- giMaxPersonalityQuizQuestion++;
+// giCurrentPersonalityQuizQuestion++;
+// giMaxPersonalityQuizQuestion++;
// OPPS!, done..time to finish up
- if( giCurrentPersonalityQuizQuestion > 15)
- {
- iCurrentImpPage = IMP_PERSONALITY_FINISH;
+// if( giCurrentPersonalityQuizQuestion > 15)
+// {
+// iCurrentImpPage = IMP_PERSONALITY_FINISH;
// process
- CompileQuestionsInStatsAndWhatNot( );
- }
+// CompileQuestionsInStatsAndWhatNot( );
+// }
- fSkipFrame = TRUE;
- }
- else if( ( InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == '=' ) )
- {
- MoveAheadAQuestion( );
- fSkipFrame = TRUE;
- }
- else if( ( InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == '-' ) )
- {
- MoveBackAQuestion( );
- fSkipFrame = TRUE;
- }
- else
- {
+// fSkipFrame = TRUE;
+// }
+// else if( ( InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == '=' ) )
+// {
+// MoveAheadAQuestion( );
+// fSkipFrame = TRUE;
+// }
+// else if( ( InputEvent.usEvent == KEY_DOWN ) && ( InputEvent.usParam == '-' ) )
+// {
+// MoveBackAQuestion( );
+// fSkipFrame = TRUE;
+// }
+// else
+// {
-*/ switch(InputEvent.usEvent)
+ switch(InputEvent.usEvent)
{
case LEFT_BUTTON_DOWN:
MouseSystemHook(LEFT_BUTTON_DOWN, (INT16)MousePos.x, (INT16)MousePos.y,_LeftButtonDown, _RightButtonDown);
@@ -1761,19 +1762,19 @@ void MoveAheadAQuestion( void )
CheckAndUpdateNextPreviousIMPQuestionButtonStates( );
-/*
- EnableButton( giPreviousQuestionButton );
- if( giCurrentPersonalityQuizQuestion >= giMaxPersonalityQuizQuestion )
- {
- DisableButton( giNextQuestionButton );
- iCurrentAnswer = -1;
- }
- else
- {
- EnableButton( giNextQuestionButton );
- }
-*/
+// EnableButton( giPreviousQuestionButton );
+
+// if( giCurrentPersonalityQuizQuestion >= giMaxPersonalityQuizQuestion )
+// {
+// DisableButton( giNextQuestionButton );
+// iCurrentAnswer = -1;
+// }
+// else
+// {
+// EnableButton( giNextQuestionButton );
+// }
+
return;
}
@@ -1792,16 +1793,16 @@ void MoveBackAQuestion( void )
EnableButton( giNextQuestionButton );
CheckAndUpdateNextPreviousIMPQuestionButtonStates( );
-/*
- if( giCurrentPersonalityQuizQuestion == 0 )
- {
- DisableButton( giPreviousQuestionButton );
- }
- else
- {
- EnableButton( giPreviousQuestionButton );
- }
-*/
+
+// if( giCurrentPersonalityQuizQuestion == 0 )
+// {
+// DisableButton( giPreviousQuestionButton );
+// }
+// else
+// {
+// EnableButton( giPreviousQuestionButton );
+// }
+
return;
}
diff --git a/Laptop/IMP Portraits.cpp b/Laptop/IMP Portraits.cpp
index 3887af43..48a45fac 100644
--- a/Laptop/IMP Portraits.cpp
+++ b/Laptop/IMP Portraits.cpp
@@ -21,10 +21,15 @@
#include "IMP Compile Character.h"
#endif
+#include "IMP Confirm.h"
+
//current and last pages
INT32 iCurrentPortrait = 0;
INT32 iLastPicture = 7;
+INT32 iLastPictureF;
+INT32 iLastPictureM;
+
// buttons needed for the IMP portrait screen
INT32 giIMPPortraitButton[ 3 ];
INT32 giIMPPortraitButtonImage[ 3 ];
@@ -52,6 +57,7 @@ void BtnIMPPortraitDoneCallback(GUI_BUTTON *btn,INT32 reason);
void EnterIMPPortraits( void )
{
+ iCurrentPortrait = 0;
// create buttons
CreateIMPPortraitButtons( );
@@ -121,7 +127,15 @@ BOOLEAN RenderPortrait( INT16 sX, INT16 sY )
// load it
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
- FilenameForBPP( pPlayerSelectedBigFaceFileNames[ iCurrentPortrait ] , VObjectDesc.ImageFile);
+
+
+ if ( gIMPMaleValues[ iCurrentPortrait ].Enabled == 1 )
+ {
+ sprintf( VObjectDesc.ImageFile, "Faces\\BigFaces\\%02d.sti", gIMPMaleValues[ iCurrentPortrait ].PortraitId );
+ }
+
+
+ //FilenameForBPP( pPlayerSelectedBigFaceFileNames[ iCurrentPortrait ] , VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &uiGraphicHandle));
// show it
@@ -138,7 +152,15 @@ BOOLEAN RenderPortrait( INT16 sX, INT16 sY )
{
// load it
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
- FilenameForBPP( pPlayerSelectedBigFaceFileNames[ iCurrentPortrait + 8 ] , VObjectDesc.ImageFile);
+
+ //FilenameForBPP( pPlayerSelectedBigFaceFileNames[ iCurrentPortrait + 8 ] , VObjectDesc.ImageFile);
+
+ if ( gIMPFemaleValues[ iCurrentPortrait ].Enabled == 1 )
+ {
+ sprintf( VObjectDesc.ImageFile, "Faces\\BigFaces\\%02d.sti", gIMPFemaleValues[ iCurrentPortrait ].PortraitId );
+ }
+
+
CHECKF(AddVideoObject(&VObjectDesc, &uiGraphicHandle));
// show it
@@ -154,12 +176,35 @@ BOOLEAN RenderPortrait( INT16 sX, INT16 sY )
return ( TRUE );
}
-
-
void IncrementPictureIndex( void )
{
- // cycle to next picture
+iCurrentPortrait++;
+if( fCharacterIsMale )
+{
+ if( gIMPMaleValues[iCurrentPortrait].uiIndex == iCurrentPortrait && gIMPMaleValues[iCurrentPortrait].PortraitId !=0 )
+ {
+ iCurrentPortrait = gIMPMaleValues[iCurrentPortrait].uiIndex;
+ }
+ else
+ {
+ iCurrentPortrait = 0;
+ }
+}
+else
+{
+ if( gIMPFemaleValues[iCurrentPortrait].uiIndex == iCurrentPortrait && gIMPFemaleValues[iCurrentPortrait].PortraitId !=0 )
+ {
+ iCurrentPortrait = gIMPFemaleValues[iCurrentPortrait].uiIndex;
+ }
+ else
+ {
+ iCurrentPortrait = 0;
+ }
+
+}
+ // cycle to next picture
+/*
iCurrentPortrait++;
// gone too far?
@@ -168,23 +213,64 @@ void IncrementPictureIndex( void )
iCurrentPortrait = 0;
}
-
+*/
return;
}
-
void DecrementPicture( void )
{
- // cycle to previous picture
+UINT32 cnt;
+UINT32 idPort = 0;
- iCurrentPortrait--;
+if( fCharacterIsMale )
+{
+ for ( cnt = 0; cnt < MAX_NEW_IMP_PORTRAITS; cnt++ )
+ {
+ if ( gIMPMaleValues[cnt].uiIndex == cnt && gIMPMaleValues[cnt].PortraitId !=0 )
+ {
+ iLastPictureM = gIMPMaleValues[cnt].uiIndex;
+ }
+ }
+
+ iLastPicture = iLastPictureM;
+}
+else
+{
+ for ( cnt = 0; cnt < MAX_NEW_IMP_PORTRAITS; cnt++ )
+ {
+ if ( gIMPFemaleValues[cnt].uiIndex == cnt && gIMPFemaleValues[cnt].PortraitId !=0 )
+ {
+ iLastPictureF = gIMPFemaleValues[cnt].uiIndex;
+ }
+ }
+
+ iLastPicture = iLastPictureF;
+}
+
+iCurrentPortrait--;
+if( fCharacterIsMale )
+{
+ if( iCurrentPortrait < 0 )
+ {
+ iCurrentPortrait = iLastPicture;
+ }
+}
+else
+{
+ if( iCurrentPortrait < 0 )
+ {
+ iCurrentPortrait = iLastPicture;
+ }
+
+}
+/*
// gone too far?
if( iCurrentPortrait < 0 )
{
- iCurrentPortrait = iLastPicture;
+ iCurrentPortrait = iLastPicture;
}
-
+*/
return;
}
@@ -364,18 +450,20 @@ void BtnIMPPortraitDoneCallback(GUI_BUTTON *btn,INT32 reason)
}*/
// grab picture number
+
+
+
if( fCharacterIsMale )
{
- // male
- iPortraitNumber = iCurrentPortrait;
+ // male
+ iPortraitNumber = gIMPMaleValues[ iCurrentPortrait ].uiIndex; //iCurrentPortrait
}
else
{
- // female
- iPortraitNumber = iCurrentPortrait + ( 8 );
-
+ // female
+ iPortraitNumber = gIMPFemaleValues[ iCurrentPortrait ].uiIndex; //iCurrentPortrait ;//+ ( 8 );
}
-
+
fButtonPendingFlag = TRUE;
}
}
diff --git a/Laptop/IMP Skill Trait.cpp b/Laptop/IMP Skill Trait.cpp
index 3beae54f..7bd7b652 100644
--- a/Laptop/IMP Skill Trait.cpp
+++ b/Laptop/IMP Skill Trait.cpp
@@ -21,6 +21,8 @@
#include "IMP Compile Character.h"
#include "GameSettings.h" // added by SANDRO
#include "IMP Color Choosing.h" // added by SANDRO
+ #include "IMP Minor Trait.h"
+ #include "Soldier Profile.h"
#endif
@@ -37,14 +39,6 @@
#define IMP_SKILL_TRAIT__COLOR FONT_MCOLOR_WHITE
-
-enum
-{
- IMP_SKILL_TRAIT__TITLE_TEXT=IMP_SKILL_TRAITS__NUMBER_SKILLS,
-};
-
-
-
#define IMP_SKILL_TRAIT__LEFT_COLUMN_START_X ( LAPTOP_SCREEN_UL_X + 15 )
#define IMP_SKILL_TRAIT__LEFT_COLUMN_START_Y ( LAPTOP_SCREEN_WEB_UL_Y + 40 )
@@ -53,9 +47,10 @@ enum
#define IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS 38
-#define IMP_SKILL_TRAIT__SKILL_TRAIT_TO_START_RIGHT_COL 6
+//#define IMP_SKILL_TRAIT__SKILL_TRAIT_TO_START_RIGHT_COL 6
#define IMP_SKILL_TRAIT__NONE_BTN_LOC_X ( LAPTOP_SCREEN_UL_X + 136 )
+#define IMP_SKILL_TRAIT__NONE_BTN_LOC_Y ( LAPTOP_SCREEN_WEB_UL_Y + 306 ) // added this one - SANDRO
#define IMP_SKILL_TRAIT__TEXT_OFFSET_X 65
#define IMP_SKILL_TRAIT__TEXT_OFFSET_Y 12
@@ -73,14 +68,17 @@ enum
// Global Variables
//
//*******************************************************************
+BOOLEAN gfSkillTraitQuestions[ 20 ];
+BOOLEAN gfSkillTraitQuestions2[ 20 ];
+
BOOLEAN gfIST_Redraw=FALSE;
-BOOLEAN gfSkillTraitQuestions[ IMP_SKILL_TRAITS__NUMBER_SKILLS ];
-
// these are the buttons for the questions
-INT32 giIMPSkillTraitAnswerButton[ IMP_SKILL_TRAITS__NUMBER_SKILLS ];
-INT32 giIMPSkillTraitAnswerButtonImage[ IMP_SKILL_TRAITS__NUMBER_SKILLS ];
+INT32 giIMPSkillTraitAnswerButton[ 20 ];
+INT32 giIMPSkillTraitAnswerButton2[ 20 ];
+INT32 giIMPSkillTraitAnswerButtonImage[ 20 ];
+INT32 giIMPSkillTraitAnswerButtonImage2[ 20 ];
// this is the Done buttons
INT32 giIMPSkillTraitFinsihButton;
@@ -88,8 +86,7 @@ INT32 giIMPSkillTraitFinsihButtonImage;
//BOOLEAN gfSkillTraitButtonChanged=FALSE;
-#define IST__NUM_SELECTABLE_TRAITS 2
-INT8 gbLastSelectedTraits[ IST__NUM_SELECTABLE_TRAITS ];
+INT8 gbLastSelectedTraits[ 10 ];
//image handle
UINT32 guiIST_GreyGoldBox;
@@ -101,16 +98,23 @@ UINT32 guiIST_GreyGoldBox;
//*******************************************************************
void BtnIMPSkillTraitAnswerCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnIMPSkillTraitAnswerCallback2(GUI_BUTTON *btn,INT32 reason);
void BtnIMPSkillTraitFinishCallback(GUI_BUTTON *btn,INT32 reason);
void AddImpSkillTraitButtons();
void HandleSkillTraitButtonStates( );
-void HandleIMPSkillTraitAnswers( UINT32 uiSkillPressed, BOOLEAN fResetAllButtons );
+void HandleIMPSkillTraitAnswers( UINT32 uiSkillPressed, BOOLEAN fSecondTrait );
void IMPSkillTraitDisplaySkills();
-INT8 CountNumSkillStraitsSelected( BOOLEAN fIncludeNoneSkill );
BOOLEAN ShouldTraitBeSkipped( UINT32 uiTrait );
-void AddSelectedSkillsToSkillsList();
+//void AddSelectedSkillsToSkillsList(); // SANDRO - second declaration not needed
void HandleLastSelectedTraits( INT8 bNewTrait );
+INT8 GetLastSelectedSkill( void );
BOOLEAN CameBackToSpecialtiesPageButNotFinished();
+
+BOOLEAN DoesSkillHaveExpertLevel( UINT32 uiSkillTrait );
+
+MOUSE_REGION gMR_SkillTraitHelpTextRegions[IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS];
+
+void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel );
//ppp
//*******************************************************************
@@ -157,13 +161,66 @@ void EnterIMPSkillTrait( void )
if( iCurrentProfileMode != IMP__FINISH )
{
//Have the NONE trait initially selected
- gfSkillTraitQuestions[ IMP_SKILL_TRAITS__NONE ] = TRUE;
+ if( gGameOptions.fNewTraitSystem )
+ {
+ gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_MAJOR_NONE ] = TRUE;
+ gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MAJOR_NONE ] = TRUE;
+ }
+ else
+ {
+ gfSkillTraitQuestions[ IMP_SKILL_TRAITS__NONE ] = TRUE;
+ gfSkillTraitQuestions2[ IMP_SKILL_TRAITS__NONE ] = TRUE;
+ }
}
HandleSkillTraitButtonStates( );
+ // add regions for help texts
+ UINT16 usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X + 62;
+ UINT16 usPosY = IMP_SKILL_TRAIT__LEFT_COLUMN_START_Y + 8;
+ for( UINT32 uiCnt=0; uiCnt < (UINT8)( gGameOptions.fNewTraitSystem ? IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS : IMP_SKILL_TRAITS__NUMBER_SKILLS ); uiCnt++ )
+ {
+ if( ShouldTraitBeSkipped( uiCnt ) )
+ {
+ //if its the none button
+ if( uiCnt == ( gGameOptions.fNewTraitSystem ? (IMP_SKILL_TRAITS_NEW_MAJOR_NONE-1) : (IMP_SKILL_TRAITS__NONE-1) ) )
+ {
+ usPosX = IMP_SKILL_TRAIT__NONE_BTN_LOC_X + 62;
+ usPosY = IMP_SKILL_TRAIT__NONE_BTN_LOC_Y + 8;
+ }
+ continue;
+ }
+ MSYS_DefineRegion( &gMR_SkillTraitHelpTextRegions[uiCnt], ( usPosX ), ( usPosY ),
+ (usPosX + 156), ( usPosY + 17), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gMR_SkillTraitHelpTextRegions[uiCnt] );
+
+ //Determine the next x location
+ if( uiCnt < (UINT8)(gGameOptions.fNewTraitSystem ? 4 : 6) )
+ usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X + 62;
+ else
+ usPosX = IMP_SKILL_TRAIT__RIGHT_COLUMN_START_X + 62;
+
+ //Determine the next Y location
+ if( uiCnt == (gGameOptions.fNewTraitSystem ? 4 : 6) )
+ usPosY = IMP_SKILL_TRAIT__RIGHT_COLUMN_START_Y + 8;
+ else
+ {
+ if( gGameOptions.fNewTraitSystem )
+ usPosY += IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS + 5;
+ else
+ usPosY += IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS;
+ }
+ //if its the none button
+ if( uiCnt == (gGameOptions.fNewTraitSystem ? (IMP_SKILL_TRAITS_NEW_MAJOR_NONE-1) : (IMP_SKILL_TRAITS__NONE-1) ) )
+ {
+ usPosX = IMP_SKILL_TRAIT__NONE_BTN_LOC_X + 62;
+ usPosY = IMP_SKILL_TRAIT__NONE_BTN_LOC_Y + 8;
+ }
+ }
+
//reset last selecterd trait
- memset( gbLastSelectedTraits, -1, IST__NUM_SELECTABLE_TRAITS );
+ memset( gbLastSelectedTraits, -1, 10 );
}
@@ -183,7 +240,7 @@ void ExitIMPSkillTrait( void )
DeleteVideoObjectFromIndex( guiIST_GreyGoldBox );
//remove the skill buttons
- for(iCnt = 0; iCnt < IMP_SKILL_TRAITS__NUMBER_SKILLS; iCnt++)
+ for(iCnt = 0; iCnt < ( gGameOptions.fNewTraitSystem ? IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS : IMP_SKILL_TRAITS__NUMBER_SKILLS ); iCnt++)
{
//if there is a button allocated
if( giIMPSkillTraitAnswerButton[iCnt] != -1 )
@@ -193,8 +250,28 @@ void ExitIMPSkillTrait( void )
}
}
+ //remove the skill buttons
+ for(iCnt = 0; iCnt < ( gGameOptions.fNewTraitSystem ? IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS : IMP_SKILL_TRAITS__NUMBER_SKILLS ); iCnt++)
+ {
+ //if there is a button allocated
+ if( giIMPSkillTraitAnswerButton2[iCnt] != -1 )
+ {
+ RemoveButton(giIMPSkillTraitAnswerButton2[ iCnt ] );
+ UnloadButtonImage(giIMPSkillTraitAnswerButtonImage2[ iCnt ] );
+ }
+ }
+
RemoveButton( giIMPSkillTraitFinsihButton );
UnloadButtonImage( giIMPSkillTraitFinsihButtonImage );
+
+ // SANDRO - remove regions
+ for( iCnt=0; iCnt < ( gGameOptions.fNewTraitSystem ? IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS : IMP_SKILL_TRAITS__NUMBER_SKILLS); iCnt++ )
+ {
+ if( ShouldTraitBeSkipped( iCnt ) )
+ continue;
+
+ MSYS_RemoveRegion( &gMR_SkillTraitHelpTextRegions[iCnt] );
+ }
}
@@ -212,13 +289,30 @@ void HandleIMPSkillTrait( void )
void AddImpSkillTraitButtons()
{
INT32 iCnt = 0;
- UINT16 usPosX, usPosY;
+ INT32 iCntMax = 0;
+ INT8 iNumSkillsToStartRightColumn = 0;
+ UINT16 usPosX, usPosY, usSpaceBetweenButtons;
+
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ iCntMax = IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS;
+ iNumSkillsToStartRightColumn = 4;
+ usSpaceBetweenButtons = IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS + 5;
+ }
+ else
+ {
+ iCntMax = IMP_SKILL_TRAITS__NUMBER_SKILLS;
+ iNumSkillsToStartRightColumn = 6;
+ usSpaceBetweenButtons = IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ // FIRST COLUMN OF BUTTONS
usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X;
usPosY = IMP_SKILL_TRAIT__LEFT_COLUMN_START_Y;
-
- for(iCnt = 0; iCnt < IMP_SKILL_TRAITS__NUMBER_SKILLS; iCnt++)
+ for(iCnt = 0; iCnt < (iCntMax); iCnt++)
{
//reset
giIMPSkillTraitAnswerButton[iCnt] = -1;
@@ -232,18 +326,17 @@ void AddImpSkillTraitButtons()
//if the merc is a FEMALE, skip this skill cause there isnt any fenmal martial artists
if( ShouldTraitBeSkipped( iCnt ) )
{
- usPosY += IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS;
-
//if its the none button
- if( iCnt == IMP_SKILL_TRAITS__NONE-1 )
+ if( iCnt == iCntMax-2 )
{
usPosX = IMP_SKILL_TRAIT__NONE_BTN_LOC_X;
+ usPosY = IMP_SKILL_TRAIT__NONE_BTN_LOC_Y;
}
continue;
}
if( iCnt == 0 )
- giIMPSkillTraitAnswerButtonImage[ iCnt ] = LoadButtonImage( "LAPTOP\\button_6.sti", -1,0,-1,1,-1 );
+ giIMPSkillTraitAnswerButtonImage[ iCnt ] = LoadButtonImage( "LAPTOP\\button_9a.sti", -1,0,-1,1,-1 );
else
giIMPSkillTraitAnswerButtonImage[ iCnt ] = UseLoadedButtonImage( giIMPSkillTraitAnswerButtonImage[ 0 ], -1,0,-1,1,-1 );
@@ -259,21 +352,87 @@ void AddImpSkillTraitButtons()
//ButtonList[ giIMPSkillTraitAnswerButton[ iCnt ] ]->ubSoundSchemeID = 0; // - This would disable the sounds totally resulted to play no sound - SANDRO
//Determine the next x location
- if( iCnt < IMP_SKILL_TRAIT__SKILL_TRAIT_TO_START_RIGHT_COL )
+ if( iCnt < iNumSkillsToStartRightColumn )
usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X;
else
usPosX = IMP_SKILL_TRAIT__RIGHT_COLUMN_START_X;
//Determine the next Y location
- if( iCnt == IMP_SKILL_TRAIT__SKILL_TRAIT_TO_START_RIGHT_COL )
+ if( iCnt == iNumSkillsToStartRightColumn )
usPosY = IMP_SKILL_TRAIT__RIGHT_COLUMN_START_Y;
else
- usPosY += IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS;
+ usPosY += usSpaceBetweenButtons;
//if its the none button
- if( iCnt == IMP_SKILL_TRAITS__NONE-1 )
+ if( iCnt == iCntMax-2 )
{
usPosX = IMP_SKILL_TRAIT__NONE_BTN_LOC_X;
+ usPosY = IMP_SKILL_TRAIT__NONE_BTN_LOC_Y;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+ // SECOND COLUMN OF BUTTONS
+
+ usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X + 26;
+ usPosY = IMP_SKILL_TRAIT__LEFT_COLUMN_START_Y;
+
+ for(iCnt = 0; iCnt < (iCntMax); iCnt++)
+ {
+ //reset
+ giIMPSkillTraitAnswerButton2[iCnt] = -1;
+
+ //if we are not DONE and are just reviewing
+ if( iCurrentProfileMode != IMP__FINISH )
+ {
+ gfSkillTraitQuestions2[ iCnt ] = FALSE;
+ }
+
+ //if the merc is a FEMALE, skip this skill cause there isnt any fenmal martial artists
+ if( ShouldTraitBeSkipped( iCnt ) )
+ {
+ //if its the none button
+ if( iCnt == iCntMax-2 )
+ {
+ usPosX = IMP_SKILL_TRAIT__NONE_BTN_LOC_X + 26;
+ usPosY = IMP_SKILL_TRAIT__NONE_BTN_LOC_Y;
+ }
+ continue;
+ }
+
+ if( iCnt == 0 )
+ giIMPSkillTraitAnswerButtonImage2[ iCnt ] = LoadButtonImage( "LAPTOP\\button_9b.sti", -1,0,-1,1,-1 );
+ else
+ giIMPSkillTraitAnswerButtonImage2[ iCnt ] = UseLoadedButtonImage( giIMPSkillTraitAnswerButtonImage2[ 0 ], -1,0,-1,1,-1 );
+
+ giIMPSkillTraitAnswerButton2[iCnt] = QuickCreateButton( giIMPSkillTraitAnswerButtonImage2[ iCnt ], usPosX, usPosY,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 3,
+ MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnIMPSkillTraitAnswerCallback2);
+
+ //Set the button data
+ MSYS_SetBtnUserData( giIMPSkillTraitAnswerButton2[iCnt], 0, iCnt );
+ SetButtonCursor( giIMPSkillTraitAnswerButton2[iCnt], CURSOR_WWW);
+
+ //Get rid of playing the button sound, it will be handled here
+ //ButtonList[ giIMPSkillTraitAnswerButton[ iCnt ] ]->ubSoundSchemeID = 0; // - This would disable the sounds totally resulted to play no sound - SANDRO
+
+ //Determine the next x location
+ if( iCnt < iNumSkillsToStartRightColumn )
+ usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X + 26;
+ else
+ usPosX = IMP_SKILL_TRAIT__RIGHT_COLUMN_START_X + 26;
+
+ //Determine the next Y location
+ if( iCnt == iNumSkillsToStartRightColumn )
+ usPosY = IMP_SKILL_TRAIT__RIGHT_COLUMN_START_Y;
+ else
+ usPosY += usSpaceBetweenButtons;
+
+ //if its the none button
+ if( iCnt == iCntMax-2 )
+ {
+ usPosX = IMP_SKILL_TRAIT__NONE_BTN_LOC_X + 26;
+ usPosY = IMP_SKILL_TRAIT__NONE_BTN_LOC_Y;
}
}
}
@@ -295,9 +454,30 @@ void BtnIMPSkillTraitAnswerCallback(GUI_BUTTON *btn,INT32 reason)
}
}
-void HandleIMPSkillTraitAnswers( UINT32 uiSkillPressed, BOOLEAN fResetAllButtons )
+void BtnIMPSkillTraitAnswerCallback2(GUI_BUTTON *btn,INT32 reason)
{
- UINT32 uiCnt;
+ // btn callback for IMP personality quiz answer button
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+// btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ INT32 iSkillTrait = MSYS_GetBtnUserData( btn, 0 );
+
+ HandleIMPSkillTraitAnswers( iSkillTrait, TRUE );
+ }
+}
+
+void HandleIMPSkillTraitAnswers( UINT32 uiSkillPressed, BOOLEAN fSecondTrait )
+{
+ UINT32 uiCnt, uiCntMax;
+
+ if ( gGameOptions.fNewTraitSystem )
+ uiCntMax = IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS;
+ else
+ uiCntMax = IMP_SKILL_TRAITS__NUMBER_SKILLS;
//if we are DONE and are just reviewing
if( iCurrentProfileMode == IMP__FINISH )
@@ -305,78 +485,240 @@ void HandleIMPSkillTraitAnswers( UINT32 uiSkillPressed, BOOLEAN fResetAllButtons
return;
}
- //if we are to reset all the buttons
- if( fResetAllButtons )
- {
- //loop through all the skill and reset them
- for( uiCnt=0; uiCnt IMP_SKILL_TRAITS__NUMBER_SKILLS )
+ if( uiSkillPressed > uiCntMax )
{
Assert( 0 );
return;
}
-
- //if its allready set
- if( gfSkillTraitQuestions[ uiSkillPressed ] )
+ if( !fSecondTrait )
{
- //dont need to do anything
- return;
- }
+ //if its allready set
+ if( gfSkillTraitQuestions[ uiSkillPressed ] )
+ {
+ gfSkillTraitQuestions[ uiSkillPressed ] = FALSE;
- HandleLastSelectedTraits( (INT8)uiSkillPressed );
+ BOOLEAN fNoSkillSelected = TRUE;
+ for ( uiCnt=0; uiCnt<(uiCntMax-1); uiCnt++ )
+ {
+ if ( gfSkillTraitQuestions[ uiCnt ] == TRUE )
+ fNoSkillSelected = FALSE;
+ }
+ if ( fNoSkillSelected )
+ {
+ // select NONE button
+ gfSkillTraitQuestions[ uiCntMax-1 ] = TRUE;
+ }
+ }
+ // if cannot have expert level of skill, don't continue
+ else if ( gfSkillTraitQuestions2[ uiSkillPressed ] && !DoesSkillHaveExpertLevel( uiSkillPressed ) )
+ {
+ //dont need to do anything
+ return;
+ }
+ else
+ {
+ // if the other trait has not been set yet, we rather set it now,
+ // instead of deselecting the already set one
+ if( gfSkillTraitQuestions2[ uiCntMax-1 ] == TRUE && gfSkillTraitQuestions[ uiCntMax-1 ] == FALSE && (uiSkillPressed != (uiCntMax-1)) )
+ {
+ // Unselect NONE button
+ gfSkillTraitQuestions2[ uiCntMax-1 ] = FALSE;
+ //Set the skill
+ gfSkillTraitQuestions2[ uiSkillPressed ] = TRUE;
+ }
+ else
+ {
+ if ( CountNumSkillTraitsSelected( FALSE ) < gSkillTraitValues.ubNumberOfMajorTraitsAllowed && CountNumSkillTraitsSelected( FALSE ) < gSkillTraitValues.ubMaxNumberOfTraits )
+ {
+ // we can select next one, simply do so
+ gfSkillTraitQuestions[ uiSkillPressed ] = TRUE;
+ // Unselect NONE button if necessary
+ gfSkillTraitQuestions[ uiCntMax-1 ] = FALSE;
-/*
- //if there are already 2 skills selected, and we are trying to PRESS a new button ( skill isnt currently set )
- if( CountNumSkillStraitsSelected() == 2 &&
- !gfSkillTraitQuestions[ uiSkillPressed ] &&
- uiSkillPressed != IMP_SKILL_TRAITS__NONE )
- {
- //if we have to, unselect an existing trait
+ HandleLastSelectedTraits( (INT8)uiSkillPressed );
+ }
+ else
+ {
+ if ( gSkillTraitValues.ubNumberOfMajorTraitsAllowed == 2 )
+ {
+ //loop through all the skill and reset them
+ for( uiCnt=0; uiCnt= (uiCntMax-2) )
+ {
+ for( uiCnt=0; uiCnt<(uiCntMax-1); uiCnt++ )
+ {
+ if ( gfSkillTraitQuestions2[ uiCnt ] == TRUE )
+ {
+ gfSkillTraitQuestions2[ uiCnt ] = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ //Set the skill
+ gfSkillTraitQuestions[ uiSkillPressed ] = TRUE;
- //play the diosabld sound
-// PlayButtonSound( giIMPSkillTraitAnswerButton[ uiSkillPressed ], BUTTON_SOUND_DISABLED_CLICK );
-
- //dont select a new one
-// return;
- }
-*/
-
- //Set the skill
-// gfSkillTraitQuestions[ uiSkillPressed ] = !gfSkillTraitQuestions[ uiSkillPressed ];
- gfSkillTraitQuestions[ uiSkillPressed ] = TRUE;
-
- //if the NONE trait was selected, clear the rest of the buttons
- if( uiSkillPressed == IMP_SKILL_TRAITS__NONE )
- {
- //reset all the traits
- HandleIMPSkillTraitAnswers( 0, TRUE );
-
- gfSkillTraitQuestions[ IMP_SKILL_TRAITS__NONE ] = TRUE;
- }
-
-
- //make sure the none skill is NOT selected if we select anything else
- if( uiSkillPressed != IMP_SKILL_TRAITS__NONE )
- {
- gfSkillTraitQuestions[ IMP_SKILL_TRAITS__NONE ] = FALSE;
- }
-
- //Play the button sound
- if( gfSkillTraitQuestions[ uiSkillPressed ] )
- {
- PlayButtonSound( giIMPSkillTraitAnswerButton[ uiSkillPressed ], BUTTON_SOUND_CLICKED_ON );
+ HandleLastSelectedTraits( (INT8)uiSkillPressed );
+ }
+ }
+ }
+
+ //Play the button sound
+ if( gfSkillTraitQuestions[ uiSkillPressed ] )
+ {
+ PlayButtonSound( giIMPSkillTraitAnswerButton[ uiSkillPressed ], BUTTON_SOUND_CLICKED_ON );
+ }
+ else
+ {
+ PlayButtonSound( giIMPSkillTraitAnswerButton[ uiSkillPressed ], BUTTON_SOUND_CLICKED_OFF );
+ }
}
else
{
- PlayButtonSound( giIMPSkillTraitAnswerButton[ uiSkillPressed ], BUTTON_SOUND_CLICKED_OFF );
+ //if its allready set
+ if( gfSkillTraitQuestions2[ uiSkillPressed ] )
+ {
+ gfSkillTraitQuestions2[ uiSkillPressed ] = FALSE;
+
+ BOOLEAN fNoSkillSelected = TRUE;
+ for ( uiCnt=0; uiCnt<(uiCntMax-1); uiCnt++ )
+ {
+ if ( gfSkillTraitQuestions2[ uiCnt ] == TRUE )
+ fNoSkillSelected = FALSE;
+ }
+ if ( fNoSkillSelected )
+ {
+ // select NONE button
+ gfSkillTraitQuestions2[ uiCntMax-1 ] = TRUE;
+ }
+ }
+ // if cannot have expert level of skill, don't continue
+ else if ( gfSkillTraitQuestions[ uiSkillPressed ] && !DoesSkillHaveExpertLevel( uiSkillPressed ) )
+ {
+ //dont need to do anything
+ return;
+ }
+ else
+ {
+ // if the other trait has not been set yet, we rather set it now,
+ // instead of deselecting the already set one
+ if( gfSkillTraitQuestions[ uiCntMax-1 ] == TRUE && gfSkillTraitQuestions2[ uiCntMax-1 ] == FALSE && (uiSkillPressed != (uiCntMax-1)) )
+ {
+ // Unselect NONE button
+ gfSkillTraitQuestions[ uiCntMax-1 ] = FALSE;
+ //Set the skill
+ gfSkillTraitQuestions[ uiSkillPressed ] = TRUE;
+ }
+ else
+ {
+ if ( CountNumSkillTraitsSelected( FALSE ) < gSkillTraitValues.ubNumberOfMajorTraitsAllowed && CountNumSkillTraitsSelected( FALSE ) < gSkillTraitValues.ubMaxNumberOfTraits )
+ {
+ // we can select next one, simply do so
+ gfSkillTraitQuestions2[ uiSkillPressed ] = TRUE;
+ // Unselect NONE button if necessary
+ gfSkillTraitQuestions2[ uiCntMax-1 ] = FALSE;
+
+ HandleLastSelectedTraits( (INT8)uiSkillPressed );
+ }
+ else
+ {
+ if ( gSkillTraitValues.ubNumberOfMajorTraitsAllowed == 2 )
+ {
+ //loop through all the skill and reset them
+ for( uiCnt=0; uiCnt= (uiCntMax-2) )
+ {
+ for( uiCnt=0; uiCnt<(uiCntMax-1); uiCnt++ )
+ {
+ if ( gfSkillTraitQuestions[ uiCnt ] == TRUE )
+ {
+ gfSkillTraitQuestions[ uiCnt ] = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ //Set the skill
+ gfSkillTraitQuestions2[ uiSkillPressed ] = TRUE;
+
+ HandleLastSelectedTraits( (INT8)uiSkillPressed );
+ }
+ }
+ }
+
+ //Play the button sound
+ if( gfSkillTraitQuestions2[ uiSkillPressed ] )
+ {
+ PlayButtonSound( giIMPSkillTraitAnswerButton2[ uiSkillPressed ], BUTTON_SOUND_CLICKED_ON );
+ }
+ else
+ {
+ PlayButtonSound( giIMPSkillTraitAnswerButton2[ uiSkillPressed ], BUTTON_SOUND_CLICKED_OFF );
+ }
}
//update buttons
@@ -386,28 +728,30 @@ void HandleIMPSkillTraitAnswers( UINT32 uiSkillPressed, BOOLEAN fResetAllButtons
gfIST_Redraw = TRUE;
}
-INT8 CountNumSkillStraitsSelected( BOOLEAN fIncludeNoneSkill )
+INT8 CountNumSkillTraitsSelected( BOOLEAN fIncludeNoneSkill )
{
- UINT32 uiCnt;
+ UINT32 uiCnt, uiCntMax;
INT8 iNumberSkills=0;
- UINT32 uiUpperLimit;
- if( fIncludeNoneSkill )
- {
- uiUpperLimit = IMP_SKILL_TRAITS__NUMBER_SKILLS;
- }
+ if ( gGameOptions.fNewTraitSystem )
+ uiCntMax = IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS;
else
- {
- uiUpperLimit = IMP_SKILL_TRAITS__NONE;
- }
+ uiCntMax = IMP_SKILL_TRAITS__NUMBER_SKILLS;
- for( uiCnt=0; uiCnt < uiUpperLimit; uiCnt++ )
+ for( uiCnt=0; uiCnt < uiCntMax; uiCnt++ )
{
+ if( !fIncludeNoneSkill && (uiCnt == (uiCntMax-1)) )
+ continue;
+
//if the skill is selected ( ie depressed )
if( gfSkillTraitQuestions[ uiCnt ] )
{
iNumberSkills++;
}
+ if( gfSkillTraitQuestions2[ uiCnt ] )
+ {
+ iNumberSkills++;
+ }
}
return( iNumberSkills );
@@ -416,9 +760,9 @@ INT8 CountNumSkillStraitsSelected( BOOLEAN fIncludeNoneSkill )
void HandleSkillTraitButtonStates( )
{
- UINT32 uiCnt;
+ INT32 uiCnt;
- for( uiCnt=0; uiCntuiFlags &= ~BUTTON_CLICKED_ON;
}
+
+ if( gfSkillTraitQuestions2[ uiCnt ] )
+ {
+ ButtonList[ giIMPSkillTraitAnswerButton2[ uiCnt ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ }
+ else
+ {
+ ButtonList[ giIMPSkillTraitAnswerButton2[ uiCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ }
}
}
void IMPSkillTraitDisplaySkills()
{
- UINT32 uiCnt;
+ UINT32 uiCnt, uiCntMax;
UINT16 usPosX, usPosY;
UINT16 usBoxPosX, usBoxPosY;
+ INT16 usSpaceBetweenButtons;
+ UINT8 uiNumSkillsToStartRightColumn;
HVOBJECT hImageHandle;
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ uiCntMax = IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS;
+ uiNumSkillsToStartRightColumn = 4;
+ usSpaceBetweenButtons = IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS + 5;
- //Display the title
- DrawTextToScreen( gzIMPSkillTraitsText[ IMP_SKILL_TRAIT__TITLE_TEXT ], IMP_SKILL_TRAIT__TITLE_X, IMP_SKILL_TRAIT__TITLE_Y, IMP_SKILL_TRAIT__TITLE_WIDTH, IMP_SKILL_TRAIT__TITLE_FONT, IMP_SKILL_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ //Display the title
+ DrawTextToScreen( gzIMPSkillTraitsTextNewMajor[ IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS ], IMP_SKILL_TRAIT__TITLE_X, IMP_SKILL_TRAIT__TITLE_Y, IMP_SKILL_TRAIT__TITLE_WIDTH, IMP_SKILL_TRAIT__TITLE_FONT, IMP_SKILL_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
+ else
+ {
+ uiCntMax = IMP_SKILL_TRAITS__NUMBER_SKILLS;
+ uiNumSkillsToStartRightColumn = 6;
+ usSpaceBetweenButtons = IMP_SKILL_TRAIT__SPACE_BTN_BUTTONS;
+
+ //Display the title
+ DrawTextToScreen( gzIMPSkillTraitsText[ IMP_SKILL_TRAITS__NUMBER_SKILLS ], IMP_SKILL_TRAIT__TITLE_X, IMP_SKILL_TRAIT__TITLE_Y, IMP_SKILL_TRAIT__TITLE_WIDTH, IMP_SKILL_TRAIT__TITLE_FONT, IMP_SKILL_TRAIT__COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ }
// Stats
GetVideoObject(&hImageHandle, guiIST_GreyGoldBox );
@@ -455,7 +825,7 @@ void IMPSkillTraitDisplaySkills()
usPosX = IMP_SKILL_TRAIT__LEFT_COLUMN_START_X + IMP_SKILL_TRAIT__TEXT_OFFSET_X;
usPosY = IMP_SKILL_TRAIT__LEFT_COLUMN_START_Y + IMP_SKILL_TRAIT__TEXT_OFFSET_Y;
- for( uiCnt=0; uiCntuiFlags|=(BUTTON_CLICKED_ON);
- //if we are just reviewing the page
- if( iCurrentProfileMode == IMP__FINISH )
+ if( gGameOptions.fNewTraitSystem )
{
- //go back tot he done screen
- iCurrentImpPage = IMP_FINISH;
+ iCurrentImpPage = IMP_MINOR_TRAITS_PAGE;
+ fButtonPendingFlag = TRUE;
}
else
{
- iCurrentImpPage = IMP_MAIN_PAGE;
-
- if( CameBackToSpecialtiesPageButNotFinished() )
+ //if we are just reviewing the page
+ if( iCurrentProfileMode == IMP__FINISH )
{
+ //go back tot he done screen
+ iCurrentImpPage = IMP_FINISH;
}
else
{
- //We are finished on this page
- iCurrentProfileMode = IMP__ATTRIBUTES;
- }
+ iCurrentImpPage = IMP_MAIN_PAGE;
+
+ if( CameBackToSpecialtiesPageButNotFinished() )
+ {
+ }
+ else
+ {
+ //We are finished on this page
+ iCurrentProfileMode = IMP__ATTRIBUTES;
+ }
+ }
}
}
}
-
BOOLEAN CameBackToSpecialtiesPageButNotFinished()
{
//if we are in a page that comes after this one
@@ -554,131 +952,308 @@ BOOLEAN CameBackToSpecialtiesPageButNotFinished()
}
}
-
-
-
-
-INT8 DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection()
+INT32 DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection()
{
- INT8 bExtraPoints=10;
- INT8 bNumSkills=0;
+ INT32 iExtraPoints=0; // set to zero - SANDRO
+ INT32 bNumSkills=0;
//Count the number of skills selected
- bNumSkills = CountNumSkillStraitsSelected( FALSE );
+ bNumSkills = CountNumSkillTraitsSelected( FALSE );
- //if there NONE selected
- if( bNumSkills == 0 )
+ // Externilized bonus for not taking skills - SANDRO
+ if( gGameOptions.fNewTraitSystem )
{
- // Externilized bonus for not taking skills - SANDRO
- bExtraPoints = 2 * (gGameExternalOptions.iBonusPointsPerSkillNotTaken);
- }
+ // add selected minor traits
+ bNumSkills += CountNumMinorTraitsSelected( FALSE );
- //if there is 1 trait selected
- else if( bNumSkills == 1 )
- {
- //if the trait is not the ones you cant be expert in )
- if( gfSkillTraitQuestions[ IMP_SKILL_TRAITS__ELECTRONICS ] ||
- gfSkillTraitQuestions[ IMP_SKILL_TRAITS__AMBIDEXTROUS ] ) // Actually camo skill can be achived at expert level, although it does nothing now - SANDRO
- // || gfSkillTraitQuestions[ IMP_SKILL_TRAITS__CAMO ] )
- {
- // Externilized bonus for not taking skills - SANDRO
- bExtraPoints = gGameExternalOptions.iBonusPointsPerSkillNotTaken;
- }
- else
- {
- bExtraPoints = 0;
- }
+ iExtraPoints = (max( 0, 3 - bNumSkills)) * (gGameExternalOptions.iBonusPointsPerSkillNotTaken);
}
-
- //else both traits selected
else
{
- bExtraPoints = 0;
+ iExtraPoints = (max( 0, 2 - bNumSkills)) * (gGameExternalOptions.iBonusPointsPerSkillNotTaken);
}
- return( bExtraPoints );
+ return( iExtraPoints );
}
BOOLEAN ShouldTraitBeSkipped( UINT32 uiTrait )
{
- // added a check to not offer martial arts to big mercs - SANDRO
- if( uiTrait == IMP_SKILL_TRAITS__MARTIAL_ARTS && (!fCharacterIsMale || bBigBodySelected()) )
- return( TRUE );
- else
+ // there are no traits discriminating any gender in new trait system
+ if( gGameOptions.fNewTraitSystem )
+ {
return( FALSE );
+ }
+ else
+ {
+ if( uiTrait == IMP_SKILL_TRAITS__MARTIAL_ARTS && (!fCharacterIsMale || bBigBodySelected()) )
+ return( TRUE );
+ else
+ return( FALSE );
+ }
}
+BOOLEAN DoesSkillHaveExpertLevel( UINT32 uiSkillTrait )
+{
+ if( gGameOptions.fNewTraitSystem )
+ {
+ return( TRUE );
+ }
+ else
+ {
+ if (uiSkillTrait == IMP_SKILL_TRAITS__ELECTRONICS ||
+ uiSkillTrait == IMP_SKILL_TRAITS__AMBIDEXTROUS ||
+ uiSkillTrait == IMP_SKILL_TRAITS__CAMO )
+ {
+ return( FALSE );
+ }
+ else
+ {
+ return( TRUE );
+ }
+ }
+ return( TRUE );
+}
void AddSelectedSkillsToSkillsList()
{
- UINT32 uiCnt;
+ INT32 uiCnt;
//loop through all the buttons and reset them
- for( uiCnt=0; uiCnt=0; iCnt-- )
+ {
+ if ( gbLastSelectedTraits[ iCnt ] > 0 )
+ {
+ gbLastSelectedTraits[ iCnt ] = 0;
+ break;
+ }
+ }
+
}
-
else
{
- //unselect old trait
- gfSkillTraitQuestions[ gbLastSelectedTraits[ 1 ] ] = FALSE;
-
- gbLastSelectedTraits[ 1 ] = gbLastSelectedTraits[ 0 ];
+ for( iCnt=0; iCnt<9; iCnt++ )
+ {
+ gbLastSelectedTraits[ (iCnt + 1) ] = gbLastSelectedTraits[ iCnt ];
+ }
gbLastSelectedTraits[ 0 ] = bNewTrait;
}
}
+
+INT8 GetLastSelectedSkill( void )
+{
+ INT16 iCnt;
+
+ for( iCnt=9; iCnt>=0; iCnt-- )
+ {
+ if ( gbLastSelectedTraits[ iCnt ] > 0 )
+ {
+ return ( gbLastSelectedTraits[ iCnt ] );
+ break;
+ }
+ }
+ return ( 0 );
+}
+
+INT32 StrengthRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ return (60);
+ else
+ return (45);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ return (55);
+ else
+ return (40);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ return (45);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ return (40);
+ }
+
+ return(0);
+}
+INT32 AgilityRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 DexterityRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 HealthRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ return (60);
+ else
+ return (45);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ return (45);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 LeadershipRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ return (50);
+ else
+ return (35);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ return (35);
+ }
+
+ return(0);
+}
+INT32 WisdomRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
+ return (75);
+ else
+ return (60);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ return (65);
+ else
+ return (50);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_SQUADLEADER ])
+ {
+ return (60);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ {
+ return (50);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 MarksmanshipRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ return (80);
+ else
+ return (65);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ return (70);
+ else
+ return (55);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_PROF_SNIPER ])
+ {
+ return (65);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_RANGER ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_GUNSLINGER ])
+ {
+ return (55);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 MechanicalRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 MedicalRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_DOCTOR ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+INT32 ExplosivesRequiredDueToMajorSkills( void )
+{
+ // Only for new trait system
+ if (!gGameOptions.fNewTraitSystem)
+ {
+ return (0);
+ }
+
+ // Check first skill trait (plus second for double trait)
+ if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ return (60);
+ else
+ return (45);
+ }
+ else if (gfSkillTraitQuestions[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ return (60);
+ else
+ return (45);
+ }
+ // Check the second skill trait
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS ])
+ {
+ return (45);
+ }
+ else if (gfSkillTraitQuestions2[ IMP_SKILL_TRAITS_NEW_TECHNICIAN ])
+ {
+ return (45);
+ }
+
+ return(0);
+}
+
+void AssignSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel )
+{
+ CHAR16 apStr[ 5000 ];
+ CHAR16 atStr[ 1500 ];
+
+ if( gGameOptions.fNewTraitSystem )
+ {
+ switch( ubTraitNumber )
+ {
+ case IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubAWBonusCtHAssaultRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[0], ( gSkillTraitValues.ubAWBonusCtHAssaultRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWBonusCtHSMGs != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[1], ( gSkillTraitValues.ubAWBonusCtHSMGs * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWBonusCtHLMGs != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[2], ( gSkillTraitValues.ubAWBonusCtHLMGs * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWFiringSpeedBonusLMGs != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[3], ( gSkillTraitValues.ubAWFiringSpeedBonusLMGs * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWPercentReadyLMGReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[4], ( gSkillTraitValues.ubAWPercentReadyLMGReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWAutoFirePenaltyReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[5], ( gSkillTraitValues.ubAWAutoFirePenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWUnwantedBulletsReduction > 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[6]);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[0], ( gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWRocketLaunchersAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[1], ( gSkillTraitValues.ubHWRocketLaunchersAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWBonusCtHGrenadeLaunchers != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[2], ( gSkillTraitValues.ubHWBonusCtHGrenadeLaunchers * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWBonusCtHRocketLaunchers != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[3], ( gSkillTraitValues.ubHWBonusCtHRocketLaunchers * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWMortarAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[4], ( gSkillTraitValues.ubHWMortarAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWMortarCtHPenaltyReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[5], ( gSkillTraitValues.ubHWMortarCtHPenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWDamageTanksBonusPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[6], ( gSkillTraitValues.ubHWDamageTanksBonusPercent * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWDamageBonusPercentForHW != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[7], ( gSkillTraitValues.ubHWDamageBonusPercentForHW * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_PROF_SNIPER:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSNBonusCtHRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[0], ( gSkillTraitValues.ubSNBonusCtHRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNBonusCtHSniperRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[1], ( gSkillTraitValues.ubSNBonusCtHSniperRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNEffRangeToTargetReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[2], ( gSkillTraitValues.ubSNEffRangeToTargetReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNAimingBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[3], ( gSkillTraitValues.ubSNAimingBonusPerClick * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNDamageBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[4], ( gSkillTraitValues.ubSNDamageBonusPerClick * (fExpertLevel ? 2 : 1)), L"%");
+ if( gSkillTraitValues.ubSNDamageBonusFromNumClicks == 0)
+ {
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsSniper[5] );
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsSniper[6] );
+ }
+ else if( gSkillTraitValues.ubSNDamageBonusFromNumClicks == 1 )
+ {
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsSniper[6] );
+ }
+ else
+ {
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsSniper[6] );
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsSniper[gSkillTraitValues.ubSNDamageBonusFromNumClicks + 4] );
+ }
+ wcscat( atStr, L"\n" );
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNChamberRoundAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[14], ( gSkillTraitValues.ubSNChamberRoundAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNAimClicksAdded != 0 )
+ {
+ if( gSkillTraitValues.ubSNAimClicksAdded == 1 && !fExpertLevel)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[15]);
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[16], ( gSkillTraitValues.ubSNAimClicksAdded * (fExpertLevel ? 2 : 1)));
+
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_RANGER:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubRABonusCtHRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[0], ( gSkillTraitValues.ubRABonusCtHRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRABonusCtHShotguns != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[1], ( gSkillTraitValues.ubRABonusCtHShotguns * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAPumpShotgunsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[2], ( gSkillTraitValues.ubRAPumpShotgunsAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[3], ( gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[4], ( gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRABreathForTravellingReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[5], ( gSkillTraitValues.ubRABreathForTravellingReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAWeatherPenaltiesReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[6], ( gSkillTraitValues.ubRAWeatherPenaltiesReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ // if( gSkillTraitValues.ubRACamoEffectivenessBonus != 0 )
+ // {
+ // swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[7], ( gSkillTraitValues.ubRACamoEffectivenessBonus * (fExpertLevel ? 2 : 1)), L"%");
+ // wcscat( apStr, atStr );
+ // }
+ if( gSkillTraitValues.ubRACamoWornountSpeedReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[8], ( gSkillTraitValues.ubRACamoWornountSpeedReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_GUNSLINGER:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubGSFiringSpeedBonusPistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[0], ( gSkillTraitValues.ubGSFiringSpeedBonusPistols * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSEffectiveRangeBonusPistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[1], ( gSkillTraitValues.ubGSEffectiveRangeBonusPistols * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSBonusCtHPistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[2], ( gSkillTraitValues.ubGSBonusCtHPistols * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSBonusCtHMachinePistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[3], ( gSkillTraitValues.ubGSBonusCtHMachinePistols * (fExpertLevel ? 2 : 1)), L"%");
+ if( gSkillTraitValues.ubGSCtHMPExcludeAuto )
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsGunslinger[4] );
+ wcscat( atStr, L"\n");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSAimingBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[5], ( gSkillTraitValues.ubGSAimingBonusPerClick * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSPercentReadyPistolsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[6], ( gSkillTraitValues.ubGSPercentReadyPistolsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSRealoadSpeedHandgunsBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[7], ( gSkillTraitValues.ubGSRealoadSpeedHandgunsBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSAimClicksAdded != 0 )
+ {
+ if( gSkillTraitValues.ubGSAimClicksAdded == 1 && !fExpertLevel )
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[8], ( gSkillTraitValues.ubGSAimClicksAdded * (fExpertLevel ? 2 : 1)));
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[9], ( gSkillTraitValues.ubGSAimClicksAdded * (fExpertLevel ? 2 : 1)));
+
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubMAPunchAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[0], ( gSkillTraitValues.ubMAPunchAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusCtHBareHands != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[1], ( gSkillTraitValues.ubMABonusCtHBareHands * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusCtHBrassKnuckles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[2], ( gSkillTraitValues.ubMABonusCtHBrassKnuckles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusDamageHandToHand != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[3], ( gSkillTraitValues.ubMABonusDamageHandToHand * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusBreathDamageHandToHand != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[4], ( gSkillTraitValues.ubMABonusBreathDamageHandToHand * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usMALostBreathRegainPenalty != 0 )
+ {
+ if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 25)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[5]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 50)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[6]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 100)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[7]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 200)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[8]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 400)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[9]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 700)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[10]);
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[11]);
+
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usMAAimedPunchDamageBonus != 0 )
+ {
+ if (!fCharacterIsMale || bBigBodySelected() || (gSkillTraitValues.fPermitExtraAnimationsOnlyToMA && (!gfSkillTraitQuestions[ubTraitNumber] || !gfSkillTraitQuestions2[ubTraitNumber])))
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[12], ( gSkillTraitValues.usMAAimedPunchDamageBonus * (fExpertLevel ? 2 : 1)), L"%");
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[13], ( gSkillTraitValues.usMAAimedPunchDamageBonus * (fExpertLevel ? 2 : 1)), L"%");
+
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAChanceToDodgeHtH != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[14], ( gSkillTraitValues.ubMAChanceToDodgeHtH * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAOnTopCTDHtHBareHanded != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[15], ( gSkillTraitValues.ubMAOnTopCTDHtHBareHanded * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles == gSkillTraitValues.ubMAOnTopCTDHtHBareHanded )
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsMartialArts[16] );
+ else if( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles > 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[17], ( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ wcscat( apStr, L"\n" );
+ }
+ else if( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[18], ( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAChanceToDodgeMelee != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[19], ( gSkillTraitValues.ubMAChanceToDodgeMelee * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAReducedAPsToSteal != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[20], ( gSkillTraitValues.ubMAReducedAPsToSteal * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAAPsChangeStanceReduction != 0 && ( gSkillTraitValues.ubMAAPsChangeStanceReduction == gSkillTraitValues.ubMAApsTurnAroundReduction == gSkillTraitValues.ubMAAPsClimbOrJumpReduction ))
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[21], ( gSkillTraitValues.ubMAAPsChangeStanceReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ else
+ {
+ if( gSkillTraitValues.ubMAAPsChangeStanceReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[22], ( gSkillTraitValues.ubMAAPsChangeStanceReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAApsTurnAroundReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[23], ( gSkillTraitValues.ubMAApsTurnAroundReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAAPsClimbOrJumpReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[24], ( gSkillTraitValues.ubMAAPsClimbOrJumpReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ }
+ if( gSkillTraitValues.ubMAChanceToCkickDoors != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[25], ( gSkillTraitValues.ubMAChanceToCkickDoors * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if (fCharacterIsMale && !bBigBodySelected() &&
+ ((gSkillTraitValues.fPermitExtraAnimationsOnlyToMA && fExpertLevel) ||
+ !gSkillTraitValues.fPermitExtraAnimationsOnlyToMA ))
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[26]);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_SQUADLEADER:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSLBonusAPsPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[0], ( gSkillTraitValues.ubSLBonusAPsPercent * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLEffectiveLevelInRadius != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[1], ( gSkillTraitValues.ubSLEffectiveLevelInRadius * (fExpertLevel ? 2 : 1)), (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLEffectiveLevelAsStandby != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[2], ( gSkillTraitValues.ubSLEffectiveLevelAsStandby * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLOverallSuppresionBonusPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[3], ( gSkillTraitValues.ubSLOverallSuppresionBonusPercent * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLMoraleGainBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[4], ( gSkillTraitValues.ubSLMoraleGainBonus * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLMoraleLossReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[5], ( gSkillTraitValues.ubSLMoraleLossReduction * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[6], gSkillTraitValues.usSLRadiusNormal);
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.usSLRadiusExtendedEar > gSkillTraitValues.usSLRadiusNormal )
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[7], gSkillTraitValues.usSLRadiusExtendedEar);
+
+ wcscat( apStr, atStr );
+ wcscat( apStr, L"\n" );
+
+ if( gSkillTraitValues.ubSLMaxBonuses > 1 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[8], gSkillTraitValues.ubSLMaxBonuses ) ;
+ wcscat( apStr, atStr );
+ }
+
+ if( gSkillTraitValues.ubSLFearResistance != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[9], ( gSkillTraitValues.ubSLFearResistance * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLDeathMoralelossMultiplier != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[10], (1 + ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * (fExpertLevel ? 2 : 1))), (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_TECHNICIAN:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.usTERepairSpeedBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[0], ( gSkillTraitValues.usTERepairSpeedBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usTELockpickingBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[1], ( gSkillTraitValues.usTELockpickingBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usTEDisarmElTrapBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[2], ( gSkillTraitValues.usTEDisarmElTrapBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usTEAttachingItemsBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[3], ( gSkillTraitValues.usTEAttachingItemsBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTEUnjamGunBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[4], ( gSkillTraitValues.ubTEUnjamGunBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTERepairElectronicsPenaltyReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[5], ( gSkillTraitValues.ubTERepairElectronicsPenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTEChanceToDetectTrapsBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[6], ( gSkillTraitValues.ubTEChanceToDetectTrapsBonus * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTECtHControlledRobotBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[7], ( gSkillTraitValues.ubTECtHControlledRobotBonus * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 2 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ else if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 1 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzIMPSkillTraitsTextNewMajor[ubTraitNumber + 11] : gzIMPSkillTraitsTextNewMajor[ubTraitNumber]));
+ wcscat( apStr, atStr );
+
+ if( gSkillTraitValues.ubTERepairRobotPenaltyReduction != 0 && fExpertLevel)
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[9], ( gSkillTraitValues.ubTERepairRobotPenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_DOCTOR:
+ {
+ BOOLEAN fCanSurgery = FALSE;
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubDONumberTraitsNeededForSurgery != 0 && ((gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop) > 0))
+ {
+ if( gSkillTraitValues.ubDONumberTraitsNeededForSurgery <= (fExpertLevel ? 2 : 1))
+ {
+ fCanSurgery = TRUE;
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[0]);
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[1], (gSkillTraitValues.ubDOSurgeryHealPercentBase + ( gSkillTraitValues.ubDOSurgeryHealPercentOnTop * (fExpertLevel ? 2 : 1))), L"%");
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.usDOSurgeryMedBagConsumption >= 60 )
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsDoctor[2] );
+
+ wcscat( apStr, L"\n" );
+ }
+ }
+ if( (gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop) > 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[3]);
+ wcscat( apStr, atStr );
+ if( fCanSurgery )
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsDoctor[4] );
+
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsDoctor[5] );
+ }
+ if( gSkillTraitValues.usDODoctorAssignmentBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[6], ( gSkillTraitValues.usDODoctorAssignmentBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDOBandagingSpeedPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[7], ( gSkillTraitValues.ubDOBandagingSpeedPercent * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDONaturalRegenBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[8], ( gSkillTraitValues.ubDONaturalRegenBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.ubDOMaxRegenBonuses > 1 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[9], gSkillTraitValues.ubDOMaxRegenBonuses ) ;
+ wcscat( apStr, atStr );
+ }
+ wcscat( apStr, L"\n" );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS_NEW_MAJOR_NONE:
+ {
+ swprintf( apStr, gzIMPMajorTraitsHelpTextsNone[0] );
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch( ubTraitNumber )
+ {
+ case IMP_SKILL_TRAITS__LOCKPICK:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[LOCKPICKING_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[0], ( gbSkillTraitBonus[LOCKPICKING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__HAND_2_HAND:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[HANDTOHAND_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[1], ( gbSkillTraitBonus[HANDTOHAND_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[2], ( 3 * gbSkillTraitBonus[HANDTOHAND_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[3], ( gbSkillTraitBonus[HANDTOHAND_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__ELECTRONICS:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[4] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__NIGHT_OPS:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[5], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[6], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[7], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[8], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[9], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__THROWING:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[THROWING_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[10], ( gbSkillTraitBonus[THROWING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[11], ( gbSkillTraitBonus[THROWING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[12], ( 10 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__TEACHING:
+ {
+ swprintf( apStr, L"" );
+ if( gGameExternalOptions.ubTeachBonusToTrain != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[13], ( gGameExternalOptions.ubTeachBonusToTrain * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( (gGameExternalOptions.usTeacherTraitEffectOnLeadership - 100) > 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[14], ( (gGameExternalOptions.usTeacherTraitEffectOnLeadership - 100) * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__HEAVY_WEAPONS:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[HEAVY_WEAPS_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[15], ( gbSkillTraitBonus[HEAVY_WEAPS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__AUTO_WEAPONS:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[16], ( 2 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[17] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__STEALTHY:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[18], ( 25 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ if( gGameExternalOptions.ubStealthTraitCoverValue != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[19], ( gGameExternalOptions.ubStealthTraitCoverValue * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__AMBIDEXTROUS:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[20] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__KNIFING:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[KNIFING_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[21], ( gbSkillTraitBonus[KNIFING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[22], ( gbSkillTraitBonus[KNIFING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[23], ( gbSkillTraitBonus[KNIFING_OT] / 3 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[24], ( gbSkillTraitBonus[KNIFING_OT] / 2 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case IMP_SKILL_TRAITS__PROF_SNIPER:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[PROF_SNIPER_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[25], ( gbSkillTraitBonus[PROF_SNIPER_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[26], ( 10 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__CAMO:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[27] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__MARTIAL_ARTS:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[MARTIALARTS_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[28], ( gbSkillTraitBonus[MARTIALARTS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[29], ( gbSkillTraitBonus[MARTIALARTS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[30], ( gbSkillTraitBonus[MARTIALARTS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[31], ( gbSkillTraitBonus[MARTIALARTS_OT] * 2 / 3 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[32], ( gbSkillTraitBonus[MARTIALARTS_OT] / 2 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[33]);
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[34]);
+ wcscat( apStr, atStr );
+ break;
+ }
+ case IMP_SKILL_TRAITS__NONE:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[35] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ }
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gMR_SkillTraitHelpTextRegions[ubTraitNumber]), apStr );
+ SetRegionHelpEndCallback( &gMR_SkillTraitHelpTextRegions[ubTraitNumber], MSYS_NO_CALLBACK );
+
+ return;
+}
\ No newline at end of file
diff --git a/Laptop/IMP Skill Trait.h b/Laptop/IMP Skill Trait.h
index a141a704..34bf42f0 100644
--- a/Laptop/IMP Skill Trait.h
+++ b/Laptop/IMP Skill Trait.h
@@ -28,10 +28,37 @@ enum
IMP_SKILL_TRAITS__NUMBER_SKILLS,
};
-// STR16 gzIMPSkillTraitsText[];
+// other set for new traits - SANDRO
+enum
+{
+ // major traits
+ IMP_SKILL_TRAITS_NEW_AUTO_WEAPONS,
+ IMP_SKILL_TRAITS_NEW_HEAVY_WEAPONS,
+ IMP_SKILL_TRAITS_NEW_PROF_SNIPER,
+ IMP_SKILL_TRAITS_NEW_RANGER,
+ IMP_SKILL_TRAITS_NEW_GUNSLINGER,
+ IMP_SKILL_TRAITS_NEW_MARTIAL_ARTS,
+ IMP_SKILL_TRAITS_NEW_SQUADLEADER,
+ IMP_SKILL_TRAITS_NEW_TECHNICIAN,
+ IMP_SKILL_TRAITS_NEW_DOCTOR,
+ IMP_SKILL_TRAITS_NEW_MAJOR_NONE,
+ IMP_SKILL_TRAITS_NEW_NUMBER_MAJOR_SKILLS,
+};
-INT8 DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection();
+INT8 CountNumSkillTraitsSelected( BOOLEAN fIncludeNoneSkill );
+INT32 DoesPlayerHaveExtraAttibutePointsToDistributeBasedOnSkillSelection();
void AddSelectedSkillsToSkillsList();
+INT32 StrengthRequiredDueToMajorSkills( void );
+INT32 AgilityRequiredDueToMajorSkills( void );
+INT32 DexterityRequiredDueToMajorSkills( void );
+INT32 HealthRequiredDueToMajorSkills( void );
+INT32 LeadershipRequiredDueToMajorSkills( void );
+INT32 WisdomRequiredDueToMajorSkills( void );
+INT32 MarksmanshipRequiredDueToMajorSkills( void );
+INT32 MechanicalRequiredDueToMajorSkills( void );
+INT32 MedicalRequiredDueToMajorSkills( void );
+INT32 ExplosivesRequiredDueToMajorSkills( void );
+
#endif
diff --git a/Laptop/IMP Text System.cpp b/Laptop/IMP Text System.cpp
index 790cf8d8..a5686932 100644
--- a/Laptop/IMP Text System.cpp
+++ b/Laptop/IMP Text System.cpp
@@ -12,6 +12,11 @@
#include "IMP Personality Finish.h"
#include "IMP Attribute Selection.h"
#include "IMP MainPage.h"
+ // added by SANDRO
+ #include "IMP Confirm.h"
+ #include "GameSettings.h"
+ #include "Text.h"
+ #include "_Ja25Englishtext.h"
#endif
#define IMP_SEEK_AMOUNT 5 * 80 * 2
@@ -180,14 +185,20 @@ void PrintImpText( void )
break;
case ( IMP_PERSONALITY ):
- // SANDRO - I HAVE CHANGED THESE TO BE ABLE TO EDIT THE TEXTS BEFORE SKILL TRAITS (THE TEXTS ARE ABOVE HERE)
- // EVEN IF IT IS A LITTLE STUPID WAY, I HAVEN'T FOUND A WAY HOW TO EDIT IMPtext.edt..
- // THE TEXTS OF "pSkillTraitBeginIMPStrings" ARE IN "_EnglishText.cpp" at the end
+ // SANDRO - I HAVE CHANGED THESE TO BE ABLE TO EDIT THE TEXTS BEFORE SKILL TRAITS
+ // EVEN IF IT IS A LITTLE STUPID WAY, I HAVEN'T FOUND A DIFFERENT WAY
//LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 60, ( 456 - 200 ), IMP_PERS_1, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
//LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 130, ( 456 - 200 ), IMP_PERS_2, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
- DisplayWrappedString( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 57, ( 456 - 200 ), 2, FONT12ARIAL, FONT_WHITE, pSkillTraitBeginIMPStrings[ 0 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
- DisplayWrappedString( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 140, ( 456 - 200 ), 2, FONT12ARIAL, FONT_WHITE, pSkillTraitBeginIMPStrings[ 1 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
-
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 57, ( 456 - 200 ), 2, FONT12ARIAL, FONT_WHITE, pSkillTraitBeginIMPStrings[ 2 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 155, ( 456 - 200 ), 2, FONT12ARIAL, FONT_WHITE, pSkillTraitBeginIMPStrings[ 3 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ }
+ else
+ {
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 57, ( 456 - 200 ), 2, FONT12ARIAL, FONT_WHITE, pSkillTraitBeginIMPStrings[ 0 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 130, LAPTOP_SCREEN_WEB_UL_Y + 140, ( 456 - 200 ), 2, FONT12ARIAL, FONT_WHITE, pSkillTraitBeginIMPStrings[ 1 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ }
LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X - 111, LAPTOP_SCREEN_WEB_UL_Y + 7, sWidth, IMP_PERS_6, FONT14ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED );
@@ -217,11 +228,21 @@ void PrintImpText( void )
}
break;
case( IMP_ATTRIBUTE_ENTRANCE ):
- LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X - 111, LAPTOP_SCREEN_WEB_UL_Y + 7, sWidth, IMP_ATTRIB_1 - 1, FONT14ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
- LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 110, LAPTOP_SCREEN_WEB_UL_Y + 50, ( 300 ), IMP_ATTRIB_5, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
- LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 110, LAPTOP_SCREEN_WEB_UL_Y + 130, ( 300 ), IMP_ATTRIB_6, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
- LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 110, LAPTOP_SCREEN_WEB_UL_Y + 200, ( 300 ), IMP_ATTRIB_7, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
-
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ CHAR16 sMinAttr[400];
+ swprintf( sMinAttr, sgAttributeSelectionText[ 4 ], gGameExternalOptions.iMinAttribute );
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 122, LAPTOP_SCREEN_WEB_UL_Y + 57, ( 466 - 190 ), 2, FONT12ARIAL, FONT_WHITE, sMinAttr,FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 122, LAPTOP_SCREEN_WEB_UL_Y + 116, ( 466 - 190 ), 2, FONT12ARIAL, FONT_WHITE, sgAttributeSelectionText[ 5 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 122, LAPTOP_SCREEN_WEB_UL_Y + 163, ( 466 - 190 ), 2, FONT12ARIAL, FONT_WHITE, sgAttributeSelectionText[ 6 ],FONT_BLACK,FALSE,CENTER_JUSTIFIED);
+ }
+ else
+ {
+ LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X - 111, LAPTOP_SCREEN_WEB_UL_Y + 7, sWidth, IMP_ATTRIB_1 - 1, FONT14ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
+ LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 110, LAPTOP_SCREEN_WEB_UL_Y + 50, ( 300 ), IMP_ATTRIB_5, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
+ LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 110, LAPTOP_SCREEN_WEB_UL_Y + 130, ( 300 ), IMP_ATTRIB_6, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
+ LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 110, LAPTOP_SCREEN_WEB_UL_Y + 200, ( 300 ), IMP_ATTRIB_7, FONT12ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
+ }
break;
case( IMP_ATTRIBUTE_PAGE ):
LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X - 111, LAPTOP_SCREEN_WEB_UL_Y + 7, sWidth, IMP_ATTRIB_1 - 1, FONT14ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
@@ -284,9 +305,13 @@ void PrintImpText( void )
LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 150, LAPTOP_SCREEN_WEB_UL_Y + 55, ( 200 ), IMP_FIN_2 - 1, FONT12ARIAL, FONT_WHITE, TRUE, 0);
break;
case( IMP_CONFIRM ):
- LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X - 111, LAPTOP_SCREEN_WEB_UL_Y + 7, sWidth, IMP_CON_1 , FONT14ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
+ LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X - 111, LAPTOP_SCREEN_WEB_UL_Y + 7, sWidth, IMP_CON_1 , FONT14ARIAL, FONT_WHITE, TRUE, CENTER_JUSTIFIED);
LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 160, LAPTOP_SCREEN_WEB_UL_Y + 60, ( 200 ), IMP_CON_2 , FONT12ARIAL, FONT_WHITE, TRUE, 0);
- LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 160, LAPTOP_SCREEN_WEB_UL_Y + 145, ( 200 ), IMP_CON_3 , FONT12ARIAL, FONT_WHITE, TRUE, 0);
+ //LoadAndDisplayIMPText( LAPTOP_SCREEN_UL_X + 160, LAPTOP_SCREEN_WEB_UL_Y + 145, ( 200 ), IMP_CON_3 , FONT12ARIAL, FONT_WHITE, TRUE, 0);
+ // SANDRO - changed to show exact cost of profile
+ CHAR16 chPayCost[1000];
+ swprintf( chPayCost, gzIMPProfileCostText[ 0 ], iGetProfileCost() );
+ DisplayWrappedString( LAPTOP_SCREEN_UL_X + 160, LAPTOP_SCREEN_WEB_UL_Y + 145, ( 200 ), 2, FONT12ARIAL, FONT_WHITE, chPayCost,FONT_BLACK,FALSE,LEFT_JUSTIFIED);
break;
}
diff --git a/Laptop/IMP Voices.cpp b/Laptop/IMP Voices.cpp
index c222ab7c..1773589e 100644
--- a/Laptop/IMP Voices.cpp
+++ b/Laptop/IMP Voices.cpp
@@ -381,41 +381,7 @@ void BtnIMPVoicesDoneCallback(GUI_BUTTON *btn,INT32 reason)
iCurrentImpPage = IMP_COLOR_CHOICE_PAGE;
// Following part removed
- // go to main page
- /*iCurrentImpPage = IMP_MAIN_PAGE;
-
- // if we are already done, leave
- if( iCurrentProfileMode == IMP__FINISH )
- {
- iCurrentImpPage = IMP_FINISH;
- }
- else
- {
- if( CameBackToVoicePageButNotFinished() )
- {
- iCurrentImpPage = IMP_MAIN_PAGE;
- }
- else
- {
- iCurrentProfileMode = IMP__PERSONALITY;
- }
- }*/
-/*
- // current mode now is voice
- else if( iCurrentProfileMode < IMP__PORTRAIT )
- {
- iCurrentProfileMode = IMP__PORTRAIT;
- }
-
- else if( iCurrentProfileMode == IMP__PORTRAIT )
- {
- // all done profiling
- iCurrentProfileMode = IMP__VOICE;
- iCurrentImpPage = IMP_FINISH;
- }
-*/
// set voice id, to grab character slot
-
// WDS: Allow flexible numbers of IMPs of each sex
LaptopSaveInfo.iIMPIndex = gGameExternalOptions.iaIMPSlots[iCurrentVoice];
diff --git a/Laptop/Laptop_VS2005.vcproj b/Laptop/Laptop_VS2005.vcproj
new file mode 100644
index 00000000..5080264e
--- /dev/null
+++ b/Laptop/Laptop_VS2005.vcproj
@@ -0,0 +1,895 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Laptop/Laptop_VS2008.vcproj b/Laptop/Laptop_VS2008.vcproj
index 7451ae38..f1651a76 100644
--- a/Laptop/Laptop_VS2008.vcproj
+++ b/Laptop/Laptop_VS2008.vcproj
@@ -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"
>
@@ -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"
>
@@ -507,6 +507,10 @@
RelativePath="IMP MainPage.h"
>
+
+
@@ -779,6 +783,10 @@
RelativePath="IMP MainPage.cpp"
>
+
+
@@ -863,10 +871,22 @@
RelativePath="Store Inventory.cpp"
>
+
+
+
+
+
+
diff --git a/Laptop/Laptop_VS2010.vcxproj b/Laptop/Laptop_VS2010.vcxproj
new file mode 100644
index 00000000..d2144bc7
--- /dev/null
+++ b/Laptop/Laptop_VS2010.vcxproj
@@ -0,0 +1,350 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}
+ Win32Proj
+ Laptop
+ Laptop
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Laptop/Laptop_VS2010.vcxproj.filters b/Laptop/Laptop_VS2010.vcxproj.filters
new file mode 100644
index 00000000..ac5f0a25
--- /dev/null
+++ b/Laptop/Laptop_VS2010.vcxproj.filters
@@ -0,0 +1,426 @@
+
+
+
+
+ {84a4f64f-bc1b-4e0c-848c-2b7c145ae615}
+
+
+ {b159d1de-d6d6-4531-b86a-b991f7210268}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Laptop/PostalService.cpp b/Laptop/PostalService.cpp
index c6952b8a..dc36da2e 100644
--- a/Laptop/PostalService.cpp
+++ b/Laptop/PostalService.cpp
@@ -313,8 +313,11 @@ BOOLEAN CPostalService::DeliverShipment(UINT16 usShipmentID)
if( (shs.pDestination->ubMapX > 0) &&
(shs.pDestination->ubMapX < MAP_WORLD_X - 1) &&
(shs.pDestination->ubMapY > 0) &&
- (shs.pDestination->ubMapY < MAP_WORLD_Y - 1) &&
- GridNoOnVisibleWorldTile(shs.pDestination->sGridNo) )
+ (shs.pDestination->ubMapY < MAP_WORLD_Y - 1) ) //&&
+ //GridNoOnVisibleWorldTile(shs.pDestination->sGridNo) )
+ // silversurfer: wtf? This test checked if the delivery tile was valid for the currently loaded sector
+ // which is not necessarily the delivery sector
+ // if we are currently below ground it will crash the game...
{
BOOLEAN fSectorLoaded = ( gWorldSectorX == shs.pDestination->ubMapX ) &&
( gWorldSectorY == shs.pDestination->ubMapY ) &&
@@ -417,8 +420,6 @@ BOOLEAN CPostalService::DeliverShipment(UINT16 usShipmentID)
tempObject[0]->data.gun.ubGunShotsLeft = 0;
}
- // TODO.RW: Hier Pablo stealing code einfgen und ubItemsDelivered reduzieren!!!
-
UINT8 cnt = -1;
// Loop through the items of a package
while ( ubItemsDelivered )
diff --git a/Laptop/XML_AIMAvailability.cpp b/Laptop/XML_AIMAvailability.cpp
new file mode 100644
index 00000000..fb76224c
--- /dev/null
+++ b/Laptop/XML_AIMAvailability.cpp
@@ -0,0 +1,234 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+ #include "aim.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ AIM_AVAILABLE curAimAvailability;
+ AIM_AVAILABLE * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef aimAvailabilityParseData;
+
+BOOLEAN AimAvailability_TextOnly;
+
+static void XMLCALL
+aimAvailabilityStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ aimAvailabilityParseData * pData = (aimAvailabilityParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "AIM_AVAILABLES") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "AIM") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "ProfilId") == 0 ||
+ strcmp(name, "AimBioID") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+aimCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ aimAvailabilityParseData * pData = (aimAvailabilityParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+aimAvailabilityEndElementHandle(void *userData, const XML_Char *name)
+{
+ aimAvailabilityParseData * pData = (aimAvailabilityParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth)
+ {
+ if(strcmp(name, "AIM_AVAILABLES") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "AIM") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if (!AimAvailability_TextOnly)
+ {
+ gAimAvailability[pData->curAimAvailability.uiIndex].uiIndex = pData->curAimAvailability.uiIndex;
+ gAimAvailability[pData->curAimAvailability.uiIndex].ProfilId = pData->curAimAvailability.ProfilId;
+ gAimAvailability[pData->curAimAvailability.uiIndex].ubAimArrayID = pData->curAimAvailability.uiIndex;
+ gAimAvailability[pData->curAimAvailability.uiIndex].AimBio = pData->curAimAvailability.AimBio;
+
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].uiIndex = pData->curAimAvailability.uiIndex;
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].ProfilId = pData->curAimAvailability.ProfilId;
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].ubAimArrayID = pData->curAimAvailability.uiIndex;
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].AimBio = pData->curAimAvailability.AimBio;
+ }
+ else
+ {
+ gAimAvailability[pData->curAimAvailability.uiIndex].uiIndex = pData->curAimAvailability.uiIndex;
+ gAimAvailability[pData->curAimAvailability.uiIndex].ProfilId = pData->curAimAvailability.ProfilId;
+ gAimAvailability[pData->curAimAvailability.uiIndex].ubAimArrayID = pData->curAimAvailability.uiIndex;
+ gAimAvailability[pData->curAimAvailability.uiIndex].AimBio = pData->curAimAvailability.AimBio;
+
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].uiIndex = pData->curAimAvailability.uiIndex;
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].ProfilId = pData->curAimAvailability.ProfilId;
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].ubAimArrayID = pData->curAimAvailability.uiIndex;
+ gAimAvailabilityTemp[pData->curAimAvailability.uiIndex].AimBio = pData->curAimAvailability.AimBio;
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAimAvailability.uiIndex = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ProfilId") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAimAvailability.ProfilId = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "AimBioID") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAimAvailability.AimBio = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInAimAvailability(STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ aimAvailabilityParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading AimAvailability.xml" );
+
+ AimAvailability_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, aimAvailabilityStartElementHandle, aimAvailabilityEndElementHandle);
+ XML_SetCharacterDataHandler(parser, aimCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in AimAvailability.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+
+BOOLEAN WriteAimAvailability(STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < NUM_PROFILES;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ // FilePrintf(hFile,"\t\t-1\r\n");
+ // FilePrintf(hFile,"\t\t0\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", gAimAvailability[cnt].ProfilId);
+ FilePrintf(hFile,"\t\t%d\r\n", gAimAvailability[cnt].AimBio);
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Laptop/XML_ConditionsForMercAvailability.cpp b/Laptop/XML_ConditionsForMercAvailability.cpp
new file mode 100644
index 00000000..929d574f
--- /dev/null
+++ b/Laptop/XML_ConditionsForMercAvailability.cpp
@@ -0,0 +1,294 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+ #include "mercs.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ CONTITION_FOR_MERC_AVAILABLE curMercAvailability;
+ CONTITION_FOR_MERC_AVAILABLE * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef mercAvailabilityParseData;
+
+BOOLEAN MercAvailability_TextOnly;
+
+static void XMLCALL
+mercAvailabilityStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ mercAvailabilityParseData * pData = (mercAvailabilityParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "MERC_AVAILABLES") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "MERC") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "ProfilId") == 0 ||
+ strcmp(name, "usMoneyPaid") == 0 ||
+ strcmp(name, "Available") == 0 ||
+ strcmp(name, "NewMercsAvailable") == 0 ||
+ strcmp(name, "StartMercsAvailable") == 0 ||
+ strcmp(name, "MercBioID") == 0 ||
+ strcmp(name, "Drunk") == 0 ||
+ strcmp(name, "uiAlternateIndex") == 0 ||
+ strcmp(name, "usDay") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+mercCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ mercAvailabilityParseData * pData = (mercAvailabilityParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+mercAvailabilityEndElementHandle(void *userData, const XML_Char *name)
+{
+ mercAvailabilityParseData * pData = (mercAvailabilityParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth)
+ {
+ if(strcmp(name, "MERC_AVAILABLES") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "MERC") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if (!MercAvailability_TextOnly)
+ {
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].uiIndex = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].ProfilId = pData->curMercAvailability.ProfilId;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].usMoneyPaid = pData->curMercAvailability.usMoneyPaid;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].usDay = pData->curMercAvailability.usDay;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].ubMercArrayID = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].NewMercsAvailable = pData->curMercAvailability.NewMercsAvailable;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].StartMercsAvailable = pData->curMercAvailability.StartMercsAvailable;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].MercBio = pData->curMercAvailability.MercBio;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].Drunk = pData->curMercAvailability.Drunk;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].uiAlternateIndex = pData->curMercAvailability.uiAlternateIndex;
+
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].uiIndex = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].ProfilId = pData->curMercAvailability.ProfilId;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].usMoneyPaid = pData->curMercAvailability.usMoneyPaid;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].usDay = pData->curMercAvailability.usDay;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].ubMercArrayID = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].NewMercsAvailable = pData->curMercAvailability.NewMercsAvailable;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].StartMercsAvailable = pData->curMercAvailability.StartMercsAvailable;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].MercBio = pData->curMercAvailability.MercBio;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].Drunk = pData->curMercAvailability.Drunk;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].uiAlternateIndex = pData->curMercAvailability.uiAlternateIndex;
+ }
+ else
+ {
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].uiIndex = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].ProfilId = pData->curMercAvailability.ProfilId;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].usMoneyPaid = pData->curMercAvailability.usMoneyPaid;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].usDay = pData->curMercAvailability.usDay;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].ubMercArrayID = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].NewMercsAvailable = pData->curMercAvailability.NewMercsAvailable;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].StartMercsAvailable = pData->curMercAvailability.StartMercsAvailable;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].MercBio = pData->curMercAvailability.MercBio;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].Drunk = pData->curMercAvailability.Drunk;
+ gConditionsForMercAvailability[pData->curMercAvailability.uiIndex].uiAlternateIndex = pData->curMercAvailability.uiAlternateIndex;
+
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].uiIndex = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].ProfilId = pData->curMercAvailability.ProfilId;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].usMoneyPaid = pData->curMercAvailability.usMoneyPaid;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].usDay = pData->curMercAvailability.usDay;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].ubMercArrayID = pData->curMercAvailability.uiIndex;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].NewMercsAvailable = pData->curMercAvailability.NewMercsAvailable;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].StartMercsAvailable = pData->curMercAvailability.StartMercsAvailable;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].MercBio = pData->curMercAvailability.MercBio;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].Drunk = pData->curMercAvailability.Drunk;
+ gConditionsForMercAvailabilityTemp[pData->curMercAvailability.uiIndex].uiAlternateIndex = pData->curMercAvailability.uiAlternateIndex;
+
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.uiIndex = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usMoneyPaid") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.usMoneyPaid = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usDay") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.usDay = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ProfilId") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.ProfilId = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "NewMercsAvailable") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.NewMercsAvailable = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "StartMercsAvailable") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.StartMercsAvailable = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "MercBioID") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.MercBio = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Drunk") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.Drunk = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "uiAlternateIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curMercAvailability.uiAlternateIndex = (UINT8) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInMercAvailability(STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ mercAvailabilityParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading MercAvailability.xml" );
+
+ MercAvailability_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, mercAvailabilityStartElementHandle, mercAvailabilityEndElementHandle);
+ XML_SetCharacterDataHandler(parser, mercCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in MercAvailability.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+
+BOOLEAN WriteMercAvailability(STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < NUM_PROFILES;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", gConditionsForMercAvailability[cnt].usMoneyPaid);
+ FilePrintf(hFile,"\t\t%d\r\n", gConditionsForMercAvailability[cnt].usDay);
+ FilePrintf(hFile,"\t\t%d\r\n", gConditionsForMercAvailability[cnt].ProfilId);
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Laptop/XML_IMPPortraits.cpp b/Laptop/XML_IMPPortraits.cpp
new file mode 100644
index 00000000..6aff0331
--- /dev/null
+++ b/Laptop/XML_IMPPortraits.cpp
@@ -0,0 +1,315 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+ #include "IMP Confirm.h"
+ #include "IMP Portraits.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ IMP_FACE_VALUES curIMPPortraits;
+ IMP_FACE_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+ //CHAR16 gzIMPPortraits[MAX_IMP_NAMES_CHARS];
+}
+typedef impPortraitsParseData;
+
+BOOLEAN IMPPortraits_TextOnly;
+
+static void XMLCALL
+impPortraitsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ impPortraitsParseData * pData = (impPortraitsParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "IMPPORTRAITSLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "IMP") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "PortraitId") == 0 ||
+ strcmp(name, "bSex") == 0 ||
+ strcmp(name, "usEyesX") == 0 ||
+ strcmp(name, "usEyesY") == 0 ||
+ strcmp(name, "usMouthY") == 0 ||
+ strcmp(name, "usMouthX") == 0 ||
+ strcmp(name, "DefaultSkin") == 0 ||
+ strcmp(name, "DefaultHair") == 0 ||
+ strcmp(name, "DefaultShirt") == 0 ||
+ strcmp(name, "DefaultPants") == 0 ||
+ strcmp(name, "DefaultBigBody") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+impPortraitsCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ impPortraitsParseData * pData = (impPortraitsParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+impPortraitsEndElementHandle(void *userData, const XML_Char *name)
+{
+ impPortraitsParseData * pData = (impPortraitsParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth)
+ {
+ if(strcmp(name, "IMPPORTRAITSLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "IMP") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if (!IMPPortraits_TextOnly)
+ {
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiEyeXPositions = pData->curIMPPortraits.uiEyeXPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiEyeYPositions = pData->curIMPPortraits.uiEyeYPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiMouthXPositions = pData->curIMPPortraits.uiMouthXPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiMouthYPositions = pData->curIMPPortraits.uiMouthYPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].PortraitId = pData->curIMPPortraits.PortraitId;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].bSex = pData->curIMPPortraits.bSex;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentSkin = pData->curIMPPortraits.iCurrentSkin;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentShirt = pData->curIMPPortraits.iCurrentShirt;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentHair = pData->curIMPPortraits.iCurrentHair;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentPants = pData->curIMPPortraits.iCurrentPants;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].bBigBody = pData->curIMPPortraits.bBigBody;
+
+ }
+ else
+ {
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiEyeXPositions = pData->curIMPPortraits.uiEyeXPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiEyeYPositions = pData->curIMPPortraits.uiEyeYPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiMouthXPositions = pData->curIMPPortraits.uiMouthXPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].uiMouthYPositions = pData->curIMPPortraits.uiMouthYPositions;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].PortraitId = pData->curIMPPortraits.PortraitId;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].bSex = pData->curIMPPortraits.bSex;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentSkin = pData->curIMPPortraits.iCurrentSkin;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentShirt = pData->curIMPPortraits.iCurrentShirt;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentHair = pData->curIMPPortraits.iCurrentHair;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].iCurrentPants = pData->curIMPPortraits.iCurrentPants;
+ gIMPFaceValues[pData->curIMPPortraits.uiIndex].bBigBody = pData->curIMPPortraits.bBigBody;
+
+ }
+
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PortraitId") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.PortraitId = (INT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bSex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.bSex = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usEyesX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.uiEyeXPositions = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usEyesY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.uiEyeYPositions = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usMouthX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.uiMouthXPositions = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usMouthY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.uiMouthYPositions = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "DefaultSkin") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.iCurrentSkin = (INT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "DefaultHair") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.iCurrentHair = (INT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "DefaultShirt") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.iCurrentShirt = (INT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "DefaultPants") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.iCurrentPants = (INT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "DefaultBigBody") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curIMPPortraits.bBigBody = (INT32) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInIMPPortraits(STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ impPortraitsParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading IMPPortraits.xml" );
+
+ IMPPortraits_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, impPortraitsStartElementHandle, impPortraitsEndElementHandle);
+ XML_SetCharacterDataHandler(parser, impPortraitsCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in IMPPortraits.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+
+void LoadIMPPortraitsTEMP()
+{
+UINT32 cnt;
+UINT32 cnt2 = 0;
+UINT32 cnt3 = 0;
+
+ for ( cnt = 0; cnt < 200; cnt++ )
+ {
+ if (gIMPFaceValues[cnt].bSex == 1 && gIMPFaceValues[cnt].PortraitId !=0)
+ {
+ gIMPFemaleValues[cnt2].uiIndex = cnt2;
+
+ gIMPFemaleValues[cnt2].Enabled = 1;
+
+ gIMPFemaleValues[cnt2].uiEyeXPositions = gIMPFaceValues[cnt].uiEyeXPositions;
+ gIMPFemaleValues[cnt2].uiEyeYPositions = gIMPFaceValues[cnt].uiEyeYPositions;
+ gIMPFemaleValues[cnt2].uiMouthXPositions = gIMPFaceValues[cnt].uiMouthXPositions;
+ gIMPFemaleValues[cnt2].uiMouthYPositions = gIMPFaceValues[cnt].uiMouthYPositions;
+ gIMPFemaleValues[cnt2].PortraitId = gIMPFaceValues[cnt].PortraitId;
+ gIMPFemaleValues[cnt2].bSex = gIMPFaceValues[cnt].bSex;
+ gIMPFemaleValues[cnt2].iCurrentSkin = gIMPFaceValues[cnt].iCurrentSkin;
+ gIMPFemaleValues[cnt2].iCurrentShirt = gIMPFaceValues[cnt].iCurrentShirt;
+ gIMPFemaleValues[cnt2].iCurrentHair = gIMPFaceValues[cnt].iCurrentHair;
+ gIMPFemaleValues[cnt2].iCurrentPants = gIMPFaceValues[cnt].iCurrentPants;
+ gIMPFemaleValues[cnt2].bBigBody = gIMPFaceValues[cnt].bBigBody;
+ cnt2++;
+ }
+ }
+
+ for ( cnt = 0; cnt < 200; cnt++ )
+ {
+ if (gIMPFaceValues[cnt].bSex == 0 && gIMPFaceValues[cnt].PortraitId !=0)
+ {
+ gIMPMaleValues[cnt3].uiIndex = cnt3;
+ gIMPMaleValues[cnt3].Enabled = 1;
+ gIMPMaleValues[cnt3].uiEyeXPositions = gIMPFaceValues[cnt].uiEyeXPositions;
+ gIMPMaleValues[cnt3].uiEyeYPositions = gIMPFaceValues[cnt].uiEyeYPositions;
+ gIMPMaleValues[cnt3].uiMouthXPositions = gIMPFaceValues[cnt].uiMouthXPositions;
+ gIMPMaleValues[cnt3].uiMouthYPositions = gIMPFaceValues[cnt].uiMouthYPositions;
+ gIMPMaleValues[cnt3].PortraitId = gIMPFaceValues[cnt].PortraitId;
+ gIMPMaleValues[cnt3].bSex = gIMPFaceValues[cnt].bSex;
+ gIMPMaleValues[cnt3].iCurrentSkin = gIMPFaceValues[cnt].iCurrentSkin;
+ gIMPMaleValues[cnt3].iCurrentShirt = gIMPFaceValues[cnt].iCurrentShirt;
+ gIMPMaleValues[cnt3].iCurrentHair = gIMPFaceValues[cnt].iCurrentHair;
+ gIMPMaleValues[cnt3].iCurrentPants = gIMPFaceValues[cnt].iCurrentPants;
+ gIMPMaleValues[cnt3].bBigBody = gIMPFaceValues[cnt].bBigBody;
+ cnt3++;
+ }
+ }
+
+}
diff --git a/Laptop/aim.cpp b/Laptop/aim.cpp
index 37754e33..fafcbcc3 100644
--- a/Laptop/aim.cpp
+++ b/Laptop/aim.cpp
@@ -14,11 +14,18 @@
#include "Text.h"
#include "LaptopSave.h"
#include "Multi Language Graphic Utils.h"
+ #include "GameSettings.h"
#endif
+#include "LocalizedStrings.h"
+#include "Soldier Profile.h"
+UINT8 MAX_NUMBER_MERCS = 0;
-UINT8 AimMercArray[ MAX_NUMBER_MERCS ];
+UINT8 AimMercArray[ NUM_PROFILES ]; //MAX_NUMBER_MERCS ];
+
+AIM_AVAILABLE_TEMP gAimAvailabilityTemp[ NUM_PROFILES ];
+AIM_AVAILABLE gAimAvailability[ NUM_PROFILES ];
UINT8 gCurrentAimPage[ NUM_AIM_SCREENS ] =
{
@@ -470,14 +477,27 @@ BOOLEAN InitAimDefaults()
CHECKF(AddVideoObject(&VObjectDesc, &guiRustBackGround));
// load the Aim Symbol graphic and add it
- VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
- GetMLGFilename( VObjectDesc.ImageFile, MLG_AIMSYMBOL );
- CHECKF(AddVideoObject(&VObjectDesc, &guiAimSymbol));
+ if(gGameExternalOptions.gfUseNewStartingGearInterface)
+ {
+ VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
+ GetMLGFilename( VObjectDesc.ImageFile, MLG_AIMSYMBOL_SMALL );
+ CHECKF(AddVideoObject(&VObjectDesc, &guiAimSymbol));
+ //Mouse region for the Links
+ MSYS_DefineRegion( &gSelectedAimLogo, AIM_SYMBOL_SMALL_X, AIM_SYMBOL_SMALL_Y, AIM_SYMBOL_SMALL_X+AIM_SYMBOL_SMALL_WIDTH, AIM_SYMBOL_SMALL_Y+AIM_SYMBOL_SMALL_HEIGHT, MSYS_PRIORITY_HIGH,
+ CURSOR_WWW, MSYS_NO_CALLBACK, SelectAimLogoRegionCallBack);
+ MSYS_AddRegion(&gSelectedAimLogo);
+ }
+ else
+ {
+ VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
+ GetMLGFilename( VObjectDesc.ImageFile, MLG_AIMSYMBOL );
+ CHECKF(AddVideoObject(&VObjectDesc, &guiAimSymbol));
+ //Mouse region for the Links
+ MSYS_DefineRegion( &gSelectedAimLogo, AIM_SYMBOL_X, AIM_SYMBOL_Y, AIM_SYMBOL_X+AIM_SYMBOL_WIDTH, AIM_SYMBOL_Y+AIM_SYMBOL_HEIGHT, MSYS_PRIORITY_HIGH,
+ CURSOR_WWW, MSYS_NO_CALLBACK, SelectAimLogoRegionCallBack);
+ MSYS_AddRegion(&gSelectedAimLogo);
+ }
- //Mouse region for the Links
- MSYS_DefineRegion( &gSelectedAimLogo, AIM_SYMBOL_X, AIM_SYMBOL_Y, AIM_SYMBOL_X+AIM_SYMBOL_WIDTH, AIM_SYMBOL_Y+AIM_SYMBOL_HEIGHT, MSYS_PRIORITY_HIGH,
- CURSOR_WWW, MSYS_NO_CALLBACK, SelectAimLogoRegionCallBack);
- MSYS_AddRegion(&gSelectedAimLogo);
return(TRUE);
@@ -514,8 +534,16 @@ BOOLEAN DrawAimDefaults()
}
// Aim Symbol
- GetVideoObject(&hAimSymbolHandle, guiAimSymbol);
- BltVideoObject(FRAME_BUFFER, hAimSymbolHandle, 0,AIM_SYMBOL_X, AIM_SYMBOL_Y, VO_BLT_SRCTRANSPARENCY,NULL);
+ if(gGameExternalOptions.gfUseNewStartingGearInterface)
+ {
+ GetVideoObject(&hAimSymbolHandle, guiAimSymbol);
+ BltVideoObject(FRAME_BUFFER, hAimSymbolHandle, 0,AIM_SYMBOL_SMALL_X, AIM_SYMBOL_SMALL_Y, VO_BLT_SRCTRANSPARENCY,NULL);
+ }
+ else
+ {
+ GetVideoObject(&hAimSymbolHandle, guiAimSymbol);
+ BltVideoObject(FRAME_BUFFER, hAimSymbolHandle, 0,AIM_SYMBOL_X, AIM_SYMBOL_Y, VO_BLT_SRCTRANSPARENCY,NULL);
+ }
return(TRUE);
}
@@ -541,8 +569,14 @@ void SelectAimLogoRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
BOOLEAN DisplayAimSlogan()
{
CHAR16 sSlogan[400];
-
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, 0, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, 0, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", 0, sSlogan, 400);
+ }
//Display Aim Text under the logo
DisplayWrappedString(AIM_LOGO_TEXT_X, AIM_LOGO_TEXT_Y, AIM_LOGO_TEXT_WIDTH, 2, AIM_LOGO_FONT, AIM_FONT_MCOLOR_WHITE, sSlogan, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
@@ -550,27 +584,37 @@ BOOLEAN DisplayAimSlogan()
}
-
BOOLEAN DisplayAimCopyright()
{
CHAR16 sSlogan[400];
- UINT32 uiStartLoc=0;
//Load and Display the copyright notice
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc=0;
+ uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_COPYRIGHT_1;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
- uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_COPYRIGHT_1;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, uiStartLoc, AIM_HISTORY_LINE_SIZE);
- DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_COPYRIGHT_2;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y + AIM_COPYRIGHT_GAP, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
- uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_COPYRIGHT_2;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, uiStartLoc, AIM_HISTORY_LINE_SIZE);
- DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y + AIM_COPYRIGHT_GAP, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
-
- uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_COPYRIGHT_3;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, uiStartLoc, AIM_HISTORY_LINE_SIZE);
- DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y + AIM_COPYRIGHT_GAP*2, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_COPYRIGHT_3;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sSlogan, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y + AIM_COPYRIGHT_GAP*2, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", AIM_COPYRIGHT_1, sSlogan, 400);
+ DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", AIM_COPYRIGHT_2, sSlogan, 400);
+ DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y + AIM_COPYRIGHT_GAP, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", AIM_COPYRIGHT_3, sSlogan, 400);
+ DrawTextToScreen(sSlogan, AIM_COPYRIGHT_X, AIM_COPYRIGHT_Y + AIM_COPYRIGHT_GAP*2, AIM_COPYRIGHT_WIDTH, AIM_COPYRIGHT_FONT, FONT_MCOLOR_DKWHITE, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
+ }
return(TRUE);
}
@@ -847,25 +891,30 @@ BOOLEAN DisplayFlowerAd( BOOLEAN fInit, BOOLEAN fRedraw )
BOOLEAN DrawWarningBox( BOOLEAN fInit, BOOLEAN fRedraw )
{
- static UINT32 uiLastTime;
- static UINT8 ubSubImage=0;
- UINT32 uiCurTime = GetJA2Clock();
+ static UINT32 uiLastTime;
+ static UINT8 ubSubImage = 0;
+ UINT32 uiCurTime = GetJA2Clock();
if( fInit || fRedraw)
{
- CHAR16 sText[400];
- UINT32 uiStartLoc=0;
+ CHAR16 sText[400];
//UINT16 usLocY = AIM_WARNING_TEXT_Y + (GetFontHeight(AIM_WARNING_FONT) + 2) * 2;
- HVOBJECT hWarningHandle;
+ HVOBJECT hWarningHandle;
//Warning
GetVideoObject(&hWarningHandle, guiWarning);
BltVideoObject(FRAME_BUFFER, hWarningHandle, 0,WARNING_X, WARNING_Y, VO_BLT_SRCTRANSPARENCY,NULL);
-
- uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_WARNING_1;
- LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ if(!g_bUseXML_Strings)
+ {
+ UINT32 uiStartLoc = AIM_HISTORY_LINE_SIZE * AIM_WARNING_1;
+ LoadEncryptedDataFromFile(AIMHISTORYFILE, sText, uiStartLoc, AIM_HISTORY_LINE_SIZE);
+ }
+ else
+ {
+ Loc::GetString(Loc::AIM_HISTORY, L"Line", AIM_WARNING_1, sText, 400);
+ }
//Display Aim Warning Text
DisplayWrappedString(AIM_WARNING_TEXT_X, AIM_WARNING_TEXT_Y, AIM_WARNING_TEXT_WIDTH, 2, AIM_WARNING_FONT, FONT_RED, sText, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED);
diff --git a/Laptop/aim.h b/Laptop/aim.h
index 7995a778..15d933aa 100644
--- a/Laptop/aim.h
+++ b/Laptop/aim.h
@@ -2,7 +2,7 @@
#define __AIM_H
#include "Cursors.h"
-
+#include "Soldier Profile.h"
//
// AIM defines
@@ -12,8 +12,32 @@
#define AIMHISTORYFILE "BINARYDATA\\AimHist.edt"
#define AIM_HISTORY_LINE_SIZE 400 * 2
-#define MAX_NUMBER_MERCS 40
-extern UINT8 AimMercArray[ MAX_NUMBER_MERCS ];
+//#define MAX_NUMBER_MERCS 40
+
+extern UINT8 MAX_NUMBER_MERCS;
+
+extern UINT8 AimMercArray[ NUM_PROFILES ];//MAX_NUMBER_MERCS ];
+
+typedef struct
+{
+ UINT8 ubAimArrayID;
+ UINT8 uiIndex;
+ UINT8 ProfilId;
+ UINT8 AimBio;
+
+} AIM_AVAILABLE;
+
+typedef struct
+{
+ UINT8 ubAimArrayID;
+ UINT8 uiIndex;
+ UINT8 ProfilId;
+ UINT8 AimBio;
+
+} AIM_AVAILABLE_TEMP;
+
+extern AIM_AVAILABLE_TEMP gAimAvailabilityTemp[ NUM_PROFILES ];
+extern AIM_AVAILABLE gAimAvailability[ NUM_PROFILES ];
#define NUM_AIM_SCREENS 6
@@ -34,6 +58,13 @@ extern UINT8 AimMercArray[ MAX_NUMBER_MERCS ];
#define AIM_SYMBOL_WIDTH 203
#define AIM_SYMBOL_HEIGHT 51
+//tais: small logo for nsgi
+#define AIM_SYMBOL_SMALL_X IMAGE_OFFSET_X + 3
+#define AIM_SYMBOL_SMALL_Y IMAGE_OFFSET_Y + 3
+#define AIM_SYMBOL_SMALL_WIDTH 102
+#define AIM_SYMBOL_SMALL_HEIGHT 26
+
+
// RustBackGround
#define RUSTBACKGROUND_SIZE_X 125
#define RUSTBACKGROUND_SIZE_Y 100
diff --git a/Laptop/email.cpp b/Laptop/email.cpp
index 392c0273..f62f968b 100644
--- a/Laptop/email.cpp
+++ b/Laptop/email.cpp
@@ -22,6 +22,8 @@
#include "LaptopSave.h"
#include "finances.h"
#include "PostalService.h"
+ #include "faces.h"
+ #include "GameSettings.h"
#include
#endif
using namespace std;
@@ -693,6 +695,26 @@ void AddEmailWithSpecialData(INT32 iMessageOffset, INT32 iMessageLength, UINT8 u
return;
}
+void AddEmailWFMercLevelUp(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32 iDate, INT32 iCurrentIMPPosition)
+{
+ CHAR16 pSubject[320];
+
+ UINT8 subjectLine = (170 - iMessageLength) * 2;
+ wcscpy( pSubject, New113AIMMercMailTexts[subjectLine] );
+
+ AddEmailMessage(iMessageOffset,iMessageLength, pSubject, iDate, ubSender, FALSE, 0, 0, iCurrentIMPPosition );
+
+ // if we are in fact int he laptop, redraw icons, might be change in mail status
+
+ if( fCurrentlyInLaptop == TRUE )
+ {
+ // redraw icons, might be new mail
+ DrawLapTopIcons();
+ }
+
+ return;
+}
+
void AddEmail(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32 iDate, INT32 iCurrentIMPPosition)
{
CHAR16 pSubject[320];
@@ -700,7 +722,6 @@ void AddEmail(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32
//MessagePtr pMessage;
//CHAR16 pMessageString[320];
-
// WANNE: Short work in both ways
LoadEncryptedDataFromFile("BINARYDATA\\Email.edt", pSubject, 640*(iMessageOffset), 640);
@@ -711,8 +732,8 @@ void AddEmail(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32
if( fCurrentlyInLaptop == TRUE )
{
- // redraw icons, might be new mail
- DrawLapTopIcons();
+ // redraw icons, might be new mail
+ DrawLapTopIcons();
}
return;
@@ -784,10 +805,23 @@ void AddEmailMessage(INT32 iMessageOffset, INT32 iMessageLength,STR16 pSubject,
//}
//pTempEmail->pText[iCounter]=NULL;
+ /*
+ // WANNE: Not needed anymore, bug is fixed!!
+ // WANNE: Fix the memory heap problem -> CTD (fix by BirdFlu)
+ // The text for the wildfire merc is too long (> 128 characters)!!
+ // copy subject
+ int _len = wcslen(pSubject);
+ pTempEmail->pSubject = (STR16) MemAlloc( (_len + 1) * sizeof(CHAR16) );
+ memset( pTempEmail->pSubject, 0, sizeof( CHAR16 ) * (_len + 1) );
+ wcsncpy(pTempEmail->pSubject,pSubject,_len);
+ pTempEmail->pSubject[_len] = 0;
+ */
+
// copy subject
pTempEmail->pSubject = (STR16) MemAlloc( 128 * sizeof(CHAR16) );
memset( pTempEmail->pSubject, 0, sizeof( CHAR16 ) * 128 );
wcscpy(pTempEmail->pSubject,pSubject);
+
// copy offset and length of the actual message in email.edt
pTempEmail->usOffset =(UINT16)iMessageOffset;
@@ -3414,10 +3448,10 @@ void HandleIMPCharProfileResultsMessage( void)
}
// personality itself
- switch( gMercProfiles[ iCurrentIMPSlot ].bPersonalityTrait)
+ switch( gMercProfiles[ iCurrentIMPSlot ].bDisability)
{
// normal as can be
- case( NO_PERSONALITYTRAIT ):
+ case( NO_DISABILITY ):
iOffSet = IMP_PERSONALITY_NORMAL;
break;
case( HEAT_INTOLERANT ):
@@ -3456,7 +3490,7 @@ void HandleIMPCharProfileResultsMessage( void)
AddEmailRecordToList( pString );
// extra paragraph for bugs
- if( gMercProfiles[ iCurrentIMPSlot ].bPersonalityTrait == FEAR_OF_INSECTS )
+ if( gMercProfiles[ iCurrentIMPSlot ].bDisability == FEAR_OF_INSECTS )
{
// persoanlity paragraph
LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( iOffSet + IMP_PERSONALITY_LENGTH + 1 ), MAIL_STRING_SIZE );
@@ -3830,163 +3864,235 @@ void HandleIMPCharProfileResultsMessage( void)
iCounter++;
}
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == KNIFING )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == KNIFING ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_KNIFE ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- // lockpick
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == LOCKPICKING)||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == LOCKPICKING) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_LOCK ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- // hand to hand
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == HANDTOHAND )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == HANDTOHAND ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_HAND ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- // electronics
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == ELECTRONICS )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == ELECTRONICS ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_ELEC ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == NIGHTOPS )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == NIGHTOPS ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_NIGHT ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == THROWING)||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == THROWING) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_THROW ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == TEACHING )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == TEACHING ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_TEACH ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == HEAVY_WEAPS )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == HEAVY_WEAPS ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_HEAVY ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == AUTO_WEAPS )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == AUTO_WEAPS ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_AUTO ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == STEALTHY )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == STEALTHY ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_STEALTH ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == AMBIDEXT)||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == AMBIDEXT) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_AMBI ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == THIEF )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == THIEF ) )
- {
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_THIEF ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == MARTIALARTS )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == MARTIALARTS ) )
+ ///////////////////////////////////////////////////////////////////////////////
+ // SANDRO - switch for old/new traits
+ if ( gGameOptions.fNewTraitSystem )
{
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_MARTIAL ), MAIL_STRING_SIZE );
-
- // add to list
- AddEmailRecordToList( pString );
+ // Auto Weapons
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, AUTO_WEAPONS_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_AUTO ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Heavy Weapons
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, HEAVY_WEAPONS_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_HEAVY ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Sniper
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, SNIPER_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[0]);
+ AddEmailRecordToList( pString );
+ }
+ // Ranger
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, RANGER_NT ) > 0 )
+ {
+ if ( gGameExternalOptions.fShowCamouflageFaces == TRUE )
+ {
+ gCamoFace[iCurrentIMPSlot].gCamoface = TRUE;
+ gCamoFace[iCurrentIMPSlot].gUrbanCamoface = FALSE;
+ gCamoFace[iCurrentIMPSlot].gDesertCamoface = FALSE;
+ gCamoFace[iCurrentIMPSlot].gSnowCamoface = FALSE;
+ }
+ wcscpy(pString, MissingIMPSkillsDescriptions[2]);
+ AddEmailRecordToList( pString );
+ }
+ // Gunslinger
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, GUNSLINGER_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[3]);
+ AddEmailRecordToList( pString );
+ }
+ // Martial Artist
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, MARTIAL_ARTS_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_MARTIAL ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Squadleader
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, SQUADLEADER_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[4]);
+ AddEmailRecordToList( pString );
+ }
+ // Technician
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, TECHNICIAN_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[5]);
+ AddEmailRecordToList( pString );
+ }
+ // Doctor
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, DOCTOR_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[6]);
+ AddEmailRecordToList( pString );
+ }
+ // Ambidextrous
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, AMBIDEXTROUS_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_AMBI ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Melee
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, MELEE_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_KNIFE ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Throwing
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, THROWING_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_THROW ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Night Ops
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, NIGHT_OPS_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_NIGHT ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Stealthy
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, STEALTHY_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_STEALTH ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Athletics
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, ATHLETICS_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[7]);
+ AddEmailRecordToList( pString );
+ }
+ // Bodybuilding
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, BODYBUILDING_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[8]);
+ AddEmailRecordToList( pString );
+ }
+ // Demolitions
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, DEMOLITIONS_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[9]);
+ AddEmailRecordToList( pString );
+ }
+ // Teaching
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, TEACHING_NT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_TEACH ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Scouting
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, SCOUTING_NT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[10]);
+ AddEmailRecordToList( pString );
+ }
+ }
+ else
+ {
+ // Lockpick
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, LOCKPICKING_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_LOCK ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Hand to Hand
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, HANDTOHAND_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_HAND ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Electronics
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, ELECTRONICS_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_ELEC ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Night Ops
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, NIGHTOPS_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_NIGHT ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Throwing
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, THROWING_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_THROW ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Teaching
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, TEACHING_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_TEACH ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Heavy Weapons
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, HEAVY_WEAPS_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_HEAVY ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Auto Weapons
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, AUTO_WEAPS_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_AUTO ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Stealthy
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, STEALTHY_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_STEALTH ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Ambidextrous
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, AMBIDEXT_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_AMBI ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Thief
+ /*if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == THIEF_OT )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == THIEF_OT ) )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_THIEF ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }*/
+ // Martial Arts
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, MARTIALARTS_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_MARTIAL ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Knifing
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, KNIFING_OT ) > 0 )
+ {
+ LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_KNIFE ), MAIL_STRING_SIZE );
+ AddEmailRecordToList( pString );
+ }
+ // Sniper
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, PROF_SNIPER_OT ) > 0 )
+ {
+ wcscpy(pString, MissingIMPSkillsDescriptions[0]);
+ // add to list
+ AddEmailRecordToList( pString );
+ }
+ // Camouflage
+ if ( ProfileHasSkillTrait( iCurrentIMPSlot, CAMOUFLAGED_OT ) > 0 )
+ {
+ if ( gGameExternalOptions.fShowCamouflageFaces == TRUE )
+ {
+ gCamoFace[iCurrentIMPSlot].gCamoface = TRUE;
+ gCamoFace[iCurrentIMPSlot].gUrbanCamoface = FALSE;
+ gCamoFace[iCurrentIMPSlot].gDesertCamoface = FALSE;
+ gCamoFace[iCurrentIMPSlot].gSnowCamoface = FALSE;
+ }
+ wcscpy(pString, MissingIMPSkillsDescriptions[1]);
+ AddEmailRecordToList( pString );
+ }
}
- // rooftop
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == PROF_SNIPER )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == PROF_SNIPER ) )
- {
- // WANNE: No entry in the Impass.edt for rooftop, so add any static text here
- // read one record from email file
- //LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_ONROOF ), MAIL_STRING_SIZE );
-
- wcscpy(pString, MissingIMPSkillsDescriptions[0]);
-
- //#ifdef GERMAN
- // wcscpy(pString, L"Dach-Treffer Bonus: ");
- //#else
- //wcscpy(pString, L"Sniper: ");
- //#endif
-
- // add to list
- AddEmailRecordToList( pString );
- }
-
- // camouflage
- if( ( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait == CAMOUFLAGED )||( gMercProfiles[ iCurrentIMPSlot ].bSkillTrait2 == CAMOUFLAGED ) )
- {
- // WANNE: No entry in the Impass.edt for camouflage, so add any static text here
- // read one record from email file
- //LoadEncryptedDataFromFile( "BINARYDATA\\Impass.edt", pString, MAIL_STRING_SIZE * ( IMP_SKILLS_SPECIAL_CAMOUFLAGED ), MAIL_STRING_SIZE );
-
- wcscpy(pString, MissingIMPSkillsDescriptions[1]);
-
- /*#ifdef GERMAN
- wcscpy(pString, L"Getarnt: ");
- #else
- wcscpy(pString, L"Camouflage: ");
- #endif*/
-
- // add to list
- AddEmailRecordToList( pString );
- }
+ ///////////////////////////////////////////////////////////////////////////////
// now the physical
// imperial physical
@@ -4770,6 +4876,7 @@ void ShutDownEmailList()
ClearPages();
}
+// Pre Process the mail, when clicking on a mail in the mail list
void PreProcessEmail( EmailPtr pMail )
{
RecordPtr pTempRecord, pCurrentRecord, pLastRecord , pTempList;
@@ -4791,21 +4898,31 @@ void PreProcessEmail( EmailPtr pMail )
// WANNE: Get the text and replace name!
int iNew113MERCMerc = 0;
+ int iNew113AIMMerc = 0;
+
if (pMail->usLength == MERC_UP_LEVEL_GASTON || pMail->usLength == MERC_UP_LEVEL_STOGIE ||
pMail->usLength == MERC_UP_LEVEL_TEX || pMail->usLength == MERC_UP_LEVEL_BIGGENS)
{
iNew113MERCMerc = pMail->usLength;
pMail->usLength = 2;
}
+ else if (pMail->usLength >= 170 && pMail->usLength <= 177)
+ {
+ iNew113AIMMerc = pMail->usLength;
+ pMail->usLength = 2;
+ }
// list doesn't exist, reload
if( !pTempRecord )
{
- while(pMail->usLength > iCounter)
+ while(pMail->usLength > iCounter)
{
- // read one record from email file
- LoadEncryptedDataFromFile( "BINARYDATA\\Email.edt", pString, MAIL_STRING_SIZE * ( iOffSet + iCounter ), MAIL_STRING_SIZE );
+ // read one record from email file
+ LoadEncryptedDataFromFile( "BINARYDATA\\Email.edt", pString, MAIL_STRING_SIZE * ( iOffSet + iCounter ), MAIL_STRING_SIZE );
+ // ----------------
+ // New MERC Merc
+ // ----------------
// WANNE: We have a new 1.13 MERC merc (Text, Gaston, Stogie or Biggens)
if (iNew113MERCMerc != 0)
{
@@ -4815,8 +4932,7 @@ void PreProcessEmail( EmailPtr pMail )
wcscpy(pString, L"\0");
if (iNew113MERCMerc == MERC_UP_LEVEL_GASTON)
{
- wcscpy( pString, New113MERCMercMailTexts[0] );
-
+ wcscpy( pString, New113MERCMercMailTexts[0] );
}
else if (iNew113MERCMerc == MERC_UP_LEVEL_STOGIE)
{
@@ -4832,21 +4948,73 @@ void PreProcessEmail( EmailPtr pMail )
}
}
}
+
+ // ----------------
+ // New AIM Merc
+ // ----------------
+ // WANNE: We have a new 1.13 MERC merc (Text, Gaston, Stogie or Biggens)
+ if (iNew113AIMMerc != 0)
+ {
+ wcscpy(pString, L"\0");
+
+ // Only output the mail text, not the subject, cause we already have the subject as text
+ if (iCounter == 1)
+ {
+ if (iNew113AIMMerc == 170)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[1] );
+ }
+ else if (iNew113MERCMerc == 171)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[3] );
+ }
+ else if (iNew113MERCMerc == 172)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[5] );
+ }
+ else if (iNew113MERCMerc == 173)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[7] );
+ }
+ else if (iNew113MERCMerc == 174)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[9] );
+ }
+ else if (iNew113MERCMerc == 175)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[11] );
+ }
+ else if (iNew113MERCMerc == 176)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[13] );
+ }
+ else if (iNew113MERCMerc == 177)
+ {
+ wcscpy( pString, New113AIMMercMailTexts[15] );
+ }
+ }
+ }
// add to list
AddEmailRecordToList( pString );
- // increment email record counter
- iCounter++;
- }
+ // increment email record counter
+ iCounter++;
+ }
- // WANNE: Set the value back
- if (iNew113MERCMerc != 0)
- {
- pMail->usLength = iNew113MERCMerc;
- }
+ // WANNE: Set the value back
+ if (iNew113MERCMerc != 0)
+ {
+ pMail->usLength = iNew113MERCMerc;
+ }
- giPrevMessageId = giMessageId;
+ // WANNE: Set the value back
+ if (iNew113AIMMerc != 0)
+ {
+ pMail->usLength = iNew113AIMMerc;
+ }
+
+ giPrevMessageId = giMessageId;
}
diff --git a/Laptop/email.h b/Laptop/email.h
index d9b072ac..c8112929 100644
--- a/Laptop/email.h
+++ b/Laptop/email.h
@@ -144,12 +144,12 @@
//#define MERC_UP_LEVEL_BIGGENS (MERC_UP_LEVEL_TEX + MERC_UP_LEVEL_TEX_LENGTH)
//#define MERC_UP_LEVEL_BIGGENS_LENGTH 2
+
#define MERC_UP_LEVEL_GASTON 165
#define MERC_UP_LEVEL_STOGIE 166
#define MERC_UP_LEVEL_TEX 167
#define MERC_UP_LEVEL_BIGGENS 168
-
struct message{
STR16 pString;
struct message *Next;
@@ -299,6 +299,10 @@ void RemoveEmailMessage(INT32 iId);
EmailPtr GetEmailMessage(INT32 iId);
void LookForUnread();
void AddEmail(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32 iDate, INT32 iCurrentIMPPosition);
+
+// WANNE: For the new WF merc
+void AddEmailWFMercLevelUp(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32 iDate, INT32 iCurrentIMPPosition);
+
void AddPreReadEmail(INT32 iMessageOffset, INT32 iMessageLength, UINT8 ubSender, INT32 iDate);
BOOLEAN DisplayNewMailBox();
void CreateDestroyNewMailButton();
diff --git a/Laptop/finances.cpp b/Laptop/finances.cpp
index 8aded9e3..1d3646cb 100644
--- a/Laptop/finances.cpp
+++ b/Laptop/finances.cpp
@@ -409,7 +409,7 @@ INT32 GetProjectedTotalDailyIncome( void )
// HEADROCK HAM 3.6: Facilities can make you money, and this is figured into your daily income.
INT32 iRate = 0;
- iRate = PredictIncomeFromPlayerMines() + (15 * GetTotalFacilityHourlyCosts( TRUE )); // 15 hours is the average time a merc can work per day
+ iRate = PredictIncomeFromPlayerMines(TRUE) + (15 * GetTotalFacilityHourlyCosts( TRUE )); // 15 hours is the average time a merc can work per day
return( iRate );
}
@@ -1167,21 +1167,23 @@ void OpenAndReadFinancesFile( void )
// file exists, read in data, continue until file end
while( FileGetSize( hFileHandle ) > uiByteCount)
{
-
// read in other data
- FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
+
// add transaction
- ProcessAndEnterAFinacialRecord(ubCode, uiDate, iAmount, ubSecondCode, iBalanceToDate);
+ ProcessAndEnterAFinacialRecord(ubCode, uiDate, iAmount, ubSecondCode, iBalanceToDate);
// increment byte counter
- uiByteCount += sizeof( INT32 ) + sizeof( UINT32 ) + sizeof( UINT8 )+ sizeof(UINT8) + sizeof( INT32 );
+ uiByteCount += sizeof( INT32 ) + sizeof( UINT32 ) + sizeof( UINT8 )+ sizeof(UINT8) + sizeof( INT32 );
}
// close file
@@ -1906,19 +1908,23 @@ BOOLEAN LoadInRecords( UINT32 uiPage )
{
// read in data
- FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+ // WANNE: Do not add the fix + 1 day here, because otherwise we have a day + 1 offset
+ // WANNE: Fix uiDate (add 1 day!)!
+ //uiDate += 1500;
+
// add transaction
- ProcessAndEnterAFinacialRecord(ubCode, uiDate, iAmount, ubSecondCode, iBalanceToDate);
+ ProcessAndEnterAFinacialRecord(ubCode, uiDate, iAmount, ubSecondCode, iBalanceToDate);
// increment byte counter
- uiByteCount += sizeof( INT32 ) + sizeof( UINT32 ) + sizeof( UINT8 )+ sizeof(UINT8) + sizeof( INT32 );
+ uiByteCount += sizeof( INT32 ) + sizeof( UINT32 ) + sizeof( UINT8 )+ sizeof(UINT8) + sizeof( INT32 );
// we've overextended our welcome, and bypassed end of file, get out
if( uiByteCount >= FileGetSize( hFileHandle ) )
@@ -2127,8 +2133,11 @@ INT32 GetPreviousDaysBalance( void )
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
// check to see if we are far enough
if( ( uiDate / ( 24 * 60 ) ) == ( iDateInMinutes / ( 24 * 60 ) ) - 2 )
@@ -2221,10 +2230,14 @@ INT32 GetTodaysBalance( void )
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
+
// check to see if we are far enough
if( ( uiDate / ( 24 * 60 ) ) == ( iDateInMinutes / ( 24 * 60 ) ) - 1 )
{
@@ -2301,15 +2314,19 @@ INT32 GetPreviousDaysIncome( void )
// incrment byte count
iByteCount += RECORD_SIZE;
- FileGetPos( hFileHandle );
+ FileGetPos( hFileHandle );
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
+
// check to see if we are far enough
if( ( uiDate / ( 24 * 60 ) )== ( iDateInMinutes / ( 24 * 60 ) ) - 2 )
{
@@ -2318,7 +2335,7 @@ INT32 GetPreviousDaysIncome( void )
// there are no entries for the previous day
if( ( uiDate / ( 24 * 60 ) ) < ( iDateInMinutes / ( 24 * 60 ) ) - 2 )
- {
+ {
fGoneTooFar = TRUE;
}
@@ -2402,10 +2419,14 @@ INT32 GetTodaysDaysIncome( void )
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
+
// check to see if we are far enough
if( ( uiDate / ( 24 * 60 ) ) == ( iDateInMinutes / ( 24 * 60 ) ) - 1 )
{
@@ -2527,16 +2548,20 @@ INT32 GetTodaysOtherDeposits( void )
{
FileSeek( hFileHandle, RECORD_SIZE * iCounter , FILE_SEEK_FROM_END );
- // incrment byte count
- iByteCount += RECORD_SIZE;
+ // incrment byte count
+ iByteCount += RECORD_SIZE;
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
+
// check to see if we are far enough
if( ( uiDate / ( 24 * 60 ) ) == ( iDateInMinutes / ( 24 * 60 ) ) - 1 )
{
@@ -2629,10 +2654,14 @@ INT32 GetYesterdaysOtherDeposits( void )
FileRead( hFileHandle, &ubCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &ubSecondCode, sizeof(UINT8), (UINT32 *)&iBytesRead );
FileRead( hFileHandle, &uiDate, sizeof(UINT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
- FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iAmount, sizeof(INT32), (UINT32 *)&iBytesRead );
+ FileRead( hFileHandle, &iBalanceToDate, sizeof(INT32), (UINT32 *)&iBytesRead );
AssertMsg( iBytesRead, "Failed To Read Data Entry");
+
+ // WANNE: Fix uiDate (add 1 day!)!
+ uiDate += 1500;
+
// check to see if we are far enough
if( ( uiDate / ( 24 * 60 ) )== ( iDateInMinutes / ( 24 * 60 ) ) - 2 )
{
diff --git a/Laptop/finances.h b/Laptop/finances.h
index f3185a0c..3da88793 100644
--- a/Laptop/finances.h
+++ b/Laptop/finances.h
@@ -53,6 +53,7 @@ enum
SOLD_ITEMS,
FACILITY_OPERATIONS, // HEADROCK HAM 3.6: Facility costs (daily payment)
MILITIA_UPKEEP, // HEADROCK HAM 3.6: Militia Upkeep Costs (daily payment)
+ TEXT_NUM_FINCANCES
};
diff --git a/Laptop/history.h b/Laptop/history.h
index 826bc04c..027e14cb 100644
--- a/Laptop/history.h
+++ b/Laptop/history.h
@@ -103,6 +103,7 @@ enum{
HISTORY_GAVE_CARMEN_HEAD,
HISTORY_SLAY_MYSTERIOUSLY_LEFT,
HISTORY_MERC_KILLED_CHARACTER,
+ TEXT_NUM_HISTORY
};
typedef struct history HistoryUnit;
diff --git a/Laptop/laptop.h b/Laptop/laptop.h
index b0898a47..8d279b98 100644
--- a/Laptop/laptop.h
+++ b/Laptop/laptop.h
@@ -194,6 +194,7 @@ enum{
FLORIST_BOOKMARK,
INSURANCE_BOOKMARK,
CANCEL_STRING,
+ TEXT_NUM_LAPTOP_BOOKMARKS
};
diff --git a/Laptop/mercs Account.cpp b/Laptop/mercs Account.cpp
index dc3c22fb..84dc2da4 100644
--- a/Laptop/mercs Account.cpp
+++ b/Laptop/mercs Account.cpp
@@ -189,9 +189,14 @@ INT32 GetNumberOfHiredMercs()
for (i = 0; i<=(NUMBER_OF_MERCS - 1); i++)
{
- if( i == MERC_LARRY_ROACHBURN )
+ // WANNE: If we have drunken merc, then skip otherwise is will exist 2 times!
+ if (gConditionsForMercAvailability[ i ].Drunk)
continue;
+ // WANNE.LARRY
+ /*if( i == MERC_LARRY_ROACHBURN )
+ continue;*/
+
usMercID = GetMercIDFromMERCArray( i );
// Is the merc hired?
@@ -489,6 +494,7 @@ void DisplayHiredMercs()
usMercIDEnd = usMercIDStart + MAX_NUMBER_MERCS_ON_PAGE;
}
+ // WANNE.LARRY: I don't understand why this is needed??? I did not change anything on this yet.
// At least second page
// This approach is needed, because auf LARRY_ROACHBURN
if (usMercIDStart > 0)
@@ -503,10 +509,15 @@ void DisplayHiredMercs()
if (usCurrentRow == usMercIDEnd - 1)
break;
- //if it larry Roach burn advance. ( cause larry is in twice, a sober larry and a stoned larry )
- if( i == MERC_LARRY_ROACHBURN )
+ // WANNE: If we have drunken merc, then skip otherwise is will exist 2 times!
+ if (gConditionsForMercAvailability[ i ].Drunk)
continue;
+ // WANNE.LARRY
+ //if it larry Roach burn advance. ( cause larry is in twice, a sober larry and a stoned larry )
+ /*if( i == MERC_LARRY_ROACHBURN )
+ continue;*/
+
usMercID = GetMercIDFromMERCArray( i );
//is the merc on the team, or is owed money
@@ -741,9 +752,14 @@ UINT32 CalculateHowMuchPlayerOwesSpeck()
for(i=0; i<(NUMBER_OF_MERCS - 1); i++)
{
- //if it larry Roach burn advance. ( cause larry is in twice, a sober larry and a stoned larry )
- if( i == MERC_LARRY_ROACHBURN )
+ // WANNE: If we have drunken merc, then skip otherwise is will exist 2 times!
+ if (gConditionsForMercAvailability[ i ].Drunk)
continue;
+
+ // WANNE.LARRY
+ //if it larry Roach burn advance. ( cause larry is in twice, a sober larry and a stoned larry )
+ //if( i == MERC_LARRY_ROACHBURN )
+ // continue;
usMercID = GetMercIDFromMERCArray( i );
//if( IsMercOnTeam( (UINT8)usMercID ) )
diff --git a/Laptop/mercs Files.cpp b/Laptop/mercs Files.cpp
index 3e70115a..7a92745f 100644
Binary files a/Laptop/mercs Files.cpp and b/Laptop/mercs Files.cpp differ
diff --git a/Laptop/mercs.cpp b/Laptop/mercs.cpp
index 1aaa37eb..fc481d3b 100644
--- a/Laptop/mercs.cpp
+++ b/Laptop/mercs.cpp
@@ -29,8 +29,9 @@
#include "connect.h"
-UINT8 NUMBER_OF_MERCS;
-UINT8 LAST_MERC_ID;
+UINT8 NUMBER_OF_MERCS = 0;
+UINT8 LAST_MERC_ID = -1;
+UINT8 NUMBER_OF_BAD_MERCS = -1;
#define MERC_TEXT_FONT FONT12ARIAL
#define MERC_TEXT_COLOR FONT_MCOLOR_WHITE
@@ -117,30 +118,9 @@ UINT8 LAST_MERC_ID;
#define MERC__AMOUNT_OF_MONEY_FOR_BUBBA 6000
#define MERC__DAY_WHEN_BUBBA_CAN_BECOME_AVAILABLE 10
-
-enum
-{
- MERC_ARRIVES_BUBBA,
- MERC_ARRIVES_LARRY,
- MERC_ARRIVES_NUMB,
- MERC_ARRIVES_TEX,
- MERC_ARRIVES_BIGGENS,
- MERC_ARRIVES_COUGAR,
- MERC_ARRIVES_GASTON,
- MERC_ARRIVES_STOGIE,
-
- NUM_MERC_ARRIVALS,
-};
-
-typedef struct
-{
- UINT16 usMoneyPaid;
- UINT16 usDay;
- UINT8 ubMercArrayID;
-
-} CONTITION_FOR_MERC_AVAILABLE;
-
-CONTITION_FOR_MERC_AVAILABLE gConditionsForMercAvailability[ NUM_MERC_ARRIVALS ] =
+CONTITION_FOR_MERC_AVAILABLE_TEMP gConditionsForMercAvailabilityTemp[ NUM_PROFILES ];
+CONTITION_FOR_MERC_AVAILABLE gConditionsForMercAvailability[ NUM_PROFILES ]; //NUM_MERC_ARRIVALS ]; //=
+/*
{
5000, 8, 6, //BUBBA
10000, 15, 7, //Larry
@@ -152,7 +132,7 @@ CONTITION_FOR_MERC_AVAILABLE gConditionsForMercAvailability[ NUM_MERC_ARRIVALS ]
26000, 31, 14, //Stogie
};
-
+*/
enum
{
@@ -183,7 +163,7 @@ UINT32 guiMercBackGround;
UINT32 guiMercVideoFaceBackground;
UINT32 guiMercVideoPopupBackground;
-UINT8 gubMercArray[ MAX_NUMBER_OF_MERCS ];
+UINT8 gubMercArray[ NUM_PROFILES ]; //MAX_NUMBER_OF_MERCS
UINT8 gubCurMercIndex;
INT32 iMercPopUpBox = -1;
@@ -281,6 +261,8 @@ MOUSE_REGION gMercSiteSubTitleMouseRegion;
void MercSiteSubTitleRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason );
+BOOLEAN LoadNewMercsFromLoadGameFile( HWFILE hFile );
+BOOLEAN SaveNewMercsToSaveGameFile( HWFILE hFile );
//*******************************
@@ -324,47 +306,57 @@ BOOLEAN CanMercBeAvailableYet( UINT8 ubMercToCheck );
UINT32 CalcMercDaysServed();
//ppp
+BOOLEAN SaveNewMercsToSaveGameFile( HWFILE hFile )
+{
+ UINT32 uiNumBytesWritten;
+
+ FileWrite( hFile, &gConditionsForMercAvailability, sizeof( gConditionsForMercAvailability), &uiNumBytesWritten );
+ if( uiNumBytesWritten != sizeof( gConditionsForMercAvailability ) )
+ {
+ return( FALSE );
+ }
+
+ return( TRUE );
+}
+
+BOOLEAN LoadNewMercsFromLoadGameFile( HWFILE hFile )
+{
+ UINT32 uiNumBytesRead;
+
+ FileRead( hFile, &gConditionsForMercAvailability, sizeof( gConditionsForMercAvailability ), &uiNumBytesRead );
+ if( uiNumBytesRead != sizeof( gConditionsForMercAvailability ) )
+ {
+ return( FALSE );
+ }
+
+ return( TRUE );
+}
void GameInitMercs()
{
-// for(i=0; i fortlaufende ID, und nicht die mercID
+// -> bei aktuellen Merc passt es
+// -> bei departed Merc wird die MercId anstatt der fortlaufenden ID bergeben!!
void RenderPersonnelFace(INT32 iId, INT32 iSlot, BOOLEAN fDead, BOOLEAN fFired, BOOLEAN fOther )
{
+ // Get the profile id (from profileId or slotId)
+ INT32 profileId = iId;
+ if (profileId == -1)
+ {
+ profileId = MercPtrs[iSlot]->ubProfile;
+ }
+
char sTemp[100];
HVOBJECT hFaceHandle;
VOBJECT_DESC VObjectDesc;
// draw face to soldier iId in slot iSlot
+ // Currently active merc!
// special case?..player generated merc
- if (fCurrentTeamMode) {
- if( ( 50 < MercPtrs[iId]->ubProfile )&&( 57 > MercPtrs[iId]->ubProfile ) )
+ if (fCurrentTeamMode)
+ {
+ if( ( 50 < profileId )&&( 57 > profileId ) )
{
- sprintf( sTemp, "%s%03d.sti", FACES_DIR, gMercProfiles[ MercPtrs[iId]->ubProfile ].ubFaceIndex );
+ sprintf( sTemp, "%s%03d.sti", FACES_DIR, gMercProfiles[profileId].ubFaceIndex );
}
else
- {
- if (gGameExternalOptions.fReadProfileDataFromXML)
- {
- // HEADROCK PROFEX: Do not read direct profile number, instead, look inside the profile for a ubFaceIndex value.
- sprintf(sTemp, "%s%02d.sti", FACES_DIR, gMercProfiles[Menptr[ iId ].ubProfile].ubFaceIndex);
- }
- else
- {
- sprintf(sTemp, "%s%02d.sti", FACES_DIR, Menptr[ iId ].ubProfile);
- }
+ {
+ sprintf(sTemp, "%s%02d.sti", FACES_DIR, gMercProfiles[profileId].ubFaceIndex);
}
- if( MercPtrs[iId]->flags.uiStatusFlags & SOLDIER_VEHICLE ) {
+ // TODO: Check if needed!
+ if( MercPtrs[iSlot]->flags.uiStatusFlags & SOLDIER_VEHICLE )
+ {
return;
}
- } else {
+ }
+ // departed mercs
+ else
+ {
//if this is not a valid merc
- if( !fDead && !fFired && !fOther ) {
+ if( !fDead && !fFired && !fOther )
+ {
return;
}
- if( ( 50 < iId )&&( 57 > iId ) )
+ if( ( 50 < profileId )&&( 57 > profileId ) )
{
- sprintf( sTemp, "%s%03d.sti", FACES_DIR, gMercProfiles[ iId ].ubFaceIndex );
+ sprintf( sTemp, "%s%03d.sti", FACES_DIR, gMercProfiles[profileId].ubFaceIndex );
}
else
{
- if (gGameExternalOptions.fReadProfileDataFromXML)
- {
- // HEADROCK PROFEX: Do not read direct profile number, instead, look inside the profile for a ubFaceIndex value.
- sprintf(sTemp, "%s%02d.sti", FACES_DIR, gMercProfiles[Menptr[ iId ].ubProfile].ubFaceIndex );
- }
- else
- {
- sprintf(sTemp, "%s%02d.sti", FACES_DIR, iId );
- }
+ sprintf(sTemp, "%s%02d.sti", FACES_DIR, gMercProfiles[profileId].ubFaceIndex );
}
}
@@ -876,34 +870,45 @@ void RenderPersonnelFace(INT32 iId, INT32 iSlot, BOOLEAN fDead, BOOLEAN fFired,
//Blt face to screen to
GetVideoObject(&hFaceHandle, guiFACE);
- if (fCurrentTeamMode) {
- if( MercPtrs[iId]->stats.bLife <= 0 ) {
+ if (fCurrentTeamMode)
+ {
+ if( MercPtrs[iSlot]->stats.bLife <= 0 )
+ {
hFaceHandle->pShades[ 0 ] = Create16BPPPaletteShaded( hFaceHandle->pPaletteEntry, DEAD_MERC_COLOR_RED, DEAD_MERC_COLOR_GREEN, DEAD_MERC_COLOR_BLUE, TRUE );
//set the red pallete to the face
SetObjectHandleShade( guiFACE, 0 );
}
- } else {
- if (fDead == TRUE) {
+ }
+ else
+ {
+ if (fDead == TRUE)
+ {
hFaceHandle->pShades[ 0 ] = Create16BPPPaletteShaded( hFaceHandle->pPaletteEntry, DEAD_MERC_COLOR_RED, DEAD_MERC_COLOR_GREEN, DEAD_MERC_COLOR_BLUE, TRUE );
//set the red pallete to the face
SetObjectHandleShade( guiFACE, 0 );
}
}
- BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,IMAGE_BOX_X+(iSlot*IMAGE_BOX_WIDTH), IMAGE_BOX_Y, VO_BLT_SRCTRANSPARENCY,NULL);
+ // TODO:Check
+ BltVideoObject(FRAME_BUFFER, hFaceHandle, 0,IMAGE_BOX_X, IMAGE_BOX_Y, VO_BLT_SRCTRANSPARENCY,NULL);
//if the merc is dead, display it
- if (!fCurrentTeamMode) {
- INT32 iHeightOfText = DisplayWrappedString(IMAGE_BOX_X, (UINT16)(IMAGE_BOX_Y+IMAGE_FULL_NAME_OFFSET_Y), IMAGE_NAME_WIDTH, 1, PERS_FONT, PERS_FONT_COLOR, gMercProfiles[ iId ].zName, 0, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT );
+ if (!fCurrentTeamMode)
+ {
+ INT32 iHeightOfText = DisplayWrappedString(IMAGE_BOX_X, (UINT16)(IMAGE_BOX_Y+IMAGE_FULL_NAME_OFFSET_Y), IMAGE_NAME_WIDTH, 1, PERS_FONT, PERS_FONT_COLOR, gMercProfiles[profileId].zName, 0, FALSE, CENTER_JUSTIFIED | DONT_DISPLAY_TEXT );
//if the string will rap
- if( ( iHeightOfText - 2 ) > GetFontHeight( PERS_FONT ) ) {
+ if( ( iHeightOfText - 2 ) > GetFontHeight( PERS_FONT ) )
+ {
//raise where we display it, and rap it
- DisplayWrappedString(IMAGE_BOX_X, (UINT16)(IMAGE_BOX_Y+IMAGE_FULL_NAME_OFFSET_Y - GetFontHeight( PERS_FONT )), IMAGE_NAME_WIDTH, 1, PERS_FONT, PERS_FONT_COLOR, gMercProfiles[ iId ].zName, 0, FALSE, CENTER_JUSTIFIED);
- } else {
- DrawTextToScreen( gMercProfiles[ iId ].zName, IMAGE_BOX_X, (UINT16)(IMAGE_BOX_Y+IMAGE_FULL_NAME_OFFSET_Y), IMAGE_NAME_WIDTH, PERS_FONT, PERS_FONT_COLOR, 0, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString(IMAGE_BOX_X, (UINT16)(IMAGE_BOX_Y+IMAGE_FULL_NAME_OFFSET_Y - GetFontHeight( PERS_FONT )), IMAGE_NAME_WIDTH, 1, PERS_FONT, PERS_FONT_COLOR, gMercProfiles[profileId].zName, 0, FALSE, CENTER_JUSTIFIED);
+ }
+ else
+ {
+ DrawTextToScreen( gMercProfiles[profileId].zName, IMAGE_BOX_X, (UINT16)(IMAGE_BOX_Y+IMAGE_FULL_NAME_OFFSET_Y), IMAGE_NAME_WIDTH, PERS_FONT, PERS_FONT_COLOR, 0, FALSE, CENTER_JUSTIFIED );
}
}
+
DeleteVideoObjectFromIndex(guiFACE);
}
@@ -1343,6 +1348,15 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
SOLDIERTYPE *pSoldier = &Menptr[iId];
BOOLEAN fAmIaRobot = AM_A_ROBOT( pSoldier );
+ // SANDRO - remove the regions
+ for( INT8 i = 0; i < 13; i++ )
+ {
+ if( fAddedTraitRegion[i] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[i] );
+ fAddedTraitRegion[i] = FALSE;
+ }
+ }
if( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
@@ -1618,57 +1632,65 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
mprintf(sX,pPersonnelScreenPoints[iCounter].y,sString);
break;
- case 14:
- // kills
- mprintf((INT16)(pPersonnelScreenPoints[21].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[21].y,pPersonnelScreenStrings[PRSNL_TXT_KILLS]);
- swprintf(sString, L"%d",gMercProfiles[Menptr[iId].ubProfile].usKills);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[21].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[21].y,sString);
- break;
+ /////////////////////////////////////////////////////////////////////////
+ // Added by SANDRO
case 15:
- // assists
- mprintf((INT16)(pPersonnelScreenPoints[22].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[22].y,pPersonnelScreenStrings[PRSNL_TXT_ASSISTS]);
- swprintf(sString, L"%d",gMercProfiles[Menptr[iId].ubProfile].usAssists);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[22].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[22].y,sString);
- break;
- case 16:
- // shots/hits
- mprintf((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[23].y,pPersonnelScreenStrings[PRSNL_TXT_HIT_PERCENTAGE]);
- uiHits = ( UINT32 )gMercProfiles[Menptr[iId].ubProfile].usShotsHit;
- uiHits *= 100;
+ // Character Trait
+ mprintf((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[23].y + 15),pPersonnelRecordsHelpTexts[43]); //L"Character:"
+ swprintf(sString, gzIMPCharacterTraitText[gMercProfiles[Menptr[iId].ubProfile].bCharacterTrait]);
- // check we have shot at least once
- if( gMercProfiles[Menptr[iId].ubProfile].usShotsFired > 0 )
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[23].y + 15),sString);
+
+ //GetVideoObject(&hHandle, guiQMark);
+ //BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[23].x + 148), ( pPersonnelScreenPoints[23].y + 5), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[5] )
{
- uiHits /= ( UINT32 )gMercProfiles[Menptr[iId].ubProfile].usShotsFired;
- }
- else
- {
- // no, set hit % to 0
- uiHits = 0;
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[5] );
}
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[5], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[23].y + 10),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[23].y + 17 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ //MSYS_DefineRegion( &gSkillTraitHelpTextRegion[3], (UINT16)( pPersonnelScreenPoints[23].x + 147 ), (UINT16)(pPersonnelScreenPoints[23].y + 4),
+ // (UINT16)( pPersonnelScreenPoints[23].x + 166 ), (UINT16)(pPersonnelScreenPoints[23].y + 15), MSYS_PRIORITY_HIGH,
+ // MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[5] );
+ fAddedTraitRegion[5] = TRUE;
+ // Assign the text
+ AssignPersonnelCharacterTraitHelpText( gMercProfiles[Menptr[iId].ubProfile].bCharacterTrait );
+ break;
- swprintf(sString, L"%d %%%%",uiHits);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- sX += StringPixLength( L"%", PERS_FONT );
- mprintf(sX,pPersonnelScreenPoints[23].y,sString);
- break;
- case 17:
- // battles
- mprintf((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[24].y,pPersonnelScreenStrings[PRSNL_TXT_BATTLES]);
- swprintf(sString, L"%d",gMercProfiles[Menptr[iId].ubProfile].usBattlesFought);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[24].y,sString);
- break;
case 18:
- // wounds
- mprintf((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[25].y,pPersonnelScreenStrings[PRSNL_TXT_TIMES_WOUNDED]);
- swprintf(sString, L"%d",gMercProfiles[Menptr[iId].ubProfile].usTimesWounded);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[25].y,sString);
+ // Disability
+ mprintf((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[25].y + 10),pPersonnelRecordsHelpTexts[44]); //L"Disability:"
+ swprintf(sString, gzIMPDisabilityTraitText[gMercProfiles[Menptr[iId].ubProfile].bDisability]);
+
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[25].y + 10),sString);
+
+ //GetVideoObject(&hHandle, guiQMark);
+ //BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[25].x + 148), ( pPersonnelScreenPoints[25].y ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[6] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[6] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[6], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[25].y + 10 ),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[25].y + 17 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ //MSYS_DefineRegion( &gSkillTraitHelpTextRegion[6], (UINT16)( pPersonnelScreenPoints[25].x + 147 ), (UINT16)( pPersonnelScreenPoints[25].y - 1),
+ // (UINT16)( pPersonnelScreenPoints[25].x + 166 ), (UINT16)(pPersonnelScreenPoints[25].y + 10), MSYS_PRIORITY_HIGH,
+ // MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[6] );
+ fAddedTraitRegion[6] = TRUE;
+ // Assign the text
+ AssignPersonnelDisabilityHelpText( gMercProfiles[Menptr[iId].ubProfile].bDisability );
break;
+ /////////////////////////////////////////////////////////////////////////
// The Mercs Skills
case 19:
@@ -1678,7 +1700,7 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
INT8 bScreenLocIndex = 19; //if you change the '19', change it below in the if statement
//Display the 'Skills' text
- mprintf( (INT16)( pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[bScreenLocIndex].y,pPersonnelScreenStrings[ PRSNL_TXT_SKILLS ] );
+ mprintf( (INT16)( pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[bScreenLocIndex].y),pPersonnelScreenStrings[ PRSNL_TXT_SKILLS ] );
//KM: April 16, 1999
//Added support for the German version, which has potential string overrun problems. For example, the text "Skills:" can
@@ -1689,67 +1711,256 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
if( !fAmIaRobot )
{
- INT8 bSkill1 = gMercProfiles[ Menptr[iId].ubProfile ].bSkillTrait;
- INT8 bSkill2 = gMercProfiles[ Menptr[iId].ubProfile ].bSkillTrait2;
-
- //if the 2 skills are the same, add the '(expert)' at the end
- if( bSkill1 == bSkill2 && bSkill1 != NO_SKILLTRAIT )
+ if (gGameOptions.fNewTraitSystem) // SANDRO - old/new traits check
{
- swprintf( sString, L"%s %s", gzMercSkillText[bSkill1], gzMercSkillText[NUM_SKILLTRAITS] );
+ UINT8 ubTempSkillArray[30];
+ INT8 bNumSkillTraits = 0;
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
-
- //KM: April 16, 1999
- //Perform the potential overrun check
- if( sX <= iMinimumX )
+ // lets rearrange our skills to a temp array
+ // we also get the number of lines (skills) to be displayed
+ for ( UINT8 ubCnt = 1; ubCnt < NUM_SKILLTRAITS_NT; ubCnt++ )
{
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[iCounter].x+(iSlot*TEXT_BOX_WIDTH) + TEXT_BOX_WIDTH-20 +TEXT_DELTA_OFFSET),0,30,0,sString, PERS_FONT, &sX, &sY);
- sX = (INT16)max( sX, iMinimumX );
+ if ( ProfileHasSkillTrait( Menptr[iId].ubProfile, ubCnt ) == 2 )
+ {
+ ubTempSkillArray[bNumSkillTraits] = (ubCnt + 19);
+ bNumSkillTraits++;
+ }
+ else if ( ProfileHasSkillTrait( Menptr[iId].ubProfile, ubCnt ) == 1 )
+ {
+ ubTempSkillArray[bNumSkillTraits] = ubCnt;
+ bNumSkillTraits++;
+ }
}
- mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
- }
- else
- {
- //Display the first skill
- if( bSkill1 != NO_SKILLTRAIT )
- {
- swprintf( sString, L"%s", gzMercSkillText[bSkill1] );
-
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
-
- //KM: April 16, 1999
- //Perform the potential overrun check
- sX = (INT16)max( sX, iMinimumX );
-
- mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
-
- bScreenLocIndex++;
- }
-
- //Display the second skill
- if( bSkill2 != NO_SKILLTRAIT )
- {
- swprintf( sString, L"%s", gzMercSkillText[bSkill2] );
-
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
-
- //KM: April 16, 1999
- //Perform the potential overrun check
- sX = (INT16)max( sX, iMinimumX );
-
- mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
-
- bScreenLocIndex++;
- }
-
- //if no skill was displayed
- if( bScreenLocIndex == 19 )
+ if ( bNumSkillTraits == 0 )
{
swprintf( sString, L"%s", pPersonnelScreenStrings[ PRSNL_TXT_NOSKILLS ] );
FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[0] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[0] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[0], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y ),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[0] );
+ fAddedTraitRegion[0] = TRUE;
+ // Assign the text
+ AssignPersonnelSkillTraitHelpText( 0, FALSE, iId, 0 );
+
+ }
+ else
+ {
+ CHAR16 sString2[500];
+ swprintf( sString2, L"" );
+ BOOLEAN fDisplayMoreTraits = FALSE;
+
+ for ( UINT8 ubCnt = 0; ubCnt < bNumSkillTraits; ubCnt++ )
+ {
+ if ( ubCnt >= 4 && bNumSkillTraits > 4 )
+ {
+ fDisplayMoreTraits = TRUE;
+ swprintf( sString, L"%s\n", gzMercSkillTextNew[ ubTempSkillArray[ubCnt] ] );
+ wcscat( sString2, sString );
+ }
+ else
+ {
+ swprintf( sString, L"%s", gzMercSkillTextNew[ ubTempSkillArray[ubCnt] ] );
+
+ if ( ubTempSkillArray[ubCnt] > 19 )
+ {
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, FONT10ARIALBOLD, &sX, &sY);
+
+ if( sX <= iMinimumX )
+ {
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH) + TEXT_BOX_WIDTH-20 +TEXT_DELTA_OFFSET),0,30,0,sString, FONT10ARIALBOLD, &sX, &sY);
+ sX = (INT16)max( sX, iMinimumX );
+ }
+ sY = (INT16)(pPersonnelScreenPoints[19].y + (ubCnt * 12));
+
+ SetFont( FONT10ARIALBOLD );
+ mprintf(sX,sY,sString);
+ SetFont( PERS_FONT );
+ }
+ else
+ {
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ if( sX <= iMinimumX )
+ {
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH) + TEXT_BOX_WIDTH-20 +TEXT_DELTA_OFFSET),0,30,0,sString, PERS_FONT, &sX, &sY);
+ sX = (INT16)max( sX, iMinimumX );
+ }
+ sY = (INT16)(pPersonnelScreenPoints[19].y + (ubCnt * 12));
+
+ mprintf(sX,sY,sString);
+
+ }
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[ubCnt] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[ubCnt] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[ubCnt], ( sX ), ( sY ),
+ ( sX + StringPixLength(sString,PERS_FONT) ), ( sY + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[ubCnt] );
+ fAddedTraitRegion[ubCnt] = TRUE;
+ // Assign the text
+ AssignPersonnelSkillTraitHelpText( ((ubTempSkillArray[ubCnt] > 19) ? (ubTempSkillArray[ubCnt]-19) : ubTempSkillArray[ubCnt]), ((ubTempSkillArray[ubCnt] > 19) ? TRUE : FALSE), Menptr[iId].ubProfile, ubCnt );
+ }
+ }
+
+ // if we have more skills than we can display, show "more" and create a tooltip box with the rest of them
+ if ( fDisplayMoreTraits )
+ {
+ swprintf( sString, L"%s", gzMercSkillTextNew[ 29 ]); // dispaly "More..."
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ if( sX <= iMinimumX )
+ {
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[19].x+(iSlot*TEXT_BOX_WIDTH) + TEXT_BOX_WIDTH-20 +TEXT_DELTA_OFFSET),0,30,0,sString, PERS_FONT, &sX, &sY);
+ sX = (INT16)max( sX, iMinimumX );
+ }
+ sY = (INT16)(pPersonnelScreenPoints[19].y + 48);
+
+ mprintf(sX,sY,sString);
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[4] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[4] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[4], ( sX ), ( sY ),
+ ( sX + StringPixLength(sString,PERS_FONT) ), ( sY + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[4] );
+ fAddedTraitRegion[4] = TRUE;
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[4]), sString2 );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[4], MSYS_NO_CALLBACK );
+ }
+ }
+ }
+ else
+ {
+ INT8 bSkill1 = 0, bSkill2 = 0;
+ bSkill1 = gMercProfiles[ Menptr[iId].ubProfile ].bSkillTraits[0];
+ bSkill2 = gMercProfiles[ Menptr[iId].ubProfile ].bSkillTraits[1];
+
+ //if the 2 skills are the same, add the '(expert)' at the end
+ if( bSkill1 == bSkill2 && bSkill1 != 0 )
+ {
+ swprintf( sString, L"%s %s", gzMercSkillText[bSkill1], gzMercSkillText[EXPERT] );
+
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+
+ //KM: April 16, 1999
+ //Perform the potential overrun check
+ if( sX <= iMinimumX )
+ {
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[iCounter].x+(iSlot*TEXT_BOX_WIDTH) + TEXT_BOX_WIDTH-20 +TEXT_DELTA_OFFSET),0,30,0,sString, PERS_FONT, &sX, &sY);
+ sX = (INT16)max( sX, iMinimumX );
+ }
+
+ mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[0] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[0] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[0], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y ),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[0] );
+ fAddedTraitRegion[0] = TRUE;
+ // Assign the text
+ AssignPersonnelSkillTraitHelpText( bSkill1, TRUE, iId, 0 );
+
+ }
+ else
+ {
+ //Display the first skill
+ if( bSkill1 != 0 )
+ {
+ swprintf( sString, L"%s", gzMercSkillText[bSkill1] );
+
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+
+ //KM: April 16, 1999
+ //Perform the potential overrun check
+ sX = (INT16)max( sX, iMinimumX );
+ mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[0] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[0] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[0], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y ),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[0] );
+ fAddedTraitRegion[0] = TRUE;
+ // Assign the text
+ AssignPersonnelSkillTraitHelpText( bSkill1, FALSE, iId, 0 );
+
+ bScreenLocIndex++;
+ }
+
+ //Display the second skill
+ if( bSkill2 != 0 )
+ {
+ swprintf( sString, L"%s", gzMercSkillText[bSkill2] );
+
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+
+ //KM: April 16, 1999
+ //Perform the potential overrun check
+ sX = (INT16)max( sX, iMinimumX );
+ mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[1] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[1] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[1], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y ),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[1] );
+ fAddedTraitRegion[1] = TRUE;
+ // Assign the text
+ AssignPersonnelSkillTraitHelpText( bSkill2, FALSE, iId, 1 );
+
+ bScreenLocIndex++;
+ }
+
+ //if no skill was displayed
+ if( bScreenLocIndex == 19 )
+ {
+ swprintf( sString, L"%s", pPersonnelScreenStrings[ PRSNL_TXT_NOSKILLS ] );
+
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[bScreenLocIndex].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,pPersonnelScreenPoints[bScreenLocIndex].y,sString);
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[0] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[0] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[0], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y ),
+ ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[bScreenLocIndex].y + 7 ), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[0] );
+ fAddedTraitRegion[0] = TRUE;
+ // Assign the text
+ AssignPersonnelSkillTraitHelpText( bSkill1, FALSE, iId, 0 );
+ }
}
}
}
@@ -1759,22 +1970,6 @@ void DisplayCharStats(INT32 iId, INT32 iSlot)
}
}
break;
-/*
- case 19:
- // total contract time served
- mprintf((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[24].y,pPersonnelScreenStrings[18]);
- if( gMercProfiles[Menptr[iId].ubProfile].usTotalDaysServed > 0 )
- {
- swprintf(sString, L"%d %s",gMercProfiles[Menptr[iId].ubProfile].usTotalDaysServed - 1, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ] );
- }
- else
- {
- swprintf(sString, L"%d %s",gMercProfiles[Menptr[iId].ubProfile].usTotalDaysServed, gpStrategicString[ STR_PB_DAYS_ABBREVIATION ] );
- }
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[24].y,sString);
- break;
-*/
}
}
return;
@@ -1963,32 +2158,19 @@ void DisplayPicturesOfCurrentTeam( void )
} // if
SOLDIERTYPE *pSoldier = MercPtrs[currentTeamList[currentOnSreenIndex]];
- if ((50 < pSoldier->ubProfile) && (57 > pSoldier->ubProfile)) {
+ if ((50 < pSoldier->ubProfile) && (57 > pSoldier->ubProfile))
+ {
sprintf( sTemp, "%s%03d.sti", SMALL_FACES_DIR, gMercProfiles[ pSoldier->ubProfile ].ubFaceIndex );
- } else {
+ }
+ else
+ {
if ( pSoldier->ubProfile < 100 )
{
- if (gGameExternalOptions.fReadProfileDataFromXML)
- {
- // HEADROCK PROFEX: Do not read direct profile number, instead, look inside the profile for a ubFaceIndex value.
- sprintf(sTemp, "%s%02d.sti", SMALL_FACES_DIR, gMercProfiles[ pSoldier->ubProfile ].ubFaceIndex);
- }
- else
- {
- sprintf(sTemp, "%s%02d.sti", SMALL_FACES_DIR, pSoldier->ubProfile);
- }
+ sprintf(sTemp, "%s%02d.sti", SMALL_FACES_DIR, gMercProfiles[ pSoldier->ubProfile ].ubFaceIndex);
}
else
{
- if (gGameExternalOptions.fReadProfileDataFromXML)
- {
- // HEADROCK PROFEX: Do not read direct profile number, instead, look inside the profile for a ubFaceIndex value.
- sprintf(sTemp, "%s%03d.sti", SMALL_FACES_DIR, gMercProfiles[ pSoldier->ubProfile ].ubFaceIndex);
- }
- else
- {
- sprintf(sTemp, "%s%03d.sti", SMALL_FACES_DIR, pSoldier->ubProfile);
- }
+ sprintf(sTemp, "%s%03d.sti", SMALL_FACES_DIR, gMercProfiles[ pSoldier->ubProfile ].ubFaceIndex);
} // else
} // else
@@ -2090,27 +2272,41 @@ void PersonnelPortraitCallback( MOUSE_REGION * pRegion, INT32 iReason )
void DisplayFaceOfDisplayedMerc( )
{
// if showing inventory, leave
- if (fCurrentTeamMode) {
- if (currentTeamIndex == -1) {
+ if (fCurrentTeamMode)
+ {
+ if (currentTeamIndex == -1)
+ {
return;
}
DisplayHighLightBox();
- RenderPersonnelFace(currentTeamList[currentTeamIndex], 0, FALSE, FALSE, FALSE );
+ RenderPersonnelFace(-1, currentTeamList[currentTeamIndex], FALSE, FALSE, FALSE );
DisplayCharName(currentTeamList[currentTeamIndex], 0 );
- if( gubPersonnelInfoState == PRSNL_INV ) {
+ if( gubPersonnelInfoState == PRSNL_INV )
+ {
return;
}
+
RenderPersonnelStats(currentTeamList[currentTeamIndex], 0 );
- } else {
- if (iCurrentPersonSelectedId == -1) {
+ }
+ else
+ {
+ if (iCurrentPersonSelectedId == -1)
+ {
return;
}
+
DisplayHighLightBox();
+
+ // Hier drfte der Aufruf falsch sein
+
RenderPersonnelFace( GetIdOfPastMercInSlot( iCurrentPersonSelectedId ), 0, IsPastMercDead( iCurrentPersonSelectedId ), IsPastMercFired( iCurrentPersonSelectedId ), IsPastMercOther( iCurrentPersonSelectedId ) );
DisplayDepartedCharName( GetIdOfPastMercInSlot( iCurrentPersonSelectedId ), 0, GetTheStateOfDepartedMerc( GetIdOfPastMercInSlot( iCurrentPersonSelectedId ) ) );
- if( gubPersonnelInfoState == PRSNL_INV ) {
+
+ if( gubPersonnelInfoState == PRSNL_INV )
+ {
return;
}
+
DisplayDepartedCharStats( GetIdOfPastMercInSlot( iCurrentPersonSelectedId ), 0, GetTheStateOfDepartedMerc( GetIdOfPastMercInSlot( iCurrentPersonSelectedId ) ) );
}
}
@@ -2153,6 +2349,16 @@ void RenderInventoryForCharacter( INT32 iId, INT32 iSlot )
GetVideoObject(&hHandle, guiPersonnelInventory);
BltVideoObject(FRAME_BUFFER, hHandle, 0,( INT16 ) ( iScreenWidthOffset + 397 ), ( INT16 ) ( iScreenHeightOffset + 200 ), VO_BLT_SRCTRANSPARENCY,NULL);
+ // SANDRO - remove the regions
+ for( INT8 i = 0; i < 13; i++ )
+ {
+ if( fAddedTraitRegion[i] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[i] );
+ fAddedTraitRegion[i] = FALSE;
+ }
+ }
+
if (!fCurrentTeamMode) {
return;
}
@@ -2197,8 +2403,8 @@ void RenderInventoryForCharacter( INT32 iId, INT32 iSlot )
usHeight = (UINT32)pTrav->usHeight;
usWidth = (UINT32)pTrav->usWidth;
- sCenX = PosX + ( abs( 57 - usWidth ) / 2 ) - pTrav->sOffsetX;
- sCenY = PosY + ( abs( 22 - usHeight ) / 2 ) - pTrav->sOffsetY;
+ sCenX = PosX + ( abs( 57 - (int)usWidth ) / 2 ) - pTrav->sOffsetX;
+ sCenY = PosY + ( abs( 22 - (int)usHeight ) / 2 ) - pTrav->sOffsetY;
// shadow
if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ]) BltVideoObjectOutlineShadowFromIndex( FRAME_BUFFER, GetInterfaceGraphicForItem( pItem ), usGraphicNum, sCenX-2, sCenY+2);
@@ -3724,6 +3930,8 @@ void DisplayLowestStatValuesForCurrentTeam( void )
{
if (fCurrentTeamMode) {
iId = GetIdOfMercWithLowestStat( iCounter );
+ if( iId == -1 )
+ continue;
} else {
iDepartedId = GetIdOfDepartedMercWithLowestStat( iCounter );
if( iDepartedId == -1 )
@@ -3739,9 +3947,9 @@ void DisplayLowestStatValuesForCurrentTeam( void )
if (fCurrentTeamMode) {
// get name
- if( iId == -1 )
+ /*if( iId == -1 )
swprintf( sString, L"%s", pPOWStrings[1] );
- else
+ else*/
swprintf( sString, L"%s", MercPtrs[ iId ]->name );
} else {
// get name
@@ -3754,9 +3962,9 @@ void DisplayLowestStatValuesForCurrentTeam( void )
case 0:
// health
if (fCurrentTeamMode) {
- if( iId == -1 )
+ /*if( iId == -1 )
iStat = -1;
- else
+ else*/
iStat = MercPtrs[ iId ]->stats.bLifeMax;
} else {
iStat = gMercProfiles[ iDepartedId ] . bLife;
@@ -3844,9 +4052,9 @@ void DisplayLowestStatValuesForCurrentTeam( void )
break;
}
- if( iStat == -1 )
+ /*if( iStat == -1 )
swprintf( sString, L"%s", pPOWStrings[1] );
- else
+ else*/
swprintf( sString, L"%d", iStat );
// right justify
@@ -3895,6 +4103,9 @@ void DisplayHighestStatValuesForCurrentTeam( void )
else
iId = GetIdOfDepartedMercWithHighestStat( iCounter );
+ if( iId == -1 )
+ continue;
+
// even or odd?..color black or yellow?
if( iCounter % 2 == 0 )
{
@@ -3905,13 +4116,14 @@ void DisplayHighestStatValuesForCurrentTeam( void )
SetFontForeground( PERS_TEXT_FONT_COLOR );
}
-
if (fCurrentTeamMode)
{
// get name
- if( iId == -1 )
+ /*if( iId == -1 )
+ {
swprintf( sString, L"%s", pPOWStrings[1] );
- else
+ }
+ else*/
swprintf( sString, L"%s", MercPtrs[ iId ]->name );
}
else
@@ -3926,9 +4138,9 @@ void DisplayHighestStatValuesForCurrentTeam( void )
case 0:
// health
if (fCurrentTeamMode) {
- if( iId == -1 )
+ /*if( iId == -1 )
iStat = -1;
- else
+ else*/
iStat = MercPtrs[ iId ]->stats.bLifeMax;
} else {
iStat = gMercProfiles[ iId ] . bLife;
@@ -4016,9 +4228,9 @@ void DisplayHighestStatValuesForCurrentTeam( void )
break;
}
- if( iStat == -1 )
+ /*if( iStat == -1 )
swprintf( sString, L"%s", pPOWStrings[1] );
- else
+ else*/
swprintf( sString, L"%d", iStat );
// right justify
@@ -4502,32 +4714,19 @@ void DisplayPortraitOfPastMerc( INT32 iId , INT32 iCounter, BOOLEAN fDead, BOOLE
HVOBJECT hFaceHandle;
VOBJECT_DESC VObjectDesc;
- if( ( 50 < iId )&&( 57 > iId ) ) {
+ if( ( 50 < iId )&&( 57 > iId ) )
+ {
sprintf( sTemp, "%s%03d.sti", SMALL_FACES_DIR, gMercProfiles[ iId ].ubFaceIndex );
- } else {
+ }
+ else
+ {
if( iId < 100 )
{
- if (gGameExternalOptions.fReadProfileDataFromXML)
- {
- // HEADROCK PROFEX: Do not read direct profile number, instead, look inside the profile for a ubFaceIndex value.
- sprintf(sTemp, "%s%02d.sti", SMALL_FACES_DIR, gMercProfiles[ iId ].ubFaceIndex );
- }
- else
- {
- sprintf(sTemp, "%s%02d.sti", SMALL_FACES_DIR, iId );
- }
+ sprintf(sTemp, "%s%02d.sti", SMALL_FACES_DIR, gMercProfiles[ iId ].ubFaceIndex );
}
else
- {
- if (gGameExternalOptions.fReadProfileDataFromXML)
- {
- // HEADROCK PROFEX: Do not read direct profile number, instead, look inside the profile for a ubFaceIndex value.
- sprintf(sTemp, "%s%03d.sti", SMALL_FACES_DIR, gMercProfiles[ iId ].ubFaceIndex );
- }
- else
- {
- sprintf(sTemp, "%s%03d.sti", SMALL_FACES_DIR, iId );
- }
+ {
+ sprintf(sTemp, "%s%03d.sti", SMALL_FACES_DIR, gMercProfiles[ iId ].ubFaceIndex );
}
}
@@ -4558,12 +4757,23 @@ void DisplayDepartedCharStats(INT32 iId, INT32 iSlot, INT32 iState)
CHAR16 sString[50];
INT16 sX, sY;
UINT32 uiHits = 0;
+ HVOBJECT hHandle;
// font stuff
SetFont( FONT10ARIAL );
SetFontBackground( FONT_BLACK );
SetFontForeground( PERS_TEXT_FONT_COLOR );
+ // SANDRO - remove the regions
+ for( INT8 i = 0; i < 13; i++ )
+ {
+ if( fAddedTraitRegion[i] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[i] );
+ fAddedTraitRegion[i] = FALSE;
+ }
+ }
+
// display the stats for a char
for(iCounter=0;iCounter 0 )
+ if( (gMercProfiles[iId].records.usShotsFired + gMercProfiles[iId].records.usMissilesLaunched + gMercProfiles[iId].records.usGrenadesThrown + gMercProfiles[iId].records.usKnivesThrown + gMercProfiles[iId].records.usBladeAttacks + gMercProfiles[iId].records.usHtHAttacks) > 0 )
{
- uiHits /= ( UINT32 )gMercProfiles[iId].usShotsFired;
+ uiHits /= ( UINT32 )(gMercProfiles[iId].records.usShotsFired + gMercProfiles[iId].records.usMissilesLaunched + gMercProfiles[iId].records.usGrenadesThrown + gMercProfiles[iId].records.usKnivesThrown + gMercProfiles[iId].records.usBladeAttacks + gMercProfiles[iId].records.usHtHAttacks);
+ if ( uiHits > 100 )
+ uiHits = 100;
}
else
{
@@ -4692,24 +4938,101 @@ void DisplayDepartedCharStats(INT32 iId, INT32 iSlot, INT32 iState)
uiHits = 0;
}
+
swprintf(sString, L"%d %%%%",uiHits);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- sX += StringPixLength( L"%", PERS_FONT );
- mprintf(sX,pPersonnelScreenPoints[23].y,sString);
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[22].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ sX += StringPixLength( L"%", PERS_FONT );
+ mprintf(sX,(pPersonnelScreenPoints[22].y - 8),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[22].x + 148), ( pPersonnelScreenPoints[22].y - 9 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[9] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[9] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[9], (UINT16)( pPersonnelScreenPoints[22].x + 147 ), (UINT16)( pPersonnelScreenPoints[22].y - 10 ),
+ (UINT16)( pPersonnelScreenPoints[22].x + 166 ), (UINT16)(pPersonnelScreenPoints[22].y + 1), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[9] );
+ fAddedTraitRegion[9] = TRUE;
+ // Assign the text
+ AssignPersonnelHitPercentageHelpText( iId );
+
break;
case 17:
- // battles
- mprintf((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[24].y,pPersonnelScreenStrings[PRSNL_TXT_BATTLES]);
- swprintf(sString, L"%d",gMercProfiles[iId].usBattlesFought);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[24].y,sString);
+ // Achievements
+ mprintf((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[23].y - 6),pPersonnelScreenStrings[PRSNL_TXT_ACHIEVEMNTS]);
+ swprintf(sString, L"%d %%%%",CalculateMercsAchievemntPercentage( iId ));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ sX += StringPixLength( L"%", PERS_FONT );
+ mprintf(sX,(pPersonnelScreenPoints[23].y - 6),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[23].x + 148), ( pPersonnelScreenPoints[23].y - 7 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[10] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[10] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[10], (UINT16)( pPersonnelScreenPoints[23].x + 147 ), (UINT16)( pPersonnelScreenPoints[23].y - 8 ),
+ (UINT16)( pPersonnelScreenPoints[23].x + 166 ), (UINT16)(pPersonnelScreenPoints[23].y + 3), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[10] );
+ fAddedTraitRegion[10] = TRUE;
+ // Assign the text
+ AssignPersonnelAchievementsHelpText( iId );
+
break;
case 18:
+ // battles
+ mprintf((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[24].y - 4),pPersonnelScreenStrings[PRSNL_TXT_BATTLES]);
+ swprintf(sString, L"%d",(gMercProfiles[iId].records.usBattlesTactical + gMercProfiles[iId].records.usBattlesAutoresolve));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[24].y - 4),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[24].x + 148), ( pPersonnelScreenPoints[24].y - 5 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[11] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[11] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[11], (UINT16)( pPersonnelScreenPoints[24].x + 147 ), (UINT16)( pPersonnelScreenPoints[24].y - 6 ),
+ (UINT16)( pPersonnelScreenPoints[24].x + 166 ), (UINT16)(pPersonnelScreenPoints[24].y + 5), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[11] );
+ fAddedTraitRegion[11] = TRUE;
+ // Assign the text
+ AssignPersonnelBattlesHelpText( iId );
+
+ break;
+ case 19:
// wounds
- mprintf((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),pPersonnelScreenPoints[25].y,pPersonnelScreenStrings[PRSNL_TXT_TIMES_WOUNDED]);
- swprintf(sString, L"%d",gMercProfiles[iId].usTimesWounded);
- FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
- mprintf(sX,pPersonnelScreenPoints[25].y,sString);
+ mprintf((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[25].y - 2),pPersonnelScreenStrings[PRSNL_TXT_TIMES_WOUNDED]);
+ swprintf(sString, L"%d",(gMercProfiles[iId].records.usTimesWoundedShot + gMercProfiles[iId].records.usTimesWoundedStabbed + (gMercProfiles[iId].records.usTimesWoundedPunched/2) + gMercProfiles[iId].records.usTimesWoundedBlasted));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[25].y - 2),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[25].x + 148), ( pPersonnelScreenPoints[25].y - 3 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[12] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[12] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[12], (UINT16)( pPersonnelScreenPoints[25].x + 147 ), (UINT16)( pPersonnelScreenPoints[25].y - 4 ),
+ (UINT16)( pPersonnelScreenPoints[25].x + 166 ), (UINT16)(pPersonnelScreenPoints[25].y + 7), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[12] );
+ fAddedTraitRegion[12] = TRUE;
+ // Assign the text
+ AssignPersonnelWoundsHelpText( iId );
+
break;
}
}
@@ -4781,7 +5104,8 @@ void DisplayDepartedCharName( INT32 iId, INT32 iSlot, INT32 iState )
}
//if the merc is an AIM merc
- else if( iId < BIFF )
+ //else if( iId < BIFF )
+ else if ( gProfilesAIM[ iId ].ProfilId == iId )
{
//if dismissed
if( iState == DEPARTED_FIRED )
@@ -4791,7 +5115,8 @@ void DisplayDepartedCharName( INT32 iId, INT32 iSlot, INT32 iState )
}
//else if its a MERC merc
- else if( iId >= BIFF && iId <= BUBBA )
+ //else if( iId >= BIFF && iId <= BUBBA )
+ else if ( gProfilesMERC[ iId ].ProfilId == iId )
{
if( iState == DEPARTED_FIRED )
swprintf( sString, L"%s", pPersonnelDepartedStateStrings[ DEPARTED_FIRED ] );
@@ -4799,7 +5124,8 @@ void DisplayDepartedCharName( INT32 iId, INT32 iSlot, INT32 iState )
swprintf( sString, L"%s", pPersonnelDepartedStateStrings[ DEPARTED_QUIT ] );
}
//must be a RPC
- else
+ //else
+ else if ( gProfilesRPC[ iId ].ProfilId == iId )
{
if( iState == DEPARTED_FIRED )
swprintf( sString, L"%s", pPersonnelDepartedStateStrings[ DEPARTED_FIRED ] );
@@ -6153,7 +6479,18 @@ void DisplayEmploymentinformation( INT32 iId, INT32 iSlot )
CHAR16 sString[50];
CHAR16 sStringA[ 50 ];
INT16 sX, sY;
+ UINT32 uiHits = 0;
+ HVOBJECT hHandle;
+ // SANDRO - remove the regions
+ for( INT8 i = 0; i < 13; i++ )
+ {
+ if( fAddedTraitRegion[i] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[i] );
+ fAddedTraitRegion[i] = FALSE;
+ }
+ }
if( Menptr[iId].flags.uiStatusFlags & SOLDIER_VEHICLE )
{
@@ -6392,6 +6729,174 @@ DEF:3/19/99:
break;
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - show num kills, hit percentage, times wounded etc. in here instead of stats table
+
+ case 14:
+ // kills
+ mprintf((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[20].y - 12),pPersonnelScreenStrings[PRSNL_TXT_KILLS]);
+ swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usKillsElites + gMercProfiles[Menptr[iId].ubProfile].records.usKillsRegulars + gMercProfiles[Menptr[iId].ubProfile].records.usKillsAdmins + gMercProfiles[Menptr[iId].ubProfile].records.usKillsHostiles + gMercProfiles[Menptr[iId].ubProfile].records.usKillsCreatures + gMercProfiles[Menptr[iId].ubProfile].records.usKillsTanks + gMercProfiles[Menptr[iId].ubProfile].records.usKillsOthers));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[20].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[20].y - 12),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[20].x + 148), ( pPersonnelScreenPoints[20].y - 13 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[7] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[7] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[7], (UINT16)( pPersonnelScreenPoints[20].x + 147 ), (UINT16)( pPersonnelScreenPoints[20].y - 14 ),
+ (UINT16)( pPersonnelScreenPoints[20].x + 166 ), (UINT16)(pPersonnelScreenPoints[20].y - 3), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[7] );
+ fAddedTraitRegion[7] = TRUE;
+ // Assign the text
+ AssignPersonnelKillsHelpText( iId );
+
+ break;
+ case 15:
+ // assists
+ mprintf((INT16)(pPersonnelScreenPoints[21].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[21].y - 10),pPersonnelScreenStrings[PRSNL_TXT_ASSISTS]);
+ swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usAssistsMercs + gMercProfiles[Menptr[iId].ubProfile].records.usAssistsMilitia + gMercProfiles[Menptr[iId].ubProfile].records.usAssistsOthers));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[21].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[21].y - 10),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[21].x + 148), ( pPersonnelScreenPoints[21].y - 11 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[8] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[8] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[8], (UINT16)( pPersonnelScreenPoints[21].x + 147 ), (UINT16)( pPersonnelScreenPoints[21].y - 12 ),
+ (UINT16)( pPersonnelScreenPoints[21].x + 166 ), (UINT16)(pPersonnelScreenPoints[21].y - 1), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[8] );
+ fAddedTraitRegion[8] = TRUE;
+ // Assign the text
+ AssignPersonnelAssistsHelpText( iId );
+
+ break;
+ case 16:
+ // shots/hits
+ mprintf((INT16)(pPersonnelScreenPoints[22].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[22].y - 8),pPersonnelScreenStrings[PRSNL_TXT_HIT_PERCENTAGE]);
+ uiHits = ( UINT32 )gMercProfiles[Menptr[iId].ubProfile].records.usShotsHit;
+ uiHits *= 100;
+
+ // check we have shot at least once
+ if( (gMercProfiles[Menptr[iId].ubProfile].records.usShotsFired + gMercProfiles[Menptr[iId].ubProfile].records.usMissilesLaunched + gMercProfiles[Menptr[iId].ubProfile].records.usGrenadesThrown + gMercProfiles[Menptr[iId].ubProfile].records.usKnivesThrown + gMercProfiles[Menptr[iId].ubProfile].records.usBladeAttacks + gMercProfiles[Menptr[iId].ubProfile].records.usHtHAttacks) > 0 )
+ {
+ uiHits /= ( UINT32 )(gMercProfiles[Menptr[iId].ubProfile].records.usShotsFired + gMercProfiles[Menptr[iId].ubProfile].records.usMissilesLaunched + gMercProfiles[Menptr[iId].ubProfile].records.usGrenadesThrown + gMercProfiles[Menptr[iId].ubProfile].records.usKnivesThrown + gMercProfiles[Menptr[iId].ubProfile].records.usBladeAttacks + gMercProfiles[Menptr[iId].ubProfile].records.usHtHAttacks);
+ if ( uiHits > 100 )
+ uiHits = 100;
+ }
+ else
+ {
+ // no, set hit % to 0
+ uiHits = 0;
+ }
+
+
+ swprintf(sString, L"%d %%%%",uiHits);
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[22].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ sX += StringPixLength( L"%", PERS_FONT );
+ mprintf(sX,(pPersonnelScreenPoints[22].y - 8),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[22].x + 148), ( pPersonnelScreenPoints[22].y - 9 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[9] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[9] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[9], (UINT16)( pPersonnelScreenPoints[22].x + 147 ), (UINT16)( pPersonnelScreenPoints[22].y - 10 ),
+ (UINT16)( pPersonnelScreenPoints[22].x + 166 ), (UINT16)(pPersonnelScreenPoints[22].y + 1), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[9] );
+ fAddedTraitRegion[9] = TRUE;
+ // Assign the text
+ AssignPersonnelHitPercentageHelpText( iId );
+
+ break;
+ case 17:
+ // Achievements
+ mprintf((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[23].y - 6),pPersonnelScreenStrings[PRSNL_TXT_ACHIEVEMNTS]);
+ swprintf(sString, L"%d %%%%", CalculateMercsAchievemntPercentage( Menptr[iId].ubProfile ));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[23].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ sX += StringPixLength( L"%", PERS_FONT );
+ mprintf(sX,(pPersonnelScreenPoints[23].y - 6),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[23].x + 148), ( pPersonnelScreenPoints[23].y - 7 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[10] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[10] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[10], (UINT16)( pPersonnelScreenPoints[23].x + 147 ), (UINT16)( pPersonnelScreenPoints[23].y - 8 ),
+ (UINT16)( pPersonnelScreenPoints[23].x + 166 ), (UINT16)(pPersonnelScreenPoints[23].y + 3), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[10] );
+ fAddedTraitRegion[10] = TRUE;
+ // Assign the text
+ AssignPersonnelAchievementsHelpText( iId );
+
+ break;
+ case 18:
+ // battles
+ mprintf((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[24].y - 4),pPersonnelScreenStrings[PRSNL_TXT_BATTLES]);
+ swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usBattlesTactical + gMercProfiles[Menptr[iId].ubProfile].records.usBattlesAutoresolve));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[24].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[24].y - 4),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[24].x + 148), ( pPersonnelScreenPoints[24].y - 5 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[11] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[11] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[11], (UINT16)( pPersonnelScreenPoints[24].x + 147 ), (UINT16)( pPersonnelScreenPoints[24].y - 6 ),
+ (UINT16)( pPersonnelScreenPoints[24].x + 166 ), (UINT16)(pPersonnelScreenPoints[24].y + 5), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[11] );
+ fAddedTraitRegion[11] = TRUE;
+ // Assign the text
+ AssignPersonnelBattlesHelpText( iId );
+
+ break;
+ case 19:
+ // wounds
+ mprintf((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[25].y - 2),pPersonnelScreenStrings[PRSNL_TXT_TIMES_WOUNDED]);
+ swprintf(sString, L"%d",(gMercProfiles[Menptr[iId].ubProfile].records.usTimesWoundedShot + gMercProfiles[Menptr[iId].ubProfile].records.usTimesWoundedStabbed + (gMercProfiles[Menptr[iId].ubProfile].records.usTimesWoundedPunched/2) + gMercProfiles[Menptr[iId].ubProfile].records.usTimesWoundedBlasted));
+ FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[25].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY);
+ mprintf(sX,(pPersonnelScreenPoints[25].y - 2),sString);
+
+ GetVideoObject(&hHandle, guiQMark);
+ BltVideoObject( FRAME_BUFFER, hHandle, 0,(pPersonnelScreenPoints[25].x + 148), ( pPersonnelScreenPoints[25].y - 3 ), VO_BLT_SRCTRANSPARENCY,NULL );
+
+ // Add specific region for fast help window
+ if( fAddedTraitRegion[12] )
+ {
+ MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[12] );
+ }
+ MSYS_DefineRegion( &gSkillTraitHelpTextRegion[12], (UINT16)( pPersonnelScreenPoints[25].x + 147 ), (UINT16)( pPersonnelScreenPoints[25].y - 4 ),
+ (UINT16)( pPersonnelScreenPoints[25].x + 166 ), (UINT16)(pPersonnelScreenPoints[25].y + 7), MSYS_PRIORITY_HIGH,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL );
+ MSYS_AddRegion( &gSkillTraitHelpTextRegion[12] );
+ fAddedTraitRegion[12] = TRUE;
+ // Assign the text
+ AssignPersonnelWoundsHelpText( iId );
+
+ break;
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}
@@ -6429,10 +6934,1583 @@ INT32 CalcTimeLeftOnMercContract( SOLDIERTYPE *pSoldier )
return( iTimeLeftOnContract );
}
+// SANDRO - Popup text windows for traits
+void AssignPersonnelSkillTraitHelpText( UINT8 ubTraitNumber, BOOLEAN fExpertLevel, INT32 IMercId, INT8 bRegionNumber )
+{
+ CHAR16 apStr[ 5000 ];
+ CHAR16 atStr[ 1500 ];
+ if( gGameOptions.fNewTraitSystem )
+ {
+ switch( ubTraitNumber )
+ {
+ case AUTO_WEAPONS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubAWBonusCtHAssaultRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[0], ( gSkillTraitValues.ubAWBonusCtHAssaultRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWBonusCtHSMGs != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[1], ( gSkillTraitValues.ubAWBonusCtHSMGs * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWBonusCtHLMGs != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[2], ( gSkillTraitValues.ubAWBonusCtHLMGs * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWFiringSpeedBonusLMGs != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[3], ( gSkillTraitValues.ubAWFiringSpeedBonusLMGs * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWPercentReadyLMGReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[4], ( gSkillTraitValues.ubAWPercentReadyLMGReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWAutoFirePenaltyReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[5], ( gSkillTraitValues.ubAWAutoFirePenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAWUnwantedBulletsReduction > 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsAutoWeapons[6]);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case HEAVY_WEAPONS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[0], ( gSkillTraitValues.ubHWGrenadeLaunchersAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWRocketLaunchersAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[1], ( gSkillTraitValues.ubHWRocketLaunchersAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWBonusCtHGrenadeLaunchers != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[2], ( gSkillTraitValues.ubHWBonusCtHGrenadeLaunchers * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWBonusCtHRocketLaunchers != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[3], ( gSkillTraitValues.ubHWBonusCtHRocketLaunchers * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWMortarAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[4], ( gSkillTraitValues.ubHWMortarAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWMortarCtHPenaltyReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[5], ( gSkillTraitValues.ubHWMortarCtHPenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWDamageTanksBonusPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[6], ( gSkillTraitValues.ubHWDamageTanksBonusPercent * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubHWDamageBonusPercentForHW != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsHeavyWeapons[7], ( gSkillTraitValues.ubHWDamageBonusPercentForHW * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case SNIPER_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSNBonusCtHRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[0], ( gSkillTraitValues.ubSNBonusCtHRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNBonusCtHSniperRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[1], ( gSkillTraitValues.ubSNBonusCtHSniperRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNEffRangeToTargetReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[2], ( gSkillTraitValues.ubSNEffRangeToTargetReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNAimingBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[3], ( gSkillTraitValues.ubSNAimingBonusPerClick * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNDamageBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[4], ( gSkillTraitValues.ubSNDamageBonusPerClick * (fExpertLevel ? 2 : 1)), L"%");
+ if( gSkillTraitValues.ubSNDamageBonusFromNumClicks == 0)
+ {
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsSniper[5] );
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsSniper[6] );
+ }
+ else if( gSkillTraitValues.ubSNDamageBonusFromNumClicks == 1 )
+ {
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsSniper[6] );
+ }
+ else
+ {
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsSniper[6] );
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsSniper[gSkillTraitValues.ubSNDamageBonusFromNumClicks + 4] );
+ }
+ wcscat( atStr, L"\n" );
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNChamberRoundAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[14], ( gSkillTraitValues.ubSNChamberRoundAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSNAimClicksAdded != 0 )
+ {
+ if( gSkillTraitValues.ubSNAimClicksAdded == 1 && !fExpertLevel )
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[15]);
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSniper[16], ( gSkillTraitValues.ubSNAimClicksAdded * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case RANGER_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubRABonusCtHRifles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[0], ( gSkillTraitValues.ubRABonusCtHRifles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRABonusCtHShotguns != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[1], ( gSkillTraitValues.ubRABonusCtHShotguns * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAPumpShotgunsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[2], ( gSkillTraitValues.ubRAPumpShotgunsAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[3], ( gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[4], ( gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRABreathForTravellingReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[5], ( gSkillTraitValues.ubRABreathForTravellingReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubRAWeatherPenaltiesReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[6], ( gSkillTraitValues.ubRAWeatherPenaltiesReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ //if( gSkillTraitValues.ubRACamoEffectivenessBonus != 0 )
+ //{
+ // swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[7], ( gSkillTraitValues.ubRACamoEffectivenessBonus * (fExpertLevel ? 2 : 1)), L"%");
+ // wcscat( apStr, atStr );
+ //}
+ if( gSkillTraitValues.ubRACamoWornountSpeedReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsRanger[8], ( gSkillTraitValues.ubRACamoWornountSpeedReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case GUNSLINGER_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubGSFiringSpeedBonusPistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[0], ( gSkillTraitValues.ubGSFiringSpeedBonusPistols * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSEffectiveRangeBonusPistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[1], ( gSkillTraitValues.ubGSEffectiveRangeBonusPistols * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSBonusCtHPistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[2], ( gSkillTraitValues.ubGSBonusCtHPistols * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSBonusCtHMachinePistols != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[3], ( gSkillTraitValues.ubGSBonusCtHMachinePistols * (fExpertLevel ? 2 : 1)), L"%");
+ if( gSkillTraitValues.ubGSCtHMPExcludeAuto )
+ wcscat( atStr, gzIMPMajorTraitsHelpTextsGunslinger[4] );
+ wcscat( atStr, L"\n");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSAimingBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[5], ( gSkillTraitValues.ubGSAimingBonusPerClick * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSPercentReadyPistolsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[6], ( gSkillTraitValues.ubGSPercentReadyPistolsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSRealoadSpeedHandgunsBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[7], ( gSkillTraitValues.ubGSRealoadSpeedHandgunsBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubGSAimClicksAdded != 0 )
+ {
+ if( gSkillTraitValues.ubGSAimClicksAdded == 1 && !fExpertLevel )
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[8], ( gSkillTraitValues.ubGSAimClicksAdded * (fExpertLevel ? 2 : 1)));
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsGunslinger[9], ( gSkillTraitValues.ubGSAimClicksAdded * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case MARTIAL_ARTS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubMAPunchAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[0], ( gSkillTraitValues.ubMAPunchAPsReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusCtHBareHands != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[1], ( gSkillTraitValues.ubMABonusCtHBareHands * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusCtHBrassKnuckles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[2], ( gSkillTraitValues.ubMABonusCtHBrassKnuckles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusDamageHandToHand != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[3], ( gSkillTraitValues.ubMABonusDamageHandToHand * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMABonusBreathDamageHandToHand != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[4], ( gSkillTraitValues.ubMABonusBreathDamageHandToHand * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usMALostBreathRegainPenalty != 0 )
+ {
+ if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 25)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[5]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 50)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[6]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 100)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[7]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 200)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[8]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 400)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[9]);
+ else if( (gSkillTraitValues.usMALostBreathRegainPenalty * (fExpertLevel ? 2 : 1)) <= 700)
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[10]);
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[11]);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usMAAimedPunchDamageBonus != 0 )
+ {
+ if (gMercProfiles[ IMercId ].ubBodyType != REGMALE || (gSkillTraitValues.fPermitExtraAnimationsOnlyToMA && !fExpertLevel))
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[12], ( gSkillTraitValues.usMAAimedPunchDamageBonus * (fExpertLevel ? 2 : 1)), L"%");
+ else
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[13], ( gSkillTraitValues.usMAAimedPunchDamageBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAChanceToDodgeHtH != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[14], ( gSkillTraitValues.ubMAChanceToDodgeHtH * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAOnTopCTDHtHBareHanded != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[15], ( gSkillTraitValues.ubMAOnTopCTDHtHBareHanded * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles == gSkillTraitValues.ubMAOnTopCTDHtHBareHanded )
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsMartialArts[16] );
+ else if( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles > 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[17], ( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ wcscat( apStr, L"\n" );
+ }
+ else if( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[18], ( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAChanceToDodgeMelee != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[19], ( gSkillTraitValues.ubMAChanceToDodgeMelee * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAReducedAPsToSteal != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[20], ( gSkillTraitValues.ubMAReducedAPsToSteal * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAAPsChangeStanceReduction != 0 && ( gSkillTraitValues.ubMAAPsChangeStanceReduction == gSkillTraitValues.ubMAApsTurnAroundReduction == gSkillTraitValues.ubMAAPsClimbOrJumpReduction ))
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[21], ( gSkillTraitValues.ubMAAPsChangeStanceReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ else
+ {
+ if( gSkillTraitValues.ubMAAPsChangeStanceReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[22], ( gSkillTraitValues.ubMAAPsChangeStanceReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAApsTurnAroundReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[23], ( gSkillTraitValues.ubMAApsTurnAroundReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMAAPsClimbOrJumpReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[24], ( gSkillTraitValues.ubMAAPsClimbOrJumpReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ }
+ if( gSkillTraitValues.ubMAChanceToCkickDoors != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[25], ( gSkillTraitValues.ubMAChanceToCkickDoors * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ //if (gMercProfiles[ IMercId ].ubBodyType == REGMALE &&
+ if (gMercProfiles[ IMercId ].ubBodyType == REGMALE &&
+ ((gSkillTraitValues.fPermitExtraAnimationsOnlyToMA && fExpertLevel) ||
+ !gSkillTraitValues.fPermitExtraAnimationsOnlyToMA ))
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsMartialArts[26]);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case SQUADLEADER_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSLBonusAPsPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[0], ( gSkillTraitValues.ubSLBonusAPsPercent * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLEffectiveLevelInRadius != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[1], ( gSkillTraitValues.ubSLEffectiveLevelInRadius * (fExpertLevel ? 2 : 1)), (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLEffectiveLevelAsStandby != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[2], ( gSkillTraitValues.ubSLEffectiveLevelAsStandby * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLOverallSuppresionBonusPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[3], ( gSkillTraitValues.ubSLOverallSuppresionBonusPercent * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLMoraleGainBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[4], ( gSkillTraitValues.ubSLMoraleGainBonus * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLMoraleLossReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[5], ( gSkillTraitValues.ubSLMoraleLossReduction * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[6], gSkillTraitValues.usSLRadiusNormal);
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.usSLRadiusExtendedEar > gSkillTraitValues.usSLRadiusNormal )
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[7], gSkillTraitValues.usSLRadiusExtendedEar);
+
+ wcscat( apStr, atStr );
+ wcscat( apStr, L"\n" );
+
+ if( gSkillTraitValues.ubSLMaxBonuses > 1 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[8], gSkillTraitValues.ubSLMaxBonuses ) ;
+ wcscat( apStr, atStr );
+ }
+
+ if( gSkillTraitValues.ubSLFearResistance != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[9], ( gSkillTraitValues.ubSLFearResistance * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSLDeathMoralelossMultiplier != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsSquadleader[10], (1 + ( gSkillTraitValues.ubSLDeathMoralelossMultiplier * (fExpertLevel ? 2 : 1))), (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case TECHNICIAN_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.usTERepairSpeedBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[0], ( gSkillTraitValues.usTERepairSpeedBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usTELockpickingBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[1], ( gSkillTraitValues.usTELockpickingBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usTEDisarmElTrapBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[2], ( gSkillTraitValues.usTEDisarmElTrapBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usTEAttachingItemsBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[3], ( gSkillTraitValues.usTEAttachingItemsBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTEUnjamGunBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[4], ( gSkillTraitValues.ubTEUnjamGunBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTERepairElectronicsPenaltyReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[5], ( gSkillTraitValues.ubTERepairElectronicsPenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTEChanceToDetectTrapsBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[6], ( gSkillTraitValues.ubTEChanceToDetectTrapsBonus * (fExpertLevel ? 2 : 1)));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTECtHControlledRobotBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[7], ( gSkillTraitValues.ubTECtHControlledRobotBonus * (fExpertLevel ? 2 : 1)), L"%", (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 2 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+ }
+ else if( gSkillTraitValues.ubTETraitsNumToRepairRobot == 1 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[8], (fExpertLevel ? gzMercSkillTextNew[ubTraitNumber + 19] : gzMercSkillTextNew[ubTraitNumber]));
+ wcscat( apStr, atStr );
+
+ if( gSkillTraitValues.ubTERepairRobotPenaltyReduction != 0 && fExpertLevel)
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsTechnician[9], ( gSkillTraitValues.ubTERepairRobotPenaltyReduction * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ }
+ break;
+ }
+ case DOCTOR_NT:
+ {
+ BOOLEAN fCanSurgery = FALSE;
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubDONumberTraitsNeededForSurgery != 0 && ((gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop) > 0))
+ {
+ if( gSkillTraitValues.ubDONumberTraitsNeededForSurgery <= (fExpertLevel ? 2 : 1))
+ {
+ fCanSurgery = TRUE;
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[0]);
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[1], (gSkillTraitValues.ubDOSurgeryHealPercentBase + ( gSkillTraitValues.ubDOSurgeryHealPercentOnTop * (fExpertLevel ? 2 : 1))), L"%");
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.usDOSurgeryMedBagConsumption >= 60 )
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsDoctor[2] );
+
+ wcscat( apStr, L"\n" );
+ }
+ }
+ if( (gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop) > 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[3]);
+ wcscat( apStr, atStr );
+ if( fCanSurgery )
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsDoctor[4] );
+
+ wcscat( apStr, gzIMPMajorTraitsHelpTextsDoctor[5] );
+ }
+ if( gSkillTraitValues.usDODoctorAssignmentBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[6], ( gSkillTraitValues.usDODoctorAssignmentBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDOBandagingSpeedPercent != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[7], ( gSkillTraitValues.ubDOBandagingSpeedPercent * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDONaturalRegenBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[8], ( gSkillTraitValues.ubDONaturalRegenBonus * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ if( gSkillTraitValues.ubDOMaxRegenBonuses > 1 )
+ {
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsDoctor[9], gSkillTraitValues.ubDOMaxRegenBonuses ) ;
+ wcscat( apStr, atStr );
+ }
+ wcscat( apStr, L"\n" );
+ }
+ break;
+ }
+ case AMBIDEXTROUS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubAMPenaltyDoubleReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[0], gSkillTraitValues.ubAMPenaltyDoubleReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMReloadSpeedMagazines != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[1], gSkillTraitValues.ubAMReloadSpeedMagazines, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMReloadSpeedLoose != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[2], gSkillTraitValues.ubAMReloadSpeedLoose, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMPickItemsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[3], gSkillTraitValues.ubAMPickItemsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMWorkBackpackAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[4], gSkillTraitValues.ubAMWorkBackpackAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMHandleDoorsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[5], gSkillTraitValues.ubAMHandleDoorsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMHandleBombsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[6], gSkillTraitValues.ubAMHandleBombsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubAMAttachingItemsAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAmbidextrous[7], gSkillTraitValues.ubAMAttachingItemsAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case MELEE_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubMEBladesAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[0], gSkillTraitValues.ubMEBladesAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtHBladesBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[1], gSkillTraitValues.ubMECtHBladesBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtHBluntBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[2], gSkillTraitValues.ubMECtHBluntBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDamageBonusBlades != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[3], gSkillTraitValues.ubMEDamageBonusBlades, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDamageBonusBlunt != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[4], gSkillTraitValues.ubMEDamageBonusBlunt, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usMEAimedMeleeAttackDamageBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[5], gSkillTraitValues.usMEAimedMeleeAttackDamageBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDodgeBladesBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[6], gSkillTraitValues.ubMEDodgeBladesBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtDBladesOnTopWithBladeInHands != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[7], gSkillTraitValues.ubMECtDBladesOnTopWithBladeInHands, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMEDodgeBluntBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[8], gSkillTraitValues.ubMEDodgeBluntBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubMECtDBluntOnTopWithBladeInHands != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsMelee[9], gSkillTraitValues.ubMECtDBluntOnTopWithBladeInHands, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case THROWING_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubTHBladesAPsReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[0], gSkillTraitValues.ubTHBladesAPsReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesMaxRange != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[1], gSkillTraitValues.ubTHBladesMaxRange, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesCtHBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[2], gSkillTraitValues.ubTHBladesCtHBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesCtHBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[3], gSkillTraitValues.ubTHBladesCtHBonusPerClick, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesDamageBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[4], gSkillTraitValues.ubTHBladesDamageBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesDamageBonusPerClick != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[5], gSkillTraitValues.ubTHBladesDamageBonusPerClick, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesSilentCriticalHitChance != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[6], gSkillTraitValues.ubTHBladesSilentCriticalHitChance, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesCriticalHitMultiplierBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[7], gSkillTraitValues.ubTHBladesCriticalHitMultiplierBonus);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTHBladesAimClicksAdded != 0 )
+ {
+ if( gSkillTraitValues.ubTHBladesAimClicksAdded == 1 )
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[8], gSkillTraitValues.ubTHBladesAimClicksAdded );
+ else
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsThrowing[9], gSkillTraitValues.ubTHBladesAimClicksAdded );
+
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case NIGHT_OPS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubNOeSightRangeBonusInDark != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[0], gSkillTraitValues.ubNOeSightRangeBonusInDark, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNOHearingRangeBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[1], gSkillTraitValues.ubNOHearingRangeBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNOHearingRangeBonusInDark != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[2], gSkillTraitValues.ubNOHearingRangeBonusInDark, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNOIterruptsBonusInDark != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[3], gSkillTraitValues.ubNOIterruptsBonusInDark, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubNONeedForSleepReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsNightOps[4], gSkillTraitValues.ubNONeedForSleepReduction);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case STEALTHY_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSTStealthModeSpeedBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[0], gSkillTraitValues.ubSTStealthModeSpeedBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSTBonusToMoveQuietly != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[1], gSkillTraitValues.ubSTBonusToMoveQuietly, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSTStealthBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[2], gSkillTraitValues.ubSTStealthBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSTStealthPenaltyForMovingReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsStealthy[3], gSkillTraitValues.ubSTStealthPenaltyForMovingReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case ATHLETICS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubATAPsMovementReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAthletics[0], gSkillTraitValues.ubATAPsMovementReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubATBPsMovementReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsAthletics[1], gSkillTraitValues.ubATBPsMovementReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case BODYBUILDING_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubBBDamageResistance != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[0], gSkillTraitValues.ubBBDamageResistance, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubBBCarryWeightBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[1], gSkillTraitValues.ubBBCarryWeightBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubBBBreathLossForHtHImpactReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[2], gSkillTraitValues.ubBBBreathLossForHtHImpactReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usBBIncreasedNeededDamageToFallDown != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsBodybuilding[3], gSkillTraitValues.usBBIncreasedNeededDamageToFallDown, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case DEMOLITIONS_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubDEAPsNeededToThrowGrenadesReduction != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[0], gSkillTraitValues.ubDEAPsNeededToThrowGrenadesReduction, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEMaxRangeToThrowGrenades != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[1], gSkillTraitValues.ubDEMaxRangeToThrowGrenades, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDECtHWhenThrowingGrenades != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[2], gSkillTraitValues.ubDECtHWhenThrowingGrenades, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEDamageOfBombsAndMines != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[3], gSkillTraitValues.ubDEDamageOfBombsAndMines, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEAttachDetonatorCheckBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[4], gSkillTraitValues.ubDEAttachDetonatorCheckBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEPlantAndRemoveBombCheckBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[5], gSkillTraitValues.ubDEPlantAndRemoveBombCheckBonus, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEPlacedBombLevelBonus != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[6], gSkillTraitValues.ubDEPlacedBombLevelBonus);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubDEShapedChargeDamageMultiplier != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsDemolitions[7], gSkillTraitValues.ubDEShapedChargeDamageMultiplier);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case TEACHING_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubTGBonusToTrainMilitia != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[0], gSkillTraitValues.ubTGBonusToTrainMilitia, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGEffectiveLDRToTrainMilitia != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[1], gSkillTraitValues.ubTGEffectiveLDRToTrainMilitia, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGBonusToTeachOtherMercs != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[2], gSkillTraitValues.ubTGBonusToTeachOtherMercs, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGEffectiveSkillValueForTeaching != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[3], gSkillTraitValues.ubTGEffectiveSkillValueForTeaching);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubTGBonusOnPractising != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsTeaching[4], gSkillTraitValues.ubTGBonusOnPractising, L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case SCOUTING_NT:
+ {
+ swprintf( apStr, L"" );
+ if( gSkillTraitValues.ubSCSightRangebonusWithScopes != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[0], gSkillTraitValues.ubSCSightRangebonusWithScopes, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.usSCSightRangebonusWithBinoculars != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[1], gSkillTraitValues.usSCSightRangebonusWithBinoculars, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.ubSCTunnelVisionReducedWithBinoculars != 0 )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[2], gSkillTraitValues.ubSCTunnelVisionReducedWithBinoculars, L"%");
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.fSCCanDetectEnemyPresenseAround )
+ {
+ if( gSkillTraitValues.fSCCanDetermineEnemyNumbersAround )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[3]);
+ wcscat( apStr, atStr );
+ }
+ else
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[4]);
+ wcscat( apStr, atStr );
+ }
+ }
+ if( gSkillTraitValues.fSCPreventsTheEnemyToAmbushMercs )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[5]);
+ wcscat( apStr, atStr );
+ }
+ if( gSkillTraitValues.fSCPreventsBloodcatsAmbushes )
+ {
+ swprintf( atStr, gzIMPMinorTraitsHelpTextsScouting[6]);
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case NO_SKILLTRAIT_NT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsNone[0] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ }
+ }
+ else
+ {
+ switch( ubTraitNumber )
+ {
+ case LOCKPICKING_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[LOCKPICKING_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[0], ( gbSkillTraitBonus[LOCKPICKING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case HANDTOHAND_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[HANDTOHAND_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[1], ( gbSkillTraitBonus[HANDTOHAND_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[2], ( 3 * gbSkillTraitBonus[HANDTOHAND_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[3], ( gbSkillTraitBonus[HANDTOHAND_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case ELECTRONICS_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[4] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case NIGHTOPS_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[5], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[6], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[7], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[8], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[9], (fExpertLevel ? 2 : 1));
+ wcscat( apStr, atStr );
+ break;
+ }
+ case THROWING_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[THROWING_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[10], ( gbSkillTraitBonus[THROWING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[11], ( gbSkillTraitBonus[THROWING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[12], ( 10 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case TEACHING_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gGameExternalOptions.ubTeachBonusToTrain != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[13], ( gGameExternalOptions.ubTeachBonusToTrain * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ if( (gGameExternalOptions.usTeacherTraitEffectOnLeadership - 100) > 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[14], ( (gGameExternalOptions.usTeacherTraitEffectOnLeadership - 100) * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case HEAVY_WEAPS_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[HEAVY_WEAPS_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[15], ( gbSkillTraitBonus[HEAVY_WEAPS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case AUTO_WEAPS_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[16], ( 2 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[17] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case STEALTHY_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[18], ( 25 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ if( gGameExternalOptions.ubStealthTraitCoverValue != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[19], ( gGameExternalOptions.ubStealthTraitCoverValue * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case AMBIDEXT_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[20] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case MARTIALARTS_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[MARTIALARTS_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[28], ( gbSkillTraitBonus[MARTIALARTS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[29], ( gbSkillTraitBonus[MARTIALARTS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[30], ( gbSkillTraitBonus[MARTIALARTS_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[31], ( gbSkillTraitBonus[MARTIALARTS_OT] * 2 / 3 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[32], ( gbSkillTraitBonus[MARTIALARTS_OT] / 2 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[33]);
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[34]);
+ wcscat( apStr, atStr );
+ break;
+ }
+ case KNIFING_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[KNIFING_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[21], ( gbSkillTraitBonus[KNIFING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[22], ( gbSkillTraitBonus[KNIFING_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[23], ( gbSkillTraitBonus[KNIFING_OT] / 3 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[24], ( gbSkillTraitBonus[KNIFING_OT] / 2 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ break;
+ }
+ case PROF_SNIPER_OT:
+ {
+ swprintf( apStr, L"" );
+ if( gbSkillTraitBonus[PROF_SNIPER_OT] != 0 )
+ {
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[25], ( gbSkillTraitBonus[PROF_SNIPER_OT] * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ }
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[26], ( 10 * (fExpertLevel ? 2 : 1)), L"%");
+ wcscat( apStr, atStr );
+ break;
+ }
+ case CAMOUFLAGED_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPOldSkillTraitsHelpTexts[27] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ case NO_SKILLTRAIT_OT:
+ {
+ swprintf( apStr, L"" );
+ swprintf( atStr, gzIMPMajorTraitsHelpTextsNone[0] );
+ wcscat( apStr, atStr );
+ break;
+ }
+ }
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[bRegionNumber]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[bRegionNumber], MSYS_NO_CALLBACK );
+
+ return;
+}
+// SANDRO - Popup text windows for character
+void AssignPersonnelCharacterTraitHelpText( UINT8 ubCharacterNumber )
+{
+ CHAR16 apStr[ 1000 ];
+
+ swprintf( apStr, L"" );
+ swprintf( apStr, gzIMPNewCharacterTraitsHelpTexts[ubCharacterNumber] );
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[5]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[5], MSYS_NO_CALLBACK );
+
+ return;
+}
+// SANDRO - Popup text windows for disability
+void AssignPersonnelDisabilityHelpText( UINT8 ubDisabilityNumber )
+{
+ CHAR16 apStr[ 500 ];
+
+ swprintf( apStr, L"" );
+ swprintf( apStr, gzIMPDisabilitiesHelpTexts[ubDisabilityNumber] );
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[6]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[6], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+void AssignPersonnelKillsHelpText( INT32 IMercId )
+{
+ CHAR16 apStr[ 1000 ];
+ CHAR16 atStr[ 150 ];
+
+ swprintf( apStr, L"" );
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsElites > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 0 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsElites );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsRegulars > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 1 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsRegulars );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsAdmins > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 2 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsAdmins );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsHostiles > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 3 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsHostiles );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsCreatures > 0 || fShowRecordsIfZero)
+ {
+ // WANNE: Only display the monster info, when we play with monsters!
+ if (gGameExternalOptions.fEnableCrepitus)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 4 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsCreatures );
+ wcscat( apStr, atStr );
+ }
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsTanks > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 5 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsTanks );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsOthers > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 6 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKillsOthers );
+ wcscat( apStr, atStr );
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[7]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[7], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+void AssignPersonnelAssistsHelpText( INT32 IMercId )
+{
+ CHAR16 apStr[ 350 ];
+ CHAR16 atStr[ 80 ];
+
+ swprintf( apStr, L"" );
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usAssistsMercs > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 7 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usAssistsMercs );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usAssistsMilitia > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 8 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usAssistsMilitia );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usAssistsOthers > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 9 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usAssistsOthers );
+ wcscat( apStr, atStr );
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[8]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[8], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+void AssignPersonnelHitPercentageHelpText( INT32 IMercId )
+{
+ CHAR16 apStr[ 1000 ];
+ CHAR16 atStr[ 150 ];
+
+ swprintf( apStr, L"" );
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usShotsFired > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 10 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usShotsFired );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usMissilesLaunched > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 11 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usMissilesLaunched );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usGrenadesThrown > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 12 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usGrenadesThrown );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usKnivesThrown > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 13 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usKnivesThrown );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usBladeAttacks > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 14 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usBladeAttacks );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usHtHAttacks > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 15 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usHtHAttacks );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usShotsHit > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 16 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usShotsHit );
+ wcscat( apStr, atStr );
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[9]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[9], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+void AssignPersonnelAchievementsHelpText( INT32 IMercId )
+{
+ CHAR16 apStr[ 1000 ];
+ CHAR16 atStr[ 80 ];
+
+ swprintf( apStr, L"" );
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usLocksPicked > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 17 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usLocksPicked );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usLocksBreached > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 18 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usLocksBreached );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTrapsRemoved > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 19 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTrapsRemoved );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usExpDetonated > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 20 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usExpDetonated );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usItemsRepaired > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 21 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usItemsRepaired );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usItemsCombined > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 22 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usItemsCombined );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usItemsStolen > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 23 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usItemsStolen );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usMilitiaTrained > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 24 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usMilitiaTrained );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usMercsBandaged > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 25 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usMercsBandaged );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usSurgeriesMade > 0 || fShowRecordsIfZero)
+ {
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ switch( gSkillTraitValues.ubDONumberTraitsNeededForSurgery )
+ {
+ case 0:
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 26 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usSurgeriesMade );
+ wcscat( apStr, atStr );
+ break;
+ case 1:
+ if ( ProfileHasSkillTrait( Menptr[IMercId].ubProfile, DOCTOR_NT ) > 0 )
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 26 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usSurgeriesMade );
+ wcscat( apStr, atStr );
+ }
+ break;
+ case 2:
+ if ( ProfileHasSkillTrait( Menptr[IMercId].ubProfile, DOCTOR_NT ) > 1 )
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 26 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usSurgeriesMade );
+ wcscat( apStr, atStr );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usNPCsDiscovered > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 27 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usNPCsDiscovered );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usSectorsDiscovered > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 28 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usSectorsDiscovered );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usAmbushesExperienced > 0 || fShowRecordsIfZero)
+ {
+ if ( gGameOptions.fNewTraitSystem && ( ProfileHasSkillTrait( Menptr[IMercId].ubProfile, SCOUTING_NT ) > 0 ) )
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 29 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usAmbushesExperienced );
+ wcscat( apStr, atStr );
+ }
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.ubQuestsHandled > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 30 ], gMercProfiles[Menptr[IMercId].ubProfile].records.ubQuestsHandled );
+ wcscat( apStr, atStr );
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[10]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[10], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+void AssignPersonnelBattlesHelpText( INT32 IMercId )
+{
+ CHAR16 apStr[ 400 ];
+ CHAR16 atStr[ 80 ];
+
+ swprintf( apStr, L"" );
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usBattlesTactical > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 31 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usBattlesTactical );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usBattlesAutoresolve > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 32 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usBattlesAutoresolve );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usBattlesRetreated > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 33 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usBattlesRetreated );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usAmbushesExperienced > 0 || fShowRecordsIfZero)
+ {
+ if (!( gGameOptions.fNewTraitSystem && ( ProfileHasSkillTrait( Menptr[IMercId].ubProfile, SCOUTING_NT ) > 0 ) ))
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 34 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usAmbushesExperienced );
+ wcscat( apStr, atStr );
+ }
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usLargestBattleFought > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 35 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usLargestBattleFought );
+ wcscat( apStr, atStr );
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[11]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[11], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+void AssignPersonnelWoundsHelpText( INT32 IMercId )
+{
+ CHAR16 apStr[ 500 ];
+ CHAR16 atStr[ 80 ];
+
+ swprintf( apStr, L"" );
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedShot > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 36 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedShot );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedStabbed > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 37 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedStabbed );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedPunched > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 38 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedPunched );
+ wcscat( apStr, atStr );
+ }
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedBlasted > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 39 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesWoundedBlasted );
+ wcscat( apStr, atStr );
+ }
+
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesSurgeryUndergoed > 0 || fShowRecordsIfZero)
+ {
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 41 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesSurgeryUndergoed );
+ wcscat( apStr, atStr );
+ }
+ }
+
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usFacilityAccidents > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 42 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usFacilityAccidents );
+ wcscat( apStr, atStr );
+ }
+
+ // WANNE: Moved to the end
+ if (gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesStatDamaged > 0 || fShowRecordsIfZero)
+ {
+ swprintf(atStr, pPersonnelRecordsHelpTexts[ 40 ], gMercProfiles[Menptr[IMercId].ubProfile].records.usTimesStatDamaged );
+ wcscat( apStr, atStr );
+ }
+
+ // Set region help text
+ SetRegionFastHelpText( &(gSkillTraitHelpTextRegion[12]), apStr );
+ SetRegionHelpEndCallback( &gSkillTraitHelpTextRegion[12], MSYS_NO_CALLBACK );
+
+ return;
+}
+
+INT8 CalculateMercsAchievemntPercentage( INT32 IMercId )
+{
+ SOLDIERTYPE *pTeamSoldier;
+ INT32 cnt=0;
+ UINT32 uiMercPoints, uiMercPercentage;
+ unsigned long ulTotalMercPoints = 0;
+
+ // run through active soldiers
+ for ( cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++)
+ {
+ pTeamSoldier = MercPtrs[cnt];
+ // Only count stats of merc (not vehicles)
+ if ( !( pTeamSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) && !AM_A_ROBOT( pTeamSoldier ) )
+ {
+ if( pTeamSoldier->bActive && pTeamSoldier->stats.bLife > 0 && pTeamSoldier->ubProfile != 0 )
+ {
+ // get total value of all mercs, adjust by importance
+ ulTotalMercPoints +=
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usLocksPicked )
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usLocksBreached )
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usTrapsRemoved *3/2)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usExpDetonated *3/2)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usItemsRepaired /2)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usItemsCombined *2)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usItemsStolen )
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usMercsBandaged *3/4)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usSurgeriesMade *3/2)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usNPCsDiscovered *4/3)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usSectorsDiscovered )
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.usMilitiaTrained /4)
+ +
+ ( gMercProfiles[ pTeamSoldier->ubProfile ].records.ubQuestsHandled *2);
+
+ }
+ }
+ }
+
+ // Now get points of our mercs
+ uiMercPoints =
+ ( gMercProfiles[ IMercId ].records.usLocksPicked )
+ +
+ ( gMercProfiles[ IMercId ].records.usLocksBreached )
+ +
+ ( gMercProfiles[ IMercId ].records.usTrapsRemoved *3/2)
+ +
+ ( gMercProfiles[ IMercId ].records.usExpDetonated *3/2)
+ +
+ ( gMercProfiles[ IMercId ].records.usItemsRepaired /2)
+ +
+ ( gMercProfiles[ IMercId ].records.usItemsCombined *2)
+ +
+ ( gMercProfiles[ IMercId ].records.usItemsStolen )
+ +
+ ( gMercProfiles[ IMercId ].records.usMercsBandaged *3/4)
+ +
+ ( gMercProfiles[ IMercId ].records.usSurgeriesMade *3/2)
+ +
+ ( gMercProfiles[ IMercId ].records.usNPCsDiscovered *4/3)
+ +
+ ( gMercProfiles[ IMercId ].records.usSectorsDiscovered )
+ +
+ ( gMercProfiles[ IMercId ].records.usMilitiaTrained /4)
+ +
+ ( gMercProfiles[ IMercId ].records.ubQuestsHandled *2);
+
+ // Calculate percentage
+ if( ulTotalMercPoints != 0 )
+ {
+ uiMercPercentage = (UINT32)(((100 * uiMercPoints)/ulTotalMercPoints)+ 0.5);
+
+ uiMercPercentage = min( 100, uiMercPercentage );
+
+ return( (UINT8)(uiMercPercentage) );
+ }
+ else
+ return( 0 );
+}
diff --git a/Laptop/personnel.h b/Laptop/personnel.h
index 2ae61512..bfce1079 100644
--- a/Laptop/personnel.h
+++ b/Laptop/personnel.h
@@ -9,6 +9,49 @@
// delay for change in ATM mode
#define DELAY_PER_MODE_CHANGE_IN_ATM 2000
+//enums for the pPersonnelScreenStrings[]
+enum
+{
+ PRSNL_TXT_HEALTH, // 0 HEALTH OF MERC
+ PRSNL_TXT_AGILITY,
+ PRSNL_TXT_DEXTERITY,
+ PRSNL_TXT_STRENGTH,
+ PRSNL_TXT_LEADERSHIP,
+ PRSNL_TXT_WISDOM, // 5
+ PRSNL_TXT_EXP_LVL, // EXPERIENCE LEVEL
+ PRSNL_TXT_MARKSMANSHIP,
+ PRSNL_TXT_MECHANICAL,
+ PRSNL_TXT_EXPLOSIVES,
+ PRSNL_TXT_MEDICAL, // 10
+ PRSNL_TXT_MED_DEPOSIT, // AMOUNT OF MEDICAL DEPOSIT PUT DOWN ON THE MERC
+ PRSNL_TXT_CURRENT_CONTRACT, // COST OF CURRENT CONTRACT
+ PRSNL_TXT_KILLS, // NUMBER OF KILLS BY MERC
+ PRSNL_TXT_ASSISTS, // NUMBER OF ASSISTS ON KILLS BY MERC
+ PRSNL_TXT_DAILY_COST, // 15 DAILY COST OF MERC
+ PRSNL_TXT_TOTAL_COST, // TOTAL COST OF MERC
+ PRSNL_TXT_CONTRACT, // COST OF CURRENT CONTRACT
+ PRSNL_TXT_TOTAL_SERVICE, // TOTAL SERVICE RENDERED BY MERC
+ PRSNL_TXT_UNPAID_AMOUNT, // AMOUNT LEFT ON MERC MERC TO BE PAID
+ PRSNL_TXT_HIT_PERCENTAGE, // 20 PERCENTAGE OF SHOTS THAT HIT TARGET
+ PRSNL_TXT_BATTLES, // NUMBER OF BATTLES FOUGHT
+ PRSNL_TXT_TIMES_WOUNDED, // NUMBER OF TIMES MERC HAS BEEN WOUNDED
+ PRSNL_TXT_SKILLS,
+ PRSNL_TXT_NOSKILLS,
+ PRSNL_TXT_ACHIEVEMNTS,
+ TEXT_NUM_PRSNL,
+};
+
+// departed states
+enum
+{
+ DEPARTED_DEAD = 0,
+ DEPARTED_FIRED,
+ DEPARTED_OTHER,
+ DEPARTED_MARRIED,
+ DEPARTED_CONTRACT_EXPIRED,
+ DEPARTED_QUIT,
+ TEXT_NUM_DEPARTED
+};
void GameInitPersonnel();
void EnterPersonnel();
diff --git a/Loading Screen.cpp b/Loading Screen.cpp
index 1a9dba07..300b01e3 100644
--- a/Loading Screen.cpp
+++ b/Loading Screen.cpp
@@ -16,11 +16,22 @@
#include "font.h"
#include "render dirty.h"
#endif
+#include "Strategic Movement.h"
+#include "UndergroundInit.h"
+#include
extern HVSURFACE ghFrameBuffer;
+extern BOOLEAN gfSchedulesHosed;
-STR8 szSectorMap[MAP_WORLD_Y][MAP_WORLD_X] = {
- {"N", "N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N"},
+
+UINT8 gubLastLoadingScreenID = LOADINGSCREEN_NOTHING;
+BOOLEAN bShowSmallImage = FALSE;
+SECTOR_LOADSCREENS gSectorLoadscreens[MAX_SECTOR_LOADSCREENS];
+
+static INT16 requestedX, requestedY, requestedZ;
+static STR8 szSector;
+static STR8 szSectorMap[MAP_WORLD_Y][MAP_WORLD_X] = {
+ {"N", "N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" , "N" , "N" , "N" , "N" , "N" , "N" , "N" ,"N"},
{"N", "A1","A2","A3","A4","A5","A6","A7","A8","A9","A10","A11","A12","A13","A14","A15","A16" ,"N"},
{"N", "B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12","B13","B14","B15","B16" ,"N"},
@@ -39,470 +50,166 @@ STR8 szSectorMap[MAP_WORLD_Y][MAP_WORLD_X] = {
{"N", "O1","O2","O3","O4","O5","O6","O7","O8","O9","O10","O11","O12","O13","O14","O15","O16" ,"N"},
{"N", "P1","P2","P3","P4","P5","P6","P7","P8","P9","P10","P11","P12","P13","P14","P15","P16" ,"N"},
- {"N","N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N"}
- };
+ {"N", "N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" ,"N" , "N" , "N" , "N" , "N" , "N" , "N" , "N" ,"N"},
+};
-UINT8 gubLastLoadingScreenID = LOADINGSCREEN_NOTHING;
-STR8 szSector;
-BOOLEAN bShowSmallImage = FALSE;
-
-SECTOR_LOADSCREENS gSectorLoadscreens[MAX_SECTOR_LOADSCREENS];
+// Map LOADINGSCREEN_NOTHING, ..., LOADINGSCREEN_NIGHTBALIME (see enum in header file)
+// to some strings which will be used to create the actual filename
+// (by appending e.g. "_800x600.sti" or something).
+// This is only used when NOT loading them from SectorLoadscreens.xml.
+static STR8 LoadScreenNames[LOADINGSCREEN_NIGHTBALIME+1] =
+{
+ "LS_Heli",
+ "LS_DayGeneric",
+ "LS_DayTown1",
+ "LS_DayTown2",
+ "LS_DayWild",
+ "LS_DayTropical",
+ "LS_DayForest",
+ "LS_DayDesert",
+ "LS_DayPalace",
+ "LS_NightGeneric",
+ "LS_NightWild",
+ "LS_NightTown1",
+ "LS_NightTown2",
+ "LS_NightForest",
+ "LS_NightTropical",
+ "LS_NightDesert",
+ "LS_NightPalace",
+ "LS_Heli",
+ "LS_Basement",
+ "LS_Mine",
+ "LS_Cave",
+ "LS_DayPine",
+ "LS_NightPine",
+ "LS_DayMilitary",
+ "LS_NightMilitary",
+ "LS_DaySAM",
+ "LS_NightSAM",
+ "LS_DayPrison",
+ "LS_NightPrison",
+ "LS_DayHospital",
+ "LS_NightHospital",
+ "LS_DayAirport",
+ "LS_NightAirport",
+ "LS_DayLab",
+ "LS_NightLab",
+ "LS_DayOmerta",
+ "LS_NightOmerta",
+ "LS_DayChitzena",
+ "LS_NightChitzena",
+ "LS_DayMine",
+ "LS_NightMine",
+ "LS_DayBalime",
+ "LS_NightBalime",
+};
//returns the UINT8 ID for the specified sector.
-UINT8 GetLoadScreenID( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
+// Which for sectors above ground is one of { HELI, DAY, NIGHT }
+// if gGameExternalOptions.gfUseExternalLoadscreens.
+// Otherwise and for underground sectors this is the actual loadsceen ID.
+UINT8 GetLoadScreenID(INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ)
{
- SECTORINFO *pSector;
- UINT8 ubSectorID;
- BOOLEAN fNight = FALSE;
+ const UINT8 ubSectorID = SECTOR( sSectorX, sSectorY );
+ const BOOLEAN fNight = NightTime(); //before 5AM or after 9PM
- ubSectorID = SECTOR( sSectorX, sSectorY );
- if( NightTime() ) //before 5AM or after 9PM
+ requestedX = sSectorX; requestedY = sSectorY; requestedZ = bSectorZ;
+
+ /* User made system - BEGIN */
+ if (gGameExternalOptions.gfUseExternalLoadscreens)
{
- fNight = TRUE;
- }
+ if (bSectorZ != 0)
+ {
+ szSector = szSectorMap [sSectorY][sSectorX]; // not really necessary, I guess
+ return UNDERGROUND;
+ }
- // Which map layer? (ground, basement 1-3)?
- switch( bSectorZ )
+ switch( ubSectorID )
+ {
+ case SEC_A9:
+ szSector = "A9";
+ return DidGameJustStart() ? HELI : (fNight ? NIGHT : DAY);
+ default:
+ szSector = szSectorMap [sSectorY][sSectorX];
+ return fNight ? NIGHT : DAY;
+ }
+ } /* WANNE: User made System - END */
+
+ /* WANNE: Sir-Tech System - BEGIN */
+ else
{
- // Ground
- case 0:
-
- /* User made system - BEGIN */
- if (gGameExternalOptions.gfUseExternalLoadscreens)
- {
- switch( ubSectorID )
- {
- case SEC_A1:
- case SEC_A2:
- case SEC_A3:
- case SEC_A4:
- case SEC_A5:
- case SEC_A6:
- case SEC_A7:
- case SEC_A8:
- // case SEC_A9: // Start sector
- case SEC_A10:
- case SEC_A11:
- case SEC_A12:
- case SEC_A13:
- case SEC_A14:
- case SEC_A15:
- case SEC_A16:
- case SEC_B1:
- case SEC_B2:
- case SEC_B3:
- case SEC_B4:
- case SEC_B5:
- case SEC_B6:
- case SEC_B7:
- case SEC_B8:
- case SEC_B9:
- case SEC_B10:
- case SEC_B11:
- case SEC_B12:
- case SEC_B13:
- case SEC_B14:
- case SEC_B15:
- case SEC_B16:
- case SEC_C1:
- case SEC_C2:
- case SEC_C3:
- case SEC_C4:
- case SEC_C5:
- case SEC_C6:
- case SEC_C7:
- case SEC_C8:
- case SEC_C9:
- case SEC_C10:
- case SEC_C11:
- case SEC_C12:
- case SEC_C13:
- case SEC_C14:
- case SEC_C15:
- case SEC_C16:
- case SEC_D1:
- case SEC_D2:
- case SEC_D3:
- case SEC_D4:
- case SEC_D5:
- case SEC_D6:
- case SEC_D7:
- case SEC_D8:
- case SEC_D9:
- case SEC_D10:
- case SEC_D11:
- case SEC_D12:
- case SEC_D13:
- case SEC_D14:
- case SEC_D15:
- case SEC_D16:
- case SEC_E1:
- case SEC_E2:
- case SEC_E3:
- case SEC_E4:
- case SEC_E5:
- case SEC_E6:
- case SEC_E7:
- case SEC_E8:
- case SEC_E9:
- case SEC_E10:
- case SEC_E11:
- case SEC_E12:
- case SEC_E13:
- case SEC_E14:
- case SEC_E15:
- case SEC_E16:
- case SEC_F1:
- case SEC_F2:
- case SEC_F3:
- case SEC_F4:
- case SEC_F5:
- case SEC_F6:
- case SEC_F7:
- case SEC_F8:
- case SEC_F9:
- case SEC_F10:
- case SEC_F11:
- case SEC_F12:
- case SEC_F13:
- case SEC_F14:
- case SEC_F15:
- case SEC_F16:
- case SEC_G1:
- case SEC_G2:
- case SEC_G3:
- case SEC_G4:
- case SEC_G5:
- case SEC_G6:
- case SEC_G7:
- case SEC_G8:
- case SEC_G9:
- case SEC_G10:
- case SEC_G11:
- case SEC_G12:
- case SEC_G13:
- case SEC_G14:
- case SEC_G15:
- case SEC_G16:
- case SEC_H1:
- case SEC_H2:
- case SEC_H3:
- case SEC_H4:
- case SEC_H5:
- case SEC_H6:
- case SEC_H7:
- case SEC_H8:
- case SEC_H9:
- case SEC_H10:
- case SEC_H11:
- case SEC_H12:
- case SEC_H13:
- case SEC_H14:
- case SEC_H15:
- case SEC_H16:
- case SEC_I1:
- case SEC_I2:
- case SEC_I3:
- case SEC_I4:
- case SEC_I5:
- case SEC_I6:
- case SEC_I7:
- case SEC_I8:
- case SEC_I9:
- case SEC_I10:
- case SEC_I11:
- case SEC_I12:
- case SEC_I13:
- case SEC_I14:
- case SEC_I15:
- case SEC_I16:
- case SEC_J1:
- case SEC_J2:
- case SEC_J3:
- case SEC_J4:
- case SEC_J5:
- case SEC_J6:
- case SEC_J7:
- case SEC_J8:
- case SEC_J9:
- case SEC_J10:
- case SEC_J11:
- case SEC_J12:
- case SEC_J13:
- case SEC_J14:
- case SEC_J15:
- case SEC_J16:
- case SEC_K1:
- case SEC_K2:
- case SEC_K3:
- case SEC_K4:
- case SEC_K5:
- case SEC_K6:
- case SEC_K7:
- case SEC_K8:
- case SEC_K9:
- case SEC_K10:
- case SEC_K11:
- case SEC_K12:
- case SEC_K13:
- case SEC_K14:
- case SEC_K15:
- case SEC_K16:
- case SEC_L1:
- case SEC_L2:
- case SEC_L3:
- case SEC_L4:
- case SEC_L5:
- case SEC_L6:
- case SEC_L7:
- case SEC_L8:
- case SEC_L9:
- case SEC_L10:
- case SEC_L11:
- case SEC_L12:
- case SEC_L13:
- case SEC_L14:
- case SEC_L15:
- case SEC_L16:
- case SEC_M1:
- case SEC_M2:
- case SEC_M3:
- case SEC_M4:
- case SEC_M5:
- case SEC_M6:
- case SEC_M7:
- case SEC_M8:
- case SEC_M9:
- case SEC_M10:
- case SEC_M11:
- case SEC_M12:
- case SEC_M13:
- case SEC_M14:
- case SEC_M15:
- case SEC_M16:
- case SEC_N1:
- case SEC_N2:
- case SEC_N3:
- case SEC_N4:
- case SEC_N5:
- case SEC_N6:
- case SEC_N7:
- case SEC_N8:
- case SEC_N9:
- case SEC_N10:
- case SEC_N11:
- case SEC_N12:
- case SEC_N13:
- case SEC_N14:
- case SEC_N15:
- case SEC_N16:
- case SEC_O1:
- case SEC_O2:
- case SEC_O3:
- case SEC_O4:
- case SEC_O5:
- case SEC_O6:
- case SEC_O7:
- case SEC_O8:
- case SEC_O9:
- case SEC_O10:
- case SEC_O11:
- case SEC_O12:
- case SEC_O13:
- case SEC_O14:
- case SEC_O15:
- case SEC_O16:
- case SEC_P1:
- case SEC_P2:
- case SEC_P3:
- case SEC_P4:
- case SEC_P5:
- case SEC_P6:
- case SEC_P7:
- case SEC_P8:
- case SEC_P9:
- case SEC_P10:
- case SEC_P11:
- case SEC_P12:
- case SEC_P13:
- case SEC_P14:
- case SEC_P15:
- case SEC_P16:
- szSector = szSectorMap [sSectorY][sSectorX];
-
- if( fNight )
- {
- return NIGHT;
- }
- else
- {
- return DAY;
- }
-
- case SEC_A9:
- szSector = "A9";
-
- if( !DidGameJustStart() )
- {
- if( fNight )
- {
- return NIGHT;
- }
- else
- {
- return DAY;
- }
- }
- else
- {
- return HELI;
- }
- }
- } /* WANNE: User made System - END */
-
- /* WANNE: Sir-Tech System - BEGIN */
- else
+ // Which map layer? (ground, basement 1-3)?
+ switch( bSectorZ )
+ {
+ // Ground
+ case 0:
{
switch( ubSectorID )
{
case SEC_A2:
case SEC_B2:
- if( fNight )
- return LOADINGSCREEN_NIGHTCHITZENA;
- return LOADINGSCREEN_DAYCHITZENA;
+ return fNight ? LOADINGSCREEN_NIGHTCHITZENA : LOADINGSCREEN_DAYCHITZENA;
case SEC_A9:
- if( !DidGameJustStart() )
- {
- if( fNight )
- return LOADINGSCREEN_NIGHTOMERTA;
- return LOADINGSCREEN_DAYOMERTA;
- }
- return LOADINGSCREEN_HELI;
+ return DidGameJustStart() ? LOADINGSCREEN_HELI :
+ (fNight ? LOADINGSCREEN_NIGHTOMERTA : LOADINGSCREEN_DAYOMERTA);
case SEC_A10:
- if( fNight )
- return LOADINGSCREEN_NIGHTOMERTA;
- return LOADINGSCREEN_DAYOMERTA;
+ return fNight ? LOADINGSCREEN_NIGHTOMERTA : LOADINGSCREEN_DAYOMERTA;
case SEC_P3:
- if( fNight )
- return LOADINGSCREEN_NIGHTPALACE;
- return LOADINGSCREEN_DAYPALACE;
+ return fNight ? LOADINGSCREEN_NIGHTPALACE : LOADINGSCREEN_DAYPALACE;
case SEC_H13:
case SEC_H14: //military installations
case SEC_I13:
case SEC_N7:
- if( fNight )
- return LOADINGSCREEN_NIGHTMILITARY;
- return LOADINGSCREEN_DAYMILITARY;
+ return fNight ? LOADINGSCREEN_NIGHTMILITARY : LOADINGSCREEN_DAYMILITARY;
case SEC_K4:
- if( fNight )
- return LOADINGSCREEN_NIGHTLAB;
- return LOADINGSCREEN_DAYLAB;
+ return fNight ? LOADINGSCREEN_NIGHTLAB : LOADINGSCREEN_DAYLAB;
case SEC_J9:
- if( fNight )
- return LOADINGSCREEN_NIGHTPRISON;
- return LOADINGSCREEN_DAYPRISON;
+ return fNight ? LOADINGSCREEN_NIGHTPRISON : LOADINGSCREEN_DAYPRISON;
case SEC_D2:
case SEC_D15:
case SEC_I8:
case SEC_N4:
- if( fNight )
- return LOADINGSCREEN_NIGHTSAM;
- return LOADINGSCREEN_DAYSAM;
+ return fNight ? LOADINGSCREEN_NIGHTSAM : LOADINGSCREEN_DAYSAM;
case SEC_F8:
- if( fNight )
- return LOADINGSCREEN_NIGHTHOSPITAL;
- return LOADINGSCREEN_DAYHOSPITAL;
+ return fNight ? LOADINGSCREEN_NIGHTHOSPITAL : LOADINGSCREEN_DAYHOSPITAL;
case SEC_B13:
case SEC_N3:
- if( fNight )
- return LOADINGSCREEN_NIGHTAIRPORT;
- return LOADINGSCREEN_DAYAIRPORT;
+ return fNight ? LOADINGSCREEN_NIGHTAIRPORT : LOADINGSCREEN_DAYAIRPORT;
case SEC_L11:
case SEC_L12:
- if( fNight )
- return LOADINGSCREEN_NIGHTBALIME;
- return LOADINGSCREEN_DAYBALIME;
+ return fNight ? LOADINGSCREEN_NIGHTBALIME : LOADINGSCREEN_DAYBALIME;
case SEC_H3:
case SEC_H8:
case SEC_D4:
- if( fNight )
- return LOADINGSCREEN_NIGHTMINE;
- return LOADINGSCREEN_DAYMINE;
+ return fNight ? LOADINGSCREEN_NIGHTMINE : LOADINGSCREEN_DAYMINE;
}
- pSector = &SectorInfo[ ubSectorID ];
- switch( pSector->ubTraversability[ 4 ] )
+ SECTORINFO *pSector = &SectorInfo[ ubSectorID ];
+ switch( pSector->ubTraversability[ THROUGH_STRATEGIC_MOVE ] )
{
case TOWN:
- if( fNight )
- {
- if( Random( 2 ) )
- {
- return LOADINGSCREEN_NIGHTTOWN2;
- }
- else
- {
- return LOADINGSCREEN_NIGHTTOWN1;
- }
- }
- else
- {
- if( Random( 2 ) )
- {
- return LOADINGSCREEN_DAYTOWN2;
- }
- else
- {
- return LOADINGSCREEN_DAYTOWN1;
- }
- }
+ return Random(2) > 0 ?
+ (fNight ? LOADINGSCREEN_NIGHTTOWN2 : LOADINGSCREEN_DAYTOWN2) :
+ (fNight ? LOADINGSCREEN_NIGHTTOWN1 : LOADINGSCREEN_DAYTOWN1);
case SAND:
case SAND_ROAD:
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTDESERT;
- }
- else
- {
- return LOADINGSCREEN_DAYDESERT;
- }
+ return fNight ? LOADINGSCREEN_NIGHTDESERT : LOADINGSCREEN_DAYDESERT;
case FARMLAND:
case FARMLAND_ROAD:
case ROAD:
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTGENERIC;
- }
- else
- {
- return LOADINGSCREEN_DAYGENERIC;
- }
+ return fNight ? LOADINGSCREEN_NIGHTGENERIC : LOADINGSCREEN_DAYGENERIC;
case PLAINS:
case SPARSE:
case HILLS:
case PLAINS_ROAD:
case SPARSE_ROAD:
case HILLS_ROAD:
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTWILD;
- }
- else
- {
- return LOADINGSCREEN_DAYWILD;
- }
+ return fNight ? LOADINGSCREEN_NIGHTWILD : LOADINGSCREEN_DAYWILD;
case DENSE:
case SWAMP:
case SWAMP_ROAD:
case DENSE_ROAD:
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTFOREST;
- }
- else
- {
- return LOADINGSCREEN_DAYFOREST;
- }
+ return fNight ? LOADINGSCREEN_NIGHTFOREST : LOADINGSCREEN_DAYFOREST;
case TROPICS:
case TROPICS_ROAD:
case WATER:
@@ -510,124 +217,98 @@ UINT8 GetLoadScreenID( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
case EW_RIVER:
case COASTAL:
case COASTAL_ROAD:
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTTROPICAL;
- }
- else
- {
- return LOADINGSCREEN_DAYTROPICAL;
- }
+ return fNight ? LOADINGSCREEN_NIGHTTROPICAL : LOADINGSCREEN_DAYTROPICAL;
default:
Assert( 0 );
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTGENERIC;
- }
- else
- {
- return LOADINGSCREEN_DAYGENERIC;
- }
+ return fNight ? LOADINGSCREEN_NIGHTGENERIC : LOADINGSCREEN_DAYGENERIC;
}
- break;
- /* WANNE: Sir-Tech System */
+ }
+ // Basement Level 1
+ case 1:
+ switch( ubSectorID )
+ {
+ case SEC_A10: //Miguel's basement
+ case SEC_I13: //Alma prison dungeon
+ case SEC_J9: //Tixa prison dungeon
+ case SEC_K4: //Orta weapons plant
+ case SEC_O3: //Meduna
+ case SEC_P3: //Meduna
+ return LOADINGSCREEN_BASEMENT;
+ default: //rest are mines
+ return LOADINGSCREEN_MINE;
+ }
+ // Basement Level 2 and 3
+ case 2:
+ case 3:
+ //all level 2 and 3 maps are caves!
+ return LOADINGSCREEN_CAVE;
+ default:
+ // shouldn't ever happen
+ Assert( FALSE );
+ return fNight ? LOADINGSCREEN_NIGHTGENERIC : LOADINGSCREEN_DAYGENERIC;
}
-
- // Basement Level 1
- case 1:
- switch( ubSectorID )
- {
- case SEC_A10: //Miguel's basement
- case SEC_I13: //Alma prison dungeon
- case SEC_J9: //Tixa prison dungeon
- case SEC_K4: //Orta weapons plant
- case SEC_O3: //Meduna
- case SEC_P3: //Meduna
- return LOADINGSCREEN_BASEMENT;
- default: //rest are mines
- return LOADINGSCREEN_MINE;
- }
- break;
- // Basement Level 2 and 3
- case 2:
- case 3:
- //all level 2 and 3 maps are caves!
- return LOADINGSCREEN_CAVE;
- default:
- // shouldn't ever happen
- Assert( FALSE );
-
- if( fNight )
- {
- return LOADINGSCREEN_NIGHTGENERIC;
- }
- else
- {
- return LOADINGSCREEN_DAYGENERIC;
- }
- }
+
+ } /* WANNE: Sir-Tech System - END */
}
-extern BOOLEAN gfSchedulesHosed;
+static void BuildLoadscreenFilename(std::string& dst, const char* path, int resolution, const char* ext)
+{
+ if (path)
+ dst.append(path);
+
+ switch (resolution)
+ {
+ case 1:
+ dst.append("_800x600");
+ break;
+ case 2:
+ dst.append("_1024x768");
+ break;
+ default:
+ break;
+ }
+
+ if (ext)
+ {
+ dst.append(".");
+ dst.append(ext);
+ }
+ else
+ // This might suck later on. If it does, remove it.
+ dst.append(".sti");
+}
//sets up the loadscreen with specified ID, and draws it to the FRAME_BUFFER,
//and refreshing the screen with it.
void DisplayLoadScreenWithID( UINT8 ubLoadScreenID )
{
- VSURFACE_DESC vs_desc;
+ VSURFACE_DESC vs_desc = {};
HVSURFACE hVSurface;
UINT32 uiLoadScreen;
- STRING512 smallImage;
- BOOLEAN fExternalLS = FALSE;
+ STRING512 smallImage = {0};
bShowSmallImage = FALSE;
- vs_desc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE;
+ vs_desc.fCreateFlags = VSURFACE_CREATE_FROMFILE | VSURFACE_SYSTEM_MEM_USAGE | VSURFACE_CREATE_FROMPNG_FALLBACK;
- if (gGameExternalOptions.gfUseExternalLoadscreens)
- {
- if ((ubLoadScreenID == HELI || ubLoadScreenID == DAY || ubLoadScreenID == DAY_ALT ||
- ubLoadScreenID == NIGHT || ubLoadScreenID == NIGHT_ALT) && szSector != NULL)
- {
- fExternalLS = TRUE;
- }
- else
- {
- fExternalLS = FALSE;
- }
- }
- else
- {
- if ((ubLoadScreenID == HELI || ubLoadScreenID == DAY || ubLoadScreenID == DAY_ALT ||
- ubLoadScreenID == NIGHT || ubLoadScreenID == NIGHT_ALT) && szSector != NULL)
- {
- fExternalLS = TRUE;
- }
- else
- {
- fExternalLS = FALSE;
- }
- }
+ const BOOLEAN fExternalLS = (szSector != NULL) && ((DAY <= ubLoadScreenID && ubLoadScreenID <= NIGHT_ALT) || (ubLoadScreenID == UNDERGROUND));
+
if (fExternalLS)
{
// Get the image path
- char szImagePath[80];
- char szImageFormat[5];
- char szFullImagePath[80];
-
- // WDS - Fix: Init strings 7/16/2007
- szImagePath[0] = 0;
- szImageFormat[0] = 0;
- szFullImagePath[0] = 0;
+ std::string imagePath;
+ std::string imageFormat;
// Start screen
if (ubLoadScreenID == HELI)
{
- strncpy(szImagePath, gSectorLoadscreens[0].szDay, 80);
-
- strncpy(szImageFormat, ".", MAX_IMAGE_FORMAT_CHARS);
- strcat(szImageFormat, gSectorLoadscreens[0].szImageFormat);
+ imagePath = gSectorLoadscreens[0].szDay;
+ imageFormat = gSectorLoadscreens[0].szImageFormat;
+ }
+ else if (ubLoadScreenID == UNDERGROUND)
+ {
+ g_luaUnderground.GetLoadscreen(requestedX, requestedY, requestedZ, imagePath, imageFormat);
}
else
{
@@ -636,53 +317,38 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID )
// We found the sector
if (strcmp(gSectorLoadscreens[i].szLocation, szSector) == 0)
{
- strncpy(szImageFormat, ".", MAX_IMAGE_FORMAT_CHARS);
-
- strcat(szImageFormat, gSectorLoadscreens[i].szImageFormat);
+ imageFormat = gSectorLoadscreens[i].szImageFormat;
BOOLEAN fAlternate = gSectorLoadscreens[i].RandomAltSector;
- if (fAlternate)
+ if (fAlternate && (Random(2) > 0))
{
- // Day
- if (ubLoadScreenID == DAY)
+ switch (ubLoadScreenID)
{
- if( Random( 2 ) )
- {
- ubLoadScreenID = DAY;
- }
- else
- {
+ case DAY:
ubLoadScreenID = DAY_ALT;
- }
- }
- // Night
- else
- {
- if( Random( 2 ) )
- {
- ubLoadScreenID = NIGHT;
- }
- else
- {
+ break;
+ case NIGHT:
ubLoadScreenID = NIGHT_ALT;
- }
+ break;
+ default:
+ break;
}
}
switch (ubLoadScreenID)
{
case DAY:
- strncpy(szImagePath, gSectorLoadscreens[i].szDay, MAX_IMAGE_PATH_CHARS);
+ imagePath = gSectorLoadscreens[i].szDay;
break;
case DAY_ALT:
- strncpy(szImagePath, gSectorLoadscreens[i].szDayAlt, MAX_IMAGE_PATH_CHARS);
+ imagePath = gSectorLoadscreens[i].szDayAlt;
break;
case NIGHT:
- strncpy(szImagePath, gSectorLoadscreens[i].szNight, MAX_IMAGE_PATH_CHARS);
+ imagePath = gSectorLoadscreens[i].szNight;
break;
case NIGHT_ALT:
- strncpy(szImagePath, gSectorLoadscreens[i].szNightAlt, MAX_IMAGE_PATH_CHARS);
+ imagePath = gSectorLoadscreens[i].szNight;
break;
}
break;
@@ -691,738 +357,36 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID )
}
// Small image: 640x480
- strncpy(szFullImagePath, szImagePath, 80);
- strcat(szFullImagePath, szImageFormat);
- strcpy(smallImage,szFullImagePath);
+ std::string strSmallImage;
+ BuildLoadscreenFilename(strSmallImage, imagePath.c_str(), 0, imageFormat.c_str());
+ strSmallImage.copy(smallImage, sizeof(smallImage)-1);
// Actual image, depending on the resolution
- if (iResolution == 1)
- {
- strncpy(szFullImagePath, szImagePath, 80);
- strcat(szFullImagePath, "_800x600");
- strcat(szFullImagePath, szImageFormat);
- }
- else if (iResolution == 2)
- {
- strncpy(szFullImagePath, szImagePath, 80);
- strcat(szFullImagePath, "_1024x768");
- strcat(szFullImagePath, szImageFormat);
- }
-
- strcpy(vs_desc.ImageFile,szFullImagePath);
+ std::string strBigImage;
+ BuildLoadscreenFilename(strBigImage, imagePath.c_str(), iResolution, imageFormat.c_str());
+ strBigImage.copy(vs_desc.ImageFile, sizeof(vs_desc.ImageFile)-1);
}
else
{
- switch( ubLoadScreenID )
- {
- case LOADINGSCREEN_NOTHING:
- strcpy(smallImage, "LOADSCREENS\\LS_Heli.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_1024x768.sti");
- }
- break;
- case LOADINGSCREEN_DAYGENERIC:
- strcpy(smallImage, "LOADSCREENS\\LS_DayGeneric.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayGeneric.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayGeneric_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayGeneric_1024x768.sti");
- }
- break;
- case LOADINGSCREEN_DAYTOWN1:
- strcpy(smallImage, "LOADSCREENS\\LS_DayTown1.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTown1.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTown1_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTown1_1024x768.sti");
- }
- break;
- case LOADINGSCREEN_DAYTOWN2:
- strcpy(smallImage, "LOADSCREENS\\LS_DayTown2.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTown2.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTown2_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTown2_1024x768.sti");
- }
+ std::string strSmallImage("LOADSCREENS\\");
+ std::string strBigImage("LOADSCREENS\\");
- break;
- case LOADINGSCREEN_DAYWILD:
- strcpy(smallImage, "LOADSCREENS\\LS_DayWild.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayWild.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayWild_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayWild_1024x768.sti");
- }
+ if (LOADINGSCREEN_NOTHING <= ubLoadScreenID && ubLoadScreenID <= LOADINGSCREEN_NIGHTBALIME)
+ {
+ BuildLoadscreenFilename(strSmallImage, LoadScreenNames[ubLoadScreenID], 0, "sti");
+ BuildLoadscreenFilename(strBigImage, LoadScreenNames[ubLoadScreenID], iResolution, "sti");
+ }
+ else
+ {
+ // for some reason the heli screen is the default
+ BuildLoadscreenFilename(strSmallImage, LoadScreenNames[0], 0, "sti");
+ BuildLoadscreenFilename(strBigImage, LoadScreenNames[0], iResolution, "sti");
+ }
- break;
- case LOADINGSCREEN_DAYTROPICAL:
- strcpy(smallImage, "LOADSCREENS\\LS_DayTropical.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTropical.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTropical_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayTropical_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYFOREST:
- strcpy(smallImage, "LOADSCREENS\\LS_DayForest.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayForest.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayForest_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayForest_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYDESERT:
- strcpy(smallImage, "LOADSCREENS\\LS_DayDesert.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayDesert.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayDesert_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayDesert_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYPALACE:
- strcpy(smallImage, "LOADSCREENS\\LS_DayPalace.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPalace.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPalace_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPalace_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTGENERIC:
- strcpy(smallImage, "LOADSCREENS\\LS_NightGeneric.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightGeneric.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightGeneric_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightGeneric_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTWILD:
- strcpy(smallImage, "LOADSCREENS\\LS_NightWild.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightWild.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightWild_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightWild_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTTOWN1:
- strcpy(smallImage, "LOADSCREENS\\LS_NightTown1.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTown1.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTown1_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTown1_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTTOWN2:
- strcpy(smallImage, "LOADSCREENS\\LS_NightTown2.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTown2.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTown2_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTown2_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTFOREST:
- strcpy(smallImage, "LOADSCREENS\\LS_NightForest.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightForest.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightForest_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightForest_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTTROPICAL:
- strcpy(smallImage, "LOADSCREENS\\LS_NightTropical.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTropical.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTropical_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightTropical_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTDESERT:
- strcpy(smallImage, "LOADSCREENS\\LS_NightDesert.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightDesert.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightDesert_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightDesert_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTPALACE:
- strcpy(smallImage, "LOADSCREENS\\LS_NightPalace.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPalace.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPalace_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPalace_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_HELI:
- strcpy(smallImage, "LOADSCREENS\\LS_Heli.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_BASEMENT:
- strcpy(smallImage, "LOADSCREENS\\LS_Basement.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Basement.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Basement_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Basement_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_MINE:
- strcpy(smallImage, "LOADSCREENS\\LS_Mine.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Mine.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Mine_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Mine_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_CAVE:
- strcpy(smallImage, "LOADSCREENS\\LS_Cave.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Cave.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Cave_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Cave_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYPINE:
- strcpy(smallImage, "LOADSCREENS\\LS_DayPine.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPine.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPine_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPine_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTPINE:
- strcpy(smallImage, "LOADSCREENS\\LS_NightPine.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPine.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPine_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPine_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYMILITARY:
- strcpy(smallImage, "LOADSCREENS\\LS_DayMilitary.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayMilitary.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayMilitary_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayMilitary_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTMILITARY:
- strcpy(smallImage, "LOADSCREENS\\LS_NightMilitary.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightMilitary.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightMilitary_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightMilitary_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYSAM:
- strcpy(smallImage, "LOADSCREENS\\LS_DaySAM.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DaySAM.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DaySAM_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DaySAM_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTSAM:
- strcpy(smallImage, "LOADSCREENS\\LS_NightSAM.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightSAM.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightSAM_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightSAM_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYPRISON:
- strcpy(smallImage, "LOADSCREENS\\LS_DayPrison.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPrison.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPrison_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayPrison_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTPRISON:
- strcpy(smallImage, "LOADSCREENS\\LS_NightPrison.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPrison.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPrison_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightPrison_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYHOSPITAL:
- strcpy(smallImage, "LOADSCREENS\\LS_DayHospital.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayHospital.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayHospital_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayHospital_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTHOSPITAL:
- strcpy(smallImage, "LOADSCREENS\\LS_NightHospital.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightHospital.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightHospital_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightHospital_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYAIRPORT:
- strcpy(smallImage, "LOADSCREENS\\LS_DayAirport.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayAirport.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayAirport_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayAirport_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTAIRPORT:
- strcpy(smallImage, "LOADSCREENS\\LS_NightAirport.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightAirport.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightAirport_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightAirport_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYLAB:
- strcpy(smallImage, "LOADSCREENS\\LS_DayLab.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayLab.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayLab_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayLab_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTLAB:
- strcpy(smallImage, "LOADSCREENS\\LS_NightLab.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightLab.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightLab_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightLab_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYOMERTA:
- strcpy(smallImage, "LOADSCREENS\\LS_DayOmerta.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayOmerta.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayOmerta_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayOmerta_1024x768.sti");
- }
- break;
- case LOADINGSCREEN_NIGHTOMERTA:
- strcpy(smallImage, "LOADSCREENS\\LS_NightOmerta.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightOmerta.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightOmerta_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightOmerta_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYCHITZENA:
- strcpy(smallImage, "LOADSCREENS\\LS_DayChitzena.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayChitzena.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayChitzena_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayChitzena_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_NIGHTCHITZENA:
- strcpy(smallImage, "LOADSCREENS\\LS_NightChitzena.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightChitzena.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightChitzena_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightChitzena_1024x768.sti");
- }
-
- break;
- case LOADINGSCREEN_DAYMINE:
- strcpy(smallImage, "LOADSCREENS\\LS_DayMine.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayMine.sti" );
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayMine_800x600.sti" );
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayMine_1024x768.sti" );
- }
-
- break;
- case LOADINGSCREEN_NIGHTMINE:
- strcpy(smallImage, "LOADSCREENS\\LS_NightMine.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightMine.sti" );
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightMine_800x600.sti" );
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightMine_1024x768.sti" );
- }
-
- break;
- case LOADINGSCREEN_DAYBALIME:
- strcpy(smallImage, "LOADSCREENS\\LS_DayBalime.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayBalime.sti" );
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayBalime_800x600.sti" );
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_DayBalime_1024x768.sti" );
- }
-
- break;
- case LOADINGSCREEN_NIGHTBALIME:
- strcpy(smallImage, "LOADSCREENS\\LS_NightBalime.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightBalime.sti" );
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightBalime_800x600.sti" );
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_NightBalime_1024x768.sti" );
- }
-
- break;
- default:
- strcpy(smallImage, "LOADSCREENS\\LS_Heli.sti");
- if (iResolution == 0)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli.sti");
- }
- else if (iResolution == 1)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_800x600.sti");
- }
- else if (iResolution == 2)
- {
- strcpy(vs_desc.ImageFile, "LOADSCREENS\\LS_Heli_1024x768.sti");
- }
- break;
- } // Switch - END
+ strSmallImage.copy(smallImage, sizeof(smallImage)-1);
+ strBigImage.copy(vs_desc.ImageFile, sizeof(vs_desc.ImageFile)-1);
}
- // Sti loadscreen (big image) is not available
- if ( AddVideoSurface( &vs_desc, &uiLoadScreen ) == FALSE && iResolution > 0)
- {
- bShowSmallImage = TRUE;
- strcpy(vs_desc.ImageFile, smallImage);
- }
if( gfSchedulesHosed )
{
@@ -1432,29 +396,45 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID )
ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0 );
mprintf( 5, 5, L"Error loading save, attempting to patch save to version 1.02...", vs_desc.ImageFile );
}
- else if( AddVideoSurface( &vs_desc, &uiLoadScreen ) )
- { //Blit the background image
- GetVideoSurface( &hVSurface, uiLoadScreen );
+ else
+ {
+ BOOLEAN fOk = FALSE;
- // Special case->show the small image centered
- if (iResolution > 0 && bShowSmallImage == TRUE)
+ if(FileExists(vs_desc.ImageFile) && AddVideoSurface(&vs_desc, &uiLoadScreen))
+ fOk = TRUE;
+ else
{
- BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, iScreenWidthOffset, iScreenHeightOffset, 0, NULL );
+ // Sti loadscreen is not available
+ // we may have tried the big image, so let's check out the small one
+ bShowSmallImage = TRUE;
+ strncpy(vs_desc.ImageFile, smallImage, sizeof(vs_desc.ImageFile)-1);
+
+ if (FileExists(vs_desc.ImageFile) && AddVideoSurface(&vs_desc, &uiLoadScreen))
+ fOk = TRUE;
+ }
+
+ if (fOk)
+ {
+ //Blit the background image
+ GetVideoSurface(&hVSurface, uiLoadScreen);
+
+ // Special case->show the small image centered
+ if (iResolution > 0 && bShowSmallImage)
+ BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, iScreenWidthOffset, iScreenHeightOffset, 0, NULL );
+ else
+ BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, 0, 0, 0, NULL );
+
+ DeleteVideoSurfaceFromIndex( uiLoadScreen );
}
else
{
- BltVideoSurfaceToVideoSurface( ghFrameBuffer, hVSurface, 0, 0, 0, 0, NULL );
+ //Failed to load the file, so use a black screen and print out message.
+ SetFont( FONT10ARIAL );
+ SetFontForeground( FONT_YELLOW );
+ SetFontShadow( FONT_NEARBLACK );
+ ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0 );
+ mprintf( 5, 5, L"%S loadscreen data file not found...", vs_desc.ImageFile );
}
-
- DeleteVideoSurfaceFromIndex( uiLoadScreen );
- }
- else
- { //Failed to load the file, so use a black screen and print out message.
- SetFont( FONT10ARIAL );
- SetFontForeground( FONT_YELLOW );
- SetFontShadow( FONT_NEARBLACK );
- ColorFillVideoSurfaceArea( FRAME_BUFFER, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0 );
- mprintf( 5, 5, L"%S loadscreen data file not found...", vs_desc.ImageFile );
}
gubLastLoadingScreenID = ubLoadScreenID;
@@ -1463,5 +443,3 @@ void DisplayLoadScreenWithID( UINT8 ubLoadScreenID )
EndFrameBufferRender();
RefreshScreen( NULL );
}
-
-
diff --git a/Loading Screen.h b/Loading Screen.h
index c37121fb..69f0b6c9 100644
--- a/Loading Screen.h
+++ b/Loading Screen.h
@@ -52,7 +52,8 @@ enum
NIGHT,
HELI,
DAY_ALT,
- NIGHT_ALT
+ NIGHT_ALT,
+ UNDERGROUND,
};
diff --git a/MPChatScreen.cpp b/MPChatScreen.cpp
index 105cdf90..0f24449a 100644
--- a/MPChatScreen.cpp
+++ b/MPChatScreen.cpp
@@ -896,7 +896,7 @@ void BtnChatTogglesCallback( GUI_BUTTON *btn, INT32 reason )
{
UINT8 ubButton = (UINT8)MSYS_GetBtnUserData( btn, 0 );
- if (ubButton == 1 && PLAYER_BSIDE != 1)
+ if (ubButton == 1 && cGameType != MP_TYPE_TEAMDEATMATCH)
return;
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
@@ -1160,7 +1160,7 @@ void EnableDisableChatLogScrollButtonsAndRegions( void )
MSYS_EnableRegion( &gChatLogScrollBarRegion );
}
- if (PLAYER_BSIDE==1)
+ if (cGameType==MP_TYPE_TEAMDEATMATCH)
{
// Only enable Allies toggle for team deathmatch
EnableButton( guiChatToggles[1] );
diff --git a/MPConnectScreen.cpp b/MPConnectScreen.cpp
index f344ba71..77447c2f 100644
--- a/MPConnectScreen.cpp
+++ b/MPConnectScreen.cpp
@@ -525,3 +525,39 @@ void CheckForContinue()
}
}
}
+
+#include
+#include
+#include
+#include
+
+void ja2::mp::InitializeMultiplayerProfile(vfs::Path const& profileRoot)
+{
+ // does the profile root directory actually exist
+ if(!vfs::OS::checkRealDirectory(profileRoot))
+ {
+ // OK, directory did not exist, probably a new profile
+ SGP_THROW_IFFALSE( vfs::OS::createRealDirectory(profileRoot),
+ _BS(L"Could not create directory : ") << profileRoot << _BS::wget );
+ }
+
+ // create and initialize a new Multiplayer profile
+ std::auto_ptr pProf( new vfs::CVirtualProfile("_MULTIPLAYER",profileRoot,true) );
+
+ if(!vfs_init::initWriteProfile(*pProf))
+ {
+ SGP_THROW(_BS(L"Could not initialize client profile") << profileRoot << _BS::wget);
+ }
+
+ vfs::CProfileStack *PS = getVFS()->getProfileStack();
+
+ // remove old Multiplayer profile (if it exists)
+ vfs::CVirtualProfile *pOldProf = PS->getProfile("_MULTIPLAYER");
+ if( pOldProf && (pOldProf == PS->topProfile()) )
+ {
+ SGP_THROW_IFFALSE(PS->popProfile(), L"Could not remove old \"_MULTIPLAYER\" profile");
+ }
+
+ // add new profile
+ PS->pushProfile(pProf.release());
+}
diff --git a/MPHostScreen.cpp b/MPHostScreen.cpp
index 19b4d8d1..c9434693 100644
--- a/MPHostScreen.cpp
+++ b/MPHostScreen.cpp
@@ -27,13 +27,13 @@
#include "gameloop.h"
#include "connect.h"
-#include "network.h" // for client name
+#include "network.h"
#include "saveloadscreen.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_init.h"
-#include "VFS/PropertyContainer.h"
-#include "VFS/os_functions.h"
+#include
+#include
+#include
+#include
#include "MPJoinScreen.h"
#include "MainMenuScreen.h"
#include "Init.h"
@@ -45,155 +45,146 @@
//
///////////////////////////////////////////
-#define MPH_TITLE_FONT FONT14ARIAL//FONT16ARIAL
-#define MPH_TITLE_COLOR FONT_MCOLOR_WHITE
+INT32 giMPHMessageBox = -1; // message box handle
-#define MPH_LABEL_TEXT_FONT FONT12ARIAL//FONT16ARIAL
-#define MPH_LABEL_TEXT_COLOR FONT_MCOLOR_WHITE
-#define MPH_TOGGLE_TEXT_FONT FONT12ARIAL//FONT16ARIAL
-#define MPH_TOGGLE_TEXT_COLOR FONT_MCOLOR_WHITE
+#define MPH_TITLE_FONT FONT14ARIAL
+#define MPH_TITLE_COLOR FONT_MCOLOR_WHITE
+
+#define MPH_LABEL_TEXT_FONT FONT10ARIAL
+#define MPH_LABEL_TEXT_COLOR FONT_MCOLOR_WHITE
+
+#define MPH_TOGGLE_TEXT_FONT FONT10ARIAL
+#define MPH_TOGGLE_TEXT_COLOR FONT_MCOLOR_WHITE
//buttons
-#define MPH_BTN_START_X iScreenWidthOffset + 320 + 143
-#define MPH_BTN_START_Y iScreenHeightOffset + 435
#define MPH_CANCEL_X iScreenWidthOffset + ((320 - 115) / 2)
-//textboxes
-#define MPH_TXT_SVRNAME_X iScreenWidthOffset + 100
-#define MPH_TXT_SVRNAME_Y iScreenHeightOffset + 167
-#define MPH_TXT_SVRNAME_WIDTH 120
-#define MPH_TXT_SVRNAME_HEIGHT 17
-#define MPH_TXT_MAXPLAYERS_X iScreenWidthOffset + 100
-#define MPH_TXT_MAXPLAYERS_Y MPH_TXT_SVRNAME_Y + MPH_TXT_SVRNAME_HEIGHT + 13
-#define MPH_TXT_MAXPLAYERS_WIDTH 40
-#define MPH_TXT_MAXPLAYERS_HEIGHT 17
-#define MPH_TXT_SQUAD_X iScreenWidthOffset + 100
-#define MPH_TXT_SQUAD_Y MPH_TXT_MAXPLAYERS_Y + MPH_TXT_MAXPLAYERS_HEIGHT + 13
-#define MPH_TXT_SQUAD_WIDTH 40
-#define MPH_TXT_SQUAD_HEIGHT 17
-#define MPH_TXT_TIME_X iScreenWidthOffset + 100
-#define MPH_TXT_TIME_Y MPH_TXT_SQUAD_Y + MPH_TXT_SQUAD_HEIGHT + 13
-#define MPH_TXT_TIME_WIDTH 60
-#define MPH_TXT_TIME_HEIGHT 17
-#define MPH_TXT_CASH_X iScreenWidthOffset + 100
-#define MPH_TXT_CASH_Y MPH_TXT_TIME_Y + MPH_TXT_TIME_HEIGHT + 13
-#define MPH_TXT_CASH_WIDTH 60
-#define MPH_TXT_CASH_HEIGHT 17
-#define MPH_TXT_DMG_X iScreenWidthOffset + 100
-#define MPH_TXT_DMG_Y MPH_TXT_CASH_Y + MPH_TXT_CASH_HEIGHT + 13
-#define MPH_TXT_DMG_WIDTH 60
-#define MPH_TXT_DMG_HEIGHT 17
-#define MPH_TXT_TIMER_X iScreenWidthOffset + 100
-#define MPH_TXT_TIMER_Y MPH_TXT_DMG_Y + MPH_TXT_DMG_HEIGHT + 13
-#define MPH_TXT_TIMER_WIDTH 60
-#define MPH_TXT_TIMER_HEIGHT 17
-#define MPH_TXT_FILE_TRANSFER_DIR_X iScreenWidthOffset + 100
-#define MPH_TXT_FILE_TRANSFER_DIR_Y MPH_TXT_TIMER_Y + MPH_TXT_TIMER_HEIGHT + 13
-#define MPH_TXT_FILE_TRANSFER_DIR_WIDTH 200
-#define MPH_TXT_FILE_TRANSFER_DIR_HEIGHT 17
-
-
+#define MPH_BTN_START_X iScreenWidthOffset + 320 + 105
+#define MPH_BTN_START_Y iScreenHeightOffset + 435
//main title
-#define MPH_MAIN_TITLE_X 0
+#define MPH_MAIN_TITLE_X 0
#define MPH_MAIN_TITLE_Y iScreenHeightOffset + 10
#define MPH_MAIN_TITLE_WIDTH SCREEN_WIDTH
-//labels
-#define MPH_LABEL_SVRNAME_X MPH_TXT_SVRNAME_X - 80
-#define MPH_LABEL_SVRNAME_Y MPH_TXT_SVRNAME_Y + 3
-#define MPH_LABEL_SVRNAME_WIDTH 80
-#define MPH_LABEL_SVRNAME_HEIGHT 17
-#define MPH_LABEL_MAXPLAYERS_X MPH_TXT_MAXPLAYERS_X - 80
-#define MPH_LABEL_MAXPLAYERS_Y MPH_TXT_MAXPLAYERS_Y + 3
-#define MPH_LABEL_MAXPLAYERS_WIDTH 80
-#define MPH_LABEL_MAXPLAYERS_HEIGHT 17
-#define MPH_LABEL_SQUAD_X MPH_TXT_SQUAD_X - 80
-#define MPH_LABEL_SQUAD_Y MPH_TXT_SQUAD_Y + 3
-#define MPH_LABEL_SQUAD_WIDTH 80
-#define MPH_LABEL_SQUAD_HEIGHT 17
-#define MPH_LABEL_TIME_X MPH_TXT_TIME_X - 80
-#define MPH_LABEL_TIME_Y MPH_TXT_TIME_Y + 3
-#define MPH_LABEL_TIME_WIDTH 80
-#define MPH_LABEL_TIME_HEIGHT 17
-#define MPH_LABEL_CASH_X MPH_TXT_CASH_X - 80
-#define MPH_LABEL_CASH_Y MPH_TXT_CASH_Y + 3
-#define MPH_LABEL_CASH_WIDTH 80
-#define MPH_LABEL_CASH_HEIGHT 17
-#define MPH_LABEL_DMG_X MPH_TXT_DMG_X - 80
-#define MPH_LABEL_DMG_Y MPH_TXT_DMG_Y + 3
-#define MPH_LABEL_DMG_WIDTH 80
-#define MPH_LABEL_DMG_HEIGHT 17
-#define MPH_LABEL_TIMER_X MPH_TXT_TIMER_X - 80
-#define MPH_LABEL_TIMER_Y MPH_TXT_TIMER_Y + 3
-#define MPH_LABEL_TIMER_WIDTH 80
-#define MPH_LABEL_TIMER_HEIGHT 17
-#define MPH_LABEL_FILE_TRANSFER_DIR_X MPH_TXT_FILE_TRANSFER_DIR_X - 80
-#define MPH_LABEL_FILE_TRANSFER_DIR_Y MPH_TXT_FILE_TRANSFER_DIR_Y + 3
-#define MPH_LABEL_FILE_TRANSFER_DIR_WIDTH 80
-#define MPH_LABEL_FILE_TRANSFER_DIR_HEIGHT 17
+#define MPH_TITLE_DISTANCE 30 // higher means closer
-//radio box locations
-#define MPH_GAP_BN_SETTINGS 35
-#define MPH_OFFSET_TO_TEXT 30
-#define MPH_OFFSET_TO_TOGGLE_BOX 170
-#define MPH_OFFSET_TO_TOGGLE_BOX_Y 9
+#define MPH_GAP_BN_SETTINGS 35
+#define MPH_OFFSET_TO_TEXT 36
+#define MPH_OFFSET_TO_TOGGLE_BOX 180
+#define MPH_OFFSET_TO_TOGGLE_BOX_Y 9
-#define MPH_DIF_SETTINGS_X iScreenWidthOffset + 320
-#define MPH_DIF_SETTINGS_Y iScreenHeightOffset + 75
-#define MPH_DIF_SETTINGS_WIDTH MPH_OFFSET_TO_TOGGLE_BOX - MPH_OFFSET_TO_TEXT
+// ---------------------------------
+// Y-Offset for Combo-Controls
+#define COMBO_Y_OFFSET 63
+// Y-Offset for Check-Controls
+#define CHECK_Y_OFFSET 50
-#define MPH_GAMETYPE_SETTINGS_X iScreenWidthOffset + 20
-#define MPH_GAMETYPE_SETTINGS_Y iScreenHeightOffset + 75
-#define MPH_GAMETYPE_SETTINGS_WIDTH MPH_OFFSET_TO_TOGGLE_BOX - MPH_OFFSET_TO_TEXT
+#define CORRECTION_Y_OFFSET (COMBO_Y_OFFSET - CHECK_Y_OFFSET)
-#define MPH_OVERRIDEMAXAI_X MPH_DIF_SETTINGS_X
-#define MPH_OVERRIDEMAXAI_Y MPH_TXT_SVRNAME_Y
-#define MPH_OVERRIDEMAXAI_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+// X-Offset for Checkbox-Controls
+#define CHECK_X_OFFSET 36
+#define COMBO_X_OFFSET 0
-#define MPH_RNDMERC_X MPH_DIF_SETTINGS_X
-#define MPH_RNDMERC_Y MPH_OVERRIDEMAXAI_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_RNDMERC_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define CHECK_WIDTH (MPH_OFFSET_TO_TOGGLE_BOX - MPH_OFFSET_TO_TEXT)
+#define COMBO_WIDTH (MPH_OFFSET_TO_TOGGLE_BOX - MPH_OFFSET_TO_TEXT)
+// ---------------------------------
-#define MPH_SAMEMERC_X MPH_DIF_SETTINGS_X
-#define MPH_SAMEMERC_Y MPH_RNDMERC_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_SAMEMERC_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+/*********************************
+ FIRST COLUMN
+**********************************/
-#define MPH_REPORTMERC_X MPH_DIF_SETTINGS_X
-#define MPH_REPORTMERC_Y MPH_SAMEMERC_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_REPORTMERC_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define FIRST_COLUMN_X iScreenWidthOffset + 10
+#define FIRST_COLUMN_Y iScreenHeightOffset + 75
-#define MPH_BOBBYRAY_X MPH_DIF_SETTINGS_X
-#define MPH_BOBBYRAY_Y MPH_REPORTMERC_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_BOBBYRAY_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define MPH_SYNC_SETTING_X FIRST_COLUMN_X + CHECK_X_OFFSET
+#define MPH_SYNC_SETTING_Y FIRST_COLUMN_Y - CORRECTION_Y_OFFSET
+#define MPH_SYNC_SETTING_WIDTH CHECK_WIDTH
-#define MPH_RNDSPAWN_X MPH_DIF_SETTINGS_X
-#define MPH_RNDSPAWN_Y MPH_BOBBYRAY_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_RNDSPAWN_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define MPH_SQUADSIZE_SETTING_X FIRST_COLUMN_X + COMBO_X_OFFSET
+#define MPH_SQUADSIZE_SETTING_Y MPH_SYNC_SETTING_Y + COMBO_Y_OFFSET + CORRECTION_Y_OFFSET
+#define MPH_SQUADSIZE_SETTING_WIDTH COMBO_WIDTH
-#define MPH_CIVS_X MPH_DIF_SETTINGS_X
-#define MPH_CIVS_Y MPH_RNDSPAWN_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_CIVS_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define MPH_TIMETURNS_SETTING_X FIRST_COLUMN_X + COMBO_X_OFFSET
+#define MPH_TIMETURNS_SETTING_Y MPH_SQUADSIZE_SETTING_Y + COMBO_Y_OFFSET
+#define MPH_TIMETURNS_SETTING_WIDTH COMBO_WIDTH
-#define MPH_USENIV_X MPH_DIF_SETTINGS_X
-#define MPH_USENIV_Y MPH_CIVS_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_USENIV_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define MPH_INVENTORY_SETTING_X FIRST_COLUMN_X + COMBO_X_OFFSET
+#define MPH_INVENTORY_SETTING_Y MPH_TIMETURNS_SETTING_Y + COMBO_Y_OFFSET
+#define MPH_INVENTORY_SETTING_WIDTH COMBO_WIDTH
-#define MPH_SEND_FILES_X MPH_DIF_SETTINGS_X
-#define MPH_SEND_FILES_Y MPH_USENIV_Y + MPH_GAP_BN_SETTINGS - 5
-#define MPH_SEND_FILES_WIDTH MPH_OFFSET_TO_TOGGLE_BOX
+#define MPH_BOBBYRAY_SETTING_X FIRST_COLUMN_X + CHECK_X_OFFSET
+#define MPH_BOBBYRAY_SETTING_Y MPH_INVENTORY_SETTING_Y + CHECK_Y_OFFSET
+#define MPH_BOBBYRAY_SETTING_WIDTH CHECK_WIDTH
-//Difficulty settings
-enum
-{
- MPH_DIFF_HARD,
- MPH_DIFF_INSANE,
- MPH_NUM_DIFF_SETTINGS,
-};
+#define MPH_REPORTMERC_SETTING_X FIRST_COLUMN_X + CHECK_X_OFFSET
+#define MPH_REPORTMERC_SETTING_Y MPH_BOBBYRAY_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET
+#define MPH_REPORTMERC_SETTING_WIDTH CHECK_WIDTH
+/*********************************
+ SECOND COLUMN
+**********************************/
-////////////////////////////////////////////
+#define SECOND_COLUMN_X iScreenWidthOffset + 210
+#define SECOND_COLUMN_Y FIRST_COLUMN_Y
+
+#define MPH_MAXPLAYERS_SETTING_X SECOND_COLUMN_X + COMBO_X_OFFSET
+#define MPH_MAXPLAYERS_SETTING_Y SECOND_COLUMN_Y
+#define MPH_MAXPLAYERS_SETTING_WIDTH COMBO_WIDTH
+
+#define MPH_STARTINGTIME_SETTING_X SECOND_COLUMN_X + COMBO_X_OFFSET
+#define MPH_STARTINGTIME_SETTING_Y MPH_MAXPLAYERS_SETTING_Y + COMBO_Y_OFFSET
+#define MPH_STARTINGTIME_SETTING_WIDTH COMBO_WIDTH
+
+#define MPH_WEAPONDAMAGE_SETTING_X SECOND_COLUMN_X + COMBO_X_OFFSET
+#define MPH_WEAPONDAMAGE_SETTING_Y MPH_STARTINGTIME_SETTING_Y + COMBO_Y_OFFSET
+#define MPH_WEAPONDAMAGE_SETTING_WIDTH COMBO_WIDTH
+
+#define MPH_TRAITS_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET
+#define MPH_TRAITS_SETTING_Y MPH_WEAPONDAMAGE_SETTING_Y + CHECK_Y_OFFSET
+#define MPH_TRAITS_SETTING_WIDTH CHECK_WIDTH
+
+#define MPH_HIREMERC_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET
+#define MPH_HIREMERC_SETTING_Y MPH_TRAITS_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET
+#define MPH_HIREMERC_SETTING_WIDTH CHECK_WIDTH
+
+#define MPH_CIVS_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET
+#define MPH_CIVS_SETTING_Y MPH_HIREMERC_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET
+#define MPH_CIVS_SETTING_WIDTH CHECK_WIDTH
+
+/*********************************
+ THIRD COLUMN
+**********************************/
+
+#define THIRD_COLUMN_X iScreenWidthOffset + 413
+#define THIRD_COLUMN_Y FIRST_COLUMN_Y
+
+#define MPH_GAMETYPE_SETTING_X THIRD_COLUMN_X + COMBO_X_OFFSET
+#define MPH_GAMETYPE_SETTING_Y THIRD_COLUMN_Y
+#define MPH_GAMETYPE_SETTING_WIDTH COMBO_WIDTH
+
+#define MPH_STARTINGCASH_SETTING_X THIRD_COLUMN_X + COMBO_X_OFFSET
+#define MPH_STARTINGCASH_SETTING_Y MPH_GAMETYPE_SETTING_Y + COMBO_Y_OFFSET
+#define MPH_STARTINGCASH_SETTING_WIDTH COMBO_WIDTH
+
+#define MPH_SECTOREDGE_SETTING_X THIRD_COLUMN_X + CHECK_X_OFFSET
+#define MPH_SECTOREDGE_SETTING_Y MPH_STARTINGCASH_SETTING_Y + CHECK_Y_OFFSET
+#define MPH_SECTOREDGE_SETTING_WIDTH CHECK_WIDTH
+
+#define MPH_DIFFICULTY_SETTING_X THIRD_COLUMN_X + COMBO_X_OFFSET
+#define MPH_DIFFICULTY_SETTING_Y MPH_SECTOREDGE_SETTING_Y + COMBO_Y_OFFSET + CORRECTION_Y_OFFSET
+#define MPH_DIFFICULTY_SETTING_WIDTH COMBO_WIDTH
+
+#define MPH_MAXENEMIES_SETTING_X THIRD_COLUMN_X + CHECK_X_OFFSET
+#define MPH_MAXENEMIES_SETTING_Y MPH_DIFFICULTY_SETTING_Y + CHECK_Y_OFFSET
+#define MPH_MAXENEMIES_SETTING_WIDTH CHECK_WIDTH
+
+#define MPH_SAMEMERC_SETTING_X THIRD_COLUMN_X + CHECK_X_OFFSET
+#define MPH_SAMEMERC_SETTING_Y MPH_MAXENEMIES_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET
+#define MPH_SAMEMERC_SETTING_WIDTH CHECK_WIDTH
+
+///////////////////////////////////////////
//
// Global Variables
//
@@ -204,6 +195,1292 @@ BOOLEAN gfMPHScreenExit = FALSE;
BOOLEAN gfReRenderMPHScreen=TRUE;
BOOLEAN gfMPHButtonsAllocated = FALSE;
+// RW:
+UINT32 guiMPHSMALLFRAME;
+
+void RenderMPHSmallSelectionFrame(INT16 sX, INT16 sY);
+
+// ----------------
+// Traits
+enum
+{
+ MPH_TRAITS_OLD = 0,
+ MPH_TRAITS_NEW = 1,
+
+ MPH_NUM_TRAITS_OPTIONS,
+};
+
+UINT32 guiMPHTraitsOptionTogglesImage[ MPH_NUM_TRAITS_OPTIONS ];
+UINT32 guiMPHTraitsOptionToggles[ MPH_NUM_TRAITS_OPTIONS ];
+void BtnMPHOldTraitsCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHNewTraitsCallback(GUI_BUTTON *btn,INT32 reason);
+void MTHNewTraitsNotPossibleMessageBoxCallBack( UINT8 bExitValue );
+
+void BtnMPHOldTraitsCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_TRAITS_SETTING_X), (MPH_TRAITS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHTraitsOptionToggles[ MPH_TRAITS_OLD ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+BOOLEAN DoMPHMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback )
+{
+ SGPRect CenteringRect= {0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
+
+ // do message box and return
+ giMPHMessageBox = DoMessageBox( ubStyle, zString, uiExitScreen, ( UINT16 ) ( usFlags| MSG_BOX_FLAG_USE_CENTERING_RECT ), ReturnCallback, &CenteringRect );
+
+ // send back return state
+ return( ( giMPHMessageBox != -1 ) );
+}
+
+UINT8 GetMPHCurrentTraitsOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+void BtnMPHNewTraitsCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ if (!gGameExternalOptions.fReadProfileDataFromXML)
+ {
+ PlayButtonSound( guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ], BUTTON_SOUND_DISABLED_CLICK );
+
+ DoMPHMessageBox( MSG_BOX_BASIC_STYLE, zGioNewTraitsImpossibleText[0], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, MTHNewTraitsNotPossibleMessageBoxCallBack );
+ }
+ else
+ {
+ RestoreExternBackgroundRect( (MPH_TRAITS_SETTING_X), (MPH_TRAITS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHTraitsOptionToggles[ MPH_TRAITS_OLD ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ], BUTTON_SOUND_CLICKED_ON );
+ }
+ }
+}
+
+void MTHNewTraitsNotPossibleMessageBoxCallBack( UINT8 bExitValue )
+{
+}
+
+// ----------------
+
+// -------------
+// Sync
+enum
+{
+ MPH_SYNC_NO = 0,
+ MPH_SYNC_YES = 1,
+
+ MPH_NUM_SYNC_OPTIONS,
+};
+
+UINT32 guiMPHSyncOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHSyncOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHNoSyncCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHYesSyncCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHNoSyncCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_SYNC_SETTING_X), (MPH_SYNC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHSyncOptionToggles[ MPH_SYNC_YES ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHSyncOptionToggles[ MPH_SYNC_NO ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+void BtnMPHYesSyncCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_SYNC_SETTING_X), (MPH_SYNC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHSyncOptionToggles[ MPH_SYNC_NO ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHSyncOptionToggles[ MPH_SYNC_YES ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentSyncOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// MaxEnemies
+enum
+{
+ MPH_MAXENEMIES_NO = 0,
+ MPH_MAXENEMIES_YES = 1,
+
+ MPH_NUM_MAXENEMIES_OPTIONS,
+};
+
+UINT32 guiMPHMaxEnemiesOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHMaxEnemiesOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHNoMaxEnemiesCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHYesMaxEnemiesCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHNoMaxEnemiesCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_MAXENEMIES_SETTING_X), (MPH_MAXENEMIES_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_YES ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_NO ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHYesMaxEnemiesCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_MAXENEMIES_SETTING_X), (MPH_MAXENEMIES_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_NO ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_YES ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentMaxEnemiesOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// Civs
+enum
+{
+ MPH_CIVS_NO = 0,
+ MPH_CIVS_YES = 1,
+
+ MPH_NUM_CIVS_OPTIONS,
+};
+
+UINT32 guiMPHCivsOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHCivsOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHNoCivsCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHYesCivsCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHNoCivsCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_CIVS_SETTING_X), (MPH_CIVS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHCivsOptionToggles[ MPH_CIVS_YES ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHCivsOptionToggles[ MPH_CIVS_NO ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHYesCivsCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_CIVS_SETTING_X), (MPH_CIVS_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHCivsOptionToggles[ MPH_CIVS_NO ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHCivsOptionToggles[ MPH_CIVS_YES ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentCivsOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// ReportMerc
+enum
+{
+ MPH_REPORTMERC_NO = 0,
+ MPH_REPORTMERC_YES = 1,
+
+ MPH_NUM_REPORTMERC_OPTIONS,
+};
+
+UINT32 guiMPHReportMercOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHReportMercOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHNoReportMercCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHYesReportMercCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHNoReportMercCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_REPORTMERC_SETTING_X), (MPH_REPORTMERC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHReportMercOptionToggles[ MPH_REPORTMERC_YES ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHReportMercOptionToggles[ MPH_REPORTMERC_NO ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHYesReportMercCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_REPORTMERC_SETTING_X), (MPH_REPORTMERC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHReportMercOptionToggles[ MPH_REPORTMERC_NO ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHReportMercOptionToggles[ MPH_REPORTMERC_YES ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentReportMercOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// HireMerc
+enum
+{
+ MPH_HIREMERC_NORMAL = 0,
+ MPH_HIREMERC_RANDOM = 1,
+
+ MPH_NUM_HIREMERC_OPTIONS,
+};
+
+UINT32 guiMPHHireMercOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHHireMercOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHRandomHireMercCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHNormalHireMercCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHRandomHireMercCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_HIREMERC_SETTING_X), (MPH_HIREMERC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHHireMercOptionToggles[ MPH_HIREMERC_NORMAL ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHHireMercOptionToggles[ MPH_HIREMERC_RANDOM ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHNormalHireMercCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_HIREMERC_SETTING_X), (MPH_HIREMERC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHHireMercOptionToggles[ MPH_HIREMERC_RANDOM ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHHireMercOptionToggles[ MPH_HIREMERC_NORMAL ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentHireMercOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// SectorEdge
+enum
+{
+ MPH_SECTOREDGE_SELECTABLE = 0,
+ MPH_SECTOREDGE_RANDOM = 1,
+
+ MPH_NUM_SECTOREDGE_OPTIONS,
+};
+
+UINT32 guiMPHSectorEdgeOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHSectorEdgeOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHRandomSectorEdgeCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHSelectableSectorEdgeCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHRandomSectorEdgeCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_SECTOREDGE_SETTING_X), (MPH_SECTOREDGE_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_SELECTABLE ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_RANDOM ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHSelectableSectorEdgeCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_SECTOREDGE_SETTING_X), (MPH_SECTOREDGE_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_RANDOM ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_SELECTABLE ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentSectorEdgeOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// BobbyRay
+enum
+{
+ MPH_BOBBYRAY_ALLOW = 0,
+ MPH_BOBBYRAY_DISABLE = 1,
+
+ MPH_NUM_BOBBYRAY_OPTIONS,
+};
+
+UINT32 guiMPHBobbyRayOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHBobbyRayOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHDisableBobbyRayCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHAllowBobbyRayCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHDisableBobbyRayCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_BOBBYRAY_SETTING_X), (MPH_BOBBYRAY_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_ALLOW ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_DISABLE ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHAllowBobbyRayCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_BOBBYRAY_SETTING_X), (MPH_BOBBYRAY_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_DISABLE ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_ALLOW ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentBobbyRayOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// SameMerc
+enum
+{
+ MPH_SAMEMERC_DISABLE = 0,
+ MPH_SAMEMERC_ALLOW = 1,
+
+ MPH_NUM_SAMEMERC_OPTIONS,
+};
+
+UINT32 guiMPHSameMercOptionTogglesImage[ MPH_NUM_SYNC_OPTIONS ];
+UINT32 guiMPHSameMercOptionToggles[ MPH_NUM_SYNC_OPTIONS ];
+void BtnMPHDisableSameMercCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnMPHAllowSameMercCallback(GUI_BUTTON *btn,INT32 reason);
+
+void BtnMPHDisableSameMercCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_SAMEMERC_SETTING_X), (MPH_SAMEMERC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHSameMercOptionToggles[ MPH_SAMEMERC_ALLOW ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHSameMercOptionToggles[ MPH_SAMEMERC_DISABLE ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+void BtnMPHAllowSameMercCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ RestoreExternBackgroundRect( (MPH_SAMEMERC_SETTING_X), (MPH_SAMEMERC_SETTING_Y + 10), 230, 40 );
+
+ ButtonList[ guiMPHSameMercOptionToggles[ MPH_SAMEMERC_DISABLE ] ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ btn->uiFlags|=(BUTTON_CLICKED_ON);
+
+ PlayButtonSound( guiMPHSameMercOptionToggles[ MPH_SAMEMERC_ALLOW ], BUTTON_SOUND_CLICKED_ON );
+ }
+}
+
+UINT8 GetCurrentSameMercOptionButtonSetting()
+{
+ UINT8 cnt;
+
+ for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
+ {
+ return( cnt );
+ }
+ }
+ return( 0 );
+}
+
+// -------------
+
+// -------------
+// Difficulty
+enum
+{
+ MPH_DIFF_EASY = 0,
+ MPH_DIFF_MED = 1,
+ MPH_DIFF_HARD = 2,
+ MPH_DIFF_INSANE = 3,
+
+ MPH_NUM_DIFF_SETTINGS,
+};
+
+INT8 iMPHDifficulty;
+
+UINT32 giMPHDifficultyButton[ 2 ];
+INT32 giMPHDifficultyButtonImage[ 2 ];
+void BtnMPHDifficultySelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHDifficultySelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHDifficultySelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHDifficulty > 0 )
+ {
+ PlayButtonSound( giMPHDifficultyButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHDifficulty--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHDifficultyButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHDifficultySelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ if ( iMPHDifficulty < 3 )
+ {
+ PlayButtonSound( giMPHDifficultyButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHDifficulty++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHDifficultyButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// GameType
+enum
+{
+ MPH_GT_DEATHMATCH = 0,
+ MPH_GT_TEAM_DEATHMATCH = 1,
+ MPH_GT_COOP = 2,
+
+ MPH_NUM_GAMETYPE_SETTINGS,
+};
+
+INT8 iMPHGameType;
+
+UINT32 giMPHGameTypeButton[ 2 ];
+INT32 giMPHGameTypeButtonImage[ 2 ];
+void BtnMPHGameTypeSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHGameTypeSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHGameTypeSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHGameType > MPH_GT_DEATHMATCH )
+ {
+ PlayButtonSound( giMPHGameTypeButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHGameType--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHGameTypeButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHGameTypeSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHGameType < MPH_GT_COOP )
+ {
+ PlayButtonSound( giMPHGameTypeButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHGameType++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHGameTypeButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// MaxPlayers
+enum
+{
+ MPH_MAXPLAYERS_2 = 2,
+ MPH_MAXPLAYERS_3 = 3,
+ MPH_MAXPLAYERS_4 = 4,
+
+ MPH_NUM_MAXPLAYERS_SETTINGS,
+};
+
+INT8 iMPHMaxPlayers;
+
+UINT32 giMPHMaxPlayersButton[ 2 ];
+INT32 giMPHMaxPlayersButtonImage[ 2 ];
+void BtnMPHMaxPlayersSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHMaxPlayersSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHMaxPlayersSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHMaxPlayers > MPH_MAXPLAYERS_2 )
+ {
+ PlayButtonSound( giMPHMaxPlayersButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHMaxPlayers--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHMaxPlayersButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHMaxPlayersSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHMaxPlayers < MPH_MAXPLAYERS_4 )
+ {
+ PlayButtonSound( giMPHMaxPlayersButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHMaxPlayers++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHMaxPlayersButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// Inventory
+enum
+{
+ MPH_INV_OLD = 0,
+ MPH_INV_NEW = 1,
+ MPH_INV_NEW_NAS = 2,
+
+ MPH_NUM_INV_OPTIONS,
+};
+
+INT8 iMPHInventory;
+
+UINT32 giMPHInventoryButton[ 2 ];
+INT32 giMPHInventoryButtonImage[ 2 ];
+void BtnMPHInventorySelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHInventorySelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHInventorySelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHInventory > MPH_INV_OLD )
+ {
+ PlayButtonSound( giMPHInventoryButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHInventory--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHInventoryButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHInventorySelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHInventory < MPH_INV_NEW_NAS )
+ {
+ PlayButtonSound( giMPHInventoryButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHInventory++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHInventoryButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// StartingTime
+enum
+{
+ MPH_STARTINGTIME_MORNING = 0,
+ MPH_STARTINGTIME_AFTERNOON = 1,
+ MPH_STARTINGTIME_NIGHT = 2,
+
+ MPH_NUM_STARTINGTIME_SETTINGS,
+};
+
+INT8 iMPHStartingTime;
+
+UINT32 giMPHStartingTimeButton[ 2 ];
+INT32 giMPHStartingTimeButtonImage[ 2 ];
+void BtnMPHStartingTimeSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHStartingTimeSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHStartingTimeSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHStartingTime > MPH_STARTINGTIME_MORNING )
+ {
+ PlayButtonSound( giMPHStartingTimeButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHStartingTime--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHStartingTimeButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHStartingTimeSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHStartingTime < MPH_STARTINGTIME_NIGHT )
+ {
+ PlayButtonSound( giMPHStartingTimeButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHStartingTime++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHStartingTimeButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// StartingCash
+enum
+{
+ MPH_STARTINGCASH_LOW = 0,
+ MPH_STARTINGCASH_MEDIUM = 1,
+ MPH_STARTINGCASH_HIGH = 2,
+ MPH_STARTINGCASH_UNLIMITED = 3,
+
+ MPH_NUM_STARTINGCASH_SETTINGS,
+};
+
+INT8 iMPHStartingCash;
+
+UINT32 giMPHStartingCashButton[ 2 ];
+INT32 giMPHStartingCashButtonImage[ 2 ];
+void BtnMPHStartingCashSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHStartingCashSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHStartingCashSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHStartingCash > MPH_STARTINGCASH_LOW )
+ {
+ PlayButtonSound( giMPHStartingCashButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHStartingCash--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHStartingCashButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHStartingCashSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHStartingCash < MPH_STARTINGCASH_UNLIMITED )
+ {
+ PlayButtonSound( giMPHStartingCashButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHStartingCash++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHStartingCashButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// WeaponDamage
+enum
+{
+ MPH_WEAPONDAMAGE_VERYLOW = 0,
+ MPH_WEAPONDAMAGE_LOW = 1,
+ MPH_WEAPONDAMAGE_NORMAL = 2,
+
+ MPH_NUM_WEAPONDAMAGE_SETTINGS,
+};
+
+INT8 iMPHWeaponDamage;
+
+UINT32 giMPHWeaponDamageButton[ 2 ];
+INT32 giMPHWeaponDamageButtonImage[ 2 ];
+void BtnMPHWeaponDamageSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHWeaponDamageSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHWeaponDamageSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHWeaponDamage > MPH_WEAPONDAMAGE_VERYLOW )
+ {
+ PlayButtonSound( giMPHWeaponDamageButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHWeaponDamage--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHWeaponDamageButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHWeaponDamageSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHWeaponDamage < MPH_WEAPONDAMAGE_NORMAL )
+ {
+ PlayButtonSound( giMPHWeaponDamageButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHWeaponDamage++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHWeaponDamageButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// TimeTurns
+enum
+{
+ MPH_TIMETURNS_NEVER = 0,
+ MPH_TIMETURNS_SLOW = 1,
+ MPH_TIMETURNS_MEDIUM = 2,
+ MPH_TIMETURNS_FAST = 3,
+
+ MPH_NUM_TIMETURNS_SETTINGS,
+};
+
+INT8 iMPHTimeTurns;
+
+UINT32 giMPHTimeTurnsButton[ 2 ];
+INT32 giMPHTimeTurnsButtonImage[ 2 ];
+void BtnMPHTimeTurnsSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHTimeTurnsSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHTimeTurnsSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHTimeTurns > MPH_TIMETURNS_NEVER )
+ {
+ PlayButtonSound( giMPHTimeTurnsButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHTimeTurns--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHTimeTurnsButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHTimeTurnsSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHTimeTurns < MPH_TIMETURNS_FAST )
+ {
+ PlayButtonSound( giMPHTimeTurnsButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHTimeTurns++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHTimeTurnsButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
+// -------------
+// SquadSize
+enum
+{
+ MPH_SQUADSIZE_1 = 1,
+ MPH_SQUADSIZE_2 = 2,
+ MPH_SQUADSIZE_3 = 3,
+ MPH_SQUADSIZE_4 = 4,
+ MPH_SQUADSIZE_5 = 5,
+ MPH_SQUADSIZE_6 = 6,
+
+ MPH_NUM_SQUADSIZE_SETTINGS,
+};
+
+INT8 iMPHSquadSize;
+
+UINT32 giMPHSquadSizeButton[ 2 ];
+INT32 giMPHSquadSizeButtonImage[ 2 ];
+void BtnMPHSquadSizeSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason );
+void BtnMPHSquadSizeSelectionRightCallback( GUI_BUTTON *btn,INT32 reason );
+
+void BtnMPHSquadSizeSelectionLeftCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHSquadSize > MPH_SQUADSIZE_1 )
+ {
+ PlayButtonSound( giMPHSquadSizeButton[0], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHSquadSize--;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHSquadSizeButton[0], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+void BtnMPHSquadSizeSelectionRightCallback( GUI_BUTTON *btn,INT32 reason )
+{
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if( reason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT || reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
+ {
+ if ( iMPHSquadSize < MPH_SQUADSIZE_6 )
+ {
+ PlayButtonSound( giMPHSquadSizeButton[1], BUTTON_SOUND_CLICKED_ON );
+
+ iMPHSquadSize++;
+ gfReRenderMPHScreen =TRUE;
+ }
+ else
+ {
+ PlayButtonSound( giMPHSquadSizeButton[1], BUTTON_SOUND_DISABLED_CLICK );
+ }
+ }
+ else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ if (btn->uiFlags & BUTTON_CLICKED_ON)
+ {
+ btn->uiFlags&=~(BUTTON_CLICKED_ON);
+ }
+ }
+}
+
+// -------------
+
//enum for different states of screen
enum
{
@@ -218,34 +1495,38 @@ UINT32 gubMPHExitScreen = MP_HOST_SCREEN; // The screen that is in control next
UINT32 guiMPHMainBackGroundImage;
+// ------------
+// String fields
// Wide-char strings that will hold the variables until they are transferred to the CHAR ascii fields
CHAR16 gzServerNameField[ 30 ] = {0} ;
-CHAR16 gzMaxPlayersField[ 2 ] = {0} ;
-CHAR16 gzSquadSizeField[ 2 ] = {0} ;
-CHAR16 gzTimeOfDayField[ 6 ] = {0};
-CHAR16 gzStartingBalanceField[ 10 ] = {0};
-INT16 giMPHTimeHours = 0;
-INT16 giMPHTimeMins = 0;
-CHAR16 gzDmgMultiplierField[ 5 ] = {0};
-CHAR16 gzTimerField[ 6 ] = {0};
CHAR16 gzFileTransferDirectory[ 100 ] = {0} ;
CHAR16 gzKitBag[ 100 ] = {0};
-UINT8 guiMPHGameType = MP_TYPE_DEATHMATCH; // default value
-UINT8 guiMPHDifficultLevel = DIF_LEVEL_HARD; // Expert
-
-INT32 giMPHMessageBox = -1; // message box handle
-
-INT giMPHOverrideMaxAI = 0;
-INT giMPHRandomMercs = 0;
-INT giMPHSameMercs = 0;
-INT giMPHReportMercs = 0;
-INT giMPHBobbyRays = 0;
-INT giMPHRandomSpawn = 0;
-INT giMPHEnableCivilians = 0;
-INT giMPHUseNIV = 0;
-INT giMPHSendFiles = 0;
+// ------------
+// Controls with Multi Selection!
+UINT8 guiMPHGameType;
+UINT8 guiMPHDifficultLevel;
+UINT8 guiMPHMaxPlayers;
+UINT8 guiMPHSquadSize;
+UINT8 guiMPHStartingTime;
+UINT8 guiMPHStartingCash;
+UINT8 guiMPHTimeTurns;
+UINT8 guiMPHWeaponDamage;
+UINT8 guiMPHInventory;
+// ------------
+// ------------
+// Controls with YES/NO
+UINT8 guiMPHMaxEnemies;
+UINT8 guiMPHSendFiles;
+UINT8 guiMPHHireMerc;
+UINT8 guiMPHSectorEdge;
+UINT8 guiMPHBobbyRay;
+UINT8 guiMPHSameMerc;
+UINT8 guiMPHReportMerc;
+UINT8 guiMPHCivs;
+UINT8 guiMPHNewTraits;
+// ------------
////////////////////////////////////////////
//
@@ -263,51 +1544,6 @@ void BtnMPHCancelCallback(GUI_BUTTON *btn,INT32 reason);
UINT32 guiMPHCancelButton;
INT32 giMPHCancelBtnImage;
-//checkbox to toggle the Diff level
-UINT32 guiMPHDifficultySettingsToggles[ MPH_NUM_DIFF_SETTINGS ];
-void BtnMPHDifficultyTogglesCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox to toggle Game Type
-UINT32 guiMPHGameTypeToggles[ NUM_MP_GAMETYPE ];
-void BtnMPHGameTypeTogglesCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for override max ai
-UINT32 guiMPHOverrideMaxAIToggle;
-void BtnMPHOverrideMaxAICallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for merc options
-UINT32 guiMPHRandomMercsToggle;
-void BtnMPHRandomMercCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for same merc
-UINT32 guiMPHSameMercToggle;
-void BtnMPHSameMercCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for report purchase
-UINT32 guiMPHReportMercToggle;
-void BtnMPHReportMercCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for bobby rays
-UINT32 guiMPHBobbyRayToggle;
-void BtnMPHBobbyRayCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for random spawn pos
-UINT32 guiMPHRandomSpawnToggle;
-void BtnMPHRandomSpawnCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for enable civilians in CO-OP
-UINT32 guiMPHCivsToggle;
-void BtnMPHCivsCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for use NIV
-UINT32 guiMPHUseNIVToggle;
-void BtnMPHUseNIVCallback(GUI_BUTTON *btn,INT32 reason);
-
-//checkbox for send files
-UINT32 guiMPHSendFiles;
-void BtnMPHSendFilesCallback(GUI_BUTTON *btn,INT32 reason);
-
-
////////////////////////////////////////////
//
// Local Function Prototypes
@@ -321,14 +1557,12 @@ BOOLEAN ExitMPHScreen();
void HandleMPHScreen();
BOOLEAN RenderMPHScreen();
void GetMPHScreenUserInput();
-void RestoreMPHButtonBackGrounds();
bool ValidateMPSettings();
void SaveMPSettings();
-UINT8 GetMPHCurrentDifficultyButtonSetting();
UINT8 GetMPHGameTypeButtonSetting();
-BOOLEAN DoMPHMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback );
-void DoneFadeOutForExitMPHScreen( void );
-void DoneFadeInForExitMPHScreen( void );
+BOOLEAN DoMPHMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback );
+void DoneFadeOutForExitMPHScreen( void );
+void DoneFadeInForExitMPHScreen( void );
////////////////////////////////////////////
//
@@ -337,423 +1571,149 @@ void DoneFadeInForExitMPHScreen( void );
///////////////////////////////////////////
void SaveMPSettings()
-{
- Get16BitStringFromField( 0, gzServerNameField, 30 ); // these indexes are based on the order created
- Get16BitStringFromField( 1, gzMaxPlayersField, 2 );
- Get16BitStringFromField( 2, gzSquadSizeField, 2 );
- Get16BitStringFromField( 7, gzFileTransferDirectory, 100 );
-#ifndef USE_VFS
- // save settings to JA2_mp.ini
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"SERVER_NAME", gzServerNameField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"MAX_CLIENTS", gzMaxPlayersField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"MAX_MERCS", gzSquadSizeField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"STARTING_BALANCE", gzStartingBalanceField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"DAMAGE_MULTIPLIER", gzDmgMultiplierField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"TIMED_TURN_SECS_PER_TICK", gzTimerField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"FILE_TRANSFER_DIRECTORY", gzFileTransferDirectory , L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"KIT_BAG", gzKitBag , L"..\\Ja2_mp.ini" );
-
-
-
- guiMPHGameType = GetMPHGameTypeButtonSetting();
- CHAR16 tmpGTStr[2];
- _itow(guiMPHGameType,tmpGTStr,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"GAME_MODE", tmpGTStr, L"..\\Ja2_mp.ini" );
-
- CHAR16 tmpTimeStr[6];
- swprintf(tmpTimeStr,L"%i.%i",giMPHTimeHours,giMPHTimeMins);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"TIME", tmpTimeStr, L"..\\Ja2_mp.ini" );
-
- CHAR16 tmpVal[2];
-
- giMPHOverrideMaxAI = ( ButtonList[ guiMPHOverrideMaxAIToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHOverrideMaxAI,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"OVERRIDE_MAX_AI", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHRandomMercs = ( ButtonList[ guiMPHRandomMercsToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHRandomMercs,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"RANDOM_MERCS", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHSameMercs = ( ButtonList[ guiMPHSameMercToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHSameMercs,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"SAME_MERC", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHBobbyRays = ( ButtonList[ guiMPHBobbyRayToggle ]->uiFlags & BUTTON_CLICKED_ON ? 0 : 1 ); // This setting is reversed
- _itow(giMPHBobbyRays,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"DISABLE_BOBBY_RAYS", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHReportMercs = ( ButtonList[ guiMPHReportMercToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHReportMercs,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"REPORT_NAME", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHRandomSpawn = ( ButtonList[ guiMPHRandomSpawnToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHRandomSpawn,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"RANDOM_EDGES", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHEnableCivilians = ( ButtonList[ guiMPHCivsToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHEnableCivilians,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"CIV_ENABLED", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHUseNIV = ( ButtonList[ guiMPHUseNIVToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHUseNIV,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"ALLOW_CUSTOM_NIV", tmpVal, L"..\\Ja2_mp.ini" );
-
- giMPHSendFiles = ( ButtonList[ guiMPHSendFiles ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHSendFiles,tmpVal,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"SYNC_CLIENTS_MP_DIR", tmpVal, L"..\\Ja2_mp.ini" );
- guiMPHDifficultLevel = GetMPHCurrentDifficultyButtonSetting();
- CHAR16 tmpDiffStr[2];
- _itow(guiMPHDifficultLevel,tmpDiffStr,10);
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"DIFFICULT_LEVEL", tmpDiffStr, L"..\\Ja2_mp.ini" );
-#else
- CPropertyContainer props;
- props.initFromIniFile("Ja2_mp.ini");
-
- props.setStringProperty(L"Ja2_mp Settings",L"SERVER_NAME", gzServerNameField);
- props.setStringProperty(L"Ja2_mp Settings",L"MAX_CLIENTS", gzMaxPlayersField);
- props.setStringProperty(L"Ja2_mp Settings",L"MAX_MERCS", gzSquadSizeField);
- props.setStringProperty(L"Ja2_mp Settings",L"STARTING_BALANCE", gzStartingBalanceField);
- props.setStringProperty(L"Ja2_mp Settings",L"DAMAGE_MULTIPLIER", gzDmgMultiplierField);
- props.setStringProperty(L"Ja2_mp Settings",L"TIMED_TURN_SECS_PER_TICK", gzTimerField);
- props.setStringProperty(L"Ja2_mp Settings",L"FILE_TRANSFER_DIRECTORY", gzFileTransferDirectory);
- props.setStringProperty(L"Ja2_mp Settings",L"KIT_BAG", gzKitBag);
-
-
- guiMPHGameType = GetMPHGameTypeButtonSetting();
- CHAR16 tmpGTStr[2];
- _itow(guiMPHGameType,tmpGTStr,10);
- props.setStringProperty(L"Ja2_mp Settings",L"GAME_MODE", tmpGTStr);
-
- CHAR16 tmpTimeStr[6];
- swprintf(tmpTimeStr,L"%i.%i",giMPHTimeHours,giMPHTimeMins);
- props.setStringProperty(L"Ja2_mp Settings",L"TIME", tmpTimeStr);
-
- CHAR16 tmpVal[2];
-
- giMPHOverrideMaxAI = ( ButtonList[ guiMPHOverrideMaxAIToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHOverrideMaxAI,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"OVERRIDE_MAX_AI", tmpVal);
-
- giMPHRandomMercs = ( ButtonList[ guiMPHRandomMercsToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHRandomMercs,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"RANDOM_MERCS", tmpVal);
-
- giMPHSameMercs = ( ButtonList[ guiMPHSameMercToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHSameMercs,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"SAME_MERC", tmpVal);
-
- giMPHBobbyRays = ( ButtonList[ guiMPHBobbyRayToggle ]->uiFlags & BUTTON_CLICKED_ON ? 0 : 1 ); // This setting is reversed
- _itow(giMPHBobbyRays,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"DISABLE_BOBBY_RAYS", tmpVal);
-
- giMPHReportMercs = ( ButtonList[ guiMPHReportMercToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHReportMercs,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"REPORT_NAME", tmpVal);
-
- giMPHRandomSpawn = ( ButtonList[ guiMPHRandomSpawnToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHRandomSpawn,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"RANDOM_EDGES", tmpVal);
-
- giMPHEnableCivilians = ( ButtonList[ guiMPHCivsToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHEnableCivilians,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"CIV_ENABLED", tmpVal);
-
- giMPHUseNIV = ( ButtonList[ guiMPHUseNIVToggle ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHUseNIV,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"ALLOW_CUSTOM_NIV", tmpVal);
-
- giMPHSendFiles = ( ButtonList[ guiMPHSendFiles ]->uiFlags & BUTTON_CLICKED_ON ? 1 : 0 );
- _itow(giMPHSendFiles,tmpVal,10);
- props.setStringProperty(L"Ja2_mp Settings",L"SYNC_CLIENTS_MP_DIR", tmpVal);
-
- guiMPHDifficultLevel = GetMPHCurrentDifficultyButtonSetting();
- CHAR16 tmpDiffStr[2];
- _itow(guiMPHDifficultLevel,tmpDiffStr,10);
- props.setStringProperty(L"Ja2_mp Settings",L"DIFFICULT_LEVEL", tmpDiffStr);
- props.writeToIniFile(L"Ja2_mp.ini",true); // This writes to the Profiles/UserProfile/ja2_mp.ini
-#endif
+{
+ MpIniExists();
+ vfs::PropertyContainer props;
+ props.initFromIniFile(JA2MP_INI_FILENAME);
+
+ guiMPHMaxPlayers = iMPHMaxPlayers;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_MAX_CLIENTS, guiMPHMaxPlayers);
+
+ guiMPHSquadSize = iMPHSquadSize;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_MAX_MERCS, guiMPHSquadSize);
+
+ guiMPHStartingCash = iMPHStartingCash;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_STARTING_BALANCE, guiMPHStartingCash);
+
+ guiMPHWeaponDamage = iMPHWeaponDamage;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_DAMAGE_MULTIPLIER, guiMPHWeaponDamage);
+
+ guiMPHTimeTurns = iMPHTimeTurns;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_TIMED_TURN_SECS_PER_TICK, guiMPHTimeTurns);
+
+ guiMPHGameType = iMPHGameType;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_GAME_MODE, guiMPHGameType);
+
+ guiMPHStartingTime = iMPHStartingTime;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_TIME, guiMPHStartingTime);
+
+ guiMPHMaxEnemies = GetCurrentMaxEnemiesOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_OVERRIDE_MAX_AI, guiMPHMaxEnemies);
+
+ guiMPHHireMerc = GetCurrentHireMercOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_RANDOM_MERCS, guiMPHHireMerc);
+
+ guiMPHSameMerc = GetCurrentSameMercOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_SAME_MERC, guiMPHSameMerc);
+
+ guiMPHBobbyRay = GetCurrentBobbyRayOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_DISABLE_BOBBY_RAYS, guiMPHBobbyRay);
+
+ guiMPHReportMerc = GetCurrentReportMercOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_REPORT_NAME, guiMPHReportMerc);
+
+ guiMPHSectorEdge = GetCurrentSectorEdgeOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_RANDOM_EDGES, guiMPHSectorEdge);
+
+ guiMPHCivs = GetCurrentCivsOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_CIV_ENABLED, guiMPHCivs);
+
+ guiMPHInventory = iMPHInventory;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_ALLOW_CUSTOM_NIV, guiMPHInventory);
+
+ guiMPHSendFiles = GetCurrentSyncOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_SYNC_CLIENTS_MP_DIR, guiMPHSendFiles);
+ guiMPHNewTraits = GetMPHCurrentTraitsOptionButtonSetting();
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_NEW_TRAITS, guiMPHNewTraits);
+ guiMPHDifficultLevel = iMPHDifficulty + 1;
+ props.setIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_DIFFICULT_LEVEL, guiMPHDifficultLevel - 1);
+ // This writes the data back (from the GUI) to the Profiles/UserProfile/ja2_mp.ini
+ props.writeToIniFile(JA2MP_INI_FILENAME, false);
}
bool ValidateMPSettings()
-{
- // Check a Server name is entered
- Get16BitStringFromField( 0, gzServerNameField, 30 ); // these indexes are based on the order created
- if (wcscmp(gzServerNameField,L"")<=0)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_SERVERNAME_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
- // Verify the Max Players
- Get16BitStringFromField( 1, gzMaxPlayersField, 2 );
- UINT8 numPlayers = _wtoi(gzMaxPlayersField);
- if (numPlayers < 2 || numPlayers > 4)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_MAXPLAYERS_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
- // Verify the Squad Size
- Get16BitStringFromField( 2, gzSquadSizeField, 2 );
- UINT8 squadSize = _wtoi(gzSquadSizeField);
- if (squadSize < 1 || squadSize > 6)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_SQUADSIZE_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
- // verify the Time of Day
- Get16BitStringFromField( 3, gzTimeOfDayField, 6 );
- wchar_t* tok;
- bool bTimeOK = true;
- int hours = 0;
- int mins = 0;
-
- // strtok is destructive, make a copy to work on
- CHAR16 tmpTODStr[6];
- memcpy(tmpTODStr,gzTimeOfDayField,sizeof(CHAR16)*5);
-
- tok = wcstok(tmpTODStr,L":");
- if (tok != NULL)
- {
- // Special case, because _wtoi() returns 0 if invalid number!
- if (wcscmp(tok, L"00") == 0)
- {
- hours = 0;
- }
- else
- {
- hours = _wtoi(tok);
- // check for invalid conversion, ie alpha chars
- // wtoi returns 0 if it cant convert, but we need this value
- // therefore if tok <> 0 then it was a bad convert.
- if (hours == 0 && wcscmp(tok,L"0") != 0)
- {
- // force error
- bTimeOK = false;
- }
- }
-
- tok = wcstok(NULL,L".");
- if (tok != NULL)
- {
- if (wcsnlen(tok, 50) >= 2 && tok[0] == '0' && tok[1] == '0')
- {
- mins = 0;
- }
- else
- {
- mins = _wtoi(tok);
- if (mins == 0 && wcscmp(tok,L"0") != 0)
- {
- // force error
- bTimeOK = false;
- }
- }
-
- // fix for single digits
- if (wcslen(tok) == 1)
- mins = mins * 10;
- }
- else
- {
- bTimeOK = false;
- }
- }
- else
- {
- bTimeOK = false;
- }
-
-
- if (bTimeOK)
- {
- giMPHTimeHours = hours;
- float ratio = (float)mins / 60.0f;
- giMPHTimeMins = (INT16)(ratio * 100);
-
- }
- else
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_TIME_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
-
- // verify the Starting Balance
- Get16BitStringFromField( 4, gzStartingBalanceField, 10 );
- UINT32 sBalance = _wtoi(gzStartingBalanceField);
- if (sBalance < 1)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_CASH_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
- Get16BitStringFromField( 5, gzDmgMultiplierField, 5 );
- double fDmg = _wtof(gzDmgMultiplierField);
- if (fDmg <= 0.0f || fDmg >= 5.0f)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_DMG_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
- Get16BitStringFromField( 6, gzTimerField, 6 );
- UINT32 iTimer = _wtoi(gzTimerField);
- if (iTimer < 0 || iTimer > 200)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_TIMER_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
- // Verify the File Transfer Directory
- Get16BitStringFromField( 7, gzFileTransferDirectory, 100 );
- if (wcscmp(gzFileTransferDirectory,L"")<=0)
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_FILE_TRANSFER_DIR_INVALID], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-
-#ifdef USE_VFS
+{
vfs::Path sUserDir(gzFileTransferDirectory);
- if(!os::createRealDirectory(sUserDir,true))
+ if(!vfs::OS::checkRealDirectory(sUserDir))
{
DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_FILE_TRANSFER_DIR_NOT_EXIST], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
return false;
}
-#endif
-
- //if (!bSkipSyncDir)
- //{
-#ifndef USE_VFS
- // Check if sync folder exists
- STRING512 syncDir;
- STRING512 executableDir;
-
- GetExecutableDirectory(executableDir);
- sprintf(syncDir, "%s\\%S", executableDir, gzFileTransferDirectory);
-
- if (!DirectoryExists(syncDir))
- {
- DoMPHMessageBox( MSG_BOX_BASIC_STYLE, gzMPHScreenText[MPH_FILE_TRANSFER_DIR_NOT_EXIST], MP_HOST_SCREEN, MSG_BOX_FLAG_OK, NULL );
- return false;
- }
-#endif
- //}
-
+
return true;
}
UINT32 MPHostScreenInit( void )
{
+ memset( &gGameOptions, 0, sizeof( GAME_OPTIONS ) );
+
// this is wrong as ScreenInit is called at game start, but the settigs can change anytime
// has be called in ScreenEnter for example
std::vector szTime(6,0);
-#ifndef USE_VFS
- // read settings from JA2_mp.ini
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"SERVER_NAME", L"Server Name", gzServerNameField, 30, L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"MAX_CLIENTS", L"4", gzMaxPlayersField, 4, L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"MAX_MERCS", L"5", gzSquadSizeField, 5 , L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"STARTING_BALANCE", L"25000", gzStartingBalanceField, 10 , L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"DAMAGE_MULTIPLIER", L"0.7", gzDmgMultiplierField, 5 , L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"TIMED_TURN_SECS_PER_TICK", L"25", gzTimerField, 5 , L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"FILE_TRANSFER_DIRECTORY", L"MULTIPLAYER/Servers/My Server", gzFileTransferDirectory, 100, L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"KIT_BAG", L"[201,214,243]", gzKitBag, 100, L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"TIME", L"13.50", &szTime[0], 5 , L"..\\Ja2_mp.ini" );
- giMPHOverrideMaxAI = GetPrivateProfileIntW( L"Ja2_mp Settings",L"OVERRIDE_MAX_AI", 0, L"..\\Ja2_mp.ini" );
- giMPHRandomMercs = GetPrivateProfileIntW( L"Ja2_mp Settings",L"RANDOM_MERCS", 0, L"..\\Ja2_mp.ini" );
- giMPHSameMercs = GetPrivateProfileIntW( L"Ja2_mp Settings",L"SAME_MERC", 1, L"..\\Ja2_mp.ini" );
- giMPHReportMercs = GetPrivateProfileIntW( L"Ja2_mp Settings",L"REPORT_NAME", 1, L"..\\Ja2_mp.ini" );
- giMPHBobbyRays = GetPrivateProfileIntW( L"Ja2_mp Settings",L"DISABLE_BOBBY_RAYS", 0, L"..\\Ja2_mp.ini" );
- giMPHRandomSpawn = GetPrivateProfileIntW( L"Ja2_mp Settings",L"RANDOM_EDGES", 0, L"..\\Ja2_mp.ini" );
- giMPHEnableCivilians = GetPrivateProfileIntW( L"Ja2_mp Settings",L"CIV_ENABLED", 0, L"..\\Ja2_mp.ini" );
- giMPHUseNIV = GetPrivateProfileIntW( L"Ja2_mp Settings",L"ALLOW_CUSTOM_NIV", 0, L"..\\Ja2_mp.ini" );
- giMPHSendFiles = GetPrivateProfileIntW( L"Ja2_mp Settings",L"SYNC_CLIENTS_MP_DIR", 1, L"..\\Ja2_mp.ini" );
- guiMPHGameType = GetPrivateProfileIntW( L"Ja2_mp Settings",L"GAME_MODE", MP_TYPE_DEATHMATCH, L"..\\Ja2_mp.ini" );
- guiMPHDifficultLevel = GetPrivateProfileIntW( L"Ja2_mp Settings",L"DIFFICULT_LEVEL", 2, L"..\\Ja2_mp.ini" );
-#else
// read settings from JA2_mp.ini
- CPropertyContainer props;
- props.initFromIniFile("Ja2_mp.ini");
- props.getStringProperty( L"Ja2_mp Settings", L"SERVER_NAME", gzServerNameField, 30, L"Server Name");
- props.getStringProperty( L"Ja2_mp Settings", L"MAX_CLIENTS", gzMaxPlayersField, 4, L"4");
- props.getStringProperty( L"Ja2_mp Settings", L"MAX_MERCS", gzSquadSizeField, 5, L"5");
- props.getStringProperty( L"Ja2_mp Settings", L"STARTING_BALANCE", gzStartingBalanceField, 10, L"25000");
- props.getStringProperty( L"Ja2_mp Settings", L"DAMAGE_MULTIPLIER", gzDmgMultiplierField, 5, L"0.7");
- props.getStringProperty( L"Ja2_mp Settings", L"TIMED_TURN_SECS_PER_TICK", gzTimerField, 5, L"25");
- props.getStringProperty( L"Ja2_mp Settings", L"FILE_TRANSFER_DIRECTORY", gzFileTransferDirectory, 100, L"MULTIPLAYER/Servers/My Server");
- props.getStringProperty( L"Ja2_mp Settings", L"KIT_BAG", gzKitBag, 100, L"[201,214,243]");
- props.getStringProperty(L"Ja2_mp Settings", L"TIME", &szTime[0], 6, L"13.50");
+ MpIniExists();
+ vfs::PropertyContainer props;
+ props.initFromIniFile(JA2MP_INI_FILENAME);
+
+ // ------------
+ // Get the data from ja2_mp.ini
+ // ------------
- giMPHOverrideMaxAI = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"OVERRIDE_MAX_AI", 0);
- giMPHRandomMercs = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"RANDOM_MERCS", 0);
- giMPHSameMercs = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"SAME_MERC", 1);
- giMPHReportMercs = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"REPORT_NAME", 1);
- giMPHBobbyRays = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"DISABLE_BOBBY_RAYS", 0);
- giMPHRandomSpawn = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"RANDOM_EDGES", 0);
- giMPHEnableCivilians = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"CIV_ENABLED", 0);
- giMPHUseNIV = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"ALLOW_CUSTOM_NIV", 0);
- giMPHSendFiles = (INT32)props.getIntProperty( L"Ja2_mp Settings",L"SYNC_CLIENTS_MP_DIR", 1);
- guiMPHGameType = (UINT8)props.getIntProperty( L"Ja2_mp Settings",L"GAME_MODE", MP_TYPE_DEATHMATCH);
- guiMPHDifficultLevel = (UINT8)props.getIntProperty( L"Ja2_mp Settings",L"DIFFICULT_LEVEL", 3); // Expert
-#endif
+ props.getStringProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_SERVER_NAME, gzServerNameField, 30, L"My JA2 Server");
- wchar_t* tok;
- bool bTimeOK = true;
- int hours = 0;
- int mins = 0;
-
- tok = wcstok(&szTime[0],L".");
-
- if (tok != NULL)
- {
- hours = _wtoi(tok);
- // check for invalid conversion, ie alpha chars
- // wtoi returns 0 if it cant convert, but we need this value
- // therefore if tok <> 0 then it was a bad convert.
- if (hours == 0 && wcscmp(tok,L"0") != 0)
- {
- // force error
- bTimeOK = false;
- }
-
- tok = wcstok(NULL,L".");
- if (tok != NULL)
- {
- mins = _wtoi(tok);
- if (mins == 0 && wcscmp(tok,L"0") != 0)
- {
- // force error
- bTimeOK = false;
- }
-
- // fix for single digits
- if (wcslen(tok) == 1)
- mins = mins * 10;
- }
- else
- {
- bTimeOK = false;
- }
- }
- else
- {
- bTimeOK = false;
- }
+ guiMPHMaxPlayers = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_MAX_CLIENTS, 4);
+
+ guiMPHSquadSize = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_MAX_MERCS, 6);
+
+ guiMPHStartingCash = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_STARTING_BALANCE, 1);
+
+ guiMPHWeaponDamage = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_DAMAGE_MULTIPLIER, 1);
+
+ guiMPHTimeTurns = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_TIMED_TURN_SECS_PER_TICK, 2);
+
+ props.getStringProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_FILE_TRANSFER_DIRECTORY, gzFileTransferDirectory, 100, L"MULTIPLAYER/Servers/My Server");
+
+ props.getStringProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_KIT_BAG, gzKitBag, 100, L"");
+
+ guiMPHStartingTime = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_TIME, 1);
+
+ guiMPHMaxEnemies = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_OVERRIDE_MAX_AI, 0);
+
+ guiMPHNewTraits = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_NEW_TRAITS, 0);
+
+ // It is not allowed to play with new traits
+ if (!gGameExternalOptions.fReadProfileDataFromXML)
+ guiMPHNewTraits = 0;
+ guiMPHHireMerc = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_RANDOM_MERCS, 0);
+
+ guiMPHSameMerc = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_SAME_MERC, 1);
+
+ guiMPHReportMerc = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_REPORT_NAME, 1);
+
+ guiMPHBobbyRay = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_DISABLE_BOBBY_RAYS, 0);
+
+ guiMPHSectorEdge = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_RANDOM_EDGES, 0);
+
+ guiMPHCivs = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_CIV_ENABLED, 0);
+
+ guiMPHInventory = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_ALLOW_CUSTOM_NIV, 0);
+
+ // It is not allowed to play with NIV
+ if (!IsNIVModeValid(true))
+ guiMPHInventory = 0;
- if (bTimeOK)
- {
- giMPHTimeHours = hours;
- float ratio = (float)mins / 100.0f;
- giMPHTimeMins = (INT16)(ratio * 60);
- swprintf(gzTimeOfDayField,L"%i:%i",giMPHTimeHours,giMPHTimeMins);
- }
+ guiMPHSendFiles = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_SYNC_CLIENTS_MP_DIR, 1);
+ guiMPHGameType = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_GAME_MODE, MP_TYPE_DEATHMATCH);
+
+ guiMPHDifficultLevel = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_DIFFICULT_LEVEL, 3) + 1;
+
return( 1 );
}
@@ -764,8 +1724,6 @@ UINT32 MPHostScreenHandle( void )
if( gfMPHScreenEntry )
{
-// PauseGame();
-
// need to reload ja2_mp.ini
MPHostScreenInit();
@@ -777,7 +1735,6 @@ UINT32 MPHostScreenHandle( void )
GetMPHScreenUserInput();
-
HandleMPHScreen();
// render buttons marked dirty
@@ -787,11 +1744,6 @@ UINT32 MPHostScreenHandle( void )
// render text boxes
RenderAllTextFields(); // textbox system call
- // render help
-// RenderFastHelp( );
-// RenderButtonsFastHelp( );
-
-
ExecuteBaseDirtyRectQueue();
EndFrameBufferRender();
@@ -815,7 +1767,6 @@ UINT32 MPHostScreenHandle( void )
if ( HandleBeginFadeIn( gubMPHExitScreen ) )
{
-
}
if( gfMPHScreenExit ) // we are exiting this screen
@@ -824,7 +1775,7 @@ UINT32 MPHostScreenHandle( void )
}
return( gubMPHExitScreen );
-} // end MPHoinScreenHandle()
+}
UINT32 MPHostScreenShutdown( void )
@@ -834,9 +1785,7 @@ UINT32 MPHostScreenShutdown( void )
BOOLEAN EnterMPHScreen()
{
- VOBJECT_DESC VObjectDesc;
- UINT16 cnt;
- UINT16 usPosY;
+ VOBJECT_DESC VObjectDesc, VObjectDesc2;
if( gfMPHButtonsAllocated )
return( TRUE );
@@ -861,6 +1810,10 @@ BOOLEAN EnterMPHScreen()
CHECKF(AddVideoObject(&VObjectDesc, &guiMPHMainBackGroundImage ));
+ VObjectDesc2.fCreateFlags=VOBJECT_CREATE_FROMFILE;
+ FilenameForBPP("INTERFACE\\GIOSmallFrame.sti", VObjectDesc2.ImageFile);
+ CHECKF(AddVideoObject(&VObjectDesc2, &guiMPHSMALLFRAME));
+
//Join button
giMPHStartBtnImage = LoadButtonImage("INTERFACE\\PreferencesButtons.sti", -1,0,-1,2,-1 );
guiMPHStartButton = CreateIconAndTextButton( giMPHStartBtnImage, gzMPHScreenText[MPH_START_TEXT], OPT_BUTTON_FONT,
@@ -895,204 +1848,483 @@ BOOLEAN EnterMPHScreen()
SetTextInputRegularColors( FONT_WHITE, 2 );
SetTextInputHilitedColors( 2, FONT_WHITE, FONT_WHITE );
SetCursorColor( Get16BPPColor(FROMRGB(255, 255, 255) ) );
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MAX PLAYERS
- //AddUserInputField( NULL ); // API Call that sets a special input-handling routine and method for the TAB key
+ giMPHMaxPlayersButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHMaxPlayersButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
- //Add Player Name textbox
- AddTextInputField( MPH_TXT_SVRNAME_X,
- MPH_TXT_SVRNAME_Y,
- MPH_TXT_SVRNAME_WIDTH,
- MPH_TXT_SVRNAME_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzServerNameField,
- 30,
- INPUTTYPE_ASCII );//23
+ // left button - decrement difficulty level
+ giMPHMaxPlayersButton[ 0 ] = QuickCreateButton( giMPHMaxPlayersButtonImage[ 0 ], MPH_MAXPLAYERS_SETTING_X + 39, MPH_MAXPLAYERS_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHMaxPlayersSelectionLeftCallback );
- //Add Num Players textbox
- AddTextInputField( MPH_TXT_MAXPLAYERS_X,
- MPH_TXT_MAXPLAYERS_Y,
- MPH_TXT_MAXPLAYERS_WIDTH,
- MPH_TXT_MAXPLAYERS_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzMaxPlayersField,
- 2,
- INPUTTYPE_ASCII );//23
+ // right button - increment difficulty level
+ giMPHMaxPlayersButton[ 1 ] = QuickCreateButton( giMPHMaxPlayersButtonImage[ 1 ], MPH_MAXPLAYERS_SETTING_X + 158, MPH_MAXPLAYERS_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHMaxPlayersSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHMaxPlayersButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHMaxPlayersButton[1],0, 1 );
- //Add Squad Size textbox
- AddTextInputField( MPH_TXT_SQUAD_X,
- MPH_TXT_SQUAD_Y,
- MPH_TXT_SQUAD_WIDTH,
- MPH_TXT_SQUAD_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzSquadSizeField,
- 2,
- INPUTTYPE_ASCII );//23
+ iMPHMaxPlayers = guiMPHMaxPlayers;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SQUAD SIZE
- //Add Time of day textbox
- AddTextInputField( MPH_TXT_TIME_X,
- MPH_TXT_TIME_Y,
- MPH_TXT_TIME_WIDTH,
- MPH_TXT_TIME_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzTimeOfDayField,
- 5,
- INPUTTYPE_ASCII );//23
+ giMPHSquadSizeButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHSquadSizeButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
- //Add Starting Cash textbox
- AddTextInputField( MPH_TXT_CASH_X,
- MPH_TXT_CASH_Y,
- MPH_TXT_CASH_WIDTH,
- MPH_TXT_CASH_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzStartingBalanceField,
- 10,
- INPUTTYPE_ASCII );//23
+ // left button - decrement difficulty level
+ giMPHSquadSizeButton[ 0 ] = QuickCreateButton( giMPHSquadSizeButtonImage[ 0 ], MPH_SQUADSIZE_SETTING_X + 39, MPH_SQUADSIZE_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHSquadSizeSelectionLeftCallback );
- //Add Damage Multiplyer textbox
- AddTextInputField( MPH_TXT_DMG_X,
- MPH_TXT_DMG_Y,
- MPH_TXT_DMG_WIDTH,
- MPH_TXT_DMG_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzDmgMultiplierField,
- 5,
- INPUTTYPE_ASCII );//23
+ // right button - increment difficulty level
+ giMPHSquadSizeButton[ 1 ] = QuickCreateButton( giMPHSquadSizeButtonImage[ 1 ], MPH_SQUADSIZE_SETTING_X + 158, MPH_SQUADSIZE_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHSquadSizeSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHSquadSizeButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHSquadSizeButton[1],0, 1 );
- //Add Turn Timer textbox
- AddTextInputField( MPH_TXT_TIMER_X,
- MPH_TXT_TIMER_Y,
- MPH_TXT_TIMER_WIDTH,
- MPH_TXT_TIMER_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzTimerField,
- 5,
- INPUTTYPE_ASCII );//23
+ iMPHSquadSize= guiMPHSquadSize;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STARTING TIME
- //Add File transfer directory textbox
- AddTextInputField( MPH_TXT_FILE_TRANSFER_DIR_X,
- MPH_TXT_FILE_TRANSFER_DIR_Y,
- MPH_TXT_FILE_TRANSFER_DIR_WIDTH,
- MPH_TXT_FILE_TRANSFER_DIR_HEIGHT,
- MSYS_PRIORITY_HIGH+2,
- gzFileTransferDirectory,
- 100,
- INPUTTYPE_ASCII );
+ giMPHStartingTimeButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHStartingTimeButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
+ // left button - decrement difficulty level
+ giMPHStartingTimeButton[ 0 ] = QuickCreateButton( giMPHStartingTimeButtonImage[ 0 ], MPH_STARTINGTIME_SETTING_X + 39, MPH_STARTINGTIME_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHStartingTimeSelectionLeftCallback );
- SetActiveField( 0 ); // Playername textbox has focus
+ // right button - increment difficulty level
+ giMPHStartingTimeButton[ 1 ] = QuickCreateButton( giMPHStartingTimeButtonImage[ 1 ], MPH_STARTINGTIME_SETTING_X + 158, MPH_STARTINGTIME_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHStartingTimeSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHStartingTimeButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHStartingTimeButton[1],0, 1 );
+ iMPHStartingTime = guiMPHStartingTime;
- //
- //Check box to toggle Difficulty settings
- //
- usPosY = MPH_DIF_SETTINGS_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y;
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STARTING CASH
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
- else if( guiMPHDifficultLevel == DIF_LEVEL_INSANE )
- ButtonList[ guiMPHDifficultySettingsToggles[ MPH_DIFF_INSANE ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ // right button - increment difficulty level
+ giMPHStartingCashButton[ 1 ] = QuickCreateButton( giMPHStartingCashButtonImage[ 1 ], MPH_STARTINGCASH_SETTING_X + 158, MPH_STARTINGCASH_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHStartingCashSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHStartingCashButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHStartingCashButton[1],0, 1 );
+
+ iMPHStartingCash = guiMPHStartingCash;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // WEAPON DAMAGE
+
+ giMPHWeaponDamageButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHWeaponDamageButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giMPHWeaponDamageButton[ 0 ] = QuickCreateButton( giMPHWeaponDamageButtonImage[ 0 ], MPH_WEAPONDAMAGE_SETTING_X + 39, MPH_WEAPONDAMAGE_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHWeaponDamageSelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giMPHWeaponDamageButton[ 1 ] = QuickCreateButton( giMPHWeaponDamageButtonImage[ 1 ], MPH_WEAPONDAMAGE_SETTING_X + 158, MPH_WEAPONDAMAGE_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHWeaponDamageSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHWeaponDamageButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHWeaponDamageButton[1],0, 1 );
+
+ iMPHWeaponDamage = guiMPHWeaponDamage;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // TIME TURNS
+
+ giMPHTimeTurnsButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHTimeTurnsButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giMPHTimeTurnsButton[ 0 ] = QuickCreateButton( giMPHTimeTurnsButtonImage[ 0 ], MPH_TIMETURNS_SETTING_X + 39, MPH_TIMETURNS_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHTimeTurnsSelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giMPHTimeTurnsButton[ 1 ] = QuickCreateButton( giMPHTimeTurnsButtonImage[ 1 ], MPH_TIMETURNS_SETTING_X + 158, MPH_TIMETURNS_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHTimeTurnsSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHTimeTurnsButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHTimeTurnsButton[1],0, 1 );
+
+ iMPHTimeTurns = guiMPHTimeTurns;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // DIFFICULTY SETTING
+
+ giMPHDifficultyButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHDifficultyButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giMPHDifficultyButton[ 0 ] = QuickCreateButton( giMPHDifficultyButtonImage[ 0 ], MPH_DIFFICULTY_SETTING_X + 39, MPH_DIFFICULTY_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHDifficultySelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giMPHDifficultyButton[ 1 ] = QuickCreateButton( giMPHDifficultyButtonImage[ 1 ], MPH_DIFFICULTY_SETTING_X + 158, MPH_DIFFICULTY_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHDifficultySelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHDifficultyButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHDifficultyButton[1],0, 1 );
+
+ iMPHDifficulty = guiMPHDifficultLevel - 1;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // GAME TYPE
+
+ giMPHGameTypeButtonImage[ 0 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,0,-1,1,-1 );
+ giMPHGameTypeButtonImage[ 1 ]= LoadButtonImage( "INTERFACE\\GIO_SELECTION_ARROWS.STI" ,-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giMPHGameTypeButton[ 0 ] = QuickCreateButton( giMPHGameTypeButtonImage[ 0 ], MPH_GAMETYPE_SETTING_X + 39, MPH_GAMETYPE_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHGameTypeSelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giMPHGameTypeButton[ 1 ] = QuickCreateButton( giMPHGameTypeButtonImage[ 1 ], MPH_GAMETYPE_SETTING_X + 158, MPH_GAMETYPE_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHGameTypeSelectionRightCallback );
+
+ // set user data
+ MSYS_SetBtnUserData(giMPHGameTypeButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHGameTypeButton[1],0, 1 );
+
+ iMPHGameType = guiMPHGameType;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // MAX ENEMIES
+
+ guiMPHMaxEnemiesOptionTogglesImage[ MPH_MAXENEMIES_NO ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_NO ] = CreateIconAndTextButton( guiMPHMaxEnemiesOptionTogglesImage[ MPH_MAXENEMIES_NO ], gzMPHScreenText[ MPH_NO ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_MAXENEMIES_SETTING_X + 74), (MPH_MAXENEMIES_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHNoMaxEnemiesCallback);
+
+ guiMPHMaxEnemiesOptionTogglesImage[ MPH_MAXENEMIES_YES ] = UseLoadedButtonImage( guiMPHMaxEnemiesOptionTogglesImage[ MPH_MAXENEMIES_NO ], -1,1,-1,3,-1 );
+ guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_YES ] = CreateIconAndTextButton( guiMPHMaxEnemiesOptionTogglesImage[ MPH_MAXENEMIES_YES ], gzMPHScreenText[ MPH_YES ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_MAXENEMIES_SETTING_X), (MPH_MAXENEMIES_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHYesMaxEnemiesCallback );
+
+ SpecifyButtonSoundScheme( guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_NO ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_YES ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_NO ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_YES ],0, 1 );
+
+ if( guiMPHMaxEnemies )
+ ButtonList[ guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_YES ] ]->uiFlags |= BUTTON_CLICKED_ON;
else
- ButtonList[ guiMPHDifficultySettingsToggles[ MPH_DIFF_HARD ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ ButtonList[ guiMPHMaxEnemiesOptionToggles[ MPH_MAXENEMIES_NO ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // HIRE MERC
+
+ guiMPHHireMercOptionTogglesImage[ MPH_HIREMERC_RANDOM ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHHireMercOptionToggles[ MPH_HIREMERC_RANDOM ] = CreateIconAndTextButton( guiMPHHireMercOptionTogglesImage[ MPH_HIREMERC_RANDOM ], gzMPHScreenText[ MPH_HIRE_RANDOM ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_HIREMERC_SETTING_X + 74), (MPH_HIREMERC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHRandomHireMercCallback);
+
+ guiMPHHireMercOptionTogglesImage[ MPH_HIREMERC_NORMAL ] = UseLoadedButtonImage( guiMPHHireMercOptionTogglesImage[ MPH_HIREMERC_RANDOM ], -1,1,-1,3,-1 );
+ guiMPHHireMercOptionToggles[ MPH_HIREMERC_NORMAL ] = CreateIconAndTextButton( guiMPHHireMercOptionTogglesImage[ MPH_HIREMERC_NORMAL ], gzMPHScreenText[ MPH_HIRE_NORMAL ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_HIREMERC_SETTING_X), (MPH_HIREMERC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHNormalHireMercCallback );
+
+ SpecifyButtonSoundScheme( guiMPHHireMercOptionToggles[ MPH_HIREMERC_RANDOM ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHHireMercOptionToggles[ MPH_HIREMERC_NORMAL ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHHireMercOptionToggles[ MPH_HIREMERC_RANDOM ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHHireMercOptionToggles[ MPH_HIREMERC_NORMAL ],0, 1 );
+
+ if( guiMPHHireMerc )
+ ButtonList[ guiMPHHireMercOptionToggles[ MPH_HIREMERC_RANDOM ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHHireMercOptionToggles[ MPH_HIREMERC_NORMAL ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SAME MERC
+
+ guiMPHSameMercOptionTogglesImage[ MPH_SAMEMERC_DISABLE ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHSameMercOptionToggles[ MPH_SAMEMERC_DISABLE ] = CreateIconAndTextButton( guiMPHSameMercOptionTogglesImage[ MPH_SAMEMERC_DISABLE ], gzMPHScreenText[ MPH_DISABLE ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_SAMEMERC_SETTING_X + 74), (MPH_SAMEMERC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHDisableSameMercCallback);
+
+ guiMPHSameMercOptionTogglesImage[ MPH_SAMEMERC_ALLOW ] = UseLoadedButtonImage( guiMPHSameMercOptionTogglesImage[ MPH_SAMEMERC_DISABLE ], -1,1,-1,3,-1 );
+ guiMPHSameMercOptionToggles[ MPH_SAMEMERC_ALLOW ] = CreateIconAndTextButton( guiMPHSameMercOptionTogglesImage[ MPH_SAMEMERC_ALLOW ], gzMPHScreenText[ MPH_ALLOW ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_SAMEMERC_SETTING_X), (MPH_SAMEMERC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHAllowSameMercCallback );
+
+ SpecifyButtonSoundScheme( guiMPHSameMercOptionToggles[ MPH_SAMEMERC_DISABLE ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHSameMercOptionToggles[ MPH_SAMEMERC_ALLOW ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHSameMercOptionToggles[ MPH_SAMEMERC_DISABLE ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHSameMercOptionToggles[ MPH_SAMEMERC_ALLOW ],0, 1 );
+
+ if( guiMPHSameMerc )
+ ButtonList[ guiMPHSameMercOptionToggles[ MPH_SAMEMERC_ALLOW ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHSameMercOptionToggles[ MPH_SAMEMERC_DISABLE ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // REPORT MERC
+
+ guiMPHReportMercOptionTogglesImage[ MPH_REPORTMERC_NO ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHReportMercOptionToggles[ MPH_REPORTMERC_NO ] = CreateIconAndTextButton( guiMPHReportMercOptionTogglesImage[ MPH_REPORTMERC_NO ], gzMPHScreenText[ MPH_NO ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_REPORTMERC_SETTING_X + 74), (MPH_REPORTMERC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHNoReportMercCallback);
+
+ guiMPHReportMercOptionTogglesImage[ MPH_REPORTMERC_YES ] = UseLoadedButtonImage( guiMPHReportMercOptionTogglesImage[ MPH_REPORTMERC_NO ], -1,1,-1,3,-1 );
+ guiMPHReportMercOptionToggles[ MPH_REPORTMERC_YES ] = CreateIconAndTextButton( guiMPHReportMercOptionTogglesImage[ MPH_REPORTMERC_YES ], gzMPHScreenText[ MPH_YES ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_REPORTMERC_SETTING_X), (MPH_REPORTMERC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHYesReportMercCallback );
+
+ SpecifyButtonSoundScheme( guiMPHReportMercOptionToggles[ MPH_REPORTMERC_NO ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHReportMercOptionToggles[ MPH_REPORTMERC_YES ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHReportMercOptionToggles[ MPH_REPORTMERC_NO ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHReportMercOptionToggles[ MPH_REPORTMERC_YES ],0, 1 );
+
+ if( guiMPHReportMerc )
+ ButtonList[ guiMPHReportMercOptionToggles[ MPH_REPORTMERC_YES ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHReportMercOptionToggles[ MPH_REPORTMERC_NO ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // BOBBY RAY
+
+ guiMPHBobbyRayOptionTogglesImage[ MPH_BOBBYRAY_DISABLE ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_DISABLE ] = CreateIconAndTextButton( guiMPHBobbyRayOptionTogglesImage[ MPH_BOBBYRAY_DISABLE ], gzMPHScreenText[ MPH_DISABLE ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_BOBBYRAY_SETTING_X + 74), (MPH_BOBBYRAY_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHDisableBobbyRayCallback);
+
+ guiMPHBobbyRayOptionTogglesImage[ MPH_BOBBYRAY_ALLOW ] = UseLoadedButtonImage( guiMPHBobbyRayOptionTogglesImage[ MPH_BOBBYRAY_DISABLE ], -1,1,-1,3,-1 );
+ guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_ALLOW ] = CreateIconAndTextButton( guiMPHBobbyRayOptionTogglesImage[ MPH_BOBBYRAY_ALLOW ], gzMPHScreenText[ MPH_ALLOW ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_BOBBYRAY_SETTING_X), (MPH_BOBBYRAY_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHAllowBobbyRayCallback );
+
+ SpecifyButtonSoundScheme( guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_DISABLE ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_ALLOW ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_DISABLE ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_ALLOW ],0, 1 );
+
+ if( guiMPHBobbyRay )
+ ButtonList[ guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_DISABLE ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHBobbyRayOptionToggles[ MPH_BOBBYRAY_ALLOW ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SECTOR EDGE
+
+ guiMPHSectorEdgeOptionTogglesImage[ MPH_SECTOREDGE_RANDOM ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_RANDOM ] = CreateIconAndTextButton( guiMPHSectorEdgeOptionTogglesImage[ MPH_SECTOREDGE_RANDOM ], gzMPHScreenText[ MPH_EDGE_RANDOM ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_SECTOREDGE_SETTING_X + 74), (MPH_SECTOREDGE_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHRandomSectorEdgeCallback);
+
+ guiMPHSectorEdgeOptionTogglesImage[ MPH_SECTOREDGE_SELECTABLE ] = UseLoadedButtonImage( guiMPHSectorEdgeOptionTogglesImage[ MPH_SECTOREDGE_RANDOM ], -1,1,-1,3,-1 );
+ guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_SELECTABLE ] = CreateIconAndTextButton( guiMPHSectorEdgeOptionTogglesImage[ MPH_SECTOREDGE_SELECTABLE ], gzMPHScreenText[ MPH_EDGE_SELECTABLE ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_SECTOREDGE_SETTING_X), (MPH_SECTOREDGE_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHSelectableSectorEdgeCallback );
+
+ SpecifyButtonSoundScheme( guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_RANDOM ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_SELECTABLE ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_RANDOM ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_SELECTABLE ],0, 1 );
+
+ if( guiMPHSectorEdge )
+ ButtonList[ guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_RANDOM ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHSectorEdgeOptionToggles[ MPH_SECTOREDGE_SELECTABLE ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // CIVS
+
+ guiMPHCivsOptionTogglesImage[ MPH_CIVS_NO ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHCivsOptionToggles[ MPH_CIVS_NO ] = CreateIconAndTextButton( guiMPHCivsOptionTogglesImage[ MPH_CIVS_NO ], gzMPHScreenText[ MPH_NO ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_CIVS_SETTING_X + 74), (MPH_CIVS_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHNoCivsCallback);
+
+ guiMPHCivsOptionTogglesImage[ MPH_CIVS_YES ] = UseLoadedButtonImage( guiMPHCivsOptionTogglesImage[ MPH_CIVS_NO ], -1,1,-1,3,-1 );
+ guiMPHCivsOptionToggles[ MPH_CIVS_YES ] = CreateIconAndTextButton( guiMPHCivsOptionTogglesImage[ MPH_CIVS_YES ], gzMPHScreenText[ MPH_YES ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_CIVS_SETTING_X), (MPH_CIVS_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHYesCivsCallback );
+
+ SpecifyButtonSoundScheme( guiMPHCivsOptionToggles[ MPH_CIVS_NO ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHCivsOptionToggles[ MPH_CIVS_YES ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHCivsOptionToggles[ MPH_CIVS_NO ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHCivsOptionToggles[ MPH_CIVS_YES ],0, 1 );
+
+ if( guiMPHCivs )
+ ButtonList[ guiMPHCivsOptionToggles[ MPH_CIVS_YES ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHCivsOptionToggles[ MPH_CIVS_NO ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ // -------------------------------------------------
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // INVENTORY / ATTACHMENT
+
+ if (IsNIVModeValid(true))
+ {
+ giMPHInventoryButtonImage[ 0 ]= UseLoadedButtonImage( giMPHDifficultyButtonImage[ 0 ],-1,0,-1,1,-1 );
+ giMPHInventoryButtonImage[ 1 ]= UseLoadedButtonImage( giMPHDifficultyButtonImage[ 1 ],-1,2,-1,3,-1 );
+
+ // left button - decrement difficulty level
+ giMPHInventoryButton[ 0 ] = QuickCreateButton( giMPHInventoryButtonImage[ 0 ], MPH_INVENTORY_SETTING_X + 39, MPH_INVENTORY_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHInventorySelectionLeftCallback );
+
+ // right button - increment difficulty level
+ giMPHInventoryButton[ 1 ] = QuickCreateButton( giMPHInventoryButtonImage[ 1 ], MPH_INVENTORY_SETTING_X + 158, MPH_INVENTORY_SETTING_Y ,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
+ BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnMPHInventorySelectionRightCallback );
- //
- //Check box to toggle GameType settings
- //
- usPosY = MPH_GAMETYPE_SETTINGS_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y;
+ // set user data
+ MSYS_SetBtnUserData(giMPHInventoryButton[0],0, 0 );
+ MSYS_SetBtnUserData(giMPHInventoryButton[1],0, 1 );
- for( cnt=0; cntuiFlags |= BUTTON_CLICKED_ON;
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // OLD/NEW TARITS SETTING
- // Override Max AI
- guiMPHOverrideMaxAIToggle = CreateCheckBoxButton( MPH_OVERRIDEMAXAI_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_OVERRIDEMAXAI_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHOverrideMaxAICallback );
- if ( giMPHOverrideMaxAI )
- ButtonList[ guiMPHOverrideMaxAIToggle ]->uiFlags |= BUTTON_CLICKED_ON;
+ guiMPHTraitsOptionTogglesImage[ MPH_TRAITS_OLD ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHTraitsOptionToggles[ MPH_TRAITS_OLD ] = CreateIconAndTextButton( guiMPHTraitsOptionTogglesImage[ MPH_TRAITS_OLD ], gzGIOScreenText[ GIO_TRAITS_OLD_TEXT ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_TRAITS_SETTING_X + 74), (MPH_TRAITS_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHOldTraitsCallback);
- // Random Mercs
- guiMPHRandomMercsToggle = CreateCheckBoxButton( MPH_RNDMERC_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_RNDMERC_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHRandomMercCallback );
- if ( giMPHRandomMercs )
- ButtonList[ guiMPHRandomMercsToggle ]->uiFlags |= BUTTON_CLICKED_ON;
+ guiMPHTraitsOptionTogglesImage[ MPH_TRAITS_NEW ] = UseLoadedButtonImage( guiMPHTraitsOptionTogglesImage[ MPH_TRAITS_OLD ], -1,1,-1,3,-1 );
+ guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ] = CreateIconAndTextButton( guiMPHTraitsOptionTogglesImage[ MPH_TRAITS_NEW ], gzGIOScreenText[ GIO_TRAITS_NEW_TEXT ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_TRAITS_SETTING_X), (MPH_TRAITS_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHNewTraitsCallback );
- //checkbox for same merc
- guiMPHSameMercToggle = CreateCheckBoxButton( MPH_SAMEMERC_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_SAMEMERC_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHSameMercCallback );
- if ( giMPHSameMercs )
- ButtonList[ guiMPHSameMercToggle ]->uiFlags |= BUTTON_CLICKED_ON;
+ SpecifyButtonSoundScheme( guiMPHTraitsOptionToggles[ MPH_TRAITS_OLD ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHTraitsOptionToggles[ MPH_TRAITS_OLD ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ],0, 1 );
- //checkbox for report purchase
- guiMPHReportMercToggle = CreateCheckBoxButton( MPH_REPORTMERC_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_REPORTMERC_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHReportMercCallback );
- if (giMPHReportMercs)
- ButtonList[ guiMPHReportMercToggle ]->uiFlags |= BUTTON_CLICKED_ON;
+ if( guiMPHNewTraits )
+ ButtonList[ guiMPHTraitsOptionToggles[ MPH_TRAITS_NEW ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHTraitsOptionToggles[ MPH_TRAITS_OLD ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SYNC GAME DIR
- //checkbox for bobby rays
- guiMPHBobbyRayToggle = CreateCheckBoxButton( MPH_BOBBYRAY_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_BOBBYRAY_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHBobbyRayCallback );
+ guiMPHSyncOptionTogglesImage[ MPH_SYNC_NO ] = LoadButtonImage( "INTERFACE\\GIOCheckButton.sti" ,-1,0,-1,2,-1 );
+ guiMPHSyncOptionToggles[ MPH_SYNC_NO ] = CreateIconAndTextButton( guiMPHSyncOptionTogglesImage[ MPH_SYNC_NO ], gzMPHScreenText[ MPH_NO ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_SYNC_SETTING_X + 74), (MPH_SYNC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHNoSyncCallback);
- if (!giMPHBobbyRays)
- ButtonList[ guiMPHBobbyRayToggle ]->uiFlags |= BUTTON_CLICKED_ON; // the setting is actually DISABLE / NEGATIVE
-
- //checkbox for random spawn pos
- guiMPHRandomSpawnToggle = CreateCheckBoxButton( MPH_RNDSPAWN_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_RNDSPAWN_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHRandomSpawnCallback );
-
- if (giMPHRandomSpawn)
- ButtonList[ guiMPHRandomSpawnToggle ]->uiFlags |= BUTTON_CLICKED_ON;
-
- // checkbox for civillians
- guiMPHCivsToggle = CreateCheckBoxButton( MPH_CIVS_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_CIVS_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHCivsCallback );
- if (giMPHEnableCivilians)
- ButtonList[ guiMPHCivsToggle ]->uiFlags |= BUTTON_CLICKED_ON;
-
- // checkbox for use NIV
- guiMPHUseNIVToggle = CreateCheckBoxButton( MPH_USENIV_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_USENIV_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHUseNIVCallback );
- if (giMPHUseNIV)
- ButtonList[ guiMPHUseNIVToggle ]->uiFlags |= BUTTON_CLICKED_ON;
-
-
- // checkbox for send files to clients
- guiMPHSendFiles = CreateCheckBoxButton( MPH_SEND_FILES_X+MPH_OFFSET_TO_TOGGLE_BOX, MPH_SEND_FILES_Y - MPH_OFFSET_TO_TOGGLE_BOX_Y,
- "INTERFACE\\OptionsCheck.sti", MSYS_PRIORITY_HIGH+10,
- BtnMPHSendFilesCallback );
-
- if (giMPHSendFiles)
- ButtonList[ guiMPHSendFiles ]->uiFlags |= BUTTON_CLICKED_ON;
+ guiMPHSyncOptionTogglesImage[ MPH_SYNC_YES ] = UseLoadedButtonImage( guiMPHSyncOptionTogglesImage[ MPH_SYNC_NO ], -1,1,-1,3,-1 );
+ guiMPHSyncOptionToggles[ MPH_SYNC_YES ] = CreateIconAndTextButton( guiMPHSyncOptionTogglesImage[ MPH_SYNC_YES ], gzMPHScreenText[ MPH_YES ], MPH_TOGGLE_TEXT_FONT,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ MPH_TOGGLE_TEXT_COLOR, NO_SHADOW,
+ TEXT_CJUSTIFIED,
+ (MPH_SYNC_SETTING_X), (MPH_SYNC_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH,
+ DEFAULT_MOVE_CALLBACK, BtnMPHYesSyncCallback );
+ SpecifyButtonSoundScheme( guiMPHSyncOptionToggles[ MPH_SYNC_NO ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ SpecifyButtonSoundScheme( guiMPHSyncOptionToggles[ MPH_SYNC_YES ], BUTTON_SOUND_SCHEME_BIGSWITCH3 );
+ MSYS_SetBtnUserData(guiMPHSyncOptionToggles[ MPH_SYNC_NO ],0, 0 );
+ MSYS_SetBtnUserData(guiMPHSyncOptionToggles[ MPH_SYNC_YES ],0, 1 );
+ if( guiMPHSendFiles )
+ ButtonList[ guiMPHSyncOptionToggles[ MPH_SYNC_YES ] ]->uiFlags |= BUTTON_CLICKED_ON;
+ else
+ ButtonList[ guiMPHSyncOptionToggles[ MPH_SYNC_NO ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
//Reset the exit screen - screen the main game loop will call next iteration
gubMPHExitScreen = MP_HOST_SCREEN;
@@ -1106,8 +2338,7 @@ BOOLEAN EnterMPHScreen()
return( TRUE );
-} // End of EnterMPHScreen()
-
+}
BOOLEAN ExitMPHScreen()
{
@@ -1119,30 +2350,169 @@ BOOLEAN ExitMPHScreen()
//Delete the main options screen background
DeleteVideoObjectFromIndex( guiMPHMainBackGroundImage );
+ DeleteVideoObjectFromIndex( guiMPHSMALLFRAME );
+
RemoveButton( guiMPHStartButton );
RemoveButton( guiMPHCancelButton );
-
UnloadButtonImage( giMPHCancelBtnImage );
UnloadButtonImage( giMPHStartBtnImage );
- //Check box to toggle Difficulty settings
- for( cnt=0; cnt review this, i think MPH_EXIT is the proceed mode...
- //if( gubMPHScreenHandler == MPH_EXIT )
- // SetMusicMode( MUSIC_NONE );
-
gfMPHScreenExit = FALSE;
gfMPHScreenEntry = TRUE;
return( TRUE );
-} // End of ExitMPHScreen()
+}
void HandleMPHScreen()
@@ -1173,8 +2538,6 @@ void HandleMPHScreen()
gubMPHExitScreen = MAINMENU_SCREEN;
gfMPHScreenExit = TRUE;
break;
-
-
case MPH_START:
{
//if we are already fading out, get out of here
@@ -1189,27 +2552,66 @@ void HandleMPHScreen()
}
break;
}
-
}
gubMPHScreenHandler = MPH_NOTHING;
}
-
if( gfReRenderMPHScreen )
{
RenderMPHScreen();
gfReRenderMPHScreen = FALSE;
- }
-
- RestoreMPHButtonBackGrounds();
-} // end of HandleMPHScreen
-
+ }
+}
BOOLEAN RenderMPHScreen()
{
HVOBJECT hPixHandle;
- UINT16 usPosY;
+
+ // --------------------------
+ // Difficulty
+ RestoreExternBackgroundRect( MPH_DIFFICULTY_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_DIFFICULTY_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // MaxPlayers
+ RestoreExternBackgroundRect( MPH_MAXPLAYERS_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_MAXPLAYERS_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // StartingTime
+ RestoreExternBackgroundRect( MPH_STARTINGTIME_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_STARTINGTIME_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // StartingCash
+ RestoreExternBackgroundRect( MPH_STARTINGCASH_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_STARTINGCASH_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // WeaponDamage
+ RestoreExternBackgroundRect( MPH_WEAPONDAMAGE_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_WEAPONDAMAGE_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // TimeTurns
+ RestoreExternBackgroundRect( MPH_TIMETURNS_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_TIMETURNS_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // SquadSize
+ RestoreExternBackgroundRect( MPH_SQUADSIZE_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_SQUADSIZE_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // GameType
+ RestoreExternBackgroundRect( MPH_GAMETYPE_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_GAMETYPE_SETTING_Y-3, 120, 20 );
+ // --------------------------
+
+ // --------------------------
+ // Inventory
+ RestoreExternBackgroundRect( MPH_INVENTORY_SETTING_X+MPH_OFFSET_TO_TEXT + 20, MPH_INVENTORY_SETTING_Y-3, 120, 20 );
+ // --------------------------
//Get the main background screen graphic and blt it
GetVideoObject(&hPixHandle, guiMPHMainBackGroundImage );
@@ -1221,86 +2623,116 @@ BOOLEAN RenderMPHScreen()
//Display the title
DrawTextToScreen( gzMPHScreenText[ MPH_TITLE_TEXT ], MPH_MAIN_TITLE_X, MPH_MAIN_TITLE_Y, MPH_MAIN_TITLE_WIDTH, MPH_TITLE_FONT, MPH_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
- // Server name text label
- DisplayWrappedString( MPH_LABEL_SVRNAME_X, MPH_LABEL_SVRNAME_Y, MPH_LABEL_SVRNAME_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_SERVERNAME_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ---------
+ // MaxPlayers
+ RenderMPHSmallSelectionFrame( (MPH_MAXPLAYERS_SETTING_X + 36), (MPH_MAXPLAYERS_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_MAXPLAYERS_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_MAXPLAYERS_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_MAXPLAYERS_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_NUMPLAYERS_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_MAXPLAYERS_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_MAXPLAYERS_SETTING_Y+6), MPH_MAXPLAYERS_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ (MPH_1 - MPH_MAXPLAYERS_2 + 1) + iMPHMaxPlayers ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -----------------
- // Num Players text label
- DisplayWrappedString( MPH_LABEL_MAXPLAYERS_X, MPH_LABEL_MAXPLAYERS_Y, MPH_LABEL_MAXPLAYERS_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_NUMPLAYERS_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // -----------------
+ // SquadSize
+ RenderMPHSmallSelectionFrame( (MPH_SQUADSIZE_SETTING_X + 36), (MPH_SQUADSIZE_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_SQUADSIZE_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_SQUADSIZE_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_SQUADSIZE_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_SQUADSIZE_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_SQUADSIZE_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_SQUADSIZE_SETTING_Y+6), MPH_SQUADSIZE_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ (MPH_1 - MPH_SQUADSIZE_1) + iMPHSquadSize ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -----------------
- // Squad Size text label
- DisplayWrappedString( MPH_LABEL_SQUAD_X, MPH_LABEL_SQUAD_Y, MPH_LABEL_SQUAD_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_SQUADSIZE_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ----------
+ // StartingTime
+ RenderMPHSmallSelectionFrame( (MPH_STARTINGTIME_SETTING_X + 36), (MPH_STARTINGTIME_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_STARTINGTIME_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_STARTINGTIME_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_STARTINGTIME_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_TIME_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_STARTINGTIME_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_STARTINGTIME_SETTING_Y+6), MPH_STARTINGTIME_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_MORNING + iMPHStartingTime ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -----------------
- // Time Of day text label
- DisplayWrappedString( MPH_LABEL_TIME_X, MPH_LABEL_TIME_Y, MPH_LABEL_TIME_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_TIME_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ------------------
+ // StartingCash
+ RenderMPHSmallSelectionFrame( (MPH_STARTINGCASH_SETTING_X + 36), (MPH_STARTINGCASH_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_STARTINGCASH_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_STARTINGCASH_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_STARTINGCASH_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_BALANCE_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_STARTINGCASH_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_STARTINGCASH_SETTING_Y+6), MPH_STARTINGCASH_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_CASH_LOW + iMPHStartingCash ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -----------------
- // Starting Cash text label
- DisplayWrappedString( MPH_LABEL_CASH_X, MPH_LABEL_CASH_Y, MPH_LABEL_CASH_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_BALANCE_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ----------
+ // WeaponDamage
+ RenderMPHSmallSelectionFrame( (MPH_WEAPONDAMAGE_SETTING_X + 36), (MPH_WEAPONDAMAGE_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_WEAPONDAMAGE_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_WEAPONDAMAGE_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_WEAPONDAMAGE_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_DMG_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_WEAPONDAMAGE_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_WEAPONDAMAGE_SETTING_Y+6), MPH_STARTINGCASH_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_DAMAGE_VERYLOW + iMPHWeaponDamage ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // --------------
- // Damage multiplier text label
- DisplayWrappedString( MPH_LABEL_DMG_X, MPH_LABEL_DMG_Y, MPH_LABEL_DMG_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_DMG_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // -----------
+ // TurnTimes
+ RenderMPHSmallSelectionFrame( (MPH_TIMETURNS_SETTING_X + 36), (MPH_TIMETURNS_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_TIMETURNS_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_TIMETURNS_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_TIMETURNS_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_TIMER_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_TIMETURNS_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_TIMETURNS_SETTING_Y+6), MPH_TIMETURNS_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_TIME_NEVER + iMPHTimeTurns ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -----------------
+
+ // ---------------
+ // Difficulty
+ RenderMPHSmallSelectionFrame( (MPH_DIFFICULTY_SETTING_X + 36), (MPH_DIFFICULTY_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_DIFFICULTY_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_DIFFICULTY_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_DIFFICULTY_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ GIO_DIF_LEVEL_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_DIFFICULTY_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_DIFFICULTY_SETTING_Y+6), MPH_DIFFICULTY_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ iMPHDifficulty + 9 ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ---------------
- // Turn timer text label
- DisplayWrappedString( MPH_LABEL_TIMER_X, MPH_LABEL_TIMER_Y, MPH_LABEL_TIMER_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_TIMER_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ---------------
+ // GameType
+ RenderMPHSmallSelectionFrame( (MPH_GAMETYPE_SETTING_X + 36), (MPH_GAMETYPE_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_GAMETYPE_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_GAMETYPE_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_GAMETYPE_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_GAMETYPE_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_GAMETYPE_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_GAMETYPE_SETTING_Y+6), MPH_GAMETYPE_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_DEATHMATCH_TEXT + iMPHGameType], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ---------------
+
+ // ---------------
+ // MaxEnemies
+ DisplayWrappedString( (MPH_MAXENEMIES_SETTING_X - 6), (UINT16)(MPH_MAXENEMIES_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_MAXENEMIES_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_OVERRIDEMAXAI_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -------------
- // File transfer directory (source directory for server, target directory for client)
- DisplayWrappedString( MPH_LABEL_FILE_TRANSFER_DIR_X, MPH_LABEL_FILE_TRANSFER_DIR_Y, MPH_LABEL_FILE_TRANSFER_DIR_WIDTH, 2, MPH_LABEL_TEXT_FONT, MPH_LABEL_TEXT_COLOR, gzMPHScreenText[ MPH_FILE_TRANSFER_DIR_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ---------------
+ // Traits
+ DisplayWrappedString( (MPH_TRAITS_SETTING_X - 6), (UINT16)(MPH_TRAITS_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_TRAITS_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ GIO_TRAITS_TEXT], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -------------
- //Display the Dif Settings Title Text
- DisplayWrappedString( MPH_DIF_SETTINGS_X, (UINT16)(MPH_DIF_SETTINGS_Y-MPH_GAP_BN_SETTINGS), MPH_DIF_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ GIO_DIF_LEVEL_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // -----------
+ // HireMerc
+ DisplayWrappedString( (MPH_HIREMERC_SETTING_X - 6), (UINT16)(MPH_HIREMERC_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_HIREMERC_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_RANDOMMERCS_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ----------
- // Hard
- usPosY = MPH_DIF_SETTINGS_Y+2;
- DisplayWrappedString( (UINT16)(MPH_DIF_SETTINGS_X+MPH_OFFSET_TO_TEXT), usPosY, MPH_DIF_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ GIO_HARD_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ------------
+ // SameMerc
+ DisplayWrappedString( (MPH_SAMEMERC_SETTING_X - 6), (UINT16)(MPH_SAMEMERC_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_SAMEMERC_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_SAMEMERC_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ----------
- // Insane
- usPosY += MPH_GAP_BN_SETTINGS-5;
- //DrawTextToScreen( gzMPHScreenText[ MPH_HARD_TEXT ], (UINT16)(MPH_DIF_SETTINGS_X+MPH_OFFSET_TO_TEXT), usPosY, MPH_MAIN_TITLE_WIDTH, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- DisplayWrappedString( (UINT16)(MPH_DIF_SETTINGS_X+MPH_OFFSET_TO_TEXT), usPosY, MPH_DIF_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ GIO_INSANE_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // -------------
+ // ReportMerc
+ DisplayWrappedString( (MPH_REPORTMERC_SETTING_X - 6), (UINT16)(MPH_REPORTMERC_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_REPORTMERC_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_RPTMERC_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -------------
- //Display the Game Type title
- DisplayWrappedString( MPH_GAMETYPE_SETTINGS_X, (UINT16)(MPH_GAMETYPE_SETTINGS_Y-MPH_GAP_BN_SETTINGS), MPH_GAMETYPE_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_GAMETYPE_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // -----------------
+ // BobbyRay
+ DisplayWrappedString( (MPH_BOBBYRAY_SETTING_X - 6), (UINT16)(MPH_BOBBYRAY_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_BOBBYRAY_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_BOBBYRAY_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ----------
- // Deathmatch
- usPosY = MPH_GAMETYPE_SETTINGS_Y+2;
- DisplayWrappedString( (UINT16)(MPH_GAMETYPE_SETTINGS_X+MPH_OFFSET_TO_TEXT), usPosY, MPH_GAMETYPE_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_DEATHMATCH_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ------------------
+ // SectorEdge
+ DisplayWrappedString( (MPH_SECTOREDGE_SETTING_X - 6), (UINT16)(MPH_SECTOREDGE_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_SECTOREDGE_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_RNDMSTART_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ----------
- // Team Deathmatch
- usPosY += MPH_GAP_BN_SETTINGS-5;
- DisplayWrappedString( (UINT16)(MPH_GAMETYPE_SETTINGS_X+MPH_OFFSET_TO_TEXT), usPosY, MPH_GAMETYPE_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_TEAMDM_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // ------------
+ // Civs
+ DisplayWrappedString( (MPH_CIVS_SETTING_X - 6), (UINT16)(MPH_CIVS_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_CIVS_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_ENABLECIV_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // -------------
- // Co-operative
- usPosY += MPH_GAP_BN_SETTINGS-5;
- DisplayWrappedString( (UINT16)(MPH_GAMETYPE_SETTINGS_X+MPH_OFFSET_TO_TEXT), usPosY, MPH_GAMETYPE_SETTINGS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_COOP_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // --------------
+ // Inventory
+ RenderMPHSmallSelectionFrame( (MPH_INVENTORY_SETTING_X + 36), (MPH_INVENTORY_SETTING_Y - 3) );
+ DisplayWrappedString( (UINT16)(MPH_INVENTORY_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (UINT16)(MPH_INVENTORY_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE - 12), MPH_INVENTORY_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ GIO_INV_TEXT ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ DisplayWrappedString( (UINT16)(MPH_INVENTORY_SETTING_X+MPH_OFFSET_TO_TEXT + 1), (MPH_INVENTORY_SETTING_Y+6), MPH_INVENTORY_SETTING_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzGIOScreenText[ iMPHInventory + 54 ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // ----------------
- // Override Max AI
- DisplayWrappedString( (UINT16)MPH_OVERRIDEMAXAI_X, MPH_OVERRIDEMAXAI_Y, MPH_OVERRIDEMAXAI_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_OVERRIDEMAXAI_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Random Mercs
- DisplayWrappedString( (UINT16)MPH_RNDMERC_X, MPH_RNDMERC_Y, MPH_RNDMERC_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_RANDOMMERCS_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Same Mercs
- DisplayWrappedString( (UINT16)MPH_SAMEMERC_X, MPH_SAMEMERC_Y, MPH_SAMEMERC_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_SAMEMERC_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Report Mercs
- DisplayWrappedString( (UINT16)MPH_REPORTMERC_X, MPH_REPORTMERC_Y, MPH_REPORTMERC_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_RPTMERC_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Allow Bobby-Rays
- DisplayWrappedString( (UINT16)MPH_BOBBYRAY_X, MPH_BOBBYRAY_Y, MPH_BOBBYRAY_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_BOBBYRAY_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Random Spawn
- DisplayWrappedString( (UINT16)MPH_RNDSPAWN_X, MPH_RNDSPAWN_Y, MPH_RNDSPAWN_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_RNDMSTART_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Civs
- DisplayWrappedString( (UINT16)MPH_CIVS_X, MPH_CIVS_Y, MPH_CIVS_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_ENABLECIV_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Use NIV
- DisplayWrappedString( (UINT16)MPH_USENIV_X, MPH_USENIV_Y, MPH_USENIV_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_USENIV_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
-
- // Send Files
- DisplayWrappedString( (UINT16)MPH_SEND_FILES_X, MPH_SEND_FILES_Y, MPH_SEND_FILES_WIDTH, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_SYNC_CLIENT_MP_DIR ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ // --------------------
+ // Sync
+ DisplayWrappedString( (MPH_SYNC_SETTING_X - 6), (UINT16)(MPH_SYNC_SETTING_Y-MPH_GAP_BN_SETTINGS + MPH_TITLE_DISTANCE), MPH_SYNC_SETTING_WIDTH + 14, 2, MPH_TOGGLE_TEXT_FONT, MPH_TOGGLE_TEXT_COLOR, gzMPHScreenText[ MPH_SYNC_GAME_DIRECTORY ], FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+ // --------------------
return( TRUE );
-} // end of RenderMPHScreen()
+}
@@ -1328,26 +2760,7 @@ void GetMPHScreenUserInput()
if (ValidateMPSettings())
{
SaveMPSettings(); // Update Profiles/UserProfile/ja2_mp.ini
-#ifdef USE_VFS
- // "gzFileTransferDirectory" is the new multiplayer profile root
- vfs::CProfileStack *PS = getVFS()->getProfileStack();
-
- // remove Multiplayer profile if it exists
- vfs::CVirtualProfile *pProf = PS->getProfile("_MULTIPLAYER");
- if( pProf && (pProf == PS->topProfile()) )
- {
- THROWIFFALSE(PS->popProfile(), "Could not remove old \"_MULTIPLAYER\" profile");
- // careful, pProf is not valid anymore
- }
- // create and initialize a new Multiplayer profile
- pProf = new vfs::CVirtualProfile("_MULTIPLAYER",true);
- PS->pushProfile(pProf);
- if(!initWriteProfile(*pProf, vfs::Path(gzFileTransferDirectory)))
- {
- THROWIFFALSE(PS->popProfile(), L"Could not remove \"_MULTIPLAYER\" profile");
- THROWEXCEPTION(L"Directory exists, but Multiplayer profile could not be iniitalized");
- }
-#endif
+ SGP_TRYCATCH_RETHROW( ja2::mp::InitializeMultiplayerProfile(vfs::Path(gzFileTransferDirectory)), L"" );
gubMPHScreenHandler = MPH_START;
}
break;
@@ -1374,29 +2787,11 @@ void BtnMPHStartCallback(GUI_BUTTON *btn,INT32 reason)
{
gubMPHScreenHandler = MPH_START;
SaveMPSettings(); // Update the Profiles/UserProfile/ja2_mp.ini
-#ifdef USE_VFS
- // "gzFileTransferDirectory" is the new multiplayer profile root
- vfs::CProfileStack *PS = getVFS()->getProfileStack();
-
- // remove Multiplayer profile if it exists
- vfs::CVirtualProfile *pProf = PS->getProfile("_MULTIPLAYER");
- if( pProf && (pProf == PS->topProfile()) )
- {
- THROWIFFALSE(PS->popProfile(), "Could not remove old \"_MULTIPLAYER\" profile");
- // careful, pProf is not valid anymore
- }
- // create and initialize a new Multiplayer profile
- pProf = new vfs::CVirtualProfile("_MULTIPLAYER",true);
- PS->pushProfile(pProf);
- if(!initWriteProfile(*pProf, vfs::Path(gzFileTransferDirectory)))
- {
- THROWIFFALSE(PS->popProfile(), L"Could not remove \"_MULTIPLAYER\" profile");
- THROWEXCEPTION(L"Directory exists, but Multiplayer profile could not be iniitalized");
- }
-#endif
+ SGP_TRYCATCH_RETHROW( ja2::mp::InitializeMultiplayerProfile(vfs::Path(gzFileTransferDirectory)), L"" );
// The difficult level has to be set there. This is the only value so far, because it is used for initialization!
- gGameOptions.ubDifficultyLevel = GetMPHCurrentDifficultyButtonSetting();
+ //gGameOptions.ubDifficultyLevel = GetMPHCurrentDifficultyButtonSetting();
+ gGameOptions.ubDifficultyLevel = iMPHDifficulty + 1;
// WANNE - MP: Reinit TableData folder and INIs
LoadExternalGameplayData(TABLEDATA_DIRECTORY);
@@ -1424,162 +2819,6 @@ void BtnMPHCancelCallback(GUI_BUTTON *btn,INT32 reason)
}
}
-void BtnMPHDifficultyTogglesCallback( GUI_BUTTON *btn, INT32 reason )
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- /*UINT8 ubButton = (UINT8)*/MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHGameTypeTogglesCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- /*UINT8 ubButton = (UINT8)*/MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags &= ~BUTTON_CLICKED_ON;
- }
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- else
- {
- UINT8 cnt;
- BOOLEAN fAnyChecked=FALSE;
-
- //if none of the other boxes are checked, do not uncheck this box
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- fAnyChecked = TRUE;
- }
- }
- //if none are checked, re check this one
- if( !fAnyChecked )
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void RestoreMPHButtonBackGrounds()
-{
- UINT8 cnt;
- UINT16 usPosY;
-
-
- usPosY = MPH_DIF_SETTINGS_Y-MPH_OFFSET_TO_TOGGLE_BOX_Y;
- //Check box to toggle Difficulty settings
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- return( cnt + 3 ); // removed two difficulty options from MPH
- }
- }
-
- return( 0 );
-}
-
-UINT8 GetMPHGameTypeButtonSetting()
-{
- UINT8 cnt;
-
- for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON )
- {
- return( cnt );
- }
- }
-
- return( 0 );
-}
-
-BOOLEAN DoMPHMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen, UINT16 usFlags, MSGBOX_CALLBACK ReturnCallback )
-{
- SGPRect CenteringRect= {0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
-
- // reset exit mode
-// gfExitGioDueToMessageBox = TRUE;
-
- // do message box and return
- giMPHMessageBox = DoMessageBox( ubStyle, zString, uiExitScreen, ( UINT16 ) ( usFlags| MSG_BOX_FLAG_USE_CENTERING_RECT ), ReturnCallback, &CenteringRect );
-
- // send back return state
- return( ( giMPHMessageBox != -1 ) );
-}
-
void DoneFadeOutForExitMPHScreen( void )
{
// As we bypassed the GIO screen, set up some game options for multiplayer here
@@ -1588,59 +2827,18 @@ void DoneFadeOutForExitMPHScreen( void )
is_host = true; // we want to be the host, not we ARE the host yet (is_server)
auto_retry = true;
giNumTries = 5;
-
- // loop through and get the status of all the buttons
- // Madd
- /*gGameOptions.fGunNut = GetCurrentGunButtonSetting();
- gGameOptions.ubGameStyle = GetCurrentGameStyleButtonSetting();
- gGameOptions.ubDifficultyLevel = GetCurrentDifficultyButtonSetting() + 1;*/
- // JA2Gold: no more timed turns setting
- //gGameOptions.fTurnTimeLimit = GetCurrentTimedTurnsButtonSetting();//hayden : re-enabled
-
+
if (is_networked)
gGameOptions.fTurnTimeLimit = TRUE;
else
gGameOptions.fTurnTimeLimit = FALSE;
- // JA2Gold: iron man
- //gGameOptions.fIronManMode = GetCurrentGameSaveButtonSetting();
-
// Bobby Rays - why would we want anything less than the best
gGameOptions.ubBobbyRay = BR_AWESOME;
-
-
- // CHRISL:
- /*if(IsNIVModeValid() == TRUE){
- switch ( GetCurrentINVOptionButtonSetting() )
- {
- case GIO_INV_OLD:
- gGameOptions.ubInventorySystem = INVENTORY_OLD;
- break;
- case GIO_INV_NEW:
- gGameOptions.ubInventorySystem = INVENTORY_NEW;
- break;
- }
- }*/
-
- // gubGIOExitScreen = INIT_SCREEN;
+
gubMPHExitScreen = INTRO_SCREEN;
- //set the fact that we should do the intro videos
-// gbIntroScreenMode = INTRO_BEGINING;
-#ifdef JA2TESTVERSION
- if( gfKeyState[ ALT ] )
- {
- if( gfKeyState[ CTRL ] )
- {
- gMercProfiles[ MIGUEL ].bMercStatus = MERC_IS_DEAD;
- gMercProfiles[ SKYRIDER ].bMercStatus = MERC_IS_DEAD;
- }
-
- SetIntroType( INTRO_ENDING );
- }
- else
-#endif
- SetIntroType( INTRO_BEGINING );
+ SetIntroType( INTRO_BEGINNING );
ExitMPHScreen(); // cleanup please, if we called a fadeout then we didnt do it above
@@ -1652,146 +2850,16 @@ void DoneFadeInForExitMPHScreen( void )
SetCurrentCursorFromDatabase( VIDEO_NO_CURSOR );
}
-void BtnMPHOverrideMaxAICallback(GUI_BUTTON *btn,INT32 reason)
+void RenderMPHSmallSelectionFrame(INT16 sX, INT16 sY)
{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHOverrideMaxAIToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
+ HVOBJECT hHandle;
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
+ // get the video object
+ GetVideoObject(&hHandle, guiMPHSMALLFRAME);
-void BtnMPHRandomMercCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
+ // blt to sX, sY relative to upper left corner
+ BltVideoObject(FRAME_BUFFER, hHandle, 0, sX, sY , VO_BLT_SRCTRANSPARENCY,NULL);
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHRandomMercsToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHSameMercCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHSameMercToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHReportMercCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHReportMercToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHBobbyRayCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHBobbyRayToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHRandomSpawnCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHRandomSpawnToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHUseNIVCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHUseNIVToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHSendFilesCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHSendFiles ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
-}
-
-void BtnMPHCivsCallback(GUI_BUTTON *btn,INT32 reason)
-{
- if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
- {
- MSYS_GetBtnUserData( btn, 0 );
-
- if( btn->uiFlags & BUTTON_CLICKED_ON )
- {
- ButtonList[ guiMPHCivsToggle ]->uiFlags &= ~BUTTON_CLICKED_ON;
-
- //enable the current button
- btn->uiFlags |= BUTTON_CLICKED_ON;
- }
- }
+ return;
}
\ No newline at end of file
diff --git a/MPJoinScreen.cpp b/MPJoinScreen.cpp
index b0c3e859..47e79a49 100644
--- a/MPJoinScreen.cpp
+++ b/MPJoinScreen.cpp
@@ -31,10 +31,10 @@
#include "saveloadscreen.h"
#include "game init.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_init.h"
-#include "VFS/PropertyContainer.h"
-#include "VFS/os_functions.h"
+#include
+#include
+#include
+#include
#include "Random.h"
@@ -51,15 +51,17 @@
#define MPJ_LABEL_TEXT_COLOR FONT_MCOLOR_WHITE
//buttons
-#define MPJ_BTN_JOIN_X iScreenWidthOffset + 320 + 143
-#define MPJ_BTN_JOIN_Y iScreenHeightOffset + 435
-#define MPJ_BTN_HOST_X MPJ_BTN_JOIN_X-180
-#define MPJ_BTN_HOST_Y iScreenHeightOffset + 435
#define MPJ_CANCEL_X iScreenWidthOffset + ((320 - 115) / 2)
+#define MPJ_BTN_HOST_X iScreenWidthOffset + 265
+#define MPJ_BTN_HOST_Y iScreenHeightOffset + 435
+
+#define MPJ_BTN_JOIN_X iScreenWidthOffset + 425
+#define MPJ_BTN_JOIN_Y iScreenHeightOffset + 435
+
//textboxes
#define MPJ_TXT_HANDLE_X iScreenWidthOffset + 100
-#define MPJ_TXT_HANDLE_Y iScreenHeightOffset + 60
+#define MPJ_TXT_HANDLE_Y iScreenHeightOffset + 100
#define MPJ_TXT_HANDLE_WIDTH 120
#define MPJ_TXT_HANDLE_HEIGHT 17
#define MPJ_TXT_IP_X iScreenWidthOffset + 100
@@ -73,7 +75,7 @@
//main title
-#define MPJ_MAIN_TITLE_X 0
+#define MPJ_MAIN_TITLE_X 0
#define MPJ_MAIN_TITLE_Y iScreenHeightOffset + 10
#define MPJ_MAIN_TITLE_WIDTH SCREEN_WIDTH
@@ -91,7 +93,6 @@
#define MPJ_LABEL_PORT_WIDTH 80
#define MPJ_LABEL_PORT_HEIGHT 17
-
////////////////////////////////////////////
//
// Global Variables
@@ -127,9 +128,8 @@ CHAR16 gzServerPortField[ 5+1 ] = {0} ;
// client sets this when joining
extern CHAR16 gzFileTransferDirectory[100];
-#ifdef USE_VFS
-void CUniqueServerId::uniqueRandomString(utf8string& str)
+void CUniqueServerId::uniqueRandomString(vfs::String& str)
{
std::vector _rand(30,0);
int pos = 0;
@@ -153,25 +153,24 @@ void CUniqueServerId::uniqueRandomString(utf8string& str)
str.r_wcs().assign(&_rand[0],29);
}
-utf8string const& CUniqueServerId::getServerId(vfs::Path dir, CPropertyContainer* props)
+vfs::String const& CUniqueServerId::getServerId(vfs::Path dir, vfs::PropertyContainer* props)
{
if(!props)
{
return _id;
}
- utf8string key = L"\"" + dir.c_wcs() + L"\"";
- utf8string id = props->getStringProperty(L"SERVER",key);
+ vfs::String key = L"\"" + dir.c_wcs() + L"\"";
+ vfs::String id = props->getStringProperty(JA2MP_INI_SERVER_SECTION,key);
if(id.empty())
{
uniqueRandomString(id);
}
_id = id;
- props->setStringProperty(L"SERVER",key,_id);
+ props->setStringProperty(JA2MP_INI_SERVER_SECTION,key,_id);
return _id;
}
CUniqueServerId s_ServerId;
-#endif
////////////////////////////////////////////
//
@@ -217,21 +216,30 @@ void DoneFadeOutForExitMPJScreen( void );
void DoneFadeInForExitMPJScreen( void );
+void MpIniExists()
+{
+ if(!getVFS()->fileExists(JA2MP_INI_FILENAME))
+ {
+ SGP_THROW_IFFALSE(getVFS()->createNewFile(JA2MP_INI_FILENAME),L"could not create file : Ja2_mp.ini");
+ vfs::tWritableFile* file = getVFS()->getWriteFile(JA2MP_INI_FILENAME);
+ if(file)
+ {
+ file->openWrite(true);
+ file->close();
+ }
+ }
+}
+
+
UINT32 MPJoinScreenInit( void )
{
-// WANNE - MP: Read the values from Profiles/UserProfile/ja2_mp.ini
-#ifndef USE_VFS
- // read settings from JA2 ini
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"SERVER_IP", L"127.0.0.1", gzServerIPField, 16, L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"SERVER_PORT", L"60005", gzServerPortField, 6, L"..\\Ja2_mp.ini" );
- GetPrivateProfileStringW( L"Ja2_mp Settings",L"CLIENT_NAME", L"Player Name", gzPlayerHandleField, 12 , L"..\\Ja2_mp.ini" );
-#else
- CPropertyContainer props;
- props.initFromIniFile( L"Ja2_mp.ini");
- props.getStringProperty( L"Ja2_mp Settings", L"SERVER_IP", gzServerIPField, 16, "127.0.0.1");
- props.getStringProperty( L"Ja2_mp Settings", L"SERVER_PORT", gzServerPortField, 6, "60005");
- props.getStringProperty( L"Ja2_mp Settings", L"CLIENT_NAME", gzPlayerHandleField, 12, L"Player Name");
-#endif
+ // WANNE - MP: Read the values from Profiles/UserProfile/ja2_mp.ini
+ MpIniExists();
+ vfs::PropertyContainer props;
+ props.initFromIniFile( JA2MP_INI_FILENAME);
+ props.getStringProperty( JA2MP_INI_INITIAL_SECTION, JA2MP_SERVER_IP, gzServerIPField, 16, "127.0.0.1");
+ props.getStringProperty( JA2MP_INI_INITIAL_SECTION, JA2MP_SERVER_PORT, gzServerPortField, 6, "60005");
+ props.getStringProperty( JA2MP_INI_INITIAL_SECTION, JA2MP_CLIENT_NAME, gzPlayerHandleField, 12, L"Player Name");
return( 1 );
}
@@ -244,23 +252,17 @@ void SaveJoinSettings(bool ReSaving)
Get16BitStringFromField( 2, gzServerPortField, 6 );
}
-#ifndef USE_VFS
- // save settings to JA2_mp.ini
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"SERVER_IP", gzServerIPField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"SERVER_PORT", gzServerPortField, L"..\\Ja2_mp.ini" );
- WritePrivateProfileStringW( L"Ja2_mp Settings",L"CLIENT_NAME", gzPlayerHandleField , L"..\\Ja2_mp.ini" );
-#else
- CPropertyContainer props;
- props.initFromIniFile("Ja2_mp.ini");
+ MpIniExists();
+ vfs::PropertyContainer props;
+ props.initFromIniFile(JA2MP_INI_FILENAME);
- props.setStringProperty(L"Ja2_mp Settings",L"SERVER_IP", gzServerIPField);
- props.setStringProperty(L"Ja2_mp Settings",L"SERVER_PORT", gzServerPortField);
- props.setStringProperty(L"Ja2_mp Settings",L"CLIENT_NAME", gzPlayerHandleField);
+ props.setStringProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_SERVER_IP, gzServerIPField);
+ props.setStringProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_SERVER_PORT, gzServerPortField);
+ props.setStringProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_CLIENT_NAME, gzPlayerHandleField);
s_ServerId.getServerId(vfs::Path(gzFileTransferDirectory), &props);
- props.writeToIniFile(L"ja2_mp.ini",true);
-#endif
+ props.writeToIniFile(JA2MP_INI_FILENAME,false);
}
bool ValidateJoinSettings(bool bSkipServerAddress, bool bSkipSyncDir)
@@ -326,30 +328,10 @@ bool ValidateJoinSettings(bool bSkipServerAddress, bool bSkipSyncDir)
if (!bSkipSyncDir)
{
-#ifndef USE_VFS
- // Create MULTIPLAYER / SERVERS if it dosent exist
- STRING512 syncDir;
- STRING512 executableDir;
-
- GetExecutableDirectory(executableDir);
- sprintf(syncDir, "%s\\multiplayer", executableDir);
-
- if (!DirectoryExists(syncDir))
+ if(vfs::OS::createRealDirectory(vfs::Path(L"Multiplayer")))
{
- CreateDirectoryA(syncDir, NULL);
+ vfs::OS::createRealDirectory(vfs::Path(L"Multiplayer/Servers"));
}
-
- sprintf(syncDir, "%s\\multiplayer\\servers", executableDir);
- if (!DirectoryExists(syncDir))
- {
- CreateDirectoryA(syncDir, NULL);
- }
-#else
- if(os::createRealDirectory(vfs::Path(L"Multiplayer")))
- {
- os::createRealDirectory(vfs::Path(L"Multiplayer/Servers"));
- }
-#endif
}
return true;
@@ -361,8 +343,6 @@ UINT32 MPJoinScreenHandle( void )
if( gfMPJScreenEntry )
{
-// PauseGame();
-
EnterMPJScreen();
gfMPJScreenEntry = FALSE;
gfMPJScreenExit = FALSE;
@@ -371,7 +351,6 @@ UINT32 MPJoinScreenHandle( void )
GetMPJScreenUserInput();
-
HandleMPJScreen();
// render buttons marked dirty
@@ -380,12 +359,7 @@ UINT32 MPJoinScreenHandle( void )
// render text boxes
RenderAllTextFields(); // textbox system call
-
- // render help
-// RenderFastHelp( );
-// RenderButtonsFastHelp( );
-
-
+
ExecuteBaseDirtyRectQueue();
EndFrameBufferRender();
@@ -409,17 +383,15 @@ UINT32 MPJoinScreenHandle( void )
if ( HandleBeginFadeIn( gubMPJExitScreen ) )
{
-
}
- if( gfMPJScreenExit ) // we are exiting this screen
+ if( gfMPJScreenExit )
{
- ExitMPJScreen(); // perform destruction
+ ExitMPJScreen();
}
return( gubMPJExitScreen );
-} // end MPJoinScreenHandle()
-
+}
UINT32 MPJoinScreenShutdown( void )
{
@@ -545,9 +517,7 @@ BOOLEAN EnterMPJScreen()
gfMPJButtonsAllocated = TRUE;
return( TRUE );
-
-} // End of EnterMPJScreen()
-
+}
BOOLEAN ExitMPJScreen()
{
@@ -582,10 +552,9 @@ BOOLEAN ExitMPJScreen()
return( TRUE );
-} // End of ExitMPJScreen()
+}
-
-void HandleMPJScreen()
+void HandleMPJScreen()
{
if( gubMPJScreenHandler != MPJ_NOTHING )
{
@@ -617,23 +586,54 @@ void HandleMPJScreen()
}
break;
}
-
}
gubMPJScreenHandler = MPJ_NOTHING;
}
-
if( gfReRenderMPJScreen )
{
RenderMPJScreen();
gfReRenderMPJScreen = FALSE;
}
+}
- // add restore backgrounds in...
- //RestoreGIOButtonBackGrounds();
-} // end of HandleMPJScreen
+void DrawHelpText()
+{
+ int x = MPJ_LABEL_HANDLE_X;
+ int y = iScreenHeightOffset + 60;
+ int width = 640 - (2 * 50);
+ int lineSpacing = 12;
+ // Visit IRC
+ DrawTextToScreen( gzMPJHelpText[ 0 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+
+ // Host
+ y += 150;
+
+ y+= lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 1 ], x, y, width, FONT12ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y+= lineSpacing + 5;
+ DrawTextToScreen( gzMPJHelpText[ 2 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y+= lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 3 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y+= lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 4 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y+= lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 5 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+
+ // Join
+ y += 20;
+
+ y += lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 6 ], x, y, width, FONT12ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y += lineSpacing + 5;
+ DrawTextToScreen( gzMPJHelpText[ 7 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y += lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 8 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ y += lineSpacing;
+ DrawTextToScreen( gzMPJHelpText[ 9 ], x, y, width, FONT10ARIAL, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+}
BOOLEAN RenderMPJScreen()
{
@@ -648,9 +648,11 @@ BOOLEAN RenderMPJScreen()
//Display the title
DrawTextToScreen( gzMPJScreenText[ MPJ_TITLE_TEXT ], MPJ_MAIN_TITLE_X, MPJ_MAIN_TITLE_Y, MPJ_MAIN_TITLE_WIDTH, MPJ_TITLE_FONT, MPJ_TITLE_COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED );
+
+ DrawHelpText();
// Player name text label
- DisplayWrappedString( MPJ_LABEL_HANDLE_X, MPJ_LABEL_HANDLE_Y, MPJ_LABEL_HANDLE_WIDTH, 2, MPJ_LABEL_TEXT_FONT, MPJ_LABEL_TEXT_COLOR, gzMPJScreenText[ MPJ_HANDLE_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ DisplayWrappedString( MPJ_LABEL_HANDLE_X, MPJ_LABEL_HANDLE_Y, MPJ_LABEL_HANDLE_WIDTH, 2, MPJ_LABEL_TEXT_FONT, MPJ_LABEL_TEXT_COLOR, gzMPJScreenText[ MPJ_HANDLE_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
// Server IP text label
DisplayWrappedString( MPJ_LABEL_IP_X, MPJ_LABEL_IP_Y, MPJ_LABEL_IP_WIDTH, 2, MPJ_LABEL_TEXT_FONT, MPJ_LABEL_TEXT_COLOR, gzMPJScreenText[ MPJ_SERVERIP_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
@@ -659,16 +661,11 @@ BOOLEAN RenderMPJScreen()
DisplayWrappedString( MPJ_LABEL_PORT_X, MPJ_LABEL_PORT_Y, MPJ_LABEL_PORT_WIDTH, 2, MPJ_LABEL_TEXT_FONT, MPJ_LABEL_TEXT_COLOR, gzMPJScreenText[ MPJ_SERVERPORT_TEXT ], FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
return( TRUE );
-} // end of RenderMPJScreen()
+}
-
-
-void GetMPJScreenUserInput()
+void GetMPJScreenUserInput()
{
InputAtom Event;
-// POINT MousePos;
-
-// GetCursorPos(&MousePos);
while( DequeueEvent( &Event ) )
{
@@ -697,11 +694,9 @@ void GetMPJScreenUserInput()
}
}
}
-} // end of GetMPJScreenUserInput()
-
+}
// CALLBACKS
-
void BtnMPJoinCallback(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
@@ -768,9 +763,6 @@ BOOLEAN DoMPJMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen
{
SGPRect CenteringRect= {0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
- // reset exit mode
-// gfExitGioDueToMessageBox = TRUE;
-
// do message box and return
giMPJMessageBox = DoMessageBox( ubStyle, zString, uiExitScreen, ( UINT16 ) ( usFlags| MSG_BOX_FLAG_USE_CENTERING_RECT ), ReturnCallback, &CenteringRect );
@@ -780,8 +772,7 @@ BOOLEAN DoMPJMessageBox( UINT8 ubStyle, const STR16 zString, UINT32 uiExitScreen
void DoneFadeOutForExitMPJScreen( void )
{
- // As we bypassed the GIO screen, set up some game options for multiplayer here
- // most things i have left as thier defaults here for testing.
+ // As we bypassed the GIO screen, set up some game options for multiplayer here
is_networked = true;
is_host = false; // we want to be a client, not we ARE a client yet (is_client)
auto_retry = true;
diff --git a/MPJoinScreen.h b/MPJoinScreen.h
index ff829119..ea6a0934 100644
--- a/MPJoinScreen.h
+++ b/MPJoinScreen.h
@@ -1,31 +1,31 @@
#ifndef _MP_JOIN_SCREEN_H_
#define _MP_JOIN_SCREEN_H_
-#include "VFS/vfs.h"
+#include
-#ifdef USE_VFS
-
-class CPropertyContainer;
+namespace vfs{
+ class PropertyContainer;
+}
class CUniqueServerId
{
public:
- utf8string const& getServerId(vfs::Path dir, CPropertyContainer* props = NULL);
+ vfs::String const& getServerId(vfs::Path dir, vfs::PropertyContainer* props = NULL);
- static void uniqueRandomString(utf8string& str);
+ static void uniqueRandomString(vfs::String& str);
private:
- utf8string _id;
+ vfs::String _id;
};
extern CUniqueServerId s_ServerId;
-#endif
-
UINT32 MPJoinScreenInit( void );
UINT32 MPJoinScreenHandle( void );
UINT32 MPJoinScreenShutdown( void );
-void SaveJoinSettings(bool ReSaving);
+void SaveJoinSettings(bool ReSaving);
+
+void MpIniExists();
diff --git a/MPScoreScreen.cpp b/MPScoreScreen.cpp
index 9bcf7cf8..5d489128 100644
--- a/MPScoreScreen.cpp
+++ b/MPScoreScreen.cpp
@@ -329,7 +329,6 @@ void HandleMPSScreen()
switch( gubMPSScreenHandler )
{
case MPS_CANCEL:
- // TODO.RW: Exit game, disconnect
if (is_server)
server_disconnect();
@@ -475,7 +474,7 @@ BOOLEAN RenderMPSScreen()
}
}
- if (PLAYER_BSIDE==MP_TYPE_COOP)
+ if (cGameType==MP_TYPE_COOP)
{
// CO-OP Mode, show stats for queens army
usPosY = MPS_PLAYERLIST_Y + (5 * MPS_PLAYER_GAP); // leave a space between players and AI
@@ -610,7 +609,7 @@ void DoneFadeOutForExitMPSScreen( void )
}
else
#endif
- SetIntroType( INTRO_BEGINING );
+ SetIntroType( INTRO_BEGINNING );
ExitMPSScreen(); // cleanup please, if we called a fadeout then we didnt do it above
diff --git a/MPXmlTeams.cpp b/MPXmlTeams.cpp
index ddd184ff..1bff9cab 100644
--- a/MPXmlTeams.cpp
+++ b/MPXmlTeams.cpp
@@ -10,10 +10,10 @@ MultiplayerTeams mpTeams = MultiplayerTeams();
// fallback data
const int MultiplayerTeams::random_merc_teams[NUM_RANDOM_MERC_TEAMS][RANDOM_MERC_TEAM_SIZE] = {
- { 16, 10, 19, 25, 4 , 11, 39 }, // Gus , Shadow, Spider , Raven , Vicki , Red , Meltdown
- { 29, 36, 28, 2 , 22, 8 , 32 }, // Magic , Scope, Danny , Lynx , Hitman , Steroid , Malice
- { 12, 5 , 20, 23, 48, 34, 17 }, // Reaper , Trevor, Cliff , Buzz , Cougar , Nails , Buns
- { 31, 7 , 33, 35, 27, 37, 1 }, // Scully , Ivan , Dr Q , Thor , Len , Wolf , Blood
+ { 16, 10, 19, 25, 4 , 11, 39 }, // Gus , Shadow, Spider , Raven , Vicki , Red , Meltdown
+ { 173, 36, 28, 2 , 22, 8 , 32 }, // Henning , Scope, Danny , Lynx , Hitman , Steroid , Malice
+ { 12, 175, 20, 23, 48, 34, 17 }, // Reaper , Laura, Cliff , Buzz , Cougar , Nails , Buns
+ { 31, 7, 33, 35, 27, 37, 1 }, // Scully , Ivan , Dr Q , Thor , Len , Wolf , Blood
};
void MultiplayerTeams::SerializeProfiles(int* dest)
diff --git a/MainMenuScreen.cpp b/MainMenuScreen.cpp
index e65e03fe..0f55c989 100644
--- a/MainMenuScreen.cpp
+++ b/MainMenuScreen.cpp
@@ -38,8 +38,8 @@
#include "mercs.h"
#include "gamesettings.h"
#include "connect.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_profile.h"
+#include
+#include
#define MAINMENU_TEXT_FILE "LoadScreens\\MainMenu.edt"
#define MAINMENU_RECORD_SIZE 80 * 2
@@ -294,7 +294,7 @@ BOOLEAN InitMainMenu( )
vfs::CVirtualProfile *pProf = PS->getProfile("_MULTIPLAYER");
if( pProf && (pProf == PS->topProfile()) )
{
- THROWIFFALSE(PS->popProfile(), "Leaving Multiplayer mode : Could not remove \"_MULTIPLAYER\" profile");
+ SGP_THROW_IFFALSE(PS->popProfile(), "Leaving Multiplayer mode : Could not remove \"_MULTIPLAYER\" profile");
}
#endif
@@ -318,7 +318,7 @@ BOOLEAN InitMainMenu( )
if (iResolution == 0)
{
- FilenameForBPP("LOADSCREENS\\MainMenuBackGround.sti", VObjectDesc.ImageFile);
+ FilenameForBPP("LOADSCREENS\\MainMenuBackGround.sti", VObjectDesc.ImageFile);
}
else if (iResolution == 1)
{
@@ -339,7 +339,7 @@ BOOLEAN InitMainMenu( )
/*
// Gray out some buttons based on status of game!
- if( gGameSettings.bLastSavedGameSlot < 0 || gGameSettings.bLastSavedGameSlot >= NUM_SAVE_GAMES )
+ if( gGameSettings.bLastSavedGameSlot < 0 || gGameSettings.bLastSavedGameSlot >= NUM_SLOT )
{
DisableButton( iMenuButtons[ LOAD_GAME ] );
}
@@ -362,7 +362,8 @@ BOOLEAN InitMainMenu( )
SetPendingNewScreen( MAINMENU_SCREEN);
guiMainMenuExitScreen = MAINMENU_SCREEN;
- InitGameOptions();
+ // WANNE: I don't think that is needed!
+ //InitGameOptions();
DequeueAllKeyBoardEvents();
@@ -406,22 +407,14 @@ void InitDependingGameStyleOptions()
LoadGameAPBPConstants();
// Load ja2_options.ini
LoadGameExternalOptions();
+ // Load new STOMP ini - SANDRO
+ LoadSkillTraitsExternalSettings();
+ // HEADROCK HAM 4: CTH constants
+ LoadCTHConstants();
+
InitSightRange(); //lal
- ReStartingGame();
-
- if (is_networked)
- {
- NUMBER_OF_MERCS = 28;
- LAST_MERC_ID = 27;
- }
- else
- {
- InitGameOptions();
-
- NUMBER_OF_MERCS = 15;
- LAST_MERC_ID = 14;
- }
+ ReStartingGame();
}
diff --git a/Multiplayer/client.cpp b/Multiplayer/client.cpp
index 5460dbfd..c189676d 100644
--- a/Multiplayer/client.cpp
+++ b/Multiplayer/client.cpp
@@ -72,6 +72,7 @@
#include "Explosion Control.h"
#include "SmokeEffects.h"
#include "MPChatScreen.h"
+#include "sgp_logger.h"
#endif
#include "MessageIdentifiers.h"
@@ -106,16 +107,15 @@
#include "MessageBoxScreen.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_init.h"
-#include "VFS/vfs_profile.h"
-#include "VFS/vfs_file_raii.h"
-#include "VFS/os_functions.h"
-#include "VFS/File/vfs_file.h"
-#include "VFS/Tools/ParserTools.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include "transfer_rules.h"
#include "keys.h"
-
#include "new.h"
#include "Types.h"
#include "connect.h"
@@ -128,15 +128,11 @@
#include "soldier profile.h"
#include "environment.h"
#include "lighting.h"
-
#include "laptop.h"
-#include "test_space.h"
#include "interface panels.h"
-
#include "game init.h"
#include "Debug Control.h"
#include "MPConnectScreen.h"
-
#include "IniReader.h"
extern CHAR16 gzFileTransferDirectory[100];
@@ -187,69 +183,7 @@ class ClientTransferCB : public FileListTransferCBInterface
// Now the file will be saved on the client
bool OnFile(OnFileStruct *onFileStruct)
{
-#ifndef USE_VFS
- // Get the directory path of the file and output it to the user!
- char* targetFileName = ExtractFilename(onFileStruct->fileName);
- //ScreenMsg( FONT_BCOLOR_ORANGE, MSG_MPSYSTEM, MPClientMessage[58], targetFileName);
- //ScreenMsg( FONT_BCOLOR_ORANGE, MSG_MPSYSTEM, L"%i. (100%%) %i/%i %S %ib->%ib / %ib->%ib\n", onFileStruct->setID, onFileStruct->fileIndex+1, onFileStruct->setCount, onFileStruct->fileName, onFileStruct->compressedTransmissionLength, onFileStruct->finalDataLength, onFileStruct->setTotalCompressedTransmissionLength, onFileStruct->setTotalFinalLength);
- // Replace server executable directory with client executable directory then we have the correct path
- char* tempFile = ReplaceCharactersInString_Client(onFileStruct->fileName, server_fileTransferDirectoryPath, client_fileTransferDirectoryPath);
- char* pathWithoutFile = ReplaceCharactersInString_Client(tempFile, targetFileName, "");
-
- // ----------------------------------
- // The directory does not exist, create it (and parent directories if needed)
- // ----------------------------------
- if (!DirectoryExists(pathWithoutFile))
- {
- // Remove the executable directory path
- pathWithoutFile = ReplaceCharactersInString_Client(pathWithoutFile, client_executableDir, "");
-
- wchar_t pathWithoutFileWChar[600];
- STRING512 currentDirectoryPath;
- wchar_t* directoryName;
- char directoryNameChar[100];
-
- // Convert char* to wchar_t*
- MultiByteToWideChar( CP_UTF8, 0, pathWithoutFile, -1, pathWithoutFileWChar, 600);
- strcpy(currentDirectoryPath, client_executableDir);
-
- directoryName = wcstok(pathWithoutFileWChar,L"\\");
- while (directoryName != NULL)
- {
- // Convert to wchar_t* to char*
- WideCharToMultiByte(CP_UTF8,0,directoryName,-1, directoryNameChar,100,NULL,NULL);
-
- // Get the full path of the directory
- strcat(currentDirectoryPath, "\\");
- strcat(currentDirectoryPath, directoryNameChar);
-
- if (!DirectoryExists(currentDirectoryPath))
- {
- // Folder does not exist, create it
- if( !MakeFileManDirectory( currentDirectoryPath ) )
- AssertMsg( 0, String("Can't create new directory '%s'.", currentDirectoryPath) );
- }
-
- // get next directory (split on "\")
- directoryName = wcstok(NULL,L"\\");
- }
- }
-
- // OJW - 20090405
- char *relativeFname = ReplaceCharactersInString_Client(onFileStruct->fileName, server_fileTransferDirectoryPath,"");
- strcpy(gCurrentTransferFilename,relativeFname);
- SetConnectScreenSubMessageA(gCurrentTransferFilename); // setting this also causes connect screen to refresh
-
- // ----------------------------------
- // Save the file to clients harddisk
- // ----------------------------------
- char *fileToSave = ReplaceCharactersInString_Client(onFileStruct->fileName, server_fileTransferDirectoryPath, client_fileTransferDirectoryPath);
-
- FILE *fp = fopen(fileToSave, "wb");
- fwrite(onFileStruct->fileData, onFileStruct->finalDataLength, 1, fp);
- fclose(fp);
-#else
if(!transferRules)
{
transferRules = new CTransferRules();
@@ -260,9 +194,9 @@ class ClientTransferCB : public FileListTransferCBInterface
//ScreenMsg( FONT_BCOLOR_ORANGE, MSG_CHAT, MPClientMessage[58], targetFileName);
vfs::Path fileName(onFileStruct->fileName);
- utf8string::str_t const& valid_str = fileName.c_wcs();
- utf8string::size_t pos = valid_str.find(L":");
- if(pos != utf8string::str_t::npos)
+ vfs::String::str_t const& valid_str = fileName.c_wcs();
+ vfs::String::size_t pos = valid_str.find(L":");
+ if(pos != vfs::String::str_t::npos)
{
// absolute path?? these are invalid and the server is not supposed to send us such paths
// potentialy malicious server -> output error
@@ -287,15 +221,13 @@ class ClientTransferCB : public FileListTransferCBInterface
try
{
vfs::COpenWriteFile wfile(fileName,true,true);
- wfile.file().write(onFileStruct->fileData,onFileStruct->finalDataLength);
+ wfile->write(onFileStruct->fileData,onFileStruct->finalDataLength);
}
- catch(CBasicException& ex)
+ catch(vfs::Exception& ex)
{
- logException(ex);
- ScreenMsg( FONT_BCOLOR_BLUE, MSG_CHAT, L"Could not write received file '%S'", targetFileName);
- //RETHROWEXCEPTION(L"Could not write received file",ex);
+ SGP_ERROR(ex.what());
+ ScreenMsg( FONT_BCOLOR_BLUE, MSG_CHAT, MPClientMessage[70], targetFileName);
}
-#endif
/*
// Make sure it worked
@@ -384,13 +316,11 @@ class ClientTransferCB : public FileListTransferCBInterface
SetConnectScreenSubMessageW(MPClientMessage[60]); // setting this also causes connect screen to refresh
//fileTransferProgress = 0;
-#ifdef USE_VFS
if(transferRules)
{
delete transferRules;
transferRules = NULL;
}
-#endif
if (recieved_settings && CLIENT_NUM > 0 && CLIENT_NUM <= 4)
{
@@ -427,15 +357,15 @@ class ClientTransferCB : public FileListTransferCBInterface
else s = pathname;
return s;
}
-#ifdef USE_VFS
+
// client has an ignore list too, as the server doesn't have to play by the rules
static CTransferRules* transferRules;
-#endif
+
} transferCallback;
-#ifdef USE_VFS
+
CTransferRules* ClientTransferCB::transferRules = NULL;
-#endif
+
ClientTransferCB transferCBClient;
@@ -481,7 +411,6 @@ typedef struct
UINT8 tsubNextTeam;
} turn_struct;
-
typedef struct
{
@@ -635,94 +564,72 @@ int random_mercs[7];
// OJW - 20090305
int client_downloading[4];
int client_progress[4];
+int TEAM;
-INT32 MAX_MERCS;
-
-int TEAM;
-//int OP_TEAM_2;
-//int OP_TEAM_3;
-//int OP_TEAM_4;
-
-
-
-UINT8 netbTeam;
+UINT8 netbTeam;
UINT8 ubID_prefix;
- bool is_connected=false;
- bool is_connecting=false;
- bool is_client=false;
- bool is_server=false;
- bool is_networked=false;
-
- bool is_host=false; // OJW - added 20081130 - new flag to signal our intention to host, coming in from the HOST screen
- bool auto_retry=true;
- int giNumTries = MAX_CONNECT_RETRIES; // default is 5 retries
- UINT32 giNextRetryTime = 0;
-
- bool requested=false;
-
-int tcount;
+bool is_connected=false;
+bool is_connecting=false;
+bool is_client=false;
+bool is_server=false;
+bool is_networked=false;
+bool is_host=false; // OJW - added 20081130 - new flag to signal our intention to host, coming in from the HOST screen
+bool auto_retry=true;
+int giNumTries = MAX_CONNECT_RETRIES; // default is 5 retries
+UINT32 giNextRetryTime = 0;
+bool requested=false;
int kit[20];
-bool DISABLE_MORALE;
- int TESTING;
- bool allowlaptop=false;
+bool allowlaptop=false;
+bool recieved_settings=false;
+// OJW - 20090422
+bool recieved_transfer_settings = false;
+bool getReal=false;
- bool recieved_settings=false;
- // OJW - 20090422
- bool recieved_transfer_settings = false;
+int CLIENT_NUM;
- bool getReal=false;
+// --------------------
+// Global Client Variables
+// --------------------
+UINT8 cStartingSectorEdge;
+char cKitBag[100];
+char cClientName[30];
+UINT8 gRandomStartingEdge;
+UINT8 gRandomMercs;
+char cServerName[30];
+char cGameDataSyncDirectory[100];
+UINT8 cReportHiredMerc;
+UINT8 cWeaponReadyBonus;
+UINT8 cDisableSpectatorMode;
+UINT8 gEnemyEnabled;
+UINT8 gCreatureEnabled;
+UINT8 gMilitiaEnabled;
+UINT8 gCivEnabled;
+UINT8 cAllowMercEquipment;
+UINT8 cSameMercAllowed;
+UINT8 cGameType;
+UINT8 cMaxMercs;
+FLOAT cDamageMultiplier;
+UINT8 cMaxClients;
+UINT8 cDisableMorale;
+// --------------------
- //char CLIENT_NUM[30];
- int CLIENT_NUM;
- char SECT_EDGE[30];
-char ckbag[100];
- char CLIENT_NAME[30];
- // OJW - 20081204
- char SERVER_NAME[30];
- int RANDOM_SPAWN;
- int RANDOM_MERCS;
-
- char SERVER_IP[30] ;
- char SERVER_PORT[30];
- char FILE_TRANSFER_DIRECTORY_CLIENT[100];
-
- int SEND_FILES_CLIENT;
-
- int INVENTORY_MODE;
- int REPORT_NAME;
- int WEAPON_READIED_BONUS;
- int DISABLE_SPEC_MODE;
-
- int ENEMY_ENABLED;
- int CREATURE_ENABLED;
- int MILITIA_ENABLED;
- int CIV_ENABLED;
-
- int ALLOW_EQUIP;
-
- int SAME_MERC;
- int PLAYER_BSIDE;
-
-int START_TEAM_TURN;
-
- bool goahead = 0;
- int numready = 0;
- int readystage = 0;
- bool status = 0;
-
- bool wiped;
-
- bool lockedgui = 0;
-
-FLOAT DAMAGE_MULTIPLIER;
-
-//int INTERRUPTS;
-int MAX_CLIENTS;
-
-UINT32 crate_usMapPos;
-
-INT16 crate_sGridX, crate_sGridY;
+// --------------------
+// Other client variables
+// --------------------
+bool goahead = 0;
+int numready = 0;
+int readystage = 0;
+bool status = 0;
+bool wiped;
+UINT32 iScoreScreenTime = 0;
+int iTeamsWiped = 0; // counts how many teams have wiped
+bool is_game_over = false;
+bool isOwnTeamWipedOut = false;
+int iDisconnectedScreen = 0;
+int bClosingChatBoxToStartGame = false;
+UINT32 iCCStartGameTime = 0;
+bool is_game_started = false;
void overide_callback( UINT8 ubResult );
void kick_callback( UINT8 ubResult );
@@ -734,21 +641,6 @@ void disconnected_callback(UINT8 ubResult);
// OJW - 20081222
void send_gameover( void );
void StartScoreScreen(); // this screen will send us to the multiplayer score screen
-bool is_game_over = false;
-UINT32 iScoreScreenTime = 0;
-int iTeamsWiped = 0; // counts how many teams have wiped
-
-bool isOwnTeamWipedOut = false;
-
-//OJW - 20090210
-int iDisconnectedScreen = 0;
-
-//OJW - 20090302
-int bClosingChatBoxToStartGame = false;
-UINT32 iCCStartGameTime = 0;
-
-// OJW - 20090317
-bool is_game_started = false;
// OJW - 20090403
extern BOOLEAN gfMPSScoreScreenCanContinue; // can the score screen continue
@@ -760,7 +652,6 @@ SystemAddress serverAddr;
settings_struct gMPServerSettings; // store a copy of our settings after we receive them
CHAR16 gszDisconnectReason[255]; // the reason we were disconnected from the server
-
// OJW - added 20081130
// - add retry timer and notification
void NetworkAutoStart()
@@ -804,6 +695,20 @@ void NetworkAutoStart()
}
}
+void InvalidClientSettingsOkBoxCallback( UINT8 bExitValue )
+{
+ // yes, load the game
+ if( bExitValue == MSG_BOX_RETURN_OK )
+ {
+ // gracefully disconnect to the main menu
+ client_disconnect();
+ guiPendingScreen = MP_JOIN_SCREEN;
+ }
+
+ return;
+}
+
+
// OJW - this is just a fudge for now and needs to be improved later
bool are_clients_downloading()
{
@@ -822,7 +727,7 @@ bool are_clients_downloading()
void HireRandomMercs()
{
MERC_HIRE_STRUCT HireMercStruct;
- for (int i=0; i < MAX_MERCS; i++)
+ for (int i=0; i < cMaxMercs; i++)
{
memset(&HireMercStruct, 0, sizeof(MERC_HIRE_STRUCT));
@@ -857,7 +762,6 @@ void send_path ( SOLDIERTYPE *pSoldier, INT32 sDestGridNo, UINT16 usMovementAni
{
//ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"Sending new path" );
-
EV_S_SENDPATHTONETWORK SNetPath;
if(pSoldier->ubID < 20)
@@ -866,67 +770,49 @@ void send_path ( SOLDIERTYPE *pSoldier, INT32 sDestGridNo, UINT16 usMovementAni
SNetPath.usSoldierID = pSoldier->ubID;
SNetPath.sAtGridNo=pSoldier->sGridNo;
-
-
- SNetPath.ubNewState=usMovementAnim;
- //if(fFromUI==255)SNetPath.ubNewState=255;
-
- SNetPath.usCurrentPathIndex=pSoldier->pathing.usPathIndex;
- memcpy(SNetPath.usPathData, pSoldier->pathing.usPathingData, sizeof(UINT16)*30);
- SNetPath.usPathDataSize=pSoldier->pathing.usPathDataSize;
- SNetPath.sDestGridNo=sDestGridNo;
+
+ SNetPath.ubNewState=usMovementAnim;
+ SNetPath.usCurrentPathIndex=pSoldier->pathing.usPathIndex;
+ memcpy(SNetPath.usPathData, pSoldier->pathing.usPathingData, sizeof(UINT16)*30);
+ SNetPath.usPathDataSize=pSoldier->pathing.usPathDataSize;
+ SNetPath.sDestGridNo=sDestGridNo;
-//this stops soldier from advancing further than one square,and requests "clearance" for another after that... :)
- //if(pSoldier->flags.fIsSoldierDelayed==FALSE)
- //{
- // pSoldier->flags.fIsSoldierDelayed=TRUE;
- // request_ovh(pSoldier->ubID);
- //}
-
-
client->RPC("sendPATH",(const char*)&SNetPath, (int)sizeof(EV_S_SENDPATHTONETWORK)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
-
}
void recievePATH(RPCParameters *rpcParameters)
{
+ //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"Recieving new path," );
+
+ EV_S_SENDPATHTONETWORK* SNetPath = (EV_S_SENDPATHTONETWORK*)rpcParameters->input;
- //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"Recieving new path," );
-
- EV_S_SENDPATHTONETWORK* SNetPath = (EV_S_SENDPATHTONETWORK*)rpcParameters->input;
+ SOLDIERTYPE *pSoldier = MercPtrs[ SNetPath->usSoldierID ];
- SOLDIERTYPE *pSoldier = MercPtrs[ SNetPath->usSoldierID ];
+
+ memcpy(pSoldier->pathing.usPathingData, SNetPath->usPathData,sizeof(UINT16)*30);
+
+ pSoldier->pathing.sDestination = SNetPath->sDestGridNo;
+ pSoldier->pathing.sFinalDestination = SNetPath->sDestGridNo;
+ pSoldier->pathing.usPathIndex=SNetPath->usCurrentPathIndex;
+ pSoldier->pathing.usPathDataSize=SNetPath->usPathDataSize;
+
+ SendGetNewSoldierPathEvent( pSoldier, SNetPath->sDestGridNo, SNetPath->ubNewState );
+
+ INT16 sCellX, sCellY;
-
- memcpy(pSoldier->pathing.usPathingData, SNetPath->usPathData,sizeof(UINT16)*30);
-
- pSoldier->pathing.sDestination = SNetPath->sDestGridNo;
- pSoldier->pathing.sFinalDestination = SNetPath->sDestGridNo;
- pSoldier->pathing.usPathIndex=SNetPath->usCurrentPathIndex;
- pSoldier->pathing.usPathDataSize=SNetPath->usPathDataSize;
-
- SendGetNewSoldierPathEvent( pSoldier, SNetPath->sDestGridNo, SNetPath->ubNewState );
-
- INT16 sCellX, sCellY;
-
-
- sCellX = CenterX( SNetPath->sAtGridNo );
- sCellY = CenterY( SNetPath->sAtGridNo );
-
- //if ( !( ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_MOVING | ANIM_SPECIALMOVE ) ) && pSoldier->fNoAPToFinishMove ) && !pSoldier->fPauseAllAnimation )
- if (( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_MOVING | ANIM_SPECIALMOVE ) ) && !(pSoldier->flags.fNoAPToFinishMove ) )
- {
- }
- else
- {
- pSoldier->EVENT_InternalSetSoldierPosition( sCellX, sCellY ,FALSE, FALSE, FALSE );
-
- }
+ sCellX = CenterX( SNetPath->sAtGridNo );
+ sCellY = CenterY( SNetPath->sAtGridNo );
- if(pSoldier)pSoldier->EVENT_InitNewSoldierAnim( SNetPath->ubNewState, 0, FALSE );
+ if (( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_MOVING | ANIM_SPECIALMOVE ) ) && !(pSoldier->flags.fNoAPToFinishMove ) )
+ {
+ }
+ else
+ {
+ pSoldier->EVENT_InternalSetSoldierPosition( sCellX, sCellY ,FALSE, FALSE, FALSE );
+ }
-
+ if(pSoldier)pSoldier->EVENT_InitNewSoldierAnim( SNetPath->ubNewState, 0, FALSE );
}
@@ -950,6 +836,7 @@ void send_stance ( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance )
SChangeStance.sXPos = pSoldier->sX;
SChangeStance.sYPos = pSoldier->sY;
SChangeStance.uiUniqueId = pSoldier -> uiUniqueSoldierIdValue;
+
//ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"change stance: %d",ubDesiredStance );
client->RPC("sendSTANCE",(const char*)&SChangeStance, (int)sizeof(EV_S_CHANGESTANCE)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
@@ -1041,81 +928,71 @@ void send_fire( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
}
void recieveFIRE(RPCParameters *rpcParameters)
-{
-
- EV_S_BEGINFIREWEAPON* SBeginFireWeapon = (EV_S_BEGINFIREWEAPON*)rpcParameters->input;
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SendBeginFireWeaponEvent" );
+{
+ EV_S_BEGINFIREWEAPON* SBeginFireWeapon = (EV_S_BEGINFIREWEAPON*)rpcParameters->input;
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"SendBeginFireWeaponEvent" );
- SOLDIERTYPE *pSoldier = MercPtrs[ SBeginFireWeapon->usSoldierID ];
+ SOLDIERTYPE *pSoldier = MercPtrs[ SBeginFireWeapon->usSoldierID ];
- pSoldier->sTargetGridNo = SBeginFireWeapon->sTargetGridNo;
- pSoldier->bTargetLevel = SBeginFireWeapon->bTargetLevel;
- pSoldier->bTargetCubeLevel = SBeginFireWeapon->bTargetCubeLevel;
- pSoldier->usAttackingWeapon = SBeginFireWeapon->uiUniqueId; //cheap hack to pass wep id.
+ pSoldier->sTargetGridNo = SBeginFireWeapon->sTargetGridNo;
+ pSoldier->bTargetLevel = SBeginFireWeapon->bTargetLevel;
+ pSoldier->bTargetCubeLevel = SBeginFireWeapon->bTargetCubeLevel;
+ pSoldier->usAttackingWeapon = SBeginFireWeapon->uiUniqueId; //cheap hack to pass wep id.
-
- SendBeginFireWeaponEvent( pSoldier, SBeginFireWeapon->sTargetGridNo );
+ SendBeginFireWeaponEvent( pSoldier, SBeginFireWeapon->sTargetGridNo );
}
void send_hit( EV_S_WEAPONHIT *SWeaponHit )
{
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"sendHIT" );
+ //EV_S_WEAPONHIT* pWeaponHit = (EV_S_WEAPONHIT*)pEventData;
+ //SOLDIERTYPE *pSoldier = MercPtrs[ usSoldierID ];
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"sendHIT" );
- //EV_S_WEAPONHIT* pWeaponHit = (EV_S_WEAPONHIT*)pEventData;
- //SOLDIERTYPE *pSoldier = MercPtrs[ usSoldierID ];
-
- EV_S_WEAPONHIT weaphit_struct;
-
- memcpy( &weaphit_struct , SWeaponHit, sizeof( EV_S_WEAPONHIT ));
-
- UINT16 usSoldierID=weaphit_struct.usSoldierID;
-
- if(SWeaponHit->usSoldierID < 20)weaphit_struct.usSoldierID = weaphit_struct.usSoldierID+ubID_prefix;
- if(SWeaponHit->ubAttackerID < 20)weaphit_struct.ubAttackerID = weaphit_struct.ubAttackerID+ubID_prefix;
+ EV_S_WEAPONHIT weaphit_struct;
+ memcpy( &weaphit_struct , SWeaponHit, sizeof( EV_S_WEAPONHIT ));
+
+ UINT16 usSoldierID=weaphit_struct.usSoldierID;
- client->RPC("sendHIT",(const char*)&weaphit_struct, (int)sizeof(EV_S_WEAPONHIT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
+ if(SWeaponHit->usSoldierID < 20)weaphit_struct.usSoldierID = weaphit_struct.usSoldierID+ubID_prefix;
+ if(SWeaponHit->ubAttackerID < 20)weaphit_struct.ubAttackerID = weaphit_struct.ubAttackerID+ubID_prefix;
+
+ client->RPC("sendHIT",(const char*)&weaphit_struct, (int)sizeof(EV_S_WEAPONHIT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieveHIT(RPCParameters *rpcParameters)
{
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"recieveHIT" );
- EV_S_WEAPONHIT* SWeaponHit = (EV_S_WEAPONHIT*)rpcParameters->input;
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"recieveHIT" );
-
- SOLDIERTYPE *pSoldier = MercPtrs[ SWeaponHit->usSoldierID ];
- UINT16 usSoldierID;
- UINT8 ubAttackerID;
-
- if((SWeaponHit->usSoldierID >= ubID_prefix) && (SWeaponHit->usSoldierID < (ubID_prefix+6))) // within our netbTeam range...
- usSoldierID = (SWeaponHit->usSoldierID - ubID_prefix);
- else
- usSoldierID = SWeaponHit->usSoldierID;
-
- if((SWeaponHit->ubAttackerID >= ubID_prefix) && (SWeaponHit->ubAttackerID < (ubID_prefix+6)))
- ubAttackerID = (SWeaponHit->ubAttackerID - ubID_prefix);
- else
- ubAttackerID = SWeaponHit->ubAttackerID;
+ EV_S_WEAPONHIT* SWeaponHit = (EV_S_WEAPONHIT*)rpcParameters->input;
+ SOLDIERTYPE *pSoldier = MercPtrs[ SWeaponHit->usSoldierID ];
+ UINT16 usSoldierID;
+ UINT8 ubAttackerID;
-
- //AddGameEvent( S_WEAPONHIT, 0, &SWeaponHit );
- WeaponHit( usSoldierID, SWeaponHit->usWeaponIndex, SWeaponHit->sDamage, SWeaponHit->sBreathLoss, SWeaponHit->usDirection, SWeaponHit->sXPos, SWeaponHit->sYPos, SWeaponHit->sZPos, SWeaponHit->sRange, ubAttackerID, SWeaponHit->fHit, SWeaponHit->ubSpecial, SWeaponHit->ubLocation );
+ if((SWeaponHit->usSoldierID >= ubID_prefix) && (SWeaponHit->usSoldierID < (ubID_prefix+6))) // within our netbTeam range...
+ usSoldierID = (SWeaponHit->usSoldierID - ubID_prefix);
+ else
+ usSoldierID = SWeaponHit->usSoldierID;
- if(SWeaponHit->fStopped)
- {
- INT8 bTeam=pSoldier->bTeam;
- INT32 iBullet = bTable[bTeam][SWeaponHit->iBullet].local_id;
-
- RemoveBullet(iBullet);
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"removed bullet" );
+ if((SWeaponHit->ubAttackerID >= ubID_prefix) && (SWeaponHit->ubAttackerID < (ubID_prefix+6)))
+ ubAttackerID = (SWeaponHit->ubAttackerID - ubID_prefix);
+ else
+ ubAttackerID = SWeaponHit->ubAttackerID;
-
- }
-
+ WeaponHit( usSoldierID, SWeaponHit->usWeaponIndex, SWeaponHit->sDamage, SWeaponHit->sBreathLoss, SWeaponHit->usDirection, SWeaponHit->sXPos, SWeaponHit->sYPos, SWeaponHit->sZPos, SWeaponHit->sRange, ubAttackerID, SWeaponHit->fHit, SWeaponHit->ubSpecial, SWeaponHit->ubLocation );
+
+ if(SWeaponHit->fStopped)
+ {
+ INT8 bTeam=pSoldier->bTeam;
+ INT32 iBullet = bTable[bTeam][SWeaponHit->iBullet].local_id;
+
+ RemoveBullet(iBullet);
+
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"removed bullet" );
+ }
}
@@ -1130,78 +1007,50 @@ void send_dismiss(UINT8 ubCurrentSoldierID)
void send_hire( UINT8 iNewIndex, UINT8 ubCurrentSoldier, INT16 iTotalContractLength, BOOLEAN fCopyProfileItemsOver)
{
-
+ send_hire_struct sHireMerc;
+
+ sHireMerc.ubProfileID=ubCurrentSoldier;
+ sHireMerc.team=TEAM;
+ sHireMerc.fCopyProfileItemsOver=fCopyProfileItemsOver;
+ sHireMerc.bTeam=netbTeam;
+
+ SOLDIERTYPE *pSoldier = MercPtrs[ iNewIndex ];
+
+ UINT8 sectorEdge = cStartingSectorEdge;
+
+ // WANNE - MP: Center
+ if (sectorEdge == MP_EDGE_CENTER)
+ sectorEdge = INSERTION_CODE_CENTER;
+
+ pSoldier->ubStrategicInsertionCode = sectorEdge;
+
+ if(ubCurrentSoldier==64)//slay
+ {
+ pSoldier->ubBodyType = REGMALE;
+ gMercProfiles[ pSoldier->ubProfile ].ubBodyType = REGMALE;
+ }
+
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[44], pSoldier->name);
+
+ AddCharacterToAnySquad( pSoldier );
+
+ //add recruited flag
+ gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
+
+ OBJECTTYPE Object;
+ int cnt;
+ for (cnt=0; cnt<20;cnt++)
+ {
+ int item=kit[cnt];
+
+ if(item != 0)
{
- send_hire_struct sHireMerc;
-
- sHireMerc.ubProfileID=ubCurrentSoldier;
- //sHireMerc.iTotalContractLength=iTotalContractLength;
- sHireMerc.team=TEAM;
- sHireMerc.fCopyProfileItemsOver=fCopyProfileItemsOver;
-
-
- sHireMerc.bTeam=netbTeam;
-
- SOLDIERTYPE *pSoldier = MercPtrs[ iNewIndex ];
-
- UINT8 sectorEdge = atoi(SECT_EDGE);
-
- // WANNE - MP: Center
- if (sectorEdge == MP_EDGE_CENTER)
- sectorEdge = INSERTION_CODE_CENTER;
-
- pSoldier->ubStrategicInsertionCode = sectorEdge;
-
- if(ubCurrentSoldier==64)//slay
- {
- pSoldier->ubBodyType = REGMALE;
- //pSoldier->EVENT_InitNewSoldierAnim( STANDING, 0 , TRUE );
- gMercProfiles[ pSoldier->ubProfile ].ubBodyType = REGMALE;
-
- }
-
-
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[44], pSoldier->name);
-
-
- AddCharacterToAnySquad( pSoldier );
- //AddSoldierToSector( pSoldier->ubID ); //add g\hired merc to sector so can access sector inv.
-
- //add recruited flag
- gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
-
- OBJECTTYPE Object;
- int cnt;
- for (cnt=0; cnt<20;cnt++)
- {
- int item=kit[cnt];
-
- if(item != 0)
- {
- CreateItem( item, 100, &Object );
- AutoPlaceObject( pSoldier, &Object, TRUE );
- }
- }
-
-
-
-
- //if (pSoldier->ubID==0)
- //{
- // ///create crate apon first hire
- ////crate_usMapPos = MAPROWCOLTOPOS( crate_sGridY, crate_sGridX );
- //crate_usMapPos = ChooseMapEdgepoint(pSoldier->ubStrategicInsertionCode);
-
- ////crate_usMapPos = ChooseMapEdgepoint(atoi(SECT_EDGE));
- //AddStructToUnLoadedMapTempFile( crate_usMapPos, SECONDOSTRUCT3, gsMercArriveSectorX, gsMercArriveSectorY, 0 );
- //}
-
-
-
-
-
- client->RPC("sendHIRE",(const char*)&sHireMerc, (int)sizeof(send_hire_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ CreateItem( item, 100, &Object );
+ AutoPlaceObject( pSoldier, &Object, TRUE );
}
+ }
+
+ client->RPC("sendHIRE",(const char*)&sHireMerc, (int)sizeof(send_hire_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieveDISMISS(RPCParameters *rpcParameters)
@@ -1216,26 +1065,15 @@ void recieveDISMISS(RPCParameters *rpcParameters)
void recieveHIRE(RPCParameters *rpcParameters)
{
-
send_hire_struct* sHireMerc = (send_hire_struct*)rpcParameters->input;
-
-
SOLDIERTYPE *pSoldier;
UINT8 iNewIndex;
UINT8 ubCount=0;
-
SOLDIERCREATE_STRUCT MercCreateStruct;
BOOLEAN fReturn = FALSE;
-
-
- // WANNE - MP: Fix by Realist (avoid CTDs)
- //memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) );
- //MercCreateStruct = SOLDIERCREATE_STRUCT();
-
-
MercCreateStruct.ubProfile = sHireMerc->ubProfileID;
MercCreateStruct.fPlayerMerc = 0;
MercCreateStruct.sSectorX = gsMercArriveSectorX;
@@ -1243,47 +1081,43 @@ void recieveHIRE(RPCParameters *rpcParameters)
MercCreateStruct.bSectorZ = 0;
MercCreateStruct.bTeam = sHireMerc->bTeam;
MercCreateStruct.fCopyProfileItemsOver = sHireMerc->fCopyProfileItemsOver;
-
-
TacticalCreateSoldier( &MercCreateStruct, &iNewIndex ) ;
pSoldier = &Menptr[iNewIndex];
pSoldier->flags.uiStatusFlags |= SOLDIER_PC;
gMercProfiles[ pSoldier->ubProfile ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
- if(!SAME_MERC)gMercProfiles[ pSoldier->ubProfile ].bMercStatus = MERC_WORKING_ELSEWHERE;
+
+ if(!cSameMercAllowed)
+ gMercProfiles[ pSoldier->ubProfile ].bMercStatus = MERC_WORKING_ELSEWHERE;
+
pSoldier->bSide=0; //default coop only
gTacticalStatus.Team[MercCreateStruct.bTeam ].bSide=0;
- if(MercCreateStruct.ubProfile==64)//slay
- {
- pSoldier->ubBodyType = REGMALE;
- //pSoldier->EVENT_InitNewSoldierAnim( STANDING, 0 , TRUE );
- gMercProfiles[ pSoldier->ubProfile ].ubBodyType = REGMALE;
-
- }
+ if(MercCreateStruct.ubProfile==64)//slay
+ {
+ pSoldier->ubBodyType = REGMALE;
+ gMercProfiles[ pSoldier->ubProfile ].ubBodyType = REGMALE;
+ }
- if(PLAYER_BSIDE==0)//all vs all only
+ if(cGameType==MP_TYPE_DEATHMATCH)//all vs all only
{
pSoldier->bSide=1;
gTacticalStatus.Team[MercCreateStruct.bTeam ].bSide=1;
}
- if(PLAYER_BSIDE==1) //allow teams
+ if(cGameType==MP_TYPE_TEAMDEATMATCH) //allow teams
{
- if(sHireMerc->team != TEAM)
- {
- pSoldier->bSide=1;
- gTacticalStatus.Team[MercCreateStruct.bTeam ].bSide=1;
- }
-
+ if(sHireMerc->team != TEAM)
+ {
+ pSoldier->bSide=1;
+ gTacticalStatus.Team[MercCreateStruct.bTeam ].bSide=1;
+ }
}
-
AddSoldierToSector( iNewIndex );
-
- if(REPORT_NAME==1)
+ if(cReportHiredMerc == 1)
{
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[5],MercCreateStruct.bTeam-5,client_names[MercCreateStruct.bTeam-6],pSoldier->name );
}
@@ -1291,120 +1125,85 @@ void recieveHIRE(RPCParameters *rpcParameters)
{
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[6],MercCreateStruct.bTeam-5,client_names[MercCreateStruct.bTeam-6] );
}
-
-
}
void send_gui_pos(SOLDIERTYPE *pSoldier, FLOAT dNewXPos, FLOAT dNewYPos)
{
-
- {
-
- gui_pos gnPOS;
+ gui_pos gnPOS;
-
+ gnPOS.usSoldierID = (pSoldier->ubID)+ubID_prefix;
+ gnPOS.dNewXPos = dNewXPos;
+ gnPOS.dNewYPos = dNewYPos;
- gnPOS.usSoldierID = (pSoldier->ubID)+ubID_prefix;
-
- gnPOS.dNewXPos = dNewXPos;
- gnPOS.dNewYPos = dNewYPos;
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"guiPOS: %f , %f", dNewXPos,dNewYPos);
-
-
- client->RPC("sendguiPOS",(const char*)&gnPOS, (int)sizeof(gui_pos)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- }
-
+ client->RPC("sendguiPOS",(const char*)&gnPOS, (int)sizeof(gui_pos)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
+
void recieveguiPOS(RPCParameters *rpcParameters)
{
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"recieveguiPOS" );
- gui_pos* gnPOS = (gui_pos*)rpcParameters->input;
+ gui_pos* gnPOS = (gui_pos*)rpcParameters->input;
- SOLDIERTYPE *pSoldier = MercPtrs[ gnPOS->usSoldierID ];
+ SOLDIERTYPE *pSoldier = MercPtrs[ gnPOS->usSoldierID ];
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"guiPOS: %f , %f", gnPOS->dNewXPos,gnPOS->dNewYPos);
-
- INT32 sNewGridNo;
+ INT32 sNewGridNo;
- sNewGridNo = GETWORLDINDEXFROMWORLDCOORDS(gnPOS->dNewXPos, gnPOS->dNewYPos );
- pSoldier->usStrategicInsertionData=sNewGridNo;
- pSoldier->ubStrategicInsertionCode=INSERTION_CODE_GRIDNO;
- pSoldier->sInsertionGridNo = pSoldier->usStrategicInsertionData;
+ sNewGridNo = GETWORLDINDEXFROMWORLDCOORDS(gnPOS->dNewXPos, gnPOS->dNewYPos );
+ pSoldier->usStrategicInsertionData=sNewGridNo;
+ pSoldier->ubStrategicInsertionCode=INSERTION_CODE_GRIDNO;
+ pSoldier->sInsertionGridNo = pSoldier->usStrategicInsertionData;
-
- pSoldier->EVENT_SetSoldierPosition( gnPOS->dNewXPos, gnPOS->dNewYPos );
-
+ pSoldier->EVENT_SetSoldierPosition( gnPOS->dNewXPos, gnPOS->dNewYPos );
}
void send_gui_dir(SOLDIERTYPE *pSoldier, UINT16 usNewDirection)
-{
-
- {
-
- gui_dir gnDIR;
+{
+ gui_dir gnDIR;
-
-
- gnDIR.usSoldierID = (pSoldier->ubID)+ubID_prefix;
- gnDIR.usNewDirection = usNewDirection;
-
-
-
- client->RPC("sendguiDIR",(const char*)&gnDIR, (int)sizeof(gui_dir)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- }
+ gnDIR.usSoldierID = (pSoldier->ubID)+ubID_prefix;
+ gnDIR.usNewDirection = usNewDirection;
+ client->RPC("sendguiDIR",(const char*)&gnDIR, (int)sizeof(gui_dir)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieveguiDIR(RPCParameters *rpcParameters)
{
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"recieveguiDIR" );
- gui_dir* gnDIR = (gui_dir*)rpcParameters->input;
+ gui_dir* gnDIR = (gui_dir*)rpcParameters->input;
- SOLDIERTYPE *pSoldier = MercPtrs[ gnDIR->usSoldierID ];
-
- pSoldier->EVENT_SetSoldierDirection( gnDIR->usNewDirection );
- //pSoldier->ubInsertionDirection = pSoldier->bDirection;
+ SOLDIERTYPE *pSoldier = MercPtrs[ gnDIR->usSoldierID ];
+
+ pSoldier->EVENT_SetSoldierDirection( gnDIR->usNewDirection );
}
-
-
void send_EndTurn( UINT8 ubNextTeam )
{
-
- {
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"sendEndTurn" );
-
- if(ubNextTeam==0)
- {
- // translate next team id for clients
- ubNextTeam=netbTeam;
- }
-
+ if(ubNextTeam==0)
+ {
+ // translate next team id for clients
+ ubNextTeam=netbTeam;
+ }
- turn_struct tStruct;
- if(is_server)Sawarded=false;
-
- tStruct.tsnetbTeam = netbTeam;
- tStruct.tsubNextTeam = ubNextTeam;
-
-
- client->RPC("sendEndTurn",(const char*)&tStruct, (int)sizeof(turn_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- }
+ turn_struct tStruct;
+ if(is_server)
+ Sawarded=false;
+ tStruct.tsnetbTeam = netbTeam;
+ tStruct.tsubNextTeam = ubNextTeam;
+
+ client->RPC("sendEndTurn",(const char*)&tStruct, (int)sizeof(turn_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieveEndTurn(RPCParameters *rpcParameters)
{
turn_struct* tStruct = (turn_struct*)rpcParameters->input;
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"recieveEndTurn" );
UINT8 sender_bTeam;
UINT8 ubTeam;
sender_bTeam=tStruct->tsnetbTeam;
ubTeam=tStruct->tsubNextTeam;
- if(is_server)Sawarded=false;
+
+ if(is_server)
+ Sawarded=false;
// if the message was recieved from the server..
if(is_server || sender_bTeam==6)
@@ -1423,208 +1222,167 @@ void recieveEndTurn(RPCParameters *rpcParameters)
if(!is_server && is_client)
EndTurn( ubTeam );
+
requested=false ;//request for realtime made or not
BeginTeamTurn( ubTeam );
}
}
-
UINT8 numenemyLAN( UINT8 ubSectorX, UINT8 ubSectorY )
{
-
SOLDIERTYPE *pSoldier;
UINT8 cnt ; //first posible lan player
UINT8 ubNumEnemies = 0;
-
for ( cnt=120 ; cnt <= 155; cnt++ )
{
pSoldier = MercPtrs[cnt];
if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 )
{
-
if ( !pSoldier->aiData.bNeutral && (pSoldier->bSide != 0 ) )
{
ubNumEnemies++;
}
}
-
}
- return ubNumEnemies;
+ return ubNumEnemies;
}
void send_AI( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 *pubID )
{
- //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"send_AI" );
+ AI_STRUCT send_inv;
+ send_inv.standard_data = *pCreateStruct;
- //SOLDIERCREATE_STRUCT aaa = *pCreateStruct;
+ for(int x=0;x<55;x++)
+ {
+ send_inv.slot[x] = pCreateStruct->Inv[x];
+ }
- AI_STRUCT send_inv;
-
- send_inv.standard_data = *pCreateStruct;
-
-
-
- for(int x=0;x<55;x++)
- {
- send_inv.slot[x] = pCreateStruct->Inv[x];
- }
-
-
-
- client->RPC("sendAI",(const char*)&send_inv, (int)sizeof(AI_STRUCT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
+ client->RPC("sendAI",(const char*)&send_inv, (int)sizeof(AI_STRUCT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieveAI (RPCParameters *rpcParameters)
{
- UINT8 iNewIndex;
- SOLDIERTYPE *pSoldier;
+ UINT8 iNewIndex;
+ SOLDIERTYPE *pSoldier;
+ AI_STRUCT* send_inv = (AI_STRUCT*)rpcParameters->input;
+ SOLDIERCREATE_STRUCT new_standard_data; //as originally my soldiercreate_struct would get its INV mangled through the RPC, so i send it packaged with it, then create a new struct and add in the bits that are still ok from the original struct, along with the packaged INV components...
- AI_STRUCT* send_inv = (AI_STRUCT*)rpcParameters->input;
+ new_standard_data.bAgility = send_inv->standard_data.bAgility;
+ new_standard_data.bAIMorale = send_inv->standard_data.bAIMorale;
+ new_standard_data.bAttitude = send_inv->standard_data.bAttitude;
+ new_standard_data.bBodyType = send_inv->standard_data.bBodyType;
+ new_standard_data.bDexterity = send_inv->standard_data.bDexterity;
+ new_standard_data.ubDirection = send_inv->standard_data.ubDirection;
+ new_standard_data.bExpLevel = send_inv->standard_data.bExpLevel;
+ new_standard_data.bExplosive = send_inv->standard_data.bExplosive;
+ new_standard_data.bLeadership = send_inv->standard_data.bLeadership;
+ new_standard_data.bLife = send_inv->standard_data.bLife;
+ new_standard_data.bLifeMax = send_inv->standard_data.bLifeMax;
+ new_standard_data.bMarksmanship = send_inv->standard_data.bMarksmanship;
+ new_standard_data.bMechanical = send_inv->standard_data.bMechanical;
+ new_standard_data.bMedical = send_inv->standard_data.bMedical;
+ new_standard_data.bMorale = send_inv->standard_data.bMorale;
+ new_standard_data.bOrders = send_inv->standard_data.bOrders;
+ new_standard_data.bPatrolCnt = send_inv->standard_data.bPatrolCnt;
+ new_standard_data.bSectorZ = send_inv->standard_data.bSectorZ;
+ new_standard_data.bStrength = send_inv->standard_data.bStrength;
+ new_standard_data.bTeam = send_inv->standard_data.bTeam;
+ new_standard_data.bUseGivenVehicleID = send_inv->standard_data.bUseGivenVehicleID;
+ new_standard_data.bWisdom = send_inv->standard_data.bWisdom;
+ new_standard_data.endOfPOD = send_inv->standard_data.endOfPOD;
+ new_standard_data.fCopyProfileItemsOver = send_inv->standard_data.fCopyProfileItemsOver;
+ new_standard_data.fHasKeys = send_inv->standard_data.fHasKeys;
+ new_standard_data.fKillSlotIfOwnerDies = send_inv->standard_data.fKillSlotIfOwnerDies;
+ new_standard_data.fOnRoof = send_inv->standard_data.fOnRoof;
+ new_standard_data.fPlayerMerc = send_inv->standard_data.fPlayerMerc;
+ new_standard_data.fPlayerPlan = send_inv->standard_data.fPlayerPlan;
+ new_standard_data.fStatic = send_inv->standard_data.fStatic;
+ new_standard_data.fUseExistingSoldier = send_inv->standard_data.fUseExistingSoldier;
+ new_standard_data.fUseGivenVehicle = send_inv->standard_data.fUseGivenVehicle;
+ new_standard_data.fVisible = send_inv->standard_data.fVisible;
+ memcpy( new_standard_data.HeadPal , send_inv->standard_data.HeadPal, sizeof( PaletteRepID ));
+ memcpy( new_standard_data.MiscPal , send_inv->standard_data.MiscPal, sizeof( PaletteRepID ));
+ memcpy( new_standard_data.name , send_inv->standard_data.name, sizeof( CHAR16 ) * 10 );
+ memcpy( new_standard_data.PantsPal , send_inv->standard_data.PantsPal, sizeof( PaletteRepID ));
+ new_standard_data.pExistingSoldier = send_inv->standard_data.pExistingSoldier;
+ new_standard_data.sInsertionGridNo = send_inv->standard_data.sInsertionGridNo;
+ memcpy( new_standard_data.SkinPal , send_inv->standard_data.SkinPal, sizeof( PaletteRepID ));
+ memcpy( new_standard_data.sPatrolGrid, send_inv->standard_data.sPatrolGrid, sizeof( INT32 ) * MAXPATROLGRIDS );//dnl ch27 230909
+ new_standard_data.sSectorX = send_inv->standard_data.sSectorX;
+ new_standard_data.sSectorY = send_inv->standard_data.sSectorY;
+ new_standard_data.ubCivilianGroup = send_inv->standard_data.ubCivilianGroup;
+ new_standard_data.ubProfile = send_inv->standard_data.ubProfile;
+ new_standard_data.ubScheduleID = send_inv->standard_data.ubScheduleID;
+ new_standard_data.ubSoldierClass = send_inv->standard_data.ubSoldierClass;
+ memcpy( new_standard_data.VestPal , send_inv->standard_data.VestPal, sizeof( PaletteRepID ));
- SOLDIERCREATE_STRUCT new_standard_data; //as originally my soldiercreate_struct would get its INV mangled through the RPC, so i send it packaged with it, then create a new struct and add in the bits that are still ok from the original struct, along with the packaged INV components...
-
+ for(int x=0;x<55;x++)
+ {
+ if(send_inv->slot[x].usItem != 0)
+ CreateItems( send_inv->slot[x].usItem, 100, send_inv->slot[x].ubNumberOfObjects, &new_standard_data.Inv[x] );
+ }
- new_standard_data.bAgility = send_inv->standard_data.bAgility;
- new_standard_data.bAIMorale = send_inv->standard_data.bAIMorale;
- new_standard_data.bAttitude = send_inv->standard_data.bAttitude;
- new_standard_data.bBodyType = send_inv->standard_data.bBodyType;
- new_standard_data.bDexterity = send_inv->standard_data.bDexterity;
- new_standard_data.ubDirection = send_inv->standard_data.ubDirection;
- new_standard_data.bExpLevel = send_inv->standard_data.bExpLevel;
- new_standard_data.bExplosive = send_inv->standard_data.bExplosive;
- new_standard_data.bLeadership = send_inv->standard_data.bLeadership;
- new_standard_data.bLife = send_inv->standard_data.bLife;
- new_standard_data.bLifeMax = send_inv->standard_data.bLifeMax;
- new_standard_data.bMarksmanship = send_inv->standard_data.bMarksmanship;
- new_standard_data.bMechanical = send_inv->standard_data.bMechanical;
- new_standard_data.bMedical = send_inv->standard_data.bMedical;
- new_standard_data.bMorale = send_inv->standard_data.bMorale;
- new_standard_data.bOrders = send_inv->standard_data.bOrders;
-
- // WANNE - MP: I had to remove this line of code, because PADDINGSLOTS in the structure
- // breaks the editor and leads to crashed of modifed maps!
- //memcpy( new_standard_data.PADDINGSLOTS, send_inv->standard_data.PADDINGSLOTS, sizeof( INT8 ) * 14 );
-
- new_standard_data.bPatrolCnt = send_inv->standard_data.bPatrolCnt;
- new_standard_data.bSectorZ = send_inv->standard_data.bSectorZ;
- new_standard_data.bStrength = send_inv->standard_data.bStrength;
- new_standard_data.bTeam = send_inv->standard_data.bTeam;
- new_standard_data.bUseGivenVehicleID = send_inv->standard_data.bUseGivenVehicleID;
- new_standard_data.bWisdom = send_inv->standard_data.bWisdom;
- //new_standard_data.ef1 = send_inv->standard_data.ef1;
- //new_standard_data.ef2 = send_inv->standard_data.ef2;
- new_standard_data.endOfPOD = send_inv->standard_data.endOfPOD;
- new_standard_data.fCopyProfileItemsOver = send_inv->standard_data.fCopyProfileItemsOver;
- new_standard_data.fHasKeys = send_inv->standard_data.fHasKeys;
- new_standard_data.fKillSlotIfOwnerDies = send_inv->standard_data.fKillSlotIfOwnerDies;
- new_standard_data.fOnRoof = send_inv->standard_data.fOnRoof;
- new_standard_data.fPlayerMerc = send_inv->standard_data.fPlayerMerc;
- new_standard_data.fPlayerPlan = send_inv->standard_data.fPlayerPlan;
- new_standard_data.fStatic = send_inv->standard_data.fStatic;
- new_standard_data.fUseExistingSoldier = send_inv->standard_data.fUseExistingSoldier;
- new_standard_data.fUseGivenVehicle = send_inv->standard_data.fUseGivenVehicle;
- new_standard_data.fVisible = send_inv->standard_data.fVisible;
- memcpy( new_standard_data.HeadPal , send_inv->standard_data.HeadPal, sizeof( PaletteRepID ));
- memcpy( new_standard_data.MiscPal , send_inv->standard_data.MiscPal, sizeof( PaletteRepID ));
- memcpy( new_standard_data.name , send_inv->standard_data.name, sizeof( CHAR16 ) * 10 );
- memcpy( new_standard_data.PantsPal , send_inv->standard_data.PantsPal, sizeof( PaletteRepID ));
- new_standard_data.pExistingSoldier = send_inv->standard_data.pExistingSoldier;
- new_standard_data.sInsertionGridNo = send_inv->standard_data.sInsertionGridNo;
- memcpy( new_standard_data.SkinPal , send_inv->standard_data.SkinPal, sizeof( PaletteRepID ));
- memcpy( new_standard_data.sPatrolGrid, send_inv->standard_data.sPatrolGrid, sizeof( INT32 ) * MAXPATROLGRIDS );//dnl ch27 230909
- new_standard_data.sSectorX = send_inv->standard_data.sSectorX;
- new_standard_data.sSectorY = send_inv->standard_data.sSectorY;
- new_standard_data.ubCivilianGroup = send_inv->standard_data.ubCivilianGroup;
- new_standard_data.ubProfile = send_inv->standard_data.ubProfile;
- new_standard_data.ubScheduleID = send_inv->standard_data.ubScheduleID;
- new_standard_data.ubSoldierClass = send_inv->standard_data.ubSoldierClass;
- memcpy( new_standard_data.VestPal , send_inv->standard_data.VestPal, sizeof( PaletteRepID ));
-
+ new_standard_data.fPlayerPlan=1;
- for(int x=0;x<55;x++)
- {
- //OBJECTTYPE Object;
- //new_standard_data.Inv[x]
+ TacticalCreateSoldier( &new_standard_data, &iNewIndex );
+ pSoldier = &Menptr[iNewIndex];
+ pSoldier->flags.uiStatusFlags |= SOLDIER_PC;
- //new_standard_data.Inv[x].fFlags = send_inv->slot[x].fFlags;
- if(send_inv->slot[x].usItem != 0)CreateItems( send_inv->slot[x].usItem, 100, send_inv->slot[x].ubNumberOfObjects, &new_standard_data.Inv[x] );
- //new_standard_data.Inv[x] = Object;
- }
-
-
- new_standard_data.fPlayerPlan=1;
-
-
- TacticalCreateSoldier( &new_standard_data, &iNewIndex );
- pSoldier = &Menptr[iNewIndex];
- pSoldier->flags.uiStatusFlags |= SOLDIER_PC;
-
- AddSoldierToSector( iNewIndex );
- //ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"recieveAI" );
-
-
-
+ AddSoldierToSector( iNewIndex );
}
void send_ready ( void )
{
- ready_struct info;
- info.client_num = CLIENT_NUM;
-
- if(readystage==0)
- {
-
- info.ready_stage = 0;
- if(status==0)
- {
- info.status = 1;
- status=1;
- numready = numready+1;
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[7],numready,MAX_CLIENTS );
- // OJW - 20081204
- client_ready[info.client_num-1]=1;
- fDrawCharacterList = true; // set the character list to be redrawn
- }
- else
- {
- info.status = 0;
- status=0;
- numready = numready-1;
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[8],numready,MAX_CLIENTS );
- // OJW - 20081204
- client_ready[info.client_num-1]=0;
- fDrawCharacterList = true; // set the character list to be redrawn
- }
- }
-
-
-
- if(is_server && numready == MAX_CLIENTS) //all ready. and server tells all to load...
- {
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[9] );
+ ready_struct info;
+ info.client_num = CLIENT_NUM;
- goahead=1;
- readystage=1;
-
- info.ready_stage = 1;
- info.status = 1;
- }
-
-
-
- client->RPC("sendREADY",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
- if(is_server && numready == MAX_CLIENTS)
+ if(readystage==0)
+ {
+ info.ready_stage = 0;
+ if(status==0)
{
-
- status=0;//reset
- numready=0;
- start_battle();//server loads
+ info.status = 1;
+ status=1;
+ numready = numready+1;
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[7],numready,cMaxClients );
+ // OJW - 20081204
+ client_ready[info.client_num-1]=1;
+ fDrawCharacterList = true; // set the character list to be redrawn
}
+ else
+ {
+ info.status = 0;
+ status=0;
+ numready = numready-1;
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[8],numready,cMaxClients );
+ // OJW - 20081204
+ client_ready[info.client_num-1]=0;
+ fDrawCharacterList = true; // set the character list to be redrawn
+ }
+ }
+
+ if(is_server && numready == cMaxClients) //all ready. and server tells all to load...
+ {
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[9] );
+
+ goahead=1;
+ readystage=1;
+
+ info.ready_stage = 1;
+ info.status = 1;
+ }
+
+ client->RPC("sendREADY",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+
+ if(is_server && numready == cMaxClients)
+ {
+ status=0;//reset
+ numready=0;
+ start_battle();//server loads
+ }
}
void recieveREADY (RPCParameters *rpcParameters)
@@ -1634,7 +1392,7 @@ void recieveREADY (RPCParameters *rpcParameters)
if(info->ready_stage==1)//recived ok for go ahead from server for level load
{
numready++;
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[10], info->client_num,client_names[info->client_num-1],numready,MAX_CLIENTS );
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[10], info->client_num,client_names[info->client_num-1],numready,cMaxClients );
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[9] );
status=0;//reset
numready=0;
@@ -1645,35 +1403,34 @@ void recieveREADY (RPCParameters *rpcParameters)
{
if (info->status==1)
{
- numready = numready+1;
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[10], info->client_num,client_names[info->client_num-1],numready,MAX_CLIENTS );
- // OJW - 20081204
- client_ready[info->client_num-1]=1;
- fDrawCharacterList = true; // set the character list to be redrawn
+ numready = numready+1;
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[10], info->client_num,client_names[info->client_num-1],numready,cMaxClients );
+ // OJW - 20081204
+ client_ready[info->client_num-1]=1;
+ fDrawCharacterList = true; // set the character list to be redrawn
}
else
{
- numready = numready-1;
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[11], info->client_num,client_names[info->client_num-1],numready,MAX_CLIENTS );
- // OJW - 20081204
- client_ready[info->client_num-1]=0;
- fDrawCharacterList = true; // set the character list to be redrawn
+ numready = numready-1;
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[11], info->client_num,client_names[info->client_num-1],numready,cMaxClients );
+ // OJW - 20081204
+ client_ready[info->client_num-1]=0;
+ fDrawCharacterList = true; // set the character list to be redrawn
}
- if(is_server && numready == MAX_CLIENTS) //all ready. and server tells all to load...and loads himself
+ if(is_server && numready == cMaxClients) //all ready. and server tells all to load...and loads himself
{
goahead=1;
readystage=1;
send_ready();
start_battle();
-
}
}
else if(info->ready_stage==36)//server allows laptop access
{
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[36] );
allowlaptop=1;
- if (RANDOM_MERCS)
+ if (gRandomMercs)
HireRandomMercs();
// server is starting the game, adjust the games max players
@@ -1684,130 +1441,123 @@ void recieveREADY (RPCParameters *rpcParameters)
if (client_names[i] != NULL && strcmp(client_names[i],"") != 0)
iPlayersConnected++;
- MAX_CLIENTS = iPlayersConnected;
+ cMaxClients = iPlayersConnected;
}
-
}
void send_loaded (void)
{
- ready_struct info;
- info.client_num = CLIENT_NUM;
- info.ready_stage = 1;//done loading level
+ ready_struct info;
+ info.client_num = CLIENT_NUM;
+ info.ready_stage = 1;//done loading level
+ info.status=1;
+
+ numready++;
+ if(numready==cMaxClients && is_server)
+ {
+ lockui(1);//unlock ui
+ readystage=0;
+ numready=0;
+
+ info.ready_stage = 2;//done placing mercs
info.status=1;
+ }
- numready++;
- if(numready==MAX_CLIENTS && is_server)
- {
- lockui(1);//unlock ui
- readystage=0;
- numready=0;
-
- info.ready_stage = 2;//done placing mercs
- info.status=1;
-
- //client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- }
-
- client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
+ client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void send_donegui ( UINT8 ubResult )
{
- if(ubResult==1 && status==0)return;//avoid double remove callback response from final message box removal
- ready_struct info;
- info.client_num = CLIENT_NUM;
- if(ubResult==1)DialogRemoved(1);//cleanup msgbox after not ready
- if(status==0)//now ready
- {
- status=1;
- numready++;
+ if(ubResult==1 && status==0)
+ return;//avoid double remove callback response from final message box removal
+
+ ready_struct info;
+ info.client_num = CLIENT_NUM;
+
+ if(ubResult==1)
+ DialogRemoved(1);//cleanup msgbox after not ready
+
+ if(status==0)//now ready
+ {
+ status=1;
+ numready++;
info.ready_stage = 3;//done placing mercs
info.status=1;
-
- SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
- DoMessageBox( MSG_BOX_BASIC_STYLE, MPClientMessage[12], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, send_donegui, &CenterRect );
-
-
- if(numready==MAX_CLIENTS && is_server)//all done
- {
-
- numready=0;
- status=0;
- info.ready_stage = 4;//done placing mercs
- info.status=1;
- gMsgBox.bHandled = MSG_BOX_RETURN_OK;
- KillTacticalPlacementGUI(); //send and kill
- ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[13]);
- }
- }
- else if(status==1)//was ready
- {
- status=0;
- numready--;
- info.ready_stage = 3;//not done placing mercs
- info.status=0;
- }
-
+ SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
+ DoMessageBox( MSG_BOX_BASIC_STYLE, MPClientMessage[12], guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, send_donegui, &CenterRect );
- client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ if(numready==cMaxClients && is_server)//all done
+ {
+ numready=0;
+ status=0;
+ info.ready_stage = 4;//done placing mercs
+ info.status=1;
+ gMsgBox.bHandled = MSG_BOX_RETURN_OK;
+ KillTacticalPlacementGUI(); //send and kill
+ ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[13]);
+ }
+ }
+ else if(status==1)//was ready
+ {
+ status=0;
+ numready--;
+ info.ready_stage = 3;//not done placing mercs
+ info.status=0;
+ }
+
+ client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieveGUI (RPCParameters *rpcParameters)
{
-
-
ready_struct* info = (ready_struct*)rpcParameters->input;
if(info->ready_stage==1 && info->status==1)
{
numready++;
- if(numready==MAX_CLIENTS && is_server)
+ if(numready==cMaxClients && is_server)
{
lockui(1);//unlock ui
readystage=0;
numready=0;
- ready_struct info;
- info.client_num = CLIENT_NUM;
- info.ready_stage = 2;//done placing mercs
- info.status=1;
+ ready_struct info;
+ info.client_num = CLIENT_NUM;
+ info.ready_stage = 2;//done placing mercs
+ info.status=1;
- client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
-
}
+
if(info->ready_stage==2 && info->status ==1)
{
lockui(1);//unlock ui
readystage=0;
numready=0;
-
}
if(info->ready_stage==3 && info->status==1)//recieved client done placement
{
numready++;
- if(numready==MAX_CLIENTS && is_server)//all done
+ if(numready==cMaxClients && is_server)//all done
{
- numready=0;
+ numready=0;
- ready_struct info;
- info.client_num = CLIENT_NUM;
- info.ready_stage = 4;//all done placing mercs, kill all
- info.status=1;
- gMsgBox.bHandled = MSG_BOX_RETURN_OK;
- status=0;
- KillTacticalPlacementGUI();
- ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[13]);
+ ready_struct info;
+ info.client_num = CLIENT_NUM;
+ info.ready_stage = 4;//all done placing mercs, kill all
+ info.status=1;
+ gMsgBox.bHandled = MSG_BOX_RETURN_OK;
+ status=0;
+ KillTacticalPlacementGUI();
+ ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[13]);
- client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
}
-
if(info->ready_stage==3 && info->status==0)//recieved client retracted place ready...
{
numready--;
@@ -1821,36 +1571,34 @@ void recieveGUI (RPCParameters *rpcParameters)
numready=0;
status=0;
}
-
}
+
void allowlaptop_callback ( UINT8 ubResult )
{
-
if(ubResult==2)
{
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[36] );
- allowlaptop=1;
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[36] );
+ allowlaptop=1;
- ready_struct info;
- info.client_num = CLIENT_NUM;
- info.ready_stage=36;
- info.status=1;
+ ready_struct info;
+ info.client_num = CLIENT_NUM;
+ info.ready_stage=36;
+ info.status=1;
- if (RANDOM_MERCS)
- HireRandomMercs();
+ if (gRandomMercs)
+ HireRandomMercs();
- // server client is starting the game, adjust the games max players
- // this will allow the game to be started, rather than saying 2/4 players are connected
- // where there are only two players connected
- int iPlayersConnected = 0;
- for (int i=0; i< 4; i++)
- if (client_names[i] != NULL && strcmp(client_names[i],"") != 0)
- iPlayersConnected++;
+ // server client is starting the game, adjust the games max players
+ // this will allow the game to be started, rather than saying 2/4 players are connected
+ // where there are only two players connected
+ int iPlayersConnected = 0;
+ for (int i=0; i< 4; i++)
+ if (client_names[i] != NULL && strcmp(client_names[i],"") != 0)
+ iPlayersConnected++;
- MAX_CLIENTS = iPlayersConnected;
-
- client->RPC("sendREADY",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ cMaxClients = iPlayersConnected;
+ client->RPC("sendREADY",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
}
@@ -1861,13 +1609,11 @@ void StartBattleChatBoxClosedCallback(void)
is_game_started = true;
}
-
-
void start_battle ( void )
{
if(!is_client)
{
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[14] );
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[14] );
}
else if(!allowlaptop && is_server)
{
@@ -1881,7 +1627,6 @@ void start_battle ( void )
if (client_names[i] != NULL && strcmp(client_names[i],"") != 0)
iPlayersConnected++;
-
if (iPlayersConnected <= 1)
{
numPlayersValid = FALSE;
@@ -1897,7 +1642,7 @@ void start_battle ( void )
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[63] );
}
// WANNE - MP: If choosen team deathmatch, there must be at least 2 different teams
- else if (PLAYER_BSIDE == MP_TYPE_TEAMDEATMATCH)
+ else if (cGameType == MP_TYPE_TEAMDEATMATCH)
{
bool areTeamsValid = FALSE;
int clientTeam = client_teams[0];
@@ -1929,10 +1674,9 @@ void start_battle ( void )
}
else if(allowlaptop)
{
-
if ( NumberOfMercsOnPlayerTeam() ==0)
{
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[15] );
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[15] );
}
else if(goahead==1)
{
@@ -1963,9 +1707,9 @@ void start_battle ( void )
GROUP *pGroup;
pGroup = GetGroup( ubGroupID );
gpBattleGroup = pGroup;
- gubPBSectorX = gpBattleGroup->ubSectorX;
- gubPBSectorY = gpBattleGroup->ubSectorY;
- gubPBSectorZ = gpBattleGroup->ubSectorZ;
+ gubPBSectorX = gpBattleGroup->ubSectorX;
+ gubPBSectorY = gpBattleGroup->ubSectorY;
+ gubPBSectorZ = gpBattleGroup->ubSectorZ;
gfEnterTacticalPlacementGUI = 1;
// OJW - 20090205
@@ -2001,18 +1745,16 @@ void start_battle ( void )
SetCurrentWorldSector( gubPBSectorX, gubPBSectorY, gubPBSectorZ );
is_game_started = true;
}
-
}
else
{
- send_ready();
+ send_ready();
}
}
else if(!allowlaptop && is_client && !is_server)
{
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[16] );
}
-
}
void DropOffItemsInSector( UINT8 ubOrderNum )
@@ -2025,8 +1767,6 @@ void DropOffItemsInSector( UINT8 ubOrderNum )
UINT8 ubItemsDelivered, ubTempNumItems;
UINT32 i;
-
-
// determine if the sector is loaded
if( ( gWorldSectorX == gsMercArriveSectorX ) && ( gWorldSectorY == gsMercArriveSectorY ) && ( gbWorldSectorZ == 0 ) )
fSectorLoaded = TRUE;
@@ -2035,8 +1775,6 @@ void DropOffItemsInSector( UINT8 ubOrderNum )
SetSectorFlag( gsMercArriveSectorX, gsMercArriveSectorY, 0, SF_ALREADY_VISITED);//allows update of item count
-
-
for(i=0; iusSoldierID < 120)
{
- //ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"send_stop" );
if(SStopMerc->usSoldierID < 20)
{
stop_struct.usSoldierID = (SStopMerc->usSoldierID)+ubID_prefix;
@@ -2120,11 +1853,12 @@ void send_stop (EV_S_STOP_MERC *SStopMerc) // used to stop a merc when he spots
stop_struct.sGridNo=SStopMerc->sGridNo;
stop_struct.ubDirection=SStopMerc->ubDirection;
stop_struct.fset=SStopMerc->fset;
+
if(stop_struct.fset==FALSE)
{
- //ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"skipped" );
return;
}
+
stop_struct.sXPos=SStopMerc->sXPos;
stop_struct.sYPos=SStopMerc->sYPos;
client->RPC("sendSTOP",(const char*)&stop_struct, (int)sizeof(EV_S_STOP_MERC)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
@@ -2133,34 +1867,18 @@ void send_stop (EV_S_STOP_MERC *SStopMerc) // used to stop a merc when he spots
void recieveSTOP (RPCParameters *rpcParameters)
{
- //ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"recieve_stop" );
-
EV_S_STOP_MERC* SStopMerc =(EV_S_STOP_MERC*)rpcParameters->input;
SOLDIERTYPE *pSoldier = MercPtrs[ SStopMerc->usSoldierID ];
-
- //INT16 sCellX, sCellY;
- //sCellX = CenterX( SStopMerc->sGridNo );
- //sCellY = CenterY( SStopMerc->sGridNo );
-
pSoldier->EVENT_InternalSetSoldierPosition( SStopMerc->sXPos, SStopMerc->sYPos,FALSE, FALSE, FALSE );
- pSoldier->EVENT_SetSoldierDirection( SStopMerc->ubDirection );
- //pSoldier->HaultSoldierFromSighting(TRUE);
- pSoldier->AdjustNoAPToFinishMove( SStopMerc->fset );
- //EVENT_StopMerc( pSoldier, SStopMerc->sGridNo, SStopMerc->bDirection );
- //pSoldier->AdjustNoAPToFinishMove( TRUE );
-
- pSoldier->flags.bTurningFromPronePosition = FALSE;
-
-
-
+ pSoldier->EVENT_SetSoldierDirection( SStopMerc->ubDirection );
+ pSoldier->AdjustNoAPToFinishMove( SStopMerc->fset );
+ pSoldier->flags.bTurningFromPronePosition = FALSE;
}
void send_interrupt (SOLDIERTYPE *pSoldier)
{
-
-
INT_STRUCT INT;
INT.ubID = pSoldier->ubID;
@@ -2169,7 +1887,6 @@ void send_interrupt (SOLDIERTYPE *pSoldier)
INT.gubOutOfTurnPersons = gubOutOfTurnPersons;
INT.Interrupted=gusSelectedSoldier+ubID_prefix;
-
if(INT.bTeam==0)
{
@@ -2177,21 +1894,18 @@ void send_interrupt (SOLDIERTYPE *pSoldier)
INT.ubID=INT.ubID+ubID_prefix;
}
- for(int i=0; i <= INT.gubOutOfTurnPersons; i++)
+ for(int i=0; i <= INT.gubOutOfTurnPersons; i++)
+ {
+ if(INT.gubOutOfTurnOrder[i] < 20)
{
- if(INT.gubOutOfTurnOrder[i] < 20)
- {
- INT.gubOutOfTurnOrder[i]=INT.gubOutOfTurnOrder[i]+ubID_prefix;
- }
+ INT.gubOutOfTurnOrder[i]=INT.gubOutOfTurnOrder[i]+ubID_prefix;
}
+ }
- //if(gubOutOfTurnPersons>0)ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Sent Int: bTeam-%d ubID-%d", INT.bTeam,INT.ubID );
-
- if(INT.bTeam !=netbTeam) gTacticalStatus.ubCurrentTeam=INT.bTeam;
+ if(INT.bTeam !=netbTeam)
+ gTacticalStatus.ubCurrentTeam=INT.bTeam;
client->RPC("sendINTERRUPT",(const char*)&INT, (int)sizeof(INT_STRUCT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
-
}
// WANNE - MP: Here we have to add AddTopMessage() on the clients
@@ -2200,7 +1914,7 @@ void recieveINTERRUPT (RPCParameters *rpcParameters)
INT_STRUCT* INT = (INT_STRUCT*)rpcParameters->input;
SOLDIERTYPE* pOpponent = MercPtrs[ INT->Interrupted];
- if(INT->bTeam==netbTeam)// ||pOpponent->bTeam==1 )//for us or AI
+ if(INT->bTeam==netbTeam)//for us or AI
{
INT->bTeam=0;
INT->ubID=INT->ubID - ubID_prefix;
@@ -2231,32 +1945,25 @@ void recieveINTERRUPT (RPCParameters *rpcParameters)
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[17] );
//stop moving merc who was interrupted and init UI bar
- SOLDIERTYPE* pMerc = MercPtrs[ INT->ubID ];
- //AdjustNoAPToFinishMove( pMerc, TRUE );
+ SOLDIERTYPE* pMerc = MercPtrs[ INT->ubID ];
pMerc->HaultSoldierFromSighting(TRUE);
- //pMerc->fTurningFromPronePosition = FALSE;// hmmm ??
FreezeInterfaceForEnemyTurn();
InitEnemyUIBar( 0, 0 );
fInterfacePanelDirty = DIRTYLEVEL2;
-
- //if (is_server)
- // AddTopMessage( COMPUTER_TURN_MESSAGE, TeamTurnString[ INT->bTeam ] );
gTacticalStatus.fInterruptOccurred = TRUE;
-
}
else
{
//it for us ! :)
if(INT->gubOutOfTurnPersons==0)//indicates finished interrupt maybe can just call end interrupt
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"old int finish" );
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"old int finish" );
}
else //start our interrupt turn
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[37] );
SOLDIERTYPE* pSoldier = MercPtrs[ INT->ubID ];
- //SOLDIERTYPE* pOpponent = MercPtrs[ INT->Interrupted];
ManSeesMan(pSoldier,pOpponent,pOpponent->sGridNo,pOpponent->pathing.bLevel,2,1);
StartInterrupt();
}
@@ -2264,29 +1971,17 @@ void recieveINTERRUPT (RPCParameters *rpcParameters)
}
void intAI (SOLDIERTYPE *pSoldier )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[17] );
- //stop moving merc who was interrupted and init UI bar
- //SOLDIERTYPE* pMerc = MercPtrs[ INT->ubID ];
- ////AdjustNoAPToFinishMove( pMerc, TRUE );
- //pMerc->HaultSoldierFromSighting(TRUE);
- //pMerc->fTurningFromPronePosition = FALSE;// hmmm ??
- //FreezeInterfaceForEnemyTurn();
- //InitEnemyUIBar( 0, 0 );
- //fInterfacePanelDirty = DIRTYLEVEL2;
- AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ pSoldier->bTeam ] );
- gTacticalStatus.fInterruptOccurred = TRUE;
-
- }
+{
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[17] );
+ AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ pSoldier->bTeam ] );
+ gTacticalStatus.fInterruptOccurred = TRUE;
+}
+
void end_interrupt ( BOOLEAN fMarkInterruptOccurred )
{
-
-
SOLDIERTYPE * pSoldier = MercPtrs[(gubOutOfTurnOrder[gubOutOfTurnPersons])];
-
INT_STRUCT INT;
-
INT.ubID = pSoldier->ubID;
INT.bTeam = pSoldier->bTeam;
memcpy(INT.gubOutOfTurnOrder, gubOutOfTurnOrder, sizeof(UINT8) * MAXMERCS);
@@ -2300,52 +1995,45 @@ void end_interrupt ( BOOLEAN fMarkInterruptOccurred )
INT.ubID=INT.ubID+ubID_prefix;
}
- for(int i=0; i <= INT.gubOutOfTurnPersons; i++)
+ for(int i=0; i <= INT.gubOutOfTurnPersons; i++)
+ {
+ if(INT.gubOutOfTurnOrder[i] < 20)
{
- if(INT.gubOutOfTurnOrder[i] < 20)
- {
- INT.gubOutOfTurnOrder[i]=INT.gubOutOfTurnOrder[i]+ubID_prefix;
- }
+ INT.gubOutOfTurnOrder[i]=INT.gubOutOfTurnOrder[i]+ubID_prefix;
}
+ }
-
-
client->RPC("endINTERRUPT",(const char*)&INT, (int)sizeof(INT_STRUCT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
-
}
void resume_turn(RPCParameters *rpcParameters)
{
INT_STRUCT* INT = (INT_STRUCT*)rpcParameters->input;
- if(is_server)Sawarded=false;
+
+ if(is_server)
+ Sawarded=false;
if(INT->bTeam==netbTeam || (INT->bTeam==1 && is_server))//may need working
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[18] );
for(int i=0; i <= INT->gubOutOfTurnPersons; i++)
+ {
+ if((INT->gubOutOfTurnOrder[i] >= ubID_prefix) && (INT->gubOutOfTurnOrder[i] < (ubID_prefix+6)))
{
- if((INT->gubOutOfTurnOrder[i] >= ubID_prefix) && (INT->gubOutOfTurnOrder[i] < (ubID_prefix+6)))
- {
- INT->gubOutOfTurnOrder[i]=INT->gubOutOfTurnOrder[i]-ubID_prefix;
- }
+ INT->gubOutOfTurnOrder[i]=INT->gubOutOfTurnOrder[i]-ubID_prefix;
}
+ }
memcpy(gubOutOfTurnOrder,INT->gubOutOfTurnOrder, sizeof(UINT8) * MAXMERCS);
gubOutOfTurnPersons = INT->gubOutOfTurnPersons;
-
-
-
EndInterrupt( INT->fMarkInterruptOccurred );
}
+ // WANNE - MP: This happens, when client 1 (=server) has done its interrupt and now it is enemies turn!
else if(INT->bTeam==1)
{
- // WANNE - MP: This happens, when client 1 (=server) has done its interrupt and now it is enemies turn!
- // WANNE - MP: Removed the AddTopMessage() again ...
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"im not server but ai just got back its turn after being interrupted..." );
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"im not server but ai just got back its turn after being interrupted..." );
AddTopMessage( COMPUTER_TURN_MESSAGE, TeamTurnString[ 1 ] );
- //maybe can add something.
}
}
@@ -2362,108 +2050,48 @@ void grid_display ( void ) //print mouse coordinates, helpfull for crate placeme
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[21], usMapPos );
}
-// WANNE: No more needed
-void mp_help(void)
-{
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L" ");
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[2]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[3]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L" ");
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[4]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[5]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[6]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[7]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[8]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[9]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[10]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L" ");
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[11]);
-}
-
-// WANNE: No more needed
-void mp_help2(void)
-{
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L" ");
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[12]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L" ");
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[13]);
-
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[14]);
-
-
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[15]);
-
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L" ");
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[16]);
- ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[11]);
-
-}
-
-void manual_overide (void)//now bound to "7"
-{
- if(is_server)
- {
- //manual overide command for server
- const STR16 msg = MPClientMessage[23];
-
- SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
- DoMessageBox( MSG_BOX_BASIC_STYLE, msg, guiCurrentScreen, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS | MSG_BOX_FLAG_USE_CENTERING_RECT, overide_callback, &CenterRect );
-
- }
- else ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[22] );
-
-}
-
void overide_callback( UINT8 ubResult )
{
if(is_server)
{
- if(ubResult==1)
- {
- allowlaptop=true;
- }
- if(ubResult==2)//overide stop #1 (awaiting client ready for launch/load)
-
-
- {
- goahead=0;
- status=0;//reset
- numready=0;
- SOLDIERTYPE *pSoldier = MercPtrs[ 0 ];
- UINT8 ubGroupID = pSoldier->ubGroupID;
+ if(ubResult==1)
+ {
+ allowlaptop=true;
+ }
- GROUP *pGroup;
- pGroup = GetGroup( ubGroupID );
- gpBattleGroup = pGroup;
- gubPBSectorX = gpBattleGroup->ubSectorX;
- gubPBSectorY = gpBattleGroup->ubSectorY;
- gubPBSectorZ = gpBattleGroup->ubSectorZ;
+ if(ubResult==2)//overide stop #1 (awaiting client ready for launch/load)
+ {
+ goahead=0;
+ status=0;//reset
+ numready=0;
+ SOLDIERTYPE *pSoldier = MercPtrs[ 0 ];
+ UINT8 ubGroupID = pSoldier->ubGroupID;
- gfEnterTacticalPlacementGUI = 1;
-
-
+ GROUP *pGroup;
+ pGroup = GetGroup( ubGroupID );
+ gpBattleGroup = pGroup;
+ gubPBSectorX = gpBattleGroup->ubSectorX;
+ gubPBSectorY = gpBattleGroup->ubSectorY;
+ gubPBSectorZ = gpBattleGroup->ubSectorZ;
- goahead=1;
- readystage=1;
- ready_struct info; //send
- info.client_num = CLIENT_NUM;
- info.ready_stage = 1;
- info.status = 1;
-
+ gfEnterTacticalPlacementGUI = 1;
+ goahead=1;
+ readystage=1;
+ ready_struct info; //send
+ info.client_num = CLIENT_NUM;
+ info.ready_stage = 1;
+ info.status = 1;
-
-
- client->RPC("sendREADY",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
- status=0;//reset
- numready=0;
-
- SetCurrentWorldSector( gubPBSectorX, gubPBSectorY, gubPBSectorZ ); //load
- }
-
-
- if(ubResult==3)
- {
+ client->RPC("sendREADY",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+
+ status=0;//reset
+ numready=0;
+
+ SetCurrentWorldSector( gubPBSectorX, gubPBSectorY, gubPBSectorZ ); //load
+ }
+
+ if(ubResult==3)
+ {
lockui(1);//unlock ui paused while wainting for loaders
ready_struct info;
@@ -2473,33 +2101,28 @@ void overide_callback( UINT8 ubResult )
info.ready_stage = 2;//done placing mercs
info.status=1;
client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
- }
- if(ubResult==4) //overide waiting on merc placement
- {
- numready=0;
+ }
- ready_struct info; //send
- info.client_num = CLIENT_NUM;
- info.ready_stage = 4;//all done placing mercs, kill all
- info.status=1;
- gMsgBox.bHandled = MSG_BOX_RETURN_OK;
- status=0;
- KillTacticalPlacementGUI(); //kill
- ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[13]);
+ if(ubResult==4) //overide waiting on merc placement
+ {
+ numready=0;
- client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
- }
-
+ ready_struct info; //send
+ info.client_num = CLIENT_NUM;
+ info.ready_stage = 4;//all done placing mercs, kill all
+ info.status=1;
+ gMsgBox.bHandled = MSG_BOX_RETURN_OK;
+ status=0;
+ KillTacticalPlacementGUI(); //kill
+ ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[13]);
+ client->RPC("sendGUI",(const char*)&info, (int)sizeof(ready_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ }
+
goahead = 0;
numready = 0;
readystage = 0;
status = 0;
-
-
-
}
}
@@ -2544,32 +2167,25 @@ void requestSETID(RPCParameters *rpcParameters)
if (!fClientReceivedAllFiles)
{
serverAddr = rpcParameters->sender;
-
+
SGPRect CenteringRect= {0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
DoMessageBox( MSG_BOX_BASIC_STYLE , MPClientMessage[64] , guiCurrentScreen, MSG_BOX_FLAG_YESNO | MSG_BOX_FLAG_USE_CENTERING_RECT, allowDownloadCallback, &CenteringRect );
-
}
}
}
}
-
-
void requestSETTINGS(void)
{
client_info cl_name;
- //cl_name.client_num=CLIENT_NUM;
- strcpy(cl_name.client_name , CLIENT_NAME);
- cl_name.team=TEAM;
-
- cl_name.cl_edge=atoi(SECT_EDGE);
+ strcpy(cl_name.client_name , cClientName);
+ cl_name.team = TEAM;
+ cl_name.cl_edge = cStartingSectorEdge;
// OJW - 20090507
// send client version to server
strcpy(cl_name.client_version,MPVERSION);
-
client->RPC("requestSETTINGS",(const char*)&cl_name, (int)sizeof(client_info)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
}
// OJW: FILE TRANSFER: Clients get notified of other clients transfer progress
@@ -2592,47 +2208,13 @@ void recieveDOWNLOADSTATUS(RPCParameters *rpcParameters)
fDrawCharacterList = true;
}
-
// WANNE: FILE TRANSFER: Get executable Directory from Server. This is used to get corret file location on client side
void recieveFILE_TRANSFER_SETTINGS (RPCParameters *rpcParameters)
{
if (!is_server && recieved_transfer_settings == 0)
{
filetransfersettings_struct* fts = (filetransfersettings_struct*)rpcParameters->input;
-#ifndef USE_VFS
- // OJW - 20090405
- gCurrentTransferBytes = 0;
- gTotalTransferBytes = fts->totalTransferBytes;
- // Now get directory
- strcpy( server_fileTransferDirectoryPath, fts->fileTransferDirectory );
-
- // Convert string to lowercase. This is needed, because the file path we received (see OnFile()) from list transfer is also lowercase
- for (INT32 i = 0; server_fileTransferDirectoryPath[i]; ++i)
- {
- server_fileTransferDirectoryPath[i] = tolower(server_fileTransferDirectoryPath[i]);
- putchar(server_fileTransferDirectoryPath[i]);
- }
-
- recieved_transfer_settings = 1;
- serverSyncClientsDirectory = fts->syncClientsDirectory;
-
- // We sync our MP game dir from the server
- if (fts->syncClientsDirectory == 1)
- {
- strcat(client_fileTransferDirectoryPath, "\\");
- strcat(client_fileTransferDirectoryPath, fts->serverName);
-
- // Replace "/" with "\"
- char* client_correctFileTransferDirectoryPath = ReplaceCharactersInString_Client(client_fileTransferDirectoryPath, "/", "\\");
-
- strcpy(client_fileTransferDirectoryPath, client_correctFileTransferDirectoryPath);
-
- // Delete the clients mp directory. It will be recreated later when we receive the files from the server
- if (DirectoryExists(client_fileTransferDirectoryPath))
- RemoveFileManDirectory(client_fileTransferDirectoryPath, true);
- }
-#else
gCurrentTransferBytes = 0;
gTotalTransferBytes = fts->totalTransferBytes;
@@ -2641,36 +2223,9 @@ void recieveFILE_TRANSFER_SETTINGS (RPCParameters *rpcParameters)
vfs::Path profileRoot = vfs::Path(gzFileTransferDirectory) + vfs::Path(server_fileTransferDirectoryPath);
/////////////////////////////////////////////////////////////////////
- vfs::CProfileStack *PS = getVFS()->getProfileStack();
-
- // remove Multiplayer profile if it exists
- vfs::CVirtualProfile *pProf = PS->getProfile("_MULTIPLAYER");
- if( pProf && (pProf == PS->topProfile()) )
- {
- THROWIFFALSE(PS->popProfile(), L"Could not remove old \"_MULTIPLAYER\" profile");
- // careful, pProf is not valid anymore
- }
- // create and initialize a new Multiplayer profile
- pProf = new vfs::CVirtualProfile("_MULTIPLAYER",true);
- PS->pushProfile(pProf);
- if(!initWriteProfile(*pProf,profileRoot))
- {
- // OK, directory did not exist, probably a new server
- if(!os::createRealDirectory(profileRoot))
- {
- THROWIFFALSE(PS->popProfile(), L"Could not remove \"_MULTIPLAYER\" profile");
- THROWEXCEPTION(L"could not create client directory");
- }
- // OK, try again
- if(!initWriteProfile(*pProf,profileRoot))
- {
- THROWIFFALSE(PS->popProfile(), L"Could not remove \"_MULTIPLAYER\" profile");
- THROWEXCEPTION(L"Could not initialize client profile");
- }
- }
+ SGP_TRYCATCH_RETHROW( ja2::mp::InitializeMultiplayerProfile(profileRoot), L"" );
/////////////////////////////////////////////////////////////////////
-
recieved_transfer_settings = 1;
serverSyncClientsDirectory = fts->syncClientsDirectory;
@@ -2679,7 +2234,6 @@ void recieveFILE_TRANSFER_SETTINGS (RPCParameters *rpcParameters)
{
// profile is setup, nothing to do here
}
-#endif
}
}
@@ -2689,209 +2243,231 @@ void recieveSETTINGS (RPCParameters *rpcParameters) //recive settings from serve
settings_struct* cl_lan = (settings_struct*)rpcParameters->input;
- char szDefault[30];
- sprintf(szDefault, "%s",cl_lan->client_name);
+ char szDefault[30];
+ sprintf(szDefault, "%s",cl_lan->client_name);
+
+ // OJW - 20081204
+ // get complete client data from the server
+ memcpy( client_edges, cl_lan->client_edges , sizeof(int) * 5);
+ memcpy( client_teams, cl_lan->client_teams , sizeof(int) * 4);
+
+ if(!recieved_settings && strcmp(cl_lan->client_name, cClientName)==0)
+ {
+ // This settings packet contains information and settings specifically for us
+ recieved_settings=1;
+
+ // save the settings so if we need to re-apply them after a reinitialisation ( after file transfer ) we can
+ memcpy ( &gMPServerSettings , cl_lan , sizeof(settings_struct) );
+
+ CLIENT_NUM=cl_lan->client_num;//assign client number from server
+
+ netbTeam = (CLIENT_NUM)+5;
+ ubID_prefix = gTacticalStatus.Team[ netbTeam ].bFirstID;//over here now
+
+ memcpy( client_names , cl_lan->client_names, sizeof( char ) * 4 * 30 );
+
+ strcpy(client_names[cl_lan->client_num-1],szDefault);
// OJW - 20081204
- // get complete client data from the server
- memcpy( client_edges, cl_lan->client_edges , sizeof(int) * 5);
- memcpy( client_teams, cl_lan->client_teams , sizeof(int) * 4);
+ strcpy(cServerName,cl_lan->server_name);
+ gRandomMercs = cl_lan->randomMercs;
+ gRandomStartingEdge = cl_lan->randomStartingEdge;
- if(!recieved_settings && strcmp(cl_lan->client_name, CLIENT_NAME)==0)
+ cStartingSectorEdge = cl_lan->startingSectorEdge;
+
+ if(gRandomMercs)
{
- // This settings packet contains information and settings specifically for us
- recieved_settings=1;
+ // copy the random merc list locally
+ memcpy(random_mercs,cl_lan->random_mercs,sizeof(int) * 7);
+ }
- // save the settings so if we need to re-apply them after a reinitialisation ( after file transfer ) we can
- memcpy ( &gMPServerSettings , cl_lan , sizeof(settings_struct) );
-
- CLIENT_NUM=cl_lan->client_num;//assign client number from server
-
- netbTeam = (CLIENT_NUM)+5;
- ubID_prefix = gTacticalStatus.Team[ netbTeam ].bFirstID;//over here now
-
- memcpy( client_names , cl_lan->client_names, sizeof( char ) * 4 * 30 );
-
- strcpy(client_names[cl_lan->client_num-1],szDefault);
-
- // OJW - 20081204
- strcpy(SERVER_NAME,cl_lan->server_name);
- RANDOM_MERCS = cl_lan->RANDOM_MERCS;
- RANDOM_SPAWN = cl_lan->RANDOM_SPAWN;
-
- // Set the starting edge
- _itoa(cl_lan->cl_edge,SECT_EDGE,10);
-
- if(RANDOM_MERCS)
- {
- // copy the random merc list locally
- memcpy(random_mercs,cl_lan->random_mercs,sizeof(int) * 7);
- }
-
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[2] );
-
-
- MAX_CLIENTS=cl_lan->max_clients;
- memcpy( ckbag, cl_lan->kitbag, sizeof(char)*100);
-
- int cnt;
- int numnum = 0;
- int kitnum = 0;
- char tempstring[4];
- memset( &kit, 0, sizeof( int )*20 );
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[2] );
- for(cnt=0; cnt < 100; cnt++)
- {
- char tempc = ckbag[cnt];
-
- if( _strnicmp(&tempc, "[",1) == 0)
- {
-
- continue;
- }
-
- else if( _strnicmp(&tempc, ",",1) == 0)
- {
- numnum=0;
- kit[kitnum]=atoi(tempstring);
-
- memset( &tempstring, 0, sizeof( char )*4 );
-
- kitnum++;
- continue;
- }
-
- else if( _strnicmp(&tempc, "]",1) == 0)
- {
- kit[kitnum]=atoi(tempstring);
- break;
- }
- else
- {
- strncpy(&tempstring[numnum],&tempc,1);
- numnum++;
- //temp = atoi(tempstring);
- }
- }
-
-
- DAMAGE_MULTIPLIER=cl_lan->damage_multiplier;
- SAME_MERC=cl_lan->same_merc;
-
-
- gsMercArriveSectorX=cl_lan->gsMercArriveSectorX;
- gsMercArriveSectorY=cl_lan->gsMercArriveSectorY;
-
- // WANNE - BMP: We have to initialize the map size here!!
- InitializeWorldSize(gsMercArriveSectorX, gsMercArriveSectorY, 0);
-
- PLAYER_BSIDE=cl_lan->gsPLAYER_BSIDE;
- DISABLE_MORALE=cl_lan->emorale;
- ChangeSelectedMapSector( gsMercArriveSectorX, gsMercArriveSectorY, 0 );
- CHAR16 str[128];
- GetSectorIDString( gsMercArriveSectorX, gsMercArriveSectorY, 0, str, TRUE );
+ cMaxClients=cl_lan->maxClients;
+ memcpy( cKitBag, cl_lan->kitBag, sizeof(char)*100);
- // WANNE - MP: If time set to 0, then no time turns
- INT32 secs_per_tick;
- if (cl_lan->secs_per_tick == 0)
+ int cnt;
+ int numnum = 0;
+ int kitnum = 0;
+ char tempstring[4];
+ memset( &kit, 0, sizeof( int )*20 );
+
+ for(cnt=0; cnt < 100; cnt++)
+ {
+ char tempc = cKitBag[cnt];
+
+ if( _strnicmp(&tempc, "[",1) == 0)
{
- gGameOptions.fTurnTimeLimit=FALSE;
- secs_per_tick=1;
+
+ continue;
+ }
+
+ else if( _strnicmp(&tempc, ",",1) == 0)
+ {
+ numnum=0;
+
+ kit[kitnum]=atoi(tempstring);
+
+ memset( &tempstring, 0, sizeof( char )*4 );
+
+ kitnum++;
+ continue;
+ }
+
+ else if( _strnicmp(&tempc, "]",1) == 0)
+ {
+ kit[kitnum]=atoi(tempstring);
+ break;
}
else
{
- gGameOptions.fTurnTimeLimit=cl_lan->sofTurnTimeLimit;
- secs_per_tick=cl_lan->secs_per_tick;
+ strncpy(&tempstring[numnum],&tempc,1);
+ numnum++;
}
-
-
- PLAYER_TEAM_TIMER_SEC_PER_TICKS=secs_per_tick;
+ }
- INT32 clstarting_balance=cl_lan->starting_balance;//set starting balance
+ cDamageMultiplier=cl_lan->damageMultiplier;
+ cSameMercAllowed=cl_lan->sameMercAllowed;
+
+ gsMercArriveSectorX=cl_lan->gsMercArriveSectorX;
+ gsMercArriveSectorY=cl_lan->gsMercArriveSectorY;
- if(LaptopSaveInfo.iCurrentBalancegameType;
+ cDisableMorale=cl_lan->disableMorale;
+ ChangeSelectedMapSector( gsMercArriveSectorX, gsMercArriveSectorY, 0 );
+ CHAR16 str[128];
+ GetSectorIDString( gsMercArriveSectorX, gsMercArriveSectorY, 0, str, TRUE );
+
+ // WANNE - MP: If time set to 0, then no time turns
+ INT32 secs_per_tick;
+ if (cl_lan->secondsPerTick == 0)
+ {
+ gGameOptions.fTurnTimeLimit=FALSE;
+ secs_per_tick=1;
+ }
+ else
+ {
+ gGameOptions.fTurnTimeLimit=cl_lan->sofTurnTimeLimit;
+ secs_per_tick=cl_lan->secondsPerTick;
+ }
+
+ PLAYER_TEAM_TIMER_SEC_PER_TICKS=secs_per_tick;
+
+ INT32 clstarting_balance=cl_lan->startingCash;//set starting balance
+
+ if(LaptopSaveInfo.iCurrentBalancesofGunNut;
- gGameOptions.ubGameStyle=cl_lan->soubGameStyle;
- gGameOptions.ubDifficultyLevel=cl_lan->soubDifficultyLevel;
-
- gGameOptions.fIronManMode=cl_lan->sofIronManMode;
- gGameOptions.ubBobbyRay=cl_lan->soubBobbyRay;
+ gGameOptions.fGunNut=cl_lan->sofGunNut;
+ gGameOptions.ubGameStyle=cl_lan->soubGameStyle;
+ gGameOptions.ubDifficultyLevel=cl_lan->soubDifficultyLevel;
+ gGameOptions.fNewTraitSystem = cl_lan->soubSkillTraits;
+ gGameOptions.fIronManMode=cl_lan->sofIronManMode;
+ gGameOptions.ubBobbyRay=cl_lan->soubBobbyRay;
-
- // Set Bobby Ray "Under Construction"?
- if(!cl_lan->soDis_Bobby)
- {
- SetBookMark( BOBBYR_BOOKMARK );
- LaptopSaveInfo.fBobbyRSiteCanBeAccessed = TRUE;
- }
+ // Set Bobby Ray "Under Construction"?
+ if(!cl_lan->disableBobbyRay)
+ {
+ SetBookMark( BOBBYR_BOOKMARK );
+ LaptopSaveInfo.fBobbyRSiteCanBeAccessed = TRUE;
+ }
- // Enable "AIM" and "MERC" only if random merc is false!
- if (!cl_lan->RANDOM_MERCS)
- {
- SetBookMark( AIM_BOOKMARK );
- SetBookMark( MERC_BOOKMARK );
- }
+ // Enable "AIM" and "MERC" only if random merc is false!
+ if (!cl_lan->randomMercs)
+ {
+ SetBookMark( AIM_BOOKMARK );
+ SetBookMark( MERC_BOOKMARK );
+ }
- if(!cl_lan->soDis_Equip)
- ALLOW_EQUIP=TRUE;
+ if(!cl_lan->disableMercEquipment)
+ cAllowMercEquipment = 1;
- MAX_MERCS=cl_lan->gsMAX_MERCS;
- TESTING=cl_lan->TESTING;
- REPORT_NAME=cl_lan->gsREPORT_NAME;
+ cMaxMercs = cl_lan->maxMercs;
+ cReportHiredMerc = cl_lan->reportHiredMerc;
- ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, MPClientMessage[24],str,MAX_CLIENTS,MAX_MERCS,PLAYER_BSIDE,SAME_MERC,DAMAGE_MULTIPLIER,gGameOptions.fTurnTimeLimit,secs_per_tick,cl_lan->soDis_Bobby,cl_lan->soDis_Equip,DISABLE_MORALE,TESTING);
- if(TESTING) ScreenMsg( FONT_WHITE, MSG_MPSYSTEM, MPClientMessage[25] );
+ // WANNE: Removed
+ /*
+ ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, MPClientMessage[24],str,cMaxClients,cMaxMercs,cGameType,cSameMercAllowed,cDamageMultiplier,gGameOptions.fTurnTimeLimit,secs_per_tick,cl_lan->disableBobbyRay,cl_lan->disableMercEquipment,cDisableMorale,0);
+ */
+
+ // WANNE - MP: I just added the NUM_SEC_IN_DAY so the game starts at Day 1 instead of Day 0
+ gGameExternalOptions.iGameStartingTime= NUM_SEC_IN_DAY + int(cl_lan->startingTime*3600);
+ // WANNE - MP: In mulitplayer the hired merc arrive immediatly, so iFirstArrivalDelay must be set to 0
+ // This also fixed the bug of the wrong hired hours!
+ gGameExternalOptions.iFirstArrivalDelay = 0;
+
+ // Disable Reinforcements
+ gGameExternalOptions.gfAllowReinforcements = false;
+ gGameExternalOptions.gfAllowReinforcementsOnlyInCity = false;
+
+ // Disable Real-Time Mode
+ // SANDRO - huh? real-time sneak is in preferences
+ //gGameExternalOptions.fAllowRealTimeSneak = false;
- // WANNE - MP: I just added the NUM_SEC_IN_DAY so the game starts at Day 1 instead of Day 0
- gGameExternalOptions.iGameStartingTime= NUM_SEC_IN_DAY + int(cl_lan->TIME*3600);
- // WANNE - MP: In mulitplayer the hired merc arrive immediatly, so iFirstArrivalDelay must be set to 0
- // This also fixed the bug of the wrong hired hours!
- gGameExternalOptions.iFirstArrivalDelay = 0;
+ gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] = false;
+ gGameExternalOptions.fQuietRealTimeSneak = false;
- // Disable Reinforcements
- gGameExternalOptions.gfAllowReinforcements = false;
- gGameExternalOptions.gfAllowReinforcementsOnlyInCity = false;
+ // WANNE: fix HOT DAY in night at arrival by night.
+ // Explanation: If game starting time + first arrival delay < 07:00 (111600) -> we arrive before the sun rises or
+ // if game starting time + first arrival delay >= 21:00 (162000) -> we arrive after the sun goes down
+ if( (gGameExternalOptions.iGameStartingTime + gGameExternalOptions. iFirstArrivalDelay) < 111600 ||
+ (gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay >= 162000))
+ {
+ // Default: Night
+ gubEnvLightValue = 12;
+ }
+ else
+ {
+ // Default: Day
+ gubEnvLightValue = 3;
+ }
- // Disable Real-Time Mode
- gGameExternalOptions.fAllowRealTimeSneak = false;
- gGameExternalOptions.fQuietRealTimeSneak = false;
+ LightSetBaseLevel(gubEnvLightValue);
- // WANNE: fix HOT DAY in night at arrival by night.
- // Explanation: If game starting time + first arrival delay < 07:00 (111600) -> we arrive before the sun rises or
- // if game starting time + first arrival delay >= 21:00 (162000) -> we arrive after the sun goes down
- if( (gGameExternalOptions.iGameStartingTime + gGameExternalOptions. iFirstArrivalDelay) < 111600 ||
- (gGameExternalOptions.iGameStartingTime + gGameExternalOptions.iFirstArrivalDelay >= 162000))
- {
- // Default: Night
- gubEnvLightValue = 12;
- }
- else
- {
- // Default: Day
- gubEnvLightValue = 3;
- }
-
- LightSetBaseLevel(gubEnvLightValue);
-
- InitNewGameClock( );
-
- WEAPON_READIED_BONUS=cl_lan->WEAPON_READIED_BONUS;
- DISABLE_SPEC_MODE=cl_lan->DISABLE_SPEC_MODE;
-
- // We have to take the selected inventory mode from the server
- gGameOptions.ubInventorySystem=cl_lan->sofNewInv;
+ InitNewGameClock( );
+
+ cWeaponReadyBonus = cl_lan->weaponReadyBonus;
+ cDisableSpectatorMode = cl_lan->disableSpectatorMode;
+
+ // -----------------
+ // RW: Inventory
+ switch (cl_lan->inventoryAttachment)
+ {
+ case 0: // Old/Old
+ gGameOptions.ubInventorySystem = INVENTORY_OLD;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_OLD;
+ break;
+ case 1: // New/Old
+ gGameOptions.ubInventorySystem = INVENTORY_NEW;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_OLD;
+ break;
+ case 2: // New/New
+ gGameOptions.ubInventorySystem = INVENTORY_NEW;
+ gGameOptions.ubAttachmentSystem = ATTACHMENT_NEW;
+ break;
+ }
+ // Server forces us to play with new Inventory, but NIV is not allowed on the client,
+ // because of wrong resolution or other stuff
+ if ( UsingNewInventorySystem() == true && !IsNIVModeValid(true) )
+ {
+ SGPRect CenteringRect= {0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
+ DoMessageBox( MSG_BOX_BASIC_STYLE , MPClientMessage[69] , guiCurrentScreen, MSG_BOX_FLAG_OK | MSG_BOX_FLAG_USE_CENTERING_RECT, InvalidClientSettingsOkBoxCallback, &CenteringRect );
+ }
+ else
+ {
// WANNE - MP: We have to re-initialize the correct interface
- if((UsingNewInventorySystem() == true) && IsNIVModeValid(true))
+ if((UsingNewInventorySystem() == true))
{
InitNewInventorySystem();
InitializeSMPanelCoordsNew();
@@ -2917,17 +2493,17 @@ void recieveSETTINGS (RPCParameters *rpcParameters) //recive settings from serve
// OJW - 20091024 - extract random table
if (!is_server)
- memcpy(guiPreRandomNums,cl_lan->random_table,sizeof(UINT32)*MAX_PREGENERATED_NUMS);
+ memcpy(guiPreRandomNums,cl_lan->random_table,sizeof(UINT32)*MAX_PREGENERATED_NUMS);
}
- else
- {
- fDrawCharacterList = true; // set the character list to be redrawn
+ }
+ else
+ {
+ fDrawCharacterList = true; // set the character list to be redrawn
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[26],cl_lan->client_num,szDefault );
-
- strcpy(client_names[cl_lan->client_num-1],szDefault);
-
- }
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[26],cl_lan->client_num,szDefault );
+
+ strcpy(client_names[cl_lan->client_num-1],szDefault);
+ }
}
void reapplySETTINGS()
@@ -2961,15 +2537,15 @@ void reapplySETTINGS()
gsMercArriveSectorX=gMPServerSettings.gsMercArriveSectorX;
gsMercArriveSectorY=gMPServerSettings.gsMercArriveSectorY;
- PLAYER_BSIDE=gMPServerSettings.gsPLAYER_BSIDE;
- DISABLE_MORALE=gMPServerSettings.emorale;
+ cGameType=gMPServerSettings.gameType;
+ cDisableMorale=gMPServerSettings.disableMorale;
ChangeSelectedMapSector( gsMercArriveSectorX, gsMercArriveSectorY, 0 );
CHAR16 str[128];
GetSectorIDString( gsMercArriveSectorX, gsMercArriveSectorY, 0, str, TRUE );
// WANNE - MP: If time set to 0, then no time turns
INT32 secs_per_tick;
- if (gMPServerSettings.secs_per_tick == 0)
+ if (gMPServerSettings.secondsPerTick == 0)
{
gGameOptions.fTurnTimeLimit=FALSE;
secs_per_tick=1;
@@ -2977,53 +2553,52 @@ void reapplySETTINGS()
else
{
gGameOptions.fTurnTimeLimit=gMPServerSettings.sofTurnTimeLimit;
- secs_per_tick=gMPServerSettings.secs_per_tick;
+ secs_per_tick=gMPServerSettings.secondsPerTick;
}
-
PLAYER_TEAM_TIMER_SEC_PER_TICKS=secs_per_tick;
- INT32 clstarting_balance=gMPServerSettings.starting_balance;//set starting balance
+ INT32 clstarting_balance=gMPServerSettings.startingCash;//set starting balance
if(LaptopSaveInfo.iCurrentBalanceclient_num == CLIENT_NUM)
{
// store the setting locally
- _itoa(cl_lan->newedge,SECT_EDGE,10);
+ cStartingSectorEdge = cl_lan->newedge;
}
}
}
-
void recieveMAPCHANGE( RPCParameters *rpcParameters )
{
mapchange_struct* cl_lan = (mapchange_struct*)rpcParameters->input;
@@ -3149,7 +2740,7 @@ void recieveMAPCHANGE( RPCParameters *rpcParameters )
// WANNE - BMP:
InitializeWorldSize( gsMercArriveSectorX, gsMercArriveSectorY, 0 );
- gGameExternalOptions.iGameStartingTime= NUM_SEC_IN_DAY + int(cl_lan->TIME*3600);
+ gGameExternalOptions.iGameStartingTime= NUM_SEC_IN_DAY + int(cl_lan->startingTime*3600);
CHAR16 str[128];
GetSectorIDString( gsMercArriveSectorX, gsMercArriveSectorY, 0, str, TRUE );
@@ -3290,7 +2881,6 @@ void recieveGRENADERESULT (RPCParameters *rpcParameters)
SOLDIERTYPE* pThrower = MercPtrs[ gres->ubOwnerID ];
if (pThrower != NULL)
{
-
// grenade wasnt thrown by one of our guys, so we should do it on the client
if (!IsOurSoldier(pThrower) && (pThrower->bTeam != 1 || !is_server))
{
@@ -3659,7 +3249,7 @@ void recieveDISARMEXPLOSIVE (RPCParameters *rpcParameters)
SOLDIERTYPE * pBombOwner = MercPtrs[gWorldItems[ gWorldBombs[ uiCount ].iItemIndex ].soldierID];
if (pBombOwner != NULL)
{
- ScreenMsg( FONT_LTBLUE , MSG_MPSYSTEM , L"%s's bomb was disarmed by %s", pBombOwner->name, pSoldier->name);
+ ScreenMsg( FONT_LTBLUE , MSG_MPSYSTEM , MPClientMessage[71], pBombOwner->name, pSoldier->name);
}
}
@@ -3755,7 +3345,6 @@ void recieveSPREADEFFECT (RPCParameters *rpcParameters)
{
SpreadEffect( sef->sGridNo , sef->ubRadius , sef->usItem , sef->ubOwner , sef->fSubsequent , sef->bLevel , sef->iSmokeEffectID , TRUE);
}
-
}
}
else
@@ -3958,15 +3547,17 @@ void recieveBULLET(RPCParameters *rpcParameters)
if (iBullet == -1)
{
- ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"Failed to create bullet");
- }
-//add bullet to bullet table for translation
+#ifdef BETAVERSION
+ ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"Failed to create bullet");
+#endif
+
+ }
+
+ //add bullet to bullet table for translation
bTable[bTeam][net_iBullet].remote_id = net_iBullet;
bTable[bTeam][net_iBullet].local_id = iBullet;
-
-
pBullet = GetBulletPtr( iBullet );
//ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"Created Bullet Id: %d",iBullet);
@@ -3990,7 +3581,6 @@ void recieveBULLET(RPCParameters *rpcParameters)
pBullet->iDistanceLimit=netb->net_bullet.iDistanceLimit;
FireBullet( pFirer, pBullet, FALSE );
-
}
void send_changestate (EV_S_CHANGESTATE * SChangeState)
@@ -3999,14 +3589,10 @@ void send_changestate (EV_S_CHANGESTATE * SChangeState)
memcpy( &new_state , SChangeState, sizeof( EV_S_CHANGESTATE ));
- if(new_state.usSoldierID < 20)new_state.usSoldierID = new_state.usSoldierID+ubID_prefix;
+ if(new_state.usSoldierID < 20)
+ new_state.usSoldierID = new_state.usSoldierID+ubID_prefix;
-
-
client->RPC("sendSTATE",(const char*)&new_state, (int)sizeof(EV_S_CHANGESTATE)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- //ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"sent state");
-
-
}
void recieveSTATE(RPCParameters *rpcParameters)
@@ -4015,26 +3601,26 @@ void recieveSTATE(RPCParameters *rpcParameters)
SOLDIERTYPE * pSoldier=MercPtrs[ new_state->usSoldierID ];
- if(pSoldier->bActive)
+ if(pSoldier->bActive)
+ {
+ // Start first AID
+ if(new_state->usNewState==START_AID)
{
- // Start first AID
- if(new_state->usNewState==START_AID)
- {
- pSoldier->EVENT_InternalSetSoldierPosition( new_state->sXPos, new_state->sYPos ,FALSE, FALSE, FALSE );
- pSoldier->ChangeSoldierStance( ANIM_CROUCH );
- pSoldier->EVENT_SetSoldierDirection( new_state->usNewDirection );
+ pSoldier->EVENT_InternalSetSoldierPosition( new_state->sXPos, new_state->sYPos ,FALSE, FALSE, FALSE );
+ pSoldier->ChangeSoldierStance( ANIM_CROUCH );
+ pSoldier->EVENT_SetSoldierDirection( new_state->usNewDirection );
- }
- // Start cutting fence
- else if (new_state->usNewState==CUTTING_FENCE)
- {
- // The usTargetGridNo holds the GridNo of the fence tile
- pSoldier->sTargetGridNo = new_state->usTargetGridNo;
+ }
+ // Start cutting fence
+ else if (new_state->usNewState==CUTTING_FENCE)
+ {
+ // The usTargetGridNo holds the GridNo of the fence tile
+ pSoldier->sTargetGridNo = new_state->usTargetGridNo;
- pSoldier->EVENT_InternalSetSoldierPosition( new_state->sXPos, new_state->sYPos ,FALSE, FALSE, FALSE );
- pSoldier->ChangeSoldierStance( ANIM_CROUCH );
- pSoldier->EVENT_SetSoldierDirection( new_state->usNewDirection );
- }
+ pSoldier->EVENT_InternalSetSoldierPosition( new_state->sXPos, new_state->sYPos ,FALSE, FALSE, FALSE );
+ pSoldier->ChangeSoldierStance( ANIM_CROUCH );
+ pSoldier->EVENT_SetSoldierDirection( new_state->usNewDirection );
+ }
pSoldier->EVENT_InitNewSoldierAnim( new_state->usNewState, new_state->usStartingAniCode, new_state->fForce );
}
@@ -4049,7 +3635,6 @@ void send_death( SOLDIERTYPE *pSoldier )
// Translate soldier id for other clients if the soldier was one of ours
if(pSoldier->ubID<20)nDeath.soldier_id=nDeath.soldier_id+ubID_prefix;
-
// if soldier died from bleeding
if(pSoldier->ubAttackerID==NULL || pSoldier->ubAttackerID == NOBODY)
{
@@ -4084,14 +3669,13 @@ void send_death( SOLDIERTYPE *pSoldier )
nDeath.attacker_id = pAttacker->ubID;
}
-
-
// Translate attacker id for other clients if attacker was one of ours
if(pAttacker->ubID<20)nDeath.attacker_id=pAttacker->ubID+ubID_prefix;
pA_bTeam=pAttacker->bTeam;
memcpy(pA_name,pAttacker->name,sizeof(CHAR16)*10);
- if (pA_bTeam==1 && PLAYER_BSIDE==MP_TYPE_COOP)
+
+ if (pA_bTeam==1 && cGameType==MP_TYPE_COOP)
{
// CO-OP Kill by an enemy ai
pA_bTeam = 5; // the server subtracts 1 from these numbers to score in scoreboard, AI is index 4
@@ -4099,15 +3683,19 @@ void send_death( SOLDIERTYPE *pSoldier )
else
{
// Any mode, kill by a players merc
- if(pA_bTeam>5)pA_bTeam=pA_bTeam-5;
- if(pA_bTeam==0)pA_bTeam= CLIENT_NUM;
+ if(pA_bTeam>5)
+ pA_bTeam=pA_bTeam-5;
+
+ if(pA_bTeam==0)
+ pA_bTeam= CLIENT_NUM;
}
}
+
if(pSoldier)
{
pS_bTeam=pSoldier->bTeam;
memcpy(pS_name,pSoldier->name,sizeof(CHAR16)*10);
- if(pS_bTeam==1 && PLAYER_BSIDE==MP_TYPE_COOP)
+ if(pS_bTeam==1 && cGameType==MP_TYPE_COOP)
{
// CO-OP Death of an enemy ai
pS_bTeam = 5; // the server subtracts 1 from these numbers to score in scoreboard, AI is index 4
@@ -4115,8 +3703,11 @@ void send_death( SOLDIERTYPE *pSoldier )
else
{
// Any mode death of a players merc
- if(pS_bTeam>5)pS_bTeam=pS_bTeam-5;
- if(pS_bTeam==0)pS_bTeam=CLIENT_NUM;
+ if(pS_bTeam>5)
+ pS_bTeam=pS_bTeam-5;
+
+ if(pS_bTeam==0)
+ pS_bTeam=CLIENT_NUM;
}
}
@@ -4137,24 +3728,26 @@ void send_death( SOLDIERTYPE *pSoldier )
char a_name[10];
WideCharToMultiByte(CP_UTF8,0,pS_name,-1, s_name,10,NULL,NULL);
WideCharToMultiByte(CP_UTF8,0,pA_name,-1, a_name,10,NULL,NULL);
- if (pSoldier->bTeam==1) MPDebugMsg( String ( "MPDEBUG SEND - Enemy AI #%d was killed by ('%s' - %d) (client %d - '%s')\n",nDeath.soldier_id,a_name,nDeath.attacker_id,pA_bTeam,client_names[pA_bTeam-1]) );
- else if (pAttacker->bTeam==1) MPDebugMsg( String ( "MPDEBUG SEND - '%s' (client %d - '%S') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,"Queens Army") );
- else MPDebugMsg( String ( "MPDEBUG SEND - '%s' (client %d - '%S') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,client_names[(pA_bTeam-1)]) );
+
+ if (pSoldier->bTeam==1)
+ MPDebugMsg( String ( "MPDEBUG SEND - Enemy AI #%d was killed by ('%s' - %d) (client %d - '%s')\n",nDeath.soldier_id,a_name,nDeath.attacker_id,pA_bTeam,client_names[pA_bTeam-1]) );
+ else if (pAttacker->bTeam==1)
+ MPDebugMsg( String ( "MPDEBUG SEND - '%s' (client %d - '%S') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,"Queens Army") );
+ else
+ MPDebugMsg( String ( "MPDEBUG SEND - '%s' (client %d - '%S') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,client_names[(pA_bTeam-1)]) );
#endif
- //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[28],(pS_bTeam), pS_name,client_names[(pS_bTeam-1)],pA_name,(pA_bTeam),client_names[(pA_bTeam-1)] );
}
void recieveDEATH (RPCParameters *rpcParameters)
{
-
death_struct* nDeath = (death_struct*)rpcParameters->input;
SOLDIERTYPE * pSoldier=MercPtrs[ nDeath->soldier_id ];
UINT16 ubAttackerID;
- if((nDeath->attacker_id >= ubID_prefix) && (nDeath->attacker_id < (ubID_prefix+6)))
- ubAttackerID = (nDeath->attacker_id - ubID_prefix);
- else
- ubAttackerID = nDeath->attacker_id;
+ if((nDeath->attacker_id >= ubID_prefix) && (nDeath->attacker_id < (ubID_prefix+6)))
+ ubAttackerID = (nDeath->attacker_id - ubID_prefix);
+ else
+ ubAttackerID = nDeath->attacker_id;
SOLDIERTYPE * pAttacker=MercPtrs[ ubAttackerID ];
INT8 pA_bTeam;
@@ -4164,20 +3757,26 @@ void recieveDEATH (RPCParameters *rpcParameters)
if(pAttacker)
{
- pA_bTeam=pAttacker->bTeam;
- memcpy(pA_name,pAttacker->name,sizeof(CHAR16)*10);
- if(pA_bTeam>5)pA_bTeam=pA_bTeam-5;
- if(pA_bTeam==0)pA_bTeam=CLIENT_NUM;
+ pA_bTeam=pAttacker->bTeam;
+ memcpy(pA_name,pAttacker->name,sizeof(CHAR16)*10);
+
+ if(pA_bTeam>5)
+ pA_bTeam=pA_bTeam-5;
+ if(pA_bTeam==0)
+ pA_bTeam=CLIENT_NUM;
}
+
if(pSoldier)
{
- pS_bTeam=pSoldier->bTeam;
- memcpy(pS_name,pSoldier->name,sizeof(CHAR16)*10);
- if(pS_bTeam>5)pS_bTeam=pS_bTeam-5;
- if(pS_bTeam==0)pS_bTeam=CLIENT_NUM;
+ pS_bTeam=pSoldier->bTeam;
+ memcpy(pS_name,pSoldier->name,sizeof(CHAR16)*10);
+
+ if(pS_bTeam>5)
+ pS_bTeam=pS_bTeam-5;
+ if(pS_bTeam==0)
+ pS_bTeam=CLIENT_NUM;
}
-
if(pSoldier->bActive)
{
pSoldier->usAnimState=50;
@@ -4190,15 +3789,15 @@ void recieveDEATH (RPCParameters *rpcParameters)
TurnSoldierIntoCorpse( pSoldier, TRUE, TRUE );
- if ( CheckForEndOfBattle( FALSE ) )
- {
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"All over red rover...");
- }
+ if ( CheckForEndOfBattle( FALSE ) )
+ {
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[72]);
+ }
+
if (pSoldier->bTeam==1)
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, MPClientMessage[67]);
- else ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[28],pS_name,(pS_bTeam),client_names[(pS_bTeam-1)],pA_name,(pA_bTeam),client_names[(pA_bTeam-1)] );
- //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[28],(pS_bTeam),pS_name,client_names[(pS_bTeam-1)],pA_name,(pA_bTeam),client_names[(pA_bTeam-1)] );
-
+ else
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[28],pS_name,(pS_bTeam),client_names[(pS_bTeam-1)],pA_name,(pA_bTeam),client_names[(pA_bTeam-1)] );
}
else
{
@@ -4206,7 +3805,9 @@ void recieveDEATH (RPCParameters *rpcParameters)
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"merc already corpse/dead");
#endif
- if (pSoldier->bTeam==1) ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, MPClientMessage[67]);
+ if (pSoldier->bTeam==1)
+ ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, MPClientMessage[67]);
+
CheckForEndOfBattle( FALSE );
}
@@ -4215,9 +3816,13 @@ void recieveDEATH (RPCParameters *rpcParameters)
char a_name[10];
WideCharToMultiByte(CP_UTF8,0,pS_name,-1, s_name,10,NULL,NULL);
WideCharToMultiByte(CP_UTF8,0,pA_name,-1, a_name,10,NULL,NULL);
- if (pSoldier->bTeam==1) MPDebugMsg( String ( "MPDEBUG RECV - Enemy AI #%d was killed by ('%s' - #%d) (client %d - '%s')\n",nDeath->soldier_id,a_name,nDeath->attacker_id,pA_bTeam,client_names[pA_bTeam-1]) );
- else if (pAttacker->bTeam==1) MPDebugMsg( String ( "MPDEBUG RECV - '%s' (client %d - '%s') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,"Queens Army") );
- else MPDebugMsg( String ( "MPDEBUG RECV - '%s' (client %d - '%s') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,client_names[(pA_bTeam-1)]) );
+
+ if (pSoldier->bTeam==1)
+ MPDebugMsg( String ( "MPDEBUG RECV - Enemy AI #%d was killed by ('%s' - #%d) (client %d - '%s')\n",nDeath->soldier_id,a_name,nDeath->attacker_id,pA_bTeam,client_names[pA_bTeam-1]) );
+ else if (pAttacker->bTeam==1)
+ MPDebugMsg( String ( "MPDEBUG RECV - '%s' (client %d - '%s') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,"Queens Army") );
+ else
+ MPDebugMsg( String ( "MPDEBUG RECV - '%s' (client %d - '%s') was killed by '%s' (client %d - '%s')\n",s_name,pS_bTeam,client_names[(pS_bTeam-1)],a_name,pA_bTeam,client_names[(pA_bTeam-1)]) );
#endif
}
@@ -4227,77 +3832,62 @@ void send_hitstruct(EV_S_STRUCTUREHIT * SStructureHit)
memcpy( &struct_hit , SStructureHit, sizeof( EV_S_STRUCTUREHIT ));
if(SStructureHit->ubAttackerID <20)struct_hit.ubAttackerID = SStructureHit->ubAttackerID+ubID_prefix;
-
client->RPC("sendhitSTRUCT",(const char*)&struct_hit, (int)sizeof(EV_S_STRUCTUREHIT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
}
void send_hitwindow(EV_S_WINDOWHIT * SWindowHit)
{
- EV_S_WINDOWHIT window_hit;
+ EV_S_WINDOWHIT window_hit;
memcpy( &window_hit , SWindowHit, sizeof( EV_S_WINDOWHIT ));
- if(SWindowHit->ubAttackerID <20)window_hit.ubAttackerID = SWindowHit->ubAttackerID+ubID_prefix;
+
+ if(SWindowHit->ubAttackerID <20)
+ window_hit.ubAttackerID = SWindowHit->ubAttackerID+ubID_prefix;
-
client->RPC("sendhitWINDOW",(const char*)&window_hit, (int)sizeof(EV_S_WINDOWHIT)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void send_miss(EV_S_MISS * SMiss)
{
-
- EV_S_MISS shot_miss;
+ EV_S_MISS shot_miss;
memcpy( &shot_miss , SMiss, sizeof( EV_S_MISS ));
- if(SMiss->ubAttackerID <20)shot_miss.ubAttackerID = SMiss->ubAttackerID+ubID_prefix;
+
+ if(SMiss->ubAttackerID <20)
+ shot_miss.ubAttackerID = SMiss->ubAttackerID+ubID_prefix;
-
client->RPC("sendMISS",(const char*)&shot_miss, (int)sizeof(EV_S_MISS)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recievehitSTRUCT (RPCParameters *rpcParameters)
{
EV_S_STRUCTUREHIT* struct_hit = (EV_S_STRUCTUREHIT*)rpcParameters->input;
- //ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"recieved structure hit");
- SOLDIERTYPE *pSoldier = MercPtrs[ struct_hit->ubAttackerID ];
- INT8 bTeam=pSoldier->bTeam;
- INT32 iBullet = bTable[bTeam][struct_hit->iBullet].local_id;
+ SOLDIERTYPE *pSoldier = MercPtrs[ struct_hit->ubAttackerID ];
+ INT8 bTeam=pSoldier->bTeam;
+ INT32 iBullet = bTable[bTeam][struct_hit->iBullet].local_id;
+ if(struct_hit->fStopped)
+ StopBullet( iBullet );
- if(struct_hit->fStopped)StopBullet( iBullet );//, ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"bullet stopped");
StructureHit( iBullet, struct_hit->usWeaponIndex, struct_hit->bWeaponStatus, struct_hit->ubAttackerID, struct_hit->sXPos, struct_hit->sYPos, struct_hit->sZPos, struct_hit->usStructureID, struct_hit->iImpact, struct_hit->fStopped );
- if(struct_hit->fStopped)RemoveBullet(iBullet);//, ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"bullet removed");
- //else ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"bullet left");
+ if(struct_hit->fStopped)
+ RemoveBullet(iBullet);
}
+
void recievehitWINDOW (RPCParameters *rpcParameters)
{
EV_S_WINDOWHIT* window_hit = (EV_S_WINDOWHIT*)rpcParameters->input;
-
-
-
WindowHit( window_hit->sGridNo, window_hit->usStructureID, window_hit->fBlowWindowSouth, window_hit->fLargeForce );
-
- //ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"recieved window hit");
}
+
void recieveMISS (RPCParameters *rpcParameters)
{
EV_S_MISS* shot_miss = (EV_S_MISS*)rpcParameters->input;
- SOLDIERTYPE *pSoldier = MercPtrs[ shot_miss->ubAttackerID ];
- INT8 bTeam=pSoldier->bTeam;
- INT32 iBullet = bTable[bTeam][shot_miss->iBullet].local_id;
-
+ SOLDIERTYPE *pSoldier = MercPtrs[ shot_miss->ubAttackerID ];
+ INT8 bTeam=pSoldier->bTeam;
+ INT32 iBullet = bTable[bTeam][shot_miss->iBullet].local_id;
ShotMiss( shot_miss->ubAttackerID, iBullet );
- //ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"recieved shot miss");
-}
-
-void cheat_func(void)
-{
- if(TESTING)
- {
- ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"gTacticalStatus.uiFlags |= SHOW_ALL_MERCS");
- gTacticalStatus.uiFlags |= SHOW_ALL_MERCS;
- }
}
BOOLEAN check_status (void)// any 'enemies' and clients left to fight ??
@@ -4321,19 +3911,20 @@ BOOLEAN check_status (void)// any 'enemies' and clients left to fight ??
soldiers++;
}
}
+
if(soldiers>0)
{
gTacticalStatus.Team[ x ].bTeamActive=1;
gTacticalStatus.Team[ x ].bMenInSector=soldiers;
- if (PLAYER_BSIDE==1 && (x==0 || x>5))
+ if (cGameType==MP_TYPE_TEAMDEATMATCH && (x==0 || x>5))
{
// store the number of active DM teams, and number of players per team still alive
int cl_num = CLIENT_NUM; // 1 based
if (x>5) cl_num = x - 5;
dm_teams[ client_teams[ cl_num - 1 ] ]++;
}
- else if (PLAYER_BSIDE != 1)
+ else if (cGameType != MP_TYPE_TEAMDEATMATCH)
{
// count number of active teams
numActiveSides++;
@@ -4345,29 +3936,31 @@ BOOLEAN check_status (void)// any 'enemies' and clients left to fight ??
gTacticalStatus.Team[x].bMenInSector=0;
}
}
+
if( (gTacticalStatus.Team[ 0 ].bTeamActive == 0) && wiped==0)//server's team has been knocked out
{
wiped=1;
ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[40] );
- if(!DISABLE_SPEC_MODE)
+ if(!cDisableSpectatorMode)
{
gTacticalStatus.uiFlags |= SHOW_ALL_MERCS;//hayden
ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, MPClientMessage[41] );
}
else
- ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"spectator mode disabled");
+ {
+ ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPClientMessage[73]);
+ }
teamwiped();
-
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[42] );
}
- if (PLAYER_BSIDE == 0)
+ if (cGameType == MP_TYPE_DEATHMATCH)
{
// check game end for DeathMatch
return (numActiveSides > 1);
}
- else if (PLAYER_BSIDE == 1)
+ else if (cGameType == MP_TYPE_TEAMDEATMATCH)
{
// check game end for Team Deathmatch
// count how many active deathmatch teams are alive (two players could be alive but might be on the same TEAM)
@@ -4381,7 +3974,7 @@ BOOLEAN check_status (void)// any 'enemies' and clients left to fight ??
return (numActiveSides > 1);
}
- else if (PLAYER_BSIDE == 2)
+ else if (cGameType == MP_TYPE_COOP)
{
// check for game end for CO-OP
// If any player team is alive && the number of enemies > 0 then continue game (true), else quit (false)
@@ -4394,9 +3987,9 @@ BOOLEAN check_status (void)// any 'enemies' and clients left to fight ??
void UpdateSoldierToNetwork ( SOLDIERTYPE *pSoldier )
{
- //this send stats to other clients at intervals
- UINT8 id = pSoldier->ubID;
- UINT32 time = GetJA2Clock();
+ //this send stats to other clients at intervals
+ UINT8 id = pSoldier->ubID;
+ UINT32 time = GetJA2Clock();
if(id < 20 || (is_server && id <120))
{
@@ -4407,13 +4000,13 @@ void UpdateSoldierToNetwork ( SOLDIERTYPE *pSoldier )
if((time - (pSoldier->usLastUpdateTime)) > 2000 && pSoldier->stats.bLife!=0)
{
pSoldier->usLastUpdateTime = time;
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"update: %d ",time );
-
EV_S_UPDATENETWORKSOLDIER SUpdateNetworkSoldier;
SUpdateNetworkSoldier.usSoldierID=pSoldier->ubID;
- if(pSoldier->ubID < 20)SUpdateNetworkSoldier.usSoldierID=pSoldier->ubID+ubID_prefix;
+
+ if(pSoldier->ubID < 20)
+ SUpdateNetworkSoldier.usSoldierID=pSoldier->ubID+ubID_prefix;
SUpdateNetworkSoldier.sAtGridNo=pSoldier->sGridNo;
SUpdateNetworkSoldier.bBreath=pSoldier->bBreath;
@@ -4423,7 +4016,6 @@ void UpdateSoldierToNetwork ( SOLDIERTYPE *pSoldier )
SUpdateNetworkSoldier.bBleeding=pSoldier->bBleeding;
SUpdateNetworkSoldier.ubNewStance= gAnimControl[ pSoldier->usAnimState ].ubEndHeight;
-
if((gTacticalStatus.ubTopMessageType == PLAYER_TURN_MESSAGE || gTacticalStatus.ubTopMessageType == PLAYER_INTERRUPT_MESSAGE || ((gTacticalStatus.ubTopMessageType == COMPUTER_INTERRUPT_MESSAGE || gTacticalStatus.ubTopMessageType == COMPUTER_TURN_MESSAGE )&& is_server)) && (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT))//update progress bar, not supporting coop yet...
{
SUpdateNetworkSoldier.usTactialTurnLimitCounter = gTacticalStatus.usTactialTurnLimitCounter;
@@ -4432,9 +4024,7 @@ void UpdateSoldierToNetwork ( SOLDIERTYPE *pSoldier )
else
SUpdateNetworkSoldier.usTactialTurnLimitCounter = 9999;
-
client->RPC("updatenetworksoldier",(const char*)&SUpdateNetworkSoldier, (int)sizeof(EV_S_UPDATENETWORKSOLDIER)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
}
}
}
@@ -4447,38 +4037,30 @@ void UpdateSoldierFromNetwork (RPCParameters *rpcParameters)
pSoldier->bBreath=SUpdateNetworkSoldier->bBreath;
pSoldier->stats.bLife=SUpdateNetworkSoldier->bLife;
+ INT16 sCellX, sCellY;
+ sCellX = CenterX( SUpdateNetworkSoldier->sAtGridNo );
+ sCellY = CenterY( SUpdateNetworkSoldier->sAtGridNo );
+ if( pSoldier->sGridNo != SUpdateNetworkSoldier->sAtGridNo)
+ {
+ pSoldier->EVENT_InternalSetSoldierPosition( sCellX, sCellY ,FALSE, FALSE, FALSE );//new syncing call to correct network lag/drift
+ }
-
- INT16 sCellX, sCellY;
- sCellX = CenterX( SUpdateNetworkSoldier->sAtGridNo );
- sCellY = CenterY( SUpdateNetworkSoldier->sAtGridNo );
-
- if( pSoldier->sGridNo != SUpdateNetworkSoldier->sAtGridNo)
- {
- pSoldier->EVENT_InternalSetSoldierPosition( sCellX, sCellY ,FALSE, FALSE, FALSE );//new syncing call to correct network lag/drift
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"sync ubid:%d grid %d to %d",pSoldier->ubID,pSoldier->sGridNo,SUpdateNetworkSoldier->sAtGridNo );
- }
-
- if(pSoldier->ubDirection != SUpdateNetworkSoldier->ubDirection)
- {
- pSoldier->EVENT_SetSoldierDesiredDirection( SUpdateNetworkSoldier->ubDirection );
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"sync ubid:%d dir %d to %d",pSoldier->ubID, pSoldier->ubDirection, SUpdateNetworkSoldier->ubDirection );
- }
- if(gAnimControl[ pSoldier->usAnimState ].ubEndHeight != SUpdateNetworkSoldier->ubNewStance && pSoldier->bCollapsed != TRUE)
- {
- pSoldier->ChangeSoldierStance( SUpdateNetworkSoldier->ubNewStance );
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"update stance");
- }
+ if(pSoldier->ubDirection != SUpdateNetworkSoldier->ubDirection)
+ {
+ pSoldier->EVENT_SetSoldierDesiredDirection( SUpdateNetworkSoldier->ubDirection );
+ }
+ if(gAnimControl[ pSoldier->usAnimState ].ubEndHeight != SUpdateNetworkSoldier->ubNewStance && pSoldier->bCollapsed != TRUE)
+ {
+ pSoldier->ChangeSoldierStance( SUpdateNetworkSoldier->ubNewStance );
+ }
-
pSoldier->bBleeding=SUpdateNetworkSoldier->bBleeding;
if( (SUpdateNetworkSoldier->usTactialTurnLimitCounter != 9999) && (gTacticalStatus.ubTopMessageType != PLAYER_TURN_MESSAGE) && (gTacticalStatus.ubTopMessageType != PLAYER_INTERRUPT_MESSAGE))
{
gTacticalStatus.usTactialTurnLimitCounter = SUpdateNetworkSoldier->usTactialTurnLimitCounter;
gTacticalStatus.usTactialTurnLimitMax = SUpdateNetworkSoldier->usTactialTurnLimitMax;
-
}
}
@@ -4487,25 +4069,23 @@ void kick_player (void)
{
if(is_server)
{
- //manual overide command for server
- const STR16 msg = L"Choose Client Number to Kick:";
-
- SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
- DoMessageBox( MSG_BOX_BASIC_STYLE, msg, guiCurrentScreen, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS | MSG_BOX_FLAG_USE_CENTERING_RECT, kick_callback, &CenterRect );
+ //manual overide command for server
+ const STR16 msg = MPClientMessage[74];
+ SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
+ DoMessageBox( MSG_BOX_BASIC_STYLE, msg, guiCurrentScreen, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS | MSG_BOX_FLAG_USE_CENTERING_RECT, kick_callback, &CenterRect );
}
- else ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[22] );
+ else
+ ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[22] );
}
+
void kick_callback (UINT8 ubResult)
-{
-
+{
kickR kick;
kick.ubResult=ubResult+5;
- //ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"kicking client " );
client->RPC("Snull_team",(const char*)&kick, (int)sizeof(kickR)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
}
void null_team (RPCParameters *rpcParameters)
@@ -4514,125 +4094,111 @@ void null_team (RPCParameters *rpcParameters)
ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[29],(kick->ubResult-5),client_names[kick->ubResult-6] );
int fID = gTacticalStatus.Team[ kick->ubResult ].bFirstID;
int lID = gTacticalStatus.Team[ kick->ubResult ].bLastID;
-
- if(kick->ubResult==netbTeam)fID=0,lID=19;
+
+ if(kick->ubResult==netbTeam)
+ fID=0,lID=19;
+
int cnt;
for ( cnt=fID ; cnt <= lID; cnt++ )
{
TacticalRemoveSoldier( cnt );
}
-
}
void overide_turn (void)
{
if(is_server)
{
- //manual overide command for server
- //const STR16 msg = MPClientMessage[30];
+ //manual overide command for server
CHAR16 Cmsg[255];
swprintf(Cmsg, MPClientMessage[30], client_names[0],client_names[1],client_names[2],client_names[3]);
-
-
- SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
- DoMessageBox( MSG_BOX_BASIC_STYLE, Cmsg, guiCurrentScreen, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS | MSG_BOX_FLAG_USE_CENTERING_RECT, turn_callback, &CenterRect );
-
+ SGPRect CenterRect = { 100, 100, SCREEN_WIDTH - 100, 300 };
+ DoMessageBox( MSG_BOX_BASIC_STYLE, Cmsg, guiCurrentScreen, MSG_BOX_FLAG_FOUR_NUMBERED_BUTTONS | MSG_BOX_FLAG_USE_CENTERING_RECT, turn_callback, &CenterRect );
}
- else ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[22] );
-
+ else
+ ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[22] );
}
void turn_callback (UINT8 ubResult)
{
-
if(is_server)
{
ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[31],ubResult );
- if(!( gTacticalStatus.uiFlags & INCOMBAT ))
- {
- gTacticalStatus.uiFlags |= INCOMBAT;
- }
- if(ubResult ==1)EndTurn( 0 );
- else EndTurn( ubResult+5 );
+ if(!( gTacticalStatus.uiFlags & INCOMBAT ))
+ {
+ gTacticalStatus.uiFlags |= INCOMBAT;
+ }
+
+ if(ubResult ==1)
+ EndTurn( 0 );
+ else
+ EndTurn( ubResult+5 );
}
}
void send_fireweapon (EV_S_FIREWEAPON *SFireWeapon)
{
- EV_S_FIREWEAPON sFire;
- //sFire.usSoldierID=SFireWeapon->usSoldierID;
+ EV_S_FIREWEAPON sFire;
- if(SFireWeapon->usSoldierID < 20)
- sFire.usSoldierID = (SFireWeapon->usSoldierID)+ubID_prefix;
- else
- sFire.usSoldierID = SFireWeapon->usSoldierID;
+ if(SFireWeapon->usSoldierID < 20)
+ sFire.usSoldierID = (SFireWeapon->usSoldierID)+ubID_prefix;
+ else
+ sFire.usSoldierID = SFireWeapon->usSoldierID;
- sFire.sTargetGridNo=SFireWeapon->sTargetGridNo;
- sFire.bTargetCubeLevel=SFireWeapon->bTargetCubeLevel;
- sFire.bTargetLevel=SFireWeapon->bTargetLevel;
-
- client->RPC("sendFIREW",(const char*)&sFire, (int)sizeof(EV_S_FIREWEAPON)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ sFire.sTargetGridNo=SFireWeapon->sTargetGridNo;
+ sFire.bTargetCubeLevel=SFireWeapon->bTargetCubeLevel;
+ sFire.bTargetLevel=SFireWeapon->bTargetLevel;
+ client->RPC("sendFIREW",(const char*)&sFire, (int)sizeof(EV_S_FIREWEAPON)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void recieve_fireweapon (RPCParameters *rpcParameters)
{
- EV_S_FIREWEAPON* SFireWeapon = (EV_S_FIREWEAPON*)rpcParameters->input;
- //ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"recieve_fireweapon" );
- //SFireWeapon.usSoldierID = pSoldier->ubID;
- ////SFireWeapon.uiUniqueId = pSoldier->uiUniqueSoldierIdValue;
- //SFireWeapon.sTargetGridNo = pSoldier->sTargetGridNo;
- //SFireWeapon.bTargetLevel = pSoldier->bTargetLevel;
- //SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel;
- //AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon );
+ EV_S_FIREWEAPON* SFireWeapon = (EV_S_FIREWEAPON*)rpcParameters->input;
SOLDIERTYPE *pSoldier = MercPtrs[ SFireWeapon->usSoldierID ];
- pSoldier->sTargetGridNo = SFireWeapon->sTargetGridNo;
- pSoldier->bTargetLevel = SFireWeapon->bTargetLevel;
- pSoldier->bTargetCubeLevel = SFireWeapon->bTargetCubeLevel;
- FireWeapon( pSoldier, SFireWeapon->sTargetGridNo );
-
+ pSoldier->sTargetGridNo = SFireWeapon->sTargetGridNo;
+ pSoldier->bTargetLevel = SFireWeapon->bTargetLevel;
+ pSoldier->bTargetCubeLevel = SFireWeapon->bTargetCubeLevel;
+ FireWeapon( pSoldier, SFireWeapon->sTargetGridNo );
}
void send_door ( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fNoAnimations )
{
-if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) )
-{
+ if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) )
+ {
doors sDoor;
sDoor.ubID=pSoldier->ubID;
sDoor.sGridNo=sGridNo;
sDoor.fNoAnimations=fNoAnimations;
-
+
client->RPC("sendDOOR",(const char*)&sDoor, (int)sizeof(doors)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-}
+ }
}
void recieve_door (RPCParameters *rpcParameters)
{
-
doors* sDoor = (doors*)rpcParameters->input;
SOLDIERTYPE *pSoldier = MercPtrs[ sDoor->ubID ];
BOOLEAN fNoAnimations = FALSE;
- if ( !AllMercsLookForDoor( sDoor->sGridNo, FALSE ) )//check for los
- {
- fNoAnimations = TRUE;
- }
-
+ if ( !AllMercsLookForDoor( sDoor->sGridNo, FALSE ) )//check for los
+ {
+ fNoAnimations = TRUE;
+ }
HandleDoorChangeFromGridNo( pSoldier, sDoor->sGridNo, fNoAnimations );
-
}
void recieveCHATMSG(RPCParameters* rpcParameters)
{
chat_msg* cmsg = (chat_msg*)rpcParameters->input;
- if (PLAYER_BSIDE==1 && cmsg->bToAll == false)
+ if (cGameType==MP_TYPE_TEAMDEATMATCH && cmsg->bToAll == false)
{
// If Team deathmatch && msg is allies only
if (client_teams[cmsg->client_num-1] == TEAM)
@@ -4703,7 +4269,6 @@ void recieveDISCONNECT(RPCParameters* rpcParameters)
if(gTacticalStatus.ubCurrentTeam==iNetbTeam)EndTurn( iNetbTeam+1 );
}
}
-
}
// OJW - 20090507
@@ -4758,7 +4323,6 @@ void disconnected_callback(UINT8 ubResult)
// else dont clean "everything" but still exit to main menu
SetPendingNewScreen(MAINMENU_SCREEN);
}
-
}
// Gracefully handle self-disconnection of the client by Dropout
@@ -4792,7 +4356,6 @@ void HandleClientConnectionLost()
// Tell the score screen it can continue
gfMPSScoreScreenCanContinue = TRUE;
}
-
}
void sendRT(void)
@@ -4806,7 +4369,6 @@ void sendRT(void)
client->RPC("sendREAL",(const char*)&rData, (int)sizeof(real_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
-
}
void gotoRT(RPCParameters *rpcParameters)
@@ -4819,31 +4381,28 @@ void gotoRT(RPCParameters *rpcParameters)
ExitCombatMode();
fInterfacePanelDirty = DIRTYLEVEL2;
-
-
if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[34] );
-
-
}
else
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, MPClientMessage[33] );
}
-getReal=false;
+ getReal=false;
}
void startCombat(UINT8 ubStartingTeam)
{
- sc_struct data;
- if(ubStartingTeam==0)
- ubStartingTeam=netbTeam;
- data.ubStartingTeam=ubStartingTeam;
- client->RPC("startCOMBAT",(const char*)&data, (int)sizeof(sc_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
+ sc_struct data;
+ if(ubStartingTeam==0)
+ ubStartingTeam=netbTeam;
+
+ data.ubStartingTeam=ubStartingTeam;
+
+ client->RPC("startCOMBAT",(const char*)&data, (int)sizeof(sc_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
void teamwiped ( void )
@@ -4858,30 +4417,29 @@ void teamwiped ( void )
if (is_server)
{
// end the co-op game if all player teams have wiped
- if (PLAYER_BSIDE==MP_TYPE_COOP)
+ if (cGameType==MP_TYPE_COOP)
{
iTeamsWiped++;
- if (iTeamsWiped >= MAX_CLIENTS)
+ if (iTeamsWiped >= cMaxClients)
game_over();
}
}
}
void recieve_wipe (RPCParameters *rpcParameters)
-
{
sc_struct* data = (sc_struct*)rpcParameters->input;
- ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"Team #%d is wiped out.", data->ubStartingTeam );
+ ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, MPClientMessage[75], data->ubStartingTeam );
if(is_server)
{
if(gTacticalStatus.ubCurrentTeam==data->ubStartingTeam)EndTurn( data->ubStartingTeam+1 );
// end the co-op game if all player teams have wiped
- if (PLAYER_BSIDE==MP_TYPE_COOP)
+ if (cGameType==MP_TYPE_COOP)
{
iTeamsWiped++;
- if (iTeamsWiped >= MAX_CLIENTS)
+ if (iTeamsWiped >= cMaxClients)
game_over();
}
}
@@ -4894,36 +4452,38 @@ void send_heal (SOLDIERTYPE *pSoldier )
data.bLife=pSoldier->stats.bLife;
data.bBleeding=pSoldier->bBleeding;
-
client->RPC("sendHEAL",(const char*)&data, (int)sizeof(heal)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
-
}
void recieve_heal (RPCParameters *rpcParameters)
{
heal* data = (heal*)rpcParameters->input;
-
UINT16 healed;
- if((data->ubID >= ubID_prefix) && (data->ubID < (ubID_prefix+6)))
- healed = (data->ubID - ubID_prefix);
- else
- healed = data->ubID;
+
+ if((data->ubID >= ubID_prefix) && (data->ubID < (ubID_prefix+6)))
+ healed = (data->ubID - ubID_prefix);
+ else
+ healed = data->ubID;
SOLDIERTYPE *pSoldier = MercPtrs[ healed ];
pSoldier->bBleeding=data->bBleeding;
pSoldier->stats.bLife=data->bLife;
+
+#if BETAVERSION
ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"healing..." );
-
+#endif
}
-
void requestAIint(SOLDIERTYPE *pSoldier )
{
AIint data;
data.ubID=pSoldier->ubID;
data.bteam=netbTeam;
+
+#ifdef BETAVERSION
ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"interrupt requested" );
+#endif
client->RPC("rINT",(const char*)&data, (int)sizeof(AIint)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
@@ -4934,17 +4494,17 @@ void awardINT (RPCParameters *rpcParameters)
SOLDIERTYPE *pSoldier = MercPtrs[ data->ubID ];
- StartInterrupt();
- //send_EndTurn(netbTeam);
+ StartInterrupt();
+#ifdef BETAVERSION
ScreenMsg( FONT_LTGREEN, MSG_INTERFACE, L"interrupt awarded" );
+#endif
}
void game_over()
{
// wait 3 seconds then notify all clients
-
// reset
isOwnTeamWipedOut = false;
@@ -4983,312 +4543,198 @@ void recieveGAMEOVER(RPCParameters *rpcParameters)
StartScoreScreen();
}
-
//***************************
//*** client connection*****
//*************************
void connect_client ( void )
{
-
- if(!is_client)
- {
- ScreenMsg( FONT_BEIGE, MSG_MPSYSTEM, MPClientMessage[0] );
-
+ if(!is_client)
+ {
+ ScreenMsg( FONT_BEIGE, MSG_MPSYSTEM, MPClientMessage[0] );
-
+ client = RakNetworkFactory::GetRakPeerInterface();
+ bool b = client->Startup(1,30,&SocketDescriptor(), 1);
+
+ //RPC's
+ REGISTER_STATIC_RPC(client, recievePATH);
+ REGISTER_STATIC_RPC(client, recieveSTANCE);
+ REGISTER_STATIC_RPC(client, recieveDIR);
+ REGISTER_STATIC_RPC(client, recieveFIRE);
+ REGISTER_STATIC_RPC(client, recieveHIT);
+ REGISTER_STATIC_RPC(client, recieveHIRE);
+ REGISTER_STATIC_RPC(client, recieveDISMISS);
+ REGISTER_STATIC_RPC(client, recieveguiPOS);
+ REGISTER_STATIC_RPC(client, recieveguiDIR);
+ REGISTER_STATIC_RPC(client, recieveEndTurn);
+ REGISTER_STATIC_RPC(client, recieveAI);
+ REGISTER_STATIC_RPC(client, recieveSTOP);
+ REGISTER_STATIC_RPC(client, recieveINTERRUPT);
+ REGISTER_STATIC_RPC(client, recieveREADY);
+ REGISTER_STATIC_RPC(client, recieveGUI);
+ REGISTER_STATIC_RPC(client, recieveSETTINGS);
+ REGISTER_STATIC_RPC(client, recieveDOWNLOADSTATUS);
+ REGISTER_STATIC_RPC(client, recieveFILE_TRANSFER_SETTINGS);
+ REGISTER_STATIC_RPC(client, recieveTEAMCHANGE);
+ REGISTER_STATIC_RPC(client, recieveEDGECHANGE);
+ REGISTER_STATIC_RPC(client, recieveMAPCHANGE);
+ REGISTER_STATIC_RPC(client, recieveBULLET);
+ REGISTER_STATIC_RPC(client, recieveGRENADE);
+ REGISTER_STATIC_RPC(client, recieveGRENADERESULT);
+ REGISTER_STATIC_RPC(client, recievePLANTEXPLOSIVE);
+ REGISTER_STATIC_RPC(client, recieveDETONATEEXPLOSIVE);
+ REGISTER_STATIC_RPC(client, recieveDISARMEXPLOSIVE);
+ REGISTER_STATIC_RPC(client, recieveSPREADEFFECT);
+ REGISTER_STATIC_RPC(client, recieveNEWSMOKEEFFECT);
+ REGISTER_STATIC_RPC(client, recieveEXPLOSIONDAMAGE);
+ REGISTER_STATIC_RPC(client, recieveSTATE);
+ REGISTER_STATIC_RPC(client, recieveDEATH);
+ REGISTER_STATIC_RPC(client, recievehitSTRUCT);
+ REGISTER_STATIC_RPC(client, recievehitWINDOW);
+ REGISTER_STATIC_RPC(client, recieveMISS);
+ REGISTER_STATIC_RPC(client, resume_turn);
+ REGISTER_STATIC_RPC(client, UpdateSoldierFromNetwork);
+ REGISTER_STATIC_RPC(client, recieve_fireweapon);
+ REGISTER_STATIC_RPC(client, recieve_door);
+ REGISTER_STATIC_RPC(client, null_team);
+ REGISTER_STATIC_RPC(client, gotoRT);
+ REGISTER_STATIC_RPC(client, recieve_wipe);
+ REGISTER_STATIC_RPC(client, recieve_heal);
+ REGISTER_STATIC_RPC(client, awardINT);
+ REGISTER_STATIC_RPC(client, recieveGAMEOVER);
+ REGISTER_STATIC_RPC(client, recieveDISCONNECT);
+ REGISTER_STATIC_RPC(client, recieveCHATMSG);
+ REGISTER_STATIC_RPC(client, requestSETID);
+ REGISTER_STATIC_RPC(client, recieveDISCONNECTREASON);
+ //***
- client=RakNetworkFactory::GetRakPeerInterface();
- bool b = client->Startup(1,30,&SocketDescriptor(), 1);
-
- //RPC's
- REGISTER_STATIC_RPC(client, recievePATH);
- REGISTER_STATIC_RPC(client, recieveSTANCE);
- REGISTER_STATIC_RPC(client, recieveDIR);
- REGISTER_STATIC_RPC(client, recieveFIRE);
- REGISTER_STATIC_RPC(client, recieveHIT);
- REGISTER_STATIC_RPC(client, recieveHIRE);
- REGISTER_STATIC_RPC(client, recieveDISMISS);
- REGISTER_STATIC_RPC(client, recieveguiPOS);
- REGISTER_STATIC_RPC(client, recieveguiDIR);
- REGISTER_STATIC_RPC(client, recieveEndTurn);
- REGISTER_STATIC_RPC(client, recieveAI);
- REGISTER_STATIC_RPC(client, recieveSTOP);
- REGISTER_STATIC_RPC(client, recieveINTERRUPT);
- REGISTER_STATIC_RPC(client, recieveREADY);
- REGISTER_STATIC_RPC(client, recieveGUI);
- REGISTER_STATIC_RPC(client, recieveSETTINGS);
- REGISTER_STATIC_RPC(client, recieveDOWNLOADSTATUS);
- REGISTER_STATIC_RPC(client, recieveFILE_TRANSFER_SETTINGS);
- REGISTER_STATIC_RPC(client, recieveTEAMCHANGE);
- REGISTER_STATIC_RPC(client, recieveEDGECHANGE);
- REGISTER_STATIC_RPC(client, recieveMAPCHANGE);
- REGISTER_STATIC_RPC(client, recieveBULLET);
- REGISTER_STATIC_RPC(client, recieveGRENADE);
- REGISTER_STATIC_RPC(client, recieveGRENADERESULT);
- REGISTER_STATIC_RPC(client, recievePLANTEXPLOSIVE);
- REGISTER_STATIC_RPC(client, recieveDETONATEEXPLOSIVE);
- REGISTER_STATIC_RPC(client, recieveDISARMEXPLOSIVE);
- REGISTER_STATIC_RPC(client, recieveSPREADEFFECT);
- REGISTER_STATIC_RPC(client, recieveNEWSMOKEEFFECT);
- REGISTER_STATIC_RPC(client, recieveEXPLOSIONDAMAGE);
- REGISTER_STATIC_RPC(client, recieveSTATE);
- REGISTER_STATIC_RPC(client, recieveDEATH);
- REGISTER_STATIC_RPC(client, recievehitSTRUCT);
- REGISTER_STATIC_RPC(client, recievehitWINDOW);
- REGISTER_STATIC_RPC(client, recieveMISS);
- REGISTER_STATIC_RPC(client, resume_turn);
- REGISTER_STATIC_RPC(client, UpdateSoldierFromNetwork);
- REGISTER_STATIC_RPC(client, recieve_fireweapon);
- REGISTER_STATIC_RPC(client, recieve_door);
- REGISTER_STATIC_RPC(client, null_team);
- REGISTER_STATIC_RPC(client, gotoRT);
- REGISTER_STATIC_RPC(client, recieve_wipe);
- REGISTER_STATIC_RPC(client, recieve_heal);
- REGISTER_STATIC_RPC(client, awardINT);
- REGISTER_STATIC_RPC(client, recieveGAMEOVER);
- REGISTER_STATIC_RPC(client, recieveDISCONNECT);
- REGISTER_STATIC_RPC(client, recieveCHATMSG);
- REGISTER_STATIC_RPC(client, requestSETID);
- REGISTER_STATIC_RPC(client, recieveDISCONNECTREASON);
- //***
-
if (b)
{
- //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"Client started, waiting for connections...");
is_client=true;
}
else
{
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"Client failed to start. Terminating.");
-
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[76]);
}
is_connected=false;
-
+ }
+ //reconnect/connect
+ if( !is_connected && !is_connecting)
+ {
+ gTacticalStatus.uiFlags&= (~SHOW_ALL_MERCS );
+
+ memset( &readyteamreg , 0 , sizeof (int) * 10);
+ //OJW - 20081204
+ memset ( &client_names,NULL,sizeof(int)*4);
+ memset ( &client_ready,0,sizeof(int)*4);
+ memset ( &client_teams,0,sizeof(int)*4);
+
+ if (!gRandomStartingEdge)
+ memset ( &client_edges,0,sizeof(int)*5);
+
+ if (gRandomMercs)
+ memset (random_mercs,0,sizeof(int)*7);
+
+ memset( gMPPlayerStats,0,sizeof(player_stats)*5);
+ memset ( &client_downloading,0,sizeof(int)*4);
+ memset ( &client_progress,0,sizeof(int)*4);
+ memset( &gszDisconnectReason,0,sizeof(CHAR16)*255);
+
+ // ----------------------------
+ // Read from ja2_mp.ini
+ // ----------------------------
+ char serverIP[30];
+
+ CIniReader iniReader(JA2MP_INI_FILENAME);
+ strncpy(serverIP, iniReader.ReadString(JA2MP_INI_INITIAL_SECTION,JA2MP_SERVER_IP, ""), 30);
+ strncpy(cClientName, iniReader.ReadString(JA2MP_INI_INITIAL_SECTION,JA2MP_CLIENT_NAME, ""), 30);
+ strncpy(cGameDataSyncDirectory, iniReader.ReadString(JA2MP_INI_INITIAL_SECTION,JA2MP_FILE_TRANSFER_DIRECTORY, "MULTIPLAYER/Servers/My Server"), 100);
+
+ vfs::PropertyContainer props;
+ props.initFromIniFile(JA2MP_INI_FILENAME);
+ UINT16 serverPort = (UINT16)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_SERVER_PORT, 60005);
+
+ // ----------------------------
+ // Save to global values
+ // ----------------------------
+ recieved_settings=0;
+ recieved_transfer_settings=0;
+ goahead = 0;
+ numready = 0;
+ readystage = 0;
+ status = 0;
+ is_game_started = false;
+ TEAM = 0;
+ isOwnTeamWipedOut = false;
+ wiped=0;
+ //disable cheating
+ gubCheatLevel = 0;
+ cMaxClients = 0; //reset server only set settings.
+ cDamageMultiplier=0;
+ cSameMercAllowed=0;
+ cDisableSpectatorMode=0;
+
+ if(is_server)
+ strcpy(serverIP, "127.0.0.1" );
+
+ //**********************
+ //here some nifty little tweaks
+
+ LaptopSaveInfo.guiNumberOfMercPaymentsInDays += 20;
+ LaptopSaveInfo.gubLastMercIndex = LAST_MERC_ID;
+ LaptopSaveInfo.ubLastMercAvailableId = 7;
+ gGameExternalOptions.fEnableSlayForever = 1;
+ LaptopSaveInfo.gubPlayersMercAccountStatus = 4;
-
-
-
- }
+ // Set fast loading of WWW sites
+ gfTemporaryDisablingOfLoadPendingFlag = TRUE;
+
+ //**********************
+
+ // WANNE: FILE TRANSFER: Build the absolut file transfer directory path for the client
+ GetExecutableDirectory(client_executableDir);
+
+ strcpy(client_fileTransferDirectoryPath, client_executableDir);
+ strcat(client_fileTransferDirectoryPath, "\\");
+ strcat(client_fileTransferDirectoryPath, cGameDataSyncDirectory);
+
+ // WANNE: FILE TRANSFER
+ client->AttachPlugin(&fltClient);
+ client->SetSplitMessageProgressInterval(1);
- //reconnect/connect
- if( !is_connected && !is_connecting)
- {
-
-
- recieved_settings=0;
- recieved_transfer_settings=0;
- goahead = 0;
- numready = 0;
- readystage = 0;
- status = 0;
- is_game_started = false;
- gTacticalStatus.uiFlags&= (~SHOW_ALL_MERCS );
- memset( &readyteamreg , 0 , sizeof (int) * 10);
- //OJW - 20081204
- memset ( &client_names,NULL,sizeof(int)*4);
- memset ( &client_ready,0,sizeof(int)*4);
- memset ( &client_teams,0,sizeof(int)*4);
- if (!RANDOM_SPAWN)
- memset ( &client_edges,0,sizeof(int)*5);
- if (RANDOM_MERCS)
- memset (random_mercs,0,sizeof(int)*7);
- memset( gMPPlayerStats,0,sizeof(player_stats)*5);
- memset ( &client_downloading,0,sizeof(int)*4);
- memset ( &client_progress,0,sizeof(int)*4);
- memset( &gszDisconnectReason,0,sizeof(CHAR16)*255);
-
-
- //retrieve settings from Ja2_mp.ini
- char ip[30];
- char port[30];
-// char client_number[30];
- char sector_edge[30];
-
- isOwnTeamWipedOut = false;
- wiped=0;
-
- //disable cheating
- gubCheatLevel = 0;
-
- //char c_x[30];
-
-
- char clname[30];
-
- MAX_CLIENTS=0;//reset server only set settings.
- //INTERRUPTS=0;
- DAMAGE_MULTIPLIER=0;
- SAME_MERC=0;
- DISABLE_SPEC_MODE=0;
-#ifndef USE_VFS
- CIniReader iniReader("..\\Ja2_mp.ini");
-#else
- CIniReader iniReader("Ja2_mp.ini");
-#endif
-
-#ifndef USE_VFS
- GetPrivateProfileString( "Ja2_mp Settings","SERVER_IP", "", ip, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","SERVER_PORT", "", port, MAX_PATH, "..\\Ja2_mp.ini" );
- // GetPrivateProfileString( "Ja2_mp Settings","CLIENT_NUM", "", client_number, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","SECTOR_EDGE", "", sector_edge, MAX_PATH, "..\\Ja2_mp.ini" );
-#else
- strncpy(ip, iniReader.ReadString("Ja2_mp Settings","SERVER_IP", ""), 30);
- strncpy(port, iniReader.ReadString("Ja2_mp Settings","SERVER_PORT", ""), 30);
- // strcpy(client_number, iniReader.ReadString("Ja2_mp Settings","CLIENT_NUM", ""));
- strncpy(sector_edge, iniReader.ReadString("Ja2_mp Settings","SECTOR_EDGE", ""), 30);
-#endif
-
- //GetPrivateProfileString( "Ja2_mp Settings","CRATE_X", "", c_x, MAX_PATH, "..\\Ja2_mp.ini" );
-
-#ifndef USE_VFS
- GetPrivateProfileString( "Ja2_mp Settings","CLIENT_NAME", "", clname, MAX_PATH, "..\\Ja2_mp.ini" );
-
- GetPrivateProfileString( "Ja2_mp Settings","FILE_TRANSFER_DIRECTORY", "Data-MP", FILE_TRANSFER_DIRECTORY_CLIENT, MAX_PATH, "..\\Ja2_mp.ini" );
-
- gGameOptions.ubInventorySystem = GetPrivateProfileInt( "Ja2_mp Settings","INVENTORY_MODE", INVENTORY_OLD, "..\\Ja2_mp.ini" );
-#else
- strncpy(clname, iniReader.ReadString("Ja2_mp Settings","CLIENT_NAME", ""), 30);
-
- strncpy(FILE_TRANSFER_DIRECTORY_CLIENT, iniReader.ReadString("Ja2_mp Settings","FILE_TRANSFER_DIRECTORY", "Data-MP"), 100);
-
- gGameOptions.ubInventorySystem = iniReader.ReadInteger("Ja2_mp Settings","INVENTORY_MODE", INVENTORY_OLD);
-#endif
-
-
- char op1[30];
- //char op2[30];
- //char op3[30];
- //char op4[30];
-#ifndef USE_VFS
- GetPrivateProfileString( "Ja2_mp Settings","TEAM","0", op1, MAX_PATH, "..\\Ja2_mp.ini" );
- //GetPrivateProfileString( "Ja2_mp Settings","OP_TEAM_2", "", op2, MAX_PATH, "..\\Ja2_mp.ini" );
- //GetPrivateProfileString( "Ja2_mp Settings","OP_TEAM_3", "", op3, MAX_PATH, "..\\Ja2_mp.ini" );
- //GetPrivateProfileString( "Ja2_mp Settings","OP_TEAM_4", "", op4, MAX_PATH, "..\\Ja2_mp.ini" );
- /*char stt[30];
- GetPrivateProfileString( "Ja2_mp Settings","START_TEAM_TURN", "", stt, MAX_PATH, "..\\Ja2_mp.ini" );*/
-#else
- strncpy(op1, iniReader.ReadString("Ja2_mp Settings","TEAM", ""), 30);
- //GetPrivateProfileString( "Ja2_mp Settings","OP_TEAM_2", "", op2, MAX_PATH, "..\\Ja2_mp.ini" );
- //GetPrivateProfileString( "Ja2_mp Settings","OP_TEAM_3", "", op3, MAX_PATH, "..\\Ja2_mp.ini" );
- //GetPrivateProfileString( "Ja2_mp Settings","OP_TEAM_4", "", op4, MAX_PATH, "..\\Ja2_mp.ini" );
- /*char stt[30];
- GetPrivateProfileString( "Ja2_mp Settings","START_TEAM_TURN", "", stt, MAX_PATH, "..\\Ja2_mp.ini" );*/
-#endif
-
- TEAM=atoi(op1);
- //OP_TEAM_2=atoi(op2);
- // OP_TEAM_3=atoi(op3);
- // OP_TEAM_4=atoi(op4);
-
- strcpy( CLIENT_NAME, clname);
-
-
- if(is_server)strcpy( SERVER_IP , "127.0.0.1" );
- else strcpy( SERVER_IP , ip );
-
- strcpy( SERVER_PORT, port );
-
- /*if (is_server) strcpy( CLIENT_NUM, "1" );
- else strcpy( CLIENT_NUM, client_number );*/
-
- strcpy( SECT_EDGE, sector_edge);
-
- //START_TEAM_TURN=atoi(stt);
- //crate_sGridX = atoi(c_x);
-// crate_sGridY = atoi(c_y);
-
- /*netbTeam = (CLIENT_NUM)+5;
- ubID_prefix = gTacticalStatus.Team[ netbTeam ].bFirstID;*/
-
-
-
-
- //**********************
- //here some nifty little tweaks
-
- LaptopSaveInfo.guiNumberOfMercPaymentsInDays += 20;
- LaptopSaveInfo.gubLastMercIndex = LAST_MERC_ID;
-
- LaptopSaveInfo.ubLastMercAvailableId = 7;
- gGameExternalOptions.fEnableSlayForever =1;
- LaptopSaveInfo.gubPlayersMercAccountStatus = 4;
-
- // Set fast loading of WWW sites
- gfTemporaryDisablingOfLoadPendingFlag = TRUE;
-
- gMercProfiles[ 57 ].sSalary = 2000;
- gMercProfiles[ 58 ].sSalary = 1500;
- gMercProfiles[ 59 ].sSalary = 600;
- gMercProfiles[ 60 ].sSalary = 500;
- gMercProfiles[ 64 ].sSalary = 1500;
- gMercProfiles[ 72 ].sSalary = 1000;
- gMercProfiles[ 148 ].sSalary = 100;
- gMercProfiles[ 68 ].sSalary = 2200; //iggy;
-
-
- //**********************
-
- // WANNE: FILE TRANSFER: Build the absolut file transfer directory path for the client
- GetExecutableDirectory(client_executableDir);
-
- strcpy(client_fileTransferDirectoryPath, client_executableDir);
- strcat(client_fileTransferDirectoryPath, "\\");
- strcat(client_fileTransferDirectoryPath, FILE_TRANSFER_DIRECTORY_CLIENT);
-
- // WANNE: FILE TRANSFER
- //fClientReceivedAllFiles = FALSE;
- client->AttachPlugin(&fltClient);
- client->SetSplitMessageProgressInterval(1);
-
- CHAR16 tmpMessage[512];
- swprintf( tmpMessage, MPClientMessage[1],SERVER_IP );
- ScreenMsg( FONT_BEIGE, MSG_MPSYSTEM, tmpMessage); // we are connecting
- SetConnectScreenSubMessageW( tmpMessage );
-
-
- client->Connect(SERVER_IP, atoi(SERVER_PORT), 0,0);
- is_connecting=true;
-
-#ifdef JA2BETAVERSION
- MPDebugMsg( String ( "connect_client()\n" ) );
-#endif
-
-
-
- }
-
- else if (is_connecting)
- {
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[4] );
- }
- else if (is_connected)
- {
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[3] );
- }
+ CHAR16 tmpMessage[512];
+ swprintf( tmpMessage, MPClientMessage[1],serverIP );
+ ScreenMsg( FONT_BEIGE, MSG_MPSYSTEM, tmpMessage); // we are connecting
+ SetConnectScreenSubMessageW( tmpMessage );
+ client->Connect(serverIP, serverPort, 0,0);
+ is_connecting = true;
+ }
+ else if (is_connecting)
+ {
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[4] );
+ }
+ else if (is_connected)
+ {
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[3] );
+ }
}
void client_packet ( void )
{
-
Packet* p;
-
if (is_client)
{
-
p = client->Receive();
while(p)
{
- //continue; // Didn't get any packets
-
// We got a packet, get the identifier with our handy function
packetIdentifier = GetPacketIdentifier(p);
- //ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"packet recieved");
+
// Check if this is a network message packet
switch (packetIdentifier)
{
@@ -5406,6 +4852,7 @@ void client_packet ( void )
}
}
}
+
// Copied from Multiplayer.cpp
// If the first byte is ID_TIMESTAMP, then we want the 5th byte
// Otherwise we want the 1st byte
@@ -5436,14 +4883,13 @@ void client_disconnect (void)
is_connecting=false;
fileTransferProgress = 0;
-
-
allowlaptop=false;
+ TEAM=0;
+
// Reset fast loading of WWW pages
gfTemporaryDisablingOfLoadPendingFlag = FALSE;
-
// clear local client cache
memset(client_names,0,sizeof(char)*4*30);
memset(client_edges,0,sizeof(int)*5);
@@ -5452,15 +4898,11 @@ void client_disconnect (void)
memset(gMPPlayerStats,0,sizeof(player_stats)*5);
memset(random_mercs,0,sizeof(int)*7);
memset ( &client_downloading,0,sizeof(int)*4);
- memset ( &client_progress,0,sizeof(int)*4);
- TEAM=0;
-
-
-
+ memset ( &client_progress,0,sizeof(int)*4);
// We're done with the network
RakNetworkFactory::DestroyRakPeerInterface(client);
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"client disconnected and shutdown");
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[77]);
#ifdef JA2BETAVERSION
MPDebugMsg( "client_disconnect()\n" );
@@ -5468,7 +4910,7 @@ void client_disconnect (void)
}
else
{
- ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, L"client is not running");
+ ScreenMsg( FONT_LTGREEN, MSG_MPSYSTEM, MPClientMessage[78]);
}
}
@@ -5489,9 +4931,7 @@ void send_edgechange(int newedge)
fDrawCharacterList = true;
fTeamPanelDirty = true;
client_edges[CLIENT_NUM-1] =newedge;
- // store the setting locally
- _itoa(newedge,SECT_EDGE,10);
-
+ cStartingSectorEdge = newedge;
}
else
{
@@ -5501,7 +4941,7 @@ void send_edgechange(int newedge)
bool can_edgechange()
{
- return (is_game_started != 1 && client_ready[CLIENT_NUM-1] == 0 && !allowlaptop && !RANDOM_SPAWN);
+ return (is_game_started != 1 && client_ready[CLIENT_NUM-1] == 0 && !allowlaptop && !gRandomStartingEdge);
}
//OJW - 20081204 - send a starting team change to all the clients
@@ -5522,7 +4962,6 @@ void send_teamchange(int newteam)
fTeamPanelDirty = true;
client_teams[lan.client_num-1] = lan.newteam;
TEAM = newteam;
-
}
else
{
@@ -5534,7 +4973,7 @@ bool can_teamchange()
{
bool isGeneralTeamchangeValid = (is_game_started != 1 && client_ready[CLIENT_NUM-1] == 0 && !allowlaptop);
- if (isGeneralTeamchangeValid && PLAYER_BSIDE == MP_TYPE_TEAMDEATMATCH)
+ if (isGeneralTeamchangeValid && cGameType == MP_TYPE_TEAMDEATMATCH)
return TRUE;
else
return FALSE;
@@ -5556,10 +4995,10 @@ void ChatCallback( UINT8 ubResult )
chat_msg cmsg;
wchar_t szPlayerName[30];
memset(szPlayerName,0,30*sizeof(wchar_t));
- mbstowcs( szPlayerName,CLIENT_NAME,30);
+ mbstowcs( szPlayerName,cClientName,30);
cmsg.bToAll = gbChatSendToAll;
- if (PLAYER_BSIDE==1 && !cmsg.bToAll)
+ if (cGameType==MP_TYPE_TEAMDEATMATCH && !cmsg.bToAll)
swprintf(cmsg.msg,MPClientMessage[56], szPlayerName, gszChatBoxInputString);
else
swprintf(cmsg.msg,MPClientMessage[52], szPlayerName, gszChatBoxInputString);
@@ -5575,5 +5014,4 @@ void ChatCallback( UINT8 ubResult )
void OpenChatMsgBox( void )
{
DoChatBox((guiCurrentScreen == GAME_SCREEN? true : false),gzMPChatboxText[1],guiCurrentScreen,ChatCallback,NULL);
-}
-
+}
\ No newline at end of file
diff --git a/Multiplayer/connect.h b/Multiplayer/connect.h
index 73fda315..629a1a64 100644
--- a/Multiplayer/connect.h
+++ b/Multiplayer/connect.h
@@ -4,6 +4,7 @@
#include "Soldier Init List.h"
#include "Merc Hiring.h"
#include "event pump.h"
+#include "Bullets.h"
extern bool isOwnTeamWipedOut;
@@ -20,34 +21,32 @@ extern bool recieved_transfer_settings;
extern INT16 serverSyncClientsDirectory;
extern int PLAYER_TEAM_TIMER_SEC_PER_TICKS;
-
-//extern char CLIENT_NUM[30];
extern int CLIENT_NUM;
-extern int ENEMY_ENABLED;
-extern int CREATURE_ENABLED;
-extern int MILITIA_ENABLED;
-extern int CIV_ENABLED;
+extern UINT8 gEnemyEnabled;
+extern UINT8 gCreatureEnabled;
+extern UINT8 gMilitiaEnabled;
+extern UINT8 gCivEnabled;
-extern int MAX_CLIENTS;
-extern int SAME_MERC;
-extern int PLAYER_BSIDE;
+extern UINT8 cMaxClients;
+extern UINT8 cSameMercAllowed;
+extern UINT8 cGameType;
extern bool allowlaptop;
extern UINT8 netbTeam;
extern UINT8 ubID_prefix;
-extern FLOAT DAMAGE_MULTIPLIER;
+extern FLOAT cDamageMultiplier;
//OJW - 20081218
-extern int RANDOM_SPAWN;
-extern int RANDOM_MERCS;
+extern UINT8 gRandomStartingEdge;
+extern UINT8 gRandomMercs;
//OJW - 20090317
extern bool is_game_started;
//OJW - 20090403
-extern int OVERRIDE_MAX_AI;
+extern UINT8 gMaxEnemiesEnabled;
//OJW - 20090405
extern STRING512 gCurrentTransferFilename;
@@ -58,17 +57,15 @@ extern UINT32 crate_usMapPos;
//extern int INTERRUPTS;
-extern int ALLOW_EQUIP;
+extern UINT8 cAllowMercEquipment;
-extern INT32 MAX_MERCS;
+extern UINT8 cMaxMercs;
void lockui (bool unlock);
void start_battle ( void );
void DropOffItemsInSector( UINT8 ubOrderNum );
-void test_func2 ( void );
-
void mp_help (void);
void mp_help2 (void);
void grid_display ( void);
@@ -97,7 +94,7 @@ void send_stance ( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance );
void send_dir ( SOLDIERTYPE *pSoldier, UINT16 usDesiredDirection );
void send_fire( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo );
void send_hit( EV_S_WEAPONHIT *SWeaponHit );
-
+void send_bullet( BULLET * pBullet, UINT16 usHandItem);
void send_hire( UINT8 iNewIndex, UINT8 ubCurrentSoldier, INT16 iTotalContractLength, BOOLEAN fCopyProfileItemsOver);
void send_dismiss( UINT8 ubCurrentSoldier);
@@ -125,6 +122,8 @@ void send_disarm_explosive(UINT32 sGridNo, UINT32 uiWorldIndex, UINT8 ubID);
void OpenChatMsgBox(void);
+INT8 FireBullet( SOLDIERTYPE * pFirer, BULLET * pBullet, BOOLEAN fFake );
+
void reapplySETTINGS();
BOOLEAN CheckConditionsForBattle( GROUP *pGroup ); // this comes from strategic movement.cpp
@@ -140,10 +139,11 @@ extern int client_edges[5];
extern int client_downloading[4];
extern int client_progress[4];
-extern char SERVER_NAME[30];
+extern char cServerName[30];
//OJW - 20081224
#define MAX_CONNECT_RETRIES 5
+#define ENABLE_COLLISION (is_server && pBullet->pFirer->ubID<120) || (!is_server && is_client && pBullet->pFirer->ubID<20) || (!is_server && !is_client)
extern bool auto_retry;
extern int giNumTries;
diff --git a/Multiplayer/fresh_header.h b/Multiplayer/fresh_header.h
index e60fc41f..353b3543 100644
--- a/Multiplayer/fresh_header.h
+++ b/Multiplayer/fresh_header.h
@@ -1,9 +1,7 @@
#pragma once
//time for a new header :)
-
extern int readyteamreg[10];
-
extern bool NOGEAR;
typedef struct
@@ -23,70 +21,49 @@ typedef struct
typedef struct
{
-UINT16 ubID;
-INT8 bLife;
-INT8 bBleeding;
+ UINT16 ubID;
+ INT8 bLife;
+ INT8 bBleeding;
}heal;
typedef struct
{
UINT16 ubID;
INT8 bteam;
-
}AIint;
+extern BOOLEAN gfUIInterfaceSetBusy;
+extern int numreadyteams;//for realtime
+extern bool requested;
+extern bool getReal;
+extern UINT8 gubCheatLevel;
+
+// Client variables
+extern UINT8 cWeaponReadyBonus;
+extern UINT8 cDisableSpectatorMode;
+extern UINT8 cDisableMorale;
+
BOOLEAN DisplayMercsInventory(UINT8 ubMercID);
void send_door ( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fNoAnimations );
-
void send_changestate (EV_S_CHANGESTATE * SChangeState);
-
void send_death( SOLDIERTYPE *pSoldier);
-
void send_hitstruct(EV_S_STRUCTUREHIT * SStructureHit);
void send_hitwindow(EV_S_WINDOWHIT * SWindowHit);
-void send_miss(EV_S_MISS * SMiss);
-
-void cheat_func(void);
-//void start_tt(void);
+void send_miss(EV_S_MISS * SMiss);
void unlock (void);
-
void UpdateSoldierToNetwork ( SOLDIERTYPE *pSoldier );
-
-extern BOOLEAN gfUIInterfaceSetBusy;
void TrashAllSoldiers( );
-
void kick_player (void);
void overide_turn (void);
-
-extern bool DISABLE_MORALE;
-
void send_fireweapon ( EV_S_FIREWEAPON * SFireWeapon);
-
void end_interrupt ( BOOLEAN fMarkInterruptOccurred );
void EndInterrupt( BOOLEAN fMarkInterruptOccurred );
void sendRT (void);
-
-extern int numreadyteams;//for realtime
-
-extern bool requested;
-extern bool getReal;
-
-extern UINT8 gubCheatLevel;
-
void startCombat(UINT8 ubStartingTeam);
-
-extern int WEAPON_READIED_BONUS;
-
void intAI (SOLDIERTYPE *pSoldier );
-
void teamwiped (void);
-
BOOLEAN check_status (void);
extern UINT8 NumEnemyInSector( );
extern INT8 NumActiveAndConsciousTeamMembers( UINT8 ubTeam );
-
void send_heal (SOLDIERTYPE *pSoldier );
-
-extern int DISABLE_SPEC_MODE;
-
void requestAIint(SOLDIERTYPE *pSoldier );
\ No newline at end of file
diff --git a/Multiplayer/network.h b/Multiplayer/network.h
index 955160e3..c801e157 100644
--- a/Multiplayer/network.h
+++ b/Multiplayer/network.h
@@ -3,17 +3,43 @@
#include "random.h"
//this one just for structs, variables and functions used between the client and server scripts...
-
-extern char CLIENT_NAME[30];
-extern char SERVER_NAME[30];
+extern char cClientName[30];
+extern char cServerName[30];
extern bool Sawarded;
-
-//extern char *fileToSend;
extern unsigned int setID;
-//extern char *fileToSendCopy;
+// ja2_mp.ini: File
+#define JA2MP_INI_FILENAME "ja2_mp.ini"
+// "ja2_mp.ini: Sections
+#define JA2MP_INI_INITIAL_SECTION "JA2 Multiplayer Initial Settings"
+#define JA2MP_INI_SERVER_SECTION "JA2 Multiplayer Servers"
+// ja2_mp.ini: Properties
+#define JA2MP_ALLOW_CUSTOM_NIV "INVENTORY_ATTACHMENTS"
+#define JA2MP_CIV_ENABLED "ENABLE_CIVILIANS_IN_COOP"
+#define JA2MP_CLIENT_NAME "PLAYER_NAME"
+#define JA2MP_DAMAGE_MULTIPLIER "WEAPON_DAMAGE"
+#define JA2MP_DIFFICULT_LEVEL "DIFFICULTY_LEVEL"
+#define JA2MP_DISABLE_BOBBY_RAYS "BOBBY_RAYS"
+#define JA2MP_FILE_TRANSFER_DIRECTORY "GAME_DATA_SYNC_DIRECTORY"
+#define JA2MP_GAME_MODE "GAME_TYPE"
+#define JA2MP_KIT_BAG "KIT_BAG"
+#define JA2MP_MAX_CLIENTS "MAX_PLAYERS"
+#define JA2MP_MAX_MERCS "MAX_MERCS"
+#define JA2MP_OVERRIDE_MAX_AI "MAX_ENEMIES_IN_COOP"
+#define JA2MP_RANDOM_EDGES "STARTING_SECTOR_EDGE"
+#define JA2MP_RANDOM_MERCS "HIRE_MERCS_METHOD"
+#define JA2MP_REPORT_NAME "REPORT_HIRED_MERC_NAME"
+#define JA2MP_SAME_MERC "SAME_MERC_ALLOWED"
+#define JA2MP_SERVER_IP "SERVER_IP"
+#define JA2MP_SERVER_NAME "SERVER_NAME"
+#define JA2MP_SERVER_PORT "SERVER_PORT"
+#define JA2MP_STARTING_BALANCE "STARTING_CASH"
+#define JA2MP_SYNC_CLIENTS_MP_DIR "SYNC_GAME_DIRECTORY"
+#define JA2MP_TIMED_TURN_SECS_PER_TICK "TIMED_TURNS"
+#define JA2MP_TIME "STARTING_TIME"
+#define JA2MP_NEW_TRAITS "SKILL_TRAITS"
typedef struct
{
@@ -26,60 +52,56 @@ typedef struct
typedef struct
{
- int max_clients;
- int same_merc;
- float damage_multiplier;
- INT16 gsMercArriveSectorX;
- INT16 gsMercArriveSectorY;
- int ENEMY_ENABLED;
- int CREATURE_ENABLED;
- int MILITIA_ENABLED;
- int CIV_ENABLED;
- int gsPLAYER_BSIDE;
- INT32 secs_per_tick;
- INT32 starting_balance;
- bool soDis_Bobby;
- bool soDis_Equip;
+ UINT8 maxClients;
+ UINT8 sameMercAllowed;
+ float damageMultiplier;
+ INT16 gsMercArriveSectorX;
+ INT16 gsMercArriveSectorY;
+ UINT8 enemyEnabled;
+ UINT8 creatureEnabled;
+ UINT8 militiaEnabled;
+ UINT8 civEnabled;
+ UINT8 gameType;
+ INT32 secondsPerTick;
+ INT32 startingCash;
+ UINT8 disableBobbyRay;
+ UINT8 disableMercEquipment;
BOOLEAN sofGunNut;
UINT8 soubGameStyle;
UINT8 soubDifficultyLevel;
+ UINT8 soubSkillTraits;
BOOLEAN sofTurnTimeLimit;
BOOLEAN sofIronManMode;
- UINT8 soubBobbyRay;
- BOOLEAN sofNewInv;
- INT32 gsMAX_MERCS;
- UINT8 client_num;
- char client_name[30];
- char client_names[4][30];
- // OJW - added 20081204
- int client_edges[5];
- int client_teams[4];
- char server_name[30];
- //int cl_ops[4];
- int team;
- int TESTING;
- char kitbag[100];
- bool emorale;
- int gsREPORT_NAME;
- int cl_edge;
- float TIME;
- int WEAPON_READIED_BONUS;
- int ALLOW_CUSTOM_NIV;
- int DISABLE_SPEC_MODE;
+ UINT8 soubBobbyRay;
+ UINT8 maxMercs;
+ UINT8 client_num;
+ char client_name[30];
+ char client_names[4][30];
+ int client_edges[5];
+ int client_teams[4];
+ char server_name[30];
+ int team;
+ char kitBag[100];
+ UINT8 disableMorale;
+ UINT8 reportHiredMerc;
+ UINT8 startingSectorEdge;
+ float startingTime;
+ UINT8 weaponReadyBonus;
+ UINT8 inventoryAttachment;
+ UINT8 disableSpectatorMode;
// OJW - added 20081220
- int RANDOM_SPAWN;
- int RANDOM_MERCS;
- int random_mercs[7];
- char server_version[30];
+ UINT8 randomStartingEdge;
+ UINT8 randomMercs;
+ int random_mercs[7];
+ char server_version[30];
// OJW - added 20091024
- UINT32 random_table[MAX_PREGENERATED_NUMS];
+ UINT32 random_table[MAX_PREGENERATED_NUMS];
} settings_struct;
// WANNE: FILE TRANSFER
typedef struct
{
- STRING512 fileTransferDirectory;
- //char fileTransferDirectory[600]; // The file transfer directory path from the server
+ STRING512 fileTransferDirectory;
int syncClientsDirectory; // Does the server want to sync files to the clients
char serverName[30]; // The name of the server. This is used on the client side as a folder inside the client transfer directory
long totalTransferBytes;
@@ -90,7 +112,7 @@ typedef struct
{
INT16 gsMercArriveSectorX;
INT16 gsMercArriveSectorY;
- float TIME;
+ float startingTime;
} mapchange_struct;
typedef struct
@@ -112,18 +134,6 @@ typedef struct
UINT8 downloading;
} progress_struct;
-//typedef struct
-//{
-// int clnum;
-// UINT8 ubid;
-//}ovh_struct;
-//
-//typedef struct
-//{
-// UINT8 ubid;
-//}adv;
-
-
typedef struct
{
BOOLEAN fMarkInterruptOccurred;
@@ -142,3 +152,10 @@ typedef struct
UINT8 ubStartingTeam;
}sc_struct;
+namespace ja2
+{
+ namespace mp
+ {
+ void InitializeMultiplayerProfile(vfs::Path const& profileRoot);
+ }
+}
\ No newline at end of file
diff --git a/Multiplayer/server.cpp b/Multiplayer/server.cpp
index ebb8e42e..70503b4a 100644
--- a/Multiplayer/server.cpp
+++ b/Multiplayer/server.cpp
@@ -1,18 +1,14 @@
-
#include "MessageIdentifiers.h"
#include "RakNetworkFactory.h"
#include "RakPeerInterface.h"
#include "RakNetStatistics.h"
#include "RakNetTypes.h"
-
-
#include "FileListTransfer.h"
#include "FileListTransferCBInterface.h"
#include "FileOperations.h"
#include "SuperFastHash.h"
#include "RakAssert.h"
#include "IncrementalReadInterface.h"
-
#include "BitStream.h"
#include "RakSleep.h"
#include
@@ -23,29 +19,22 @@
#include
#include
#include
-
#include "connect.h"
-
#include "types.h"
#include "gamesettings.h"
#include "message.h"
#include "FileMan.h"
-
#include "IniReader.h"
-#include "VFS/vfs.h"
-#include "VFS/Tools/ParserTools.h"
+#include
+#include "transfer_rules.h"
#include "MPJoinScreen.h"
-
#include "game init.h"
-
#include "text.h"
#include "network.h"
-
#include "message.h"
#include "overhead.h"
#include "fresh_header.h"
#include "Debug Control.h"
-
#include "MPXmlTeams.hpp"
extern CHAR16 gzFileTransferDirectory[100];
@@ -80,51 +69,41 @@ class ServerFileListProgress : public FileListProgress
}
} serverFileListProgress;
-
-
-char kbag[100];
-char net_div[30];
-INT32 gsMAX_MERCS;
-bool gsMORALE;
-int gsREPORT_NAME;
-
+// ------------------------------
+// Global Server Variables from ja2_mp.ini
+// ------------------------------
+char gKitBag[100];
+UINT8 gMaxMercs;
+UINT8 gDisableMorale;
+UINT8 gReportHiredMerc;
+UINT8 gDisableBobbyRay;
+UINT8 gDisableMercEquipment;
+UINT8 gSameMercAllowed;
+float gDamageMultiplier;
+UINT8 gMaxClients ;
+UINT8 gGameType;
+UINT8 gDifficultyLevel;
+UINT8 gSkillTraits;
+UINT8 gSyncGameDirectory;
+INT32 gSecondsPerTick;
+INT32 gStartingCash;
+float gStartingTime;
+UINT8 gWeaponReadyBonus;
+UINT8 gInventoryAttachment;
+UINT8 gDisableSpectatorMode;
+UINT8 gMaxEnemiesEnabled;
+// ------------------------------
UINT16 nc; //number of open connection
UINT16 ncr; //number of ready confirmed connections
//something keep record of ready connections ..
int mercs_ready[255];
-bool gsDis_Bobby;
-bool gsDis_Equip;
-
-int gsSAME_MERC;
-float gsDAMAGE_MULTIPLIER;
-int gsINTERRUPTS ;
-int gsMAX_CLIENTS ;
-int gsPLAYER_BSIDE;
-int gsTESTING;
-int gsDIFFICULT_LEVEL;
-char gsFILE_TRANSFER_DIRECTORY_SERVER[100];
-
-int gsSYNC_CLIENTS_MP_DIR;
-
-INT32 gssecs_per_tick;
-INT32 gsstarting_balance;
-float TIME;
-int sWEAPON_READIED_BONUS;
-int sALLOW_CUSTOM_NIV;
-int sDISABLE_SPEC_MODE;
-
-// OJW - 20090403 - override max enemies for co-op
-int OVERRIDE_MAX_AI;
-
unsigned char SGetPacketIdentifier(Packet *p);
unsigned char SpacketIdentifier;
RakPeerInterface *server;
-
-
// WANNE: FILE TRANSFER
FileListTransfer fltServer; // flt1
IncrementalReadInterface incrementalReadInterface;
@@ -132,8 +111,6 @@ FileList fileList;
// OJW - 20090405
long fileListTotalBytes=0;
-
-
int numreadyteams;
int readyteamreg[10];
@@ -149,21 +126,6 @@ typedef struct
}client_data;
client_data client_d[4];
-
-// OJW - 20081223
-// Random Merc teams
-// First attempt at "balanced" teams
-// moved to mpxmlteams.cpp
-/*
-int random_merc_teams[4][7] =
-{
- { 16, 10, 19, 25, 4 , 11, 39 } , // Gus , Shadow, Spider , Raven , Vicki , Red , Meltdown
- { 29, 36, 28, 2 , 22, 8 , 32 } , // Magic , Scope, Danny , Lynx , Hitman , Steroid , Malice
- { 12, 5 , 20, 23, 48, 34, 17 } , // Reaper , Trevor, Cliff , Buzz , Cougar , Nails , Buns
- { 31, 7 , 33, 35, 27, 37, 1 } // Scully , Ivan , Dr Q , Thor , Len , Wolf , Blood
-};
-*/
-
int client_mercteam[4] = { 0 , 1 , 2 , 3 }; // random index of random_merc_teams per player
bool inline can_joingame();
@@ -535,27 +497,6 @@ void receiveSETID(RPCParameters *rpcParameters)
fltServer.Send(&fileList,server,rpcParameters->sender,setID,MEDIUM_PRIORITY,0,false, &incrementalReadInterface, 5000);
}
-//void sendALLFILESRECEIVED(RPCParameters *rpcParameters)
-//{
-// ScreenMsg( FONT_BCOLOR_ORANGE, MSG_MPSYSTEM, L"%S", rpcParameters->input);
-//}
-
-
-//
-//void rINT(RPCParameters *rpcParameters)//who is first
-//{
-//
-// AIint* data = (AIint*)rpcParameters->input;
-//
-// if( !Sawarded )
-// {
-// PauseAITemporarily();
-// Sawarded=true;
-// //send back to sender
-// server->RPC("awardINT",(const char*)rpcParameters->input, (*rpcParameters).numberOfBitsOfData, HIGH_PRIORITY, RELIABLE, 0, rpcParameters->sender, false, 0, UNASSIGNED_NETWORK_ID,0);
-// }
-//}
-
void startCOMBAT(RPCParameters *rpcParameters)
{
if(!( gTacticalStatus.uiFlags & INCOMBAT ))
@@ -570,43 +511,38 @@ void startCOMBAT(RPCParameters *rpcParameters)
}
-
-
-
-
void sendREAL(RPCParameters *rpcParameters)
{
real_struct* rData = (real_struct*)rpcParameters->input;
-
-
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"netbTeam %d is ready for realtime",rData->bteam );//diabled unless testing as cheats
if(readyteamreg[rData->bteam]==0)
{
readyteamreg[rData->bteam]=1;//register vote, to prevent double voting ;p~ //hayden
numreadyteams++;
- int numactiveteams=0;
- int b;
- for(int i=6;i<=LAST_TEAM;i++)
- {
- if(i==6)b=0;
- else b=i;
+ int numactiveteams=0;
+ int b;
+ for(int i=6;i<=LAST_TEAM;i++)
+ {
+ if(i==6)
+ b=0;
+ else
+ b=i;
- if(gTacticalStatus.Team[ b ].bTeamActive)numactiveteams++;
+ if(gTacticalStatus.Team[ b ].bTeamActive)
+ numactiveteams++;
+ }
- }//same
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPServerMessage[5], numreadyteams, numactiveteams );
- //check # clients ready for realtime
- if (numreadyteams >= numactiveteams)
- {
- //if all send notification for realtime changeover
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"Switching to realtime..." );
- numreadyteams=0;
- memset( &readyteamreg , 0 , sizeof (int) * 10);
+ //check # clients ready for realtime
+ if (numreadyteams >= numactiveteams)
+ {
+ //if all send notification for realtime changeover
+ //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"Switching to realtime..." );
+ numreadyteams=0;
+ memset( &readyteamreg , 0 , sizeof (int) * 10);
- server->RPC("gotoRT",(const char*)rpcParameters->input, (*rpcParameters).numberOfBitsOfData, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- }
+ server->RPC("gotoRT",(const char*)rpcParameters->input, (*rpcParameters).numberOfBitsOfData, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
+ }
}
}
@@ -623,9 +559,6 @@ void sendCHATMSG(RPCParameters *rpcParameters)
server->RPC("recieveCHATMSG",(const char*)rpcParameters->input, (*rpcParameters).numberOfBitsOfData, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
-
-
-
// OJW - 20081223
// fix client disconnecting mid game, allowing the game to proceed
void HandleDisconnect(SystemAddress sender)
@@ -666,7 +599,7 @@ void rSortArray(int* arr, int len)
{
int iRandPos = rand() % tmpList.size();
for(Iter = tmpList.begin(); iRandPos>0; iRandPos--, Iter++);
- //Iter += iRandPos;
+
shuffledList.push_front(*Iter);
tmpList.erase(Iter);
}
@@ -683,37 +616,18 @@ void rSortArray(int* arr, int len)
void requestFILE_TRANSFER_SETTINGS(RPCParameters *rpcParameters)
{
SystemAddress sender = rpcParameters->sender;//get senders address
-#ifndef USE_VFS
- STRING512 executableDir;
- GetExecutableDirectory(executableDir);
- STRING512 fileTransferDir;
- strcpy(fileTransferDir, executableDir);
- strcat(fileTransferDir, "\\");
- strcat(fileTransferDir, gsFILE_TRANSFER_DIRECTORY_SERVER);
-
- // Replace all "/" with "\" from the server path
- char* correctFileTransferDir = ReplaceCharactersInString_Server(fileTransferDir, "/", "\\");
-
filetransfersettings_struct fts;
- fts.syncClientsDirectory = gsSYNC_CLIENTS_MP_DIR;
- strcpy(fts.fileTransferDirectory, correctFileTransferDir);
- strcpy(fts.serverName, SERVER_NAME);
- fts.totalTransferBytes = fileListTotalBytes;
-#else
- filetransfersettings_struct fts;
-
- fts.syncClientsDirectory = gsSYNC_CLIENTS_MP_DIR;
+ fts.syncClientsDirectory = gSyncGameDirectory;
strcpy(fts.fileTransferDirectory, s_ServerId.getServerId(vfs::Path(gzFileTransferDirectory)).utf8().c_str());
- strcpy(fts.serverName, SERVER_NAME);
+ strcpy(fts.serverName, cServerName);
fts.totalTransferBytes = fileListTotalBytes;
-#endif
+
// OJW - 200907819 - Only send to the client that asked for it
server->RPC("recieveFILE_TRANSFER_SETTINGS",(const char*)&fts, (int)sizeof(filetransfersettings_struct)*8, HIGH_PRIORITY, RELIABLE, 0, sender, false, 0, UNASSIGNED_NETWORK_ID,0);
}
-
//************************* //UNASSIGNED_SYSTEM_ADDRESS
//START INTERNAL SERVER
//*************************
@@ -741,11 +655,7 @@ void requestSETTINGS(RPCParameters *rpcParameters )
server->CloseConnection(rpcParameters->sender, true);
return;
}
-
- // WANNE: FILE TRANSFER: A client connected -> start the file transfer!
- if (gsSYNC_CLIENTS_MP_DIR)
- requestSETID(rpcParameters->sender);
-
+
//server assigned client numbers - hayden.
SystemAddress sender = rpcParameters->sender;//get senders address
int bslot = f_rec_num(0,blank);//get empty record slot
@@ -753,105 +663,107 @@ void requestSETTINGS(RPCParameters *rpcParameters )
int new_cl_num = bslot+1;//client number to assign
client_d[bslot].cl_number=new_cl_num; //record clients number
-
settings_struct lan;
-
- //lan.client_num = clinf->client_num;//old client assigned number
+
lan.client_num = new_cl_num; //new server assigned number
strcpy(lan.client_name , clinf->client_name);
- lan.RANDOM_SPAWN = RANDOM_SPAWN;
- lan.RANDOM_MERCS = RANDOM_MERCS;
+ lan.randomStartingEdge = gRandomStartingEdge;
+ lan.randomMercs = gRandomMercs;
- lan.max_clients = gsMAX_CLIENTS;
- memcpy(lan.kitbag , kbag,sizeof (char)*100);
- lan.damage_multiplier = gsDAMAGE_MULTIPLIER;
+ lan.maxClients = gMaxClients;
+ memcpy(lan.kitBag , gKitBag,sizeof (char)*100);
+ lan.damageMultiplier = gDamageMultiplier;
- lan.same_merc = gsSAME_MERC;
+ lan.sameMercAllowed = gSameMercAllowed;
lan.gsMercArriveSectorX=gsMercArriveSectorX;
lan.gsMercArriveSectorY=gsMercArriveSectorY;
- lan.ENEMY_ENABLED=ENEMY_ENABLED;
- lan.CREATURE_ENABLED=CREATURE_ENABLED;
- lan.MILITIA_ENABLED=MILITIA_ENABLED;
- lan.CIV_ENABLED=CIV_ENABLED;
+ lan.enemyEnabled = gEnemyEnabled;
+ lan.creatureEnabled = gCreatureEnabled;
+ lan.militiaEnabled = gMilitiaEnabled;
+ lan.civEnabled = gCivEnabled;
- lan.gsPLAYER_BSIDE=gsPLAYER_BSIDE;
+ lan.gameType=gGameType;
- lan.emorale=gsMORALE;
- lan.gsREPORT_NAME=gsREPORT_NAME;
-//something new
- lan.secs_per_tick=gssecs_per_tick;
+ lan.disableMorale=gDisableMorale;
+ lan.reportHiredMerc=gReportHiredMerc;
+ lan.secondsPerTick = gSecondsPerTick;
lan.soubBobbyRay=gGameOptions.ubBobbyRay;
lan.sofGunNut=gGameOptions.fGunNut;
lan.soubGameStyle=gGameOptions.ubGameStyle;
- lan.soubDifficultyLevel=gsDIFFICULT_LEVEL;
+ lan.soubDifficultyLevel=gDifficultyLevel;
+ lan.soubSkillTraits=gSkillTraits;
lan.sofTurnTimeLimit=gGameOptions.fTurnTimeLimit;
lan.sofIronManMode=gGameOptions.fIronManMode;
- lan.starting_balance=gsstarting_balance;
-
- // OJW - 20090319 - Changing allow custom NIV to force NIV on all clients
- // as with the new join screen setup, no way for the individual client to choose
- // whether or not to use NIV. If this is wrong, its easily fixed...
- // just change description text for the toggle option on the host screen to
- // "Allow custom inventory" and delete this if statement.
- if (sALLOW_CUSTOM_NIV==1 && IsNIVModeValid(true))
- gGameOptions.ubInventorySystem = INVENTORY_NEW;
- else
- gGameOptions.ubInventorySystem = INVENTORY_OLD;
+ lan.startingCash = gStartingCash;
- lan.sofNewInv=gGameOptions.ubInventorySystem;
+ // Old/Old
+ if (gInventoryAttachment == INVENTORY_OLD)
+ {
+ lan.inventoryAttachment = 0;
+ }
+ else
+ {
+ // New/Old
+ if (gGameOptions.ubAttachmentSystem == ATTACHMENT_OLD)
+ {
+ lan.inventoryAttachment = 1; // New/Old
+ }
+ // New/New
+ else
+ {
+ lan.inventoryAttachment = 2; // New/New
+ }
+ }
+
+ lan.disableBobbyRay=gDisableBobbyRay;
+ lan.disableMercEquipment=gDisableMercEquipment;
- lan.soDis_Bobby=gsDis_Bobby;
- lan.soDis_Equip=gsDis_Equip;
-
- lan.gsMAX_MERCS=gsMAX_MERCS;
+ lan.maxMercs = gMaxMercs;
memcpy( lan.client_names , client_names, sizeof( char ) * 4 * 30 );
lan.team=clinf->team;
// OJW - 20090530 - fix teams not initialised properly
client_teams[ lan.client_num - 1 ] = lan.team;
-
- lan.TESTING=gsTESTING;
-
+
// OJW - 20081218
- if (RANDOM_SPAWN)
+ if (gRandomStartingEdge)
{
// Get the edge from the randomized "client_edges"
- lan.cl_edge = client_edges[lan.client_num-1];
+ lan.startingSectorEdge = client_edges[lan.client_num-1];
}
else
{
// WANNE: on DM, each client should get a unique starting edge per default
- if (gsPLAYER_BSIDE == MP_TYPE_DEATHMATCH || gsPLAYER_BSIDE == MP_TYPE_TEAMDEATMATCH)
+ if (gGameType == MP_TYPE_DEATHMATCH || gGameType == MP_TYPE_TEAMDEATMATCH)
{
client_edges[0] = MP_EDGE_NORTH; // client 1
client_edges[1] = MP_EDGE_SOUTH; // client 2
client_edges[2] = MP_EDGE_EAST; // client 3
client_edges[3] = MP_EDGE_WEST; // client 4
- lan.cl_edge = client_edges[lan.client_num-1];
+ lan.startingSectorEdge = client_edges[lan.client_num-1];
}
else
{
- lan.cl_edge=clinf->cl_edge;
+ lan.startingSectorEdge=clinf->cl_edge;
}
}
// OJW - 20081223
- if (RANDOM_MERCS)
- {
- //memcpy(lan.random_mercs, random_merc_teams[client_mercteam[lan.client_num - 1]], sizeof(int) * 7);
+ if (gRandomMercs)
+ {
mpTeams.SerializeProfiles(lan.random_mercs);
}
- lan.TIME=TIME;
- lan.WEAPON_READIED_BONUS=sWEAPON_READIED_BONUS;
- lan.ALLOW_CUSTOM_NIV=sALLOW_CUSTOM_NIV;
- lan.DISABLE_SPEC_MODE=sDISABLE_SPEC_MODE;
+ lan.startingTime = gStartingTime;
+ lan.weaponReadyBonus = gWeaponReadyBonus;
+ lan.inventoryAttachment = gInventoryAttachment;
+ lan.disableSpectatorMode = gDisableSpectatorMode;
// OJW - 20081204
- strcpy(lan.server_name , SERVER_NAME);
+ strcpy(lan.server_name , cServerName);
memcpy(lan.client_edges,client_edges,sizeof(int)*5);
memcpy(lan.client_teams,client_teams,sizeof(int)*4);
@@ -864,7 +776,10 @@ void requestSETTINGS(RPCParameters *rpcParameters )
server->RPC("recieveSETTINGS",(const char*)&lan, (int)sizeof(settings_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
- } // end if(can_joingame)
+ // WANNE: FILE TRANSFER: A client connected -> start the file transfer!
+ if (gSyncGameDirectory)
+ requestSETID(rpcParameters->sender);
+ }
}
// added 081201 by Owen , allow the server to change the map while its still not in laptop mode
@@ -876,7 +791,7 @@ void send_mapchange(void)
lan.gsMercArriveSectorX=gsMercArriveSectorX;
lan.gsMercArriveSectorY=gsMercArriveSectorY;
- lan.TIME=TIME;
+ lan.startingTime = gStartingTime;
server->RPC("recieveMAPCHANGE",(const char*)&lan, (int)sizeof(mapchange_struct)*8, HIGH_PRIORITY, RELIABLE, 0, UNASSIGNED_SYSTEM_ADDRESS, true, 0, UNASSIGNED_NETWORK_ID,0);
}
@@ -909,53 +824,6 @@ void CheckIncomingConnection(Packet* p)
void AddFilesToSendList()
{
-#ifndef USE_VFS
- STRING512 executableDir;
- GetExecutableDirectory(executableDir);
-
- HANDLE hFileIn;
- HCONTAINER hStack = CreateStack( 100000, 600 );
- WIN32_FIND_DATA find, inFind;
-
- find.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY;
- inFind.dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY;
-
- STRING512 fileTransferDir;
- strcpy(fileTransferDir, executableDir);
-
- // WANNE: Build the complete file transfer directory for the server
- strcat(fileTransferDir, "\\");
- strcat(fileTransferDir, gsFILE_TRANSFER_DIRECTORY_SERVER);
-
- char* correctFileTransferDir = ReplaceCharactersInString_Server(fileTransferDir, "/", "\\");
- if (DirectoryExists(correctFileTransferDir))
- {
- strcat(correctFileTransferDir, "\\*.*");
-
- hFileIn = FindFirstFile( correctFileTransferDir, &inFind );
-
- // Get all files (recursive) inside the folder "cSubDir" == FILE_TRANSFER_DIR_SERVER
- INT32 iNumFiles = GetFilesInDirectory( hStack, correctFileTransferDir, hFileIn, &inFind );
-
- CHAR filename[600];
- INT32 i;
- for ( i=0 ; igetProfileStack();
@@ -969,7 +837,7 @@ void AddFilesToSendList()
CTransferRules transferRules;
transferRules.initFromTxtFile("transfer_rules.txt");
vfs::IBaseLocation* loc = prof->getLocation("");
- THROWIFFALSE(loc != NULL, "MP profile was successfully created, but the root directory is not included");
+ SGP_THROW_IFFALSE(loc != NULL, "MP profile was successfully created, but the root directory is not included");
vfs::IBaseLocation::Iterator it = loc->begin();
int i=0;
for(; !it.end(); it.next(), i++)
@@ -990,269 +858,167 @@ void AddFilesToSendList()
std::vector data(fsize,0);
rfile->read(&data[0], fsize);
rfile->close();
- fileList.AddFile(utf8string::as_utf8(valid_path()).c_str(),&data[0], fsize,fsize,FileListNodeContext(0,0), false);
+ fileList.AddFile(vfs::String::as_utf8(valid_path()).c_str(),&data[0], fsize,fsize,FileListNodeContext(0,0), false);
}
}
- }
- if(i == 0)
- {
- // no files?
- //char* outputTransferDir = ReplaceCharactersInString_Server(correctFileTransferDir, "\\*.*", "");
- //ScreenMsg( FONT_RED, MSG_MPSYSTEM, L"The Sync. MP Directory '%S' does not exist on the server. Cannot send any files to the clients!", outputTransferDir);
- }
-#endif
+ }
}
void start_server (void)
{
if(!is_server)
{
-#ifndef USE_VFS
- CIniReader iniReader("..\\Ja2_mp.ini");
-#else
- CIniReader iniReader("Ja2_mp.ini");
-#endif
- //retrieve settings from .ini
-
- f_rec_num(1,blank);//wipe clean
- //char maxclients[30];
- char port[30];
- char SERVER_PORT[30];
- //char MAX_CLIENTS[30] ;
-#ifndef USE_VFS
- // GetPrivateProfileString( "Ja2_mp Settings","MAX_CLIENTS", "4", maxclients, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","SERVER_PORT", "60005", port, MAX_PATH, "..\\Ja2_mp.ini" );
- // strcpy( MAX_CLIENTS , maxclients );
- strcpy( SERVER_PORT, port );
-#else
- // GetPrivateProfileString( "Ja2_mp Settings","MAX_CLIENTS", "", maxclients, MAX_PATH, "..\\Ja2_mp.ini" );
- strcpy(port, iniReader.ReadString("Ja2_mp Settings","SERVER_PORT", "60005"));
- // strcpy( MAX_CLIENTS , maxclients );
- strcpy( SERVER_PORT, port );
-#endif
-
- char ints[30];
- char maxclients[30];
-
- char hire_same_merc[30];
- char bteam1_enabled[30];
- //char bteam2_enabled[30];
- char bteam3_enabled[30];
- char bteam4_enabled[30];
-
- char player_bside[30];
- char difficult_level[30];
-
- char sBalance[30];
- char time_div[30];
- char mor[30];
-
- char sRandomMercs[30];
- char sRandomEdges[30];
-
- // OJW - 20081204
-#ifndef USE_VFS
- GetPrivateProfileString( "Ja2_mp Settings","SERVER_NAME", "Server Name", SERVER_NAME, MAX_PATH, "..\\Ja2_mp.ini" );
-
- GetPrivateProfileString( "Ja2_mp Settings","SAME_MERC", "1", hire_same_merc, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","DISABLE_MORALE", "0", mor, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","MAX_CLIENTS", "4", maxclients, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","DAMAGE_MULTIPLIER", "0.7", net_div, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","RANDOM_MERCS", "0", sRandomMercs, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","RANDOM_EDGES", "0", sRandomEdges, MAX_PATH, "..\\Ja2_mp.ini" );
-
- GetPrivateProfileString( "Ja2_mp Settings","ENEMY_ENABLED", "0", bteam1_enabled, MAX_PATH, "..\\Ja2_mp.ini" );
- //GetPrivateProfileString( "Ja2_mp Settings","CREATURE_ENABLED", "0", bteam2_enabled, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","MILITIA_ENABLED", "0", bteam3_enabled, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","CIV_ENABLED", "0", bteam4_enabled, MAX_PATH, "..\\Ja2_mp.ini" );
-
- GetPrivateProfileString( "Ja2_mp Settings","GAME_MODE", "0", player_bside, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","DIFFICULT_LEVEL", "3", difficult_level, MAX_PATH, "..\\Ja2_mp.ini" );
-
- // OJW - 20090304 - override max number of ai's in co-op
- char sOverrideMaxAI[30];
- OVERRIDE_MAX_AI = 0;
- GetPrivateProfileString( "Ja2_mp Settings","OVERRIDE_MAX_AI", "0", sOverrideMaxAI, MAX_PATH, "..\\Ja2_mp.ini" );
-
- // WANNE: FILE TRANSFER
- GetPrivateProfileString( "Ja2_mp Settings", "FILE_TRANSFER_DIRECTORY", "Data-MP", gsFILE_TRANSFER_DIRECTORY_SERVER, MAX_PATH, "..\\Ja2_mp.ini" );
-
- char sendFiles[30];
- GetPrivateProfileString( "Ja2_mp Settings", "SYNC_CLIENTS_MP_DIR", "1", sendFiles, MAX_PATH, "..\\Ja2_mp.ini" );
- gsSYNC_CLIENTS_MP_DIR = atoi(sendFiles);
-#else
- strncpy(SERVER_NAME, iniReader.ReadString("Ja2_mp Settings","SERVER_NAME", "Server Name"), 30);
-
- strncpy(hire_same_merc, iniReader.ReadString("Ja2_mp Settings","SAME_MERC", "1"), 30);
- strncpy(mor, iniReader.ReadString("Ja2_mp Settings","DISABLE_MORALE", "0"), 30);
- strncpy(maxclients, iniReader.ReadString("Ja2_mp Settings","MAX_CLIENTS", "4"), 30);
- strncpy(net_div, iniReader.ReadString("Ja2_mp Settings","DAMAGE_MULTIPLIER", "0.7"), 30);
- strncpy(sRandomMercs, iniReader.ReadString("Ja2_mp Settings","RANDOM_MERCS", "0"), 30);
- strncpy(sRandomEdges, iniReader.ReadString("Ja2_mp Settings","RANDOM_EDGES", "0"), 30);
-
- strncpy(bteam1_enabled, iniReader.ReadString("Ja2_mp Settings","ENEMY_ENABLED", "0"), 30);
- //GetPrivateProfileString( "Ja2_mp Settings","CREATURE_ENABLED", "", bteam2_enabled, MAX_PATH, "..\\Ja2_mp.ini" );
- strncpy(bteam3_enabled, iniReader.ReadString("Ja2_mp Settings","MILITIA_ENABLED", "0"), 30);
- strncpy(bteam4_enabled, iniReader.ReadString("Ja2_mp Settings","CIV_ENABLED", "0"), 30);
-
- strncpy(player_bside, iniReader.ReadString( "Ja2_mp Settings","GAME_MODE", "0"), 30);
- strncpy(difficult_level, iniReader.ReadString( "Ja2_mp Settings", "DIFFICULT_LEVEL", "3"), 30);
-
- // OJW - 20090304 - override max number of ai's in co-op
- char sOverrideMaxAI[30];
- OVERRIDE_MAX_AI = 0;
- strncpy(sOverrideMaxAI, iniReader.ReadString("Ja2_mp Settings","OVERRIDE_MAX_AI", "0"), 30);
-
- // WANNE: FILE TRANSFER
- strncpy(gsFILE_TRANSFER_DIRECTORY_SERVER, iniReader.ReadString("Ja2_mp Settings", "FILE_TRANSFER_DIRECTORY", "Data-MP"), 100 );
-
- char sendFiles[30];
- strncpy(sendFiles, iniReader.ReadString( "Ja2_mp Settings", "SYNC_CLIENTS_MP_DIR", "1"), 30 );
- gsSYNC_CLIENTS_MP_DIR = atoi(sendFiles);
-
-#endif
- gsSYNC_CLIENTS_MP_DIR = atoi(sendFiles);
-
-//something new
- gsMORALE=0;
- if(atoi(mor)==1)gsMORALE=1;
-
-#ifndef USE_VFS
- GetPrivateProfileString( "Ja2_mp Settings","KIT_BAG", "[201,214,243]", kbag, MAX_PATH, "..\\Ja2_mp.ini" );
-
- char rpn[30];
- GetPrivateProfileString( "Ja2_mp Settings","REPORT_NAME", "1", rpn, MAX_PATH, "..\\Ja2_mp.ini" );
- gsREPORT_NAME=atoi(rpn);
-
- GetPrivateProfileString( "Ja2_mp Settings","STARTING_BALANCE", "25000", sBalance, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","TIMED_TURN_SECS_PER_TICK", "13.50", time_div, MAX_PATH, "..\\Ja2_mp.ini" );
-
- char dis_bob[30];
- char dis_equip[30];
- char max_merc[30];
- char test[30];
- GetPrivateProfileString( "Ja2_mp Settings","DISABLE_BOBBY_RAYS", "", dis_bob, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","DISABLE_AIM_AND_MERC_EQUIP", "", dis_equip, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","MAX_MERCS", "5", max_merc, MAX_PATH, "..\\Ja2_mp.ini" );
- GetPrivateProfileString( "Ja2_mp Settings","TESTING", "0", test, MAX_PATH, "..\\Ja2_mp.ini" );
- gsDis_Bobby=false;
- gsDis_Equip=false;
-#else
- strncpy(kbag, iniReader.ReadString("Ja2_mp Settings","KIT_BAG", "[201,214,243]"), 100);
-
- char rpn[30];
- strncpy(rpn, iniReader.ReadString("Ja2_mp Settings","REPORT_NAME", "1"), 30);
- gsREPORT_NAME=atoi(rpn);
-
- strncpy(sBalance, iniReader.ReadString("Ja2_mp Settings","STARTING_BALANCE", "25000"), 30);
- strncpy(time_div, iniReader.ReadString("Ja2_mp Settings","TIMED_TURN_SECS_PER_TICK", "25"), 30);
-
- char dis_bob[30];
- char dis_equip[30];
- char max_merc[30];
- char test[30];
- strncpy(dis_bob, iniReader.ReadString("Ja2_mp Settings","DISABLE_BOBBY_RAYS", "0"), 30);
- strncpy(dis_equip, iniReader.ReadString("Ja2_mp Settings","DISABLE_AIM_AND_MERC_EQUIP", "0"), 30);
- strncpy(max_merc, iniReader.ReadString("Ja2_mp Settings","MAX_MERCS", "5"), 30);
- strncpy(test, iniReader.ReadString("Ja2_mp Settings","TESTING", "0"), 30);
- gsDis_Bobby=false;
- gsDis_Equip=false;
-#endif
-
- if(atoi(dis_bob)==1)gsDis_Bobby=true;
- if(atoi(dis_equip)==1)gsDis_Equip=true;
-
- gsMAX_MERCS=atoi(max_merc);
- gsTESTING = atoi(test);
-
- gsPLAYER_BSIDE = atoi(player_bside);
-
- gsDIFFICULT_LEVEL = atoi(difficult_level);
- ENEMY_ENABLED=0;
- CREATURE_ENABLED=0;
- MILITIA_ENABLED=0;
- CIV_ENABLED=0;
-
- RANDOM_MERCS = atoi(sRandomMercs);
- RANDOM_SPAWN = atoi(sRandomEdges);
-
- if (RANDOM_SPAWN)
- {
- // create random starting edges
- int spawns[5] = { 0 , 1 , 2 , 3, 9 };
+ f_rec_num(1,blank);//wipe clean
- // Randomize spawns
- rSortArray(spawns,5);
- memcpy(client_edges,spawns,sizeof(int)*5);
- }
+ // ----------------------------
+ // Read from ja2_mp.ini
+ // ----------------------------
- if (RANDOM_MERCS)
- {
- // randomly sort team indexes to give client
- // one of four random merc teams
- rSortArray(client_mercteam,4);
- mpTeams.HandleServerStarted();
- }
+ CIniReader iniReader(JA2MP_INI_FILENAME); // Wird nur fr Strings gebraucht
+ strncpy(cServerName, iniReader.ReadString(JA2MP_INI_INITIAL_SECTION, JA2MP_SERVER_NAME, "My JA2 Server"), 30 );
+ strncpy(gKitBag, iniReader.ReadString(JA2MP_INI_INITIAL_SECTION,JA2MP_KIT_BAG, ""), 100);
+
+ vfs::PropertyContainer props;
+ props.initFromIniFile(JA2MP_INI_FILENAME);
+ UINT16 serverPort = (UINT16)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_SERVER_PORT, 60005);
+ UINT8 maxClients = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_MAX_CLIENTS, 4);
+ UINT8 sameMercAllowed = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_SAME_MERC, 1);
+ UINT8 civEnabled = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_CIV_ENABLED, 0);
+ UINT8 gameType = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_GAME_MODE, 0);
+ UINT8 difficultyLevel = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_DIFFICULT_LEVEL, 3);
+ UINT8 skillTraits = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_NEW_TRAITS, 0);
+ UINT8 randomMercs = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION,JA2MP_RANDOM_MERCS, 0);
+ UINT8 randomStartingEdge = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_RANDOM_EDGES, 0);
+ UINT8 damageSelection = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_DAMAGE_MULTIPLIER, 1);
+ UINT8 maxEnemiesEnabled = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_OVERRIDE_MAX_AI, 0);
+ UINT8 syncGameDirectory = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_SYNC_CLIENTS_MP_DIR, 1);
+ UINT8 reportHiredMerc = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_REPORT_NAME, 1);
+ UINT8 startingCashSelection = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_STARTING_BALANCE, 25000);
+ UINT8 timeTurnsSelection = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_TIMED_TURN_SECS_PER_TICK, 2);
+ UINT8 disableBobbyRay = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_DISABLE_BOBBY_RAYS, 0);
+ UINT8 maxMercs = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_MAX_MERCS, 6);
+ UINT8 timeSelection = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_TIME, 1);
+ UINT8 inventoryAttachment = (UINT8)props.getIntProperty(JA2MP_INI_INITIAL_SECTION, JA2MP_ALLOW_CUSTOM_NIV, 0);
- if(gsPLAYER_BSIDE==2)//only enable ai during coop
- {
- ENEMY_ENABLED = 1; // always enable enemies in co-op
- MILITIA_ENABLED = atoi(bteam3_enabled);
- CIV_ENABLED = atoi(bteam4_enabled);
- // OJW - 20090403 - override max ais
- if (atoi(sOverrideMaxAI)==1)
- OVERRIDE_MAX_AI = 1;
- }
+ // ----------------------------
+ // Save to global values
+ // ----------------------------
+ gMaxClients = maxClients;
+ gMaxEnemiesEnabled = 0;
+ gDisableMorale = 0;
+ gSyncGameDirectory = syncGameDirectory;
+ gReportHiredMerc = reportHiredMerc;
+ gDisableBobbyRay = disableBobbyRay;
+ gDisableMercEquipment = 0; // Disable AIM and MERC equipment
+ gMaxMercs = maxMercs;
+ gGameType = gameType;
+ gDifficultyLevel = difficultyLevel;
+ gSkillTraits = skillTraits;
+ gEnemyEnabled = 0;
+ gCreatureEnabled = 0;
+ gMilitiaEnabled = 0;
+ gCivEnabled = 0;
+ gRandomMercs = randomMercs;
+ gRandomStartingEdge = randomStartingEdge;
+ gWeaponReadyBonus = 0;
+ gDisableSpectatorMode = 0;
+ gInventoryAttachment = inventoryAttachment;
- // random_mercs implies same_merc
- gsSAME_MERC = RANDOM_MERCS ? 1 : atoi(hire_same_merc);
- gsDAMAGE_MULTIPLIER =(FLOAT)atof(net_div);
- gsINTERRUPTS = atoi(ints);
- gsMAX_CLIENTS = atoi(maxclients);
+ if (gRandomStartingEdge)
+ {
+ // create random starting edges
+ int spawns[5] = { 0 , 1 , 2 , 3, 9 }; // 9 == Center
+
+ // Randomize spawns
+ rSortArray(spawns,5);
+ memcpy(client_edges,spawns,sizeof(int)*5);
+ }
- gssecs_per_tick=atoi(time_div) ;
- gsstarting_balance=atoi(sBalance);
-#ifndef USE_VFS
- char time[30];
- GetPrivateProfileString( "Ja2_mp Settings","TIME", "", time, MAX_PATH, "..\\Ja2_mp.ini" );
- TIME=(FLOAT)atof(time);
+ if (gRandomMercs)
+ {
+ // randomly sort team indexes to give client
+ // one of four random merc teams
+ rSortArray(client_mercteam,4);
+ mpTeams.HandleServerStarted();
+ }
- char wpr[30];
- GetPrivateProfileString( "Ja2_mp Settings","WEAPON_READIED_BONUS", "", wpr, MAX_PATH, "..\\Ja2_mp.ini" );
- sWEAPON_READIED_BONUS=atoi(wpr);
+ if(gGameType == MP_TYPE_COOP)//only enable ai during coop
+ {
+ gEnemyEnabled = 1; // always enable enemies in co-op
+ gMilitiaEnabled = 0; // always disable militia
+ gCivEnabled = civEnabled;
+ gMaxEnemiesEnabled = maxEnemiesEnabled;
+ }
- char acniv[30];
- GetPrivateProfileString( "Ja2_mp Settings","ALLOW_CUSTOM_NIV", "", acniv, MAX_PATH, "..\\Ja2_mp.ini" );
- sALLOW_CUSTOM_NIV=atoi(acniv);
+ // random_mercs implies same_merc
+ gSameMercAllowed = gRandomMercs ? 1 : sameMercAllowed;
+
+ switch (damageSelection)
+ {
+ case 0: // Very Low
+ gDamageMultiplier = 0.2f;
+ break;
+ case 1: // Low
+ gDamageMultiplier = 0.7f;
+ break;
+ case 2: // Normal
+ gDamageMultiplier = 1.0f;
+ break;
+ }
- char dspec[30];
- GetPrivateProfileString( "Ja2_mp Settings","DISABLE_SPEC_MODE", "", dspec, MAX_PATH, "..\\Ja2_mp.ini" );
- sDISABLE_SPEC_MODE=atoi(dspec);
-#else
- char time[30];
- strncpy(time, iniReader.ReadString("Ja2_mp Settings","TIME", "0"), 30);
- TIME=(FLOAT)atof(time);
+ switch (timeTurnsSelection)
+ {
+ case 0: // Never
+ gSecondsPerTick = 0;
+ break;
+ case 1: // Slow
+ gSecondsPerTick = 5;
+ break;
+ case 2: // Medium
+ gSecondsPerTick = 100;
+ break;
+ case 3: // Fast
+ gSecondsPerTick = 400;
+ break;
+ }
- char wpr[30];
- strncpy(wpr, iniReader.ReadString("Ja2_mp Settings","WEAPON_READIED_BONUS", "0"), 30);
- sWEAPON_READIED_BONUS=atoi(wpr);
-
- char acniv[30];
- strncpy(acniv, iniReader.ReadString("Ja2_mp Settings","ALLOW_CUSTOM_NIV", "0"), 30);
- sALLOW_CUSTOM_NIV=atoi(acniv);
-
- char dspec[30];
- strncpy(dspec, iniReader.ReadString("Ja2_mp Settings","DISABLE_SPEC_MODE", "0"), 30);
- sDISABLE_SPEC_MODE=atoi(dspec);
-#endif
- //**********************
+ switch (startingCashSelection)
+ {
+ case 0: // Low
+ gStartingCash = 5000;
+ break;
+ case 1: // Medium
+ gStartingCash = 50000;
+ break;
+ case 2: // High
+ gStartingCash = 100000;
+ break;
+ case 3: // Unlimited
+ gStartingCash = 999999999;
+ break;
+ }
+
+ switch (timeSelection)
+ {
+ case 0: // Morning
+ gStartingTime = 7.00f;
+ break;
+ case 1: // Afternoon
+ gStartingTime = 13.00f;
+ break;
+ case 2: // Night
+ gStartingTime = 2.00;
+ break;
+ }
+
+ //**********************
ScreenMsg( FONT_ORANGE, MSG_MPSYSTEM, MPServerMessage[0] );
server=RakNetworkFactory::GetRakPeerInterface();
- bool b = server->Startup(gsMAX_CLIENTS, 30, &SocketDescriptor(atoi(SERVER_PORT),0), 1);
+ bool b = server->Startup(gMaxClients, 30, &SocketDescriptor(serverPort,0), 1);
- server->SetMaximumIncomingConnections((gsMAX_CLIENTS));
+ server->SetMaximumIncomingConnections((gMaxClients));
//RPC's
REGISTER_STATIC_RPC(server, sendPATH);
@@ -1286,9 +1052,7 @@ void start_server (void)
REGISTER_STATIC_RPC(server, sendDEATH);
REGISTER_STATIC_RPC(server, sendhitSTRUCT);
REGISTER_STATIC_RPC(server, sendhitWINDOW);
- REGISTER_STATIC_RPC(server, sendMISS);
- //REGISTER_STATIC_RPC(server, rOVH);
-
+ REGISTER_STATIC_RPC(server, sendMISS);
REGISTER_STATIC_RPC(server, updatenetworksoldier);
REGISTER_STATIC_RPC(server, Snull_team);
REGISTER_STATIC_RPC(server, sendFIREW);
@@ -1302,25 +1066,20 @@ void start_server (void)
REGISTER_STATIC_RPC(server, sendTEAMCHANGE);
REGISTER_STATIC_RPC(server, sendGAMEOVER);
REGISTER_STATIC_RPC(server, sendCHATMSG);
- REGISTER_STATIC_RPC(server, receiveSETID);
- //REGISTER_STATIC_RPC(server, sendALLFILESRECEIVED);
- //REGISTER_STATIC_RPC(server, rINT);
- //
+ REGISTER_STATIC_RPC(server, receiveSETID);
if (b)
{
- ScreenMsg( FONT_ORANGE, MSG_MPSYSTEM, MPServerMessage[1]);
- //ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, MPServerMessage[2]);
+ ScreenMsg( FONT_ORANGE, MSG_MPSYSTEM, MPServerMessage[1]);
is_server = true;
-
// WANNE: FILE TRANSFER
server->AttachPlugin(&fltServer);
server->SetSplitMessageProgressInterval(1);
fltServer.SetCallback(&serverFileListProgress);
fileListTotalBytes=0;
- if (gsSYNC_CLIENTS_MP_DIR == 1)
+ if (gSyncGameDirectory == 1)
{
AddFilesToSendList();
}
@@ -1339,7 +1098,6 @@ void start_server (void)
}
-
// recieve and process server info packets
void server_packet ( void )
diff --git a/Multiplayer/transfer_rules.cpp b/Multiplayer/transfer_rules.cpp
new file mode 100644
index 00000000..aac4e2fb
--- /dev/null
+++ b/Multiplayer/transfer_rules.cpp
@@ -0,0 +1,126 @@
+#include "transfer_rules.h"
+#include "Debug.h"
+#include
+#include
+#include
+#include
+#include
+
+CTransferRules::CTransferRules()
+: m_eDefaultAction(ACCEPT)
+{};
+
+
+bool CTransferRules::initFromTxtFile(vfs::Path const& sPath)
+{
+ // try to open via VirtualFileSystem
+ if(getVFS()->fileExists(sPath))
+ {
+ return initFromTxtFile(getVFS()->getReadFile(sPath));
+ }
+ else
+ {
+ // file doesn't exist or VFS not initialized yet
+ vfs::IBaseFile* pFile = new vfs::CFile(sPath);
+ if(pFile)
+ {
+ bool success = initFromTxtFile(vfs::tReadableFile::cast(pFile));
+ delete pFile;
+ return success;
+ }
+ }
+ return false;
+}
+
+bool CTransferRules::initFromTxtFile(vfs::tReadableFile* pFile)
+{
+ if(pFile && pFile->openRead())
+ {
+ vfs::COpenReadFile rfile(pFile);
+ std::string sBuffer;
+ vfs::UInt32 line_counter = 0;
+ vfs::CReadLine rl(*pFile);
+ while(rl.getLine(sBuffer))
+ {
+ line_counter++;
+ // very simple parsing : key = value
+ if(!sBuffer.empty())
+ {
+ // remove leading white spaces
+ ::size_t iStart = sBuffer.find_first_not_of(" \t",0);
+ char first = sBuffer.at(iStart);
+ switch(first)
+ {
+ case '!':
+ case ';':
+ case '#':
+ // comment -> do nothing
+ break;
+ default:
+ ::size_t iEnd = sBuffer.find_first_of(" \t", iStart);
+ if(iEnd != std::string::npos)
+ {
+ SRule rule;
+ std::string action = sBuffer.substr(iStart, iEnd - iStart);
+ if( vfs::StrCmp::Equal(action, "deny") )
+ {
+ rule.action = CTransferRules::DENY;
+ }
+ else if( vfs::StrCmp::Equal(action, "accept") )
+ {
+ rule.action = CTransferRules::ACCEPT;
+ }
+ else
+ {
+ std::wstring trybuffer = L"Invalid UTF-8 character in string";
+ VFS_IGNOREEXCEPTION( trybuffer = vfs::String(sBuffer).c_wcs(), "" ); /* just make sure we don't break off when string conversion fails */
+ std::wstringstream wss;
+ wss << L"Unknown action in file \"" << pFile->getPath().c_wcs()
+ << L", line " << line_counter << " : " << vfs::String(sBuffer).c_wcs();
+ SGP_THROW(wss.str().c_str());
+ }
+ try
+ {
+ rule.pattern = vfs::Path(vfs::trimString(sBuffer, iEnd, sBuffer.length()));
+ }
+ catch(vfs::Exception& ex)
+ {
+ std::wstringstream wss;
+ wss << L"Could not convert string, invalid utf8 encoding in file \"" << pFile->getPath().c_wcs()
+ << L"\", line " << line_counter;
+ SGP_RETHROW(wss.str().c_str(), ex);
+ }
+ m_listRules.push_back(rule);
+ }
+ break;
+ }; // end switch
+ } // end if (empty)
+ } // end while(!eof)
+ return true;
+ }
+ return false;
+}
+
+void CTransferRules::setDefaultAction(CTransferRules::EAction act)
+{
+ m_eDefaultAction = act;
+}
+
+CTransferRules::EAction CTransferRules::getDefaultAction()
+{
+ return m_eDefaultAction;
+}
+
+CTransferRules::EAction CTransferRules::applyRule(vfs::String const& sStr)
+{
+ tPatternList::iterator sit = m_listRules.begin();
+ for(; sit != m_listRules.end(); ++sit)
+ {
+ if(matchPattern(sit->pattern(), sStr))
+ {
+ return sit->action;
+ }
+ }
+ return m_eDefaultAction;
+}
+
diff --git a/Multiplayer/transfer_rules.h b/Multiplayer/transfer_rules.h
new file mode 100644
index 00000000..11c0a516
--- /dev/null
+++ b/Multiplayer/transfer_rules.h
@@ -0,0 +1,39 @@
+#ifndef _TRANSFER_RULES_H_
+#define _TRANSFER_RULES_H_
+
+#include
+#include
+
+#include
+
+class CTransferRules
+{
+public:
+ enum EAction
+ {
+ DENY,
+ ACCEPT,
+ };
+public:
+ CTransferRules();
+
+ bool initFromTxtFile(vfs::Path const& sPath);
+ bool initFromTxtFile(vfs::tReadableFile* pFile);
+
+ void setDefaultAction(EAction act);
+ EAction getDefaultAction();
+
+ EAction applyRule(vfs::String const& sStr);
+private:
+ struct SRule
+ {
+ EAction action;
+ vfs::Path pattern;
+ };
+ typedef std::list tPatternList;
+ tPatternList m_listRules;
+ EAction m_eDefaultAction;
+};
+
+
+#endif // _TRANSFER_RULES_H_
diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp
index b5ba248a..32db5250 100644
--- a/SaveLoadGame.cpp
+++ b/SaveLoadGame.cpp
@@ -112,6 +112,7 @@
#include "Facilities.h"
// HEADROCK HAM 3.6: Yet another include, goddammit
#include "Town Militia.h"
+ #include "Items.h"
#endif
#include "BobbyR.h"
@@ -124,8 +125,11 @@
#include "BobbyRMailOrder.h"
#include "Mercs.h"
#include "INIReader.h"
+#include "mercs.h"
+#include "soldier Profile.h"
+#include "LuaInitNPCs.h"
-#include "VFS/vfs.h"
+#include
//rain
#include "Rain.h"
//end rain
@@ -139,6 +143,7 @@
//
/////////////////////////////////////////////////////
+#include "LuaInitNPCs.h"
void GetBestPossibleSectorXYZValues( INT16 *psSectorX, INT16 *psSectorY, INT8 *pbSectorZ );
extern void NextLoopCheckForEnoughFreeHardDriveSpace();
@@ -218,6 +223,7 @@ typedef struct
BOOLEAN fShowTeamFlag;
BOOLEAN fShowMineFlag;
BOOLEAN fShowAircraftFlag;
+ BOOLEAN fShowMobileRestrictionsFlag; // HEADROCK HAM 4: Showing Manual Mobile Restrictions
// is the helicopter available to player?
BOOLEAN fHelicopterAvailable;
@@ -406,8 +412,12 @@ typedef struct
// HEADROCK HAM 3.6: Global variable keeping track of Militia Upkeep Costs at last midnight.
UINT32 uiTotalUpkeepForMilitia;
- // HEADROCK HAM 3.6: Removed 16 fillers (16 bytes) to accomodate the above new variables.
- UINT8 ubFiller[534]; //This structure should be 1024 bytes
+ // HEADROCK HAM 4: Added manual restrictions
+ UINT8 ubManualRestrictMilitia[256];
+
+ BOOLEAN HiddenNames[500]; //legion by Jazz
+
+ UINT8 ubFiller[278]; //This structure should be 1588 bytes
} GENERAL_SAVE_INFO;
@@ -433,6 +443,7 @@ extern EmailPtr pEmailList;
extern UINT32 guiCurrentUniqueSoldierId;
extern BOOLEAN gfHavePurchasedItemsFromTony;
+INT32 ReadFieldByField(HWFILE hFile, PTR pDest, UINT32 uiFieldSize, UINT32 uiElementSize, UINT32 uiCurByteCount);
/////////////////////////////////////////////////////
//
@@ -1158,17 +1169,181 @@ BOOLEAN SOLDIERCREATE_STRUCT::Load(HWFILE hFile, int versionToLoad, bool loadChe
//BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion)
BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool forceLoadOldEncryption, bool wasSavedWithEncryption)
{
- UINT32 uiNumBytesRead;
+ UINT32 uiNumBytesRead;
+ INT32 numBytesRead = 0;
this->initialize();
//if we are at the most current version, then fine
if ( guiCurrentSaveGameVersion >= NIV_SAVEGAME_DATATYPE_CHANGE && forceLoadOldVersion == false)
{
// WANNE - BMP: DONE!
- if ( !FileRead( hFile, this, SIZEOF_MERCPROFILESTRUCT_POD, &uiNumBytesRead ) )
- {
- return(FALSE);
+// if ( !FileRead( hFile, this, SIZEOF_MERCPROFILESTRUCT_POD, &uiNumBytesRead ) )
+// {
+// return(FALSE);
+// }
+ FileRead( hFile, this->zName, sizeof(this->zName), &uiNumBytesRead);
+ numBytesRead += uiNumBytesRead;
+ numBytesRead = ReadFieldByField( hFile, this->zNickname, sizeof(this->zNickname), sizeof(CHAR16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiAttnSound, sizeof(this->uiAttnSound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiCurseSound, sizeof(this->uiCurseSound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiDieSound, sizeof(this->uiDieSound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiGoodSound, sizeof(this->uiGoodSound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiGruntSound, sizeof(this->uiGruntSound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiGrunt2Sound, sizeof(this->uiGrunt2Sound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiOkSound, sizeof(this->uiOkSound), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubFaceIndex, sizeof(this->ubFaceIndex), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->PANTS, sizeof(this->PANTS), sizeof(CHAR8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->VEST, sizeof(this->VEST), sizeof(CHAR8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->SKIN, sizeof(this->SKIN), sizeof(CHAR8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->HAIR, sizeof(this->HAIR), sizeof(CHAR8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bSex, sizeof(this->bSex), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bArmourAttractiveness, sizeof(this->bArmourAttractiveness), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubMiscFlags2, sizeof(this->ubMiscFlags2), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bEvolution, sizeof(this->bEvolution), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubMiscFlags, sizeof(this->ubMiscFlags), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bSexist, sizeof(this->bSexist), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLearnToHate, sizeof(this->bLearnToHate), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bStealRate, sizeof(this->bStealRate), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bVocalVolume, sizeof(this->bVocalVolume), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubQuoteRecord, sizeof(this->ubQuoteRecord), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bDeathRate, sizeof(this->bDeathRate), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bScientific, sizeof(this->bScientific), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sExpLevelGain, sizeof(this->sExpLevelGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sLifeGain, sizeof(this->sLifeGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sAgilityGain, sizeof(this->sAgilityGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sDexterityGain, sizeof(this->sDexterityGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sWisdomGain, sizeof(this->sWisdomGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sMarksmanshipGain, sizeof(this->sMarksmanshipGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sMedicalGain, sizeof(this->sMedicalGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sMechanicGain, sizeof(this->sMechanicGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sExplosivesGain, sizeof(this->sExplosivesGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubBodyType, sizeof(this->ubBodyType), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMedical, sizeof(this->bMedical), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usEyesX, sizeof(this->usEyesX), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usEyesY, sizeof(this->usEyesY), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usMouthX, sizeof(this->usMouthX), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usMouthY, sizeof(this->usMouthY), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiEyeDelay, sizeof(this->uiEyeDelay), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiMouthDelay, sizeof(this->uiMouthDelay), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiBlinkFrequency, sizeof(this->uiBlinkFrequency), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiExpressionFrequency, sizeof(this->uiExpressionFrequency), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sSectorX, sizeof(this->sSectorX), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sSectorY, sizeof(this->sSectorY), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiDayBecomesAvailable, sizeof(this->uiDayBecomesAvailable), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bStrength, sizeof(this->bStrength), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLifeMax, sizeof(this->bLifeMax), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bExpLevelDelta, sizeof(this->bExpLevelDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLifeDelta, sizeof(this->bLifeDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bAgilityDelta, sizeof(this->bAgilityDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bDexterityDelta, sizeof(this->bDexterityDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bWisdomDelta, sizeof(this->bWisdomDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMarksmanshipDelta, sizeof(this->bMarksmanshipDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMedicalDelta, sizeof(this->bMedicalDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMechanicDelta, sizeof(this->bMechanicDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bExplosivesDelta, sizeof(this->bExplosivesDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bStrengthDelta, sizeof(this->bStrengthDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLeadershipDelta, sizeof(this->bLeadershipDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usTotalDaysServed, sizeof(this->usTotalDaysServed), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sLeadershipGain, sizeof(this->sLeadershipGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sStrengthGain, sizeof(this->sStrengthGain), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiBodyTypeSubFlags, sizeof(this->uiBodyTypeSubFlags), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sSalary, sizeof(this->sSalary), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLife, sizeof(this->bLife), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bDexterity, sizeof(this->bDexterity), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bDisability, sizeof(this->bDisability), sizeof(INT8), numBytesRead);
+ if(guiCurrentSaveGameVersion >= STOMP12_SAVEGAME_DATATYPE_CHANGE2)
+ numBytesRead = ReadFieldByField( hFile, this->bSkillTraits, sizeof(this->bSkillTraits), sizeof(INT8), numBytesRead);
+ else //CHRISL: Prior to STOMP12_SAVEGAME_DATATYPE_CHANGE2, bSkillTraits was only a single INT8 value
+ numBytesRead = ReadFieldByField( hFile, this->bSkillTraits, sizeof(INT8), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bReputationTolerance, sizeof(this->bReputationTolerance), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bExplosive, sizeof(this->bExplosive), sizeof(INT8), numBytesRead);
+ if(guiCurrentSaveGameVersion < STOMP12_SAVEGAME_DATATYPE_CHANGE2)
+ { //CHRISL: These two variables no longer exist but we should read them into bSKillTraits[1] and [2]
+ numBytesRead = ReadFieldByField( hFile, &this->bSkillTraits[1], sizeof(INT8), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bSkillTraits[2], sizeof(INT8), sizeof(INT8), numBytesRead);
}
+ numBytesRead = ReadFieldByField( hFile, &this->bLeadership, sizeof(this->bLeadership), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->bBuddy, sizeof(this->bBuddy), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->bHated, sizeof(this->bHated), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bExpLevel, sizeof(this->bExpLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMarksmanship, sizeof(this->bMarksmanship), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMinService, sizeof(this->bMinService), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bWisdom, sizeof(this->bWisdom), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bResigned, sizeof(this->bResigned), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bActive, sizeof(this->bActive), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->usApproachFactor, sizeof(this->usApproachFactor), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMainGunAttractiveness, sizeof(this->bMainGunAttractiveness), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bAgility, sizeof(this->bAgility), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->fUseProfileInsertionInfo, sizeof(this->fUseProfileInsertionInfo), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->_old_sGridNo, sizeof(this->_old_sGridNo), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubQuoteActionID, sizeof(this->ubQuoteActionID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMechanical, sizeof(this->bMechanical), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubInvUndroppable, sizeof(this->ubInvUndroppable), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->ubRoomRangeStart, sizeof(this->ubRoomRangeStart), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->bMercTownReputation, sizeof(this->bMercTownReputation), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->usStatChangeChances, sizeof(this->usStatChangeChances), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->usStatChangeSuccesses, sizeof(this->usStatChangeSuccesses), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubStrategicInsertionCode, sizeof(this->ubStrategicInsertionCode), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->ubRoomRangeEnd, sizeof(this->ubRoomRangeEnd), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubLastQuoteSaid, sizeof(this->ubLastQuoteSaid), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bRace, sizeof(this->bRace), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bNationality, sizeof(this->bNationality), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bAppearance, sizeof(this->bAppearance), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bAppearanceCareLevel, sizeof(this->bAppearanceCareLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bRefinement, sizeof(this->bRefinement), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bRefinementCareLevel, sizeof(this->bRefinementCareLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bHatedNationality, sizeof(this->bHatedNationality), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bHatedNationalityCareLevel, sizeof(this->bHatedNationalityCareLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bRacist, sizeof(this->bRacist), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiWeeklySalary, sizeof(this->uiWeeklySalary), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiBiWeeklySalary, sizeof(this->uiBiWeeklySalary), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMedicalDeposit, sizeof(this->bMedicalDeposit), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bAttitude, sizeof(this->bAttitude), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bCharacterTrait, sizeof(this->bCharacterTrait), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bBaseMorale, sizeof(this->bBaseMorale), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sMedicalDepositAmount, sizeof(this->sMedicalDepositAmount), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLearnToLike, sizeof(this->bLearnToLike), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->ubApproachVal, sizeof(this->ubApproachVal), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->ubApproachMod, sizeof(this->ubApproachMod), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bTown, sizeof(this->bTown), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bTownAttachment, sizeof(this->bTownAttachment), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usOptionalGearCost, sizeof(this->usOptionalGearCost), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->bMercOpinion, sizeof(this->bMercOpinion), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bApproached, sizeof(this->bApproached), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bMercStatus, sizeof(this->bMercStatus), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->bHatedTime, sizeof(this->bHatedTime), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLearnToLikeTime, sizeof(this->bLearnToLikeTime), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLearnToHateTime, sizeof(this->bLearnToHateTime), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, this->bHatedCount, sizeof(this->bHatedCount), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLearnToLikeCount, sizeof(this->bLearnToLikeCount), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLearnToHateCount, sizeof(this->bLearnToHateCount), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubLastDateSpokenTo, sizeof(this->ubLastDateSpokenTo), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bLastQuoteSaidWasSpecial, sizeof(this->bLastQuoteSaidWasSpecial), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bSectorZ, sizeof(this->bSectorZ), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->usStrategicInsertionData, sizeof(this->usStrategicInsertionData), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bFriendlyOrDirectDefaultResponseUsedRecently, sizeof(this->bFriendlyOrDirectDefaultResponseUsedRecently), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bRecruitDefaultResponseUsedRecently, sizeof(this->bRecruitDefaultResponseUsedRecently), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bThreatenDefaultResponseUsedRecently, sizeof(this->bThreatenDefaultResponseUsedRecently), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bNPCData, sizeof(this->bNPCData), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->iBalance, sizeof(this->iBalance), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sTrueSalary, sizeof(this->sTrueSalary), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubCivilianGroup, sizeof(this->ubCivilianGroup), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubNeedForSleep, sizeof(this->ubNeedForSleep), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiMoney, sizeof(this->uiMoney), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->bNPCData2, sizeof(this->bNPCData2), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubMiscFlags3, sizeof(this->ubMiscFlags3), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubDaysOfMoraleHangover, sizeof(this->ubDaysOfMoraleHangover), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubNumTimesDrugUseInLifetime, sizeof(this->ubNumTimesDrugUseInLifetime), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiPrecedentQuoteSaid, sizeof(this->uiPrecedentQuoteSaid), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiProfileChecksum, sizeof(this->uiProfileChecksum), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->_old_sPreCombatGridNo, sizeof(this->_old_sPreCombatGridNo), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubTimeTillNextHatedComplaint, sizeof(this->ubTimeTillNextHatedComplaint), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->ubSuspiciousDeath, sizeof(this->ubSuspiciousDeath), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->iMercMercContractLength, sizeof(this->iMercMercContractLength), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->uiTotalCostToDate, sizeof(this->uiTotalCostToDate), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sGridNo, sizeof(this->sGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField( hFile, &this->sPreCombatGridNo, sizeof(this->sPreCombatGridNo), sizeof(INT32), numBytesRead);
+ //numBytesRead = ReadFieldByField( hFile, &this->endOfPOD, sizeof(this->endOfPOD), sizeof(char), numBytesRead);
int size;
if ( !FileRead( hFile, &size, sizeof(int), &uiNumBytesRead ) )
{
@@ -1197,6 +1372,11 @@ BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool for
bInvStatus[x] = status;
bInvNumber[x] = number;
}
+ // SANDRO - read records
+ if ( !FileRead( hFile, &this->records, sizeof(STRUCT_Records), &uiNumBytesRead ) )
+ {
+ return(FALSE);
+ }
if ( this->uiProfileChecksum != this->GetChecksum() )
{
return( FALSE );
@@ -1269,6 +1449,11 @@ BOOLEAN MERCPROFILESTRUCT::Save(HWFILE hFile)
return(FALSE);
}
}
+ // SANDRO - save records
+ if ( !FileWrite( hFile, &this->records, sizeof(STRUCT_Records), &uiNumBytesWritten ) )
+ {
+ return(FALSE);
+ }
return TRUE;
}
@@ -1318,7 +1503,10 @@ BOOLEAN SOLDIERTYPE::Save(HWFILE hFile)
}
return TRUE;
}
-
+/*CHRISL: This function is designed to allow reading the save game file one field at a time. We currently save structures by saving a block of memory,
+but variables are stored in memory so that they fit neatly into a WORD resulting in the program automatically adding some padding. This padding is saved
+during the save game process and this function is designed to calculate where that padding is so that we can account for it during the load process. The
+use of this function should allow changes to be made to various structures within the designated "POD", while still allowing for save game continuity.*/
INT32 ReadFieldByField(HWFILE hFile, PTR pDest, UINT32 uiFieldSize, UINT32 uiElementSize, UINT32 uiCurByteCount)
{
UINT32 uiNumBytesRead;
@@ -1345,14 +1533,336 @@ INT32 ReadFieldByField(HWFILE hFile, PTR pDest, UINT32 uiFieldSize, UINT32 uiEle
BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
{
UINT32 uiNumBytesRead;
- INT32 numBytesRead = 0;
+ INT32 numBytesRead = 0, temp = 0;
char padding[10];
//if we are at the most current version, then fine
if ( guiCurrentSaveGameVersion >= NIV_SAVEGAME_DATATYPE_CHANGE )
{
//the soldier type info has changed at version 102
- //CHRISL: It was further changed at version 104 to allow for 16bit action points for the 100AP system
+ //CHRISL: To accomodate future changes to this structure, we'll load each value field by field
+ numBytesRead = 0;
+ FileRead( hFile, this, (offsetof(SOLDIERTYPE, ubBodyType)+sizeof(ubBodyType)), &uiNumBytesRead );
+ numBytesRead += uiNumBytesRead;
+ if(guiCurrentSaveGameVersion >= AP100_SAVEGAME_DATATYPE_CHANGE)
+ { //CHRISL: It was changed at version 104 to allow for 16bit action points for the 100AP system
+ numBytesRead = ReadFieldByField(hFile, &this->bActionPoints, sizeof(bActionPoints), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bInitialActionPoints, sizeof(bInitialActionPoints), sizeof(INT16), numBytesRead);
+ }
+ else
+ {
+ numBytesRead = ReadFieldByField(hFile, &this->bActionPoints, sizeof(bActionPoints), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bInitialActionPoints, sizeof(bInitialActionPoints), sizeof(INT8), numBytesRead);
+ }
+ numBytesRead = ReadFieldByField(hFile, &this->bOldLife, sizeof(bOldLife), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bVisible, sizeof(bVisible), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bActive, sizeof(bActive), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTeam, sizeof(bTeam), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pTempObject, sizeof(pTempObject), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pKeyRing, sizeof(pKeyRing), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bInSector, sizeof(bInSector), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bFlashPortraitFrame, sizeof(bFlashPortraitFrame), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sFractLife, sizeof(sFractLife), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBleeding, sizeof(bBleeding), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBreath, sizeof(bBreath), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBreathMax, sizeof(bBreathMax), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bStealthMode, sizeof(bStealthMode), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sBreathRed, sizeof(sBreathRed), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubWaitActionToDo, sizeof(ubWaitActionToDo), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubInsertionDirection, sizeof(ubInsertionDirection), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bGunType, sizeof(bGunType), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubOppNum, sizeof(ubOppNum), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bLastRenderVisibleValue, sizeof(bLastRenderVisibleValue), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubAttackingHand, sizeof(ubAttackingHand), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sWeightCarriedAtTurnStart, sizeof(sWeightCarriedAtTurnStart), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iHealableInjury, sizeof(iHealableInjury), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->fDoingSurgery, sizeof(fDoingSurgery), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->lUnregainableBreath, sizeof(lUnregainableBreath), sizeof(signed long), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubCriticalStatDamage, sizeof(ubCriticalStatDamage), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubGroupID, sizeof(ubGroupID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubMovementNoiseHeard, sizeof(ubMovementNoiseHeard), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->dXPos, sizeof(dXPos), sizeof(FLOAT), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->dYPos, sizeof(dYPos), sizeof(FLOAT), numBytesRead);
+ if(guiCurrentSaveGameVersion >= NCTH_DATATYPE_CHANGE){
+ numBytesRead = ReadFieldByField(hFile, &this->sOldXPos, sizeof(sOldXPos), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sOldYPos, sizeof(sOldYPos), sizeof(INT16), numBytesRead);
+ } else {
+ //CHRISL: These used to be floats but we've reduced them to INT16
+ numBytesRead = ReadFieldByField(hFile, &this->sOldXPos, sizeof(sOldXPos), sizeof(INT16), numBytesRead);
+ temp = ReadFieldByField(hFile, &padding, sizeof(INT16), sizeof(INT16), temp);
+ numBytesRead = ReadFieldByField(hFile, &this->sOldYPos, sizeof(sOldYPos), sizeof(INT16), numBytesRead);
+ temp = ReadFieldByField(hFile, &padding, sizeof(INT16), sizeof(INT16), temp);
+ }
+ numBytesRead = ReadFieldByField(hFile, &this->sInitialGridNo, sizeof(sInitialGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sGridNo, sizeof(sGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDirection, sizeof(ubDirection), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sHeightAdjustment, sizeof(sHeightAdjustment), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sDesiredHeight, sizeof(sDesiredHeight), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sTempNewGridNo, sizeof(sTempNewGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sRoomNo, sizeof(sRoomNo), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bOverTerrainType, sizeof(bOverTerrainType), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bOldOverTerrainType, sizeof(bOldOverTerrainType), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bCollapsed, sizeof(bCollapsed), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBreathCollapsed, sizeof(bBreathCollapsed), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDesiredHeight, sizeof(ubDesiredHeight), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usPendingAnimation, sizeof(usPendingAnimation), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubPendingStanceChange, sizeof(ubPendingStanceChange), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usAnimState, sizeof(usAnimState), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiAIDelay, sizeof(uiAIDelay), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sReloadDelay, sizeof(sReloadDelay), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubAttackerID, sizeof(ubAttackerID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubPreviousAttackerID, sizeof(ubPreviousAttackerID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sInsertionGridNo, sizeof(sInsertionGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->AnimCache, sizeof(AnimCache), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bSide, sizeof(bSide), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bViewRange, sizeof(bViewRange), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bNewOppCnt, sizeof(bNewOppCnt), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bService, sizeof(bService), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usAniCode, sizeof(usAniCode), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usAniFrame, sizeof(usAniFrame), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sAniDelay, sizeof(sAniDelay), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDelayedMovementCauseMerc, sizeof(ubDelayedMovementCauseMerc), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sDelayedMovementCauseGridNo, sizeof(sDelayedMovementCauseGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sReservedMovementGridNo, sizeof(sReservedMovementGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sTargetGridNo, sizeof(sTargetGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTargetLevel, sizeof(bTargetLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTargetCubeLevel, sizeof(bTargetCubeLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sLastTarget, sizeof(sLastTarget), sizeof(INT32), numBytesRead);
+ if(guiCurrentSaveGameVersion >= NCTH_DATATYPE_CHANGE){
+ numBytesRead = ReadFieldByField(hFile, &this->dPrevMuzzleOffsetX, sizeof(dPrevMuzzleOffsetX), sizeof(FLOAT), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->dPrevMuzzleOffsetY, sizeof(dPrevMuzzleOffsetY), sizeof(FLOAT), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->dPrevCounterForceX, sizeof(dPrevCounterForceX), sizeof(FLOAT), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->dPrevCounterForceY, sizeof(dPrevCounterForceY), sizeof(FLOAT), numBytesRead);
+ } else {
+ numBytesRead += sizeof(FLOAT);
+ numBytesRead += sizeof(FLOAT);
+ numBytesRead += sizeof(FLOAT);
+ numBytesRead += sizeof(FLOAT);
+ }
+ numBytesRead = ReadFieldByField(hFile, &this->bTilesMoved, sizeof(bTilesMoved), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->dNextBleed, sizeof(dNextBleed), sizeof(FLOAT), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubTilesMovedPerRTBreathUpdate, sizeof(ubTilesMovedPerRTBreathUpdate), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usLastMovementAnimPerRTBreathUpdate, sizeof(usLastMovementAnimPerRTBreathUpdate), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sLocatorFrame, sizeof(sLocatorFrame), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iFaceIndex, sizeof(iFaceIndex), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usFrontArcFullTileList, sizeof(usFrontArcFullTileList), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usFrontArcFullTileGridNos, sizeof(usFrontArcFullTileGridNos), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->HeadPal, sizeof(HeadPal), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->PantsPal, sizeof(PantsPal), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->VestPal, sizeof(VestPal), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->SkinPal, sizeof(SkinPal), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->MiscPal, sizeof(MiscPal), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->p8BPPPalette, sizeof(p8BPPPalette), sizeof(SGPPaletteEntry), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->p16BPPPalette, sizeof(p16BPPPalette), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pShades, sizeof(pShades), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pGlowShades, sizeof(pGlowShades), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pCurrentShade, sizeof(pCurrentShade), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubFadeLevel, sizeof(ubFadeLevel), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubServiceCount, sizeof(ubServiceCount), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubServicePartner, sizeof(ubServicePartner), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pThrowParams, sizeof(pThrowParams), 4, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bReverse, sizeof(bReverse), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pLevelNode, sizeof(pLevelNode), 4, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pExternShadowLevelNode, sizeof(pExternShadowLevelNode), 4, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pRoofUILevelNode, sizeof(pRoofUILevelNode), 4, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pBackGround, sizeof(pBackGround), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pZBackground, sizeof(pZBackground), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usUnblitX, sizeof(usUnblitX), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usUnblitY, sizeof(usUnblitY), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usUnblitWidth, sizeof(usUnblitWidth), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usUnblitHeight, sizeof(usUnblitHeight), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubStrategicInsertionCode, sizeof(ubStrategicInsertionCode), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usStrategicInsertionData, sizeof(usStrategicInsertionData), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iLight, sizeof(iLight), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iMuzFlash, sizeof(iMuzFlash), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bMuzFlashCount, sizeof(bMuzFlashCount), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sX, sizeof(sX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sY, sizeof(sY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usOldAniState, sizeof(usOldAniState), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sOldAniCode, sizeof(sOldAniCode), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBulletsLeft, sizeof(bBulletsLeft), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubSuppressionPoints, sizeof(ubSuppressionPoints), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiTimeOfLastRandomAction, sizeof(uiTimeOfLastRandomAction), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usLastRandomAnim, sizeof(usLastRandomAnim), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usAnimSurface, sizeof(usAnimSurface), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sZLevel, sizeof(sZLevel), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sWalkToAttackGridNo, sizeof(sWalkToAttackGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sWalkToAttackWalkToCost, sizeof(sWalkToAttackWalkToCost), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sLocatorOffX, sizeof(sLocatorOffX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sLocatorOffY, sizeof(sLocatorOffY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pForcedShade, sizeof(pForcedShade), 4, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bDisplayDamageCount, sizeof(bDisplayDamageCount), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sDamage, sizeof(sDamage), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sDamageX, sizeof(sDamageX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sDamageY, sizeof(sDamageY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bDamageDir, sizeof(bDamageDir), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bDoBurst, sizeof(bDoBurst), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usUIMovementMode, sizeof(usUIMovementMode), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bUIInterfaceLevel, sizeof(bUIInterfaceLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubProfile, sizeof(ubProfile), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubQuoteRecord, sizeof(ubQuoteRecord), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubQuoteActionID, sizeof(ubQuoteActionID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubBattleSoundID, sizeof(ubBattleSoundID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubClosePanelFrame, sizeof(ubClosePanelFrame), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDeadPanelFrame, sizeof(ubDeadPanelFrame), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bOpenPanelFrame, sizeof(bOpenPanelFrame), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sPanelFaceX, sizeof(sPanelFaceX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sPanelFaceY, sizeof(sPanelFaceY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bNumHitsThisTurn, sizeof(bNumHitsThisTurn), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usQuoteSaidFlags, sizeof(usQuoteSaidFlags), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bLastSkillCheck, sizeof(bLastSkillCheck), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubSkillCheckAttempts, sizeof(ubSkillCheckAttempts), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bVocalVolume, sizeof(bVocalVolume), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bStartFallDir, sizeof(bStartFallDir), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubPendingDirection, sizeof(ubPendingDirection), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiAnimSubFlags, sizeof(uiAnimSubFlags), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bAimShotLocation, sizeof(bAimShotLocation), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubHitLocation, sizeof(ubHitLocation), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pEffectShades, sizeof(pEffectShades), 4, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubPlannedUIAPCost, sizeof(ubPlannedUIAPCost), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sPlannedTargetX, sizeof(sPlannedTargetX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sPlannedTargetY, sizeof(sPlannedTargetY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sSpreadLocations, sizeof(sSpreadLocations), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sStartGridNo, sizeof(sStartGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sEndGridNo, sizeof(sEndGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sForcastGridno, sizeof(sForcastGridno), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sZLevelOverride, sizeof(sZLevelOverride), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bMovedPriorToInterrupt, sizeof(bMovedPriorToInterrupt), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iEndofContractTime, sizeof(iEndofContractTime), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iStartContractTime, sizeof(iStartContractTime), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iTotalContractLength, sizeof(iTotalContractLength), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iNextActionSpecialData, sizeof(iNextActionSpecialData), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubWhatKindOfMercAmI, sizeof(ubWhatKindOfMercAmI), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bAssignment, sizeof(bAssignment), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bOldAssignment, sizeof(bOldAssignment), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTrainStat, sizeof(bTrainStat), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sSectorX, sizeof(sSectorX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sSectorY, sizeof(sSectorY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bSectorZ, sizeof(bSectorZ), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iVehicleId, sizeof(iVehicleId), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pMercPath, sizeof(pMercPath), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usMedicalDeposit, sizeof(usMedicalDeposit), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usLifeInsurance, sizeof(usLifeInsurance), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiStartMovementTime, sizeof(uiStartMovementTime), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiOptimumMovementTime, sizeof(uiOptimumMovementTime), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usLastUpdateTime, sizeof(usLastUpdateTime), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiSoldierUpdateNumber, sizeof(uiSoldierUpdateNumber), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubSoldierUpdateType, sizeof(ubSoldierUpdateType), sizeof(BYTE), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sScheduledStop, sizeof(sScheduledStop), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iStartOfInsuranceContract, sizeof(iStartOfInsuranceContract), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiLastAssignmentChangeMin, sizeof(uiLastAssignmentChangeMin), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iTotalLengthOfInsuranceContract, sizeof(iTotalLengthOfInsuranceContract), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubSoldierClass, sizeof(ubSoldierClass), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubAPsLostToSuppression, sizeof(ubAPsLostToSuppression), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubSuppressorID, sizeof(ubSuppressorID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDesiredSquadAssignment, sizeof(ubDesiredSquadAssignment), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubNumTraversalsAllowedToMerge, sizeof(ubNumTraversalsAllowedToMerge), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usPendingAnimation2, sizeof(usPendingAnimation2), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubCivilianGroup, sizeof(ubCivilianGroup), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiUniqueSoldierIdValue, sizeof(uiUniqueSoldierIdValue), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bEndDoorOpenCode, sizeof(bEndDoorOpenCode), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubScheduleID, sizeof(ubScheduleID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sEndDoorOpenCodeData, sizeof(sEndDoorOpenCodeData), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBlockedByAnotherMercDirection, sizeof(bBlockedByAnotherMercDirection), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usAttackingWeapon, sizeof(usAttackingWeapon), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bWeaponMode, sizeof(bWeaponMode), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubTargetID, sizeof(ubTargetID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bAIScheduleProgress, sizeof(bAIScheduleProgress), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sOffWorldGridNo, sizeof(sOffWorldGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pAniTile, sizeof(pAniTile), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bCamo, sizeof(bCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sAbsoluteFinalDestination, sizeof(sAbsoluteFinalDestination), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubHiResDirection, sizeof(ubHiResDirection), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubHiResDesiredDirection, sizeof(ubHiResDesiredDirection), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubLastFootPrintSound, sizeof(ubLastFootPrintSound), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bVehicleID, sizeof(bVehicleID), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bMovementDirection, sizeof(bMovementDirection), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sOldGridNo, sizeof(sOldGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usDontUpdateNewGridNoOnMoveAnimChange, sizeof(usDontUpdateNewGridNoOnMoveAnimChange), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sBoundingBoxWidth, sizeof(sBoundingBoxWidth), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sBoundingBoxHeight, sizeof(sBoundingBoxHeight), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sBoundingBoxOffsetX, sizeof(sBoundingBoxOffsetX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sBoundingBoxOffsetY, sizeof(sBoundingBoxOffsetY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiTimeSameBattleSndDone, sizeof(uiTimeSameBattleSndDone), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bOldBattleSnd, sizeof(bOldBattleSnd), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iBurstSoundID, sizeof(iBurstSoundID), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bSlotItemTakenFrom, sizeof(bSlotItemTakenFrom), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubAutoBandagingMedic, sizeof(ubAutoBandagingMedic), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubRobotRemoteHolderID, sizeof(ubRobotRemoteHolderID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiTimeOfLastContractUpdate, sizeof(uiTimeOfLastContractUpdate), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTypeOfLastContract, sizeof(bTypeOfLastContract), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTurnsCollapsed, sizeof(bTurnsCollapsed), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bSleepDrugCounter, sizeof(bSleepDrugCounter), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubMilitiaKills, sizeof(ubMilitiaKills), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bBlindedCounter, sizeof(bBlindedCounter), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubHoursOnAssignment, sizeof(ubHoursOnAssignment), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubMercJustFired, sizeof(ubMercJustFired), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubTurnsUntilCanSayHeardNoise, sizeof(ubTurnsUntilCanSayHeardNoise), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usQuoteSaidExtFlags, sizeof(usQuoteSaidExtFlags), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sContPathLocation, sizeof(sContPathLocation), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bGoodContPath, sizeof(bGoodContPath), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubPendingActionInterrupted, sizeof(ubPendingActionInterrupted), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bNoiseLevel, sizeof(bNoiseLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bRegenerationCounter, sizeof(bRegenerationCounter), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bRegenBoostersUsedToday, sizeof(bRegenBoostersUsedToday), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bNumPelletsHitBy, sizeof(bNumPelletsHitBy), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sSkillCheckGridNo, sizeof(sSkillCheckGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubLastEnemyCycledID, sizeof(ubLastEnemyCycledID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubPrevSectorID, sizeof(ubPrevSectorID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubNumTilesMovesSinceLastForget, sizeof(ubNumTilesMovesSinceLastForget), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTurningIncrement, sizeof(bTurningIncrement), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiBattleSoundID, sizeof(uiBattleSoundID), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->usValueGoneUp, sizeof(usValueGoneUp), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubNumLocateCycles, sizeof(ubNumLocateCycles), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDelayedMovementFlags, sizeof(ubDelayedMovementFlags), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubCTGTTargetID, sizeof(ubCTGTTargetID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiMercChecksum, sizeof(uiMercChecksum), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bCurrentCivQuote, sizeof(bCurrentCivQuote), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bCurrentCivQuoteDelta, sizeof(bCurrentCivQuoteDelta), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubMiscSoldierFlags, sizeof(ubMiscSoldierFlags), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubReasonCantFinishMove, sizeof(ubReasonCantFinishMove), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sLocationOfFadeStart, sizeof(sLocationOfFadeStart), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bUseExitGridForReentryDirection, sizeof(bUseExitGridForReentryDirection), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiTimeSinceLastSpoke, sizeof(uiTimeSinceLastSpoke), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubContractRenewalQuoteCode, sizeof(ubContractRenewalQuoteCode), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sPreTraversalGridNo, sizeof(sPreTraversalGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiXRayActivatedTime, sizeof(uiXRayActivatedTime), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bTurningFromUI, sizeof(bTurningFromUI), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bPendingActionData5, sizeof(bPendingActionData5), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bDelayedStrategicMoraleMod, sizeof(bDelayedStrategicMoraleMod), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubDoorOpeningNoise, sizeof(ubDoorOpeningNoise), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->pGroup, sizeof(pGroup), 1, numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubLeaveHistoryCode, sizeof(ubLeaveHistoryCode), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bOverrideMoveSpeed, sizeof(bOverrideMoveSpeed), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiTimeSoldierWillArrive, sizeof(uiTimeSoldierWillArrive), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bVehicleUnderRepairID, sizeof(bVehicleUnderRepairID), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iTimeCanSignElsewhere, sizeof(iTimeCanSignElsewhere), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bHospitalPriceModifier, sizeof(bHospitalPriceModifier), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiStartTimeOfInsuranceContract, sizeof(uiStartTimeOfInsuranceContract), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bCorpseQuoteTolerance, sizeof(bCorpseQuoteTolerance), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bDeafenedCounter, sizeof(bDeafenedCounter), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iPositionSndID, sizeof(iPositionSndID), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->iTuringSoundID, sizeof(iTuringSoundID), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubLastDamageReason, sizeof(ubLastDamageReason), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sLastTwoLocations, sizeof(sLastTwoLocations), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->uiTimeSinceLastBleedGrunt, sizeof(uiTimeSinceLastBleedGrunt), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->ubNextToPreviousAttackerID, sizeof(ubNextToPreviousAttackerID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->bDoAutofire, sizeof(bDoAutofire), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->numFlanks, sizeof(numFlanks), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->lastFlankSpot, sizeof(lastFlankSpot), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sniper, sizeof(sniper), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->origDir, sizeof(origDir), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->wornCamo, sizeof(wornCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->urbanCamo, sizeof(urbanCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->wornUrbanCamo, sizeof(wornUrbanCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->desertCamo, sizeof(desertCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->wornDesertCamo, sizeof(wornDesertCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->snowCamo, sizeof(snowCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->wornSnowCamo, sizeof(wornSnowCamo), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->sFacilityTypeOperated, sizeof(sFacilityTypeOperated), sizeof(INT16), numBytesRead);
+// if(numBytesRead != SIZEOF_SOLDIERTYPE_POD)
+// return(FALSE);
+/* //CHRISL: It was further changed at version 104 to allow for 16bit action points for the 100AP system
//first, load the POD
if ( guiCurrentSaveGameVersion >= AP100_SAVEGAME_DATATYPE_CHANGE )
{
@@ -1381,7 +1891,7 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
numBytesRead += uiNumBytesRead;
if(numBytesRead != SIZEOF_SOLDIERTYPE_POD)
return(FALSE);
- }
+ }*/
//load the OO inventory
if ( !this->inv.Load(hFile) )
@@ -1491,10 +2001,33 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile)
{
return(FALSE);
}
- if ( !FileRead( hFile, &this->stats, sizeof(STRUCT_Statistics), &uiNumBytesRead ) )
+ //Load STRUCT_AIData
+ numBytesRead = 0;
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bExpLevel, sizeof(stats.bExpLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bLife, sizeof(stats.bLife), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bLifeMax, sizeof(stats.bLifeMax), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bStrength, sizeof(stats.bStrength), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bAgility, sizeof(stats.bAgility), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bDexterity, sizeof(stats.bDexterity), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bWisdom, sizeof(stats.bWisdom), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bLeadership, sizeof(stats.bLeadership), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bMarksmanship, sizeof(stats.bMarksmanship), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bMechanical, sizeof(stats.bMechanical), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bExplosive, sizeof(stats.bExplosive), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bMedical, sizeof(stats.bMedical), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.bScientific, sizeof(stats.bScientific), sizeof(INT8), numBytesRead);
+ if ( guiCurrentSaveGameVersion >= STOMP12_SAVEGAME_DATATYPE_CHANGE2 )
+ numBytesRead = ReadFieldByField(hFile, &this->stats.ubSkillTraits, sizeof(stats.ubSkillTraits), sizeof(UINT8), numBytesRead);
+ else
{
- return(FALSE);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.ubSkillTraits[0], sizeof(UINT8), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.ubSkillTraits[1], sizeof(UINT8), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &this->stats.ubSkillTraits[2], sizeof(UINT8), sizeof(UINT8), numBytesRead);
}
+// if ( !FileRead( hFile, &this->stats, sizeof(STRUCT_Statistics), &uiNumBytesRead ) )
+// {
+// return(FALSE);
+// }
if ( !FileRead( hFile, &this->pathing, sizeof(STRUCT_Pathing), &uiNumBytesRead ) )
{
return(FALSE);
@@ -1584,6 +2117,7 @@ BOOLEAN WORLDITEM::Load(INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMap
}
else
LOADDATA(this, *hBuffer, SIZEOF_WORLDITEM_POD);
+
// Load the OO OBJECTTYPE
this->object.Load(hBuffer, dMajorMapVersion, ubMinorMapVersion);
}
@@ -1637,6 +2171,54 @@ BOOLEAN WORLDITEM::Load(HWFILE hFile)
return TRUE;
}
+BOOLEAN WORLDITEM::Load( HWFILE hFile, float dMajorMapVersion, UINT8 ubMinorMapVersion )
+{
+ UINT32 uiNumBytesRead;
+ //if we are at the most current version, then fine
+ if(dMajorMapVersion >= 6.0 && ubMinorMapVersion > 26)
+ {
+ if(dMajorMapVersion < 7.0)
+ {
+ _OLD_WORLDITEM oldWorldItem;
+
+ //load the POD
+ if ( !FileRead( hFile, this, _OLD_SIZEOF_WORLDITEM_POD, &uiNumBytesRead ) )
+ {
+ return(FALSE);
+ }
+ *this = oldWorldItem;
+ }
+ else
+ {
+ //load the POD
+ if ( !FileRead( hFile, this, SIZEOF_WORLDITEM_POD, &uiNumBytesRead ) )
+ {
+ return(FALSE);
+ }
+ }
+
+ //now load the OO OBJECTTYPE
+ if ( !this->object.Load(hFile) )
+ {
+ return FALSE;
+ }
+ }
+ //if we need to load an older save
+ else
+ {
+ //load the old data into a suitable structure, it's just POD
+ OLD_WORLDITEM_101 oldWorldItem;
+ if ( !FileRead( hFile, &oldWorldItem, sizeof(OLD_WORLDITEM_101), &uiNumBytesRead ) )
+ {
+ return(FALSE);
+ }
+
+ *this = oldWorldItem;
+ }
+
+ return TRUE;
+}
+
BOOLEAN StackedObjectData::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion )
{
//when this function is called, the file has been loaded into a buffer using FileRead
@@ -1696,7 +2278,8 @@ BOOLEAN StackedObjectData::Save( HWFILE hFile, bool fSavingMap )
UINT32 uiNumBytesWritten;
int size = 0;
for (attachmentList::iterator iter = attachments.begin(); iter != attachments.end(); ++iter) {
- if (iter->exists() == true) {
+ //WarmSteel - In fact, attachments CAN be null now with NAS.
+ if (iter->exists() == true || UsingNewAttachmentSystem()==true) {
++size;
}
else {
@@ -1714,7 +2297,8 @@ BOOLEAN StackedObjectData::Save( HWFILE hFile, bool fSavingMap )
return(FALSE);
}
for (attachmentList::iterator iter = attachments.begin(); iter != attachments.end(); ++iter) {
- if (iter->exists() == true) {
+ //WarmSteel - Can be null with NAS, sadly.
+ if (iter->exists() == true || UsingNewAttachmentSystem()==true) {
if (! iter->Save(hFile, fSavingMap)) {
return FALSE;
}
@@ -1785,6 +2369,7 @@ BOOLEAN OBJECTTYPE::Load( HWFILE hFile )
}
*/
}
+ RemoveProhibitedAttachments(NULL, this, (*this).usItem);
return TRUE;
}
@@ -1815,6 +2400,7 @@ BOOLEAN OBJECTTYPE::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorM
LOADDATA( &OldSavedObject101, *hBuffer, sizeof(OLD_OBJECTTYPE_101) );
(*this) = OldSavedObject101;
}
+ RemoveProhibitedAttachments(NULL, this, (*this).usItem);
return TRUE;
}
@@ -1983,11 +2569,11 @@ BOOLEAN InitSaveDir()
#else
if(is_networked)
{
- sprintf( gSaveDir, "%s", utf8string::as_utf8(pMessageStrings[ MSG_MPSAVEDIRECTORY ] + 3).c_str() );
+ sprintf( gSaveDir, "%s", vfs::String::as_utf8(pMessageStrings[ MSG_MPSAVEDIRECTORY ] + 3).c_str() );
}
else
{
- sprintf( gSaveDir, "%s", utf8string::as_utf8(pMessageStrings[ MSG_SAVEDIRECTORY ] + 3).c_str() );
+ sprintf( gSaveDir, "%s", vfs::String::as_utf8(pMessageStrings[ MSG_SAVEDIRECTORY ] + 3).c_str() );
}
#endif
return TRUE;
@@ -2020,7 +2606,7 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
#endif
#endif
- if( ubSaveGameID >= NUM_SAVE_GAMES && ubSaveGameID < EARLIST_SPECIAL_SAVE )
+ if( ubSaveGameID > NUM_SLOT && ubSaveGameID < EARLIST_SPECIAL_SAVE )
return( FALSE ); //ddd
alreadySaving = true;
@@ -2112,8 +2698,8 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
if(is_networked)
{
SaveGameHeader.uiDay = CLIENT_NUM;
- SaveGameHeader.ubHour = MAX_CLIENTS;
- SaveGameHeader.ubMin = MAX_MERCS;
+ SaveGameHeader.ubHour = cMaxClients;
+ SaveGameHeader.ubMin = cMaxMercs;
}
//copy over the initial game options
@@ -2144,6 +2730,8 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
// CHRISL: We need to know what inventory system we're using early on
SaveGameHeader.ubInventorySystem = gGameOptions.ubInventorySystem;
+ SaveGameHeader.ubAttachmentSystem = gGameOptions.ubAttachmentSystem;
+
//
// Save the Save Game header file
//
@@ -2864,8 +3452,36 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing mail orders");
goto FAILED_TO_SAVE;
}
+
+ //New profiles by Jazz
+ if( !SaveNewMercsToSaveGameFile( hFile ) )
+ {
+ ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing mercs profiles");
+ goto FAILED_TO_SAVE;
+ }
+ #ifdef JA2BETAVERSION
+ SaveGameFilePosition( FileGetPos( hFile ), "New Mercs Profiles" );
+ #endif
+
+ //New system profiles by Jazz
+ if( !SaveNewSystemMercsToSaveGameFile( hFile ) )
+ {
+ ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing new system mercs profiles");
+ goto FAILED_TO_SAVE;
+ }
+ #ifdef JA2BETAVERSION
+ SaveGameFilePosition( FileGetPos( hFile ), "New system Mercs Profiles" );
+ #endif
-
+ //save lua global
+ if( !SaveLuaGlobalToSaveGameFile( hFile ) )
+ {
+ ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing lua global");
+ goto FAILED_TO_SAVE;
+ }
+ #ifdef JA2BETAVERSION
+ SaveGameFilePosition( FileGetPos( hFile ), "Lua global" );
+ #endif
//Close the saved game file
FileClose( hFile );
@@ -2901,7 +3517,7 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc )
}
//restore the music mode
- SetMusicMode( gubMusicMode );
+ SetMusicMode( GetMusicMode() );
//Unset the fact that we are saving a game
gTacticalStatus.uiFlags &= ~LOADING_SAVED_GAME;
@@ -3013,7 +3629,7 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
#endif
//is it a valid save number
- if( ubSavedGameID >= NUM_SAVE_GAMES )
+ if( ubSavedGameID >= NUM_SLOT )
{
if( ubSavedGameID != SAVE__END_TURN_NUM )
return( FALSE );
@@ -3094,9 +3710,10 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
if(SaveGameHeader.uiSavedGameVersion < NIV_SAVEGAME_DATATYPE_CHANGE)
SaveGameHeader.ubInventorySystem = 0;
gGameOptions.ubInventorySystem = SaveGameHeader.ubInventorySystem;
+
if((UsingNewInventorySystem() == true))
{
- if(IsNIVModeValid() == FALSE){
+ if(IsNIVModeValid(true) == FALSE){
// Only load NewInv in higher screen res
FileClose( hFile );
return(FALSE);
@@ -3108,11 +3725,16 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
}
else
{
+ if(UsingNewAttachmentSystem()==true)
+ return(FALSE);
+
InitInventoryOld();
InitOldInventorySystem();
InitializeSMPanelCoordsOld();
InitializeInvPanelCoordsOld();
}
+
+ gGameOptions.ubAttachmentSystem = SaveGameHeader.ubAttachmentSystem;
//if the player is loading up an older version of the game, and the person DOESNT have the cheats on,
if( guiCurrentSaveGameVersion < 65 && !CHEATER_CHEAT_LEVEL( ) )
@@ -4200,14 +4822,68 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
}
}
+ uiRelEndPerc += 1;
+ SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Load New Mercs Prfiles..." );
+ RenderProgressBar( 0, 100 );
+ uiRelStartPerc = uiRelEndPerc;
+
+
+ if( guiCurrentSaveGameVersion >= 113 )
+ {
+ if( !LoadNewMercsFromLoadGameFile( hFile ) )
+ {
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadNewMercsFromLoadGameFile failed" ) );
+ FileClose( hFile );
+ return( FALSE );
+ }
+ }
+ #ifdef JA2BETAVERSION
+ LoadGameFilePosition( FileGetPos( hFile ), "Load Mercs Prfiles" );
+ #endif
+
+ uiRelEndPerc += 1;
+ SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Load New Sytem Mercs Prfiles..." );
+ RenderProgressBar( 0, 100 );
+ uiRelStartPerc = uiRelEndPerc;
+
+ if( guiCurrentSaveGameVersion >= 113 )
+ {
+ if( !LoadNewSystemMercsToSaveGameFile( hFile ) )
+ {
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadNewSystemMercsToSaveGameFile failed" ) );
+ FileClose( hFile );
+ return( FALSE );
+ }
+ }
+ #ifdef JA2BETAVERSION
+ LoadGameFilePosition( FileGetPos( hFile ), "Load New Sytem Mercs Prfiles" );
+ #endif
uiRelEndPerc += 1;
SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Final Checks..." );
RenderProgressBar( 0, 100 );
uiRelStartPerc = uiRelEndPerc;
+ uiRelEndPerc += 1;
+ SetRelativeStartAndEndPercentage( 0, uiRelStartPerc, uiRelEndPerc, L"Lua Global System..." );
+ RenderProgressBar( 0, 100 );
+ uiRelStartPerc = uiRelEndPerc;
+ if( guiCurrentSaveGameVersion >= 114 )
+ {
+ if( !LoadLuaGlobalFromLoadGameFile( hFile ) )
+ {
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadLuaGlobalFromLoadGameFile failed" ) );
+ FileClose( hFile );
+ return FALSE;
+ }
+ }
+ #ifdef JA2BETAVERSION
+ LoadGameFilePosition( FileGetPos( hFile ), "Lua Global System" );
+ #endif
+
+
//
//Close the saved game file
//
@@ -4499,7 +5175,6 @@ BOOLEAN LoadSavedGame( int ubSavedGameID )
//now change the savegame format so that temp files are saved and loaded correctly
guiCurrentSaveGameVersion = SAVE_GAME_VERSION;
-
return( TRUE );
}
@@ -4757,10 +5432,10 @@ BOOLEAN LoadSoldierStructure( HWFILE hFile )
}
//if the soldier is an IMP character
- if( Menptr[cnt].ubWhatKindOfMercAmI == MERC_TYPE__PLAYER_CHARACTER && Menptr[cnt].bTeam == gbPlayerNum )
- {
- ResetIMPCharactersEyesAndMouthOffsets( Menptr[ cnt ].ubProfile );
- }
+ //if( Menptr[cnt].ubWhatKindOfMercAmI == MERC_TYPE__PLAYER_CHARACTER && Menptr[cnt].bTeam == gbPlayerNum )
+ //{
+ // ResetIMPCharactersEyesAndMouthOffsets( Menptr[ cnt ].ubProfile );
+ //}
//if the saved game version is before x, calculate the amount of money paid to mercs
if( guiCurrentSaveGameVersion < 83 )
@@ -6003,7 +6678,7 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile )
GENERAL_SAVE_INFO sGeneralInfo;
memset( &sGeneralInfo, 0, sizeof( GENERAL_SAVE_INFO ) );
- sGeneralInfo.ubMusicMode = gubMusicMode;
+ sGeneralInfo.ubMusicMode = GetMusicMode();
sGeneralInfo.uiCurrentUniqueSoldierId = guiCurrentUniqueSoldierId;
sGeneralInfo.uiCurrentScreen = guiPreviousOptionScreen;
@@ -6018,6 +6693,7 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile )
sGeneralInfo.fShowMineFlag = fShowMineFlag;
sGeneralInfo.fShowAircraftFlag = fShowAircraftFlag;
sGeneralInfo.fShowTeamFlag = fShowTeamFlag;
+ sGeneralInfo.fShowMobileRestrictionsFlag = fShowMobileRestrictionsFlag; // HEADROCK HAM 4
sGeneralInfo.fHelicopterAvailable = fHelicopterAvailable;
@@ -6216,6 +6892,15 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile )
// HEADROCK HAM 3.6: Save new global variable for militia upkeep
sGeneralInfo.uiTotalUpkeepForMilitia = guiTotalUpkeepForMilitia;
+ // HEADROCK HAM 4: Save global array for Manual Mobile Militia Restrictions
+ // testing for loop
+ memcpy(sGeneralInfo.ubManualRestrictMilitia, gubManualRestrictMilitia, sizeof( UINT8 )*256);
+
+ for (int i=0;i<500;i++)
+ {
+ sGeneralInfo.HiddenNames[i] = !zHiddenNames[i].Hidden; //legion2
+ }
+
//Setup the
//Save the current music mode
FileWrite( hFile, &sGeneralInfo, sizeof( GENERAL_SAVE_INFO ), &uiNumBytesWritten );
@@ -6234,15 +6919,145 @@ extern UINT32 guiRainLoop;
BOOLEAN LoadGeneralInfo( HWFILE hFile )
{
- UINT32 uiNumBytesRead;
+ //UINT32 uiNumBytesRead;
+ INT32 numBytesRead = 0;
+ UINT8 filler = 0;
GENERAL_SAVE_INFO sGeneralInfo;
memset( &sGeneralInfo, 0, sizeof( GENERAL_SAVE_INFO ) );
-
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiCurrentScreen, sizeof(sGeneralInfo.uiCurrentScreen), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiCurrentUniqueSoldierId, sizeof(sGeneralInfo.uiCurrentUniqueSoldierId), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubMusicMode, sizeof(sGeneralInfo.ubMusicMode), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHavePurchasedItemsFromTony, sizeof(sGeneralInfo.fHavePurchasedItemsFromTony), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.usSelectedSoldier, sizeof(sGeneralInfo.usSelectedSoldier), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sRenderCenterX, sizeof(sGeneralInfo.sRenderCenterX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sRenderCenterY, sizeof(sGeneralInfo.sRenderCenterY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fAtLeastOneMercWasHired, sizeof(sGeneralInfo.fAtLeastOneMercWasHired), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowItemsFlag, sizeof(sGeneralInfo.fShowItemsFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowTownFlag, sizeof(sGeneralInfo.fShowTownFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowTeamFlag, sizeof(sGeneralInfo.fShowTeamFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowMineFlag, sizeof(sGeneralInfo.fShowMineFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowAircraftFlag, sizeof(sGeneralInfo.fShowAircraftFlag), sizeof(BOOLEAN), numBytesRead);
+ if ( guiCurrentSaveGameVersion >= NEW_GENERAL_SAVE_INFO_DATA )
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowMobileRestrictionsFlag, sizeof(sGeneralInfo.fShowMobileRestrictionsFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHelicopterAvailable, sizeof(sGeneralInfo.fHelicopterAvailable), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iHelicopterVehicleId, sizeof(sGeneralInfo.iHelicopterVehicleId), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.UNUSEDiTotalHeliDistanceSinceRefuel, sizeof(sGeneralInfo.UNUSEDiTotalHeliDistanceSinceRefuel), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iTotalAccumulatedCostByPlayer, sizeof(sGeneralInfo.iTotalAccumulatedCostByPlayer), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fSkyRiderAvailable, sizeof(sGeneralInfo.fSkyRiderAvailable), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.UNUSEDfSkyriderMonologue, sizeof(sGeneralInfo.UNUSEDfSkyriderMonologue), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.UNUSED, sizeof(sGeneralInfo.UNUSED), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHelicopterIsAirBorne, sizeof(sGeneralInfo.fHelicopterIsAirBorne), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHeliReturnStraightToBase, sizeof(sGeneralInfo.fHeliReturnStraightToBase), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHoveringHelicopter, sizeof(sGeneralInfo.fHoveringHelicopter), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiStartHoverTime, sizeof(sGeneralInfo.uiStartHoverTime), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiHelicopterSkyriderTalkState, sizeof(sGeneralInfo.uiHelicopterSkyriderTalkState), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowEstoniRefuelHighLight, sizeof(sGeneralInfo.fShowEstoniRefuelHighLight), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowOtherSAMHighLight, sizeof(sGeneralInfo.fShowOtherSAMHighLight), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowDrassenSAMHighLight, sizeof(sGeneralInfo.fShowDrassenSAMHighLight), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiEnvWeather, sizeof(sGeneralInfo.uiEnvWeather), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubDefaultButton, sizeof(sGeneralInfo.ubDefaultButton), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fSkyriderEmptyHelpGiven, sizeof(sGeneralInfo.fSkyriderEmptyHelpGiven), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fEnterMapDueToContract, sizeof(sGeneralInfo.fEnterMapDueToContract), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubHelicopterHitsTaken, sizeof(sGeneralInfo.ubHelicopterHitsTaken), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubQuitType, sizeof(sGeneralInfo.ubQuitType), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fSkyriderSaidCongratsOnTakingSAM, sizeof(sGeneralInfo.fSkyriderSaidCongratsOnTakingSAM), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sContractRehireSoldierID, sizeof(sGeneralInfo.sContractRehireSoldierID), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.GameOptions, sizeof(sGeneralInfo.GameOptions), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiSeedNumber, sizeof(sGeneralInfo.uiSeedNumber), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiBaseJA2Clock, sizeof(sGeneralInfo.uiBaseJA2Clock), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sCurInterfacePanel, sizeof(sGeneralInfo.sCurInterfacePanel), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubSMCurrentMercID, sizeof(sGeneralInfo.ubSMCurrentMercID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fFirstTimeInMapScreen, sizeof(sGeneralInfo.fFirstTimeInMapScreen), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fDisableDueToBattleRoster, sizeof(sGeneralInfo.fDisableDueToBattleRoster), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fDisableMapInterfaceDueToBattle, sizeof(sGeneralInfo.fDisableMapInterfaceDueToBattle), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sBoxerGridNo, sizeof(sGeneralInfo.sBoxerGridNo), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubBoxerID, sizeof(sGeneralInfo.ubBoxerID), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fBoxerFought, sizeof(sGeneralInfo.fBoxerFought), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHelicopterDestroyed, sizeof(sGeneralInfo.fHelicopterDestroyed), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowMapScreenHelpText, sizeof(sGeneralInfo.fShowMapScreenHelpText), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iSortStateForMapScreenList, sizeof(sGeneralInfo.iSortStateForMapScreenList), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fFoundTixa, sizeof(sGeneralInfo.fFoundTixa), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiTimeOfLastSkyriderMonologue, sizeof(sGeneralInfo.uiTimeOfLastSkyriderMonologue), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowCambriaHospitalHighLight, sizeof(sGeneralInfo.fShowCambriaHospitalHighLight), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fSkyRiderSetUp, sizeof(sGeneralInfo.fSkyRiderSetUp), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fRefuelingSiteAvailable, sizeof(sGeneralInfo.fRefuelingSiteAvailable), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.gCurrentMeanwhileDef, sizeof(sGeneralInfo.gCurrentMeanwhileDef), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubPlayerProgressSkyriderLastCommentedOn, sizeof(sGeneralInfo.ubPlayerProgressSkyriderLastCommentedOn), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.gfMeanwhileTryingToStart, sizeof(sGeneralInfo.gfMeanwhileTryingToStart), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.gfInMeanwhile, sizeof(sGeneralInfo.gfInMeanwhile), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sDeadMercs, sizeof(sGeneralInfo.sDeadMercs), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.gbPublicNoiseLevel, sizeof(sGeneralInfo.gbPublicNoiseLevel), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.gubScreenCount, sizeof(sGeneralInfo.gubScreenCount), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.usOldMeanWhileFlags, sizeof(sGeneralInfo.usOldMeanWhileFlags), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iPortraitNumber, sizeof(sGeneralInfo.iPortraitNumber), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sWorldSectorLocationOfFirstBattle, sizeof(sGeneralInfo.sWorldSectorLocationOfFirstBattle), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fUnReadMailFlag, sizeof(sGeneralInfo.fUnReadMailFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fNewMailFlag, sizeof(sGeneralInfo.fNewMailFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fOldUnReadFlag, sizeof(sGeneralInfo.fOldUnReadFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fOldNewMailFlag, sizeof(sGeneralInfo.fOldNewMailFlag), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fShowMilitia, sizeof(sGeneralInfo.fShowMilitia), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fNewFilesInFileViewer, sizeof(sGeneralInfo.fNewFilesInFileViewer), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fLastBoxingMatchWonByPlayer, sizeof(sGeneralInfo.fLastBoxingMatchWonByPlayer), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiUNUSED, sizeof(sGeneralInfo.uiUNUSED), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fSamSiteFound, sizeof(sGeneralInfo.fSamSiteFound), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubNumTerrorists, sizeof(sGeneralInfo.ubNumTerrorists), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubCambriaMedicalObjects, sizeof(sGeneralInfo.ubCambriaMedicalObjects), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fDisableTacticalPanelButtons, sizeof(sGeneralInfo.fDisableTacticalPanelButtons), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sSelMapX, sizeof(sGeneralInfo.sSelMapX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sSelMapY, sizeof(sGeneralInfo.sSelMapY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iCurrentMapSectorZ, sizeof(sGeneralInfo.iCurrentMapSectorZ), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.usHasPlayerSeenHelpScreenInCurrentScreen, sizeof(sGeneralInfo.usHasPlayerSeenHelpScreenInCurrentScreen), sizeof(UINT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fHideHelpInAllScreens, sizeof(sGeneralInfo.fHideHelpInAllScreens), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubBoxingMatchesWon, sizeof(sGeneralInfo.ubBoxingMatchesWon), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubBoxersRests, sizeof(sGeneralInfo.ubBoxersRests), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fBoxersResting, sizeof(sGeneralInfo.fBoxersResting), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubDesertTemperature, sizeof(sGeneralInfo.ubDesertTemperature), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubGlobalTemperature, sizeof(sGeneralInfo.ubGlobalTemperature), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sMercArriveSectorX, sizeof(sGeneralInfo.sMercArriveSectorX), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sMercArriveSectorY, sizeof(sGeneralInfo.sMercArriveSectorY), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fCreatureMeanwhileScenePlayed, sizeof(sGeneralInfo.fCreatureMeanwhileScenePlayed), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubPlayerNum, sizeof(sGeneralInfo.ubPlayerNum), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fPersistantPBI, sizeof(sGeneralInfo.fPersistantPBI), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubEnemyEncounterCode, sizeof(sGeneralInfo.ubEnemyEncounterCode), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubExplicitEnemyEncounterCode, sizeof(sGeneralInfo.ubExplicitEnemyEncounterCode), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fBlitBattleSectorLocator, sizeof(sGeneralInfo.fBlitBattleSectorLocator), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubPBSectorX, sizeof(sGeneralInfo.ubPBSectorX), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubPBSectorY, sizeof(sGeneralInfo.ubPBSectorY), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubPBSectorZ, sizeof(sGeneralInfo.ubPBSectorZ), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fCantRetreatInPBI, sizeof(sGeneralInfo.fCantRetreatInPBI), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fExplosionQueueActive, sizeof(sGeneralInfo.fExplosionQueueActive), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubUnused, sizeof(sGeneralInfo.ubUnused), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiMeanWhileFlags, sizeof(sGeneralInfo.uiMeanWhileFlags), sizeof(UINT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.bSelectedInfoChar, sizeof(sGeneralInfo.bSelectedInfoChar), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.bHospitalPriceModifier, sizeof(sGeneralInfo.bHospitalPriceModifier), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.bUnused2, sizeof(sGeneralInfo.bUnused2), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iHospitalTempBalance, sizeof(sGeneralInfo.iHospitalTempBalance), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iHospitalRefund, sizeof(sGeneralInfo.iHospitalRefund), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fPlayerTeamSawJoey, sizeof(sGeneralInfo.fPlayerTeamSawJoey), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fMikeShouldSayHi, sizeof(sGeneralInfo.fMikeShouldSayHi), sizeof(INT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.iTotalOwedForFacilityOperationsToday, sizeof(sGeneralInfo.iTotalOwedForFacilityOperationsToday), sizeof(INT32), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.sSkyriderCostModifier, sizeof(sGeneralInfo.sSkyriderCostModifier), sizeof(INT16), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.fOutstandingFacilityDebt, sizeof(sGeneralInfo.fOutstandingFacilityDebt), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.uiTotalUpkeepForMilitia, sizeof(sGeneralInfo.uiTotalUpkeepForMilitia), sizeof(UINT32), numBytesRead);
+ if ( guiCurrentSaveGameVersion >= NEW_GENERAL_SAVE_INFO_DATA ){
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubManualRestrictMilitia, sizeof(sGeneralInfo.ubManualRestrictMilitia), sizeof(UINT8), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.HiddenNames, sizeof(sGeneralInfo.HiddenNames), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubFiller, sizeof(sGeneralInfo.ubFiller), sizeof(UINT8), numBytesRead);
+ } else {
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.HiddenNames, sizeof(sGeneralInfo.HiddenNames), sizeof(BOOLEAN), numBytesRead);
+ numBytesRead = ReadFieldByField(hFile, &sGeneralInfo.ubFiller, sizeof(sGeneralInfo.ubFiller), sizeof(UINT8), numBytesRead);
+ for(UINT32 count = 0; count < sizeof(sGeneralInfo.ubManualRestrictMilitia); count++)
+ numBytesRead = ReadFieldByField(hFile, &filler, sizeof(filler), sizeof(UINT8), numBytesRead);
+ }
+ //CHRISL: GENERAL_SAVE_INFO is only 1586 but we have to read in DWORD lengths so we need to read additional filler bits from the save game file
+ for(UINT32 count = numBytesRead; count < sizeof( GENERAL_SAVE_INFO ); count++)
+ numBytesRead = ReadFieldByField(hFile, &filler, sizeof(filler), sizeof(UINT8), numBytesRead);
//Load the current music mode
- FileRead( hFile, &sGeneralInfo, sizeof( GENERAL_SAVE_INFO ), &uiNumBytesRead );
- if( uiNumBytesRead != sizeof( GENERAL_SAVE_INFO ) )
+ //FileRead( hFile, &sGeneralInfo, sizeof( GENERAL_SAVE_INFO ), &uiNumBytesRead );
+ //if( uiNumBytesRead != sizeof( GENERAL_SAVE_INFO ) )
+ if( numBytesRead != sizeof( GENERAL_SAVE_INFO ) )
{
FileClose( hFile );
return( FALSE );
@@ -6271,6 +7086,7 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile )
fShowMineFlag = sGeneralInfo.fShowMineFlag;
fShowAircraftFlag = sGeneralInfo.fShowAircraftFlag;
fShowTeamFlag = sGeneralInfo.fShowTeamFlag;
+ fShowMobileRestrictionsFlag = sGeneralInfo.fShowMobileRestrictionsFlag;
fHelicopterAvailable = sGeneralInfo.fHelicopterAvailable;
@@ -6500,6 +7316,94 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile )
// HEADROCK HAM 3.6: Load new global variable for militia upkeep
guiTotalUpkeepForMilitia = sGeneralInfo.uiTotalUpkeepForMilitia;
+ // HEADROCK HAM 4: Load Manual Mobile Militia Restrictions
+ memcpy(gubManualRestrictMilitia, sGeneralInfo.ubManualRestrictMilitia, sizeof(UINT8) * 256);
+
+ for (int i=0;i<500;i++)
+ {
+ zHiddenNames[i].Hidden = !sGeneralInfo.HiddenNames[i];
+ }
+
+ if ( gGameExternalOptions.fShowCamouflageFaces == TRUE )
+ {
+
+ //Camo Face by Jazz
+ for (int i=0;i<255;i++)
+ {
+ gCamoFace[i].gCamoface = FALSE;
+ gCamoFace[i].gUrbanCamoface = FALSE;
+ gCamoFace[i].gDesertCamoface = FALSE;
+ gCamoFace[i].gSnowCamoface = FALSE;
+ }
+
+ SOLDIERTYPE * pSoldier;
+ INT8 bMercID, bLastTeamID;
+ bMercID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
+ bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;
+ for ( pSoldier = MercPtrs[ bMercID ]; bMercID <= bLastTeamID; bMercID++,pSoldier++)
+ {
+ if ( pSoldier->bCamo > 0 )
+ {
+ gCamoFace[pSoldier->ubProfile].gCamoface = TRUE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ else
+ {
+ gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ if ( pSoldier->urbanCamo > 0 )
+ {
+ gCamoFace[pSoldier->ubProfile].gUrbanCamoface = TRUE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ else
+ {
+ gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+
+ if ( pSoldier->desertCamo > 0 )
+ {
+ gCamoFace[pSoldier->ubProfile].gDesertCamoface = TRUE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ else
+ {
+ gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ if ( pSoldier->snowCamo > 0 )
+ {
+ gCamoFace[pSoldier->ubProfile].gSnowCamoface = TRUE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ else
+ {
+ gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+
+ if ( pSoldier->snowCamo == 0 && pSoldier->bCamo == 0 && pSoldier->urbanCamo == 0 && pSoldier->desertCamo == 0)
+ {
+ gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
+ gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
+ gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
+ gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
+ DeleteSoldierFace( pSoldier );
+ pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
+ }
+ }
+ }
+
return( TRUE );
}
diff --git a/SaveLoadGame.h b/SaveLoadGame.h
index 26c4b4cb..f1966f0f 100644
--- a/SaveLoadGame.h
+++ b/SaveLoadGame.h
@@ -21,7 +21,7 @@ class SOLDIERTYPE;
// WDS - Automatically try to save when an assertion failure occurs
#define SAVE__ASSERTION_FAILURE 97
-#define SAVE__TIMED_AUTOSAVE 11
+#define SAVE__TIMED_AUTOSAVE 19 // WANNE: This slot does not show up in the load/save screen because it is > 18
#define EARLIST_SPECIAL_SAVE 97
@@ -64,9 +64,9 @@ typedef struct
UINT8 ubInventorySystem;
- UINT8 ubFiller[109];
-
+ UINT8 ubAttachmentSystem;
+ UINT8 ubFiller[108]; // WANNE: Changed from 109 to 108 because of ubNewAttachmentSystem integration
} SAVED_GAME_HEADER;
diff --git a/SaveLoadScreen.cpp b/SaveLoadScreen.cpp
index 82ed886f..baf66743 100644
--- a/SaveLoadScreen.cpp
+++ b/SaveLoadScreen.cpp
@@ -45,6 +45,8 @@
BOOLEAN gfSchedulesHosed = FALSE;
extern UINT32 guiBrokenSaveGameVersion;
+UINT16 NUM_SLOT;
+
//////////////////////////////////////////////////////
//
// Defines
@@ -89,15 +91,13 @@ extern UINT32 guiBrokenSaveGameVersion;
#define SLG_UNSELECTED_COLOR FONT_MCOLOR_DKWHITE
#define SLG_SAVELOCATION_WIDTH 605
-#define SLG_SAVELOCATION_HEIGHT 30//46
+//#define SLG_SAVELOCATION_HEIGHT 30//46 //legion off
#define SLG_FIRST_SAVED_SPOT_X iScreenWidthOffset + 17
#define SLG_FIRST_SAVED_SPOT_Y iScreenHeightOffset + 49
-#define SLG_GAP_BETWEEN_LOCATIONS 35//47
-
-
+//#define SLG_GAP_BETWEEN_LOCATIONS 35//47 //legion off
#define SLG_DATE_OFFSET_X 13
-#define SLG_DATE_OFFSET_Y 11
+//#define SLG_DATE_OFFSET_Y 11 //legion off
#define SLG_SECTOR_OFFSET_X 95//105//114
#define SLG_SECTOR_OFFSET_Y SLG_DATE_OFFSET_Y
@@ -122,8 +122,8 @@ extern UINT32 guiBrokenSaveGameVersion;
#define SLG_SAVE_LOAD_BTN_POS_X iScreenWidthOffset + 123
#define SLG_SAVE_LOAD_BTN_POS_Y iScreenHeightOffset + 438
-#define SLG_SELECTED_SLOT_GRAPHICS_NUMBER 3
-#define SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER 2
+//#define SLG_SELECTED_SLOT_GRAPHICS_NUMBER 3 //legion off
+//#define SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER 2 //legion off
#define SLG_DOUBLE_CLICK_DELAY 500
@@ -176,6 +176,12 @@ INT8 gbSetSlotToBeSelected=-1;
UINT32 guiSlgBackGroundImage;
UINT32 guiBackGroundAddOns;
+UINT32 guiBackGroundAddOns_New;
+UINT32 SLG_SAVELOCATION_HEIGHT;
+UINT32 SLG_GAP_BETWEEN_LOCATIONS;
+UINT32 SLG_DATE_OFFSET_Y;
+UINT32 SLG_SELECTED_SLOT_GRAPHICS_NUMBER;
+UINT32 SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER;
// The string that will contain the game desc text
CHAR16 gzGameDescTextField[ SIZE_OF_SAVE_GAME_DESC ] = {0} ;
@@ -194,7 +200,7 @@ BOOLEAN gfLoadedGame = FALSE; //Used to know when a game has been loaded, the f
BOOLEAN gfLoadGameUponEntry = FALSE;
-BOOLEAN gfHadToMakeBasementLevels = FALSE;
+//BOOLEAN gfHadToMakeBasementLevels = FALSE;
BOOLEAN gfGettingNameFromSaveLoadScreen = FALSE;
@@ -280,6 +286,37 @@ void StartFadeOutForSaveLoadScreen();
//
//////////////////////////////////////////////////////
+void LoadSaveGameOldOrNew()
+{
+ if (gGameExternalOptions.fSaveGameSlot == TRUE)
+ {
+ NUM_SLOT = NUM_SAVE_GAMES_NEW;
+ //SAVE_LOAD_SELECTED_FONT = FONT12ARIAL;
+ //SAVE_LOAD_NUMBER_FONT = FONT12ARIAL;
+ //SAVE_LOAD_HIGHLIGHTED_FONT = FONT12ARIAL;
+ //SAVE_LOAD_NORMAL_FONT = FONT12ARIAL;
+ SLG_SAVELOCATION_HEIGHT = 15;
+ SLG_GAP_BETWEEN_LOCATIONS = 20;
+ SLG_DATE_OFFSET_Y = 5;
+ SLG_SELECTED_SLOT_GRAPHICS_NUMBER = 1;
+ SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER = 0;
+ }
+ else
+ {
+ NUM_SLOT = NUM_SAVE_GAMES_OLD;
+ //SAVE_LOAD_SELECTED_FONT = FONT12ARIAL;
+ //SAVE_LOAD_NUMBER_FONT = FONT12ARIAL;
+ //SAVE_LOAD_HIGHLIGHTED_FONT = FONT12ARIAL;
+ //SAVE_LOAD_NORMAL_FONT = FONT12ARIAL;
+ SLG_SAVELOCATION_HEIGHT = 30;
+ SLG_GAP_BETWEEN_LOCATIONS = 35;
+ SLG_DATE_OFFSET_Y = 11;
+ SLG_SELECTED_SLOT_GRAPHICS_NUMBER = 3;
+ SLG_UNSELECTED_SLOT_GRAPHICS_NUMBER = 2;
+ }
+
+}
+
UINT32 SaveLoadScreenInit()
{
@@ -466,18 +503,23 @@ BOOLEAN EnterSaveLoadScreen()
// if( guiPreviousOptionScreen != MAINMENU_SCREEN )
// gbSetSlotToBeSelected = -1;
- // This is a hack to get sector names , but... if the underground sector is NOT loaded
- if( !gpUndergroundSectorInfoHead )
- {
- BuildUndergroundSectorInfoList();
- gfHadToMakeBasementLevels = TRUE;
- }
- else
- {
- gfHadToMakeBasementLevels = FALSE;
- }
+ // In reality, this is not needed, but even screws things up
+ //// This is a hack to get sector names , but... if the underground sector is NOT loaded
+ //if( !gpUndergroundSectorInfoHead )
+ //{
+ // BuildUndergroundSectorInfoList();
+ // gfHadToMakeBasementLevels = TRUE;
+ //}
+ //else
+ //{
+ // gfHadToMakeBasementLevels = FALSE;
+ //}
+
+ //guiSaveLoadExitScreen = SAVE_LOAD_SCREEN;
+ // this is where we came from; if loading of resources fails, this is also where we go next/back
+ extern UINT32 guiPreviousScreen;
+ guiSaveLoadExitScreen = guiPreviousScreen;
- guiSaveLoadExitScreen = SAVE_LOAD_SCREEN;
//init the list
InitSaveGameArray();
@@ -510,6 +552,14 @@ BOOLEAN EnterSaveLoadScreen()
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
GetMLGFilename( VObjectDesc.ImageFile, MLG_LOADSAVEHEADER );
CHECKF(AddVideoObject(&VObjectDesc, &guiBackGroundAddOns));
+
+ if (gGameExternalOptions.fSaveGameSlot == TRUE)
+ {
+ VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
+ FilenameForBPP("INTERFACE\\LOADSCREENADDONS_SAVEGAME.sti", VObjectDesc.ImageFile);
+ CHECKF(AddVideoObject(&VObjectDesc, &guiBackGroundAddOns_New));
+ }
+
guiSlgButtonImage = LoadButtonImage("INTERFACE\\LoadScreenAddOns.sti", -1,6,-1,9,-1 );
@@ -580,7 +630,7 @@ BOOLEAN EnterSaveLoadScreen()
usPosX = SLG_FIRST_SAVED_SPOT_X;
usPosY = SLG_FIRST_SAVED_SPOT_Y;
- for(i=0; i= NUM_SAVE_GAMES || bSaveGameID < 0 )
+ if( bSaveGameID >= NUM_SLOT || bSaveGameID < 0 )
{
return;
}
@@ -1164,7 +1221,7 @@ BOOLEAN InitSaveGameArray()
SAVED_GAME_HEADER SaveGameHeader;
- for( cnt=0; cnt NUM_SAVE_GAMES )
+ if( bEntry < 0 || bEntry > NUM_SLOT )
{
//memset( &pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) );
memset( pSaveGameHeader, 0, sizeof( SAVED_GAME_HEADER ) );
@@ -1685,7 +1749,7 @@ void SelectedSaveRegionCallBack(MOUSE_REGION * pRegion, INT32 iReason )
}
//Reset the regions
- for( i=0; i= 1 && gbSelectedSaveLocation < NUM_SAVE_GAMES-1 )
+ if( gbSelectedSaveLocation >= 1 && gbSelectedSaveLocation < NUM_SLOT-1 )
{
SetSelection( (UINT8)(gbSelectedSaveLocation + 1) );
}
@@ -2542,7 +2606,7 @@ void MoveSelectionUpOrDown( BOOLEAN fUp )
}
else
{
- for( i=gbSelectedSaveLocation+1; i
/*
#ifdef __cplusplus
@@ -217,9 +217,73 @@ extern void _DebugMessage(const char *pSourceFile, unsigned uiLineNum, const cha
#define DebugAttackBusy(x)
#endif
-#include "VFS/vfs_debug.h"
+#define SGP_CALLER_LOCATION , int line=0, const char* function=NULL, const char* file=NULL
+#define SGP_CALLER_LOCATION_IMPL , int line, const char* function, const char* file
+#define SGP_GET_CALLER_LOCATION , __LINE__, __FUNCTION__, __FILE__
+#define SGP_SET_CALLER_LOCATION , line, function, file
-void _ExceptionMessage( CBasicException &ex );
+#include
+#include
+
+namespace vfs { class Exception; }
+namespace sgp
+{
+ class WString
+ {
+ public:
+ WString(std::string const& s){
+ convert_string(s,str);
+ }
+ WString(const char* s) {
+ convert_string(s,str);
+ }
+ WString(std::wstring const& s) : str(s) {
+ }
+ WString(const wchar_t* s) : str(s) {
+ }
+ public:
+ std::wstring str;
+ };
+
+ class Exception : public std::exception
+ {
+ public:
+ Exception(WString const& msg SGP_CALLER_LOCATION);
+
+ // default exception
+ Exception(WString const& msg, Exception& ex SGP_CALLER_LOCATION);
+
+ // compatibility with std::exception
+ Exception(WString const& msg, std::exception& ex SGP_CALLER_LOCATION);
+
+#if defined(USE_VFS)
+ // compatibility with vfs::Exception
+ Exception(WString const& msg, vfs::Exception& ex SGP_CALLER_LOCATION);
+#endif
+
+ virtual const char* what() const throw();
+
+ struct Excp
+ {
+ int line;
+ std::string function, file;
+ std::wstring msg;
+ };
+ std::list _msg;
+ };
+}
+
+#define SGP_THROW(msg) throw sgp::Exception( (msg) SGP_GET_CALLER_LOCATION )
+#define SGP_RETHROW(msg, ex) throw sgp::Exception( (msg), (ex) SGP_GET_CALLER_LOCATION )
+#define SGP_TRYCATCH_RETHROW(expr, msg) try { (expr); } catch(std::exception &ex) { throw sgp::Exception((msg), (ex) SGP_GET_CALLER_LOCATION); }
+
+#define SGP_THROW_IFFALSE(cond, msg) if((cond) == false) { throw sgp::Exception(msg SGP_GET_CALLER_LOCATION); }
+#define SGP_THROW_IFNULL(ptr, msg) if((ptr) == NULL) { throw sgp::Exception(msg SGP_GET_CALLER_LOCATION); }
+
+#include
+
+void _ExceptionMessage( sgp::Exception &ex );
+void _ExceptionMessage( vfs::Exception &ex );
/*
#ifdef __cplusplus
diff --git a/Standard Gaming Platform/DEBUG.cpp b/Standard Gaming Platform/DEBUG.cpp
index 8bae2ac5..515cba7f 100644
--- a/Standard Gaming Platform/DEBUG.cpp
+++ b/Standard Gaming Platform/DEBUG.cpp
@@ -48,9 +48,11 @@
#ifndef _NO_DEBUG_TXT
#include "fileman.h"
#endif
-#include "GameSettings.h"
+#include "GameSettings.h"
#include "SaveLoadGame.h"
+#include "debug_util.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -402,7 +404,7 @@ void DbgShutdown() {};
extern HVOBJECT FontObjs[25];
-
+#include
void _FailMessage(const char* message, unsigned lineNum, const char * functionName, const char* sourceFileName)
{
// This function shouldn't recurse
@@ -411,6 +413,8 @@ void _FailMessage(const char* message, unsigned lineNum, const char * functionNa
return;
alreadyInThisFunction = true;
+ sgp::dumpStackTrace(message);
+
std::stringstream basicInformation;
basicInformation << "Assertion Failure [Line " << lineNum;
if (functionName) {
@@ -501,10 +505,26 @@ STR8 String(const STR8 String, ...)
}
-void _ExceptionMessage( CBasicException &ex )
+void _ExceptionMessage( sgp::Exception &ex )
{
g_ExceptionList.clear();
- CBasicException::CALLSTACK::iterator it = ex.m_CallStack.begin();
+ std::list::iterator it = ex._msg.begin();
+ for(; it!=ex._msg.end(); ++it)
+ {
+ SExceptionData exd;
+ exd.message = (*it).msg;
+ exd.function = (*it).function;
+ exd.file = (*it).file;
+ exd.line = (*it).line;
+ g_ExceptionList.push_back(exd);
+ }
+ _FailMessage("",0,"");
+}
+
+void _ExceptionMessage( vfs::Exception &ex )
+{
+ g_ExceptionList.clear();
+ vfs::Exception::CALLSTACK::iterator it = ex.m_CallStack.begin();
for(; it!=ex.m_CallStack.end(); ++it)
{
SExceptionData exd;
@@ -517,5 +537,127 @@ void _ExceptionMessage( CBasicException &ex )
_FailMessage("",0,"");
}
+#include
+#include
+
+sgp::Exception::Exception(sgp::WString const& msg SGP_CALLER_LOCATION_IMPL)
+{
+ Excp excp;
+ excp.line = line;
+ excp.file = file ? file : "";
+ excp.function = function ? function : "";
+ excp.msg = msg.str;
+
+ _msg.push_back(excp);
+}
+
+sgp::Exception::Exception(sgp::WString const& msg, Exception& ex SGP_CALLER_LOCATION_IMPL)
+{
+ _msg.insert(_msg.end(), ex._msg.begin(), ex._msg.end());
+
+ Excp excp;
+ excp.line = line;
+ excp.file = file ? file : "";
+ excp.function = function ? function : "";
+ excp.msg = msg.str;
+
+ _msg.push_back(excp);
+}
+
+#if defined(USE_VFS)
+sgp::Exception::Exception(sgp::WString const& msg, vfs::Exception& ex SGP_CALLER_LOCATION_IMPL)
+{
+ vfs::Exception::CALLSTACK::iterator it = ex.m_CallStack.begin();
+ for(; it != ex.m_CallStack.end(); ++it)
+ {
+ Excp excp;
+ excp.file = it->file.utf8();
+ excp.function = it->function.utf8();
+ excp.line = it->line;
+ excp.msg = it->message.c_wcs();
+ _msg.push_back(excp);
+ }
+
+ Excp excp;
+ excp.line = line;
+ excp.file = file ? file : "";
+ excp.function = function ? function : "";
+ excp.msg = msg.str;
+
+ _msg.push_back(excp);
+}
+#endif
+
+sgp::Exception::Exception(WString const& msg, std::exception& ex SGP_CALLER_LOCATION_IMPL)
+{
+ if(dynamic_cast(&ex))
+ {
+ sgp::Exception& sgp_ex = *static_cast(&ex);
+ _msg.insert(_msg.end(), sgp_ex._msg.begin(), sgp_ex._msg.end());
+ }
+ else if(dynamic_cast(&ex))
+ {
+ vfs::Exception& vfs_ex = *static_cast(&ex);
+ vfs::Exception::CALLSTACK::iterator it = vfs_ex.m_CallStack.begin();
+ for(; it != vfs_ex.m_CallStack.end(); ++it)
+ {
+ Excp excp;
+ excp.file = it->file.utf8();
+ excp.function = it->function.utf8();
+ excp.line = it->line;
+ excp.msg = it->message.c_wcs();
+ _msg.push_back(excp);
+ }
+ }
+ else
+ {
+ Excp excp;
+ excp.file = "";
+ excp.function = "";
+ excp.line = -1;
+ convert_string(ex.what(), excp.msg);
+ _msg.push_back(excp);
+ }
+
+ Excp excp;
+ excp.line = line;
+ excp.file = file ? file : "";
+ excp.function = function ? function : "";
+ excp.msg = msg.str;
+
+ _msg.push_back(excp);
+}
+
+
+#if defined(_WIN32) || defined(WIN64)
+# define ENDL "\r\n"
+#else
+# define ENDL "\n"
+#endif
+
+static std::string gs_exception_string;
+
+const char* sgp::Exception::what() const
+{
+ // cannot return pointer local variable
+ std::stringstream ss;
+ ss.str("");
+ ss.clear();
+
+ std::list::const_reverse_iterator rit = _msg.rbegin();
+ for(; rit != _msg.rend(); ++rit)
+ {
+ std::string msg;
+ convert_string(rit->msg, msg);
+ //wss << "========== " << rit->time << " =========="ENDL;
+ ss << "File : " << rit->file << ENDL;
+ ss << "Line : " << rit->line << ENDL;
+ ss << "Location : " << rit->function << ENDL;
+ ss << " " << msg << ENDL;
+ }
+
+ gs_exception_string = ss.str();
+ return gs_exception_string.c_str();
+}
diff --git a/Standard Gaming Platform/FileMan.cpp b/Standard Gaming Platform/FileMan.cpp
index 0cef6310..1e2d5267 100644
--- a/Standard Gaming Platform/FileMan.cpp
+++ b/Standard Gaming Platform/FileMan.cpp
@@ -45,18 +45,18 @@
#include "Container.h"
#include "LibraryDataBase.h"
#include "io.h"
-
+ #include "sgp_logger.h"
#endif
using namespace std;
-#include "VFS/vfs.h"
-#include "VFS/os_functions.h"
-#include "VFS/vfs_settings.h"
+#include
+#include
+#include
#ifdef USE_VFS
-#include "VFS/vfs_file_raii.h"
+#include
#include
+
+
@@ -495,6 +499,10 @@
RelativePath="RAD.H"
>
+
+
@@ -511,6 +519,14 @@
RelativePath="sgp.h"
>
+
+
+
+
@@ -631,6 +647,14 @@
RelativePath="DEBUG.cpp"
>
+
+
+
+
@@ -727,6 +751,10 @@
RelativePath="sgp.cpp"
>
+
+
diff --git a/Standard Gaming Platform/SGP_VS2010.vcxproj b/Standard Gaming Platform/SGP_VS2010.vcxproj
new file mode 100644
index 00000000..13489454
--- /dev/null
+++ b/Standard Gaming Platform/SGP_VS2010.vcxproj
@@ -0,0 +1,326 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}
+ Win32Proj
+ SGP
+ SGP
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;NO_ZLIB_COMPRESSION;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;NO_ZLIB_COMPRESSION;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;NO_ZLIB_COMPRESSION;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;NO_ZLIB_COMPRESSION;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;NO_ZLIB_COMPRESSION;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Standard Gaming Platform/SGP_VS2010.vcxproj.filters b/Standard Gaming Platform/SGP_VS2010.vcxproj.filters
new file mode 100644
index 00000000..4d7304a1
--- /dev/null
+++ b/Standard Gaming Platform/SGP_VS2010.vcxproj.filters
@@ -0,0 +1,354 @@
+
+
+
+
+ {efcdc6de-effe-499c-865f-bbb1cd30a876}
+
+
+ {3abaeda9-a6ab-443e-9e82-5b43020f6328}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Standard Gaming Platform/Types.h b/Standard Gaming Platform/Types.h
index ad4b1861..46d11e0e 100644
--- a/Standard Gaming Platform/Types.h
+++ b/Standard Gaming Platform/Types.h
@@ -33,8 +33,10 @@
#if defined( JA2 ) || defined( UTILS )
typedef unsigned int UINT32;
-typedef __int64 INT64; // WANNE - BMP: Used for Big Maps
+typedef signed __int64 INT64; // WANNE - BMP: Used for Big Maps
typedef signed int INT32;
+typedef unsigned __int64 UINT64;
+typedef unsigned long long UINT128;
#else
typedef unsigned int UINT32;
typedef int INT32;
@@ -132,4 +134,52 @@ typedef VECTOR4 MATRIX4[4]; // 4x4 matrix
typedef VECTOR4 COLOR; // rgba color array
+#include
+#include
+
+inline void convert_string(std::wstring const& str_in, std::string &str_out)
+{
+#if !defined(USE_VFS)
+ const wchar_t* src = str_in.c_str();
+ size_t len = wcstombs(NULL, src, str_in.length());
+ if(len > 0)
+ {
+ str_out.resize(len);
+ wcstombs(&str_out[0], src, len);
+ }
+#else
+ if(vfs::Settings::getUseUnicode())
+ {
+ str_out = vfs::String::as_utf8(str_in);
+ }
+ else
+ {
+ vfs::String::narrow(str_in, str_out);
+ }
+#endif
+}
+
+inline void convert_string(std::string const& str_in, std::wstring &str_out)
+{
+#if !defined(USE_VFS)
+ const char* src = str_in.c_str();
+ size_t len = mbstowcs(NULL, src, str_in.length());
+ if(len > 0)
+ {
+ str_out.resize(len);
+ mbstowcs(&str_out[0], src, len);
+ }
+#else
+ if(vfs::Settings::getUseUnicode())
+ {
+ vfs::String::as_utf16(str_in, str_out);
+ }
+ else
+ {
+ vfs::String::widen(str_in, str_out);
+ }
+#endif
+}
+
+
#endif
\ No newline at end of file
diff --git a/Standard Gaming Platform/WinFont.cpp b/Standard Gaming Platform/WinFont.cpp
index f3545e5a..72968228 100644
Binary files a/Standard Gaming Platform/WinFont.cpp and b/Standard Gaming Platform/WinFont.cpp differ
diff --git a/Standard Gaming Platform/debug_util.cpp b/Standard Gaming Platform/debug_util.cpp
new file mode 100644
index 00000000..5f6e680c
--- /dev/null
+++ b/Standard Gaming Platform/debug_util.cpp
@@ -0,0 +1,37 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "debug_util.h"
+
+const void *const *StackTrace::Addresses(size_t* count) {
+ *count = trace_.size();
+ if (trace_.size())
+ return &trace_[0];
+ return NULL;
+}
+
+void sgp::dumpStackTrace(vfs::String const& msg)
+{
+ // the first error is the important one anyway
+ static bool already_dumping = false;
+
+ if(!already_dumping) // needs a mutes to be sure
+ {
+ already_dumping = true;
+ StackTrace str;
+ str.PrintBacktrace(msg.utf8().c_str());
+ already_dumping = false;
+ }
+}
+
+#ifdef __MINGW32__
+StackTrace::StackTrace()
+{
+}
+
+void StackTrace::PrintBacktrace(const char* msg)
+{
+}
+
+#endif
diff --git a/Standard Gaming Platform/debug_util.h b/Standard Gaming Platform/debug_util.h
new file mode 100644
index 00000000..ac06cfe5
--- /dev/null
+++ b/Standard Gaming Platform/debug_util.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a cross platform interface for helper functions related to debuggers.
+// You should use this to test if you're running under a debugger, and if you
+// would like to yield (breakpoint) into the debugger.
+
+#ifndef BASE_DEBUG_UTIL_H_
+#define BASE_DEBUG_UTIL_H_
+
+#include
+#include
+
+#include "sgp_logger.h"
+
+// A macro to disallow the copy constructor and operator= functions
+// This should be used in the private: declarations for a class
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+// An older, deprecated, politically incorrect name for the above.
+#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) DISALLOW_COPY_AND_ASSIGN(TypeName)
+
+// A stacktrace can be helpful in debugging. For example, you can include a
+// stacktrace member in a object (probably around #ifndef NDEBUG) so that you
+// can later see where the given object was created from.
+class StackTrace {
+public:
+ // Create a stacktrace from the current location
+ StackTrace();
+ // Get an array of instruction pointer values.
+ // count: (output) the number of elements in the returned array
+ const void *const *Addresses(size_t* count);
+ // Print a backtrace to stderr
+ void PrintBacktrace(const char* msg);
+
+ // Resolve backtrace to symbols and write to stream.
+ void OutputToStream(const char* msg, sgp::Logger::LogInstance* os);
+
+private:
+ std::vector trace_;
+ int count_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(StackTrace);
+};
+
+namespace sgp
+{
+ void dumpStackTrace(vfs::String const& msg);
+}
+
+#endif // BASE_DEBUG_UTIL_H_
diff --git a/Standard Gaming Platform/debug_win_util.cpp b/Standard Gaming Platform/debug_win_util.cpp
new file mode 100644
index 00000000..7e9df4ad
--- /dev/null
+++ b/Standard Gaming Platform/debug_win_util.cpp
@@ -0,0 +1,223 @@
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+
+#if defined(_MSC_VER)
+
+#include "debug_util.h"
+
+#include
+
+
+#include
+#include
+
+#include
+
+
+
+// The arraysize(arr) macro returns the # of elements in an array arr.
+// The expression is a compile-time constant, and therefore can be
+// used in defining new arrays, for example. If you use arraysize on
+// a pointer by mistake, you will get a compile-time error.
+//
+// One caveat is that arraysize() doesn't accept any array of an
+// anonymous type or a type defined inside a function. In these rare
+// cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is
+// due to a limitation in C++'s template system. The limitation might
+// eventually be removed, but it hasn't happened yet.
+
+// This template function declaration is used in defining arraysize.
+// Note that the function doesn't need an implementation, as we only
+// use its type.
+template
+char (&ArraySizeHelper(T (&array)[N]))[N];
+
+// That gcc wants both of these prototypes seems mysterious. VC, for
+// its part, can't decide which to use (another mystery). Matching of
+// template overloads: the final frontier.
+#ifndef _MSC_VER
+template
+char (&ArraySizeHelper(const T (&array)[N]))[N];
+#endif
+
+#define arraysize(array) (sizeof(ArraySizeHelper(array)))
+
+
+namespace {
+ // SymbolContext is a threadsafe singleton that wraps the DbgHelp Sym* family
+ // of functions. The Sym* family of functions may only be invoked by one
+ // thread at a time. SymbolContext code may access a symbol server over the
+ // network while holding the lock for this singleton. In the case of high
+ // latency, this code will adversly affect performance.
+ //
+ // There is also a known issue where this backtrace code can interact
+ // badly with breakpad if breakpad is invoked in a separate thread while
+ // we are using the Sym* functions. This is because breakpad does now
+ // share a lock with this function. See this related bug:
+ //
+ // http://code.google.com/p/google-breakpad/issues/detail?id=311
+ //
+ // This is a very unlikely edge case, and the current solution is to
+ // just ignore it.
+ class SymbolContext {
+ public:
+ static SymbolContext* Get() {
+ static SymbolContext* s_singleton = NULL;
+ if(!s_singleton) s_singleton = new SymbolContext();
+ return s_singleton;
+ // We use a leaky singleton because code may call this during process
+ // termination.
+
+ //return Singleton >::get();
+ }
+
+ // Returns the error code of a failed initialization.
+ DWORD init_error() const {
+ return init_error_;
+ }
+
+ // For the given trace, attempts to resolve the symbols, and output a trace
+ // to the ostream os. The format for each line of the backtrace is:
+ //
+ // SymbolName[0xAddress+Offset] (FileName:LineNo)
+ //
+ // This function should only be called if Init() has been called. We do not
+ // LOG(FATAL) here because this code is called might be triggered by a
+ // LOG(FATAL) itself.
+ void OutputTraceToStream(const std::vector& trace, sgp::Logger::LogInstance* os) {
+ //AutoLock lock(lock_);
+
+ for (size_t i = 0; (i < trace.size()); ++i) {
+ const int kMaxNameLength = 256;
+ DWORD_PTR frame = reinterpret_cast(trace[i]);
+
+ // Code adapted from MSDN example:
+ // http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
+ ULONG64 buffer[
+ (sizeof(SYMBOL_INFO) +
+ kMaxNameLength * sizeof(wchar_t) +
+ sizeof(ULONG64) - 1) /
+ sizeof(ULONG64)];
+
+ // Initialize symbol information retrieval structures.
+ DWORD64 sym_displacement = 0;
+ PSYMBOL_INFO symbol = reinterpret_cast(&buffer[0]);
+ symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ symbol->MaxNameLen = kMaxNameLength;
+ BOOL has_symbol = SymFromAddr(GetCurrentProcess(), frame,
+ &sym_displacement, symbol);
+
+ // Attempt to retrieve line number information.
+ DWORD line_displacement = 0;
+ IMAGEHLP_LINE64 line = {};
+ line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+ BOOL has_line = SymGetLineFromAddr64(GetCurrentProcess(), frame,
+ &line_displacement, &line);
+
+ // Output the backtrace line.
+ (*os) << " ";
+ if (has_symbol)
+ {
+ (*os) << " [0x" << trace[i] << "+" << sym_displacement << "]\t";
+ (*os) << vfs::String(symbol->Name);
+ }
+ else
+ {
+ (*os) << " [0x" << trace[i] << "]\t";
+ // If there is no symbol information, add a spacer.
+ (*os) << " (No symbol)";
+ }
+ if (has_line)
+ {
+ (*os) << " - (" << line.FileName << ":" << line.LineNumber << ")";
+ }
+ (*os) << sgp::endl;
+ }
+ (*os) << sgp::endl;
+ }
+
+ private:
+ SymbolContext() : init_error_(ERROR_SUCCESS) {
+ // Initializes the symbols for the process.
+ // Defer symbol load until they're needed, use undecorated names, and
+ // get line numbers.
+ SymSetOptions(SYMOPT_DEFERRED_LOADS |
+ SYMOPT_UNDNAME |
+ SYMOPT_LOAD_LINES);
+ if (SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
+ init_error_ = ERROR_SUCCESS;
+ } else {
+ __debugbreak();
+ init_error_ = GetLastError();
+ }
+ }
+
+ DWORD init_error_;
+ //Lock lock_;
+ DISALLOW_COPY_AND_ASSIGN(SymbolContext);
+ };
+
+} // namespace
+
+#define ENABLE_STACK_TRACE 0
+StackTrace::StackTrace() {
+ // From http://msdn.microsoft.com/en-us/library/bb204633(VS.85).aspx,
+ // the sum of FramesToSkip and FramesToCapture must be less than 63,
+ // so set it to 62.
+ const int kMaxCallers = 62;
+
+ void* callers[kMaxCallers];
+ // TODO(ajwong): Migrate this to StackWalk64.
+
+ // WANNE: VS 2005 compilation error
+ // WANNE: I disabled the method call "CaptureStackBackTrace()" because it gives a compilation error in VS 2005
+#if ENABLE_STACK_TRACE
+ int count = CaptureStackBackTrace(0, kMaxCallers, callers, NULL);
+
+ // WANNE: This also does not work in VS 2005
+ //int count = RtlCaptureStackBackTrace(0, kMaxCallers, callers, NULL);
+ if (count > 0) {
+ trace_.resize(count);
+ memcpy(&trace_[0], callers, sizeof(callers[0]) * count);
+ } else {
+ trace_.resize(0);
+ }
+#endif
+}
+
+static struct StackTraceLog {
+ sgp::Logger_ID id;
+ StackTraceLog() {
+ id = sgp::Logger::instance().createLogger();
+ sgp::Logger::instance().connectFile(id, L"stack_trace.log", false, sgp::Logger::FLUSH_ON_ENDL);
+ };
+} s_log;
+
+void StackTrace::PrintBacktrace(const char* msg) {
+ OutputToStream(msg, &(SGP_LOG(s_log.id)));
+}
+
+void StackTrace::OutputToStream(const char* msg, sgp::Logger::LogInstance* os) {
+ SymbolContext* context = SymbolContext::Get();
+ DWORD error = context->init_error();
+ if (error != ERROR_SUCCESS)
+ {
+ (*os) << "Error initializing symbols (" << error
+ << "). Dumping unresolved backtrace:"
+ << sgp::endl;
+ for (size_t i = 0; (i < trace_.size()); ++i)
+ {
+ (*os) << "\t" << trace_[i] << sgp::endl;
+ }
+ }
+ else
+ {
+ (*os) << L"Backtrace: " << (msg != NULL ? msg : "") << sgp::endl;
+ context->OutputTraceToStream(trace_, os);
+ }
+}
+
+#endif // _MSC_VER
diff --git a/Standard Gaming Platform/himage.cpp b/Standard Gaming Platform/himage.cpp
index b91dfe8e..08d5c1a6 100644
--- a/Standard Gaming Platform/himage.cpp
+++ b/Standard Gaming Platform/himage.cpp
@@ -20,9 +20,9 @@
#include "vobject.h"
#endif
-#include "VFS/vfs.h"
+#include
-const utf8string::str_t CONST_DOTJPC(L".jpc.7z");
+const vfs::String::str_t CONST_DOTJPC(L".jpc.7z");
@@ -52,14 +52,92 @@ typedef union
UINT32 uiValue;
} SplitUINT32;
-HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents )
+namespace ImageFileType
{
- HIMAGE hImage = NULL;
- SGPFILENAME Extension;
- CHAR8 ExtensionSep[] = ".";
- STR StrPtr;
+ typedef std::map ExtMap_t;
+
+ static int map(vfs::String const& ext)
+ {
+ static ExtMap_t _ext_map;
+ static bool inited = false;
+ if(!inited)
+ {
+ _ext_map["pcx"] = PCX_FILE_READER;
+ _ext_map["tga"] = TGA_FILE_READER;
+ _ext_map["sti"] = STCI_FILE_READER;
+ _ext_map["png"] = PNG_FILE_READER;
+ _ext_map["jpc.7z"] = JPC_FILE_READER;
+ inited = true;
+ }
+ ExtMap_t::const_iterator cit = _ext_map.find(ext);
+ if(cit != _ext_map.end())
+ {
+ return cit->second;
+ }
+ return UNKNOWN_FILE_READER;
+ }
+
+ static int getFileReaderType(std::string& filename, TestOrder order)
+ {
+ std::string::size_type pos = filename.find_last_of(".");
+ std::string ext = filename.substr(pos+1, std::string::npos);
+ if(ext.empty())
+ {
+ ext = "pcx";
+ filename += ".pcx";
+ }
+ int reader_type = map(ext);
+
+ /*
+ * if DEFAULT, then just check existance of file
+ * if not STI, then there is no different load order, just continue as usual
+ */
+ if(order == DEFAULT || reader_type != STCI_FILE_READER)
+ {
+ return getVFS()->fileExists(filename) ? reader_type : UNKNOWN_FILE_READER;
+ }
+ /*
+ * file must have originally been an STI file, but should be treated as a JPC or a PNG file
+ */
+ else if(order == JPC || order == PNG)
+ {
+ vfs::String file = filename.substr(0, pos+1).append(order == JPC ? "jpc.7z" : "png");
+ if( getVFS()->fileExists(file) )
+ {
+ filename = file.utf8();
+ return order == JPC ? JPC_FILE_READER : PNG_FILE_READER;
+ }
+ return UNKNOWN_FILE_READER;
+ }
+ /*
+ * file must have originally been an STI file, but should be treated as a JPC or a PNG file
+ * if the replacement filetypes don't exist, fall back to STI
+ */
+ else if(order == JPC_FALLBACK || order == PNG_FALLBACK)
+ {
+ vfs::String file = filename.substr(0, pos+1).append(order == JPC_FALLBACK ? "jpc.7z" : "png");
+ if( getVFS()->fileExists(file) )
+ {
+ filename = file.utf8();
+ return order == JPC_FALLBACK ? JPC_FILE_READER : PNG_FILE_READER;
+ }
+ // fallback to original type
+ return getVFS()->fileExists(filename) ? reader_type : UNKNOWN_FILE_READER;
+ }
+ return UNKNOWN_FILE_READER;
+ }
+};
+
+HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents, ImageFileType::TestOrder order )
+{
+ HIMAGE hImage = NULL;
+ CHAR8 ExtensionSep[] = ".";
UINT32 iFileLoader;
+#if 0
+ SGPFILENAME Extension;
+ STR StrPtr;
+
// Depending on extension of filename, use different image readers
// Get extension
StrPtr = strstr( ImageFile, ExtensionSep );
@@ -96,9 +174,9 @@ HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents )
#ifdef USE_VFS
// see if there is a .jpc file first and when that fails, try .sti
vfs::Path str(ImageFile);
- utf8string::str_t const& findext = str.c_wcs();
- utf8string::size_t dot = findext.find_last_of(vfs::Const::DOT());
- utf8string fname = findext.substr(0,dot).append(CONST_DOTJPC);
+ vfs::String::str_t const& findext = str.c_wcs();
+ vfs::String::size_t dot = findext.find_last_of(vfs::Const::DOT());
+ vfs::String fname = findext.substr(0,dot).append(CONST_DOTJPC);
if(getVFS()->fileExists(fname))
{
iFileLoader = JPC_FILE_READER;
@@ -116,7 +194,7 @@ HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents )
break;
}
#ifdef USE_VFS
- else if ( StrCmp::Equal(Extension, L"jpc.7z") )
+ else if ( vfs::StrCmp::Equal(Extension, L"jpc.7z") )
{
iFileLoader = JPC_FILE_READER;
break;
@@ -137,6 +215,23 @@ HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents )
return( NULL );
}
+#else
+ std::string filename(ImageFile);
+ iFileLoader = ImageFileType::getFileReaderType(filename, order);
+ if ( iFileLoader == UNKNOWN_FILE_READER )
+ {
+ //If in debug, make fatal!
+#ifdef JA2
+#ifdef _DEBUG
+ //FatalError( "Resource file %s does not exist.", ImageFile );
+#endif
+#endif
+ DbgMessage( TOPIC_HIMAGE, DBG_LEVEL_2, String("Resource file %s does not exist.", ImageFile) );
+
+ return( NULL );
+ }
+
+#endif
// Create memory for image structure
hImage = (HIMAGE)MemAlloc( sizeof( image_type ) );
@@ -152,7 +247,7 @@ HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents )
//hImage->pui16BPPPalette = NULL;
// Set filename and loader
- strcpy( hImage->ImageFile, ImageFile );
+ strncpy( hImage->ImageFile, /*ImageFile*/filename.c_str(), filename.length() );
hImage->iFileLoader = iFileLoader;
if ( !LoadImageData( hImage, fContents ) )
diff --git a/Standard Gaming Platform/himage.h b/Standard Gaming Platform/himage.h
index 2396b23c..bc997f72 100644
--- a/Standard Gaming Platform/himage.h
+++ b/Standard Gaming Platform/himage.h
@@ -138,9 +138,21 @@ typedef struct
extern "C" {
#endif
+namespace ImageFileType
+{
+ enum TestOrder
+ {
+ DEFAULT = 0, // check extension
+ JPC, // ignore file extension, test only *.jpc
+ JPC_FALLBACK, // test *.jpc, fallback to original type
+ PNG, // ignore file extension, test only *.png
+ PNG_FALLBACK, // test *.png, fallback to original type
+ };
+};
+
// This function will return NULL if it fails, and call SetLastError() to set
// error information
-HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents );
+HIMAGE CreateImage( SGPFILENAME ImageFile, UINT16 fContents, ImageFileType::TestOrder order = ImageFileType::JPC_FALLBACK);
// This function destroys the HIMAGE structure as well as its contents
BOOLEAN DestroyImage( HIMAGE hImage );
diff --git a/Standard Gaming Platform/input.cpp b/Standard Gaming Platform/input.cpp
index 568484ca..874d87f2 100644
--- a/Standard Gaming Platform/input.cpp
+++ b/Standard Gaming Platform/input.cpp
@@ -8,6 +8,10 @@
#elif defined( WIZ8_PRECOMPILED_HEADERS )
#include "WIZ8 SGP ALL.H"
#else
+//** dd .
+#define _WIN32_WINNT 0x500
+
+//**
#include "types.h"
#include
#include //dnl
@@ -69,12 +73,18 @@ BOOLEAN gfRecordedLeftButtonUp;
UINT32 guiLeftButtonRepeatTimer;
UINT32 guiRightButtonRepeatTimer;
+UINT32 guiMiddleButtonRepeatTimer;
+UINT32 guiX1ButtonRepeatTimer;
+UINT32 guiX2ButtonRepeatTimer;
BOOLEAN gfTrackMousePos; // TRUE = queue mouse movement events, FALSE = don't
BOOLEAN gfLeftButtonState; // TRUE = Pressed, FALSE = Not Pressed
BOOLEAN gfRightButtonState; // TRUE = Pressed, FALSE = Not Pressed
BOOLEAN gfMiddleButtonState;//dnl TRUE = Pressed, FALSE = Not Pressed
-INT16 gsMouseWheelDeltaValue;//dnl positive value indicates that the wheel was rotated forward, negative value indicates that the wheel was rotated backward, and user handler procedure for mouse wheel should restore after usege this value to zero!
+//INT16 gsMouseWheelDeltaValue;//dnl positive value indicates that the wheel was rotated forward, negative value indicates that the wheel was rotated backward, and user handler procedure for mouse wheel should restore after usege this value to zero!
+BOOLEAN gfX1ButtonState;
+BOOLEAN gfX2ButtonState;
+
INT16 gusMouseXPos; // X position of the mouse on screen
INT16 gusMouseYPos; // y position of the mouse on screen
@@ -104,322 +114,131 @@ StringInput *gpCurrentStringDescriptor;
void QueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam);
void RedirectToString(UINT16 uiInputCharacter);
-void HandleSingleClicksAndButtonRepeats( void );
-void AdjustMouseForWindowOrigin(void);
+void HandleSingleClicksAndButtonRepeats( void );
+void AdjustMouseForWindowOrigin(void);
// These are the hook functions for both keyboard and mouse
LRESULT CALLBACK KeyboardHandler(int Code, WPARAM wParam, LPARAM lParam)
{
-#ifndef JA2
- if((Code < 0) || (!gfApplicationActive))
-#else
- if (Code < 0)
-#endif
- { // Do not handle this message, pass it on to another window
- return CallNextHookEx(ghKeyboardHook, Code, wParam, lParam);
- }
+ if (Code < 0) // Do not handle this message, pass it on to another window
+ return CallNextHookEx(ghKeyboardHook, Code, wParam, lParam);
- if (lParam & TRANSITION_MASK)
- { // The key has been released
- KeyUp(wParam, lParam);
- //gfSGPInputReceived = TRUE;
- }
+ if (lParam & TRANSITION_MASK) // The key has been released
+ KeyUp(wParam, lParam); //gfSGPInputReceived = TRUE;
else
{ // Key was up
KeyDown(wParam, lParam);
gfSGPInputReceived = TRUE;
}
-
return TRUE;
}
-#ifdef JA2
LRESULT CALLBACK MouseHandler(int Code, WPARAM wParam, LPARAM lParam)
{
UINT32 uiParam;
POINT mpos;
+ MOUSEHOOKSTRUCTEX* p_mhs;
-#ifndef JA2
- if((Code < 0) || (!gfApplicationActive))
-#else
- if (Code < 0)
-#endif
- { // Do not handle this message, pass it on to another window
- return CallNextHookEx(ghMouseHook, Code, wParam, lParam);
- }
+ if (Code < 0) // Do not handle this message, pass it on to another window
+ return CallNextHookEx(ghMouseHook, Code, wParam, lParam);
+
+ p_mhs = (MOUSEHOOKSTRUCTEX*)lParam;
+
+ mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
+ ScreenToClient( ghWindow, &mpos);
+ gusMouseXPos = (INT16)mpos.x;
+ gusMouseYPos = (INT16)mpos.y;
+ uiParam = gusMouseYPos;
+ uiParam = uiParam << 16;
+ uiParam = uiParam | gusMouseXPos;
switch (wParam)
{
- case WM_LBUTTONDOWN :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient( ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update the button state
- gfLeftButtonState = TRUE;
-
- //Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
- QueueEvent(LEFT_BUTTON_DOWN, 0, uiParam);
+ case WM_XBUTTONDOWN://**
+ if( p_mhs->mouseData== (XBUTTON1<<16) ) //MessageBeep(-1);
+ {
+ gfX1ButtonState = TRUE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(X1_BUTTON_DOWN, 0, uiParam);
+ }
+ if( p_mhs->mouseData== (XBUTTON2<<16) ) //MessageBeep(0x00000040L);
+ {
+ gfX2ButtonState = TRUE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(X2_BUTTON_DOWN, 0, uiParam);
+ }
break;
- case WM_LBUTTONUP :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient( ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update the button state
- gfLeftButtonState = FALSE;
-
- // Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
- QueueEvent(LEFT_BUTTON_UP, 0, uiParam);
+ case WM_XBUTTONUP://**
+ if( p_mhs->mouseData== (XBUTTON1<<16) )
+ {
+ gfX1ButtonState = FALSE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(X1_BUTTON_UP, 0, uiParam);
+ }
+ if( p_mhs->mouseData== (XBUTTON2<<16) )
+ {
+ gfX2ButtonState = FALSE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(X2_BUTTON_UP, 0, uiParam);
+ }
break;
- case WM_RBUTTONDOWN :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient( ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update the button state
- gfRightButtonState = TRUE;
-
- // Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
- QueueEvent(RIGHT_BUTTON_DOWN, 0, uiParam);
+ case WM_MOUSEWHEEL:
+ if(p_mhs->mouseData==(WHEEL_DELTA<<16)) //up MessageBeep(-1);
+ QueueEvent(MOUSE_WHEEL_UP, 0, uiParam);
+ if(p_mhs->mouseData==(-WHEEL_DELTA<<16)) //dn MessageBeep(0x00000040L);
+ QueueEvent(MOUSE_WHEEL_DOWN, 0, uiParam);
break;
- case WM_RBUTTONUP :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient( ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update the button state
- gfRightButtonState = FALSE;
-
- //Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
- QueueEvent(RIGHT_BUTTON_UP, 0, uiParam);
+ case WM_MBUTTONDOWN:
+ gfMiddleButtonState= TRUE; //Set that we have input
+ gfSGPInputReceived = TRUE;//Set that we have input
+ QueueEvent(MIDDLE_BUTTON_DOWN, 0, uiParam);// Trigger an input event
break;
-
- //dnl begin part for additional mouse events
- case WM_MBUTTONDOWN :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient(ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update the button state
- gfMiddleButtonState = TRUE;
-
- //Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
- QueueEvent(MIDDLE_BUTTON_DOWN, 0, uiParam);
- break;
- case WM_MBUTTONUP :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient(ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update the button state
- gfMiddleButtonState = FALSE;
-
- //Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
+ case WM_MBUTTONUP:
+ gfMiddleButtonState= FALSE;
+ gfSGPInputReceived = TRUE;
QueueEvent(MIDDLE_BUTTON_UP, 0, uiParam);
break;
- //case WM_MBUTTONDBLCLK:
- // break;
- case WM_MOUSEWHEEL :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient(ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
- // Update mouse wheel delta value
- gsMouseWheelDeltaValue = GetMouseWheelDeltaValue(((MOUSEHOOKSTRUCTEX *)lParam)->mouseData);
-
- //Set that we have input
- gfSGPInputReceived = TRUE;
-
- // Trigger an input event
- QueueEvent(MOUSE_WHEEL, 0, uiParam);
+ case WM_LBUTTONDOWN:
+ gfLeftButtonState = TRUE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(LEFT_BUTTON_DOWN, 0, uiParam);
break;
-
- //dnl end part for additional mouse events
- case WM_MOUSEMOVE :
- // Update the current mouse position
- mpos = ((MOUSEHOOKSTRUCT *)lParam)->pt;
- ScreenToClient( ghWindow, &mpos);
- gusMouseXPos = (INT16)mpos.x;
- gusMouseYPos = (INT16)mpos.y;
- uiParam = gusMouseYPos;
- uiParam = uiParam << 16;
- uiParam = uiParam | gusMouseXPos;
-
+ case WM_LBUTTONUP:
+ gfLeftButtonState = FALSE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(LEFT_BUTTON_UP, 0, uiParam);
+ break;
+ case WM_RBUTTONDOWN:
+ gfRightButtonState = TRUE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(RIGHT_BUTTON_DOWN, 0, uiParam);
+ break;
+ case WM_RBUTTONUP:
+ gfRightButtonState = FALSE;
+ gfSGPInputReceived = TRUE;
+ QueueEvent(RIGHT_BUTTON_UP, 0, uiParam);
+ break;
+ case WM_MOUSEMOVE:
// Trigger an input event
if (gfTrackMousePos == TRUE)
- {
QueueEvent(MOUSE_POS, 0, uiParam);
- }
- //Set that we have input
- gfSGPInputReceived = TRUE;
+ gfSGPInputReceived = TRUE;
break;
- default :
+ default:
return CallNextHookEx(ghMouseHook, Code, wParam, lParam);
}
+ //ddd why below code commented?
// if (gusMouseXPos < 0 || gusMouseXPos >= SCREEN_WIDTH ||
// gusMouseYPos < 0 || gusMouseYPos >= SCREEN_HEIGHT)
- {
return CallNextHookEx(ghMouseHook, Code, wParam, lParam);
- }
return TRUE;
}
-#else
-// Wizardry mouse hander
-
-LRESULT CALLBACK MouseHandler(int Code, WPARAM wParam, LPARAM lParam)
-{
- UINT32 uiParam;
- UINT32 uiXPos, uiYPos;
- RECT rcClient;
- BOOLEAN fOutsideClient=FALSE;
- static BOOLEAN fResizing=FALSE;
- LRESULT Result;
-
- uiXPos= (((MOUSEHOOKSTRUCT *)lParam)->pt).x;
- uiYPos= (((MOUSEHOOKSTRUCT *)lParam)->pt).y;
-
- if(!VideoIsFullScreen())
- {
- if(wParam==WM_NCLBUTTONDOWN)
- {
- fResizing=TRUE;
- }
- VideoGetClientRect(&rcClient);
- if((uiXPos < (UINT32)rcClient.left) || (uiXPos > (UINT32)rcClient.right) || (uiYPos < (UINT32)rcClient.top) || (uiYPos > (UINT32)rcClient.bottom))
- {
- fOutsideClient=TRUE;
- }
- }
-
- if((Code < 0) || (!gfApplicationActive) || fOutsideClient || fResizing)
- {
- // Do not handle this message, pass it on to another window
- Result = CallNextHookEx(ghMouseHook, Code, wParam, lParam);
-
- if((wParam==WM_LBUTTONUP) || (wParam==WM_NCLBUTTONUP))
- {
- fResizing=FALSE;
- }
- return(Result);
- }
-
- switch (wParam)
- {
- case WM_LBUTTONUP:
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_MOUSEMOVE:
- if(VideoIsFullScreen())
- {
- gusMouseXPos = (UINT16)(uiXPos);
- gusMouseYPos = (UINT16)(uiYPos);
- }
- else
- {
- gusMouseXPos = (UINT16)(uiXPos-rcClient.left);
- gusMouseYPos = (UINT16)(uiYPos-rcClient.top);
- }
- uiParam = (UINT32)gusMouseYPos<<16 | (UINT32)gusMouseXPos;
-
- //Set that we have input
- gfSGPInputReceived = TRUE;
- break;
- }
-
- if ( wParam == WM_MOUSEWHEEL )
- {
- return( FALSE );
- }
-
- switch (wParam)
- {
- case WM_LBUTTONDOWN:
- gfLeftButtonState = TRUE;
- QueueEvent(LEFT_BUTTON_DOWN, 0, uiParam);
- break;
- case WM_LBUTTONUP:
- gfLeftButtonState = FALSE;
- QueueEvent(LEFT_BUTTON_UP, 0, uiParam);
- break;
- case WM_RBUTTONDOWN:
- gfRightButtonState = TRUE;
- QueueEvent(RIGHT_BUTTON_DOWN, 0, uiParam);
- break;
- case WM_RBUTTONUP:
- gfRightButtonState = FALSE;
- QueueEvent(RIGHT_BUTTON_UP, 0, uiParam);
- break;
- case WM_MOUSEMOVE:
- if(gfTrackMousePos)
- QueueEvent(MOUSE_POS, 0, uiParam);
- break;
- }
-
- return(TRUE);
-}
-
-#endif
BOOLEAN InitializeInputManager(void)
{
@@ -531,19 +350,25 @@ void QueueEvent(UINT16 ubInputEvent, UINT32 usParam, UINT32 uiParam)
}
if (ubInputEvent == RIGHT_BUTTON_DOWN)
- {
guiRightButtonRepeatTimer = uiTimer + BUTTON_REPEAT_TIMEOUT;
- }
+ if (ubInputEvent == MIDDLE_BUTTON_DOWN)
+ guiMiddleButtonRepeatTimer = uiTimer + BUTTON_REPEAT_TIMEOUT;
+ if (ubInputEvent == X1_BUTTON_DOWN)
+ guiX1ButtonRepeatTimer = uiTimer + BUTTON_REPEAT_TIMEOUT;
+ if (ubInputEvent == X2_BUTTON_DOWN)
+ guiX2ButtonRepeatTimer = uiTimer + BUTTON_REPEAT_TIMEOUT;
if (ubInputEvent == LEFT_BUTTON_UP)
- {
guiLeftButtonRepeatTimer = 0;
- }
-
if (ubInputEvent == RIGHT_BUTTON_UP)
- {
guiRightButtonRepeatTimer = 0;
- }
+ if (ubInputEvent == MIDDLE_BUTTON_UP)
+ guiMiddleButtonRepeatTimer = 0;
+ if (ubInputEvent == X1_BUTTON_UP)
+ guiX1ButtonRepeatTimer = 0;
+ if (ubInputEvent == X2_BUTTON_UP)
+ guiX2ButtonRepeatTimer = 0;
+
if ( (ubInputEvent == LEFT_BUTTON_UP) )
{
diff --git a/Standard Gaming Platform/input.h b/Standard Gaming Platform/input.h
index 36b6f0f0..fc5fa577 100644
--- a/Standard Gaming Platform/input.h
+++ b/Standard Gaming Platform/input.h
@@ -18,9 +18,21 @@
#define RIGHT_BUTTON_UP 0x0100
#define RIGHT_BUTTON_REPEAT 0x0200
#define MOUSE_POS 0x0400
-#define MOUSE_WHEEL 0x0800
-#define MIDDLE_BUTTON_UP 0x1000//dnl
-#define MIDDLE_BUTTON_DOWN 0x2000//dnl
+#define MOUSE_WHEEL 0x0800
+#define MOUSE_WHEEL_UP 0x0800
+#define MOUSE_WHEEL_DOWN 0x1000
+#define MIDDLE_BUTTON_DOWN 0x2000
+#define MIDDLE_BUTTON_UP 0x4000
+#define MIDDLE_BUTTON_REPEAT 0x8000
+#define X1_BUTTON_DOWN 0x8010
+#define X1_BUTTON_UP 0x8020
+#define X1_BUTTON_REPEAT 0x8030
+#define X2_BUTTON_DOWN 0x8040
+#define X2_BUTTON_UP 0x8050
+#define X2_BUTTON_REPEAT 0x8060
+//#define MIDDLE_BUTTON_UP 0x1000//dnl
+//#define MIDDLE_BUTTON_DOWN 0x2000//dnl
+
#define SHIFT_DOWN 0x01
#define CTRL_DOWN 0x02
diff --git a/Standard Gaming Platform/mousesystem.cpp b/Standard Gaming Platform/mousesystem.cpp
index 2a75b271..5071d13e 100644
--- a/Standard Gaming Platform/mousesystem.cpp
+++ b/Standard Gaming Platform/mousesystem.cpp
@@ -40,6 +40,8 @@
#include "mousesystem.h"
#include "Cursor Control.h"
#include "Button System.h"
+ ///***ddd
+ #include "GameSettings.h"
#endif
#ifdef JA2_PRECOMPILED_HEADERS
@@ -79,7 +81,8 @@ INT32 MSYS_CurrentID=MSYS_ID_SYSTEM;
INT16 MSYS_CurrentMX=0;
INT16 MSYS_CurrentMY=0;
INT16 MSYS_CurrentButtons=0;
-INT16 MSYS_Action=0;
+INT16 MSYS_Action=MSYS_NO_ACTION;
+INT16 MSYS_Wheel=0;
BOOLEAN MSYS_SystemInitialized=FALSE;
BOOLEAN MSYS_UseMouseHandlerHook=FALSE;
@@ -114,7 +117,7 @@ void ExecuteMouseHelpEndCallBack( MOUSE_REGION *region );
//values there as well. That's the only reason why I left this here.
MOUSE_REGION MSYS_SystemBaseRegion = {
MSYS_ID_SYSTEM, MSYS_PRIORITY_SYSTEM, BASE_REGION_FLAGS,
- -32767, -32767, 32767, 32767, 0, 0, 0, 0, 0, 0,
+ -32767, -32767, 32767, 32767, 0, 0, 0, 0, 0, 0, 0,
MSYS_NO_CALLBACK, MSYS_NO_CALLBACK, { 0,0,0,0 },
0, 0, -1, MSYS_NO_CALLBACK, NULL, NULL };
@@ -158,6 +161,7 @@ INT32 MSYS_Init(void)
MSYS_CurrentMX = 0;
MSYS_CurrentMY = 0;
MSYS_CurrentButtons = 0;
+ MSYS_Wheel = 0;
MSYS_Action=MSYS_NO_ACTION;
MSYS_PrevRegion = NULL;
@@ -168,25 +172,26 @@ INT32 MSYS_Init(void)
MSYS_GrabRegion = NULL;
// Setup the system's background region
- MSYS_SystemBaseRegion.IDNumber = MSYS_ID_SYSTEM;
- MSYS_SystemBaseRegion.PriorityLevel = MSYS_PRIORITY_SYSTEM;
- MSYS_SystemBaseRegion.uiFlags = BASE_REGION_FLAGS;
- MSYS_SystemBaseRegion.RegionTopLeftX = -32767;
- MSYS_SystemBaseRegion.RegionTopLeftY = -32767;
+ MSYS_SystemBaseRegion.IDNumber = MSYS_ID_SYSTEM;
+ MSYS_SystemBaseRegion.PriorityLevel = MSYS_PRIORITY_SYSTEM;
+ MSYS_SystemBaseRegion.uiFlags = BASE_REGION_FLAGS;
+ MSYS_SystemBaseRegion.RegionTopLeftX = -32767;
+ MSYS_SystemBaseRegion.RegionTopLeftY = -32767;
MSYS_SystemBaseRegion.RegionBottomRightX = 32767;
MSYS_SystemBaseRegion.RegionBottomRightY = 32767;
- MSYS_SystemBaseRegion.MouseXPos = 0;
- MSYS_SystemBaseRegion.MouseYPos = 0;
- MSYS_SystemBaseRegion.RelativeXPos = 0;
- MSYS_SystemBaseRegion.RelativeYPos = 0;
- MSYS_SystemBaseRegion.ButtonState = 0;
- MSYS_SystemBaseRegion.Cursor = 0;
- MSYS_SystemBaseRegion.UserData[0] = 0;
- MSYS_SystemBaseRegion.UserData[1] = 0;
- MSYS_SystemBaseRegion.UserData[2] = 0;
- MSYS_SystemBaseRegion.UserData[3] = 0;
+ MSYS_SystemBaseRegion.MouseXPos = 0;
+ MSYS_SystemBaseRegion.MouseYPos = 0;
+ MSYS_SystemBaseRegion.RelativeXPos = 0;
+ MSYS_SystemBaseRegion.RelativeYPos = 0;
+ MSYS_SystemBaseRegion.ButtonState = 0;
+ MSYS_SystemBaseRegion.Cursor = 0;
+ MSYS_SystemBaseRegion.WheelState = 0;
+ MSYS_SystemBaseRegion.UserData[0] = 0;
+ MSYS_SystemBaseRegion.UserData[1] = 0;
+ MSYS_SystemBaseRegion.UserData[2] = 0;
+ MSYS_SystemBaseRegion.UserData[3] = 0;
MSYS_SystemBaseRegion.MovementCallback = MSYS_NO_CALLBACK;
- MSYS_SystemBaseRegion.ButtonCallback = MSYS_NO_CALLBACK;
+ MSYS_SystemBaseRegion.ButtonCallback = MSYS_NO_CALLBACK;
MSYS_SystemBaseRegion.FastHelpTimer = 0;
MSYS_SystemBaseRegion.FastHelpText = 0;
@@ -204,7 +209,17 @@ INT32 MSYS_Init(void)
return(1);
}
-
+/*
+LONG WINAPI UEFilter(PEXCEPTION_POINTERS pEI)
+{
+ MessageBox(NULL, ("Exception"), ("Oops !!!"), MB_ICONSTOP);
+ TerminateProcess(GetCurrentProcess(), -1);
+ return -1;
+}
+ SetUnhandledExceptionFilter(UEFilter);
+
+*(char*)0 = 0;
+*/
//======================================================================================================
@@ -232,6 +247,8 @@ void MSYS_Shutdown(void)
//
void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLEAN LeftButton, BOOLEAN RightButton)
{
+
+
// If the mouse system isn't initialized, get out o' here
if(!MSYS_SystemInitialized)
return;
@@ -240,6 +257,12 @@ void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLE
if(!MSYS_UseMouseHandlerHook)
return;
+ if(!gGameExternalOptions.fExtMouseKeyEnabled &&
+ (Type == MIDDLE_BUTTON_UP || Type == MIDDLE_BUTTON_DOWN || Type == X1_BUTTON_DOWN ||
+ Type == X1_BUTTON_UP || Type == X2_BUTTON_DOWN || Type == X2_BUTTON_UP || Type == X1_BUTTON_REPEAT ||
+ Type == X2_BUTTON_REPEAT || Type == MOUSE_WHEEL_UP || Type == MOUSE_WHEEL_DOWN ) )
+ return;
+
MSYS_Action=MSYS_NO_ACTION;
switch(Type)
{
@@ -247,12 +270,23 @@ void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLE
case LEFT_BUTTON_UP:
case RIGHT_BUTTON_DOWN:
case RIGHT_BUTTON_UP:
+ case MIDDLE_BUTTON_UP:
+ case MIDDLE_BUTTON_DOWN:
+ case X1_BUTTON_DOWN:
+ case X1_BUTTON_UP:
+ case X2_BUTTON_DOWN:
+ case X2_BUTTON_UP:
+
//MSYS_Action|=MSYS_DO_BUTTONS;
if(Type == LEFT_BUTTON_DOWN)
+ {
MSYS_Action |= MSYS_DO_LBUTTON_DWN;
+ MSYS_CurrentButtons|=MSYS_LEFT_BUTTON;
+ }
else if(Type == LEFT_BUTTON_UP)
{
MSYS_Action |= MSYS_DO_LBUTTON_UP;
+ MSYS_CurrentButtons&=(~MSYS_LEFT_BUTTON);
//Kris:
//Used only if applicable. This is used for that special button that is locked with the
//mouse press -- just like windows. When you release the button, the previous state
@@ -265,9 +299,45 @@ void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLE
#endif
}
else if(Type == RIGHT_BUTTON_DOWN)
+ {
MSYS_Action |= MSYS_DO_RBUTTON_DWN;
+ MSYS_CurrentButtons|=MSYS_RIGHT_BUTTON;
+ }
else if(Type == RIGHT_BUTTON_UP)
+ {
MSYS_Action |= MSYS_DO_RBUTTON_UP;
+ MSYS_CurrentButtons&=(~MSYS_RIGHT_BUTTON);
+ }
+ else if(Type == MIDDLE_BUTTON_DOWN)
+ {
+ MSYS_Action |= MSYS_DO_MBUTTON_DWN;
+ MSYS_CurrentButtons|=MSYS_MIDDLE_BUTTON;
+ }
+ else if(Type == MIDDLE_BUTTON_UP)
+ {
+ MSYS_Action |= MSYS_DO_MBUTTON_UP;
+ MSYS_CurrentButtons&=(~MSYS_MIDDLE_BUTTON);
+ }
+ else if(Type == X1_BUTTON_DOWN)
+ {
+ MSYS_Action |= MSYS_DO_X1BUTTON_DWN;
+ MSYS_CurrentButtons|=MSYS_X1_BUTTON;
+ }
+ else if(Type == X1_BUTTON_UP)
+ {
+ MSYS_Action |= MSYS_DO_X1BUTTON_UP;
+ MSYS_CurrentButtons&=(~MSYS_X1_BUTTON);
+ }
+ else if(Type == X2_BUTTON_DOWN)
+ {
+ MSYS_Action |= MSYS_DO_X2BUTTON_DWN;
+ MSYS_CurrentButtons|=MSYS_X2_BUTTON;
+ }
+ else if(Type == X2_BUTTON_UP)
+ {
+ MSYS_Action |= MSYS_DO_X2BUTTON_UP;
+ MSYS_CurrentButtons&=(~MSYS_X2_BUTTON);
+ }
if(LeftButton)
MSYS_CurrentButtons|=MSYS_LEFT_BUTTON;
@@ -293,11 +363,20 @@ void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLE
// Call mouse region with new reason
case LEFT_BUTTON_REPEAT:
case RIGHT_BUTTON_REPEAT:
+ case MIDDLE_BUTTON_REPEAT:
+ case X1_BUTTON_REPEAT:
+ case X2_BUTTON_REPEAT:
if(Type == LEFT_BUTTON_REPEAT)
MSYS_Action |= MSYS_DO_LBUTTON_REPEAT;
else if(Type == RIGHT_BUTTON_REPEAT)
MSYS_Action |= MSYS_DO_RBUTTON_REPEAT;
+ else if(Type == MIDDLE_BUTTON_REPEAT)
+ MSYS_Action |= MSYS_DO_MBUTTON_REPEAT;
+ else if(Type == X1_BUTTON_REPEAT)
+ MSYS_Action |= MSYS_DO_X1BUTTON_REPEAT;
+ else if(Type == X2_BUTTON_REPEAT)
+ MSYS_Action |= MSYS_DO_X2BUTTON_REPEAT;
if((Xcoord != MSYS_CurrentMX) || (Ycoord != MSYS_CurrentMY))
{
@@ -308,6 +387,20 @@ void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLE
MSYS_UpdateMouseRegion();
break;
+ case MOUSE_WHEEL_UP:
+ case MOUSE_WHEEL_DOWN:
+ if(Type == MOUSE_WHEEL_UP)
+ {
+ MSYS_Action |= MSYS_DO_WHEEL_UP;
+ MSYS_Wheel++;
+ }
+ else if(Type == MOUSE_WHEEL_DOWN)
+ {
+ MSYS_Action |= MSYS_DO_WHEEL_DOWN;
+ MSYS_Wheel--;
+ }
+ MSYS_UpdateMouseRegion();
+ break;
case MOUSE_POS:
if((Xcoord != MSYS_CurrentMX) || (Ycoord != MSYS_CurrentMY) || gfRefreshUpdate )
@@ -326,6 +419,17 @@ void MSYS_SGP_Mouse_Handler_Hook(UINT16 Type,UINT16 Xcoord, UINT16 Ycoord, BOOLE
DbgMessage(TOPIC_MOUSE_SYSTEM, DBG_LEVEL_0, "ERROR -- MSYS 2 SGP Mouse Hook got bad type");
break;
}
+ // check for moved mouse
+ if((Xcoord != MSYS_CurrentMX) || (Ycoord != MSYS_CurrentMY) || gfRefreshUpdate )
+ {
+ MSYS_Action|=MSYS_DO_MOVE;
+ MSYS_CurrentMX = Xcoord;
+ MSYS_CurrentMY = Ycoord;
+ }
+
+ // update if something happened
+ if (MSYS_Action != MSYS_NO_ACTION)
+ MSYS_UpdateMouseRegion();
}
@@ -713,6 +817,8 @@ void MSYS_UpdateMouseRegion(void)
MSYS_CurrRegion->RelativeYPos = MSYS_CurrentMY - MSYS_CurrRegion->RegionTopLeftY;
MSYS_CurrRegion->ButtonState = MSYS_CurrentButtons;
+ MSYS_CurrRegion->WheelState = MSYS_Wheel;
+ MSYS_Wheel = 0;
if( MSYS_CurrRegion->uiFlags & MSYS_REGION_ENABLED &&
MSYS_CurrRegion->uiFlags & MSYS_MOVE_CALLBACK && MSYS_Action & MSYS_DO_MOVE )
@@ -1080,7 +1186,7 @@ void MSYS_DisableRegion(MOUSE_REGION *region)
//
void MSYS_SetCurrentCursor(UINT16 Cursor)
{
- TRYCATCH_RETHROW(SetCurrentCursorFromDatabase( Cursor ), "Could not set Cursor");
+ SGP_TRYCATCH_RETHROW(SetCurrentCursorFromDatabase( Cursor ), "Could not set Cursor");
}
@@ -1746,3 +1852,8 @@ MOUSE_REGION *get_next_entry_in_MSYS_RegList(MOUSE_REGION *current_region)
{
return current_region->next;
}
+
+void ResetWheelState( MOUSE_REGION *region )
+{
+ region->WheelState = 0;
+}
\ No newline at end of file
diff --git a/Standard Gaming Platform/mousesystem.h b/Standard Gaming Platform/mousesystem.h
index 89021089..87d17297 100644
--- a/Standard Gaming Platform/mousesystem.h
+++ b/Standard Gaming Platform/mousesystem.h
@@ -35,22 +35,23 @@ typedef void (*MOUSE_CALLBACK)(struct _MOUSE_REGION *,INT32); // Define MOUSE_CA
typedef void (*MOUSE_HELPTEXT_DONE_CALLBACK)( ); // the help is done callback
typedef struct _MOUSE_REGION {
- UINT16 IDNumber; // Region's ID number, set by mouse system
- INT8 PriorityLevel; // Region's Priority, set by system and/or caller
- UINT32 uiFlags; // Region's state flags
- INT16 RegionTopLeftX; // Screen area affected by this region (absolute coordinates)
- INT16 RegionTopLeftY;
- INT16 RegionBottomRightX;
- INT16 RegionBottomRightY;
- INT16 MouseXPos; // Mouse's Coordinates in absolute screen coordinates
- INT16 MouseYPos;
- INT16 RelativeXPos; // Mouse's Coordinates relative to the Top-Left corner of the region
- INT16 RelativeYPos;
- UINT16 ButtonState; // Current state of the mouse buttons
- UINT16 Cursor; // Cursor to use when mouse in this region (see flags)
+ UINT16 IDNumber; // Region's ID number, set by mouse system
+ INT8 PriorityLevel; // Region's Priority, set by system and/or caller
+ UINT32 uiFlags; // Region's state flags
+ INT16 RegionTopLeftX; // Screen area affected by this region (absolute coordinates)
+ INT16 RegionTopLeftY;
+ INT16 RegionBottomRightX;
+ INT16 RegionBottomRightY;
+ INT16 MouseXPos; // Mouse's Coordinates in absolute screen coordinates
+ INT16 MouseYPos;
+ INT16 RelativeXPos; // Mouse's Coordinates relative to the Top-Left corner of the region
+ INT16 RelativeYPos;
+ UINT16 ButtonState; // Current state of the mouse buttons
+ INT16 WheelState; // Wheel state +/-number of wheel units
+ UINT16 Cursor; // Cursor to use when mouse in this region (see flags)
MOUSE_CALLBACK MovementCallback; // Pointer to callback function if movement occured in this region
- MOUSE_CALLBACK ButtonCallback; // Pointer to callback function if button action occured in this region
- INT32 UserData[4]; // User Data, can be set to anything!
+ MOUSE_CALLBACK ButtonCallback; // Pointer to callback function if button action occured in this region
+ INT32 UserData[4]; // User Data, can be set to anything!
//Fast help vars.
INT16 FastHelpTimer; // Countdown timer for FastHelp text
@@ -70,28 +71,28 @@ typedef struct _MOUSE_REGION {
// *****************************************************************************
// Mouse Region Flags
-#define MSYS_NO_FLAGS 0x00000000
-#define MSYS_MOUSE_IN_AREA 0x00000001
-#define MSYS_SET_CURSOR 0x00000002
-#define MSYS_MOVE_CALLBACK 0x00000004
-#define MSYS_BUTTON_CALLBACK 0x00000008
-#define MSYS_REGION_EXISTS 0x00000010
-#define MSYS_SYSTEM_INIT 0x00000020
-#define MSYS_REGION_ENABLED 0x00000040
-#define MSYS_FASTHELP 0x00000080
-#define MSYS_GOT_BACKGROUND 0x00000100
-#define MSYS_HAS_BACKRECT 0x00000200
-#define MSYS_FASTHELP_RESET 0x00000400
+#define MSYS_NO_FLAGS 0x00000000
+#define MSYS_MOUSE_IN_AREA 0x00000001
+#define MSYS_SET_CURSOR 0x00000002
+#define MSYS_MOVE_CALLBACK 0x00000004
+#define MSYS_BUTTON_CALLBACK 0x00000008
+#define MSYS_REGION_EXISTS 0x00000010
+#define MSYS_SYSTEM_INIT 0x00000020
+#define MSYS_REGION_ENABLED 0x00000040
+#define MSYS_FASTHELP 0x00000080
+#define MSYS_GOT_BACKGROUND 0x00000100
+#define MSYS_HAS_BACKRECT 0x00000200
+#define MSYS_FASTHELP_RESET 0x00000400
#define MSYS_ALLOW_DISABLED_FASTHELP 0x00000800
// Mouse region IDs
-#define MSYS_ID_BASE 1
-#define MSYS_ID_MAX 0xfffffff // ( INT32 max )
+#define MSYS_ID_BASE 1
+#define MSYS_ID_MAX 0xfffffff // ( INT32 max )
#define MSYS_ID_SYSTEM 0
// Mouse region priorities
#define MSYS_PRIORITY_LOWEST 0
-#define MSYS_PRIORITY_LOW 15
+#define MSYS_PRIORITY_LOW 15
#define MSYS_PRIORITY_BASE 31
#define MSYS_PRIORITY_NORMAL 31
#define MSYS_PRIORITY_HIGH 63
@@ -100,20 +101,43 @@ typedef struct _MOUSE_REGION {
#define MSYS_PRIORITY_AUTO -1
// Mouse system defines used during updates
-#define MSYS_NO_ACTION 0
-#define MSYS_DO_MOVE 1
-#define MSYS_DO_LBUTTON_DWN 2
-#define MSYS_DO_LBUTTON_UP 4
-#define MSYS_DO_RBUTTON_DWN 8
-#define MSYS_DO_RBUTTON_UP 16
+#define MSYS_NO_ACTION 0
+#define MSYS_DO_MOVE 1
+#define MSYS_DO_LBUTTON_DWN 2
+#define MSYS_DO_LBUTTON_UP 4
+#define MSYS_DO_RBUTTON_DWN 8
+#define MSYS_DO_RBUTTON_UP 16
#define MSYS_DO_LBUTTON_REPEAT 32
#define MSYS_DO_RBUTTON_REPEAT 64
+#define MSYS_DO_MBUTTON_DWN 128
+#define MSYS_DO_MBUTTON_UP 256
+#define MSYS_DO_MBUTTON_REPEAT 512
-#define MSYS_DO_BUTTONS (MSYS_DO_LBUTTON_DWN|MSYS_DO_LBUTTON_UP|MSYS_DO_RBUTTON_DWN|MSYS_DO_RBUTTON_UP|MSYS_DO_RBUTTON_REPEAT|MSYS_DO_LBUTTON_REPEAT)
+#define MSYS_DO_X1BUTTON_DWN 1024
+#define MSYS_DO_X1BUTTON_UP 2048
+#define MSYS_DO_X1BUTTON_REPEAT 4096
+#define MSYS_DO_X2BUTTON_DWN 8192
+#define MSYS_DO_X2BUTTON_UP 16384
+#define MSYS_DO_X2BUTTON_REPEAT 32768
+
+#define MSYS_DO_WHEEL_UP 65536
+#define MSYS_DO_WHEEL_DOWN 131072
+
+#define MSYS_DO_BUTTONS (MSYS_DO_LBUTTON_DWN|MSYS_DO_LBUTTON_UP|MSYS_DO_LBUTTON_REPEAT|\
+ MSYS_DO_RBUTTON_DWN|MSYS_DO_RBUTTON_UP|MSYS_DO_RBUTTON_REPEAT|\
+ MSYS_DO_MBUTTON_DWN|MSYS_DO_MBUTTON_UP|MSYS_DO_MBUTTON_REPEAT|\
+ MSYS_DO_X1BUTTON_DWN|MSYS_DO_X1BUTTON_UP|MSYS_DO_X1BUTTON_REPEAT|\
+ MSYS_DO_X2BUTTON_DWN|MSYS_DO_X2BUTTON_UP|MSYS_DO_X2BUTTON_REPEAT)
+
+#define MSYS_DO_WHEEL (MSYS_DO_WHEEL_UP|MSYS_DO_WHEEL_DOWN)
+//#define MSYS_DO_BUTTONS (MSYS_DO_LBUTTON_DWN|MSYS_DO_LBUTTON_UP|MSYS_DO_RBUTTON_DWN|MSYS_DO_RBUTTON_UP|MSYS_DO_RBUTTON_REPEAT|MSYS_DO_LBUTTON_REPEAT)
// Mouse system button masks
-#define MSYS_LEFT_BUTTON 1
-#define MSYS_RIGHT_BUTTON 2
+#define MSYS_LEFT_BUTTON 1
+#define MSYS_RIGHT_BUTTON 2
+#define MSYS_MIDDLE_BUTTON 4
+#define MSYS_X1_BUTTON 8
+#define MSYS_X2_BUTTON 16
// Mouse system special values
#define MSYS_NO_CALLBACK NULL
@@ -127,8 +151,8 @@ typedef struct _MOUSE_REGION {
#define MSYS_CALLBACK_REASON_LBUTTON_UP 8
#define MSYS_CALLBACK_REASON_RBUTTON_DWN 16
#define MSYS_CALLBACK_REASON_RBUTTON_UP 32
-#define MSYS_CALLBACK_REASON_BUTTONS (MSYS_CALLBACK_REASON_LBUTTON_DWN|MSYS_CALLBACK_REASON_LBUTTON_UP| \
- MSYS_CALLBACK_REASON_RBUTTON_DWN|MSYS_CALLBACK_REASON_RBUTTON_UP)
+//#define MSYS_CALLBACK_REASON_BUTTONS (MSYS_CALLBACK_REASON_LBUTTON_DWN|MSYS_CALLBACK_REASON_LBUTTON_UP| \
+// MSYS_CALLBACK_REASON_RBUTTON_DWN|MSYS_CALLBACK_REASON_RBUTTON_UP)
#define MSYS_CALLBACK_REASON_LOST_MOUSE 64
#define MSYS_CALLBACK_REASON_GAIN_MOUSE 128
@@ -142,6 +166,26 @@ typedef struct _MOUSE_REGION {
//supports double clicks and single clicks, make sure the DOUBLECLICK event is checked first (rejecting
//the LBUTTON_DWN event if detected)
#define MSYS_CALLBACK_REASON_LBUTTON_DOUBLECLICK 1024
+#define MSYS_CALLBACK_REASON_MBUTTON_DWN 2048
+#define MSYS_CALLBACK_REASON_MBUTTON_UP 4096
+#define MSYS_CALLBACK_REASON_MBUTTON_REPEAT 8192
+#define MSYS_CALLBACK_REASON_WHEEL_UP 16384
+#define MSYS_CALLBACK_REASON_WHEEL_DOWN 32768
+#define MSYS_CALLBACK_REASON_X1BUTTON_DWN 65536
+#define MSYS_CALLBACK_REASON_X1BUTTON_UP 131072
+#define MSYS_CALLBACK_REASON_X1BUTTON_REPEAT 262144
+#define MSYS_CALLBACK_REASON_X2BUTTON_DWN 524288
+#define MSYS_CALLBACK_REASON_X2BUTTON_UP 1048576
+#define MSYS_CALLBACK_REASON_X2BUTTON_REPEAT 2097152
+
+
+#define MSYS_CALLBACK_REASON_BUTTONS (MSYS_CALLBACK_REASON_LBUTTON_DWN|MSYS_CALLBACK_REASON_LBUTTON_UP| \
+ MSYS_CALLBACK_REASON_RBUTTON_DWN|MSYS_CALLBACK_REASON_RBUTTON_UP| \
+ MSYS_CALLBACK_REASON_MBUTTON_DWN|MSYS_CALLBACK_REASON_MBUTTON_UP|\
+ MSYS_CALLBACK_REASON_X1BUTTON_DWN|MSYS_CALLBACK_REASON_X1BUTTON_UP|\
+ MSYS_CALLBACK_REASON_X2BUTTON_DWN|MSYS_CALLBACK_REASON_X2BUTTON_UP)
+
+#define MSYS_CALLBACK_REASON_WHEEL (MSYS_CALLBACK_REASON_WHEEL_UP|MSYS_CALLBACK_REASON_WHEEL_DOWN)
// Mouse grabbing return codes
@@ -217,7 +261,7 @@ void EnableMouseFastHelp( void );
void DisableMouseFastHelp( void );
void ResetClickedMode(void);
-
+void ResetWheelState( MOUSE_REGION *region );
#ifdef _JA2_RENDER_DIRTY
BOOLEAN SetRegionSavedRect( MOUSE_REGION *region);
diff --git a/Standard Gaming Platform/radbase.h b/Standard Gaming Platform/radbase.h
new file mode 100644
index 00000000..39a62353
--- /dev/null
+++ b/Standard Gaming Platform/radbase.h
@@ -0,0 +1,369 @@
+// __RAD16__ means 16 bit code (Win16)
+// __RAD32__ means 32 bit code (DOS, Win386, Win32s, Mac)
+
+// __RADDOS__ means DOS code (16 or 32 bit)
+// __RADWIN__ means Windows code (Win16, Win386, Win32s)
+// __RADWINEXT__ means Windows 386 extender (Win386)
+// __RADNT__ means Win32s code
+// __RADMAC__ means Macintosh
+// __RADXBOX__ means the XBox console
+// __RADNGC__ means the Nintendo GameCube
+
+// __RADX86__ means Intel x86
+// __RADMMX__ means Intel x86 MMX instructions are allowed
+// __RAD68K__ means 68K
+// __RADPPC__ means PowerPC
+
+// __RADLITTLEENDIAN__ means processor is little-endian (x86)
+// __RADBIGENDIAN__ means processor is big-endian (680x0, PPC)
+
+#ifndef __RADBASEH__
+#define __RADBASEH__
+
+#if defined(GEKKO)
+
+ #define __RADNGC__
+ #define __RAD32__
+ #define __RADPPC__
+ #define __RADBIGENDIAN__
+ #define RADINLINE inline
+
+#elif (defined(__MWERKS__) && !defined(__INTEL__)) || defined(__MRC__) || defined(THINK_C) || defined(powerc) || defined(macintosh) || defined(__powerc)
+
+ #define __RADMAC__
+ #if defined(powerc) || defined(__powerc)
+ #define __RADPPC__
+ #else
+ #define __RAD68K__
+ #endif
+
+ #define __RAD32__
+ #define __RADBIGENDIAN__
+
+ #if defined(__MWERKS__)
+ #if (defined(__cplusplus) || ! __option(only_std_keywords))
+ #define RADINLINE inline
+ #endif
+ #elif defined(__MRC__)
+ #if defined(__cplusplus)
+ #define RADINLINE inline
+ #endif
+ #endif
+
+#else
+
+ #define __RADX86__
+ #define __RADMMX__
+
+ #ifdef __MWERKS__
+ #define _WIN32
+ #endif
+
+ #ifdef __DOS__
+ #define __RADDOS__
+ #endif
+
+ #ifdef __386__
+ #define __RAD32__
+ #endif
+
+ #ifdef _Windows //For Borland
+ #ifdef __WIN32__
+ #define WIN32
+ #else
+ #define __WINDOWS__
+ #endif
+ #endif
+
+ #ifdef _WINDOWS //For MS
+ #ifndef _WIN32
+ #define __WINDOWS__
+ #endif
+ #endif
+
+ #ifdef _WIN32
+ #ifdef _XBOX
+ #define __RADXBOX__
+ #else
+ #define __RADNT__
+ #endif
+ #define __RADWIN__
+ #define __RAD32__
+ #else
+ #ifdef __NT__
+ #ifdef _XBOX
+ #define __RADXBOX__
+ #else
+ #define __RADNT__
+ #endif
+ #define __RADWIN__
+ #define __RAD32__
+ #else
+ #ifdef __WINDOWS_386__
+ #define __RADWIN__
+ #define __RADWINEXT__
+ #define __RAD32__
+ #else
+ #ifdef __WINDOWS__
+ #define __RADWIN__
+ #define __RAD16__
+ #else
+ #ifdef WIN32
+ #ifdef _XBOX
+ #define __RADXBOX__
+ #else
+ #define __RADNT__
+ #endif
+ #define __RADWIN__
+ #define __RAD32__
+ #endif
+ #endif
+ #endif
+ #endif
+ #endif
+
+ #define __RADLITTLEENDIAN__
+ #define RADINLINE __inline
+#endif
+
+#if (!defined(__RADDOS__) && !defined(__RADWIN__) && !defined(__RADMAC__) && !defined(__RADNGC__) && !defined(__RADXBOX__))
+ #error "RAD.H did not detect your platform. Define __DOS__, __WINDOWS__, WIN32, macintosh, or powerc."
+#endif
+
+#ifdef __RADFINAL__
+#define RADTODO(str) { char __str[0]=str; }
+#else
+#define RADTODO(str)
+#endif
+
+#ifdef __RADNGC__
+
+ #define RADLINK
+ #define RADEXPLINK
+ #define RADEXPFUNC RADDEFFUNC
+ #define RADASMLINK
+ #define PTR4
+
+#elif defined(__RADMAC__)
+
+ // this define is for CodeWarrior 11's stupid new libs (even though
+ // we don't use longlong's).
+
+ #define __MSL_LONGLONG_SUPPORT__
+
+ #define RADLINK
+ #define RADEXPLINK
+
+ #ifdef __CFM68K__
+ #ifdef __RADINDLL__
+ #define RADEXPFUNC RADDEFFUNC __declspec(export)
+ #else
+ #define RADEXPFUNC RADDEFFUNC __declspec(import)
+ #endif
+ #else
+ #define RADEXPFUNC RADDEFFUNC
+ #endif
+ #define RADASMLINK
+
+#else
+
+ #ifdef __RADNT__
+ #ifndef _WIN32
+ #define _WIN32
+ #endif
+ #ifndef WIN32
+ #define WIN32
+ #endif
+ #endif
+
+ #ifdef __RADWIN__
+ #ifdef __RAD32__
+ #ifdef __RADXBOX__
+
+ #define RADLINK __stdcall
+ #define RADEXPLINK __stdcall
+ #define RADEXPFUNC RADDEFFUNC
+
+ #else
+ #ifdef __RADNT__
+
+ #define RADLINK __stdcall
+ #define RADEXPLINK __stdcall
+
+ #ifdef __RADINEXE__
+ #define RADEXPFUNC RADDEFFUNC
+ #else
+ #ifndef __RADINDLL__
+ #define RADEXPFUNC RADDEFFUNC __declspec(dllimport)
+ #ifdef __BORLANDC__
+ #if __BORLANDC__<=0x460
+ #undef RADEXPFUNC
+ #define RADEXPFUNC RADDEFFUNC
+ #endif
+ #endif
+ #else
+ #define RADEXPFUNC RADDEFFUNC __declspec(dllexport)
+ #endif
+ #endif
+ #else
+ #define RADLINK __pascal
+ #define RADEXPLINK __far __pascal
+ #define RADEXPFUNC RADDEFFUNC
+ #endif
+ #endif
+ #else
+ #define RADLINK __pascal
+ #define RADEXPLINK __far __pascal __export
+ #define RADEXPFUNC RADDEFFUNC
+ #endif
+ #else
+ #define RADLINK __pascal
+ #define RADEXPLINK __pascal
+ #define RADEXPFUNC RADDEFFUNC
+ #endif
+
+ #define RADASMLINK __cdecl
+
+#endif
+
+#ifndef __RADXBOX__
+ #ifdef __RADWIN__
+ #ifndef _WINDOWS
+ #define _WINDOWS
+ #endif
+ #endif
+#endif
+
+#ifndef RADDEFFUNC
+
+#ifdef __cplusplus
+ #define RADDEFFUNC extern "C"
+ #define RADDEFSTART extern "C" {
+ #define RADDEFEND }
+ #define RADDEFINEDATA extern "C"
+ #define RADDECLAREDATA extern "C"
+ #define RADDEFAULT( val ) =val
+#else
+ #define RADDEFFUNC
+ #define RADDEFSTART
+ #define RADDEFEND
+ #define RADDEFINEDATA
+ #define RADDECLAREDATA extern
+ #define RADDEFAULT( val )
+#endif
+
+#endif
+
+#ifdef __RADNGC__
+ #define RAD_ATTRIBUTE_ALIGN(num) __attribute__ ((aligned (num)))
+#else
+ #ifdef __RADX86__
+ #define RAD_ATTRIBUTE_ALIGN(num) __declspec(align(num))
+ #else
+ #define RAD_ATTRIBUTE_ALIGN(num)
+ #endif
+#endif
+
+#ifdef __RADX86__
+ #ifdef __WATCOMC__
+ #define RAD_ALIGN_TYPE double
+ #define RAD_ALIGN_DEF 0.0
+ #else
+ #define RAD_ALIGN_TYPE double __declspec(align(8))
+ #define RAD_ALIGN_DEF 0.0
+ #endif
+#else
+ #define RAD_ALIGN_TYPE double
+ #define RAD_ALIGN_DEF 0.0
+#endif
+
+#define RAD_ALIGN_ADD_TYPE(var) RAD_ALIGN_TYPE var##align = RAD_ALIGN_DEF
+
+#define S8 signed char
+#define U8 unsigned char
+#define U32 unsigned long
+#define S32 signed long
+#define F32 float
+#define F64 double
+
+#if defined(__MWERKS__) || defined(__MRC__) || defined( GEKKO )
+ #define U64 unsigned long long
+ #define S64 signed long long
+#else
+ #define U64 unsigned __int64
+ #define S64 signed __int64
+#endif
+
+#ifdef __RAD32__
+ #define PTR4
+ #define U16 unsigned short
+ #define S16 signed short
+#else
+ #define PTR4 __far
+ #define U16 unsigned int
+ #define S16 signed int
+#endif
+
+#ifndef RAD_NO_LOWERCASE_TYPES
+
+#ifdef __RADNGC__
+
+ // Unfortunately dolphin\types.h typedefs the
+ // same types that we use.
+ // So we use the typedefs for this platform.
+
+ #include
+
+#else
+
+#ifndef u8
+ #define u8 U8
+#endif
+#ifndef s8
+ #define s8 S8
+#endif
+#ifndef u16
+ #define u16 U16
+#endif
+#ifndef s16
+ #define s16 S16
+#endif
+#ifndef u32
+ #define u32 U32
+#endif
+#ifndef s32
+ #define s32 S32
+#endif
+#ifndef u64
+ #define u64 U64
+#endif
+#ifndef s64
+ #define s64 S64
+#endif
+#ifndef f32
+ #define f32 F32
+#endif
+#ifndef f64
+ #define f64 F64
+#endif
+
+#endif
+
+#endif
+
+#ifndef radassert
+ #if defined(_DEBUG) && !defined(NDEBUG)
+ #ifdef __RADNGC__
+ #define radassert( cond ) { if (!(cond)) { OSReport("Assert: %s File: %s Line %i\n",#cond,__FILE__, __LINE__); BreakPoint(); } }
+ #else
+ #define radassert( cond ) { if (!(cond)) BreakPoint(); }
+ #endif
+ #else
+ #define radassert( cond )
+ #endif
+#endif
+
+typedef void PTR4* (RADLINK PTR4* RADMEMALLOC) (U32 bytes);
+typedef void (RADLINK PTR4* RADMEMFREE) (void PTR4* ptr);
+
+#endif
diff --git a/Standard Gaming Platform/sgp.cpp b/Standard Gaming Platform/sgp.cpp
index 5f7b3e3a..f1edaa0a 100644
--- a/Standard Gaming Platform/sgp.cpp
+++ b/Standard Gaming Platform/sgp.cpp
@@ -37,15 +37,20 @@
#include "input.h"
#include "zmouse.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_init.h"
-#include "VFS/File/vfs_file.h"
-#include "VFS/Location/vfs_slf_library.h"
-#include "VFS/Tools/Log.h"
-#include "VFS/Tools/ParserTools.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "sgp_logger.h"
#include "Text.h"
-#include "VFS/os_functions.h"
-#include "VFS/vfs_settings.h"
+#include "LocalizedStrings.h"
+#include "ExportStrings.h"
+#include "ImportStrings.h"
#define USE_CONSOLE 0
@@ -79,17 +84,53 @@ static std::list vfs_config_ini;
static bool s_DebugKeyboardInput = false;
static vfs::Path s_CodePage;
-void SHOWEXCEPTION(CBasicException& ex)
+static vfs::FileLogger *vfslog = NULL;
+
+void SHOWEXCEPTION(sgp::Exception& ex)
{
try {
_ExceptionMessage(ex);
}
- catch(CBasicException &ex2) {
- logException(ex2);
+ catch(sgp::Exception &ex2) {
+ SGP_ERROR(ex2.what());
exit(0);
}
}
+void SHOWEXCEPTION(vfs::Exception& ex)
+{
+ try {
+ _ExceptionMessage(ex);
+ }
+ catch(vfs::Exception &ex2) {
+ SGP_ERROR(ex2.what());
+ exit(0);
+ }
+}
+
+#define HANDLE_FATAL_ERROR \
+ catch(sgp::Exception &ex){ \
+ SGP_ERROR(ex.what()); \
+ FatalError((const STR8)ex.what()); \
+ exit(0); } \
+ catch(vfs::Exception &ex){ \
+ SGP_ERROR(ex.what()); \
+ FatalError((const STR8)ex.getExceptionString().utf8().c_str()); \
+ exit(0); } \
+ catch(std::exception &ex){ \
+ SGP_ERROR(ex.what()); \
+ FatalError((const STR8)ex.what()); \
+ exit(0); } \
+ catch(const char* msg){ \
+ SGP_ERROR(msg); \
+ FatalError((const STR8)msg); \
+ exit(0); } \
+ catch(...){ \
+ SGP_ERROR("Caught undefined exception"); \
+ FatalError("Caught undefined exception"); \
+ exit(0); }
+
+
extern UINT32 MemDebugCounter;
#ifdef JA2
extern BOOLEAN gfPauseDueToPlayerGamePause;
@@ -159,6 +200,15 @@ BOOLEAN gfIgnoreMessages=FALSE;
// GLOBAL VARIBLE, SET TO DEFAULT BUT CAN BE CHANGED BY THE GAME IF INIT FILE READ
UINT8 gbPixelDepth = PIXEL_DEPTH;
+bool s_bExportStrings = false;
+extern bool g_bUseXML_Strings;// = false;
+bool g_bUseXML_Structures = false;
+bool g_bUseXML_Tilesets = false;
+
+#ifdef USE_VFS
+static vfs::Path sp_force_load_jsd_xml_file;
+#endif
+
INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LPARAM lParam)
{
static BOOLEAN fRestore = FALSE;
@@ -174,11 +224,14 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP
return(DefWindowProc(hWindow, Message, wParam, lParam));
// ATE: This is for older win95 or NT 3.51 to get MOUSE_WHEEL Messages
- if ( Message == guiMouseWheelMsg )
- {
- QueueEvent(MOUSE_WHEEL, wParam, lParam);
- return( 0L );
- }
+ //if ( Message == guiMouseWheelMsg )
+ //{
+ // QueueEvent(MOUSE_WHEEL, wParam, lParam);
+ // return( 0L );
+ //}
+
+
+
switch(Message)
{
@@ -186,11 +239,11 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP
PostQuitMessage(0);
break;
/*dnl kick this out, because in input.sgp MouseHandler() hook has priority so it will process same event twice, someone force MouseHandler() hook to always return unhandled events status so what ever mouse event you process in WindowProcedure() be aware that this event is already occur in MouseHandler() (mouse clicks, move etc.) Probably this is done because when you lost focus even if you click back on window region this will not restore them, so need condition in MouseHandler to restore window focus
- case WM_MOUSEWHEEL:
- {
- QueueEvent(MOUSE_WHEEL, wParam, lParam);
- break;
- }
+// case WM_MOUSEWHEEL:
+// {
+// QueueEvent(MOUSE_WHEEL, wParam, lParam);
+// break;
+// }
*/
#ifdef JA2
case WM_MOVE:
@@ -526,9 +579,9 @@ INT32 FAR PASCAL WindowProcedure(HWND hWindow, UINT16 Message, WPARAM wParam, LP
#ifdef USE_CODE_PAGE
if(s_DebugKeyboardInput)
{
- static CLog& debugKeys = *CLog::Create(L"DebugKeys.txt");
+ static vfs::Log& debugKeys = *vfs::Log::Create(L"DebugKeys.txt");
static int input_counter = 1;
- debugKeys << (input_counter++) << " : " << (int)wParam << CLog::endl;
+ debugKeys << (input_counter++) << " : " << (int)wParam << vfs::Log::endl;
}
#endif // USE_CODE_PAGE
KeyDown(wParam, lParam);
@@ -594,32 +647,7 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
#endif
// Second, read in settings
- std::list exlist;
- try
- {
- GetRuntimeSettings( );
- }
- catch(CBasicException& ex)
- {
- logException(ex);
- // nothing is set up, no vfs, no video manager
- // regular error processing wouldn't work here
- // set default values and continue as if nothing has happened
- iResolution = 1;
-
- gbPixelDepth = PIXEL_DEPTH;
-
- SCREEN_WIDTH = 800;
- SCREEN_HEIGHT = 600;
-
- iScreenWidthOffset = (SCREEN_WIDTH - 640) / 2;
- iScreenHeightOffset = (SCREEN_HEIGHT - 480) / 2;
-
- iScreenMode = 1;
- iPlayIntro = 0;
- // rethrow exception after full setup
- exlist.push_back(ex);
- }
+ GetRuntimeSettings( );
// Initialize the Debug Manager - success doesn't matter
InitializeDebugManager();
@@ -698,13 +726,14 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
//InitializeJA2TimerID();
#ifdef USE_VFS
- vfs::Path exe_dir, exe_file;
- os::getExecutablePath(exe_dir, exe_file);
+ //vfs::Path exe_dir, exe_file;
+ //os::getExecutablePath(exe_dir, exe_file);
- // set current directory to exe's directory
- os::setCurrectDirectory(exe_dir);
+ //// set current directory to exe's directory
+ //os::setCurrectDirectory(exe_dir);
+
+ SGP_THROW_IFFALSE( vfs_init::initVirtualFileSystem( vfs_config_ini ), L"Initializing Virtual File System failed");
- THROWIFFALSE( initVirtualFileSystem( vfs_config_ini ), L"Initializing Virtual File System failed");
s_VfsIsInitialized = true;
@@ -713,6 +742,19 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
getVFS()->getVirtualLocation(vfs::Path(pMessageStrings[MSG_SAVEDIRECTORY]+3),true)->setIsExclusive(true);
getVFS()->getVirtualLocation(vfs::Path(pMessageStrings[MSG_MPSAVEDIRECTORY]+3),true)->setIsExclusive(true);
+ if(!sp_force_load_jsd_xml_file.empty())
+ {
+ try
+ {
+ std::string filename = vfs::String::as_utf8(sp_force_load_jsd_xml_file());
+ STRUCTURE_FILE_REF *pStructureFileRef = LoadStructureFile((STR8)filename.c_str());
+ }
+ catch(std::exception &ex)
+ {
+ SGP_RETHROW(_BS(L"failed to load and/or process file : ") << sp_force_load_jsd_xml_file << _BS::wget, ex);
+ }
+ }
+
#ifdef USE_CODE_PAGE
charSet::InitializeCharSets();
@@ -723,11 +765,11 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
CodePageReader cpr;
cpr.ReadCodePage(s_CodePage);
}
- catch(CBasicException& ex)
+ catch(std::exception& ex)
{
std::wstringstream wss;
wss << L"Could not process codepage file \"" << s_CodePage() << L"\"";
- RETHROWEXCEPTION(wss.str().c_str(), &ex);
+ SGP_RETHROW(wss.str().c_str(), ex);
}
}
#endif // USE_CODE_PAGE
@@ -762,6 +804,16 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
gCustomDataCat.NewCat(std::string(CurrentDir) + '\\' + customDataPath);
}
#endif
+
+ if(g_bUseXML_Strings)
+ {
+ if(s_bExportStrings)
+ {
+ Loc::ExportStrings();
+ }
+ Loc::ImportStrings();
+ }
+
//#ifdef JA2
InitJA2SplashScreen();
//#endif
@@ -813,10 +865,6 @@ BOOLEAN InitializeStandardGamingPlatform(HINSTANCE hInstance, int sCommandShow)
gfGameInitialized = TRUE;
- if(!exlist.empty())
- {
- RETHROWEXCEPTION(L"Error during reading runtime settings", &exlist.front());
- }
return TRUE;
}
@@ -893,17 +941,19 @@ void ShutdownStandardGamingPlatform(void)
ShutdownDebugManager();
- CLog::flushFinally();
+ sgp::Logger::instance().shutdown();
+ vfs::Log::flushDeleteAll();
+ if(vfslog) delete vfslog;
vfs::CVirtualFileSystem::shutdownVFS();
- CFileAllocator::clear();
+ vfs::ObjectAllocator::clear();
}
#ifdef USE_VFS
#include "MPJoinScreen.h"
-utf8string getGameID()
+vfs::String getGameID()
{
- static utf8string _id;
+ static vfs::String _id;
static bool has_id = false;
if(!has_id)
{
@@ -914,6 +964,58 @@ utf8string getGameID()
}
#endif
+#include "debug_util.h"
+#include
+
+class VfsLogAdapter : public vfs::Aspects::ILogger
+{
+public:
+ VfsLogAdapter(sgp::Logger_ID ID, bool stacktrace = false) : _id(ID), _trace(stacktrace) {};
+
+ virtual void Msg(const wchar_t* msg)
+ {
+ SGP_LOG(_id, msg);
+ if(_trace)
+ {
+ sgp::dumpStackTrace(msg);
+ }
+ }
+ virtual void Msg(const char* msg)
+ {
+ SGP_LOG(_id, msg);
+ if(_trace)
+ {
+ sgp::dumpStackTrace(msg);
+ }
+ }
+private:
+ sgp::Logger_ID _id;
+ bool _trace;
+};
+
+//#include
+//#include "sgp_mutex.h"
+//class VfsMutex : public vfs::Aspects::IMutex
+//{
+//public:
+// virtual void lock(){
+// _mutex.lock();
+// }
+// virtual void unlock(){
+// _mutex.unlock();
+// }
+//private:
+// sgp::Mutex _mutex;
+//};
+//class VfsMutexFactory : public vfs::Aspects::IMutexFactory
+//{
+//public:
+// virtual vfs::Aspects::IMutex* createMutex()
+// {
+// return new VfsMutex();
+// }
+//};
+
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCommandLine, int sCommandShow)
{
@@ -951,6 +1053,22 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
HWND hPrevInstanceWindow;
UINT32 uiTimer = 0;
+#ifdef USE_VFS
+ vfs::Log::setSharedString( getGameID() );
+#endif
+ //if(!vfs::Aspects::getMutexFactory())
+ //{
+ // vfs::Aspects::setMutexFactory( new VfsMutexFactory() );
+ //}
+ sgp::Logger_ID VFS_LOG = sgp::Logger::instance().createLogger();
+
+ sgp::Logger::instance().connectFile(VFS_LOG, L"vfs.log", false, sgp::Logger::FLUSH_ON_DELETE);
+
+ VfsLogAdapter* vfslog = new VfsLogAdapter(VFS_LOG, false);
+ VfsLogAdapter* vfslog_error = new VfsLogAdapter(VFS_LOG, true);
+
+ vfs::Aspects::setLogger(vfslog, vfslog, vfslog_error, NULL /* vfslog */);
+
// Make sure that only one instance of this application is running at once
// // Look for prev instance by searching for the window
hPrevInstanceWindow = FindWindowEx( NULL, NULL, APPLICATION_NAME, APPLICATION_NAME );
@@ -967,10 +1085,6 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
// Initialize random number generator
InitializeRandom(); // no Shutdown
-#ifdef USE_VFS
- CLog::setSharedString( getGameID() );
-#endif
-
//rain
//NSLoadSettings();
//NSSaveSettings();
@@ -1029,9 +1143,9 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
// ShowCursor(FALSE);
#ifdef USE_VFS
- vfs::Path exe_dir, exe_file;
- os::getExecutablePath(exe_dir, exe_file);
- os::setCurrectDirectory(exe_dir);
+ //vfs::Path exe_dir, exe_file;
+ //os::getExecutablePath(exe_dir, exe_file);
+ //os::setCurrectDirectory(exe_dir);
#else
STRING512 sExecutableDir;
GetExecutableDirectory( sExecutableDir );
@@ -1046,65 +1160,11 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
return 0;
}
}
- catch(CBasicException &ex)
- {
- if(!s_VfsIsInitialized)
- {
- vfs::CFile* fonts = new vfs::CFile("Data/Fonts.slf");
- vfs::CSLFLibrary* slfLib = new vfs::CSLFLibrary(vfs::tReadableFile::cast(fonts),"");
- if(slfLib->init())
- {
- getVFS()->addLocation(slfLib,"doesn't matter");
- }
- // fonts not initialized
- FontTranslationTable *pFontTable = CreateEnglishTransTable( );
- if ( pFontTable == NULL )
- {
- return( FALSE );
- }
+ HANDLE_FATAL_ERROR;
- // Initialize Font Manager
- FastDebugMsg("Initializing the Font Manager");
- // Init the manager and copy the TransTable stuff into it.
- if ( !InitializeFontManager( 8, pFontTable ) )
- {
- FastDebugMsg("FAILED : Initializing Font Manager");
- return FALSE;
- }
- // Don't need this thing anymore, so get rid of it (but don't de-alloc the contents)
- MemFree( pFontTable );
- if ( !InitializeFonts( ) )
- {
- // Send debug message and quit
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "COULD NOT INUT FONT SYSTEM...");
- return( ERROR_SCREEN );
- }
- }
- gfProgramIsRunning = 1;
- logException(ex);
- SHOWEXCEPTION(ex);
- }
- catch(std::exception &ex)
- {
- gfProgramIsRunning = 1;
- CBasicException nex(ex.what(),_FUNCTION_FORMAT_,__LINE__,__FILE__);
- logException(nex);
- SHOWEXCEPTION(nex);
- }
- catch(const char* msg)
- {
- gfProgramIsRunning = 1;
- CBasicException ex(msg,_FUNCTION_FORMAT_,__LINE__,__FILE__);
- logException(ex);
- SHOWEXCEPTION(ex);
- }
- catch(...)
- {
- gfProgramIsRunning = 1;
- CBasicException ex("Caught undefined exception", _FUNCTION_FORMAT_, __LINE__, __FILE__);
- logException( ex );
- SHOWEXCEPTION(ex);
- }
+#ifdef USE_VFS
+ vfs::Log::flushReleaseAll();
+#endif
#ifdef LUACONSOLE
if (1==iScreenMode)
@@ -1114,9 +1174,13 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
#endif
#ifdef JA2
- #ifdef ENGLISH
+# ifdef ENGLISH
+ try
+ {
SetIntroType( INTRO_SPLASH );
- #endif
+ }
+ HANDLE_FATAL_ERROR;
+# endif
#endif
gfApplicationActive = TRUE;
@@ -1146,27 +1210,32 @@ int PASCAL HandledWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pC
DispatchMessage(&Message);
}
}
- catch(CBasicException &ex)
+ catch(sgp::Exception &ex)
{
- logException(ex);
+ SGP_ERROR(ex.what());
+ SHOWEXCEPTION(ex);
+ }
+ catch(vfs::Exception &ex)
+ {
+ SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
catch(std::exception &ex)
{
- CBasicException nex(ex.what(),_FUNCTION_FORMAT_,__LINE__,__FILE__);
- logException(nex);
+ sgp::Exception nex(ex.what());
+ SGP_ERROR(nex.what());
SHOWEXCEPTION(nex);
}
catch(const char* msg)
{
- CBasicException ex(msg,_FUNCTION_FORMAT_,__LINE__,__FILE__);
- logException(ex);
+ sgp::Exception ex(msg);
+ SGP_ERROR(ex.what());
SHOWEXCEPTION(ex);
}
catch(...)
{
- CBasicException ex("Caught undefined exception", _FUNCTION_FORMAT_, __LINE__, __FILE__);
- logException( ex );
+ sgp::Exception ex("Caught undefined exception");
+ SGP_ERROR( ex.what() );
SHOWEXCEPTION(ex);
}
@@ -1262,7 +1331,7 @@ void GetRuntimeSettings( )
strcat(INIFile, "\\Ja2.ini");
#else
- CPropertyContainer oProps;
+ vfs::PropertyContainer oProps;
oProps.initFromIniFile("Ja2.ini");
#endif
iResolution = -1;
@@ -1272,24 +1341,24 @@ void GetRuntimeSettings( )
iResolution = atoi(zScreenResolution);
}
#else
- utf8string loc = oProps.getStringProperty("Ja2 Settings", L"LOCALE");
+ vfs::String loc = oProps.getStringProperty("Ja2 Settings", L"LOCALE");
if(!loc.empty())
{
- THROWIFFALSE( setlocale(LC_ALL, loc.utf8().c_str()), BuildString().add(L"invalid locale : ").add(loc).get());
+ SGP_THROW_IFFALSE( setlocale(LC_ALL, loc.utf8().c_str()), _BS(L"invalid locale : ") << loc << _BS::wget );
}
iResolution = (int)oProps.getIntProperty(L"Ja2 Settings", L"SCREEN_RESOLUTION", -1);
vfs::Settings::setUseUnicode( !oProps.getBoolProperty(L"Ja2 Settings", L"VFS_NO_UNICODE", false) );
- std::list ini_list;
+ std::list ini_list;
- utf8string vfs_config_file;
+ vfs::String vfs_config_file;
if(oProps.getStringProperty(L"Ja2 Settings", L"VFS_CONFIG", vfs_config_file))
{
- CPropertyContainer temp_cont;
+ vfs::PropertyContainer temp_cont;
temp_cont.initFromIniFile(vfs_config_file);
- utf8string temp_str;
+ vfs::String temp_str;
if(temp_cont.getStringProperty(L"vfs_config", L"VFS_CONFIG_INI", temp_str))
{
oProps.setStringProperty(L"Ja2 Settings", L"VFS_CONFIG_INI", temp_str);
@@ -1298,7 +1367,7 @@ void GetRuntimeSettings( )
if(oProps.getStringListProperty(L"Ja2 Settings", L"VFS_CONFIG_INI", ini_list, L""))
{
vfs_config_ini.clear();
- for(std::list::iterator it = ini_list.begin(); it != ini_list.end(); ++it)
+ for(std::list::iterator it = ini_list.begin(); it != ini_list.end(); ++it)
{
vfs_config_ini.push_back(*it);
}
@@ -1307,6 +1376,25 @@ void GetRuntimeSettings( )
{
vfs_config_ini.push_back(L"vfs_config.ini");
}
+ std::list merge_list;
+ if(oProps.getStringListProperty(L"Ja2 Settings", L"MERGE_INI_FILES", merge_list, L""))
+ {
+ for(std::list::iterator it = merge_list.begin(); it != merge_list.end(); ++it)
+ {
+ CIniReader::RegisterFileForMerging(*it);
+ }
+ }
+#endif
+
+#ifdef USE_VFS
+ extern bool g_bUsePngItemImages;
+ g_bUsePngItemImages = oProps.getBoolProperty(L"Ja2 Settings", L"USE_PNG_ITEM_IMAGES", false);
+ g_bUseXML_Structures = oProps.getBoolProperty(L"Ja2 Settings", L"USE_XML_STRUCTURES", false);
+ g_bUseXML_Tilesets = oProps.getBoolProperty(L"Ja2 Settings", L"USE_XML_TILESETS", false);
+ g_bUseXML_Strings = oProps.getBoolProperty(L"Ja2 Settings", L"USE_XML_STRINGS", false);
+ s_bExportStrings = oProps.getBoolProperty(L"Ja2 Settings", L"EXPORT_STRINGS", false);
+
+ sp_force_load_jsd_xml_file = oProps.getStringProperty(L"Ja2 Settings", L"FORCE_LOAD_JSD_XML_FILE", L"");
#endif
#ifdef JA2EDITOR
@@ -1320,11 +1408,6 @@ void GetRuntimeSettings( )
#endif
#endif
-#ifdef USE_VFS
- extern bool g_bUsePngItemImages;
- g_bUsePngItemImages = oProps.getBoolProperty(L"Ja2 Settings", "USE_PNG_ITEM_IMAGES", false);
-#endif
-
int iResX;
int iResY;
diff --git a/Standard Gaming Platform/sgp_auto_memory.h b/Standard Gaming Platform/sgp_auto_memory.h
new file mode 100644
index 00000000..08c63495
--- /dev/null
+++ b/Standard Gaming Platform/sgp_auto_memory.h
@@ -0,0 +1,113 @@
+#ifndef _SGP_AUTO_MEMORY_H_
+#define _SGP_AUTO_MEMORY_H_
+
+namespace sgp
+{
+ /************************************************************/
+
+ template
+ class TAutoArray
+ {
+ public:
+ T& operator[](size_t index)
+ {
+ return _array[index];
+ }
+
+ T* operator()()
+ {
+ return _array;
+ }
+ T* operator->()
+ {
+ return _array;
+ }
+ T& operator*()
+ {
+ return *_array;
+ }
+ bool operator!()
+ {
+ // NULL == _array
+ return !_array;
+ }
+
+ T* release()
+ {
+ T* tmp = _array;
+ _array = NULL;
+ return tmp;
+ }
+ protected:
+ T* _array;
+ };
+
+ /************************************************************/
+
+ template
+ class AutoArray : public TAutoArray
+ {
+ public:
+ AutoArray(size_t size)
+ {
+ _array = new T[size];
+ }
+ ~AutoArray()
+ {
+ if(_array)
+ {
+ delete[] _array;
+ }
+ }
+ };
+
+ /************************************************************/
+
+ template
+ class AutoCArray : public TAutoArray
+ {
+ public:
+ AutoCArray(size_t size = 1, size_t sizeof_elem=1)
+ {
+ _array = (T*)Alloc( size * sizeof_elem );
+ }
+ ~AutoCArray()
+ {
+ if(_array)
+ {
+ Dealloc(_array);
+ }
+ }
+ };
+
+ /************************************************************/
+
+} // namespace sgp
+
+#ifdef JA2
+
+#include "MemMan.h"
+
+namespace sgp
+{
+ template
+ class AutoMMArray : public sgp::TAutoArray
+ {
+ public:
+ AutoMMArray(size_t size, size_t sizeof_elem=1)
+ {
+ _array = (T*)MemAlloc( size * sizeof_elem );
+ }
+ ~AutoMMArray()
+ {
+ if(_array)
+ {
+ MemFree(_array);
+ }
+ }
+ };
+}
+
+#endif
+
+#endif // _SGP_AUTO_MEMORY_H_
diff --git a/Standard Gaming Platform/sgp_logger.cpp b/Standard Gaming Platform/sgp_logger.cpp
new file mode 100644
index 00000000..54772eba
--- /dev/null
+++ b/Standard Gaming Platform/sgp_logger.cpp
@@ -0,0 +1,270 @@
+#include "sgp_logger.h"
+#include "Debug.h"
+#include "Font Control.h"
+
+#include "Message.h"
+#include
+
+static inline void flush_screen(std::wstringstream& stream)
+{
+ std::wstring str = stream.str();
+ if(!str.empty())
+ {
+ ScreenMsg(MSG_FONT_YELLOW, 255, (STR16)str.c_str());
+ }
+}
+
+int sgp::Logger::_next_log_id = -1;
+
+#if defined(USE_VFS)
+ //std::vector sgp::Logger::_logs;
+ std::vector sgp::Logger::_logs;
+#endif
+
+sgp::Logger::Logger()
+{
+#if defined(USE_VFS)
+ connectFile(this->createLogger(), L"game_log.log", false, sgp::Logger::FLUSH_ON_ENDL);
+#endif
+}
+
+sgp::Logger::~Logger()
+{
+}
+
+sgp::Logger& sgp::Logger::instance()
+{
+ static Logger _logger;
+ return _logger;
+}
+
+bool sgp::Logger::init()
+{
+ return true;
+}
+
+bool sgp::Logger::shutdown()
+{
+ for(::size_t i=0; i < _logs.size(); ++i)
+ {
+#if defined(USE_VFS)
+ disconnectFile(i);
+#endif
+ disconnectStream(i);
+ disconnectScreen(i);
+ }
+ return true;
+}
+
+sgp::Logger_ID sgp::Logger::createLogger()
+{
+ _logs.push_back(sgp::Logger::LogData());
+ Logger_ID id = _logs.size() - 1;
+ _logs[id].timer.startTimer();
+ return id;
+}
+
+sgp::Logger::FlushMode sgp::Logger::flushMode(sgp::Logger_ID id)
+{
+ sgp::Logger::FlushMode fmode = (sgp::Logger::FlushMode)-1;
+ if(id >= 0 && id < _logs.size())
+ {
+ if(_logs[id].file)
+ {
+ vfs::Log::EFlushMode fm = _logs[id].file->flushMode();
+
+ if (fm == vfs::Log::FLUSH_ON_DELETE) fmode = sgp::Logger::FLUSH_ON_DELETE;
+ else if(fm == vfs::Log::FLUSH_IMMEDIATELY) fmode = sgp::Logger::FLUSH_IMMIDIATELY;
+ else if(fm == vfs::Log::FLUSH_BUFFER) fmode = sgp::Logger::FLUSH_FULL_BUFFER;
+ else if(fm == vfs::Log::FLUSH_ON_ENDL) fmode = sgp::Logger::FLUSH_ON_ENDL;
+ }
+ }
+ return fmode;
+}
+
+void sgp::Logger::flushMode(sgp::Logger_ID id, sgp::Logger::FlushMode fmode)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ vfs::Log::EFlushMode fm;
+ if (fmode == sgp::Logger::FLUSH_ON_DELETE) fm = vfs::Log::FLUSH_ON_DELETE;
+ else if(fmode == sgp::Logger::FLUSH_IMMIDIATELY) fm = vfs::Log::FLUSH_IMMEDIATELY;
+ else if(fmode == sgp::Logger::FLUSH_FULL_BUFFER) fm = vfs::Log::FLUSH_BUFFER;
+ else if(fmode == sgp::Logger::FLUSH_ON_ENDL) fm = vfs::Log::FLUSH_ON_ENDL;
+ else fm = vfs::Log::FLUSH_IMMEDIATELY;
+
+ if(_logs[id].file)
+ {
+ _logs[id].file->releaseFile();
+ _logs[id].file->flushMode(fm);
+ }
+ }
+}
+
+
+#if defined(USE_VFS)
+void sgp::Logger::connectFile(sgp::Logger_ID id, vfs::Path const& log_file, bool append, FlushMode fmode)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ vfs::Log::EFlushMode fm;
+ if (fmode == sgp::Logger::FLUSH_ON_DELETE) fm = vfs::Log::FLUSH_ON_DELETE;
+ else if(fmode == sgp::Logger::FLUSH_IMMIDIATELY) fm = vfs::Log::FLUSH_IMMEDIATELY;
+ else if(fmode == sgp::Logger::FLUSH_FULL_BUFFER) fm = vfs::Log::FLUSH_BUFFER;
+ else if(fmode == sgp::Logger::FLUSH_ON_ENDL) fm = vfs::Log::FLUSH_ON_ENDL;
+ else fm = vfs::Log::FLUSH_IMMEDIATELY;
+
+ _logs[id].file = vfs::Log::create(log_file,append,fm);
+ }
+}
+void sgp::Logger::disconnectFile(sgp::Logger_ID id)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ if(_logs[id].file)
+ {
+ _logs[id].file->destroy();
+ _logs[id].file = NULL;
+ }
+ }
+}
+#endif
+
+void sgp::Logger::connectStream(sgp::Logger_ID id, std::ostream& stream)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ _logs[id].stream = &std::wcout;
+ }
+}
+void sgp::Logger::disconnectStream(sgp::Logger_ID id)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ _logs[id].stream = NULL;
+ }
+}
+
+void sgp::Logger::connectScreen(sgp::Logger_ID id)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ if(_logs[id].screen)
+ {
+ disconnectScreen(id);
+ }
+ _logs[id].screen = new std::wstringstream;
+ }
+}
+void sgp::Logger::disconnectScreen(sgp::Logger_ID id)
+{
+ if(id >= 0 && id < _logs.size())
+ {
+ if(_logs[id].screen)
+ {
+ flush_screen(*_logs[id].screen);
+ delete _logs[id].screen;
+ _logs[id].screen = NULL;
+ }
+ }
+}
+
+
+//#if defined(USE_VFS)
+//int sgp::Logger::createLogger(vfs::Path const& log_file, bool append, FlushMode fp)
+//{
+// vfs::Log::EFlushMode fm;
+// if(fp == sgp::Logger::FLUSH_ON_DELETE) fm = vfs::Log::FLUSH_ON_DELETE;
+// else if(fp == sgp::Logger::FLUSH_IMMIDIATELY) fm = vfs::Log::FLUSH_IMMEDIATELY;
+// else if(fp == sgp::Logger::FLUSH_FULL_BUFFER) fm = vfs::Log::FLUSH_BUFFER;
+// else if(fp == sgp::Logger::FLUSH_ON_ENDL) fm = vfs::Log::FLUSH_ON_ENDL;
+// else fm = vfs::Log::FLUSH_IMMEDIATELY;
+//
+// _logs.push_back(STimeLog());
+// _next_log_id++;
+// _logs[_next_log_id]._log = vfs::Log::create(log_file,append,fm);
+// _logs[_next_log_id]._timer.startTimer();
+// return _next_log_id;
+//}
+//#endif
+
+sgp::Logger::LogInstance sgp::Logger::logger(sgp::Logger_ID id)
+{
+ if(id < _logs.size())
+ {
+#if defined(USE_VFS)
+ std::wstringstream tmp;
+ tmp << L"[" << _logs[id].timer.running() << L"] : ";
+ std::wstring str(tmp.str());
+
+ LogData& ld = _logs[id];
+ if(ld.file) {
+ (*ld.file).lock();
+ (*ld.file) << str;
+ }
+ if(ld.stream) {
+ (*ld.stream) << str;
+ }
+ if(ld.screen) {
+ (*ld.screen) << str;
+ }
+#endif
+ return sgp::Logger::LogInstance(&ld);
+ }
+ SGP_THROW(L"Unknown log id");
+}
+
+template <>
+sgp::Logger::LogInstance& sgp::Logger::LogInstance::operator<< (sgp::_flush const& e)
+{
+ if(_log.file)
+ {
+#if defined(USE_VFS)
+ (*_log.file).flush();
+ (*_log.file).unlock();
+#endif
+ }
+ if(_log.stream)
+ {
+ (*_log.stream).flush();
+ }
+ if(_log.screen)
+ {
+ flush_screen(*_log.screen);
+ }
+ return *this;
+}
+
+template <>
+sgp::Logger::LogInstance& sgp::Logger::LogInstance::operator<< (sgp::_endl const& e)
+{
+ if(_log.file)
+ {
+#if defined(USE_VFS)
+ (*_log.file) << vfs::Log::endl;
+ if(_log.file->flushMode() == vfs::Log::FLUSH_ON_ENDL)
+ {
+ (*_log.file).flush();
+ }
+ (*_log.file).unlock();
+#endif
+ }
+ if(_log.stream)
+ {
+ (*_log.stream) << std::endl;
+ (*_log.stream).flush();
+ }
+ if(_log.screen)
+ {
+ flush_screen(*_log.screen);
+ }
+ return *this;
+}
+template <>
+sgp::Logger::LogInstance& sgp::Logger::LogInstance::operator<< (sgp::_lock const& l)
+{
+#if defined(USE_VFS)
+ _log.file->lock();
+#endif
+ return *this;
+}
diff --git a/Standard Gaming Platform/sgp_logger.h b/Standard Gaming Platform/sgp_logger.h
new file mode 100644
index 00000000..d93c7cd6
--- /dev/null
+++ b/Standard Gaming Platform/sgp_logger.h
@@ -0,0 +1,149 @@
+#ifndef SGP_LOGGER_H
+#define SGP_LOGGER_H
+
+#include
+#if defined(USE_VFS)
+# include
+# include
+# include
+#else
+# include
+#endif
+
+namespace sgp
+{
+ typedef unsigned int Logger_ID;
+
+ enum _endl{endl};
+ enum _lock{lock};
+ enum _flush{flush};
+
+ class Logger
+ {
+ struct LogData
+ {
+#if defined(USE_VFS)
+ LogData() : file(NULL), stream(NULL), screen(NULL) {};
+ vfs::HPTimer timer;
+ vfs::Log* file;
+#else
+ LogData() : stream(NULL), screen(NULL) {};
+#endif
+ std::wostream* stream;
+ std::wstringstream* screen;
+ };
+ public:
+
+ enum FlushMode
+ {
+ FLUSH_ON_DELETE,
+ FLUSH_ON_ENDL,
+ FLUSH_ON_FLUSH,
+ FLUSH_FULL_BUFFER,
+ FLUSH_IMMIDIATELY,
+ };
+
+ // need to lock/unlock on every logging operation, as they can be called from multiple threads
+ class LogInstance
+ {
+ friend class Logger;
+ LogInstance(LogData* ld) : _log(*ld) {};
+ public:
+ template
+ LogInstance& operator<<(T const& t){
+ if(_log.stream) (*_log.stream) << t;
+ if(_log.screen) (*_log.screen) << t;
+#if defined(USE_VFS)
+ if(_log.file ) (*_log.file) << t;
+#endif
+ return *this;
+ }
+ private:
+ LogData& _log;
+ };
+
+
+ static Logger& instance();
+
+ bool init();
+ bool shutdown();
+
+ LogInstance logger(Logger_ID id);
+
+ Logger_ID createLogger();
+
+#if defined(USE_VFS)
+ void connectFile(Logger_ID id, vfs::Path const& log_file, bool append, FlushMode fp);
+ void disconnectFile(Logger_ID id);
+#endif
+ void connectStream(Logger_ID id, std::ostream& stream);
+ void disconnectStream(Logger_ID id);
+
+ void connectScreen(Logger_ID id);
+ void disconnectScreen(Logger_ID id);
+
+ void flushMode(Logger_ID id, FlushMode fmode);
+ FlushMode flushMode(Logger_ID id);
+ private:
+ Logger();
+ ~Logger();
+
+ private:
+ static int _next_log_id;
+
+ static std::vector _logs;
+ };
+
+ template <>
+ Logger::LogInstance& Logger::LogInstance::operator<< <_endl>(_endl const& e);
+ template <>
+ Logger::LogInstance& Logger::LogInstance::operator<< <_lock>(_lock const& l);
+ template <>
+ Logger::LogInstance& Logger::LogInstance::operator<< <_flush>(_flush const& f);
+}
+
+#if defined(USE_VFS)
+inline sgp::Logger::LogInstance SGP_LOG(sgp::Logger_ID id, vfs::String const& str){
+#else
+inline sgp::Logger::LogInstance SGP_LOG(int id, const char* str){
+#endif
+ return sgp::Logger::instance().logger(id) << (str) << sgp::endl;
+}
+inline sgp::Logger::LogInstance SGP_LOG(sgp::Logger_ID id){
+ return sgp::Logger::instance().logger(id);
+}
+
+#if defined(USE_VFS)
+inline sgp::Logger::LogInstance SGP_INFO(vfs::String const& str){
+#else
+inline sgp::Logger::LogInstance SGP_INFO(const char* str){
+#endif
+ return sgp::Logger::instance().logger(0) << str << sgp::endl;
+}
+inline sgp::Logger::LogInstance SGP_INFO(){
+ return sgp::Logger::instance().logger(0);
+}
+
+#if defined(USE_VFS)
+inline sgp::Logger::LogInstance SGP_WARNING(vfs::String const& str){
+#else
+inline sgp::Logger::LogInstance SGP_WARNING(const char* str){
+#endif
+ return sgp::Logger::instance().logger(0) << "WARNING : " << str << sgp::endl;
+}
+inline sgp::Logger::LogInstance SGP_WARNING(){
+ return sgp::Logger::instance().logger(0) << "WARNING : ";
+}
+
+#if defined(USE_VFS)
+inline sgp::Logger::LogInstance SGP_ERROR(vfs::String const& str){
+#else
+inline sgp::Logger::LogInstance SGP_ERROR(const char* str){
+#endif
+ return sgp::Logger::instance().logger(0) << "ERROR : " << str << sgp::endl;
+}
+inline sgp::Logger::LogInstance SGP_ERROR(){
+ return sgp::Logger::instance().logger(0) << "ERROR : ";
+}
+
+#endif // SGP_LOGGER_H
diff --git a/Standard Gaming Platform/soundman.cpp b/Standard Gaming Platform/soundman.cpp
index 43209612..6386eaa3 100644
--- a/Standard Gaming Platform/soundman.cpp
+++ b/Standard Gaming Platform/soundman.cpp
@@ -21,6 +21,7 @@
#include "random.h"
#include "fmod.h"
#include "fmod_errors.h"
+ #include "sgp_logger.h"
#endif
// Uncomment this to disable the startup of sound hardware
@@ -1801,14 +1802,16 @@ UINT32 uiCount;
return(FALSE);
}
-#include "VFS/vfs.h"
-#include "VFS/Tools/Log.h"
-
// Lesh modifications
// Sound debug
-#ifdef USE_VFS
-static CLog& s_SoundLog = *CLog::create(SndDebugFileName,true);
-#endif
+static struct SoundLog {
+ sgp::Logger_ID id;
+ SoundLog() {
+ id = sgp::Logger::instance().createLogger();
+ sgp::Logger::instance().connectFile(id, SndDebugFileName, true, sgp::Logger::FLUSH_ON_DELETE);
+ }
+} s_SoundLog;
+
//*****************************************************************************************
// SoundLog
// Writes string into log file
@@ -1826,7 +1829,7 @@ void SoundLog(CHAR8 *strMessage)
fclose(SndDebug);
}
#else
- s_SoundLog << strMessage << CLog::ENDL;
+ SGP_LOG(s_SoundLog.id, vfs::String::widen(strMessage,strlen(strMessage)));
#endif
}
diff --git a/Standard Gaming Platform/video.cpp b/Standard Gaming Platform/video.cpp
index 51e15aa7..95adb585 100644
--- a/Standard Gaming Platform/video.cpp
+++ b/Standard Gaming Platform/video.cpp
@@ -18,11 +18,12 @@
#include "Fileman.h"
#include "Input.h"
#include "GameSettings.h"
+#include "sgp_logger.h"
#endif
#include "resource.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_file_raii.h"
+#include
+#include
#include "Local.h"
#include "text.h"
@@ -665,15 +666,39 @@ void ShutdownVideoManager(void)
// down
//
- IDirectDrawSurface2_Release(gpMouseCursorOriginal);
- IDirectDrawSurface2_Release(gpMouseCursor);
- IDirectDrawSurface2_Release(gMouseCursorBackground[0].pSurface);
- IDirectDrawSurface2_Release(gpBackBuffer);
- IDirectDrawSurface2_Release(gpPrimarySurface);
+ if(gpMouseCursorOriginal)
+ {
+ IDirectDrawSurface2_Release(gpMouseCursorOriginal);
+ gpMouseCursorOriginal = NULL;
+ }
+ if(gpMouseCursor)
+ {
+ IDirectDrawSurface2_Release(gpMouseCursor);
+ gpMouseCursor = NULL;
+ }
+ if(gMouseCursorBackground[0].pSurface)
+ {
+ IDirectDrawSurface2_Release(gMouseCursorBackground[0].pSurface);
+ gMouseCursorBackground[0].pSurface = NULL;
+ }
+ if(gpBackBuffer)
+ {
+ IDirectDrawSurface2_Release(gpBackBuffer);
+ gpBackBuffer = NULL;
+ }
+ if(gpPrimarySurface)
+ {
+ IDirectDrawSurface2_Release(gpPrimarySurface);
+ gpPrimarySurface = NULL;
+ }
- IDirectDraw2_RestoreDisplayMode( gpDirectDrawObject );
- IDirectDraw2_SetCooperativeLevel(gpDirectDrawObject, ghWindow, DDSCL_NORMAL );
- IDirectDraw2_Release( gpDirectDrawObject );
+ if(gpDirectDrawObject)
+ {
+ IDirectDraw2_RestoreDisplayMode( gpDirectDrawObject );
+ IDirectDraw2_SetCooperativeLevel(gpDirectDrawObject, ghWindow, DDSCL_NORMAL );
+ IDirectDraw2_Release( gpDirectDrawObject );
+ gpDirectDrawObject = NULL;
+ }
// destroy the window
// DestroyWindow( ghWindow );
@@ -1993,7 +2018,7 @@ void RefreshScreen(void *DummyVariable)
{
vfs::COpenWriteFile wfile(FileName,true,true);
char head[] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, LOBYTE(SCREEN_WIDTH), HIBYTE(SCREEN_WIDTH), LOBYTE(SCREEN_HEIGHT), HIBYTE(SCREEN_HEIGHT), 0x10, 0};
- TRYCATCH_RETHROW(wfile.file().write(head,18), L"");
+ SGP_TRYCATCH_RETHROW(wfile->write(head,18), L"");
#endif
//
@@ -2034,7 +2059,7 @@ void RefreshScreen(void *DummyVariable)
#ifndef USE_VFS
fwrite( p16BPPData, SCREEN_WIDTH * 2, 1, OutputFile);
#else
- TRYCATCH_RETHROW(wfile.file().write((vfs::Byte*)p16BPPData, SCREEN_WIDTH * 2), L"");
+ SGP_TRYCATCH_RETHROW(wfile->write((vfs::Byte*)p16BPPData, SCREEN_WIDTH * 2), L"");
#endif
}
else
@@ -2042,7 +2067,7 @@ void RefreshScreen(void *DummyVariable)
#ifndef USE_VFS
fwrite((void *)(((UINT8 *)SurfaceDescription.lpSurface) + (iIndex * SCREEN_WIDTH * 2)), SCREEN_WIDTH * 2, 1, OutputFile);
#else
- TRYCATCH_RETHROW(wfile.file().write((vfs::Byte*)(((UINT8 *)SurfaceDescription.lpSurface) + (iIndex * SCREEN_WIDTH * 2)), SCREEN_WIDTH * 2), L"");
+ SGP_TRYCATCH_RETHROW(wfile->write((vfs::Byte*)(((UINT8 *)SurfaceDescription.lpSurface) + (iIndex * SCREEN_WIDTH * 2)), SCREEN_WIDTH * 2), L"");
#endif
}
}
@@ -2069,9 +2094,9 @@ void RefreshScreen(void *DummyVariable)
}
#ifdef USE_VFS
- catch(CBasicException& ex)
+ catch(std::exception& ex)
{
- RETHROWEXCEPTION(L"",&ex);
+ SGP_RETHROW(L"", ex);
}
#endif
@@ -3177,8 +3202,12 @@ void FatalError( const STR8 pError, ...)
gfFatalError = TRUE;
// Release DDraw
- IDirectDraw2_RestoreDisplayMode( gpDirectDrawObject );
- IDirectDraw2_Release( gpDirectDrawObject );
+ if(gpDirectDrawObject)
+ {
+ IDirectDraw2_RestoreDisplayMode( gpDirectDrawObject );
+ IDirectDraw2_Release( gpDirectDrawObject );
+ gpDirectDrawObject = NULL;
+ }
ShowWindow( ghWindow, SW_HIDE );
// destroy the window
@@ -3186,8 +3215,8 @@ void FatalError( const STR8 pError, ...)
gfProgramIsRunning = FALSE;
- MessageBox( ghWindow, gFatalErrorString, "JA2 Fatal Error", MB_OK | MB_TASKMODAL );
-
+ //MessageBox( ghWindow, gFatalErrorString, "JA2 Fatal Error", MB_OK | MB_TASKMODAL );
+ MessageBoxW( ghWindow, vfs::String::as_utf16(gFatalErrorString).c_str(), L"JA2 Fatal Error", MB_OK | MB_TASKMODAL );
}
@@ -3383,7 +3412,7 @@ void RefreshMovieCache( )
#ifndef USE_VFS
fwrite(&Header, sizeof(TARGA_HEADER), 1, disk);
#else
- TRYCATCH_RETHROW(wfile.file().write((vfs::Byte*)&Header, sizeof(TARGA_HEADER)), L"");
+ SGP_TRYCATCH_RETHROW(wfile->write((vfs::Byte*)&Header, sizeof(TARGA_HEADER)), L"");
#endif
pDest = gpFrameData[ cnt ];
@@ -3394,7 +3423,7 @@ void RefreshMovieCache( )
#ifndef USE_VFS
fwrite( ( pDest + ( iCountY * SCREEN_WIDTH ) + iCountX ), sizeof(UINT16), 1, disk);
#else
- TRYCATCH_RETHROW(wfile.file().write( (vfs::Byte*)( pDest + ( iCountY * SCREEN_WIDTH ) + iCountX ), sizeof(UINT16)), L"");
+ SGP_TRYCATCH_RETHROW(wfile->write( (vfs::Byte*)( pDest + ( iCountY * SCREEN_WIDTH ) + iCountX ), sizeof(UINT16)), L"");
#endif
}
@@ -3414,9 +3443,9 @@ void RefreshMovieCache( )
//SetFileManCurrentDirectory( ExecDir );
#else
}
- catch(CBasicException& ex)
+ catch(std::exception& ex)
{
- logException(ex);
+ SGP_ERROR(ex.what());
}
#endif
}
diff --git a/Standard Gaming Platform/vobject.cpp b/Standard Gaming Platform/vobject.cpp
index c393ee67..1ce9b7a0 100644
--- a/Standard Gaming Platform/vobject.cpp
+++ b/Standard Gaming Platform/vobject.cpp
@@ -302,7 +302,7 @@ BOOLEAN BltVideoObjectFromIndex(UINT32 uiDestVSurface, UINT32 uiSrcVObject, UINT
// Now we have the video object and surface, call the VO blitter function
if ( !BltVideoObjectToBuffer( pBuffer, uiPitch, hSrcVObject, usRegionIndex, iDestX, iDestY, fBltFlags, pBltFx ) )
{
- UnLockVideoSurface( uiDestVSurface );
+ UnLockVideoSurface( uiDestVSurface );
// VO Blitter will set debug messages for error conditions
return FALSE;
}
@@ -434,8 +434,19 @@ HVOBJECT CreateVideoObject( VOBJECT_DESC *VObjectDesc )
{
if ( VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMFILE )
{
+ ImageFileType::TestOrder order = ImageFileType::JPC_FALLBACK;
+
+ if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMJPC) {
+ order = ImageFileType::JPC;
+ } else if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMJPC_FALLBACK) {
+ order = ImageFileType::JPC_FALLBACK;
+ } else if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMPNG) {
+ order = ImageFileType::PNG_FALLBACK;
+ } else if(VObjectDesc->fCreateFlags & VOBJECT_CREATE_FROMPNG_FALLBACK) {
+ order = ImageFileType::PNG_FALLBACK;
+ }
// Create himage object from file
- hImage = CreateImage( VObjectDesc->ImageFile, IMAGE_ALLIMAGEDATA );
+ hImage = CreateImage( VObjectDesc->ImageFile, IMAGE_ALLIMAGEDATA, order );
if ( hImage == NULL )
{
@@ -457,17 +468,31 @@ HVOBJECT CreateVideoObject( VOBJECT_DESC *VObjectDesc )
if(hImage->ubBitDepth == 32)
{
- hVObject->p16BPPObject = new SixteenBPPObjectInfo;
- int SIZE = hImage->usHeight*hImage->usWidth;
- hVObject->pPixData = new UINT32[SIZE];
- memcpy(hVObject->pPixData, hImage->p32BPPData, SIZE*sizeof(UINT32));
- hVObject->p16BPPObject->p16BPPData = NULL;
- hVObject->p16BPPObject->sOffsetX = 0;
- hVObject->p16BPPObject->sOffsetY = 0;
- hVObject->p16BPPObject->ubShadeLevel = 0;
- hVObject->p16BPPObject->usHeight = hImage->usHeight;
- hVObject->p16BPPObject->usWidth = hImage->usWidth;
- hVObject->p16BPPObject->usRegionIndex = 0;
+ SGP_THROW_IFFALSE(hImage->usNumberOfObjects > 0, L"bad himage");
+
+ // create one 16bpp object (that contains 32bpp data)
+ hVObject->p16BPPObject = (SixteenBPPObjectInfo*)MemAlloc(sizeof(SixteenBPPObjectInfo));
+ if(!hVObject->p16BPPObject)
+ {
+ SGP_THROW(L"bad alloc");
+ }
+ memset(hVObject->p16BPPObject, 0, sizeof(SixteenBPPObjectInfo));
+
+ int SIZE = hImage->pETRLEObject[0].usHeight * hImage->pETRLEObject[0].usWidth * sizeof(UINT32);
+ hVObject->p16BPPObject->p16BPPData = (UINT16*)MemAlloc(SIZE); // UINT32*
+ if(!hVObject->p16BPPObject->p16BPPData)
+ {
+ MemFree(hVObject->p16BPPObject);
+ SGP_THROW(L"bad alloc");
+ }
+ memcpy(hVObject->p16BPPObject->p16BPPData, hImage->p32BPPData, SIZE);
+
+ hVObject->p16BPPObject->sOffsetX = hImage->pETRLEObject[0].sOffsetX;
+ hVObject->p16BPPObject->sOffsetY = hImage->pETRLEObject[0].sOffsetY;
+ hVObject->p16BPPObject->ubShadeLevel = 0;
+ hVObject->p16BPPObject->usHeight = hImage->pETRLEObject[0].usHeight;
+ hVObject->p16BPPObject->usWidth = hImage->pETRLEObject[0].usWidth;
+ hVObject->p16BPPObject->usRegionIndex = 0;
hVObject->usNumberOf16BPPObjects = 1;
hVObject->ubBitDepth = hImage->ubBitDepth;
@@ -481,16 +506,31 @@ HVOBJECT CreateVideoObject( VOBJECT_DESC *VObjectDesc )
}
else if(hImage->ubBitDepth == 16)
{
- hVObject->p16BPPObject = new SixteenBPPObjectInfo;
- int SIZE = hImage->usHeight*hImage->usWidth;
- hVObject->p16BPPObject->p16BPPData = new UINT16[SIZE];
- memcpy(hVObject->p16BPPObject->p16BPPData, hImage->p16BPPData, SIZE*sizeof(UINT16));
- hVObject->p16BPPObject->sOffsetX = 0;
- hVObject->p16BPPObject->sOffsetY = 0;
- hVObject->p16BPPObject->ubShadeLevel = 0;
- hVObject->p16BPPObject->usHeight = hImage->usHeight;
- hVObject->p16BPPObject->usWidth = hImage->usWidth;
- hVObject->p16BPPObject->usRegionIndex = 0;
+ SGP_THROW_IFFALSE(hImage->usNumberOfObjects > 0, L"bad himage");
+
+ // create one 16bpp object (that contains 32bpp data)
+ hVObject->p16BPPObject = (SixteenBPPObjectInfo*)MemAlloc(sizeof(SixteenBPPObjectInfo));
+ if(!hVObject->p16BPPObject)
+ {
+ SGP_THROW(L"bad alloc");
+ }
+ memset(hVObject->p16BPPObject, 0, sizeof(SixteenBPPObjectInfo));
+
+ int SIZE = hImage->pETRLEObject[0].usHeight * hImage->pETRLEObject[0].usWidth * sizeof(UINT16);
+ hVObject->p16BPPObject->p16BPPData = (UINT16*)MemAlloc(SIZE);
+ if(!hVObject->p16BPPObject->p16BPPData)
+ {
+ MemFree(hVObject->p16BPPObject);
+ SGP_THROW(L"bad alloc");
+ }
+ memcpy(hVObject->p16BPPObject->p16BPPData, hImage->p16BPPData, SIZE);
+
+ hVObject->p16BPPObject->sOffsetX = hImage->pETRLEObject[0].sOffsetX;
+ hVObject->p16BPPObject->sOffsetY = hImage->pETRLEObject[0].sOffsetY;
+ hVObject->p16BPPObject->ubShadeLevel = 0;
+ hVObject->p16BPPObject->usHeight = hImage->pETRLEObject[0].usHeight;
+ hVObject->p16BPPObject->usWidth = hImage->pETRLEObject[0].usWidth;
+ hVObject->p16BPPObject->usRegionIndex = 0;
hVObject->usNumberOf16BPPObjects = 1;
hVObject->ubBitDepth = hImage->ubBitDepth;
@@ -520,9 +560,9 @@ HVOBJECT CreateVideoObject( VOBJECT_DESC *VObjectDesc )
// Set values
hVObject->usNumberOfObjects = TempETRLEData.usNumberOfObjects;
- hVObject->pETRLEObject = TempETRLEData.pETRLEObject;
- hVObject->pPixData = TempETRLEData.pPixData;
- hVObject->uiSizePixData = TempETRLEData.uiSizePixData;
+ hVObject->pETRLEObject = TempETRLEData.pETRLEObject;
+ hVObject->pPixData = TempETRLEData.pPixData;
+ hVObject->uiSizePixData = TempETRLEData.uiSizePixData;
// Set palette from himage
if ( hImage->ubBitDepth == 8 )
@@ -768,11 +808,11 @@ UINT32 count;
BOOLEAN BltVideoObjectToBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJECT hSrcVObject, UINT16 usIndex, INT32 iDestX, INT32 iDestY, INT32 fBltFlags, blt_fx *pBltFx )
{
// Sometimes an exception is thrown in that method.
- __try
+//BF __try
{
// Assertions
//Assert( pBuffer != NULL );
- THROWIFFALSE( pBuffer != NULL, L"No Destination Buffer" );
+ SGP_THROW_IFFALSE( pBuffer != NULL, L"No Destination Buffer" );
if ( hSrcVObject == NULL )
{
@@ -780,13 +820,14 @@ BOOLEAN BltVideoObjectToBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJE
}
//Assert( hSrcVObject != NULL );
- THROWIFFALSE( hSrcVObject != NULL, L"No Source Object" )
+ SGP_THROW_IFFALSE( hSrcVObject != NULL, L"No Source Object" )
SixteenBPPObjectInfo *image = NULL;
// Check For Flags and bit depths
switch( hSrcVObject->ubBitDepth )
{
case 32:
+ SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
image = &hSrcVObject->p16BPPObject[usIndex];
#if 0
Blt16BPPTo16BPPTrans( pBuffer, uiDestPitchBYTES,
@@ -796,24 +837,35 @@ BOOLEAN BltVideoObjectToBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJE
0 );
#else
Blt32BPPTo16BPPTrans( pBuffer, uiDestPitchBYTES,
- (UINT32*)hSrcVObject->pPixData, image->usWidth * sizeof(UINT32),
+ (UINT32*)image->p16BPPData, image->usWidth * sizeof(UINT32),
iDestX, iDestY,
0, 0, image->usWidth, image->usHeight);
#endif
break;
case 16:
+ SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
image = &hSrcVObject->p16BPPObject[usIndex];
- Blt16BPPTo16BPP( pBuffer, uiDestPitchBYTES,
- image->p16BPPData, image->usWidth * sizeof(UINT16),
- iDestX, iDestY,
- 0, 0, image->usWidth, image->usHeight );
+ if ( fBltFlags & VO_BLT_SRCTRANSPARENCY )
+ {
+ Blt16BPPTo16BPPTrans( pBuffer, uiDestPitchBYTES,
+ image->p16BPPData, image->usWidth * sizeof(UINT16),
+ iDestX, iDestY,
+ 0, 0, image->usWidth, image->usHeight, 0x1F ); // 0x1f = 5 bits of blue
+ }
+ else
+ {
+ Blt16BPPTo16BPP( pBuffer, uiDestPitchBYTES,
+ image->p16BPPData, image->usWidth * sizeof(UINT16),
+ iDestX, iDestY,
+ 0, 0, image->usWidth, image->usHeight );
+ }
break;
case 8:
- THROWIFFALSE( hSrcVObject->usNumberOfObjects > usIndex, L"Video object index is larger than the number of subimages");
+ SGP_THROW_IFFALSE( hSrcVObject->usNumberOfObjects > usIndex, L"Video object index is larger than the number of subimages");
// Switch based on flags given
do
{
@@ -877,10 +929,11 @@ BOOLEAN BltVideoObjectToBuffer( UINT16 *pBuffer, UINT32 uiDestPitchBYTES, HVOBJE
return( TRUE );
}
- __except(filter(GetExceptionCode(), GetExceptionInformation()))
- {
- return ( TRUE );
- }
+ //BF
+ //__except(filter(GetExceptionCode(), GetExceptionInformation()))
+ //{
+ // return ( TRUE );
+ //}
}
BOOLEAN PixelateVideoObjectRect( UINT32 uiDestVSurface, INT32 X1, INT32 Y1, INT32 X2, INT32 Y2)
@@ -1452,13 +1505,30 @@ BOOLEAN BltVideoObjectOutlineShadowFromIndex(UINT32 uiDestVSurface, UINT32 uiSrc
#endif
CHECKF( GetVideoObject( &hSrcVObject, uiSrcVObject ) );
- if( BltIsClipped( hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect) )
+ if(hSrcVObject->ubBitDepth == 8)
{
- Blt8BPPDataTo16BPPBufferOutlineShadowClip((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect );
+ if( BltIsClipped( hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect) )
+ {
+ Blt8BPPDataTo16BPPBufferOutlineShadowClip((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex, &ClippingRect );
+ }
+ else
+ {
+ Blt8BPPDataTo16BPPBufferOutlineShadow((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex );
+ }
}
- else
+ else if(hSrcVObject->ubBitDepth == 16)
{
- Blt8BPPDataTo16BPPBufferOutlineShadow((UINT16*)pBuffer, uiPitch, hSrcVObject, iDestX, iDestY, usIndex );
+ SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
+ SixteenBPPObjectInfo &image = hSrcVObject->p16BPPObject[0];
+ Blt16BPPTo16BPPTransShadow(pBuffer, uiPitch, image.p16BPPData, image.usWidth * sizeof(UINT16),
+ iDestX, iDestY, 0, 0, image.usWidth, image.usHeight, 0x1F);
+ }
+ else if(hSrcVObject->ubBitDepth == 32)
+ {
+ SGP_THROW_IFFALSE(usIndex < hSrcVObject->usNumberOf16BPPObjects, L"index larger that number images");
+ SixteenBPPObjectInfo &image = hSrcVObject->p16BPPObject[0];
+ Blt32BPPTo16BPPTransShadow(pBuffer, uiPitch, (UINT32*)image.p16BPPData, image.usWidth * sizeof(UINT32),
+ iDestX, iDestY, 0, 0, image.usWidth, image.usHeight);
}
// Now we have the video object and surface, call the VO blitter function
diff --git a/Standard Gaming Platform/vobject.h b/Standard Gaming Platform/vobject.h
index a2f6b8e6..54a0a3be 100644
--- a/Standard Gaming Platform/vobject.h
+++ b/Standard Gaming Platform/vobject.h
@@ -72,6 +72,10 @@ typedef struct
#define VOBJECT_CREATE_DEFAULT 0x00000020 // Creates and empty object of given width, height and BPP
#define VOBJECT_CREATE_FROMFILE 0x00000040 // Creates a video object from a file ( using HIMAGE )
#define VOBJECT_CREATE_FROMHIMAGE 0x00000080 // Creates a video object from a pre-loaded hImage
+#define VOBJECT_CREATE_FROMJPC 0x00010000 // replace file extension : sti -> jpc.7z
+#define VOBJECT_CREATE_FROMPNG 0x00020000 // replace file extension : sti -> png
+#define VOBJECT_CREATE_FROMJPC_FALLBACK 0x00100000 // replace file extension : sti -> jpc.7z, fall back to sti when it doesn't exist
+#define VOBJECT_CREATE_FROMPNG_FALLBACK 0x00200000 // replace file extension : sti -> png, fall back to sti when it doesn't exist
// VOBJECT FLAGS
#define VOBJECT_FLAG_SHADETABLE_SHARED 0x00000100
diff --git a/Standard Gaming Platform/vobject_blitters.cpp b/Standard Gaming Platform/vobject_blitters.cpp
index 188f4018..ffa1d868 100644
--- a/Standard Gaming Platform/vobject_blitters.cpp
+++ b/Standard Gaming Platform/vobject_blitters.cpp
@@ -19,6 +19,7 @@
#include "vobject.h"
#include "vobject_blitters.h"
#include "shading.h"
+ #include "sgp_logger.h"
#endif
#include
+
+
+
+
@@ -471,6 +479,10 @@
RelativePath="Strategic Merc Handler.h"
>
+
+
@@ -563,6 +575,14 @@
RelativePath="Hourly Update.cpp"
>
+
+
+
+
@@ -651,6 +671,10 @@
RelativePath="Strategic Merc Handler.cpp"
>
+
+
diff --git a/Strategic/Strategic_VS2010.vcxproj b/Strategic/Strategic_VS2010.vcxproj
new file mode 100644
index 00000000..a5f528a5
--- /dev/null
+++ b/Strategic/Strategic_VS2010.vcxproj
@@ -0,0 +1,317 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}
+ Win32Proj
+ Strategic
+ Strategic
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Strategic/Strategic_VS2010.vcxproj.filters b/Strategic/Strategic_VS2010.vcxproj.filters
new file mode 100644
index 00000000..00b93da1
--- /dev/null
+++ b/Strategic/Strategic_VS2010.vcxproj.filters
@@ -0,0 +1,327 @@
+
+
+
+
+ {e965b12d-833b-4ed2-b5fe-b519e2d661e3}
+
+
+ {7fc727d5-3708-404e-8267-410283203b63}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Strategic/Town Militia.cpp b/Strategic/Town Militia.cpp
index 104fe038..e7b25579 100644
--- a/Strategic/Town Militia.cpp
+++ b/Strategic/Town Militia.cpp
@@ -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);
-}
+}
\ No newline at end of file
diff --git a/Strategic/Town Militia.h b/Strategic/Town Militia.h
index ac0d1c92..9489508a 100644
--- a/Strategic/Town Militia.h
+++ b/Strategic/Town Militia.h
@@ -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 );
diff --git a/Strategic/UndergroundInit.cpp b/Strategic/UndergroundInit.cpp
index 031f2cd5..b45bca95 100644
--- a/Strategic/UndergroundInit.cpp
+++ b/Strategic/UndergroundInit.cpp
@@ -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(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(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(s->ubNumAdmins) << LF;
+ m_log << "\t\tTroops: " << static_cast(s->ubNumTroops) << LF;
+ m_log << "\t\tElites: " << static_cast(s->ubNumElites) << LF;
+ m_log << "\t- Creature population" << LF;
+ m_log << "\t\tBloodcats: " << static_cast(s->ubNumBloodcats) << LF;
+ m_log << "\t\tCrepitus: " << static_cast(s->ubNumCreatures) << LF;
+ m_log << "\t\t- Habitat: " << static_cast(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 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 buffer = vector(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(y+'A'-1) << x << '-' << z;
+ string tmp;
+ ss >> tmp;
+ return tmp;
+}
diff --git a/Strategic/UndergroundInit.h b/Strategic/UndergroundInit.h
index b9de6c64..e93ebbbf 100644
--- a/Strategic/UndergroundInit.h
+++ b/Strategic/UndergroundInit.h
@@ -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
+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 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
diff --git a/Strategic/XML_Bloodcats.cpp b/Strategic/XML_Bloodcats.cpp
index 3347ae00..d1faa1a7 100644
--- a/Strategic/XML_Bloodcats.cpp
+++ b/Strategic/XML_Bloodcats.cpp
@@ -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 )
{
diff --git a/Strategic/XML_DynamicRestrictions.cpp b/Strategic/XML_DynamicRestrictions.cpp
index f0cd8340..6c9c5b16 100644
--- a/Strategic/XML_DynamicRestrictions.cpp
+++ b/Strategic/XML_DynamicRestrictions.cpp
@@ -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;
}
}
diff --git a/Strategic/XML_ExtraItems.cpp b/Strategic/XML_ExtraItems.cpp
index 1cc23f4a..c7be4a6e 100644
--- a/Strategic/XML_ExtraItems.cpp
+++ b/Strategic/XML_ExtraItems.cpp
@@ -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
diff --git a/Strategic/XML_FacilityTypes.cpp b/Strategic/XML_FacilityTypes.cpp
index 66270d4a..8717fb35 100644
--- a/Strategic/XML_FacilityTypes.cpp
+++ b/Strategic/XML_FacilityTypes.cpp
@@ -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 encountered too early! Please make sure to close all opened tags first.");
+ SGP_THROW(L"FacilityTypes.XML Error: Tag 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 tag was encountered too early! Please make sure all tags are closed properly.");
+ SGP_THROW(L"FacilityTypes.XML Error: A 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 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 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);
diff --git a/Strategic/XML_SectorNames.cpp b/Strategic/XML_SectorNames.cpp
index 9ed5863f..bad51e8c 100644
--- a/Strategic/XML_SectorNames.cpp
+++ b/Strategic/XML_SectorNames.cpp
@@ -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);
diff --git a/Strategic/XML_UniformColors.cpp b/Strategic/XML_UniformColors.cpp
index 5544f21c..0b1064db 100644
--- a/Strategic/XML_UniformColors.cpp
+++ b/Strategic/XML_UniformColors.cpp
@@ -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 );
}
}
diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp
index ce0d6946..92c9abd2 100644
--- a/Strategic/mapscreen.cpp
+++ b/Strategic/mapscreen.cpp
@@ -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 ()
// 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; iflags.uiStatusFlags & SOLDIER_VEHICLE))
{
- if(pInventoryPoolList[i].fExists == TRUE && (pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE))
+ for(unsigned int i = 0; iinv[x].exists() == true)
+ for(int x = 0; xinv[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; iinv[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; iinv[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; iinv[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; iinv[i].exists() == true)
+ {
+ AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
+ DeleteObj(&pSoldier->inv[i]);
+ }
+ fTeamPanelDirty = TRUE;
+ fMapPanelDirty = TRUE;
+ fInterfacePanelDirty = DIRTYLEVEL2;
+ }
+ for(int i = HELMETPOS; iinv[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 );
}
diff --git a/Strategic/mapscreen.h b/Strategic/mapscreen.h
index ddb25e66..16a216a7 100644
--- a/Strategic/mapscreen.h
+++ b/Strategic/mapscreen.h
@@ -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
\ No newline at end of file
diff --git a/Strategic/strategic town reputation.cpp b/Strategic/strategic town reputation.cpp
index e6745951..53965f6d 100644
--- a/Strategic/strategic town reputation.cpp
+++ b/Strategic/strategic town reputation.cpp
@@ -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++ )
{
diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp
index 9e88d07f..7d51463f 100644
--- a/Strategic/strategicmap.cpp
+++ b/Strategic/strategicmap.cpp
@@ -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: " <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;
+ //}
}
}
diff --git a/Strategic/strategicmap.h b/Strategic/strategicmap.h
index 730d3ae2..087228cd 100644
--- a/Strategic/strategicmap.h
+++ b/Strategic/strategicmap.h
@@ -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 );
diff --git a/Tactical/Animation Control.cpp b/Tactical/Animation Control.cpp
index 363981d5..df989ca3 100644
--- a/Tactical/Animation Control.cpp
+++ b/Tactical/Animation Control.cpp
@@ -18,6 +18,7 @@
#include "rotting corpses.h"
#include "points.h"
#include "Debug Control.h"
+#include "Random.h"
#endif
#include "connect.h"
@@ -42,6 +43,35 @@ typedef struct
static UINT16 CrouchedThrowAnimationScript[MAX_FRAMES_PER_ANIM] = { 1,2,3,4,5,6,7,8,9,460,10,11,12,13,14,442,603,999,0,0,0,0 };
//
+///ddd
+static UINT16 StoneAnimationScript[MAX_FRAMES_PER_ANIM] = { 1,2,3,4,5,6,7,8,402,1,2,3,4,5,6,7,8,402,1,2,3,4,5,6,7,8,601,999,0,0,0,0,0 };
+
+static UINT16 CrouchedShootRocketScript[MAX_FRAMES_PER_ANIM] =
+{757,1,2,3,4,5,6,7,8,9,10,11,12,470,430,13,14,15,16,477,17,18,19,20,753,499,999,0,0,0,0};
+static UINT16 SwatWithKnifeScript[MAX_FRAMES_PER_ANIM] =
+//{1,2,3,4,5,6,7,703,8,9,10,11,704,12,13,14,15,16,17,18,19,501,999,0,0,0,0};
+{5,703,6,7,8,9,10,11,704,12,13,14,15,16,501,999,0,0,0,0};// 2
+static UINT16 SwatBackWithKnifeScript[MAX_FRAMES_PER_ANIM] =
+{16,15,14,13,12,704,11,10,9,8,7,6,703,5,501,999,0,0,0,0};
+
+static UINT16 SwatBackWithNothingScript[MAX_FRAMES_PER_ANIM] =
+{16,15,14,13,12,704,11,10,9,8,7,6,703,5,501,999,0,0,0,0};
+
+//, .
+static UINT16 ThrowGrenadeStanceAnimationScript[MAX_FRAMES_PER_ANIM] = { 1,2,3,4,5,6,7,8,9,10,460,11,12,13,14,15,16,17,18,19,442,601,999,0,0,0,0 };
+static UINT16 LobGrenadeStanceAnimationScript[MAX_FRAMES_PER_ANIM] = { 1,2,3,4,5,6,7,8,9,10,460,11,12,13,14,15,16,17,18,19,442,601,999,0,0,0,0 };
+//
+static UINT16 ROLL_L_AnimationScript[MAX_FRAMES_PER_ANIM] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,501,999,0,0,0,0 };
+static UINT16 ROLL_R_AnimationScript[MAX_FRAMES_PER_ANIM] = { 14,13,12,11,10,9,8,7,6,5,4,3,2,1,501,999,0,0,0,0 };
+
+
+
+
+
+
+
+
+
ANI_SPEED_DEF gubAnimCrawlSpeeds[ TOTALBODYTYPES ];
//Block for anim file
UINT16 gusAnimInst[ MAX_ANIMATIONS ][ MAX_FRAMES_PER_ANIM ];
@@ -929,6 +959,27 @@ ANIMCONTROLTYPE gAnimControl[ NUMANIMATIONSTATES ] =
// crouch throwing
"THROW ITEM CROUCHED", 0, 80, (FLOAT)0, ANIM_STATIONARY | ANIM_NOMOVE_MARKER | ANIM_NONINTERRUPT | ANIM_MIN_EFFORT | ANIM_ATTACK, ANIM_CROUCH, ANIM_CROUCH, -1,
// crouch throwing
gubAnimSurfaceIndex[ REGMALE ][ THROW_ITEM_CROUCHED ] = RGMCRTHROW;
//
+ //ddd shoot rocket crouched
+ gubAnimSurfaceIndex[ REGMALE ][ SHOOT_ROCKET_CROUCHED ] = RGMCRROCKET;
+ gubAnimSurfaceIndex[ REGMALE ][ SWATTING_WK ] = RGMSWKNIFE;
+ gubAnimSurfaceIndex[ REGMALE ][ SWAT_BACKWARDS_WK ] = RGMSWKNIFE;
+ gubAnimSurfaceIndex[ REGMALE ][ SWAT_BACKWARDS_NOTHING ] = RGMNOTHING_SWAT;
+ //
+ gubAnimSurfaceIndex[ REGMALE ][ THROW_GRENADE_STANCE ] = RGMSTHRG;
+ gubAnimSurfaceIndex[ REGMALE ][ LOB_GRENADE_STANCE ] = RGMSLOBG;
+ //
+ gubAnimSurfaceIndex[ REGMALE ][ ROLL_PRONE_L ] = RGMROLL_PR;
+ gubAnimSurfaceIndex[ REGMALE ][ ROLL_PRONE_R ] = RGMROLL_PR;
+
+
gubAnimSurfaceMidWaterSubIndex[ REGMALE ][ STANDING][0] = RGMWATER_R_STD;
gubAnimSurfaceMidWaterSubIndex[ REGMALE ][ WALKING ][0] = RGMWATER_R_WALK;
@@ -1671,6 +1735,19 @@ void InitAnimationSurfacesPerBodytype( )
// crouch throwing
gubAnimSurfaceIndex[ BIGMALE ][ THROW_ITEM_CROUCHED ] = BGMCRTHROW;
//
+//dddd
+ gubAnimSurfaceIndex[ BIGMALE ][ BIGGUY_STONE ] = BGMWITHSTONE;
+ gubAnimSurfaceIndex[ BIGMALE ][ SHOOT_ROCKET_CROUCHED ] = BGMCRROCKET;
+ gubAnimSurfaceIndex[ BIGMALE ][ SWATTING_WK ] = BGMSWKNIFE;
+ gubAnimSurfaceIndex[ BIGMALE ][ SWAT_BACKWARDS_WK ] = BGMSWKNIFE;
+ gubAnimSurfaceIndex[ BIGMALE ][ SWAT_BACKWARDS_NOTHING ] = BGMNOTHING_SWAT;
+ //
+ gubAnimSurfaceIndex[ BIGMALE ][ THROW_GRENADE_STANCE ] = BGMSTHRG;
+ gubAnimSurfaceIndex[ BIGMALE ][ LOB_GRENADE_STANCE ] = BGMSLOBG;
+ //
+ gubAnimSurfaceIndex[ BIGMALE ][ ROLL_PRONE_L ] = BGMROLL_PR;
+ gubAnimSurfaceIndex[ BIGMALE ][ ROLL_PRONE_R ] = BGMROLL_PR;
+
gubAnimSurfaceItemSubIndex[ BIGMALE ][ STANDING ] = BGMPISTOLBREATH;
gubAnimSurfaceItemSubIndex[ BIGMALE ][ WALKING ] = BGMNOTHING_WALK;
@@ -1793,6 +1870,14 @@ void InitAnimationSurfacesPerBodytype( )
gRandomAnimDefs[ BIGMALE ][ 6 ].ubFlags = RANDOM_ANIM_DRUNK;
gRandomAnimDefs[ BIGMALE ][ 6 ].ubAnimHeight = ANIM_STAND;
+ ///ddd big guy with stone
+ gRandomAnimDefs[ BIGMALE ][ 7 ].ubHandRestriction = RANDOM_ANIM_NOTHINGINHAND;
+ gRandomAnimDefs[ BIGMALE ][ 7 ].sAnimID = BIGGUY_STONE;
+ gRandomAnimDefs[ BIGMALE ][ 7 ].ubStartRoll = 20;
+ gRandomAnimDefs[ BIGMALE ][ 7 ].ubEndRoll = 26;
+ gRandomAnimDefs[ BIGMALE ][ 7 ].ubFlags = RANDOM_ANIM_CASUAL ;
+ gRandomAnimDefs[ BIGMALE ][ 7 ].ubAnimHeight = ANIM_STAND;
+
gubAnimSurfaceCorpseID[ BIGMALE ][ GENERIC_HIT_DEATH ] = MMERC_FWD;
gubAnimSurfaceCorpseID[ BIGMALE ][ FALLBACK_HIT_DEATH ] = MMERC_BCK;
@@ -1810,8 +1895,8 @@ void InitAnimationSurfacesPerBodytype( )
gubAnimSurfaceCorpseID[ BIGMALE ][ FALLBACK_HIT_DEATHTWITCHNB ] = MMERC_BCK;
gubAnimSurfaceCorpseID[ BIGMALE ][ PRONE_HIT_DEATHTWITCHNB ] = MMERC_PRN;
gubAnimSurfaceCorpseID[ BIGMALE ][ PRONE_LAY_FROMHIT ] = MMERC_PRN;
- gubAnimSurfaceCorpseID[ REGMALE ][ FALLOFF ] = MMERC_FALLF;
- gubAnimSurfaceCorpseID[ REGMALE ][ FALLFORWARD_ROOF ] = MMERC_FALL;
+ gubAnimSurfaceCorpseID[ BIGMALE ][ FALLOFF ] = MMERC_FALLF;
+ gubAnimSurfaceCorpseID[ BIGMALE ][ FALLFORWARD_ROOF ] = MMERC_FALL;
gubAnimSurfaceCorpseID[ BIGMALE ][ FLYBACKHIT_STOP ] = MMERC_DHD;
gubAnimSurfaceCorpseID[ BIGMALE ][ STAND_FALLFORWARD_STOP ] = MMERC_FWD;
gubAnimSurfaceCorpseID[ BIGMALE ][ FALLBACKHIT_STOP ] = MMERC_BCK;
@@ -2039,6 +2124,18 @@ void InitAnimationSurfacesPerBodytype( )
// crouch throwing
gubAnimSurfaceIndex[ STOCKYMALE ][ THROW_ITEM_CROUCHED ] = RGMCRTHROW;
//
+ //dddd
+ gubAnimSurfaceIndex[ STOCKYMALE ][ SHOOT_ROCKET_CROUCHED ] = RGMCRROCKET;
+ gubAnimSurfaceIndex[ STOCKYMALE ][ SWATTING_WK ] = RGMSWKNIFE;
+ gubAnimSurfaceIndex[ STOCKYMALE ][ SWAT_BACKWARDS_WK ] = RGMSWKNIFE;
+ gubAnimSurfaceIndex[ STOCKYMALE ][ SWAT_BACKWARDS_NOTHING ] = RGMNOTHING_SWAT;
+ //
+ gubAnimSurfaceIndex[ STOCKYMALE ][ THROW_GRENADE_STANCE ] = RGMSTHRG;
+ gubAnimSurfaceIndex[ STOCKYMALE ][ LOB_GRENADE_STANCE ] = RGMSLOBG;
+ //
+ gubAnimSurfaceIndex[ STOCKYMALE ][ ROLL_PRONE_L ] = RGMROLL_PR;
+ gubAnimSurfaceIndex[ STOCKYMALE ][ ROLL_PRONE_R ] = RGMROLL_PR;
+
gubAnimSurfaceItemSubIndex[ STOCKYMALE ][ STANDING ] = RGMPISTOLBREATH;
gubAnimSurfaceItemSubIndex[ STOCKYMALE ][ WALKING ] = RGMNOTHING_WALK;
@@ -2394,6 +2491,19 @@ void InitAnimationSurfacesPerBodytype( )
// crouch throwing
gubAnimSurfaceIndex[ REGFEMALE ][ THROW_ITEM_CROUCHED ] = RGFCRTHROW;
//
+ //ddd
+ gubAnimSurfaceIndex[ REGFEMALE ][ SHOOT_ROCKET_CROUCHED ] = RGFCRROCKET;
+ gubAnimSurfaceIndex[ REGFEMALE ][ SWAT_BACKWARDS_NOTHING ] = RGFNOTHING_SWAT;
+ gubAnimSurfaceIndex[ REGFEMALE ][ SWATTING_WK ] = RGFSWKNIFE;
+ gubAnimSurfaceIndex[ REGFEMALE ][ SWAT_BACKWARDS_WK ] = RGFSWKNIFE;
+ //
+ gubAnimSurfaceIndex[ REGFEMALE ][ THROW_GRENADE_STANCE ] = RGFSTHRG;
+ gubAnimSurfaceIndex[ REGFEMALE ][ LOB_GRENADE_STANCE ] = RGFSLOBG;
+ //
+ gubAnimSurfaceIndex[ REGFEMALE ][ ROLL_PRONE_L ] = RGFROLL_PR;
+ gubAnimSurfaceIndex[ REGFEMALE ][ ROLL_PRONE_R ] = RGFROLL_PR;
+
+
gubAnimSurfaceItemSubIndex[ REGFEMALE ][ STANDING ] = RGFPISTOLBREATH;
gubAnimSurfaceItemSubIndex[ REGFEMALE ][ WALKING ] = RGFNOTHING_WALK;
@@ -3058,17 +3168,60 @@ BOOLEAN LoadAnimationStateInstructions( )
return( FALSE );
}
+ //ddd 320 ;(
+ // ,
+ UINT16 fuckTheBoundz[320][100];
+
//Read in block
- if ( !FileRead( hFile, gusAnimInst, sizeof( gusAnimInst ), &uiBytesRead ) )
+ //if ( !FileRead( hFile, gusAnimInst, sizeof( gusAnimInst ), &uiBytesRead ) ) //commentet by ddd
+ if ( !FileRead( hFile, fuckTheBoundz, sizeof( fuckTheBoundz ), &uiBytesRead ) )
{
return( FALSE );
}
FileClose( hFile );
+ //memcpy(gusAnimInst, fuckTheBoundz, sizeof(gusAnimInst));
+ for(int i=0;i<320;i++)
+ memcpy(gusAnimInst[i],fuckTheBoundz[i],sizeof(fuckTheBoundz[i]));
+ //gusAnimInst[i][0] = fuckTheBoundz[i][0];
+
+ //! 2
+// char gS[22];
+// UINT32 uiNumBytesWritten = 64000;
+// int ggg[MAX_ANIMATIONS][MAX_FRAMES_PER_ANIM];
+// sprintf(gS, "%s\\%s", "c:", "zzz");
+// hFile = FileOpen( gS, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+//
+// for(int i=0;i<=MAX_ANIMATIONS;i++)
+// {
+// FilePrintf(hFile,"\r\n :%02d === \r\n",i);
+// for(int ii=0;ii<=MAX_FRAMES_PER_ANIM;ii++)
+// FilePrintf(hFile,"%02d ",gusAnimInst[i][ii]);
+//
+// }
+// //ggg[i][ii]=gusAnimInst[i][ii];
+// //FileWrite( hFile, &ggg, sizeof( ggg ), &uiNumBytesWritten );
+//FileClose( hFile );
+//!
+//strcpy(NULL, "crash");
+
// crouch throwing
memcpy(gusAnimInst[ THROW_ITEM_CROUCHED ],CrouchedThrowAnimationScript,sizeof(CrouchedThrowAnimationScript));
// crouch throwing
+
+ //ddd
+ memcpy(gusAnimInst[ BIGGUY_STONE ],StoneAnimationScript,sizeof(StoneAnimationScript));
+ memcpy(gusAnimInst[ SHOOT_ROCKET_CROUCHED ],CrouchedShootRocketScript,sizeof(CrouchedShootRocketScript));
+ memcpy(gusAnimInst[ SWATTING_WK ],SwatWithKnifeScript,sizeof(SwatWithKnifeScript));
+ memcpy(gusAnimInst[ SWAT_BACKWARDS_WK ],SwatBackWithKnifeScript,sizeof(SwatBackWithKnifeScript));
+ memcpy(gusAnimInst[ SWAT_BACKWARDS_NOTHING ],SwatBackWithNothingScript,sizeof(SwatBackWithNothingScript));
+
+ memcpy(gusAnimInst[ THROW_GRENADE_STANCE ],ThrowGrenadeStanceAnimationScript,sizeof(ThrowGrenadeStanceAnimationScript));
+ memcpy(gusAnimInst[ LOB_GRENADE_STANCE ],LobGrenadeStanceAnimationScript,sizeof(LobGrenadeStanceAnimationScript));
+
+ memcpy(gusAnimInst[ ROLL_PRONE_L ],ROLL_L_AnimationScript,sizeof(ROLL_L_AnimationScript));
+ memcpy(gusAnimInst[ ROLL_PRONE_R ],ROLL_R_AnimationScript,sizeof(ROLL_R_AnimationScript));
return( TRUE );
}
@@ -3438,7 +3591,7 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
// Assume a target gridno is here.... get direction...
// ATE: use +2 in gridno because here head is far from body
- bDir = (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo + 2, pSoldier->sTargetGridNo );
+ bDir = (INT8)GetDirectionToGridNoFromGridNo( (INT16)( pSoldier->sGridNo + 2 ), pSoldier->sTargetGridNo );
return( gusQueenMonsterSpitAnimPerDir[ bDir ] );
}
@@ -3456,6 +3609,8 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
if ( pSoldier->uiAnimSubFlags & SUB_ANIM_BIGGUYSHOOT2 )
{
usAnimSurface = BGMSTANDAIM;
+// if(Random(2)) usAnimSurface = BGMSTANDAIM; //ddd
+// else usAnimSurface = BGMSTANDAIM2;
}
}
@@ -3557,6 +3712,15 @@ UINT16 DetermineSoldierAnimationSurface( SOLDIERTYPE *pSoldier, UINT16 usAnimSta
usAltAnimSurface = gubAnimSurfaceItemSubIndex[pSoldier->ubBodyType][usAnimState];
if ( usAltAnimSurface != INVALID_ANIMATION )
{
+ //ddd{
+ /*if ( usAnimSurface == BGMSTANDAIM2 )
+ {
+
+ usAnimSurface = BGMFLEX;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"usanimcashe");
+
+ }
+ else //}ddd*/
usAnimSurface = usAltAnimSurface;
fAdjustedForItem = TRUE;
}
diff --git a/Tactical/Animation Control.h b/Tactical/Animation Control.h
index eaf92b23..8e40ec28 100644
--- a/Tactical/Animation Control.h
+++ b/Tactical/Animation Control.h
@@ -7,9 +7,9 @@
// Defines
// #######################################################
-#define MAX_ANIMATIONS 320
+#define MAX_ANIMATIONS 350 //!!!!!ddd 30 .
#define MAX_FRAMES_PER_ANIM 100
-#define MAX_RANDOM_ANIMS_PER_BODYTYPE 7
+#define MAX_RANDOM_ANIMS_PER_BODYTYPE 8
#define RANDOM_ANIM_NOTHINGINHAND 0
#define RANDOM_ANIM_RIFLEINHAND 1
@@ -542,7 +542,18 @@ enum AnimationStates
// crouch throwing
THROW_ITEM_CROUCHED,
//
-
+ ///ddd
+ BIGGUY_STONE,
+ SHOOT_ROCKET_CROUCHED,
+ SWATTING_WK,
+ SWAT_BACKWARDS_WK,
+ SWAT_BACKWARDS_NOTHING,
+ THROW_GRENADE_STANCE, //ddd -
+ LOB_GRENADE_STANCE,
+ //
+ ROLL_PRONE_R,
+ ROLL_PRONE_L,
+
NUMANIMATIONSTATES
};
diff --git a/Tactical/Animation Data.cpp b/Tactical/Animation Data.cpp
index 425b74ce..11767942 100644
--- a/Tactical/Animation Data.cpp
+++ b/Tactical/Animation Data.cpp
@@ -478,6 +478,31 @@ AnimationSurfaceType gAnimSurfaceDatabase[ NUMANIMATIONSURFACETYPES ] =
BGMCRTHROW, "ANIMS\\M_MERC\\M_CR_THR.STI", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
RGFCRTHROW, "ANIMS\\F_MERC\\F_CR_THR.STI", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
//
+ //ddd big man with stone
+ BGMWITHSTONE, "ANIMS\\M_MERC\\M_STEIN.STI", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ //ddd crouched shoot rocket
+ RGMCRROCKET, "ANIMS\\S_MERC\\S_LAW_CR.sti", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ BGMCRROCKET, "ANIMS\\M_MERC\\M_LAW_CR.sti", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGFCRROCKET, "ANIMS\\F_MERC\\F_LAW_CR.sti", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+
+ BGMSWKNIFE , "ANIMS\\M_MERC\\M_K_SWAT_K.sti", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGFSWKNIFE , "ANIMS\\F_MERC\\F_K_SWAT_K.sti", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGMSWKNIFE , "ANIMS\\S_MERC\\S_K_SWAT.sti", C_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+
+ // 2
+ BGMSTHRG, "ANIMS\\M_MERC\\M_THROW_G.sti", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ //
+ RGFSTHRG, "ANIMS\\F_MERC\\F_THROW.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGMSTHRG, "ANIMS\\S_MERC\\S_THROW_G.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+
+ BGMSLOBG, "ANIMS\\M_MERC\\M_THROW_GLOB.sti", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGFSLOBG, "ANIMS\\F_MERC\\F_LOB.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGMSLOBG, "ANIMS\\S_MERC\\S_THROW_GLOB.sti", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ //
+ RGMROLL_PR, "ANIMS\\S_MERC\\S_ROLL_N.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ BGMROLL_PR, "ANIMS\\M_MERC\\M_ROLL_N.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+ RGFROLL_PR, "ANIMS\\F_MERC\\F_ROLL_N.STI", S_STRUCT, 0, 8, TO_INIT, NULL, NULL, 0, -1,
+
};
@@ -828,12 +853,6 @@ BOOLEAN LoadAnimationSurface( UINT16 usSoldierID, UINT16 usSurfaceIndex, UINT16
{
AuxObjectData *pAuxData;
- if (usSurfaceIndex == 251)
- {
- int a = 10;
- a++;
- }
-
// Check for valid surface
CHECKF( usSurfaceIndex < NUMANIMATIONSURFACETYPES );
@@ -953,13 +972,6 @@ BOOLEAN LoadAnimationSurface( UINT16 usSoldierID, UINT16 usSurfaceIndex, UINT16
BOOLEAN UnLoadAnimationSurface( UINT16 usSoldierID, UINT16 usSurfaceIndex )
{
-
- if (usSurfaceIndex == 251)
- {
- int a = 10;
- a++;
- }
-
// Decrement usage flag, only if this soldier has it currently tagged
if ( gbAnimUsageHistory[ usSurfaceIndex ][ usSoldierID ] > 0 )
{
diff --git a/Tactical/Animation Data.h b/Tactical/Animation Data.h
index 5cac37ce..c39c7cff 100644
--- a/Tactical/Animation Data.h
+++ b/Tactical/Animation Data.h
@@ -508,6 +508,29 @@ typedef enum
RGFCRTHROW,
//
+//***ddd
+BGMWITHSTONE,
+//for crouched shoot rocket
+ RGMCRROCKET,
+ BGMCRROCKET,
+ RGFCRROCKET,
+//swatting with knife
+ BGMSWKNIFE,
+ RGFSWKNIFE,
+ RGMSWKNIFE,
+// .
+ BGMSTHRG,
+ RGFSTHRG,
+ RGMSTHRG,
+// .
+ BGMSLOBG,
+ RGFSLOBG,
+ RGMSLOBG,
+// !
+ RGMROLL_PR,
+ BGMROLL_PR,
+ RGFROLL_PR,
+
NUMANIMATIONSURFACETYPES
} AnimationSurfaceTypes;
diff --git a/Tactical/Arms Dealer Init.cpp b/Tactical/Arms Dealer Init.cpp
index 2b447ff1..a5a6d4b3 100644
--- a/Tactical/Arms Dealer Init.cpp
+++ b/Tactical/Arms Dealer Init.cpp
@@ -16,6 +16,7 @@
#include "Handle Items.h"
#include "Quests.h"
#include "Scheduling.h"
+ #include "GameSettings.h"
#endif
#include
@@ -92,6 +93,9 @@ void LimitArmsDealersInventory( UINT8 ubArmsDealer, UINT32 uDealerItemType, UIN
void GuaranteeAtLeastOneItemOfType( UINT8 ubArmsDealer, UINT32 uiDealerItemType );
void GuaranteeAtLeastXItemsOfIndex( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubHowMany );
+void GuaranteeAtMostNumOfItemsForItem( UINT8 ubArmsDealer, INT16 sItemIndex, UINT8 ubAtMostNumItems );
+
+
void ArmsDealerGetsFreshStock( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubNumItems );
BOOLEAN ItemContainsLiquid( UINT16 usItemIndex );
UINT8 DetermineDealerItemCondition( UINT8 ubArmsDealer, UINT16 usItemIndex );
@@ -147,7 +151,6 @@ void InitAllArmsDealers()
UINT8 ubArmsDealer;
ShutDownArmsDealers();
-
//Initialize the initial status & inventory for each of the arms dealers
for( ubArmsDealer = 0; ubArmsDealer < NUM_ARMS_DEALERS; ubArmsDealer++ )
{
@@ -1271,7 +1274,7 @@ BOOLEAN ItemContainsLiquid( UINT16 usItemIndex )
bool ItemIsSpecial(DEALER_SPECIAL_ITEM& item)
{
for (int x = 0; x < item.object.ubNumberOfObjects; ++x) {
- if (item.object[x]->attachments.empty() == false) {
+ if (item.object[x]->AttachmentListSize() > 0) {
//items with attachments are special
return true;
}
@@ -1347,11 +1350,16 @@ void AddObjectToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE *pObject )
for (attachmentList::iterator iter = seperateObject[0]->attachments.begin(); iter != seperateObject[0]->attachments.end();) {
// ARM: Note: this is only used for selling, not repairs, so attachmentes are seperated when sold to a dealer
// If the attachment is detachable
- if (! (Item[ iter->usItem ].inseparable ) )
+ if (! (Item[ iter->usItem ].inseparable ) && iter->exists())
{
// add this particular attachment (they can't be imprinted, or themselves have attachments!)
AddObjectToArmsDealerInventory( ubArmsDealer, &(*iter) );
- iter = pData->attachments.erase(iter);
+
+ iter = pData->RemoveAttachmentAtIter(iter);
+
+ if(UsingNewAttachmentSystem()==true)
+ ++iter;
+
if (iter == pData->attachments.end()) {
break;
}
@@ -1494,7 +1502,7 @@ void AddItemToArmsDealerInventory( UINT8 ubArmsDealer, OBJECTTYPE& object )
{
//we can only add items to a stack if the item has no attachments (not even default)
//and if it is either perfect or ammo (and same amount of ammo)
- if (object[0]->attachments.empty() == true &&
+ if (/*object[0]->attachments.empty() == true*/ object[0]->AttachmentListSize() &&
(object[0]->data.objectStatus == 100 || Item [ object.usItem ].usItemClass == IC_AMMO)) {
//first find existing items with same perfect status, if found add to that, else create new one
@@ -1832,7 +1840,7 @@ UINT32 CalculateObjectItemRepairTime( UINT8 ubArmsDealer, OBJECTTYPE *pItemObjec
// add time to repair any attachments on it
for (attachmentList::iterator iter = (*pItemObject)[x]->attachments.begin(); iter != (*pItemObject)[x]->attachments.end(); ++iter) {
// if damaged and repairable
- if ( ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) )
+ if ( ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) && iter->exists())
{
//uiRepairTime += CalculateSimpleItemRepairTime( ubArmsDealer, iter->usItem, (*iter)[x]->data.objectStatus );
uiRepairTime += CalculateObjectItemRepairTime( ubArmsDealer, &(*iter) );
@@ -1890,7 +1898,7 @@ UINT32 CalculateObjectItemRepairCost( UINT8 ubArmsDealer, OBJECTTYPE *pItemObjec
// add cost of repairing any attachments on it
for (attachmentList::iterator iter = (*pItemObject)[x]->attachments.begin(); iter != (*pItemObject)[x]->attachments.end(); ++iter) {
// if damaged and repairable
- if ( ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) )
+ if ( ( (*iter)[x]->data.objectStatus < 100 ) && CanDealerRepairItem( ubArmsDealer, iter->usItem ) && iter->exists())
{
uiRepairCost += CalculateObjectItemRepairCost( ubArmsDealer, &(*iter));
}
@@ -2265,3 +2273,25 @@ UINT32 CalculateMinutesClosedBetween( UINT8 ubArmsDealer, UINT32 uiStartTime, UI
return ( uiMinutesClosed );
}
+
+void GuaranteeAtMostNumOfItemsForItem( UINT8 ubArmsDealer, INT16 sItemIndex, UINT8 ubAtMostNumItems )
+{
+
+ if( gArmsDealerStatus[ ubArmsDealer ].fOutOfBusiness )
+ return;
+
+ //ADB, ya, a whole 1 line of extra code!
+ // not permitted for repair dealers - would take extra code to avoid counting items under repair!
+ //Assert( !DoesDealerDoRepairs( ubArmsDealer ) );
+ int itemsIHave = 0;
+ for (DealerItemList::iterator iter = gArmsDealersInventory[ ubArmsDealer ].begin();
+ iter != gArmsDealersInventory[ ubArmsDealer ].end(); ++iter) {
+ if (iter->ItemIsInInventory() == true
+ && iter->object.usItem == sItemIndex
+ && iter->IsUnderRepair() == false) {
+ itemsIHave -= iter->object.ubNumberOfObjects;
+ //if there are any of these in stock
+
+ }
+ }
+}
diff --git a/Tactical/Arms Dealer Init.h b/Tactical/Arms Dealer Init.h
index 68194476..d711a946 100644
--- a/Tactical/Arms Dealer Init.h
+++ b/Tactical/Arms Dealer Init.h
@@ -362,6 +362,8 @@ UINT16 CalcValueOfItemToDealer( UINT8 ubArmsDealer, UINT16 usItemIndex, BOOLEAN
UINT32 CalculateOvernightRepairDelay( UINT8 ubArmsDealer, UINT32 uiTimeWhenFreeToStartIt, UINT32 uiMinutesToFix );
UINT32 CalculateMinutesClosedBetween( UINT8 ubArmsDealer, UINT32 uiStartTime, UINT32 uiEndTime );
+extern void GuaranteeAtLeastXItemsOfIndex( UINT8 ubArmsDealer, UINT16 usItemIndex, UINT8 ubHowMany );
+
#endif
\ No newline at end of file
diff --git a/Tactical/ArmsDealerInvInit.cpp b/Tactical/ArmsDealerInvInit.cpp
index 629f9a3b..d43e1709 100644
--- a/Tactical/ArmsDealerInvInit.cpp
+++ b/Tactical/ArmsDealerInvInit.cpp
@@ -901,6 +901,7 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
}
// items normally not sold at shops are unsuitable
+// if ( Item[ usItemIndex ].fFlags & ITEM_NOT_BUYABLE )
if ( Item[ usItemIndex ].notbuyable )
{
return(ITEM_SUITABILITY_NONE);
@@ -916,8 +917,21 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
}
// the following staple items are always deemed highly suitable regardless of player's progress:
+ //switch (usItemIndex)
+ //{
+ // case FIRSTAIDKIT:
+ // case MEDICKIT:
+ // case TOOLKIT:
+ // case LOCKSMITHKIT:
+
+ // case CANTEEN:
+ // case CROWBAR:
+ // case JAR:
+ // case JAR_ELIXIR:
+ // case JAR_CREATURE_BLOOD:
if ( Item[usItemIndex].medical || Item[usItemIndex].canteen || Item[usItemIndex].medicalkit || Item[usItemIndex].locksmithkit || Item[usItemIndex].toolkit || Item[usItemIndex].crowbar || Item[usItemIndex].jar )
return(ITEM_SUITABILITY_ALWAYS);
+ //}
// If it's not BobbyRay, Tony, or Devin
@@ -931,11 +945,13 @@ UINT8 GetCurrentSuitabilityForItem( INT8 bArmsDealer, UINT16 usItemIndex, BOOLEA
// figure out the appropriate range of coolness based on player's maximum progress so far
- if ( bArmsDealer == bobbyRaysID )
+ if ( bArmsDealer == bobbyRaysID ) {
ubMinCoolness = 1;
- else
+ ubMaxCoolness = HighestPlayerProgressPercentage() / 10 + 1;
+ } else {
ubMinCoolness = HighestPlayerProgressPercentage() * armsDealerInfo[bArmsDealer].coolnessProgressRate / 100;
- ubMaxCoolness = ubMinCoolness + 1;
+ ubMaxCoolness = HighestPlayerProgressPercentage() * armsDealerInfo[bArmsDealer].coolnessProgressRate / 100 + 1;
+ }
//Madd: Bobby Ray's will sell higher coolness stuff if it's used, and may also have a better selection at the start of the game, depending on selection
if ( (bArmsDealer == bobbyRaysID || armsDealerInfo[bArmsDealer].useBRSetting) && gGameOptions.ubBobbyRay > BR_GOOD )
diff --git a/Tactical/Boxing.cpp b/Tactical/Boxing.cpp
index b897ed8b..8a7d7624 100644
--- a/Tactical/Boxing.cpp
+++ b/Tactical/Boxing.cpp
@@ -24,6 +24,7 @@
#include "Animation Data.h"
#include "Font Control.h"
#include "message.h"
+ #include "GameSettings.h" // added by SANDRO
#endif
INT32 gsBoxerGridNo[ NUM_BOXERS ] = { 11393, 11233, 11073 };
@@ -386,10 +387,24 @@ BOOLEAN PickABoxer( void )
pBoxer->stats.bDexterity = __min( 100, pBoxer->stats.bDexterity + gubBoxersRests * 5 );
pBoxer->stats.bAgility = __min( 100, pBoxer->stats.bAgility + gubBoxersRests * 5 );
pBoxer->stats.bLifeMax = __min( 100, pBoxer->stats.bLifeMax + gubBoxersRests * 5 );
+ // give the 2nd boxer Hand to hand - SANDRO
+ if ( (uiLoop == NUM_BOXERS - 2) )
+ {
+ if (gGameOptions.fNewTraitSystem) // SANDRO - traits
+ pBoxer->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
+ else
+ pBoxer->stats.ubSkillTraits[0] = HANDTOHAND_OT;
+ }
// give the 3rd boxer martial arts
if ( (uiLoop == NUM_BOXERS - 1) && pBoxer->ubBodyType == REGMALE )
{
- pBoxer->stats.ubSkillTrait1 = MARTIALARTS;
+ if (gGameOptions.fNewTraitSystem) // SANDRO - traits
+ {
+ pBoxer->stats.ubSkillTraits[0] = MARTIAL_ARTS_NT;
+ pBoxer->stats.ubSkillTraits[1] = MARTIAL_ARTS_NT;
+ }
+ else
+ pBoxer->stats.ubSkillTraits[0] = MARTIALARTS_OT;
}
return( TRUE );
}
diff --git a/Tactical/Campaign.cpp b/Tactical/Campaign.cpp
index 15bbbcd1..4179e3a7 100644
--- a/Tactical/Campaign.cpp
+++ b/Tactical/Campaign.cpp
@@ -300,6 +300,20 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
}
*/
+ // SANDRO - penalty for primitive people, they get lesser chance to gain point for certain skills
+ if ( gGameOptions.fNewTraitSystem && (usChance > 10) && (ubStat != EXPERAMT) && (pProfile->bCharacterTrait == CHAR_TRAIT_PRIMITIVE) )
+ {
+ switch (ubStat)
+ {
+ case WISDOMAMT:
+ case MEDICALAMT:
+ case EXPLODEAMT:
+ case MECHANAMT:
+ case LDRAMT:
+ usChance = max(1, (usChance - 10)); // -10% chance to gain the point
+ break;
+ }
+ }
// maximum possible usChance is 99%
@@ -451,6 +465,7 @@ void ChangeStat( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UINT8 ubSta
UINT8 ubMercMercIdValue = 0;
UINT16 usIncreaseValue = 0;
UINT16 usSubpointsPerPoint;
+ INT8 bDamagedStatToRaise = -1; // added by SANDRO
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel );
@@ -529,54 +544,63 @@ void ChangeStat( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UINT8 ubSta
if (pSoldier != NULL)
{
// build ptrs to appropriate soldiertype stat fields
+ // SANDRO - added a variable for stat repair
switch( ubStat )
{
case HEALTHAMT:
pbSoldierStatPtr = &( pSoldier->stats.bLifeMax );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeHealthTime);
usIncreaseValue = HEALTH_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_HEALTH;
break;
case AGILAMT:
pbSoldierStatPtr = &( pSoldier->stats.bAgility );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeAgilityTime);
usIncreaseValue = AGIL_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_AGILITY;
break;
case DEXTAMT:
pbSoldierStatPtr = &( pSoldier->stats.bDexterity );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeDexterityTime);
usIncreaseValue = DEX_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_DEXTERITY;
break;
case WISDOMAMT:
pbSoldierStatPtr = &( pSoldier->stats.bWisdom );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeWisdomTime);
usIncreaseValue = WIS_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_WISDOM;
break;
case MEDICALAMT:
pbSoldierStatPtr = &( pSoldier->stats.bMedical );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeMedicalTime);
usIncreaseValue = MED_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_MEDICAL;
break;
case EXPLODEAMT:
pbSoldierStatPtr = &( pSoldier->stats.bExplosive );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeExplosivesTime);
usIncreaseValue = EXP_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_EXPLOSIVES;
break;
case MECHANAMT:
pbSoldierStatPtr = &( pSoldier->stats.bMechanical );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeMechanicalTime);
usIncreaseValue = MECH_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_MECHANICAL;
break;
case MARKAMT:
pbSoldierStatPtr = &( pSoldier->stats.bMarksmanship );
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeMarksmanshipTime);
usIncreaseValue = MRK_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_MARKSMANSHIP;
break;
case EXPERAMT:
@@ -589,12 +613,14 @@ void ChangeStat( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UINT8 ubSta
pbSoldierStatPtr = &(pSoldier->stats.bStrength);
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeStrengthTime);
usIncreaseValue = STRENGTH_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_STRENGTH;
break;
case LDRAMT:
pbSoldierStatPtr = &( pSoldier->stats.bLeadership);
puiStatTimerPtr = &( pSoldier->timeChanges.uiChangeLeadershipTime);
usIncreaseValue = LDR_INCREASE;
+ bDamagedStatToRaise = DAMAGED_STAT_LEADERSHIP;
break;
}
}
@@ -633,6 +659,13 @@ void ChangeStat( MERCPROFILESTRUCT *pProfile, SOLDIERTYPE *pSoldier, UINT8 ubSta
// transfer over change to soldiertype structure
*pbSoldierStatPtr = *pbStatPtr;
+ // SANDRO - reduce damaged stat if this stat was increased normally
+ if ( fChangeTypeIncrease && (bDamagedStatToRaise != -1) )
+ {
+ if (pSoldier->ubCriticalStatDamage[ bDamagedStatToRaise ] > 0)
+ pSoldier->ubCriticalStatDamage[ bDamagedStatToRaise ] = max( 0, (pSoldier->ubCriticalStatDamage[ bDamagedStatToRaise ] - sPtsChanged));
+ }
+
// if it's a level gain, or sometimes for other stats
// ( except health; not only will it sound silly, but
// also we give points for health on sector traversal and this would
@@ -1016,6 +1049,7 @@ void HandleAnyStatChangesAfterAttack( void )
UINT32 CalcNewSalary(UINT32 uiOldSalary, BOOLEAN fIncrease, UINT32 uiMaxLimit)
{
UINT32 uiNewSalary;
+ FLOAT SalaryMultiplier = (FLOAT) ((gGameExternalOptions.gMercLevelUpSalaryIncreasePercentage / 100) + 1);
// if he was working for free, it's still free!
if (uiOldSalary == 0)
@@ -1025,11 +1059,11 @@ UINT32 CalcNewSalary(UINT32 uiOldSalary, BOOLEAN fIncrease, UINT32 uiMaxLimit)
if (fIncrease)
{
- uiNewSalary = (UINT32) (uiOldSalary * SALARY_CHANGE_PER_LEVEL);
+ uiNewSalary = (UINT32) (uiOldSalary * SalaryMultiplier);
}
else
{
- uiNewSalary = (UINT32) (uiOldSalary / SALARY_CHANGE_PER_LEVEL);
+ uiNewSalary = (UINT32) (uiOldSalary / SalaryMultiplier);
}
// round it off to a reasonable multiple
@@ -1247,26 +1281,41 @@ void HandleUnhiredMercDeaths( INT32 iProfileID )
// calculate this merc's (small) chance to get killed today (out of 1000)
sChance = 10 - pProfile->bExpLevel;
- switch (pProfile->bPersonalityTrait)
- {
- case FORGETFUL:
- case NERVOUS:
- case PSYCHO:
- // these guys are somewhat more likely to get killed (they have "problems")
- sChance += 2;
- break;
+ // SANDRO - certain traits makes us less likely to get killed
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ if (pProfile->bDisability != NO_DISABILITY)
+ {
+ sChance += 1;
+ }
+ if ( ProfileHasSkillTrait( iProfileID, SQUADLEADER_NT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, SQUADLEADER_NT );
+ if ( ProfileHasSkillTrait( iProfileID, TECHNICIAN_NT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, TECHNICIAN_NT );
+ if ( ProfileHasSkillTrait( iProfileID, DOCTOR_NT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, DOCTOR_NT );
+ if ( ProfileHasSkillTrait( iProfileID, STEALTHY_NT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, STEALTHY_NT );
+ if ( ProfileHasSkillTrait( iProfileID, BODYBUILDING_NT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, BODYBUILDING_NT );
+ if ( ProfileHasSkillTrait( iProfileID, SCOUTING_NT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, SCOUTING_NT );
}
-
- // stealthy guys are slightly less likely to get killed (they're careful)
- if (pProfile->bSkillTrait == STEALTHY)
- {
- sChance -= 1;
+ else
+ {
+ switch (pProfile->bDisability)
+ {
+ case FORGETFUL:
+ case NERVOUS:
+ case PSYCHO:
+ // these guys are somewhat more likely to get killed (they have "problems")
+ sChance += 2;
+ break;
+ }
+ // stealthy guys are slightly less likely to get killed (they're careful)
+ if ( ProfileHasSkillTrait( iProfileID, STEALTHY_OT ) > 0 )
+ sChance -= ProfileHasSkillTrait( iProfileID, STEALTHY_OT );
}
- if (pProfile->bSkillTrait2 == STEALTHY)
- {
- sChance -= 1;
- }
-
if ((INT16) PreRandom(1000) < sChance)
{
@@ -1278,7 +1327,8 @@ void HandleUnhiredMercDeaths( INT32 iProfileID )
gStrategicStatus.ubUnhiredMercDeaths++;
//send an email as long as the merc is from aim
- if( iProfileID < BIFF )
+ // if( iProfileID < BIFF )
+ if ( gProfilesAIM[ iProfileID ].ProfilId == iProfileID ) //new profiles by Jazz
{
//send an email to the player telling the player that a merc died
AddEmailWithSpecialData(MERC_DIED_ON_OTHER_ASSIGNMENT, MERC_DIED_ON_OTHER_ASSIGNMENT_LENGTH, AIM_SITE, GetWorldTotalMin(), 0, iProfileID );
@@ -1340,7 +1390,7 @@ UINT8 CurrentPlayerProgressPercentage(void)
// figure out the player's current mine income
- uiCurrentIncome = PredictIncomeFromPlayerMines();
+ uiCurrentIncome = PredictIncomeFromPlayerMines(FALSE);
// figure out the player's potential mine income
uiPossibleIncome = CalcMaxPlayerIncomeFromMines();
@@ -1453,8 +1503,11 @@ UINT8 CurrentPlayerProgressPercentage(void)
// And failsafes here. I'm not 100% sure about these though: I've never personally seen progress
// values go over 100, and I don't think they SHOULD... Can the game handle values > 100? Should it?
usCurrentProgress = __min(100, usCurrentProgress);
+ usCurrentProgress = __max(0, usCurrentProgress);
// No less than 0, or the minimum set in the INI file.
- usCurrentProgress = __max(gGameExternalOptions.ubGameProgressMinimum, __max(0, usCurrentProgress));
+ UINT32 uiMinProgress = __max(gGameExternalOptions.ubGameProgressMinimum, 0);
+ usCurrentProgress = __max(uiMinProgress, usCurrentProgress);
+
return((UINT8)usCurrentProgress);
}
diff --git a/Tactical/Campaign.h b/Tactical/Campaign.h
index 7caaa1c5..b45cb84f 100644
--- a/Tactical/Campaign.h
+++ b/Tactical/Campaign.h
@@ -36,7 +36,8 @@ extern UINT16 LEVEL_SUBPOINTS_TO_IMPROVE;
#define WORKIMPROVERATE 2 // increase to make working mercs improve more
#define TRAINIMPROVERATE 2 // increase to make training mercs improve more
-#define SALARY_CHANGE_PER_LEVEL 1.25 // Mercs salary is multiplied by this
+//tais: externalized the salary multiplier to gGameExternalOptions.gMercLevelUpSalaryIncreasePercentage
+//#define SALARY_CHANGE_PER_LEVEL 1.25 // Mercs salary is multiplied by this
#define MAX_DAILY_SALARY 30000 // must fit into an INT16 (32k)
#define MAX_LARGE_SALARY 500000 // no limit, really
diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp
index 748cef8d..12a45b9b 100644
--- a/Tactical/Civ Quotes.cpp
+++ b/Tactical/Civ Quotes.cpp
@@ -40,21 +40,22 @@
#define HIGH_TOWN_LOYALTY 80
#define CIV_QUOTE_HINT 99
-
-typedef struct
-{
- UINT8 ubNumEntries;
- UINT8 ubUnusedCurrentEntry;
-
-} CIV_QUOTE;
-
extern void CaptureTimerCallback( void );
BOOLEAN gfSurrendered = FALSE;
-CIV_QUOTE gCivQuotes[ NUM_CIV_QUOTES ];
+//--------------------------------------------------------------
+//Not used
+typedef struct
+{
+ UINT16 ubNumEntries;
+ UINT16 ubUnusedCurrentEntry; //Unused
-UINT8 gubNumEntries[ NUM_CIV_QUOTES ] =
+} CIV_QUOTE;
+
+CIV_QUOTE gCivQuotes[ NUM_CIV_QUOTES]; //Not used
+
+UINT16 gubNumEntries[ NUM_CIV_QUOTES ] = // Not used
{
15,
15,
@@ -111,7 +112,7 @@ UINT8 gubNumEntries[ NUM_CIV_QUOTES ] =
3,
3
};
-
+//--------------------------------------------------------------
typedef struct
{
@@ -131,20 +132,24 @@ CHAR16 gzCivQuote[ 320 ];
UINT16 gusCivQuoteBoxWidth;
UINT16 gusCivQuoteBoxHeight;
-
-void CopyNumEntriesIntoQuoteStruct( )
+//--------------------------------------------------------------
+void CopyNumEntriesIntoQuoteStruct( ) // Not used
{
INT32 cnt;
for ( cnt = 0; cnt < NUM_CIV_QUOTES; cnt++ )
- {
- gCivQuotes[ cnt ].ubNumEntries = gubNumEntries[ cnt ];
+ {
+
+ if (cnt <= 50)
+ gCivQuotes[ cnt ].ubNumEntries = gubNumEntries[ cnt ];
+ else
+ gCivQuotes[ cnt ].ubNumEntries = 15;
}
}
+//--------------------------------------------------------------
-
-BOOLEAN GetCivQuoteText( UINT8 ubCivQuoteID, UINT8 ubEntryID, STR16 zQuote )
+BOOLEAN GetCivQuoteText(UINT16 ubCivQuoteID, UINT16 ubEntryID, STR16 zQuote )
{
CHAR8 zFileName[164];
@@ -163,7 +168,10 @@ BOOLEAN GetCivQuoteText( UINT8 ubCivQuoteID, UINT8 ubEntryID, STR16 zQuote )
}
else
{
- sprintf( zFileName,"NPCDATA\\CIV%02d.edt",ubCivQuoteID );
+ if (ubCivQuoteID <= 9)
+ sprintf( zFileName,"NPCDATA\\CIV%02d.edt",ubCivQuoteID );
+ else
+ sprintf( zFileName,"NPCDATA\\CIV%d.edt",ubCivQuoteID );
}
CHECKF( FileExists( zFileName ) );
@@ -370,18 +378,18 @@ void QuoteOverlayClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
}
-void BeginCivQuote( SOLDIERTYPE *pCiv, UINT8 ubCivQuoteID, UINT8 ubEntryID, INT16 sX, INT16 sY )
+void BeginCivQuote( SOLDIERTYPE *pCiv, UINT16 ubCivQuoteID, UINT16 ubEntryID, INT16 sX, INT16 sY )
{
VIDEO_OVERLAY_DESC VideoOverlayDesc;
- CHAR16 zQuote[ 320 ];
-
+ CHAR16 zQuote[ 320 ];
+
// OK, do we have another on?
if ( gCivQuoteData.bActive )
{
// Delete?
ShutDownQuoteBox( TRUE );
}
-
+
// get text
if ( !GetCivQuoteText( ubCivQuoteID, ubEntryID, zQuote ) )
{
@@ -469,7 +477,7 @@ void BeginCivQuote( SOLDIERTYPE *pCiv, UINT8 ubCivQuoteID, UINT8 ubEntryID, INT1
}
-UINT8 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT8 *pubCivHintToUse, BOOLEAN fCanUseHints )
+UINT16 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT16 *pubCivHintToUse, BOOLEAN fCanUseHints )
{
UINT8 ubCivType;
INT8 bTownId;
@@ -478,11 +486,29 @@ UINT8 DetermineCivQuoteEntry( SOLDIERTYPE *pCiv, UINT8 *pubCivHintToUse, BOOLEAN
INT8 bCivHint;
INT8 bMineId;
BOOLEAN bMiners = FALSE;
-
+ UINT16 iCounter2;
+ UINT16 FileEDTQUoteID;
+
(*pubCivHintToUse) = 0;
ubCivType = GetCivType( pCiv );
-
+
+
+ for( iCounter2 = NON_CIV_GROUP; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
+ {
+ if (pCiv->ubCivilianGroup > QUEENS_CIV_GROUP && pCiv->ubCivilianGroup == iCounter2)
+ {
+ if ( pCiv->aiData.bNeutral )
+ {
+ return( FileEDTQUoteID = iCounter2*2 +10);
+ }
+ else
+ {
+ return( FileEDTQUoteID = iCounter2*2 + 11);
+ }
+ }
+ }
+
if ( ubCivType == CIV_TYPE_ENEMY )
{
// Determine what type of quote to say...
@@ -778,19 +804,23 @@ void HandleCivQuote( )
void StartCivQuote( SOLDIERTYPE *pCiv )
{
- UINT8 ubCivQuoteID;
+ UINT16 ubCivQuoteID;
INT16 sX, sY;
- UINT8 ubEntryID = 0;
+ UINT16 ubEntryID = 0;
INT16 sScreenX, sScreenY;
- UINT8 ubCivHintToUse;
-
+ UINT16 ubCivHintToUse;
+ UINT16 CivQuoteDelta = 0;
+
+ UINT16 ubCivQuoteID2;
+ UINT16 RandomVal;
+
// ATE: Check for old quote.....
// This could have been stored on last attempt...
if ( pCiv->bCurrentCivQuote == CIV_QUOTE_HINT )
{
// Determine which quote to say.....
- // CAN'T USE HINTS, since we just did one...
- pCiv->bCurrentCivQuote = -1;
+ // CAN'T USE HINTS, since we just did one...
+ pCiv->bCurrentCivQuote = -1;
pCiv->bCurrentCivQuoteDelta = 0;
ubCivQuoteID = DetermineCivQuoteEntry( pCiv, &ubCivHintToUse, FALSE );
}
@@ -799,7 +829,23 @@ void StartCivQuote( SOLDIERTYPE *pCiv )
// Determine which quote to say.....
ubCivQuoteID = DetermineCivQuoteEntry( pCiv, &ubCivHintToUse, TRUE );
}
-
+
+ if (ubCivQuoteID == CIV_QUOTE_ADULTS_REBELS || ubCivQuoteID == CIV_QUOTE_KIDS_REBELS || ubCivQuoteID == CIV_QUOTE_ENEMY_OFFER_SURRENDER )
+ {
+ RandomVal = 5;
+ }
+ else if (ubCivQuoteID == CIV_QUOTE_PC_MARRIED)
+ {
+ RandomVal = 2;
+ }
+ else if (ubCivQuoteID == CIV_QUOTE_HICKS_SEE_US_AT_NIGHT)
+ {
+ RandomVal = 3;
+ }
+ else
+ RandomVal = 15;
+
+
// Determine entry id
// ATE: Try and get entry from soldier pointer....
if ( ubCivQuoteID != CIV_QUOTE_HINT )
@@ -807,19 +853,23 @@ void StartCivQuote( SOLDIERTYPE *pCiv )
if ( pCiv->bCurrentCivQuote == -1 )
{
// Pick random one
- pCiv->bCurrentCivQuote = (INT8)Random( gCivQuotes[ ubCivQuoteID ].ubNumEntries - 2 );
+ //pCiv->bCurrentCivQuote = (INT8)Random( gCivQuotes[ ubCivQuoteID ].ubNumEntries - 2 );
+ ubCivQuoteID2 = Random(RandomVal-2);
pCiv->bCurrentCivQuoteDelta = 0;
}
- ubEntryID = pCiv->bCurrentCivQuote + pCiv->bCurrentCivQuoteDelta;
+ //ubEntryID = pCiv->bCurrentCivQuote + pCiv->bCurrentCivQuoteDelta;
+ ubEntryID = ubCivQuoteID2 + pCiv->bCurrentCivQuoteDelta;
}
else
{
- ubEntryID = ubCivHintToUse;
+ ubEntryID =ubCivHintToUse;
// ATE: set value for quote ID.....
- pCiv->bCurrentCivQuote = ubCivQuoteID;
- pCiv->bCurrentCivQuoteDelta = ubEntryID;
+ //pCiv->bCurrentCivQuote = ubCivQuoteID;
+ ubCivQuoteID2 = ubCivQuoteID;
+ CivQuoteDelta = ubEntryID;
+ //pCiv->bCurrentCivQuoteDelta = ubEntryID;
}
@@ -835,20 +885,26 @@ void StartCivQuote( SOLDIERTYPE *pCiv )
// Increment use
if ( ubCivQuoteID != CIV_QUOTE_HINT )
{
- pCiv->bCurrentCivQuoteDelta++;
-
+ //pCiv->bCurrentCivQuoteDelta++;
+ CivQuoteDelta++;
+ /*
if ( pCiv->bCurrentCivQuoteDelta == 2 )
{
pCiv->bCurrentCivQuoteDelta = 0;
}
+ */
+ if ( CivQuoteDelta == 2 )
+ {
+ CivQuoteDelta = 0;
+ }
+
+
}
}
-
void InitCivQuoteSystem( )
{
- memset( &gCivQuotes, 0, sizeof( gCivQuotes ) );
- CopyNumEntriesIntoQuoteStruct( );
+ memset( &gCivQuotes, 0, sizeof( gCivQuotes ) ); //Not used
memset( &gCivQuoteData, 0, sizeof( gCivQuoteData ) );
gCivQuoteData.bActive = FALSE;
@@ -856,12 +912,13 @@ void InitCivQuoteSystem( )
gCivQuoteData.iDialogueBox = -1;
}
-
+//--------------------------------------------------------------
+//is allowed remove. Not used and remove from SaveLoadGame.cpp.
BOOLEAN SaveCivQuotesToSaveGameFile( HWFILE hFile )
{
UINT32 uiNumBytesWritten;
- FileWrite( hFile, &gCivQuotes, sizeof( gCivQuotes ), &uiNumBytesWritten );
+ FileWrite( hFile, &gCivQuotes, sizeof( gCivQuotes), &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( gCivQuotes ) )
{
return( FALSE );
@@ -870,7 +927,7 @@ BOOLEAN SaveCivQuotesToSaveGameFile( HWFILE hFile )
return( TRUE );
}
-
+//is allowed remove. Not used and remove from SaveLoadGame.cpp.
BOOLEAN LoadCivQuotesFromLoadGameFile( HWFILE hFile )
{
UINT32 uiNumBytesRead;
@@ -881,7 +938,140 @@ BOOLEAN LoadCivQuotesFromLoadGameFile( HWFILE hFile )
return( FALSE );
}
- CopyNumEntriesIntoQuoteStruct( );
+ CopyNumEntriesIntoQuoteStruct( ); //Not used
return( TRUE );
}
+//--------------------------------------------------------------
+
+// SANDRO - soldier taunts
+void StartEnemyTaunt( SOLDIERTYPE *pCiv, INT8 iTauntType )
+{
+ INT16 sX, sY;
+ UINT8 ubEntryID = 0;
+ INT16 sScreenX, sScreenY;
+ UINT16 iTauntNumber;
+ STR16 sTauntText;
+ VIDEO_OVERLAY_DESC VideoOverlayDesc;
+ CHAR16 gzTauntQuote[ 320 ];
+
+ // if we have a different quote on, return, this one is not important
+ if ( gCivQuoteData.bActive )
+ {
+ return;
+ }
+
+ switch(iTauntType)
+ {
+ case TAUNT_FIRE_GUN:
+ iTauntNumber = Random(15);
+ sTauntText = sEnemyTauntsFireGun[iTauntNumber];
+ break;
+ case TAUNT_FIRE_LAUNCHER:
+ iTauntNumber = Random(4);
+ sTauntText = sEnemyTauntsFireLauncher[iTauntNumber];
+ break;
+ case TAUNT_THROW:
+ iTauntNumber = Random(7);
+ sTauntText = sEnemyTauntsThrow[iTauntNumber];
+ break;
+ case TAUNT_CHARGE_KNIFE:
+ iTauntNumber = Random(5);
+ sTauntText = sEnemyTauntsChargeKnife[iTauntNumber];
+ break;
+ case TAUNT_RUN_AWAY:
+ iTauntNumber = Random(7);
+ sTauntText = sEnemyTauntsRunAway[iTauntNumber];
+ break;
+ case TAUNT_SEEK_NOISE:
+ iTauntNumber = Random(4);
+ sTauntText = sEnemyTauntsSeekNoise[iTauntNumber];
+ break;
+ case TAUNT_ALERT:
+ iTauntNumber = Random(3);
+ sTauntText = sEnemyTauntsAlert[iTauntNumber];
+ break;
+ case TAUNT_GOT_HIT:
+ iTauntNumber = Random(7);
+ sTauntText = sEnemyTauntsGotHit[iTauntNumber];
+ break;
+ default:
+ return;
+ break;
+ }
+
+ // Determine location...
+ // Get location of civ on screen.....
+ GetSoldierScreenPos( pCiv, &sScreenX, &sScreenY );
+ sX = sScreenX;
+ sY = sScreenY;
+
+#ifdef TAIWANESE
+ swprintf( gzTauntQuote, L"%s", sTauntText );
+#else
+ swprintf( gzTauntQuote, L"\"%s\"", sTauntText );
+#endif
+
+ // Create video oeverlay....
+ memset( &VideoOverlayDesc, 0, sizeof( VIDEO_OVERLAY_DESC ) );
+
+ // Prepare text box
+ gCivQuoteData.iDialogueBox = PrepareMercPopupBox( gCivQuoteData.iDialogueBox , BASIC_MERC_POPUP_BACKGROUND, BASIC_MERC_POPUP_BORDER, gzTauntQuote, DIALOGUE_DEFAULT_WIDTH, 0, 0, 0, &gusCivQuoteBoxWidth, &gusCivQuoteBoxHeight );
+
+ // OK, find center for box......
+ sX = sX - ( gusCivQuoteBoxWidth / 2 );
+ sY = sY - ( gusCivQuoteBoxHeight / 2 );
+
+ // OK, limit to screen......
+ {
+ if ( sX < 0 )
+ {
+ sX = 0;
+ }
+
+ // CHECK FOR LEFT/RIGHT
+ if ( ( sX + gusCivQuoteBoxWidth ) > SCREEN_WIDTH )
+ {
+ sX = SCREEN_WIDTH - gusCivQuoteBoxWidth;
+ }
+
+ // Now check for top
+ if ( sY < gsVIEWPORT_WINDOW_START_Y )
+ {
+ sY = gsVIEWPORT_WINDOW_START_Y;
+ }
+
+ // Check for bottom
+ if ( ( sY + gusCivQuoteBoxHeight ) > (SCREEN_HEIGHT - INV_INTERFACE_HEIGHT))
+ {
+ sY = (SCREEN_HEIGHT - INV_INTERFACE_HEIGHT) - gusCivQuoteBoxHeight;
+ }
+ }
+
+ VideoOverlayDesc.sLeft = sX;
+ VideoOverlayDesc.sTop = sY;
+ VideoOverlayDesc.sRight = VideoOverlayDesc.sLeft + gusCivQuoteBoxWidth;
+ VideoOverlayDesc.sBottom = VideoOverlayDesc.sTop + gusCivQuoteBoxHeight;
+ VideoOverlayDesc.sX = VideoOverlayDesc.sLeft;
+ VideoOverlayDesc.sY = VideoOverlayDesc.sTop;
+ VideoOverlayDesc.BltCallback = RenderCivQuoteBoxOverlay;
+
+ gCivQuoteData.iVideoOverlay = RegisterVideoOverlay( 0, &VideoOverlayDesc );
+
+
+ //Define main region
+ MSYS_DefineRegion( &(gCivQuoteData.MouseRegion), VideoOverlayDesc.sLeft, VideoOverlayDesc.sTop, VideoOverlayDesc.sRight, VideoOverlayDesc.sBottom, MSYS_PRIORITY_HIGHEST,
+ CURSOR_NORMAL, MSYS_NO_CALLBACK, QuoteOverlayClickCallback );
+ // Add region
+ MSYS_AddRegion( &(gCivQuoteData.MouseRegion) );
+
+
+ gCivQuoteData.bActive = TRUE;
+
+ gCivQuoteData.uiTimeOfCreation = GetJA2Clock( );
+
+ gCivQuoteData.uiDelayTime = FindDelayForString( gzCivQuote ) + 1500;
+
+ gCivQuoteData.pCiv = pCiv;
+
+}
\ No newline at end of file
diff --git a/Tactical/Civ Quotes.h b/Tactical/Civ Quotes.h
index 2847b0ae..9afe8641 100644
--- a/Tactical/Civ Quotes.h
+++ b/Tactical/Civ Quotes.h
@@ -11,8 +11,8 @@
enum
{
- CIV_QUOTE_ADULTS_BEGGING,
- CIV_QUOTE_KIDS_BEGGING,
+ CIV_QUOTE_ADULTS_BEGGING, //CIV00.EDT
+ CIV_QUOTE_KIDS_BEGGING,
CIV_QUOTE_ADULTS_RECENT_BUG_ATTACK,
CIV_QUOTE_KIDS_RECENT_BUG_ATTACK,
CIV_QUOTE_ADULTS_BUG_EXTERMINATED_X_TIME,
@@ -22,7 +22,7 @@ enum
CIV_QUOTE_ADULTS_HIGH_LOYALTY,
CIV_QUOTE_KIDS_HIGH_LOYALTY,
- CIV_QUOTE_ADULTS_ALL_PURPOSE,
+ CIV_QUOTE_ADULTS_ALL_PURPOSE, //CIV10.EDT
CIV_QUOTE_KIDS_ALL_PURPOSE,
CIV_QUOTE_ADULTS_LIBREATED_FIRST_TIME,
CIV_QUOTE_KIDS_LIBREATED_FIRST_TIME,
@@ -33,7 +33,7 @@ enum
CIV_QUOTE_GOONS_FRIENDLY,
CIV_QUOTE_GOONS_ENEMIES,
- CIV_QUOTE_ADULTS_REBELS,
+ CIV_QUOTE_ADULTS_REBELS, //CIV20.EDT
CIV_QUOTE_KIDS_REBELS,
CIV_QUOTE_GREEN_MILITIA,
CIV_QUOTE_MEDIUM_MILITIA,
@@ -44,7 +44,7 @@ enum
CIV_QUOTE_ENEMY_THREAT,
CIV_QUOTE_ENEMY_ELITE,
- CIV_QUOTE_ADULTS_COWER,
+ CIV_QUOTE_ADULTS_COWER, //CIV30.EDT
CIV_QUOTE_KIDS_COWER,
CIV_QUOTE_PC_MARRIED,
CIV_QUOTE_KID_SLAVES,
@@ -54,22 +54,25 @@ enum
CIV_QUOTE_ENEMY_OFFER_SURRENDER,
CIV_QUOTE_HICKS_SEE_US_AT_NIGHT,
CIV_QUOTE_DEIDRANNA_DEAD,
-
- CIV_QUOTE_40,
- CIV_QUOTE_41,
- CIV_QUOTE_42,
- CIV_QUOTE_43,
- CIV_QUOTE_44,
- CIV_QUOTE_45,
- CIV_QUOTE_46,
- CIV_QUOTE_47,
- CIV_QUOTE_48,
- CIV_QUOTE_49,
-
+
+ CIV_QUOTE_NEW = CIV_QUOTE_DEIDRANNA_DEAD + 1000, // 500 reserved
+
NUM_CIV_QUOTES
};
+enum //enemy taunts - SANDRO
+{
+ TAUNT_FIRE_GUN,
+ TAUNT_FIRE_LAUNCHER,
+ TAUNT_THROW,
+ TAUNT_CHARGE_KNIFE,
+ TAUNT_RUN_AWAY,
+ TAUNT_SEEK_NOISE,
+ TAUNT_ALERT,
+ TAUNT_GOT_HIT
+};
+void StartEnemyTaunt( SOLDIERTYPE *pCiv, INT8 iTauntType ); //enemy taunts - SANDRO
void InitCivQuoteSystem( );
@@ -84,6 +87,6 @@ BOOLEAN LoadCivQuotesFromLoadGameFile( HWFILE hFile );
BOOLEAN ShutDownQuoteBoxIfActive( );
-void BeginCivQuote( SOLDIERTYPE *pCiv, UINT8 ubCivQuoteID, UINT8 ubEntryID, INT16 sX, INT16 sY );
+void BeginCivQuote( SOLDIERTYPE *pCiv, UINT16 ubCivQuoteID, UINT16 ubEntryID, INT16 sX, INT16 sY );
#endif
\ No newline at end of file
diff --git a/Tactical/Dialogue Control.cpp b/Tactical/Dialogue Control.cpp
index a7499597..2c500356 100644
--- a/Tactical/Dialogue Control.cpp
+++ b/Tactical/Dialogue Control.cpp
@@ -55,6 +55,7 @@
#include "end game.h"
#include "los.h"
#include "qarray.h"
+ #include "Soldier Profile.h"
#endif
#include
#include "Auto Resolve.h"
@@ -83,7 +84,7 @@ class SOLDIERTYPE;
#define DIALOGUE_DEFAULT_SUBTITLE_WIDTH 200
#define TEXT_DELAY_MODIFIER 60
-
+SOUND_PROFILE_VALUES gSoundProfileValue[NUM_PROFILES];
typedef struct
{
@@ -114,16 +115,19 @@ extern BOOLEAN gfWaitingForTriggerTimer;
BOOLEAN fExternFacesLoaded = FALSE;
-UINT32 uiExternalStaticNPCFaces[ NUMBER_OF_EXTERNAL_NPC_FACES ];
-UINT32 uiExternalFaceProfileIds[ NUMBER_OF_EXTERNAL_NPC_FACES ]=
-{
- 97,
- 106,
- 148,
- 156,
- 157,
- 158,
-};
+
+// head miners' external profile ids have been moved to lua script
+std::vector uiExternalStaticNPCFaces;
+//UINT32 uiExternalStaticNPCFaces[ NUMBER_OF_EXTERNAL_NPC_FACES ];
+//UINT32 uiExternalFaceProfileIds[ NUMBER_OF_EXTERNAL_NPC_FACES ]=
+//{
+// 97,
+// 106,
+// 148,
+// 156,
+// 157,
+// 158,
+//};
UINT8 gubMercValidPrecedentQuoteID[ NUMBER_VALID_MERC_PRECEDENT_QUOTES ] =
{ 80, 81, 82, 83, 86, 87, 88, 95, 97, 99, 100, 101, 102 };
@@ -302,10 +306,16 @@ void InitalizeStaticExternalNPCFaces( void )
fExternFacesLoaded = TRUE;
- for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
- {
- uiExternalStaticNPCFaces[ iCounter ] = ( UINT32 )InitFace( ( UINT8 )( uiExternalFaceProfileIds[ iCounter ] ), NOBODY, FACE_FORCE_SMALL );
- }
+
+ //
+ // Code for loading miners' faces has been moved to LuaMines::InitMinerFaces ...
+ //
+ //for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
+ //{
+ // uiExternalStaticNPCFaces[ iCounter ] = ( UINT32 )InitFace( ( UINT8 )( uiExternalFaceProfileIds[ iCounter ] ), NOBODY, FACE_FORCE_SMALL );
+ //}
+ // ... put Skyrider's face at index 0
+ uiExternalStaticNPCFaces.push_back(( UINT32 )InitFace( ( UINT8 )( SKYRIDER ), NOBODY, FACE_FORCE_SMALL ));
return;
}
@@ -322,10 +332,16 @@ void ShutdownStaticExternalNPCFaces( void )
fExternFacesLoaded = FALSE;
// remove all external npc faces
- for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
+ //for( iCounter = 0; iCounter < NUMBER_OF_EXTERNAL_NPC_FACES; iCounter++ )
+ //{
+ // DeleteFace( uiExternalStaticNPCFaces[ iCounter ] );
+ //}
+ for (std::vector::iterator face = uiExternalStaticNPCFaces.begin();
+ face != uiExternalStaticNPCFaces.end(); ++face)
{
- DeleteFace( uiExternalStaticNPCFaces[ iCounter ] );
+ DeleteFace(*face);
}
+ uiExternalStaticNPCFaces.clear();
}
@@ -1599,11 +1615,11 @@ BOOLEAN ExecuteCharacterDialogue( UINT8 ubCharacterNum, UINT16 usQuoteNum, INT32
// now being used in a different way...
/*
if ( ( (usQuoteNum == QUOTE_PERSONALITY_TRAIT &&
- (gMercProfiles[ubCharacterNum].bPersonalityTrait == FORGETFUL ||
- gMercProfiles[ubCharacterNum].bPersonalityTrait == CLAUSTROPHOBIC ||
- gMercProfiles[ubCharacterNum].bPersonalityTrait == NERVOUS ||
- gMercProfiles[ubCharacterNum].bPersonalityTrait == NONSWIMMER ||
- gMercProfiles[ubCharacterNum].bPersonalityTrait == FEAR_OF_INSECTS))
+ (gMercProfiles[ubCharacterNum].bDisability == FORGETFUL ||
+ gMercProfiles[ubCharacterNum].bDisability == CLAUSTROPHOBIC ||
+ gMercProfiles[ubCharacterNum].bDisability == NERVOUS ||
+ gMercProfiles[ubCharacterNum].bDisability == NONSWIMMER ||
+ gMercProfiles[ubCharacterNum].bDisability == FEAR_OF_INSECTS))
//usQuoteNum == QUOTE_STARTING_TO_WHINE ||
#ifdef JA2BETAVERSION
|| usQuoteNum == QUOTE_WHINE_EQUIPMENT) && (guiCurrentScreen != QUEST_DEBUG_SCREEN) )
@@ -1750,11 +1766,14 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
// sprintf( zFileName,"NPC_SPEECH\\g_%03d_%03d.wav",ubCharacterNum,usQuoteNum );
// }
// #else
+ if ( gSoundProfileValue[ubCharacterNum].EnabledSound == TRUE )
+ {
sprintf( zFileName,"NPC_SPEECH\\d_%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
if ( !FileExists( zFileName ) )
{
sprintf( zFileName,"NPC_SPEECH\\d_%03d_%03d.wav",ubCharacterNum,usQuoteNum );
}
+ }
// #endif
}
else
@@ -1763,7 +1782,9 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
sprintf( zFileName,"NPCDATA\\d_%03d.EDT", ubCharacterNum );
}
}
- else if ( ubCharacterNum >= FIRST_RPC && ubCharacterNum < GASTON &&
+ //else if ( ubCharacterNum >= FIRST_RPC && ubCharacterNum < GASTON &&
+ //new profiles by Jazz
+ else if ( ( gProfilesRPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesNPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesVehicle[ubCharacterNum].ProfilId == ubCharacterNum ) &&
( !( gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
|| ProfileCurrentlyTalkingInDialoguePanel( ubCharacterNum )
|| (gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_FORCENPCQUOTE) )
@@ -1786,11 +1807,14 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
if ( fWavFile )
{
- // Lesh: patch to allow playback ogg speech files
- sprintf( zFileName,"NPC_SPEECH\\%03d_%03d.ogg",ubFileNumID,usQuoteNum );
- if ( !FileExists( zFileName ) )
+ if ( gSoundProfileValue[ubFileNumID].EnabledSound == TRUE )
{
- sprintf( zFileName,"NPC_SPEECH\\%03d_%03d.wav",ubFileNumID,usQuoteNum );
+ // Lesh: patch to allow playback ogg speech files
+ sprintf( zFileName,"NPC_SPEECH\\%03d_%03d.ogg",ubFileNumID,usQuoteNum );
+ if ( !FileExists( zFileName ) )
+ {
+ sprintf( zFileName,"NPC_SPEECH\\%03d_%03d.wav",ubFileNumID,usQuoteNum );
+ }
}
}
else
@@ -1804,8 +1828,12 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
if ( fWavFile )
{
#ifdef RUSSIAN
- if( ubCharacterNum >= FIRST_RPC && ubCharacterNum < GASTON && gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
+ // if( ubCharacterNum >= FIRST_RPC && ubCharacterNum < GASTON && gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
+ //new profiles by Jazz
+ if ( ( gProfilesRPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesNPC[ubCharacterNum].ProfilId == ubCharacterNum || gProfilesVehicle[ubCharacterNum].ProfilId == ubCharacterNum ) && gMercProfiles[ ubCharacterNum ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED )
{
+ if ( gSoundProfileValue[ubCharacterNum].EnabledSound == TRUE )
+ {
sprintf( zFileName,"SPEECH\\r_%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
if ( !FileExists( zFileName ) )
{
@@ -1821,15 +1849,20 @@ CHAR8 *GetDialogueDataFilename( UINT8 ubCharacterNum, UINT16 usQuoteNum, BOOLEAN
}
//
}
+ }
}
else
#endif
- { // build name of wav file (characternum + quotenum)
+ {
+ if ( gSoundProfileValue[ubCharacterNum].EnabledSound == TRUE )
+ {
+ // build name of wav file (characternum + quotenum)
sprintf( zFileName,"SPEECH\\%03d_%03d.ogg",ubCharacterNum,usQuoteNum );
if ( !FileExists( zFileName ) )
{
sprintf( zFileName,"SPEECH\\%03d_%03d.wav",ubCharacterNum,usQuoteNum );
}
+ }
}
}
else
@@ -2636,12 +2669,12 @@ void SayQuote58FromNearbyMercInSector( INT32 sGridNo, INT8 bDistance, UINT16 usQ
SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, 0, 0, TRUE ) )
{
// ATE: This is to check gedner for this quote...
- if ( QuoteExp_GenderCode[ pTeamSoldier->ubProfile ] == 0 && bSex == FEMALE )
+ if ( QuoteExp[ pTeamSoldier->ubProfile ].QuoteExpGenderCode == 0 && bSex == FEMALE )
{
continue;
}
- if ( QuoteExp_GenderCode[ pTeamSoldier->ubProfile ] == 1 && bSex == MALE )
+ if ( QuoteExp[ pTeamSoldier->ubProfile ].QuoteExpGenderCode == 1 && bSex == MALE )
{
continue;
}
diff --git a/Tactical/Dialogue Control.h b/Tactical/Dialogue Control.h
index 0c704032..9039cb78 100644
--- a/Tactical/Dialogue Control.h
+++ b/Tactical/Dialogue Control.h
@@ -3,6 +3,17 @@
#include "faces.h"
#include "gamescreen.h"
+#include "soldier profile type.h"
+#include
+
+typedef struct
+{
+ UINT16 uiIndex; // add
+ BOOLEAN EnabledSound;
+
+} SOUND_PROFILE_VALUES;
+
+extern SOUND_PROFILE_VALUES gSoundProfileValue[NUM_PROFILES];
// An enumeration for dialog quotes
enum DialogQuoteIDs
@@ -209,12 +220,12 @@ enum DialogQuoteIDs
enum{
SKYRIDER_EXTERNAL_FACE =0,
- MINER_FRED_EXTERNAL_FACE,
- MINER_MATT_EXTERNAL_FACE,
- MINER_OSWALD_EXTERNAL_FACE,
- MINER_CALVIN_EXTERNAL_FACE,
- MINER_CARL_EXTERNAL_FACE,
- NUMBER_OF_EXTERNAL_NPC_FACES,
+ //MINER_FRED_EXTERNAL_FACE,
+ //MINER_MATT_EXTERNAL_FACE,
+ //MINER_OSWALD_EXTERNAL_FACE,
+ //MINER_CALVIN_EXTERNAL_FACE,
+ //MINER_CARL_EXTERNAL_FACE,
+ //NUMBER_OF_EXTERNAL_NPC_FACES,
};
@@ -225,8 +236,9 @@ enum{
UPDATE_BOX_REASON_SHOW_BOX,
};
-extern UINT32 uiExternalStaticNPCFaces[ ];
-extern UINT32 uiExternalFaceProfileIds[ ];
+//extern UINT32 uiExternalStaticNPCFaces[ ];
+extern std::vector uiExternalStaticNPCFaces;
+//extern UINT32 uiExternalFaceProfileIds[ ];
// Functions for handling dialogue Q
BOOLEAN InitalizeDialogueControl();
diff --git a/Tactical/DisplayCover.cpp b/Tactical/DisplayCover.cpp
index 7734241d..72038389 100644
--- a/Tactical/DisplayCover.cpp
+++ b/Tactical/DisplayCover.cpp
@@ -40,21 +40,22 @@ class SOLDIERTYPE;
//******* Local Defines **************************************************
+enum COVER_VALUES
+{
+ INVALID_COVER=-1,
+ NO_COVER=0,
+ MIN_COVER=1,
+ MED_COVER=2,
+ MAX_COVER=3
+};
+
struct CoverCell
{
INT32 sGridNo;
INT8 bCover;
BOOLEAN fInverseColor;
- CoverCell() : sGridNo(NOWHERE), bCover(-1), fInverseColor(FALSE) {}
-};
-
-enum COVER_VALUES
-{
- NO_COVER=0,
- MIN_COVER=1,
- MED_COVER=2,
- MAX_COVER=3
+ CoverCell() : sGridNo(NOWHERE), bCover(INVALID_COVER), fInverseColor(FALSE) {}
};
enum COVER_DRAW_MODE {
@@ -63,35 +64,28 @@ enum COVER_DRAW_MODE {
COVER_DRAW_ENEMY_VIEW
};
-COVER_DRAW_MODE gubDrawMode = COVER_DRAW_OFF;
-
const UINT8 animArr[3] = {
ANIM_PRONE,
ANIM_CROUCH,
ANIM_STAND
};
-//****** Global Variables *****************************************
-
-// yea way too big... but some bytes more memory is cheap, as well as some extra loops
-// PS: brainscells arn't cheap ;)
-#define COVER_X_CELLS WORLD_COLS
-#define COVER_Y_CELLS WORLD_ROWS
+// yea way too big... but some bytes more memory is cheap
+#define COVER_X_CELLS WORLD_COLS_MAX
+#define COVER_Y_CELLS WORLD_ROWS_MAX
#define COVER_Z_CELLS 2 // roof or no roof
+//****** Local Variables *********************************************
+
INT16 gsMinCellX, gsMinCellY, gsMaxCellX, gsMaxCellY = -1;
-// WANNE - BMP: COVER_X_CELLS, COVER_Y_CELLS, have to be constants,
-// so I set them to 2000 (for rows and cols). In normal map it is 160
-
-//CoverCell gCoverViewArea[ COVER_X_CELLS ][ COVER_Y_CELLS ][ COVER_Z_CELLS ];
-CoverCell gCoverViewArea[ 2000 ][ 2000 ][ COVER_Z_CELLS ];
+CoverCell gCoverViewArea[ COVER_X_CELLS ][ COVER_Y_CELLS ][ COVER_Z_CELLS ];
DWORD guiCoverNextUpdateTime = 0;
-//******* Function Prototypes ***************************************
+COVER_DRAW_MODE gubDrawMode = COVER_DRAW_OFF;
-void SwitchCoverDrawMode();
+//******* Local Function Prototypes ***********************************
CHAR16* GetTerrainName( const UINT8& ubTerrainType );
@@ -116,30 +110,71 @@ BOOLEAN HasAdjTile( const INT32& ubX, const INT32& ubY );
//******* Functions **************************************************
-// TODO: internationalize
+///BEGIN key binding functions
+void SwitchToMercView()
+{
+ if (gubDrawMode == COVER_DRAW_MERC_VIEW)
+ return;
+
+ gubDrawMode = COVER_DRAW_MERC_VIEW;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzDisplayCoverText[DC_MSG__COVER_DRAW_MERC_VIEW]);
+ DisplayCover(TRUE);
+}
+
+void SwitchToEnemyView()
+{
+ if (gubDrawMode == COVER_DRAW_ENEMY_VIEW)
+ return;
+
+ gubDrawMode = COVER_DRAW_ENEMY_VIEW;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzDisplayCoverText[DC_MSG__COVER_DRAW_ENEMY_VIEW]);
+ DisplayCover(TRUE);
+}
+
+void SwitchViewOff()
+{
+ if (gubDrawMode == COVER_DRAW_OFF)
+ return;
+
+ gubDrawMode = COVER_DRAW_OFF;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzDisplayCoverText[DC_MSG__COVER_DRAW_OFF]);
+ DisplayCover(TRUE);
+}
+
+void ToggleEnemyView()
+{
+ if (gubDrawMode == COVER_DRAW_ENEMY_VIEW) {
+ SwitchViewOff();
+ } else {
+ SwitchToEnemyView();
+ }
+}
+
+void ToggleMercView()
+{
+ if (gubDrawMode == COVER_DRAW_MERC_VIEW) {
+ SwitchViewOff();
+ } else {
+ SwitchToMercView();
+ }
+}
+
void SwitchCoverDrawMode()
{
- CHAR16 zDebugString[512];
-
switch(gubDrawMode)
{
case COVER_DRAW_OFF:
- swprintf( zDebugString, gzDisplayCoverText[DC_MSG__COVER_DRAW_MERC_VIEW] );
- gubDrawMode = COVER_DRAW_MERC_VIEW;
+ SwitchToMercView();
break;
case COVER_DRAW_MERC_VIEW:
- swprintf( zDebugString, gzDisplayCoverText[DC_MSG__COVER_DRAW_ENEMY_VIEW] );
- gubDrawMode = COVER_DRAW_ENEMY_VIEW;
+ SwitchToEnemyView();
break;
default:
- swprintf( zDebugString, gzDisplayCoverText[DC_MSG__COVER_DRAW_OFF] );
- gubDrawMode = COVER_DRAW_OFF;
+ SwitchViewOff();
break;
}
-
- DisplayCover(TRUE);
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zDebugString );
}
+///END key binding functions
void GetGridNoForViewPort( const INT32& ubX, const INT32& ubY, INT32& sGridNo )
{
@@ -472,10 +507,7 @@ void CalculateCoverForSoldier( SOLDIERTYPE* pSoldier, const INT32& sTargetGridNo
pbPublOL = gbPublicOpplist[ OUR_TEAM ] + pOpponent->ubID;
// if this opponent is unknown personally and publicly
- if( *pbPersOL != SEEN_CURRENTLY &&
- *pbPersOL != SEEN_THIS_TURN &&
- *pbPublOL != SEEN_CURRENTLY &&
- *pbPublOL != SEEN_THIS_TURN )
+ if( *pbPersOL != SEEN_CURRENTLY && *pbPublOL != SEEN_CURRENTLY )
{
continue; // next merc
}
@@ -503,7 +535,7 @@ void CalculateCoverFromSoldier( SOLDIERTYPE* pFromSoldier, const INT32& sTargetG
if (pToSoldier == NULL) {
usAdjustedSight = usSightLimit;
} else {
- usAdjustedSight = usSightLimit + usSightLimit * GetSightAdjustment( pToSoldier, sTargetGridNo, ubStance ) /100;
+ usAdjustedSight = usSightLimit + usSightLimit * GetSightAdjustment( pToSoldier, sTargetGridNo, (INT8) fRoof, ubStance ) /100;
}
if ( SoldierToVirtualSoldierLineOfSightTest( pFromSoldier, sTargetGridNo, (INT8) fRoof, ubStance, FALSE, usAdjustedSight ) != 0 )
@@ -526,17 +558,20 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
{
UINT8 ubLightLevel = LightTrueLevel(sTargetGridNo, gsInterfaceLevel);
- UINT8 ubBrightness = 100 * (SHADE_MIN - ubLightLevel)/SHADE_MIN; // percentage
+ UINT8 ubBrightness = 100 - 100 * (ubLightLevel-SHADE_MAX)/(SHADE_MIN-SHADE_MAX); // percentage
+ INT8 ubTerrainType = GetTerrainTypeForGrid(sTargetGridNo, gsInterfaceLevel);
- INT8 ubTerrainType = GetTerrainTypeForGrid(sTargetGridNo);
-
- INT8 ubCover = - GetSightAdjustment(pSoldier, sTargetGridNo);
+ INT8 ubCover = - GetSightAdjustment(pSoldier, sTargetGridNo, gsInterfaceLevel);
//display a string with cover value of current selected merc and brightness
- swprintf( zOutputString, gzDisplayCoverText[DC_MSG__COVER_INFORMATION], ubCover, GetTerrainName(ubTerrainType), ubBrightness );
+ //swprintf( zOutputString, gzDisplayCoverText[DC_MSG__COVER_INFORMATION], ubCover, GetTerrainName(ubTerrainType), ubBrightness );
//Display the msg
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
+
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE,
+ gzDisplayCoverText[DC_MSG__COVER_INFORMATION],
+ ubCover, GetTerrainName(ubTerrainType), ubBrightness );
}
//Get the range to the target location
@@ -558,7 +593,7 @@ void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
pSoldier->bTargetLevel = bTempTargetLevel;
// HEADROCK HAM 3.6: Calculate Gun Range using formula.
- UINT16 usGunRange = GunRange(&pSoldier->inv[HANDPOS]);
+ UINT16 usGunRange = GunRange(&pSoldier->inv[HANDPOS], pSoldier ); // SANDRO - added argument
swprintf( zOutputString, gzDisplayCoverText[DC_MSG__GUN_RANGE_INFORMATION], usRange / 10, usGunRange / 10, uiHitChance );
//Display the msg
diff --git a/Tactical/DisplayCover.h b/Tactical/DisplayCover.h
index c5bc22de..91345c2b 100644
--- a/Tactical/DisplayCover.h
+++ b/Tactical/DisplayCover.h
@@ -1,8 +1,38 @@
#ifndef _DISPLAY_COVER__H_
#define _DISPLAY_COVER__H_
+void DisplayCoverOfSelectedGridNo( );
+void RemoveCoverOfSelectedGridNo();
+
void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo );
void DisplayCover(const BOOLEAN& forceUpdate = FALSE);
+
+void SwitchToMercView();
+void SwitchToEnemyView();
+void SwitchViewOff();
+
+void ToggleMercView();
+void ToggleEnemyView();
+
void SwitchCoverDrawMode();
+void RemoveVisibleGridNoAtSelectedGridNo();
+void DisplayGridNoVisibleToSoldierGrid( );
+
+
+#define DC_MAX_COVER_RANGE 43 //31
+#define DC__SOLDIER_VISIBLE_RANGE 43 //31
+#define DC__MIN_SIZE 4
+#define DC__MAX_SIZE 21 //11
+
+#ifdef JA2TESTVERSION
+ void DisplayLosAndDisplayCoverUsageScreenMsg();
+#endif
+
+void ChangeSizeOfDisplayCover( INT32 iNewSize );
+
+void ChangeSizeOfLOS( INT32 iNewSize );
+//ddd for optimize oppponent turn
+INT8 CalcCoverForGridNoBasedOnTeamKnownEnemies( SOLDIERTYPE *pSoldier, INT16 sTargetGridNo, INT8 bStance );
+//ddd for optimize oppponent turn
#endif
diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp
index d64518a7..f4f8d13e 100644
--- a/Tactical/Drugs And Alcohol.cpp
+++ b/Tactical/Drugs And Alcohol.cpp
@@ -10,6 +10,7 @@
#include "morale.h"
#include "points.h"
#include "message.h"
+ #include "GameSettings.h" // SANDRO - had to add this, dammit!
#include "Random.h"
#include "Text.h"
#include "Interface.h"
@@ -151,30 +152,84 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
// 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 -= 5;
- pSoldier->stats.bDexterity -= 5;
- 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);
- if (pSoldier->stats.bWisdom < 1)
- pSoldier->stats.bWisdom = 1;
- if (pSoldier->stats.bDexterity < 1)
- pSoldier->stats.bDexterity = 1;
- if (pSoldier->stats.bStrength < 1)
- pSoldier->stats.bStrength = 1;
+ // make those stats RED for a while...
+ // SANDRO - we don't need to do this with new system, as we simply show all damaged stats in red until healed
+ pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
+ pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
+ pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
+ pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// export stat changes to profile
gMercProfiles[ pSoldier->ubProfile ].bWisdom = pSoldier->stats.bWisdom;
gMercProfiles[ pSoldier->ubProfile ].bDexterity = pSoldier->stats.bDexterity;
gMercProfiles[ pSoldier->ubProfile ].bStrength = pSoldier->stats.bStrength;
+ gMercProfiles[ pSoldier->ubProfile ].bAgility = pSoldier->stats.bAgility;
- // 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 );
+ // SANDRO - merc records - stat damaged
+ gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
}
}
}
@@ -308,9 +363,16 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
// increase life
pSoldier->stats.bLife = __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax );
+ //SANDRO - Insta-healable injury reduction
+ if( pSoldier->iHealableInjury > 0 )
+ {
+ pSoldier->iHealableInjury = max(0, (pSoldier->iHealableInjury - (100 * LIFE_GAIN_PER_REGEN_POINT)));
+ }
+
if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
{
pSoldier->bBleeding = 0;
+ pSoldier->iHealableInjury = 0;
}
else if ( pSoldier->bBleeding + pSoldier->stats.bLife > pSoldier->stats.bLifeMax )
{
diff --git a/Tactical/End Game.cpp b/Tactical/End Game.cpp
index c13efeb9..edb0ad2f 100644
--- a/Tactical/End Game.cpp
+++ b/Tactical/End Game.cpp
@@ -116,7 +116,7 @@ void ChangeO3SectorStatue( BOOLEAN fFromExplosion )
ExitGrid.ubGotoSectorX = 3;
ExitGrid.ubGotoSectorY = MAP_ROW_O;
ExitGrid.ubGotoSectorZ = 1;
- ExitGrid.usGridNo = 13037;
+ ExitGrid.usGridNo = 13037; //dnl!!!
AddExitGridToWorld( 13669, &ExitGrid );
gpWorldLevelData[ 13669 ].uiFlags |= MAPELEMENT_REVEALED;
@@ -187,7 +187,7 @@ void HandleDeidrannaDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLev
{
if ( OK_INSECTOR_MERC( pTeamSoldier ) && !( pTeamSoldier->flags.uiStatusFlags & SOLDIER_GASSED ) && !AM_AN_EPC( pTeamSoldier ) )
{
- if ( QuoteExp_WitnessDeidrannaDeath[ pTeamSoldier->ubProfile ] )
+ if ( QuoteExp[ pTeamSoldier->ubProfile ].QuoteExpWitnessDeidrannaDeath )
{
if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
{
@@ -475,7 +475,7 @@ void HandleQueenBitchDeath( SOLDIERTYPE *pKillerSoldier, INT32 sGridNo, INT8 bLe
{
if ( OK_INSECTOR_MERC( pTeamSoldier ) && !( pTeamSoldier->flags.uiStatusFlags & SOLDIER_GASSED ) && !AM_AN_EPC( pTeamSoldier ) )
{
- if ( QuoteExp_WitnessQueenBugDeath[ pTeamSoldier->ubProfile ] )
+ if ( QuoteExp[ pTeamSoldier->ubProfile ].QuoteExpWitnessQueenBugDeath )
{
if ( SoldierTo3DLocationLineOfSightTest( pTeamSoldier, sGridNo, bLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
{
diff --git a/Tactical/Faces.cpp b/Tactical/Faces.cpp
index f6e9397b..1d698788 100644
--- a/Tactical/Faces.cpp
+++ b/Tactical/Faces.cpp
@@ -61,90 +61,10 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
extern BOOLEAN gfInItemPickupMenu;
+RPC_SMALL_FACE_VALUES gRPCSmallFaceValues[200];
+UINT8 ubRPCNumSmallFaceValues = 200;
-
-typedef struct
-{
- INT8 bEyesX;
- INT8 bEyesY;
- INT8 bMouthX;
- INT8 bMouthY;
-
-} RPC_SMALL_FACE_VALUES;
-
-
-RPC_SMALL_FACE_VALUES gRPCSmallFaceValues[ ] =
-{
- 9, 8, 8, 24, // MIGUEL ( 57 )
- 8, 8, 7, 24, // CARLOS ( 58 )
- 10, 8, 8, 26, // IRA ( 59 )
- 7, 8, 7, 26, // DIMITRI ( 60 )
- 6, 7, 7, 23, // DEVIN ( 61 )
- 0, 0, 0, 0, // THE RAT ( 62 )
- 8, 7, 8, 23, // ( 63 )
- 8, 8, 8, 22, // SLAY ( 64 )
- 0, 0, 0, 0, // ( 65 )
- 9, 4, 7, 22, // DYNAMO ( 66 )
- 8, 8, 8, 25, // SHANK ( 67 )
- 4, 6, 5, 22, // IGGY ( 68 )
- 8, 9, 7, 25, // VINCE ( 69 )
- 4, 7, 5, 25, // CONRAD ( 70 )
- 9, 7, 8, 22, // CARL ( 71 )
- 9, 7, 9, 25, // MADDOG ( 72 )
- 0, 0, 0, 0, // ( 73 )
- 0, 0, 0, 0, // ( 74 )
-
- 9, 3, 8, 23, // MARIA ( 88 )
-
- 9, 3, 8, 25, // JOEY ( 90 )
-
- 11, 7, 9, 24, // SKYRIDER ( 97 )
- 9, 5, 7, 23, // Miner ( 106 )
-
- 6, 4, 6, 24, // JOHN ( 118 )
- 12,4, 10, 24, // ( 119 )
- 8, 6, 8, 23, // Miner ( 148 )
- 6, 5, 6, 23, // Miner ( 156 )
- 13, 7, 11, 24, // Miner ( 157 )
- 9, 7, 8, 22, // Miner ( 158 )
-
-};
-
-UINT8 gubRPCSmallFaceProfileNum[] =
-{
- 57, // entry 0
- 58,
- 59,
- 60,
- 61,
- 62,
- 63,
- 64,
- 65,
- 66, // entry 9
- 67,
- 68,
- 69,
- 70,
- 71,
- 72,
- 73,
- 74,
- 88,
- 90, // entry 19
- 97,
- 106,
- 118,
- 119,
- 148, // entry 24
- 156,
- 157,
- 158,
-
-};
-
-UINT8 ubRPCNumSmallFaceValues = 28;
-
+CAMO_FACE gCamoFace[255];
extern BOOLEAN gfSMDisableForItems;
extern INT16 gsCurInterfacePanel;
@@ -293,24 +213,91 @@ INT32 InternalInitFace( UINT8 usMercProfileID, UINT8 ubSoldierID, UINT32 uiInitF
}
else if ( usMercProfileID == TEX )
{
- if( gMercProfiles[ TEX ].bSkillTrait2 == CAMOUFLAGED )
+ // SANDRO - old/new traits check (I am not sure if this is used at all)
+ if ( gGameOptions.fNewTraitSystem )
{
- sprintf( VObjectDesc.ImageFile, "FACES\\B167c.sti" );
+ if ( ProfileHasSkillTrait( TEX, RANGER_NT ) > 0 )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\B167c.sti" );
+ }
+ }
+ else
+ {
+ if ( ProfileHasSkillTrait( TEX, CAMOUFLAGED_OT ) > 0 )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\B167c.sti" );
+ }
}
}
-
}
else
{
- if( iFaceFileID < 100 )
+ if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
- // The filename is the profile ID!
- sprintf( VObjectDesc.ImageFile, "FACES\\%02d.sti", iFaceFileID );
+ if( iFaceFileID < 100 )
+ {
+ // The filename is the profile ID!
+ sprintf( VObjectDesc.ImageFile, "FACES\\%02d.sti", iFaceFileID );
+
+ if ( gCamoFace[usMercProfileID].gCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\WoodCamo\\%02d.sti", iFaceFileID );
+ }
+ else if ( gCamoFace[usMercProfileID].gUrbanCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\UrbanCamo\\%02d.sti", iFaceFileID );
+ }
+ else if ( gCamoFace[usMercProfileID].gDesertCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\DesertCamo\\%02d.sti", iFaceFileID );
+ }
+ else if ( gCamoFace[usMercProfileID].gSnowCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\SnowCamo\\%02d.sti", iFaceFileID );
+ }
+
+ if (!FileExists(VObjectDesc.ImageFile))
+ sprintf( VObjectDesc.ImageFile, "FACES\\%02d.sti", iFaceFileID );
+ }
+ else
+ {
+
+ sprintf( VObjectDesc.ImageFile, "FACES\\%03d.sti", iFaceFileID );
+
+ if ( gCamoFace[usMercProfileID].gCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\Woodcamo\\%03d.sti", iFaceFileID );
+ }
+ else if ( gCamoFace[usMercProfileID].gUrbanCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\UrbanCamo\\%03d.sti", iFaceFileID );
+ }
+ else if ( gCamoFace[usMercProfileID].gDesertCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\DesertCamo\\%03d.sti", iFaceFileID );
+ }
+ else if ( gCamoFace[usMercProfileID].gSnowCamoface == TRUE )
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\SnowCamo\\%03d.sti", iFaceFileID );
+ }
+
+ if (!FileExists(VObjectDesc.ImageFile))
+ sprintf( VObjectDesc.ImageFile, "FACES\\%03d.sti", iFaceFileID );
+
+ }
}
- else
+ else if (gGameExternalOptions.fShowCamouflageFaces == FALSE )
{
- sprintf( VObjectDesc.ImageFile, "FACES\\%03d.sti", iFaceFileID );
+ if( iFaceFileID < 100 )
+ {
+ // The filename is the profile ID!
+ sprintf( VObjectDesc.ImageFile, "FACES\\%02d.sti", iFaceFileID );
+ }
+ else
+ {
+ sprintf( VObjectDesc.ImageFile, "FACES\\%03d.sti", iFaceFileID );
+ }
}
}
@@ -507,50 +494,21 @@ void GetFaceRelativeCoordinates( FACETYPE *pFace, UINT16 *pusEyesX, UINT16 *pusE
usMouthY = gMercProfiles[ usMercProfileID ].usMouthY;
usMouthX = gMercProfiles[ usMercProfileID ].usMouthX;
- //if( usMercProfileID == TEX && gMercProfiles[ TEX ].bSkillTrait2 == CAMOUFLAGED )
- //{
- // usEyesX = 13;
- // usEyesY = 34;
- // usMouthX = 13;
- // usMouthY = 55;
- //}
-
// Use some other values for x,y, base on if we are a RPC!
if ( !( pFace->uiFlags & FACE_BIGFACE ) ||( pFace->uiFlags & FACE_FORCE_SMALL ))
{
- if (usMercProfileID == TEX)
- {
- // 3, 6, 3, 23, // Tex ( 64 )
- usEyesX = 3;
- usEyesY = 6;
- usMouthX = 3;
- usMouthY = 23;
- }
- else if (usMercProfileID == BIGGENS)
- {
- // 5, 6, 5, 25, // Biggens ( 61 )
- usEyesX = 5;
- usEyesY = 6;
- usMouthX = 5;
- usMouthY = 25;
-
- }
- // Are we a recruited merc? .. or small?
- else if( ( gMercProfiles[ usMercProfileID ].ubMiscFlags & ( PROFILE_MISC_FLAG_RECRUITED | PROFILE_MISC_FLAG_EPCACTIVE ) ) ||( pFace->uiFlags & FACE_FORCE_SMALL ) )
- {
- // Loop through all values of availible merc IDs to find ours!
- for ( cnt = 0; cnt < ubRPCNumSmallFaceValues; cnt++ )
- {
- // We've found one!
- if ( gubRPCSmallFaceProfileNum[ cnt ] == usMercProfileID )
- {
- usEyesX = gRPCSmallFaceValues[ cnt ].bEyesX;
- usEyesY = gRPCSmallFaceValues[ cnt ].bEyesY;
- usMouthY = gRPCSmallFaceValues[ cnt ].bMouthY;
- usMouthX = gRPCSmallFaceValues[ cnt ].bMouthX;
- }
- }
-
+ // Loop through all values of availible merc IDs to find ours!
+ for ( cnt = 0; cnt < ubRPCNumSmallFaceValues; cnt++ )
+ {
+ // We've found one!
+ if (gRPCSmallFaceValues[ cnt ].FaceIndex == usMercProfileID &&
+ gRPCSmallFaceValues[ cnt ].uiIndex != 65535)
+ {
+ usEyesX = gRPCSmallFaceValues[ cnt ].bEyesX;
+ usEyesY = gRPCSmallFaceValues[ cnt ].bEyesY;
+ usMouthY = gRPCSmallFaceValues[ cnt ].bMouthY;
+ usMouthX = gRPCSmallFaceValues[ cnt ].bMouthX;
+ }
}
}
@@ -558,7 +516,6 @@ void GetFaceRelativeCoordinates( FACETYPE *pFace, UINT16 *pusEyesX, UINT16 *pusE
(*pusEyesY) = usEyesY;
(*pusMouthX) = usMouthX;
(*pusMouthY) = usMouthY;
-
}
@@ -1195,6 +1152,88 @@ BOOLEAN RenderAutoFaceFromSoldier( UINT8 ubSoldierID )
return( RenderAutoFace( MercPtrs[ ubSoldierID ]->iFaceIndex ) );
}
+//---------------------------------------LEGION-------------------------------
+
+void GetXYForIconPlacement_legion( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY )
+{
+ INT16 sX, sY;
+ UINT16 usWidth, usHeight;
+ ETRLEObject *pTrav;
+ HVOBJECT hVObject;
+
+ // Get height, width of icon...
+ GetVideoObject( &hVObject, guiPORTRAITICONS_NV );
+ pTrav = &(hVObject->pETRLEObject[ ubIndex ] );
+ usHeight = pTrav->usHeight;
+ usWidth = pTrav->usWidth;
+
+ sX = sFaceX + pFace->usFaceWidth - usWidth - 1;
+ sY = sFaceY + pFace->usFaceHeight - usHeight - 1;
+
+ *psX = sX;
+ *psY = sY;
+}
+
+void GetXYForRightIconPlacement_legion_NV( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY, INT8 bNumIcons )
+{
+ INT16 sX, sY;
+ UINT16 usWidth, usHeight;
+ ETRLEObject *pTrav;
+ HVOBJECT hVObject;
+
+ // Get height, width of icon...
+ GetVideoObject( &hVObject, guiPORTRAITICONS_NV );
+ pTrav = &(hVObject->pETRLEObject[ ubIndex ] );
+ usHeight = pTrav->usHeight;
+ usWidth = pTrav->usWidth;
+
+ sX = sFaceX + ( usWidth * bNumIcons ) + 1;
+ sY = sFaceY + pFace->usFaceHeight - usHeight - 1;
+
+ *psX = sX;
+ *psY = sY;
+}
+void DoRightIcon_legion_NV( UINT32 uiRenderBuffer, FACETYPE *pFace, INT16 sFaceX, INT16 sFaceY, INT8 bNumIcons, UINT8 sIconIndex )
+{
+ INT16 sIconX, sIconY;
+
+ GetXYForRightIconPlacement_legion_NV( pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons );
+ BltVideoObjectFromIndex( uiRenderBuffer, guiPORTRAITICONS_NV, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
+
+}
+
+void GetXYForRightIconPlacement_legion_GAS_MASK( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY, INT8 bNumIcons )
+{
+ INT16 sX, sY;
+ UINT16 usWidth, usHeight;
+ ETRLEObject *pTrav;
+ HVOBJECT hVObject;
+
+ // Get height, width of icon...
+ GetVideoObject( &hVObject, guiPORTRAITICONS_GAS_MASK );
+ pTrav = &(hVObject->pETRLEObject[ ubIndex ] );
+ usHeight = pTrav->usHeight;
+ usWidth = pTrav->usWidth;
+
+ sX = sFaceX + ( usWidth * bNumIcons ) + 1;
+ sY = sFaceY + pFace->usFaceHeight - usHeight - 1;
+
+ *psX = sX;
+ *psY = sY;
+}
+void DoRightIcon_legion_GAS_MASK( UINT32 uiRenderBuffer, FACETYPE *pFace, INT16 sFaceX, INT16 sFaceY, INT8 bNumIcons, UINT8 sIconIndex )
+{
+ INT16 sIconX, sIconY;
+
+ // Find X, y for placement
+
+ GetXYForRightIconPlacement_legion_GAS_MASK( pFace, sIconIndex, sFaceX, sFaceY, &sIconX, &sIconY, bNumIcons );
+ BltVideoObjectFromIndex( uiRenderBuffer, guiPORTRAITICONS_GAS_MASK, sIconIndex, sIconX, sIconY, VO_BLT_SRCTRANSPARENCY, NULL );
+
+}
+//----------------------------------------------------------------
+
+
void GetXYForIconPlacement( FACETYPE *pFace, UINT16 ubIndex, INT16 sFaceX, INT16 sFaceY, INT16 *psX, INT16 *psY )
{
INT16 sX, sY;
@@ -1268,6 +1307,14 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
UINT8 *pDestBuf;
UINT16 usLineColor;
INT8 bNumRightIcons = 0;
+
+ BOOLEAN fDoIcon_legion = FALSE; //legion
+ INT16 sIconIndex_legion =-1; //legion
+ INT8 bNumRightIcons_legion = 0;
+ BOOLEAN MASK = FALSE; //legion
+ UINT32 uiFaceItemOne=0;
+ UINT32 uiFaceItemTwo=0;
+ UINT8 ubFaceItemsCombined=0;
// If we are using an extern buffer...
if ( fUseExternBuffer )
@@ -1428,6 +1475,310 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
fDoIcon = TRUE;
}
+
+
+//------------------------------------Legion 2 by jazz--------------------------------
+ // rewritten by silversurfer
+ // this section chooses the icons for face gear if the ini setting "SHOW_TACTICAL_FACE_ICONS" is TRUE
+ // and the merc actually wears something to be shown
+ if (gGameExternalOptions.fShowTacticalFaceIcons == TRUE && MercPtrs[ pFace->ubSoldierID ]->stats.bLife > 0 &&
+ ( MercPtrs[ pFace->ubSoldierID ]->inv[HEAD1POS].usItem + MercPtrs[ pFace->ubSoldierID ]->inv[HEAD2POS].usItem ) > 0 )
+ {
+ uiFaceItemOne=MercPtrs[ pFace->ubSoldierID ]->inv[HEAD1POS].usItem;
+ uiFaceItemTwo=MercPtrs[ pFace->ubSoldierID ]->inv[HEAD2POS].usItem;
+
+ // check first face slot
+ if ( uiFaceItemOne != NONE )
+ {
+ switch( uiFaceItemOne )
+ {
+ // gas mask
+ case GASMASK:
+ uiFaceItemOne = 1;
+ break;
+ // NV goggles
+ case 211:
+ case 246:
+ case 1024:
+ case 1025:
+ uiFaceItemOne = 2;
+ break;
+ // sun goggles
+ case 212:
+ uiFaceItemOne = 3;
+ break;
+ // extended ear
+ case 210:
+ uiFaceItemOne = 4;
+ break;
+ default:
+ uiFaceItemOne = 0;
+ break;
+ }
+ }
+
+ // check second face slot
+ if ( uiFaceItemTwo != NONE )
+ {
+ switch( uiFaceItemTwo )
+ {
+ // gas mask
+ case GASMASK:
+ uiFaceItemTwo = 21;
+ break;
+ // NV goggles
+ case 211:
+ case 246:
+ case 1024:
+ case 1025:
+ uiFaceItemTwo = 42;
+ break;
+ // sun goggles
+ case 212:
+ uiFaceItemTwo = 63;
+ break;
+ // extended ear
+ case 210:
+ uiFaceItemTwo = 84;
+ break;
+ default:
+ uiFaceItemTwo = 0;
+ break;
+ }
+ }
+
+ // Now select the correct icon. This uses a matrix from uiFaceOneItem and uiFaceTwoItem (simple addition)
+ // the numbers on the outer border are used if that is the only item worn in that slot
+ //
+ // 21 42 63 84
+ // face slot 1 \ slot 2 gas mask | NV goggles | sun goggles | extended ear
+ // 1 gas mask -- 43 64 85
+ // 2 NV goggles 23 -- -- 86
+ // 3 sun goggles 24 -- -- 87
+ // 4 extended ear 25 46 67 --
+ //
+ // this matrix leaves room for expansion
+ ubFaceItemsCombined = uiFaceItemOne + uiFaceItemTwo;
+
+ switch( ubFaceItemsCombined )
+ {
+ // gas mask only
+ case 1:
+ case 21:
+ sIconIndex = 9;
+ fDoIcon = TRUE;
+ break;
+ // NV goggles only
+ case 2:
+ case 42:
+ sIconIndex = 10;
+ fDoIcon = TRUE;
+ break;
+ // sun goggles only
+ case 3:
+ case 63:
+ sIconIndex = 15;
+ fDoIcon = TRUE;
+ break;
+ // extended ear only
+ case 4:
+ case 84:
+ sIconIndex = 12;
+ fDoIcon = TRUE;
+ break;
+ // gas mask + NV goggles
+ case 23:
+ case 43:
+ sIconIndex = 11;
+ fDoIcon = TRUE;
+ break;
+ // gas mask + sun goggles
+ case 24:
+ case 64:
+ sIconIndex = 16;
+ fDoIcon = TRUE;
+ break;
+ // gas mask + extended ear
+ case 25:
+ case 85:
+ sIconIndex = 13;
+ fDoIcon = TRUE;
+ break;
+ // NV goggles + extended ear
+ case 46:
+ case 86:
+ sIconIndex = 14;
+ fDoIcon = TRUE;
+ break;
+ // sun goggles + extended ear
+ case 67:
+ case 87:
+ sIconIndex = 18;
+ fDoIcon = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ // this section chooses the pictures for gas mask and NV goggles if the ini setting "SHOW_TACTICAL_FACE_GEAR" is TRUE
+ // and the merc actually wears something to be shown
+ if (gGameExternalOptions.fShowTacticalFaceGear == TRUE && MercPtrs[ pFace->ubSoldierID ]->stats.bLife > 0 &&
+ ( MercPtrs[ pFace->ubSoldierID ]->inv[HEAD1POS].usItem + MercPtrs[ pFace->ubSoldierID ]->inv[HEAD2POS].usItem ) > 0 &&
+ // dirty hack for IMPs because they don't have pictures for face gear
+ ( MercPtrs[ pFace->ubSoldierID ]->ubProfile < 51 || MercPtrs[ pFace->ubSoldierID ]->ubProfile > 56 ))
+ {
+ // WANNE: Removed the limitation
+ // silversurfer: don't overwrite icons if they shall be shown!
+ //if ( !gGameExternalOptions.fShowTacticalFaceIcons )
+ {
+ uiFaceItemOne=MercPtrs[ pFace->ubSoldierID ]->inv[HEAD1POS].usItem;
+ uiFaceItemTwo=MercPtrs[ pFace->ubSoldierID ]->inv[HEAD2POS].usItem;
+
+ // check first face slot
+ if ( uiFaceItemOne != NONE )
+ {
+ switch( uiFaceItemOne )
+ {
+ // gas mask
+ case GASMASK:
+ uiFaceItemOne = 1;
+ break;
+ // NV goggles
+ case 211:
+ case 246:
+ case 1024:
+ case 1025:
+ uiFaceItemOne = 2;
+ break;
+ default:
+ uiFaceItemOne = 0;
+ break;
+ }
+ }
+
+ // check second face slot
+ if ( uiFaceItemTwo != NONE )
+ {
+ switch( uiFaceItemTwo )
+ {
+ // gas mask
+ case GASMASK:
+ uiFaceItemTwo = 21;
+ break;
+ // NV goggles
+ case 211:
+ case 246:
+ case 1024:
+ case 1025:
+ uiFaceItemTwo = 42;
+ break;
+ default:
+ uiFaceItemTwo = 0;
+ break;
+ }
+ }
+
+ // Now select the correct picture. This uses a matrix from uiFaceOneItem and uiFaceTwoItem (simple addition)
+ // the numbers on the outer border are used if that is the only item worn in that slot
+ //
+ // 21 42 63 84
+ // face slot 1 \ slot 2 gas mask | NV goggles | sun goggles | extended ear
+ // 1 gas mask -- 43 64 85
+ // 2 NV goggles 23 -- -- 86
+ // 3 sun goggles 24 -- -- 87
+ // 4 extended ear 25 46 67 --
+ //
+ // this matrix leaves room for expansion
+ // we only need a few of the matrix' values this time because we only show gas mask or NV goggles pictures
+ ubFaceItemsCombined = uiFaceItemOne + uiFaceItemTwo;
+ }
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ // silversurfer: we don't want to display icons for gas mask or NV goggles because you can actually see the merc wearing the gear
+ // in case of gas mask together with NV we display the picture of the item in face slot 1 and the icon of the item
+ // in face slot 2 (if icons are allowed)
+ switch( ubFaceItemsCombined )
+ {
+ // gas mask only
+ case 1:
+ case 21:
+ DoRightIcon_legion_GAS_MASK( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ //fDoIcon = FALSE;
+
+ break;
+ // NV goggles only
+ case 2:
+ case 42:
+ DoRightIcon_legion_NV( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ //fDoIcon = FALSE;
+
+ break;
+ // NV goggles + gas mask
+ case 23:
+ DoRightIcon_legion_NV( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ /*if ( gGameExternalOptions.fShowTacticalFaceIcons )
+ {
+ sIconIndex = 9;
+ fDoIcon = TRUE;
+ }*/
+
+ break;
+ // gas mask + NV goggles
+ case 43:
+ DoRightIcon_legion_GAS_MASK( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ /*if ( gGameExternalOptions.fShowTacticalFaceIcons )
+ {
+ sIconIndex = 10;
+ fDoIcon = TRUE;
+ }*/
+
+ break;
+ // gas mask + sun goggles
+ case 24:
+ case 64:
+ DoRightIcon_legion_GAS_MASK( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ //sIconIndex = 15;
+ //fDoIcon = TRUE;
+
+ break;
+ // gas mask + extended ear
+ case 25:
+ case 85:
+ DoRightIcon_legion_GAS_MASK( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ //sIconIndex = 12;
+ //fDoIcon = TRUE;
+
+ break;
+ // NV goggles + extended ear
+ case 46:
+ case 86:
+ DoRightIcon_legion_NV( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons_legion, MercPtrs[ pFace->ubSoldierID ]->ubProfile );
+
+ // WANNE: Removed silversurfers limitation, because it is too complex for the players :)
+ //sIconIndex = 12;
+ //fDoIcon = TRUE;
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ //------------------------------------end of tactical face gear-----------------------------
+
// If blind...
if ( MercPtrs[ pFace->ubSoldierID ]->bBlindedCounter > 0 )
{
diff --git a/Tactical/Handle Doors.cpp b/Tactical/Handle Doors.cpp
index d963c0de..72a0578f 100644
--- a/Tactical/Handle Doors.cpp
+++ b/Tactical/Handle Doors.cpp
@@ -338,16 +338,19 @@ void InteractWithOpenableStruct( SOLDIERTYPE *pSoldier, STRUCTURE *pStructure, U
if ( pDoor )
{
if ( DoTrapCheckOnStartingMenu( pSoldier, pDoor ) )
- {
- fTrapsFound = TRUE;
- }
+ {
+ fTrapsFound = TRUE;
+ }
}
// Pull Up Menu
- if ( !fTrapsFound )
- {
- InitDoorOpenMenu( pSoldier, pStructure, ubDirection, TRUE );
- }
+ if ( !fTrapsFound )
+ {
+ // HEADROCK HAM 4: Why not just close the object? Why do we need a menu if there's only one option on it (CLOSE)?
+ // P.S. I don't think it's even possible for opened structures to be trapped to begin with.
+ //InitDoorOpenMenu( pSoldier, pStructure, ubDirection, TRUE );
+ pSoldier->ChangeSoldierState( GetAnimStateForInteraction( pSoldier, fDoor, CLOSE_DOOR ), 0, FALSE );
+ }
}
else
{
@@ -475,7 +478,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
if ( pStructure->fFlags & STRUCTURE_OPEN )
{
// Set costs for these
- sAPCost = APBPConstants[AP_OPEN_DOOR];
+ sAPCost = GetAPsToOpenDoor( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_OPEN_DOOR];
fHandleDoor = TRUE;
@@ -500,7 +503,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
// Set costs for these
// Set AP costs to that of opening a door
- sAPCost = APBPConstants[AP_OPEN_DOOR];
+ sAPCost = GetAPsToOpenDoor( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_OPEN_DOOR];
pSoldier->ChangeSoldierState( GetAnimStateForInteraction( pSoldier, fDoor, END_OPEN_DOOR ), 0, FALSE );
@@ -584,7 +587,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
if ( pDoor == NULL )
{
// Set costs for these
- sAPCost = APBPConstants[AP_OPEN_DOOR];
+ sAPCost = GetAPsToOpenDoor( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_OPEN_DOOR];
// Open if it's not locked....
@@ -689,7 +692,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
case HANDLE_DOOR_EXPLODE:
// Set costs for these
- sAPCost = APBPConstants[AP_EXPLODE_DOOR];
+ sAPCost = GetAPsToBombDoor( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_EXPLODE_DOOR];
if ( pDoor == NULL )
@@ -717,7 +720,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
case HANDLE_DOOR_LOCKPICK:
// Set costs for these
- sAPCost = APBPConstants[AP_PICKLOCK];
+ sAPCost = GetAPsToPicklock( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_PICKLOCK];
// Attempt to pick lock
@@ -834,7 +837,7 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
case HANDLE_DOOR_UNTRAP:
// Set costs for these
- sAPCost = APBPConstants[AP_UNTRAP_DOOR];
+ sAPCost = GetAPsToUntrapDoor( pSoldier ); // SANDRO
sBPCost = APBPConstants[BP_UNTRAP_DOOR];
// OK, if we have no lock, show that!
@@ -931,7 +934,8 @@ BOOLEAN HandleOpenableStruct( SOLDIERTYPE *pSoldier, INT32 sGridNo, STRUCTURE *p
else
{
// Set costs for these
- sAPCost = APBPConstants[AP_OPEN_DOOR];
+ // SANDRO - changed this
+ sAPCost = GetAPsToOpenDoor( pSoldier );
sBPCost = APBPConstants[BP_OPEN_DOOR];
// Open if it's not locked....
diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp
index 7d2cd9db..3d1f9597 100644
--- a/Tactical/Handle Items.cpp
+++ b/Tactical/Handle Items.cpp
@@ -61,6 +61,9 @@
#include "end game.h"
#include "interface control.h"
#include "Map Screen Interface Map Inventory.h"
+ // added by SANDRO
+ #include "Game Clock.h"
+ #include "Morale.h"
#endif
#define NUM_ITEMS_LISTED 8
@@ -437,26 +440,28 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
// If this is a player guy, show message about no APS
if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
{
- if ( (pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == PSYCHO) )
+ if ( (pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) )
{
// psychos might possibly switch to burst if they can
// Changed by ADB, rev 1513
//if ( !pSoldier->bDoBurst && IsGunBurstCapable( pSoldier, HANDPOS, FALSE ) )
- if ( !pSoldier->bDoBurst && IsGunBurstCapable( &pSoldier->inv[HANDPOS], FALSE, pSoldier ) )
+ // SANDRO - messed this a little.. decrease morale a bit when we would like to go psycho,
+ // but have not a gun capable for it
+ if ( PreRandom( 3 + pSoldier->aiData.bAimTime ) == 0 && !pSoldier->bDoBurst )
{
- // chance of firing burst if we have points... chance decreasing when ordered to do aimed shot
-
- // temporarily set burst to true to calculate action points
- pSoldier->bDoBurst = TRUE;
- sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, TRUE, 0 );
- // reset burst mode to false (which is what it was at originally)
- pSoldier->bDoBurst = FALSE;
-
- if ( EnoughPoints( pSoldier, sAPCost, 0, FALSE ) )
+ if ( IsGunBurstCapable( &pSoldier->inv[HANDPOS], FALSE, pSoldier ) )
{
- // we have enough points to do this burst, roll the dice and see if we want to change
- if ( Random( 3 + pSoldier->aiData.bAimTime ) == 0 )
+ // chance of firing burst if we have points... chance decreasing when ordered to do aimed shot
+
+ // temporarily set burst to true to calculate action points
+ pSoldier->bDoBurst = TRUE;
+ sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, TRUE, 0 );
+ // reset burst mode to false (which is what it was at originally)
+ pSoldier->bDoBurst = FALSE;
+
+ if ( EnoughPoints( pSoldier, sAPCost, 0, FALSE ) )
{
+ // we have enough points to do this burst, roll the dice and see if we want to change
pSoldier->DoMercBattleSound( BATTLE_SOUND_LAUGH1 );
pSoldier->bDoBurst = TRUE;
pSoldier->bWeaponMode = WM_BURST;
@@ -465,7 +470,12 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name );
}
}
-
+ else if ( !IsGunAutofireCapable( &pSoldier->inv[HANDPOS] ) )
+ {
+ // reduce morale for we are using a gun without burst or autofire and cannot go psycho
+ //HandleMoraleEventForSoldier( pSoldier, MORALE_PSYCHO_UNABLE_TO_PSYCHO );
+ HandleMoraleEvent( pSoldier, MORALE_PSYCHO_UNABLE_TO_PSYCHO, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
+ }
}
}
@@ -480,7 +490,19 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
//Rounding down resulted in division by zero and caused a crash.
UINT32 diceSides = RAND_MAX / ( max(10,pSoldier->stats.bMarksmanship) / 10) ;
- DOUBLE avgAPadded = max(((400.0f-2.0f*pSoldier->stats.bAgility))*(63.0f-5.0f*(pSoldier->stats.bExpLevel+2.0f*NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS )))/2700.0f,1); //Important! don't make this zero, the formulae don't like it.
+ DOUBLE avgAPadded;
+ // SANDRO - Slightly changed this formula to make the auto weapons trait little more needed if new traits activated -
+ if( gGameOptions.fNewTraitSystem )
+ {
+ // also include possible squadleader bonus
+ UINT8 uiEffExpLev = min( 10, (pSoldier->stats.bExpLevel + (gSkillTraitValues.ubSLEffectiveLevelInRadius * GetSquadleadersCountInVicinity( pSoldier, TRUE, FALSE ))));
+ avgAPadded = max(((400.0f-2.0f*pSoldier->stats.bDexterity))*(90.0f-5.0f*(uiEffExpLev+gSkillTraitValues.ubAWUnwantedBulletsReduction*NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/2700.0f,1); //Important! don't make this zero, the formulae don't like it.
+ }
+ else
+ {
+ avgAPadded = max(((400.0f-2.0f*pSoldier->stats.bAgility))*(63.0f-5.0f*(pSoldier->stats.bExpLevel+2.0f*NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT )))/2700.0f,1); //Important! don't make this zero, the formulae don't like it.
+ }
+
UINT32 chanceToMisfire = (UINT32)(((DOUBLE)diceSides*(2.0f*avgAPadded+1.0f-sqrt(4.0f*avgAPadded+1.0f)))/(2.0f*avgAPadded)); //derive the chace to misfire from the desired average AP overspent, derived suing
UINT32 chanceToMisfireDry = (UINT32)(((DOUBLE)diceSides*(avgAPadded+1.0f-sqrt(2.0f*avgAPadded+1.0f)))/(avgAPadded)); //chance to misfire if weapon is dry. Designed to waste avgAPadded/2 APs
//soldiers get better at controlling bursts with levels, and reflex time (agility)
@@ -491,10 +513,13 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
//UINT32 startAPcost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, TRUE, 0 );
UINT32 roll;
- if((pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == PSYCHO) && Random(100) < 20)
+ // SANDRO - changed Random to PreRandom to avoid save-load mania
+ if((pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) && PreRandom(100) < 20)
{
chanceToMisfire = diceSides;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name );
+
+ pSoldier->DoMercBattleSound( BATTLE_SOUND_LAUGH1 ); // Added the laugh sound when going Psycho on autofire - SANDRO
}
chanceToMisfire = __min(diceSides-1, chanceToMisfire); //cap the misfire chance, no-one has reflexes this bad
@@ -503,11 +528,17 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
chanceToMisfireDry = __min(diceSides-1, chanceToMisfireDry); //cap the misfire chance, no-one has reflexes this bad
chanceToMisfireDry = __max(1, chanceToMisfireDry); //cap the misfire chance, no-one has reflexes this good
+ //CHRISL: Since LMGs can only use autofire, give them slightly better control over misfire
+ if(Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].ubWeaponClass == MGCLASS && Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].ubWeaponType == GUN_LMG){
+ chanceToMisfire = (INT32)(chanceToMisfire * .75f);
+ chanceToMisfireDry = (INT32)(chanceToMisfireDry * .75f);
+ }
+
//roll dice for each AP to see if we failed to stop firing
do
{
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"HandleItem: auto fire - Rolling dice");
- roll = Random(diceSides);
+ roll = PreRandom(diceSides); // changed Random to PreRandom - SANDRO
//roll = rand();//Random(diceSides);
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Rolled %d vs %d", roll, ((pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire)?chanceToMisfire:chanceToMisfireDry));
@@ -540,7 +571,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
// 1 round
else
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 63 ], pSoldier->name, __min(pSoldier->bDoAutofire,pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft) - startAuto );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 63 ], pSoldier->name ); // SANDRO - no need for attaching the number if only one round is shot
}
}
}
@@ -1457,7 +1488,16 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo )
// EXPLOSIVES GAIN (25): Place a bomb, or buried and armed a mine
StatChange( pSoldier, EXPLODEAMT, 25, FALSE );
- pSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( pSoldier ) / 20) + (EffectiveExpLevel( pSoldier ) / 3) );
+ // SANDRO - STOMP traits - Demolitions bonus to trap level
+ if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, DEMOLITIONS_NT ))
+ {
+ // +5 trap level for Demolitions trait
+ pSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( max( 10, (8 + gSkillTraitValues.ubDEPlacedBombLevelBonus)), (( EffectiveExplosive( pSoldier ) / 20) + (EffectiveExpLevel( pSoldier ) / 3) + gSkillTraitValues.ubDEPlacedBombLevelBonus) );
+ }
+ else
+ {
+ pSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( pSoldier ) / 20) + (EffectiveExpLevel( pSoldier ) / 3) );
+ }
pSoldier->inv[ HANDPOS ][0]->data.misc.ubBombOwner = pSoldier->ubID + 2;
// we now know there is something nasty here
@@ -1538,11 +1578,27 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT32 sGridNo )
// Draw item depending on distance from buddy
if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE )
{
- pSoldier->usPendingAnimation = LOB_ITEM;
+
+ //ddd -
+ if( (pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM) &&
+ ( (pSoldier->ubBodyType == BIGMALE) || (pSoldier->ubBodyType == REGMALE) ) )
+ pSoldier->usPendingAnimation = LOB_GRENADE_STANCE;
+ else
+ pSoldier->usPendingAnimation = LOB_ITEM;
+
}
else
- {
- pSoldier->usPendingAnimation = THROW_ITEM;
+ { //ddd -
+ //INT32 uiItemClass; // . ?
+ // uiItemClass= Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass;
+ //if( (uiItemClass == IC_GRENADE) &&
+
+
+ if( (pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM) &&
+ ( (pSoldier->ubBodyType == BIGMALE) || (pSoldier->ubBodyType == REGMALE) ) )
+ pSoldier->usPendingAnimation = THROW_GRENADE_STANCE;
+ else
+ pSoldier->usPendingAnimation = THROW_ITEM;
}
}
@@ -1913,7 +1969,7 @@ void SoldierGetItemFromWorld( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT32 sGr
if ( fShouldSayCoolQuote && pSoldier->bTeam == gbPlayerNum )
{
// Do we have this quote..?
- if ( QuoteExp_GotGunOrUsedGun[ pSoldier->ubProfile ] == QUOTE_FOUND_SOMETHING_SPECIAL )
+ if ( QuoteExp[ pSoldier->ubProfile ].QuoteExpGotGunOrUsedGun == QUOTE_FOUND_SOMETHING_SPECIAL )
{
// Have we not said it today?
if ( !( pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_FOUND_SOMETHING_NICE ) )
@@ -2007,7 +2063,7 @@ void HandleSoldierPickupItem( SOLDIERTYPE *pSoldier, INT32 iItemIndex, INT32 sGr
wchar_t string2[20];
ptr = wcscat(buffer, string);
- _ltow(APBPConstants[AP_DISARM_MINE], string2, 10);
+ _ltow(GetAPsToDisarmMine( pSoldier ), string2, 10); // SANDRO
ptr = wcscat(buffer, string2);
string = L"AP)";
ptr = wcscat(buffer, string);
@@ -3995,7 +4051,7 @@ void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier )
ubTargetMercID = (UINT8)pSoldier->aiData.uiPendingActionData4;
// ATE: Deduct APs!
- DeductPoints( pSoldier, APBPConstants[AP_PICKUP_ITEM], 0 );
+ DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 ); // SANDRO
if ( VerifyGiveItem( pSoldier, &pTSoldier ) )
{
@@ -4063,7 +4119,9 @@ void SoldierGiveItemFromAnimation( SOLDIERTYPE *pSoldier )
// Switch on target...
// Are we a player dude.. ( target? )
- if ( ubProfile < FIRST_RPC || RPC_RECRUITED( pTSoldier ) || ubProfile >= GASTON )
+ // if ( ubProfile < FIRST_RPC || RPC_RECRUITED( pTSoldier ) || ubProfile >= GASTON )
+ //new profiles by Jazz
+ if ( ( gProfilesAIM[ubProfile].ProfilId == ubProfile || gProfilesMERC[ubProfile].ProfilId == ubProfile || gProfilesIMP[ubProfile].ProfilId == ubProfile ) || RPC_RECRUITED( pTSoldier ) )
{
fToTargetPlayer = TRUE;
}
@@ -4314,7 +4372,17 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
if ( ArmBomb( &(gpTempSoldier->inv[HANDPOS]), ubExitValue ) )
{
- gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) );
+ // SANDRO - STOMP traits - Demolitions bonus to trap level
+ if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( gpTempSoldier, DEMOLITIONS_NT ))
+ {
+ // increase trap level for Demolitions trait
+ gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( max( 10, (8 + gSkillTraitValues.ubDEPlacedBombLevelBonus)), (( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) + gSkillTraitValues.ubDEPlacedBombLevelBonus) );
+ }
+ else
+ {
+ gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) );
+ }
+
// HACK IMMINENT!
// value of 1 is stored in maps for SIDE of bomb owner... when we want to use IDs!
// so we add 2 to all owner IDs passed through here and subtract 2 later
@@ -4548,8 +4616,9 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
//CHRISL: first things first. If we're in combat, we need to spend some APs to disarm the device
if((gTacticalStatus.uiFlags & INCOMBAT) || (gTacticalStatus.fEnemyInSector))
{
- if(EnoughPoints(gpBoobyTrapSoldier, APBPConstants[AP_DISARM_MINE], APBPConstants[BP_DISARM_MINE], TRUE))
- DeductPoints(gpBoobyTrapSoldier, APBPConstants[AP_DISARM_MINE], APBPConstants[BP_DISARM_MINE]);
+ // SANDRO was here, AP_DISARM_MINE changed to GetAPsToDisarmMine
+ if(EnoughPoints(gpBoobyTrapSoldier, GetAPsToDisarmMine( gpBoobyTrapSoldier ), APBPConstants[BP_DISARM_MINE], TRUE))
+ DeductPoints(gpBoobyTrapSoldier, GetAPsToDisarmMine( gpBoobyTrapSoldier ), APBPConstants[BP_DISARM_MINE]);
else
return;
}
@@ -4589,12 +4658,18 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
{
// disarmed our team's boobytrap!
StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (4 * gbTrapDifficulty), FALSE );
+
+ // SANDRO - merc records - trap removal count (don't count our own traps)
+ gMercProfiles[ gpBoobyTrapSoldier->ubProfile ].records.usTrapsRemoved++;
}
}
else
{
// disarmed a boobytrap!
StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (6 * gbTrapDifficulty), FALSE );
+
+ // SANDRO - merc records - trap removal count
+ gMercProfiles[ gpBoobyTrapSoldier->ubProfile ].records.usTrapsRemoved++;
}
// have merc say this is good
@@ -4632,7 +4707,7 @@ void BoobyTrapMessageBoxCallBack( UINT8 ubExitValue )
CreateItem( DETONATOR, gTempObject[0]->data.misc.bBombStatus, &TempAttachment );
}
- if (ValidAttachment( TempAttachment.usItem , gTempObject.usItem ))
+ if (ValidAttachment( TempAttachment.usItem , &gTempObject ))
{
gTempObject.AttachObject(NULL, &TempAttachment, FALSE);
}
@@ -4747,6 +4822,10 @@ void BoobyTrapInMapScreenMessageBoxCallBack( UINT8 ubExitValue )
// disarmed a boobytrap!
StatChange( gpBoobyTrapSoldier, EXPLODEAMT, (UINT16) (6 * gbTrapDifficulty), FALSE );
+ // SANDRO - merc records - trap removal count
+ if ( gpBoobyTrapSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ gpBoobyTrapSoldier->ubProfile ].records.usTrapsRemoved++;
+
// have merc say this is good
gpBoobyTrapSoldier->DoMercBattleSound( BATTLE_SOUND_COOL1 );
@@ -5467,7 +5546,7 @@ UINT8 StealItems(SOLDIERTYPE* pSoldier,SOLDIERTYPE* pOpponent, UINT8* ubIndexRet
fStealItem = FALSE;
pObject=&pOpponent->inv[i];
- if (pObject->exists() == true)
+ if ((pObject->exists() == true) && !(Item[pObject->usItem].defaultundroppable )) // CHECK! Undroppable items cannot be stolen - SANDRO
{
// Is the enemy collapsed
if ( pOpponent->stats.bLife < OKLIFE || pOpponent->bCollapsed )
@@ -5591,6 +5670,7 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
BOOLEAN fPickup;
BOOLEAN fShouldSayCoolQuote = FALSE;
BOOLEAN fDidSayCoolQuote = FALSE;
+ BOOLEAN fNotEnoughAPs = FALSE; // added by SANDRO
// OK. CHECK IF WE ARE DOING ALL IN THIS POOL....
if ( iItemIndex == ITEM_PICKUP_ACTION_ALL || iItemIndex == ITEM_PICKUP_SELECTION )
@@ -5611,17 +5691,51 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
cnt++;
if ( fPickup )
{
- // Make copy of item
- gTempObject = pOpponent->inv[pTempItemPool->iItemIndex];
- if ( ItemIsCool( &gTempObject ) )
+ ////////////////////////////////////////////////////////////////////
+ // SANDRO - added mechanism for APs needed to steal all items..
+ if ( gGameExternalOptions.fEnhancedCloseCombatSystem )
{
- fShouldSayCoolQuote = TRUE;
+ if (pSoldier->bActionPoints >= GetBasicAPsToPickupItem( pSoldier ) )
+ {
+ DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 );
+
+ // Make copy of item
+ gTempObject = pOpponent->inv[pTempItemPool->iItemIndex];
+ if ( ItemIsCool( &gTempObject ) )
+ {
+ fShouldSayCoolQuote = TRUE;
+ }
+ if ( !AutoPlaceObject( pSoldier, &gTempObject, TRUE ) )
+ {
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
+ DeleteObj(&pOpponent->inv[pTempItemPool->iItemIndex]);
+
+ // add to merc records
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pSoldier->ubProfile ].records.usItemsStolen++;
+
+ }
+ else
+ {
+ fNotEnoughAPs = TRUE;
+ }
}
- if ( !AutoPlaceObject( pSoldier, &gTempObject, TRUE ) )
+ else // original code
{
- AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ // Make copy of item
+ gTempObject = pOpponent->inv[pTempItemPool->iItemIndex];
+ if ( ItemIsCool( &gTempObject ) )
+ {
+ fShouldSayCoolQuote = TRUE;
+ }
+ if ( !AutoPlaceObject( pSoldier, &gTempObject, TRUE ) )
+ {
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
+ DeleteObj(&pOpponent->inv[pTempItemPool->iItemIndex]);
}
- DeleteObj(&pOpponent->inv[pTempItemPool->iItemIndex]);
+ ////////////////////////////////////////////////////////////////////
}
pTempItemPool = pTempItemPool->pNext;
}
@@ -5649,6 +5763,13 @@ void SoldierStealItemFromSoldier( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
{
pSoldier->DoMercBattleSound( BATTLE_SOUND_GOTIT );
}
+
+ // SANDRO - show a message, that we had insufficient APs to take all items
+ if ( fNotEnoughAPs && pSoldier->bTeam == gbPlayerNum && gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_NOT_ENOUGH_APS_TO_STEAL_ALL], pSoldier->name );
+ }
+
gpTempSoldier = pSoldier;
gsTempGridNo = sGridNo;
SetCustomizableTimerCallbackAndDelay( 1000, CheckForPickedOwnership, TRUE );
diff --git a/Tactical/Handle Items.h b/Tactical/Handle Items.h
index 767b2118..f6d6f25f 100644
--- a/Tactical/Handle Items.h
+++ b/Tactical/Handle Items.h
@@ -54,15 +54,15 @@ typedef struct TAG_ITEM_POOL
struct TAG_ITEM_POOL *pNext;
struct TAG_ITEM_POOL *pPrev;
- INT32 iItemIndex;
- INT8 bVisible;
- INT8 bFlashColor;
- UINT32 uiTimerID;
- INT32 sGridNo;
- UINT8 ubLevel;
- UINT16 usFlags;
- INT8 bRenderZHeightAboveLevel;
- LEVELNODE *pLevelNode;
+ INT32 iItemIndex;
+ INT8 bVisible;
+ INT8 bFlashColor;
+ UINT32 uiTimerID;
+ INT32 sGridNo;
+ UINT8 ubLevel;
+ UINT16 usFlags;
+ INT8 bRenderZHeightAboveLevel;
+ LEVELNODE *pLevelNode;
} ITEM_POOL;
diff --git a/Tactical/Handle UI Plan.cpp b/Tactical/Handle UI Plan.cpp
index 2449ce28..81140b3e 100644
--- a/Tactical/Handle UI Plan.cpp
+++ b/Tactical/Handle UI Plan.cpp
@@ -67,7 +67,7 @@ BOOLEAN AddUIPlan( INT32 sGridNo, UINT8 ubPlanID )
// Adjust for running if we are not already running
if ( gpUIPlannedSoldier->usUIMovementMode == RUNNING )
{
- sAPCost += APBPConstants[AP_START_RUN_COST];
+ sAPCost += GetAPsStartRun( gpUIPlannedSoldier ); // changed by SANDRO
}
if ( EnoughPoints( gpUIPlannedSoldier, sAPCost, 0, FALSE ) )
diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp
index eb57745b..ed827448 100644
--- a/Tactical/Handle UI.cpp
+++ b/Tactical/Handle UI.cpp
@@ -88,10 +88,21 @@
#include "Map Information.h"
#include "Soldier Control.h"
#include "DisplayCover.h"
+ //ddd
+ #include "aiinternals.h"
+ //#include "los.h"
+ //#include "structure wrap.h"
+ //#include "DisplayCover.h"
+ //ddd
#endif
#include "teamturns.h"
+//////////////////////////////////////////////////////////////////////////////
+// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
+// On the bottom here, there are these functions made
+//////////////////////////////////////////////////////////////////////
+
//extern BOOLEAN gfDisplayFullCountRingBurst;
extern UINT16 PickSoldierReadyAnimation( SOLDIERTYPE *pSoldier, BOOLEAN fEndReady );
@@ -231,6 +242,8 @@ INT16 gsTreeRevealYPos;
// taken out of header to remove multiple symbol definitions (jonathanl)
BOOLEAN gfUICtHBar;
+// HEADROCK HAM 4: A new Struct to contain all CTH display data
+CTHDISPLAY gCTHDisplay;
// HEADROCK HAM B1/2: Created an array to hold CTH of different bullets for Burst/Auto CTH Bar.
UINT8 gbCtH[ 10 ];
UINT8 gbCtHBurstCount;
@@ -396,6 +409,10 @@ BOOLEAN gfUserTurnRegionActive = FALSE;
BOOLEAN fRightButtonDown = FALSE;
BOOLEAN fLeftButtonDown = FALSE;
BOOLEAN fIgnoreLeftUp = FALSE;
+///*** dddd
+BOOLEAN fMiddleButtonDown = FALSE;
+BOOLEAN fX1ButtonDown = FALSE;
+BOOLEAN fX2ButtonDown = FALSE;
BOOLEAN gUITargetReady = FALSE;
BOOLEAN gUITargetShotWaiting = FALSE;
@@ -477,6 +494,54 @@ void SetUIMouseCursor( );
void ClearEvent( UI_EVENT *pUIEvent );
UINT8 GetAdjustedAnimHeight( UINT8 ubAnimHeight, INT8 bChange );
+
+//-------------------------Legion 2 okno-----------------------------------------------------------
+void GetMercOknoDirection( UINT8 ubSoldierID, BOOLEAN *pfGoDown, BOOLEAN *pfGoUp )
+{
+ INT8 bNewDirection;
+ SOLDIERTYPE *pSoldier;
+
+ *pfGoDown = FALSE;
+ *pfGoUp = FALSE;
+
+ if ( !GetSoldier( &pSoldier, ubSoldierID ) )
+ {
+ return;
+ }
+
+ if ( pSoldier->pathing.bLevel == 0 && ( pSoldier->ubDirection == NORTH || pSoldier->ubDirection == EAST || pSoldier->ubDirection == SOUTH || pSoldier->ubDirection == WEST ))
+ {
+ if ( FindHeigherLevelOkno( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &bNewDirection ) )
+ {
+ *pfGoUp = TRUE;
+ }
+ }
+}
+
+void GetMercFenceDirection( UINT8 ubSoldierID, BOOLEAN *pfGoDown, BOOLEAN *pfGoUp )
+{
+ INT8 bNewDirection;
+ SOLDIERTYPE *pSoldier;
+
+ *pfGoDown = FALSE;
+ *pfGoUp = FALSE;
+
+ if ( !GetSoldier( &pSoldier, ubSoldierID ) )
+ {
+ return;
+ }
+
+ if ( pSoldier->pathing.bLevel == 0 )
+ {
+ if ( FindHeigherLevelFence( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &bNewDirection ) )
+ {
+ *pfGoUp = TRUE;
+ }
+ }
+}
+//----------------------------------------------------------------------------------
+
+
void PreventFromTheFreezingBug(SOLDIERTYPE* pSoldier)
{
gfUIInterfaceSetBusy = FALSE;
@@ -1207,6 +1272,59 @@ UINT32 UIHandleEndTurn( UI_EVENT *pUIEvent )
SaveGame( SAVE__END_TURN_NUM, L"End Turn Auto Save" );
}
+ ////ddd
+ if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT ) )
+ {
+//UINT32 uiStartTime, uiEndTime;
+//uiStartTime = GetJA2Clock();
+
+
+ memset( gubWorldTileInLight, FALSE, sizeof( gubWorldTileInLight ) );
+ memset( gubIsCorpseThere, FALSE, sizeof( gubIsCorpseThere ) );
+ memset( gubMerkCanSeeThisTile, FALSE, sizeof( gubMerkCanSeeThisTile ) );
+ // . WORLD_MAX .. ! !!! ;)
+ for(INT32 i=0; istats.bLife >= OKLIFE && tS->sGridNo != NOWHERE && tS->bInSector )
+ {
+ //loop through all the gridnos that we are interested in
+ for (sYOffset = -30; sYOffset <= 30; sYOffset++)
+ for (sXOffset = -30; sXOffset <= 30; sXOffset++)
+ {
+ sGridNo = tS->sGridNo + sXOffset + (MAXCOL * sYOffset);
+ if ( sGridNo <= 0 || sGridNo >= WORLD_MAX ) continue;
+ //usSightLimit = tS->GetMaxDistanceVisible(sGridNo, FALSE, CALC_FROM_WANTED_DIR);
+ if(gubMerkCanSeeThisTile[sGridNo]==0)
+ gubMerkCanSeeThisTile[sGridNo]=//SoldierToVirtualSoldierLineOfSightTest( tS, sGridNo, FALSE, ANIM_STAND, TRUE, usSightLimit );
+ SoldierToVirtualSoldierLineOfSightTest( tS, sGridNo, tS->pathing.bLevel,
+ ANIM_STAND, TRUE, CALC_FROM_WANTED_DIR);
+
+ }//fo
+ }//if
+/////////////////////////////////////////////////////////////////////////////
+//uiEndTime = GetJA2Clock();
+//ScreenMsg( 144,0, L"t=%d",uiEndTime - uiStartTime );
+//
+ }
+ //ddd **
+
// End our turn!
if (is_server || !is_client)
{
@@ -2100,7 +2218,7 @@ UINT32 UIHandleMCycleMovement( UI_EVENT *pUIEvent )
else if ( pSoldier->usUIMovementMode == SWATTING )
{
pSoldier->usUIMovementMode = CRAWLING;
- if ( IsValidMovementMode( pSoldier, CRAWLING ) )
+ if ( IsValidMovementMode( pSoldier, CRAWLING ) && IsValidStance(pSoldier, ANIM_PRONE) )
{
fGoodMode = TRUE;
}
@@ -2567,6 +2685,30 @@ void AttackRequesterCallback( UINT8 bExitValue )
}
}
+// SANDRO - added function
+void SurgeryRequesterCallback( UINT8 bExitValue )
+{
+ if( bExitValue == MSG_BOX_RETURN_YES )
+ {
+ //gpRequesterMerc->ubSurgeryApprovalMerc = gpRequesterTargetMerc->ubID;
+ gTacticalStatus.ubLastRequesterSurgeryTargetID = gpRequesterTargetMerc->ubID;
+
+ UIHandleMercAttack( gpRequesterMerc , gpRequesterTargetMerc, gsRequesterGridNo );
+ }
+ else if( bExitValue == MSG_BOX_RETURN_NO )
+ {
+ gTacticalStatus.ubLastRequesterSurgeryTargetID = NOBODY;
+
+ if (!gpRequesterTargetMerc->bBleeding && gpRequesterTargetMerc->stats.bLife >= OKLIFE)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_NO_NEED_FIRST_AID_STR ], gpRequesterTargetMerc->name );
+ }
+ else
+ {
+ UIHandleMercAttack( gpRequesterMerc , gpRequesterTargetMerc, gsRequesterGridNo );
+ }
+ }
+}
UINT32 UIHandleCAMercShoot( UI_EVENT *pUIEvent )
{
@@ -2611,6 +2753,30 @@ UINT32 UIHandleCAMercShoot( UI_EVENT *pUIEvent )
DoMessageBox( MSG_BOX_BASIC_STYLE, zStr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, AttackRequesterCallback, NULL );
}
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Should we ask if we really want to do the surgery?
+ else if (Item[ pSoldier->inv[ HANDPOS ].usItem ].medicalkit && (NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery)
+ && (pTSoldier->bTeam == OUR_TEAM || pTSoldier->bTeam == MILITIA_TEAM)
+ && (IS_MERC_BODY_TYPE( pTSoldier ) || IS_CIV_BODY_TYPE( pTSoldier ))
+ && gGameOptions.fNewTraitSystem && pTSoldier->iHealableInjury >= 100
+ && pTSoldier->ubID != pSoldier->ubID && gTacticalStatus.ubLastRequesterSurgeryTargetID != pTSoldier->ubID )
+ {
+ CHAR16 zStr[200];
+
+ gpRequesterMerc = pSoldier;
+ gpRequesterTargetMerc = pTSoldier;
+ gsRequesterGridNo = usMapPos;
+
+ fDidRequester = TRUE;
+
+ if (pTSoldier->bBleeding)
+ swprintf( zStr, New113Message[ MSG113_DO_WE_WANT_SURGERY_FIRST ], pTSoldier->name, (pTSoldier->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )) / 10000) );
+ else
+ swprintf( zStr, New113Message[ MSG113_DO_WE_WANT_SURGERY ], pTSoldier->name, (pTSoldier->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )) / 10000) );
+
+ DoMessageBox( MSG_BOX_BASIC_STYLE, zStr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, SurgeryRequesterCallback, NULL );
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////
}
if ( !fDidRequester )
@@ -3801,7 +3967,7 @@ INT8 DrawUIMovementPath( SOLDIERTYPE *pSoldier, INT32 usMapPos, UINT32 uiFlags )
{
sActionGridNo = sIntTileGridNo;
}
- CalcInteractiveObjectAPs( sIntTileGridNo, pStructure, &sAPCost, &sBPCost );
+ CalcInteractiveObjectAPs( pSoldier, sIntTileGridNo, pStructure, &sAPCost, &sBPCost ); // SANDRO - added argument
//sAPCost += UIPlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, PLOT, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
sAPCost += UIPlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, fPlot, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
@@ -4033,7 +4199,23 @@ INT8 DrawUIMovementPath( SOLDIERTYPE *pSoldier, INT32 usMapPos, UINT32 uiFlags )
{
sActionGridNo = sAdjustedGridNo;
}
- sAPCost += APBPConstants[AP_STEAL_ITEM];
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // CHANGED BY SANDRO - REDUCE AP COST TO STEAL FOR MARTIAL ARTS AND HAND TO HAND NEW TRAITS
+ if (MercPtrs[ gusUIFullTargetID ]->bCollapsed && gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ sAPCost += (GetBasicAPsToPickupItem( pSoldier )); // stealing from collapsed soldiers is treated differently
+ }
+ else if ((HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT )) && ( gGameOptions.fNewTraitSystem ))
+ {
+ sAPCost += max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5));
+ }
+ else
+ {
+ sAPCost += APBPConstants[AP_STEAL_ITEM];
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////
+
// CJC August 13 2002: take into account stance in AP prediction
if (!(PTR_STANDING))
{
@@ -4097,12 +4279,12 @@ INT8 DrawUIMovementPath( SOLDIERTYPE *pSoldier, INT32 usMapPos, UINT32 uiFlags )
sAPCost += UIPlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, fPlot, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints);
if ( sAPCost != 0 )
{
- sAPCost += APBPConstants[AP_PICKUP_ITEM];
+ sAPCost += GetBasicAPsToPickupItem( pSoldier ); // SANDRO
}
}
else
{
- sAPCost += APBPConstants[AP_PICKUP_ITEM];
+ sAPCost += GetBasicAPsToPickupItem( pSoldier ); // SANDRO
}
if ( sActionGridNo != pSoldier->sGridNo )
@@ -4145,19 +4327,21 @@ INT16 APsToTurnAround(SOLDIERTYPE *pSoldier, INT16 sAdjustedGridNo)
{
if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ( ANIM_BREATH | ANIM_OK_CHARGE_AP_FOR_TURN | ANIM_FIREREADY ) && !fInitalMove && !pSoldier->flags.fDontChargeTurningAPs )
{
- // Which position has the soldier?
- switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
- {
- case ANIM_STAND:
- sAPCost += APBPConstants[AP_LOOK_STANDING];
- break;
- case ANIM_CROUCH:
- sAPCost += APBPConstants[AP_LOOK_CROUCHED];
- break;
- case ANIM_PRONE:
- sAPCost += APBPConstants[AP_LOOK_PRONE];
- break;
- }
+ // SANDRO - hey, we have a function for this, why not to use it, huh?
+ sAPCost += GetAPsToLook( pSoldier );
+ //// Which position has the soldier?
+ //switch( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
+ //{
+ //case ANIM_STAND:
+ // sAPCost += APBPConstants[AP_LOOK_STANDING];
+ // break;
+ //case ANIM_CROUCH:
+ // sAPCost += APBPConstants[AP_LOOK_CROUCHED];
+ // break;
+ //case ANIM_PRONE:
+ // sAPCost += APBPConstants[AP_LOOK_PRONE];
+ // break;
+ //}
}
}
@@ -4312,18 +4496,27 @@ BOOLEAN UIMouseOnValidAttackLocation( SOLDIERTYPE *pSoldier )
return( FALSE );
}
- if ( pTSoldier->bBleeding == 0 && pTSoldier->stats.bLife != pTSoldier->stats.bLifeMax )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 19 ], pTSoldier->name );
- return( FALSE );
- }
-
- if ( pTSoldier->bBleeding == 0 && pTSoldier->stats.bLife >= OKLIFE )
+ // SANDRO - doctor with medical bag trying to do the surgery
+ if ((NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery) && Item[pSoldier->inv[ HANDPOS ].usItem].medicalkit && gGameOptions.fNewTraitSystem
+ && (pTSoldier->stats.bLife != pTSoldier->stats.bLifeMax) && (pTSoldier->iHealableInjury >= 100))
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_NO_NEED_FIRST_AID_STR ], pTSoldier->name );
- return( FALSE );
+ // should come a question first if you really want to do the surgery
+ return( TRUE );
}
+ else
+ {
+ if ( pTSoldier->bBleeding == 0 && pTSoldier->stats.bLife != pTSoldier->stats.bLifeMax )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 19 ], pTSoldier->name );
+ return( FALSE );
+ }
+ if ( pTSoldier->bBleeding == 0 && pTSoldier->stats.bLife >= OKLIFE )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ CANNOT_NO_NEED_FIRST_AID_STR ], pTSoldier->name );
+ return( FALSE );
+ }
+ }
}
return( TRUE );
@@ -4377,42 +4570,42 @@ BOOLEAN SoldierCanAffordNewStance( SOLDIERTYPE *pSoldier, UINT8 ubDesiredStance
if((UsingNewInventorySystem() == true))
if(pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag)
bAP = bBP = 1;
- bAP += APBPConstants[AP_CROUCH];
+ bAP += GetAPsCrouch(pSoldier, FALSE);
bBP += APBPConstants[BP_CROUCH];
break;
case ANIM_CROUCH - ANIM_STAND:
if((UsingNewInventorySystem() == true))
if(pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag)
bAP = bBP = 2;
- bAP += APBPConstants[AP_CROUCH];
+ bAP += GetAPsCrouch(pSoldier, FALSE);
bBP += APBPConstants[BP_CROUCH];
break;
case ANIM_STAND - ANIM_PRONE:
if((UsingNewInventorySystem() == true))
if(pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag)
bAP = bBP = 2;
- bAP += APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE];
+ bAP += GetAPsCrouch(pSoldier, FALSE) + GetAPsProne(pSoldier, FALSE);
bBP += APBPConstants[BP_CROUCH] + APBPConstants[BP_PRONE];
break;
case ANIM_PRONE - ANIM_STAND:
if((UsingNewInventorySystem() == true))
if(pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag)
bAP = bBP = 4;
- bAP += APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE];
+ bAP += GetAPsCrouch(pSoldier, FALSE) + GetAPsProne(pSoldier, FALSE);
bBP += APBPConstants[BP_CROUCH] + APBPConstants[BP_PRONE];
break;
case ANIM_CROUCH - ANIM_PRONE:
if((UsingNewInventorySystem() == true))
if(pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag)
bAP = bBP = 1;
- bAP += APBPConstants[AP_PRONE];
+ bAP += GetAPsProne(pSoldier, FALSE);
bBP += APBPConstants[BP_PRONE];
break;
case ANIM_PRONE - ANIM_CROUCH:
if((UsingNewInventorySystem() == true))
if(pSoldier->inv[BPACKPOCKPOS].exists() == true && !pSoldier->flags.ZipperFlag)
bAP = bBP = 2;
- bAP += APBPConstants[AP_PRONE];
+ bAP += GetAPsProne(pSoldier, FALSE);
bBP += APBPConstants[BP_PRONE];
break;
@@ -4466,6 +4659,9 @@ void SetMovementModeCursor( SOLDIERTYPE *pSoldier )
break;
case SWATTING:
+ ///ddd quick fix for losed cursor {
+ case SWATTING_WK:
+ ///ddd quick fix for losed cursor }
guiNewUICursor = MOVE_SWAT_UICURSOR;
break;
@@ -5590,7 +5786,9 @@ BOOLEAN IsValidTalkableNPC( UINT8 ubSoldierID, BOOLEAN fGive , BOOLEAN fAllowMer
}
}
- if ( pSoldier->ubProfile != NO_PROFILE && pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < GASTON && !RPC_RECRUITED( pSoldier ) && !AM_AN_EPC( pSoldier ) )
+// if ( pSoldier->ubProfile != NO_PROFILE && pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < GASTON && !RPC_RECRUITED( pSoldier ) && !AM_AN_EPC( pSoldier ) )
+ //new profiles by Jazz
+ if ( pSoldier->ubProfile != NO_PROFILE && ( gProfilesRPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile || gProfilesNPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile ) && !RPC_RECRUITED( pSoldier ) && !AM_AN_EPC( pSoldier ) )
{
fValidGuy = TRUE;
}
@@ -5739,7 +5937,7 @@ BOOLEAN HandleTalkInit( )
case 1:
- if ( QuoteExp_PassingDislike[ pTSoldier->ubProfile ] )
+ if ( QuoteExp[ pTSoldier->ubProfile ].QuoteExpPassingDislike )
{
ubQuoteNum = QUOTE_PASSING_DISLIKE;
}
@@ -6469,4 +6667,4 @@ BOOLEAN IsValidJumpLocation( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fChec
}
return( FALSE );
-}
+}
\ No newline at end of file
diff --git a/Tactical/Handle UI.h b/Tactical/Handle UI.h
index 14132fb4..672158a9 100644
--- a/Tactical/Handle UI.h
+++ b/Tactical/Handle UI.h
@@ -220,6 +220,20 @@ extern BOOLEAN gTintBulletCounts;
extern BOOLEAN gfUIAutofireBulletCount;
extern BOOLEAN gfUICtHBar;
+// HEADROCK HAM 4: Now a STRUCT containing several variables for CTH display
+typedef struct
+{
+ UINT8 MuzzleSwayPercentage;
+ FLOAT ScopeMagFactor;
+ FLOAT ProjectionFactor;
+ FLOAT FinalMagFactor;
+ INT32 iShooterGridNo;
+ INT32 iTargetGridNo;
+ FLOAT dTargetZ; // CellZ of target (not tile coordinates!)
+ BOOLEAN fMaxAimReached;
+} CTHDISPLAY;
+
+extern CTHDISPLAY gCTHDisplay;
// HEADROCK HAM B1/2: Multiple-bullet CTH bar array (replaces old single integer)
extern UINT8 gbCtH[ 10 ];
extern UINT8 gbCtHBurstCount;
@@ -353,4 +367,11 @@ void PreventFromTheFreezingBug(SOLDIERTYPE* pSoldier);
void GetGridNoScreenXY( INT32 sGridNo, INT16 *pScreenX, INT16 *pScreenY );
+//Legion by Jazz
+void GetMercOknoDirection( UINT8 ubSoldierID, BOOLEAN *pfGoDown, BOOLEAN *pfGoUp );
+void GetMercFenceDirection( UINT8 ubSoldierID, BOOLEAN *pfGoDown, BOOLEAN *pfGoUp );
+
+// HEADROCK HAM 4: Tells the targeting cursor whether we're adding bullets to autofire, or adding aim click levels.
+extern BOOLEAN fAutofireBulletsMode;
+
#endif
\ No newline at end of file
diff --git a/Tactical/Interface Control.cpp b/Tactical/Interface Control.cpp
index 80af3d22..4d633d96 100644
--- a/Tactical/Interface Control.cpp
+++ b/Tactical/Interface Control.cpp
@@ -49,6 +49,7 @@
#include "Militia Control.h"
#include "Map Screen Interface.h"
#include "civ quotes.h"
+ #include "GameSettings.h"
#endif
/* I deleted here declaration of clock coords for tactical screen i will declare them
@@ -689,6 +690,14 @@ void RenderTopmostTacticalInterface( )
RenderAccumulatedBurstLocations( );
+ // HEADROCK HAM 4: The NCTH indicator is now drawn to the FRAMEBUFFER instead of the MOUSEBUFFER. This is
+ // due to size constraints related to drawing directly on the cursor. This indicator follows the mouse, and
+ // is a mouse-cursor in everything but name. See the function itself for more details.
+ if (UsingNewCTHSystem() == true && gfUICtHBar)
+ {
+ DrawCTHIndicator();
+ }
+
// Loop through all mercs and make go
for ( cnt = 0; cnt < guiNumMercSlots; cnt++ )
{
diff --git a/Tactical/Interface Dialogue.cpp b/Tactical/Interface Dialogue.cpp
index 8ab979ee..b52bc05e 100644
--- a/Tactical/Interface Dialogue.cpp
+++ b/Tactical/Interface Dialogue.cpp
@@ -1800,7 +1800,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
ExitGrid.ubGotoSectorX = 10;
ExitGrid.ubGotoSectorY = 1;
ExitGrid.ubGotoSectorZ = 1;
- ExitGrid.usGridNo = 12722;
+ ExitGrid.usGridNo = 12722; //dnl!!!
ApplyMapChangesToMapTempFile( TRUE );
AddExitGridToWorld( 7887, &ExitGrid );
@@ -2260,7 +2260,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
case NPC_ACTION_SEND_PACOS_INTO_HIDING:
pSoldier = FindSoldierByProfileID( 114, FALSE );
- sGridNo = 16028;
+ sGridNo = 16028; //dnl!!!
if (pSoldier)
{
if (NewOKDestination( pSoldier, sGridNo, TRUE, 0 ) )
@@ -2280,7 +2280,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
break;
case NPC_ACTION_HAVE_PACOS_FOLLOW:
pSoldier = FindSoldierByProfileID( 114, FALSE );
- sGridNo = 18193;
+ sGridNo = 18193; //dnl!!!
if (pSoldier)
{
if (NewOKDestination( pSoldier, sGridNo, TRUE, 0 ) )
@@ -2314,6 +2314,8 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
case NPC_ACTION_TRIGGER_END_OF_FOOD_QUEST:
AddHistoryToPlayersLog( HISTORY_TALKED_TO_FATHER_WALKER, 0, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY );
AddFutureDayStrategicEvent( EVENT_SET_BY_NPC_SYSTEM, GetWorldMinutesInDay(), NPC_SYSTEM_EVENT_ACTION_PARAM_BONUS + NPC_ACTION_TRIGGER_END_OF_FOOD_QUEST, 1 );
+ // SANDRO - merc records - quest counter (food quest)
+ GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 4, NO_PROFILE );
break;
case NPC_ACTION_REMOVE_CONRAD:
@@ -2355,10 +2357,9 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
break;
case NPC_ACTION_DELAYED_MAKE_BRENDA_LEAVE:
- // set event to invoke Brenda's (#85) record 9 a minute from
- // now
+ // set event to invoke Brenda's (#85) record 9 ten minutes from now
DeleteTalkingMenu();
- AddSameDayStrategicEvent( EVENT_SET_BY_NPC_SYSTEM, GetWorldMinutesInDay() + 360, NPC_SYSTEM_EVENT_ACTION_PARAM_BONUS + NPC_ACTION_DELAYED_MAKE_BRENDA_LEAVE );
+ AddSameDayStrategicEvent( EVENT_SET_BY_NPC_SYSTEM, GetWorldMinutesInDay() + 10, NPC_SYSTEM_EVENT_ACTION_PARAM_BONUS + NPC_ACTION_DELAYED_MAKE_BRENDA_LEAVE );
break;
case NPC_ACTION_SEX:
@@ -2373,7 +2374,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
// add a money item with $10000 to the tile in front of Kyle
// and then have him pick it up
{
- INT32 sGridNo = 14952;
+ INT32 sGridNo = 14952; //dnl!!!
INT32 iWorldItem;
pSoldier = FindSoldierByProfileID( ubTargetNPC, FALSE );
@@ -2451,25 +2452,25 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
case NPC_ACTION_OPEN_CARLAS_DOOR:
if (usActionCode == NPC_ACTION_OPEN_CARLAS_DOOR )
{
- sGridNo = 12290;
+ sGridNo = 12290; //dnl!!!
}
// fall through
case NPC_ACTION_OPEN_CINDYS_DOOR:
if (usActionCode == NPC_ACTION_OPEN_CINDYS_DOOR )
{
- sGridNo = 13413;
+ sGridNo = 13413; //dnl!!!
}
// fall through
case NPC_ACTION_OPEN_BAMBIS_DOOR:
if (usActionCode == NPC_ACTION_OPEN_BAMBIS_DOOR )
{
- sGridNo = 11173;
+ sGridNo = 11173; //dnl!!!
}
// fall through
case NPC_ACTION_OPEN_MARIAS_DOOR:
if (usActionCode == NPC_ACTION_OPEN_MARIAS_DOOR )
{
- sGridNo = 10852;
+ sGridNo = 10852; //dnl!!!
}
// JA3Gold: unlock the doors instead of opening them
{
@@ -2890,6 +2891,15 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
}
// CJC Nov 28 2002 - fixed history record which didn't have location specified
AddHistoryToPlayersLog( HISTORY_GAVE_CARMEN_HEAD, 0, GetWorldTotalMin(), gWorldSectorX, gWorldSectorY );
+
+ // SANDRO - end the quest here - the team will gain exp and records by now
+ if (gMercProfiles[ CARMEN ].bNPCData <= 0)
+ {
+ SetFactTrue( FACT_ALL_TERRORISTS_KILLED );
+ EndQuest( QUEST_KILL_TERRORISTS, gWorldSectorX, gWorldSectorY );
+
+ IncrementTownLoyaltyEverywhere( LOYALTY_BONUS_TERRORISTS_DEALT_WITH );// end terrorist quest
+ }
break;
case NPC_ACTION_CARMEN_LEAVES_FOR_GOOD:
@@ -2903,13 +2913,14 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
break;
case NPC_ACTION_CARMEN_LEAVES_ON_NEXT_SECTOR_LOAD:
- if (gMercProfiles[ CARMEN ].bNPCData == 0)
- {
- SetFactTrue( FACT_ALL_TERRORISTS_KILLED );
- // the next time we change sectors, quest 2 will be set to done
+ // SANDRO - removed from here
+ // if (gMercProfiles[ CARMEN ].bNPCData == 0)
+ //{
+ // SetFactTrue( FACT_ALL_TERRORISTS_KILLED );
+ // // the next time we change sectors, quest 2 will be set to done
- IncrementTownLoyaltyEverywhere( LOYALTY_BONUS_TERRORISTS_DEALT_WITH );
- }
+ // IncrementTownLoyaltyEverywhere( LOYALTY_BONUS_TERRORISTS_DEALT_WITH );
+ //}
// anyhow Carmen has given the player money so reset his balance to 0.
gMercProfiles[ CARMEN ].uiMoney = 0;
break;
@@ -3186,7 +3197,7 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
if ( pSoldier->ubProfile == ARMAND )
{
- sGridNo = 6968;
+ sGridNo = 6968; //dnl!!!
}
else
{
@@ -3933,6 +3944,8 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
else
{
TriggerNPCRecord( SERGEANT, 12 );
+ // SANDRO - give reward for rescuing Krott and getting the rocket rifle
+ GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 5, CONRAD );
}
break;
@@ -3985,6 +3998,8 @@ void HandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum
if ( gfLastBoxingMatchWonByPlayer && !BoxerAvailable() )
{
TriggerNPCRecord( KINGPIN, 15 );
+ // SANDRO - merc records - quest counter (Kingpin impressed)
+ GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 4, NO_PROFILE );
}
break;
@@ -4845,7 +4860,7 @@ BOOLEAN NPCOpenThing( SOLDIERTYPE *pSoldier, BOOLEAN fDoor )
// for Armand, hard code to tile 6968
if ( pSoldier->ubProfile == ARMAND )
{
- sStructGridNo = 6968;
+ sStructGridNo = 6968; //dnl!!!
}
else
{
diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp
index a131ee46..ba05102d 100644
--- a/Tactical/Interface Enhanced.cpp
+++ b/Tactical/Interface Enhanced.cpp
@@ -90,201 +90,23 @@ UINT32 guiItemInfoWeaponIcon;
UINT32 guiItemInfoAmmoIcon;
UINT32 guiItemInfoExplosiveIcon;
UINT32 guiItemInfoArmorIcon;
-UINT32 guiItemInfoMiscIcon;
+//UINT32 guiItemInfoMiscIcon;
+// HEADROCK HAM 4: Image for secondary icons
+UINT32 guiItemInfoSecondaryIcon;
+// HEADROCK HAM 4: This replaces "Misc" icons.
+UINT32 guiItemInfoAdvancedIcon;
-// HEADROCK: Start additional values.
-INT16 BULLET_DRAW_X;
-INT16 BULLET_DRAW_Y;
-INT16 BULLET_AUTO_X;
-INT16 BULLET_AUTO_Y;
-INT16 BULLET_RELOAD_X;
-INT16 BULLET_RELOAD_Y;
-INT16 BULLET_MRELOAD_X;
-INT16 BULLET_MRELOAD_Y;
-INT16 BULLET_RANGE_X;
-INT16 BULLET_RANGE_Y;
-INT16 BULLET_DAMAGE_X;
-INT16 BULLET_DAMAGE_Y;
-INT16 BULLET_AUTOPEN_X;
-INT16 BULLET_AUTOPEN_Y;
-INT16 BULLET_AUTO5AP_X;
-INT16 BULLET_AUTO5AP_Y;
-INT16 BULLET_ACC_X;
-INT16 BULLET_ACC_Y;
-INT16 BULLET_RELIABILITY_X;
-INT16 BULLET_RELIABILITY_Y;
-INT16 BULLET_REPAIR_X;
-INT16 BULLET_REPAIR_Y;
-INT16 BULLET_LOUDNESS_X;
-INT16 BULLET_LOUDNESS_Y;
-INT16 BULLET_FLASH_X;
-INT16 BULLET_FLASH_Y;
-INT16 BULLET_TOHIT_X;
-INT16 BULLET_TOHIT_Y;
-INT16 BULLET_BESTLASERRANGE_X;
-INT16 BULLET_BESTLASERRANGE_Y;
-INT16 BULLET_AIMBONUS_X;
-INT16 BULLET_AIMBONUS_Y;
-INT16 BULLET_MINRANGEAIMBONUS_X;
-INT16 BULLET_MINRANGEAIMBONUS_Y;
-INT16 BULLET_BIPOD_X;
-INT16 BULLET_BIPOD_Y;
+// HEADROCK HAM 4: New tooltip regions for UDB replace the old regions.
+#define NUM_UDB_FASTHELP_REGIONS 102
+MOUSE_REGION gUDBFasthelpRegions[NUM_UDB_FASTHELP_REGIONS];
-// HEADROCK: Icon Locations for AMMO stats
-INT16 BULLET_ARMORPEN_X;
-INT16 BULLET_ARMORPEN_Y;
-INT16 BULLET_TUMBLE_X;
-INT16 BULLET_TUMBLE_Y;
-INT16 BULLET_PREARMOR_X;
-INT16 BULLET_PREARMOR_Y;
-INT16 BULLET_TRACER_X;
-INT16 BULLET_TRACER_Y;
-INT16 BULLET_ANTITANK_X;
-INT16 BULLET_ANTITANK_Y;
-INT16 BULLET_LOCKBUSTER_X;
-INT16 BULLET_LOCKBUSTER_Y;
-INT16 BULLET_IGNOREARMOR_X;
-INT16 BULLET_IGNOREARMOR_Y;
-INT16 BULLET_ACIDIC_X;
-INT16 BULLET_ACIDIC_Y;
-INT16 BULLET_AMMORANGEBON_X;
-INT16 BULLET_AMMORANGEBON_Y;
-INT16 BULLET_AMMODAMAGEBON_X;
-INT16 BULLET_AMMODAMAGEBON_Y;
-INT16 BULLET_AMMOTOHITBON_X;
-INT16 BULLET_AMMOTOHITBON_Y;
-INT16 BULLET_AMMOBURSTBON_X;
-INT16 BULLET_AMMOBURSTBON_Y;
-INT16 BULLET_AMMOAUTOBON_X;
-INT16 BULLET_AMMOAUTOBON_Y;
-INT16 BULLET_AMMORELIABILITYBON_X;
-INT16 BULLET_AMMORELIABILITYBON_Y;
-INT16 BULLET_AMMONOISESUPP_X;
-INT16 BULLET_AMMONOISESUPP_Y;
-
-// HEADROCK: Icon Locations for EXPLOSIVES stats
-INT16 BULLET_EXPLOSIVEDAMAGE_X;
-INT16 BULLET_EXPLOSIVEDAMAGE_Y;
-INT16 BULLET_EXPLOSIVESTUNDAMAGE_X;
-INT16 BULLET_EXPLOSIVESTUNDAMAGE_Y;
-INT16 BULLET_EXPLOSIVELOUDNESS_X;
-INT16 BULLET_EXPLOSIVELOUDNESS_Y;
-INT16 BULLET_EXPLOSIVEVOLATILITY_X;
-INT16 BULLET_EXPLOSIVEVOLATILITY_Y;
-INT16 BULLET_EXPLOSIVERADIUS_X;
-INT16 BULLET_EXPLOSIVERADIUS_Y;
-INT16 BULLET_EXPLOSIVESTARTRADIUS_X;
-INT16 BULLET_EXPLOSIVESTARTRADIUS_Y;
-INT16 BULLET_EXPLOSIVEARROW_X;
-INT16 BULLET_EXPLOSIVEARROW_Y;
-INT16 BULLET_EXPLOSIVEENDRADIUS_X;
-INT16 BULLET_EXPLOSIVEENDRADIUS_Y;
-INT16 BULLET_EXPLOSIVEDURATION_X;
-INT16 BULLET_EXPLOSIVEDURATION_Y;
-
-// HEADROCK: Icon Locations for ARMOR stats
-INT16 BULLET_ARMOR_X;
-INT16 BULLET_ARMOR_Y;
-INT16 BULLET_ARMORCOVERAGE_X;
-INT16 BULLET_ARMORCOVERAGE_Y;
-INT16 BULLET_ARMORDEGRADE_X;
-INT16 BULLET_ARMORDEGRADE_Y;
-INT16 BULLET_ARMORAPBONUS_X;
-INT16 BULLET_ARMORAPBONUS_Y;
-INT16 BULLET_ARMORAIMBONUS_X;
-INT16 BULLET_ARMORAIMBONUS_Y;
-INT16 BULLET_ARMORWOODCAMO_X;
-INT16 BULLET_ARMORWOODCAMO_Y;
-INT16 BULLET_ARMORURBANCAMO_X;
-INT16 BULLET_ARMORURBANCAMO_Y;
-INT16 BULLET_ARMORDESERTCAMO_X;
-INT16 BULLET_ARMORDESERTCAMO_Y;
-INT16 BULLET_ARMORSNOWCAMO_X;
-INT16 BULLET_ARMORSNOWCAMO_Y;
-INT16 BULLET_ARMORSTEALTH_X;
-INT16 BULLET_ARMORSTEALTH_Y;
-INT16 BULLET_ARMORVISIONRANGEBONUS_X;
-INT16 BULLET_ARMORVISIONRANGEBONUS_Y;
-INT16 BULLET_ARMORDAYVISIONRANGEBONUS_X;
-INT16 BULLET_ARMORDAYVISIONRANGEBONUS_Y;
-INT16 BULLET_ARMORNIGHTVISIONRANGEBONUS_X;
-INT16 BULLET_ARMORNIGHTVISIONRANGEBONUS_Y;
-INT16 BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_X;
-INT16 BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_Y;
-INT16 BULLET_ARMORCAVEVISIONRANGEBONUS_X;
-INT16 BULLET_ARMORCAVEVISIONRANGEBONUS_Y;
-INT16 BULLET_ARMORPERCENTTUNNELVISION_X;
-INT16 BULLET_ARMORPERCENTTUNNELVISION_Y;
-INT16 BULLET_ARMORHEARINGRANGEBONUS_X;
-INT16 BULLET_ARMORHEARINGRANGEBONUS_Y;
-
-// HEADROCK: Generic Icon Locations for MISC Item Stats
-INT16 BULLET_COL1ROW1_X;
-INT16 BULLET_COL1ROW1_Y;
-INT16 BULLET_COL1ROW2_X;
-INT16 BULLET_COL1ROW2_Y;
-INT16 BULLET_COL1ROW3_X;
-INT16 BULLET_COL1ROW3_Y;
-INT16 BULLET_COL1ROW4_X;
-INT16 BULLET_COL1ROW4_Y;
-INT16 BULLET_COL1ROW5_X;
-INT16 BULLET_COL1ROW5_Y;
-INT16 BULLET_COL1ROW6_X;
-INT16 BULLET_COL1ROW6_Y;
-INT16 BULLET_COL1ROW7_X;
-INT16 BULLET_COL1ROW7_Y;
-INT16 BULLET_COL1ROW8_X;
-INT16 BULLET_COL1ROW8_Y;
-INT16 BULLET_COL1ROW9_X;
-INT16 BULLET_COL1ROW9_Y;
-INT16 BULLET_COL1ROW10_X;
-INT16 BULLET_COL1ROW10_Y;
-INT16 BULLET_COL1ROW11_X;
-INT16 BULLET_COL1ROW11_Y;
-INT16 BULLET_COL1ROW12_X;
-INT16 BULLET_COL1ROW12_Y;
-INT16 BULLET_COL2ROW1_X;
-INT16 BULLET_COL2ROW1_Y;
-INT16 BULLET_COL2ROW2_X;
-INT16 BULLET_COL2ROW2_Y;
-INT16 BULLET_COL2ROW3_X;
-INT16 BULLET_COL2ROW3_Y;
-INT16 BULLET_COL2ROW4_X;
-INT16 BULLET_COL2ROW4_Y;
-INT16 BULLET_COL2ROW5_X;
-INT16 BULLET_COL2ROW5_Y;
-INT16 BULLET_COL2ROW6_X;
-INT16 BULLET_COL2ROW6_Y;
-INT16 BULLET_COL2ROW7_X;
-INT16 BULLET_COL2ROW7_Y;
-// HEADROCK: End additional values.
-
-// HEADROCK: New regions for stats tooltips
-MOUSE_REGION gStatsFasthelpRegions[20];
-
-extern INV_DESC_STATS gWeaponStats[];
extern INV_DESC_STATS gMoneyStats[];
-extern SGPRect gItemDescProsConsRects[];
extern INV_DESC_STATS gLBEStats[];
extern INV_ATTACHXY gItemDescAttachmentsXY[];
-
-// HEADROCK: New array to contain locations for MiscItem stats.
-INV_DESC_STATS gMiscItemStatsEDB[28];
-
-// WEAPON stat tooltips
-SGPRect gWeaponDescStatsRects[20];
-
-// Ammo Stat Tooltips
-SGPRect gAmmoDescStatsRects[20];
-
-// ARMOR Stat Tooltips
-SGPRect gArmorDescStatsRects[20];
-
-// EXPLOSIVES Stat Tooltips
-SGPRect gExplosiveDescStatsRects[20];
-
-// MISC ITEM Stat Tooltips
-SGPRect gMiscItemDescStatsRects[20];
+// HEADROCK HAM 4: Declare here so other functions may use it.
+void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject );
+void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject );
+void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject );
extern void HelpTextDoneCallback( void );
@@ -292,449 +114,583 @@ UINT8 UsingEDBSystem()
{
if(iResolution == 0) //640x480, never allow EDB
return 0;
+
if(gGameSettings.fOptions[ TOPTION_ENHANCED_DESC_BOX ] == TRUE)
{
if(guiCurrentScreen == MAP_SCREEN) //Strategic
{
- if(gGameExternalOptions.iEnhancedDescriptionBox == 0)
- return 1;
- if(gGameExternalOptions.iEnhancedDescriptionBox == 1)
+ if(gGameExternalOptions.iEnhancedDescriptionBox == 0 || gGameExternalOptions.iEnhancedDescriptionBox == 1 )
return 1;
}
else //Tactical
{
- if(gGameExternalOptions.iEnhancedDescriptionBox == 0)
- return (UsingNewInventorySystem()==true?1:2);
- if(gGameExternalOptions.iEnhancedDescriptionBox == 2)
- return (UsingNewInventorySystem()==true?1:2);
+ // HEADROCK HAM 4: With the introduction of UDB, it is no longer possible to display an extended
+ // description box for OIV (unless the interface panel is increased... which I doubt it will be).
+ if (UsingNewInventorySystem()==false)
+ return 0;
+ if(gGameExternalOptions.iEnhancedDescriptionBox == 0 || gGameExternalOptions.iEnhancedDescriptionBox == 2)
+ return 1;
}
}
return 0;
}
-void InitEDBCoords()
+void InitEDBCoords(OBJECTTYPE * pObject)
{
- if(UsingEDBSystem() == 0)
- return;
- if(guiCurrentScreen == MAP_SCREEN)
+ if (UsingEDBSystem() > 0)
{
- // Icon Locations
- gMiscItemStatsEDB[0].sX = 47; gMiscItemStatsEDB[0].sY = 124; gMiscItemStatsEDB[0].sValDx = 0; // COL 1; ROW 1
- gMiscItemStatsEDB[1].sX = 47; gMiscItemStatsEDB[1].sY = 136; gMiscItemStatsEDB[1].sValDx = 0; // COL 1; ROW 2
- gMiscItemStatsEDB[2].sX = 47; gMiscItemStatsEDB[2].sY = 148; gMiscItemStatsEDB[2].sValDx = 0; // COL 1; ROW 3
- gMiscItemStatsEDB[3].sX = 47; gMiscItemStatsEDB[3].sY = 160; gMiscItemStatsEDB[3].sValDx = 0; // COL 1; ROW 4
- gMiscItemStatsEDB[4].sX = 47; gMiscItemStatsEDB[4].sY = 172; gMiscItemStatsEDB[4].sValDx = 0; // COL 1; ROW 5
- gMiscItemStatsEDB[5].sX = 47; gMiscItemStatsEDB[5].sY = 184; gMiscItemStatsEDB[5].sValDx = 0; // COL 1; ROW 6
- gMiscItemStatsEDB[6].sX = 47; gMiscItemStatsEDB[6].sY = 196; gMiscItemStatsEDB[6].sValDx = 0; // COL 1; ROW 7
- gMiscItemStatsEDB[7].sX = 144; gMiscItemStatsEDB[7].sY = 124; gMiscItemStatsEDB[7].sValDx = 0; // COL 2; ROW 1
- gMiscItemStatsEDB[8].sX = 144; gMiscItemStatsEDB[8].sY = 136; gMiscItemStatsEDB[8].sValDx = 0; // COL 2; ROW 2
- gMiscItemStatsEDB[9].sX = 144; gMiscItemStatsEDB[9].sY = 148; gMiscItemStatsEDB[9].sValDx = 0; // COL 2; ROW 3
- gMiscItemStatsEDB[10].sX = 144; gMiscItemStatsEDB[10].sY = 160; gMiscItemStatsEDB[10].sValDx = 0; // COL 2; ROW 4
- gMiscItemStatsEDB[11].sX = 144; gMiscItemStatsEDB[11].sY = 172; gMiscItemStatsEDB[11].sValDx = 0; // COL 2; ROW 5
- gMiscItemStatsEDB[12].sX = 144; gMiscItemStatsEDB[12].sY = 184; gMiscItemStatsEDB[12].sValDx = 0; // COL 2; ROW 6
- gMiscItemStatsEDB[13].sX = 144; gMiscItemStatsEDB[13].sY = 196; gMiscItemStatsEDB[13].sValDx = 0; // COL 2; ROW 7
- // EQUALS signs Locations
- gMiscItemStatsEDB[14].sX = 97; gMiscItemStatsEDB[14].sY = 124; gMiscItemStatsEDB[14].sValDx = 12; // COL 1; ROW 1
- gMiscItemStatsEDB[15].sX = 97; gMiscItemStatsEDB[15].sY = 136; gMiscItemStatsEDB[15].sValDx = 12; // COL 1; ROW 2
- gMiscItemStatsEDB[16].sX = 97; gMiscItemStatsEDB[16].sY = 148; gMiscItemStatsEDB[16].sValDx = 12; // COL 1; ROW 3
- gMiscItemStatsEDB[17].sX = 97; gMiscItemStatsEDB[17].sY = 160; gMiscItemStatsEDB[17].sValDx = 12; // COL 1; ROW 4
- gMiscItemStatsEDB[18].sX = 97; gMiscItemStatsEDB[18].sY = 172; gMiscItemStatsEDB[18].sValDx = 12; // COL 1; ROW 5
- gMiscItemStatsEDB[19].sX = 97; gMiscItemStatsEDB[19].sY = 184; gMiscItemStatsEDB[19].sValDx = 12; // COL 1; ROW 6
- gMiscItemStatsEDB[20].sX = 97; gMiscItemStatsEDB[20].sY = 196; gMiscItemStatsEDB[20].sValDx = 12; // COL 1; ROW 7
- gMiscItemStatsEDB[21].sX = 194; gMiscItemStatsEDB[21].sY = 124; gMiscItemStatsEDB[21].sValDx = 12; // COL 2; ROW 1
- gMiscItemStatsEDB[22].sX = 194; gMiscItemStatsEDB[22].sY = 136; gMiscItemStatsEDB[22].sValDx = 12; // COL 2; ROW 2
- gMiscItemStatsEDB[23].sX = 194; gMiscItemStatsEDB[23].sY = 148; gMiscItemStatsEDB[23].sValDx = 12; // COL 2; ROW 3
- gMiscItemStatsEDB[24].sX = 194; gMiscItemStatsEDB[24].sY = 160; gMiscItemStatsEDB[24].sValDx = 12; // COL 2; ROW 4
- gMiscItemStatsEDB[25].sX = 194; gMiscItemStatsEDB[25].sY = 172; gMiscItemStatsEDB[25].sValDx = 12; // COL 2; ROW 5
- gMiscItemStatsEDB[26].sX = 194; gMiscItemStatsEDB[26].sY = 184; gMiscItemStatsEDB[26].sValDx = 12; // COL 2; ROW 6
- gMiscItemStatsEDB[27].sX = 194; gMiscItemStatsEDB[27].sY = 196; gMiscItemStatsEDB[27].sValDx = 12; // COL 2; ROW 7
+ //////////////////////////////////////////////////////////////
+ // UDB Offsets.
+ // These offsets allow us to efficiently render UDB in two different places (for Strategic
+ // and Tactical) without changing anything else. This is thanks to UDB being almost exactly
+ // the same interface in both screens!
- gWeaponDescStatsRects[0].iLeft = 46; gWeaponDescStatsRects[0].iTop = 229; gWeaponDescStatsRects[0].iRight = 103; gWeaponDescStatsRects[0].iBottom = 240; // First Column
- gWeaponDescStatsRects[1].iLeft = 46; gWeaponDescStatsRects[1].iTop = 241; gWeaponDescStatsRects[1].iRight = 103; gWeaponDescStatsRects[1].iBottom = 252;
- gWeaponDescStatsRects[2].iLeft = 46; gWeaponDescStatsRects[2].iTop = 253; gWeaponDescStatsRects[2].iRight = 103; gWeaponDescStatsRects[2].iBottom = 264;
- gWeaponDescStatsRects[3].iLeft = 46; gWeaponDescStatsRects[3].iTop = 265; gWeaponDescStatsRects[3].iRight = 103; gWeaponDescStatsRects[3].iBottom = 276;
- gWeaponDescStatsRects[4].iLeft = 46; gWeaponDescStatsRects[4].iTop = 277; gWeaponDescStatsRects[4].iRight = 103; gWeaponDescStatsRects[4].iBottom = 288;
- gWeaponDescStatsRects[5].iLeft = 46; gWeaponDescStatsRects[5].iTop = 289; gWeaponDescStatsRects[5].iRight = 103; gWeaponDescStatsRects[5].iBottom = 300;
- gWeaponDescStatsRects[6].iLeft = 46; gWeaponDescStatsRects[6].iTop = 301; gWeaponDescStatsRects[6].iRight = 103; gWeaponDescStatsRects[6].iBottom = 312;
- gWeaponDescStatsRects[7].iLeft = 111; gWeaponDescStatsRects[7].iTop = 241; gWeaponDescStatsRects[7].iRight = 168; gWeaponDescStatsRects[7].iBottom = 252; // Second Column
- gWeaponDescStatsRects[8].iLeft = 111; gWeaponDescStatsRects[8].iTop = 253; gWeaponDescStatsRects[8].iRight = 168; gWeaponDescStatsRects[8].iBottom = 264;
- gWeaponDescStatsRects[9].iLeft = 111; gWeaponDescStatsRects[9].iTop = 265; gWeaponDescStatsRects[9].iRight = 168; gWeaponDescStatsRects[9].iBottom = 276;
- gWeaponDescStatsRects[10].iLeft = 111; gWeaponDescStatsRects[10].iTop = 277; gWeaponDescStatsRects[10].iRight = 168; gWeaponDescStatsRects[10].iBottom = 288;
- gWeaponDescStatsRects[11].iLeft = 111; gWeaponDescStatsRects[11].iTop = 289; gWeaponDescStatsRects[11].iRight = 168; gWeaponDescStatsRects[11].iBottom = 300;
- gWeaponDescStatsRects[12].iLeft = 111; gWeaponDescStatsRects[12].iTop = 301; gWeaponDescStatsRects[12].iRight = 168; gWeaponDescStatsRects[12].iBottom = 312;
- gWeaponDescStatsRects[13].iLeft = 173; gWeaponDescStatsRects[13].iTop = 229; gWeaponDescStatsRects[13].iRight = 230; gWeaponDescStatsRects[13].iBottom = 240; // Third Column
- gWeaponDescStatsRects[14].iLeft = 173; gWeaponDescStatsRects[14].iTop = 241; gWeaponDescStatsRects[14].iRight = 230; gWeaponDescStatsRects[14].iBottom = 252;
- gWeaponDescStatsRects[15].iLeft = 173; gWeaponDescStatsRects[15].iTop = 253; gWeaponDescStatsRects[15].iRight = 230; gWeaponDescStatsRects[15].iBottom = 264;
- gWeaponDescStatsRects[16].iLeft = 173; gWeaponDescStatsRects[16].iTop = 265; gWeaponDescStatsRects[16].iRight = 230; gWeaponDescStatsRects[16].iBottom = 276;
- gWeaponDescStatsRects[17].iLeft = 173; gWeaponDescStatsRects[17].iTop = 277; gWeaponDescStatsRects[17].iRight = 230; gWeaponDescStatsRects[17].iBottom = 288;
- gWeaponDescStatsRects[18].iLeft = 173; gWeaponDescStatsRects[18].iTop = 289; gWeaponDescStatsRects[18].iRight = 230; gWeaponDescStatsRects[18].iBottom = 300;
- gWeaponDescStatsRects[19].iLeft = 173; gWeaponDescStatsRects[19].iTop = 301; gWeaponDescStatsRects[19].iRight = 230; gWeaponDescStatsRects[19].iBottom = 312;
+ INT16 UDBOffsetX;
+ INT16 UDBOffsetY;
+
+ UDBOffsetX = gsInvDescX;
+ UDBOffsetY = gsInvDescY;
- gAmmoDescStatsRects[0].iLeft = 46; gAmmoDescStatsRects[0].iTop = 229; gAmmoDescStatsRects[0].iRight = 103; gAmmoDescStatsRects[0].iBottom = 240; // First Column
- gAmmoDescStatsRects[1].iLeft = 46; gAmmoDescStatsRects[1].iTop = 241; gAmmoDescStatsRects[1].iRight = 103; gAmmoDescStatsRects[1].iBottom = 252;
- gAmmoDescStatsRects[2].iLeft = 46; gAmmoDescStatsRects[2].iTop = 253; gAmmoDescStatsRects[2].iRight = 103; gAmmoDescStatsRects[2].iBottom = 264;
- gAmmoDescStatsRects[3].iLeft = 113; gAmmoDescStatsRects[3].iTop = 229; gAmmoDescStatsRects[3].iRight = 135; gAmmoDescStatsRects[3].iBottom = 252; // Second Column
- gAmmoDescStatsRects[4].iLeft = 140; gAmmoDescStatsRects[4].iTop = 229; gAmmoDescStatsRects[4].iRight = 165; gAmmoDescStatsRects[4].iBottom = 252;
- gAmmoDescStatsRects[5].iLeft = 113; gAmmoDescStatsRects[5].iTop = 253; gAmmoDescStatsRects[5].iRight = 135; gAmmoDescStatsRects[5].iBottom = 276;
- gAmmoDescStatsRects[6].iLeft = 140; gAmmoDescStatsRects[6].iTop = 253; gAmmoDescStatsRects[6].iRight = 165; gAmmoDescStatsRects[6].iBottom = 276;
- gAmmoDescStatsRects[7].iLeft = 113; gAmmoDescStatsRects[7].iTop = 277; gAmmoDescStatsRects[7].iRight = 135; gAmmoDescStatsRects[7].iBottom = 300;
- gAmmoDescStatsRects[8].iLeft = 173; gAmmoDescStatsRects[8].iTop = 229; gAmmoDescStatsRects[8].iRight = 230; gAmmoDescStatsRects[8].iBottom = 240; // Third Column
- gAmmoDescStatsRects[9].iLeft = 173; gAmmoDescStatsRects[9].iTop = 241; gAmmoDescStatsRects[9].iRight = 230; gAmmoDescStatsRects[9].iBottom = 252;
- gAmmoDescStatsRects[10].iLeft = 173; gAmmoDescStatsRects[10].iTop = 253; gAmmoDescStatsRects[10].iRight = 230; gAmmoDescStatsRects[10].iBottom = 264;
- gAmmoDescStatsRects[11].iLeft = 173; gAmmoDescStatsRects[11].iTop = 265; gAmmoDescStatsRects[11].iRight = 230; gAmmoDescStatsRects[11].iBottom = 276;
- gAmmoDescStatsRects[12].iLeft = 173; gAmmoDescStatsRects[12].iTop = 277; gAmmoDescStatsRects[12].iRight = 230; gAmmoDescStatsRects[12].iBottom = 288; // Fourth Column
- gAmmoDescStatsRects[13].iLeft = 173; gAmmoDescStatsRects[13].iTop = 289; gAmmoDescStatsRects[13].iRight = 230; gAmmoDescStatsRects[13].iBottom = 300;
- gAmmoDescStatsRects[14].iLeft = 173; gAmmoDescStatsRects[14].iTop = 301; gAmmoDescStatsRects[14].iRight = 230; gAmmoDescStatsRects[14].iBottom = 312; // Placeholders
- gAmmoDescStatsRects[15].iLeft = 0; gAmmoDescStatsRects[15].iTop = 0; gAmmoDescStatsRects[15].iRight = 1; gAmmoDescStatsRects[15].iBottom = 1;
- gAmmoDescStatsRects[16].iLeft = 0; gAmmoDescStatsRects[16].iTop = 0; gAmmoDescStatsRects[16].iRight = 1; gAmmoDescStatsRects[16].iBottom = 1;
- gAmmoDescStatsRects[17].iLeft = 0; gAmmoDescStatsRects[17].iTop = 0; gAmmoDescStatsRects[17].iRight = 1; gAmmoDescStatsRects[17].iBottom = 1;
- gAmmoDescStatsRects[18].iLeft = 0; gAmmoDescStatsRects[18].iTop = 0; gAmmoDescStatsRects[18].iRight = 1; gAmmoDescStatsRects[18].iBottom = 1;
- gAmmoDescStatsRects[19].iLeft = 0; gAmmoDescStatsRects[19].iTop = 0; gAmmoDescStatsRects[19].iRight = 1; gAmmoDescStatsRects[19].iBottom = 1;
+ // Adjust for NAS
+ if(UsingNewAttachmentSystem() == true)
+ {
+ UDBOffsetX += sNASXCorrection(pObject);
+ UDBOffsetY += sNASYCorrection(pObject);
+ }
+ // If no NAS, adjust tactical screen coordinates separately.
+ if (guiCurrentScreen != MAP_SCREEN)
+ {
+ UDBOffsetX += 224;
+ UDBOffsetY += -114;
+ if (UseNASDesc( pObject ))
+ {
+ UDBOffsetX -= 128;
+ }
+ }
- gArmorDescStatsRects[0].iLeft = 46; gArmorDescStatsRects[0].iTop = 229; gArmorDescStatsRects[0].iRight = 103; gArmorDescStatsRects[0].iBottom = 240; // First Column
- gArmorDescStatsRects[1].iLeft = 46; gArmorDescStatsRects[1].iTop = 241; gArmorDescStatsRects[1].iRight = 103; gArmorDescStatsRects[1].iBottom = 252;
- gArmorDescStatsRects[2].iLeft = 46; gArmorDescStatsRects[2].iTop = 253; gArmorDescStatsRects[2].iRight = 103; gArmorDescStatsRects[2].iBottom = 264;
- gArmorDescStatsRects[3].iLeft = 111; gArmorDescStatsRects[3].iTop = 229; gArmorDescStatsRects[3].iRight = 168; gArmorDescStatsRects[3].iBottom = 240; // Second Column
- gArmorDescStatsRects[4].iLeft = 111; gArmorDescStatsRects[4].iTop = 241; gArmorDescStatsRects[4].iRight = 168; gArmorDescStatsRects[4].iBottom = 252;
- gArmorDescStatsRects[5].iLeft = 111; gArmorDescStatsRects[5].iTop = 253; gArmorDescStatsRects[5].iRight = 168; gArmorDescStatsRects[5].iBottom = 264;
- gArmorDescStatsRects[6].iLeft = 111; gArmorDescStatsRects[6].iTop = 265; gArmorDescStatsRects[6].iRight = 168; gArmorDescStatsRects[6].iBottom = 276;
- gArmorDescStatsRects[7].iLeft = 111; gArmorDescStatsRects[7].iTop = 277; gArmorDescStatsRects[7].iRight = 168; gArmorDescStatsRects[7].iBottom = 288;
- gArmorDescStatsRects[8].iLeft = 111; gArmorDescStatsRects[8].iTop = 289; gArmorDescStatsRects[8].iRight = 168; gArmorDescStatsRects[8].iBottom = 300;
- gArmorDescStatsRects[9].iLeft = 111; gArmorDescStatsRects[9].iTop = 301; gArmorDescStatsRects[9].iRight = 168; gArmorDescStatsRects[9].iBottom = 312;
- gArmorDescStatsRects[10].iLeft = 173; gArmorDescStatsRects[10].iTop = 229; gArmorDescStatsRects[10].iRight = 230; gArmorDescStatsRects[10].iBottom = 240; // Third Column
- gArmorDescStatsRects[11].iLeft = 173; gArmorDescStatsRects[11].iTop = 241; gArmorDescStatsRects[11].iRight = 230; gArmorDescStatsRects[11].iBottom = 252;
- gArmorDescStatsRects[12].iLeft = 173; gArmorDescStatsRects[12].iTop = 253; gArmorDescStatsRects[12].iRight = 230; gArmorDescStatsRects[12].iBottom = 264;
- gArmorDescStatsRects[13].iLeft = 173; gArmorDescStatsRects[13].iTop = 265; gArmorDescStatsRects[13].iRight = 230; gArmorDescStatsRects[13].iBottom = 276;
- gArmorDescStatsRects[14].iLeft = 173; gArmorDescStatsRects[14].iTop = 277; gArmorDescStatsRects[14].iRight = 230; gArmorDescStatsRects[14].iBottom = 288;
- gArmorDescStatsRects[15].iLeft = 173; gArmorDescStatsRects[15].iTop = 289; gArmorDescStatsRects[15].iRight = 230; gArmorDescStatsRects[15].iBottom = 300;
- gArmorDescStatsRects[16].iLeft = 173; gArmorDescStatsRects[16].iTop = 301; gArmorDescStatsRects[16].iRight = 230; gArmorDescStatsRects[16].iBottom = 312;
- gArmorDescStatsRects[17].iLeft = 0; gArmorDescStatsRects[17].iTop = 0; gArmorDescStatsRects[17].iRight = 1; gArmorDescStatsRects[17].iBottom = 1; // Placeholders
- gArmorDescStatsRects[18].iLeft = 0; gArmorDescStatsRects[18].iTop = 0; gArmorDescStatsRects[18].iRight = 1; gArmorDescStatsRects[18].iBottom = 1;
- gArmorDescStatsRects[19].iLeft = 0; gArmorDescStatsRects[19].iTop = 0; gArmorDescStatsRects[19].iRight = 1; gArmorDescStatsRects[19].iBottom = 1;
+ ///////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB LBE background coordinates
+ // These depend on Strategic/Tactical...
+ if (guiCurrentScreen == MAP_SCREEN)
+ {
+ gItemDescLBEBackground[0].sLeft = 58 + UDBOffsetX; gItemDescLBEBackground[0].sTop = 366 + UDBOffsetY;
+ gItemDescLBEBackground[1].sLeft = 15 + UDBOffsetX; gItemDescLBEBackground[1].sTop = 416 + UDBOffsetY;
+ gItemDescLBEBackground[2].sLeft = 59 + UDBOffsetX; gItemDescLBEBackground[2].sTop = 340 + UDBOffsetY;
+ gItemDescLBEBackground[3].sLeft = 25 + UDBOffsetX; gItemDescLBEBackground[3].sTop = 346 + UDBOffsetY;
+ }
+ else
+ {
+ gItemDescLBEBackground[0].sLeft = 251 + UDBOffsetX; gItemDescLBEBackground[0].sTop = 121 + UDBOffsetY;
+ gItemDescLBEBackground[1].sLeft = 251 + UDBOffsetX; gItemDescLBEBackground[1].sTop = 121 + UDBOffsetY;
+ gItemDescLBEBackground[2].sLeft = 251 + UDBOffsetX; gItemDescLBEBackground[2].sTop = 121 + UDBOffsetY;
+ gItemDescLBEBackground[3].sLeft = 251 + UDBOffsetX; gItemDescLBEBackground[3].sTop = 121 + UDBOffsetY;
+ }
- gExplosiveDescStatsRects[0].iLeft = 46; gExplosiveDescStatsRects[0].iTop = 229; gExplosiveDescStatsRects[0].iRight = 103; gExplosiveDescStatsRects[0].iBottom = 240; // First Column
- gExplosiveDescStatsRects[1].iLeft = 46; gExplosiveDescStatsRects[1].iTop = 241; gExplosiveDescStatsRects[1].iRight = 103; gExplosiveDescStatsRects[1].iBottom = 252;
- gExplosiveDescStatsRects[2].iLeft = 46; gExplosiveDescStatsRects[2].iTop = 253; gExplosiveDescStatsRects[2].iRight = 103; gExplosiveDescStatsRects[2].iBottom = 264;
- gExplosiveDescStatsRects[3].iLeft = 46; gExplosiveDescStatsRects[3].iTop = 265; gExplosiveDescStatsRects[3].iRight = 103; gExplosiveDescStatsRects[3].iBottom = 276;
- gExplosiveDescStatsRects[4].iLeft = 131; gExplosiveDescStatsRects[4].iTop = 229; gExplosiveDescStatsRects[4].iRight = 147; gExplosiveDescStatsRects[4].iBottom = 264; // Second Column
- gExplosiveDescStatsRects[5].iLeft = 113; gExplosiveDescStatsRects[5].iTop = 229; gExplosiveDescStatsRects[5].iRight = 129; gExplosiveDescStatsRects[5].iBottom = 264;
- gExplosiveDescStatsRects[6].iLeft = 145; gExplosiveDescStatsRects[6].iTop = 229; gExplosiveDescStatsRects[6].iRight = 165; gExplosiveDescStatsRects[6].iBottom = 264;
- gExplosiveDescStatsRects[7].iLeft = 111; gExplosiveDescStatsRects[7].iTop = 277; gExplosiveDescStatsRects[7].iRight = 168; gExplosiveDescStatsRects[7].iBottom = 288;
- gExplosiveDescStatsRects[8].iLeft = 0; gExplosiveDescStatsRects[8].iTop = 0; gExplosiveDescStatsRects[8].iRight = 1; gExplosiveDescStatsRects[8].iBottom = 1; // Placeholders
- gExplosiveDescStatsRects[9].iLeft = 0; gExplosiveDescStatsRects[9].iTop = 0; gExplosiveDescStatsRects[9].iRight = 1; gExplosiveDescStatsRects[9].iBottom = 1;
- gExplosiveDescStatsRects[10].iLeft = 0; gExplosiveDescStatsRects[10].iTop = 0; gExplosiveDescStatsRects[10].iRight = 1; gExplosiveDescStatsRects[10].iBottom = 1;
- gExplosiveDescStatsRects[11].iLeft = 0; gExplosiveDescStatsRects[11].iTop = 0; gExplosiveDescStatsRects[11].iRight = 1; gExplosiveDescStatsRects[11].iBottom = 1;
- gExplosiveDescStatsRects[12].iLeft = 0; gExplosiveDescStatsRects[12].iTop = 0; gExplosiveDescStatsRects[12].iRight = 1; gExplosiveDescStatsRects[12].iBottom = 1;
- gExplosiveDescStatsRects[13].iLeft = 0; gExplosiveDescStatsRects[13].iTop = 0; gExplosiveDescStatsRects[13].iRight = 1; gExplosiveDescStatsRects[13].iBottom = 1;
- gExplosiveDescStatsRects[14].iLeft = 0; gExplosiveDescStatsRects[14].iTop = 0; gExplosiveDescStatsRects[14].iRight = 1; gExplosiveDescStatsRects[14].iBottom = 1;
- gExplosiveDescStatsRects[15].iLeft = 0; gExplosiveDescStatsRects[15].iTop = 0; gExplosiveDescStatsRects[15].iRight = 1; gExplosiveDescStatsRects[15].iBottom = 1;
- gExplosiveDescStatsRects[16].iLeft = 0; gExplosiveDescStatsRects[16].iTop = 0; gExplosiveDescStatsRects[16].iRight = 1; gExplosiveDescStatsRects[16].iBottom = 1;
- gExplosiveDescStatsRects[17].iLeft = 0; gExplosiveDescStatsRects[17].iTop = 0; gExplosiveDescStatsRects[17].iRight = 1; gExplosiveDescStatsRects[17].iBottom = 1;
- gExplosiveDescStatsRects[18].iLeft = 0; gExplosiveDescStatsRects[18].iTop = 0; gExplosiveDescStatsRects[18].iRight = 1; gExplosiveDescStatsRects[18].iBottom = 1;
- gExplosiveDescStatsRects[19].iLeft = 0; gExplosiveDescStatsRects[19].iTop = 0; gExplosiveDescStatsRects[19].iRight = 1; gExplosiveDescStatsRects[19].iBottom = 1;
+ ///////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB Description Page
- gMiscItemDescStatsRects[0].iLeft = 46; gMiscItemDescStatsRects[0].iTop = 229; gMiscItemDescStatsRects[0].iRight = 103; gMiscItemDescStatsRects[0].iBottom = 240; // First Column
- gMiscItemDescStatsRects[1].iLeft = 46; gMiscItemDescStatsRects[1].iTop = 241; gMiscItemDescStatsRects[1].iRight = 103; gMiscItemDescStatsRects[1].iBottom = 252;
- gMiscItemDescStatsRects[2].iLeft = 46; gMiscItemDescStatsRects[2].iTop = 253; gMiscItemDescStatsRects[2].iRight = 103; gMiscItemDescStatsRects[2].iBottom = 264;
- gMiscItemDescStatsRects[3].iLeft = 46; gMiscItemDescStatsRects[3].iTop = 265; gMiscItemDescStatsRects[3].iRight = 103; gMiscItemDescStatsRects[3].iBottom = 276;
- gMiscItemDescStatsRects[4].iLeft = 46; gMiscItemDescStatsRects[4].iTop = 277; gMiscItemDescStatsRects[4].iRight = 103; gMiscItemDescStatsRects[4].iBottom = 288;
- gMiscItemDescStatsRects[5].iLeft = 46; gMiscItemDescStatsRects[5].iTop = 289; gMiscItemDescStatsRects[5].iRight = 103; gMiscItemDescStatsRects[5].iBottom = 300;
- gMiscItemDescStatsRects[6].iLeft = 46; gMiscItemDescStatsRects[6].iTop = 301; gMiscItemDescStatsRects[6].iRight = 103; gMiscItemDescStatsRects[6].iBottom = 312;
- gMiscItemDescStatsRects[7].iLeft = 144; gMiscItemDescStatsRects[7].iTop = 229; gMiscItemDescStatsRects[7].iRight = 230; gMiscItemDescStatsRects[7].iBottom = 240; // First Column
- gMiscItemDescStatsRects[8].iLeft = 144; gMiscItemDescStatsRects[8].iTop = 241; gMiscItemDescStatsRects[8].iRight = 230; gMiscItemDescStatsRects[8].iBottom = 252;
- gMiscItemDescStatsRects[9].iLeft = 144; gMiscItemDescStatsRects[9].iTop = 253; gMiscItemDescStatsRects[9].iRight = 230; gMiscItemDescStatsRects[9].iBottom = 264;
- gMiscItemDescStatsRects[10].iLeft = 144; gMiscItemDescStatsRects[10].iTop = 265; gMiscItemDescStatsRects[10].iRight = 230; gMiscItemDescStatsRects[10].iBottom = 276;
- gMiscItemDescStatsRects[11].iLeft = 144; gMiscItemDescStatsRects[11].iTop = 277; gMiscItemDescStatsRects[11].iRight = 230; gMiscItemDescStatsRects[11].iBottom = 288;
- gMiscItemDescStatsRects[12].iLeft = 144; gMiscItemDescStatsRects[12].iTop = 289; gMiscItemDescStatsRects[12].iRight = 230; gMiscItemDescStatsRects[12].iBottom = 300;
- gMiscItemDescStatsRects[13].iLeft = 144; gMiscItemDescStatsRects[13].iTop = 301; gMiscItemDescStatsRects[13].iRight = 230; gMiscItemDescStatsRects[13].iBottom = 312;
- gMiscItemDescStatsRects[14].iLeft = 0; gMiscItemDescStatsRects[14].iTop = 0; gMiscItemDescStatsRects[14].iRight = 1; gMiscItemDescStatsRects[14].iBottom = 1; // Placeholders
- gMiscItemDescStatsRects[15].iLeft = 0; gMiscItemDescStatsRects[15].iTop = 0; gMiscItemDescStatsRects[15].iRight = 1; gMiscItemDescStatsRects[15].iBottom = 1;
- gMiscItemDescStatsRects[16].iLeft = 0; gMiscItemDescStatsRects[16].iTop = 0; gMiscItemDescStatsRects[16].iRight = 1; gMiscItemDescStatsRects[16].iBottom = 1;
- gMiscItemDescStatsRects[17].iLeft = 0; gMiscItemDescStatsRects[17].iTop = 0; gMiscItemDescStatsRects[17].iRight = 1; gMiscItemDescStatsRects[17].iBottom = 1;
- gMiscItemDescStatsRects[18].iLeft = 0; gMiscItemDescStatsRects[18].iTop = 0; gMiscItemDescStatsRects[18].iRight = 1; gMiscItemDescStatsRects[18].iBottom = 1;
- gMiscItemDescStatsRects[19].iLeft = 0; gMiscItemDescStatsRects[19].iTop = 0; gMiscItemDescStatsRects[19].iRight = 1; gMiscItemDescStatsRects[19].iBottom = 1;
+ // Full item description
+ gItemDescTextRegions[0].sLeft = 20 + UDBOffsetX; gItemDescTextRegions[0].sTop = 128 + UDBOffsetY; gItemDescTextRegions[0].sRight = 230 + UDBOffsetX; gItemDescTextRegions[0].sBottom = 200 + UDBOffsetY;
+
+ // Condition
+ gItemDescTextRegions[1].sLeft = 20 + UDBOffsetX; gItemDescTextRegions[1].sTop = 230 + UDBOffsetY; gItemDescTextRegions[1].sRight = 230 + UDBOffsetX; gItemDescTextRegions[1].sBottom = 238 + UDBOffsetY;
+
+ // Weight
+ gItemDescTextRegions[2].sLeft = 20 + UDBOffsetX; gItemDescTextRegions[2].sTop = 242 + UDBOffsetY; gItemDescTextRegions[2].sRight = 230 + UDBOffsetX; gItemDescTextRegions[2].sBottom = 250 + UDBOffsetY;
+
+ // PROS label
+ gItemDescTextRegions[3].sLeft = 20 + UDBOffsetX; gItemDescTextRegions[3].sTop = 280 + UDBOffsetY; gItemDescTextRegions[3].sRight = 230 + UDBOffsetX; gItemDescTextRegions[3].sBottom = 288 + UDBOffsetY;
+
+ // PROS text
+ gItemDescTextRegions[4].sLeft = 50 + UDBOffsetX; gItemDescTextRegions[4].sTop = 280 + UDBOffsetY; gItemDescTextRegions[4].sRight = 230 + UDBOffsetX; gItemDescTextRegions[4].sBottom = 288 + UDBOffsetY;
+
+ // CONS label
+ gItemDescTextRegions[5].sLeft = 20 + UDBOffsetX; gItemDescTextRegions[5].sTop = 292 + UDBOffsetY; gItemDescTextRegions[5].sRight = 230 + UDBOffsetX; gItemDescTextRegions[5].sBottom = 300 + UDBOffsetY;
+
+ // CONS text
+ gItemDescTextRegions[6].sLeft = 50 + UDBOffsetX; gItemDescTextRegions[6].sTop = 292 + UDBOffsetY; gItemDescTextRegions[6].sRight = 230 + UDBOffsetX; gItemDescTextRegions[6].sBottom = 300 + UDBOffsetY;
+
+ ////////////////// MONEY TEXT COORDINATES
+ gMoneyStats[0].sX = 20 + UDBOffsetX; gMoneyStats[0].sY = 230 + UDBOffsetY; // Money
+ gMoneyStats[1].sX = 63 + UDBOffsetX; gMoneyStats[1].sY = 230 + UDBOffsetY; // Remaining
+ gMoneyStats[2].sX = 20 + UDBOffsetX; gMoneyStats[2].sY = 245 + UDBOffsetY; // Money
+ gMoneyStats[3].sX = 63 + UDBOffsetX; gMoneyStats[3].sY = 245 + UDBOffsetY; // Removing
+ gMoneyStats[4].sX = 145 + UDBOffsetX; gMoneyStats[4].sY = 230 + UDBOffsetY; // AMT remaining
+ gMoneyStats[5].sX = 145 + UDBOffsetX; gMoneyStats[5].sY = 245 + UDBOffsetY; // AMT removing
+
+ ///////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB General Page - Header locations
+
+ // "Primary" header
+ gItemDescGenHeaderRegions[0].sLeft = 12 + UDBOffsetX; gItemDescGenHeaderRegions[0].sTop = 119 + UDBOffsetY; gItemDescGenHeaderRegions[0].sRight = 126 + UDBOffsetX; gItemDescGenHeaderRegions[0].sBottom = 131 + UDBOffsetY;
+
+ // "Secondary" header (for weapons: "AP costs")
+ gItemDescGenHeaderRegions[1].sLeft = 128 + UDBOffsetX; gItemDescGenHeaderRegions[1].sTop = 119 + UDBOffsetY; gItemDescGenHeaderRegions[1].sRight = 242 + UDBOffsetX; gItemDescGenHeaderRegions[1].sBottom = 131 + UDBOffsetY;
+
+ // "Burst / Auto" header (for weapons only)
+ gItemDescGenHeaderRegions[2].sLeft = 128 + UDBOffsetX; gItemDescGenHeaderRegions[2].sTop = 230 + UDBOffsetY; gItemDescGenHeaderRegions[2].sRight = 242 + UDBOffsetX; gItemDescGenHeaderRegions[2].sBottom = 242 + UDBOffsetY;
+
+ ///////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB General Page - Index Locations
+
+ // "Primary" index
+ gItemDescGenIndexRegions[0][0].sLeft = 12 + UDBOffsetX; gItemDescGenIndexRegions[0][0].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[0][0].sRight = 61 + UDBOffsetX; gItemDescGenIndexRegions[0][0].sBottom = 146 + UDBOffsetY;
+ gItemDescGenIndexRegions[0][1].sLeft = 63 + UDBOffsetX; gItemDescGenIndexRegions[0][1].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[0][1].sRight = 84 + UDBOffsetX; gItemDescGenIndexRegions[0][1].sBottom = 146 + UDBOffsetY;
+ gItemDescGenIndexRegions[0][2].sLeft = 86 + UDBOffsetX; gItemDescGenIndexRegions[0][2].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[0][2].sRight = 105 + UDBOffsetX; gItemDescGenIndexRegions[0][2].sBottom = 146 + UDBOffsetY;
+ gItemDescGenIndexRegions[0][3].sLeft = 107 + UDBOffsetX; gItemDescGenIndexRegions[0][3].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[0][3].sRight = 127 + UDBOffsetX; gItemDescGenIndexRegions[0][3].sBottom = 146 + UDBOffsetY;
+
+ // "Secondary" index
+ gItemDescGenIndexRegions[1][0].sLeft = 130 + UDBOffsetX; gItemDescGenIndexRegions[1][0].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[1][0].sRight = 179 + UDBOffsetX; gItemDescGenIndexRegions[1][0].sBottom = 146 + UDBOffsetY;
+ gItemDescGenIndexRegions[1][1].sLeft = 181 + UDBOffsetX; gItemDescGenIndexRegions[1][1].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[1][1].sRight = 202 + UDBOffsetX; gItemDescGenIndexRegions[1][1].sBottom = 146 + UDBOffsetY;
+ gItemDescGenIndexRegions[1][2].sLeft = 204 + UDBOffsetX; gItemDescGenIndexRegions[1][2].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[1][2].sRight = 223 + UDBOffsetX; gItemDescGenIndexRegions[1][2].sBottom = 146 + UDBOffsetY;
+ gItemDescGenIndexRegions[1][3].sLeft = 225 + UDBOffsetX; gItemDescGenIndexRegions[1][3].sTop = 134 + UDBOffsetY; gItemDescGenIndexRegions[1][3].sRight = 245 + UDBOffsetX; gItemDescGenIndexRegions[1][3].sBottom = 146 + UDBOffsetY;
+
+ // "Tertiary" index (for weapons only)
+ gItemDescGenIndexRegions[2][0].sLeft = 130 + UDBOffsetX; gItemDescGenIndexRegions[2][0].sTop = 245 + UDBOffsetY; gItemDescGenIndexRegions[2][0].sRight = 179 + UDBOffsetX; gItemDescGenIndexRegions[2][0].sBottom = 257 + UDBOffsetY;
+ gItemDescGenIndexRegions[2][1].sLeft = 181 + UDBOffsetX; gItemDescGenIndexRegions[2][1].sTop = 245 + UDBOffsetY; gItemDescGenIndexRegions[2][1].sRight = 202 + UDBOffsetX; gItemDescGenIndexRegions[2][1].sBottom = 257 + UDBOffsetY;
+ gItemDescGenIndexRegions[2][2].sLeft = 204 + UDBOffsetX; gItemDescGenIndexRegions[2][2].sTop = 245 + UDBOffsetY; gItemDescGenIndexRegions[2][2].sRight = 223 + UDBOffsetX; gItemDescGenIndexRegions[2][2].sBottom = 257 + UDBOffsetY;
+ gItemDescGenIndexRegions[2][3].sLeft = 225 + UDBOffsetX; gItemDescGenIndexRegions[2][3].sTop = 245 + UDBOffsetY; gItemDescGenIndexRegions[2][3].sRight = 245 + UDBOffsetX; gItemDescGenIndexRegions[2][3].sBottom = 257 + UDBOffsetY;
+
+ //////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB General Page - Data locations
+ // There are NUM_UDB_GEN_LINES*2 lines on the UDB page. Half are on the left side, half
+ // on the right. Each line has 4 individual parts, see the indexes above.
+ // The right column is currently only used for WEAPONS. Other item types have their
+ // own coordinate arrays as they are used to display non-tabulated information.
+
+ // Left Column, row 1
+ gItemDescGenRegions[0][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[0][0].sTop = 150 + UDBOffsetY; gItemDescGenRegions[0][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[0][0].sBottom = 162 + UDBOffsetY;
+ gItemDescGenRegions[0][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[0][1].sTop = 150 + UDBOffsetY; gItemDescGenRegions[0][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[0][1].sBottom = 162 + UDBOffsetY;
+ gItemDescGenRegions[0][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[0][2].sTop = 150 + UDBOffsetY; gItemDescGenRegions[0][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[0][2].sBottom = 162 + UDBOffsetY;
+ gItemDescGenRegions[0][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[0][3].sTop = 150 + UDBOffsetY; gItemDescGenRegions[0][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[0][3].sBottom = 162 + UDBOffsetY;
+
+ // Left Column, row 2
+ gItemDescGenRegions[1][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[1][0].sTop = 163 + UDBOffsetY; gItemDescGenRegions[1][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[1][0].sBottom = 175 + UDBOffsetY;
+ gItemDescGenRegions[1][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[1][1].sTop = 163 + UDBOffsetY; gItemDescGenRegions[1][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[1][1].sBottom = 175 + UDBOffsetY;
+ gItemDescGenRegions[1][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[1][2].sTop = 163 + UDBOffsetY; gItemDescGenRegions[1][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[1][2].sBottom = 175 + UDBOffsetY;
+ gItemDescGenRegions[1][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[1][3].sTop = 163 + UDBOffsetY; gItemDescGenRegions[1][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[1][3].sBottom = 175 + UDBOffsetY;
+
+ // Left Column, row 3
+ gItemDescGenRegions[2][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[2][0].sTop = 176 + UDBOffsetY; gItemDescGenRegions[2][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[2][0].sBottom = 188 + UDBOffsetY;
+ gItemDescGenRegions[2][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[2][1].sTop = 176 + UDBOffsetY; gItemDescGenRegions[2][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[2][1].sBottom = 188 + UDBOffsetY;
+ gItemDescGenRegions[2][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[2][2].sTop = 176 + UDBOffsetY; gItemDescGenRegions[2][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[2][2].sBottom = 188 + UDBOffsetY;
+ gItemDescGenRegions[2][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[2][3].sTop = 176 + UDBOffsetY; gItemDescGenRegions[2][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[2][3].sBottom = 188 + UDBOffsetY;
+
+ // Left Column, row 4
+ gItemDescGenRegions[3][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[3][0].sTop = 189 + UDBOffsetY; gItemDescGenRegions[3][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[3][0].sBottom = 201 + UDBOffsetY;
+ gItemDescGenRegions[3][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[3][1].sTop = 189 + UDBOffsetY; gItemDescGenRegions[3][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[3][1].sBottom = 201 + UDBOffsetY;
+ gItemDescGenRegions[3][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[3][2].sTop = 189 + UDBOffsetY; gItemDescGenRegions[3][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[3][2].sBottom = 201 + UDBOffsetY;
+ gItemDescGenRegions[3][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[3][3].sTop = 189 + UDBOffsetY; gItemDescGenRegions[3][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[3][3].sBottom = 201 + UDBOffsetY;
+
+ // Left Column, row 5
+ gItemDescGenRegions[4][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[4][0].sTop = 202 + UDBOffsetY; gItemDescGenRegions[4][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[4][0].sBottom = 214 + UDBOffsetY;
+ gItemDescGenRegions[4][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[4][1].sTop = 202 + UDBOffsetY; gItemDescGenRegions[4][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[4][1].sBottom = 214 + UDBOffsetY;
+ gItemDescGenRegions[4][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[4][2].sTop = 202 + UDBOffsetY; gItemDescGenRegions[4][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[4][2].sBottom = 214 + UDBOffsetY;
+ gItemDescGenRegions[4][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[4][3].sTop = 202 + UDBOffsetY; gItemDescGenRegions[4][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[4][3].sBottom = 214 + UDBOffsetY;
+
+ // Left Column, row 6
+ gItemDescGenRegions[5][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[5][0].sTop = 215 + UDBOffsetY; gItemDescGenRegions[5][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[5][0].sBottom = 227 + UDBOffsetY;
+ gItemDescGenRegions[5][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[5][1].sTop = 215 + UDBOffsetY; gItemDescGenRegions[5][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[5][1].sBottom = 227 + UDBOffsetY;
+ gItemDescGenRegions[5][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[5][2].sTop = 215 + UDBOffsetY; gItemDescGenRegions[5][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[5][2].sBottom = 227 + UDBOffsetY;
+ gItemDescGenRegions[5][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[5][3].sTop = 215 + UDBOffsetY; gItemDescGenRegions[5][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[5][3].sBottom = 227 + UDBOffsetY;
+
+ // Left Column, row 7
+ gItemDescGenRegions[6][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[6][0].sTop = 228 + UDBOffsetY; gItemDescGenRegions[6][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[6][0].sBottom = 242 + UDBOffsetY;
+ gItemDescGenRegions[6][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[6][1].sTop = 228 + UDBOffsetY; gItemDescGenRegions[6][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[6][1].sBottom = 242 + UDBOffsetY;
+ gItemDescGenRegions[6][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[6][2].sTop = 228 + UDBOffsetY; gItemDescGenRegions[6][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[6][2].sBottom = 242 + UDBOffsetY;
+ gItemDescGenRegions[6][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[6][3].sTop = 228 + UDBOffsetY; gItemDescGenRegions[6][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[6][3].sBottom = 242 + UDBOffsetY;
+
+ // Left Column, row 8
+ gItemDescGenRegions[7][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[7][0].sTop = 243 + UDBOffsetY; gItemDescGenRegions[7][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[7][0].sBottom = 255 + UDBOffsetY;
+ gItemDescGenRegions[7][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[7][1].sTop = 243 + UDBOffsetY; gItemDescGenRegions[7][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[7][1].sBottom = 255 + UDBOffsetY;
+ gItemDescGenRegions[7][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[7][2].sTop = 243 + UDBOffsetY; gItemDescGenRegions[7][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[7][2].sBottom = 255 + UDBOffsetY;
+ gItemDescGenRegions[7][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[7][3].sTop = 243 + UDBOffsetY; gItemDescGenRegions[7][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[7][3].sBottom = 255 + UDBOffsetY;
+
+ // Left Column, row 9
+ gItemDescGenRegions[8][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[8][0].sTop = 256 + UDBOffsetY; gItemDescGenRegions[8][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[8][0].sBottom = 268 + UDBOffsetY;
+ gItemDescGenRegions[8][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[8][1].sTop = 256 + UDBOffsetY; gItemDescGenRegions[8][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[8][1].sBottom = 268 + UDBOffsetY;
+ gItemDescGenRegions[8][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[8][2].sTop = 256 + UDBOffsetY; gItemDescGenRegions[8][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[8][2].sBottom = 268 + UDBOffsetY;
+ gItemDescGenRegions[8][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[8][3].sTop = 256 + UDBOffsetY; gItemDescGenRegions[8][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[8][3].sBottom = 268 + UDBOffsetY;
+
+ // Left Column, row 10
+ gItemDescGenRegions[9][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[9][0].sTop = 269 + UDBOffsetY; gItemDescGenRegions[9][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[9][0].sBottom = 281 + UDBOffsetY;
+ gItemDescGenRegions[9][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[9][1].sTop = 269 + UDBOffsetY; gItemDescGenRegions[9][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[9][1].sBottom = 281 + UDBOffsetY;
+ gItemDescGenRegions[9][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[9][2].sTop = 269 + UDBOffsetY; gItemDescGenRegions[9][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[9][2].sBottom = 281 + UDBOffsetY;
+ gItemDescGenRegions[9][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[9][3].sTop = 269 + UDBOffsetY; gItemDescGenRegions[9][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[9][3].sBottom = 281 + UDBOffsetY;
+
+ // Left Column, row 11
+ gItemDescGenRegions[10][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[10][0].sTop = 282 + UDBOffsetY; gItemDescGenRegions[10][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[10][0].sBottom = 294 + UDBOffsetY;
+ gItemDescGenRegions[10][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[10][1].sTop = 282 + UDBOffsetY; gItemDescGenRegions[10][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[10][1].sBottom = 294 + UDBOffsetY;
+ gItemDescGenRegions[10][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[10][2].sTop = 282 + UDBOffsetY; gItemDescGenRegions[10][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[10][2].sBottom = 294 + UDBOffsetY;
+ gItemDescGenRegions[10][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[10][3].sTop = 282 + UDBOffsetY; gItemDescGenRegions[10][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[10][3].sBottom = 294 + UDBOffsetY;
+
+ // Left Column, row 12
+ gItemDescGenRegions[11][0].sLeft = 12 + UDBOffsetX; gItemDescGenRegions[11][0].sTop = 295 + UDBOffsetY; gItemDescGenRegions[11][0].sRight = 61 + UDBOffsetX; gItemDescGenRegions[11][0].sBottom = 307 + UDBOffsetY;
+ gItemDescGenRegions[11][1].sLeft = 63 + UDBOffsetX; gItemDescGenRegions[11][1].sTop = 295 + UDBOffsetY; gItemDescGenRegions[11][1].sRight = 84 + UDBOffsetX; gItemDescGenRegions[11][1].sBottom = 307 + UDBOffsetY;
+ gItemDescGenRegions[11][2].sLeft = 86 + UDBOffsetX; gItemDescGenRegions[11][2].sTop = 295 + UDBOffsetY; gItemDescGenRegions[11][2].sRight = 105 + UDBOffsetX; gItemDescGenRegions[11][2].sBottom = 307 + UDBOffsetY;
+ gItemDescGenRegions[11][3].sLeft = 107 + UDBOffsetX; gItemDescGenRegions[11][3].sTop = 295 + UDBOffsetY; gItemDescGenRegions[11][3].sRight = 127 + UDBOffsetX; gItemDescGenRegions[11][3].sBottom = 307 + UDBOffsetY;
+
+ // Right Column, row 1
+ gItemDescGenRegions[13][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[13][0].sTop = 150 + UDBOffsetY; gItemDescGenRegions[13][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[13][0].sBottom = 162 + UDBOffsetY;
+ gItemDescGenRegions[13][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[13][1].sTop = 150 + UDBOffsetY; gItemDescGenRegions[13][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[13][1].sBottom = 162 + UDBOffsetY;
+ gItemDescGenRegions[13][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[13][2].sTop = 150 + UDBOffsetY; gItemDescGenRegions[13][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[13][2].sBottom = 162 + UDBOffsetY;
+ gItemDescGenRegions[13][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[13][3].sTop = 150 + UDBOffsetY; gItemDescGenRegions[13][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[13][3].sBottom = 162 + UDBOffsetY;
+
+ // Right Column, row 2
+ gItemDescGenRegions[14][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[14][0].sTop = 163 + UDBOffsetY; gItemDescGenRegions[14][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[14][0].sBottom = 175 + UDBOffsetY;
+ gItemDescGenRegions[14][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[14][1].sTop = 163 + UDBOffsetY; gItemDescGenRegions[14][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[14][1].sBottom = 175 + UDBOffsetY;
+ gItemDescGenRegions[14][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[14][2].sTop = 163 + UDBOffsetY; gItemDescGenRegions[14][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[14][2].sBottom = 175 + UDBOffsetY;
+ gItemDescGenRegions[14][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[14][3].sTop = 163 + UDBOffsetY; gItemDescGenRegions[14][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[14][3].sBottom = 175 + UDBOffsetY;
+
+ // Right Column, row 3
+ gItemDescGenRegions[15][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[15][0].sTop = 176 + UDBOffsetY; gItemDescGenRegions[15][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[15][0].sBottom = 188 + UDBOffsetY;
+ gItemDescGenRegions[15][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[15][1].sTop = 176 + UDBOffsetY; gItemDescGenRegions[15][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[15][1].sBottom = 188 + UDBOffsetY;
+ gItemDescGenRegions[15][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[15][2].sTop = 176 + UDBOffsetY; gItemDescGenRegions[15][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[15][2].sBottom = 188 + UDBOffsetY;
+ gItemDescGenRegions[15][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[15][3].sTop = 176 + UDBOffsetY; gItemDescGenRegions[15][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[15][3].sBottom = 188 + UDBOffsetY;
+
+ // Right Column, row 4
+ gItemDescGenRegions[16][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[16][0].sTop = 189 + UDBOffsetY; gItemDescGenRegions[16][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[16][0].sBottom = 201 + UDBOffsetY;
+ gItemDescGenRegions[16][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[16][1].sTop = 189 + UDBOffsetY; gItemDescGenRegions[16][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[16][1].sBottom = 201 + UDBOffsetY;
+ gItemDescGenRegions[16][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[16][2].sTop = 189 + UDBOffsetY; gItemDescGenRegions[16][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[16][2].sBottom = 201 + UDBOffsetY;
+ gItemDescGenRegions[16][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[16][3].sTop = 189 + UDBOffsetY; gItemDescGenRegions[16][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[16][3].sBottom = 201 + UDBOffsetY;
+
+ // Right Column, row 5
+ gItemDescGenRegions[17][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[17][0].sTop = 202 + UDBOffsetY; gItemDescGenRegions[17][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[17][0].sBottom = 214 + UDBOffsetY;
+ gItemDescGenRegions[17][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[17][1].sTop = 202 + UDBOffsetY; gItemDescGenRegions[17][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[17][1].sBottom = 214 + UDBOffsetY;
+ gItemDescGenRegions[17][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[17][2].sTop = 202 + UDBOffsetY; gItemDescGenRegions[17][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[17][2].sBottom = 214 + UDBOffsetY;
+ gItemDescGenRegions[17][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[17][3].sTop = 202 + UDBOffsetY; gItemDescGenRegions[17][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[17][3].sBottom = 214 + UDBOffsetY;
+
+ // Right Column, row 6
+ gItemDescGenRegions[18][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[18][0].sTop = 215 + UDBOffsetY; gItemDescGenRegions[18][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[18][0].sBottom = 227 + UDBOffsetY;
+ gItemDescGenRegions[18][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[18][1].sTop = 215 + UDBOffsetY; gItemDescGenRegions[18][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[18][1].sBottom = 227 + UDBOffsetY;
+ gItemDescGenRegions[18][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[18][2].sTop = 215 + UDBOffsetY; gItemDescGenRegions[18][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[18][2].sBottom = 227 + UDBOffsetY;
+ gItemDescGenRegions[18][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[18][3].sTop = 215 + UDBOffsetY; gItemDescGenRegions[18][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[18][3].sBottom = 227 + UDBOffsetY;
+
+ // NOTE a skip of Y here - these belong to the "tertiary" column, which is below the "secondary" column, separated by an index and header.
+ // Right Column, row 7
+ gItemDescGenRegions[19][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[19][0].sTop = 261 + UDBOffsetY; gItemDescGenRegions[19][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[19][0].sBottom = 273 + UDBOffsetY;
+ gItemDescGenRegions[19][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[19][1].sTop = 261 + UDBOffsetY; gItemDescGenRegions[19][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[19][1].sBottom = 273 + UDBOffsetY;
+ gItemDescGenRegions[19][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[19][2].sTop = 261 + UDBOffsetY; gItemDescGenRegions[19][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[19][2].sBottom = 273 + UDBOffsetY;
+ gItemDescGenRegions[19][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[19][3].sTop = 261 + UDBOffsetY; gItemDescGenRegions[19][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[19][3].sBottom = 273 + UDBOffsetY;
+
+ // Right Column, row 8
+ gItemDescGenRegions[20][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[20][0].sTop = 274 + UDBOffsetY; gItemDescGenRegions[20][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[20][0].sBottom = 286 + UDBOffsetY;
+ gItemDescGenRegions[20][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[20][1].sTop = 274 + UDBOffsetY; gItemDescGenRegions[20][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[20][1].sBottom = 286 + UDBOffsetY;
+ gItemDescGenRegions[20][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[20][2].sTop = 274 + UDBOffsetY; gItemDescGenRegions[20][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[20][2].sBottom = 286 + UDBOffsetY;
+ gItemDescGenRegions[20][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[20][3].sTop = 274 + UDBOffsetY; gItemDescGenRegions[20][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[20][3].sBottom = 286 + UDBOffsetY;
+
+ // Right Column, row 9
+ gItemDescGenRegions[21][0].sLeft = 130 + UDBOffsetX; gItemDescGenRegions[21][0].sTop = 287 + UDBOffsetY; gItemDescGenRegions[21][0].sRight = 179 + UDBOffsetX; gItemDescGenRegions[21][0].sBottom = 299 + UDBOffsetY;
+ gItemDescGenRegions[21][1].sLeft = 181 + UDBOffsetX; gItemDescGenRegions[21][1].sTop = 287 + UDBOffsetY; gItemDescGenRegions[21][1].sRight = 202 + UDBOffsetX; gItemDescGenRegions[21][1].sBottom = 299 + UDBOffsetY;
+ gItemDescGenRegions[21][2].sLeft = 204 + UDBOffsetX; gItemDescGenRegions[21][2].sTop = 287 + UDBOffsetY; gItemDescGenRegions[21][2].sRight = 223 + UDBOffsetX; gItemDescGenRegions[21][2].sBottom = 299 + UDBOffsetY;
+ gItemDescGenRegions[21][3].sLeft = 225 + UDBOffsetX; gItemDescGenRegions[21][3].sTop = 287 + UDBOffsetY; gItemDescGenRegions[21][3].sRight = 245 + UDBOffsetX; gItemDescGenRegions[21][3].sBottom = 299 + UDBOffsetY;
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB General Page - Secondary Data locations
+ // These icons will appear on the RIGHT columns of the general page. The are larger
+ // than the normal icons, and indicate flags. Armor, Ammo and Misc Items will use
+ // these to display special flag properties like "Electronic" or "Tracer effect".
+
+ // First row
+ gItemDescGenSecondaryRegions[0].sLeft = 131 + UDBOffsetX; gItemDescGenSecondaryRegions[0].sTop = 135 + UDBOffsetY; gItemDescGenSecondaryRegions[0].sRight = 156 + UDBOffsetX; gItemDescGenSecondaryRegions[0].sBottom = 160 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[1].sLeft = 159 + UDBOffsetX; gItemDescGenSecondaryRegions[1].sTop = 135 + UDBOffsetY; gItemDescGenSecondaryRegions[1].sRight = 184 + UDBOffsetX; gItemDescGenSecondaryRegions[1].sBottom = 160 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[2].sLeft = 187 + UDBOffsetX; gItemDescGenSecondaryRegions[2].sTop = 135 + UDBOffsetY; gItemDescGenSecondaryRegions[2].sRight = 212 + UDBOffsetX; gItemDescGenSecondaryRegions[2].sBottom = 160 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[3].sLeft = 215 + UDBOffsetX; gItemDescGenSecondaryRegions[3].sTop = 135 + UDBOffsetY; gItemDescGenSecondaryRegions[3].sRight = 240 + UDBOffsetX; gItemDescGenSecondaryRegions[3].sBottom = 160 + UDBOffsetY;
+
+ // Second row
+ gItemDescGenSecondaryRegions[4].sLeft = 131 + UDBOffsetX; gItemDescGenSecondaryRegions[4].sTop = 163 + UDBOffsetY; gItemDescGenSecondaryRegions[4].sRight = 156 + UDBOffsetX; gItemDescGenSecondaryRegions[4].sBottom = 188 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[5].sLeft = 159 + UDBOffsetX; gItemDescGenSecondaryRegions[5].sTop = 163 + UDBOffsetY; gItemDescGenSecondaryRegions[5].sRight = 184 + UDBOffsetX; gItemDescGenSecondaryRegions[5].sBottom = 188 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[6].sLeft = 187 + UDBOffsetX; gItemDescGenSecondaryRegions[6].sTop = 163 + UDBOffsetY; gItemDescGenSecondaryRegions[6].sRight = 212 + UDBOffsetX; gItemDescGenSecondaryRegions[6].sBottom = 188 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[7].sLeft = 215 + UDBOffsetX; gItemDescGenSecondaryRegions[7].sTop = 163 + UDBOffsetY; gItemDescGenSecondaryRegions[7].sRight = 240 + UDBOffsetX; gItemDescGenSecondaryRegions[7].sBottom = 188 + UDBOffsetY;
+
+ // Third row
+
+ gItemDescGenSecondaryRegions[8].sLeft = 131 + UDBOffsetX; gItemDescGenSecondaryRegions[8].sTop = 191 + UDBOffsetY; gItemDescGenSecondaryRegions[8].sRight = 156 + UDBOffsetX; gItemDescGenSecondaryRegions[8].sBottom = 216 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[9].sLeft = 159 + UDBOffsetX; gItemDescGenSecondaryRegions[9].sTop = 191 + UDBOffsetY; gItemDescGenSecondaryRegions[9].sRight = 184 + UDBOffsetX; gItemDescGenSecondaryRegions[9].sBottom = 216 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[10].sLeft = 187 + UDBOffsetX; gItemDescGenSecondaryRegions[10].sTop = 191 + UDBOffsetY; gItemDescGenSecondaryRegions[10].sRight = 212 + UDBOffsetX; gItemDescGenSecondaryRegions[10].sBottom = 216 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[11].sLeft = 215 + UDBOffsetX; gItemDescGenSecondaryRegions[11].sTop = 191 + UDBOffsetY; gItemDescGenSecondaryRegions[11].sRight = 240 + UDBOffsetX; gItemDescGenSecondaryRegions[11].sBottom = 216 + UDBOffsetY;
+
+ // Fourth row
+ gItemDescGenSecondaryRegions[12].sLeft = 131 + UDBOffsetX; gItemDescGenSecondaryRegions[12].sTop = 219 + UDBOffsetY; gItemDescGenSecondaryRegions[12].sRight = 156 + UDBOffsetX; gItemDescGenSecondaryRegions[12].sBottom = 244 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[13].sLeft = 159 + UDBOffsetX; gItemDescGenSecondaryRegions[13].sTop = 219 + UDBOffsetY; gItemDescGenSecondaryRegions[13].sRight = 184 + UDBOffsetX; gItemDescGenSecondaryRegions[13].sBottom = 244 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[14].sLeft = 187 + UDBOffsetX; gItemDescGenSecondaryRegions[14].sTop = 219 + UDBOffsetY; gItemDescGenSecondaryRegions[14].sRight = 212 + UDBOffsetX; gItemDescGenSecondaryRegions[14].sBottom = 244 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[15].sLeft = 215 + UDBOffsetX; gItemDescGenSecondaryRegions[15].sTop = 219 + UDBOffsetY; gItemDescGenSecondaryRegions[15].sRight = 240 + UDBOffsetX; gItemDescGenSecondaryRegions[15].sBottom = 244 + UDBOffsetY;
+
+ // Fifth row
+ gItemDescGenSecondaryRegions[16].sLeft = 131 + UDBOffsetX; gItemDescGenSecondaryRegions[16].sTop = 247 + UDBOffsetY; gItemDescGenSecondaryRegions[16].sRight = 156 + UDBOffsetX; gItemDescGenSecondaryRegions[16].sBottom = 272 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[17].sLeft = 159 + UDBOffsetX; gItemDescGenSecondaryRegions[17].sTop = 247 + UDBOffsetY; gItemDescGenSecondaryRegions[17].sRight = 184 + UDBOffsetX; gItemDescGenSecondaryRegions[17].sBottom = 272 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[18].sLeft = 187 + UDBOffsetX; gItemDescGenSecondaryRegions[18].sTop = 247 + UDBOffsetY; gItemDescGenSecondaryRegions[18].sRight = 212 + UDBOffsetX; gItemDescGenSecondaryRegions[18].sBottom = 272 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[19].sLeft = 215 + UDBOffsetX; gItemDescGenSecondaryRegions[19].sTop = 247 + UDBOffsetY; gItemDescGenSecondaryRegions[19].sRight = 240 + UDBOffsetX; gItemDescGenSecondaryRegions[19].sBottom = 272 + UDBOffsetY;
+
+ // Sixth row
+ gItemDescGenSecondaryRegions[20].sLeft = 131 + UDBOffsetX; gItemDescGenSecondaryRegions[20].sTop = 275 + UDBOffsetY; gItemDescGenSecondaryRegions[20].sRight = 156 + UDBOffsetX; gItemDescGenSecondaryRegions[20].sBottom = 300 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[21].sLeft = 159 + UDBOffsetX; gItemDescGenSecondaryRegions[21].sTop = 275 + UDBOffsetY; gItemDescGenSecondaryRegions[21].sRight = 184 + UDBOffsetX; gItemDescGenSecondaryRegions[21].sBottom = 300 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[22].sLeft = 187 + UDBOffsetX; gItemDescGenSecondaryRegions[22].sTop = 275 + UDBOffsetY; gItemDescGenSecondaryRegions[22].sRight = 212 + UDBOffsetX; gItemDescGenSecondaryRegions[22].sBottom = 300 + UDBOffsetY;
+ gItemDescGenSecondaryRegions[23].sLeft = 215 + UDBOffsetX; gItemDescGenSecondaryRegions[23].sTop = 275 + UDBOffsetY; gItemDescGenSecondaryRegions[23].sRight = 240 + UDBOffsetX; gItemDescGenSecondaryRegions[23].sBottom = 300 + UDBOffsetY;
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB Advanced Page
+ // The set of data appears on the third UDB page. It shows bonuses given by items either
+ // to other items (through attachment/ammo) or directly to the person wearing/using
+ // the item.
+ // Each row contains 4 elements, the first being the icon position, and then
+ // one element per stance (Standing, crouching, prone).
+
+ /////////// INDEX
+ gItemDescAdvIndexRegions[0][0].sLeft = 12 + UDBOffsetX; gItemDescAdvIndexRegions[0][0].sTop = 119 + UDBOffsetY; gItemDescAdvIndexRegions[0][0].sRight = 125 + UDBOffsetX; gItemDescAdvIndexRegions[0][0].sBottom = 132 + UDBOffsetY;
+ gItemDescAdvIndexRegions[0][1].sLeft = 128 + UDBOffsetX; gItemDescAdvIndexRegions[0][1].sTop = 119 + UDBOffsetY; gItemDescAdvIndexRegions[0][1].sRight = 157 + UDBOffsetX; gItemDescAdvIndexRegions[0][1].sBottom = 132 + UDBOffsetY;
+ gItemDescAdvIndexRegions[0][2].sLeft = 160 + UDBOffsetX; gItemDescAdvIndexRegions[0][2].sTop = 119 + UDBOffsetY; gItemDescAdvIndexRegions[0][2].sRight = 189 + UDBOffsetX; gItemDescAdvIndexRegions[0][2].sBottom = 132 + UDBOffsetY;
+ gItemDescAdvIndexRegions[0][3].sLeft = 193 + UDBOffsetX; gItemDescAdvIndexRegions[0][3].sTop = 119 + UDBOffsetY; gItemDescAdvIndexRegions[0][3].sRight = 220 + UDBOffsetX; gItemDescAdvIndexRegions[0][3].sBottom = 132 + UDBOffsetY;
+
+ gItemDescAdvRegions[0][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[0][0].sTop = 138 + UDBOffsetY; gItemDescAdvRegions[0][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[0][0].sBottom = 150 + UDBOffsetY;
+ gItemDescAdvRegions[0][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[0][1].sTop = 138 + UDBOffsetY; gItemDescAdvRegions[0][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[0][1].sBottom = 150 + UDBOffsetY;
+ gItemDescAdvRegions[0][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[0][2].sTop = 138 + UDBOffsetY; gItemDescAdvRegions[0][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[0][2].sBottom = 150 + UDBOffsetY;
+ gItemDescAdvRegions[0][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[0][3].sTop = 138 + UDBOffsetY; gItemDescAdvRegions[0][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[0][3].sBottom = 150 + UDBOffsetY;
+
+ gItemDescAdvRegions[1][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[1][0].sTop = 151 + UDBOffsetY; gItemDescAdvRegions[1][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[1][0].sBottom = 163 + UDBOffsetY;
+ gItemDescAdvRegions[1][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[1][1].sTop = 151 + UDBOffsetY; gItemDescAdvRegions[1][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[1][1].sBottom = 163 + UDBOffsetY;
+ gItemDescAdvRegions[1][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[1][2].sTop = 151 + UDBOffsetY; gItemDescAdvRegions[1][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[1][2].sBottom = 163 + UDBOffsetY;
+ gItemDescAdvRegions[1][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[1][3].sTop = 151 + UDBOffsetY; gItemDescAdvRegions[1][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[1][3].sBottom = 163 + UDBOffsetY;
+
+ gItemDescAdvRegions[2][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[2][0].sTop = 164 + UDBOffsetY; gItemDescAdvRegions[2][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[2][0].sBottom = 176 + UDBOffsetY;
+ gItemDescAdvRegions[2][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[2][1].sTop = 164 + UDBOffsetY; gItemDescAdvRegions[2][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[2][1].sBottom = 176 + UDBOffsetY;
+ gItemDescAdvRegions[2][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[2][2].sTop = 164 + UDBOffsetY; gItemDescAdvRegions[2][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[2][2].sBottom = 176 + UDBOffsetY;
+ gItemDescAdvRegions[2][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[2][3].sTop = 164 + UDBOffsetY; gItemDescAdvRegions[2][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[2][3].sBottom = 176 + UDBOffsetY;
+
+ gItemDescAdvRegions[3][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[3][0].sTop = 177 + UDBOffsetY; gItemDescAdvRegions[3][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[3][0].sBottom = 189 + UDBOffsetY;
+ gItemDescAdvRegions[3][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[3][1].sTop = 177 + UDBOffsetY; gItemDescAdvRegions[3][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[3][1].sBottom = 189 + UDBOffsetY;
+ gItemDescAdvRegions[3][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[3][2].sTop = 177 + UDBOffsetY; gItemDescAdvRegions[3][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[3][2].sBottom = 189 + UDBOffsetY;
+ gItemDescAdvRegions[3][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[3][3].sTop = 177 + UDBOffsetY; gItemDescAdvRegions[3][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[3][3].sBottom = 189 + UDBOffsetY;
+
+ gItemDescAdvRegions[4][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[4][0].sTop = 190 + UDBOffsetY; gItemDescAdvRegions[4][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[4][0].sBottom = 202 + UDBOffsetY;
+ gItemDescAdvRegions[4][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[4][1].sTop = 190 + UDBOffsetY; gItemDescAdvRegions[4][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[4][1].sBottom = 202 + UDBOffsetY;
+ gItemDescAdvRegions[4][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[4][2].sTop = 190 + UDBOffsetY; gItemDescAdvRegions[4][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[4][2].sBottom = 202 + UDBOffsetY;
+ gItemDescAdvRegions[4][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[4][3].sTop = 190 + UDBOffsetY; gItemDescAdvRegions[4][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[4][3].sBottom = 202 + UDBOffsetY;
+
+ gItemDescAdvRegions[5][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[5][0].sTop = 203 + UDBOffsetY; gItemDescAdvRegions[5][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[5][0].sBottom = 215 + UDBOffsetY;
+ gItemDescAdvRegions[5][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[5][1].sTop = 203 + UDBOffsetY; gItemDescAdvRegions[5][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[5][1].sBottom = 215 + UDBOffsetY;
+ gItemDescAdvRegions[5][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[5][2].sTop = 203 + UDBOffsetY; gItemDescAdvRegions[5][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[5][2].sBottom = 215 + UDBOffsetY;
+ gItemDescAdvRegions[5][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[5][3].sTop = 203 + UDBOffsetY; gItemDescAdvRegions[5][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[5][3].sBottom = 215 + UDBOffsetY;
+
+ gItemDescAdvRegions[6][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[6][0].sTop = 216 + UDBOffsetY; gItemDescAdvRegions[6][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[6][0].sBottom = 228 + UDBOffsetY;
+ gItemDescAdvRegions[6][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[6][1].sTop = 216 + UDBOffsetY; gItemDescAdvRegions[6][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[6][1].sBottom = 228 + UDBOffsetY;
+ gItemDescAdvRegions[6][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[6][2].sTop = 216 + UDBOffsetY; gItemDescAdvRegions[6][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[6][2].sBottom = 228 + UDBOffsetY;
+ gItemDescAdvRegions[6][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[6][3].sTop = 216 + UDBOffsetY; gItemDescAdvRegions[6][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[6][3].sBottom = 228 + UDBOffsetY;
+
+ gItemDescAdvRegions[7][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[7][0].sTop = 229 + UDBOffsetY; gItemDescAdvRegions[7][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[7][0].sBottom = 241 + UDBOffsetY;
+ gItemDescAdvRegions[7][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[7][1].sTop = 229 + UDBOffsetY; gItemDescAdvRegions[7][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[7][1].sBottom = 241 + UDBOffsetY;
+ gItemDescAdvRegions[7][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[7][2].sTop = 229 + UDBOffsetY; gItemDescAdvRegions[7][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[7][2].sBottom = 241 + UDBOffsetY;
+ gItemDescAdvRegions[7][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[7][3].sTop = 229 + UDBOffsetY; gItemDescAdvRegions[7][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[7][3].sBottom = 241 + UDBOffsetY;
+
+ gItemDescAdvRegions[8][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[8][0].sTop = 242 + UDBOffsetY; gItemDescAdvRegions[8][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[8][0].sBottom = 254 + UDBOffsetY;
+ gItemDescAdvRegions[8][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[8][1].sTop = 242 + UDBOffsetY; gItemDescAdvRegions[8][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[8][1].sBottom = 254 + UDBOffsetY;
+ gItemDescAdvRegions[8][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[8][2].sTop = 242 + UDBOffsetY; gItemDescAdvRegions[8][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[8][2].sBottom = 254 + UDBOffsetY;
+ gItemDescAdvRegions[8][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[8][3].sTop = 242 + UDBOffsetY; gItemDescAdvRegions[8][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[8][3].sBottom = 254 + UDBOffsetY;
+
+ gItemDescAdvRegions[9][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[9][0].sTop = 255 + UDBOffsetY; gItemDescAdvRegions[9][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[9][0].sBottom = 267 + UDBOffsetY;
+ gItemDescAdvRegions[9][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[9][1].sTop = 255 + UDBOffsetY; gItemDescAdvRegions[9][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[9][1].sBottom = 267 + UDBOffsetY;
+ gItemDescAdvRegions[9][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[9][2].sTop = 255 + UDBOffsetY; gItemDescAdvRegions[9][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[9][2].sBottom = 267 + UDBOffsetY;
+ gItemDescAdvRegions[9][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[9][3].sTop = 255 + UDBOffsetY; gItemDescAdvRegions[9][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[9][3].sBottom = 267 + UDBOffsetY;
+
+ gItemDescAdvRegions[10][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[10][0].sTop = 268 + UDBOffsetY; gItemDescAdvRegions[10][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[10][0].sBottom = 280 + UDBOffsetY;
+ gItemDescAdvRegions[10][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[10][1].sTop = 268 + UDBOffsetY; gItemDescAdvRegions[10][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[10][1].sBottom = 280 + UDBOffsetY;
+ gItemDescAdvRegions[10][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[10][2].sTop = 268 + UDBOffsetY; gItemDescAdvRegions[10][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[10][2].sBottom = 280 + UDBOffsetY;
+ gItemDescAdvRegions[10][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[10][3].sTop = 268 + UDBOffsetY; gItemDescAdvRegions[10][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[10][3].sBottom = 280 + UDBOffsetY;
+
+ gItemDescAdvRegions[11][0].sLeft = 12 + UDBOffsetX; gItemDescAdvRegions[11][0].sTop = 281 + UDBOffsetY; gItemDescAdvRegions[11][0].sRight = 126 + UDBOffsetX; gItemDescAdvRegions[11][0].sBottom = 293 + UDBOffsetY;
+ gItemDescAdvRegions[11][1].sLeft = 130 + UDBOffsetX; gItemDescAdvRegions[11][1].sTop = 281 + UDBOffsetY; gItemDescAdvRegions[11][1].sRight = 157 + UDBOffsetX; gItemDescAdvRegions[11][1].sBottom = 293 + UDBOffsetY;
+ gItemDescAdvRegions[11][2].sLeft = 162 + UDBOffsetX; gItemDescAdvRegions[11][2].sTop = 281 + UDBOffsetY; gItemDescAdvRegions[11][2].sRight = 189 + UDBOffsetX; gItemDescAdvRegions[11][2].sBottom = 293 + UDBOffsetY;
+ gItemDescAdvRegions[11][3].sLeft = 194 + UDBOffsetX; gItemDescAdvRegions[11][3].sTop = 281 + UDBOffsetY; gItemDescAdvRegions[11][3].sRight = 221 + UDBOffsetX; gItemDescAdvRegions[11][3].sBottom = 293 + UDBOffsetY;
}
- else
+ else // ODB
{
- if (UsingEDBSystem() == 1)
+ ///////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: UDB LBE background coordinates
+ // These depend on Strategic/Tactical...
+ if (guiCurrentScreen == MAP_SCREEN)
{
- // Icon Locations
- gMiscItemStatsEDB[0].sX = 203; gMiscItemStatsEDB[0].sY = 44; gMiscItemStatsEDB[0].sValDx = 0; // 0) COL 1; ROW 1
- gMiscItemStatsEDB[1].sX = 203; gMiscItemStatsEDB[1].sY = 56; gMiscItemStatsEDB[1].sValDx = 0; // 1) COL 1; ROW 2
- gMiscItemStatsEDB[2].sX = 203; gMiscItemStatsEDB[2].sY = 68; gMiscItemStatsEDB[2].sValDx = 0; // 2) COL 1; ROW 3
- gMiscItemStatsEDB[3].sX = 203; gMiscItemStatsEDB[3].sY = 80; gMiscItemStatsEDB[3].sValDx = 0; // 3) COL 1; ROW 4
- gMiscItemStatsEDB[4].sX = 203; gMiscItemStatsEDB[4].sY = 92; gMiscItemStatsEDB[4].sValDx = 0; // 4) COL 1; ROW 5
- gMiscItemStatsEDB[5].sX = 203; gMiscItemStatsEDB[5].sY = 104; gMiscItemStatsEDB[5].sValDx = 0; // 5) COL 1; ROW 6
- gMiscItemStatsEDB[6].sX = 203; gMiscItemStatsEDB[6].sY = 116; gMiscItemStatsEDB[6].sValDx = 0; // 6) COL 1; ROW 7
- gMiscItemStatsEDB[7].sX = 203; gMiscItemStatsEDB[7].sY = 128; gMiscItemStatsEDB[7].sValDx = 0; // 7) COL 1; ROW 8
- gMiscItemStatsEDB[8].sX = 203; gMiscItemStatsEDB[8].sY = 140; gMiscItemStatsEDB[8].sValDx = 0; // 8) COL 1; ROW 9
- gMiscItemStatsEDB[9].sX = 203; gMiscItemStatsEDB[9].sY = 152; gMiscItemStatsEDB[9].sValDx = 0; // 9) COL 1; ROW 10
- gMiscItemStatsEDB[10].sX = 203; gMiscItemStatsEDB[10].sY = 164; gMiscItemStatsEDB[10].sValDx = 0; // 10) COL 1; ROW 11
- gMiscItemStatsEDB[11].sX = 203; gMiscItemStatsEDB[11].sY = 176; gMiscItemStatsEDB[11].sValDx = 0; // 11) COL 1; ROW 12
- // EQUALS signs Locations
- gMiscItemStatsEDB[12].sX = 283; gMiscItemStatsEDB[12].sY = 44; gMiscItemStatsEDB[12].sValDx = 12; // 12) COL 1; ROW 1
- gMiscItemStatsEDB[13].sX = 283; gMiscItemStatsEDB[13].sY = 56; gMiscItemStatsEDB[13].sValDx = 12; // 13) COL 1; ROW 2
- gMiscItemStatsEDB[14].sX = 283; gMiscItemStatsEDB[14].sY = 68; gMiscItemStatsEDB[14].sValDx = 12; // 14) COL 1; ROW 3
- gMiscItemStatsEDB[15].sX = 283; gMiscItemStatsEDB[15].sY = 80; gMiscItemStatsEDB[15].sValDx = 12; // 15) COL 1; ROW 4
- gMiscItemStatsEDB[16].sX = 283; gMiscItemStatsEDB[16].sY = 92; gMiscItemStatsEDB[16].sValDx = 12; // 16) COL 1; ROW 5
- gMiscItemStatsEDB[17].sX = 283; gMiscItemStatsEDB[17].sY = 104; gMiscItemStatsEDB[17].sValDx = 12; // 17) COL 1; ROW 6
- gMiscItemStatsEDB[18].sX = 283; gMiscItemStatsEDB[18].sY = 116; gMiscItemStatsEDB[18].sValDx = 12; // 18) COL 1; ROW 7
- gMiscItemStatsEDB[19].sX = 283; gMiscItemStatsEDB[19].sY = 128; gMiscItemStatsEDB[19].sValDx = 12; // 19) COL 1; ROW 8
- gMiscItemStatsEDB[20].sX = 283; gMiscItemStatsEDB[20].sY = 140; gMiscItemStatsEDB[20].sValDx = 12; // 20) COL 1; ROW 9
- gMiscItemStatsEDB[21].sX = 283; gMiscItemStatsEDB[21].sY = 152; gMiscItemStatsEDB[21].sValDx = 12; // 21) COL 1; ROW 10
- gMiscItemStatsEDB[22].sX = 283; gMiscItemStatsEDB[22].sY = 164; gMiscItemStatsEDB[22].sValDx = 12; // 22) COL 1; ROW 11
- gMiscItemStatsEDB[23].sX = 283; gMiscItemStatsEDB[23].sY = 176; gMiscItemStatsEDB[23].sValDx = 12; // 23) COL 1; ROW 12
- // MISC
- gMiscItemStatsEDB[24].sX = 0; gMiscItemStatsEDB[24].sY = 0; gMiscItemStatsEDB[24].sValDx = 0;
- gMiscItemStatsEDB[25].sX = 0; gMiscItemStatsEDB[25].sY = 0; gMiscItemStatsEDB[25].sValDx = 0;
- gMiscItemStatsEDB[26].sX = 0; gMiscItemStatsEDB[26].sY = 0; gMiscItemStatsEDB[26].sValDx = 0;
- gMiscItemStatsEDB[27].sX = 0; gMiscItemStatsEDB[27].sY = 0; gMiscItemStatsEDB[27].sValDx = 0;
+ INT16 sOffsetY = sNASYCorrection( pObject );
- gWeaponDescStatsRects[0].iLeft = 202; gWeaponDescStatsRects[0].iTop = 42; gWeaponDescStatsRects[0].iRight = 260; gWeaponDescStatsRects[0].iBottom = 53; // First Column
- gWeaponDescStatsRects[1].iLeft = 202; gWeaponDescStatsRects[1].iTop = 54; gWeaponDescStatsRects[1].iRight = 260; gWeaponDescStatsRects[1].iBottom = 65;
- gWeaponDescStatsRects[2].iLeft = 202; gWeaponDescStatsRects[2].iTop = 66; gWeaponDescStatsRects[2].iRight = 260; gWeaponDescStatsRects[2].iBottom = 77;
- gWeaponDescStatsRects[3].iLeft = 202; gWeaponDescStatsRects[3].iTop = 78; gWeaponDescStatsRects[3].iRight = 260; gWeaponDescStatsRects[3].iBottom = 89;
- gWeaponDescStatsRects[4].iLeft = 202; gWeaponDescStatsRects[4].iTop = 90; gWeaponDescStatsRects[4].iRight = 260; gWeaponDescStatsRects[4].iBottom = 101;
- gWeaponDescStatsRects[5].iLeft = 202; gWeaponDescStatsRects[5].iTop = 102; gWeaponDescStatsRects[5].iRight = 260; gWeaponDescStatsRects[5].iBottom = 113;
- gWeaponDescStatsRects[6].iLeft = 202; gWeaponDescStatsRects[6].iTop = 114; gWeaponDescStatsRects[6].iRight = 260; gWeaponDescStatsRects[6].iBottom = 125;
- gWeaponDescStatsRects[7].iLeft = 267; gWeaponDescStatsRects[7].iTop = 54; gWeaponDescStatsRects[7].iRight = 325; gWeaponDescStatsRects[7].iBottom = 65; // Second Column
- gWeaponDescStatsRects[8].iLeft = 267; gWeaponDescStatsRects[8].iTop = 66; gWeaponDescStatsRects[8].iRight = 325; gWeaponDescStatsRects[8].iBottom = 77;
- gWeaponDescStatsRects[9].iLeft = 267; gWeaponDescStatsRects[9].iTop = 78; gWeaponDescStatsRects[9].iRight = 325; gWeaponDescStatsRects[9].iBottom = 89;
- gWeaponDescStatsRects[10].iLeft = 267; gWeaponDescStatsRects[10].iTop = 90; gWeaponDescStatsRects[10].iRight = 325; gWeaponDescStatsRects[10].iBottom = 101;
- gWeaponDescStatsRects[11].iLeft = 267; gWeaponDescStatsRects[11].iTop = 102; gWeaponDescStatsRects[11].iRight = 325; gWeaponDescStatsRects[11].iBottom = 113;
- gWeaponDescStatsRects[12].iLeft = 267; gWeaponDescStatsRects[12].iTop = 114; gWeaponDescStatsRects[12].iRight = 325; gWeaponDescStatsRects[12].iBottom = 125;
- gWeaponDescStatsRects[13].iLeft = 267; gWeaponDescStatsRects[13].iTop = 134; gWeaponDescStatsRects[13].iRight = 325; gWeaponDescStatsRects[13].iBottom = 145;
- gWeaponDescStatsRects[14].iLeft = 267; gWeaponDescStatsRects[14].iTop = 146; gWeaponDescStatsRects[14].iRight = 325; gWeaponDescStatsRects[14].iBottom = 157;
- gWeaponDescStatsRects[15].iLeft = 267; gWeaponDescStatsRects[15].iTop = 158; gWeaponDescStatsRects[15].iRight = 325; gWeaponDescStatsRects[15].iBottom = 169;
- gWeaponDescStatsRects[16].iLeft = 267; gWeaponDescStatsRects[16].iTop = 170; gWeaponDescStatsRects[16].iRight = 325; gWeaponDescStatsRects[16].iBottom = 181;
- gWeaponDescStatsRects[17].iLeft = 225; gWeaponDescStatsRects[17].iTop = 134; gWeaponDescStatsRects[17].iRight = 241; gWeaponDescStatsRects[17].iBottom = 157;
- gWeaponDescStatsRects[18].iLeft = 202; gWeaponDescStatsRects[18].iTop = 158; gWeaponDescStatsRects[18].iRight = 260; gWeaponDescStatsRects[18].iBottom = 169;
- gWeaponDescStatsRects[19].iLeft = 202; gWeaponDescStatsRects[19].iTop = 170; gWeaponDescStatsRects[19].iRight = 260; gWeaponDescStatsRects[19].iBottom = 181;
+ gItemDescLBEBackground[0].sLeft = 94 + gsInvDescX; gItemDescLBEBackground[0].sTop = 286 + gsInvDescY + sOffsetY;
+ gItemDescLBEBackground[1].sLeft = 15 + gsInvDescX; gItemDescLBEBackground[1].sTop = 298 + gsInvDescY + sOffsetY;
+ gItemDescLBEBackground[2].sLeft = 94 + gsInvDescX; gItemDescLBEBackground[2].sTop = 286 + gsInvDescY + sOffsetY;
+ gItemDescLBEBackground[3].sLeft = 61 + gsInvDescX; gItemDescLBEBackground[3].sTop = 274 + gsInvDescY + sOffsetY;
- gAmmoDescStatsRects[0].iLeft = 202; gAmmoDescStatsRects[0].iTop = 42; gAmmoDescStatsRects[0].iRight = 260; gAmmoDescStatsRects[0].iBottom = 53; // First Column
- gAmmoDescStatsRects[1].iLeft = 202; gAmmoDescStatsRects[1].iTop = 54; gAmmoDescStatsRects[1].iRight = 260; gAmmoDescStatsRects[1].iBottom = 65;
- gAmmoDescStatsRects[2].iLeft = 202; gAmmoDescStatsRects[2].iTop = 66; gAmmoDescStatsRects[2].iRight = 260; gAmmoDescStatsRects[2].iBottom = 77;
- gAmmoDescStatsRects[3].iLeft = 269; gAmmoDescStatsRects[3].iTop = 42; gAmmoDescStatsRects[3].iRight = 291; gAmmoDescStatsRects[3].iBottom = 65; // Second Column
- gAmmoDescStatsRects[4].iLeft = 296; gAmmoDescStatsRects[4].iTop = 42; gAmmoDescStatsRects[4].iRight = 321; gAmmoDescStatsRects[4].iBottom = 65;
- gAmmoDescStatsRects[5].iLeft = 269; gAmmoDescStatsRects[5].iTop = 66; gAmmoDescStatsRects[5].iRight = 291; gAmmoDescStatsRects[5].iBottom = 89;
- gAmmoDescStatsRects[6].iLeft = 296; gAmmoDescStatsRects[6].iTop = 66; gAmmoDescStatsRects[6].iRight = 321; gAmmoDescStatsRects[6].iBottom = 89;
- gAmmoDescStatsRects[7].iLeft = 269; gAmmoDescStatsRects[7].iTop = 90; gAmmoDescStatsRects[7].iRight = 291; gAmmoDescStatsRects[7].iBottom = 113;
- gAmmoDescStatsRects[8].iLeft = 202; gAmmoDescStatsRects[8].iTop = 134; gAmmoDescStatsRects[8].iRight = 260; gAmmoDescStatsRects[8].iBottom = 145; // Third Column
- gAmmoDescStatsRects[9].iLeft = 202; gAmmoDescStatsRects[9].iTop = 158; gAmmoDescStatsRects[9].iRight = 260; gAmmoDescStatsRects[9].iBottom = 169;
- gAmmoDescStatsRects[10].iLeft = 267; gAmmoDescStatsRects[10].iTop = 134; gAmmoDescStatsRects[10].iRight = 325; gAmmoDescStatsRects[10].iBottom = 145;
- gAmmoDescStatsRects[11].iLeft = 267; gAmmoDescStatsRects[11].iTop = 146; gAmmoDescStatsRects[11].iRight = 325; gAmmoDescStatsRects[11].iBottom = 157;
- gAmmoDescStatsRects[12].iLeft = 267; gAmmoDescStatsRects[12].iTop = 158; gAmmoDescStatsRects[12].iRight = 325; gAmmoDescStatsRects[12].iBottom = 169; // Fourth Column
- gAmmoDescStatsRects[13].iLeft = 202; gAmmoDescStatsRects[13].iTop = 170; gAmmoDescStatsRects[13].iRight = 260; gAmmoDescStatsRects[13].iBottom = 181;
- gAmmoDescStatsRects[14].iLeft = 267; gAmmoDescStatsRects[14].iTop = 170; gAmmoDescStatsRects[14].iRight = 325; gAmmoDescStatsRects[14].iBottom = 181; // Placeholders
- gAmmoDescStatsRects[15].iLeft = 0; gAmmoDescStatsRects[15].iTop = 0; gAmmoDescStatsRects[15].iRight = 1; gAmmoDescStatsRects[15].iBottom = 1;
- gAmmoDescStatsRects[16].iLeft = 0; gAmmoDescStatsRects[16].iTop = 0; gAmmoDescStatsRects[16].iRight = 1; gAmmoDescStatsRects[16].iBottom = 1;
- gAmmoDescStatsRects[17].iLeft = 0; gAmmoDescStatsRects[17].iTop = 0; gAmmoDescStatsRects[17].iRight = 1; gAmmoDescStatsRects[17].iBottom = 1;
- gAmmoDescStatsRects[18].iLeft = 0; gAmmoDescStatsRects[18].iTop = 0; gAmmoDescStatsRects[18].iRight = 1; gAmmoDescStatsRects[18].iBottom = 1;
- gAmmoDescStatsRects[19].iLeft = 0; gAmmoDescStatsRects[19].iTop = 0; gAmmoDescStatsRects[19].iRight = 1; gAmmoDescStatsRects[19].iBottom = 1;
+ ////////////////// MONEY TEXT COORDINATES
+ gMoneyStats[0].sX = 48 + gsInvDescX; gMoneyStats[0].sY = 98 + gsInvDescY + sOffsetY; // Money
+ gMoneyStats[1].sX = 56 + gsInvDescX; gMoneyStats[1].sY = 108 + gsInvDescY + sOffsetY; // Remaining
+ gMoneyStats[2].sX = 48 + gsInvDescX; gMoneyStats[2].sY = 125 + gsInvDescY + sOffsetY; // Money
+ gMoneyStats[3].sX = 56 + gsInvDescX; gMoneyStats[3].sY = 135 + gsInvDescY + sOffsetY; // Removing
+ gMoneyStats[4].sX = 140 + gsInvDescX; gMoneyStats[4].sY = 108 + gsInvDescY + sOffsetY; // AMT remaining
+ gMoneyStats[5].sX = 140 + gsInvDescX; gMoneyStats[5].sY = 135 + gsInvDescY + sOffsetY; // AMT removing
- gArmorDescStatsRects[0].iLeft = 202; gArmorDescStatsRects[0].iTop = 42; gArmorDescStatsRects[0].iRight = 260; gArmorDescStatsRects[0].iBottom = 53; // First Column
- gArmorDescStatsRects[1].iLeft = 202; gArmorDescStatsRects[1].iTop = 54; gArmorDescStatsRects[1].iRight = 260; gArmorDescStatsRects[1].iBottom = 65;
- gArmorDescStatsRects[2].iLeft = 202; gArmorDescStatsRects[2].iTop = 66; gArmorDescStatsRects[2].iRight = 260; gArmorDescStatsRects[2].iBottom = 77;
- gArmorDescStatsRects[3].iLeft = 267; gArmorDescStatsRects[3].iTop = 42; gArmorDescStatsRects[3].iRight = 325; gArmorDescStatsRects[3].iBottom = 53; // Second Column
- gArmorDescStatsRects[4].iLeft = 267; gArmorDescStatsRects[4].iTop = 54; gArmorDescStatsRects[4].iRight = 325; gArmorDescStatsRects[4].iBottom = 65;
- gArmorDescStatsRects[5].iLeft = 267; gArmorDescStatsRects[5].iTop = 66; gArmorDescStatsRects[5].iRight = 325; gArmorDescStatsRects[5].iBottom = 77;
- gArmorDescStatsRects[6].iLeft = 267; gArmorDescStatsRects[6].iTop = 78; gArmorDescStatsRects[6].iRight = 325; gArmorDescStatsRects[6].iBottom = 89;
- gArmorDescStatsRects[7].iLeft = 267; gArmorDescStatsRects[7].iTop = 90; gArmorDescStatsRects[7].iRight = 325; gArmorDescStatsRects[7].iBottom = 101;
- gArmorDescStatsRects[8].iLeft = 267; gArmorDescStatsRects[8].iTop = 102; gArmorDescStatsRects[8].iRight = 325; gArmorDescStatsRects[8].iBottom = 113;
- gArmorDescStatsRects[9].iLeft = 267; gArmorDescStatsRects[9].iTop = 114; gArmorDescStatsRects[9].iRight = 325; gArmorDescStatsRects[9].iBottom = 125;
- gArmorDescStatsRects[10].iLeft = 202; gArmorDescStatsRects[10].iTop = 134; gArmorDescStatsRects[10].iRight = 260; gArmorDescStatsRects[10].iBottom = 145; // Third Column
- gArmorDescStatsRects[11].iLeft = 202; gArmorDescStatsRects[11].iTop = 146; gArmorDescStatsRects[11].iRight = 260; gArmorDescStatsRects[11].iBottom = 157;
- gArmorDescStatsRects[12].iLeft = 202; gArmorDescStatsRects[12].iTop = 158; gArmorDescStatsRects[12].iRight = 260; gArmorDescStatsRects[12].iBottom = 169;
- gArmorDescStatsRects[13].iLeft = 202; gArmorDescStatsRects[13].iTop = 170; gArmorDescStatsRects[13].iRight = 260; gArmorDescStatsRects[13].iBottom = 181;
- gArmorDescStatsRects[14].iLeft = 267; gArmorDescStatsRects[14].iTop = 134; gArmorDescStatsRects[14].iRight = 325; gArmorDescStatsRects[14].iBottom = 145; // Fourth Column
- gArmorDescStatsRects[15].iLeft = 267; gArmorDescStatsRects[15].iTop = 146; gArmorDescStatsRects[15].iRight = 325; gArmorDescStatsRects[15].iBottom = 157;
- gArmorDescStatsRects[16].iLeft = 267; gArmorDescStatsRects[16].iTop = 158; gArmorDescStatsRects[16].iRight = 325; gArmorDescStatsRects[16].iBottom = 169;
- gArmorDescStatsRects[17].iLeft = 0; gArmorDescStatsRects[17].iTop = 0; gArmorDescStatsRects[17].iRight = 1; gArmorDescStatsRects[17].iBottom = 1; // Placeholders
- gArmorDescStatsRects[18].iLeft = 0; gArmorDescStatsRects[18].iTop = 0; gArmorDescStatsRects[18].iRight = 1; gArmorDescStatsRects[18].iBottom = 1;
- gArmorDescStatsRects[19].iLeft = 0; gArmorDescStatsRects[19].iTop = 0; gArmorDescStatsRects[19].iRight = 1; gArmorDescStatsRects[19].iBottom = 1;
+ //////////////////////////////////////////////////////////////////////
+ // ODB has exactly four separate regions. Each has 8 sub-regions, which can be
+ // used to display data at irregular intervals. This allows ODB to function as
+ // smoothly as EDB does.
+ // In addition, ODB uses some of the UDB regions to display things like PROS/CONS
+ // and Description Text. This reduces the use of redundant arrays...
- gExplosiveDescStatsRects[0].iLeft = 202; gExplosiveDescStatsRects[0].iTop = 42; gExplosiveDescStatsRects[0].iRight = 260; gExplosiveDescStatsRects[0].iBottom = 53; // First Column
- gExplosiveDescStatsRects[1].iLeft = 202; gExplosiveDescStatsRects[1].iTop = 54; gExplosiveDescStatsRects[1].iRight = 260; gExplosiveDescStatsRects[1].iBottom = 65;
- gExplosiveDescStatsRects[2].iLeft = 202; gExplosiveDescStatsRects[2].iTop = 66; gExplosiveDescStatsRects[2].iRight = 260; gExplosiveDescStatsRects[2].iBottom = 77;
- gExplosiveDescStatsRects[3].iLeft = 202; gExplosiveDescStatsRects[3].iTop = 78; gExplosiveDescStatsRects[3].iRight = 260; gExplosiveDescStatsRects[3].iBottom = 89;
- gExplosiveDescStatsRects[4].iLeft = 290; gExplosiveDescStatsRects[4].iTop = 42; gExplosiveDescStatsRects[4].iRight = 306; gExplosiveDescStatsRects[4].iBottom = 77; // Second Column
- gExplosiveDescStatsRects[5].iLeft = 269; gExplosiveDescStatsRects[5].iTop = 42; gExplosiveDescStatsRects[5].iRight = 285; gExplosiveDescStatsRects[5].iBottom = 77;
- gExplosiveDescStatsRects[6].iLeft = 301; gExplosiveDescStatsRects[6].iTop = 42; gExplosiveDescStatsRects[6].iRight = 321; gExplosiveDescStatsRects[6].iBottom = 77;
- gExplosiveDescStatsRects[7].iLeft = 267; gExplosiveDescStatsRects[7].iTop = 90; gExplosiveDescStatsRects[7].iRight = 325; gExplosiveDescStatsRects[7].iBottom = 101;
- gExplosiveDescStatsRects[8].iLeft = 0; gExplosiveDescStatsRects[8].iTop = 0; gExplosiveDescStatsRects[8].iRight = 1; gExplosiveDescStatsRects[8].iBottom = 1; // Placeholders
- gExplosiveDescStatsRects[9].iLeft = 0; gExplosiveDescStatsRects[9].iTop = 0; gExplosiveDescStatsRects[9].iRight = 1; gExplosiveDescStatsRects[9].iBottom = 1;
- gExplosiveDescStatsRects[10].iLeft = 0; gExplosiveDescStatsRects[10].iTop = 0; gExplosiveDescStatsRects[10].iRight = 1; gExplosiveDescStatsRects[10].iBottom = 1;
- gExplosiveDescStatsRects[11].iLeft = 0; gExplosiveDescStatsRects[11].iTop = 0; gExplosiveDescStatsRects[11].iRight = 1; gExplosiveDescStatsRects[11].iBottom = 1;
- gExplosiveDescStatsRects[12].iLeft = 0; gExplosiveDescStatsRects[12].iTop = 0; gExplosiveDescStatsRects[12].iRight = 1; gExplosiveDescStatsRects[12].iBottom = 1;
- gExplosiveDescStatsRects[13].iLeft = 0; gExplosiveDescStatsRects[13].iTop = 0; gExplosiveDescStatsRects[13].iRight = 1; gExplosiveDescStatsRects[13].iBottom = 1;
- gExplosiveDescStatsRects[14].iLeft = 0; gExplosiveDescStatsRects[14].iTop = 0; gExplosiveDescStatsRects[14].iRight = 1; gExplosiveDescStatsRects[14].iBottom = 1;
- gExplosiveDescStatsRects[15].iLeft = 0; gExplosiveDescStatsRects[15].iTop = 0; gExplosiveDescStatsRects[15].iRight = 1; gExplosiveDescStatsRects[15].iBottom = 1;
- gExplosiveDescStatsRects[16].iLeft = 0; gExplosiveDescStatsRects[16].iTop = 0; gExplosiveDescStatsRects[16].iRight = 1; gExplosiveDescStatsRects[16].iBottom = 1;
- gExplosiveDescStatsRects[17].iLeft = 0; gExplosiveDescStatsRects[17].iTop = 0; gExplosiveDescStatsRects[17].iRight = 1; gExplosiveDescStatsRects[17].iBottom = 1;
- gExplosiveDescStatsRects[18].iLeft = 0; gExplosiveDescStatsRects[18].iTop = 0; gExplosiveDescStatsRects[18].iRight = 1; gExplosiveDescStatsRects[18].iBottom = 1;
- gExplosiveDescStatsRects[19].iLeft = 0; gExplosiveDescStatsRects[19].iTop = 0; gExplosiveDescStatsRects[19].iRight = 1; gExplosiveDescStatsRects[19].iBottom = 1;
+ // First Data Row (Condition / Ammo label)
+ gODBItemDescRegions[0][0].sLeft = 52 + gsInvDescX; gODBItemDescRegions[0][0].sTop = 98 + gsInvDescY + sOffsetY; gODBItemDescRegions[0][0].sRight = 167 + gsInvDescX; gODBItemDescRegions[0][0].sBottom = 106 + gsInvDescY + sOffsetY;
+
+ // Second Data Row (Weight)
+ gODBItemDescRegions[1][0].sLeft = 52 + gsInvDescX; gODBItemDescRegions[1][0].sTop = 108 + gsInvDescY + sOffsetY; gODBItemDescRegions[1][0].sRight = 167 + gsInvDescX; gODBItemDescRegions[1][0].sBottom = 116 + gsInvDescY + sOffsetY;
+
+ // Third Data Row (Usually basic Gun Statistics)
+ // Left Side
+ gODBItemDescRegions[2][0].sLeft = 52 + gsInvDescX; gODBItemDescRegions[2][0].sTop = 124 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[2][3].sLeft = 91 + gsInvDescX; gODBItemDescRegions[2][3].sTop = 124 + gsInvDescY + sOffsetY; gODBItemDescRegions[2][3].sRight = 107 + gsInvDescX; gODBItemDescRegions[2][3].sBottom = 132 + gsInvDescY + sOffsetY;
+
+ // Right Side
+ gODBItemDescRegions[2][4].sLeft = 117 + gsInvDescX; gODBItemDescRegions[2][4].sTop = 124 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[2][7].sLeft = 152 + gsInvDescX; gODBItemDescRegions[2][7].sTop = 124 + gsInvDescY + sOffsetY; gODBItemDescRegions[2][7].sRight = 168 + gsInvDescX; gODBItemDescRegions[2][7].sBottom = 132 + gsInvDescY + sOffsetY;
+
+ // Fourth Data Row (Usually AP Costs)
+ // Left Side
+ gODBItemDescRegions[3][0].sLeft = 52 + gsInvDescX; gODBItemDescRegions[3][0].sTop = 135 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[3][1].sLeft = 77 + gsInvDescX; gODBItemDescRegions[3][1].sTop = 135 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[3][2].sLeft = 86 + gsInvDescX; gODBItemDescRegions[3][2].sTop = 135 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[3][3].sLeft = 91 + gsInvDescX; gODBItemDescRegions[3][3].sTop = 135 + gsInvDescY + sOffsetY; gODBItemDescRegions[3][3].sRight = 107 + gsInvDescX; gODBItemDescRegions[3][3].sBottom = 143 + gsInvDescY + sOffsetY;
+ // Right Side
+ gODBItemDescRegions[3][4].sLeft = 117 + gsInvDescX; gODBItemDescRegions[3][4].sTop = 135 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[3][6].sLeft = 145 + gsInvDescX; gODBItemDescRegions[3][6].sTop = 135 + gsInvDescY + sOffsetY;
+ gODBItemDescRegions[3][7].sLeft = 152 + gsInvDescX; gODBItemDescRegions[3][7].sTop = 135 + gsInvDescY + sOffsetY; gODBItemDescRegions[3][7].sRight = 168 + gsInvDescX; gODBItemDescRegions[3][7].sBottom = 143 + gsInvDescY + sOffsetY;
+
+ // Description Text Area
+ gItemDescTextRegions[0].sLeft = 23 + gsInvDescX; gItemDescTextRegions[0].sTop = 170 + gsInvDescY + sOffsetY; gItemDescTextRegions[0].sRight = 233 + gsInvDescX;
+
+ // PROS/CONS areas
+ gItemDescTextRegions[3].sLeft = 23 + gsInvDescX; gItemDescTextRegions[3].sTop = 230 + gsInvDescY + sOffsetY; gItemDescTextRegions[3].sRight = 233 + gsInvDescX; gItemDescTextRegions[3].sBottom = 238 + gsInvDescY + sOffsetY;
+ gItemDescTextRegions[4].sLeft = 59 + gsInvDescX; gItemDescTextRegions[4].sTop = 230 + gsInvDescY + sOffsetY; gItemDescTextRegions[4].sRight = 233 + gsInvDescX; gItemDescTextRegions[4].sBottom = 238 + gsInvDescY + sOffsetY;
+ gItemDescTextRegions[5].sLeft = 23 + gsInvDescX; gItemDescTextRegions[5].sTop = 240 + gsInvDescY + sOffsetY; gItemDescTextRegions[5].sRight = 233 + gsInvDescX; gItemDescTextRegions[5].sBottom = 250 + gsInvDescY + sOffsetY;
+ gItemDescTextRegions[6].sLeft = 59 + gsInvDescX; gItemDescTextRegions[6].sTop = 240 + gsInvDescY + sOffsetY; gItemDescTextRegions[6].sRight = 233 + gsInvDescX; gItemDescTextRegions[6].sBottom = 250 + gsInvDescY + sOffsetY;
- gMiscItemDescStatsRects[0].iLeft = 202; gMiscItemDescStatsRects[0].iTop = 42; gMiscItemDescStatsRects[0].iRight = 325; gMiscItemDescStatsRects[0].iBottom = 53; // Only one column for misc items in tactical - 12 fields.
- gMiscItemDescStatsRects[1].iLeft = 202; gMiscItemDescStatsRects[1].iTop = 54; gMiscItemDescStatsRects[1].iRight = 325; gMiscItemDescStatsRects[1].iBottom = 65;
- gMiscItemDescStatsRects[2].iLeft = 202; gMiscItemDescStatsRects[2].iTop = 66; gMiscItemDescStatsRects[2].iRight = 325; gMiscItemDescStatsRects[2].iBottom = 77;
- gMiscItemDescStatsRects[3].iLeft = 202; gMiscItemDescStatsRects[3].iTop = 78; gMiscItemDescStatsRects[3].iRight = 325; gMiscItemDescStatsRects[3].iBottom = 89;
- gMiscItemDescStatsRects[4].iLeft = 202; gMiscItemDescStatsRects[4].iTop = 90; gMiscItemDescStatsRects[4].iRight = 325; gMiscItemDescStatsRects[4].iBottom = 101;
- gMiscItemDescStatsRects[5].iLeft = 202; gMiscItemDescStatsRects[5].iTop = 102; gMiscItemDescStatsRects[5].iRight = 325; gMiscItemDescStatsRects[5].iBottom = 113;
- gMiscItemDescStatsRects[6].iLeft = 202; gMiscItemDescStatsRects[6].iTop = 114; gMiscItemDescStatsRects[6].iRight = 325; gMiscItemDescStatsRects[6].iBottom = 125;
- gMiscItemDescStatsRects[7].iLeft = 202; gMiscItemDescStatsRects[7].iTop = 126; gMiscItemDescStatsRects[7].iRight = 325; gMiscItemDescStatsRects[7].iBottom = 137;
- gMiscItemDescStatsRects[8].iLeft = 202; gMiscItemDescStatsRects[8].iTop = 138; gMiscItemDescStatsRects[8].iRight = 325; gMiscItemDescStatsRects[8].iBottom = 149;
- gMiscItemDescStatsRects[9].iLeft = 202; gMiscItemDescStatsRects[9].iTop = 150; gMiscItemDescStatsRects[9].iRight = 325; gMiscItemDescStatsRects[9].iBottom = 161;
- gMiscItemDescStatsRects[10].iLeft = 202; gMiscItemDescStatsRects[10].iTop = 162; gMiscItemDescStatsRects[10].iRight = 325; gMiscItemDescStatsRects[10].iBottom = 173;
- gMiscItemDescStatsRects[11].iLeft = 202; gMiscItemDescStatsRects[11].iTop = 174; gMiscItemDescStatsRects[11].iRight = 325; gMiscItemDescStatsRects[11].iBottom = 185;
- gMiscItemDescStatsRects[12].iLeft = 0; gMiscItemDescStatsRects[12].iTop = 0; gMiscItemDescStatsRects[12].iRight = 1; gMiscItemDescStatsRects[12].iBottom = 1; // Placeholders
- gMiscItemDescStatsRects[13].iLeft = 0; gMiscItemDescStatsRects[13].iTop = 0; gMiscItemDescStatsRects[13].iRight = 1; gMiscItemDescStatsRects[13].iBottom = 1;
- gMiscItemDescStatsRects[14].iLeft = 0; gMiscItemDescStatsRects[14].iTop = 0; gMiscItemDescStatsRects[14].iRight = 1; gMiscItemDescStatsRects[14].iBottom = 1;
- gMiscItemDescStatsRects[15].iLeft = 0; gMiscItemDescStatsRects[15].iTop = 0; gMiscItemDescStatsRects[15].iRight = 1; gMiscItemDescStatsRects[15].iBottom = 1;
- gMiscItemDescStatsRects[16].iLeft = 0; gMiscItemDescStatsRects[16].iTop = 0; gMiscItemDescStatsRects[16].iRight = 1; gMiscItemDescStatsRects[16].iBottom = 1;
- gMiscItemDescStatsRects[17].iLeft = 0; gMiscItemDescStatsRects[17].iTop = 0; gMiscItemDescStatsRects[17].iRight = 1; gMiscItemDescStatsRects[17].iBottom = 1;
- gMiscItemDescStatsRects[18].iLeft = 0; gMiscItemDescStatsRects[18].iTop = 0; gMiscItemDescStatsRects[18].iRight = 1; gMiscItemDescStatsRects[18].iBottom = 1;
- gMiscItemDescStatsRects[19].iLeft = 0; gMiscItemDescStatsRects[19].iTop = 0; gMiscItemDescStatsRects[19].iRight = 1; gMiscItemDescStatsRects[19].iBottom = 1;
}
- else if (UsingEDBSystem() == 2) // Tactical OIV-EDB
+ else
{
- // Icon Locations
- gMiscItemStatsEDB[0].sX = 274; gMiscItemStatsEDB[0].sY = 14; gMiscItemStatsEDB[0].sValDx = 0; // 0) COL 1; ROW 1
- gMiscItemStatsEDB[1].sX = 274; gMiscItemStatsEDB[1].sY = 26; gMiscItemStatsEDB[1].sValDx = 0; // 1) COL 1; ROW 2
- gMiscItemStatsEDB[2].sX = 274; gMiscItemStatsEDB[2].sY = 38; gMiscItemStatsEDB[2].sValDx = 0; // 2) COL 1; ROW 3
- gMiscItemStatsEDB[3].sX = 274; gMiscItemStatsEDB[3].sY = 50; gMiscItemStatsEDB[3].sValDx = 0; // 3) COL 1; ROW 4
- gMiscItemStatsEDB[4].sX = 274; gMiscItemStatsEDB[4].sY = 62; gMiscItemStatsEDB[4].sValDx = 0; // 4) COL 1; ROW 5
- gMiscItemStatsEDB[5].sX = 274; gMiscItemStatsEDB[5].sY = 74; gMiscItemStatsEDB[5].sValDx = 0; // 5) COL 1; ROW 6
- gMiscItemStatsEDB[6].sX = 274; gMiscItemStatsEDB[6].sY = 86; gMiscItemStatsEDB[6].sValDx = 0; // 6) COL 1; ROW 7
- gMiscItemStatsEDB[7].sX = 375; gMiscItemStatsEDB[7].sY = 14; gMiscItemStatsEDB[7].sValDx = 0; // 7) COL 1; ROW 8
- gMiscItemStatsEDB[8].sX = 375; gMiscItemStatsEDB[8].sY = 26; gMiscItemStatsEDB[8].sValDx = 0; // 8) COL 1; ROW 9
- gMiscItemStatsEDB[9].sX = 375; gMiscItemStatsEDB[9].sY = 38; gMiscItemStatsEDB[9].sValDx = 0; // 9) COL 1; ROW 10
- gMiscItemStatsEDB[10].sX = 375; gMiscItemStatsEDB[10].sY = 50; gMiscItemStatsEDB[10].sValDx = 0; // 10) COL 1; ROW 11
- gMiscItemStatsEDB[11].sX = 375; gMiscItemStatsEDB[11].sY = 62; gMiscItemStatsEDB[11].sValDx = 0; // 11) COL 1; ROW 12
- // EQUALS signs Locations
- gMiscItemStatsEDB[12].sX = 324; gMiscItemStatsEDB[12].sY = 14; gMiscItemStatsEDB[12].sValDx = 12; // 12) COL 1; ROW 1
- gMiscItemStatsEDB[13].sX = 324; gMiscItemStatsEDB[13].sY = 26; gMiscItemStatsEDB[13].sValDx = 12; // 13) COL 1; ROW 2
- gMiscItemStatsEDB[14].sX = 324; gMiscItemStatsEDB[14].sY = 38; gMiscItemStatsEDB[14].sValDx = 12; // 14) COL 1; ROW 3
- gMiscItemStatsEDB[15].sX = 324; gMiscItemStatsEDB[15].sY = 50; gMiscItemStatsEDB[15].sValDx = 12; // 15) COL 1; ROW 4
- gMiscItemStatsEDB[16].sX = 324; gMiscItemStatsEDB[16].sY = 62; gMiscItemStatsEDB[16].sValDx = 12; // 16) COL 1; ROW 5
- gMiscItemStatsEDB[17].sX = 324; gMiscItemStatsEDB[17].sY = 74; gMiscItemStatsEDB[17].sValDx = 12; // 17) COL 1; ROW 6
- gMiscItemStatsEDB[18].sX = 324; gMiscItemStatsEDB[18].sY = 86; gMiscItemStatsEDB[18].sValDx = 12; // 18) COL 1; ROW 7
- gMiscItemStatsEDB[19].sX = 425; gMiscItemStatsEDB[19].sY = 14; gMiscItemStatsEDB[19].sValDx = 12; // 19) COL 1; ROW 8
- gMiscItemStatsEDB[20].sX = 425; gMiscItemStatsEDB[20].sY = 26; gMiscItemStatsEDB[20].sValDx = 12; // 20) COL 1; ROW 9
- gMiscItemStatsEDB[21].sX = 425; gMiscItemStatsEDB[21].sY = 38; gMiscItemStatsEDB[21].sValDx = 12; // 21) COL 1; ROW 10
- gMiscItemStatsEDB[22].sX = 425; gMiscItemStatsEDB[22].sY = 50; gMiscItemStatsEDB[22].sValDx = 12; // 22) COL 1; ROW 11
- gMiscItemStatsEDB[23].sX = 425; gMiscItemStatsEDB[23].sY = 62; gMiscItemStatsEDB[23].sValDx = 12; // 23) COL 1; ROW 12
- // MISC
- gMiscItemStatsEDB[24].sX = 0; gMiscItemStatsEDB[24].sY = 0; gMiscItemStatsEDB[24].sValDx = 0;
- gMiscItemStatsEDB[25].sX = 0; gMiscItemStatsEDB[25].sY = 0; gMiscItemStatsEDB[25].sValDx = 0;
- gMiscItemStatsEDB[26].sX = 0; gMiscItemStatsEDB[26].sY = 0; gMiscItemStatsEDB[26].sValDx = 0;
- gMiscItemStatsEDB[27].sX = 0; gMiscItemStatsEDB[27].sY = 0; gMiscItemStatsEDB[27].sValDx = 0;
+ // Tactical NAS/ODB and regular ODB are radically different in shape, so we need two separate
+ // definition tables.
+ if (UseNASDesc( pObject ))
+ {
+ // No LBE/MONEY coordinates, since NAS doesn't run with either such item.
+ /*
+ gItemDescLBEBackground[0].sLeft = 320 + gsInvDescX; gItemDescLBEBackground[0].sTop = 8 + gsInvDescY;
+ gItemDescLBEBackground[1].sLeft = 3 + gsInvDescX; gItemDescLBEBackground[1].sTop = 137 + gsInvDescY;
+ gItemDescLBEBackground[2].sLeft = 320 + gsInvDescX; gItemDescLBEBackground[2].sTop = 8 + gsInvDescY;
+ gItemDescLBEBackground[3].sLeft = 320 + gsInvDescX; gItemDescLBEBackground[3].sTop = 8 + gsInvDescY;
- gWeaponDescStatsRects[0].iLeft = 273; gWeaponDescStatsRects[0].iTop = 12; gWeaponDescStatsRects[0].iRight = 331; gWeaponDescStatsRects[0].iBottom = 23; // First Column
- gWeaponDescStatsRects[1].iLeft = 273; gWeaponDescStatsRects[1].iTop = 24; gWeaponDescStatsRects[1].iRight = 331; gWeaponDescStatsRects[1].iBottom = 35;
- gWeaponDescStatsRects[2].iLeft = 273; gWeaponDescStatsRects[2].iTop = 36; gWeaponDescStatsRects[2].iRight = 331; gWeaponDescStatsRects[2].iBottom = 47;
- gWeaponDescStatsRects[3].iLeft = 273; gWeaponDescStatsRects[3].iTop = 48; gWeaponDescStatsRects[3].iRight = 331; gWeaponDescStatsRects[3].iBottom = 59;
- gWeaponDescStatsRects[4].iLeft = 273; gWeaponDescStatsRects[4].iTop = 60; gWeaponDescStatsRects[4].iRight = 331; gWeaponDescStatsRects[4].iBottom = 71;
- gWeaponDescStatsRects[5].iLeft = 273; gWeaponDescStatsRects[5].iTop = 72; gWeaponDescStatsRects[5].iRight = 331; gWeaponDescStatsRects[5].iBottom = 83;
- gWeaponDescStatsRects[6].iLeft = 273; gWeaponDescStatsRects[6].iTop = 84; gWeaponDescStatsRects[6].iRight = 331; gWeaponDescStatsRects[6].iBottom = 95;
- gWeaponDescStatsRects[7].iLeft = 340; gWeaponDescStatsRects[7].iTop = 24; gWeaponDescStatsRects[7].iRight = 398; gWeaponDescStatsRects[7].iBottom = 35; // Second Column
- gWeaponDescStatsRects[8].iLeft = 340; gWeaponDescStatsRects[8].iTop = 36; gWeaponDescStatsRects[8].iRight = 398; gWeaponDescStatsRects[8].iBottom = 47;
- gWeaponDescStatsRects[9].iLeft = 340; gWeaponDescStatsRects[9].iTop = 48; gWeaponDescStatsRects[9].iRight = 398; gWeaponDescStatsRects[9].iBottom = 59;
- gWeaponDescStatsRects[10].iLeft = 340; gWeaponDescStatsRects[10].iTop = 60; gWeaponDescStatsRects[10].iRight = 398; gWeaponDescStatsRects[10].iBottom = 71;
- gWeaponDescStatsRects[11].iLeft = 340; gWeaponDescStatsRects[11].iTop = 72; gWeaponDescStatsRects[11].iRight = 398; gWeaponDescStatsRects[11].iBottom = 83;
- gWeaponDescStatsRects[12].iLeft = 340; gWeaponDescStatsRects[12].iTop = 84; gWeaponDescStatsRects[12].iRight = 398; gWeaponDescStatsRects[12].iBottom = 95;
- gWeaponDescStatsRects[13].iLeft = 407; gWeaponDescStatsRects[13].iTop = 36; gWeaponDescStatsRects[13].iRight = 465; gWeaponDescStatsRects[13].iBottom = 47; // These are non-sequential!
- gWeaponDescStatsRects[14].iLeft = 407; gWeaponDescStatsRects[14].iTop = 48; gWeaponDescStatsRects[14].iRight = 465; gWeaponDescStatsRects[14].iBottom = 59;
- gWeaponDescStatsRects[15].iLeft = 407; gWeaponDescStatsRects[15].iTop = 60; gWeaponDescStatsRects[15].iRight = 465; gWeaponDescStatsRects[15].iBottom = 71;
- gWeaponDescStatsRects[16].iLeft = 407; gWeaponDescStatsRects[16].iTop = 72; gWeaponDescStatsRects[16].iRight = 465; gWeaponDescStatsRects[16].iBottom = 83;
- gWeaponDescStatsRects[17].iLeft = 407; gWeaponDescStatsRects[17].iTop = 12; gWeaponDescStatsRects[17].iRight = 465; gWeaponDescStatsRects[17].iBottom = 23;
- gWeaponDescStatsRects[18].iLeft = 407; gWeaponDescStatsRects[18].iTop = 24; gWeaponDescStatsRects[18].iRight = 465; gWeaponDescStatsRects[18].iBottom = 35;
- gWeaponDescStatsRects[19].iLeft = 407; gWeaponDescStatsRects[19].iTop = 84; gWeaponDescStatsRects[19].iRight = 465; gWeaponDescStatsRects[19].iBottom = 95;
+ ////////////////// MONEY TEXT COORDINATES
+ gMoneyStats[0].sX = 204 + gsInvDescX; gMoneyStats[0].sY = 14 + gsInvDescY; // Money
+ gMoneyStats[1].sX = 212 + gsInvDescX; gMoneyStats[1].sY = 24 + gsInvDescY; // Remaining
+ gMoneyStats[2].sX = 204 + gsInvDescX; gMoneyStats[2].sY = 41 + gsInvDescY; // Money
+ gMoneyStats[3].sX = 212 + gsInvDescX; gMoneyStats[3].sY = 51 + gsInvDescY; // Removing
+ gMoneyStats[4].sX = 282 + gsInvDescX; gMoneyStats[4].sY = 24 + gsInvDescY; // AMT remaining
+ gMoneyStats[5].sX = 282 + gsInvDescX; gMoneyStats[5].sY = 51 + gsInvDescY; // AMT removing
+ */
- gAmmoDescStatsRects[0].iLeft = 273; gAmmoDescStatsRects[0].iTop = 12; gAmmoDescStatsRects[0].iRight = 331; gAmmoDescStatsRects[0].iBottom = 23; // First Column
- gAmmoDescStatsRects[1].iLeft = 273; gAmmoDescStatsRects[1].iTop = 24; gAmmoDescStatsRects[1].iRight = 331; gAmmoDescStatsRects[1].iBottom = 35;
- gAmmoDescStatsRects[2].iLeft = 273; gAmmoDescStatsRects[2].iTop = 36; gAmmoDescStatsRects[2].iRight = 331; gAmmoDescStatsRects[2].iBottom = 47;
- gAmmoDescStatsRects[3].iLeft = 342; gAmmoDescStatsRects[3].iTop = 12; gAmmoDescStatsRects[3].iRight = 364; gAmmoDescStatsRects[3].iBottom = 35; // Second Column
- gAmmoDescStatsRects[4].iLeft = 369; gAmmoDescStatsRects[4].iTop = 12; gAmmoDescStatsRects[4].iRight = 391; gAmmoDescStatsRects[4].iBottom = 35;
- gAmmoDescStatsRects[5].iLeft = 342; gAmmoDescStatsRects[5].iTop = 36; gAmmoDescStatsRects[5].iRight = 364; gAmmoDescStatsRects[5].iBottom = 59;
- gAmmoDescStatsRects[6].iLeft = 369; gAmmoDescStatsRects[6].iTop = 36; gAmmoDescStatsRects[6].iRight = 391; gAmmoDescStatsRects[6].iBottom = 59;
- gAmmoDescStatsRects[7].iLeft = 342; gAmmoDescStatsRects[7].iTop = 60; gAmmoDescStatsRects[7].iRight = 364; gAmmoDescStatsRects[7].iBottom = 83;
- gAmmoDescStatsRects[8].iLeft = 407; gAmmoDescStatsRects[8].iTop = 12; gAmmoDescStatsRects[8].iRight = 465; gAmmoDescStatsRects[8].iBottom = 23; // Third Column
- gAmmoDescStatsRects[9].iLeft = 407; gAmmoDescStatsRects[9].iTop = 24; gAmmoDescStatsRects[9].iRight = 465; gAmmoDescStatsRects[9].iBottom = 35;
- gAmmoDescStatsRects[10].iLeft = 407; gAmmoDescStatsRects[10].iTop = 36; gAmmoDescStatsRects[10].iRight = 465; gAmmoDescStatsRects[10].iBottom = 47;
- gAmmoDescStatsRects[11].iLeft = 407; gAmmoDescStatsRects[11].iTop = 48; gAmmoDescStatsRects[11].iRight = 465; gAmmoDescStatsRects[11].iBottom = 59;
- gAmmoDescStatsRects[12].iLeft = 407; gAmmoDescStatsRects[12].iTop = 60; gAmmoDescStatsRects[12].iRight = 465; gAmmoDescStatsRects[12].iBottom = 71;
- gAmmoDescStatsRects[13].iLeft = 407; gAmmoDescStatsRects[13].iTop = 72; gAmmoDescStatsRects[13].iRight = 465; gAmmoDescStatsRects[13].iBottom = 83;
- gAmmoDescStatsRects[14].iLeft = 407; gAmmoDescStatsRects[14].iTop = 84; gAmmoDescStatsRects[14].iRight = 465; gAmmoDescStatsRects[14].iBottom = 95; // Placeholders
- gAmmoDescStatsRects[15].iLeft = 0; gAmmoDescStatsRects[15].iTop = 0; gAmmoDescStatsRects[15].iRight = 1; gAmmoDescStatsRects[15].iBottom = 1;
- gAmmoDescStatsRects[16].iLeft = 0; gAmmoDescStatsRects[16].iTop = 0; gAmmoDescStatsRects[16].iRight = 1; gAmmoDescStatsRects[16].iBottom = 1;
- gAmmoDescStatsRects[17].iLeft = 0; gAmmoDescStatsRects[17].iTop = 0; gAmmoDescStatsRects[17].iRight = 1; gAmmoDescStatsRects[17].iBottom = 1;
- gAmmoDescStatsRects[18].iLeft = 0; gAmmoDescStatsRects[18].iTop = 0; gAmmoDescStatsRects[18].iRight = 1; gAmmoDescStatsRects[18].iBottom = 1;
- gAmmoDescStatsRects[19].iLeft = 0; gAmmoDescStatsRects[19].iTop = 0; gAmmoDescStatsRects[19].iRight = 1; gAmmoDescStatsRects[19].iBottom = 1;
+ //////////////////////////////////////////////////////////////////////
+ // ODB has exactly four separate regions. Each has 8 sub-regions, which can be
+ // used to display data at irregular intervals. This allows ODB to function as
+ // smoothly as EDB does.
+ // In addition, ODB uses some of the UDB regions to display things like PROS/CONS
+ // and Description Text. This reduces the use of redundant arrays...
- gArmorDescStatsRects[0].iLeft = 273; gArmorDescStatsRects[0].iTop = 12; gArmorDescStatsRects[0].iRight = 331; gArmorDescStatsRects[0].iBottom = 23; // First Column
- gArmorDescStatsRects[1].iLeft = 273; gArmorDescStatsRects[1].iTop = 24; gArmorDescStatsRects[1].iRight = 331; gArmorDescStatsRects[1].iBottom = 35;
- gArmorDescStatsRects[2].iLeft = 273; gArmorDescStatsRects[2].iTop = 36; gArmorDescStatsRects[2].iRight = 331; gArmorDescStatsRects[2].iBottom = 47;
- gArmorDescStatsRects[3].iLeft = 340; gArmorDescStatsRects[3].iTop = 12; gArmorDescStatsRects[3].iRight = 398; gArmorDescStatsRects[3].iBottom = 23; // Second Column
- gArmorDescStatsRects[4].iLeft = 340; gArmorDescStatsRects[4].iTop = 24; gArmorDescStatsRects[4].iRight = 398; gArmorDescStatsRects[4].iBottom = 35;
- gArmorDescStatsRects[5].iLeft = 340; gArmorDescStatsRects[5].iTop = 36; gArmorDescStatsRects[5].iRight = 398; gArmorDescStatsRects[5].iBottom = 47;
- gArmorDescStatsRects[6].iLeft = 340; gArmorDescStatsRects[6].iTop = 48; gArmorDescStatsRects[6].iRight = 398; gArmorDescStatsRects[6].iBottom = 59;
- gArmorDescStatsRects[7].iLeft = 340; gArmorDescStatsRects[7].iTop = 50; gArmorDescStatsRects[7].iRight = 398; gArmorDescStatsRects[7].iBottom = 71;
- gArmorDescStatsRects[8].iLeft = 340; gArmorDescStatsRects[8].iTop = 62; gArmorDescStatsRects[8].iRight = 398; gArmorDescStatsRects[8].iBottom = 83;
- gArmorDescStatsRects[9].iLeft = 340; gArmorDescStatsRects[9].iTop = 74; gArmorDescStatsRects[9].iRight = 398; gArmorDescStatsRects[9].iBottom = 95;
- gArmorDescStatsRects[10].iLeft = 407; gArmorDescStatsRects[10].iTop = 12; gArmorDescStatsRects[10].iRight = 465; gArmorDescStatsRects[10].iBottom = 23; // Third Column
- gArmorDescStatsRects[11].iLeft = 407; gArmorDescStatsRects[11].iTop = 24; gArmorDescStatsRects[11].iRight = 465; gArmorDescStatsRects[11].iBottom = 35;
- gArmorDescStatsRects[12].iLeft = 407; gArmorDescStatsRects[12].iTop = 36; gArmorDescStatsRects[12].iRight = 465; gArmorDescStatsRects[12].iBottom = 47;
- gArmorDescStatsRects[13].iLeft = 407; gArmorDescStatsRects[13].iTop = 48; gArmorDescStatsRects[13].iRight = 465; gArmorDescStatsRects[13].iBottom = 59;
- gArmorDescStatsRects[14].iLeft = 407; gArmorDescStatsRects[14].iTop = 60; gArmorDescStatsRects[14].iRight = 465; gArmorDescStatsRects[14].iBottom = 71;
- gArmorDescStatsRects[15].iLeft = 407; gArmorDescStatsRects[15].iTop = 72; gArmorDescStatsRects[15].iRight = 465; gArmorDescStatsRects[15].iBottom = 83;
- gArmorDescStatsRects[16].iLeft = 407; gArmorDescStatsRects[16].iTop = 84; gArmorDescStatsRects[16].iRight = 465; gArmorDescStatsRects[16].iBottom = 95;
- gArmorDescStatsRects[17].iLeft = 0; gArmorDescStatsRects[17].iTop = 0; gArmorDescStatsRects[17].iRight = 1; gArmorDescStatsRects[17].iBottom = 1; // Placeholders
- gArmorDescStatsRects[18].iLeft = 0; gArmorDescStatsRects[18].iTop = 0; gArmorDescStatsRects[18].iRight = 1; gArmorDescStatsRects[18].iBottom = 1;
- gArmorDescStatsRects[19].iLeft = 0; gArmorDescStatsRects[19].iTop = 0; gArmorDescStatsRects[19].iRight = 1; gArmorDescStatsRects[19].iBottom = 1;
+ // First Data Row (Condition / Ammo label)
+ gODBItemDescRegions[0][0].sLeft = 270 + gsInvDescX; gODBItemDescRegions[0][0].sTop = 15 + gsInvDescY; gODBItemDescRegions[0][0].sRight = 418 + gsInvDescX; gODBItemDescRegions[0][0].sBottom = 23 + gsInvDescY;
- gExplosiveDescStatsRects[0].iLeft = 273; gExplosiveDescStatsRects[0].iTop = 12; gExplosiveDescStatsRects[0].iRight = 331; gExplosiveDescStatsRects[0].iBottom = 23; // First Column
- gExplosiveDescStatsRects[1].iLeft = 273; gExplosiveDescStatsRects[1].iTop = 24; gExplosiveDescStatsRects[1].iRight = 331; gExplosiveDescStatsRects[1].iBottom = 35;
- gExplosiveDescStatsRects[2].iLeft = 273; gExplosiveDescStatsRects[2].iTop = 36; gExplosiveDescStatsRects[2].iRight = 331; gExplosiveDescStatsRects[2].iBottom = 47;
- gExplosiveDescStatsRects[3].iLeft = 273; gExplosiveDescStatsRects[3].iTop = 48; gExplosiveDescStatsRects[3].iRight = 331; gExplosiveDescStatsRects[3].iBottom = 59;
- gExplosiveDescStatsRects[4].iLeft = 358; gExplosiveDescStatsRects[4].iTop = 12; gExplosiveDescStatsRects[4].iRight = 374; gExplosiveDescStatsRects[4].iBottom = 47; // Second Column
- gExplosiveDescStatsRects[5].iLeft = 342; gExplosiveDescStatsRects[5].iTop = 12; gExplosiveDescStatsRects[5].iRight = 358; gExplosiveDescStatsRects[5].iBottom = 47;
- gExplosiveDescStatsRects[6].iLeft = 376; gExplosiveDescStatsRects[6].iTop = 12; gExplosiveDescStatsRects[6].iRight = 395; gExplosiveDescStatsRects[6].iBottom = 47;
- gExplosiveDescStatsRects[7].iLeft = 341; gExplosiveDescStatsRects[7].iTop = 60; gExplosiveDescStatsRects[7].iRight = 465; gExplosiveDescStatsRects[7].iBottom = 71;
- gExplosiveDescStatsRects[8].iLeft = 0; gExplosiveDescStatsRects[8].iTop = 0; gExplosiveDescStatsRects[8].iRight = 1; gExplosiveDescStatsRects[8].iBottom = 1; // Placeholders
- gExplosiveDescStatsRects[9].iLeft = 0; gExplosiveDescStatsRects[9].iTop = 0; gExplosiveDescStatsRects[9].iRight = 1; gExplosiveDescStatsRects[9].iBottom = 1;
- gExplosiveDescStatsRects[10].iLeft = 0; gExplosiveDescStatsRects[10].iTop = 0; gExplosiveDescStatsRects[10].iRight = 1; gExplosiveDescStatsRects[10].iBottom = 1;
- gExplosiveDescStatsRects[11].iLeft = 0; gExplosiveDescStatsRects[11].iTop = 0; gExplosiveDescStatsRects[11].iRight = 1; gExplosiveDescStatsRects[11].iBottom = 1;
- gExplosiveDescStatsRects[12].iLeft = 0; gExplosiveDescStatsRects[12].iTop = 0; gExplosiveDescStatsRects[12].iRight = 1; gExplosiveDescStatsRects[12].iBottom = 1;
- gExplosiveDescStatsRects[13].iLeft = 0; gExplosiveDescStatsRects[13].iTop = 0; gExplosiveDescStatsRects[13].iRight = 1; gExplosiveDescStatsRects[13].iBottom = 1;
- gExplosiveDescStatsRects[14].iLeft = 0; gExplosiveDescStatsRects[14].iTop = 0; gExplosiveDescStatsRects[14].iRight = 1; gExplosiveDescStatsRects[14].iBottom = 1;
- gExplosiveDescStatsRects[15].iLeft = 0; gExplosiveDescStatsRects[15].iTop = 0; gExplosiveDescStatsRects[15].iRight = 1; gExplosiveDescStatsRects[15].iBottom = 1;
- gExplosiveDescStatsRects[16].iLeft = 0; gExplosiveDescStatsRects[16].iTop = 0; gExplosiveDescStatsRects[16].iRight = 1; gExplosiveDescStatsRects[16].iBottom = 1;
- gExplosiveDescStatsRects[17].iLeft = 0; gExplosiveDescStatsRects[17].iTop = 0; gExplosiveDescStatsRects[17].iRight = 1; gExplosiveDescStatsRects[17].iBottom = 1;
- gExplosiveDescStatsRects[18].iLeft = 0; gExplosiveDescStatsRects[18].iTop = 0; gExplosiveDescStatsRects[18].iRight = 1; gExplosiveDescStatsRects[18].iBottom = 1;
- gExplosiveDescStatsRects[19].iLeft = 0; gExplosiveDescStatsRects[19].iTop = 0; gExplosiveDescStatsRects[19].iRight = 1; gExplosiveDescStatsRects[19].iBottom = 1;
+ // Second Data Row (Weight)
+ gODBItemDescRegions[1][0].sLeft = 270 + gsInvDescX; gODBItemDescRegions[1][0].sTop = 25 + gsInvDescY; gODBItemDescRegions[1][0].sRight = 418 + gsInvDescX; gODBItemDescRegions[1][0].sBottom = 33 + gsInvDescY;
- gMiscItemDescStatsRects[0].iLeft = 273; gMiscItemDescStatsRects[0].iTop = 12; gMiscItemDescStatsRects[0].iRight = 370; gMiscItemDescStatsRects[0].iBottom = 23; // Column 1
- gMiscItemDescStatsRects[1].iLeft = 273; gMiscItemDescStatsRects[1].iTop = 24; gMiscItemDescStatsRects[1].iRight = 370; gMiscItemDescStatsRects[1].iBottom = 35;
- gMiscItemDescStatsRects[2].iLeft = 273; gMiscItemDescStatsRects[2].iTop = 36; gMiscItemDescStatsRects[2].iRight = 370; gMiscItemDescStatsRects[2].iBottom = 47;
- gMiscItemDescStatsRects[3].iLeft = 273; gMiscItemDescStatsRects[3].iTop = 48; gMiscItemDescStatsRects[3].iRight = 370; gMiscItemDescStatsRects[3].iBottom = 59;
- gMiscItemDescStatsRects[4].iLeft = 273; gMiscItemDescStatsRects[4].iTop = 60; gMiscItemDescStatsRects[4].iRight = 370; gMiscItemDescStatsRects[4].iBottom = 71;
- gMiscItemDescStatsRects[5].iLeft = 273; gMiscItemDescStatsRects[5].iTop = 72; gMiscItemDescStatsRects[5].iRight = 370; gMiscItemDescStatsRects[5].iBottom = 83;
- gMiscItemDescStatsRects[6].iLeft = 273; gMiscItemDescStatsRects[6].iTop = 84; gMiscItemDescStatsRects[6].iRight = 370; gMiscItemDescStatsRects[6].iBottom = 95;
- gMiscItemDescStatsRects[7].iLeft = 374; gMiscItemDescStatsRects[7].iTop = 12; gMiscItemDescStatsRects[7].iRight = 471; gMiscItemDescStatsRects[7].iBottom = 23; // Column Two
- gMiscItemDescStatsRects[8].iLeft = 374; gMiscItemDescStatsRects[8].iTop = 24; gMiscItemDescStatsRects[8].iRight = 471; gMiscItemDescStatsRects[8].iBottom = 35;
- gMiscItemDescStatsRects[9].iLeft = 374; gMiscItemDescStatsRects[9].iTop = 36; gMiscItemDescStatsRects[9].iRight = 471; gMiscItemDescStatsRects[9].iBottom = 47;
- gMiscItemDescStatsRects[10].iLeft = 374; gMiscItemDescStatsRects[10].iTop = 48; gMiscItemDescStatsRects[10].iRight = 471; gMiscItemDescStatsRects[10].iBottom = 59;
- gMiscItemDescStatsRects[11].iLeft = 374; gMiscItemDescStatsRects[11].iTop = 60; gMiscItemDescStatsRects[11].iRight = 471; gMiscItemDescStatsRects[11].iBottom = 71;
- gMiscItemDescStatsRects[12].iLeft = 0; gMiscItemDescStatsRects[12].iTop = 0; gMiscItemDescStatsRects[12].iRight = 1; gMiscItemDescStatsRects[12].iBottom = 1; // Placeholders
- gMiscItemDescStatsRects[13].iLeft = 0; gMiscItemDescStatsRects[13].iTop = 0; gMiscItemDescStatsRects[13].iRight = 1; gMiscItemDescStatsRects[13].iBottom = 1;
- gMiscItemDescStatsRects[14].iLeft = 0; gMiscItemDescStatsRects[14].iTop = 0; gMiscItemDescStatsRects[14].iRight = 1; gMiscItemDescStatsRects[14].iBottom = 1;
- gMiscItemDescStatsRects[15].iLeft = 0; gMiscItemDescStatsRects[15].iTop = 0; gMiscItemDescStatsRects[15].iRight = 1; gMiscItemDescStatsRects[15].iBottom = 1;
- gMiscItemDescStatsRects[16].iLeft = 0; gMiscItemDescStatsRects[16].iTop = 0; gMiscItemDescStatsRects[16].iRight = 1; gMiscItemDescStatsRects[16].iBottom = 1;
- gMiscItemDescStatsRects[17].iLeft = 0; gMiscItemDescStatsRects[17].iTop = 0; gMiscItemDescStatsRects[17].iRight = 1; gMiscItemDescStatsRects[17].iBottom = 1;
- gMiscItemDescStatsRects[18].iLeft = 0; gMiscItemDescStatsRects[18].iTop = 0; gMiscItemDescStatsRects[18].iRight = 1; gMiscItemDescStatsRects[18].iBottom = 1;
- gMiscItemDescStatsRects[19].iLeft = 0; gMiscItemDescStatsRects[19].iTop = 0; gMiscItemDescStatsRects[19].iRight = 1; gMiscItemDescStatsRects[19].iBottom = 1;
+ // Third Data Row (Usually basic Gun Statistics)
+ // Left Side
+ gODBItemDescRegions[2][0].sLeft = 270 + gsInvDescX; gODBItemDescRegions[2][0].sTop = 40 + gsInvDescY;
+ gODBItemDescRegions[2][3].sLeft = 209 + gsInvDescX; gODBItemDescRegions[2][3].sTop = 40 + gsInvDescY; gODBItemDescRegions[2][3].sRight = 334 + gsInvDescX; gODBItemDescRegions[2][3].sBottom = 48 + gsInvDescY;
+
+ // Right Side
+ gODBItemDescRegions[2][4].sLeft = 346 + gsInvDescX; gODBItemDescRegions[2][4].sTop = 40 + gsInvDescY;
+ gODBItemDescRegions[2][7].sLeft = 383 + gsInvDescX; gODBItemDescRegions[2][7].sTop = 40 + gsInvDescY; gODBItemDescRegions[2][7].sRight = 418 + gsInvDescX; gODBItemDescRegions[2][7].sBottom = 48 + gsInvDescY;
+
+ // Fourth Data Row (Usually AP Costs)
+ // Left Side
+ gODBItemDescRegions[3][0].sLeft = 270 + gsInvDescX; gODBItemDescRegions[3][0].sTop = 50 + gsInvDescY;
+ gODBItemDescRegions[3][1].sLeft = 290 + gsInvDescX; gODBItemDescRegions[3][1].sTop = 49 + gsInvDescY;
+ gODBItemDescRegions[3][2].sLeft = 302 + gsInvDescX; gODBItemDescRegions[3][2].sTop = 50 + gsInvDescY;
+ gODBItemDescRegions[3][3].sLeft = 309 + gsInvDescX; gODBItemDescRegions[3][3].sTop = 50 + gsInvDescY; gODBItemDescRegions[3][3].sRight = 334 + gsInvDescX; gODBItemDescRegions[3][3].sBottom = 58 + gsInvDescY;
+ // Right Side
+ gODBItemDescRegions[3][4].sLeft = 344 + gsInvDescX; gODBItemDescRegions[3][4].sTop = 49 + gsInvDescY;
+ gODBItemDescRegions[3][6].sLeft = 372 + gsInvDescX; gODBItemDescRegions[3][6].sTop = 50 + gsInvDescY;
+ gODBItemDescRegions[3][7].sLeft = 383 + gsInvDescX; gODBItemDescRegions[3][7].sTop = 50 + gsInvDescY; gODBItemDescRegions[3][7].sRight = 418 + gsInvDescX; gODBItemDescRegions[3][7].sBottom = 58 + gsInvDescY;
+
+ // Description Text Area
+ gItemDescTextRegions[0].sLeft = 265 + gsInvDescX; gItemDescTextRegions[0].sTop = 70 + gsInvDescY; gItemDescTextRegions[0].sRight = 415 + gsInvDescX;
+
+ // PROS/CONS areas
+ gItemDescTextRegions[3].sLeft = 265 + gsInvDescX; gItemDescTextRegions[3].sTop = 170 + gsInvDescY; gItemDescTextRegions[3].sRight = 415 + gsInvDescX; gItemDescTextRegions[3].sBottom = 188 + gsInvDescY;
+ gItemDescTextRegions[4].sLeft = 295 + gsInvDescX; gItemDescTextRegions[4].sTop = 170 + gsInvDescY; gItemDescTextRegions[4].sRight = 415 + gsInvDescX; gItemDescTextRegions[4].sBottom = 188 + gsInvDescY;
+ gItemDescTextRegions[5].sLeft = 265 + gsInvDescX; gItemDescTextRegions[5].sTop = 180 + gsInvDescY; gItemDescTextRegions[5].sRight = 415 + gsInvDescX; gItemDescTextRegions[5].sBottom = 200 + gsInvDescY;
+ gItemDescTextRegions[6].sLeft = 295 + gsInvDescX; gItemDescTextRegions[6].sTop = 180 + gsInvDescY; gItemDescTextRegions[6].sRight = 415 + gsInvDescX; gItemDescTextRegions[6].sBottom = 200 + gsInvDescY;
+ }
+ else
+ {
+ gItemDescLBEBackground[0].sLeft = 320 + gsInvDescX; gItemDescLBEBackground[0].sTop = 8 + gsInvDescY;
+ gItemDescLBEBackground[1].sLeft = 3 + gsInvDescX; gItemDescLBEBackground[1].sTop = 137 + gsInvDescY;
+ gItemDescLBEBackground[2].sLeft = 320 + gsInvDescX; gItemDescLBEBackground[2].sTop = 8 + gsInvDescY;
+ gItemDescLBEBackground[3].sLeft = 320 + gsInvDescX; gItemDescLBEBackground[3].sTop = 8 + gsInvDescY;
+
+ ////////////////// MONEY TEXT COORDINATES
+ gMoneyStats[0].sX = 204 + gsInvDescX; gMoneyStats[0].sY = 14 + gsInvDescY; // Money
+ gMoneyStats[1].sX = 212 + gsInvDescX; gMoneyStats[1].sY = 24 + gsInvDescY; // Remaining
+ gMoneyStats[2].sX = 204 + gsInvDescX; gMoneyStats[2].sY = 41 + gsInvDescY; // Money
+ gMoneyStats[3].sX = 212 + gsInvDescX; gMoneyStats[3].sY = 51 + gsInvDescY; // Removing
+ gMoneyStats[4].sX = 282 + gsInvDescX; gMoneyStats[4].sY = 24 + gsInvDescY; // AMT remaining
+ gMoneyStats[5].sX = 282 + gsInvDescX; gMoneyStats[5].sY = 51 + gsInvDescY; // AMT removing
+
+ //////////////////////////////////////////////////////////////////////
+ // ODB has exactly four separate regions. Each has 8 sub-regions, which can be
+ // used to display data at irregular intervals. This allows ODB to function as
+ // smoothly as EDB does.
+ // In addition, ODB uses some of the UDB regions to display things like PROS/CONS
+ // and Description Text. This reduces the use of redundant arrays...
+
+ // First Data Row (Condition / Ammo label)
+ gODBItemDescRegions[0][0].sLeft = 202 + gsInvDescX; gODBItemDescRegions[0][0].sTop = 15 + gsInvDescY; gODBItemDescRegions[0][0].sRight = 311 + gsInvDescX; gODBItemDescRegions[0][0].sBottom = 23 + gsInvDescY;
+
+ // Second Data Row (Weight)
+ gODBItemDescRegions[1][0].sLeft = 202 + gsInvDescX; gODBItemDescRegions[1][0].sTop = 25 + gsInvDescY; gODBItemDescRegions[1][0].sRight = 311 + gsInvDescX; gODBItemDescRegions[1][0].sBottom = 33 + gsInvDescY;
+
+ // Third Data Row (Usually basic Gun Statistics)
+ // Left Side
+ gODBItemDescRegions[2][0].sLeft = 202 + gsInvDescX; gODBItemDescRegions[2][0].sTop = 40 + gsInvDescY;
+ gODBItemDescRegions[2][3].sLeft = 141 + gsInvDescX; gODBItemDescRegions[2][3].sTop = 40 + gsInvDescY; gODBItemDescRegions[2][3].sRight = 260 + gsInvDescX; gODBItemDescRegions[2][3].sBottom = 48 + gsInvDescY;
+
+ // Right Side
+ gODBItemDescRegions[2][4].sLeft = 265 + gsInvDescX; gODBItemDescRegions[2][4].sTop = 40 + gsInvDescY;
+ gODBItemDescRegions[2][7].sLeft = 302 + gsInvDescX; gODBItemDescRegions[2][7].sTop = 40 + gsInvDescY; gODBItemDescRegions[2][7].sRight = 311 + gsInvDescX; gODBItemDescRegions[2][7].sBottom = 48 + gsInvDescY;
+
+ // Fourth Data Row (Usually AP Costs)
+ // Left Side
+ gODBItemDescRegions[3][0].sLeft = 202 + gsInvDescX; gODBItemDescRegions[3][0].sTop = 50 + gsInvDescY;
+ gODBItemDescRegions[3][1].sLeft = 222 + gsInvDescX; gODBItemDescRegions[3][1].sTop = 49 + gsInvDescY;
+ gODBItemDescRegions[3][2].sLeft = 234 + gsInvDescX; gODBItemDescRegions[3][2].sTop = 50 + gsInvDescY;
+ gODBItemDescRegions[3][3].sLeft = 241 + gsInvDescX; gODBItemDescRegions[3][3].sTop = 50 + gsInvDescY; gODBItemDescRegions[3][3].sRight = 260 + gsInvDescX; gODBItemDescRegions[3][3].sBottom = 58 + gsInvDescY;
+ // Right Side
+ gODBItemDescRegions[3][4].sLeft = 263 + gsInvDescX; gODBItemDescRegions[3][4].sTop = 49 + gsInvDescY;
+ gODBItemDescRegions[3][6].sLeft = 291 + gsInvDescX; gODBItemDescRegions[3][6].sTop = 50 + gsInvDescY;
+ gODBItemDescRegions[3][7].sLeft = 302 + gsInvDescX; gODBItemDescRegions[3][7].sTop = 50 + gsInvDescY; gODBItemDescRegions[3][7].sRight = 311 + gsInvDescX; gODBItemDescRegions[3][7].sBottom = 58 + gsInvDescY;
+
+ // Description Text Area
+ gItemDescTextRegions[0].sLeft = 11 + gsInvDescX; gItemDescTextRegions[0].sTop = 80 + gsInvDescY; gItemDescTextRegions[0].sRight = 300 + gsInvDescX;
+
+ // PROS/CONS areas
+ gItemDescTextRegions[3].sLeft = 11 + gsInvDescX; gItemDescTextRegions[3].sTop = 110 + gsInvDescY; gItemDescTextRegions[3].sRight = 300 + gsInvDescX; gItemDescTextRegions[3].sBottom = 118 + gsInvDescY;
+ gItemDescTextRegions[4].sLeft = 47 + gsInvDescX; gItemDescTextRegions[4].sTop = 110 + gsInvDescY; gItemDescTextRegions[4].sRight = 300 + gsInvDescX; gItemDescTextRegions[4].sBottom = 118 + gsInvDescY;
+ gItemDescTextRegions[5].sLeft = 11 + gsInvDescX; gItemDescTextRegions[5].sTop = 120 + gsInvDescY; gItemDescTextRegions[5].sRight = 300 + gsInvDescX; gItemDescTextRegions[5].sBottom = 130 + gsInvDescY;
+ gItemDescTextRegions[6].sLeft = 47 + gsInvDescX; gItemDescTextRegions[6].sTop = 120 + gsInvDescY; gItemDescTextRegions[6].sRight = 300 + gsInvDescX; gItemDescTextRegions[6].sBottom = 130 + gsInvDescY;
+ }
}
+
}
}
@@ -748,339 +704,57 @@ void SetupItemDescAttachmentsXY(UINT8 ID, INT16 sX, INT16 sY, INT16 sHeight, INT
gItemDescAttachmentsXY[ID].sBarDy = sBarDy;
}
-void InitDescStatCoords()
-{
+void InitDescStatCoords(OBJECTTYPE *pObject)
+{
+ std::vector usAttachmentSlotIndexVector = GetItemSlots(pObject);
+ memset(gItemDescAttachmentsXY, 0, MAX_ATTACHMENTS);
if( guiCurrentScreen == MAP_SCREEN )
- {
- SetupItemDescAttachmentsXY(0, 175, 9, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
- SetupItemDescAttachmentsXY(1, 213, 9, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
- SetupItemDescAttachmentsXY(2, 175, 37, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
- SetupItemDescAttachmentsXY(3, 213, 37, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ {
+ //WarmSteel - If we're using the new attachment system and the item in question does not have an empty attachment list.
+ if(UsingNewAttachmentSystem()==true && !usAttachmentSlotIndexVector.empty() && UseNASDesc(pObject))
+ {
+ //Loop throught the attachments and get their slot id's
+ for (UINT8 x = 0; x < usAttachmentSlotIndexVector.size(); x++){
+ //WarmSteel - Tell this slot where it's supposed to be.
+ if(AttachmentSlots[usAttachmentSlotIndexVector[x]].fBigSlot){
+ SetupItemDescAttachmentsXY(x, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosX, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosY, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_BIG_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ } else {
+ SetupItemDescAttachmentsXY(x, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosX, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosY, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ }
+ }
+ }
+ //Not a valid item for NAS, use default
+ else
+ {
+ SetupItemDescAttachmentsXY(0, 175, 9, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ SetupItemDescAttachmentsXY(1, 213, 9, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ SetupItemDescAttachmentsXY(2, 175, 37, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ SetupItemDescAttachmentsXY(3, 213, 37, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ }
+
}
else
{
- SetupItemDescAttachmentsXY(0, 133, 11, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
- SetupItemDescAttachmentsXY(1, 167, 11, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
- SetupItemDescAttachmentsXY(2, 133, 38, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
- SetupItemDescAttachmentsXY(3, 167, 38, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
- }
-
- if(UsingEDBSystem() > 0)
- {
- if( guiCurrentScreen == MAP_SCREEN )
+ //WarmSteel - If we're using the new attachment system and the item in question does not have an empty attachment list.
+ if(UsingNewAttachmentSystem()==true && !usAttachmentSlotIndexVector.empty() && UseNASDesc(pObject))
{
- gWeaponStats[0].sX = 52; gWeaponStats[0].sY = 98; gWeaponStats[0].sValDx = 76; // 0) STATUS
- gWeaponStats[1].sX = 52; gWeaponStats[1].sY = 108; gWeaponStats[1].sValDx = 76; // 1) WEIGHT
- // Labels and Values
- gWeaponStats[2].sX = 47; gWeaponStats[2].sY = 124; gWeaponStats[2].sValDx = 30; // 2) COL 1; ROW 1
- gWeaponStats[3].sX = 47; gWeaponStats[3].sY = 136; gWeaponStats[3].sValDx = 30; // 3) COL 1; ROW 2
- gWeaponStats[4].sX = 47; gWeaponStats[4].sY = 148; gWeaponStats[4].sValDx = 30; // 4) COL 1; ROW 3
- gWeaponStats[5].sX = 47; gWeaponStats[5].sY = 160; gWeaponStats[5].sValDx = 30; // 5) COL 1; ROW 4
- gWeaponStats[6].sX = 47; gWeaponStats[6].sY = 172; gWeaponStats[6].sValDx = 30; // 6) COL 1; ROW 5
- gWeaponStats[7].sX = 47; gWeaponStats[7].sY = 184; gWeaponStats[7].sValDx = 30; // 7) COL 1; ROW 6
- gWeaponStats[8].sX = 47; gWeaponStats[8].sY = 196; gWeaponStats[8].sValDx = 30; // 8) COL 1; ROW 7
- gWeaponStats[9].sX = 112; gWeaponStats[9].sY = 124; gWeaponStats[9].sValDx = 29; // 9) COL 2; ROW 1
- gWeaponStats[10].sX = 112; gWeaponStats[10].sY = 136; gWeaponStats[10].sValDx = 29; // 10) COL 2; ROW 2
- gWeaponStats[11].sX = 112; gWeaponStats[11].sY = 148; gWeaponStats[11].sValDx = 29; // 11) COL 2; ROW 3
- gWeaponStats[12].sX = 112; gWeaponStats[12].sY = 160; gWeaponStats[12].sValDx = 29; // 12) COL 2; ROW 4
- gWeaponStats[13].sX = 112; gWeaponStats[13].sY = 172; gWeaponStats[13].sValDx = 29; // 13) COL 2; ROW 5
- gWeaponStats[14].sX = 112; gWeaponStats[14].sY = 184; gWeaponStats[14].sValDx = 29; // 14) COL 2; ROW 6
- gWeaponStats[15].sX = 112; gWeaponStats[15].sY = 196; gWeaponStats[15].sValDx = 29; // 15) COL 2; ROW 7
- gWeaponStats[16].sX = 174; gWeaponStats[16].sY = 124; gWeaponStats[16].sValDx = 30; // 16) COL 3; ROW 1
- gWeaponStats[17].sX = 174; gWeaponStats[17].sY = 136; gWeaponStats[17].sValDx = 30; // 17) COL 3; ROW 2
- gWeaponStats[18].sX = 174; gWeaponStats[18].sY = 148; gWeaponStats[18].sValDx = 30; // 18) COL 3; ROW 3
- gWeaponStats[19].sX = 174; gWeaponStats[19].sY = 160; gWeaponStats[19].sValDx = 30; // 19) COL 3; ROW 4
- gWeaponStats[20].sX = 174; gWeaponStats[20].sY = 172; gWeaponStats[20].sValDx = 30; // 20) COL 3; ROW 5
- gWeaponStats[21].sX = 174; gWeaponStats[21].sY = 184; gWeaponStats[21].sValDx = 30; // 21) COL 3; ROW 6
- gWeaponStats[22].sX = 174; gWeaponStats[22].sY = 196; gWeaponStats[22].sValDx = 30; // 22) COL 3; ROW 7
- // EQUALS signs
- gWeaponStats[23].sX = 79; gWeaponStats[23].sY = 124; gWeaponStats[23].sValDx = 0; // 23) COL 1; ROW 1
- gWeaponStats[24].sX = 79; gWeaponStats[24].sY = 136; gWeaponStats[24].sValDx = 0; // 24) COL 1; ROW 2
- gWeaponStats[25].sX = 79; gWeaponStats[25].sY = 148; gWeaponStats[25].sValDx = 0; // 25) COL 1; ROW 3
- gWeaponStats[26].sX = 79; gWeaponStats[26].sY = 160; gWeaponStats[26].sValDx = 0; // 26) COL 1; ROW 4
- gWeaponStats[27].sX = 79; gWeaponStats[27].sY = 172; gWeaponStats[27].sValDx = 0; // 27) COL 1; ROW 5
- gWeaponStats[28].sX = 79; gWeaponStats[28].sY = 184; gWeaponStats[28].sValDx = 0; // 28) COL 1; ROW 6
- gWeaponStats[29].sX = 79; gWeaponStats[29].sY = 196; gWeaponStats[29].sValDx = 0; // 29) COL 1; ROW 7
- gWeaponStats[30].sX = 145; gWeaponStats[30].sY = 124; gWeaponStats[30].sValDx = 0; // 30) COL 2; ROW 1
- gWeaponStats[31].sX = 145; gWeaponStats[31].sY = 136; gWeaponStats[31].sValDx = 0; // 31) COL 2; ROW 2
- gWeaponStats[32].sX = 145; gWeaponStats[32].sY = 148; gWeaponStats[32].sValDx = 0; // 32) COL 2; ROW 3
- gWeaponStats[33].sX = 145; gWeaponStats[33].sY = 160; gWeaponStats[33].sValDx = 0; // 33) COL 2; ROW 4
- gWeaponStats[34].sX = 145; gWeaponStats[34].sY = 172; gWeaponStats[34].sValDx = 0; // 34) COL 2; ROW 5
- gWeaponStats[35].sX = 145; gWeaponStats[35].sY = 184; gWeaponStats[35].sValDx = 0; // 35) COL 2; ROW 6
- gWeaponStats[36].sX = 145; gWeaponStats[36].sY = 196; gWeaponStats[36].sValDx = 0; // 36) COL 2; ROW 7
- gWeaponStats[37].sX = 206; gWeaponStats[37].sY = 124; gWeaponStats[37].sValDx = 0; // 37) COL 3; ROW 1
- gWeaponStats[38].sX = 206; gWeaponStats[38].sY = 136; gWeaponStats[38].sValDx = 0; // 38) COL 3; ROW 2
- gWeaponStats[39].sX = 206; gWeaponStats[39].sY = 148; gWeaponStats[39].sValDx = 0; // 39) COL 3; ROW 3
- gWeaponStats[40].sX = 206; gWeaponStats[40].sY = 160; gWeaponStats[40].sValDx = 0; // 40) COL 3; ROW 4
- gWeaponStats[41].sX = 206; gWeaponStats[41].sY = 172; gWeaponStats[41].sValDx = 0; // 41) COL 3; ROW 5
- gWeaponStats[42].sX = 206; gWeaponStats[42].sY = 184; gWeaponStats[42].sValDx = 0; // 42) COL 3; ROW 6
- gWeaponStats[43].sX = 206; gWeaponStats[43].sY = 196; gWeaponStats[43].sValDx = 0; // 43) COL 3; ROW 7
- // Nonregular locations for explosive data (COL 2; ROW 3)
- gWeaponStats[44].sX = 116; gWeaponStats[44].sY = 148; gWeaponStats[44].sValDx = 0; // 44) COL 2; ROW 3; LOC 1
- gWeaponStats[45].sX = 134; gWeaponStats[45].sY = 148; gWeaponStats[45].sValDx = 0; // 45) COL 2; ROW 3; LOC 2
- gWeaponStats[46].sX = 150; gWeaponStats[46].sY = 148; gWeaponStats[46].sValDx = 0; // 46) COL 2; ROW 3; LOC 3
-
- gMoneyStats[0].sX = 51; gMoneyStats[0].sY = 124; gMoneyStats[0].sValDx = 45; // Money
- gMoneyStats[1].sX = 61; gMoneyStats[1].sY = 136; gMoneyStats[1].sValDx = 65; // Remaining
- gMoneyStats[2].sX = 51; gMoneyStats[2].sY = 172; gMoneyStats[2].sValDx = 45; // Money
- gMoneyStats[3].sX = 61; gMoneyStats[3].sY = 184; gMoneyStats[3].sValDx = 65; // Removing
- gMoneyStats[4].sX = 47; gMoneyStats[4].sY = 148; gMoneyStats[4].sValDx = 62; // AMT remaining
- gMoneyStats[5].sX = 47; gMoneyStats[5].sY = 196; gMoneyStats[5].sValDx = 62; // AMT removing
-
- gItemDescProsConsRects[0].iLeft = 14; gItemDescProsConsRects[0].iTop = 291; gItemDescProsConsRects[0].iRight = 250; gItemDescProsConsRects[0].iBottom = 298;
- gItemDescProsConsRects[1].iLeft = 14; gItemDescProsConsRects[1].iTop = 299; gItemDescProsConsRects[1].iRight = 250; gItemDescProsConsRects[1].iBottom = 306;
- }
- else
- {
- if (UsingEDBSystem() == 1) // NIV EDB
- {
- gWeaponStats[0].sX = 205; gWeaponStats[0].sY = 14; gWeaponStats[0].sValDx = 91; // 0) STATUS
- gWeaponStats[1].sX = 205; gWeaponStats[1].sY = 24; gWeaponStats[1].sValDx = 91; // 1) WEIGHT
- // Labels and Values
- gWeaponStats[2].sX = 203; gWeaponStats[2].sY = 44; gWeaponStats[2].sValDx = 30; // 2) COL 1; ROW 1
- gWeaponStats[3].sX = 203; gWeaponStats[3].sY = 56; gWeaponStats[3].sValDx = 30; // 3) COL 1; ROW 2
- gWeaponStats[4].sX = 203; gWeaponStats[4].sY = 68; gWeaponStats[4].sValDx = 30; // 4) COL 1; ROW 3
- gWeaponStats[5].sX = 203; gWeaponStats[5].sY = 80; gWeaponStats[5].sValDx = 30; // 5) COL 1; ROW 4
- gWeaponStats[6].sX = 203; gWeaponStats[6].sY = 92; gWeaponStats[6].sValDx = 30; // 6) COL 1; ROW 5
- gWeaponStats[7].sX = 203; gWeaponStats[7].sY = 104; gWeaponStats[7].sValDx = 30; // 7) COL 1; ROW 6
- gWeaponStats[8].sX = 203; gWeaponStats[8].sY = 116; gWeaponStats[8].sValDx = 30; // 8) COL 1; ROW 7
- gWeaponStats[9].sX = 268; gWeaponStats[9].sY = 44; gWeaponStats[9].sValDx = 30; // 9) COL 2; ROW 1
- gWeaponStats[10].sX = 268; gWeaponStats[10].sY = 56; gWeaponStats[10].sValDx = 30; // 10) COL 2; ROW 2
- gWeaponStats[11].sX = 268; gWeaponStats[11].sY = 68; gWeaponStats[11].sValDx = 30; // 11) COL 2; ROW 3
- gWeaponStats[12].sX = 268; gWeaponStats[12].sY = 80; gWeaponStats[12].sValDx = 30; // 12) COL 2; ROW 4
- gWeaponStats[13].sX = 268; gWeaponStats[13].sY = 92; gWeaponStats[13].sValDx = 30; // 13) COL 2; ROW 5
- gWeaponStats[14].sX = 268; gWeaponStats[14].sY = 104; gWeaponStats[14].sValDx = 30; // 14) COL 2; ROW 6
- gWeaponStats[15].sX = 268; gWeaponStats[15].sY = 116; gWeaponStats[15].sValDx = 30; // 15) COL 2; ROW 7
- gWeaponStats[16].sX = 203; gWeaponStats[16].sY = 136; gWeaponStats[16].sValDx = 30; // 16) COL 3; ROW 1
- gWeaponStats[17].sX = 203; gWeaponStats[17].sY = 160; gWeaponStats[17].sValDx = 30; // 17) COL 3; ROW 3
- gWeaponStats[18].sX = 268; gWeaponStats[18].sY = 136; gWeaponStats[18].sValDx = 30; // 18) COL 4; ROW 1
- gWeaponStats[19].sX = 268; gWeaponStats[19].sY = 148; gWeaponStats[19].sValDx = 30; // 19) COL 4; ROW 2
- gWeaponStats[20].sX = 268; gWeaponStats[20].sY = 160; gWeaponStats[20].sValDx = 30; // 20) COL 4; ROW 3
- gWeaponStats[21].sX = 268; gWeaponStats[21].sY = 172; gWeaponStats[21].sValDx = 30; // 21) COL 4; ROW 4
- gWeaponStats[22].sX = 203; gWeaponStats[22].sY = 172; gWeaponStats[22].sValDx = 30; // 22) COL 3; ROW 4
- // EQUALS signs
- gWeaponStats[23].sX = 235; gWeaponStats[23].sY = 44; gWeaponStats[23].sValDx = 0; // 23) COL 1; ROW 1
- gWeaponStats[24].sX = 235; gWeaponStats[24].sY = 56; gWeaponStats[24].sValDx = 0; // 24) COL 1; ROW 2
- gWeaponStats[25].sX = 235; gWeaponStats[25].sY = 68; gWeaponStats[25].sValDx = 0; // 25) COL 1; ROW 3
- gWeaponStats[26].sX = 235; gWeaponStats[26].sY = 80; gWeaponStats[26].sValDx = 0; // 26) COL 1; ROW 4
- gWeaponStats[27].sX = 235; gWeaponStats[27].sY = 92; gWeaponStats[27].sValDx = 0; // 27) COL 1; ROW 5
- gWeaponStats[28].sX = 235; gWeaponStats[28].sY = 104; gWeaponStats[28].sValDx = 0; // 28) COL 1; ROW 6
- gWeaponStats[29].sX = 235; gWeaponStats[29].sY = 116; gWeaponStats[29].sValDx = 0; // 29) COL 1; ROW 7
- gWeaponStats[30].sX = 300; gWeaponStats[30].sY = 44; gWeaponStats[30].sValDx = 0; // 30) COL 2; ROW 1
- gWeaponStats[31].sX = 300; gWeaponStats[31].sY = 56; gWeaponStats[31].sValDx = 0; // 31) COL 2; ROW 2
- gWeaponStats[32].sX = 300; gWeaponStats[32].sY = 68; gWeaponStats[32].sValDx = 0; // 32) COL 2; ROW 3
- gWeaponStats[33].sX = 300; gWeaponStats[33].sY = 80; gWeaponStats[33].sValDx = 0; // 33) COL 2; ROW 4
- gWeaponStats[34].sX = 300; gWeaponStats[34].sY = 92; gWeaponStats[34].sValDx = 0; // 34) COL 2; ROW 5
- gWeaponStats[35].sX = 300; gWeaponStats[35].sY = 104; gWeaponStats[35].sValDx = 0; // 35) COL 2; ROW 6
- gWeaponStats[36].sX = 300; gWeaponStats[36].sY = 116; gWeaponStats[36].sValDx = 0; // 36) COL 2; ROW 7
- gWeaponStats[37].sX = 235; gWeaponStats[37].sY = 136; gWeaponStats[37].sValDx = 0; // 37) COL 3; ROW 1
- gWeaponStats[38].sX = 235; gWeaponStats[38].sY = 160; gWeaponStats[38].sValDx = 0; // 38) COL 3; ROW 3
- gWeaponStats[39].sX = 300; gWeaponStats[39].sY = 136; gWeaponStats[39].sValDx = 0; // 39) COL 4; ROW 1
- gWeaponStats[40].sX = 300; gWeaponStats[40].sY = 148; gWeaponStats[40].sValDx = 0; // 40) COL 4; ROW 2
- gWeaponStats[41].sX = 300; gWeaponStats[41].sY = 160; gWeaponStats[41].sValDx = 0; // 41) COL 4; ROW 3
- gWeaponStats[42].sX = 300; gWeaponStats[42].sY = 172; gWeaponStats[42].sValDx = 0; // 42) COL 4; ROW 4
- gWeaponStats[43].sX = 235; gWeaponStats[43].sY = 172; gWeaponStats[43].sValDx = 0; // 43) COL 3; ROW 4
- // Nonregular locations for explosive radius values (COL 2; ROW 3)
- gWeaponStats[44].sX = 273; gWeaponStats[44].sY = 68; gWeaponStats[44].sValDx = 0; // 44) COL 2; ROW 3; LOC 1 - Starting Radius
- gWeaponStats[45].sX = 291; gWeaponStats[45].sY = 68; gWeaponStats[45].sValDx = 0; // 45) COL 2; ROW 3; LOC 2 - Single Radius
- gWeaponStats[46].sX = 307; gWeaponStats[46].sY = 68; gWeaponStats[46].sValDx = 0; // 46) COL 2; ROW 3; LOC 3 - Final Radius
-
- gMoneyStats[0].sX = 203; gMoneyStats[0].sY = 44; gMoneyStats[0].sValDx = 45; // Money
- gMoneyStats[1].sX = 213; gMoneyStats[1].sY = 56; gMoneyStats[1].sValDx = 65; // Remaining
- gMoneyStats[2].sX = 203; gMoneyStats[2].sY = 92; gMoneyStats[2].sValDx = 45; // Money
- gMoneyStats[3].sX = 213; gMoneyStats[3].sY = 104; gMoneyStats[3].sValDx = 65; // Removing
- gMoneyStats[4].sX = 203; gMoneyStats[4].sY = 56; gMoneyStats[4].sValDx = 100; // AMT remaining
- gMoneyStats[5].sX = 203; gMoneyStats[5].sY = 104; gMoneyStats[5].sValDx = 100; // AMT removing
-
- gItemDescProsConsRects[0].iLeft = 14; gItemDescProsConsRects[0].iTop = 169; gItemDescProsConsRects[0].iRight = 188; gItemDescProsConsRects[0].iBottom = 176;
- gItemDescProsConsRects[1].iLeft = 14; gItemDescProsConsRects[1].iTop = 177; gItemDescProsConsRects[1].iRight = 188; gItemDescProsConsRects[1].iBottom = 184;
- }
- if (UsingEDBSystem() == 2) // OIV EDB
- {
- gWeaponStats[0].sX = 202; gWeaponStats[0].sY = 16; gWeaponStats[0].sValDx = 36; // 0) STATUS
- gWeaponStats[1].sX = 202; gWeaponStats[1].sY = 64; gWeaponStats[1].sValDx = 36; // 1) WEIGHT
- // Labels and Values
- gWeaponStats[2].sX = 274; gWeaponStats[2].sY = 14; gWeaponStats[2].sValDx = 30; // 2) COL 1; ROW 1
- gWeaponStats[3].sX = 274; gWeaponStats[3].sY = 26; gWeaponStats[3].sValDx = 30; // 3) COL 1; ROW 2
- gWeaponStats[4].sX = 274; gWeaponStats[4].sY = 38; gWeaponStats[4].sValDx = 30; // 4) COL 1; ROW 3
- gWeaponStats[5].sX = 274; gWeaponStats[5].sY = 50; gWeaponStats[5].sValDx = 30; // 5) COL 1; ROW 4
- gWeaponStats[6].sX = 274; gWeaponStats[6].sY = 62; gWeaponStats[6].sValDx = 30; // 6) COL 1; ROW 5
- gWeaponStats[7].sX = 274; gWeaponStats[7].sY = 74; gWeaponStats[7].sValDx = 30; // 7) COL 1; ROW 6
- gWeaponStats[8].sX = 274; gWeaponStats[8].sY = 86; gWeaponStats[8].sValDx = 30; // 8) COL 1; ROW 7
- gWeaponStats[9].sX = 341; gWeaponStats[9].sY = 14; gWeaponStats[9].sValDx = 30; // 9) COL 2; ROW 1
- gWeaponStats[10].sX = 341; gWeaponStats[10].sY = 26; gWeaponStats[10].sValDx = 30; // 10) COL 2; ROW 2
- gWeaponStats[11].sX = 341; gWeaponStats[11].sY = 38; gWeaponStats[11].sValDx = 30; // 11) COL 2; ROW 3
- gWeaponStats[12].sX = 341; gWeaponStats[12].sY = 50; gWeaponStats[12].sValDx = 30; // 12) COL 2; ROW 4
- gWeaponStats[13].sX = 341; gWeaponStats[13].sY = 62; gWeaponStats[13].sValDx = 30; // 13) COL 2; ROW 5
- gWeaponStats[14].sX = 341; gWeaponStats[14].sY = 74; gWeaponStats[14].sValDx = 30; // 14) COL 2; ROW 6
- gWeaponStats[15].sX = 341; gWeaponStats[15].sY = 86; gWeaponStats[15].sValDx = 30; // 15) COL 2; ROW 7
- gWeaponStats[16].sX = 408; gWeaponStats[16].sY = 14; gWeaponStats[16].sValDx = 30; // 16) COL 3; ROW 1
- gWeaponStats[17].sX = 408; gWeaponStats[17].sY = 26; gWeaponStats[17].sValDx = 30; // 17) COL 3; ROW 2
- gWeaponStats[18].sX = 408; gWeaponStats[18].sY = 38; gWeaponStats[18].sValDx = 30; // 18) COL 3; ROW 3
- gWeaponStats[19].sX = 408; gWeaponStats[19].sY = 50; gWeaponStats[19].sValDx = 30; // 19) COL 3; ROW 4
- gWeaponStats[20].sX = 408; gWeaponStats[20].sY = 62; gWeaponStats[20].sValDx = 30; // 20) COL 3; ROW 5
- gWeaponStats[21].sX = 408; gWeaponStats[21].sY = 74; gWeaponStats[21].sValDx = 30; // 21) COL 3; ROW 6
- gWeaponStats[22].sX = 408; gWeaponStats[22].sY = 86; gWeaponStats[22].sValDx = 30; // 22) COL 3; ROW 7
- // EQUALS signs
- gWeaponStats[23].sX = 306; gWeaponStats[23].sY = 14; gWeaponStats[23].sValDx = 0; // 23) COL 1; ROW 1
- gWeaponStats[24].sX = 306; gWeaponStats[24].sY = 26; gWeaponStats[24].sValDx = 0; // 24) COL 1; ROW 2
- gWeaponStats[25].sX = 306; gWeaponStats[25].sY = 38; gWeaponStats[25].sValDx = 0; // 25) COL 1; ROW 3
- gWeaponStats[26].sX = 306; gWeaponStats[26].sY = 50; gWeaponStats[26].sValDx = 0; // 26) COL 1; ROW 4
- gWeaponStats[27].sX = 306; gWeaponStats[27].sY = 62; gWeaponStats[27].sValDx = 0; // 27) COL 1; ROW 5
- gWeaponStats[28].sX = 306; gWeaponStats[28].sY = 74; gWeaponStats[28].sValDx = 0; // 28) COL 1; ROW 6
- gWeaponStats[29].sX = 306; gWeaponStats[29].sY = 86; gWeaponStats[29].sValDx = 0; // 39) COL 1; ROW 7
- gWeaponStats[30].sX = 373; gWeaponStats[30].sY = 14; gWeaponStats[30].sValDx = 0; // 30) COL 2; ROW 1
- gWeaponStats[31].sX = 373; gWeaponStats[31].sY = 26; gWeaponStats[31].sValDx = 0; // 31) COL 2; ROW 2
- gWeaponStats[32].sX = 373; gWeaponStats[32].sY = 38; gWeaponStats[32].sValDx = 0; // 32) COL 2; ROW 3
- gWeaponStats[33].sX = 373; gWeaponStats[33].sY = 50; gWeaponStats[33].sValDx = 0; // 33) COL 2; ROW 4
- gWeaponStats[34].sX = 373; gWeaponStats[34].sY = 62; gWeaponStats[34].sValDx = 0; // 34) COL 2; ROW 5
- gWeaponStats[35].sX = 373; gWeaponStats[35].sY = 74; gWeaponStats[35].sValDx = 0; // 35) COL 2; ROW 6
- gWeaponStats[36].sX = 373; gWeaponStats[36].sY = 86; gWeaponStats[36].sValDx = 0; // 36) COL 2; ROW 7
- gWeaponStats[37].sX = 440; gWeaponStats[37].sY = 14; gWeaponStats[37].sValDx = 0; // 37) COL 3; ROW 1
- gWeaponStats[38].sX = 440; gWeaponStats[38].sY = 26; gWeaponStats[38].sValDx = 0; // 48) COL 3; ROW 2
- gWeaponStats[39].sX = 440; gWeaponStats[39].sY = 38; gWeaponStats[39].sValDx = 0; // 49) COL 3; ROW 3
- gWeaponStats[40].sX = 440; gWeaponStats[40].sY = 50; gWeaponStats[40].sValDx = 0; // 40) COL 3; ROW 4
- gWeaponStats[41].sX = 440; gWeaponStats[41].sY = 62; gWeaponStats[41].sValDx = 0; // 41) COL 3; ROW 5
- gWeaponStats[42].sX = 440; gWeaponStats[42].sY = 74; gWeaponStats[42].sValDx = 0; // 42) COL 3; ROW 6
- gWeaponStats[43].sX = 440; gWeaponStats[43].sY = 86; gWeaponStats[43].sValDx = 0; // 43) COL 3; ROW 7
- // Nonregular locations for explosive radius values (COL 2; ROW 3)
- gWeaponStats[44].sX = 345; gWeaponStats[44].sY = 38; gWeaponStats[44].sValDx = 0; // 44) COL 2; ROW 3; LOC 1 - Starting Radius
- gWeaponStats[45].sX = 362; gWeaponStats[45].sY = 38; gWeaponStats[45].sValDx = 0; // 45) COL 2; ROW 3; LOC 2 - Single Radius
- gWeaponStats[46].sX = 381; gWeaponStats[46].sY = 38; gWeaponStats[46].sValDx = 0; // 46) COL 2; ROW 3; LOC 3 - Final Radius
-
- gMoneyStats[0].sX = 202; gMoneyStats[0].sY = 14; gMoneyStats[0].sValDx = 45; // Money
- gMoneyStats[1].sX = 202; gMoneyStats[1].sY = 26; gMoneyStats[1].sValDx = 65; // Remaining
- gMoneyStats[2].sX = 202; gMoneyStats[2].sY = 62; gMoneyStats[2].sValDx = 45; // Money
- gMoneyStats[3].sX = 202; gMoneyStats[3].sY = 74; gMoneyStats[3].sValDx = 65; // Removing
- gMoneyStats[4].sX = 202; gMoneyStats[4].sY = 38; gMoneyStats[4].sValDx = 100; // AMT remaining
- gMoneyStats[5].sX = 202; gMoneyStats[5].sY = 86; gMoneyStats[5].sValDx = 100; // AMT removing
-
- gItemDescProsConsRects[0].iLeft = 433; gItemDescProsConsRects[0].iTop = 104; gItemDescProsConsRects[0].iRight = 467; gItemDescProsConsRects[0].iBottom = 115;
- gItemDescProsConsRects[1].iLeft = 433; gItemDescProsConsRects[1].iTop = 116; gItemDescProsConsRects[1].iRight = 467; gItemDescProsConsRects[1].iBottom = 127;
+ for (UINT8 x = 0; x < usAttachmentSlotIndexVector.size(); x++){
+ //WarmSteel - Tell this slot where it's supposed to be.
+ if(AttachmentSlots[usAttachmentSlotIndexVector[x]].fBigSlot){
+ SetupItemDescAttachmentsXY(x, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosX, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosY, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_BIG_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ } else {
+ SetupItemDescAttachmentsXY(x, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosX, AttachmentSlots[usAttachmentSlotIndexVector[x]].usDescPanelPosY, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-9, INV_BAR_DY);
+ }
}
}
- }
- else
- {
- if(guiCurrentScreen ==MAP_SCREEN)
- {
- gWeaponStats[0].sX = 52; gWeaponStats[0].sY = 98; gWeaponStats[0].sValDx = 89; // 0) STATUS
- gWeaponStats[1].sX = 52; gWeaponStats[1].sY = 108; gWeaponStats[1].sValDx = 89; // 1) WEIGHT
- gWeaponStats[2].sX = 117; gWeaponStats[2].sY = 124; gWeaponStats[2].sValDx = 21; // 2) RANGE
- gWeaponStats[3].sX = 52; gWeaponStats[3].sY = 124; gWeaponStats[3].sValDx = 30; // 3) DAMAGE
- gWeaponStats[4].sX = 52; gWeaponStats[4].sY = 98; gWeaponStats[4].sValDx = 80;
- gWeaponStats[5].sX = 52; gWeaponStats[5].sY = 135; gWeaponStats[5].sValDx = 30; // 5) AP
- gWeaponStats[6].sX = 117; gWeaponStats[6].sY = 135; gWeaponStats[6].sValDx = 25;
- gWeaponStats[7].sX = 86; gWeaponStats[7].sY = 135; gWeaponStats[7].sValDx = 0; // 7) =
- gWeaponStats[8].sX = 145; gWeaponStats[8].sY = 135; gWeaponStats[8].sValDx = 0; // 8) =
- gWeaponStats[9].sX = 0; gWeaponStats[9].sY = 0; gWeaponStats[9].sValDx = 0;
- gWeaponStats[10].sX = 0; gWeaponStats[10].sY = 0; gWeaponStats[10].sValDx = 0;
- gWeaponStats[11].sX = 0; gWeaponStats[11].sY = 0; gWeaponStats[11].sValDx = 0;
- gWeaponStats[12].sX = 0; gWeaponStats[12].sY = 0; gWeaponStats[12].sValDx = 0;
- gWeaponStats[13].sX = 0; gWeaponStats[13].sY = 0; gWeaponStats[13].sValDx = 0;
- gWeaponStats[14].sX = 0; gWeaponStats[14].sY = 0; gWeaponStats[14].sValDx = 0;
- gWeaponStats[15].sX = 0; gWeaponStats[15].sY = 0; gWeaponStats[15].sValDx = 0;
- gWeaponStats[16].sX = 0; gWeaponStats[16].sY = 0; gWeaponStats[16].sValDx = 0;
- gWeaponStats[17].sX = 0; gWeaponStats[17].sY = 0; gWeaponStats[17].sValDx = 0;
- gWeaponStats[18].sX = 0; gWeaponStats[18].sY = 0; gWeaponStats[18].sValDx = 0;
- gWeaponStats[19].sX = 0; gWeaponStats[19].sY = 0; gWeaponStats[19].sValDx = 0;
- gWeaponStats[20].sX = 0; gWeaponStats[20].sY = 0; gWeaponStats[20].sValDx = 0;
- gWeaponStats[21].sX = 0; gWeaponStats[21].sY = 0; gWeaponStats[21].sValDx = 0;
- gWeaponStats[22].sX = 0; gWeaponStats[22].sY = 0; gWeaponStats[22].sValDx = 0;
- gWeaponStats[23].sX = 0; gWeaponStats[23].sY = 0; gWeaponStats[23].sValDx = 0;
- gWeaponStats[24].sX = 0; gWeaponStats[24].sY = 0; gWeaponStats[24].sValDx = 0;
- gWeaponStats[25].sX = 0; gWeaponStats[25].sY = 0; gWeaponStats[25].sValDx = 0;
- gWeaponStats[26].sX = 0; gWeaponStats[26].sY = 0; gWeaponStats[26].sValDx = 0;
- gWeaponStats[27].sX = 0; gWeaponStats[27].sY = 0; gWeaponStats[27].sValDx = 0;
- gWeaponStats[28].sX = 0; gWeaponStats[28].sY = 0; gWeaponStats[28].sValDx = 0;
- gWeaponStats[29].sX = 0; gWeaponStats[29].sY = 0; gWeaponStats[29].sValDx = 0;
- gWeaponStats[30].sX = 0; gWeaponStats[30].sY = 0; gWeaponStats[30].sValDx = 0;
- gWeaponStats[31].sX = 0; gWeaponStats[31].sY = 0; gWeaponStats[31].sValDx = 0;
- gWeaponStats[32].sX = 0; gWeaponStats[32].sY = 0; gWeaponStats[32].sValDx = 0;
- gWeaponStats[33].sX = 0; gWeaponStats[33].sY = 0; gWeaponStats[33].sValDx = 0;
- gWeaponStats[34].sX = 0; gWeaponStats[34].sY = 0; gWeaponStats[34].sValDx = 0;
- gWeaponStats[35].sX = 0; gWeaponStats[35].sY = 0; gWeaponStats[35].sValDx = 0;
- gWeaponStats[36].sX = 0; gWeaponStats[36].sY = 0; gWeaponStats[36].sValDx = 0;
- gWeaponStats[37].sX = 0; gWeaponStats[37].sY = 0; gWeaponStats[37].sValDx = 0;
- gWeaponStats[38].sX = 0; gWeaponStats[38].sY = 0; gWeaponStats[38].sValDx = 0;
- gWeaponStats[39].sX = 0; gWeaponStats[39].sY = 0; gWeaponStats[39].sValDx = 0;
- gWeaponStats[40].sX = 0; gWeaponStats[40].sY = 0; gWeaponStats[40].sValDx = 0;
- gWeaponStats[41].sX = 0; gWeaponStats[41].sY = 0; gWeaponStats[41].sValDx = 0;
- gWeaponStats[42].sX = 0; gWeaponStats[42].sY = 0; gWeaponStats[42].sValDx = 0;
- gWeaponStats[43].sX = 0; gWeaponStats[43].sY = 0; gWeaponStats[43].sValDx = 0;
- gWeaponStats[44].sX = 0; gWeaponStats[44].sY = 0; gWeaponStats[44].sValDx = 0;
- gWeaponStats[45].sX = 0; gWeaponStats[45].sY = 0; gWeaponStats[45].sValDx = 0;
- gWeaponStats[46].sX = 0; gWeaponStats[46].sY = 0; gWeaponStats[46].sValDx = 0;
-
- gMoneyStats[0].sX = 51; gMoneyStats[0].sY = 97; gMoneyStats[0].sValDx = 45;
- gMoneyStats[1].sX = 61; gMoneyStats[1].sY = 107; gMoneyStats[1].sValDx = 75;
- gMoneyStats[2].sX = 51; gMoneyStats[2].sY = 125; gMoneyStats[2].sValDx = 45;
- gMoneyStats[3].sX = 61; gMoneyStats[3].sY = 135; gMoneyStats[3].sValDx = 70;
- gMoneyStats[4].sX = 0; gMoneyStats[4].sY = 0; gMoneyStats[4].sValDx = 0;
- gMoneyStats[5].sX = 0; gMoneyStats[5].sY = 0; gMoneyStats[5].sValDx = 0;
-
- gItemDescProsConsRects[0].iLeft = 14; gItemDescProsConsRects[0].iTop = 231; gItemDescProsConsRects[0].iRight = 240; gItemDescProsConsRects[0].iBottom = 238;
- gItemDescProsConsRects[1].iLeft = 14; gItemDescProsConsRects[1].iTop = 239; gItemDescProsConsRects[1].iRight = 240; gItemDescProsConsRects[1].iBottom = 246;
- }
+ //Not a valid item for NAS, use default
else
{
- gWeaponStats[0].sX = 202; gWeaponStats[0].sY = 15; gWeaponStats[0].sValDx = 83; // 0) STATUS
- gWeaponStats[1].sX = 202; gWeaponStats[1].sY = 25; gWeaponStats[1].sValDx = 83; // 1) WEIGHT
- gWeaponStats[2].sX = 265; gWeaponStats[2].sY = 40; gWeaponStats[2].sValDx = 20; // 2) RANGE
- gWeaponStats[3].sX = 202; gWeaponStats[3].sY = 40; gWeaponStats[3].sValDx = 32; // 3) DAMAGE
- gWeaponStats[4].sX = 202; gWeaponStats[4].sY = 15; gWeaponStats[4].sValDx = 83; // 4) KEY
- gWeaponStats[5].sX = 202; gWeaponStats[5].sY = 50; gWeaponStats[5].sValDx = 32; // 5) AP
- gWeaponStats[6].sX = 265; gWeaponStats[6].sY = 50; gWeaponStats[6].sValDx = 20;
- gWeaponStats[7].sX = 234; gWeaponStats[7].sY = 50; gWeaponStats[7].sValDx = 0; // 7) =
- gWeaponStats[8].sX = 290; gWeaponStats[8].sY = 50; gWeaponStats[8].sValDx = 0; // 8) =
- gWeaponStats[9].sX = 0; gWeaponStats[9].sY = 0; gWeaponStats[9].sValDx = 0;
- gWeaponStats[10].sX = 0; gWeaponStats[10].sY = 0; gWeaponStats[10].sValDx = 0;
- gWeaponStats[11].sX = 0; gWeaponStats[11].sY = 0; gWeaponStats[11].sValDx = 0;
- gWeaponStats[12].sX = 0; gWeaponStats[12].sY = 0; gWeaponStats[12].sValDx = 0;
- gWeaponStats[13].sX = 0; gWeaponStats[13].sY = 0; gWeaponStats[13].sValDx = 0;
- gWeaponStats[14].sX = 0; gWeaponStats[14].sY = 0; gWeaponStats[14].sValDx = 0;
- gWeaponStats[15].sX = 0; gWeaponStats[15].sY = 0; gWeaponStats[15].sValDx = 0;
- gWeaponStats[16].sX = 0; gWeaponStats[16].sY = 0; gWeaponStats[16].sValDx = 0;
- gWeaponStats[17].sX = 0; gWeaponStats[17].sY = 0; gWeaponStats[17].sValDx = 0;
- gWeaponStats[18].sX = 0; gWeaponStats[18].sY = 0; gWeaponStats[18].sValDx = 0;
- gWeaponStats[19].sX = 0; gWeaponStats[19].sY = 0; gWeaponStats[19].sValDx = 0;
- gWeaponStats[20].sX = 0; gWeaponStats[20].sY = 0; gWeaponStats[20].sValDx = 0;
- gWeaponStats[21].sX = 0; gWeaponStats[21].sY = 0; gWeaponStats[21].sValDx = 0;
- gWeaponStats[22].sX = 0; gWeaponStats[22].sY = 0; gWeaponStats[22].sValDx = 0;
- gWeaponStats[23].sX = 0; gWeaponStats[23].sY = 0; gWeaponStats[23].sValDx = 0;
- gWeaponStats[24].sX = 0; gWeaponStats[24].sY = 0; gWeaponStats[24].sValDx = 0;
- gWeaponStats[25].sX = 0; gWeaponStats[25].sY = 0; gWeaponStats[25].sValDx = 0;
- gWeaponStats[26].sX = 0; gWeaponStats[26].sY = 0; gWeaponStats[26].sValDx = 0;
- gWeaponStats[27].sX = 0; gWeaponStats[27].sY = 0; gWeaponStats[27].sValDx = 0;
- gWeaponStats[28].sX = 0; gWeaponStats[28].sY = 0; gWeaponStats[28].sValDx = 0;
- gWeaponStats[29].sX = 0; gWeaponStats[29].sY = 0; gWeaponStats[29].sValDx = 0;
- gWeaponStats[30].sX = 0; gWeaponStats[30].sY = 0; gWeaponStats[30].sValDx = 0;
- gWeaponStats[31].sX = 0; gWeaponStats[31].sY = 0; gWeaponStats[31].sValDx = 0;
- gWeaponStats[32].sX = 0; gWeaponStats[32].sY = 0; gWeaponStats[32].sValDx = 0;
- gWeaponStats[33].sX = 0; gWeaponStats[33].sY = 0; gWeaponStats[33].sValDx = 0;
- gWeaponStats[34].sX = 0; gWeaponStats[34].sY = 0; gWeaponStats[34].sValDx = 0;
- gWeaponStats[35].sX = 0; gWeaponStats[35].sY = 0; gWeaponStats[35].sValDx = 0;
- gWeaponStats[36].sX = 0; gWeaponStats[36].sY = 0; gWeaponStats[36].sValDx = 0;
- gWeaponStats[37].sX = 0; gWeaponStats[37].sY = 0; gWeaponStats[37].sValDx = 0;
- gWeaponStats[38].sX = 0; gWeaponStats[38].sY = 0; gWeaponStats[38].sValDx = 0;
- gWeaponStats[39].sX = 0; gWeaponStats[39].sY = 0; gWeaponStats[39].sValDx = 0;
- gWeaponStats[40].sX = 0; gWeaponStats[40].sY = 0; gWeaponStats[40].sValDx = 0;
- gWeaponStats[41].sX = 0; gWeaponStats[41].sY = 0; gWeaponStats[41].sValDx = 0;
- gWeaponStats[42].sX = 0; gWeaponStats[42].sY = 0; gWeaponStats[42].sValDx = 0;
- gWeaponStats[43].sX = 0; gWeaponStats[43].sY = 0; gWeaponStats[43].sValDx = 0;
- gWeaponStats[44].sX = 0; gWeaponStats[44].sY = 0; gWeaponStats[44].sValDx = 0;
- gWeaponStats[45].sX = 0; gWeaponStats[45].sY = 0; gWeaponStats[45].sValDx = 0;
- gWeaponStats[46].sX = 0; gWeaponStats[46].sY = 0; gWeaponStats[46].sValDx = 0;
-
- gMoneyStats[0].sX = 202; gMoneyStats[0].sY = 14; gMoneyStats[0].sValDx = 78;
- gMoneyStats[1].sX = 212; gMoneyStats[1].sY = 25; gMoneyStats[1].sValDx = 78;
- gMoneyStats[2].sX = 203; gMoneyStats[2].sY = 40; gMoneyStats[2].sValDx = 78;
- gMoneyStats[3].sX = 212; gMoneyStats[3].sY = 51; gMoneyStats[3].sValDx = 78;
- gMoneyStats[4].sX = 0; gMoneyStats[4].sY = 0; gMoneyStats[4].sValDx = 0;
- gMoneyStats[5].sX = 0; gMoneyStats[5].sY = 0; gMoneyStats[5].sValDx = 0;
-
- gItemDescProsConsRects[0].iLeft = 7; gItemDescProsConsRects[0].iTop = 111; gItemDescProsConsRects[0].iRight = 313; gItemDescProsConsRects[0].iBottom = 118;
- gItemDescProsConsRects[1].iLeft = 7; gItemDescProsConsRects[1].iTop = 119; gItemDescProsConsRects[1].iRight = 313; gItemDescProsConsRects[1].iBottom = 126;
+ //default setup
+ SetupItemDescAttachmentsXY(0, 133, 11, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
+ SetupItemDescAttachmentsXY(1, 167, 11, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
+ SetupItemDescAttachmentsXY(2, 133, 38, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
+ SetupItemDescAttachmentsXY(3, 167, 38, SM_INV_SLOT_HEIGHT, ATTACH_SLOT_WIDTH, INV_BAR_DX-8, INV_BAR_DY+1);
}
}
}
@@ -1196,11 +870,11 @@ void InitLBECoords()
{
if(UsingEDBSystem() > 0)
{
- gLBEStats[0].sX = 456; gLBEStats[0].sY = 10; gLBEStats[0].sValDx = 0; //Thigh 1
- gLBEStats[1].sX = 492; gLBEStats[1].sY = 10; gLBEStats[1].sValDx = 0; //Thigh 2
- gLBEStats[2].sX = 456; gLBEStats[2].sY = 34; gLBEStats[2].sValDx = 0; //Thigh 3
- gLBEStats[3].sX = 492; gLBEStats[3].sY = 34; gLBEStats[3].sValDx = 0; //Thigh 4
- gLBEStats[4].sX = 467; gLBEStats[4].sY = 58; gLBEStats[4].sValDx = 0; //Thigh 5
+ gLBEStats[0].sX = 597; gLBEStats[0].sY = 9; gLBEStats[0].sValDx = 0; //Thigh 1
+ gLBEStats[1].sX = 633; gLBEStats[1].sY = 9; gLBEStats[1].sValDx = 0; //Thigh 2
+ gLBEStats[2].sX = 597; gLBEStats[2].sY = 33; gLBEStats[2].sValDx = 0; //Thigh 3
+ gLBEStats[3].sX = 633; gLBEStats[3].sY = 33; gLBEStats[3].sValDx = 0; //Thigh 4
+ gLBEStats[4].sX = 608; gLBEStats[4].sY = 57; gLBEStats[4].sValDx = 0; //Thigh 5
gLBEStats[5].sX = 0; gLBEStats[5].sY = 0; gLBEStats[5].sValDx = 0; //Thigh 6
gLBEStats[6].sX = 0; gLBEStats[6].sY = 0; gLBEStats[6].sValDx = 0; //Thigh 7
gLBEStats[7].sX = 0; gLBEStats[7].sY = 0; gLBEStats[7].sValDx = 0; //Thigh 8
@@ -1208,50 +882,50 @@ void InitLBECoords()
gLBEStats[9].sX = 0; gLBEStats[9].sY = 0; gLBEStats[9].sValDx = 0; //Thigh 10
gLBEStats[10].sX = 0; gLBEStats[10].sY = 0; gLBEStats[10].sValDx = 0; //Thigh 11
gLBEStats[11].sX = 0; gLBEStats[11].sY = 0; gLBEStats[11].sValDx = 0; //Thigh 12
- gLBEStats[12].sX = 456; gLBEStats[12].sY = 10; gLBEStats[12].sValDx = 0; //Vest 1
- gLBEStats[13].sX = 492; gLBEStats[13].sY = 10; gLBEStats[13].sValDx = 0; //Vest 2
- gLBEStats[14].sX = 528; gLBEStats[14].sY = 10; gLBEStats[14].sValDx = 0; //Vest 3
- gLBEStats[15].sX = 564; gLBEStats[15].sY = 10; gLBEStats[15].sValDx = 0; //Vest 4
- gLBEStats[16].sX = 600; gLBEStats[16].sY = 10; gLBEStats[16].sValDx = 0; //Vest 5
- gLBEStats[17].sX = 456; gLBEStats[17].sY = 34; gLBEStats[17].sValDx = 0; //Vest 6
- gLBEStats[18].sX = 492; gLBEStats[18].sY = 34; gLBEStats[18].sValDx = 0; //Vest 7
- gLBEStats[19].sX = 528; gLBEStats[19].sY = 34; gLBEStats[19].sValDx = 0; //Vest 8
- gLBEStats[20].sX = 564; gLBEStats[20].sY = 34; gLBEStats[20].sValDx = 0; //Vest 9
- gLBEStats[21].sX = 600; gLBEStats[21].sY = 34; gLBEStats[21].sValDx = 0; //Vest 10
- gLBEStats[22].sX = 636; gLBEStats[22].sY = 10; gLBEStats[22].sValDx = 0; //Vest 11
- gLBEStats[23].sX = 636; gLBEStats[23].sY = 34; gLBEStats[23].sValDx = 0; //Vest 12
- gLBEStats[24].sX = 456; gLBEStats[24].sY = 10; gLBEStats[24].sValDx = 0; //CPack 1
- gLBEStats[25].sX = 492; gLBEStats[25].sY = 10; gLBEStats[25].sValDx = 0; //CPack 2
- gLBEStats[26].sX = 456; gLBEStats[26].sY = 34; gLBEStats[26].sValDx = 0; //CPack 3
- gLBEStats[27].sX = 492; gLBEStats[27].sY = 34; gLBEStats[27].sValDx = 0; //CPack 4
- gLBEStats[28].sX = 528; gLBEStats[28].sY = 10; gLBEStats[28].sValDx = 0; //CPack 5
- gLBEStats[29].sX = 528; gLBEStats[29].sY = 34; gLBEStats[29].sValDx = 0; //CPack 6
- gLBEStats[30].sX = 528; gLBEStats[30].sY = 58; gLBEStats[30].sValDx = 0; //CPack 7
+ gLBEStats[12].sX = 597; gLBEStats[12].sY = 9; gLBEStats[12].sValDx = 0; //Vest 1
+ gLBEStats[13].sX = 633; gLBEStats[13].sY = 9; gLBEStats[13].sValDx = 0; //Vest 2
+ gLBEStats[14].sX = 669; gLBEStats[14].sY = 9; gLBEStats[14].sValDx = 0; //Vest 3
+ gLBEStats[15].sX = 705; gLBEStats[15].sY = 9; gLBEStats[15].sValDx = 0; //Vest 4
+ gLBEStats[16].sX = 741; gLBEStats[16].sY = 9; gLBEStats[16].sValDx = 0; //Vest 5
+ gLBEStats[17].sX = 597; gLBEStats[17].sY = 33; gLBEStats[17].sValDx = 0; //Vest 6
+ gLBEStats[18].sX = 633; gLBEStats[18].sY = 33; gLBEStats[18].sValDx = 0; //Vest 7
+ gLBEStats[19].sX = 669; gLBEStats[19].sY = 33; gLBEStats[19].sValDx = 0; //Vest 8
+ gLBEStats[20].sX = 705; gLBEStats[20].sY = 33; gLBEStats[20].sValDx = 0; //Vest 9
+ gLBEStats[21].sX = 741; gLBEStats[21].sY = 33; gLBEStats[21].sValDx = 0; //Vest 10
+ gLBEStats[22].sX = 663; gLBEStats[22].sY = 57; gLBEStats[22].sValDx = 0; //Vest 11
+ gLBEStats[23].sX = 663; gLBEStats[23].sY = 81; gLBEStats[23].sValDx = 0; //Vest 12
+ gLBEStats[24].sX = 597; gLBEStats[24].sY = 10; gLBEStats[24].sValDx = 0; //CPack 1
+ gLBEStats[25].sX = 633; gLBEStats[25].sY = 10; gLBEStats[25].sValDx = 0; //CPack 2
+ gLBEStats[26].sX = 597; gLBEStats[26].sY = 34; gLBEStats[26].sValDx = 0; //CPack 3
+ gLBEStats[27].sX = 633; gLBEStats[27].sY = 34; gLBEStats[27].sValDx = 0; //CPack 4
+ gLBEStats[28].sX = 669; gLBEStats[28].sY = 10; gLBEStats[28].sValDx = 0; //CPack 5
+ gLBEStats[29].sX = 669; gLBEStats[29].sY = 34; gLBEStats[29].sValDx = 0; //CPack 6
+ gLBEStats[30].sX = 669; gLBEStats[30].sY = 58; gLBEStats[30].sValDx = 0; //CPack 7
gLBEStats[31].sX = 0; gLBEStats[31].sY = 0; gLBEStats[31].sValDx = 0; //CPack 8
gLBEStats[32].sX = 0; gLBEStats[32].sY = 0; gLBEStats[32].sValDx = 0; //CPack 9
gLBEStats[33].sX = 0; gLBEStats[33].sY = 0; gLBEStats[33].sValDx = 0; //CPack 10
gLBEStats[34].sX = 0; gLBEStats[34].sY = 0; gLBEStats[34].sValDx = 0; //CPack 11
gLBEStats[35].sX = 0; gLBEStats[35].sY = 0; gLBEStats[35].sValDx = 0; //CPack 12
- gLBEStats[36].sX = 456; gLBEStats[36].sY = 10; gLBEStats[36].sValDx = 0; //BPack 1
- gLBEStats[37].sX = 456; gLBEStats[37].sY = 34; gLBEStats[37].sValDx = 0; //BPack 2
- gLBEStats[38].sX = 456; gLBEStats[38].sY = 58; gLBEStats[38].sValDx = 0; //BPack 3
- gLBEStats[39].sX = 456; gLBEStats[39].sY = 82; gLBEStats[39].sValDx = 0; //BPack 4
- gLBEStats[40].sX = 492; gLBEStats[40].sY = 10; gLBEStats[40].sValDx = 0; //BPack 5
- gLBEStats[41].sX = 492; gLBEStats[41].sY = 34; gLBEStats[41].sValDx = 0; //BPack 6
- gLBEStats[42].sX = 492; gLBEStats[42].sY = 58; gLBEStats[42].sValDx = 0; //BPack 7
- gLBEStats[43].sX = 492; gLBEStats[43].sY = 82; gLBEStats[43].sValDx = 0; //BPack 8
- gLBEStats[44].sX = 528; gLBEStats[44].sY = 10; gLBEStats[44].sValDx = 0; //BPack 9
- gLBEStats[45].sX = 528; gLBEStats[45].sY = 34; gLBEStats[45].sValDx = 0; //BPack 10
- gLBEStats[46].sX = 528; gLBEStats[46].sY = 58; gLBEStats[46].sValDx = 0; //BPack 11
- gLBEStats[47].sX = 528; gLBEStats[47].sY = 82; gLBEStats[47].sValDx = 0; //BPack 12
+ gLBEStats[36].sX = 597; gLBEStats[36].sY = 9; gLBEStats[36].sValDx = 0; //BPack 1
+ gLBEStats[37].sX = 597; gLBEStats[37].sY = 33; gLBEStats[37].sValDx = 0; //BPack 2
+ gLBEStats[38].sX = 597; gLBEStats[38].sY = 57; gLBEStats[38].sValDx = 0; //BPack 3
+ gLBEStats[39].sX = 597; gLBEStats[39].sY = 81; gLBEStats[39].sValDx = 0; //BPack 4
+ gLBEStats[40].sX = 633; gLBEStats[40].sY = 9; gLBEStats[40].sValDx = 0; //BPack 5
+ gLBEStats[41].sX = 633; gLBEStats[41].sY = 33; gLBEStats[41].sValDx = 0; //BPack 6
+ gLBEStats[42].sX = 633; gLBEStats[42].sY = 57; gLBEStats[42].sValDx = 0; //BPack 7
+ gLBEStats[43].sX = 633; gLBEStats[43].sY = 81; gLBEStats[43].sValDx = 0; //BPack 8
+ gLBEStats[44].sX = 669; gLBEStats[44].sY = 9; gLBEStats[44].sValDx = 0; //BPack 9
+ gLBEStats[45].sX = 669; gLBEStats[45].sY = 33; gLBEStats[45].sValDx = 0; //BPack 10
+ gLBEStats[46].sX = 669; gLBEStats[46].sY = 57; gLBEStats[46].sValDx = 0; //BPack 11
+ gLBEStats[47].sX = 669; gLBEStats[47].sY = 81; gLBEStats[47].sValDx = 0; //BPack 12
}
else
{
- gLBEStats[0].sX = 586; gLBEStats[0].sY = 10; gLBEStats[0].sValDx = 0; //Thigh 1
- gLBEStats[1].sX = 622; gLBEStats[1].sY = 10; gLBEStats[1].sValDx = 0; //Thigh 2
- gLBEStats[2].sX = 586; gLBEStats[2].sY = 34; gLBEStats[2].sValDx = 0; //Thigh 3
- gLBEStats[3].sX = 622; gLBEStats[3].sY = 34; gLBEStats[3].sValDx = 0; //Thigh 4
- gLBEStats[4].sX = 597; gLBEStats[4].sY = 58; gLBEStats[4].sValDx = 0; //Thigh 5
+ gLBEStats[0].sX = 442; gLBEStats[0].sY = 10; gLBEStats[0].sValDx = 0; //Thigh 1
+ gLBEStats[1].sX = 478; gLBEStats[1].sY = 10; gLBEStats[1].sValDx = 0; //Thigh 2
+ gLBEStats[2].sX = 442; gLBEStats[2].sY = 34; gLBEStats[2].sValDx = 0; //Thigh 3
+ gLBEStats[3].sX = 478; gLBEStats[3].sY = 34; gLBEStats[3].sValDx = 0; //Thigh 4
+ gLBEStats[4].sX = 453; gLBEStats[4].sY = 58; gLBEStats[4].sValDx = 0; //Thigh 5
gLBEStats[5].sX = 0; gLBEStats[5].sY = 0; gLBEStats[5].sValDx = 0; //Thigh 6
gLBEStats[6].sX = 0; gLBEStats[6].sY = 0; gLBEStats[6].sValDx = 0; //Thigh 7
gLBEStats[7].sX = 0; gLBEStats[7].sY = 0; gLBEStats[7].sValDx = 0; //Thigh 8
@@ -1259,635 +933,267 @@ void InitLBECoords()
gLBEStats[9].sX = 0; gLBEStats[9].sY = 0; gLBEStats[9].sValDx = 0; //Thigh 10
gLBEStats[10].sX = 0; gLBEStats[10].sY = 0; gLBEStats[10].sValDx = 0; //Thigh 11
gLBEStats[11].sX = 0; gLBEStats[11].sY = 0; gLBEStats[11].sValDx = 0; //Thigh 12
- gLBEStats[12].sX = 269; gLBEStats[12].sY = 139; gLBEStats[12].sValDx = 0; //Vest 1
- gLBEStats[13].sX = 305; gLBEStats[13].sY = 139; gLBEStats[13].sValDx = 0; //Vest 2
- gLBEStats[14].sX = 341; gLBEStats[14].sY = 139; gLBEStats[14].sValDx = 0; //Vest 3
- gLBEStats[15].sX = 377; gLBEStats[15].sY = 139; gLBEStats[15].sValDx = 0; //Vest 4
- gLBEStats[16].sX = 413; gLBEStats[16].sY = 139; gLBEStats[16].sValDx = 0; //Vest 5
- gLBEStats[17].sX = 269; gLBEStats[17].sY = 163; gLBEStats[17].sValDx = 0; //Vest 6
- gLBEStats[18].sX = 305; gLBEStats[18].sY = 163; gLBEStats[18].sValDx = 0; //Vest 7
- gLBEStats[19].sX = 341; gLBEStats[19].sY = 163; gLBEStats[19].sValDx = 0; //Vest 8
- gLBEStats[20].sX = 377; gLBEStats[20].sY = 163; gLBEStats[20].sValDx = 0; //Vest 9
- gLBEStats[21].sX = 413; gLBEStats[21].sY = 163; gLBEStats[21].sValDx = 0; //Vest 10
- gLBEStats[22].sX = 449; gLBEStats[22].sY = 139; gLBEStats[22].sValDx = 0; //Vest 11
- gLBEStats[23].sX = 449; gLBEStats[23].sY = 163; gLBEStats[23].sValDx = 0; //Vest 12
- gLBEStats[24].sX = 585; gLBEStats[24].sY = 10; gLBEStats[24].sValDx = 0; //CPack 1
- gLBEStats[25].sX = 621; gLBEStats[25].sY = 10; gLBEStats[25].sValDx = 0; //CPack 2
- gLBEStats[26].sX = 585; gLBEStats[26].sY = 34; gLBEStats[26].sValDx = 0; //CPack 3
- gLBEStats[27].sX = 621; gLBEStats[27].sY = 34; gLBEStats[27].sValDx = 0; //CPack 4
- gLBEStats[28].sX = 657; gLBEStats[28].sY = 10; gLBEStats[28].sValDx = 0; //CPack 5
- gLBEStats[29].sX = 657; gLBEStats[29].sY = 34; gLBEStats[29].sValDx = 0; //CPack 6
- gLBEStats[30].sX = 657; gLBEStats[30].sY = 58; gLBEStats[30].sValDx = 0; //CPack 7
+ gLBEStats[12].sX = 125; gLBEStats[12].sY = 139; gLBEStats[12].sValDx = 0; //Vest 1
+ gLBEStats[13].sX = 161; gLBEStats[13].sY = 139; gLBEStats[13].sValDx = 0; //Vest 2
+ gLBEStats[14].sX = 197; gLBEStats[14].sY = 139; gLBEStats[14].sValDx = 0; //Vest 3
+ gLBEStats[15].sX = 233; gLBEStats[15].sY = 139; gLBEStats[15].sValDx = 0; //Vest 4
+ gLBEStats[16].sX = 269; gLBEStats[16].sY = 139; gLBEStats[16].sValDx = 0; //Vest 5
+ gLBEStats[17].sX = 125; gLBEStats[17].sY = 163; gLBEStats[17].sValDx = 0; //Vest 6
+ gLBEStats[18].sX = 161; gLBEStats[18].sY = 163; gLBEStats[18].sValDx = 0; //Vest 7
+ gLBEStats[19].sX = 197; gLBEStats[19].sY = 163; gLBEStats[19].sValDx = 0; //Vest 8
+ gLBEStats[20].sX = 233; gLBEStats[20].sY = 163; gLBEStats[20].sValDx = 0; //Vest 9
+ gLBEStats[21].sX = 269; gLBEStats[21].sY = 163; gLBEStats[21].sValDx = 0; //Vest 10
+ gLBEStats[22].sX = 305; gLBEStats[22].sY = 139; gLBEStats[22].sValDx = 0; //Vest 11
+ gLBEStats[23].sX = 305; gLBEStats[23].sY = 163; gLBEStats[23].sValDx = 0; //Vest 12
+ gLBEStats[24].sX = 442; gLBEStats[24].sY = 10; gLBEStats[24].sValDx = 0; //CPack 1
+ gLBEStats[25].sX = 478; gLBEStats[25].sY = 10; gLBEStats[25].sValDx = 0; //CPack 2
+ gLBEStats[26].sX = 442; gLBEStats[26].sY = 34; gLBEStats[26].sValDx = 0; //CPack 3
+ gLBEStats[27].sX = 478; gLBEStats[27].sY = 34; gLBEStats[27].sValDx = 0; //CPack 4
+ gLBEStats[28].sX = 514; gLBEStats[28].sY = 10; gLBEStats[28].sValDx = 0; //CPack 5
+ gLBEStats[29].sX = 514; gLBEStats[29].sY = 34; gLBEStats[29].sValDx = 0; //CPack 6
+ gLBEStats[30].sX = 514; gLBEStats[30].sY = 58; gLBEStats[30].sValDx = 0; //CPack 7
gLBEStats[31].sX = 0; gLBEStats[31].sY = 0; gLBEStats[31].sValDx = 0; //CPack 8
gLBEStats[32].sX = 0; gLBEStats[32].sY = 0; gLBEStats[32].sValDx = 0; //CPack 9
gLBEStats[33].sX = 0; gLBEStats[33].sY = 0; gLBEStats[33].sValDx = 0; //CPack 10
gLBEStats[34].sX = 0; gLBEStats[34].sY = 0; gLBEStats[34].sValDx = 0; //CPack 11
gLBEStats[35].sX = 0; gLBEStats[35].sY = 0; gLBEStats[35].sValDx = 0; //CPack 12
- gLBEStats[36].sX = 585; gLBEStats[36].sY = 10; gLBEStats[36].sValDx = 0; //BPack 1
- gLBEStats[37].sX = 585; gLBEStats[37].sY = 34; gLBEStats[37].sValDx = 0; //BPack 2
- gLBEStats[38].sX = 585; gLBEStats[38].sY = 58; gLBEStats[38].sValDx = 0; //BPack 3
- gLBEStats[39].sX = 585; gLBEStats[39].sY = 82; gLBEStats[39].sValDx = 0; //BPack 4
- gLBEStats[40].sX = 621; gLBEStats[40].sY = 10; gLBEStats[40].sValDx = 0; //BPack 5
- gLBEStats[41].sX = 621; gLBEStats[41].sY = 34; gLBEStats[41].sValDx = 0; //BPack 6
- gLBEStats[42].sX = 621; gLBEStats[42].sY = 58; gLBEStats[42].sValDx = 0; //BPack 7
- gLBEStats[43].sX = 621; gLBEStats[43].sY = 82; gLBEStats[43].sValDx = 0; //BPack 8
- gLBEStats[44].sX = 657; gLBEStats[44].sY = 10; gLBEStats[44].sValDx = 0; //BPack 9
- gLBEStats[45].sX = 657; gLBEStats[45].sY = 34; gLBEStats[45].sValDx = 0; //BPack 10
- gLBEStats[46].sX = 657; gLBEStats[46].sY = 58; gLBEStats[46].sValDx = 0; //BPack 11
- gLBEStats[47].sX = 657; gLBEStats[47].sY = 82; gLBEStats[47].sValDx = 0; //BPack 12
+ gLBEStats[36].sX = 442; gLBEStats[36].sY = 10; gLBEStats[36].sValDx = 0; //BPack 1
+ gLBEStats[37].sX = 442; gLBEStats[37].sY = 34; gLBEStats[37].sValDx = 0; //BPack 2
+ gLBEStats[38].sX = 442; gLBEStats[38].sY = 58; gLBEStats[38].sValDx = 0; //BPack 3
+ gLBEStats[39].sX = 442; gLBEStats[39].sY = 82; gLBEStats[39].sValDx = 0; //BPack 4
+ gLBEStats[40].sX = 478; gLBEStats[40].sY = 10; gLBEStats[40].sValDx = 0; //BPack 5
+ gLBEStats[41].sX = 478; gLBEStats[41].sY = 34; gLBEStats[41].sValDx = 0; //BPack 6
+ gLBEStats[42].sX = 478; gLBEStats[42].sY = 58; gLBEStats[42].sValDx = 0; //BPack 7
+ gLBEStats[43].sX = 478; gLBEStats[43].sY = 82; gLBEStats[43].sValDx = 0; //BPack 8
+ gLBEStats[44].sX = 514; gLBEStats[44].sY = 10; gLBEStats[44].sValDx = 0; //BPack 9
+ gLBEStats[45].sX = 514; gLBEStats[45].sY = 34; gLBEStats[45].sValDx = 0; //BPack 10
+ gLBEStats[46].sX = 514; gLBEStats[46].sY = 58; gLBEStats[46].sValDx = 0; //BPack 11
+ gLBEStats[47].sX = 514; gLBEStats[47].sY = 82; gLBEStats[47].sValDx = 0; //BPack 12
}
}
}
-void InitItemDescriptionBoxOffsets()
+void InitItemDescriptionBoxOffsets(OBJECTTYPE * pObject)
{
- // Initiate variables for Enhanced Item Description Box system
- if(guiCurrentScreen ==MAP_SCREEN) //Strategic
- {
- if(UsingEDBSystem() > 0)
+ if(UsingNewAttachmentSystem()==true){
+ INT16 sY = gsInvDescY + sNASYCorrection(pObject);
+ INT16 sX = gsInvDescX + sNASXCorrection(pObject);
+
+ // Initiate variables for Enhanced Item Description Box system
+ if(guiCurrentScreen ==MAP_SCREEN) //Strategic
{
- // STRATEGIC Description Box Icons
- BULLET_DRAW_X = (112 + gsInvDescX);
- BULLET_DRAW_Y = (136 + gsInvDescY);
- BULLET_SING_X = (112 + gsInvDescX);
- BULLET_SING_Y = (148 + gsInvDescY);
- BULLET_BURST_X = (112 + gsInvDescX);
- BULLET_BURST_Y = (160 + gsInvDescY);
- BULLET_AUTO_X = (112 + gsInvDescX);
- BULLET_AUTO_Y = (172 + gsInvDescY);
- BULLET_RELOAD_X = (112 + gsInvDescX);
- BULLET_RELOAD_Y = (184 + gsInvDescY);
- BULLET_MRELOAD_X = (112 + gsInvDescX);
- BULLET_MRELOAD_Y = (196 + gsInvDescY);
- BULLET_RANGE_X = (47 + gsInvDescX);
- BULLET_RANGE_Y = (124 + gsInvDescY);
- BULLET_DAMAGE_X = (47 + gsInvDescX);
- BULLET_DAMAGE_Y = (136 + gsInvDescY);
- BULLET_AUTOPEN_X = (47 + gsInvDescX);
- BULLET_AUTOPEN_Y = (148 + gsInvDescY);
- BULLET_AUTO5AP_X = (47 + gsInvDescX);
- BULLET_AUTO5AP_Y = (160 + gsInvDescY);
- BULLET_ACC_X = (47 + gsInvDescX);
- BULLET_ACC_Y = (172 + gsInvDescY);
- BULLET_RELIABILITY_X = (47 + gsInvDescX);
- BULLET_RELIABILITY_Y = (184 + gsInvDescY);
- BULLET_REPAIR_X = (47 + gsInvDescX);
- BULLET_REPAIR_Y = (196 + gsInvDescY);
- BULLET_LOUDNESS_X = (174 + gsInvDescX);
- BULLET_LOUDNESS_Y = (136 + gsInvDescY);
- BULLET_FLASH_X = (198 + gsInvDescX);
- BULLET_FLASH_Y = (124 + gsInvDescY);
- BULLET_TOHIT_X = (174 + gsInvDescX);
- BULLET_TOHIT_Y = (148 + gsInvDescY);
- BULLET_BESTLASERRANGE_X = (174 + gsInvDescX);
- BULLET_BESTLASERRANGE_Y = (160 + gsInvDescY);
- BULLET_AIMBONUS_X = (174 + gsInvDescX);
- BULLET_AIMBONUS_Y = (172 + gsInvDescY);
- BULLET_MINRANGEAIMBONUS_X = (174 + gsInvDescX);
- BULLET_MINRANGEAIMBONUS_Y = (184 + gsInvDescY);
- BULLET_BIPOD_X = (174 + gsInvDescX);
- BULLET_BIPOD_Y = (196 + gsInvDescY);
+ if(UsingEDBSystem() > 0)
+ {
+ //WarmSteel - LBE and money do not get a NAS discription box.
+ if(!UseNASDesc(pObject)){
+ ITEMDESC_CALIBER_X = (105 + sX);
+ ITEMDESC_CALIBER_Y = ( 66 + sY);
+ ITEMDESC_CALIBER_WIDTH = 149;
+ ITEMDESC_NAME_X = ( 7 + sX);
+ ITEMDESC_NAME_Y = ( 65 + sY);
+ ITEMDESC_ITEM_X = ( 25 + sX);
+ ITEMDESC_ITEM_Y = ( 6 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 18 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 53 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = (28 + sX);
+ ITEMDESC_AMMO_Y = (44 + sY);
+ ITEMDESC_DONE_X = (199 + sX);
+ ITEMDESC_DONE_Y = (334 + sY);
- // Icon Locations for AMMO stats
- BULLET_ARMORPEN_X = (47 + gsInvDescX);
- BULLET_ARMORPEN_Y = (124 + gsInvDescY);
- BULLET_TUMBLE_X = (47 + gsInvDescX);
- BULLET_TUMBLE_Y = (136 + gsInvDescY);
- BULLET_PREARMOR_X = (47 + gsInvDescX);
- BULLET_PREARMOR_Y = (148 + gsInvDescY);
- BULLET_TRACER_X = (115 + gsInvDescX);
- BULLET_TRACER_Y = (124 + gsInvDescY);
- BULLET_ANTITANK_X = (140 + gsInvDescX);
- BULLET_ANTITANK_Y = (124 + gsInvDescY);
- BULLET_LOCKBUSTER_X = (115 + gsInvDescX);
- BULLET_LOCKBUSTER_Y = (148 + gsInvDescY);
- BULLET_IGNOREARMOR_X = (140 + gsInvDescX);
- BULLET_IGNOREARMOR_Y = (148 + gsInvDescY);
- BULLET_ACIDIC_X = (115 + gsInvDescX);
- BULLET_ACIDIC_Y = (172 + gsInvDescY);
- BULLET_AMMORANGEBON_X = (174 + gsInvDescX);
- BULLET_AMMORANGEBON_Y = (124 + gsInvDescY);
- BULLET_AMMODAMAGEBON_X = (174 + gsInvDescX);
- BULLET_AMMODAMAGEBON_Y = (136 + gsInvDescY);
- BULLET_AMMOTOHITBON_X = (174 + gsInvDescX);
- BULLET_AMMOTOHITBON_Y = (148 + gsInvDescY);
- BULLET_AMMOAUTOBON_X = (174 + gsInvDescX);
- BULLET_AMMOAUTOBON_Y = (160 + gsInvDescY);
- BULLET_AMMOBURSTBON_X = (174 + gsInvDescX);
- BULLET_AMMOBURSTBON_Y = (172 + gsInvDescY);
- BULLET_AMMORELIABILITYBON_X = (174 + gsInvDescX);
- BULLET_AMMORELIABILITYBON_Y = (184 + gsInvDescY);
- BULLET_AMMONOISESUPP_X = (174 + gsInvDescX);
- BULLET_AMMONOISESUPP_Y = (196 + gsInvDescY);
+ } else {
- // Icon Locations for EXPLOSIVES stats
- BULLET_EXPLOSIVEDAMAGE_X = (47 + gsInvDescX);
- BULLET_EXPLOSIVEDAMAGE_Y = (124 + gsInvDescY);
- BULLET_EXPLOSIVESTUNDAMAGE_X = (47 + gsInvDescX);
- BULLET_EXPLOSIVESTUNDAMAGE_Y = (136 + gsInvDescY);
- BULLET_EXPLOSIVELOUDNESS_X = (47 + gsInvDescX);
- BULLET_EXPLOSIVELOUDNESS_Y = (148 + gsInvDescY);
- BULLET_EXPLOSIVEVOLATILITY_X = (47 + gsInvDescX);
- BULLET_EXPLOSIVEVOLATILITY_Y = (160 + gsInvDescY);
- BULLET_EXPLOSIVERADIUS_X = (131 + gsInvDescX);
- BULLET_EXPLOSIVERADIUS_Y = (124 + gsInvDescY);
- BULLET_EXPLOSIVESTARTRADIUS_X = (113 + gsInvDescX);
- BULLET_EXPLOSIVESTARTRADIUS_Y = (124 + gsInvDescY);
- BULLET_EXPLOSIVEARROW_X = (131 + gsInvDescX);
- BULLET_EXPLOSIVEARROW_Y = (130 + gsInvDescY);
- BULLET_EXPLOSIVEENDRADIUS_X = (146 + gsInvDescX);
- BULLET_EXPLOSIVEENDRADIUS_Y = (124 + gsInvDescY);
- BULLET_EXPLOSIVEDURATION_X = (112 + gsInvDescX);
- BULLET_EXPLOSIVEDURATION_Y = (172 + gsInvDescY);
-
- // Icon Locations for ARMOR stats
- BULLET_ARMOR_X = (47 + gsInvDescX);
- BULLET_ARMOR_Y = (124 + gsInvDescY);
- BULLET_ARMORCOVERAGE_X = (47 + gsInvDescX);
- BULLET_ARMORCOVERAGE_Y = (136 + gsInvDescY);
- BULLET_ARMORDEGRADE_X = (47 + gsInvDescX);
- BULLET_ARMORDEGRADE_Y = (148 + gsInvDescY);
- BULLET_ARMORAPBONUS_X = (112 + gsInvDescX);
- BULLET_ARMORAPBONUS_Y = (124 + gsInvDescY);
- BULLET_ARMORAIMBONUS_X = (112 + gsInvDescX);
- BULLET_ARMORAIMBONUS_Y = (136 + gsInvDescY);
- BULLET_ARMORWOODCAMO_X = (112 + gsInvDescX);
- BULLET_ARMORWOODCAMO_Y = (148 + gsInvDescY);
- BULLET_ARMORURBANCAMO_X = (112 + gsInvDescX);
- BULLET_ARMORURBANCAMO_Y = (160 + gsInvDescY);
- BULLET_ARMORDESERTCAMO_X = (112 + gsInvDescX);
- BULLET_ARMORDESERTCAMO_Y = (172 + gsInvDescY);
- BULLET_ARMORSNOWCAMO_X = (112 + gsInvDescX);
- BULLET_ARMORSNOWCAMO_Y = (184 + gsInvDescY);
- BULLET_ARMORSTEALTH_X = (112 + gsInvDescX);
- BULLET_ARMORSTEALTH_Y = (196 + gsInvDescY);
- BULLET_ARMORVISIONRANGEBONUS_X = (174 + gsInvDescX);
- BULLET_ARMORVISIONRANGEBONUS_Y = (124 + gsInvDescY);
- BULLET_ARMORDAYVISIONRANGEBONUS_X = (175 + gsInvDescX);
- BULLET_ARMORDAYVISIONRANGEBONUS_Y = (136 + gsInvDescY);
- BULLET_ARMORNIGHTVISIONRANGEBONUS_X = (175 + gsInvDescX);
- BULLET_ARMORNIGHTVISIONRANGEBONUS_Y = (148 + gsInvDescY);
- BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_X = (175 + gsInvDescX);
- BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_Y = (160 + gsInvDescY);
- BULLET_ARMORCAVEVISIONRANGEBONUS_X = (175 + gsInvDescX);
- BULLET_ARMORCAVEVISIONRANGEBONUS_Y = (172 + gsInvDescY);
- BULLET_ARMORPERCENTTUNNELVISION_X = (175 + gsInvDescX);
- BULLET_ARMORPERCENTTUNNELVISION_Y = (184 + gsInvDescY);
- BULLET_ARMORHEARINGRANGEBONUS_X = (174 + gsInvDescX);
- BULLET_ARMORHEARINGRANGEBONUS_Y = (196 + gsInvDescY);
-
- // Generic Icon Locations for MISC Item Stats
- BULLET_COL1ROW1_X = (47 + gsInvDescX);
- BULLET_COL1ROW1_Y = (124 + gsInvDescY);
- BULLET_COL1ROW2_X = (47 + gsInvDescX);
- BULLET_COL1ROW2_Y = (136 + gsInvDescY);
- BULLET_COL1ROW3_X = (47 + gsInvDescX);
- BULLET_COL1ROW3_Y = (148 + gsInvDescY);
- BULLET_COL1ROW4_X = (47 + gsInvDescX);
- BULLET_COL1ROW4_Y = (160 + gsInvDescY);
- BULLET_COL1ROW5_X = (47 + gsInvDescX);
- BULLET_COL1ROW5_Y = (172 + gsInvDescY);
- BULLET_COL1ROW6_X = (47 + gsInvDescX);
- BULLET_COL1ROW6_Y = (184 + gsInvDescY);
- BULLET_COL1ROW7_X = (47 + gsInvDescX);
- BULLET_COL1ROW7_Y = (196 + gsInvDescY);
- BULLET_COL2ROW1_X = (144 + gsInvDescX);
- BULLET_COL2ROW1_Y = (124 + gsInvDescY);
- BULLET_COL2ROW2_X = (144 + gsInvDescX);
- BULLET_COL2ROW2_Y = (136 + gsInvDescY);
- BULLET_COL2ROW3_X = (144 + gsInvDescX);
- BULLET_COL2ROW3_Y = (148 + gsInvDescY);
- BULLET_COL2ROW4_X = (144 + gsInvDescX);
- BULLET_COL2ROW4_Y = (160 + gsInvDescY);
- BULLET_COL2ROW5_X = (144 + gsInvDescX);
- BULLET_COL2ROW5_Y = (172 + gsInvDescY);
- BULLET_COL2ROW6_X = (144 + gsInvDescX);
- BULLET_COL2ROW6_Y = (184 + gsInvDescY);
- BULLET_COL2ROW7_X = (144 + gsInvDescX);
- BULLET_COL2ROW7_Y = (196 + gsInvDescY);
-
- ITEMDESC_CALIBER_X = (105 + gsInvDescX);
- ITEMDESC_CALIBER_Y = ( 66 + gsInvDescY);
- ITEMDESC_CALIBER_WIDTH = 149;
- ITEMDESC_NAME_X = ( 7 + gsInvDescX);
- ITEMDESC_NAME_Y = ( 65 + gsInvDescY);
- ITEMDESC_ITEM_X = ( 25 + gsInvDescX);
- ITEMDESC_ITEM_Y = ( 6 + gsInvDescY);
- // END ICONS SEGMENT
- ITEMDESC_DESC_START_X = ( 23 + gsInvDescX );
- ITEMDESC_DESC_START_Y = (230 + gsInvDescY);
- ITEMDESC_PROS_START_X = ( 23 + gsInvDescX );
- ITEMDESC_PROS_START_Y = (290 + gsInvDescY);
- ITEMDESC_CONS_START_X = ( 23 + gsInvDescX );
- ITEMDESC_CONS_START_Y = (300 + gsInvDescY);
- ITEMDESC_DESC_WIDTH = 220;
- ITEMDESC_ITEM_STATUS_X = ( 18 + gsInvDescX );
- ITEMDESC_ITEM_STATUS_Y = ( 53 + gsInvDescY );
- ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_CALIBER_X = (105 + sX);
+ ITEMDESC_CALIBER_Y = ( 66 + sY);
+ ITEMDESC_CALIBER_WIDTH = 149;
+ ITEMDESC_NAME_X = ( 7 + sX);
+ ITEMDESC_NAME_Y = ( 65 + sY);
+ ITEMDESC_ITEM_X = ( 54 +sX);
+ ITEMDESC_ITEM_Y = ( -51 +sY);
+ ITEMDESC_ITEM_STATUS_X = ( 47 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( -4 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = (55 + sX);
+ ITEMDESC_AMMO_Y = (-14 + sY);
+ ITEMDESC_DONE_X = (199 + sX);
+ ITEMDESC_DONE_Y = (334 + sY);
+ }
+ }
+ else
+ {
+ //WarmSteel - LBE and money do not get a NAS discription box.
+ if(!UseNASDesc(pObject)){
+ ITEMDESC_CALIBER_X = (105 + sX);
+ ITEMDESC_CALIBER_Y = ( 66 + sY);
+ ITEMDESC_CALIBER_WIDTH = 149;
+ ITEMDESC_NAME_X = ( 7 + sX);
+ ITEMDESC_NAME_Y = ( 65 + sY);
+ ITEMDESC_ITEM_X = ( 25 + sX);
+ ITEMDESC_ITEM_Y = ( 6 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 18 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 53 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = (28 + sX);
+ ITEMDESC_AMMO_Y = (44 + sY);
+ ITEMDESC_DONE_X = (204 + sX);
+ ITEMDESC_DONE_Y = (107 + sY);
+ } else {
+ ITEMDESC_CALIBER_X = (105 + sX);
+ ITEMDESC_CALIBER_Y = ( 65 + sY);
+ ITEMDESC_CALIBER_WIDTH = 149;
+ ITEMDESC_NAME_X = ( 7 + sX);
+ ITEMDESC_NAME_Y = ( 65 + sY);
+ ITEMDESC_ITEM_X = ( 54 + sX);
+ ITEMDESC_ITEM_Y = ( -51 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 47 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( -4 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = (54 + sX);
+ ITEMDESC_AMMO_Y = (-15 + sY);
+ ITEMDESC_DONE_X = (204 + sX);
+ ITEMDESC_DONE_Y = (107 + sY);
+ }
+ }
}
- else
+ else //Tactical
{
- // STRATEGIC Description Box Icon locations
- BULLET_SING_X = ( 77 + gsInvDescX);
- BULLET_SING_Y = (135 + gsInvDescY);
- BULLET_BURST_X = (117 + gsInvDescX);
- BULLET_BURST_Y = (135 + gsInvDescY);
- ITEMDESC_CALIBER_X = (105 + gsInvDescX);
- ITEMDESC_CALIBER_Y = ( 66 + gsInvDescY);
- ITEMDESC_CALIBER_WIDTH = 149;
- ITEMDESC_NAME_X = ( 7 + gsInvDescX);
- ITEMDESC_NAME_Y = ( 65 + gsInvDescY);
- ITEMDESC_ITEM_X = ( 25 + gsInvDescX);
- ITEMDESC_ITEM_Y = ( 6 + gsInvDescY);
- // END ICONS SEGMENT
- ITEMDESC_DESC_START_X = ( 23 + gsInvDescX ); // Description Text Box, Strategic
- ITEMDESC_DESC_START_Y = (170 + gsInvDescY);
- ITEMDESC_PROS_START_X = ( 23 + gsInvDescX ); // Pros, Strategic
- ITEMDESC_PROS_START_Y = (230 + gsInvDescY);
- ITEMDESC_CONS_START_X = ( 23 + gsInvDescX ); // Cons, Strategic
- ITEMDESC_CONS_START_Y = (240 + gsInvDescY);
- ITEMDESC_DESC_WIDTH = 220;
- ITEMDESC_ITEM_STATUS_X = ( 18 + gsInvDescX );
- ITEMDESC_ITEM_STATUS_Y = ( 53 + gsInvDescY );
- ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ if(UsingEDBSystem() == 1) // NIV EDB
+ {
+ //WarmSteel - LBE and money do not get a NAS discription box.
+ if(!UseNASDesc(pObject)){
+ // Icon locations, Tactical
+ ITEMDESC_CALIBER_X = (50 + sX);
+ ITEMDESC_CALIBER_Y = (78 + sY);
+ ITEMDESC_CALIBER_WIDTH = 240;
+ ITEMDESC_NAME_X = (16 + sX);
+ ITEMDESC_NAME_Y = (67 + sY);
+ ITEMDESC_ITEM_X = ( 15 + sX);
+ ITEMDESC_ITEM_Y = ( 8 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 6 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 53 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = (15 + sX);
+ ITEMDESC_AMMO_Y = (43 + sY);
+ } else {
+ ITEMDESC_CALIBER_X = (-180 + sX);
+ ITEMDESC_CALIBER_Y = (180 + sY);
+ ITEMDESC_CALIBER_WIDTH = 240;
+ ITEMDESC_NAME_X = (-180 + sX);
+ ITEMDESC_NAME_Y = (180 + sY);
+ ITEMDESC_ITEM_X = ( -133 + sX);
+ ITEMDESC_ITEM_Y = ( 63 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( -143 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 109 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = (-135 + sX);
+ ITEMDESC_AMMO_Y = (99 + sY);
+ }
+ } else {
+
+ //WarmSteel - LBE and money do not get a NAS discription box.
+ if(!UseNASDesc(pObject)){
+ ITEMDESC_CALIBER_X = (16 + sX); // Gun Caliber string location, Tactical, money or LBE
+ ITEMDESC_CALIBER_Y = (67 + sY);
+ ITEMDESC_CALIBER_WIDTH = 240;//142;
+ ITEMDESC_NAME_X = (16 + sX);
+ ITEMDESC_NAME_Y = (67 + sY);
+ ITEMDESC_ITEM_X = ( 15 + sX);
+ ITEMDESC_ITEM_Y = ( 8 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 6 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 53 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = 15 + sX;
+ ITEMDESC_AMMO_Y = 43 + sY;
+ } else {
+ // Icon locations, TACTICAL
+ ITEMDESC_CALIBER_X = (-80 + sX); // Gun Caliber string location, Tactical
+ ITEMDESC_CALIBER_Y = (180 + sY);
+ ITEMDESC_CALIBER_WIDTH = 240;//142;
+ ITEMDESC_NAME_X = (-80 + sX);
+ ITEMDESC_NAME_Y = (180 + sY);
+ ITEMDESC_ITEM_X = ( -33 + sX);
+ ITEMDESC_ITEM_Y = ( 64 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( -42 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 109 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = -33 + sX;
+ ITEMDESC_AMMO_Y = 99 + sY;
+ }
+ }
}
- }
- else //Tactical
- {
- if(UsingEDBSystem() == 1) // NIV EDB
+ } else {
+ INT16 sY = gsInvDescY;
+ INT16 sX = gsInvDescX;
+
+ // Initiate variables for Enhanced Item Description Box system
+ if(guiCurrentScreen ==MAP_SCREEN) //Strategic
{
- // Icon locations, Tactical
- BULLET_DRAW_X = (268 + gsInvDescX);
- BULLET_DRAW_Y = (56 + gsInvDescY);
- BULLET_SING_X = (268 + gsInvDescX);
- BULLET_SING_Y = (68 + gsInvDescY);
- BULLET_BURST_X = (268 + gsInvDescX);
- BULLET_BURST_Y = (80 + gsInvDescY);
- BULLET_AUTO_X = (268 + gsInvDescX);
- BULLET_AUTO_Y = (92 + gsInvDescY);
- BULLET_RELOAD_X = (268 + gsInvDescX);
- BULLET_RELOAD_Y = (104 + gsInvDescY);
- BULLET_MRELOAD_X = (268 + gsInvDescX);
- BULLET_MRELOAD_Y = (116 + gsInvDescY);
- BULLET_RANGE_X = (203 + gsInvDescX);
- BULLET_RANGE_Y = (44 + gsInvDescY);
- BULLET_DAMAGE_X = (203 + gsInvDescX);
- BULLET_DAMAGE_Y = (56 + gsInvDescY);
- BULLET_AUTOPEN_X = (203 + gsInvDescX);
- BULLET_AUTOPEN_Y = (68 + gsInvDescY);
- BULLET_AUTO5AP_X = (203 + gsInvDescX);
- BULLET_AUTO5AP_Y = (80 + gsInvDescY);
- BULLET_ACC_X = (203 + gsInvDescX);
- BULLET_ACC_Y = (92 + gsInvDescY);
- BULLET_RELIABILITY_X = (203 + gsInvDescX);
- BULLET_RELIABILITY_Y = (104 + gsInvDescY);
- BULLET_REPAIR_X = (203 + gsInvDescX);
- BULLET_REPAIR_Y = (116 + gsInvDescY);
- BULLET_FLASH_X = (226 + gsInvDescX); //291
- BULLET_FLASH_Y = (136 + gsInvDescY); //136
- BULLET_LOUDNESS_X = (203 + gsInvDescX); //268
- BULLET_LOUDNESS_Y = (160 + gsInvDescY); //159
- BULLET_TOHIT_X = (268 + gsInvDescX); //203
- BULLET_TOHIT_Y = (136 + gsInvDescY); //136
- BULLET_BESTLASERRANGE_X = (268 + gsInvDescX); //203
- BULLET_BESTLASERRANGE_Y = (148 + gsInvDescY); //148
- BULLET_AIMBONUS_X = (268 + gsInvDescX); //203
- BULLET_AIMBONUS_Y = (160 + gsInvDescY); //160
- BULLET_MINRANGEAIMBONUS_X = (268 + gsInvDescX); //203
- BULLET_MINRANGEAIMBONUS_Y = (172 + gsInvDescY); //172
- BULLET_BIPOD_X = (203 + gsInvDescX); //268
- BULLET_BIPOD_Y = (172 + gsInvDescY); //171
-
- // Icon Locations for AMMO stats
- BULLET_ARMORPEN_X = (203 + gsInvDescX);
- BULLET_ARMORPEN_Y = (44 + gsInvDescY);
- BULLET_TUMBLE_X = (203 + gsInvDescX);
- BULLET_TUMBLE_Y = (56 + gsInvDescY);
- BULLET_PREARMOR_X = (203 + gsInvDescX);
- BULLET_PREARMOR_Y = (68 + gsInvDescY);
- BULLET_TRACER_X = (271 + gsInvDescX);
- BULLET_TRACER_Y = (44 + gsInvDescY);
- BULLET_ANTITANK_X = (296 + gsInvDescX);
- BULLET_ANTITANK_Y = (44 + gsInvDescY);
- BULLET_LOCKBUSTER_X = (271 + gsInvDescX);
- BULLET_LOCKBUSTER_Y = (68 + gsInvDescY);
- BULLET_IGNOREARMOR_X = (296 + gsInvDescX);
- BULLET_IGNOREARMOR_Y = (68 + gsInvDescY);
- BULLET_ACIDIC_X = (271 + gsInvDescX);
- BULLET_ACIDIC_Y = (92 + gsInvDescY);
- BULLET_AMMORANGEBON_X = (203 + gsInvDescX);
- BULLET_AMMORANGEBON_Y = (136 + gsInvDescY);
- BULLET_AMMODAMAGEBON_X = (203 + gsInvDescX);
- BULLET_AMMODAMAGEBON_Y = (160 + gsInvDescY);
- BULLET_AMMOTOHITBON_X = (268 + gsInvDescX);
- BULLET_AMMOTOHITBON_Y = (136 + gsInvDescY);
- BULLET_AMMORELIABILITYBON_X = (203 + gsInvDescX);
- BULLET_AMMORELIABILITYBON_Y = (172 + gsInvDescY);
- BULLET_AMMOAUTOBON_X = (268 + gsInvDescX);
- BULLET_AMMOAUTOBON_Y = (148 + gsInvDescY);
- BULLET_AMMOBURSTBON_X = (268 + gsInvDescX);
- BULLET_AMMOBURSTBON_Y = (160 + gsInvDescY);
- BULLET_AMMONOISESUPP_X = (268 + gsInvDescX);
- BULLET_AMMONOISESUPP_Y = (172 + gsInvDescY);
-
- // Icon Locations for EXPLOSIVES stats
- BULLET_EXPLOSIVEDAMAGE_X = (203 + gsInvDescX);
- BULLET_EXPLOSIVEDAMAGE_Y = (44 + gsInvDescY);
- BULLET_EXPLOSIVESTUNDAMAGE_X = (203 + gsInvDescX);
- BULLET_EXPLOSIVESTUNDAMAGE_Y = (56 + gsInvDescY);
- BULLET_EXPLOSIVELOUDNESS_X = (203 + gsInvDescX);
- BULLET_EXPLOSIVELOUDNESS_Y = (68 + gsInvDescY);
- BULLET_EXPLOSIVEVOLATILITY_X = (203 + gsInvDescX);
- BULLET_EXPLOSIVEVOLATILITY_Y = (80 + gsInvDescY);
- BULLET_EXPLOSIVERADIUS_X = (288 + gsInvDescX);
- BULLET_EXPLOSIVERADIUS_Y = (44 + gsInvDescY);
- BULLET_EXPLOSIVESTARTRADIUS_X = (270 + gsInvDescX);
- BULLET_EXPLOSIVESTARTRADIUS_Y = (44 + gsInvDescY);
- BULLET_EXPLOSIVEARROW_X = (287 + gsInvDescX);
- BULLET_EXPLOSIVEARROW_Y = (50 + gsInvDescY);
- BULLET_EXPLOSIVEENDRADIUS_X = (303 + gsInvDescX);
- BULLET_EXPLOSIVEENDRADIUS_Y = (44 + gsInvDescY);
- BULLET_EXPLOSIVEDURATION_X = (268 + gsInvDescX);
- BULLET_EXPLOSIVEDURATION_Y = (92 + gsInvDescY);
-
- // Icon Locations for ARMOR stats
- BULLET_ARMOR_X = (203 + gsInvDescX);
- BULLET_ARMOR_Y = (44 + gsInvDescY);
- BULLET_ARMORCOVERAGE_X = (203 + gsInvDescX);
- BULLET_ARMORCOVERAGE_Y = (56 + gsInvDescY);
- BULLET_ARMORDEGRADE_X = (203 + gsInvDescX);
- BULLET_ARMORDEGRADE_Y = (68 + gsInvDescY);
- BULLET_ARMORAPBONUS_X = (268 + gsInvDescX);
- BULLET_ARMORAPBONUS_Y = (44 + gsInvDescY);
- BULLET_ARMORAIMBONUS_X = (268 + gsInvDescX);
- BULLET_ARMORAIMBONUS_Y = (56 + gsInvDescY);
- BULLET_ARMORWOODCAMO_X = (268 + gsInvDescX);
- BULLET_ARMORWOODCAMO_Y = (68 + gsInvDescY);
- BULLET_ARMORURBANCAMO_X = (268 + gsInvDescX);
- BULLET_ARMORURBANCAMO_Y = (80 + gsInvDescY);
- BULLET_ARMORDESERTCAMO_X = (268 + gsInvDescX);
- BULLET_ARMORDESERTCAMO_Y = (92 + gsInvDescY);
- BULLET_ARMORSNOWCAMO_X = (268 + gsInvDescX);
- BULLET_ARMORSNOWCAMO_Y = (104 + gsInvDescY);
- BULLET_ARMORSTEALTH_X = (268 + gsInvDescX);
- BULLET_ARMORSTEALTH_Y = (116 + gsInvDescY);
- BULLET_ARMORVISIONRANGEBONUS_X = (203 + gsInvDescX);
- BULLET_ARMORVISIONRANGEBONUS_Y = (136 + gsInvDescY);
- BULLET_ARMORDAYVISIONRANGEBONUS_X = (203 + gsInvDescX);
- BULLET_ARMORDAYVISIONRANGEBONUS_Y = (148 + gsInvDescY);
- BULLET_ARMORNIGHTVISIONRANGEBONUS_X = (203 + gsInvDescX);
- BULLET_ARMORNIGHTVISIONRANGEBONUS_Y = (160 + gsInvDescY);
- BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_X = (203 + gsInvDescX);
- BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_Y = (172 + gsInvDescY);
- BULLET_ARMORCAVEVISIONRANGEBONUS_X = (268 + gsInvDescX);
- BULLET_ARMORCAVEVISIONRANGEBONUS_Y = (136 + gsInvDescY);
- BULLET_ARMORPERCENTTUNNELVISION_X = (268 + gsInvDescX);
- BULLET_ARMORPERCENTTUNNELVISION_Y = (148 + gsInvDescY);
- BULLET_ARMORHEARINGRANGEBONUS_X = (268 + gsInvDescX);
- BULLET_ARMORHEARINGRANGEBONUS_Y = (160 + gsInvDescY);
-
- // Generic Icon Locations for MISC Item Stats
- BULLET_COL1ROW1_X = (203 + gsInvDescX);
- BULLET_COL1ROW1_Y = (44 + gsInvDescY);
- BULLET_COL1ROW2_X = (203 + gsInvDescX);
- BULLET_COL1ROW2_Y = (56 + gsInvDescY);
- BULLET_COL1ROW3_X = (203 + gsInvDescX);
- BULLET_COL1ROW3_Y = (68 + gsInvDescY);
- BULLET_COL1ROW4_X = (203 + gsInvDescX);
- BULLET_COL1ROW4_Y = (80 + gsInvDescY);
- BULLET_COL1ROW5_X = (203 + gsInvDescX);
- BULLET_COL1ROW5_Y = (92 + gsInvDescY);
- BULLET_COL1ROW6_X = (203 + gsInvDescX);
- BULLET_COL1ROW6_Y = (104 + gsInvDescY);
- BULLET_COL1ROW7_X = (203 + gsInvDescX);
- BULLET_COL1ROW7_Y = (116 + gsInvDescY);
- BULLET_COL1ROW8_X = (203 + gsInvDescX);
- BULLET_COL1ROW8_Y = (128 + gsInvDescY);
- BULLET_COL1ROW9_X = (203 + gsInvDescX);
- BULLET_COL1ROW9_Y = (140 + gsInvDescY);
- BULLET_COL1ROW10_X = (203 + gsInvDescX);
- BULLET_COL1ROW10_Y = (152 + gsInvDescY);
- BULLET_COL1ROW11_X = (203 + gsInvDescX);
- BULLET_COL1ROW11_Y = (164 + gsInvDescY);
- BULLET_COL1ROW12_X = (203 + gsInvDescX);
- BULLET_COL1ROW12_Y = (176 + gsInvDescY);
- ITEMDESC_CALIBER_X = ( 50 + gsInvDescX);
- ITEMDESC_CALIBER_Y = ( 78 + gsInvDescY);
- ITEMDESC_CALIBER_WIDTH = 142;
- ITEMDESC_NAME_X = ( 16 + gsInvDescX);
- ITEMDESC_NAME_Y = ( 67 + gsInvDescY);
- ITEMDESC_ITEM_X = ( 8 + gsInvDescX);
- ITEMDESC_ITEM_Y = ( 11 + gsInvDescY);
- ITEMDESC_DESC_START_X = ( 11 + gsInvDescX);
- ITEMDESC_DESC_START_Y = ( 94 + gsInvDescY);
- ITEMDESC_PROS_START_X = ( 11 + gsInvDescX );
- ITEMDESC_PROS_START_Y = (168 + gsInvDescY);
- ITEMDESC_CONS_START_X = ( 11 + gsInvDescX );
- ITEMDESC_CONS_START_Y = (178 + gsInvDescY);
- ITEMDESC_DESC_WIDTH = 180;
- ITEMDESC_ITEM_STATUS_X = ( 6 + gsInvDescX );
- ITEMDESC_ITEM_STATUS_Y = ( 60 + gsInvDescY );
- ITEMDESC_ITEM_STATUS_HEIGHT = 50;
+ if(UsingEDBSystem() > 0)
+ {
+ // STRATEGIC Description Box Icons
+ ITEMDESC_CALIBER_X = (105 + sX);
+ ITEMDESC_CALIBER_Y = ( 66 + sY);
+ ITEMDESC_CALIBER_WIDTH = 149;
+ ITEMDESC_NAME_X = ( 7 + sX);
+ ITEMDESC_NAME_Y = ( 65 + sY);
+ ITEMDESC_ITEM_X = ( 25 + sX);
+ ITEMDESC_ITEM_Y = ( 6 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 18 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 53 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = 10 + 16 + sX;
+ ITEMDESC_AMMO_Y = 50 - 6 + sY;
+ ITEMDESC_DONE_X = 199 + sX;
+ ITEMDESC_DONE_Y = 334 + sY;
+ }
+ else
+ {
+ ITEMDESC_CALIBER_X = (105 + sX);
+ ITEMDESC_CALIBER_Y = ( 66 + sY);
+ ITEMDESC_CALIBER_WIDTH = 149;
+ ITEMDESC_NAME_X = ( 7 + sX);
+ ITEMDESC_NAME_Y = ( 65 + sY);
+ ITEMDESC_ITEM_X = ( 25 + sX);
+ ITEMDESC_ITEM_Y = ( 6 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 18 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 53 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 40;
+ ITEMDESC_AMMO_X = 10 + 18 + sX;
+ ITEMDESC_AMMO_Y = 50 - 6 + sY;
+ ITEMDESC_DONE_X = 204 + sX;
+ ITEMDESC_DONE_Y = 107 + sY;
+ }
}
- else if(UsingEDBSystem() == 2) // OIV EDB
+ else //Tactical
{
- // Icon locations, Tactical
- BULLET_DRAW_X = (341 + gsInvDescX);
- BULLET_DRAW_Y = (26 + gsInvDescY);
- BULLET_SING_X = (341 + gsInvDescX);
- BULLET_SING_Y = (38 + gsInvDescY);
- BULLET_BURST_X = (341 + gsInvDescX);
- BULLET_BURST_Y = (50 + gsInvDescY);
- BULLET_AUTO_X = (341 + gsInvDescX);
- BULLET_AUTO_Y = (62 + gsInvDescY);
- BULLET_RELOAD_X = (341 + gsInvDescX);
- BULLET_RELOAD_Y = (74 + gsInvDescY);
- BULLET_MRELOAD_X = (341 + gsInvDescX);
- BULLET_MRELOAD_Y = (86 + gsInvDescY);
- BULLET_RANGE_X = (274 + gsInvDescX);
- BULLET_RANGE_Y = (14 + gsInvDescY);
- BULLET_DAMAGE_X = (274 + gsInvDescX);
- BULLET_DAMAGE_Y = (26 + gsInvDescY);
- BULLET_AUTOPEN_X = (274 + gsInvDescX);
- BULLET_AUTOPEN_Y = (38 + gsInvDescY);
- BULLET_AUTO5AP_X = (274 + gsInvDescX);
- BULLET_AUTO5AP_Y = (50 + gsInvDescY);
- BULLET_ACC_X = (274 + gsInvDescX);
- BULLET_ACC_Y = (62 + gsInvDescY);
- BULLET_RELIABILITY_X = (274 + gsInvDescX);
- BULLET_RELIABILITY_Y = (74 + gsInvDescY);
- BULLET_REPAIR_X = (274 + gsInvDescX);
- BULLET_REPAIR_Y = (86 + gsInvDescY);
- BULLET_FLASH_X = (431 + gsInvDescX); //291
- BULLET_FLASH_Y = (14 + gsInvDescY); //136
- BULLET_LOUDNESS_X = (408 + gsInvDescX); //268
- BULLET_LOUDNESS_Y = (26 + gsInvDescY); //159
- BULLET_TOHIT_X = (408 + gsInvDescX); //203
- BULLET_TOHIT_Y = (38 + gsInvDescY); //136
- BULLET_BESTLASERRANGE_X = (408 + gsInvDescX); //203
- BULLET_BESTLASERRANGE_Y = (50 + gsInvDescY); //148
- BULLET_AIMBONUS_X = (408 + gsInvDescX); //203
- BULLET_AIMBONUS_Y = (62 + gsInvDescY); //160
- BULLET_MINRANGEAIMBONUS_X = (408 + gsInvDescX); //203
- BULLET_MINRANGEAIMBONUS_Y = (74 + gsInvDescY); //172
- BULLET_BIPOD_X = (408 + gsInvDescX); //268
- BULLET_BIPOD_Y = (86 + gsInvDescY); //171
-
- // Icon Locations for AMMO stats
- BULLET_ARMORPEN_X = (274 + gsInvDescX);
- BULLET_ARMORPEN_Y = (14 + gsInvDescY);
- BULLET_TUMBLE_X = (274 + gsInvDescX);
- BULLET_TUMBLE_Y = (26 + gsInvDescY);
- BULLET_PREARMOR_X = (274 + gsInvDescX);
- BULLET_PREARMOR_Y = (38 + gsInvDescY);
- BULLET_TRACER_X = (344 + gsInvDescX);
- BULLET_TRACER_Y = (14 + gsInvDescY);
- BULLET_ANTITANK_X = (369 + gsInvDescX);
- BULLET_ANTITANK_Y = (14 + gsInvDescY);
- BULLET_LOCKBUSTER_X = (344 + gsInvDescX);
- BULLET_LOCKBUSTER_Y = (38 + gsInvDescY);
- BULLET_IGNOREARMOR_X = (369 + gsInvDescX);
- BULLET_IGNOREARMOR_Y = (38 + gsInvDescY);
- BULLET_ACIDIC_X = (344 + gsInvDescX);
- BULLET_ACIDIC_Y = (62 + gsInvDescY);
- BULLET_AMMORANGEBON_X = (408 + gsInvDescX);
- BULLET_AMMORANGEBON_Y = (14 + gsInvDescY);
- BULLET_AMMODAMAGEBON_X = (408 + gsInvDescX);
- BULLET_AMMODAMAGEBON_Y = (26 + gsInvDescY);
- BULLET_AMMOTOHITBON_X = (408 + gsInvDescX);
- BULLET_AMMOTOHITBON_Y = (38 + gsInvDescY);
- BULLET_AMMOAUTOBON_X = (408 + gsInvDescX);
- BULLET_AMMOAUTOBON_Y = (50 + gsInvDescY);
- BULLET_AMMOBURSTBON_X = (408 + gsInvDescX);
- BULLET_AMMOBURSTBON_Y = (62 + gsInvDescY);
- BULLET_AMMORELIABILITYBON_X = (408 + gsInvDescX);
- BULLET_AMMORELIABILITYBON_Y = (74 + gsInvDescY);
- BULLET_AMMONOISESUPP_X = (408 + gsInvDescX);
- BULLET_AMMONOISESUPP_Y = (86 + gsInvDescY);
-
- // Icon Locations for EXPLOSIVES stats
- BULLET_EXPLOSIVEDAMAGE_X = (274 + gsInvDescX);
- BULLET_EXPLOSIVEDAMAGE_Y = (14 + gsInvDescY);
- BULLET_EXPLOSIVESTUNDAMAGE_X = (274 + gsInvDescX);
- BULLET_EXPLOSIVESTUNDAMAGE_Y = (26 + gsInvDescY);
- BULLET_EXPLOSIVELOUDNESS_X = (274 + gsInvDescX);
- BULLET_EXPLOSIVELOUDNESS_Y = (38 + gsInvDescY);
- BULLET_EXPLOSIVEVOLATILITY_X = (274 + gsInvDescX);
- BULLET_EXPLOSIVEVOLATILITY_Y = (50 + gsInvDescY);
- BULLET_EXPLOSIVERADIUS_X = (359 + gsInvDescX);
- BULLET_EXPLOSIVERADIUS_Y = (14 + gsInvDescY);
- BULLET_EXPLOSIVESTARTRADIUS_X = (343 + gsInvDescX);
- BULLET_EXPLOSIVESTARTRADIUS_Y = (14 + gsInvDescY);
- BULLET_EXPLOSIVEARROW_X = (362 + gsInvDescX);
- BULLET_EXPLOSIVEARROW_Y = (20 + gsInvDescY);
- BULLET_EXPLOSIVEENDRADIUS_X = (378 + gsInvDescX);
- BULLET_EXPLOSIVEENDRADIUS_Y = (14 + gsInvDescY);
- BULLET_EXPLOSIVEDURATION_X = (341 + gsInvDescX);
- BULLET_EXPLOSIVEDURATION_Y = (62 + gsInvDescY);
-
- // Icon Locations for ARMOR stats
- BULLET_ARMOR_X = (274 + gsInvDescX);
- BULLET_ARMOR_Y = (14 + gsInvDescY);
- BULLET_ARMORCOVERAGE_X = (274 + gsInvDescX);
- BULLET_ARMORCOVERAGE_Y = (26 + gsInvDescY);
- BULLET_ARMORDEGRADE_X = (274 + gsInvDescX);
- BULLET_ARMORDEGRADE_Y = (38 + gsInvDescY);
- BULLET_ARMORAPBONUS_X = (341 + gsInvDescX);
- BULLET_ARMORAPBONUS_Y = (14 + gsInvDescY);
- BULLET_ARMORAIMBONUS_X = (341 + gsInvDescX);
- BULLET_ARMORAIMBONUS_Y = (26 + gsInvDescY);
- BULLET_ARMORWOODCAMO_X = (341 + gsInvDescX);
- BULLET_ARMORWOODCAMO_Y = (38 + gsInvDescY);
- BULLET_ARMORURBANCAMO_X = (341 + gsInvDescX);
- BULLET_ARMORURBANCAMO_Y = (50 + gsInvDescY);
- BULLET_ARMORDESERTCAMO_X = (341 + gsInvDescX);
- BULLET_ARMORDESERTCAMO_Y = (62 + gsInvDescY);
- BULLET_ARMORSNOWCAMO_X = (341 + gsInvDescX);
- BULLET_ARMORSNOWCAMO_Y = (74 + gsInvDescY);
- BULLET_ARMORSTEALTH_X = (341 + gsInvDescX);
- BULLET_ARMORSTEALTH_Y = (86 + gsInvDescY);
- BULLET_ARMORVISIONRANGEBONUS_X = (408 + gsInvDescX);
- BULLET_ARMORVISIONRANGEBONUS_Y = (14 + gsInvDescY);
- BULLET_ARMORDAYVISIONRANGEBONUS_X = (408 + gsInvDescX);
- BULLET_ARMORDAYVISIONRANGEBONUS_Y = (26 + gsInvDescY);
- BULLET_ARMORNIGHTVISIONRANGEBONUS_X = (408 + gsInvDescX);
- BULLET_ARMORNIGHTVISIONRANGEBONUS_Y = (38 + gsInvDescY);
- BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_X = (408 + gsInvDescX);
- BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_Y = (50 + gsInvDescY);
- BULLET_ARMORCAVEVISIONRANGEBONUS_X = (408 + gsInvDescX);
- BULLET_ARMORCAVEVISIONRANGEBONUS_Y = (68 + gsInvDescY);
- BULLET_ARMORPERCENTTUNNELVISION_X = (408 + gsInvDescX);
- BULLET_ARMORPERCENTTUNNELVISION_Y = (72 + gsInvDescY);
- BULLET_ARMORHEARINGRANGEBONUS_X = (408 + gsInvDescX);
- BULLET_ARMORHEARINGRANGEBONUS_Y = (86 + gsInvDescY);
-
- // Generic Icon Locations for MISC Item Stats
- BULLET_COL1ROW1_X = (274 + gsInvDescX);
- BULLET_COL1ROW1_Y = (14 + gsInvDescY);
- BULLET_COL1ROW2_X = (274 + gsInvDescX);
- BULLET_COL1ROW2_Y = (26 + gsInvDescY);
- BULLET_COL1ROW3_X = (274 + gsInvDescX);
- BULLET_COL1ROW3_Y = (38 + gsInvDescY);
- BULLET_COL1ROW4_X = (274 + gsInvDescX);
- BULLET_COL1ROW4_Y = (50 + gsInvDescY);
- BULLET_COL1ROW5_X = (274 + gsInvDescX);
- BULLET_COL1ROW5_Y = (62 + gsInvDescY);
- BULLET_COL1ROW6_X = (274 + gsInvDescX);
- BULLET_COL1ROW6_Y = (74 + gsInvDescY);
- BULLET_COL1ROW7_X = (274 + gsInvDescX);
- BULLET_COL1ROW7_Y = (86 + gsInvDescY);
- BULLET_COL1ROW8_X = (375 + gsInvDescX);
- BULLET_COL1ROW8_Y = (14 + gsInvDescY);
- BULLET_COL1ROW9_X = (375 + gsInvDescX);
- BULLET_COL1ROW9_Y = (26 + gsInvDescY);
- BULLET_COL1ROW10_X = (375 + gsInvDescX);
- BULLET_COL1ROW10_Y = (38 + gsInvDescY);
- BULLET_COL1ROW11_X = (375 + gsInvDescX);
- BULLET_COL1ROW11_Y = (50 + gsInvDescY);
- BULLET_COL1ROW12_X = (375 + gsInvDescX);
- BULLET_COL1ROW12_Y = (62 + gsInvDescY);
- ITEMDESC_CALIBER_X = ( 53 + gsInvDescX); // Caliber text moved two lines below item name, and pulled closer
- ITEMDESC_CALIBER_Y = ( 78 + gsInvDescY);
- ITEMDESC_CALIBER_WIDTH = 142;
- ITEMDESC_NAME_X = ( 16 + gsInvDescX);
- ITEMDESC_NAME_Y = ( 67 + gsInvDescY);
- ITEMDESC_ITEM_X = ( 8 + gsInvDescX);
- ITEMDESC_ITEM_Y = ( 11 + gsInvDescY);
- ITEMDESC_DESC_START_X = (11 + gsInvDescX); // Description text Y moved downwards one line.
- ITEMDESC_DESC_START_Y = (102 + gsInvDescY);
- ITEMDESC_PROS_START_X = (438 + gsInvDescX ); // Pros and cons moved to the extreme right of the text box. They
- ITEMDESC_PROS_START_Y = (106 + gsInvDescY); // now show just the words "PROS" and "CONS", and have a tooltip
- ITEMDESC_CONS_START_X = (438 + gsInvDescX ); // region over them for expanded text. :D
- ITEMDESC_CONS_START_Y = (118 + gsInvDescY);
- ITEMDESC_DESC_WIDTH = 415; // Much wider in OIV tactical than other shapes
- ITEMDESC_ITEM_STATUS_X = ( 6 + gsInvDescX );
- ITEMDESC_ITEM_STATUS_Y = ( 60 + gsInvDescY );
- ITEMDESC_ITEM_STATUS_HEIGHT = 50;
- }
- else
- {
- // Icon locations, TACTICAL
- BULLET_SING_X = (222 + gsInvDescX);
- BULLET_SING_Y = (49 + gsInvDescY);
- BULLET_BURST_X = (263 + gsInvDescX);
- BULLET_BURST_Y = (49 + gsInvDescY);
- ITEMDESC_CALIBER_X = (162 + gsInvDescX); // Gun Caliber string location, Tactical
- ITEMDESC_CALIBER_Y = ( 67 + gsInvDescY);
- ITEMDESC_CALIBER_WIDTH = 142;
- ITEMDESC_NAME_X = ( 16 + gsInvDescX);
- ITEMDESC_NAME_Y = ( 67 + gsInvDescY);
- ITEMDESC_ITEM_X = ( 8 + gsInvDescX);
- ITEMDESC_ITEM_Y = ( 11 + gsInvDescY);
- ITEMDESC_DESC_START_X = (11 + gsInvDescX); // Item Desc Box offset, tactical
- ITEMDESC_DESC_START_Y = (80 + gsInvDescY);
- ITEMDESC_PROS_START_X = ( 11 + gsInvDescX ); // Pros, tactical
- ITEMDESC_PROS_START_Y = (110 + gsInvDescY);
- ITEMDESC_CONS_START_X = ( 11 + gsInvDescX ); // Cons, Tactical
- ITEMDESC_CONS_START_Y = (120 + gsInvDescY);
- ITEMDESC_DESC_WIDTH = 301; // Text box width, Tactical
- ITEMDESC_ITEM_STATUS_X = ( 6 + gsInvDescX );
- ITEMDESC_ITEM_STATUS_Y = ( 60 + gsInvDescY );
- ITEMDESC_ITEM_STATUS_HEIGHT = 50;
+ if(UsingEDBSystem() == 1) // NIV EDB
+ {
+ ITEMDESC_CALIBER_X = ( 50 + sX);
+ ITEMDESC_CALIBER_Y = ( 78 + sY);
+ ITEMDESC_CALIBER_WIDTH = 142;
+ ITEMDESC_NAME_X = ( 16 + sX);
+ ITEMDESC_NAME_Y = ( 67 + sY);
+ ITEMDESC_ITEM_X = ( 8 + sX);
+ ITEMDESC_ITEM_Y = ( 11 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 6 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 60 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 50;
+ ITEMDESC_AMMO_X = 10 + sX;
+ ITEMDESC_AMMO_Y = 50 + sY;
+ } else {
+ ITEMDESC_CALIBER_X = (162 + sX); // Gun Caliber string location, Tactical
+ ITEMDESC_CALIBER_Y = ( 67 + sY);
+ ITEMDESC_CALIBER_WIDTH = 142;
+ ITEMDESC_NAME_X = ( 16 + sX);
+ ITEMDESC_NAME_Y = ( 67 + sY);
+ ITEMDESC_ITEM_X = ( 8 + sX);
+ ITEMDESC_ITEM_Y = ( 11 + sY);
+ ITEMDESC_ITEM_STATUS_X = ( 6 + sX );
+ ITEMDESC_ITEM_STATUS_Y = ( 60 + sY );
+ ITEMDESC_ITEM_STATUS_HEIGHT = 50;
+ ITEMDESC_AMMO_X = 10 + sX;
+ ITEMDESC_AMMO_Y = 50 + sY;
+ }
}
}
}
@@ -1914,9 +1220,16 @@ BOOLEAN InternalInitEnhancedDescBox()
strcpy( VObjectDesc.ImageFile, "INTERFACE\\ItemInfoArmorIcons.STI" );
CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoArmorIcon ) );
+ // HEADROCK HAM 4: Secondary icons
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
- strcpy( VObjectDesc.ImageFile, "INTERFACE\\ItemInfoMiscIcons.STI" );
- CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoMiscIcon ) );
+ strcpy( VObjectDesc.ImageFile, "INTERFACE\\ItemInfoSecondaryIcons.STI" );
+ CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoSecondaryIcon ) );
+
+ // HEADROCK HAM 4: Advanced Icons
+ VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
+ strcpy( VObjectDesc.ImageFile, "INTERFACE\\ItemInfoAdvancedIcons.STI" );
+ CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoAdvancedIcon ) );
+
}
return (TRUE);
@@ -1924,1604 +1237,2017 @@ BOOLEAN InternalInitEnhancedDescBox()
void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurrentItemDescriptionScreen )
{
- INT32 cnt;
+ INT32 cnt, cnt2;
INT32 threshold;
+ INT32 iRegionsCreated = 0;
+ INT32 iFirstDataRegion = 0;
- InitEDBCoords();
+ InitEDBCoords( gpItemDescObject );
//start by deleting the currently defined regions if they exist
- for ( cnt = 0; cnt < 20; cnt++ )
+ for ( cnt = 0; cnt < NUM_UDB_FASTHELP_REGIONS; cnt++ )
{
- if( gStatsFasthelpRegions[ cnt ].IDNumber != 0 )
- MSYS_RemoveRegion( &gStatsFasthelpRegions[ cnt ]);
+ if( gUDBFasthelpRegions[ cnt ].IDNumber != 0 )
+ MSYS_RemoveRegion( &gUDBFasthelpRegions[ cnt ]);
}
if( guiCurrentScreen == MAP_SCREEN )
threshold = 13;
else
threshold = 11;
-
- // Strategic EDB
- if ( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+
+
+ /////////////////////////////////////////////////////////////////////////////////
+ // WEAPONS
+ /////////////////////////////////////////////////////////////////////////////////
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH )
{
- ///////////////////////////////////////////
- // Begin Weapon Item Tooltip Regions
-
- if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH )
+ if (gubDescBoxPage == 1)
{
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gWeaponDescStatsRects[ cnt ].iLeft),
- (INT16)(gWeaponDescStatsRects[ cnt ].iTop),
- (INT16)(gWeaponDescStatsRects[ cnt ].iRight),
- (INT16)(gWeaponDescStatsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+ /////////////////// HEADERS
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzWeaponStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
+ for (cnt = 0; cnt < 3; cnt++)
+ {
+ /////////////////// HEADER #1: Primary Properties
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenHeaderRegions[cnt].sLeft),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sTop),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sRight),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ if (cnt > 0)
+ {
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBHeaderTooltipText[ cnt+1 ] );
+ }
+ else
+ {
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBHeaderTooltipText[ cnt ] );
+ }
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
-
- // Enable regions one-by-one as necessary
+
+ ////////////////// INDEXES
+ for (cnt = 0; cnt < 3; cnt++)
+ {
+ for (cnt2 = 0; cnt2 < 4; cnt2++)
+ {
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenIndexRegions[cnt][cnt2].sLeft),
+ (INT16)(gItemDescGenIndexRegions[cnt][cnt2].sTop),
+ (INT16)(gItemDescGenIndexRegions[cnt][cnt2].sRight),
+ (INT16)(gItemDescGenIndexRegions[cnt][cnt2].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
- // Relevant to all weapons
-
- // RELIABILITY
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
-
- // REPAIR EASE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
-
- //////////////////////////////////
- // BEGIN SINGLE ATTACK SEGMENT
-
- // Non-Launcher Guns and Grenade-Launchers only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
-
- // SINGLE-SHOT AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
-
- if ( Weapon[gpItemDescObject->usItem].NoSemiAuto )
- {
- // "NO SINGLE-SHOT"
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelp[ 23 ] );
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBGenIndexTooltipText[ cnt2 ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
}
- // Rocket-Launchers Only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && Item[gpItemDescObject->usItem].rocketlauncher )
+ iFirstDataRegion = iRegionsCreated;
+ CHAR16 pStr[1000];
+
+ ///////////////// PRIMARY DATA - ICONS
+ for (cnt = 0; cnt < 12; cnt++)
{
- // SINGLE ROCKET-LAUNCH AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelp[ 21 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenRegions[cnt][0].sLeft),
+ (INT16)(gItemDescGenRegions[cnt][0].sTop),
+ (INT16)(gItemDescGenRegions[cnt][0].sRight),
+ (INT16)(gItemDescGenRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ if(UsingNewCTHSystem() == true)
+ swprintf( pStr, L"%s%s", szUDBGenWeaponsStatsTooltipText[ cnt ], szUDBGenWeaponsStatsExplanationsTooltipText[ cnt ]);
+ else
+ swprintf( pStr, L"%s", gzWeaponStatsFasthelpTactical[ cnt ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), pStr );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
}
- // Throwing-Knives Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_THROWING_KNIFE )
+ // HEADROCK HAM 4: TODO in the future: Add tooltips explaining how much bonus is given by EACH ATTACHMENT.
+
+ ///////////////// AP COST DATA - ICONS
+ for (cnt = 13; cnt < 19; cnt++)
{
- // THROW KNIFE AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelp[ 20 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenRegions[cnt][0].sLeft),
+ (INT16)(gItemDescGenRegions[cnt][0].sTop),
+ (INT16)(gItemDescGenRegions[cnt][0].sRight),
+ (INT16)(gItemDescGenRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ if(UsingNewCTHSystem() == true)
+ swprintf( pStr, L"%s%s", szUDBGenWeaponsStatsTooltipText[ cnt ], szUDBGenWeaponsStatsExplanationsTooltipText[ cnt ]);
+ else
+ swprintf( pStr, L"%s", gzWeaponStatsFasthelpTactical[ cnt ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), pStr );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
}
- // Blades Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_BLADE )
+ ///////////////// BURST/AUTOFIRE DATA - ICONS
+ for (cnt = 19; cnt < 22; cnt++)
{
- // SLASH AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelp[ 22 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenRegions[cnt][0].sLeft),
+ (INT16)(gItemDescGenRegions[cnt][0].sTop),
+ (INT16)(gItemDescGenRegions[cnt][0].sRight),
+ (INT16)(gItemDescGenRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ if(UsingNewCTHSystem() == true)
+ swprintf( pStr, L"%s%s", szUDBGenWeaponsStatsTooltipText[ cnt ], szUDBGenWeaponsStatsExplanationsTooltipText[ cnt ]);
+ else
+ swprintf( pStr, L"%s", gzWeaponStatsFasthelpTactical[ cnt ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), pStr );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
}
- // Blunts Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_PUNCH )
- {
- // SLASH AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelp[ 26 ] );
- }
+ /////////////////////////////////////////////////////////
+ // Now enable regions that fit this specific weapon's information.
- // END SINGLE ATTACK SEGMENT
- ////////////////////////////////////
-
- ////////////////////////////////////
- // BEGIN BURST ATTACK SEGMENT
-
- // Non-Launcher Guns and Grenade-Launchers only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- // BURST
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 9 ] );
-
- if (GetShotsPerBurst(gpItemDescObject) <= 0 )
- {
- // "NO BURST"
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 9 ]), gzWeaponStatsFasthelp[ 24 ] );
- }
- }
-
- // END BURST ATTACK SEGMENT
- ////////////////////////////////////
-
- ////////////////////////////////////
- // BEGIN AUTO ATTACK SEGMENT
-
- // Non-Launcher Guns Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 10 ] );
-
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) <= 0 )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 10 ]), gzWeaponStatsFasthelp[ 25 ] );
- }
- }
-
- // END AUTO ATTACK SEGMENT
- ///////////////////////////////////
-
- // Guns, Throwing knives and Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
- {
- // RANGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
- }
-
- // Guns and Launchers Only
+ /////////////////// ACCURACY
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
{
- // ACCURACY
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 0 ] );
}
- // Guns and Multi-use Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // RELOAD AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 11 ] );
-
- if ( Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
- {
- // RELOAD MANUALLY AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 12 ] );
- }
- }
-
- // Guns and Grenade Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
- // DRAW AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
- }
-
- // Non-Launcher Guns, Blades, and Throwing Knives only
+ /////////////////// DAMAGE
if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_BLADE|IC_PUNCH|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
{
- // DAMAGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 1 ] );
}
- // Non-Launcher Guns Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher )
+ /////////////////// RANGE
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
{
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 || GetShotsPerBurst(gpItemDescObject)> 0 )
- {
- // BURST PENALTY
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- if ( GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 && GetShotsPerBurst(gpItemDescObject) <= 0 )
- {
- // Change help text to "Autofire Penalty" (no burst)
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 2 ]), gzWeaponStatsFasthelp[ 27 ] );
- }
- if ( GetShotsPerBurst(gpItemDescObject) > 0 && GetAutofireShotsPerFiveAPs(gpItemDescObject) <= 0 )
- {
- // Change help text to "Burst Penalty" (no autofire)
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 2 ]), gzWeaponStatsFasthelp[ 28 ] );
- }
- }
-
- if ( GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
- {
- // AUTOFIRE SHOTS PER 5 AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
- }
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
}
- //////////////////////////////////////////////////////////////////////
- // Begin non-type-specific icons. These are not type specific because they represent bonuses
- // which may one day be added to various types of weapons by modders...
-
- if (Weapon[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubAttackVolume > 0 )
+ /////////////////// AIMING LEVELS
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
{
- // NOISE REDUCTION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 14 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
}
-
+
+ /////////////////// SCOPE MAGNIFICATION
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_GUN )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 4 ] );
+ }
+
+ /////////////////// PROJECTION FACTOR
+ if ( GetProjectionFactor( gpItemDescObject ) > 1.0f )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 5 ] );
+ }
+ /////////////////// FLASH SUPPRESSION
if (IsFlashSuppressorAlt( gpItemDescObject ) == TRUE)
{
- // HIDE FLASH
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 13 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 6 ] );
}
- if (GetFlatToHitBonus( gpItemDescObject ) != 0)
+ /////////////////// LOUDNESS
+ if (Weapon[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubAttackVolume > 0 )
{
- // HIT BONUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 15 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 7 ] );
+ }
- if (GetFlatToHitBonus( gpItemDescObject ) > 0 && GetAverageBestLaserRange( gpItemDescObject ) / 10 > 0 )
+ /////////////////// RELIABILITY
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 8 ] );
+ }
+
+ /////////////////// REPAIR EASE
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 9 ] );
+ }
+
+ /////////////////// MinRangeForAimBonus
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 10 ] );
+ }
+
+ /////////////////// ToHitBonus
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 11 ] );
+ }
+
+ /////////////////// AP TO DRAW
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !Item[ gpItemDescObject->usItem].rocketlauncher )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 12 ] );
+ }
+
+ /////////////////// AP TO SINGLE ATTACK
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 13 ] );
+ }
+
+ /////////////////// AP TO BURST
+ if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[gpItemDescObject->usItem].rocketlauncher )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 14 ] );
+ }
+
+ /////////////////// AP TO AUTOFIRE
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 15 ] );
+ }
+
+ /////////////////// AP TO RELOAD
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 16 ] );
+ }
+
+ /////////////////// AP TO RELOAD MANUALLY
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher && Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 17 ] );
+ }
+
+ /////////////////// RECOIL X/Y
+ if( UsingNewCTHSystem() == true )
+ {
+ if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher && (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 || GetShotsPerBurst(gpItemDescObject)> 0 ) )
{
- // LASER RANGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 16 ] );
- }
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 18 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 19 ] );
+ }
+ }
+ else /////////////////// BIPOD
+ {
+ if( GetBipodBonus(gpItemDescObject) > 0 )
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 19 ] );
}
- if (GetBipodBonus( gpItemDescObject ) != 0)
+ /////////////////// BULLETS PER 5 AP
+ if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher && GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
- // BIPOD BONUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 19 ] );
- }
-
- if (IsScoped( gpItemDescObject ))
- {
- // SCOPE AIM BONUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 17 ] );
- if (GetMinRangeForAimBonus( gpItemDescObject ) > 0)
- {
- // LASER RANGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 18 ] );
- }
- }
-
- }
-
- ///////////////////////////////////////////////////
- // Begin Ammo Item Tooltip Section
-
- else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_AMMO )
- {
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gAmmoDescStatsRects[ cnt ]. iLeft),
- (INT16)(gAmmoDescStatsRects[ cnt ].iTop),
- (INT16)(gAmmoDescStatsRects[ cnt ].iRight),
- (INT16)(gAmmoDescStatsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzAmmoStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
- }
-
- // AMMO PENETRATION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
-
- // AMMO TUMBLE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
-
- // AMMO PRE-IMPACT EXPLOSION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- // TRACER
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].tracerEffect )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
- }
-
- // ANTI-TANK
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
- }
-
- // LOCKBUSTER
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].lockBustingPower )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
- }
-
- // IGNORE ARMOR
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ignoreArmour )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
- }
-
- // ACIDIC ICON
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].acidic )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
- }
-
- // RANGE BONUS
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- }
-
- // DAMAGE BONUS
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 9 ] );
- }
-
- // TO HIT BONUS
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 10 ] );
- }
-
- // AUTO BONUS
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 11 ] );
- }
-
- // BURST BONUS
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 12 ] );
- }
-
- // RELIABILITY BONUS
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 13 ] );
- }
-
- // NOISE SUPPRESSION
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 14 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 20 ] );
}
}
+ }
- ///////////////////////////////////////////////////
- // Begin Armor Item Tooltip Section
+ /////////////////////////////////////////////////////////////////////////////////
+ // ARMOR
+ /////////////////////////////////////////////////////////////////////////////////
- else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_ARMOUR )
+ else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_ARMOUR )
+ {
+ if (gubDescBoxPage == 1)
{
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gArmorDescStatsRects[ cnt ]. iLeft),
- (INT16)(gArmorDescStatsRects[ cnt ].iTop),
- (INT16)(gArmorDescStatsRects[ cnt ].iRight),
- (INT16)(gArmorDescStatsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+ /////////////////// HEADERS
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzArmorStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
+ for (cnt = 0; cnt < 2; cnt++)
+ {
+ /////////////////// HEADER #1: Primary Properties
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenHeaderRegions[cnt].sLeft),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sTop),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sRight),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBHeaderTooltipText[ cnt ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
- // PROTECTION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
-
- // COVERAGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
-
- // ARMOR DEGRADE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- // AP BONUS
- if ( GetAPBonus ( gpItemDescObject ) != 0 )
+ ////////////////// INDEX
+ for (cnt = 0; cnt < 4; cnt++)
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sLeft),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sTop),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sRight),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBGenIndexTooltipText[ cnt ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
- // AIM BONUS
- if ( GetFlatAimBonus( gpItemDescObject ) != 0 )
+ iFirstDataRegion = iRegionsCreated;
+ CHAR16 pStr[1000];
+
+ ///////////////// PRIMARY DATA - ICONS
+ for (cnt = 0; cnt < 3; cnt++)
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenRegions[cnt][0].sLeft),
+ (INT16)(gItemDescGenRegions[cnt][0].sTop),
+ (INT16)(gItemDescGenRegions[cnt][0].sRight),
+ (INT16)(gItemDescGenRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ swprintf( pStr, L"%s%s", szUDBGenArmorStatsTooltipText[ cnt ], szUDBGenArmorStatsExplanationsTooltipText[ cnt ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), pStr );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
}
- // WOODLAND CAMO
- if ( GetCamoBonus( gpItemDescObject ) > 0 )
+ //////////////////// PROTECTION
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 0 ] );
}
- // URBAN CAMO
- if ( GetUrbanCamoBonus( gpItemDescObject ) > 0 )
+ //////////////////// COVERAGE
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 1 ] );
}
- // DESERT CAMO
- if ( GetDesertCamoBonus( gpItemDescObject ) > 0 )
+ //////////////////// DEGRADE RATE
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
- }
-
- // SNOW CAMO
- if ( GetSnowCamoBonus( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- }
-
- // STEALTH
- if ( GetStealthBonus( gpItemDescObject ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 9 ] );
- }
-
- // VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 10 ] );
- }
-
- // DAY VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 1 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 11 ] );
- }
-
- // NIGHT VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 12 ] );
- }
-
- // BRIGHT LIGHT VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 13 ] );
- }
-
- // CAVE VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 14 ] );
- }
-
- // PERCENT TUNNEL VISION
- if ( GetItemPercentTunnelVision( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 15 ] );
- }
-
- // HEARING RANGE BONUS
- if ( GetItemHearingRangeBonus( gpItemDescObject ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 16 ] );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
}
}
+ }
- //////////////////////////////////////
- // Begin Explosive Item Tooltips Section
- else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_EXPLOSV )
+ else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_AMMO )
+ {
+ if (gubDescBoxPage == 1)
{
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
+ /////////////////// HEADERS
+ for (cnt = 0; cnt < 2; cnt++)
{
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gExplosiveDescStatsRects[ cnt ]. iLeft),
- (INT16)(gExplosiveDescStatsRects[ cnt ].iTop),
- (INT16)(gExplosiveDescStatsRects[ cnt ].iRight),
- (INT16)(gExplosiveDescStatsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+ /////////////////// HEADER #1: Primary Properties
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenHeaderRegions[cnt].sLeft),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sTop),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sRight),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzExplosiveStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBHeaderTooltipText[ cnt ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
- // DAMAGE
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage > 0 )
+ ////////////////// INDEX
+ for (cnt = 0; cnt < 4; cnt++)
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sLeft),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sTop),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sRight),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBGenIndexTooltipText[ cnt ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
- // STUN DAMAGE
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage > 0 )
+ iFirstDataRegion = iRegionsCreated;
+ CHAR16 pStr[1000];
+
+ ///////////////// PRIMARY DATA - ICONS
+ for (cnt = 0; cnt < 3; cnt++)
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenRegions[cnt][0].sLeft),
+ (INT16)(gItemDescGenRegions[cnt][0].sTop),
+ (INT16)(gItemDescGenRegions[cnt][0].sRight),
+ (INT16)(gItemDescGenRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ swprintf( pStr, L"%s%s", szUDBGenAmmoStatsTooltipText[ cnt ], szUDBGenAmmoStatsExplanationsTooltipText[ cnt ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), pStr );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
+ }
+
+ //////////////////// ARMOR PIERCING
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 0 ] );
+ }
+
+ //////////////////// TUMBLE
+ {
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 1 ] );
}
- // LOUDNESS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- // VOLATILITY
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility > 0 )
+ //////////////////// PRE-ARMOR EXPLOSION
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
- }
-
- // SINGLE-EVENT EXPLOSION data
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0 )
- {
- // RADIUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
-
- }
- // PROLONGED EXPLOSION data
- else if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
- {
-
- // DURATION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
-
- // STARTING RADIUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
-
- // FINAL RADIUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
- }
- }
-
- //////////////////////////////////////////////////////////
- // The following is more complex - it sets up tooltip regions based not on predetermined order but on how much data there is on the chart.
- // It begins with defining all regions, then goes on to set the helptext of each one based on each value encountered in the item's stats.
- // At the very end, it enables as many tooltips as values encountered.
-
- else
- {
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gMiscItemDescStatsRects[ cnt ]. iLeft),
- (INT16)(gMiscItemDescStatsRects[ cnt ].iTop),
- (INT16)(gMiscItemDescStatsRects[ cnt ].iRight),
- (INT16)(gMiscItemDescStatsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
- }
-
- cnt=0;
-
- // ITEM SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].itemsizebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 0 ] );
- cnt++;
- }
-
- // RELIABILITY MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 1 ] );
- cnt++;
- }
-
- // NOISE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 2 ] );
- cnt++;
- }
-
- // HIDE MUZZLE FLASH ICON
- if ( Item[ gpItemDescObject->usItem ].hidemuzzleflash > 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 3 ] );
- cnt++;
- }
-
- // BIPOD ICON
- if ( Item[ gpItemDescObject->usItem ].bipod != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 4 ] );
- cnt++;
- }
-
- // RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 5 ] );
- cnt++;
- }
-
- // TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 6 ] );
- cnt++;
- }
-
- // LASER RANGE
- if ( Item[ gpItemDescObject->usItem ].bestlaserrange > 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 7 ] );
- cnt++;
- }
-
- // AIMING MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].aimbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 8 ] );
- cnt++;
- }
-
- // MINIMUM RANGE FOR AIMING BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].minrangeforaimbonus > 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 33 ] );
- cnt++;
- }
-
- // MAGAZINE SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].magsizebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 17 ] );
- cnt++;
- }
-
- // BURST SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].burstsizebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 9 ] );
- cnt++;
- }
-
- // BURST TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 10 ] );
- cnt++;
- }
-
- // AUTO TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 11 ] );
- cnt++;
- }
-
- // AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].APBonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 12 ] );
- cnt++;
- }
-
- // BURST AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentburstfireapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 13 ] );
- cnt++;
- }
-
- // AUTOFIRE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentautofireapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 14 ] );
- cnt++;
- }
-
- // READY AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreadytimeapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 15 ] );
- cnt++;
- }
-
- // RELOAD AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreloadtimeapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 16 ] );
- cnt++;
- }
-
- // SINGLE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 18 ] );
- cnt++;
- }
-
- // DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 19 ] );
- cnt++;
- }
-
- // MELEE DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].meleedamagebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 20 ] );
- cnt++;
- }
-
- // WOOD CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].camobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 21 ] );
- cnt++;
- }
-
- // URBAN CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].urbanCamobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 22 ] );
- cnt++;
- }
-
- // DESERT CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].desertCamobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 23 ] );
- cnt++;
- }
-
- // SNOW CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].snowCamobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 24 ] );
- cnt++;
- }
-
- // STEALTH MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].stealthbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 25 ] );
- cnt++;
- }
-
- // HEARING RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].hearingrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 26 ] );
- cnt++;
- }
-
- // VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].visionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 27 ] );
- cnt++;
- }
-
- // DAY VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].dayvisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 28 ] );
- cnt++;
- }
-
- // NIGHT VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].nightvisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 29 ] );
- cnt++;
- }
-
- // BRIGHT LIGHT VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 30 ] );
- cnt++;
- }
-
- // CAVE VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].cavevisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 31 ] );
- cnt++;
- }
-
- // PERCENT TUNNEL VISION MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percenttunnelvision != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 32 ] );
- cnt++;
- }
-
- UINT8 cntval = cnt;
-
- // Enable as many regions as required
- for ( cnt = 0; cntusItem ].usItemClass & IC_EXPLOSV )
{
- ///////////////////////////////////////////
- // Begin Weapon Item Tooltip Regions
-
- if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH )
+ if (gubDescBoxPage == 1)
{
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gWeaponDescStatsRects[ cnt ].iLeft + gsInvDescX),
- (INT16)(gWeaponDescStatsRects[ cnt ].iTop + gsInvDescY),
- (INT16)(gWeaponDescStatsRects[ cnt ].iRight + gsInvDescX),
- (INT16)(gWeaponDescStatsRects[ cnt ].iBottom + gsInvDescY),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+ /////////////////// HEADERS
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzWeaponStatsFasthelpTactical[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
+ for (cnt = 0; cnt < 2; cnt++)
+ {
+ /////////////////// HEADER #1: Primary Properties
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenHeaderRegions[cnt].sLeft),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sTop),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sRight),
+ (INT16)(gItemDescGenHeaderRegions[cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBHeaderTooltipText[ cnt ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
-
- // Enable regions one-by-one as necessary
+
+ ////////////////// INDEX
+ for (cnt = 0; cnt < 4; cnt++)
+ {
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sLeft),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sTop),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sRight),
+ (INT16)(gItemDescGenIndexRegions[0][cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
- // Relevant to all weapons
-
- // RELIABILITY
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
-
- // REPAIR EASE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
-
- //////////////////////////////////
- // BEGIN SINGLE ATTACK SEGMENT
-
- // Non-Launcher Guns and Grenade-Launchers only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
-
- // SINGLE-SHOT AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
-
- if ( Weapon[gpItemDescObject->usItem].NoSemiAuto )
- {
- // "NO SINGLE-SHOT"
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelpTactical[ 23 ] );
- }
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBGenIndexTooltipText[ cnt ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+
+ iRegionsCreated++;
}
- // Rocket-Launchers Only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && Item[gpItemDescObject->usItem].rocketlauncher )
+ iFirstDataRegion = iRegionsCreated;
+ CHAR16 pStr[1000];
+
+ ///////////////// PRIMARY DATA - ICONS
+ for (cnt = 0; cnt < 7; cnt++)
{
- // SINGLE ROCKET-LAUNCH AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelpTactical[ 21 ] );
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenRegions[cnt][0].sLeft),
+ (INT16)(gItemDescGenRegions[cnt][0].sTop),
+ (INT16)(gItemDescGenRegions[cnt][0].sRight),
+ (INT16)(gItemDescGenRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
}
- // Throwing-Knives Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_THROWING_KNIFE )
- {
- // THROW KNIFE AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelpTactical[ 20 ] );
- }
-
- // Blades Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_BLADE )
- {
- // SLASH AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelpTactical[ 22 ] );
- }
-
- // Blunts Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_PUNCH )
- {
- // SLASH AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 8 ]), gzWeaponStatsFasthelpTactical[ 26 ] );
- }
-
- // END SINGLE ATTACK SEGMENT
- ////////////////////////////////////
-
- ////////////////////////////////////
- // BEGIN BURST ATTACK SEGMENT
-
- // Non-Launcher Guns and Grenade-Launchers only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- // BURST
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 9 ] );
-
- if (GetShotsPerBurst(gpItemDescObject) <= 0 )
- {
- // "NO BURST"
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 9 ]), gzWeaponStatsFasthelpTactical[ 24 ] );
- }
- }
-
- // END BURST ATTACK SEGMENT
- ////////////////////////////////////
-
- ////////////////////////////////////
- // BEGIN AUTO ATTACK SEGMENT
-
- // Non-Launcher Guns Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 10 ] );
-
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) <= 0 )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 10 ]), gzWeaponStatsFasthelpTactical[ 25 ] );
- }
- }
-
- // END AUTO ATTACK SEGMENT
- ///////////////////////////////////
-
- // Guns, Throwing knives and Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
- {
- // RANGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
- }
-
- // Guns and Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
- {
- // ACCURACY
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
- }
-
- // Guns and Multi-use Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // RELOAD AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 11 ] );
-
- if ( Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
- {
- // RELOAD MANUALLY AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 12 ] );
- }
- }
-
- // Guns and Grenade Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_PUNCH) && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
- // DRAW AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
- }
-
- // Non-Launcher Guns, Blades, and Throwing Knives only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_BLADE|IC_PUNCH|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // DAMAGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
- }
-
- // Non-Launcher Guns Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 || GetShotsPerBurst(gpItemDescObject)> 0 )
- {
- // BURST PENALTY
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- if ( GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 && GetShotsPerBurst(gpItemDescObject) <= 0 )
- {
- // Change help text to "Autofire Penalty" (no burst)
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 2 ]), gzWeaponStatsFasthelp[ 27 ] );
- }
- if ( GetShotsPerBurst(gpItemDescObject) > 0 && GetAutofireShotsPerFiveAPs(gpItemDescObject) <= 0 )
- {
- // Change help text to "Burst Penalty" (no autofire)
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ 2 ]), gzWeaponStatsFasthelp[ 28 ] );
- }
- }
-
- if ( GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
- {
- // AUTOFIRE SHOTS PER 5 AP
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
- }
- }
-
- //////////////////////////////////////////////////////////////////////
- // Begin non-type-specific icons. These are not type specific because they represent bonuses
- // which may one day be added to various types of weapons by modders...
-
- if (Weapon[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubAttackVolume > 0 )
- {
- // NOISE REDUCTION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 18 ] ); //14
- }
-
- if (IsFlashSuppressorAlt( gpItemDescObject ) == TRUE)
- {
- // HIDE FLASH
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 17 ] ); //13
- }
-
- if (GetFlatToHitBonus( gpItemDescObject ) != 0)
- {
- // HIT BONUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 13 ] ); //15
-
- if (GetFlatToHitBonus( gpItemDescObject ) > 0 && GetAverageBestLaserRange( gpItemDescObject ) / 10 > 0 )
- {
- // LASER RANGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 14 ] ); //16
- }
- }
-
- if (GetBipodBonus( gpItemDescObject ) != 0)
- {
- // BIPOD BONUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 19 ] );
- }
-
- if (IsScoped( gpItemDescObject ))
- {
- // SCOPE AIM BONUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 15 ] ); //17
- if (GetMinRangeForAimBonus( gpItemDescObject ) / 10 > 0 )
- {
- // LASER RANGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 16 ] ); //18
- }
- }
-
- }
-
- ///////////////////////////////////////////////////
- // Begin Ammo Item Tooltip Section
-
- else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_AMMO )
- {
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gAmmoDescStatsRects[ cnt ]. iLeft + gsInvDescX),
- (INT16)(gAmmoDescStatsRects[ cnt ].iTop + gsInvDescY),
- (INT16)(gAmmoDescStatsRects[ cnt ].iRight + gsInvDescX),
- (INT16)(gAmmoDescStatsRects[ cnt ].iBottom + gsInvDescY),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzAmmoStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
- }
-
- // AMMO PENETRATION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
-
- // AMMO TUMBLE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
-
- // AMMO PRE-IMPACT EXPLOSION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- // TRACER
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].tracerEffect )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
- }
-
- // ANTI-TANK
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
- }
-
- // LOCKBUSTER
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].lockBustingPower )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
- }
-
- // IGNORE ARMOR
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ignoreArmour )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
- }
-
- // ACIDIC ICON
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].acidic )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
- }
-
- // RANGE BONUS
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- }
-
- // DAMAGE BONUS
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 9 ] );
- }
-
- // TO HIT BONUS
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 10 ] );
- }
-
- // AUTO BONUS
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 11 ] );
- }
-
- // BURST BONUS
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 12 ] );
- }
-
- // RELIABILITY BONUS
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 13 ] );
- }
-
- // NOISE SUPPRESSION
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 14 ] );
- }
- }
-
- ///////////////////////////////////////////////////
- // Begin Armor Item Tooltip Section
-
- else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_ARMOUR )
- {
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gArmorDescStatsRects[ cnt ]. iLeft + gsInvDescX),
- (INT16)(gArmorDescStatsRects[ cnt ].iTop + gsInvDescY),
- (INT16)(gArmorDescStatsRects[ cnt ].iRight + gsInvDescX),
- (INT16)(gArmorDescStatsRects[ cnt ].iBottom + gsInvDescY),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzArmorStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
- }
-
- // PROTECTION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
-
- // COVERAGE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
-
- // ARMOR DEGRADE
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
-
- // AP BONUS
- if ( GetAPBonus ( gpItemDescObject ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
- }
-
- // AIM BONUS
- if ( GetFlatAimBonus( gpItemDescObject ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
- }
-
- // WOODLAND CAMO
- if ( GetCamoBonus( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
- }
-
- // URBAN CAMO
- if ( GetUrbanCamoBonus( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
- }
-
- // DESERT CAMO
- if ( GetDesertCamoBonus( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
- }
-
- // SNOW CAMO
- if ( GetSnowCamoBonus( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 8 ] );
- }
-
- // STEALTH
- if ( GetStealthBonus( gpItemDescObject ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 9 ] );
- }
-
- // VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 10 ] );
- }
-
- // DAY VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 1 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 11 ] );
- }
-
- // NIGHT VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 12 ] );
- }
-
- // BRIGHT LIGHT VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 13 ] );
- }
-
- // CAVE VISION RANGE BONUS
- if ( GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 14 ] );
- }
-
- // PERCENT TUNNEL VISION
- if ( GetItemPercentTunnelVision( gpItemDescObject ) > 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 15 ] );
- }
-
- // HEARING RANGE BONUS
- if ( GetItemHearingRangeBonus( gpItemDescObject ) != 0 )
- {
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 16 ] );
- }
- }
-
- //////////////////////////////////////
- // Begin Explosive Item Tooltips Section
- else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_EXPLOSV )
- {
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
- {
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gExplosiveDescStatsRects[ cnt ]. iLeft + gsInvDescX),
- (INT16)(gExplosiveDescStatsRects[ cnt ].iTop + gsInvDescY),
- (INT16)(gExplosiveDescStatsRects[ cnt ].iRight + gsInvDescX),
- (INT16)(gExplosiveDescStatsRects[ cnt ].iBottom + gsInvDescY),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzExplosiveStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
- }
-
- // DAMAGE
+ //////////////////// DAMAGE
if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage > 0 )
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 0 ] );
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 0 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 0 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 0 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 0 ] );
}
- // STUN DAMAGE
+ //////////////////// STUN-DAMAGE
if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage > 0 )
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 1 ] );
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 1 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 1 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 1 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 1 ] );
}
-
- // LOUDNESS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 2 ] );
- // VOLATILITY
+ //////////////////// BLAST RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType != 5
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType != 1 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 2 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 2 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// STUN BLAST RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 1 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 3 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 3 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// NOISE BLAST RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 5 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 4 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 4 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// TEARGAS START RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 2 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 5 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 5 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// MUSTARD GAS START RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 3 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 6 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 6 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// LIGHT START RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 4 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 7 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 7 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// SMOKE START RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 6 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 8 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 8 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// INCENDIARY START RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 8 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 9 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 9 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 2 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] );
+ }
+
+ //////////////////// TEARGAS END RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 2 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 10 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 10 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 3 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
+ }
+
+ //////////////////// MUSTARD GAS END RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 3 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 11 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 11 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 3 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
+ }
+
+ //////////////////// LIGHT END RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 4 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 12 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 12 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 3 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
+ }
+
+ //////////////////// SMOKE END RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 6 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 13 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 13 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 3 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
+ }
+
+ //////////////////// NAPALM END RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 8 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 14 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 14 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 3 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 3 ] );
+ }
+
+ //////////////////// DURATION
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 15 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 15 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 4 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 4 ] );
+ }
+
+ //////////////////// LOUDNESS
+ {
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 16 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 16 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 5 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 5 ] );
+ }
+
+ //////////////////// VOLATILITY
if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility > 0 )
{
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 3 ] );
+ swprintf( pStr, L"%s%s", szUDBGenExplosiveStatsTooltipText[ 17 ], szUDBGenExplosiveStatsExplanationsTooltipText[ 17 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + 6 ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 6 ] );
}
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // SECONDARY PROPERTIES TOOLTIPS
+ // These are item-flags, shown as large icons on the right hand column of the General
+ // UDB page. They appear only for non-weapon items (no room in the weapon page).
- // SINGLE-EVENT EXPLOSION data
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0 )
+ if (gubDescBoxPage == 1 &&
+ !(Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH ) )
+ {
+ iFirstDataRegion = iRegionsCreated;
+ CHAR16 pStr[1000];
+
+ for (cnt = 0; cnt < 26; cnt++)
+ {
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescGenSecondaryRegions[cnt].sLeft),
+ (INT16)(gItemDescGenSecondaryRegions[cnt].sTop),
+ (INT16)(gItemDescGenSecondaryRegions[cnt].sRight),
+ (INT16)(gItemDescGenSecondaryRegions[cnt].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
+ }
+
+ cnt = 0;
+
+ if (Item[ gpItemDescObject->usItem ].usItemClass & IC_ARMOUR)
+ {
+ //////////////////// EXPLOSIVE RESISTANCE
+ if (Item[ gpItemDescObject->usItem ].flakjacket)
{
- // RADIUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 4 ] );
-
- }
- // PROLONGED EXPLOSION data
- else if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
- {
-
- // DURATION
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 7 ] );
-
- // STARTING RADIUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 5 ] );
-
- // FINAL RADIUS
- MSYS_EnableRegion( &gStatsFasthelpRegions[ 6 ] );
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 5 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 5 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
}
}
- //////////////////////////////////////////////////////////
- // The following is more complex - it sets up tooltip regions based not on predetermined order but on how much data there is on the chart.
- // It begins with defining all regions, then goes on to set the helptext of each one based on each value encountered in the item's stats.
- // At the very end, it enables as many tooltips as values encountered.
-
- else
+ if (Item[ gpItemDescObject->usItem ].usItemClass & IC_AMMO)
{
- // Create all regions
- for (cnt = 0; cnt < 20; cnt++)
+ /////////////////// TRACER AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].tracerEffect )
{
- MSYS_DefineRegion( &gStatsFasthelpRegions[ cnt ],
- (INT16)(gMiscItemDescStatsRects[ cnt ].iLeft + gsInvDescX),
- (INT16)(gMiscItemDescStatsRects[ cnt ].iTop + gsInvDescY),
- (INT16)(gMiscItemDescStatsRects[ cnt ].iRight + gsInvDescX),
- (INT16)(gMiscItemDescStatsRects[ cnt ].iBottom + gsInvDescY),
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 0 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 0 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ /////////////////// ANTI-TANK AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 1 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 1 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ /////////////////// IGNORE ARMOR AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ignoreArmour )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 2 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 2 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ /////////////////// ACIDIC AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].acidic )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 3 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 3 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ /////////////////// LOCKBUSTING AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].lockBustingPower )
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 4 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 4 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+ }
+
+ if (Item[ gpItemDescObject->usItem ].usItemClass & IC_EXPLOSV)
+ {
+ ////////////////// LOCK BOMB
+ if (Item[ gpItemDescObject->usItem ].lockbomb)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 25 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 25 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+ }
+
+ /////////////////////////////////////////////////
+ // Draw stats that can be had by any item.
+
+ //////////////////// WATERPROOF
+ if (!Item[ gpItemDescObject->usItem ].waterdamages)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 6 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 6 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// ELECTRONIC
+ if (Item[ gpItemDescObject->usItem ].electronic)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 7 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 7 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// GAS MASK
+ if (Item[ gpItemDescObject->usItem ].gasmask)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 8 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 8 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// NEEDS BATTERIES
+ if (Item[ gpItemDescObject->usItem ].needsbatteries)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 9 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 9 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// LOCKSMITH'S KIT
+ if (Item[ gpItemDescObject->usItem ].locksmithkit)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 10 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 10 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// WIRE CUTTERS
+ if (Item[ gpItemDescObject->usItem ].wirecutters)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 11 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 11 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// CROWBAR
+ if (Item[ gpItemDescObject->usItem ].crowbar)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 12 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 12 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// CROWBAR
+ if (Item[ gpItemDescObject->usItem ].metaldetector)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 13 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 13 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// REMOTE TRIGGER
+ if (Item[ gpItemDescObject->usItem ].remotetrigger)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 14 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 14 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// REMOTE DETONATOR
+ if (Item[ gpItemDescObject->usItem ].remotedetonator)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 15 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 15 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// TIMER DETONATOR
+ if (Item[ gpItemDescObject->usItem ].detonator)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 16 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 16 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// GAS CAN
+ if (Item[ gpItemDescObject->usItem ].gascan)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 17 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 17 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// TOOLKIT
+ if (Item[ gpItemDescObject->usItem ].toolkit)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 18 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 18 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// THERMAL OPTICS
+ if (Item[ gpItemDescObject->usItem ].thermaloptics)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 19 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 19 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// X-RAY DEVICE
+ if (Item[ gpItemDescObject->usItem ].xray)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 20 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 20 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// CANTEEN
+ if (Item[ gpItemDescObject->usItem ].canteen)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 21 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 21 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// ALCOHOL
+ if (Item[ gpItemDescObject->usItem ].alcohol)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 22 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 22 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// FIRST-AID KIT
+ if (Item[ gpItemDescObject->usItem ].firstaidkit)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 23 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 23 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+
+ //////////////////// MEDICAL KIT
+ if (Item[ gpItemDescObject->usItem ].medicalkit)
+ {
+ swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 24 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 24 ]);
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] );
+ cnt++;
+ }
+ }
+
+ //////////////////////////////////////////////////////
+ // ADVANCED PROPERTY TOOLTIPS
+
+ if (gubDescBoxPage == 2)
+ {
+ INT16 sFirstLine = gubDescBoxLine;
+ INT16 sLastLine = gubDescBoxLine + NUM_UDB_ADV_LINES;
+ INT16 cnt = 0;
+ INT16 sOffsetX = 0;
+ INT16 sOffsetY = 0;
+
+ //////////////////// INDEX
+
+ for (cnt = 0; cnt < 4; cnt++)
+ {
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescAdvIndexRegions[0][cnt].sLeft),
+ (INT16)(gItemDescAdvIndexRegions[0][cnt].sTop),
+ (INT16)(gItemDescAdvIndexRegions[0][cnt].sRight),
+ (INT16)(gItemDescAdvIndexRegions[0][cnt].sBottom),
MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
- MSYS_AddRegion( &gStatsFasthelpRegions[ cnt ]);
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ cnt ] );
- SetRegionHelpEndCallback( &(gStatsFasthelpRegions[ cnt ]), HelpTextDoneCallback );
- MSYS_DisableRegion( &gStatsFasthelpRegions[ cnt ] );
- }
-
- cnt=0;
-
- // ITEM SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].itemsizebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 0 ] );
- cnt++;
- }
-
- // RELIABILITY MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 1 ] );
- cnt++;
- }
-
- // NOISE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 2 ] );
- cnt++;
- }
-
- // HIDE MUZZLE FLASH ICON
- if ( Item[ gpItemDescObject->usItem ].hidemuzzleflash > 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 3 ] );
- cnt++;
- }
-
- // BIPOD ICON
- if ( Item[ gpItemDescObject->usItem ].bipod != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 4 ] );
- cnt++;
- }
-
- // RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 5 ] );
- cnt++;
- }
-
- // TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 6 ] );
- cnt++;
- }
-
- // LASER RANGE
- if ( Item[ gpItemDescObject->usItem ].bestlaserrange > 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 7 ] );
- cnt++;
- }
-
- // AIMING MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].aimbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 8 ] );
- cnt++;
- }
-
- // MINIMUM RANGE FOR AIMING BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].minrangeforaimbonus > 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 33 ] );
- cnt++;
- }
-
- // MAGAZINE SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].magsizebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 17 ] );
- cnt++;
- }
-
- // BURST SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].burstsizebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 9 ] );
- cnt++;
- }
-
- // BURST TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 10 ] );
- cnt++;
- }
-
- // AUTO TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 11 ] );
- cnt++;
- }
-
- // AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].APBonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 12 ] );
- cnt++;
- }
-
- // BURST AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentburstfireapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 13 ] );
- cnt++;
- }
-
- // AUTOFIRE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentautofireapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 14 ] );
- cnt++;
- }
-
- // READY AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreadytimeapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 15 ] );
- cnt++;
- }
-
- // RELOAD AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreloadtimeapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 16 ] );
- cnt++;
- }
-
- // SINGLE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentapreduction != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 18 ] );
- cnt++;
- }
-
- // DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 19 ] );
- cnt++;
- }
-
- // MELEE DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].meleedamagebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 20 ] );
- cnt++;
- }
-
- // WOOD CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].camobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 21 ] );
- cnt++;
- }
-
- // URBAN CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].urbanCamobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 22 ] );
- cnt++;
- }
-
- // DESERT CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].desertCamobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 23 ] );
- cnt++;
- }
-
- // SNOW CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].snowCamobonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 24 ] );
- cnt++;
- }
-
- // STEALTH MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].stealthbonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 25 ] );
- cnt++;
- }
-
- // HEARING RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].hearingrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 26 ] );
- cnt++;
- }
-
- // VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].visionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 27 ] );
- cnt++;
- }
-
- // DAY VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].dayvisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 28 ] );
- cnt++;
- }
-
- // NIGHT VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].nightvisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 29 ] );
- cnt++;
- }
-
- // BRIGHT LIGHT VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 30 ] );
- cnt++;
- }
-
- // CAVE VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].cavevisionrangebonus != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 31 ] );
- cnt++;
- }
-
- // PERCENT TUNNEL VISION MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percenttunnelvision != 0 && cnt<=threshold )
- {
- SetRegionFastHelpText( &(gStatsFasthelpRegions[ cnt ]), gzMiscItemStatsFasthelp[ 32 ] );
- cnt++;
- }
-
- UINT8 cntval = cnt;
-
- // Enable as many regions as required
- for ( cnt = 0; cnt 0 )
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iRegionsCreated ]), gzUDBAdvIndexTooltipText[ 4 ] );
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ iRegionsCreated++;
}
+
+ /////////////////// DATA
+
+ iFirstDataRegion = iRegionsCreated;
+ CHAR16 pStr[1000];
+
+ for (cnt = 0; cnt < NUM_UDB_ADV_LINES; cnt++)
+ {
+ MSYS_DefineRegion( &gUDBFasthelpRegions[ iRegionsCreated ],
+ (INT16)(gItemDescAdvRegions[cnt][0].sLeft),
+ (INT16)(gItemDescAdvRegions[cnt][0].sTop),
+ (INT16)(gItemDescAdvRegions[cnt][0].sRight),
+ (INT16)(gItemDescAdvRegions[cnt][0].sBottom),
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gUDBFasthelpRegions[ iRegionsCreated ]);
+ SetRegionHelpEndCallback( &(gUDBFasthelpRegions[ iRegionsCreated ]), HelpTextDoneCallback );
+ MSYS_DisableRegion( &gUDBFasthelpRegions[ iRegionsCreated ] );
+
+ iRegionsCreated++;
+ }
+
+ cnt = 0;
+
+ ///////////////////// ACCURACY MODIFIER
+ if (GetAccuracyModifier( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 0 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 0 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 0 ], szUDBAdvStatsExplanationsTooltipText[ 0 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+ ///////////////////// FLAT BASE MODIFIER
+ if (GetFlatBaseModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetFlatBaseModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetFlatBaseModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass& (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 1 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 1 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 1 ], szUDBAdvStatsExplanationsTooltipText[ 1 ]);
+ }
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// PERCENT BASE MODIFIER
+ if (GetPercentBaseModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentBaseModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentBaseModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 2 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 2 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 2 ], szUDBAdvStatsExplanationsTooltipText[ 2 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// FLAT AIM MODIFIER
+ if (GetFlatAimModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetFlatAimModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetFlatAimModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 3 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 3 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 3 ], szUDBAdvStatsExplanationsTooltipText[ 3 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// PERCENT AIM MODIFIER
+ if (GetPercentAimModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentAimModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentAimModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 4 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 4 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 4 ], szUDBAdvStatsExplanationsTooltipText[ 4 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// AIMING LEVELS MODIFIER
+ if (GetAimLevelsModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetAimLevelsModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetAimLevelsModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 5 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 5 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 5 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 5 ], szUDBAdvStatsExplanationsTooltipText[ 5 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// CTH CAP MODIFIER
+ if (GetPercentCapModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentCapModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentCapModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 6 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 6 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 6 ], szUDBAdvStatsExplanationsTooltipText[ 6 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// GUN HANDLING MODIFIER
+ if (GetPercentHandlingModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentHandlingModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentHandlingModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 7 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 7 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 7 ], szUDBAdvStatsExplanationsTooltipText[ 7 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// DROP COMPENSATION MODIFIER
+ if (GetDropCompensationModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetDropCompensationModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetDropCompensationModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 8 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 8 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 8 ], szUDBAdvStatsExplanationsTooltipText[ 8 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// TARGET TRACKING MODIFIER
+ if (GetTargetTrackingModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetTargetTrackingModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetTargetTrackingModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 9 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 9 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 9 ], szUDBAdvStatsExplanationsTooltipText[ 9 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// DAMAGE MODIFIER
+ if (GetDamageBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 10 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 10 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 10 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 10 ], szUDBAdvStatsExplanationsTooltipText[ 10 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// MELEE DAMAGE MODIFIER
+ if (GetMeleeDamageBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 11 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 11 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 11 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 11 ], szUDBAdvStatsExplanationsTooltipText[ 11 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// RANGE MODIFIER
+ if (GetRangeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 12 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 12 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 12 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 12 ], szUDBAdvStatsExplanationsTooltipText[ 12 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// SCOPE MAGNIFICATION
+ if (GetHighestScopeMagnificationFactor( gpItemDescObject ) > 1.0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 13 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 13 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 13 ], szUDBAdvStatsExplanationsTooltipText[ 13 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// PROJECTION FACTOR
+ if (GetProjectionFactor( gpItemDescObject ) > 1.0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 14 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 14 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 14 ], szUDBAdvStatsExplanationsTooltipText[ 14 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ INT8 bDummy;
+ INT8 bRecoilModifier;
+ GetFlatRecoilModifier( gpItemDescObject, &bRecoilModifier, &bDummy );
+ ///////////////////// LATERAL RECOIL MODIFIER
+ if (bRecoilModifier != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 15 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 15 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 15 ], szUDBAdvStatsExplanationsTooltipText[ 15 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ GetFlatRecoilModifier( gpItemDescObject, &bDummy, &bRecoilModifier );
+ ///////////////////// VERTICAL RECOIL MODIFIER
+ if (bRecoilModifier != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 16 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 16 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 16 ], szUDBAdvStatsExplanationsTooltipText[ 16 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// MAX COUNTER FORCE MODIFIER
+ if ((GetCounterForceMaxModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetCounterForceMaxModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetCounterForceMaxModifier( gpItemDescObject, ANIM_PRONE ) != 0 ) )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 17 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 17 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 17 ], szUDBAdvStatsExplanationsTooltipText[ 17 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// COUNTER FORCE ACCURACY MODIFIER
+ if (GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 18 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 18 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 18 ], szUDBAdvStatsExplanationsTooltipText[ 18 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// COUNTER FORCE FREQUENCY MODIFIER
+ if (GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 19 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 19 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 19 ], szUDBAdvStatsExplanationsTooltipText[ 19 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// AP MODIFIER
+ if (GetAPBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 20 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 20 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 20 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 20 ], szUDBAdvStatsExplanationsTooltipText[ 20 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// DRAW AP MODIFIER
+ if (GetPercentReadyTimeAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 21 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 21 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 21 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 21 ], szUDBAdvStatsExplanationsTooltipText[ 21 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// SINGLE-ATTACK AP MODIFIER
+ if (GetPercentAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 22 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 22 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 22 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 22 ], szUDBAdvStatsExplanationsTooltipText[ 22 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// BURST AP MODIFIER
+ if (GetPercentBurstFireAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 23 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 23 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 23 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 23 ], szUDBAdvStatsExplanationsTooltipText[ 23 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// AUTOFIRE AP MODIFIER
+ if (GetPercentAutofireAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 24 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 24 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 24 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 24 ], szUDBAdvStatsExplanationsTooltipText[ 24 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// RELOAD AP MODIFIER
+ if (GetPercentReloadTimeAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 25 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 25 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 25 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 25 ], szUDBAdvStatsExplanationsTooltipText[ 25 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// MAGAZINE SIZE MODIFIER
+ if (GetMagSizeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 26 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 26 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 26 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 26 ], szUDBAdvStatsExplanationsTooltipText[ 26 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// BURST SIZE MODIFIER
+ if (GetBurstSizeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 27 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 27 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 27 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 27 ], szUDBAdvStatsExplanationsTooltipText[ 27 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// HIDE MUZZLE FLASH
+ if (IsFlashSuppressorAlt( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 28 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 28 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 28 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 28 ], szUDBAdvStatsExplanationsTooltipText[ 28 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// LOUDNESS MODIFIER
+ if (GetPercentNoiseVolume( gpItemDescObject )-100 != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 29 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 29 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 29 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 29 ], szUDBAdvStatsExplanationsTooltipText[ 29 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// ALTER ITEM SIZE
+ if (CalculateItemSize( gpItemDescObject ) - Item[ gpItemDescObject->usItem ].ItemSize != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 30 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 30 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 30 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 30 ], szUDBAdvStatsExplanationsTooltipText[ 30 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// RELIABILITY MODIFIER
+ if (!(Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_PUNCH|IC_ARMOUR|IC_EXPLOSV)) &&
+ GetReliability( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 31 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 31 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 31 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 31 ], szUDBAdvStatsExplanationsTooltipText[ 31 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// WOODLAND CAMO
+ if (GetCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 32 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 32 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 32 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 32 ], szUDBAdvStatsExplanationsTooltipText[ 32 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// URBAN CAMO
+ if (GetUrbanCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 33 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 33 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 33 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 33 ], szUDBAdvStatsExplanationsTooltipText[ 33 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// DESERT CAMO
+ if (GetDesertCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 34 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 34 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 34 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 34 ], szUDBAdvStatsExplanationsTooltipText[ 34 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// SNOW CAMO
+ if (GetSnowCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 35 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 35 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 35 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 35 ], szUDBAdvStatsExplanationsTooltipText[ 35 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// STEALTH MODIFIER
+ if (GetStealthBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 36 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 36 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 36 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 36 ], szUDBAdvStatsExplanationsTooltipText[ 36 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// HEARING RANGE MODIFIER
+ if (GetItemHearingRangeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 37 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 37 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 37 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 37 ], szUDBAdvStatsExplanationsTooltipText[ 37 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 38 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 38 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 38 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 38 ], szUDBAdvStatsExplanationsTooltipText[ 38 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// NIGHT VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 2 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 39 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 39 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 39 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 39 ], szUDBAdvStatsExplanationsTooltipText[ 39 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// DAY VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 1 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 40 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 40 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 40 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 40 ], szUDBAdvStatsExplanationsTooltipText[ 40 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// BRIGHT LIGHT VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 3 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 41 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 41 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 41 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 41 ], szUDBAdvStatsExplanationsTooltipText[ 41 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// CAVE VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 4 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 42 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 42 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 42 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 42 ], szUDBAdvStatsExplanationsTooltipText[ 42 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ ///////////////////// PERCENT TUNNEL VISION
+ if (GetItemPercentTunnelVision( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ if( UsingNewCTHSystem() == false )
+ {
+ swprintf( pStr, L"%s", szUDBAdvStatsTooltipText[ 43 ]);
+ }
+ else if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 43 ], szUDBAdvStatsExplanationsTooltipTextForWeapons[ 43 ]);
+ }
+ else
+ {
+ swprintf( pStr, L"%s%s", szUDBAdvStatsTooltipText[ 43 ], szUDBAdvStatsExplanationsTooltipText[ 43 ]);
+ }
+ SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ]), pStr );
+ MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + (cnt-sFirstLine) ] );
+ }
+ cnt++;
+ }
+
+ gubDescBoxTotalAdvLines = (UINT8)cnt;
}
}
@@ -3533,25 +3259,19 @@ void DeleteEnhancedDescBox( UINT32 guiCurrentItemDescriptionScreen )
DeleteVideoObjectFromIndex( guiItemInfoAmmoIcon );
DeleteVideoObjectFromIndex( guiItemInfoArmorIcon );
DeleteVideoObjectFromIndex( guiItemInfoExplosiveIcon );
- DeleteVideoObjectFromIndex( guiItemInfoMiscIcon );
+ // HEADROCK HAM 4: Delete new icons
+ DeleteVideoObjectFromIndex( guiItemInfoSecondaryIcon );
+ DeleteVideoObjectFromIndex( guiItemInfoAdvancedIcon );
- if ( guiCurrentItemDescriptionScreen ==MAP_SCREEN && UsingEDBSystem() > 0 )
+ if ( UsingEDBSystem() > 0 )
{
- UINT16 RegionsToRemove = 20;
-
- for (cnt = 0; cnt < RegionsToRemove; cnt++)
+ // HEADROCK HAM 4: UDB fasthelp
+ for ( cnt = 0; cnt < NUM_UDB_FASTHELP_REGIONS; cnt++ )
{
- MSYS_RemoveRegion( &gStatsFasthelpRegions[cnt] );
- }
- }
-
- if ( guiCurrentItemDescriptionScreen !=MAP_SCREEN && UsingEDBSystem() > 0 )
- {
- UINT16 RegionsToRemove = 20;
-
- for (cnt = 0; cnt < RegionsToRemove; cnt++)
- {
- MSYS_RemoveRegion( &gStatsFasthelpRegions[cnt] );
+ if( gUDBFasthelpRegions[ cnt ].IDNumber != 0 )
+ {
+ MSYS_RemoveRegion( &gUDBFasthelpRegions[ cnt ]);
+ }
}
}
}
@@ -3559,790 +3279,1188 @@ void DeleteEnhancedDescBox( UINT32 guiCurrentItemDescriptionScreen )
void DrawWeaponStats( OBJECTTYPE * gpItemDescObject )
{
INT32 cnt;
+ INT16 sOffsetX = 2;
+ INT16 sOffsetY = 1;
if( UsingEDBSystem() == 0 )
return;
- // Start with icons relevant to all weapons
-
- // RELIABILITY ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 9, BULLET_RELIABILITY_X, BULLET_RELIABILITY_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // REPAIR EASE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 10, BULLET_REPAIR_X, BULLET_REPAIR_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- //////////////////////////////////
- // BEGIN SINGLE ATTACK SEGMENT
-
- // Non-Launcher Guns only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
+ if (gubDescBoxPage == 1)
{
- // "NO SINGLE-SHOT" ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 19, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
+ //////////////////// ACCURACY
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
{
- // SINGLE SHOT AP ICON overwrites shadow
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 0, BULLET_SING_X+1, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 8, gItemDescGenRegions[0][0].sLeft+sOffsetX, gItemDescGenRegions[0][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
- }
- // Rocket-Launchers Only
- if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && Item[gpItemDescObject->usItem].rocketlauncher )
- {
- // SINGLE ROCKET-LAUNCH AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 21, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // Grenade-Launchers Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
+ //////////////////// DAMAGE
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
{
- // SINGLE GRENADE-LAUNCH AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 24, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 5, gItemDescGenRegions[1][0].sLeft+sOffsetX, gItemDescGenRegions[1][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
- }
- // Throwing-Knives Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_THROWING_KNIFE )
- {
- // THROW KNIFE AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 22, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // Blades Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_BLADE )
- {
- // SLASH AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 20, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // Blunts Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_PUNCH )
- {
- // BASH AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 26, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // END SINGLE ATTACK SEGMENT
- ////////////////////////////////////
-
- ////////////////////////////////////
- // BEGIN BURST ATTACK SEGMENT
-
- // Non-Launcher Guns Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- // "NO BURST" ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 11, BULLET_BURST_X, BULLET_BURST_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- if (GetShotsPerBurst(gpItemDescObject)> 0)
+ //////////////////// RANGE
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
{
- for ( cnt = 0; cnt < GetShotsPerBurst(gpItemDescObject); cnt++ )
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 4, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// ALLOWED AIM LEVELS
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 33, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// SCOPE MAGNIFICATION
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_GUN )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 15, gItemDescGenRegions[4][0].sLeft+sOffsetX, gItemDescGenRegions[4][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// PROJECTION FACTOR
+ if (GetProjectionFactor( gpItemDescObject ) > 1.0)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 14, gItemDescGenRegions[5][0].sLeft+sOffsetX, gItemDescGenRegions[5][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// FLASH SUPPRESSION
+ if (IsFlashSuppressorAlt( gpItemDescObject ))
+ {
+ // HIDE FLASH ICON
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 28, gItemDescGenRegions[6][0].sLeft+sOffsetX, gItemDescGenRegions[6][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// LOUDNESS
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 17, gItemDescGenRegions[7][0].sLeft+sOffsetX, gItemDescGenRegions[7][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// RELIABILITY
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 9, gItemDescGenRegions[8][0].sLeft+sOffsetX, gItemDescGenRegions[8][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// REPAIR EASE
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 10, gItemDescGenRegions[9][0].sLeft+sOffsetX, gItemDescGenRegions[9][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// MinRangeForAimBonus
+ if( UsingNewCTHSystem() == false )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 27, gItemDescGenRegions[10][0].sLeft+sOffsetX, gItemDescGenRegions[10][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// BestLaserRange
+ if( UsingNewCTHSystem() == false )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 13, gItemDescGenRegions[11][0].sLeft+sOffsetX, gItemDescGenRegions[11][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// DRAW COST
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem].rocketlauncher )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 1, gItemDescGenRegions[13][0].sLeft+sOffsetX, gItemDescGenRegions[13][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////////// SINGLE SHOT COST - GUN
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
+ {
+ // "NO SINGLE-SHOT" ICON
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 19, gItemDescGenRegions[14][0].sLeft+sOffsetX, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+
+ if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
{
- // BURST FIRE ICON overwrites shadow
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 0, BULLET_BURST_X + cnt * (BULLET_WIDTH/2 + 1) +1, BULLET_BURST_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ // SINGLE SHOT AP ICON overwrites shadow
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 0, gItemDescGenRegions[14][0].sLeft+sOffsetX+1, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
}
- }
- // Grenade-Launchers Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- if (GetShotsPerBurst(gpItemDescObject)> 0)
+ /////////////////// SINGLE SHOT COST - ROCKET
+ if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) && Item[gpItemDescObject->usItem].rocketlauncher )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 25, BULLET_BURST_X, BULLET_BURST_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ // SINGLE ROCKET-LAUNCH AP ICON
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 21, gItemDescGenRegions[14][0].sLeft+sOffsetX, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
- }
- // END BURST ATTACK SEGMENT
- ////////////////////////////////////
-
- ////////////////////////////////////
- // BEGIN AUTO ATTACK SEGMENT
-
- // Non-Launcher Guns Only
- if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
- {
- // "NO-AUTO" ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 12, BULLET_AUTO_X, BULLET_AUTO_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
+ /////////////////// SINGLE SHOT COST - GRENADE LAUNCHER
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher
+ && !Weapon[gpItemDescObject->usItem].NoSemiAuto )
{
- for ( cnt = 0; cnt < 10; cnt++ )
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 24, gItemDescGenRegions[14][0].sLeft+sOffsetX, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ /////////////////// SINGLE SHOT COST - THROWING KNIFE
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_THROWING_KNIFE )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 22, gItemDescGenRegions[14][0].sLeft+sOffsetX, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ /////////////////// SINGLE SHOT COST - STABBING KNIFE
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_BLADE )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 20, gItemDescGenRegions[14][0].sLeft+sOffsetX, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ /////////////////// SINGLE SHOT COST - BLUNT WEAPON
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_PUNCH )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 26, gItemDescGenRegions[14][0].sLeft+sOffsetX, gItemDescGenRegions[14][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ /////////////////// BURST COST - GUN
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
+ {
+ // "NO BURST" ICON
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 11, gItemDescGenRegions[15][0].sLeft+sOffsetX, gItemDescGenRegions[15][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+
+ if (GetShotsPerBurst(gpItemDescObject)> 0)
{
- // AUTO FIRE ICON overwrites shadow
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 0, BULLET_AUTO_X + cnt * (BULLET_WIDTH/2 + 1) +1, BULLET_AUTO_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ for ( cnt = 0; cnt < GetShotsPerBurst(gpItemDescObject); cnt++ )
+ {
+ // BURST FIRE ICON overwrites shadow
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 0, gItemDescGenRegions[15][0].sLeft+sOffsetX + cnt * (BULLET_WIDTH/2 + 1) +1, gItemDescGenRegions[15][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
}
}
- }
- // END AUTO ATTACK SEGMENT
- ///////////////////////////////////
+ ////////////////// BURST COST - GRENADE LAUNCHER
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER && !Item[gpItemDescObject->usItem].rocketlauncher
+ && GetShotsPerBurst(gpItemDescObject)> 0)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 25, gItemDescGenRegions[15][0].sLeft+sOffsetX, gItemDescGenRegions[15][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
- // Guns, Throwing knives and Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
- {
- // RANGE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 4, BULLET_RANGE_X, BULLET_RANGE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
+ ////////////////// AUTOFIRE COST
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_GUN && !Item[gpItemDescObject->usItem].rocketlauncher )
+ {
+ // "NO-AUTO" ICON
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 12, gItemDescGenRegions[16][0].sLeft+sOffsetX, gItemDescGenRegions[16][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
- // Guns and Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
- {
- // ACCURACY ICON (Always displayed for these items, even if accuracy is 0)
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 8, BULLET_ACC_X, BULLET_ACC_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
+ {
+ for ( cnt = 0; cnt < 10; cnt++ )
+ {
+ // AUTO FIRE ICON overwrites shadow
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 0, gItemDescGenRegions[16][0].sLeft+sOffsetX + cnt * (BULLET_WIDTH/2 + 1) +1, gItemDescGenRegions[16][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+ }
- // NOISE REDUCTION ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 17, BULLET_LOUDNESS_X, BULLET_LOUDNESS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // Guns and Multi-use Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // RELOAD AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 2, BULLET_RELOAD_X, BULLET_RELOAD_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ ////////////////// RELOAD COST
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 2, gItemDescGenRegions[17][0].sLeft+sOffsetX, gItemDescGenRegions[17][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
- if ( Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
+ ////////////////// MANUAL RELOAD COST
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher
+ && Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
{
- // AP to Reload Manually ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 3, BULLET_MRELOAD_X, BULLET_MRELOAD_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 3, gItemDescGenRegions[18][0].sLeft+sOffsetX, gItemDescGenRegions[18][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
- }
-
- // Guns and Grenade Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
- // DRAW AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 1, BULLET_DRAW_X, BULLET_DRAW_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // Non-Launcher Guns, Blades, and Throwing Knives only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // DAMAGE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 5, BULLET_DAMAGE_X, BULLET_DAMAGE_Y-1, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- // Non-Launcher Guns Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
- if (GetShotsPerBurst(gpItemDescObject)> 0 && GetAutofireShotsPerFiveAPs(gpItemDescObject) <= 0 )
- // BURST PENALTY ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 30, BULLET_AUTOPEN_X, BULLET_AUTOPEN_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- else if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 && GetShotsPerBurst(gpItemDescObject) <= 0)
- // AUTO PENALTY ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 6, BULLET_AUTOPEN_X, BULLET_AUTOPEN_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- else if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 && GetShotsPerBurst(gpItemDescObject) > 0 )
- // BURST/AUTO PENALTY ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 29, BULLET_AUTOPEN_X, BULLET_AUTOPEN_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 || GetShotsPerBurst(gpItemDescObject)> 0 )
+ ///////////////// RECOIL X/Y
+ if( UsingNewCTHSystem() == true )
{
- if ( Weapon[ gpItemDescObject->usItem ].bAutofireShotsPerFiveAP > 0 )
+ if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
+ && ( GetShotsPerBurst(gpItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 ) )
{
- // AUTOFIRE SHOTS PER 5 AP ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 7, BULLET_AUTO5AP_X, BULLET_AUTO5AP_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 31, gItemDescGenRegions[19][0].sLeft+sOffsetX, gItemDescGenRegions[19][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 32, gItemDescGenRegions[20][0].sLeft+sOffsetX, gItemDescGenRegions[20][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ }
+ else ///////////////// BIPOD
+ {
+ if( GetBipodBonus(gpItemDescObject) > 0)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 16, gItemDescGenRegions[20][0].sLeft+sOffsetX, gItemDescGenRegions[20][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
}
-
- }
-
- //////////////////////////////////////////////////////////////////////
- // Begin non-type-specific icons. These are not type specific because they represent bonuses
- // which may one day be added to various types of weapons by modders...
- if (IsFlashSuppressorAlt( gpItemDescObject ) == TRUE)
- {
- UINT8 icon = 28;
- if(guiCurrentScreen != MAP_SCREEN && UsingNewInventorySystem() == true)
- icon = 18;
- // HIDE FLASH ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, icon, BULLET_FLASH_X, BULLET_FLASH_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- if (GetFlatToHitBonus( gpItemDescObject ) != 0)
- {
- // HIT BONUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 13, BULLET_TOHIT_X, BULLET_TOHIT_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- if (GetFlatToHitBonus( gpItemDescObject ) > 0 && GetAverageBestLaserRange( gpItemDescObject ) / 10 > 0)
+ ///////////////// AUTOFIRE SHOTS PER 5 AP ICON
+ if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
+ && GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
- // LASER RANGE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 14, BULLET_BESTLASERRANGE_X, BULLET_BESTLASERRANGE_Y-1, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- }
-
- if (GetBipodBonus( gpItemDescObject ) != 0)
- {
- // BIPOD BONUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 16, BULLET_BIPOD_X, BULLET_BIPOD_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- if (IsScoped( gpItemDescObject ))
- {
- // SCOPE AIM BONUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 15, BULLET_AIMBONUS_X, BULLET_AIMBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- if (GetMinRangeForAimBonus( gpItemDescObject ))
- {
- // SCOPE MIN RANGE FOR AIM BONUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 27, BULLET_MINRANGEAIMBONUS_X, BULLET_MINRANGEAIMBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoWeaponIcon, 7, gItemDescGenRegions[21][0].sLeft+sOffsetX, gItemDescGenRegions[21][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
}
- }
+ }
+ else if(gubDescBoxPage == 2)
+ {
+ DrawAdvancedStats( gpItemDescObject );
+ }
}
void DrawAmmoStats( OBJECTTYPE * gpItemDescObject )
{
- // ARMOR PIERCING ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 0, BULLET_ARMORPEN_X, BULLET_ARMORPEN_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ INT16 sOffsetX = 2;
+ INT16 sOffsetY = 1;
- // TUMBLE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 1, BULLET_TUMBLE_X, BULLET_TUMBLE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingEDBSystem() == 0 )
+ return;
- // PRE-ARMOR EXPLOSION ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 2, BULLET_PREARMOR_X, BULLET_PREARMOR_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- // ANTI-TANK ICON
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank )
+ if (gubDescBoxPage == 1)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 3, BULLET_ANTITANK_X, BULLET_ANTITANK_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ //////////////// ARMOR PIERCING
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 0, gItemDescGenRegions[0][0].sLeft+sOffsetX, gItemDescGenRegions[0][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ //////////////// TUMBLING
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 1, gItemDescGenRegions[1][0].sLeft+sOffsetX, gItemDescGenRegions[1][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ //////////////// PRE-ARMOR EXPLOSION
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 2, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ DrawSecondaryStats( gpItemDescObject );
+ }
+ else if (gubDescBoxPage == 2)
+ {
+ DrawAdvancedStats( gpItemDescObject );
}
- // IGNORE ARMOR ICON
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ignoreArmour )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 4, BULLET_IGNOREARMOR_X, BULLET_IGNOREARMOR_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // ACIDIC ICON
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].acidic )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 5, BULLET_ACIDIC_X, BULLET_ACIDIC_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // LOCKBUSTER ICON
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].lockBustingPower )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 6, BULLET_LOCKBUSTER_X, BULLET_LOCKBUSTER_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // TRACER
- if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].tracerEffect )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 7, BULLET_TRACER_X, BULLET_TRACER_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // RANGE BONUS
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 8, BULLET_AMMORANGEBON_X, BULLET_AMMORANGEBON_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // DAMAGE BONUS
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 9, BULLET_AMMODAMAGEBON_X, BULLET_AMMODAMAGEBON_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // TO HIT BONUS
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 11, BULLET_AMMOTOHITBON_X, BULLET_AMMOTOHITBON_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // AUTO PENALTY BONUS
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus > 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 10, BULLET_AMMOAUTOBON_X, BULLET_AMMOAUTOBON_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- // BURST PENALTY BONUS
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus > 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 15, BULLET_AMMOBURSTBON_X, BULLET_AMMOBURSTBON_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // RELIABILITY BONUS
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 12, BULLET_AMMORELIABILITYBON_X, BULLET_AMMORELIABILITYBON_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // NOISE SUPPRESSION
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction > 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 13, BULLET_AMMONOISESUPP_X, BULLET_AMMONOISESUPP_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
}
void DrawExplosiveStats( OBJECTTYPE * gpItemDescObject )
{
+ INT16 sOffsetX = 2;
+ INT16 sOffsetY = 1;
+
if( UsingEDBSystem() == 0 )
return;
- // DAMAGE ICON
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage > 0 )
+ if (gubDescBoxPage == 1)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 0, BULLET_EXPLOSIVEDAMAGE_X, BULLET_EXPLOSIVEDAMAGE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ ////////////////////// DAMAGE
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage > 0 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 0, gItemDescGenRegions[0][0].sLeft+sOffsetX, gItemDescGenRegions[0][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// STUN DAMAGE
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage > 0 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 1, gItemDescGenRegions[1][0].sLeft+sOffsetX, gItemDescGenRegions[1][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// SOUND BLAST
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 5 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 6, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// STUN BLAST
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 1 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 5, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// OTHER BLASTS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType != 1
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType != 5 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 4, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// START+END RADIUS: TEAR GAS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 2 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 9, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 10, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// START+END RADIUS: MUSTARD GAS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 3 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 13, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 14, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// START+END RADIUS: LIGHT
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 4 )
+ {
+ // Note light is reversed (large to small)
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 18, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 17, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// START+END RADIUS: SMOKE
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 6 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 11, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 12, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// START+END RADIUS: NAPALM
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0
+ && Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 8 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 15, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 16, gItemDescGenRegions[3][0].sLeft+sOffsetX, gItemDescGenRegions[3][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// DURATION
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 7, gItemDescGenRegions[4][0].sLeft+sOffsetX, gItemDescGenRegions[4][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// LOUDNESS
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 2, gItemDescGenRegions[5][0].sLeft+sOffsetX, gItemDescGenRegions[5][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////////// VOLATILITY
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility > 0 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 3, gItemDescGenRegions[6][0].sLeft+sOffsetX, gItemDescGenRegions[6][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ DrawSecondaryStats( gpItemDescObject );
}
-
- // STUN DAMAGE ICON
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage > 0 )
+ else if (gubDescBoxPage == 2)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 1, BULLET_EXPLOSIVESTUNDAMAGE_X, BULLET_EXPLOSIVESTUNDAMAGE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // LOUDNESS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 2, BULLET_EXPLOSIVELOUDNESS_X, BULLET_EXPLOSIVELOUDNESS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- // VOLATILITY ICON
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility > 0 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 3, BULLET_EXPLOSIVEVOLATILITY_X, BULLET_EXPLOSIVEVOLATILITY_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // SINGLE-EVENT EXPLOSION data
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0 )
- {
- // SOUND RADIUS ICON
- if ( Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 5 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 6, BULLET_EXPLOSIVERADIUS_X, BULLET_EXPLOSIVERADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- else if ( Explosive[Item[ gpItemDescObject->usItem].ubClassIndex ].ubType == 1 )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 5, BULLET_EXPLOSIVERADIUS_X, BULLET_EXPLOSIVERADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
- else
- {
- // RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 4, BULLET_EXPLOSIVERADIUS_X, BULLET_EXPLOSIVERADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- }
- // PROLONGED EXPLOSION data
- else if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
- {
- // ARROW
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 8, BULLET_EXPLOSIVEARROW_X, BULLET_EXPLOSIVEARROW_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // DURATION ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 7, BULLET_EXPLOSIVEDURATION_X, BULLET_EXPLOSIVEDURATION_Y, VO_BLT_SRCTRANSPARENCY, NULL );
-
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 2)
- {
- // STARTING RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 9, BULLET_EXPLOSIVESTARTRADIUS_X, BULLET_EXPLOSIVESTARTRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // FINAL RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 10, BULLET_EXPLOSIVEENDRADIUS_X, BULLET_EXPLOSIVEENDRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // MUSTARD GAS
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 3)
- {
- // STARTING RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 13, BULLET_EXPLOSIVESTARTRADIUS_X, BULLET_EXPLOSIVESTARTRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // FINAL RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 14, BULLET_EXPLOSIVEENDRADIUS_X, BULLET_EXPLOSIVEENDRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // LIGHT
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 4)
- {
- // HEADROCK: Please note that these two are reversed for lights, as for some reason lights start
- // at larger radius and decay to a smaller one.
-
- // STARTING RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 18, BULLET_EXPLOSIVESTARTRADIUS_X, BULLET_EXPLOSIVESTARTRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // FINAL RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 17, BULLET_EXPLOSIVEENDRADIUS_X, BULLET_EXPLOSIVEENDRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // SMOKE
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 6)
- {
- // STARTING RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 11, BULLET_EXPLOSIVESTARTRADIUS_X, BULLET_EXPLOSIVESTARTRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // FINAL RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 12, BULLET_EXPLOSIVEENDRADIUS_X, BULLET_EXPLOSIVEENDRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
- // NAPALM
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 8)
- {
- // STARTING RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 15, BULLET_EXPLOSIVESTARTRADIUS_X, BULLET_EXPLOSIVESTARTRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // FINAL RADIUS ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoExplosiveIcon, 16, BULLET_EXPLOSIVEENDRADIUS_X, BULLET_EXPLOSIVEENDRADIUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- }
-
+ DrawAdvancedStats( gpItemDescObject );
}
}
void DrawArmorStats( OBJECTTYPE * gpItemDescObject )
{
+ INT16 sOffsetX = 2;
+ INT16 sOffsetY = 1;
+
if( UsingEDBSystem() == 0 )
return;
- // HELMET
- if ( Armour[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubArmourClass == 0 )
+ if (gubDescBoxPage == 1)
{
- // ARMOR VALUE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 1, BULLET_ARMOR_X, BULLET_ARMOR_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // ARMOR COVERAGE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 4, BULLET_ARMORCOVERAGE_X, BULLET_ARMORCOVERAGE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ /////////////////// PROTECTION VALUE
+ {
+ // HELMET
+ if ( Armour[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubArmourClass == 0 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 1, gItemDescGenRegions[0][0].sLeft + sOffsetX, gItemDescGenRegions[0][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ // LEGGINGS
+ else if ( Armour[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubArmourClass == 2 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 2, gItemDescGenRegions[0][0].sLeft + sOffsetX, gItemDescGenRegions[0][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ // VEST and anything else
+ else
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 0, gItemDescGenRegions[0][0].sLeft + sOffsetX, gItemDescGenRegions[0][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+
+ /////////////////// COVERAGE VALUE
+ {
+ // HELMET
+ if ( Armour[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubArmourClass == 0 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 4, gItemDescGenRegions[1][0].sLeft + sOffsetX, gItemDescGenRegions[1][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ // LEGGINGS
+ else if ( Armour[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubArmourClass == 2 )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 5, gItemDescGenRegions[1][0].sLeft + sOffsetX, gItemDescGenRegions[1][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ // VEST and anything else
+ else
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 3, gItemDescGenRegions[1][0].sLeft + sOffsetX, gItemDescGenRegions[1][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+
+ ////////////////// ARMOR DEGRADE
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 6, gItemDescGenRegions[2][0].sLeft + sOffsetX, gItemDescGenRegions[2][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ ////////////////// SECONDARY ARMOR PROPERTIES
+ DrawSecondaryStats( gpItemDescObject );
}
- // LEGGINGS
- else if ( Armour[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubArmourClass == 2 )
+ else if (gubDescBoxPage == 2)
{
- // ARMOR VALUE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 2, BULLET_ARMOR_X, BULLET_ARMOR_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // ARMOR COVERAGE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 5, BULLET_ARMORCOVERAGE_X, BULLET_ARMORCOVERAGE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ DrawAdvancedStats( gpItemDescObject );
}
- // VEST and anything else
- else
+}
+
+void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject )
+{
+ if (gubDescBoxPage != 2)
{
- // ARMOR VALUE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 0, BULLET_ARMOR_X, BULLET_ARMOR_Y, VO_BLT_SRCTRANSPARENCY, NULL );
- // ARMOR COVERAGE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 3, BULLET_ARMORCOVERAGE_X, BULLET_ARMORCOVERAGE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ return;
}
- // ARMOR DEGRADE ICON
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 6, BULLET_ARMORDEGRADE_X, BULLET_ARMORDEGRADE_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ INT16 sFirstLine = gubDescBoxLine;
+ INT16 sLastLine = gubDescBoxLine + NUM_UDB_ADV_LINES;
+ INT16 cnt = 0; // Counts number of properties encountered
+ INT16 sOffsetX = 0;
+ INT16 sOffsetY = 0;
- // AP BONUS ICON
- if ( GetAPBonus ( gpItemDescObject ) != 0 )
+ ///////////////////// ACCURACY MODIFIER
+ if ( GetAccuracyModifier( gpItemDescObject ))
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 11, BULLET_ARMORAPBONUS_X, BULLET_ARMORAPBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 0, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // AIM BONUS ICON
- if ( GetFlatAimBonus( gpItemDescObject ) != 0 )
+ ///////////////////// FLAT BASE MODIFIER
+ if (GetFlatBaseModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetFlatBaseModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetFlatBaseModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 12, BULLET_ARMORAIMBONUS_X, BULLET_ARMORAIMBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 1, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // WOODLAND CAMO ICON
- if ( GetCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// PERCENT BASE MODIFIER
+ if (GetPercentBaseModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentBaseModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentBaseModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 7, BULLET_ARMORWOODCAMO_X, BULLET_ARMORWOODCAMO_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 2, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // URBAN CAMO ICON
- if ( GetUrbanCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// FLAT AIM MODIFIER
+ if (GetFlatAimModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetFlatAimModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetFlatAimModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 8, BULLET_ARMORURBANCAMO_X, BULLET_ARMORURBANCAMO_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 3, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // DESERT CAMO ICON
- if ( GetDesertCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// PERCENT AIM MODIFIER
+ if (GetPercentAimModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentAimModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentAimModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 9, BULLET_ARMORDESERTCAMO_X, BULLET_ARMORDESERTCAMO_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 4, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // SNOW CAMO ICON
- if ( GetSnowCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// AIMING LEVELS MODIFIER
+ if (GetAimLevelsModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetAimLevelsModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetAimLevelsModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 10, BULLET_ARMORSNOWCAMO_X, BULLET_ARMORSNOWCAMO_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 5, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
}
- // STEALTH ICON
- if ( GetStealthBonus( gpItemDescObject ) != 0 )
+ ///////////////////// CTH CAP MODIFIER
+ if (GetPercentCapModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentCapModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentCapModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 18, BULLET_ARMORSTEALTH_X, BULLET_ARMORSTEALTH_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 6, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].visionrangebonus != 0 )
+ ///////////////////// GUN HANDLING MODIFIER
+ if (GetPercentHandlingModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetPercentHandlingModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetPercentHandlingModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 17, BULLET_ARMORVISIONRANGEBONUS_X, BULLET_ARMORVISIONRANGEBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 7, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // DAY VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].dayvisionrangebonus != 0 )
+ ///////////////////// DROP COMPENSATION MODIFIER
+ if (GetDropCompensationModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetDropCompensationModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetDropCompensationModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 14, BULLET_ARMORDAYVISIONRANGEBONUS_X, BULLET_ARMORDAYVISIONRANGEBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 8, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+ ///////////////////// TARGET TRACKING MODIFIER
+ if (GetTargetTrackingModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetTargetTrackingModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetTargetTrackingModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 9, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // NIGHT VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].nightvisionrangebonus != 0 )
+ ///////////////////// DAMAGE MODIFIER
+ if (GetDamageBonus( gpItemDescObject ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 13, BULLET_ARMORNIGHTVISIONRANGEBONUS_X, BULLET_ARMORNIGHTVISIONRANGEBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 10, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
}
- // BRIGHT LIGHT VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus != 0 )
+ ///////////////////// MELEE DAMAGE MODIFIER
+ if (GetMeleeDamageBonus( gpItemDescObject ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 15, BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_X, BULLET_ARMORBRIGHTLIGHTVISIONRANGEBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 11, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
}
- // CAVE VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].cavevisionrangebonus != 0 )
+ ///////////////////// RANGE MODIFIER
+ if (GetRangeBonus( gpItemDescObject ) != 0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 16, BULLET_ARMORCAVEVISIONRANGEBONUS_X, BULLET_ARMORCAVEVISIONRANGEBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 12, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
}
- // PERCENT TUNNEL VISION ICON
- if ( Item[ gpItemDescObject->usItem ].percenttunnelvision > 0 )
+ ///////////////////// SCOPE MAGNIFICATION
+ if (GetHighestScopeMagnificationFactor( gpItemDescObject ) > 1.0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 19, BULLET_ARMORPERCENTTUNNELVISION_X, BULLET_ARMORPERCENTTUNNELVISION_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 13, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
}
- // HEARING RANGE BONUS ICON
- if ( GetItemHearingRangeBonus( gpItemDescObject ) != 0 )
+ ///////////////////// PROJECTION FACTOR
+ if (cnt-sFirstLine < sLastLine &&
+ GetProjectionFactor( gpItemDescObject ) > 1.0 )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoArmorIcon, 20, BULLET_ARMORHEARINGRANGEBONUS_X, BULLET_ARMORHEARINGRANGEBONUS_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 14, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+ ///////////////////// LATERAL RECOIL MODIFIER
+ INT8 bRecoilModifier;
+ INT8 bDummy;
+ GetFlatRecoilModifier( gpItemDescObject, &bRecoilModifier, &bDummy );
+ if (bRecoilModifier != 0)
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 15, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+
+ GetFlatRecoilModifier( gpItemDescObject, &bDummy, &bRecoilModifier );
+ ///////////////////// VERTICAL RECOIL MODIFIER
+ if (bRecoilModifier != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 16, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// MAX COUNTER FORCE MODIFIER
+ if (GetCounterForceMaxModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetCounterForceMaxModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetCounterForceMaxModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 17, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// COUNTER FORCE ACCURACY MODIFIER
+ if (GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 18, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// COUNTER FORCE FREQUENCY MODIFIER
+ if (GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_STAND ) != 0
+ || GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_CROUCH ) != 0
+ || GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_PRONE ) != 0 )
+ {
+ if( UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 19, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+ }
+
+ ///////////////////// AP MODIFIER
+ if (GetAPBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 20, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// DRAW AP MODIFIER
+ if (GetPercentReadyTimeAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 21, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// SINGLE-ATTACK AP MODIFIER
+ if (GetPercentAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 22, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// BURST AP MODIFIER
+ if (GetPercentBurstFireAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 23, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// AUTOFIRE AP MODIFIER
+ if (GetPercentAutofireAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 24, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// RELOAD AP MODIFIER
+ if (GetPercentReloadTimeAPReduction( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 25, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// MAGAZINE SIZE MODIFIER
+ if (GetMagSizeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 26, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// BURST SIZE MODIFIER
+ if (GetBurstSizeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 27, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// HIDE MUZZLE FLASH
+ if (IsFlashSuppressorAlt( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 28, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// LOUDNESS MODIFIER
+ if (GetPercentNoiseVolume( gpItemDescObject )-100 != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 29, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// ITEM SIZE MODIFIER
+ if (CalculateItemSize( gpItemDescObject ) - Item[ gpItemDescObject->usItem ].ItemSize != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 30, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// RELIABILITY MODIFIER
+ if (!(Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_PUNCH|IC_ARMOUR|IC_EXPLOSV)) &&
+ GetReliability( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 31, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// WOODLAND CAMO
+ if (GetCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 32, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// URBAN CAMO
+ if (GetUrbanCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 33, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// DESERT CAMO
+ if (GetDesertCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 34, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// SNOW CAMO
+ if (GetSnowCamoBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 35, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// STEALTH MODIFIER
+ if (GetStealthBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 36, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// HEARING RANGE MODIFIER
+ if (GetItemHearingRangeBonus( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 37, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 0 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 38, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// NIGHT VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 2 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 39, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// DAY VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 1 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 40, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// BRIGHT LIGHT VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 3 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 41, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// CAVE VISION RANGE MODIFIER
+ if (GetItemVisionRangeBonus( gpItemDescObject, 4 ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 42, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
+ }
+
+ ///////////////////// PERCENT TUNNEL VISION
+ if (GetItemPercentTunnelVision( gpItemDescObject ) != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAdvancedIcon, 43, gItemDescAdvRegions[cnt-sFirstLine][0].sLeft + sOffsetX, gItemDescAdvRegions[cnt-sFirstLine][0].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ cnt++;
}
}
void DrawMiscStats( OBJECTTYPE * gpItemDescObject )
{
- INT32 cnt = 0;
- INT32 threshold;
+ if (gubDescBoxPage == 1)
+ {
+ DrawSecondaryStats( gpItemDescObject );
+ }
+ else if (gubDescBoxPage == 2)
+ {
+ DrawAdvancedStats( gpItemDescObject );
+ }
- if( guiCurrentScreen == MAP_SCREEN )
- threshold = 13;
- else
- threshold = 11;
-
- if( UsingEDBSystem() == 0 )
+}
+
+///////////////////////////////////////////////////////////////////////////////////////
+// HEADROCK HAM 4: UDB: Draws item flags as large icons on the secondary column
+void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
+{
+ if (UsingEDBSystem() == 0)
+ {
return;
+ }
- // ITEM SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].itemsizebonus != 0 && cnt<=threshold )
+ if (gubDescBoxPage != 1)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 0, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
+ // Secondary stats are drawn only on page 1.
+ return;
}
-
- // RELIABILITY MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 && cnt<=threshold )
+
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_WEAPON || IC_PUNCH))
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 1, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
+ // Weapons have no space on their UDB General page to show Secondary Stats anyway.
+ return;
}
-
- // NOISE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction != 0 && cnt<=threshold )
+
+ INT32 cnt = 0;
+ INT32 sOffsetX = 0;
+ INT32 sOffsetY = 0;
+
+ /////////////////////////////////////////////////////////////////////////////////
+ // Start with class-specific secondaries
+
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_ARMOUR))
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 2, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ ////////////////// FLAK JACKET
+ if (Item[ gpItemDescObject->usItem ].flakjacket)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 5, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+ }
+
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_AMMO))
+ {
+ /////////////////// TRACER AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].tracerEffect )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 0, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+
+ /////////////////// ANTI-TANK AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].antiTank )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 1, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+
+ /////////////////// IGNORE ARMOR AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].ignoreArmour )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 2, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+
+ /////////////////// ACIDIC AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].acidic )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 3, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+
+ /////////////////// LOCKBUSTING AMMO
+ if ( AmmoTypes[Magazine[Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].lockBustingPower )
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 4, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+ }
+
+ if (Item[ gpItemDescObject->usItem ].usItemClass & (IC_EXPLOSV))
+ {
+ ////////////////// LOCK BOMB
+ if (Item[ gpItemDescObject->usItem ].lockbomb)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 25, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
+ cnt++;
+ }
+ }
+
+ /////////////////////////////////////////////////
+ // Draw stats that can be had by any item.
+
+ //////////////////// WATERPROOF
+ if (!Item[ gpItemDescObject->usItem ].waterdamages)
+ {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 6, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // HIDE MUZZLE FLASH ICON
- if ( Item[ gpItemDescObject->usItem ].hidemuzzleflash > 0 && cnt<=threshold )
+ //////////////////// ELECTRONIC
+ if (Item[ gpItemDescObject->usItem ].electronic)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 3, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 7, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // BIPOD ICON
- if ( Item[ gpItemDescObject->usItem ].bipod != 0 && cnt<=threshold )
+ //////////////////// GAS MASK
+ if (Item[ gpItemDescObject->usItem ].gasmask)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 4, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 8, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 && cnt<=threshold )
+ //////////////////// NEEDS BATTERIES
+ if (Item[ gpItemDescObject->usItem ].needsbatteries)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 5, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 9, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 && cnt<=threshold )
+ //////////////////// LOCKSMITH'S KIT
+ if (Item[ gpItemDescObject->usItem ].locksmithkit)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 6, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 10, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // LASER RANGE ICON
- if ( Item[ gpItemDescObject->usItem ].bestlaserrange > 0 && cnt<=threshold )
+ //////////////////// WIRE CUTTERS
+ if (Item[ gpItemDescObject->usItem ].wirecutters)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 7, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY + 2, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 11, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // AIMING MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].aimbonus != 0 && cnt<=threshold )
+ //////////////////// CROWBAR
+ if (Item[ gpItemDescObject->usItem ].crowbar)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 8, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 12, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // MINIMUM RANGE FOR AIMING ICON
- if ( Item[ gpItemDescObject->usItem ].minrangeforaimbonus > 0 && cnt<=threshold )
+ //////////////////// CROWBAR
+ if (Item[ gpItemDescObject->usItem ].metaldetector)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 33, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 13, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // MAGAZINE SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].magsizebonus != 0 && cnt<=threshold )
+ //////////////////// REMOTE TRIGGER
+ if (Item[ gpItemDescObject->usItem ].remotetrigger)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 17, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 14, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // BURST SIZE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].burstsizebonus != 0 && cnt<=threshold )
+ //////////////////// REMOTE DETONATOR
+ if (Item[ gpItemDescObject->usItem ].remotedetonator)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 9, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 15, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // BURST TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus != 0 && cnt<=threshold )
+ //////////////////// TIMER DETONATOR
+ if (Item[ gpItemDescObject->usItem ].detonator)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 10, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 16, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // AUTO TO-HIT MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus != 0 && cnt<=threshold )
+ //////////////////// GAS CAN
+ if (Item[ gpItemDescObject->usItem ].gascan)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 11, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 17, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].APBonus != 0 && cnt<=threshold )
+ //////////////////// TOOLKIT
+ if (Item[ gpItemDescObject->usItem ].toolkit)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 12, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 18, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // BURST AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentburstfireapreduction != 0 && cnt<=threshold )
+ //////////////////// THERMAL OPTICS
+ if (Item[ gpItemDescObject->usItem ].thermaloptics)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 13, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 19, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // AUTOFIRE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentautofireapreduction != 0 && cnt<=threshold )
+ //////////////////// X-RAY DEVICE
+ if (Item[ gpItemDescObject->usItem ].xray)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 14, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 20, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // READY AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreadytimeapreduction != 0 && cnt<=threshold )
+ //////////////////// CANTEEN
+ if (Item[ gpItemDescObject->usItem ].canteen)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 15, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 21, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // RELOAD AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreloadtimeapreduction != 0 && cnt<=threshold )
+ //////////////////// ALCOHOL
+ if (Item[ gpItemDescObject->usItem ].alcohol)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 16, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 22, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // SINGLE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentapreduction != 0 && cnt<=threshold )
+ //////////////////// FIRST-AID KIT
+ if (Item[ gpItemDescObject->usItem ].firstaidkit)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 18, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 23, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
- // DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 && cnt<=threshold )
+ //////////////////// MEDICAL KIT
+ if (Item[ gpItemDescObject->usItem ].medicalkit)
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 19, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // MELEE DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].meleedamagebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 20, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // WOOD CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].camobonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 21, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // URBAN CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].urbanCamobonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 22, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // DESERT CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].desertCamobonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 23, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // SNOW CAMO ICON
- if ( Item[ gpItemDescObject->usItem ].snowCamobonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 24, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // STEALTH MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].stealthbonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 25, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // HEARING RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].hearingrangebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 26, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].visionrangebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 27, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // DAY VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].dayvisionrangebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 29, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // NIGHT VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].nightvisionrangebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 28, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // BRIGHT LIGHT VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 30, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // CAVE VISION RANGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].cavevisionrangebonus != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 31, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
- cnt++;
- }
-
- // PERCENT TUNNEL VISION MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percenttunnelvision != 0 && cnt<=threshold )
- {
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoMiscIcon, 32, gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 24, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
cnt++;
}
}
@@ -4352,429 +4470,1498 @@ void DrawWeaponValues( OBJECTTYPE * gpItemDescObject )
static CHAR16 pStr[ 100 ];
INT16 usX, usY;
INT16 ubAttackAPs;
+ UINT8 ubNumLine;
+ INT16 sTop;
+ INT16 sHeight;
+ INT16 sLeft;
+ INT16 sWidth;
if( UsingEDBSystem() == 0 )
return;
- // Start with data relevant to all weapons
-
- // "AP COSTS" header
- SetFontForeground( FONT_MCOLOR_WHITE );
- mprintf( gWeaponStats[ 9 ].sX + gsInvDescX + 2, gWeaponStats[ 9 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 2 ] );
- SetFontForeground( 6 );
-
- // RELIABILITY
- // equals
- mprintf( gWeaponStats[ 28 ].sX + gsInvDescX, gWeaponStats[ 28 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // Calculate ammo reliability
- INT8 iAmmoReliability = 0;
- if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && (*gpItemDescObject)[0]->data.gun.ubGunShotsLeft > 0 )
- {
- iAmmoReliability = Item[( *gpItemDescObject )[0]->data.gun.usGunAmmoItem].bReliability;
- }
- else
- {
- iAmmoReliability = 0;
- }
-
- INT8 iReliabilityValue = iAmmoReliability + Item[ gpItemDescObject->usItem ].bReliability;
-
- // Determine color for value print
- SetFontForeground ( 5 );
- if (iReliabilityValue < 0)
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iReliabilityValue > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iReliabilityValue > 0 )
- {
- swprintf( pStr, L"%+2d", iReliabilityValue );
- }
- else
- {
- swprintf( pStr, L"%2d", iReliabilityValue );
- }
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 7 ].sX + gsInvDescX + gWeaponStats[ 7 ].sValDx), (INT16)(gWeaponStats[ 7 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
-
- // REPAIR EASE
- // equals
- mprintf( gWeaponStats[ 29 ].sX + gsInvDescX, gWeaponStats[ 29 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // Determine repair ease
- INT8 iRepairEaseValue = Item[ gpItemDescObject->usItem ].bRepairEase;
-
- // Determine color for value printing
- SetFontForeground ( 5 );
- if (iRepairEaseValue < 0)
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iRepairEaseValue > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iRepairEaseValue > 0 )
- {
- swprintf( pStr, L"%+2d", iRepairEaseValue );
- }
- else
- {
- swprintf( pStr, L"%2d", iRepairEaseValue );
- }
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 8 ].sX + gsInvDescX + gWeaponStats[ 8 ].sValDx), (INT16)(gWeaponStats[ 8 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
-
- SetFontForeground( 6 );
-
// ShotsPer4Turns -> ubAttackAPs, used later for all shot AP values
ubAttackAPs = BaseAPsToShootOrStab( APBPConstants[DEFAULT_APS], APBPConstants[DEFAULT_AIMSKILL], gpItemDescObject );
+ INT16 ubBasicAttackAPs = BaseAPsToShootOrStabNoModifier( APBPConstants[DEFAULT_APS], APBPConstants[DEFAULT_AIMSKILL], gpItemDescObject );
- // SINGLE SHOT AP
- if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // The following attributes are only drawn when the UDB is set to show the General Page.
+
+ if (gubDescBoxPage == 1)
{
- // equals
- mprintf( gWeaponStats[ 32 ].sX + gsInvDescX, gWeaponStats[ 32 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ ////////////////////////////////////////////////// HEADERS
- // Determine color for printing value
- if (ubAttackAPs <= EXCEPTIONAL_AP_COST)
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ // "PRIMARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 0 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sTop, gItemDescGenHeaderRegions[0].sRight - gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sBottom - gItemDescGenHeaderRegions[0].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
+
+ // "AP COSTS" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 2 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sTop, gItemDescGenHeaderRegions[1].sRight - gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sBottom - gItemDescGenHeaderRegions[1].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
+
+ // "BURST / AUTOFIRE" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 3 ] );
+ // If weapon has no burst/autofire, draw in greyish color.
+ if (GetShotsPerBurst(gpItemDescObject) <= 0 && GetAutofireShotsPerFiveAPs(gpItemDescObject) <= 0)
+ SetFontForeground( FONT_MCOLOR_DKGRAY );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[2].sLeft, gItemDescGenHeaderRegions[2].sTop, gItemDescGenHeaderRegions[2].sRight - gItemDescGenHeaderRegions[2].sLeft, gItemDescGenHeaderRegions[2].sBottom - gItemDescGenHeaderRegions[2].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
+
+ SetFontForeground( 6 );
+
+ ///////////////////////////////////////////////////// INDEXES
+
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ // Find out whether we need to display 2 or 3 indexes.
+ UINT8 Limit;
+ if (GetShotsPerBurst(gpItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0)
{
- SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
+ Limit = 3;
}
else
{
- SetFontForeground( 5 );
+ Limit = 2;
}
- // print value
- swprintf( pStr, L"%2d", ubAttackAPs );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 11 ].sX + gsInvDescX + gWeaponStats[ 11 ].sValDx), (INT16)(gWeaponStats[ 11 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
-
- // BURST AP
- if (GetShotsPerBurst(gpItemDescObject)> 0)
- {
- // equals
- mprintf( gWeaponStats[ 33 ].sX + gsInvDescX, gWeaponStats[ 33 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", ubAttackAPs + CalcAPsToBurst( APBPConstants[DEFAULT_APS], gpItemDescObject ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 12 ].sX + gsInvDescX + gWeaponStats[ 12 ].sValDx), (INT16)(gWeaponStats[ 12 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
-
- // AUTO AP
- if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
- {
- // equals
- mprintf( gWeaponStats[ 34 ].sX + gsInvDescX, gWeaponStats[ 34 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", ubAttackAPs + CalcAPsToAutofire( APBPConstants[DEFAULT_APS], gpItemDescObject, 3 ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 13 ].sX + gsInvDescX + gWeaponStats[ 13 ].sValDx), (INT16)(gWeaponStats[ 13 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
-
- // PRINT VALUES FOR SPECIFIC WEAPON TYPES
-
- // Guns and Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
- {
- // ACCURACY
- // equals
- mprintf( gWeaponStats[ 27 ].sX + gsInvDescX, gWeaponStats[ 27 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // Get accuracy value
- INT8 iAccuracyValue = Weapon[ gpItemDescObject->usItem ].bAccuracy;
-
- // Determine color for value printing
- SetFontForeground( 5 );
- if (iAccuracyValue < 0)
+ // Repeatedly draw each index: four separate column headers per index.
+ for (UINT8 cnt = 0; cnt < Limit; cnt++)
{
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iAccuracyValue > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAccuracyValue > 0 )
- {
- swprintf( pStr, L"%+2d", iAccuracyValue );
- }
- else
- {
- swprintf( pStr, L"%2d", iAccuracyValue );
- }
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 6 ].sX + gsInvDescX + gWeaponStats[ 6 ].sValDx), (INT16)(gWeaponStats[ 6 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
- // LOUDNESS
- // equals
- mprintf( gWeaponStats[ 38 ].sX + gsInvDescX, gWeaponStats[ 38 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // Get loudness value
- INT16 iLoudnessValue = GetFinalLoudness( gpItemDescObject );
-
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", iLoudnessValue );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 17 ].sX + gsInvDescX + gWeaponStats[ 17 ].sValDx), (INT16)(gWeaponStats[ 17 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
-
- // Guns and Multi-use Launchers Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // RELOAD AP
- // equals
- mprintf( gWeaponStats[ 35 ].sX + gsInvDescX, gWeaponStats[ 35 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", Weapon[ gpItemDescObject->usItem ].APsToReload );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 14 ].sX + gsInvDescX + gWeaponStats[ 14 ].sValDx), (INT16)(gWeaponStats[ 14 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
- if ( Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
- {
- // RELOAD MANUALLY AP
- // equals
- mprintf( gWeaponStats[ 36 ].sX + gsInvDescX, gWeaponStats[ 36 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", Weapon[gpItemDescObject->usItem].APsToReloadManually );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 15 ].sX + gsInvDescX + gWeaponStats[ 15 ].sValDx), (INT16)(gWeaponStats[ 15 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
- }
-
- // Guns and Grenade Launchers only
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
- // DRAW AP
- // equals
- mprintf( gWeaponStats[ 31 ].sX + gsInvDescX, gWeaponStats[ 31 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // calculate Draw AP
- INT16 iDrawAP = 0;
- iDrawAP = (Weapon[ gpItemDescObject->usItem ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction(gpItemDescObject)) / 100);
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", iDrawAP );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 10 ].sX + gsInvDescX + gWeaponStats[ 10 ].sValDx), (INT16)(gWeaponStats[ 10 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
-
- // Non-Launcher Guns Only
- if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher )
- {
-
- if ( GetShotsPerBurst(gpItemDescObject)> 0 && ! GetAutofireShotsPerFiveAPs(gpItemDescObject) )
- {
- // BURST PENALTY
- // equals
- mprintf( gWeaponStats[ 25 ].sX + gsInvDescX, gWeaponStats[ 25 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", GetBurstPenalty( gpItemDescObject, FALSE ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 4 ].sX + gsInvDescX + gWeaponStats[ 4 ].sValDx), (INT16)(gWeaponStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
- // Note "else if" here to avoid displaying both types of penalties...
-
- else if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
- {
- // AUTO PENALTY
- // equals
- mprintf( gWeaponStats[ 25 ].sX + gsInvDescX, gWeaponStats[ 25 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%d", GetAutoPenalty( gpItemDescObject, FALSE ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 4 ].sX + gsInvDescX + gWeaponStats[ 4 ].sValDx), (INT16)(gWeaponStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
- // Add BurstPenalty if necessary
- if (GetShotsPerBurst(gpItemDescObject)> 0 )
+ for (UINT8 cnt2 = 0; cnt2 < 4; cnt2++)
{
- // Colored white and placed in front of the auto penalty.
- static CHAR16 pStr2[ 100 ];
- SetFontForeground( FONT_WHITE );
- swprintf(pStr2, L"%d/", GetBurstPenalty( gpItemDescObject, FALSE ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 4 ].sX + gsInvDescX + gWeaponStats[ 4 ].sValDx) - StringPixLength(pStr,BLOCKFONT2), (INT16)(gWeaponStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr2, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr2 );
- SetFontForeground( 6 );
+ // Select "PROPERTY", "0", "+" or "=" as appropriate.
+ swprintf(pStr, L"%s", gzItemDescGenIndexes[ cnt2 ]);
+
+ FindFontCenterCoordinates( gItemDescGenIndexRegions[cnt][cnt2].sLeft, gItemDescGenIndexRegions[cnt][cnt2].sTop, gItemDescGenIndexRegions[cnt][cnt2].sRight - gItemDescGenIndexRegions[cnt][cnt2].sLeft, gItemDescGenIndexRegions[cnt][cnt2].sBottom - gItemDescGenIndexRegions[cnt][cnt2].sTop, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+ }
+
+ SetFontForeground( 6 );
+ //////////////////// ACCURACY
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
+ {
+ // Set line to draw into
+ ubNumLine = 0;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get accuracy value
+ INT8 iAccuracyValue = (UsingNewCTHSystem() == true ? Weapon[ gpItemDescObject->usItem ].nAccuracy : Weapon[ gpItemDescObject->usItem ].bAccuracy);
+
+ // Get Modified Accuracy value
+ INT8 iFinalAccuracyValue = GetGunAccuracy( gpItemDescObject );
+
+ // Get difference
+ INT8 iAccuracyDifference = iFinalAccuracyValue - iAccuracyValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iAccuracyValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iAccuracyDifference < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iAccuracyDifference > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iAccuracyDifference > 0 )
+ {
+ swprintf( pStr, L"%+d", iAccuracyDifference );
+ }
+ else if ( iAccuracyDifference < 0 )
+ {
+ swprintf( pStr, L"%d", iAccuracyDifference );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalAccuracyValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+ /////////////// DAMAGE
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
+ {
+ // Set line to draw into
+ ubNumLine = 1;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base damage value
+ UINT8 iDamageValue = GetBasicDamage ( gpItemDescObject );
+
+ // Get Modified Accuracy value
+ UINT8 iFinalDamageValue = GetDamage ( gpItemDescObject );
+
+ // Get difference
+ INT8 iDamageModifier = iFinalDamageValue - iDamageValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iDamageValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iDamageModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iDamageModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iDamageModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iDamageModifier );
+ }
+ else if ( iDamageModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iDamageModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalDamageValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+ /////////////// RANGE
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
+ {
+ // Set line to draw into
+ ubNumLine = 2;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Range value
+ UINT16 iRangeValue = Weapon[ gpItemDescObject->usItem ].usRange;
+
+ // Get Final Range value
+ UINT16 iFinalRangeValue = GunRange( gpItemDescObject, NULL );
+
+ // Get difference
+ INT16 iRangeModifier = iFinalRangeValue - iRangeValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iRangeValue/10 );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iRangeModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iRangeModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iRangeModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iRangeModifier/10 );
+ }
+ else if ( iRangeModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iRangeModifier/10 );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalRangeValue/10 );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ /////////////// AIM LEVELS
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
+ {
+ // Set line to draw into
+ ubNumLine = 3;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get Final Aiming Levels
+ UINT16 iFinalAimLevelsValue = GetAllowedAimingLevelsForItem( gpItemDescObject, ANIM_STAND );
+
+ // Get modifier
+ INT16 iAimLevelsModifier = GetAimLevelsModifier( gpItemDescObject, ANIM_STAND );
+
+ // Get Base Value
+ UINT16 iAimLevelsValue = iFinalAimLevelsValue - iAimLevelsModifier;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iAimLevelsValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iAimLevelsModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iAimLevelsModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iAimLevelsModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iAimLevelsModifier );
+ }
+ else if ( iAimLevelsModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iAimLevelsModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalAimLevelsValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ //////////////// SCOPE MAGNIFICATION FACTOR
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_GUN )
+ {
+ // Set line to draw into
+ ubNumLine = 4;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ FLOAT iScopeMagValue; // Get base Magnification value
+ FLOAT iScopeMagModifier; // Get best Magnification value
+ FLOAT iFinalScopeMagValue; // Get final Magnification value
+
+ if(UsingNewCTHSystem()==true){
+ iScopeMagValue = __max(1.0f, Item[ gpItemDescObject->usItem ].scopemagfactor);
+ iScopeMagModifier = GetHighestScopeMagnificationFactor( gpItemDescObject );
+ iFinalScopeMagValue = __max( iScopeMagValue, iScopeMagModifier );
+ } else {
+ iScopeMagValue = __max(0.0f, Item[ gpItemDescObject->usItem ].aimbonus);
+ iScopeMagModifier = (FLOAT)GetFlatAimBonus( gpItemDescObject );
+ iFinalScopeMagValue = __max( iScopeMagValue, iScopeMagModifier );
}
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iScopeMagValue > 1.0f)
+ {
+ swprintf( pStr, L"%3.1f", iScopeMagValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--");
+ }
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print Scope Mag factor from attachments
+ SetFontForeground( 5 );
+ if (iScopeMagModifier > 1.0f && iScopeMagModifier > iScopeMagValue)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%3.1f", iScopeMagModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--", iScopeMagModifier );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", iFinalScopeMagValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
- // Note "if" here to display this regardless of BURST PENALTY
+ ///////////////// (LASER) PROJECTION FACTOR
+ if (GetProjectionFactor( gpItemDescObject ) > 1.0 )
+ {
+ // Set line to draw into
+ ubNumLine = 5;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ FLOAT iProjectionValue; // Get base Projection value
+ FLOAT iProjectionModifier; // Get best Projection value
+ FLOAT iFinalProjectionValue; // Get final Projection value
+
+ if(UsingNewCTHSystem() == true){
+ iProjectionValue = __max(1.0f, Item[ gpItemDescObject->usItem ].projectionfactor);
+ iProjectionModifier = GetProjectionFactor( gpItemDescObject );
+ iFinalProjectionValue = __max( iProjectionValue, iProjectionModifier );
+ } else {
+ iProjectionValue = __max(0.0f, Item[ gpItemDescObject->usItem ].bestlaserrange / 10);
+ iProjectionModifier = (FLOAT)GetAverageBestLaserRange( gpItemDescObject ) / 10;
+ iFinalProjectionValue = __max( iProjectionValue, iProjectionModifier );
+ }
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iProjectionValue > 1.0f)
+ {
+ swprintf( pStr, L"%3.1f", iProjectionValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--");
+ }
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print Projection factor from attachments
+ SetFontForeground( 5 );
+ if (iProjectionModifier > 1.0f && iProjectionModifier > iProjectionValue)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%3.1f", iProjectionModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--", iProjectionModifier );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", iFinalProjectionValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ///////////////// FLASH SUPPRESSION
+ if (IsFlashSuppressorAlt( gpItemDescObject ) == TRUE)
+ {
+ // Set line to draw into
+ ubNumLine = 6;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Does gun have flash suppression?
+ BOOLEAN iFlashValue = Item[ gpItemDescObject->usItem ].hidemuzzleflash;
+
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iFlashValue)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"Y" );
+ }
+ else
+ {
+ swprintf( pStr, L"--");
+ }
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ if (!iFlashValue)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"Y" );
+ }
+ else
+ {
+ swprintf( pStr, L"--");
+ }
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"Y" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ////////////////// LOUDNESS
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) )
+ {
+ // Set line to draw into
+ ubNumLine = 7;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Loudness value
+ UINT8 iLoudnessValue = Weapon[Item[gpItemDescObject->usItem].ubClassIndex].ubAttackVolume;
+
+ // Get final Loudness value
+ INT16 iFinalLoudnessValue = GetFinalLoudness( gpItemDescObject );
+
+ // Get Loudness modifier
+ INT16 iLoudnessModifier = iFinalLoudnessValue - iLoudnessValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iLoudnessValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iLoudnessModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iLoudnessModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iLoudnessModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iLoudnessModifier );
+ }
+ else if ( iLoudnessModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iLoudnessModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalLoudnessValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ /////////////////// RELIABILITY
+ {
+ // Set line to draw into
+ ubNumLine = 8;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Reliability value
+ INT8 iReliabilityValue = Item[gpItemDescObject->usItem].bReliability;
+
+ // Get final Reliability value
+ INT16 iFinalReliabilityValue = GetReliability( gpItemDescObject );
+
+ // Get Reliability modifier
+ INT16 iReliabilityModifier = iFinalReliabilityValue - iReliabilityValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iReliabilityValue < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iReliabilityValue );
+ }
+ else if ( iReliabilityValue > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iReliabilityValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iReliabilityModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iReliabilityModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iReliabilityModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iReliabilityModifier );
+ }
+ else if ( iReliabilityModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iReliabilityModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalReliabilityValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ /////////////////// REPAIR EASE
+ {
+ // Set line to draw into
+ ubNumLine = 9;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Reliability value
+ INT8 iRepairEaseValue = Item[gpItemDescObject->usItem].bRepairEase;
+
+ // Get final Reliability value
+ INT8 iFinalRepairEaseValue = iRepairEaseValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iRepairEaseValue < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iRepairEaseValue );
+ }
+ else if ( iRepairEaseValue > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iRepairEaseValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalRepairEaseValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ /////////////////// MinRangeForAimBonus
+ if( UsingNewCTHSystem() == false )
+ {
+ // Set line to draw into
+ ubNumLine = 10;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Reliability value
+ INT16 iMinRangeForAimBonusValue = Item[gpItemDescObject->usItem].minrangeforaimbonus / 10;
+
+ // Get final Reliability value
+ INT16 iFinalMinRangeForAimBonusValue = GetMinRangeForAimBonus(gpItemDescObject) / 10;
+
+ // Get Reliability modifier
+ INT16 iMinRangeForAimBonusModifier = iFinalMinRangeForAimBonusValue - iMinRangeForAimBonusValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iMinRangeForAimBonusValue < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iMinRangeForAimBonusValue );
+ }
+ else if ( iMinRangeForAimBonusValue > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iMinRangeForAimBonusValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iMinRangeForAimBonusModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iMinRangeForAimBonusModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iMinRangeForAimBonusModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iMinRangeForAimBonusModifier );
+ }
+ else if ( iMinRangeForAimBonusModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iMinRangeForAimBonusModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalMinRangeForAimBonusValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ /////////////////// ToHitBonus
+ if( UsingNewCTHSystem() == false )
+ {
+ // Set line to draw into
+ ubNumLine = 11;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Reliability value
+ INT16 iToHitBonusValue = Item[gpItemDescObject->usItem].tohitbonus;
+
+ // Get final Reliability value
+ INT16 iFinalToHitBonusValue = GetFlatToHitBonus(gpItemDescObject);
+
+ // Get Reliability modifier
+ INT16 iToHitBonusModifier = iFinalToHitBonusValue - iToHitBonusValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iToHitBonusValue < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iToHitBonusValue );
+ }
+ else if ( iToHitBonusValue > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iToHitBonusValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iToHitBonusModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iToHitBonusModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iToHitBonusModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iToHitBonusModifier );
+ }
+ else if ( iToHitBonusModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iToHitBonusModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalToHitBonusValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ///////////////////// DRAW AP
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem].rocketlauncher )
+ {
+ // Set line to draw into
+ ubNumLine = 13;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final Draw Cost
+ INT16 iFinalDrawAPCost = (Weapon[ gpItemDescObject->usItem ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction(gpItemDescObject)) / 100);
+
+ // Get base Draw Cost
+ INT16 iDrawAPCost = Weapon[ gpItemDescObject->usItem ].ubReadyTime;
+
+ // Get Draw Cost Modifier
+ INT16 iDrawAPCostModifier = iFinalDrawAPCost - iDrawAPCost;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iDrawAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iDrawAPCostModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iDrawAPCostModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iDrawAPCostModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iDrawAPCostModifier );
+ }
+ else if ( iDrawAPCostModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iDrawAPCostModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalDrawAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ ////////////////// SINGLE SHOT AP
+ if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
+ {
+ // Set line to draw into
+ ubNumLine = 14;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final Attack Cost
+ INT16 iFinalSingleAPCost = ubAttackAPs;
+
+ // Get base Attack Cost
+ INT16 iSingleAPCost = ubBasicAttackAPs;
+
+ // Get Attack Cost Modifier
+ INT16 iSingleAPCostModifier = iFinalSingleAPCost - iSingleAPCost;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iSingleAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iSingleAPCostModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iSingleAPCostModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iSingleAPCostModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iSingleAPCostModifier );
+ }
+ else if ( iSingleAPCostModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iSingleAPCostModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalSingleAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ /////////////////// BURST AP
+ if (GetShotsPerBurst(gpItemDescObject)> 0)
+ {
+ // Set line to draw into
+ ubNumLine = 15;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final Burst Cost
+ INT16 iFinalBurstAPCost = ubAttackAPs + CalcAPsToBurst( APBPConstants[DEFAULT_APS], gpItemDescObject );
+
+ // Get base Burst Cost
+ INT16 iBurstAPCost = ubBasicAttackAPs + CalcAPsToBurstNoModifier( APBPConstants[DEFAULT_APS], gpItemDescObject );
+
+ // Get Burst Cost Modifier
+ INT16 iBurstAPCostModifier = iFinalBurstAPCost - iBurstAPCost;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iBurstAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iBurstAPCostModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iBurstAPCostModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iBurstAPCostModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iBurstAPCostModifier );
+ }
+ else if ( iBurstAPCostModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iBurstAPCostModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalBurstAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ ////////////////// AUTO AP
if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
- // AUTOFIRE SHOTS PER 5 AP
- // equals
- mprintf( gWeaponStats[ 26 ].sX + gsInvDescX, gWeaponStats[ 26 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ // Set line to draw into
+ ubNumLine = 16;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
- // print value
+ // Get final Autofire Cost
+ INT16 iFinalAutoAPCost = ubAttackAPs + CalcAPsToAutofire( APBPConstants[DEFAULT_APS], gpItemDescObject, 3 );
+
+ // Get base Autofire Cost
+ INT16 iAutoAPCost = ubBasicAttackAPs + CalcAPsToAutofireNoModifier( APBPConstants[DEFAULT_APS], gpItemDescObject, 3 );
+
+ // Get Autofire Cost Modifier
+ INT16 iAutoAPCostModifier = iFinalAutoAPCost - iAutoAPCost;
+
+ // Print base value
SetFontForeground( 5 );
- swprintf( pStr, L"%2d", GetAutofireShotsPerFiveAPs( gpItemDescObject ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 5 ].sX + gsInvDescX + gWeaponStats[ 5 ].sValDx), (INT16)(gWeaponStats[ 5 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iAutoAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
- }
- }
-
- //////////////////////////////////////////////////////////////////////
- // Begin non-weapontype-specific data. These are not type specific because they represent bonuses
- // which may one day be added to various types of weapons by modders...
- if (GetFlatToHitBonus( gpItemDescObject ) != 0)
- {
- // HIT BONUS
- // equals
- mprintf( gWeaponStats[ 39 ].sX + gsInvDescX, gWeaponStats[ 39 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // Determine Color for Value Printing
- SetFontForeground( 5 );
- if (GetFlatToHitBonus ( gpItemDescObject ) < 0)
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if (GetFlatToHitBonus ( gpItemDescObject ) > 0)
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // Print Value
- if ( GetFlatToHitBonus ( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d", GetFlatToHitBonus ( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d", GetFlatToHitBonus ( gpItemDescObject ) );
- }
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 18 ].sX + gsInvDescX + gWeaponStats[ 18 ].sValDx), (INT16)(gWeaponStats[ 18 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
- if (GetFlatToHitBonus( gpItemDescObject ) > 0 && GetAverageBestLaserRange( gpItemDescObject ) / 10 > 0 )
- {
- // LASER RANGE
- // equals
- mprintf( gWeaponStats[ 40 ].sX + gsInvDescX, gWeaponStats[ 40 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
+ // Print modifier
SetFontForeground( 5 );
- swprintf( pStr, L"%2d", GetAverageBestLaserRange( gpItemDescObject ) / 10 );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 19 ].sX + gsInvDescX + gWeaponStats[ 19 ].sValDx), (INT16)(gWeaponStats[ 19 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ if (iAutoAPCostModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iAutoAPCostModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iAutoAPCostModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iAutoAPCostModifier );
+ }
+ else if ( iAutoAPCostModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iAutoAPCostModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
- }
- if (GetBipodBonus( gpItemDescObject ) != 0)
- {
- // BIPOD BONUS
- // equals
- mprintf( gWeaponStats[ 43 ].sX + gsInvDescX, gWeaponStats[ 43 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- if (GetBipodBonus( gpItemDescObject ) < 0)
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if (GetBipodBonus( gpItemDescObject ) > 0)
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- if ( GetBipodBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d", GetBipodBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d", GetBipodBonus( gpItemDescObject ) );
- }
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 22 ].sX + gsInvDescX + gWeaponStats[ 22 ].sValDx), (INT16)(gWeaponStats[ 22 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
- }
-
- if (IsScoped( gpItemDescObject ))
- {
- // SCOPE AIM BONUS
- // equals
- mprintf( gWeaponStats[ 41 ].sX + gsInvDescX, gWeaponStats[ 41 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- if (GetFlatAimBonus( gpItemDescObject ) < 0)
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if (GetFlatAimBonus( gpItemDescObject ) > 0)
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- if ( GetFlatAimBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d", GetFlatAimBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d", GetFlatAimBonus( gpItemDescObject ) );
- }
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 20 ].sX + gsInvDescX + gWeaponStats[ 20 ].sValDx), (INT16)(gWeaponStats[ 20 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- SetFontForeground( 6 );
-
-
- if (GetMinRangeForAimBonus(gpItemDescObject) > 0)
- {
- // SCOPE MINIMUM RANGE FOR AIM BONUS
- // equals
- mprintf( gWeaponStats[ 42 ].sX + gsInvDescX, gWeaponStats[ 42 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", GetMinRangeForAimBonus( gpItemDescObject )/10 );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 21 ].sX + gsInvDescX + gWeaponStats[ 21 ].sValDx), (INT16)(gWeaponStats[ 21 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalAutoAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
+
+ // Reset font color
SetFontForeground( 6 );
}
+
+ ///////////////////// RELOAD AP
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
+ {
+ // Set line to draw into
+ ubNumLine = 17;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final Reload Cost
+ INT16 iFinalReloadAPCost = GetAPsToReload( gpItemDescObject );
+
+ // Get base Reload Cost
+ INT16 iReloadAPCost = Weapon[ gpItemDescObject->usItem ].APsToReload;
+
+ // Get Reload Cost Modifier
+ INT16 iReloadAPCostModifier = iFinalReloadAPCost - iReloadAPCost;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iReloadAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iReloadAPCostModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( iReloadAPCostModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iReloadAPCostModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iReloadAPCostModifier );
+ }
+ else if ( iReloadAPCostModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iReloadAPCostModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalReloadAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ ///////////////////// MANUAL RELOAD AP
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher
+ && Weapon[gpItemDescObject->usItem].APsToReloadManually > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 18;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final Manual Reload Cost
+ INT16 iFinalManualReloadAPCost = Weapon[ gpItemDescObject->usItem ].APsToReloadManually;
+
+ // Get base Manual Reload Cost
+ INT16 iManualReloadAPCost = iFinalManualReloadAPCost;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iManualReloadAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalManualReloadAPCost );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+
+ ///////////////////// RECOIL X/Y
+ if ( UsingNewCTHSystem() == true )
+ {
+ if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
+ && GetShotsPerBurst(gpItemDescObject)> 0 || GetAutofireShotsPerFiveAPs(gpItemDescObject))
+ {
+
+ INT8 iFinalRecoilX = 0;
+ INT8 iFinalRecoilY = 0;
+
+ // Get final Recoil
+ GetRecoil( gpItemDescObject, &iFinalRecoilX, &iFinalRecoilY, 2 );
+
+ // Get base Recoil
+ INT8 iRecoilX = Weapon[ gpItemDescObject->usItem ].bRecoilX;
+ INT8 iRecoilY = Weapon[ gpItemDescObject->usItem ].bRecoilY;
+
+ if (iRecoilX == -127) { iRecoilX = 0; } // -127 means "invalid". These guns don't actually have any recoil parameters.
+ if (iRecoilY == -127) { iRecoilY = 0; }
+
+ // Get Recoil Modifiers
+ INT16 iRecoilXModifier = iFinalRecoilX - iRecoilX;
+ INT16 iRecoilYModifier = iFinalRecoilY - iRecoilY;
+
+ // RECOIL X
+
+ // Set line to draw into
+ ubNumLine = 19;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iRecoilX );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if ( (iRecoilXModifier < 0 && iRecoilX > 0) || (iRecoilXModifier > 0 && iRecoilX < 0) )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( (iRecoilXModifier > 0 && iRecoilX > 0) || (iRecoilXModifier < 0 && iRecoilX < 0) )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iRecoilXModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iRecoilXModifier );
+ }
+ else if ( iRecoilXModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iRecoilXModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalRecoilX );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+
+ // RECOIL Y
+
+ // Set line to draw into
+ ubNumLine = 20;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iRecoilY );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if ( (iRecoilYModifier < 0 && iRecoilY > 0) || (iRecoilYModifier > 0 && iRecoilY < 0) )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ else if ( (iRecoilYModifier > 0 && iRecoilY > 0) || (iRecoilYModifier < 0 && iRecoilY < 0) )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ // Add positive/negative sign
+ if ( iRecoilYModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iRecoilYModifier );
+ }
+ else if ( iRecoilYModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iRecoilYModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalRecoilY );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+ }
+ }
+ else ///////////////// BIPOD
+ {
+ if( GetBipodBonus(gpItemDescObject) > 0)
+ {
+ // Set line to draw into
+ ubNumLine = 20;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get base Reliability value
+ INT16 iBipodValue = Item[gpItemDescObject->usItem].bipod;
+
+ // Get final Reliability value
+ INT16 iFinalBipodValue = GetBipodBonus(gpItemDescObject);
+
+ // Get Reliability modifier
+ INT16 iBipodModifier = iFinalBipodValue - iBipodValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ if (iBipodValue < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iBipodValue );
+ }
+ else if ( iBipodValue > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iBipodValue );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iBipodModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iBipodModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iBipodModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iBipodModifier );
+ }
+ else if ( iBipodModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iBipodModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalBipodValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+ }
+
+ /////////////////// AUTOFIRE BULLETS PER 5 AP
+ if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN && !Item[ gpItemDescObject->usItem].rocketlauncher
+ && GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 21;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final B/5AP
+ INT16 iFinalB5AP = GetAutofireShotsPerFiveAPs( gpItemDescObject );
+
+ // Get base B/5AP Cost
+ INT16 iB5AP = iFinalB5AP;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iB5AP );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalB5AP );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
+
+ }
+ }
+ if (gubDescBoxPage == 2)
+ {
+ DrawAdvancedValues( gpItemDescObject );
}
}
@@ -4782,363 +5969,201 @@ void DrawAmmoValues( OBJECTTYPE * gpItemDescObject, int shotsLeft )
{
static CHAR16 pStr[ 100 ];
INT16 usY;
- INT16 sStrX;
- UINT16 uiStringLength;
+ INT16 usX;
+ UINT8 ubNumLine;
+ INT16 sLeft, sTop, sWidth, sHeight;
if( UsingEDBSystem() == 0 )
return;
- // AMMO AMOUNT
- // label
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 0 ].sX + gsInvDescX, gWeaponStats[ 0 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 16 ] );
-
- // data
- SetFontForeground( 5 );
- swprintf( pStr, L"%d/%d", shotsLeft, Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubMagSize ); //Pulmu: Correct # of rounds for stacked ammo.
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 0 ].sX + gsInvDescX + gWeaponStats[ 0 ].sValDx+6), (INT16)(gWeaponStats[ 0 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- if (UsingEDBSystem() == 2)
- mprintf( sStrX - 6, gWeaponStats[ 0 ].sY + gsInvDescY + 12, pStr );
- else
- mprintf( sStrX, gWeaponStats[ 0 ].sY + gsInvDescY, pStr );
-
- // AMMO PENETRATION
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 23 ].sX + gsInvDescX -5, gWeaponStats[ 23 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- FLOAT fArmourImpactReduction = 0.0;
- fArmourImpactReduction = (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionDivisor;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( fArmourImpactReduction > 1.0 )
+ if (gubDescBoxPage == 0)
{
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( fArmourImpactReduction < 1.0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- swprintf( pStr, L"%1.2f", fArmourImpactReduction );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 2 ].sX + gsInvDescX + gWeaponStats[ 2 ].sValDx), (INT16)(gWeaponStats[ 2 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 2 ].sY + gsInvDescY, pStr );
-
- // AMMO TUMBLE
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 24 ].sX + gsInvDescX -5, gWeaponStats[ 24 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- FLOAT fAfterArmourImpactReduction = 0.0;
- fAfterArmourImpactReduction = (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].afterArmourDamageMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].afterArmourDamageDivisor;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( fAfterArmourImpactReduction < 1.0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( fAfterArmourImpactReduction > 1.0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- swprintf( pStr, L"%1.2f", fAfterArmourImpactReduction );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 3 ].sX + gsInvDescX + gWeaponStats[ 3 ].sValDx), (INT16)(gWeaponStats[ 3 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 3 ].sY + gsInvDescY, pStr );
-
- // AMMO PRE-ARMOR EXPLOSION
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 25 ].sX + gsInvDescX -5, gWeaponStats[ 25 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- FLOAT fBeforeArmourImpactReduction = 0.0;
- fBeforeArmourImpactReduction = (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].beforeArmourDamageMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].beforeArmourDamageDivisor;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( fBeforeArmourImpactReduction < 1.0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( fBeforeArmourImpactReduction > 1.0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- swprintf( pStr, L"%1.2f", fBeforeArmourImpactReduction );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 4 ].sX + gsInvDescX + gWeaponStats[ 4 ].sValDx), (INT16)(gWeaponStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 4 ].sY + gsInvDescY, pStr );
-
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 )
- {
- // AMMO RANGE BONUS
- // equals
+ ////////////////////////// AMMO REMAINING
SetFontForeground( 6 );
- mprintf( gWeaponStats[ 37 ].sX + gsInvDescX, gWeaponStats[ 37 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ swprintf( pStr, gWeaponStatsDesc[16] );
+ mprintf( gItemDescTextRegions[1].sLeft, gItemDescTextRegions[1].sTop, pStr );
- // determine value
- INT16 iRangeBonus = 0;
- iRangeBonus = Item[ gpItemDescObject->usItem ].rangebonus;
-
- // determine value print color
SetFontForeground( 5 );
- if ( iRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iRangeBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iRangeBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iRangeBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iRangeBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 16 ].sX + gsInvDescX + gWeaponStats[ 16 ].sValDx), (INT16)(gWeaponStats[ 16 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 16 ].sY + gsInvDescY, pStr );
+ swprintf( pStr, L"%d/%d", (*gpItemDescObject)[ gubItemDescStatusIndex ]->data.ubShotsLeft, Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubMagSize );
+ FindFontRightCoordinates( gItemDescTextRegions[1].sLeft, gItemDescTextRegions[1].sTop, gItemDescTextRegions[1].sRight - gItemDescTextRegions[1].sLeft, gItemDescTextRegions[1].sBottom - gItemDescTextRegions[1].sTop, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
-
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 )
+ else if (gubDescBoxPage == 1)
{
- // AMMO DAMAGE BONUS
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 38 ].sX + gsInvDescX, gWeaponStats[ 38 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ ////////////////////////////////////////////////// HEADERS
- // determine value
- INT16 iDamageBonus = 0;
- iDamageBonus = Item[ gpItemDescObject->usItem ].damagebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iDamageBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iDamageBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iDamageBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iDamageBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iDamageBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 17 ].sX + gsInvDescX + gWeaponStats[ 17 ].sValDx), (INT16)(gWeaponStats[ 17 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 17 ].sY + gsInvDescY, pStr );
- }
+ SetFontForeground( FONT_MCOLOR_WHITE );
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 )
- {
- // AMMO TO-HIT BONUS
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 39 ].sX + gsInvDescX, gWeaponStats[ 39 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ // "PRIMARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 0 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sTop, gItemDescGenHeaderRegions[0].sRight - gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sBottom - gItemDescGenHeaderRegions[0].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
- // determine value
- INT16 iToHitBonus = 0;
- iToHitBonus = Item[ gpItemDescObject->usItem ].tohitbonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iToHitBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iToHitBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iToHitBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iToHitBonus );
- }
- else
- {
- swprintf( pStr, L"%2d", iToHitBonus );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 18 ].sX + gsInvDescX + gWeaponStats[ 18 ].sValDx), (INT16)(gWeaponStats[ 18 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 18 ].sY + gsInvDescY, pStr );
- }
+ // "SECONDARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 1 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sTop, gItemDescGenHeaderRegions[1].sRight - gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sBottom - gItemDescGenHeaderRegions[1].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus )
- {
- // AUTO PENALTY MODIFIER
- // equals
- mprintf( gWeaponStats[ 40 ].sX + gsInvDescX, gWeaponStats[ 40 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
SetFontForeground( 6 );
- // determine value
- INT16 iAutoBonus = 0;
- iAutoBonus = Item[ gpItemDescObject->usItem ].autofiretohitbonus;
+ ///////////////////////////////////////////////////// INDEXES
- // determine value print color
- SetFontForeground( 5 );
- if ( iAutoBonus < 0 )
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ for (UINT8 cnt = 0; cnt < 4; cnt++)
{
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iAutoBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAutoBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iAutoBonus );
- }
- else
- {
- swprintf( pStr, L"%2d", iAutoBonus );
+ // Select "PROPERTY", "0", "+" or "=" as appropriate.
+ swprintf(pStr, L"%s", gzItemDescGenIndexes[ cnt ]);
+
+ FindFontCenterCoordinates( gItemDescGenIndexRegions[0][cnt].sLeft, gItemDescGenIndexRegions[0][cnt].sTop, gItemDescGenIndexRegions[0][cnt].sRight - gItemDescGenIndexRegions[0][cnt].sLeft, gItemDescGenIndexRegions[0][cnt].sBottom - gItemDescGenIndexRegions[0][cnt].sTop, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 19 ].sX + gsInvDescX + gWeaponStats[ 19 ].sValDx), (INT16)(gWeaponStats[ 19 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 19 ].sY + gsInvDescY, pStr );
- }
-
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus )
- {
- // BURST PENALTY MODIFIER
- // equals
SetFontForeground( 6 );
- mprintf( gWeaponStats[ 41 ].sX + gsInvDescX, gWeaponStats[ 41 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
- // determine value
- INT16 iBurstBonus = 0;
- iBurstBonus = Item[ gpItemDescObject->usItem ].bursttohitbonus;
+ ///////////////// ARMOR PIERCING
+ {
+ // Set line to draw into
+ ubNumLine = 0;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
- // determine value print color
- SetFontForeground( 5 );
- if ( iBurstBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iBurstBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iBurstBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iBurstBonus );
- }
- else
- {
- swprintf( pStr, L"%2d", iBurstBonus );
+ // Get final Penetration
+ FLOAT fArmourImpactReduction = 1.0f / ((FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].armourImpactReductionDivisor);
+
+ // Get base Penetration
+ FLOAT fFinalArmourImpactReduction = fArmourImpactReduction;
+
+ // Print base value
+ SetFontForeground( 5 );
+ if ( fArmourImpactReduction < 1.0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( fArmourImpactReduction > 1.0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", fArmourImpactReduction );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", fFinalArmourImpactReduction );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 20 ].sX + gsInvDescX + gWeaponStats[ 20 ].sValDx), (INT16)(gWeaponStats[ 20 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 20 ].sY + gsInvDescY, pStr );
+ ///////////////////// TUMBLING
+ {
+ // Set line to draw into
+ ubNumLine = 1;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+
+ // Get final Tumbling
+ FLOAT fAfterArmourImpactReduction = (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].afterArmourDamageMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].afterArmourDamageDivisor;
+
+ // Get base Tumbling
+ FLOAT fFinalAfterArmourImpactReduction = fAfterArmourImpactReduction;
+
+ // Print base value
+ SetFontForeground( 5 );
+ if ( fAfterArmourImpactReduction < 1.0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( fAfterArmourImpactReduction > 1.0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", fAfterArmourImpactReduction );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", fFinalAfterArmourImpactReduction );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ///////////////////// PRE-ARMOR EXPLOSION
+ {
+ // Set line to draw into
+ ubNumLine = 2;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final Explosion
+ FLOAT fPreArmourImpactReduction = (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].beforeArmourDamageMultiplier / (FLOAT) AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].beforeArmourDamageDivisor;
+
+ // Get base Explosion
+ FLOAT fFinalPreArmourImpactReduction = fPreArmourImpactReduction;
+
+ // Print base value
+ SetFontForeground( 5 );
+ if ( fPreArmourImpactReduction < 1.0 )
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( fPreArmourImpactReduction > 1.0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", fPreArmourImpactReduction );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%3.1f", fFinalPreArmourImpactReduction );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
}
-
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 )
+ else if (gubDescBoxPage == 2)
{
- // AMMO RELIABILITY BONUS
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 42 ].sX + gsInvDescX, gWeaponStats[ 42 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iReliabilityBonus = 0;
- iReliabilityBonus = Item[ gpItemDescObject->usItem ].bReliability;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iReliabilityBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iReliabilityBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iReliabilityBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iReliabilityBonus );
- }
- else
- {
- swprintf( pStr, L"%2d", iReliabilityBonus );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 21 ].sX + gsInvDescX + gWeaponStats[ 21 ].sValDx), (INT16)(gWeaponStats[ 21 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 21 ].sY + gsInvDescY, pStr );
- }
-
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction > 0 )
- {
- // AMMO NOISE SUPPRESSION
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 41 ].sX + gsInvDescX, gWeaponStats[ 41 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iNoiseSuppression = 0;
- iNoiseSuppression = Item[ gpItemDescObject->usItem ].percentnoisereduction * -1;
-
- SetFontForeground( 5 );
- if ( iNoiseSuppression > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iNoiseSuppression < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iNoiseSuppression > 0 )
- {
- swprintf( pStr, L"%+2d%%", iNoiseSuppression );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iNoiseSuppression );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 22 ].sX + gsInvDescX + gWeaponStats[ 22 ].sValDx), (INT16)(gWeaponStats[ 22 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 22 ].sY + gsInvDescY, pStr );
+ DrawAdvancedValues( gpItemDescObject );
}
}
@@ -5146,145 +6171,392 @@ void DrawExplosiveValues( OBJECTTYPE * gpItemDescObject )
{
static CHAR16 pStr[ 100 ];
INT16 usY;
- INT16 sStrX;
- UINT16 uiStringLength;
+ INT16 usX;
+ UINT8 ubNumLine;
+ INT16 sLeft, sTop, sWidth, sHeight;
if( UsingEDBSystem() == 0 )
return;
- // DAMAGE
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage > 0 )
+ if (gubDescBoxPage == 1)
{
- // equals
+ ////////////////////////////////////////////////// HEADERS
+
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ // "PRIMARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 0 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sTop, gItemDescGenHeaderRegions[0].sRight - gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sBottom - gItemDescGenHeaderRegions[0].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
+
+ // "SECONDARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 1 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sTop, gItemDescGenHeaderRegions[1].sRight - gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sBottom - gItemDescGenHeaderRegions[1].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
+
SetFontForeground( 6 );
- mprintf( gWeaponStats[ 23 ].sX + gsInvDescX, gWeaponStats[ 23 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
- // print value
- SetFontForeground( 5 );
-
- // HEADROCK HAM 3.6: Can now use negative modifier.
- UINT16 explDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage );
+ ///////////////////////////////////////////////////// INDEXES
- //swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage + ( (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage * gGameExternalOptions.ubExplosivesDamageMultiplier ) / 100 ));
- swprintf( pStr, L"%2d", explDamage );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 2 ].sX + gsInvDescX + gWeaponStats[ 2 ].sValDx), (INT16)(gWeaponStats[ 2 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 2 ].sY + gsInvDescY, pStr );
- }
+ SetFontForeground( FONT_MCOLOR_WHITE );
- // STUN DAMAGE
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage > 0 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 24 ].sX + gsInvDescX, gWeaponStats[ 24 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
-
- // HEADROCK HAM 3.6: Can now use negative modifier.
- UINT16 explStunDamage = (UINT16) GetModifiedExplosiveDamage( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage );
-
- //swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage + ( (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage * gGameExternalOptions.ubExplosivesDamageMultiplier ) / 100 ));
- swprintf( pStr, L"%2d", explStunDamage );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 3 ].sX + gsInvDescX + gWeaponStats[ 3 ].sValDx), (INT16)(gWeaponStats[ 3 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 3 ].sY + gsInvDescY, pStr );
- }
-
- // LOUDNESS
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 25 ].sX + gsInvDescX, gWeaponStats[ 25 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolume );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 4 ].sX + gsInvDescX + gWeaponStats[ 4 ].sValDx), (INT16)(gWeaponStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 4 ].sY + gsInvDescY, pStr );
-
- // VOLATILITY
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility > 0 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 26 ].sX + gsInvDescX, gWeaponStats[ 26 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 5 ].sX + gsInvDescX + gWeaponStats[ 5 ].sValDx), (INT16)(gWeaponStats[ 5 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 5 ].sY + gsInvDescY, pStr );
- }
-
- // SINGLE-EVENT EXPLOSION data
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0 )
- {
- // BLAST RADIUS
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 24 ].sX + gsInvDescX, gWeaponStats[ 24 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%d", 1 + ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubRadius * 2 ) );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontCenterCoordinates( (INT16)(gWeaponStats[ 45 ].sX + gsInvDescX), (INT16)(gWeaponStats[ 45 ].sY + gsInvDescY ), 12 ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 45 ].sY + gsInvDescY, pStr );
-
- }
- // PROLONGED EXPLOSION data
- else if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
- {
- // DURATION
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 34 ].sX + gsInvDescX, gWeaponStats[ 34 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 13 ].sX + gsInvDescX + gWeaponStats[ 13 ].sValDx), (INT16)(gWeaponStats[ 13 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 13 ].sY + gsInvDescY, pStr );
-
- // Headrock: this integer contains the number of the array item that contains the location
- // in which to display each radius value. If the explosive is a light, the values are displayed
- // in reverse locations.
-
- INT16 isLightLocation = 0;
-
- if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 4 )
+ for (UINT8 cnt = 0; cnt < 4; cnt++)
{
- isLightLocation = 2;
+ // Select "PROPERTY", "0", "+" or "=" as appropriate.
+ swprintf(pStr, L"%s", gzItemDescGenIndexes[ cnt ]);
+
+ FindFontCenterCoordinates( gItemDescGenIndexRegions[0][cnt].sLeft, gItemDescGenIndexRegions[0][cnt].sTop, gItemDescGenIndexRegions[0][cnt].sRight - gItemDescGenIndexRegions[0][cnt].sLeft, gItemDescGenIndexRegions[0][cnt].sBottom - gItemDescGenIndexRegions[0][cnt].sTop, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
- // STARTING RADIUS
- // equals
SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 33 ].sX + gsInvDescX, gWeaponStats[ 33 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%d", 1 + ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStartRadius * 2) );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontCenterCoordinates( (INT16)(gWeaponStats[ 44+isLightLocation ].sX + gsInvDescX), (INT16)(gWeaponStats[ 44+isLightLocation ].sY + gsInvDescY ), 12 ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 44+isLightLocation ].sY + gsInvDescY, pStr );
+ ////////////////// DAMAGE
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 0;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
- // FINAL RADIUS
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 33 ].sX + gsInvDescX, gWeaponStats[ 33 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ // Get final damage
+ INT16 iFinalDamage = GetModifiedExplosiveDamage( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDamage );
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%d", 1 + ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubRadius * 2) );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontCenterCoordinates( (INT16)(gWeaponStats[ 46-isLightLocation ].sX + gsInvDescX), (INT16)(gWeaponStats[ 46-isLightLocation ].sY + gsInvDescY ), 12 ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 46-isLightLocation ].sY + gsInvDescY, pStr );
+ // Get base damage
+ INT16 iDamage = iFinalDamage;
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iDamage );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalDamage );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ /////////////////// STUN DAMAGE
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 1;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final damage
+ INT16 iFinalStunDamage = GetModifiedExplosiveDamage( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStunDamage);
+
+ // Get base damage
+ INT16 iStunDamage = iFinalStunDamage;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iStunDamage );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalStunDamage );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ////////////////////// BLAST RADIUS
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration == 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 2;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final damage
+ INT16 iFinalBlastRadius = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubRadius;
+
+ // Get base damage
+ INT16 iBlastRadius = iFinalBlastRadius;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iBlastRadius );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalBlastRadius );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ////////////////////// PROLONGED EFFECT: START
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 2;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ INT16 iFinalEffectStartRadius;
+ // Get final damage
+ if (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 4)
+ {
+ iFinalEffectStartRadius = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubRadius;
+ }
+ else
+ {
+ iFinalEffectStartRadius = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStartRadius;
+ }
+
+ // Get base damage
+ INT16 iEffectStartRadius = iFinalEffectStartRadius;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iEffectStartRadius );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalEffectStartRadius );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ////////////////////// PROLONGED EFFECT: END
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 3;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ INT16 iFinalEffectEndRadius;
+ // Get final damage
+ if (Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubType == 4)
+ {
+ iFinalEffectEndRadius = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubStartRadius;
+ }
+ else
+ {
+ iFinalEffectEndRadius = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubRadius;
+ }
+
+ // Get base damage
+ INT16 iEffectEndRadius = iFinalEffectEndRadius;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iEffectEndRadius );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalEffectEndRadius );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ ////////////////////// PROLONGED EFFECT: DURATION
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 4;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final damage
+ INT16 iFinalEffectDuration = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDuration;
+
+ // Get base damage
+ INT16 iEffectDuration = iFinalEffectDuration;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iEffectDuration );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalEffectDuration );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ //////////////////// LOUDNESS
+ {
+ // Set line to draw into
+ ubNumLine = 5;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final damage
+ INT16 iFinalLoudness = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolume;
+
+ // Get base damage
+ INT16 iLoudness = iFinalLoudness;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iLoudness );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalLoudness );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
+ //////////////////// VOLATILITY
+ if ( Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility > 0 )
+ {
+ // Set line to draw into
+ ubNumLine = 6;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get final damage
+ INT16 iFinalVolatility = Explosive[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubVolatility;
+
+ // Get base damage
+ INT16 iVolatility = iFinalVolatility;
+
+ // Print base value
+ SetFontForeground( 5 );
+
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iVolatility );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // no modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalVolatility );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+ }
+ else if (gubDescBoxPage == 2)
+ {
+ DrawAdvancedValues( gpItemDescObject );
}
}
@@ -5292,1872 +6564,2392 @@ void DrawArmorValues( OBJECTTYPE * gpItemDescObject )
{
static CHAR16 pStr[ 100 ];
INT16 usY;
- INT16 sStrX;
- UINT16 uiStringLength;
+ INT16 usX;
+ UINT8 ubNumLine;
+ INT16 sLeft, sTop, sWidth, sHeight;
if( UsingEDBSystem() == 0 )
return;
- // ARMOR VALUE
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 23 ].sX + gsInvDescX, gWeaponStats[ 23 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // The following attributes are only drawn when the UDB is set to show the General Page.
- // print value
- SetFontForeground( 5 );
-
- // Calculate Value including attachments
- UINT16 iProtection = 0;
- iProtection = Armour[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubProtection;
-
- for (attachmentList::iterator iter = (*gpItemDescObject)[0]->attachments.begin(); iter != (*gpItemDescObject)[0]->attachments.end(); ++iter)
+ if (gubDescBoxPage == 1)
{
- if (Item[ iter->usItem ].usItemClass == IC_ARMOUR)
- {
- iProtection += Armour[Item[iter->usItem].ubClassIndex].ubProtection;
- }
- }
+ ////////////////////////////////////////////////// HEADERS
- swprintf( pStr, L"%2d", iProtection );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 2 ].sX + gsInvDescX + gWeaponStats[ 2 ].sValDx), (INT16)(gWeaponStats[ 2 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- //wcscat( pStr, L"%%" );
- mprintf( sStrX, gWeaponStats[ 2 ].sY + gsInvDescY, pStr );
+ SetFontForeground( FONT_MCOLOR_WHITE );
- // ARMOR COVERAGE
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 23 ].sX + gsInvDescX, gWeaponStats[ 23 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ // "PRIMARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 0 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sTop, gItemDescGenHeaderRegions[0].sRight - gItemDescGenHeaderRegions[0].sLeft, gItemDescGenHeaderRegions[0].sBottom - gItemDescGenHeaderRegions[0].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d%%", Armour[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubCoverage );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 3 ].sX + gsInvDescX + gWeaponStats[ 3 ].sValDx), (INT16)(gWeaponStats[ 3 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
+ // "SECONDARY" header
+ swprintf( pStr, L"%s", gzItemDescGenHeaders[ 1 ] );
+ FindFontCenterCoordinates( gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sTop, gItemDescGenHeaderRegions[1].sRight - gItemDescGenHeaderRegions[1].sLeft, gItemDescGenHeaderRegions[1].sBottom - gItemDescGenHeaderRegions[1].sTop, pStr, BLOCKFONT2, &usX, &usY );
+ mprintf( usX, usY, pStr );
- mprintf( sStrX, gWeaponStats[ 3 ].sY + gsInvDescY, pStr );
-
- // ARMOR DEGRADE
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 25 ].sX + gsInvDescX, gWeaponStats[ 25 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d", Armour[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDegradePercent );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 4 ].sX + gsInvDescX + gWeaponStats[ 4 ].sValDx), (INT16)(gWeaponStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 4 ].sY + gsInvDescY, pStr );
-
- // AP BONUS
- if ( GetAPBonus ( gpItemDescObject ) != 0 )
- {
- // equals
SetFontForeground( 6 );
- mprintf( gWeaponStats[ 30 ].sX + gsInvDescX, gWeaponStats[ 30 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
- // determine value
- INT16 iAPBonus = 0;
- iAPBonus = GetAPBonus( gpItemDescObject );
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iAPBonus < 0 )
+ ///////////////////////////////////////////////////// INDEXES
+
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ for (UINT8 cnt = 0; cnt < 4; cnt++)
{
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Select "PROPERTY", "0", "+" or "=" as appropriate.
+ swprintf(pStr, L"%s", gzItemDescGenIndexes[ cnt ]);
+
+ FindFontCenterCoordinates( gItemDescGenIndexRegions[0][cnt].sLeft, gItemDescGenIndexRegions[0][cnt].sTop, gItemDescGenIndexRegions[0][cnt].sRight - gItemDescGenIndexRegions[0][cnt].sLeft, gItemDescGenIndexRegions[0][cnt].sBottom - gItemDescGenIndexRegions[0][cnt].sTop, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
- else if ( iAPBonus > 0 )
+
+ SetFontForeground( 6 );
+
+ /////////////////// PROTECTION
{
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ // Set line to draw into
+ ubNumLine = 0;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get protection value
+ UINT16 iProtectionValue = Armour[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubProtection;
+
+ // Get Final Protection value
+ UINT16 iFinalProtectionValue = iProtectionValue;
+ for (attachmentList::iterator iter = (*gpItemDescObject)[0]->attachments.begin(); iter != (*gpItemDescObject)[0]->attachments.end(); ++iter)
+ {
+ if (Item[ iter->usItem ].usItemClass == IC_ARMOUR)
+ {
+ iFinalProtectionValue += Armour[Item[iter->usItem].ubClassIndex].ubProtection;
+ }
+ }
+
+ // Get difference
+ INT16 iProtectionModifier = iFinalProtectionValue - iProtectionValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iProtectionValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ if (iProtectionModifier < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ }
+ else if ( iProtectionModifier > 0 )
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ }
+ // Add positive/negative sign
+ if ( iProtectionModifier > 0 )
+ {
+ swprintf( pStr, L"+%d", iProtectionModifier );
+ }
+ else if ( iProtectionModifier < 0 )
+ {
+ swprintf( pStr, L"%d", iProtectionModifier );
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ }
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalProtectionValue );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
}
-
- // print value
- if ( iAPBonus > 0 )
+
+ /////////////////// COVERAGE
{
- swprintf( pStr, L"%+2d", iAPBonus );
+ // Set line to draw into
+ ubNumLine = 1;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get Coverage value
+ UINT8 iCoverageValue = Armour[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubCoverage;
+
+ // Get Final Coverage value
+ UINT8 iFinalCoverageValue = iCoverageValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iCoverageValue );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalCoverageValue );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
}
- else
+
+ //////////////////// DEGRADE RATE
{
- swprintf( pStr, L"%2d", iAPBonus );
+ // Set line to draw into
+ ubNumLine = 2;
+ // Set Y coordinates
+ sTop = gItemDescGenRegions[ubNumLine][1].sTop;
+ sHeight = gItemDescGenRegions[ubNumLine][1].sBottom - sTop;
+
+ // Get Degrade value
+ UINT8 iDegradeValue = Armour[Item[ gpItemDescObject->usItem ].ubClassIndex ].ubDegradePercent;
+
+ // Get Final Degrade value
+ UINT8 iFinalDegradeValue = iDegradeValue;
+
+ // Print base value
+ SetFontForeground( 5 );
+ sLeft = gItemDescGenRegions[ubNumLine][1].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][1].sRight - sLeft;
+ swprintf( pStr, L"%d", iDegradeValue );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ mprintf( usX, usY, pStr );
+
+ // Print modifier
+ SetFontForeground( 5 );
+ swprintf( pStr, L"--" );
+ sLeft = gItemDescGenRegions[ubNumLine][2].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][2].sRight - sLeft;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ // Print final value
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ sLeft = gItemDescGenRegions[ubNumLine][3].sLeft;
+ sWidth = gItemDescGenRegions[ubNumLine][3].sRight - sLeft;
+ swprintf( pStr, L"%d", iFinalDegradeValue );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ mprintf( usX, usY, pStr );
+
+ // Reset font color
+ SetFontForeground( 6 );
}
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 9 ].sX + gsInvDescX + gWeaponStats[ 9 ].sValDx), (INT16)(gWeaponStats[ 9 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 9 ].sY + gsInvDescY, pStr );
+ }
+ else if (gubDescBoxPage == 2)
+ {
+ DrawAdvancedValues( gpItemDescObject );
+ }
+}
+
+void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject )
+{
+ if (gubDescBoxPage != 2)
+ {
+ return;
}
- // AIM BONUS
- if ( GetFlatAimBonus( gpItemDescObject ) != 0 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 31 ].sX + gsInvDescX, gWeaponStats[ 31 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ INT16 sFirstLine = gubDescBoxLine;
+ INT16 sLastLine = gubDescBoxLine + NUM_UDB_ADV_LINES;
+ INT16 cnt = 0;
- // determine value
- INT16 iAimBonus = 0;
- iAimBonus = GetFlatAimBonus( gpItemDescObject );
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iAimBonus < 0 )
+ static CHAR16 pStr[ 100 ];
+ INT16 usY;
+ INT16 usX;
+ INT16 sLeft, sTop, sWidth, sHeight;
+
+ INT16 iModifier[3];
+ FLOAT iFloatModifier[3];
+
+ INT8 bDummyValue;
+ INT8 bRecoilModifier;
+
+ ///////////////////// INDEX
+ swprintf( pStr, gzItemDescGenIndexes[0] );
+ sLeft = gItemDescAdvIndexRegions[0][0].sLeft;
+ sTop = gItemDescAdvIndexRegions[0][0].sTop;
+ sWidth = gItemDescAdvIndexRegions[0][0].sRight - sLeft;
+ sHeight = gItemDescAdvIndexRegions[0][0].sBottom - sTop;
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ mprintf( usX, usY, pStr );
+
+ ///////////////////// ACCURACY MODIFIER
+ iModifier[0] = GetAccuracyModifier( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 && UsingNewCTHSystem() == true)
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
{
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iAimBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAimBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iAimBonus );
- }
- else
- {
- swprintf( pStr, L"%2d", iAimBonus );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 10 ].sX + gsInvDescX + gWeaponStats[ 10 ].sValDx), (INT16)(gWeaponStats[ 10 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 10 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // WOODLAND CAMO
- if ( GetCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// FLAT BASE MODIFIER
+ iModifier[0] = GetFlatBaseModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetFlatBaseModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetFlatBaseModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 31 ].sX + gsInvDescX, gWeaponStats[ 31 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // print value
- SetFontForeground( 5 );
- if ( GetCamoBonus( gpItemDescObject ) < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( GetCamoBonus( gpItemDescObject ) > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( GetCamoBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d%%", GetCamoBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d%%", GetCamoBonus( gpItemDescObject ) );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 11 ].sX + gsInvDescX + gWeaponStats[ 11 ].sValDx), (INT16)(gWeaponStats[ 11 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 11 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // URBAN CAMO
- if ( GetUrbanCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// PERCENT BASE MODIFIER
+ iModifier[0] = GetPercentBaseModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetPercentBaseModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetPercentBaseModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 32 ].sX + gsInvDescX, gWeaponStats[ 32 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // print value
- SetFontForeground( 5 );
- if ( GetUrbanCamoBonus( gpItemDescObject ) < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( GetUrbanCamoBonus( gpItemDescObject ) > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( GetUrbanCamoBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d%%", GetUrbanCamoBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d%%", GetUrbanCamoBonus( gpItemDescObject ) );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 12 ].sX + gsInvDescX + gWeaponStats[ 12 ].sValDx), (INT16)(gWeaponStats[ 12 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 12 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // DESERT CAMO
- if ( GetDesertCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// FLAT AIM MODIFIER
+ iModifier[0] = GetFlatAimModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetFlatAimModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetFlatAimModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 34 ].sX + gsInvDescX, gWeaponStats[ 34 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // print value
- SetFontForeground( 5 );
- if ( GetDesertCamoBonus( gpItemDescObject ) < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( GetDesertCamoBonus( gpItemDescObject ) > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( GetDesertCamoBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d%%", GetDesertCamoBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d%%", GetDesertCamoBonus( gpItemDescObject ) );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 13 ].sX + gsInvDescX + gWeaponStats[ 13 ].sValDx), (INT16)(gWeaponStats[ 13 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 13 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // SNOW CAMO
- if ( GetSnowCamoBonus( gpItemDescObject ) > 0 )
+ ///////////////////// PERCENT AIM MODIFIER
+ iModifier[0] = GetPercentAimModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetPercentAimModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetPercentAimModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 35 ].sX + gsInvDescX, gWeaponStats[ 35 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // print value
- SetFontForeground( 5 );
- if ( GetSnowCamoBonus( gpItemDescObject ) < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( GetSnowCamoBonus( gpItemDescObject ) > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( GetSnowCamoBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d%%", GetSnowCamoBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d%%", GetSnowCamoBonus( gpItemDescObject ) );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 14 ].sX + gsInvDescX + gWeaponStats[ 14 ].sValDx), (INT16)(gWeaponStats[ 14 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 14 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // STEALTH
- if ( GetBasicStealthBonus( gpItemDescObject ) != 0 )
+ ///////////////////// AIMING LEVELS MODIFIER
+ iModifier[0] = GetAimLevelsModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetAimLevelsModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetAimLevelsModifier( gpItemDescObject, ANIM_PRONE );
+ if (iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0 )
{
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 35 ].sX + gsInvDescX, gWeaponStats[ 35 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // print value
- SetFontForeground( 5 );
- if ( GetBasicStealthBonus( gpItemDescObject ) < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( GetBasicStealthBonus( gpItemDescObject ) > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( GetBasicStealthBonus( gpItemDescObject ) > 0 )
- {
- swprintf( pStr, L"%+2d%%", GetBasicStealthBonus( gpItemDescObject ) );
- }
- else
- {
- swprintf( pStr, L"%2d%%", GetBasicStealthBonus( gpItemDescObject ) );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 15 ].sX + gsInvDescX + gWeaponStats[ 15 ].sValDx), (INT16)(gWeaponStats[ 15 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 15 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].visionrangebonus != 0 )
+ ///////////////////// CTH CAP MODIFIER
+ iModifier[0] = GetPercentCapModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetPercentCapModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetPercentCapModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 37 ].sX + gsInvDescX, gWeaponStats[ 37 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // determine value
- INT16 iVisionRangeBonus = 0;
- iVisionRangeBonus = Item[ gpItemDescObject->usItem ].visionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iVisionRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iVisionRangeBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iVisionRangeBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iVisionRangeBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iVisionRangeBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 16 ].sX + gsInvDescX + gWeaponStats[ 16 ].sValDx), (INT16)(gWeaponStats[ 16 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 16 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // DAY VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].dayvisionrangebonus != 0 )
+ ///////////////////// GUN HANDLING MODIFIER
+ iModifier[0] = GetPercentHandlingModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetPercentHandlingModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetPercentHandlingModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 38 ].sX + gsInvDescX, gWeaponStats[ 38 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // determine value
- INT16 iVisionRangeBonus = 0;
- iVisionRangeBonus = Item[ gpItemDescObject->usItem ].dayvisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iVisionRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iVisionRangeBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iVisionRangeBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iVisionRangeBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iVisionRangeBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 17 ].sX + gsInvDescX + gWeaponStats[ 17 ].sValDx), (INT16)(gWeaponStats[ 17 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 17 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // NIGHT VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].nightvisionrangebonus != 0 )
+ ///////////////////// DROP COMPENSATION MODIFIER
+ iModifier[0] = GetDropCompensationModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetDropCompensationModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetDropCompensationModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 39 ].sX + gsInvDescX, gWeaponStats[ 39 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // determine value
- INT16 iVisionRangeBonus = 0;
- iVisionRangeBonus = Item[ gpItemDescObject->usItem ].nightvisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iVisionRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iVisionRangeBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iVisionRangeBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iVisionRangeBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iVisionRangeBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 18 ].sX + gsInvDescX + gWeaponStats[ 18 ].sValDx), (INT16)(gWeaponStats[ 18 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 18 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // BRIGHT LIGHT VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus != 0 )
+ ///////////////////// TARGET TRACKING MODIFIER
+ iModifier[0] = GetTargetTrackingModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetTargetTrackingModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetTargetTrackingModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
{
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 40 ].sX + gsInvDescX, gWeaponStats[ 40 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // determine value
- INT16 iVisionRangeBonus = 0;
- iVisionRangeBonus = Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iVisionRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iVisionRangeBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iVisionRangeBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iVisionRangeBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iVisionRangeBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 19 ].sX + gsInvDescX + gWeaponStats[ 19 ].sValDx), (INT16)(gWeaponStats[ 19 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 19 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // CAVE VISION RANGE BONUS ICON
- if ( Item[ gpItemDescObject->usItem ].cavevisionrangebonus != 0 )
+ ///////////////////// DAMAGE MODIFIER
+ if (Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_THROWING_KNIFE))
+ iModifier[0] = (GetDamageBonus( gpItemDescObject ) * gGameExternalOptions.iGunDamageModifier) / 100;
+ else if (Item[gpItemDescObject->usItem].usItemClass & (IC_BLADE|IC_PUNCH))
+ iModifier[0] = (GetDamageBonus( gpItemDescObject ) * gGameExternalOptions.iMeleeDamageModifier) / 100;
+ else if (Item[gpItemDescObject->usItem].usItemClass & (IC_EXPLOSV|IC_LAUNCHER))
+ iModifier[0] = (GetDamageBonus( gpItemDescObject ) * gGameExternalOptions.iExplosivesDamageModifier) / 100;
+ else
+ iModifier[0] = GetDamageBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
{
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 41 ].sX + gsInvDescX, gWeaponStats[ 41 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // determine value
- INT16 iVisionRangeBonus = 0;
- iVisionRangeBonus = Item[ gpItemDescObject->usItem ].cavevisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iVisionRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iVisionRangeBonus > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iVisionRangeBonus > 0 )
- {
- swprintf( pStr, L"%+2d", iVisionRangeBonus / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iVisionRangeBonus / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 20 ].sX + gsInvDescX + gWeaponStats[ 20 ].sValDx), (INT16)(gWeaponStats[ 20 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 20 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // PERCENT TUNNEL VISION ICON
- if ( Item[ gpItemDescObject->usItem ].percenttunnelvision > 0 )
+ ///////////////////// MELEE DAMAGE MODIFIER
+ iModifier[0] = GetMeleeDamageBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
{
- // equals
- SetFontForeground( 6 );
- //mprintf( gWeaponStats[ 34 ].sX + gsInvDescX, gWeaponStats[ 34 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // print value
- SetFontForeground( 5 );
- swprintf( pStr, L"%2d%%", Item[ gpItemDescObject->usItem ].percenttunnelvision );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 21 ].sX + gsInvDescX + gWeaponStats[ 21 ].sValDx), (INT16)(gWeaponStats[ 21 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gWeaponStats[ 21 ].sY + gsInvDescY, pStr );
+ cnt++;
}
- // HEARING RANGE BONUS ICON
- if ( GetItemHearingRangeBonus( gpItemDescObject ) != 0 )
+ ///////////////////// RANGE MODIFIER
+ iModifier[0] = GetRangeBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
{
- // equals
- SetFontForeground( 6 );
- mprintf( gWeaponStats[ 42 ].sX + gsInvDescX, gWeaponStats[ 42 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
- // determine value
- INT16 iHearingRangeBonus = 0;
- iHearingRangeBonus = GetItemHearingRangeBonus( gpItemDescObject );
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iHearingRangeBonus < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else if ( iHearingRangeBonus > 0 )
+ cnt++;
+ }
+
+ ///////////////////// SCOPE MAGNIFICATION
+ iFloatModifier[0] = GetHighestScopeMagnificationFactor( gpItemDescObject );
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] > 1.0 && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
{
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 1.0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%3.1fx", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"1.0x" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
-
- // print value
- if ( iHearingRangeBonus > 0 )
+ cnt++;
+ }
+
+ ///////////////////// PROJECTION FACTOR
+ iFloatModifier[0] = GetProjectionFactor( gpItemDescObject );
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] > 1.0 && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
{
- swprintf( pStr, L"%+2d", iHearingRangeBonus / 10 );
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 1.0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%3.1fx", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"1.0x" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- else
+ cnt++;
+ }
+
+ ///////////////////// LATERAL RECOIL MODIFIER
+ GetFlatRecoilModifier( gpItemDescObject, &bRecoilModifier, &bDummyValue );
+ iModifier[0] = bRecoilModifier;
+ iModifier[1] = bRecoilModifier;
+ iModifier[2] = bRecoilModifier;
+ if (iModifier[0] != 0 && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
{
- swprintf( pStr, L"%2d", iHearingRangeBonus / 10 );
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
}
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 22 ].sX + gsInvDescX + gWeaponStats[ 22 ].sValDx), (INT16)(gWeaponStats[ 22 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 22 ].sY + gsInvDescY, pStr );
+ cnt++;
+ }
+
+ ///////////////////// VERTICAL RECOIL MODIFIER
+ GetFlatRecoilModifier( gpItemDescObject, &bDummyValue, &bRecoilModifier );
+ iModifier[0] = bRecoilModifier;
+ iModifier[1] = bRecoilModifier;
+ iModifier[2] = bRecoilModifier;
+ if (iModifier[0] != 0 && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// MAX COUNTER FORCE MODIFIER
+ iModifier[0] = GetCounterForceMaxModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetCounterForceMaxModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetCounterForceMaxModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// COUNTER FORCE ACCURACY MODIFIER
+ iModifier[0] = GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetCounterForceAccuracyModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// COUNTER FORCE FREQUENCY MODIFIER
+ iModifier[0] = GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_STAND );
+ iModifier[1] = GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_CROUCH );
+ iModifier[2] = GetCounterForceFrequencyModifier( gpItemDescObject, ANIM_PRONE );
+ if ((iModifier[0] != 0 || iModifier[1] != 0 || iModifier[2] != 0) && UsingNewCTHSystem() == true )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// AP MODIFIER
+ iModifier[0] = GetAPBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// DRAW AP MODIFIER
+ iModifier[0] = GetPercentReadyTimeAPReduction( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"-%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", abs(iModifier[cnt2]) );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// SINGLE-ATTACK AP MODIFIER
+ iModifier[0] = GetPercentAPReduction( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"-%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", abs(iModifier[cnt2]) );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// BURST AP MODIFIER
+ iModifier[0] = GetPercentBurstFireAPReduction( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"-%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", abs(iModifier[cnt2]) );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// AUTOFIRE AP MODIFIER
+ iModifier[0] = GetPercentAutofireAPReduction( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"-%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", abs(iModifier[cnt2]) );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// RELOAD AP MODIFIER
+ iModifier[0] = GetPercentReloadTimeAPReduction( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"-%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", abs(iModifier[cnt2]) );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// MAGAZINE SIZE MODIFIER
+ iModifier[0] = GetMagSizeBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// BURST SIZE MODIFIER
+ iModifier[0] = GetBurstSizeBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// HIDE MUZZLE FLASH
+ iModifier[0] = IsFlashSuppressorAlt( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2])
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"Y", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// LOUDNESS MODIFIER
+ iModifier[0] = GetPercentNoiseVolume( gpItemDescObject )-100;
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", abs(iModifier[cnt2]) );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// ITEM SIZE MODIFIER
+ iModifier[0] = CalculateItemSize( gpItemDescObject ) - Item[ gpItemDescObject->usItem ].ItemSize;
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// RELIABILITY MODIFIER
+ iModifier[0] = GetReliability( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (!(Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_PUNCH|IC_ARMOUR|IC_EXPLOSV)) &&
+ iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// WOODLAND CAMO
+ iModifier[0] = GetCamoBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// URBAN CAMO
+ iModifier[0] = GetUrbanCamoBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// DESERT CAMO
+ iModifier[0] = GetDesertCamoBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// SNOW CAMO
+ iModifier[0] = GetSnowCamoBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// STEALTH MODIFIER
+ iModifier[0] = GetStealthBonus( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// HEARING RANGE MODIFIER
+ iFloatModifier[0] = (GetItemHearingRangeBonus( gpItemDescObject ) / 10.0f);
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iFloatModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// VISION RANGE MODIFIER
+ iFloatModifier[0] = (GetItemVisionRangeBonus( gpItemDescObject, 0 ) / 10.0f);
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iFloatModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// NIGHT VISION RANGE MODIFIER
+ iFloatModifier[0] = (GetItemVisionRangeBonus( gpItemDescObject, 2 ) / 10.0f);
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iFloatModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// DAY VISION RANGE MODIFIER
+ iFloatModifier[0] = (GetItemVisionRangeBonus( gpItemDescObject, 1 ) / 10.0f);
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iFloatModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// BRIGHT LIGHT VISION RANGE MODIFIER
+ iFloatModifier[0] = (GetItemVisionRangeBonus( gpItemDescObject, 3 ) / 10.0f);
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iFloatModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// CAVE VISION RANGE MODIFIER
+ iFloatModifier[0] = (GetItemVisionRangeBonus( gpItemDescObject, 4 ) / 10.0f);
+ iFloatModifier[1] = iFloatModifier[0];
+ iFloatModifier[2] = iFloatModifier[0];
+ if (iFloatModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iFloatModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"+%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else if (iFloatModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"%3.1f", iFloatModifier[cnt2] );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
+ }
+
+ ///////////////////// PERCENT TUNNEL VISION
+ iModifier[0] = GetItemPercentTunnelVision( gpItemDescObject );
+ iModifier[1] = iModifier[0];
+ iModifier[2] = iModifier[0];
+ if (iModifier[0] != 0 )
+ {
+ if (cnt >= sFirstLine && cnt < sLastLine)
+ {
+ // Set Y coordinates
+ sTop = gItemDescAdvRegions[cnt-sFirstLine][1].sTop;
+ sHeight = gItemDescAdvRegions[cnt-sFirstLine][1].sBottom - sTop;
+
+ // Print Values
+ for (UINT8 cnt2 = 0; cnt2 < 3; cnt2++)
+ {
+ if (UsingNewCTHSystem() == false && cnt2 > 0)
+ break;
+ SetFontForeground( 5 );
+ sLeft = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sLeft;
+ sWidth = gItemDescAdvRegions[cnt-sFirstLine][cnt2+1].sRight - sLeft;
+ if (iModifier[cnt2] > 0)
+ {
+ SetFontForeground( ITEMDESC_FONTNEGATIVE );
+ swprintf( pStr, L"+%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else if (iModifier[cnt2] < 0)
+ {
+ SetFontForeground( ITEMDESC_FONTPOSITIVE );
+ swprintf( pStr, L"%d", iModifier[cnt2] );
+ wcscat( pStr, L"%" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%" );
+ #endif
+ }
+ else
+ {
+ swprintf( pStr, L"--" );
+ FindFontCenterCoordinates( sLeft, sTop, sWidth, sHeight, pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+ }
+ cnt++;
}
}
void DrawMiscValues( OBJECTTYPE * gpItemDescObject )
{
- static CHAR16 pStr[ 100 ];
- INT16 usY;
- INT16 sStrX;
- UINT16 uiStringLength;
- UINT8 cnt;
-
if( UsingEDBSystem() == 0 )
return;
- if(guiCurrentScreen ==MAP_SCREEN)
- cnt = 14;
- else
- cnt = 12;
-
- // ITEM SIZE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].itemsizebonus != 0 && cnt<=27 )
+ if (gubDescBoxPage == 2)
{
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iItemSizeModifier = 0;
- iItemSizeModifier = Item[ gpItemDescObject->usItem ].itemsizebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iItemSizeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iItemSizeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iItemSizeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iItemSizeModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iItemSizeModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // RELIABILITY MODIFIER
- if ( Item[ gpItemDescObject->usItem ].bReliability != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iReliabilityModifier = 0;
- iReliabilityModifier = Item[ gpItemDescObject->usItem ].bReliability;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iReliabilityModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iReliabilityModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iReliabilityModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iReliabilityModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iReliabilityModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // NOISE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].percentnoisereduction != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iLoudnessModifier = 0;
- iLoudnessModifier = Item[ gpItemDescObject->usItem ].percentnoisereduction * -1 ;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iLoudnessModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iLoudnessModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iLoudnessModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iLoudnessModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iLoudnessModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // HIDE MUZZLE FLASH
- // NO DATA SHOWN, icon either appears or does not appear.
- // HEADROCK HAM 3.5 - Fixed this, because the count needs to be increased to skip a line!
- if ( Item[ gpItemDescObject->usItem ].hidemuzzleflash > 0 && cnt<=27 )
- {
- cnt++;
- }
-
- // BIPOD
- if ( Item[ gpItemDescObject->usItem ].bipod != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iBipodModifier = 0;
- iBipodModifier = Item[ gpItemDescObject->usItem ].bipod;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iBipodModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iBipodModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iBipodModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iBipodModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iBipodModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // RANGE
- if ( Item[ gpItemDescObject->usItem ].rangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iRangeModifier = 0;
- iRangeModifier = Item[ gpItemDescObject->usItem ].rangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iRangeModifier / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iRangeModifier / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // TO-HIT MODIFIER
- if ( Item[ gpItemDescObject->usItem ].tohitbonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iToHitModifier = 0;
- iToHitModifier = Item[ gpItemDescObject->usItem ].tohitbonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iToHitModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iToHitModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iToHitModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iToHitModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iToHitModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // LASER RANGE
- if ( Item[ gpItemDescObject->usItem ].bestlaserrange > 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iLaserRange = 0;
- iLaserRange = Item[ gpItemDescObject->usItem ].bestlaserrange;
-
- // determine value print color
- SetFontForeground( 5 );
-
- // print value
- swprintf( pStr, L"%2d", iLaserRange / 10 );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // AIMING MODIFIER
- if ( Item[ gpItemDescObject->usItem ].aimbonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iAimModifier = 0;
- iAimModifier = Item[ gpItemDescObject->usItem ].aimbonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iAimModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iAimModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAimModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iAimModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iAimModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // MINIMUM RANGE FOR AIMING BONUS
- if ( Item[ gpItemDescObject->usItem ].minrangeforaimbonus > 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iMinRangeAimingBonus = 0;
- iMinRangeAimingBonus = Item[ gpItemDescObject->usItem ].minrangeforaimbonus;
-
- // determine value print color
- SetFontForeground( 5 );
-
- // print value
- swprintf( pStr, L"%2d", iMinRangeAimingBonus / 10 );
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // MAGAZINE SIZE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].magsizebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iMagSizeModifier = 0;
- iMagSizeModifier = Item[ gpItemDescObject->usItem ].magsizebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iMagSizeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iMagSizeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iMagSizeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iMagSizeModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iMagSizeModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // BURST SIZE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].burstsizebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iBurstSizeModifier = 0;
- iBurstSizeModifier = Item[ gpItemDescObject->usItem ].burstsizebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iBurstSizeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iBurstSizeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iBurstSizeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iBurstSizeModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iBurstSizeModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // BURST TO-HIT MODIFIER
- if ( Item[ gpItemDescObject->usItem ].bursttohitbonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iBurstToHitModifier = 0;
- iBurstToHitModifier = Item[ gpItemDescObject->usItem ].bursttohitbonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iBurstToHitModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iBurstToHitModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iBurstToHitModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iBurstToHitModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iBurstToHitModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // AUTO TO-HIT MODIFIER
- if ( Item[ gpItemDescObject->usItem ].autofiretohitbonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iAutoToHitModifier = 0;
- iAutoToHitModifier = Item[ gpItemDescObject->usItem ].autofiretohitbonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iAutoToHitModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iAutoToHitModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAutoToHitModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iAutoToHitModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iAutoToHitModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // AP MODIFIER
- if ( Item[ gpItemDescObject->usItem ].APBonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iAPModifier = 0;
- iAPModifier = Item[ gpItemDescObject->usItem ].APBonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iAPModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iAPModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAPModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iAPModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iAPModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // BURST AP MODIFIER
- if ( Item[ gpItemDescObject->usItem ].percentburstfireapreduction != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iBurstAPModifier = 0;
- iBurstAPModifier = Item[ gpItemDescObject->usItem ].percentburstfireapreduction * -1 ;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iBurstAPModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iBurstAPModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iBurstAPModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iBurstAPModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iBurstAPModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // AUTOFIRE AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentautofireapreduction != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iAutoAPModifier = 0;
- iAutoAPModifier = Item[ gpItemDescObject->usItem ].percentautofireapreduction * -1 ;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iAutoAPModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iAutoAPModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iAutoAPModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iAutoAPModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iAutoAPModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // READY AP MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].percentreadytimeapreduction != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iReadyAPModifier = 0;
- iReadyAPModifier = Item[ gpItemDescObject->usItem ].percentreadytimeapreduction * -1 ;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iReadyAPModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iReadyAPModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iReadyAPModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iReadyAPModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iReadyAPModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // RELOAD AP MODIFIER
- if ( Item[ gpItemDescObject->usItem ].percentreloadtimeapreduction != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iReloadAPModifier = 0;
- iReloadAPModifier = Item[ gpItemDescObject->usItem ].percentreloadtimeapreduction * -1 ;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iReloadAPModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iReloadAPModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iReloadAPModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iReloadAPModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iReloadAPModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // SINGLE AP MODIFIER
- if ( Item[ gpItemDescObject->usItem ].percentapreduction != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iSingleAPModifier = 0;
- iSingleAPModifier = Item[ gpItemDescObject->usItem ].percentapreduction * -1 ;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iSingleAPModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iSingleAPModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iSingleAPModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iSingleAPModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iSingleAPModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // DAMAGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].damagebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iDamageModifier = 0;
- iDamageModifier = Item[ gpItemDescObject->usItem ].damagebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iDamageModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iDamageModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iDamageModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iDamageModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iDamageModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // MELEE DAMAGE MODIFIER ICON
- if ( Item[ gpItemDescObject->usItem ].meleedamagebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iMeleeDamageModifier = 0;
- iMeleeDamageModifier = Item[ gpItemDescObject->usItem ].meleedamagebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iMeleeDamageModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iMeleeDamageModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iMeleeDamageModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iMeleeDamageModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iMeleeDamageModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // WOOD CAMO
- if ( Item[ gpItemDescObject->usItem ].camobonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iWoodCamoModifier = 0;
- iWoodCamoModifier = Item[ gpItemDescObject->usItem ].camobonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iWoodCamoModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iWoodCamoModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iWoodCamoModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iWoodCamoModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iWoodCamoModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // URBAN CAMO
- if ( Item[ gpItemDescObject->usItem ].urbanCamobonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iUrbanCamoModifier = 0;
- iUrbanCamoModifier = Item[ gpItemDescObject->usItem ].urbanCamobonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iUrbanCamoModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iUrbanCamoModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iUrbanCamoModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iUrbanCamoModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iUrbanCamoModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // DESERT CAMO
- if ( Item[ gpItemDescObject->usItem ].desertCamobonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iDesertCamoModifier = 0;
- iDesertCamoModifier = Item[ gpItemDescObject->usItem ].desertCamobonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iDesertCamoModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iDesertCamoModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iDesertCamoModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iDesertCamoModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iDesertCamoModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // SNOW CAMO
- if ( Item[ gpItemDescObject->usItem ].snowCamobonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iSnowCamoModifier = 0;
- iSnowCamoModifier = Item[ gpItemDescObject->usItem ].snowCamobonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iSnowCamoModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iSnowCamoModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iSnowCamoModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iSnowCamoModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iSnowCamoModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // STEALTH MODIFIER
- if ( Item[ gpItemDescObject->usItem ].stealthbonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iStealthModifier = 0;
- iStealthModifier = Item[ gpItemDescObject->usItem ].stealthbonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iStealthModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iStealthModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iStealthModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iStealthModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iStealthModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // HEARING RANGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].hearingrangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iHearingRangeModifier = 0;
- iHearingRangeModifier = Item[ gpItemDescObject->usItem ].hearingrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iHearingRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iHearingRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iHearingRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iHearingRangeModifier );
- }
- else
- {
- swprintf( pStr, L"%2d", iHearingRangeModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // VISION RANGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].visionrangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iVisionRangeModifier = 0;
- iVisionRangeModifier = Item[ gpItemDescObject->usItem ].visionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iVisionRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iVisionRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iVisionRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iVisionRangeModifier / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iVisionRangeModifier / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // DAY VISION RANGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].dayvisionrangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iDayVisionRangeModifier = 0;
- iDayVisionRangeModifier = Item[ gpItemDescObject->usItem ].dayvisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iDayVisionRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iDayVisionRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iDayVisionRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iDayVisionRangeModifier / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iDayVisionRangeModifier / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // NIGHT VISION RANGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].nightvisionrangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iNightVisionRangeModifier = 0;
- iNightVisionRangeModifier = Item[ gpItemDescObject->usItem ].nightvisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iNightVisionRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iNightVisionRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iNightVisionRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iNightVisionRangeModifier / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iNightVisionRangeModifier / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // BRIGHT LIGHT VISION RANGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iBrightLightVisionRangeModifier = 0;
- iBrightLightVisionRangeModifier = Item[ gpItemDescObject->usItem ].brightlightvisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iBrightLightVisionRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iBrightLightVisionRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iBrightLightVisionRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iBrightLightVisionRangeModifier / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iBrightLightVisionRangeModifier / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // CAVE VISION RANGE MODIFIER
- if ( Item[ gpItemDescObject->usItem ].cavevisionrangebonus != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iCaveVisionRangeModifier = 0;
- iCaveVisionRangeModifier = Item[ gpItemDescObject->usItem ].cavevisionrangebonus;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iCaveVisionRangeModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iCaveVisionRangeModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iCaveVisionRangeModifier > 0 )
- {
- swprintf( pStr, L"%+2d", iCaveVisionRangeModifier / 10 );
- }
- else
- {
- swprintf( pStr, L"%2d", iCaveVisionRangeModifier / 10 );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
- }
-
- // PERCENT TUNNEL VISION MODIFIER
- if ( Item[ gpItemDescObject->usItem ].percenttunnelvision != 0 && cnt<=27 )
- {
- // equals
- SetFontForeground( 6 );
- mprintf( gMiscItemStatsEDB[ cnt ].sX + gsInvDescX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
-
- // determine value
- INT16 iPercentTunnelVisionModifier = 0;
- iPercentTunnelVisionModifier = Item[ gpItemDescObject->usItem ].percenttunnelvision;
-
- // determine value print color
- SetFontForeground( 5 );
- if ( iPercentTunnelVisionModifier > 0 )
- {
- SetFontForeground( ITEMDESC_FONTNEGATIVE );
- }
- else if ( iPercentTunnelVisionModifier < 0 )
- {
- SetFontForeground( ITEMDESC_FONTPOSITIVE );
- }
-
- // print value
- if ( iPercentTunnelVisionModifier > 0 )
- {
- swprintf( pStr, L"%+2d%%", iPercentTunnelVisionModifier );
- }
- else
- {
- swprintf( pStr, L"%2d%%", iPercentTunnelVisionModifier );
- }
- uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ cnt ].sX + gsInvDescX + gMiscItemStatsEDB[ cnt ].sValDx), (INT16)(gMiscItemStatsEDB[ cnt ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( sStrX, gMiscItemStatsEDB[ cnt ].sY + gsInvDescY, pStr );
- cnt++;
+ DrawAdvancedValues( gpItemDescObject );
}
}
-
diff --git a/Tactical/Interface Enhanced.h b/Tactical/Interface Enhanced.h
index ebd8aed5..ae01f42f 100644
--- a/Tactical/Interface Enhanced.h
+++ b/Tactical/Interface Enhanced.h
@@ -4,14 +4,18 @@
extern INV_DESC_STATS gMiscItemStatsEDB[];
UINT8 UsingEDBSystem();
-void InitItemDescriptionBoxOffsets();
+void InitItemDescriptionBoxOffsets(OBJECTTYPE * gpItemDescObject);
BOOLEAN InternalInitEnhancedDescBox();
void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurrentItemDescriptionScreen );
void DeleteEnhancedDescBox( UINT32 guiCurrentItemDescriptionScreen );
-void InitDescStatCoords();
+void InitDescStatCoords(OBJECTTYPE *pObject);
void InitLBECoords();
-void InitEDBCoords();
+void InitEDBCoords(OBJECTTYPE * pObject);
+// HEADROCK HAM 4: UDB Secondary Stats column icons (no values)
+void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject );
+void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject );
+void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject );
void DrawWeaponStats( OBJECTTYPE * gpItemDescObject );
void DrawAmmoStats( OBJECTTYPE * gpItemDescObject );
void DrawExplosiveStats( OBJECTTYPE * gpItemDescObject );
diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp
index 8766bec7..1bb20252 100644
--- a/Tactical/Interface Items.cpp
+++ b/Tactical/Interface Items.cpp
@@ -3,6 +3,7 @@
#include "language defines.h"
#else
#include "builddefines.h"
+ #include "mapscreen.h"
#include
#include
#include
@@ -77,6 +78,10 @@
#include "InterfaceItemImages.h"
#endif
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SANDRO - all "APBPConstants[AP_PICKUP_ITEM]" were replaced by GetBasicAPsToPickupItem()
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -128,13 +133,6 @@ extern int SM_ITEMDESC_START_Y;
#define CAMO_REGION_HEIGHT 75
#define CAMO_REGION_WIDTH 75
-// HEADROCK: Changed to INT16s for dynamic ODB-EDB switch. These are icon locations for the Description Box.
-// With EDB, many more icons will appear, for new object data fields.
-INT16 BULLET_SING_X;
-INT16 BULLET_SING_Y;
-INT16 BULLET_BURST_X;
-INT16 BULLET_BURST_Y;
-
#define BULLET_WIDTH 3
#define BULLET_GAP 5
@@ -145,16 +143,13 @@ INT16 ITEMDESC_NAME_X;
INT16 ITEMDESC_NAME_Y;
INT16 ITEMDESC_ITEM_X;
INT16 ITEMDESC_ITEM_Y;
-INT16 ITEMDESC_DESC_START_X;
-INT16 ITEMDESC_DESC_START_Y;
-INT16 ITEMDESC_PROS_START_X;
-INT16 ITEMDESC_PROS_START_Y;
-INT16 ITEMDESC_CONS_START_X;
-INT16 ITEMDESC_CONS_START_Y;
-INT16 ITEMDESC_DESC_WIDTH;
INT16 ITEMDESC_ITEM_STATUS_X;
INT16 ITEMDESC_ITEM_STATUS_Y;
INT16 ITEMDESC_ITEM_STATUS_HEIGHT;
+INT16 ITEMDESC_AMMO_X;
+INT16 ITEMDESC_AMMO_Y;
+INT16 ITEMDESC_DONE_X;
+INT16 ITEMDESC_DONE_Y;
#define DOTDOTDOT L"..."
#define COMMA_AND_SPACE L", "
@@ -165,9 +160,6 @@ INT16 ITEMDESC_ITEM_STATUS_HEIGHT;
#define ITEMDESC_ITEM_WIDTH 117
#define ITEMDESC_ITEM_HEIGHT 54
-#define ITEMDESC_AMMO_X ( 10 + gsInvDescX )
-#define ITEMDESC_AMMO_Y ( 50 + gsInvDescY )
-
#define ITEMDESC_AMMO_TEXT_X 3
#define ITEMDESC_AMMO_TEXT_Y 1
#define ITEMDESC_AMMO_TEXT_WIDTH 31
@@ -180,7 +172,7 @@ INT16 ITEMDESC_ITEM_STATUS_HEIGHT;
#define ITEM_FONT TINYFONT1
//CHRISL: Moved to Interface Items.h for EDB
-//#define EXCEPTIONAL_DAMAGE 40
+//#define EXCEPTIONAL_GUN_DAMAGE 40
//#define EXCEPTIONAL_WEIGHT 20
//#define EXCEPTIONAL_RANGE 400
//#define EXCEPTIONAL_MAGAZINE 50
@@ -247,17 +239,23 @@ UINT32 guiNewlyPlacedItemTimer = 0;
BOOLEAN gfBadThrowItemCTGH;
BOOLEAN gfDontChargeAPsToPickup = FALSE;
BOOLEAN gbItemPointerLocateGood = FALSE;
+INT32 iItemPosition = 0;
// ITEM DESCRIPTION BOX STUFF
UINT32 guiItemDescBox;
UINT32 guiItemDescBoxBackground;
+// HEADROCK HAM 4: Image file for LBE backgrounds
+UINT32 guiItemInfoLBEBackground;
UINT32 guiMapItemDescBox;
+UINT32 guiAttachmentSlot;
UINT32 guiItemGraphic;
UINT32 guiMoneyGraphicsForDescBox;
UINT32 guiBullet;
BOOLEAN gfInItemDescBox = FALSE;
UINT32 guiCurrentItemDescriptionScreen=0;
OBJECTTYPE *gpItemDescObject = NULL;
+// HEADROCK HAM 4: Remembers the object that was open before an attachment desc is opened on top of it.
+OBJECTTYPE *gpItemDescPrevObject = NULL;
BOOLEAN gfItemDescObjectIsAttachment = FALSE;
CHAR16 gzItemName[ SIZE_ITEM_NAME ];
CHAR16 gzItemDesc[ SIZE_ITEM_INFO ];
@@ -280,7 +278,7 @@ MOUSE_REGION gItemDescAttachmentRegions[MAX_ATTACHMENTS];
MOUSE_REGION gProsAndConsRegions[2];
void BtnMoneyButtonCallback(GUI_BUTTON *btn,INT32 reason);
-UINT32 guiMoneyButtonBtn[MAX_ATTACHMENTS];
+UINT32 guiMoneyButtonBtn[OLD_MAX_ATTACHMENTS_101];
INT32 guiMoneyButtonImage;
INT32 guiMoneyDoneButtonImage;
@@ -352,6 +350,22 @@ extern BOOLEAN fMapScreenBottomDirty;
INT32 giMapInvDescButtonImage;
INT32 giMapInvDescButton = -1;
+// HEADROCK HAM 4: Item Description Box TAB buttons for UDB
+INT32 giMapInvDescTabButtonImage;
+INT32 giInvDescTabButtonImage;
+INT32 giInvDescTabButton[3] = {-1, -1, -1};
+void ItemDescTabButtonCallback( GUI_BUTTON *btn, INT32 reason );
+void ItemDescTabButtonOn( UINT8 ubItemDescTabButtonIndex );
+void ItemDescTabButtonOff( UINT8 ubItemDescTabButtonIndex );
+// HEADROCK HAM 4: Item Description Box Scroll Buttons for UDB
+INT32 giInvDescAdvButtonUpImage;
+INT32 giInvDescAdvButtonDownImage;
+INT32 giInvDescAdvButton[2] = {-1, -1};
+void ItemDescAdvButtonCallback( GUI_BUTTON *btn, INT32 reason );
+void ItemDescAdvButtonOn( UINT8 ubItemDescAdvButtonIndex );
+void ItemDescAdvButtonOff( UINT8 ubItemDescAdvButtonIndex );
+void ItemDescAdvButtonCheck( void );
+
// the done descrition button callback
void ItemDescDoneButtonCallback( GUI_BUTTON *btn, INT32 reason );
@@ -435,9 +449,6 @@ typedef struct
STR16 sString2[NUM_INV_HELPTEXT_ENTRIES];
} INV_HELPTEXT;
-//CHRISL: Moved declaration to InitDescStatCoords for EDB
-INV_DESC_STATS gWeaponStats[47];
-
//CHRISL: Moved declaration to InitDescStatCoords for EDB
// displayed AFTER the mass/weight/"Kg" line
INV_DESC_STATS gMoneyStats[6];
@@ -445,10 +456,7 @@ INV_DESC_STATS gMoneyStats[6];
//CHRISL: Created for LBENODE Rendering with EDB
INV_DESC_STATS gLBEStats[48];
-INV_ATTACHXY gItemDescAttachmentsXY[4];
-
-//CHRISL: Moved declaration to InitDescStatCoords for EDB
-SGPRect gItemDescProsConsRects[2];
+INV_ATTACHXY gItemDescAttachmentsXY[MAX_ATTACHMENTS];
INV_HELPTEXT gItemDescHelpText =
{
@@ -487,6 +495,18 @@ UINT32 guiBodyInvVO[ 5 ][ 2 ];
UINT32 guiGoldKeyVO;
INT8 gbCompatibleApplyItem = FALSE;
+// HEADROCK HAM 4: New region coordinate tables for UDB
+INV_DESC_REGIONS gItemDescLBEBackground[4]; // Coordinates for displaying LBE background image
+INV_DESC_REGIONS gItemDescGenHeaderRegions[3]; // Header text regions for various parts of the General Tab
+INV_DESC_REGIONS gItemDescGenIndexRegions[3][4]; // Index text regions for various parts of the General Tab
+INV_DESC_REGIONS gItemDescGenRegions[NUM_UDB_GEN_LINES * 2][4]; // Data regions, 4 sub-columns each
+INV_DESC_REGIONS gItemDescGenSecondaryRegions[26]; // Secondary data regions, 3x5
+INV_DESC_REGIONS gItemDescTextRegions[7]; // Main description regions
+INV_DESC_REGIONS gItemDescAdvIndexRegions[1][4];
+INV_DESC_REGIONS gItemDescAdvRegions[NUM_UDB_ADV_LINES][4]; // Advanced data regions, 4 sub-columns each
+
+INV_DESC_REGIONS gODBItemDescRegions[4][8]; // Four regions of eight sub-regions each.
+
BOOLEAN AttemptToAddSubstring( STR16 zDest, STR16 zTemp, UINT32 * puiStringLength, UINT32 uiPixLimit )
{
UINT32 uiRequiredStringLength, uiTempStringLength;
@@ -529,6 +549,7 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi
ubWeight = ubWeight + Item[ (*pObject)[0]->data.gun.usGunAmmoItem ].ubWeight;
}
+ //CHRISL: TODO - This needs to be updated for NCTH
if (Weapon[usItem].bAccuracy >= EXCEPTIONAL_ACCURACY )
{
zTemp = Message[STR_ACCURATE];
@@ -559,7 +580,9 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi
}
}
- if ( GunRange( pObject ) >= EXCEPTIONAL_RANGE )
+ UINT16 exceptionalRange = (UINT16)((EXCEPTIONAL_RANGE * gGameExternalOptions.iGunRangeModifier ) / 100);
+
+ if ( GunRange( pObject, NULL ) >= exceptionalRange ) // SANDRO - added argument
{
zTemp = Message[STR_LONG_RANGE];
if ( ! AttemptToAddSubstring( zItemPros, zTemp, &uiStringLength, uiPixLimit ) )
@@ -568,7 +591,19 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi
}
}
- if (GetDamage(pObject) >= EXCEPTIONAL_DAMAGE)
+ UINT16 exceptionalDamage;
+ // Melee damage
+ if ( Item[pObject->usItem].usItemClass == IC_BLADE || Item[pObject->usItem].usItemClass == IC_PUNCH || Item[pObject->usItem].usItemClass == IC_TENTACLES )
+ {
+ exceptionalDamage = (UINT16)(( EXCEPTIONAL_MELEE_DAMAGE * gGameExternalOptions.iMeleeDamageModifier ) / 100);
+ }
+ // Gun damage
+ else
+ {
+ exceptionalDamage = (UINT16)(( EXCEPTIONAL_GUN_DAMAGE * gGameExternalOptions.iGunDamageModifier ) / 100);
+ }
+
+ if (GetDamage(pObject) >= exceptionalDamage)
{
zTemp = Message[STR_HIGH_DAMAGE];
if ( ! AttemptToAddSubstring( zItemPros, zTemp, &uiStringLength, uiPixLimit ) )
@@ -604,7 +639,7 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi
}
}
- if ( Item[usItem].bReliability >= EXCEPTIONAL_RELIABILITY )
+ if ( GetReliability( pObject ) >= EXCEPTIONAL_RELIABILITY )
{
zTemp = Message[STR_RELIABLE];
if ( ! AttemptToAddSubstring( zItemPros, zTemp, &uiStringLength, uiPixLimit ) )
@@ -650,6 +685,7 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi
zItemCons[0] = 0;
+ //CHRISL: TODO - This needs to be updated for NCTH
if (Weapon[usItem].bAccuracy <= BAD_ACCURACY)
{
zTemp = Message[STR_INACCURATE];
@@ -685,7 +721,7 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi
}
}
- if ( GunRange( pObject ) <= BAD_RANGE)
+ if ( GunRange( pObject, NULL ) <= BAD_RANGE) // SANDRO - added argument
{
zTemp = Message[STR_SHORT_RANGE];
if ( ! AttemptToAddSubstring( zItemCons, zTemp, &uiStringLength, uiPixLimit ) )
@@ -740,7 +776,7 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi
}
}
- if ( Item[usItem].bReliability <= BAD_RELIABILITY )
+ if ( GetReliability( pObject ) <= BAD_RELIABILITY )
{
zTemp = Message[STR_UNRELIABLE];
if ( ! AttemptToAddSubstring( zItemCons, zTemp, &uiStringLength, uiPixLimit ) )
@@ -769,6 +805,85 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi
}
}
+BOOLEAN UseNASDesc(OBJECTTYPE *pObject){
+ if(pObject->exists() == FALSE)
+ return FALSE;
+ return (Item[pObject->usItem].usItemClass != IC_LBEGEAR && Item[pObject->usItem].usItemClass != IC_MONEY && UsingNewAttachmentSystem()==true);
+}
+
+//WarmSteel - This function is used to move groups of items with NAS along the Y axe
+INT16 sNASYCorrection(OBJECTTYPE * pObject){
+
+ //WarmSteel - If this confuses you, it's basically the same structure as in InitDescStatCoords.
+ if(UseNASDesc(pObject)){
+ if(UsingEDBSystem() > 0)
+ {
+ if( guiCurrentScreen == MAP_SCREEN )
+ {
+ return 113;
+ }
+ else
+ {
+ if (UsingEDBSystem() == 1) // NIV EDB
+ {
+ return 0;
+ }
+ if (UsingEDBSystem() == 2) // OIV EDB
+ {
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ if(guiCurrentScreen ==MAP_SCREEN)
+ {
+ return 113;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ }
+ //WarmSteel - Item does not qualify for NAS layout.
+ return 0;
+}
+//WarmSteel - This function is used to move groups of items with NAS along the X axe
+INT16 sNASXCorrection(OBJECTTYPE * pObject){
+
+ //WarmSteel - If this confuses you, it's basically the same structure as in InitDescStatCoords.
+ if(UseNASDesc(pObject)){
+ if(UsingEDBSystem() > 0)
+ {
+ if( guiCurrentScreen == MAP_SCREEN )
+ {
+ return 0;
+ }
+ else
+ {
+ if (UsingEDBSystem()) // NIV EDB
+ {
+ return 190;
+ }
+ }
+ }
+ else //ODB
+ {
+ if(guiCurrentScreen ==MAP_SCREEN)
+ {
+ return 0;
+ }
+ else
+ {
+ return 90;
+ }
+ }
+ }
+ //WarmSteel - Item does not qualify for NAS layout.
+ return 0;
+}
+
// CHRISL: New function to setup GSMInvData based on game options
void InitInvData(INV_REGIONS &InvData, BOOLEAN fBigPocket, INT16 sBarDx, INT16 sBarDy, INT16 sWidth, INT16 sHeight, INT16 sX, INT16 sY)
{
@@ -1472,7 +1587,7 @@ void INVRenderINVPanelItem( SOLDIERTYPE *pSoldier, INT16 sPocket, UINT8 fDirtyLe
if(gpItemPointer != NULL)
{
if(!gfSMDisableForItems && !CanItemFitInPosition(pSoldier, gpItemPointer, (INT8)sPocket, FALSE)){
- if(!ValidAttachment(gpItemPointer->usItem, pObject->usItem)){
+ if(!ValidAttachment(gpItemPointer->usItem, pObject )){
fHatchItOut = TRUE;
}
else{
@@ -1571,7 +1686,7 @@ BOOLEAN CompatibleItemForApplyingOnMerc( OBJECTTYPE *pTestObject )
// ATE: Would be nice to have flag here to check for these types....
if ( Item[usItem].camouflagekit || usItem == ADRENALINE_BOOSTER || usItem == REGEN_BOOSTER ||
usItem == SYRINGE_3 || usItem == SYRINGE_4 || usItem == SYRINGE_5 ||
- Item[usItem].alcohol || Item[usItem].canteen || usItem == JAR_ELIXIR )
+ Item[usItem].alcohol || Item[usItem].canteen || usItem == JAR_ELIXIR || (usItem == 1022 && gGameExternalOptions.fCamoRemoving) ) // Added rag usable on self - SANDRO
{
return( TRUE );
}
@@ -1737,8 +1852,8 @@ BOOLEAN HandleCompatibleAmmoUIForMapScreen( SOLDIERTYPE *pSoldier, INT32 bInvPos
continue;
}
- if ( ValidAttachment( pObject->usItem, pTestObject->usItem ) ||
- ValidAttachment( pTestObject->usItem, pObject->usItem ) ||
+ if ( ValidAttachment( pObject->usItem, pTestObject ) ||
+ ValidAttachment( pTestObject->usItem, pObject ) ||
ValidLaunchable( pTestObject->usItem, pObject->usItem ) ||
ValidLaunchable( pObject->usItem, pTestObject->usItem ) )
{
@@ -1838,8 +1953,8 @@ BOOLEAN HandleCompatibleAmmoUIForMapInventory( SOLDIERTYPE *pSoldier, INT32 bInv
continue;
}
- if ( ValidAttachment( pObject->usItem, pTestObject->usItem ) ||
- ValidAttachment( pTestObject->usItem, pObject->usItem ) ||
+ if ( ValidAttachment( pObject->usItem, pTestObject ) ||
+ ValidAttachment( pTestObject->usItem, pObject ) ||
ValidLaunchable( pTestObject->usItem, pObject->usItem ) ||
ValidLaunchable( pObject->usItem, pTestObject->usItem ) )
{
@@ -1970,8 +2085,8 @@ BOOLEAN InternalHandleCompatibleAmmoUI( SOLDIERTYPE *pSoldier, OBJECTTYPE *pTest
continue;
}
- if ( ValidAttachment( pObject->usItem, pTestObject->usItem ) ||
- ValidAttachment( pTestObject->usItem, pObject->usItem ) ||
+ if ( ValidAttachment( pObject->usItem, pTestObject ) ||
+ ValidAttachment( pTestObject->usItem, pObject ) ||
ValidLaunchable( pTestObject->usItem, pObject->usItem ) ||
ValidLaunchable( pObject->usItem, pTestObject->usItem ) )
{
@@ -2298,7 +2413,7 @@ void RenderPocketItemCapacity( UINT32 uiWhichBuffer, UINT8 pCapacity, INT16 bPos
if(pSoldier != NULL && !CanItemFitInPosition( pSoldier, gpItemPointer, (INT8)bPos, FALSE ))
{
// Further check to see if the cursor item is valid ammo or a valid attachment
- if(!CompatibleAmmoForGun(gpItemPointer, &pSoldier->inv[bPos]) && !ValidAttachment(gpItemPointer->usItem, pSoldier->inv[bPos].usItem))
+ if(!CompatibleAmmoForGun(gpItemPointer, &pSoldier->inv[bPos]) && !ValidAttachment(gpItemPointer->usItem, &(pSoldier->inv[bPos])))
{
return;
}
@@ -2328,7 +2443,7 @@ void RenderPocketItemCapacity( UINT32 uiWhichBuffer, UINT8 pCapacity, INT16 bPos
SetFontForeground( FONT_YELLOW );
swprintf( pStr, L"L" );
}
- else if(ValidAttachment(gpItemPointer->usItem, pSoldier->inv[bPos].usItem))
+ else if(ValidAttachment(gpItemPointer->usItem, &(pSoldier->inv[bPos]) ))
{
SetFontForeground( FONT_YELLOW );
swprintf( pStr, L"A" );
@@ -2586,7 +2701,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
#endif
if ( ItemHasAttachments( pObject, pSoldier, iter ) )
{
- if ( !IsGrenadeLauncherAttached( pObject ) )
+ if ( !IsGrenadeLauncherAttached( pObject, iter ) )
{
SetFontForeground( FONT_GREEN );
}
@@ -2698,7 +2813,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
else
{
OBJECTTYPE* pAttachment = (*pObject)[iter]->GetAttachmentAtIndex(ubStatusIndex - RENDER_ITEM_ATTACHMENT1);
- if (pAttachment) {
+ if (pAttachment->exists()) {
swprintf( pStr, L"%s", ShortItemNames[ pAttachment->usItem ] );
}
}
@@ -2822,59 +2937,101 @@ BOOLEAN InitItemDescriptionBox( SOLDIERTYPE *pSoldier, UINT8 ubPosition, INT16 s
// HEADROCK: The following two functions set various coordinates for use by the description box, depending on
// an options.ini setting that determines whether the Enhanced box or the Original box is used.
-void InitItemDescriptionBoxStartCoords( BOOLEAN fIsEnhanced )
+void InitItemDescriptionBoxStartCoords( BOOLEAN fIsEnhanced, BOOLEAN fUsingNAS )
{
UINT8 mode = UsingEDBSystem();
+ if(fUsingNAS){
+ if (guiCurrentItemDescriptionScreen != SHOPKEEPER_SCREEN)
+ {
+ ITEMDESC_START_X = 115;
+ ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
+ ITEMDESC_HEIGHT = 195;
+ ITEMDESC_WIDTH = 335; // OIV only
+ }
+ else if( UsingNewInventorySystem() == true ) // ODB/NIV
+ {
+ ITEMDESC_START_X = 200;//259;
+ ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
+ ITEMDESC_HEIGHT = guiCurrentItemDescriptionScreen == SHOPKEEPER_SCREEN ? 193 : 195;
+ ITEMDESC_WIDTH = 430; // OIV only
+ }
+ else // ODB/OIV
+ {
+ ITEMDESC_HEIGHT = 193;
+ ITEMDESC_WIDTH = 430; // OIV only
+ ITEMDESC_START_X = 214;//214
+ ITEMDESC_START_Y = (1-(ITEMDESC_HEIGHT-INV_INTERFACE_HEIGHT) + INV_INTERFACE_START_Y);
+ }
- if( mode == 1 ) // EDB
- {
- ITEMDESC_START_X = 115;
- ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
- ITEMDESC_HEIGHT = 195;
- ITEMDESC_WIDTH = 335; // OIV only
- }
- else if( mode == 2 ) // EDB/OIV Tactical
- {
- ITEMDESC_START_X = 214;
- ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
- ITEMDESC_HEIGHT = 133;
- ITEMDESC_WIDTH = 477; // OIV only
- }
- else if( UsingNewInventorySystem() == true ) // ODB/NIV
- {
- ITEMDESC_START_X = 259;
- ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
- ITEMDESC_HEIGHT = guiCurrentItemDescriptionScreen == SHOPKEEPER_SCREEN ? 133 : 195;
- ITEMDESC_WIDTH = 320; // OIV only
- }
- else // ODB/OIV
- {
- ITEMDESC_START_X = 214;
- ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
- ITEMDESC_HEIGHT = 133;
- ITEMDESC_WIDTH = 320; // OIV only
- }
+ if(UsingNewInventorySystem() == true && guiCurrentScreen == GAME_SCREEN)
+ {
+ if(iResolution == 0)
+ ITEMDESC_WIDTH = 526;
+ else if(iResolution == 1)
+ ITEMDESC_WIDTH = 686;
+ else if(iResolution == 2)
+ ITEMDESC_WIDTH = 910;
+ }
- if(UsingNewInventorySystem() == true && guiCurrentScreen == GAME_SCREEN)
- {
- if(iResolution == 0)
- ITEMDESC_WIDTH = 526;
- else if(iResolution == 1)
- ITEMDESC_WIDTH = 686;
- else if(iResolution == 2)
- ITEMDESC_WIDTH = 910;
- }
+ //CHRISL: This allows EDB to work in Strategic OIV mode
+ if(guiCurrentScreen == MAP_SCREEN)
+ {
+ if(iResolution == 0) // 640x480 res
+ ITEMDESC_HEIGHT = 268;
+ else if(iResolution == 2 || UsingNewInventorySystem() == true) // 1024x768 or NIV
+ ITEMDESC_HEIGHT = 490;
+ else if(iResolution == 1) // 800x600
+ ITEMDESC_HEIGHT = (mode > 0) ? 490 : 373;
+ ITEMDESC_WIDTH = ((UsingNewInventorySystem() == true && iResolution != 0)) ? 272 : 272;
+ }
+ } else {
+ if( UsingNewInventorySystem() == true ) // ODB/NIV
+ {
+ if (guiCurrentItemDescriptionScreen != SHOPKEEPER_SCREEN)
+ {
+ // HEADROCK HAM 4:
+ ITEMDESC_START_X = 115;
+ ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
+ ITEMDESC_HEIGHT = 195;
+ ITEMDESC_WIDTH = 335; // OIV only
+ }
+ else
+ {
+ ITEMDESC_START_X = 259;
+ ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
+ ITEMDESC_HEIGHT = guiCurrentItemDescriptionScreen == SHOPKEEPER_SCREEN ? 133 : 195;
+ ITEMDESC_WIDTH = 320; // OIV only
+ }
+ }
+ else // ODB/OIV
+ {
+ ITEMDESC_START_X = 214;
+ ITEMDESC_START_Y = (1 + INV_INTERFACE_START_Y);
+ ITEMDESC_HEIGHT = 133;
+ ITEMDESC_WIDTH = 320; // OIV only
+ }
- //CHRISL: This allows EDB to work in Strategic OIV mode
- if(guiCurrentScreen == MAP_SCREEN)
- {
- if(iResolution == 0) // 640x480 res
- ITEMDESC_HEIGHT = 268;
- else if(iResolution == 2 || UsingNewInventorySystem() == true) // 1024x768 or NIV
- ITEMDESC_HEIGHT = 490;
- else if(iResolution == 1) // 800x600
- ITEMDESC_HEIGHT = 373;
- ITEMDESC_WIDTH = ((UsingNewInventorySystem() == true && iResolution != 0)) ? 272 : 272;
+ if(UsingNewInventorySystem() == true && guiCurrentScreen == GAME_SCREEN)
+ {
+ if(iResolution == 0)
+ ITEMDESC_WIDTH = 526;
+ else if(iResolution == 1)
+ ITEMDESC_WIDTH = 686;
+ else if(iResolution == 2)
+ ITEMDESC_WIDTH = 910;
+ }
+
+ //CHRISL: This allows EDB to work in Strategic OIV mode
+ if(guiCurrentScreen == MAP_SCREEN)
+ {
+ if(iResolution == 0) // 640x480 res
+ ITEMDESC_HEIGHT = 268;
+ else if(iResolution == 2 || UsingNewInventorySystem() == true) // 1024x768 or NIV
+ ITEMDESC_HEIGHT = 490;
+ else if(iResolution == 1) // 800x600
+ ITEMDESC_HEIGHT = 373;
+ ITEMDESC_WIDTH = ((UsingNewInventorySystem() == true && iResolution != 0)) ? 272 : 272;
+ }
}
}
@@ -2897,19 +3054,6 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
INT16 usX, usY;
INT16 sForeColour;
-/* Moved to InitItemDescriptionBoxStartCoords
- // CHRISL: Set some initial coords
- ITEMDESC_START_X = ((UsingNewInventorySystem() == true && iResolution != 0)) ? 259 : 214; //115:214
- ITEMDESC_START_Y = ((UsingNewInventorySystem() == true && iResolution != 0)) ? (1 + INV_INTERFACE_START_Y) : (1 + INV_INTERFACE_START_Y);
- ITEMDESC_HEIGHT = ((UsingNewInventorySystem() == true && iResolution != 0)) ? 195 : 133; //195:133
- ITEMDESC_WIDTH = 320;
-*/
- // This initializes the start coordinates of the description box, based on the box we want to use.
- //CHRISL: Initialize coords based on EDB/NIV settings
- InitDescStatCoords();
- InitEDBCoords();
- InitItemDescriptionBoxStartCoords( gGameExternalOptions.iEnhancedDescriptionBox );
-
//CHRISL: We only want this condition to be true when looking at MONEY. Not IC_MONEY since we can't actually split
// things like gold nuggets or wallets.
// ADB: Make sure the current object isn't money if there's something in hand
@@ -2925,6 +3069,9 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
//Set the current screen
guiCurrentItemDescriptionScreen = guiCurrentScreen;
+ // Set up start coordinates for the box.
+ InitItemDescriptionBoxStartCoords( gGameExternalOptions.iEnhancedDescriptionBox, UseNASDesc( pObject ) );
+
// Set X, Y
if(guiCurrentScreen == GAME_SCREEN)
{
@@ -2939,7 +3086,11 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
// Headrock: initialize coordinates of icons, values and text, based on gsInvDescXY and the type of description
// box we want to use.
- InitItemDescriptionBoxOffsets();
+ //CHRISL: Initialize coords based on EDB/NIV settings
+ // This initializes the start coordinates of the description box, based on the box we want to use.
+ InitDescStatCoords( pObject );
+ InitEDBCoords( pObject );
+ InitItemDescriptionBoxOffsets(pObject);
gpItemDescObject = pObject;
gubItemDescStatusIndex = ubStatusIndex;
@@ -2961,11 +3112,11 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
// HEADROCK: Create "Done" button. Coordinates changed - button moved to new location for
// enhanced Description Box project.
if(UsingEDBSystem() > 0)
- giMapInvDescButton= QuickCreateButton( giMapInvDescButtonImage, (UINT16)( gsInvDescX + 199 ), (UINT16)( gsInvDescY + 334 ),
+ giMapInvDescButton= QuickCreateButton( giMapInvDescButtonImage, (UINT16)( ITEMDESC_DONE_X ), (UINT16)(ITEMDESC_DONE_Y),
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
( GUI_CALLBACK )BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)ItemDescDoneButtonCallback );
else
- giMapInvDescButton= QuickCreateButton( giMapInvDescButtonImage, (UINT16)( gsInvDescX + 204 ), (UINT16)( gsInvDescY + 107 ),
+ giMapInvDescButton= QuickCreateButton( giMapInvDescButtonImage, (UINT16)( ITEMDESC_DONE_X ), (UINT16)(ITEMDESC_DONE_Y),
BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
( GUI_CALLBACK )BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)ItemDescDoneButtonCallback );
@@ -2984,13 +3135,9 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
MSYS_AddRegion( &gInvDesc);
}
- // Add region
+ // Add ammo eject button for GUN type objects.
if ( (Item[ pObject->usItem ].usItemClass & IC_GUN) && !Item[pObject->usItem].rocketlauncher )
{
- // Add button
-// if( guiCurrentScreen != MAP_SCREEN )
- //if( guiCurrentItemDescriptionScreen != MAP_SCREEN )
-
if ( GetMagSize(gpItemDescObject) <= 99 )
{
// HEADROCK HAM 3.4: "Bullet Hide" feature - bullet count only shown during combat if character is competent enough.
@@ -3023,25 +3170,6 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
giItemDescAmmoButtonImages = LoadButtonImage(ubString,AmmoTypes[(*pObject)[ubStatusIndex]->data.gun.ubGunAmmoType].grayed,AmmoTypes[(*pObject)[ubStatusIndex]->data.gun.ubGunAmmoType].offNormal,-1,AmmoTypes[(*pObject)[ubStatusIndex]->data.gun.ubGunAmmoType].onNormal,-1 );
- //switch( (*pObject)[ubStatusIndex]->data.gun.ubGunAmmoType )
- //{
- // case AMMO_AP:
- // case AMMO_SUPER_AP:
- // //sForeColour = ITEMDESC_FONTAPFORE;
- // giItemDescAmmoButtonImages = LoadButtonImage(ubString,8,5,-1,7,-1 );
- // break;
- // case AMMO_HP:
- // //sForeColour = ITEMDESC_FONTHPFORE;
- //
- // giItemDescAmmoButtonImages = LoadButtonImage(ubString,12,9,-1,11,-1 );
- // break;
- // default:
- // //sForeColour = FONT_MCOLOR_WHITE;
- // giItemDescAmmoButtonImages = LoadButtonImage(ubString,4,1,-1,3,-1 );
- // break;
-
- //}
-
if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
{
// in mapscreen, move over a bit
@@ -3049,7 +3177,7 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
sForeColour, FONT_MCOLOR_BLACK,
sForeColour, FONT_MCOLOR_BLACK,
TEXT_CJUSTIFIED,
- (INT16)(ITEMDESC_AMMO_X + 18), (INT16)(ITEMDESC_AMMO_Y - 5), BUTTON_TOGGLE ,MSYS_PRIORITY_HIGHEST,
+ (INT16)(ITEMDESC_AMMO_X), (INT16)(ITEMDESC_AMMO_Y), BUTTON_TOGGLE ,MSYS_PRIORITY_HIGHEST,
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescAmmoCallback );
}
@@ -3057,14 +3185,12 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
{
// not in mapscreen
- giItemDescAmmoButton = CreateIconAndTextButton( giItemDescAmmoButtonImages, pStr, TINYFONT1,
+ giItemDescAmmoButton = CreateIconAndTextButton( giItemDescAmmoButtonImages, pStr, TINYFONT1,
sForeColour, FONT_MCOLOR_BLACK,
sForeColour, FONT_MCOLOR_BLACK,
TEXT_CJUSTIFIED,
(INT16)(ITEMDESC_AMMO_X), (INT16)(ITEMDESC_AMMO_Y), BUTTON_TOGGLE ,MSYS_PRIORITY_HIGHEST,
DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescAmmoCallback );
-
- //if we are being called from the
}
//if we are being init from the shop keeper screen and this is a dealer item we are getting info from
if( guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE && pShopKeeperItemDescObject != NULL )
@@ -3090,94 +3216,55 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
}
// HEADROCK: Tooltip Regions for stats. Only happens with Enhanced Description Box turned on.
- // EDB 1.3: Moves this here to init coordinates earlier.
if(UsingEDBSystem() > 0)
InternalInitEDBTooltipRegion( gpItemDescObject, guiCurrentItemDescriptionScreen );
+ // Item pros and cons tooltips region is created now.
if ( ITEM_PROS_AND_CONS( gpItemDescObject->usItem ) )
{
- if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+ for ( cnt = 0; cnt < 2; cnt++ )
{
- for ( cnt = 0; cnt < 2; cnt++ )
+ // HEADROCK: Rectangle coordinates for tooltip determined by description box used.
+ // Add region for pros/cons help text
+ MSYS_DefineRegion( &gProsAndConsRegions[ cnt ],
+ gItemDescTextRegions[3+(cnt*2)].sLeft,
+ gItemDescTextRegions[3+(cnt*2)].sTop,
+ gItemDescTextRegions[3+(cnt*2)].sRight,
+ gItemDescTextRegions[3+(cnt*2)].sBottom,
+ MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
+
+ MSYS_AddRegion( &gProsAndConsRegions[cnt]);
+
+ if (cnt == 0)
{
- // HEADROCK: Rectangle coordinates for tooltip determined by description box used.
- // Add region for pros/cons help text
- MSYS_DefineRegion( &gProsAndConsRegions[ cnt ],
- (INT16)(gsInvDescX + gItemDescProsConsRects[ cnt ].iLeft),
- (INT16)(gsInvDescY + gItemDescProsConsRects[ cnt ].iTop),
- (INT16)(gsInvDescX + gItemDescProsConsRects[ cnt ].iRight),
- (INT16)(gsInvDescY + gItemDescProsConsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gProsAndConsRegions[cnt]);
-
- if (cnt == 0)
- {
- wcscpy( gzFullItemPros, gzProsLabel );
- wcscat( gzFullItemPros, L" " );
- // use temp variable to prevent an initial comma from being displayed
- GenerateProsString( gzFullItemTemp, gpItemDescObject, 1000 );
- wcscat( gzFullItemPros, gzFullItemTemp );
- SetRegionFastHelpText( &(gProsAndConsRegions[ cnt ]), gzFullItemPros );
- }
- else
- {
- wcscpy( gzFullItemCons, gzConsLabel );
- wcscat( gzFullItemCons, L" " );
- // use temp variable to prevent an initial comma from being displayed
- GenerateConsString( gzFullItemTemp, gpItemDescObject, 1000 );
- wcscat( gzFullItemCons, gzFullItemTemp );
- SetRegionFastHelpText( &(gProsAndConsRegions[ cnt ]), gzFullItemCons );
- }
- SetRegionHelpEndCallback( &(gProsAndConsRegions[ cnt ]), HelpTextDoneCallback );
+ wcscpy( gzFullItemPros, gzProsLabel );
+ wcscat( gzFullItemPros, L" " );
+ // use temp variable to prevent an initial comma from being displayed
+ GenerateProsString( gzFullItemTemp, gpItemDescObject, 1000 );
+ wcscat( gzFullItemPros, gzFullItemTemp );
+ SetRegionFastHelpText( &(gProsAndConsRegions[ cnt ]), gzFullItemPros );
}
-
- }
- else
- {
- for ( cnt = 0; cnt < 2; cnt++ )
+ else
{
- // Headrock: Rectangle coordinates for tooltip determined by description box used.
- // Add region for pros/cons help text
- MSYS_DefineRegion( &gProsAndConsRegions[ cnt ],
- (INT16)(gsInvDescX + gItemDescProsConsRects[ cnt ].iLeft),
- (INT16)(gsInvDescY + gItemDescProsConsRects[ cnt ].iTop),
- (INT16)(gsInvDescX + gItemDescProsConsRects[ cnt ].iRight),
- (INT16)(gsInvDescY + gItemDescProsConsRects[ cnt ].iBottom),
- MSYS_PRIORITY_HIGHEST, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescCallback );
-
- MSYS_AddRegion( &gProsAndConsRegions[cnt]);
-
- if (cnt == 0)
- {
- wcscpy( gzFullItemPros, gzProsLabel );
- wcscat( gzFullItemPros, L" " );
- // use temp variable to prevent an initial comma from being displayed
- GenerateProsString( gzFullItemTemp, gpItemDescObject, 1000 );
- wcscat( gzFullItemPros, gzFullItemTemp );
- SetRegionFastHelpText( &(gProsAndConsRegions[ cnt ]), gzFullItemPros );
- }
- else
- {
- wcscpy( gzFullItemCons, gzConsLabel );
- wcscat( gzFullItemCons, L" " );
- // use temp variable to prevent an initial comma from being displayed
- GenerateConsString( gzFullItemTemp, gpItemDescObject, 1000 );
- wcscat( gzFullItemCons, gzFullItemTemp );
- SetRegionFastHelpText( &(gProsAndConsRegions[ cnt ]), gzFullItemCons );
- }
- SetRegionHelpEndCallback( &(gProsAndConsRegions[ cnt ]), HelpTextDoneCallback );
+ wcscpy( gzFullItemCons, gzConsLabel );
+ wcscat( gzFullItemCons, L" " );
+ // use temp variable to prevent an initial comma from being displayed
+ GenerateConsString( gzFullItemTemp, gpItemDescObject, 1000 );
+ wcscat( gzFullItemCons, gzFullItemTemp );
+ SetRegionFastHelpText( &(gProsAndConsRegions[ cnt ]), gzFullItemCons );
}
+ SetRegionHelpEndCallback( &(gProsAndConsRegions[ cnt ]), HelpTextDoneCallback );
}
}
// Load graphic
// HEADROCK: Select STI based on Description Box used:
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
- if(UsingEDBSystem() > 0)
+ // HEADROCK HAM 4: No more need for two files. Just use one.
+ //if(UsingEDBSystem() > 0)
strcpy( VObjectDesc.ImageFile, "INTERFACE\\infobox_interface_edb.sti" );
- else
- strcpy( VObjectDesc.ImageFile, "INTERFACE\\infobox_interface.sti" );
+ //else
+ // strcpy( VObjectDesc.ImageFile, "INTERFACE\\infobox_interface.sti" );
CHECKF( AddVideoObject( &VObjectDesc, &guiItemDescBox) );
if(ubPosition != 255 && UsingNewInventorySystem() == true)
@@ -3191,16 +3278,29 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
// HEADROCK: Select STI based on Description Box used:
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
- if(UsingEDBSystem() > 0)
+ // HEADROCK HAM 4: No more need for two files. Just use the EDB one.
+ //if(UsingEDBSystem() > 0)
strcpy( VObjectDesc.ImageFile, "INTERFACE\\iteminfoc_edb.STI" );
- else
- strcpy( VObjectDesc.ImageFile, "INTERFACE\\iteminfoc.STI" );
+ //else
+ // strcpy( VObjectDesc.ImageFile, "INTERFACE\\iteminfoc.STI" );
CHECKF( AddVideoObject( &VObjectDesc, &guiMapItemDescBox) );
+ if(UsingNewInventorySystem())
+ {
+ // HEADROCK HAM 4: LBE backgrounds for desc box
+ VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
+ strcpy( VObjectDesc.ImageFile, "INTERFACE\\INFOBOX_LBE.STI" );
+ CHECKF( AddVideoObject( &VObjectDesc, &guiItemInfoLBEBackground) );
+ }
+
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
strcpy( VObjectDesc.ImageFile, "INTERFACE\\bullet.STI" );
CHECKF( AddVideoObject( &VObjectDesc, &guiBullet) );
+ VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
+ strcpy( VObjectDesc.ImageFile, "INTERFACE\\ATTACHMENT_SLOT.STI" );
+ CHECKF( AddVideoObject( &VObjectDesc, &guiAttachmentSlot) );
+
// HEADROCK: Added new STIs
CHECKF( InternalInitEnhancedDescBox() );
@@ -3225,7 +3325,7 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
{
guiMoneyButtonImage = LoadButtonImage("INTERFACE\\Info_bil.sti", -1,1,-1,2,-1 );
- for(cnt=0; cnt 0)
+ {
+ if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+ {
+ giMapInvDescTabButtonImage= LoadButtonImage( "INTERFACE\\iteminfotabbutton.sti" ,-1,0,-1,1,-1 );
+ }
+ else
+ {
+ giInvDescTabButtonImage= LoadButtonImage( "INTERFACE\\iteminfotacticaltabbutton.sti" ,-1,0,-1,1,-1 );
+ }
+ for (cnt = 0; cnt < 3; cnt++)
+ {
+ if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+ {
+ giInvDescTabButton[cnt] = CreateIconAndTextButton( giMapInvDescTabButtonImage, gzItemDescTabButtonText[cnt], BLOCKFONT2,
+ 5, DEFAULT_SHADOW,
+ 5, DEFAULT_SHADOW,
+ TEXT_CJUSTIFIED,
+ (UINT16)( gsInvDescX + 11 + (cnt*77) ), (UINT16)( gsInvDescY + 92 + sNASYCorrection( pObject ) ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
+ DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescTabButtonCallback );
+ }
+ else
+ {
+ // NAS-specific offset to these buttons
+ INT16 sNASOffsetX;
+ if (UseNASDesc( pObject ))
+ {
+ sNASOffsetX = 62;
+ }
+ else
+ {
+ sNASOffsetX = 0;
+ }
+ giInvDescTabButton[cnt] = CreateIconAndTextButton( giInvDescTabButtonImage, gzItemDescTabButtonShortText[cnt], BLOCKFONT2,
+ 5, DEFAULT_SHADOW,
+ 5, DEFAULT_SHADOW,
+ TEXT_CJUSTIFIED,
+ (UINT16)( gsInvDescX + 200 + sNASOffsetX ), (UINT16)( gsInvDescY + 4 + (cnt*63) ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
+ DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescTabButtonCallback );
+ }
+ //giInvDescTabButton[cnt] = QuickCreateButton( giMapInvDescTabButtonImage, (UINT16)( gsInvDescX + 11 + (cnt*77) ), (UINT16)( gsInvDescY + 92 ),
+ // BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
+ // DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescTabButtonCallback );
+ MSYS_SetBtnUserData( giInvDescTabButton[cnt], 0, cnt);
+ SetButtonFastHelpText( giInvDescTabButton[ cnt ], gzUDBButtonTooltipText[ cnt ] );
+ }
+
+ // Toggle on the button that corresponds to our selected tab.
+ ItemDescTabButtonOn( gubDescBoxPage );
+ }
+
+ // HEADROCK HAM 4: Up/Down Arrow Buttons for Advanced tab.
+ if (UsingEDBSystem() > 0)
+ {
+ INT16 sButtonLocationX;
+ INT16 sButtonLocationY1;
+ INT16 sButtonLocationY2;
+ if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+ {
+ // NAS and NON-NAS uses the same basic coordinates - adds Y Offset as necessary through the NAS-related
+ // adjustment function.
+ sButtonLocationX = 224;
+ sButtonLocationY1 = 118;
+ sButtonLocationY2 = 295;
+ }
+ else
+ {
+ // NAS pushes everything 62 pixels right.
+ if (UseNASDesc(pObject))
+ {
+ sButtonLocationX = 510;
+ sButtonLocationY1 = 5;
+ sButtonLocationY2 = 175;
+ }
+ else
+ {
+ sButtonLocationX = 448;
+ sButtonLocationY1 = 5;
+ sButtonLocationY2 = 175;
+ }
+ }
+
+ /////////// Up Button
+ giInvDescAdvButtonUpImage= LoadButtonImage( "INTERFACE\\iteminfoadvancedbutton.sti" ,-1,0,-1,2,-1 );
+ giInvDescAdvButton[0] = QuickCreateButton( giInvDescAdvButtonUpImage, (UINT16)( gsInvDescX + sButtonLocationX ), (UINT16)( gsInvDescY + sButtonLocationY1 + sNASYCorrection( pObject ) ),
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
+ DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescAdvButtonCallback );
+
+ MSYS_SetBtnUserData( giInvDescAdvButton[0], 0, 0);
+
+ ////////// Down Button
+ giInvDescAdvButtonDownImage= LoadButtonImage( "INTERFACE\\iteminfoadvancedbutton.sti" ,-1,1,-1,3,-1 );
+ giInvDescAdvButton[1] = QuickCreateButton( giInvDescAdvButtonDownImage, (UINT16)( gsInvDescX + sButtonLocationX ), (UINT16)( gsInvDescY + sButtonLocationY2 + sNASYCorrection( pObject ) ),
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGHEST,
+ DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)ItemDescAdvButtonCallback );
+
+ MSYS_SetBtnUserData( giInvDescAdvButton[1], 0, 1);
+
+ // Hide both buttons. They'll be shown if required.
+ HideButton( giInvDescAdvButton[0] );
+ HideButton( giInvDescAdvButton[1] );
+ }
+
fInterfacePanelDirty = DIRTYLEVEL2;
@@ -3314,7 +3518,7 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
}
// if ( !(Item[ pObject->usItem ].fFlags & ITEM_HIDDEN_ADDON) && ( ValidAttachment( gpItemPointer->usItem, pObject->usItem ) || ValidLaunchable( gpItemPointer->usItem, pObject->usItem ) || ValidMerge( gpItemPointer->usItem, pObject->usItem ) ) )
- if ( !(Item[ pObject->usItem ].hiddenaddon ) && ( ValidAttachment( gpItemPointer->usItem, pObject->usItem ) || ValidLaunchable( gpItemPointer->usItem, pObject->usItem ) || ValidMerge( gpItemPointer->usItem, pObject->usItem ) ) )
+ if ( !(Item[ pObject->usItem ].hiddenaddon ) && ( ValidAttachment( gpItemPointer->usItem, pObject ) || ValidLaunchable( gpItemPointer->usItem, pObject->usItem ) || ValidMerge( gpItemPointer->usItem, pObject->usItem ) ) )
{
SetUpFastHelpListRegions(
gItemDescHelpText.iXPosition,
@@ -3347,44 +3551,160 @@ BOOLEAN InternalInitItemDescriptionBox( OBJECTTYPE *pObject, INT16 sX, INT16 sY,
//CHRISL: This function is designed to recreate the attachment tooltips
void UpdateAttachmentTooltips(OBJECTTYPE *pObject, UINT8 ubStatusIndex)
{
- INT32 cnt;
+ UINT32 slotCount = 0;
+
+ //WarmSteel - Copied most of this from bobby rays attachment listing. No need to reinvent the wheel.
+ BOOLEAN fAttachmentsFound = FALSE;
+ // Contains entire string of attachment names
+ CHAR16 attachStr[2500];
+ // Contains current attachment string
+ CHAR16 attachStr2[100];
+ // Contains temporary attachment list before added to string constant from text.h
+ CHAR16 attachStr3[2500];
+ UINT16 usAttachment;
+ std::vector attachList, parseList;
+ std::vector usAttachmentSlotIndexVector = GetItemSlots(pObject);
//start by deleting the currently defined regions if they exist
- for ( cnt = 0; cnt < MAX_ATTACHMENTS; cnt++ )
+ for (INT32 cnt = 0; cnt < MAX_ATTACHMENTS; cnt++ )
{
if( gItemDescAttachmentRegions[cnt].IDNumber != 0 )
MSYS_RemoveRegion( &gItemDescAttachmentRegions[cnt]);
}
//now, create new regions
- for ( cnt = 0; cnt < MAX_ATTACHMENTS; cnt++ )
+ for (slotCount = 0; ;++slotCount )
{
+ //stopping conditions, not inside the for loop because it is different depending on the attachment system.
+ if (UsingNewAttachmentSystem()==true) {
+ if(slotCount >= usAttachmentSlotIndexVector.size())
+ break;
+ } else {
+ if(slotCount >= OLD_MAX_ATTACHMENTS_101)
+ break;
+ }
+
+ //Empty those Strings
+ swprintf( attachStr, L"" );
+ swprintf( attachStr2, L"" );
+ swprintf( attachStr3, L"" );
+
+ fAttachmentsFound = FALSE;
+
// Build a mouse region here that is over any others.....
//if (guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN )
if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
- MSYS_DefineRegion( &gItemDescAttachmentRegions[cnt], (INT16)(gsInvDescX + gItemDescAttachmentsXY[cnt].sX), (INT16)(gsInvDescY + gItemDescAttachmentsXY[cnt].sY), (INT16)(gsInvDescX + gItemDescAttachmentsXY[cnt].sX + gItemDescAttachmentsXY[cnt].sWidth), (INT16)(gsInvDescY + gItemDescAttachmentsXY[cnt].sY + gItemDescAttachmentsXY[cnt].sHeight), MSYS_PRIORITY_HIGHEST,
+ MSYS_DefineRegion( &gItemDescAttachmentRegions[slotCount], (INT16)(gsInvDescX + gItemDescAttachmentsXY[slotCount].sX), (INT16)(gsInvDescY + gItemDescAttachmentsXY[slotCount].sY), (INT16)(gsInvDescX + gItemDescAttachmentsXY[slotCount].sX + gItemDescAttachmentsXY[slotCount].sWidth), (INT16)(gsInvDescY + gItemDescAttachmentsXY[slotCount].sY + gItemDescAttachmentsXY[slotCount].sHeight), MSYS_PRIORITY_HIGHEST,
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescAttachmentsCallback );
else
- MSYS_DefineRegion( &gItemDescAttachmentRegions[cnt], (INT16)(gsInvDescX + gItemDescAttachmentsXY[cnt].sX), (INT16)(gsInvDescY + gItemDescAttachmentsXY[cnt].sY), (INT16)(gsInvDescX + gItemDescAttachmentsXY[cnt].sX + gItemDescAttachmentsXY[cnt].sBarDx + gItemDescAttachmentsXY[cnt].sWidth), (INT16)(gsInvDescY + gItemDescAttachmentsXY[cnt].sY + gItemDescAttachmentsXY[cnt].sHeight), MSYS_PRIORITY_HIGHEST,
+ MSYS_DefineRegion( &gItemDescAttachmentRegions[slotCount], (INT16)(gsInvDescX + gItemDescAttachmentsXY[slotCount].sX), (INT16)(gsInvDescY + gItemDescAttachmentsXY[slotCount].sY), (INT16)(gsInvDescX + gItemDescAttachmentsXY[slotCount].sX + gItemDescAttachmentsXY[slotCount].sBarDx + gItemDescAttachmentsXY[slotCount].sWidth), (INT16)(gsInvDescY + gItemDescAttachmentsXY[slotCount].sY + gItemDescAttachmentsXY[slotCount].sHeight), MSYS_PRIORITY_HIGHEST,
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ItemDescAttachmentsCallback );
// Add region
- MSYS_AddRegion( &gItemDescAttachmentRegions[cnt]);
- MSYS_SetRegionUserData( &gItemDescAttachmentRegions[cnt], 0, cnt );
+ MSYS_AddRegion( &gItemDescAttachmentRegions[slotCount]);
+ MSYS_SetRegionUserData( &gItemDescAttachmentRegions[slotCount], 0, slotCount );
//CHRISL: Include the ubStatusIndex in the region information so we know which object in a stack we're looking at
- MSYS_SetRegionUserData( &gItemDescAttachmentRegions[cnt], 1, ubStatusIndex );
+ MSYS_SetRegionUserData( &gItemDescAttachmentRegions[slotCount], 1, ubStatusIndex );
// CHRISL: Instead of looking at object 0, let's look at the object we actually right clicked on using ubStatusIndex
- OBJECTTYPE* pAttachment = (*pObject)[ubStatusIndex]->GetAttachmentAtIndex(cnt);
- if (pAttachment) {
- SetRegionFastHelpText( &(gItemDescAttachmentRegions[ cnt ]), ItemNames[ pAttachment->usItem ] );
- SetRegionHelpEndCallback( &(gItemDescAttachmentRegions[ cnt ]), HelpTextDoneCallback );
- }
- else
- {
- SetRegionFastHelpText( &(gItemDescAttachmentRegions[ cnt ]), Message[ STR_ATTACHMENTS ] );
- SetRegionHelpEndCallback( &(gItemDescAttachmentRegions[ cnt ]), HelpTextDoneCallback );
+ OBJECTTYPE* pAttachment = (*pObject)[ubStatusIndex]->GetAttachmentAtIndex(slotCount);
+ if (pAttachment->exists()) {
+ SetRegionFastHelpText( &(gItemDescAttachmentRegions[ slotCount ]), ItemNames[ pAttachment->usItem ] );
+ } else if (UsingNewAttachmentSystem()==true && !usAttachmentSlotIndexVector.empty()) {
+
+ UINT16 usLoopSlotID = usAttachmentSlotIndexVector[slotCount];
+ attachList.clear();
+
+ //Print all attachments that fit on this item.
+ for(UINT16 usLoop = 0; usLoop < MAXATTACHMENTS; usLoop++)
+ { //We no longer find valid attachments from AttachmentSlots.xml so we need to work a bit harder to get our list
+ usAttachment = 0;
+ if(Attachment[usLoop][1] == pObject->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[usLoop][0]].nasAttachmentClass)
+ { //search primary item attachments.xml
+ usAttachment = Attachment[usLoop][0];
+ }
+ else if(Launchable[usLoop][1] == pObject->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Launchable[usLoop][0]].nasAttachmentClass)
+ { //search primary item launchables.xml
+ usAttachment = Launchable[usLoop][0];
+ }
+ else
+ { //search for attachments/launchables made valid by other attachments
+ for(UINT8 x=0; x<(*pObject)[ubStatusIndex]->attachments.size(); x++)
+ {
+ OBJECTTYPE* pAttachment2 = (*pObject)[ubStatusIndex]->GetAttachmentAtIndex(x);
+ if(pAttachment2->exists())
+ {
+ if(Attachment[usLoop][1] == pAttachment2->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Attachment[usLoop][0]].nasAttachmentClass)
+ usAttachment = Attachment[usLoop][0];
+ else if(Launchable[usLoop][1] == pAttachment2->usItem && AttachmentSlots[usLoopSlotID].nasAttachmentClass & Item[Launchable[usLoop][0]].nasAttachmentClass)
+ usAttachment = Launchable[usLoop][0];
+ }
+ }
+ }
+ if(Attachment[usLoop][0] == 0 && Launchable[usLoop][0] == 0)
+ break;
+
+ if( usAttachment > 0 && !Item[usAttachment].hiddenaddon && !Item[usAttachment].hiddenattachment && ItemIsLegal(usAttachment))
+ attachList.push_back(usAttachment);
+ }
+
+ if(attachList.size()>0){
+ parseList = attachList;
+ for(std::vector::iterator pIter=parseList.begin(); pIter != parseList.end(); ++pIter){
+ BOOLEAN fDuplicate = FALSE;
+ for(std::vector::iterator aIter=attachList.begin(); aIter != attachList.end();){
+ UINT16 pi = *pIter;
+ UINT16 ai = *aIter;
+ if(pi == ai && !fDuplicate){
+ fDuplicate = TRUE;
+ ++aIter;
+ continue;
+ } else if(pi == ai && fDuplicate){
+ aIter = attachList.erase(aIter);
+ continue;
+ } else {
+ ++aIter;
+ }
+ }
+ }
+ }
+ for(UINT16 loop = 0; loop < attachList.size(); loop++){
+ usAttachment = attachList[loop];
+ // If the attachment is not hidden
+ if (usAttachment > 0 && !Item[ usAttachment ].hiddenaddon && !Item[ usAttachment ].hiddenattachment)
+ {
+ if (wcslen( attachStr3 ) + wcslen(Item[usAttachment].szItemName) > 3600)
+ {
+ // End list early to avoid overflow
+ wcscat( attachStr3, L"\n..." );
+ break;
+ }
+ else
+ {// Add the attachment's name to the list.
+ fAttachmentsFound = TRUE;
+ swprintf( attachStr2, L"\n%s", Item[ usAttachment ].szItemName );
+ wcscat( attachStr3, attachStr2);
+ }
+ }
+ }
+
+ if (fAttachmentsFound)
+ {
+ // Add extra empty line and attachment list title
+ swprintf( attachStr, L"%s:\n ", Message[ STR_ATTACHMENTS ] );
+ // Print the attachments
+ wcscat( attachStr, attachStr3 );
+ } else if(usLoopSlotID != 0) {
+ swprintf( attachStr2, L"\n%s", AttachmentSlots[usLoopSlotID].szSlotName );
+ wcscat( attachStr, attachStr2);
+ } else {
+ wcscat( attachStr, Message[ STR_ATTACHMENTS ] );
+ }
+ SetRegionFastHelpText( &(gItemDescAttachmentRegions[ slotCount ]), attachStr );
+ } else {
+ SetRegionFastHelpText( &(gItemDescAttachmentRegions[ slotCount ]), Message[ STR_ATTACHMENTS ] );
}
+ SetRegionHelpEndCallback( &(gItemDescAttachmentRegions[ slotCount ]), HelpTextDoneCallback );
}
}
@@ -3488,7 +3808,7 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason)
//holding an item
if(Magazine[Item[gpItemPointer->usItem].ubClassIndex].ubCalibre == Weapon[Item[gpItemDescObject->usItem].ubClassIndex].ubCalibre)
{
- ReloadGun(gpItemDescSoldier, gpItemDescObject, gpItemPointer);
+ ReloadGun(gpItemDescSoldier, gpItemDescObject, gpItemPointer, ubStatusIndex);
}
if(gpItemPointer->ubNumberOfObjects == 0)
{
@@ -3627,9 +3947,9 @@ void ItemDescAmmoCallback(GUI_BUTTON *btn,INT32 reason)
//CHRISL: We need to know which item in the stack we're working with.
-void DoAttachment( UINT8 subObject )
+void DoAttachment( UINT8 subObject, INT32 iItemPos )
{
- if ( gpItemDescObject->AttachObject( gpItemDescSoldier, gpItemPointer, TRUE, subObject ) )
+ if ( gpItemDescObject->AttachObject( gpItemDescSoldier, gpItemPointer, TRUE, subObject, iItemPos) )
{
if (gpItemPointer->exists() == false)
{
@@ -3679,7 +3999,7 @@ void PermanantAttachmentMessageBoxCallBack( UINT8 ubExitValue )
{
if ( ubExitValue == MSG_BOX_RETURN_YES )
{
- DoAttachment(0);
+ DoAttachment(0, iItemPosition);
}
// else do nothing
}
@@ -3689,7 +4009,7 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
UINT32 uiItemPos, ubStatusIndex;
static BOOLEAN fRightDown = FALSE;
- if ( gfItemDescObjectIsAttachment )
+ if ( gfItemDescObjectIsAttachment || !gpItemDescObject->exists() )
{
// screen out completely
return;
@@ -3712,19 +4032,44 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
if ( gpItemPointer != NULL )
{
// nb pointer could be NULL because of inventory manipulation in mapscreen from sector inv
- if ( !gpItemPointerSoldier || EnoughPoints( gpItemPointerSoldier, AttachmentAPCost( gpItemPointer->usItem, gpItemDescObject->usItem ), 0, TRUE ) )
+ if ( !gpItemPointerSoldier || EnoughPoints( gpItemPointerSoldier, AttachmentAPCost( gpItemPointer->usItem, gpItemDescObject, gpItemPointerSoldier ), 0, TRUE ) )
{
// if ( (Item[ gpItemPointer->usItem ].fFlags & ITEM_INSEPARABLE) && ValidAttachment( gpItemPointer->usItem, gpItemDescObject->usItem ) )
- if ( (Item[ gpItemPointer->usItem ].inseparable ) && ValidAttachment( gpItemPointer->usItem, gpItemDescObject->usItem ) )
+ if ( (Item[ gpItemPointer->usItem ].inseparable ) && ValidAttachment( gpItemPointer->usItem, gpItemDescObject ) )
{
+ iItemPosition = uiItemPos;
DoScreenIndependantMessageBox( Message[ STR_PERMANENT_ATTACHMENT ], ( UINT8 )MSG_BOX_FLAG_YESNO, PermanantAttachmentMessageBoxCallBack );
return;
}
- DoAttachment((UINT8)ubStatusIndex);
+ DoAttachment((UINT8)ubStatusIndex, uiItemPos);
+ if(gpItemPointer->exists()){
+ if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+ {
+ // Set mouse
+ guiExternVo = GetInterfaceGraphicForItem( &(Item[ gpItemPointer->usItem ]) );
+ gusExternVoSubIndex = Item[ gpItemPointer->usItem ].ubGraphicNum;
+
+ MSYS_ChangeRegionCursor( &gMPanelRegion , EXTERN_CURSOR );
+ MSYS_SetCurrentCursor( EXTERN_CURSOR );
+ fMapInventoryItem=TRUE;
+ fTeamPanelDirty=TRUE;
+ }
+
+ //Dirty interface
+ fInterfacePanelDirty = DIRTYLEVEL2;
+
+ // re-evaluate repairs
+ gfReEvaluateEveryonesNothingToDo = TRUE;
+
+ UpdateItemHatches();
+
+
+ }
if(gpItemDescObject != NULL)
{
+ InitDescStatCoords(gpItemDescObject);
UpdateAttachmentTooltips(gpItemDescObject, ubStatusIndex);
InternalInitEDBTooltipRegion(gpItemDescObject, guiCurrentItemDescriptionScreen);
}
@@ -3733,11 +4078,11 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
else
{
// ATE: Make sure we have enough AP's to drop it if we pick it up!
- if ( pAttachment && EnoughPoints( gpItemDescSoldier, ( AttachmentAPCost( pAttachment->usItem, gpItemDescObject->usItem ) + APBPConstants[AP_PICKUP_ITEM] ), 0, TRUE ) )
+ if ( pAttachment->exists() && EnoughPoints( gpItemDescSoldier, ( AttachmentAPCost( pAttachment->usItem, gpItemDescObject, gpItemPointerSoldier ) + APBPConstants[AP_PICKUP_ITEM] ), 0, TRUE ) )
{
// Get attachment if there is one
// The follwing function will handle if no attachment is here
- if ( gpItemDescObject->RemoveAttachment( pAttachment, &gItemPointer, ubStatusIndex ) )
+ if ( gpItemDescObject->RemoveAttachment( pAttachment, &gItemPointer, ubStatusIndex, gpItemDescSoldier ) )
{
gpItemPointer = &gItemPointer;
gpItemPointerSoldier = gpItemDescSoldier;
@@ -3769,13 +4114,14 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
UpdateItemHatches();
- if(gpItemDescObject != NULL)
- {
- UpdateAttachmentTooltips(gpItemDescObject, ubStatusIndex);
- InternalInitEDBTooltipRegion(gpItemDescObject, guiCurrentItemDescriptionScreen);
- }
}
}
+ if(gpItemDescObject != NULL)
+ {
+ InitDescStatCoords(gpItemDescObject);
+ UpdateAttachmentTooltips(gpItemDescObject, ubStatusIndex);
+ InternalInitEDBTooltipRegion(gpItemDescObject, guiCurrentItemDescriptionScreen);
+ }
}
}
else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_DWN )
@@ -3786,7 +4132,7 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
{
fRightDown = FALSE;
- if ( pAttachment )
+ if ( pAttachment->exists() )
{
static OBJECTTYPE Object2;
@@ -3798,7 +4144,9 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
fShopkeeperItem = TRUE;
}
+ OBJECTTYPE *pTemp = gpItemDescObject;
DeleteItemDescriptionBox( );
+ gpItemDescPrevObject = pTemp;
Object2 = *pAttachment;
gfItemDescObjectIsAttachment = TRUE;
@@ -3813,6 +4161,7 @@ void ItemDescAttachmentsCallback( MOUSE_REGION * pRegion, INT32 iReason )
}
}
+/*INT8 DetermineShowBox( )
INT8 DetermineShowBox( )
{
if(gpItemDescObject == NULL)
@@ -3825,19 +4174,22 @@ INT8 DetermineShowBox( )
if (UsingEDBSystem() == 2)
{
if (Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_EXPLOSV|IC_AMMO|IC_ARMOUR|IC_PUNCH) && UsingEDBSystem() > 0 )
- return 6;
+ return(UsingNewAttachmentSystem()==true ? 8 : 6);
else
- return 7;
+ return(UsingNewAttachmentSystem()==true ? 9 : 7);
}
else if (guiCurrentItemDescriptionScreen == MAP_SCREEN)
{
if (Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_EXPLOSV|IC_AMMO|IC_ARMOUR|IC_PUNCH) && UsingEDBSystem() > 0 )
- return 6;
+ return(UsingNewAttachmentSystem()==true ? 7 : 6);
else
- return 1;
+ if(UsingEDBSystem() > 0)
+ return(UsingNewAttachmentSystem()==true ? 8 : 1);
+ else
+ return(UsingNewAttachmentSystem()==true ? 6 : 1);
}
else
- return 0;
+ return(UsingNewAttachmentSystem()==true ? 5 : 0);
}
else if(UsingNewInventorySystem() == true) //NIV
{
@@ -3845,32 +4197,274 @@ INT8 DetermineShowBox( )
return (gpItemDescObject->GetLBEPointer(gubItemDescStatusIndex)->lbeClass + (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 1 : 0));
else if(Item[gpItemDescObject->usItem].usItemClass == IC_LBEGEAR)
return (LoadBearingEquipment[Item[gpItemDescObject->usItem].ubClassIndex].lbeClass + (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 1 : 0));
- else if (Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_EXPLOSV|IC_AMMO|IC_ARMOUR|IC_PUNCH) && UsingEDBSystem() > 0 )
- return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 6 : 5);
- else
- return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 1 : 0);
+ else if (Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_EXPLOSV|IC_AMMO|IC_ARMOUR|IC_PUNCH) && UsingEDBSystem() > 0 ){
+ if(UsingNewAttachmentSystem()==true)
+ return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 7 : 8);
+ else
+ return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 6 : 5);
+ }else{
+ if(UsingNewAttachmentSystem()==true && UsingEDBSystem() > 0 && Item[gpItemDescObject->usItem].usItemClass != IC_MONEY)
+ return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 8 : 9);
+ else if(UsingNewAttachmentSystem()==true && Item[gpItemDescObject->usItem].usItemClass != IC_MONEY)
+ return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 6 : 5);
+ else
+ return (guiCurrentItemDescriptionScreen == MAP_SCREEN ? 1 : 0);
+ }
}
return 0;
+}*/
+
+INT8 DetermineShowBox( )
+{
+ INT8 bShowBox = 0;
+
+ // HEADROCK HAM 4: Function altered for Ultra Description Box
+
+ if(gpItemDescObject == NULL)
+ return 0;
+
+ if(iResolution == 0)
+ return 0;
+
+ if(UsingEDBSystem() <= 0)
+ if (guiCurrentItemDescriptionScreen == MAP_SCREEN)
+ if (UseNASDesc( gpItemDescObject) )
+ return 2;
+ else
+ return 1;
+ else
+ if (UseNASDesc( gpItemDescObject) )
+ return 1;
+ else
+ return 0;
+
+ if(UsingNewInventorySystem() == false) //OIV
+ {
+ if (guiCurrentItemDescriptionScreen == MAP_SCREEN)
+ {
+ if (UsingEDBSystem() > 0)
+ {
+ if (Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_PUNCH))
+ {
+ switch (gubDescBoxPage)
+ {
+ case 0:
+ bShowBox = 3;
+ break;
+ case 1:
+ bShowBox = 4;
+ break;
+ case 2:
+ bShowBox = 6;
+ break;
+ }
+ }
+ else
+ {
+ switch (gubDescBoxPage)
+ {
+ case 0:
+ bShowBox = 3;
+ break;
+ case 1:
+ bShowBox = 5;
+ break;
+ case 2:
+ bShowBox = 6;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (UseNASDesc( gpItemDescObject) )
+ bShowBox = 2;
+ else
+ bShowBox = 1;
+ }
+ }
+ else
+ return 0; // Tactical OIV no longer enables UDB. It always defaults to ODB.
+ }
+ else if(UsingNewInventorySystem() == true) //NIV
+ {
+ if (Item[gpItemDescObject->usItem].usItemClass & (IC_WEAPON|IC_PUNCH) && UsingEDBSystem() > 0 )
+ {
+ if (guiCurrentItemDescriptionScreen == MAP_SCREEN)
+ {
+ switch (gubDescBoxPage)
+ {
+ case 0:
+ bShowBox = 3;
+ break;
+ case 1:
+ bShowBox = 4;
+ break;
+ case 2:
+ bShowBox = 6;
+ break;
+ }
+ }
+ else
+ {
+ switch (gubDescBoxPage)
+ {
+ case 0:
+ bShowBox = 2;
+ break;
+ case 1:
+ bShowBox = 3;
+ break;
+ case 2:
+ bShowBox = 5;
+ break;
+ }
+ }
+ }
+ else if (UsingEDBSystem() > 0)
+ {
+ if (guiCurrentItemDescriptionScreen == MAP_SCREEN)
+ {
+ switch (gubDescBoxPage)
+ {
+ case 0:
+ bShowBox = 3;
+ break;
+ case 1:
+ bShowBox = 5;
+ break;
+ case 2:
+ bShowBox = 6;
+ break;
+ }
+ }
+ else
+ {
+ switch (gubDescBoxPage)
+ {
+ case 0:
+ bShowBox = 2;
+ break;
+ case 1:
+ bShowBox = 4;
+ break;
+ case 2:
+ bShowBox = 5;
+ break;
+ }
+ }
+ }
+ else
+ if (UseNASDesc( gpItemDescObject) )
+ bShowBox = 2;
+ else
+ bShowBox = 1;
+ }
+
+ if (UsingEDBSystem() > 0 && UseNASDesc( gpItemDescObject ))
+ {
+ bShowBox += 4;
+ }
+
+ return bShowBox;
+}
+
+// HEADROCK HAM 4: This picks an LBE picture to be displayed on top of the description box when necessary.
+INT8 DetermineShowLBE( )
+{
+ if(gpItemDescObject == NULL)
+ return -1;
+
+ if(iResolution == 0)
+ return -1;
+
+ if(!UsingNewInventorySystem())
+ {
+ return -1;
+ }
+ else
+ {
+ if(!(gpItemDescObject->IsActiveLBE(gubItemDescStatusIndex) || Item[gpItemDescObject->usItem].usItemClass == IC_LBEGEAR))
+ {
+ return -1;
+ }
+ else
+ {
+ if(gpItemDescObject->IsActiveLBE(gubItemDescStatusIndex))
+ return (gpItemDescObject->GetLBEPointer(gubItemDescStatusIndex)->lbeClass - 1);
+ else if(Item[gpItemDescObject->usItem].usItemClass == IC_LBEGEAR)
+ return (LoadBearingEquipment[Item[gpItemDescObject->usItem].ubClassIndex].lbeClass - 1);
+ else
+ return -1;
+ }
+ }
+}
+
+// HEADROCK HAM 4: Function to get the number of the item condition string
+UINT8 GetConditionString( UINT8 ubStatus, UINT8 *ubFontColor )
+{
+ if (ubStatus > 99)
+ {
+ *ubFontColor = FONT_WHITE;
+ return 0;
+ }
+ else if (ubStatus >= 95 && ubStatus <= 99)
+ {
+ *ubFontColor = FONT_LTGREEN;
+ return 1;
+ }
+ else if (ubStatus >= 80 && ubStatus <= 94)
+ {
+ *ubFontColor = FONT_GREEN;
+ return 2;
+ }
+ else if (ubStatus >= 60 && ubStatus <= 79)
+ {
+ *ubFontColor = FONT_YELLOW;
+ return 3;
+ }
+ else if (ubStatus >= 40 && ubStatus <= 59)
+ {
+ *ubFontColor = FONT_ORANGE;
+ return 4;
+ }
+ else if (ubStatus >= 10 && ubStatus <= 39)
+ {
+ *ubFontColor = FONT_RED;
+ return 5;
+ }
+ else if (ubStatus < 10)
+ {
+ *ubFontColor = FONT_DKRED;
+ return 6;
+ }
+ // Default
+ else
+ {
+ return 0;
+ }
}
void RenderItemDescriptionBox( )
{
- ETRLEObject *pTrav;
- UINT32 usHeight, usWidth;
- INT16 sCenX, sCenY, sStrX;
- HVOBJECT hVObject;
- CHAR16 sTempString[ 128 ];
+ ETRLEObject *pTrav;
+ UINT32 usHeight, usWidth;
+ INT32 sOffsetX, sOffsetY;
+ INT16 sCenX, sCenY, sStrX;
+ HVOBJECT hVObject;
+ CHAR16 sTempString[ 128 ];
- UINT16 uiStringLength, uiRightLength;
- static CHAR16 pStr[ 100 ];
- INT32 cnt;
- FLOAT fWeight;
- INT16 usX, usY;
- INT16 ubAttackAPs;
- BOOLEAN fHatchOutAttachments = gfItemDescObjectIsAttachment; // if examining attachment, always hatch out attachment slots
- INT16 sProsConsIndent;
- INT8 showBox=DetermineShowBox();
+ UINT16 uiStringLength;
+ static CHAR16 pStr[ 100 ];
+ INT32 cnt;
+ FLOAT fWeight;
+ INT16 usX, usY;
+ INT16 ubAttackAPs;
+ INT16 sProsConsIndent;
+ INT8 showBox = DetermineShowBox();
+ INT8 showLBE = DetermineShowLBE();
+ std::vector usAttachmentSlotIndexVector = GetItemSlots(gpItemDescObject, gubItemDescStatusIndex);
int status = 0;
int shotsLeft = 0;
@@ -3883,14 +4477,33 @@ void RenderItemDescriptionBox( )
{
// TAKE A LOOK AT THE VIDEO OBJECT SIZE ( ONE OF TWO SIZES ) AND CENTER!
GetVideoObject( &hVObject, guiItemGraphic );
- pTrav = &(hVObject->pETRLEObject[ 0 ] );
- usHeight = (UINT32)pTrav->usHeight;
- usWidth = (UINT32)pTrav->usWidth;
+ if(hVObject->ubBitDepth == 8)
+ {
+ pTrav = &(hVObject->pETRLEObject[ 0 ] );
+ usHeight = (UINT32)pTrav->usHeight;
+ usWidth = (UINT32)pTrav->usWidth;
+ sOffsetX = (INT32)pTrav->sOffsetX;
+ sOffsetY = (INT32)pTrav->sOffsetY;
+ }
+ else if(hVObject->ubBitDepth == 16 && hVObject->p16BPPObject)
+ {
+ usHeight = hVObject->p16BPPObject->usHeight;
+ usWidth = hVObject->p16BPPObject->usWidth;
+ sOffsetX = hVObject->p16BPPObject->sOffsetX;
+ sOffsetY = hVObject->p16BPPObject->sOffsetY;
+ }
+ else if(hVObject->ubBitDepth == 32)
+ {
+ usHeight = hVObject->p16BPPObject->usHeight;
+ usWidth = hVObject->p16BPPObject->usWidth;
+ sOffsetX = hVObject->p16BPPObject->sOffsetX;
+ sOffsetY = hVObject->p16BPPObject->sOffsetY;
+ }
// CENTER IN SLOT!
// REMOVE OFFSETS!
- sCenX = ITEMDESC_ITEM_X + (INT16)( abs( ITEMDESC_ITEM_WIDTH - (double)usWidth ) / 2 ) - pTrav->sOffsetX;
- sCenY = ITEMDESC_ITEM_Y + (INT16)( abs( ITEMDESC_ITEM_HEIGHT - (double)usHeight ) / 2 )- pTrav->sOffsetY;
+ sCenX = ITEMDESC_ITEM_X + (INT16)( abs( ITEMDESC_ITEM_WIDTH - (double)usWidth ) / 2 ) - sOffsetX;
+ sCenY = ITEMDESC_ITEM_Y + (INT16)( abs( ITEMDESC_ITEM_HEIGHT - (double)usHeight ) / 2 )- sOffsetY;
RenderBackpackButtons(1); /* CHRISL: Needed for new inventory backpack buttons */
@@ -3903,6 +4516,29 @@ void RenderItemDescriptionBox( )
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemDescBox, showBox, gsInvDescX, gsInvDescY, VO_BLT_SRCTRANSPARENCY, NULL );
}
+ //WarmSteel - Draw the attachment slots needed for NAS, read their positions from XML.
+ if(UsingNewAttachmentSystem()==true && UseNASDesc(gpItemDescObject) && !usAttachmentSlotIndexVector.empty()){
+
+ for(UINT16 slotCount = 0; slotCount < usAttachmentSlotIndexVector.size(); slotCount++){
+ INT16 sX = gsInvDescX + AttachmentSlots[usAttachmentSlotIndexVector[slotCount]].usDescPanelPosX - 6; //Warmsteel - Retracting a number to account for the status bar.
+ INT16 sY = gsInvDescY + AttachmentSlots[usAttachmentSlotIndexVector[slotCount]].usDescPanelPosY - 1;
+
+ //WarmSteel - Clear the background rectangle so we can paint it.
+ if ( guiSAVEBUFFER == FRAME_BUFFER )
+ {
+ InvalidateRegion( sX, sY, (INT16)(sX + 8), (INT16)(sY + 8 ) );
+ }
+ else
+ {
+ RestoreExternBackgroundRect( sX, sY, 8, 8 );
+ }
+ if(AttachmentSlots[usAttachmentSlotIndexVector[slotCount]].fBigSlot){
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiAttachmentSlot, 1, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
+ } else {
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiAttachmentSlot, 0, sX, sY, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+ }
//Display the money 'seperating' border
if ( gpItemDescObject->usItem == MONEY )
{
@@ -3911,8 +4547,10 @@ void RenderItemDescriptionBox( )
}
// Display item
- if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ]) BltVideoObjectOutlineShadowFromIndex( guiSAVEBUFFER, guiItemGraphic, 0, sCenX - 2, sCenY + 2 );
-
+ if(gGameSettings.fOptions[ TOPTION_SHOW_ITEM_SHADOW ])
+ {
+ BltVideoObjectOutlineShadowFromIndex( guiSAVEBUFFER, guiItemGraphic, 0, sCenX - 2, sCenY + 2 );
+ }
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemGraphic, 0, sCenX, sCenY, VO_BLT_SRCTRANSPARENCY, NULL );
// Display status
@@ -3925,16 +4563,53 @@ void RenderItemDescriptionBox( )
RenderLBENODEItems( gpItemDescObject, gubItemDescStatusIndex );
}
+ // HEADROCK HAM 4: First, display LBE Background
+ if(UsingNewInventorySystem() == true && Item[gpItemDescObject->usItem].usItemClass == IC_LBEGEAR && showLBE >= 0)
+ {
+ // Exchange LBE images to conserve space in tactical, as appropriate for the UDB/ODB system used.
+ INT8 showLBEImage = showLBE;
+ if (guiCurrentItemDescriptionScreen != MAP_SCREEN)
+ if (UsingEDBSystem() > 0)
+ showLBEImage += 4;
+ else
+ showLBEImage += 8;
+
+ // Draw LBE background image
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoLBEBackground, showLBEImage, gItemDescLBEBackground[showLBE].sLeft, gItemDescLBEBackground[showLBE].sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ // Render LBE items
+ RenderLBENODEItems( gpItemDescObject, gubItemDescStatusIndex );
+ }
+
if (gpItemPointer)
{
-// if ( ( Item[ gpItemPointer->usItem ].fFlags & ITEM_HIDDEN_ADDON ) ||
- if ( ( Item[ gpItemPointer->usItem ].hiddenaddon ) ||
-
- ( !ValidItemAttachment( gpItemDescObject, gpItemPointer->usItem, FALSE ) &&
- !ValidMerge( gpItemPointer->usItem, gpItemDescObject->usItem ) && !ValidLaunchable( gpItemPointer->usItem, gpItemDescObject->usItem ) ) )
+ if(UsingNewAttachmentSystem()==true)
{
- // hatch out the attachment panels
- fHatchOutAttachments = TRUE;
+ //WarmSteel - This hatches out attachment slots one by one, instead of all of em.
+ for(cnt = 0; cnt < (INT32)(*gpItemDescObject)[gubItemDescStatusIndex]->attachments.size(); cnt++)
+ {
+ //if ( ( Item[ gpItemPointer->usItem ].fFlags & ITEM_HIDDEN_ADDON ) ||
+ if ( ( Item[ gpItemPointer->usItem ].hiddenaddon ) ||
+
+ ( !ValidItemAttachmentSlot( gpItemDescObject, gpItemPointer->usItem, FALSE, FALSE, gubItemDescStatusIndex, cnt, FALSE, NULL, usAttachmentSlotIndexVector) &&
+ !ValidMerge( gpItemPointer->usItem, gpItemDescObject->usItem ) ) )
+ {
+ // hatch out this attachment panel
+ DrawHatchOnInventory( guiSAVEBUFFER, (INT16) (gsInvDescX + gItemDescAttachmentsXY[ cnt ].sX), (INT16) (gsInvDescY + gItemDescAttachmentsXY[ cnt ].sY - 2), (INT16)(gItemDescAttachmentsXY[ cnt ].sWidth + gItemDescAttachmentsXY[ cnt ].sBarDx), (INT16) (gItemDescAttachmentsXY[ cnt ].sHeight + 2) );
+ }
+ }
+ } else {
+ for(cnt = 0; cnt < OLD_MAX_ATTACHMENTS_101; cnt++)
+ {
+ //if ( ( Item[ gpItemPointer->usItem ].fFlags & ITEM_HIDDEN_ADDON ) ||
+ if ( ( Item[ gpItemPointer->usItem ].hiddenaddon ) ||
+
+ ( !ValidItemAttachment( gpItemDescObject, gpItemPointer->usItem, FALSE, FALSE, gubItemDescStatusIndex, usAttachmentSlotIndexVector) &&
+ !ValidMerge( gpItemPointer->usItem, gpItemDescObject->usItem ) && !ValidLaunchable( gpItemPointer->usItem, gpItemDescObject->usItem ) ) )
+ {
+ // hatch out the attachment panels
+ DrawHatchOnInventory( guiSAVEBUFFER, (INT16) (gsInvDescX + gItemDescAttachmentsXY[ cnt ].sX), (INT16) (gsInvDescY + gItemDescAttachmentsXY[ cnt ].sY - 2), (INT16)(gItemDescAttachmentsXY[ cnt ].sWidth + gItemDescAttachmentsXY[ cnt ].sBarDx), (INT16) (gItemDescAttachmentsXY[ cnt ].sHeight + 2) );
+ }
+ }
}
}
@@ -3943,21 +4618,29 @@ void RenderItemDescriptionBox( )
for (attachmentList::iterator iter = (*gpItemDescObject)[gubItemDescStatusIndex]->attachments.begin();
iter != (*gpItemDescObject)[gubItemDescStatusIndex]->attachments.end(); ++iter, ++cnt) {
- sCenX = gsInvDescX + gItemDescAttachmentsXY[cnt].sX;
- sCenY = gsInvDescY + gItemDescAttachmentsXY[cnt].sY;
- INVRenderItem( guiSAVEBUFFER, NULL, gpItemDescObject, sCenX, sCenY, gItemDescAttachmentsXY[cnt].sWidth, gItemDescAttachmentsXY[cnt].sHeight, DIRTYLEVEL2, NULL, (UINT8)(RENDER_ITEM_ATTACHMENT1 + cnt), FALSE, 0, gubItemDescStatusIndex );
- sCenX = sCenX + gItemDescAttachmentsXY[cnt].sBarDx;
- sCenY = sCenY + gItemDescAttachmentsXY[cnt].sBarDy;
- DrawItemUIBarEx( gpItemDescObject, (UINT8)(DRAW_ITEM_STATUS_ATTACHMENT1 + cnt), sCenX, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, Get16BPPColor( STATUS_BAR ), Get16BPPColor( STATUS_BAR_SHADOW ), TRUE , guiSAVEBUFFER, gubItemDescStatusIndex );
- }
- for (cnt = 0; cnt < MAX_ATTACHMENTS; ++cnt)
- {
- if (fHatchOutAttachments)
- {
- DrawHatchOnInventory( guiSAVEBUFFER, (INT16) (gsInvDescX + gItemDescAttachmentsXY[ cnt ].sX), (INT16) (gsInvDescY + gItemDescAttachmentsXY[ cnt ].sY - 2), (INT16)(gItemDescAttachmentsXY[ cnt ].sWidth + gItemDescAttachmentsXY[ cnt ].sBarDx), (INT16) (gItemDescAttachmentsXY[ cnt ].sHeight + 2) );
+ if(iter->exists()){
+ sCenX = gsInvDescX + gItemDescAttachmentsXY[cnt].sX;
+ sCenY = gsInvDescY + gItemDescAttachmentsXY[cnt].sY;
+ INVRenderItem( guiSAVEBUFFER, NULL, gpItemDescObject, sCenX, sCenY, gItemDescAttachmentsXY[cnt].sWidth, gItemDescAttachmentsXY[cnt].sHeight, DIRTYLEVEL2, NULL, (UINT8)(RENDER_ITEM_ATTACHMENT1 + cnt), FALSE, 0, gubItemDescStatusIndex );
+ sCenX = sCenX + gItemDescAttachmentsXY[cnt].sBarDx;
+ sCenY = sCenY + gItemDescAttachmentsXY[cnt].sBarDy;
+ DrawItemUIBarEx( gpItemDescObject, (UINT8)(DRAW_ITEM_STATUS_ATTACHMENT1 + cnt), sCenX, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, Get16BPPColor( STATUS_BAR ), Get16BPPColor( STATUS_BAR_SHADOW ), TRUE , guiSAVEBUFFER, gubItemDescStatusIndex );
}
}
+ // HEADROCK HAM 4: If vieweing the UDB Advanced page, reveal buttons and set them as appropriate
+ if (UsingEDBSystem() && gubDescBoxPage == 2)
+ {
+ ShowButton( giInvDescAdvButton[0] );
+ ShowButton( giInvDescAdvButton[1] );
+ ItemDescAdvButtonCheck();
+ }
+ else if (UsingEDBSystem())
+ {
+ HideButton( giInvDescAdvButton[0] );
+ HideButton( giInvDescAdvButton[1] );
+ }
+
//HEADROCK/CHRISL: This condition needs to run differently depending on whether EDB is active of not
if(UsingEDBSystem() > 0)
{
@@ -3988,20 +4671,20 @@ void RenderItemDescriptionBox( )
{
// display bullets for ROF
if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiBullet, 0, BULLET_SING_X, BULLET_SING_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiBullet, 0, gODBItemDescRegions[3][1].sLeft, gODBItemDescRegions[3][1].sTop, VO_BLT_SRCTRANSPARENCY, NULL );
if ( GetShotsPerBurst(gpItemDescObject) > 0 )
{
for ( cnt = 0; cnt < __min(GetShotsPerBurst(gpItemDescObject),12); cnt++ )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiBullet, 0, BULLET_BURST_X + cnt * (BULLET_WIDTH/2 + 1), BULLET_BURST_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiBullet, 0, gODBItemDescRegions[3][4].sLeft + cnt * (BULLET_WIDTH/2 + 1), gODBItemDescRegions[3][4].sTop, VO_BLT_SRCTRANSPARENCY, NULL );
}
}
else if ( GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
for ( cnt = 0; cnt < 10; cnt++ )
{
- BltVideoObjectFromIndex( guiSAVEBUFFER, guiBullet, 0, BULLET_BURST_X + cnt * (BULLET_WIDTH/2 + 1), BULLET_BURST_Y, VO_BLT_SRCTRANSPARENCY, NULL );
+ BltVideoObjectFromIndex( guiSAVEBUFFER, guiBullet, 0, gODBItemDescRegions[3][4].sLeft + cnt * (BULLET_WIDTH/2 + 1), gODBItemDescRegions[3][4].sTop, VO_BLT_SRCTRANSPARENCY, NULL );
}
}
@@ -4020,6 +4703,12 @@ void RenderItemDescriptionBox( )
RenderLBENODEItems( gpItemDescObject, gubItemDescStatusIndex );
}
+ ////////////////////////////////////////////////////////////////////////////////////
+ // This section displays on screen all values that are common to both EDB and ODB.
+ // They are drawn based on variable coordinates, which have been set beforehand
+ // based on the system being used.
+ ////////////////////////////////////////////////////////////////////////////////////
+
// Render font desc
SetFont( ITEMDESC_FONT );
SetFontBackground( FONT_MCOLOR_BLACK );
@@ -4034,15 +4723,11 @@ void RenderItemDescriptionBox( )
mprintf( ITEMDESC_NAME_X, ITEMDESC_NAME_Y, L"%s", gzItemName );
#endif
- // Render "normal" item data
- SetFontForeground( FONT_BLACK );
- SetFontShadow( ITEMDESC_FONTSHADOW2 );
-
- // Item Full Description
- DisplayWrappedString( (INT16)ITEMDESC_DESC_START_X, (INT16)ITEMDESC_DESC_START_Y, ITEMDESC_DESC_WIDTH, 2, ITEMDESC_FONT, FONT_BLACK, gzItemDesc, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
-
+ // Render extra data on name bar for weapons and launchers (Caliber, Fingerprints)
if ( ITEM_PROS_AND_CONS( gpItemDescObject->usItem ) )
{
+ SetFontForeground( FONT_BLACK );
+ SetFontShadow( ITEMDESC_FONTSHADOW2 );
// Caliber
if ( (Item[gpItemDescObject->usItem].fingerprintid ) && (*gpItemDescObject)[gubItemDescStatusIndex]->data.ubImprintID < NO_PROFILE )
{
@@ -4057,46 +4742,204 @@ void RenderItemDescriptionBox( )
FindFontRightCoordinates( (INT16) ITEMDESC_CALIBER_X, (INT16) ITEMDESC_CALIBER_Y, ITEMDESC_CALIBER_WIDTH, ITEM_STATS_HEIGHT, pStr, ITEMDESC_FONT, &usX, &usY);
mprintf( usX, usY, pStr );
-
- SetFontForeground( FONT_MCOLOR_DKWHITE2 );
- SetFontShadow( ITEMDESC_FONTSHADOW3 );
- // PROs
- mprintf( (INT16)ITEMDESC_PROS_START_X, (INT16)ITEMDESC_PROS_START_Y, gzProsLabel );
-
- // HEADROCK: Disabled PROs/CONs text for OIV EDB Tactical
- if (UsingEDBSystem() != 2)
- {
- sProsConsIndent = __max( StringPixLength( gzProsLabel, ITEMDESC_FONT ), StringPixLength( gzConsLabel, ITEMDESC_FONT ) ) + 10;
- gzItemPros[0] = 0;
- GenerateProsString( gzItemPros, gpItemDescObject, ITEMDESC_DESC_WIDTH - sProsConsIndent - StringPixLength( DOTDOTDOT, ITEMDESC_FONT ) );
- if (gzItemPros[0] != 0)
- {
- SetFontForeground( FONT_BLACK );
- SetFontShadow( ITEMDESC_FONTSHADOW2 );
- DisplayWrappedString( (INT16)(ITEMDESC_PROS_START_X + sProsConsIndent), (INT16)ITEMDESC_PROS_START_Y, (INT16)(ITEMDESC_DESC_WIDTH - sProsConsIndent), 2, ITEMDESC_FONT, FONT_BLACK, gzItemPros, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
- }
- }
-
- SetFontForeground( FONT_MCOLOR_DKWHITE2 );
- SetFontShadow( ITEMDESC_FONTSHADOW3 );
- // CONs
- mprintf( (INT16)ITEMDESC_CONS_START_X, (INT16)ITEMDESC_CONS_START_Y, gzConsLabel );
-
- // HEADROCK: Disabled PROs/CONs text for OIV EDB Tactical
- if (UsingEDBSystem() != 2)
- {
- GenerateConsString( gzItemCons, gpItemDescObject, ITEMDESC_DESC_WIDTH - sProsConsIndent - StringPixLength( DOTDOTDOT, ITEMDESC_FONT ) );
- if (gzItemCons[0] != 0)
- {
- SetFontForeground( FONT_BLACK );
- SetFontShadow( ITEMDESC_FONTSHADOW2 );
- DisplayWrappedString( (INT16)(ITEMDESC_CONS_START_X + sProsConsIndent), (INT16)ITEMDESC_CONS_START_Y, (INT16)(ITEMDESC_DESC_WIDTH - sProsConsIndent), 2, ITEMDESC_FONT, FONT_BLACK, gzItemCons, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
- }
- }
}
- // Get length of string
- uiRightLength=35;
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Render Item DESCRIPTION page. Contains the item's full-text description, item
+ // condition, item weight, and for weapons also PROS and CONS.
+ if (UsingEDBSystem() == 0 || gubDescBoxPage == 0)
+ {
+ UINT8 ForegroundColor;
+ UINT8 ShadowColor;
+ SetFont( BLOCKFONT2 );
+
+ /////////// DISPLAY FULL DESCRIPTION TEXT
+ if (UsingEDBSystem())
+ {
+ ForegroundColor = 6;
+ ShadowColor = DEFAULT_SHADOW;
+ }
+ else
+ {
+ ForegroundColor = FONT_MCOLOR_BLACK;
+ ShadowColor = ITEMDESC_FONTSHADOW2;
+ }
+ SetFontShadow( ShadowColor );
+
+ DisplayWrappedString( gItemDescTextRegions[0].sLeft, gItemDescTextRegions[0].sTop, gItemDescTextRegions[0].sRight - gItemDescTextRegions[0].sLeft, 2, ITEMDESC_FONT, ForegroundColor, gzItemDesc, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+
+ /////////// DISPLAY CONDITION
+ ForegroundColor = 6;
+ SetFontShadow( DEFAULT_SHADOW );
+
+ // Note: for Ammo items, remaining bullets replace condition, so it's handled later on.
+ // For money, condition is irrelevant, and not displayed here.
+ if ( Item[ gpItemDescObject->usItem ].usItemClass != IC_AMMO && Item[ gpItemDescObject->usItem ].usItemClass != IC_MONEY )
+ {
+ ////////// label
+ if (UsingEDBSystem())
+ {
+ // UDB system displays a string with colored condition text.
+ SetFontForeground( ForegroundColor );
+ swprintf( pStr, L"%s", gConditionDesc[0] ); // "In "
+ mprintf( gItemDescTextRegions[1].sLeft, gItemDescTextRegions[1].sTop, pStr );
+ // Record length
+ INT16 indent = StringPixLength( gConditionDesc[0], ITEMDESC_FONT );
+
+ UINT8 ConditionColor = 0;
+ UINT8 ConditionStringNum = GetConditionString( status, &ConditionColor );
+ swprintf( pStr, L"%s", gConditionDesc[ConditionStringNum+1 ] );
+ SetFontForeground( ConditionColor );
+ mprintf( gItemDescTextRegions[1].sLeft+indent+2, gItemDescTextRegions[1].sTop, pStr );
+ // Record length
+ indent += StringPixLength( gConditionDesc[ConditionStringNum + 1], ITEMDESC_FONT );
+
+ SetFontForeground( ForegroundColor );
+ swprintf( pStr, L"%s", gConditionDesc[8] ); // " Condition."
+ mprintf( gItemDescTextRegions[1].sLeft + indent + 2, gItemDescTextRegions[1].sTop, pStr );
+ }
+ else
+ {
+ SetFontForeground( ForegroundColor );
+ swprintf( pStr, L"%s", gWeaponStatsDesc[ 0 ] );
+ mprintf( gODBItemDescRegions[0][0].sLeft, gODBItemDescRegions[0][0].sTop, pStr );
+ }
+
+ SetFontForeground( 5 );
+
+ // value
+ // This is gross, but to get the % to work out right...
+ swprintf( pStr, L"%2d%%", status);
+
+ if (UsingEDBSystem())
+ {
+ FindFontRightCoordinates( gItemDescTextRegions[1].sLeft, gItemDescTextRegions[1].sTop, gItemDescTextRegions[1].sRight - gItemDescTextRegions[1].sLeft, gItemDescTextRegions[1].sBottom - gItemDescTextRegions[1].sTop ,pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ FindFontRightCoordinates( gODBItemDescRegions[0][0].sLeft, gODBItemDescRegions[0][0].sTop, gODBItemDescRegions[0][0].sRight - gODBItemDescRegions[0][0].sLeft, gODBItemDescRegions[0][0].sBottom - gODBItemDescRegions[0][0].sTop ,pStr, BLOCKFONT2, &usX, &usY);
+ }
+
+ #ifdef CHINESE
+ wcscat( pStr, ChineseSpecString1 );
+ #else
+ wcscat( pStr, L"%%" );
+ #endif
+
+ mprintf( usX, usY, pStr );
+ }
+
+ /////////// DISPLAY WEIGHT
+ // Note: Money has no weight. Skip this.
+ if(Item[ gpItemDescObject->usItem ].usItemClass != IC_MONEY)
+ {
+ SetFontForeground( 6 );
+
+ // label
+ if (UsingEDBSystem())
+ {
+ mprintf( gItemDescTextRegions[2].sLeft, gItemDescTextRegions[2].sTop, gWeaponStatsDesc[1] );
+ }
+ else
+ {
+ mprintf( gODBItemDescRegions[1][0].sLeft, gODBItemDescRegions[1][0].sTop, gWeaponStatsDesc[1] );
+ }
+ // Calculate total weight of item and attachments
+ fWeight = gpItemDescObject->GetWeightOfObjectInStack(gubItemDescStatusIndex) / 10.0f;
+ if ( !gGameSettings.fOptions[ TOPTION_USE_METRIC_SYSTEM ] ) // metric units not enabled
+ {
+ fWeight = fWeight * 2.2f;
+ }
+ if ( fWeight < 0.1 && gubItemDescStatusIndex < gpItemDescObject->ubNumberOfObjects )
+ {
+ fWeight = 0.1f;
+ }
+ // Change value colors
+ if (fWeight <= (EXCEPTIONAL_WEIGHT / 10) && Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON )
+ {
+ SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
+ }
+ else
+ {
+ SetFontForeground( 5 );
+ }
+ //Print
+ swprintf( pStr, L"%1.1f %s", fWeight, GetWeightUnitString() );
+ if (UsingEDBSystem())
+ {
+ FindFontRightCoordinates( gItemDescTextRegions[2].sLeft, gItemDescTextRegions[2].sTop, gItemDescTextRegions[2].sRight - gItemDescTextRegions[2].sLeft ,gItemDescTextRegions[2].sBottom - gItemDescTextRegions[2].sTop ,pStr, BLOCKFONT2, &usX, &usY);
+ }
+ else
+ {
+ FindFontRightCoordinates( gODBItemDescRegions[1][0].sLeft, gODBItemDescRegions[1][0].sTop, gODBItemDescRegions[1][0].sRight - gODBItemDescRegions[1][0].sLeft ,gODBItemDescRegions[1][0].sBottom - gODBItemDescRegions[1][0].sTop ,pStr, BLOCKFONT2, &usX, &usY);
+ }
+ mprintf( usX, usY, pStr );
+ }
+
+ /////////// DISPLAY PROS/CONS (weapons and launchers only)
+
+ if ( ITEM_PROS_AND_CONS( gpItemDescObject->usItem ) )
+ {
+ SetFontForeground( FONT_MCOLOR_DKWHITE2 );
+ SetFontShadow( ITEMDESC_FONTSHADOW3 );
+ // PROs
+ mprintf( gItemDescTextRegions[3].sLeft, gItemDescTextRegions[3].sTop, gzProsLabel );
+
+ sProsConsIndent = __max( StringPixLength( gzProsLabel, ITEMDESC_FONT ), StringPixLength( gzConsLabel, ITEMDESC_FONT ) ) + 10;
+ gzItemPros[0] = 0;
+ GenerateProsString( gzItemPros, gpItemDescObject, (gItemDescTextRegions[4].sRight - gItemDescTextRegions[4].sLeft) - StringPixLength( DOTDOTDOT, ITEMDESC_FONT ) );
+ if (gzItemPros[0] != 0)
+ {
+ if (UsingEDBSystem())
+ {
+ ForegroundColor = 5;
+ SetFontShadow( DEFAULT_SHADOW );
+ }
+ else
+ {
+ ForegroundColor = FONT_MCOLOR_BLACK;
+ SetFontShadow( ITEMDESC_FONTSHADOW2 );
+ }
+
+ DisplayWrappedString( gItemDescTextRegions[4].sLeft, gItemDescTextRegions[4].sTop, (gItemDescTextRegions[4].sRight - gItemDescTextRegions[4].sLeft), 2, ITEMDESC_FONT, ForegroundColor, gzItemPros, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED );
+ }
+
+ SetFontForeground( FONT_MCOLOR_DKWHITE2 );
+ SetFontShadow( ITEMDESC_FONTSHADOW3 );
+ // CONs
+ mprintf( gItemDescTextRegions[5].sLeft, gItemDescTextRegions[5].sTop, gzConsLabel );
+
+ // HEADROCK: Disabled PROs/CONs text for OIV EDB Tactical
+
+ GenerateConsString( gzItemCons, gpItemDescObject, (gItemDescTextRegions[6].sRight - gItemDescTextRegions[6].sLeft) - StringPixLength( DOTDOTDOT, ITEMDESC_FONT ) );
+ if (gzItemCons[0] != 0)
+ {
+ if (UsingEDBSystem())
+ {
+ ForegroundColor = 5;
+ SetFontShadow( DEFAULT_SHADOW );
+ }
+ else
+ {
+ ForegroundColor = FONT_MCOLOR_BLACK;
+ SetFontShadow( ITEMDESC_FONTSHADOW2 );
+ }
+
+ DisplayWrappedString( gItemDescTextRegions[6].sLeft, gItemDescTextRegions[6].sTop, (gItemDescTextRegions[6].sRight - gItemDescTextRegions[6].sLeft), 2, ITEMDESC_FONT, ForegroundColor, gzItemCons, FONT_MCOLOR_BLACK, FALSE, LEFT_JUSTIFIED);
+ }
+ MSYS_EnableRegion( &(gProsAndConsRegions[ 0 ]) );
+ MSYS_EnableRegion( &(gProsAndConsRegions[ 1 ]) );
+ }
+ }
+ // HEADROCK HAM 4: If not displaying the UDB Description Page, disable the pros/cons rects.
+ else
+ {
+ MSYS_DisableRegion( &(gProsAndConsRegions[ 0 ]) );
+ MSYS_DisableRegion( &(gProsAndConsRegions[ 1 ]) );
+ }
+
+ // Render "normal" item data
+ SetFontShadow( DEFAULT_SHADOW );
//////////////////////////////////////////////////////////////////////////////
// DATA VALUES
@@ -4105,139 +4948,84 @@ void RenderItemDescriptionBox( )
// they are replaced by icons, which have already been blitted above.
//////////////////////////////////////////////////////////////////////////////
- // We begin by printing out data for ALL items, namely status and weight.
- SetFont( BLOCKFONT2 );
- SetFontForeground( 6 );
- SetFontShadow( DEFAULT_SHADOW );
-
- // For ammo, capacity replaces status. Money and Keys do not get a status display at all.
- if ( Item[ gpItemDescObject->usItem ].usItemClass != IC_AMMO && Item[ gpItemDescObject->usItem ].usItemClass != IC_MONEY )
- {
- // STATUS
- // label
- mprintf( gWeaponStats[ 0 ].sX + gsInvDescX, gWeaponStats[ 0 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 0 ] );
- SetFontForeground( 5 );
- // print value
- // This is gross, but to get the % to work out right...
- swprintf( pStr, L"%2d%%", status);
- if (UsingEDBSystem() == 2)
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 0 ].sX + gsInvDescX + gWeaponStats[ 0 ].sValDx), (INT16)(gWeaponStats[ 0 ].sY + gsInvDescY + 12 ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- else
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 0 ].sX + gsInvDescX + gWeaponStats[ 0 ].sValDx), (INT16)(gWeaponStats[ 0 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
-
- #ifdef CHINESE
- wcscat( pStr, ChineseSpecString1 );
- #else
- wcscat( pStr, L"%%" );
- #endif
-
- mprintf( usX, usY, pStr );
- }
-
- if(Item[ gpItemDescObject->usItem ].usItemClass != IC_MONEY)
- {
- // WEIGHT
- SetFontForeground( 6 );
- swprintf( sTempString, gWeaponStatsDesc[ 1 ], GetWeightUnitString() );
- mprintf( gWeaponStats[ 1 ].sX + gsInvDescX, gWeaponStats[ 1 ].sY + gsInvDescY, L"%s", sTempString );
-
- // Calculate total weight of item and attachments
- fWeight = gpItemDescObject->GetWeightOfObjectInStack(gubItemDescStatusIndex) / 10.0f;
- if ( !gGameSettings.fOptions[ TOPTION_USE_METRIC_SYSTEM ] ) // metric units not enabled
- {
- fWeight = fWeight * 2.2f;
- }
- if ( fWeight < 0.1 && gubItemDescStatusIndex < gpItemDescObject->ubNumberOfObjects )
- {
- fWeight = 0.1f;
- }
- // Values
- if (fWeight <= (EXCEPTIONAL_WEIGHT / 10) && Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON )
- {
- SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
- }
- else
- {
- SetFontForeground( 5 );
- }
- //Weight
- swprintf( pStr, L"%1.1f", fWeight );
- if (UsingEDBSystem() == 2)
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 1 ].sX + gsInvDescX + gWeaponStats[ 1 ].sValDx), (INT16)(gWeaponStats[ 1 ].sY + gsInvDescY + 12 ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- else
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 1 ].sX + gsInvDescX + gWeaponStats[ 1 ].sValDx), (INT16)(gWeaponStats[ 1 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- }
-
/////////////////////////////////////////
// BEGIN WEAPONS-SPECIFIC CHARACTERISTICS
/////////////////////////////////////////
if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_WEAPON || Item[ gpItemDescObject->usItem ].usItemClass & IC_PUNCH )
{
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
- {
- // RANGE
- SetFontForeground( 6 );
- if(UsingEDBSystem() > 0)
- mprintf( gWeaponStats[ 23 ].sX + gsInvDescX, gWeaponStats[ 23 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
- else
- mprintf( gWeaponStats[ 2 ].sX + gsInvDescX, gWeaponStats[ 2 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 3 ] );
-
- if ( GunRange( gpItemDescObject ) >= EXCEPTIONAL_RANGE)
- {
- SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
- }
- else
- {
- SetFontForeground( 5 );
- }
- swprintf( pStr, L"%2d", ( GunRange( gpItemDescObject ) ) / 10 );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 2 ].sX + gsInvDescX + gWeaponStats[ 2 ].sValDx), (INT16)(gWeaponStats[ 2 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- }
- if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
- {
- // DAMAGE
- SetFontForeground( 6 );
- if(UsingEDBSystem() > 0)
- mprintf( gWeaponStats[ 24 ].sX + gsInvDescX, gWeaponStats[ 24 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
- else
- mprintf( gWeaponStats[ 3 ].sX + gsInvDescX, gWeaponStats[ 3 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 4 ] );
-
- UINT8 ubImpact = GetDamage(gpItemDescObject);
-
- if ( ubImpact >= EXCEPTIONAL_DAMAGE)
- {
- SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
- }
- else
- {
- SetFontForeground( 5 );
- }
-
- //Damage
- swprintf( pStr, L"%2d", ubImpact );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 3 ].sX + gsInvDescX + gWeaponStats[ 3 ].sValDx), (INT16)(gWeaponStats[ 3 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
- }
-
if(UsingEDBSystem() > 0)
+ {
+ SetFontShadow( ITEMDESC_FONTSHADOW3 );
DrawWeaponValues(gpItemDescObject);
+ }
else
{
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER|IC_THROWING_KNIFE) )
+ {
+ // RANGE
+ SetFontForeground( 6 );
+ mprintf( gODBItemDescRegions[2][4].sLeft, gODBItemDescRegions[2][4].sTop, L"%s", gWeaponStatsDesc[ 3 ] );
+
+ if ( GunRange( gpItemDescObject, NULL ) >= EXCEPTIONAL_RANGE)
+ {
+ SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
+ }
+ else
+ {
+ SetFontForeground( 5 );
+ }
+ swprintf( pStr, L"%2d", ( GunRange( gpItemDescObject, NULL ) ) / 10 );
+ FindFontRightCoordinates( gODBItemDescRegions[2][7].sLeft, gODBItemDescRegions[2][7].sTop, gODBItemDescRegions[2][7].sRight - gODBItemDescRegions[2][7].sLeft, gODBItemDescRegions[2][7].sBottom - gODBItemDescRegions[2][7].sTop ,pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+ if ( Item[ gpItemDescObject->usItem ].usItemClass & (IC_GUN|IC_PUNCH|IC_BLADE|IC_THROWING_KNIFE) && !Item[ gpItemDescObject->usItem ].singleshotrocketlauncher )
+ {
+ // DAMAGE
+ SetFontForeground( 6 );
+ mprintf( gODBItemDescRegions[2][0].sLeft, gODBItemDescRegions[2][0].sTop, L"%s", gWeaponStatsDesc[ 4 ] );
+
+ UINT8 ubImpact = GetDamage(gpItemDescObject);
+
+ UINT16 exceptionalDamage;
+ // Melee damage
+ if ( Item[gpItemDescObject->usItem].usItemClass == IC_BLADE || Item[gpItemDescObject->usItem].usItemClass == IC_PUNCH || Item[gpItemDescObject->usItem].usItemClass == IC_TENTACLES )
+ {
+ exceptionalDamage = (UINT16)(( EXCEPTIONAL_MELEE_DAMAGE * gGameExternalOptions.iMeleeDamageModifier ) / 100);
+ }
+ // Gun damage
+ else
+ {
+ exceptionalDamage = (UINT16)(( EXCEPTIONAL_GUN_DAMAGE * gGameExternalOptions.iGunDamageModifier ) / 100);
+ }
+
+ if ( ubImpact >= exceptionalDamage)
+ {
+ SetFontForeground( ITEMDESC_FONTHIGHLIGHT );
+ }
+ else
+ {
+ SetFontForeground( 5 );
+ }
+
+ //Damage
+ swprintf( pStr, L"%2d", ubImpact );
+ FindFontRightCoordinates( gODBItemDescRegions[2][3].sLeft, gODBItemDescRegions[2][3].sTop, gODBItemDescRegions[2][3].sRight - gODBItemDescRegions[2][3].sLeft, gODBItemDescRegions[2][3].sBottom - gODBItemDescRegions[2][3].sTop ,pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+ }
+
//LABELS
SetFontForeground( 6 );
- mprintf( gWeaponStats[ 5 ].sX + gsInvDescX, gWeaponStats[ 5 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 6 ] );
+ mprintf( gODBItemDescRegions[3][0].sLeft, gODBItemDescRegions[3][0].sTop, L"%s", gWeaponStatsDesc[ 6 ] );
if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_GUN || Item[ gpItemDescObject->usItem ].usItemClass & IC_LAUNCHER)
{
// equals sign
if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
- mprintf( gWeaponStats[ 7 ].sX + gsInvDescX, gWeaponStats[ 7 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 7 ] );
+ mprintf( gODBItemDescRegions[3][2].sLeft, gODBItemDescRegions[3][2].sTop, L"%s", gWeaponStatsDesc[ 7 ] );
}
if (GetShotsPerBurst(gpItemDescObject) > 0 || GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0 )
{
- mprintf( gWeaponStats[ 8 ].sX + gsInvDescX, gWeaponStats[ 8 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 8 ] );
+ mprintf( gODBItemDescRegions[3][6].sLeft, gODBItemDescRegions[3][6].sTop, L"%s", gWeaponStatsDesc[ 8 ] );
}
ubAttackAPs = BaseAPsToShootOrStab( APBPConstants[DEFAULT_APS], APBPConstants[DEFAULT_AIMSKILL], gpItemDescObject );
@@ -4258,7 +5046,7 @@ void RenderItemDescriptionBox( )
if ( !Weapon[gpItemDescObject->usItem].NoSemiAuto )
{
swprintf( pStr, L"%2d", ubAttackAPs );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 5 ].sX + gsInvDescX + gWeaponStats[ 5 ].sValDx), (INT16)(gWeaponStats[ 5 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ FindFontRightCoordinates( gODBItemDescRegions[3][3].sLeft, gODBItemDescRegions[3][3].sTop, gODBItemDescRegions[3][3].sRight - gODBItemDescRegions[3][3].sLeft, gODBItemDescRegions[3][3].sBottom - gODBItemDescRegions[3][3].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
@@ -4273,14 +5061,14 @@ void RenderItemDescriptionBox( )
SetFontForeground( 5 );
}
swprintf( pStr, L"%2d", ubAttackAPs + CalcAPsToBurst( APBPConstants[DEFAULT_APS], gpItemDescObject ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 6 ].sX + gsInvDescX + gWeaponStats[ 6 ].sValDx), (INT16)(gWeaponStats[ 6 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ FindFontRightCoordinates( gODBItemDescRegions[3][7].sLeft, gODBItemDescRegions[3][7].sTop, gODBItemDescRegions[3][7].sRight - gODBItemDescRegions[3][7].sLeft, gODBItemDescRegions[3][7].sBottom - gODBItemDescRegions[3][7].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
else if (GetAutofireShotsPerFiveAPs(gpItemDescObject) > 0)
{
SetFontForeground( 5 );
swprintf( pStr, L"%2d", ubAttackAPs + CalcAPsToAutofire( APBPConstants[DEFAULT_APS], gpItemDescObject, 3 ) );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 6 ].sX + gsInvDescX + gWeaponStats[ 6 ].sValDx), (INT16)(gWeaponStats[ 6 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ FindFontRightCoordinates( gODBItemDescRegions[3][7].sLeft, gODBItemDescRegions[3][7].sTop, gODBItemDescRegions[3][7].sRight - gODBItemDescRegions[3][7].sLeft, gODBItemDescRegions[3][7].sBottom - gODBItemDescRegions[3][7].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
}
@@ -4293,74 +5081,88 @@ void RenderItemDescriptionBox( )
}
else if ( gpItemDescObject->usItem == MONEY )
{
- //Labels
- SetFont( BLOCKFONT2 );
- SetFontShadow( DEFAULT_SHADOW );
- SetFontForeground( 6 );
-
- //Display the 'Seperate text'
- if( gfAddingMoneyToMercFromPlayersAccount )
- mprintf( (UINT16)(gMoneyButtonLoc.x + gMoneyButtonOffsets[4].x), (UINT16)(gMoneyButtonLoc.y + gMoneyButtonOffsets[4].y), gzMoneyAmounts[5] );
- else
- mprintf( (UINT16)(gMoneyButtonLoc.x + gMoneyButtonOffsets[4].x), (UINT16)(gMoneyButtonLoc.y + gMoneyButtonOffsets[4].y ), gzMoneyAmounts[4] );
-
- //if the player is removing money from the players account
- if( gfAddingMoneyToMercFromPlayersAccount )
+ if ((UsingEDBSystem() && gubDescBoxPage == 0) || !UsingEDBSystem())
{
- //Display the 'Removing'
- mprintf( gMoneyStats[ 0 ].sX + gsInvDescX, gMoneyStats[ 0 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_PLAYERS ] );
- //Display the 'REmaining'
- mprintf( gMoneyStats[ 2 ].sX + gsInvDescX, gMoneyStats[ 2 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_AMOUNT_2_WITHDRAW ] );
+ for (INT8 x = 0; x < 4; x++)
+ {
+ EnableButton(guiMoneyButtonBtn[ x ]);
+ }
+ //Labels
+ SetFont( BLOCKFONT2 );
+ SetFontShadow( DEFAULT_SHADOW );
+ SetFontForeground( 6 );
+
+ //Display the 'Seperate text'
+ if( gfAddingMoneyToMercFromPlayersAccount )
+ mprintf( (UINT16)(gMoneyButtonLoc.x + gMoneyButtonOffsets[4].x), (UINT16)(gMoneyButtonLoc.y + gMoneyButtonOffsets[4].y), gzMoneyAmounts[5] );
+ else
+ mprintf( (UINT16)(gMoneyButtonLoc.x + gMoneyButtonOffsets[4].x), (UINT16)(gMoneyButtonLoc.y + gMoneyButtonOffsets[4].y ), gzMoneyAmounts[4] );
+
+ //if the player is removing money from the players account
+ if( gfAddingMoneyToMercFromPlayersAccount )
+ {
+ //Display the 'Removing'
+ mprintf( gMoneyStats[ 0 ].sX, gMoneyStats[ 0 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_PLAYERS ] );
+ //Display the 'REmaining'
+ mprintf( gMoneyStats[ 2 ].sX, gMoneyStats[ 2 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_AMOUNT_2_WITHDRAW ] );
+ }
+ else
+ {
+ //Display the 'Removing'
+ mprintf( gMoneyStats[ 0 ].sX, gMoneyStats[ 0 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_AMOUNT ] );
+ //Display the 'REmaining'
+ mprintf( gMoneyStats[ 2 ].sX, gMoneyStats[ 2 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_AMOUNT_2_SPLIT ] );
+ }
+
+ // if the player is taking money from their account
+ if( gfAddingMoneyToMercFromPlayersAccount )
+ {
+ //Display the 'Amt removing'
+ mprintf( gMoneyStats[ 1 ].sX, gMoneyStats[ 1 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_BALANCE ] );
+ //Display the 'REmaining amount'
+ mprintf( gMoneyStats[ 3 ].sX, gMoneyStats[ 3 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_TO_WITHDRAW ] );
+ }
+ else
+ {
+ //Display the 'Amt removing'
+ mprintf( gMoneyStats[ 1 ].sX, gMoneyStats[ 1 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_REMAINING ] );
+ //Display the 'REmaining amount'
+ mprintf( gMoneyStats[ 3 ].sX, gMoneyStats[ 3 ].sY, L"%s", gMoneyStatsDesc[ MONEY_DESC_TO_SPLIT ] );
+ }
+
+ //Display the total amount of money remaining
+ SetFontForeground( 5 );
+ swprintf( pStr, L"%ld", gRemoveMoney.uiMoneyRemaining );
+ InsertCommasForDollarFigure( pStr );
+ InsertDollarSignInToString( pStr );
+ FindFontRightCoordinates( gMoneyStats[ 4 ].sX, gMoneyStats[ 4 ].sY, ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
+
+ //Display the total amount of money removing
+ SetFontForeground( 5 );
+ swprintf( pStr, L"%ld", gRemoveMoney.uiMoneyRemoving );
+ InsertCommasForDollarFigure( pStr );
+ InsertDollarSignInToString( pStr );
+ FindFontRightCoordinates( gMoneyStats[ 5 ].sX, gMoneyStats[ 5 ].sY, ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ mprintf( usX, usY, pStr );
}
else
{
- //Display the 'Removing'
- mprintf( gMoneyStats[ 0 ].sX + gsInvDescX, gMoneyStats[ 0 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_AMOUNT ] );
- //Display the 'REmaining'
- mprintf( gMoneyStats[ 2 ].sX + gsInvDescX, gMoneyStats[ 2 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_AMOUNT_2_SPLIT ] );
- }
+ for (INT8 x = 0; x < 4; x++)
+ {
+ DisableButton(guiMoneyButtonBtn[ x ]);
+ //Labels
+ SetFont( BLOCKFONT2 );
+ SetFontShadow( DEFAULT_SHADOW );
+ SetFontForeground( FONT_GRAY6 );
- // if the player is taking money from their account
- if( gfAddingMoneyToMercFromPlayersAccount )
- {
- //Display the 'Amt removing'
- mprintf( gMoneyStats[ 1 ].sX + gsInvDescX, gMoneyStats[ 1 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_BALANCE ] );
- //Display the 'REmaining amount'
- mprintf( gMoneyStats[ 3 ].sX + gsInvDescX, gMoneyStats[ 3 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_TO_WITHDRAW ] );
+ //Display the 'Seperate text'
+ if( gfAddingMoneyToMercFromPlayersAccount )
+ mprintf( (UINT16)(gMoneyButtonLoc.x + gMoneyButtonOffsets[4].x), (UINT16)(gMoneyButtonLoc.y + gMoneyButtonOffsets[4].y), gzMoneyAmounts[5] );
+ else
+ mprintf( (UINT16)(gMoneyButtonLoc.x + gMoneyButtonOffsets[4].x), (UINT16)(gMoneyButtonLoc.y + gMoneyButtonOffsets[4].y ), gzMoneyAmounts[4] );
+ }
}
- else
- {
- //Display the 'Amt removing'
- mprintf( gMoneyStats[ 1 ].sX + gsInvDescX, gMoneyStats[ 1 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_REMAINING ] );
- //Display the 'REmaining amount'
- mprintf( gMoneyStats[ 3 ].sX + gsInvDescX, gMoneyStats[ 3 ].sY + gsInvDescY, L"%s", gMoneyStatsDesc[ MONEY_DESC_TO_SPLIT ] );
- }
-
- //Display the total amount of money remaining
- SetFontForeground( 5 );
- swprintf( pStr, L"%ld", gRemoveMoney.uiMoneyRemaining );
- InsertCommasForDollarFigure( pStr );
- InsertDollarSignInToString( pStr );
- if( guiCurrentItemDescriptionScreen != MAP_SCREEN )
- FindFontRightCoordinates( (INT16)(gMoneyStats[ 1 ].sX + gsInvDescX + gMoneyStats[ 1 ].sValDx), (INT16)(gMoneyStats[ 1 ].sY + gsInvDescY ), (UINT16)(ITEM_STATS_WIDTH-3) ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- else if(UsingEDBSystem() > 0)
- FindFontRightCoordinates( (INT16)(gMoneyStats[ 4 ].sX + gsInvDescX + gMoneyStats[ 4 ].sValDx), (INT16)(gMoneyStats[ 4 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- else
- FindFontRightCoordinates( (INT16)(gMoneyStats[ 1 ].sX + gsInvDescX + gMoneyStats[ 1 ].sValDx), (INT16)(gMoneyStats[ 1 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
-
- //Display the total amount of money removing
- SetFontForeground( 5 );
- swprintf( pStr, L"%ld", gRemoveMoney.uiMoneyRemoving );
- InsertCommasForDollarFigure( pStr );
- InsertDollarSignInToString( pStr );
- if( guiCurrentItemDescriptionScreen != MAP_SCREEN )
- FindFontRightCoordinates( (INT16)(gMoneyStats[ 3 ].sX + gsInvDescX + gMoneyStats[ 3 ].sValDx), (INT16)(gMoneyStats[ 3 ].sY + gsInvDescY), (UINT16)(ITEM_STATS_WIDTH-3) ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- else if(UsingEDBSystem() > 0)
- FindFontRightCoordinates( (INT16)(gMoneyStats[ 5 ].sX + gsInvDescX + gMoneyStats[ 5 ].sValDx), (INT16)(gMoneyStats[ 5 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- else
- FindFontRightCoordinates( (INT16)(gMoneyStats[ 3 ].sX + gsInvDescX + gMoneyStats[ 3 ].sValDx), (INT16)(gMoneyStats[ 3 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
- mprintf( usX, usY, pStr );
}
else if ( Item[ gpItemDescObject->usItem ].usItemClass == IC_MONEY )
{
@@ -4380,76 +5182,48 @@ void RenderItemDescriptionBox( )
else if ( ( InKeyRingPopup() == TRUE ) || ( Item[ gpItemDescObject->usItem ].usItemClass & IC_KEY ) )
{
SetFontForeground( 6 );
+ SetFontShadow( DEFAULT_SHADOW );
- if(UsingEDBSystem() > 0)
+ if(UsingEDBSystem() > 0 && gubDescBoxPage == 0)
{
// build description for keys .. the sector found
swprintf( pStr, L"%s", sKeyDescriptionStrings[ 0 ] );
- mprintf( gWeaponStats[ 2 ].sX + gsInvDescX, gWeaponStats[ 2 ].sY + gsInvDescY, pStr );
+ mprintf( gItemDescTextRegions[3].sLeft, gItemDescTextRegions[3].sTop, pStr );
swprintf( pStr, L"%s", sKeyDescriptionStrings[ 1 ] );
- if (UsingEDBSystem() == 1)
- mprintf( gWeaponStats[ 5 ].sX + gsInvDescX, gWeaponStats[ 5 ].sY + gsInvDescY, pStr );
- else if (UsingEDBSystem() == 2)
- mprintf( gWeaponStats[ 6 ].sX + gsInvDescX, gWeaponStats[ 6 ].sY + gsInvDescY, pStr );
+ mprintf( gItemDescTextRegions[5].sLeft, gItemDescTextRegions[5].sTop, pStr );
}
- else
+ else if(UsingEDBSystem() == 0)
{
// build description for keys .. the sector found
swprintf( pStr, L"%s", sKeyDescriptionStrings[ 0 ] );
- mprintf( gWeaponStats[ 3 ].sX + gsInvDescX, gWeaponStats[ 3 ].sY + gsInvDescY, pStr );
+ mprintf( gODBItemDescRegions[2][0].sLeft, gODBItemDescRegions[2][0].sTop, pStr );
swprintf( pStr, L"%s", sKeyDescriptionStrings[ 1 ] );
- mprintf( gWeaponStats[ 5 ].sX + gsInvDescX, gWeaponStats[ 5 ].sY + gsInvDescY , pStr );
+ mprintf( gODBItemDescRegions[3][0].sLeft, gODBItemDescRegions[3][0].sTop, pStr );
}
SetFontForeground( 5 );
GetShortSectorString( ( INT16 ) SECTORX( KeyTable[ (*gpItemDescObject)[gubItemDescStatusIndex]->data.key.ubKeyID ].usSectorFound ), ( INT16 ) SECTORY( KeyTable[ (*gpItemDescObject)[gubItemDescStatusIndex]->data.key.ubKeyID ].usSectorFound ), sTempString );
swprintf( pStr, L"%s", sTempString );
- if(UsingEDBSystem() > 0)
+ if(UsingEDBSystem() > 0 && gubDescBoxPage == 0)
{
- if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
- {
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ 15 ].sX + gsInvDescX + gMiscItemStatsEDB[ 15 ].sValDx), (INT16)(gMiscItemStatsEDB[ 15 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ 15 ].sY + gsInvDescY, pStr );
- }
- else if (UsingEDBSystem() == 1)
- {
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ 12 ].sX + gsInvDescX + gMiscItemStatsEDB[ 12 ].sValDx), (INT16)(gMiscItemStatsEDB[ 12 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ 12 ].sY + gsInvDescY, pStr );
- }
- else if (UsingEDBSystem() == 2)
- {
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ 13 ].sX + gsInvDescX + gMiscItemStatsEDB[ 13 ].sValDx), (INT16)(gMiscItemStatsEDB[ 13 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ 13 ].sY + gsInvDescY, pStr );
- }
+ FindFontRightCoordinates( gItemDescTextRegions[4].sLeft, gItemDescTextRegions[4].sTop, gItemDescTextRegions[4].sRight - gItemDescTextRegions[4].sLeft ,gItemDescTextRegions[4].sBottom - gItemDescTextRegions[4].sTop ,pStr, BLOCKFONT2, &sStrX, &usY);
+ mprintf( sStrX, usY, pStr );
}
- else
+ else if (UsingEDBSystem() == 0)
{
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 3 ].sX + gsInvDescX ), (INT16)(gWeaponStats[ 3 ].sY + gsInvDescY ), 110 ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ FindFontRightCoordinates( gODBItemDescRegions[2][7].sLeft, gODBItemDescRegions[2][7].sTop, gODBItemDescRegions[2][7].sRight - gODBItemDescRegions[2][7].sLeft ,gODBItemDescRegions[2][7].sBottom - gODBItemDescRegions[2][7].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
swprintf( pStr, L"%d", KeyTable[ (*gpItemDescObject)[gubItemDescStatusIndex]->data.key.ubKeyID ].usDateFound );
- if(UsingEDBSystem() > 0)
+ if(UsingEDBSystem() > 0 && gubDescBoxPage == 0)
{
- if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
- {
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ 18 ].sX + gsInvDescX + gMiscItemStatsEDB[ 18 ].sValDx), (INT16)(gMiscItemStatsEDB[ 18 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ 18 ].sY + gsInvDescY, pStr );
- }
- else if (UsingEDBSystem() == 1)
- {
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ 15 ].sX + gsInvDescX + gMiscItemStatsEDB[ 15 ].sValDx), (INT16)(gMiscItemStatsEDB[ 13 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ 15 ].sY + gsInvDescY, pStr );
- }
- else if (UsingEDBSystem() == 2)
- {
- FindFontRightCoordinates( (INT16)(gMiscItemStatsEDB[ 17 ].sX + gsInvDescX + gMiscItemStatsEDB[ 17 ].sValDx), (INT16)(gMiscItemStatsEDB[ 17 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gMiscItemStatsEDB[ 17 ].sY + gsInvDescY, pStr );
- }
+ FindFontRightCoordinates( gItemDescTextRegions[6].sLeft, gItemDescTextRegions[6].sTop, gItemDescTextRegions[6].sRight - gItemDescTextRegions[6].sLeft ,gItemDescTextRegions[6].sBottom - gItemDescTextRegions[6].sTop ,pStr, BLOCKFONT2, &sStrX, &usY);
+ mprintf( sStrX, usY, pStr );
}
- else
+ else if (UsingEDBSystem() == 0)
{
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 5 ].sX + gsInvDescX ), (INT16)(gWeaponStats[ 5 ].sY + gsInvDescY ), 110 ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &usX, &usY);
+ FindFontRightCoordinates( gODBItemDescRegions[3][7].sLeft, gODBItemDescRegions[3][7].sTop, gODBItemDescRegions[3][7].sRight - gODBItemDescRegions[3][7].sLeft ,gODBItemDescRegions[3][7].sBottom - gODBItemDescRegions[3][7].sTop ,pStr, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY, pStr );
}
}
@@ -4466,7 +5240,7 @@ void RenderItemDescriptionBox( )
DrawAmmoValues(gpItemDescObject,shotsLeft);
else
{
- mprintf( gWeaponStats[ 0 ].sX + gsInvDescX, gWeaponStats[ 0 ].sY + gsInvDescY, L"%s", gWeaponStatsDesc[ 5 ] );
+ mprintf( gODBItemDescRegions[0][0].sLeft, gODBItemDescRegions[0][0].sTop, L"%s", gWeaponStatsDesc[ 5 ] );
// Values
SetFontForeground( 5 );
@@ -4474,8 +5248,8 @@ void RenderItemDescriptionBox( )
// Ammo
swprintf( pStr, L"%d/%d", shotsLeft, Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex ].ubMagSize ); //Pulmu: Correct # of rounds for stacked ammo.
uiStringLength=StringPixLength(pStr, ITEMDESC_FONT );
- FindFontRightCoordinates( (INT16)(gWeaponStats[ 0 ].sX + gsInvDescX + gWeaponStats[ 0 ].sValDx+6), (INT16)(gWeaponStats[ 0 ].sY + gsInvDescY ), ITEM_STATS_WIDTH ,ITEM_STATS_HEIGHT ,pStr, BLOCKFONT2, &sStrX, &usY);
- mprintf( sStrX, gWeaponStats[ 0 ].sY + gsInvDescY, pStr );
+ FindFontRightCoordinates( gODBItemDescRegions[0][0].sLeft, gODBItemDescRegions[0][0].sTop, gODBItemDescRegions[0][0].sRight - gODBItemDescRegions[0][0].sLeft ,gODBItemDescRegions[0][0].sBottom - gODBItemDescRegions[0][0].sTop ,pStr, BLOCKFONT2, &sStrX, &usY);
+ mprintf( sStrX, usY, pStr );
}
}
else if ( Item[ gpItemDescObject->usItem ].usItemClass & IC_EXPLOSV )
@@ -4698,12 +5472,28 @@ void DeleteItemDescriptionBox( )
UINT8 ubAPCost = 0;
// check for change in attachments
- unsigned int originalSize = gOriginalAttachments.size();
- unsigned int newSize = (*gpItemDescObject)[0]->attachments.size();
+ //unsigned int originalSize = gOriginalAttachments.size();
+ //unsigned int newSize = (*gpItemDescObject)[0]->attachments.size();
+
+ //WarmSteel size() is no longer sufficient, because the list contains null objects.
+ unsigned int originalSize = 0;
+ unsigned int newSize = 0;
+ attachmentList::iterator originalIter;
+ attachmentList::iterator newIter;
+
+ for (originalIter = gOriginalAttachments.begin(), newIter = (*gpItemDescObject)[0]->attachments.begin();
+ originalIter != gOriginalAttachments.end() && newIter != (*gpItemDescObject)[0]->attachments.end();
+ ++originalIter, ++newIter){
+ if(originalIter->exists()){
+ originalSize++;
+ }
+ if(newIter->exists()){
+ newSize++;
+ }
+ }
+
if (newSize != originalSize) {
- attachmentList::iterator originalIter;
- attachmentList::iterator newIter;
//an attachment was changed, find the change
for (originalIter = gOriginalAttachments.begin(), newIter = (*gpItemDescObject)[0]->attachments.begin();
originalIter != gOriginalAttachments.end() && newIter != (*gpItemDescObject)[0]->attachments.end();
@@ -4717,7 +5507,7 @@ void DeleteItemDescriptionBox( )
}
if (newSize < originalSize) {
//an attachment was removed, charge APs
- ubAPCost = AttachmentAPCost(originalIter->usItem,gpItemDescObject->usItem);
+ ubAPCost = AttachmentAPCost(originalIter->usItem,gpItemDescObject, gpAttachSoldier ); // SANDRO - added argument
}
else {
//an attachment was added charge APs
@@ -4728,7 +5518,7 @@ void DeleteItemDescriptionBox( )
}
else
{
- ubAPCost = AttachmentAPCost(newIter->usItem,gpItemDescObject->usItem);
+ ubAPCost = AttachmentAPCost(newIter->usItem,gpItemDescObject, gpAttachSoldier); // SANDRO - added argument
}
}
}
@@ -4744,7 +5534,10 @@ void DeleteItemDescriptionBox( )
DeleteVideoObjectFromIndex( guiItemDescBox );
if(UsingNewInventorySystem() == true && guiItemDescBoxBackground != 0)
DeleteVideoObjectFromIndex( guiItemDescBoxBackground );
+ if(UsingNewInventorySystem() == true && guiItemInfoLBEBackground != 0)
+ DeleteVideoObjectFromIndex( guiItemInfoLBEBackground );
DeleteVideoObjectFromIndex( guiMapItemDescBox );
+ DeleteVideoObjectFromIndex( guiAttachmentSlot );
RenderBackpackButtons(0); /* CHRISL: Needed for new inventory backpack buttons */
DeleteVideoObjectFromIndex( guiBullet );
DeleteEnhancedDescBox( guiCurrentItemDescriptionScreen );
@@ -4760,22 +5553,75 @@ void DeleteItemDescriptionBox( )
RemoveButton( giMapInvDescButton );
}
+ // HEADROCK HAM 4: Remove TAB buttons for UDB
+ if (UsingEDBSystem() > 0)
+ {
+ if( guiCurrentItemDescriptionScreen == MAP_SCREEN )
+ {
+ UnloadButtonImage( giMapInvDescTabButtonImage );
+ }
+ else
+ {
+ UnloadButtonImage( giInvDescTabButtonImage );
+ }
+ for (cnt = 0; cnt < 3; cnt++)
+ {
+ RemoveButton( giInvDescTabButton[cnt] );
+ }
+ }
+
+ // HEADROCK HAM 4: Remove ADVANCED buttons for UDB
+ if (UsingEDBSystem() > 0)
+ {
+ UnloadButtonImage( giInvDescAdvButtonUpImage );
+ UnloadButtonImage( giInvDescAdvButtonDownImage );
+ for (cnt = 0; cnt < 2; cnt++)
+ {
+ if ( giInvDescAdvButton[cnt] != -1 )
+ {
+ RemoveButton( giInvDescAdvButton[cnt] );
+ }
+ }
+ }
+
// Remove region
MSYS_RemoveRegion( &gInvDesc);
if( gpItemDescObject->usItem != MONEY )
{
- for ( cnt = 0; cnt < MAX_ATTACHMENTS; cnt++ )
+ if (UsingNewAttachmentSystem()==true)
{
- MSYS_RemoveRegion( &gItemDescAttachmentRegions[cnt]);
+ // WANNE: Bugfix: Fixed CTD when closing sector inventory in strategy screen with open item description
+ if (gpItemDescObject[0].objectStack.size() == 0)
+ {
+ for ( cnt = 0; cnt < MAX_ATTACHMENTS; cnt++)
+ {
+ MSYS_RemoveRegion( &gItemDescAttachmentRegions[cnt]);
+ }
+ }
+ else
+ {
+ for ( cnt = 0; cnt < (INT32)(*gpItemDescObject)[0]->attachments.size(); cnt++ )
+ {
+ MSYS_RemoveRegion( &gItemDescAttachmentRegions[cnt]);
+ }
+ }
+ }
+ else
+ {
+ // WANNE: Bugfix: Attachment regions were not removed when playing without NAS and when closing the description box
+ for (cnt = 0; cnt < OLD_MAX_ATTACHMENTS_101; cnt++)
+ {
+ MSYS_RemoveRegion( &gItemDescAttachmentRegions[cnt]);
+ }
}
}
else
{
UnloadButtonImage( guiMoneyButtonImage );
UnloadButtonImage( guiMoneyDoneButtonImage );
- for ( cnt = 0; cnt < MAX_ATTACHMENTS; cnt++ )
+ for ( cnt = 0; cnt < OLD_MAX_ATTACHMENTS_101; cnt++ )
{
RemoveButton( guiMoneyButtonBtn[cnt] );
}
@@ -4830,6 +5676,8 @@ void DeleteItemDescriptionBox( )
gfItemDescObjectIsAttachment = FALSE;
gpItemDescObject = NULL;
+ gpItemDescPrevObject = NULL;
+
}
@@ -5052,6 +5900,10 @@ void DrawItemTileCursor( )
if (GetMouseMapPos( &usMapPos) )
{
+ /*CHRISL: For some reason it's possible that gpItemPointerSoldier is not correctly set when we come into this function, but we require it to be set for
+ this function to work. So for now, let's set it using gusUIFullTargetID.*/
+ if(gpItemPointerSoldier->exists() == false)
+ gpItemPointerSoldier = MercPtrs[ gusUIFullTargetID ];
if ( gfUIFullTargetFound )
{
// Force mouse position to guy...
@@ -5104,7 +5956,6 @@ void DrawItemTileCursor( )
// Get Pyth spaces away.....
sDist = PythSpacesAway( gpItemPointerSoldier->sGridNo, gusCurMousePos );
-
// If we are here and we are not selected, select!
// ATE Design discussion propably needed here...
if ( gpItemPointerSoldier->ubID != gusSelectedSoldier )
@@ -5164,7 +6015,7 @@ void DrawItemTileCursor( )
// If we are tossing...
if ( sDist <= 1 && gfUIMouseOnValidCatcher == 0 || gfUIMouseOnValidCatcher == 4 )
{
- gsCurrentActionPoints = APBPConstants[AP_PICKUP_ITEM];
+ gsCurrentActionPoints = GetBasicAPsToPickupItem( gpItemPointerSoldier );
}
else
{
@@ -5403,7 +6254,7 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
// Check if we have APs....
if ( !EnoughPoints( gpItemPointerSoldier, gsCurrentActionPoints, 0, TRUE ) )
{
- if ( gfDontChargeAPsToPickup && gsCurrentActionPoints == APBPConstants[AP_PICKUP_ITEM] )
+ if ( gfDontChargeAPsToPickup && gsCurrentActionPoints == GetBasicAPsToPickupItem( gpItemPointerSoldier ) )
{
}
@@ -5540,7 +6391,9 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
EndItemPointer( );
// If we are giving it to somebody not on our team....
- if ( MercPtrs[ ubSoldierID ]->ubProfile < FIRST_RPC || MercPtrs[ubSoldierID]->ubProfile >= GASTON || RPC_RECRUITED( MercPtrs[ ubSoldierID ] ) )
+ //if ( MercPtrs[ ubSoldierID ]->ubProfile < FIRST_RPC || MercPtrs[ubSoldierID]->ubProfile >= GASTON || RPC_RECRUITED( MercPtrs[ ubSoldierID ] ) )
+ //new profiles by Jazz
+ if ( gProfilesIMP[MercPtrs[ ubSoldierID ]->ubProfile].ProfilId == MercPtrs[ ubSoldierID ]->ubProfile || gProfilesAIM[MercPtrs[ ubSoldierID ]->ubProfile].ProfilId == MercPtrs[ ubSoldierID ]->ubProfile || gProfilesMERC[MercPtrs[ ubSoldierID ]->ubProfile].ProfilId == MercPtrs[ ubSoldierID ]->ubProfile || RPC_RECRUITED( MercPtrs[ ubSoldierID ] ) )
{
}
@@ -5566,7 +6419,7 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
if ( !gfDontChargeAPsToPickup )
{
// Deduct points
- DeductPoints( gpItemPointerSoldier, APBPConstants[AP_PICKUP_ITEM], 0 );
+ DeductPoints( gpItemPointerSoldier, GetBasicAPsToPickupItem( gpItemPointerSoldier ), 0 );
}
SoldierDropItem( gpItemPointerSoldier, gpItemPointer );
@@ -5582,7 +6435,7 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
if ( !gfDontChargeAPsToPickup )
{
// Deduct points
- DeductPoints( gpItemPointerSoldier, APBPConstants[AP_PICKUP_ITEM], 0 );
+ DeductPoints( gpItemPointerSoldier, GetBasicAPsToPickupItem(gpItemPointerSoldier), 0 );
}
// Play animation....
@@ -5620,7 +6473,7 @@ BOOLEAN HandleItemPointerClick( INT32 usMapPos )
if ( !gfDontChargeAPsToPickup )
{
// Deduct points
- DeductPoints( gpItemPointerSoldier, APBPConstants[AP_PICKUP_ITEM], 0 );
+ DeductPoints( gpItemPointerSoldier, GetBasicAPsToPickupItem(gpItemPointerSoldier), 0 );
}
SoldierDropItem( gpItemPointerSoldier, gpItemPointer );
@@ -6526,22 +7379,22 @@ UINT32 GetInterfaceGraphicForItem( INVTYPE *pItem )
// CHECK SUBCLASS
if ( pItem->ubGraphicType == 0 )
{
- TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oGUNSM.getVObjectForItem(pItem->ubGraphicNum) : guiGUNSM,
+ SGP_TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oGUNSM.getVObjectForItem(pItem->ubGraphicNum) : guiGUNSM,
L"Failed to retrieve gun image" );
}
else if ( pItem->ubGraphicType == 1 )
{
- TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oP1ITEMS.getVObjectForItem(pItem->ubGraphicNum) : guiP1ITEMS,
+ SGP_TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oP1ITEMS.getVObjectForItem(pItem->ubGraphicNum) : guiP1ITEMS,
L"Failed to retrieve P1 item image" );
}
else if ( pItem->ubGraphicType == 2 )
{
- TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oP2ITEMS.getVObjectForItem(pItem->ubGraphicNum) : guiP2ITEMS,
+ SGP_TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oP2ITEMS.getVObjectForItem(pItem->ubGraphicNum) : guiP2ITEMS,
L"Failed to retrieve P2 item image" );
}
else
{
- TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oP3ITEMS.getVObjectForItem(pItem->ubGraphicNum) : guiP3ITEMS,
+ SGP_TRYCATCH_RETHROW( id = g_bUsePngItemImages ? g_oP3ITEMS.getVObjectForItem(pItem->ubGraphicNum) : guiP3ITEMS,
L"Failed to retrieve P3 item image" );
}
return id;
@@ -6587,6 +7440,8 @@ BOOLEAN LoadTileGraphicForItem( INVTYPE *pItem, UINT32 *puiVo )
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("LoadTileGraphicForItem"));
+ const char* ext = g_bUsePngItemImages ? ".png" : ".sti";
+
// CHECK SUBCLASS
ubGraphic = pItem->ubGraphicNum;
@@ -6597,50 +7452,50 @@ BOOLEAN LoadTileGraphicForItem( INVTYPE *pItem, UINT32 *puiVo )
if ( ubGraphic < 10 )
{
- sprintf( zName, "gun0%d.sti", ubGraphic );
+ sprintf( zName, "gun0%d", ubGraphic );
}
else
{
- sprintf( zName, "gun%d.sti", ubGraphic );
+ sprintf( zName, "gun%d", ubGraphic );
}
}
else if ( pItem->ubGraphicType == 1 )
{
if ( ubGraphic < 10 )
{
- sprintf( zName, "p1item0%d.sti", ubGraphic );
+ sprintf( zName, "p1item0%d", ubGraphic );
}
else
{
- sprintf( zName, "p1item%d.sti", ubGraphic );
+ sprintf( zName, "p1item%d", ubGraphic );
}
}
else if ( pItem->ubGraphicType == 2 )
{
if ( ubGraphic < 10 )
{
- sprintf( zName, "p2item0%d.sti", ubGraphic );
+ sprintf( zName, "p2item0%d", ubGraphic );
}
else
{
- sprintf( zName, "p2item%d.sti", ubGraphic );
+ sprintf( zName, "p2item%d", ubGraphic );
}
}
else
{
if ( ubGraphic < 10 )
{
- sprintf( zName, "p3item0%d.sti", ubGraphic );
+ sprintf( zName, "p3item0%d", ubGraphic );
}
else
{
- sprintf( zName, "p3item%d.sti", ubGraphic );
+ sprintf( zName, "p3item%d", ubGraphic );
}
}
//Load item
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
- sprintf( VObjectDesc.ImageFile, "BIGITEMS\\%s", zName );
+ sprintf( VObjectDesc.ImageFile, "BIGITEMS\\%s%s", zName, ext );
CHECKF( AddVideoObject( &VObjectDesc, &uiVo) );
*puiVo = uiVo;
@@ -6671,7 +7526,13 @@ void ItemDescCallback( MOUSE_REGION * pRegion, INT32 iReason )
//Only exit the screen if we are NOT in the money interface. Only the DONE button should exit the money interface.
if( gpItemDescObject->usItem != MONEY )
{
+ OBJECTTYPE *pTemp = gpItemDescPrevObject;
DeleteItemDescriptionBox( );
+ if (pTemp != NULL)
+ {
+ InternalInitItemDescriptionBox( pTemp, gsInvDescX, gsInvDescY, 0, gpItemDescSoldier );
+ }
+
}
}
}
@@ -6688,7 +7549,12 @@ void ItemDescCallback( MOUSE_REGION * pRegion, INT32 iReason )
//Only exit the screen if we are NOT in the money interface. Only the DONE button should exit the money interface.
// if( gpItemDescObject->usItem != MONEY )
{
+ OBJECTTYPE *pTemp = gpItemDescPrevObject;
DeleteItemDescriptionBox( );
+ if (pTemp != NULL)
+ {
+ InternalInitItemDescriptionBox( pTemp, gsInvDescX, gsInvDescY, 0, gpItemDescSoldier );
+ }
}
}
}
@@ -8107,10 +8973,17 @@ void BtnMoneyButtonCallback(GUI_BUTTON *btn,INT32 reason)
if( ubButton != M_DONE )
{
RenderItemDescriptionBox( );
- for( i=0; iArea.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
@@ -8150,10 +9023,17 @@ void BtnMoneyButtonCallback(GUI_BUTTON *btn,INT32 reason)
}
RenderItemDescriptionBox( );
- for( i=0; iArea.RegionTopLeftX, btn->Area.RegionTopLeftY, btn->Area.RegionBottomRightX, btn->Area.RegionBottomRightY);
}
@@ -8267,7 +9147,7 @@ void RemoveMoney()
void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier, int subObject )
{
- CHAR16 pStr[ 250 ];
+ CHAR16 pStr[ 500 ];
UINT16 usItem = pObject->usItem;
INT32 iNumAttachments = 0;
INT16 sValue;
@@ -8394,6 +9274,7 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier
//Info for weapons
//swprintf( pStr, L"%s (%s) [%d%%]\n%s %d\n%s %d\n%s %d (%d)\n%s %s\n%s %1.1f %s",
+ INT8 accuracy = (UsingNewCTHSystem()==true?Weapon[ usItem ].nAccuracy:Weapon[ usItem ].bAccuracy);
#ifdef CHINESE
swprintf( pStr, ChineseSpecString4,
#else
@@ -8405,12 +9286,12 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier
AmmoCaliber[ Weapon[ usItem ].ubCalibre ],
sValue,
gWeaponStatsDesc[ 9 ], //Accuracy String
- Weapon[ usItem ].bAccuracy,
+ accuracy,
gWeaponStatsDesc[ 11 ], //Damage String
GetDamage(pObject),
gWeaponStatsDesc[ 10 ], //Range String
- gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? GunRange( pObject )/10 : GunRange( pObject ), //Modified Range
- gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? Weapon[ usItem ].usRange/10 : Weapon[ usItem ].usRange, //Gun Range
+ gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? GunRange( pObject, NULL )/10 : GunRange( pObject, NULL ), // SANDRO - added argument //Modified Range
+ gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? GetModifiedGunRange(usItem)/10 : GetModifiedGunRange(usItem), //Gun Range
gWeaponStatsDesc[ 6 ], //AP String
(Weapon[ usItem ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction( pObject )) / 100), // Ready AP's
apStr, //AP's
@@ -8451,6 +9332,7 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier
}
//Info for weapons
+ INT8 accuracy = (UsingNewCTHSystem()==true?Weapon[ usItem ].nAccuracy:Weapon[ usItem ].bAccuracy);
#ifdef CHINESE
swprintf( pStr, L"%s [%d%]\n%s %d\n%s %d\n%s %d (%d)\n%s %s\n%s %1.1f %s",
@@ -8461,12 +9343,12 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier
ItemNames[ usItem ],
sValue,
gWeaponStatsDesc[ 9 ], //Accuracy String
- Weapon[ usItem ].bAccuracy,
+ accuracy,
gWeaponStatsDesc[ 11 ], //Damage String
GetDamage(pObject),
gWeaponStatsDesc[ 10 ], //Range String
- gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? GunRange( pObject )/10 : GunRange( pObject ), //Modified Range
- gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? Weapon[ usItem ].usRange/10 : Weapon[ usItem ].usRange, //Gun Range
+ gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? GunRange( pObject, NULL )/10 : GunRange( pObject, NULL ), // SANDRO - added argument //Modified Range
+ gGameSettings.fOptions[ TOPTION_SHOW_WEAPON_RANGE_IN_TILES ] ? GetModifiedGunRange(usItem)/10 : GetModifiedGunRange(usItem), //Gun Range
gWeaponStatsDesc[ 6 ], //AP String
apStr, //AP's
gWeaponStatsDesc[ 12 ], //Weight String
@@ -8633,24 +9515,37 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier
// Add attachment string....
+ CHAR16 attachString[ 300 ];
+ memset(attachString,0,sizeof(attachString));
for (attachmentList::iterator iter = (*pObject)[subObject]->attachments.begin(); iter != (*pObject)[subObject]->attachments.end(); ++iter) {
- iNumAttachments++;
+ if(iter->exists()){
- if ( iNumAttachments == 1 )
- {
- wcscat( pStr, L"\n[" );
- }
- else
- {
- wcscat( pStr, L", " );
- }
+ //Break off if it's too long.
+ if(wcslen(attachString)>270){
+ wcscat( attachString, L"\n...." );
+ break;
+ }
- wcscat( pStr, ItemNames[ iter->usItem ] );
+ iNumAttachments++;
+
+ if ( iNumAttachments == 1 )
+ {
+ swprintf( attachString, L"\n \n%s:\n", Message[ STR_ATTACHMENTS ] );
+ }
+ else
+ {
+ wcscat( attachString, L"\n" );
+ }
+
+ wcscat( attachString, ItemNames[ iter->usItem ] );
+ }
}
+
if ( iNumAttachments > 0 )
{
- wcscat( pStr, pMessageStrings[ MSG_END_ATTACHMENT_LIST ] );
+ wcscat( pStr, attachString);
+ //wcscat( pStr, pMessageStrings[ MSG_END_ATTACHMENT_LIST ] );
}
}
@@ -9037,3 +9932,174 @@ void DeletePool(ITEM_POOL *pItemPool)
MemFree(pItemPoolToDelete);
}
}
+
+void ItemDescTabButtonCallback( GUI_BUTTON *btn, INT32 reason )
+{
+ switch (btn->UserData[0])
+ {
+ case 0:
+ gubDescBoxPage = 0;
+ InternalInitEDBTooltipRegion( gpItemDescObject, guiCurrentItemDescriptionScreen );
+ RenderItemDescriptionBox();
+ MarkAButtonDirty( giItemDescAmmoButton ); // Required for tactical screen
+ ItemDescTabButtonOn( 0 );
+ ItemDescTabButtonOff( 1 );
+ ItemDescTabButtonOff( 2 );
+ break;
+ case 1:
+ gubDescBoxPage = 1;
+ InternalInitEDBTooltipRegion( gpItemDescObject, guiCurrentItemDescriptionScreen );
+ RenderItemDescriptionBox();
+ MarkAButtonDirty( giItemDescAmmoButton ); // Required for tactical screen
+ ItemDescTabButtonOff( 0 );
+ ItemDescTabButtonOn( 1 );
+ ItemDescTabButtonOff( 2 );
+ break;
+ case 2:
+ gubDescBoxPage = 2;
+ InternalInitEDBTooltipRegion( gpItemDescObject, guiCurrentItemDescriptionScreen );
+ RenderItemDescriptionBox();
+ MarkAButtonDirty( giItemDescAmmoButton ); // Required for tactical screen
+ ItemDescTabButtonOff( 0 );
+ ItemDescTabButtonOff( 1 );
+ ItemDescTabButtonOn( 2 );
+ break;
+ }
+}
+
+void ItemDescTabButtonOn( UINT8 ubItemDescTabButtonIndex )
+{
+ Assert( ubItemDescTabButtonIndex < 3 );
+
+ // if button doesn't exist, return
+ if ( giInvDescTabButton[ ubItemDescTabButtonIndex ] == -1 )
+ {
+ return;
+ }
+
+ Assert( giInvDescTabButton[ ubItemDescTabButtonIndex ] < MAX_BUTTONS );
+
+ ButtonList[ giInvDescTabButton[ ubItemDescTabButtonIndex ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ MarkAButtonDirty( giInvDescTabButton[ ubItemDescTabButtonIndex ] );
+}
+
+void ItemDescTabButtonOff( UINT8 ubItemDescTabButtonIndex )
+{
+ Assert( ubItemDescTabButtonIndex < 3 );
+
+ // if button doesn't exist, return
+ if ( giInvDescTabButton[ ubItemDescTabButtonIndex ] == -1 )
+ {
+ return;
+ }
+
+ Assert( giInvDescTabButton[ ubItemDescTabButtonIndex ] < MAX_BUTTONS );
+
+ ButtonList[ giInvDescTabButton[ ubItemDescTabButtonIndex ] ]->uiFlags &= ~(BUTTON_CLICKED_ON);
+
+ MarkAButtonDirty( giInvDescTabButton[ ubItemDescTabButtonIndex ] );
+}
+
+void ItemDescAdvButtonCallback( GUI_BUTTON *btn, INT32 reason )
+{
+ if (reason == MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ switch (btn->UserData[0])
+ {
+ case 0:
+ gubDescBoxLine--;
+ InternalInitEDBTooltipRegion( gpItemDescObject, guiCurrentItemDescriptionScreen );
+ RenderItemDescriptionBox();
+ // Required for tactical screen
+ MarkAButtonDirty( giItemDescAmmoButton );
+ for (INT8 x = 0; x < 3; x++)
+ {
+ if (giInvDescTabButton[x] != -1)
+ {
+ // HEADROCK HAM 4: Makes sure the Tab Buttons are always redrawn on top.
+ MarkAButtonDirty( giInvDescTabButton[ x ] );
+ }
+ }
+ ItemDescAdvButtonOff( 0 );
+ ItemDescTabButtonOff( 1 );
+ ItemDescAdvButtonCheck();
+ break;
+ case 1:
+ gubDescBoxLine++;
+ InternalInitEDBTooltipRegion( gpItemDescObject, guiCurrentItemDescriptionScreen );
+ RenderItemDescriptionBox();
+ // Required for tactical screen
+ MarkAButtonDirty( giItemDescAmmoButton );
+ for (INT8 x = 0; x < 3; x++)
+ {
+ if (giInvDescTabButton[x] != -1)
+ {
+ // HEADROCK HAM 4: Makes sure the Tab Buttons are always redrawn on top.
+ MarkAButtonDirty( giInvDescTabButton[ x ] );
+ }
+ }
+ ItemDescTabButtonOff( 0 );
+ ItemDescTabButtonOff( 1 );
+ ItemDescAdvButtonCheck();
+ break;
+ }
+ }
+}
+
+void ItemDescAdvButtonOn( UINT8 ubItemDescAdvButtonIndex )
+{
+ Assert( ubItemDescAdvButtonIndex < 2 );
+
+ // if button doesn't exist, return
+ if ( giInvDescAdvButton[ ubItemDescAdvButtonIndex ] == -1 )
+ {
+ return;
+ }
+
+ Assert( giInvDescAdvButton[ ubItemDescAdvButtonIndex ] < MAX_BUTTONS );
+
+ ButtonList[ giInvDescAdvButton[ ubItemDescAdvButtonIndex ] ]->uiFlags |= BUTTON_CLICKED_ON;
+
+ MarkAButtonDirty( giInvDescAdvButton[ 0 ] );
+ MarkAButtonDirty( giInvDescAdvButton[ 1 ] );
+}
+
+void ItemDescAdvButtonOff( UINT8 ubItemDescAdvButtonIndex )
+{
+ Assert( ubItemDescAdvButtonIndex < 2 );
+
+ // if button doesn't exist, return
+ if ( giInvDescAdvButton[ ubItemDescAdvButtonIndex ] == -1 )
+ {
+ return;
+ }
+
+ Assert( giInvDescAdvButton[ ubItemDescAdvButtonIndex ] < MAX_BUTTONS );
+
+ ButtonList[ giInvDescAdvButton[ ubItemDescAdvButtonIndex ] ]->uiFlags &= ~(BUTTON_CLICKED_ON);
+
+ MarkAButtonDirty( giInvDescAdvButton[ 0 ] );
+ MarkAButtonDirty( giInvDescAdvButton[ 1 ] );
+}
+
+void ItemDescAdvButtonCheck( void )
+{
+ if (gubDescBoxLine <= 0)
+ {
+ DisableButton( giInvDescAdvButton[0] );
+ }
+ else
+ {
+ EnableButton( giInvDescAdvButton[0] );
+ }
+
+ if (NUM_UDB_ADV_LINES < gubDescBoxTotalAdvLines - gubDescBoxLine)
+ {
+ EnableButton( giInvDescAdvButton[1] );
+ }
+ else
+ {
+ DisableButton( giInvDescAdvButton[1] );
+ }
+}
diff --git a/Tactical/Interface Items.h b/Tactical/Interface Items.h
index 2fc6c668..9173c533 100644
--- a/Tactical/Interface Items.h
+++ b/Tactical/Interface Items.h
@@ -10,6 +10,7 @@
#define SM_INV_SLOT_WIDTH 30
#define SM_INV_SLOT_HEIGHT 23
#define ATTACH_SLOT_WIDTH 32
+#define ATTACH_SLOT_BIG_WIDTH 64
#define VEST_INV_SLOT_WIDTH 43
#define VEST_INV_SLOT_HEIGHT 24
#define LEGS_INV_SLOT_WIDTH 43
@@ -17,6 +18,30 @@
#define HEAD_INV_SLOT_WIDTH 43
#define HEAD_INV_SLOT_HEIGHT 24
+#define NUM_UDB_GEN_LINES 12
+#define NUM_UDB_ADV_LINES 12
+
+// HEADROCK HAM 4: These rectangle definitions are used in UDB to determine locations for icons, data, and tooltip
+// regions. They replace the plethora of region data provided in EDB.
+typedef struct
+{
+ INT16 sLeft;
+ INT16 sTop;
+ INT16 sRight;
+ INT16 sBottom;
+} INV_DESC_REGIONS;
+
+extern INV_DESC_REGIONS gItemDescLBEBackground[4]; // Coordinates for displaying LBE background image
+extern INV_DESC_REGIONS gItemDescGenHeaderRegions[3]; // Header text regions for various parts of the General Tab
+extern INV_DESC_REGIONS gItemDescGenIndexRegions[3][4]; // Index text regions for various parts of the General Tab
+extern INV_DESC_REGIONS gItemDescGenRegions[NUM_UDB_GEN_LINES * 2][4]; // Data regions, 4 sub-columns each
+extern INV_DESC_REGIONS gItemDescGenSecondaryRegions[26]; // Secondary data regions, 3x5 for now (possible 3x6?)
+extern INV_DESC_REGIONS gItemDescTextRegions[7]; // Main description regions
+extern INV_DESC_REGIONS gItemDescAdvIndexRegions[1][4];
+extern INV_DESC_REGIONS gItemDescAdvRegions[NUM_UDB_ADV_LINES][4]; // Advanced data regions, 4 sub-columns each
+
+// ODB arrays
+extern INV_DESC_REGIONS gODBItemDescRegions[4][8]; // Four regions of eight sub-regions each.
//CHRISL: moved from Interface Items.cpp
typedef struct
@@ -54,7 +79,8 @@ void ItemDescCallback( MOUSE_REGION * pRegion, INT32 iReason );
#define INV_BAR_DY 21
#define ITEM_STATS_WIDTH 26
#define ITEM_STATS_HEIGHT 8
-#define EXCEPTIONAL_DAMAGE 40
+#define EXCEPTIONAL_GUN_DAMAGE 40
+#define EXCEPTIONAL_MELEE_DAMAGE 40
#define EXCEPTIONAL_WEIGHT 20
#define EXCEPTIONAL_RANGE 400
#define EXCEPTIONAL_MAGAZINE 50
@@ -81,16 +107,13 @@ extern INT16 ITEMDESC_NAME_X;
extern INT16 ITEMDESC_NAME_Y;
extern INT16 ITEMDESC_ITEM_X;
extern INT16 ITEMDESC_ITEM_Y;
-extern INT16 ITEMDESC_DESC_START_X;
-extern INT16 ITEMDESC_DESC_START_Y;
-extern INT16 ITEMDESC_PROS_START_X;
-extern INT16 ITEMDESC_PROS_START_Y;
-extern INT16 ITEMDESC_CONS_START_X;
-extern INT16 ITEMDESC_CONS_START_Y;
-extern INT16 ITEMDESC_DESC_WIDTH;
extern INT16 ITEMDESC_ITEM_STATUS_X;
extern INT16 ITEMDESC_ITEM_STATUS_Y;
extern INT16 ITEMDESC_ITEM_STATUS_HEIGHT;
+extern INT16 ITEMDESC_AMMO_X;
+extern INT16 ITEMDESC_AMMO_Y;
+extern INT16 ITEMDESC_DONE_X;
+extern INT16 ITEMDESC_DONE_Y;
// A STRUCT USED INTERNALLY FOR INV SLOT REGIONS
typedef struct
@@ -211,7 +234,9 @@ BOOLEAN InitKeyItemDescriptionBox( SOLDIERTYPE *pSoldier, UINT8 ubPosition, INT1
void RenderItemDescriptionBox( );
void HandleItemDescriptionBox( BOOLEAN *pfDirty );
void DeleteItemDescriptionBox( );
-
+extern BOOLEAN UseNASDesc(OBJECTTYPE *pObject);
+INT16 sNASXCorrection(OBJECTTYPE * pObject);
+INT16 sNASYCorrection(OBJECTTYPE * pObject);
BOOLEAN InItemStackPopup( );
BOOLEAN InitItemStackPopup( SOLDIERTYPE *pSoldier, UINT8 ubPosition, INT16 sInvX, INT16 sInvY, INT16 sInvWidth, INT16 sInvHeight );
diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp
index b119bc70..4efed5ae 100644
--- a/Tactical/Interface Panels.cpp
+++ b/Tactical/Interface Panels.cpp
@@ -76,6 +76,8 @@
#include "Campaign.h"
#endif
+//legion by Jazz
+#include "Interface Utils.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -367,6 +369,7 @@ typedef enum
DONE_IMAGES,
MAPSCREEN_IMAGES,
BACKPACK_IMAGES,
+ //HOP_IMAGES, //legion by Jazz
NUM_SM_BUTTON_IMAGES
};
@@ -435,10 +438,14 @@ UINT16 gusOldItemIndex;
UINT16 gusNewItemIndex;
BOOLEAN gfDeductPoints;
-
-
-
-
+// HEADROCK HAM 4: This variable tells the program what "page" of the description box we are currently looking at.
+// By saving this in memory, we tell the DescBox which background and values to draw, and make sure that we end up
+// on the same page every time we open the description box. UDB buttons allow switching between pages.
+UINT8 gubDescBoxPage;
+// Record which line we're looking at. This only applied to the Advanced tab in description boxes.
+UINT8 gubDescBoxLine;
+// Record how many lines this item has to display. This only applies to the Advanced tab.
+UINT8 gubDescBoxTotalAdvLines;
INT32 iSMPanelButtons[ NUM_SM_BUTTONS ];
INT32 iTEAMPanelButtons[ NUM_TEAM_BUTTONS ];
@@ -464,6 +471,8 @@ MOUSE_REGION gTEAM_FirstHandInv[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_SecondHandInv[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
MOUSE_REGION gTEAM_EnemyIndicator[ NUMBER_OF_SOLDIERS_PER_SQUAD ];
+MOUSE_REGION gSM_SELMERCCamoRegion; // Added by Sandro
+
BOOLEAN gfTEAM_HandInvDispText[ NUMBER_OF_SOLDIERS_PER_SQUAD ][ NUM_INV_SLOTS ];
BOOLEAN gfSM_HandInvDispText[ NUM_INV_SLOTS ];
@@ -501,7 +510,9 @@ INT8 gbZipperButPos[2][2] =
1, 0
};
-
+//Legion by Jazz
+void BtnOknoCallback(GUI_BUTTON *btn,INT32 reason);
+void BtnFenceCallback(GUI_BUTTON *btn,INT32 reason);
// Mouse button and region callbacks
//void BtnPositionCallback( GUI_BUTTON *btn, INT32 reason );
@@ -561,7 +572,7 @@ void UpdateSelectedSoldier( UINT16 usSoldierID, BOOLEAN fSelect );
void CheckForFacePanelStartAnims( SOLDIERTYPE *pSoldier, INT16 sPanelX, INT16 sPanelY );
void HandleSoldierFaceFlash( SOLDIERTYPE *pSoldier, INT16 sFaceX, INT16 sFaceY );
BOOLEAN PlayerExistsInSlot( UINT8 ubID );
-void UpdateStatColor( UINT32 uiTimer, BOOLEAN fUpdate );
+void UpdateStatColor( UINT32 uiTimer, BOOLEAN fIncrease, BOOLEAN fDamaged ); // SADNRO - added argument
extern void UpdateItemHatches();
@@ -795,6 +806,10 @@ void UpdateSMPanel( )
INT8 bDirection;
UINT8 ubStanceState;
+ //jump window by Jazz
+ //BOOLEAN fNearLowerLevelOkno;
+ //BOOLEAN fNearHeigherLevelOkno;
+
if (TileIsOutOfBounds(gpSMCurrentMerc->sGridNo))
{
return;
@@ -940,9 +955,47 @@ void UpdateSMPanel( )
DisableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
+
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //DisableButton( iSMPanelButtons[ HOP_BUTTON ] ); //Legion by Jazz
+ //}
GetMercClimbDirection( gpSMCurrentMerc->ubID, &fNearLowerLevel, &fNearHeigherLevel );
+
+//--------------------- Legion-----------------
+/*
+if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ {
+
+ if ( gpSMCurrentMerc->pathing.bLevel == 0 )
+ {
+ GetMercOknoDirection( gpSMCurrentMerc->ubID, &fNearLowerLevelOkno, &fNearHeigherLevelOkno ); //Legion by JAzz
+ if ( fNearLowerLevelOkno || fNearHeigherLevelOkno )
+ {
+ if ( fNearLowerLevelOkno )
+ {
+ if ( EnoughPoints( gpSMCurrentMerc, GetAPsToJumpThroughWindows( gpSMCurrentMerc, TRUE ), 0, FALSE ) )
+ {
+ EnableButton( iSMPanelButtons[ HOP_BUTTON ] );
+ }
+ }
+
+ if ( fNearHeigherLevelOkno )
+ {
+ if ( EnoughPoints( gpSMCurrentMerc, GetAPsToJumpThroughWindows( gpSMCurrentMerc, FALSE ), 0, FALSE ) )
+ {
+ EnableButton( iSMPanelButtons[ HOP_BUTTON ] );
+ }
+ }
+ }
+ }
+ }
+*/
+ //---------
+
if ( fNearLowerLevel || fNearHeigherLevel )
{
if ( fNearLowerLevel )
@@ -962,6 +1015,27 @@ void UpdateSMPanel( )
}
}
+ //----------------------------Legion by Jazz------------------------------
+ //DisableButton
+ /*
+ if (gGameExternalOptions.fCanJumpThroughWindows == TRUE )
+ {
+ if ( FindOknoDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) && gpSMCurrentMerc->pathing.bLevel == 0 )
+ {
+ EnableButton( iSMPanelButtons[ HOP_BUTTON ] );
+ }
+ }
+ */
+ if (gGameExternalOptions.fCanClimbOnWalls == TRUE)
+ {
+ if ( FindFenceDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) )
+ {
+ EnableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
+ }
+
+ }
+ //------------------------------------------
+
if ( FindFenceJumpDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) )
{
EnableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
@@ -1040,6 +1114,11 @@ void UpdateSMPanel( )
// If not selected ( or dead ), disable/gray some buttons
if ( gusSelectedSoldier != gpSMCurrentMerc->ubID || ( gpSMCurrentMerc->stats.bLife < OKLIFE ) || (gTacticalStatus.ubCurrentTeam != gbPlayerNum) || gfSMDisableForItems )
{
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //DisableButton( iSMPanelButtons[ HOP_BUTTON ] ); //Legion by Jazz
+ //}
DisableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
DisableButton( iSMPanelButtons[ BURSTMODE_BUTTON ] );
DisableButton( iSMPanelButtons[ STANCEUP_BUTTON ] );
@@ -1110,7 +1189,7 @@ void ReevaluateItemHatches( SOLDIERTYPE *pSoldier, BOOLEAN fAllValid )
//if( guiCurrentScreen != MAP_SCREEN )
{
// Check attachments, override to valid placement if valid merge...
- if ( ValidAttachment( gpItemPointer->usItem, pSoldier->inv[ cnt ].usItem ) )
+ if ( ValidAttachment( gpItemPointer->usItem, &(pSoldier->inv[ cnt ]) ) )
{
gbInvalidPlacementSlot[ cnt ] = FALSE;
}
@@ -1289,6 +1368,11 @@ void EnableSMPanelButtons( BOOLEAN fEnable , BOOLEAN fFromItemPickup )
// only enable the following if NOT in shopkeeper's interface
if ( !(guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) )
{
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //EnableButton( iSMPanelButtons[ HOP_BUTTON ] ); //Legion by JAzz
+ //}
EnableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
EnableButton( iSMPanelButtons[ BURSTMODE_BUTTON ] );
EnableButton( iSMPanelButtons[ STANCEUP_BUTTON ] );
@@ -1332,6 +1416,11 @@ void EnableSMPanelButtons( BOOLEAN fEnable , BOOLEAN fFromItemPickup )
}
else
{
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //DisableButton( iSMPanelButtons[ HOP_BUTTON ] ); //Legion by Jazz
+ //}
DisableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
DisableButton( iSMPanelButtons[ BURSTMODE_BUTTON ] );
DisableButton( iSMPanelButtons[ STANCEUP_BUTTON ] );
@@ -2059,6 +2148,11 @@ BOOLEAN InitializeSMPanel( )
MSYS_NO_CURSOR, MSYS_NO_CALLBACK, SelectedMercButtonCallback );
MSYS_AddRegion( &gSM_SELMERCBarsRegion );
+ // Added by SANDRO - define region for camo tooltip window
+ MSYS_DefineRegion( &gSM_SELMERCCamoRegion, ( SM_CAMMO_X + 2), ( SM_CAMMO_Y ),
+ (SM_CAMMO_X + 28), (SM_CAMMO_Y + 10), MSYS_PRIORITY_NORMAL,
+ MSYS_NO_CURSOR, MSYS_NO_CALLBACK, SelectedMercButtonCallback );
+ MSYS_AddRegion( &gSM_SELMERCCamoRegion );
// CHRISL: Setup default coords
if((UsingNewInventorySystem() == true))
@@ -2090,7 +2184,9 @@ BOOLEAN InitializeSMPanel( )
BOOLEAN CreateSMPanelButtons( )
{
-CHAR8 ubString[48];
+ CHAR8 ubString[48];
+ //CHAR8 ubString2[48]; //legion DisableButton
+ //CHAR8 ubString3[48]; //legion
// CHRISL: Reset backpack buttons as well
giSMStealthImages = giSMZipperImages = giSMDropPackImages = -1;
@@ -2099,6 +2195,14 @@ CHAR8 ubString[48];
gfAllDisabled = FALSE;
FilenameForBPP("INTERFACE\\inventory_buttons.sti", ubString);
+
+ //Legion by Jazz
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ // FilenameForBPP("INTERFACE\\inventory_buttons_WINDOW_2.sti", ubString2); //LEGION
+ //}
+ //-----------------------
// Load button Graphics
iSMPanelImages[ STANCEUP_IMAGES ] = LoadButtonImage(ubString,-1,0,-1,10,-1 );
@@ -2112,8 +2216,21 @@ CHAR8 ubString[48];
iSMPanelImages[ LOOK_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,2,-1,12,-1 );
iSMPanelImages[ TALK_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,6,-1,16,-1 );
iSMPanelImages[ MUTE_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,5,-1,15,-1 );
+
+ //Legion by Jazz
+ //DisableButton
+ /*
+ if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ {
+ iSMPanelImages[ OPTIONS_IMAGES ] = LoadButtonImage(ubString2,-1,0,-1,1,-1 ); //legion
+ }
+ else
+ {
iSMPanelImages[ OPTIONS_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,24,-1,25,-1 );
-
+ }
+ */
+ iSMPanelImages[ OPTIONS_IMAGES ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ] ,-1,24,-1,25,-1 );
+
iBurstButtonImages[ WM_NORMAL ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 7, -1, -1, -1 );
iBurstButtonImages[ WM_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
iBurstButtonImages[ WM_AUTOFIRE ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
@@ -2121,6 +2238,12 @@ CHAR8 ubString[48];
iBurstButtonImages[ WM_ATTACHED_GL_BURST ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
iBurstButtonImages[ WM_ATTACHED_GL_AUTO ] = UseLoadedButtonImage( iSMPanelImages[ STANCEUP_IMAGES ], -1, 17, -1, -1, -1 );
+ //Legion by JAzz
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ // iSMPanelImages[ HOP_IMAGES ] = LoadButtonImage(ubString2,-1,2,-1,3,-1 );
+ //}
FilenameForBPP("INTERFACE\\invadd-ons.sti", ubString);
// Load button Graphics
@@ -2140,6 +2263,29 @@ CHAR8 ubString[48];
// SET BUTTONS TO -1
memset( iSMPanelButtons, -1, sizeof( iSMPanelButtons ) );
+
+
+ //Legion by Jazz
+ //DisableButton
+ /*if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ {
+
+ if (UsingNewInventorySystem() == true)
+ {
+ iSMPanelButtons[ HOP_BUTTON ] = QuickCreateButton( iSMPanelImages[ HOP_IMAGES ], SM_BURSTMODEB_X-30, SM_BURSTMODEB_Y,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGH - 1,
+ DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)BtnOknoCallback );
+ }
+ else
+ {
+ iSMPanelButtons[ HOP_BUTTON ] = QuickCreateButton( iSMPanelImages[ HOP_IMAGES ], SM_BURSTMODEB_X-98, SM_BURSTMODEB_Y+35,
+ BUTTON_TOGGLE, MSYS_PRIORITY_HIGH - 1,
+ DEFAULT_MOVE_CALLBACK, (GUI_CALLBACK)BtnOknoCallback );
+ }
+ }
+ */
+ //-----------------------
+
iSMPanelButtons[ SM_MAP_SCREEN_BUTTON ] = QuickCreateButton( iSMPanelImages[ MAPSCREEN_IMAGES ], SM_MAPSCREEN_X, SM_MAPSCREEN_Y,
BUTTON_TOGGLE, MSYS_PRIORITY_HIGH - 1,
@@ -2385,6 +2531,8 @@ BOOLEAN ShutdownSMPanel( )
MSYS_RemoveRegion( &gSM_SELMERCMoneyRegion );
MSYS_RemoveRegion( &gSM_SELMERCEnemyIndicatorRegion );
+ MSYS_RemoveRegion( &gSM_SELMERCCamoRegion ); // added - SANDRO
+
HandleMouseOverSoldierFaceForContMove( gpSMCurrentMerc, FALSE );
MSYS_RemoveRegion( &gViewportRegion );
@@ -2515,6 +2663,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sAgilityGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sAgilityGain+1)) / SubpointsPerPoint(AGILAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_AGI_Y-1);
ClipRect.iBottom = (SM_AGI_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_AGI_X;
@@ -2526,6 +2675,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sDexterityGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sDexterityGain+1)) / SubpointsPerPoint(DEXTAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_DEX_Y-1);
ClipRect.iBottom = (SM_DEX_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_DEX_X;
@@ -2537,6 +2687,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sStrengthGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sStrengthGain+1)) / SubpointsPerPoint(STRAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_STR_Y-1);
ClipRect.iBottom = (SM_STR_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_STR_X;
@@ -2548,6 +2699,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sWisdomGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sWisdomGain+1)) / SubpointsPerPoint(WISDOMAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_WIS_Y-1);
ClipRect.iBottom = (SM_WIS_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_WIS_X;
@@ -2559,6 +2711,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMarksmanshipGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMarksmanshipGain+1)) / SubpointsPerPoint(MARKAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_MRKM_Y-1);
ClipRect.iBottom = (SM_MRKM_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_MRKM_X;
@@ -2570,6 +2723,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sLeadershipGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sLeadershipGain+1)) / SubpointsPerPoint(LDRAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_CHAR_Y-1);
ClipRect.iBottom = (SM_CHAR_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_CHAR_X;
@@ -2581,6 +2735,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMechanicGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMechanicGain+1)) / SubpointsPerPoint(MECHANAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_MECH_Y-1);
ClipRect.iBottom = (SM_MECH_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_MECH_X;
@@ -2592,6 +2747,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExplosivesGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExplosivesGain+1)) / SubpointsPerPoint(EXPLODEAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_EXPL_Y-1);
ClipRect.iBottom = (SM_EXPL_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_EXPL_X;
@@ -2603,6 +2759,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMedicalGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sMedicalGain+1)) / SubpointsPerPoint(MEDICALAMT,0);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_MED_Y-1);
ClipRect.iBottom = (SM_MED_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_MED_X;
@@ -2614,6 +2771,7 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExpLevelGain)
{
ubBarWidth = (SM_STATS_WIDTH * (gMercProfiles[ gpSMCurrentMerc->ubProfile ].sExpLevelGain+1)) / SubpointsPerPoint(EXPERAMT, gpSMCurrentMerc->stats.bExpLevel);
+ ubBarWidth = __max(0, __min(ubBarWidth, SM_STATS_WIDTH));
ClipRect.iTop = (SM_EXPLVL_Y-1);
ClipRect.iBottom = (SM_EXPLVL_Y-1) + SM_STATS_HEIGHT;
ClipRect.iLeft = SM_EXPLVL_X;
@@ -2675,61 +2833,61 @@ void RenderSMPanel( BOOLEAN *pfDirty )
mprintf( SM_CAMMO_PERCENT_X, SM_CAMMO_PERCENT_Y, L"%%" );
#endif
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeAgilityTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & AGIL_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeAgilityTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & AGIL_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bAgility );
FindFontRightCoordinates(SM_AGI_X, SM_AGI_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeDexterityTime,( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & DEX_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeDexterityTime,( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & DEX_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bDexterity );
FindFontRightCoordinates(SM_DEX_X, SM_DEX_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeStrengthTime, ( BOOLEAN )( gpSMCurrentMerc->usValueGoneUp & STRENGTH_INCREASE?TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeStrengthTime, ( BOOLEAN )( gpSMCurrentMerc->usValueGoneUp & STRENGTH_INCREASE?TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bStrength );
FindFontRightCoordinates(SM_STR_X, SM_STR_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeLeadershipTime, ( BOOLEAN )( gpSMCurrentMerc->usValueGoneUp & LDR_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeLeadershipTime, ( BOOLEAN )( gpSMCurrentMerc->usValueGoneUp & LDR_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_LEADERSHIP] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bLeadership );
FindFontRightCoordinates(SM_CHAR_X, SM_CHAR_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeWisdomTime,( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & WIS_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeWisdomTime,( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & WIS_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bWisdom );
FindFontRightCoordinates(SM_WIS_X, SM_WIS_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeLevelTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & LVL_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeLevelTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & LVL_INCREASE? TRUE: FALSE ), FALSE );
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bExpLevel );
FindFontRightCoordinates(SM_EXPLVL_X, SM_EXPLVL_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeMarksmanshipTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & MRK_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeMarksmanshipTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & MRK_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_MARKSMANSHIP] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bMarksmanship );
FindFontRightCoordinates(SM_MRKM_X, SM_MRKM_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeExplosivesTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & EXP_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeExplosivesTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & EXP_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_EXPLOSIVES] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bExplosive );
FindFontRightCoordinates(SM_EXPL_X, SM_EXPL_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeMechanicalTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & MECH_INCREASE ? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeMechanicalTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & MECH_INCREASE ? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_MECHANICAL] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bMechanical );
FindFontRightCoordinates(SM_MECH_X, SM_MECH_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
mprintf( usX, usY , sString );
- UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeMedicalTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & MED_INCREASE? TRUE: FALSE ) );
+ UpdateStatColor( gpSMCurrentMerc->timeChanges.uiChangeMedicalTime, ( BOOLEAN ) ( gpSMCurrentMerc->usValueGoneUp & MED_INCREASE? TRUE: FALSE ), ( BOOLEAN ) ( ( gGameOptions.fNewTraitSystem && ( gpSMCurrentMerc->ubCriticalStatDamage[DAMAGED_STAT_MEDICAL] > 0 )) ? TRUE : FALSE)); // SANDRO
swprintf( sString, L"%2d", gpSMCurrentMerc->stats.bMedical );
FindFontRightCoordinates(SM_MED_X, SM_MED_Y ,SM_STATS_WIDTH ,SM_STATS_HEIGHT ,sString, BLOCKFONT2, &usX, &usY);
@@ -2796,6 +2954,42 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if ( *pfDirty != DIRTYLEVEL0 )
{
+ ///////////////////////////////////////////////////////////////////////
+ // SANDRO - added a tooltip window showing exact camo percentage for every type
+ // *******************************************************************
+ CHAR16 pStrCamo[400];
+ swprintf( pStrCamo, L"" );
+ swprintf( pStr, L"");
+ if ((gpSMCurrentMerc->bCamo + gpSMCurrentMerc->wornCamo) > 0 )
+ {
+ swprintf( pStrCamo, L"\n%d/%d%s %s", gpSMCurrentMerc->bCamo, gpSMCurrentMerc->wornCamo, L"%", gzMiscItemStatsFasthelp[ 21 ]);
+ wcscat( pStr, pStrCamo);
+ swprintf( pStrCamo, L"" );
+ }
+ if ((gpSMCurrentMerc->urbanCamo + gpSMCurrentMerc->wornUrbanCamo) > 0 )
+ {
+ swprintf( pStrCamo, L"\n%d/%d%s %s", gpSMCurrentMerc->urbanCamo, gpSMCurrentMerc->wornUrbanCamo, L"%", gzMiscItemStatsFasthelp[ 22 ]);
+ wcscat( pStr, pStrCamo);
+ swprintf( pStrCamo, L"" );
+ }
+ if ((gpSMCurrentMerc->desertCamo + gpSMCurrentMerc->wornDesertCamo) > 0 )
+ {
+ swprintf( pStrCamo, L"\n%d/%d%s %s", gpSMCurrentMerc->desertCamo, gpSMCurrentMerc->wornDesertCamo, L"%", gzMiscItemStatsFasthelp[ 23 ]);
+ wcscat( pStr, pStrCamo);
+ swprintf( pStrCamo, L"" );
+ }
+ if ((gpSMCurrentMerc->snowCamo + gpSMCurrentMerc->wornSnowCamo) > 0 )
+ {
+ swprintf( pStrCamo, L"\n%d/%d%s %s", gpSMCurrentMerc->snowCamo, gpSMCurrentMerc->wornSnowCamo, L"%", gzMiscItemStatsFasthelp[ 24 ] );
+ wcscat( pStr, pStrCamo);
+ swprintf( pStrCamo, L"" );
+ }
+
+ SetRegionFastHelpText( &(gSM_SELMERCCamoRegion), pStr );
+ SetRegionHelpEndCallback( &gSM_SELMERCCamoRegion, SkiHelpTextDoneCallBack );
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+
// UPdate stats!
if ( gpSMCurrentMerc->stats.bLife != 0 )
{
@@ -2881,10 +3075,14 @@ void RenderSMPanel( BOOLEAN *pfDirty )
// Render clock
// CHRISL: If we're in NIV mode, don't render the clock on the SM panel
if(UsingNewInventorySystem() == false)
+ {
RenderClock( INTERFACE_CLOCK_X, INTERFACE_CLOCK_Y );
- CreateMouseRegionForPauseOfClock( INTERFACE_CLOCK_X, INTERFACE_CLOCK_Y );
+ CreateMouseRegionForPauseOfClock( INTERFACE_CLOCK_X, INTERFACE_CLOCK_Y );
+ }
+
// CHRISL: Change function call to include X,Y coordinates.
RenderTownIDString( LOCATION_NAME_X, LOCATION_NAME_Y );
+
}//XXXj in tactical bug is: NIV pushes town name +Y and boom
else
{
@@ -2921,11 +3119,16 @@ void RenderSMPanel( BOOLEAN *pfDirty )
}
-void UpdateStatColor( UINT32 uiTimer, BOOLEAN fIncrease )
+void UpdateStatColor( UINT32 uiTimer, BOOLEAN fIncrease, BOOLEAN fDamaged ) // SANDRO - added argument
{
if ( gpSMCurrentMerc->stats.bLife >= OKLIFE )
{
- if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + uiTimer) && ( uiTimer != 0 ) )
+ // SANDRO - if damaged stat we could regain, show in red until repaired
+ if( fDamaged )
+ {
+ SetFontForeground( FONT_RED );
+ }
+ else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + uiTimer) && ( uiTimer != 0 ) )
{
if( fIncrease )
{
@@ -3063,6 +3266,34 @@ void SMInvClickCamoCallback( MOUSE_REGION * pRegion, INT32 iReason )
{
if ( fGoodAPs )
{
+ if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
+ {
+ if ( gpSMCurrentMerc->bCamo > 0 )
+ {
+ gCamoFace[gpSMCurrentMerc->ubProfile].gCamoface = TRUE;
+ DeleteSoldierFace( gpSMCurrentMerc );// remove face
+ gpSMCurrentMerc->iFaceIndex = InitSoldierFace( gpSMCurrentMerc );// create new face
+ }
+ if ( gpSMCurrentMerc->urbanCamo > 0 )
+ {
+ gCamoFace[gpSMCurrentMerc->ubProfile].gUrbanCamoface = TRUE;
+ DeleteSoldierFace( gpSMCurrentMerc );// remove face
+ gpSMCurrentMerc->iFaceIndex = InitSoldierFace( gpSMCurrentMerc );// create new face
+ }
+ if ( gpSMCurrentMerc->desertCamo > 0)
+ {
+ gCamoFace[gpSMCurrentMerc->ubProfile].gDesertCamoface = TRUE;
+ DeleteSoldierFace( gpSMCurrentMerc );// remove face
+ gpSMCurrentMerc->iFaceIndex = InitSoldierFace( gpSMCurrentMerc );// create new face
+ }
+ if ( gpSMCurrentMerc->snowCamo > 0)
+ {
+ gCamoFace[gpSMCurrentMerc->ubProfile].gSnowCamoface = TRUE;
+ DeleteSoldierFace( gpSMCurrentMerc );// remove face
+ gpSMCurrentMerc->iFaceIndex = InitSoldierFace( gpSMCurrentMerc );// create new face
+ }
+ }
+
// Dirty
fInterfacePanelDirty = DIRTYLEVEL2;
@@ -3442,7 +3673,7 @@ void SMInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
if ( uiHandPos == HANDPOS || uiHandPos == SECONDHANDPOS || uiHandPos == HELMETPOS || uiHandPos == VESTPOS || uiHandPos == LEGPOS )
{
//if ( ValidAttachmentClass( usNewItemIndex, usOldItemIndex ) )
- if ( ValidAttachment( usNewItemIndex, usOldItemIndex ) )
+ if ( ValidAttachment( usNewItemIndex, &(gpSMCurrentMerc->inv[uiHandPos]) ) )
{
// it's an attempt to attach; bring up the inventory panel
if ( !InItemDescriptionBox( ) )
@@ -3658,6 +3889,10 @@ BOOLEAN ChangeZipperStatus(SOLDIERTYPE *pSoldier, BOOLEAN newStatus)
//Set AP cost based on what we're doing
sAPCost = (newStatus) ? APBPConstants[AP_CLOSE_ZIPPER] : APBPConstants[AP_OPEN_ZIPPER];
+ // SANDRO - ambidextrous bonus to handle things faster
+ if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, AMBIDEXTROUS_NT ) )
+ sAPCost = (INT16)((sAPCost * (100 - gSkillTraitValues.ubAMWorkBackpackAPsReduction) / 100) + 0.5);
+
//Are we currently in combat?
if(gTacticalStatus.uiFlags & INCOMBAT)
{
@@ -3830,7 +4065,7 @@ void MergeMessageBoxCallBack( UINT8 ubExitValue )
{
//ADB see what happens here
DebugBreakpoint();
- gpSMCurrentMerc->inv[ gubHandPos ].AttachObject( gpItemPointerSoldier, gpItemPointer );
+ gpSMCurrentMerc->inv[ gubHandPos ].AttachObject( gpItemPointerSoldier, gpItemPointer, FALSE );
// re-evaluate repairs
gfReEvaluateEveryonesNothingToDo = TRUE;
@@ -4205,6 +4440,18 @@ void BtnClimbCallback(GUI_BUTTON *btn,INT32 reason)
{
gpSMCurrentMerc->BeginSoldierClimbUpRoof( );
}
+
+ //---------------Legion by JAzz-----------
+
+ if (gGameExternalOptions.fCanClimbOnWalls == TRUE)
+ {
+ if ( FindFenceDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) )
+ {
+ gpSMCurrentMerc->BeginSoldierFence( );
+ }
+ }
+
+ //------------------------------------------
if ( FindFenceJumpDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) )
{
@@ -4686,7 +4933,7 @@ BOOLEAN InitializeTEAMPanelCoords( )
*/
// CHRISL: New definitions for the team panel clock and location coordinates
INTERFACE_CLOCK_TM_X = ( SCREEN_WIDTH - 86 );
- INTERFACE_CLOCK_TM_Y = ( 98 + INTERFACE_START_Y );
+ INTERFACE_CLOCK_TM_Y = ( 99 + INTERFACE_START_Y );
LOCATION_NAME_TM_X = ( SCREEN_WIDTH - 92 );
LOCATION_NAME_TM_Y = ( 65 + INTERFACE_START_Y );
@@ -6770,7 +7017,8 @@ void KeyRingSlotInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
BOOLEAN fOKToGo = FALSE;
BOOLEAN fDeductPoints = FALSE;
- if( ( gpItemPointer->usItem < FIRST_KEY ) || ( gpItemPointer->usItem > KEY_32 ) )
+ // WANNE: Instead of checking the item number for a key, check the itemclass!!!
+ if (Item[gpItemPointer->usItem].usItemClass != IC_KEY)
{
return;
}
@@ -6944,6 +7192,11 @@ void KeyRingSlotInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason )
void DisableSMPpanelButtonsWhenInShopKeeperInterface( BOOLEAN fDontDrawButtons )
{
//Go through the buttons that will be under the ShopKeepers ATM panel and disable them
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //DisableButton( iSMPanelButtons[ HOP_BUTTON ] ); //Legion by Jazz
+ //}
DisableButton( iSMPanelButtons[ STANCEUP_BUTTON ] );
DisableButton( iSMPanelButtons[ UPDOWN_BUTTON ] );
DisableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
@@ -6962,6 +7215,11 @@ void DisableSMPpanelButtonsWhenInShopKeeperInterface( BOOLEAN fDontDrawButtons )
//Make sure the mapscreen button is disabled
DisableButton( iSMPanelButtons[ SM_MAP_SCREEN_BUTTON ] );
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //DisableButton( iSMPanelButtons[ HOP_BUTTON ] ); //legion by Jazz
+ //}
DisableButton( iSMPanelButtons[ STANCEUP_BUTTON ] );
DisableButton( iSMPanelButtons[ UPDOWN_BUTTON ] );
DisableButton( iSMPanelButtons[ CLIMB_BUTTON ] );
@@ -6982,6 +7240,11 @@ void DisableSMPpanelButtonsWhenInShopKeeperInterface( BOOLEAN fDontDrawButtons )
//ATM:
//Go through the buttons that will be under the ShopKeepers ATM panel and disable them
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //ButtonList[ iSMPanelButtons[ HOP_BUTTON ] ]->uiFlags &= ~BUTTON_DIRTY; //Legion by Jazz
+ //}
ButtonList[ iSMPanelButtons[ STANCEUP_BUTTON ] ]->uiFlags &= ~BUTTON_DIRTY;
ButtonList[ iSMPanelButtons[ UPDOWN_BUTTON ] ]->uiFlags &= ~BUTTON_DIRTY;
ButtonList[ iSMPanelButtons[ CLIMB_BUTTON ] ]->uiFlags &= ~BUTTON_DIRTY;
@@ -7006,7 +7269,12 @@ void DisableSMPpanelButtonsWhenInShopKeeperInterface( BOOLEAN fDontDrawButtons )
//Make sure the mapscreen button is disabled
ButtonList[ iSMPanelButtons[ SM_MAP_SCREEN_BUTTON ] ]->uiFlags &= ~BUTTON_ENABLED;
-
+
+ //DisableButton
+ //if (gGameExternalOptions.fCanJumpThroughWindows == TRUE)
+ //{
+ //ButtonList[ iSMPanelButtons[ HOP_BUTTON ] ]->uiFlags |= BUTTON_FORCE_UNDIRTY; //legion by Jazz
+ //}
ButtonList[ iSMPanelButtons[ STANCEUP_BUTTON ] ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
ButtonList[ iSMPanelButtons[ UPDOWN_BUTTON ] ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
ButtonList[ iSMPanelButtons[ CLIMB_BUTTON ] ]->uiFlags |= BUTTON_FORCE_UNDIRTY;
@@ -7189,6 +7457,120 @@ void GoToMapScreenFromTactical( void )
gfEnteringMapScreen = TRUE;
}
+//-------------Legion by Jazz-----------------------------------
+void BtnOknoCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ INT8 bDirection;
+
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+
+ if ( gpSMCurrentMerc->pathing.bLevel == 1 )
+ {
+ return;
+ }
+
+
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ }
+ else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+
+ if ( FindWindowJumpDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) )
+ {
+ gpSMCurrentMerc->BeginSoldierClimbWindow( );
+ }
+
+ }
+ else if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE )
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ }
+
+}
+
+void BtnFenceCallback(GUI_BUTTON *btn,INT32 reason)
+{
+ BOOLEAN fNearHeigherLevelFence;
+ BOOLEAN fNearLowerLevelFence;
+ INT8 bDirection;
+
+ if (!(btn->uiFlags & BUTTON_ENABLED))
+ return;
+
+ if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
+ {
+ btn->uiFlags |= BUTTON_CLICKED_ON;
+ }
+ else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+
+ GetMercFenceDirection( gpSMCurrentMerc->ubID, &fNearLowerLevelFence, &fNearHeigherLevelFence );
+
+
+ if ( FindFenceDirection( gpSMCurrentMerc, gpSMCurrentMerc->sGridNo, gpSMCurrentMerc->ubDirection, &bDirection ) )
+ {
+ gpSMCurrentMerc->BeginSoldierFence( );
+ }
+
+ }
+ else if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE )
+ {
+ btn->uiFlags &= (~BUTTON_CLICKED_ON );
+ }
+
+}
+
+//----LEGION 2---------
+BOOLEAN HandleKlerykPistolet( SOLDIERTYPE *pSoldier, UINT32 uiHandPos, UINT16 usReplaceItem )
+{
+ BOOLEAN fRefuse = FALSE;
+
+ if ( pSoldier->ubProfile == 57 )
+ {
+ if ( uiHandPos == HANDPOS || uiHandPos == SECONDHANDPOS )
+ {
+ if ( usReplaceItem == NOTHING )
+ {
+ fRefuse = TRUE;
+ }
+ else
+ { //legion
+ // Do we have nothing or the leather vest or kevlar leather vest?
+ if ( usReplaceItem == 4520 ) //zoty pistolet items.xml
+ {
+ // This is good....
+ fRefuse = FALSE;
+ }
+ else
+ {
+ fRefuse = TRUE;
+ }
+ }
+
+ if ( fRefuse )
+ {
+ // Say quote!
+ TacticalCharacterDialogue( pSoldier, 85 );
+ return( TRUE );
+ }
+ }
+ }
+
+ return( FALSE );
+}
+
+
+//-----------
+
+
+//---------------------------------------------
+
// Moved to Weapons.cpp by ADB, rev 1513
/*void HandleTacticalEffectsOfEquipmentChange( SOLDIERTYPE *pSoldier, UINT32 uiInvPos, UINT16 usOldItem, UINT16 usNewItem )
diff --git a/Tactical/Interface Panels.h b/Tactical/Interface Panels.h
index bb0de3bc..7e98e1de 100644
--- a/Tactical/Interface Panels.h
+++ b/Tactical/Interface Panels.h
@@ -18,6 +18,7 @@ typedef enum
MUTE_BUTTON,
SM_DONE_BUTTON,
SM_MAP_SCREEN_BUTTON,
+ //HOP_BUTTON, //Legion by Jazz
NUM_SM_BUTTONS
};
@@ -47,6 +48,7 @@ extern int INTERFACE_CLOCK_Y;
extern int LOCATION_NAME_X;
extern int LOCATION_NAME_Y;
+
BOOLEAN CreateSMPanelButtons( );
void RemoveSMPanelButtons( );
BOOLEAN InitializeSMPanel( );
@@ -155,4 +157,13 @@ UINT8 FindNextMercInTeamPanel( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKLife
// CHRISL: New callback functions for backpack buttons
BOOLEAN ChangeDropPackStatus(SOLDIERTYPE *pSoldier, BOOLEAN newStatus);
+// HEADROCK HAM 4: This variable tells the program what "page" of the description box we are currently looking at.
+// By saving this in memory, we tell the DescBox which background and values to draw, and make sure that we end up
+// on the same page every time we open the description box. UDB buttons allow switching between pages.
+extern UINT8 gubDescBoxPage;
+// Record which line we're looking at. This only applied to the Advanced tab in description boxes.
+extern UINT8 gubDescBoxLine;
+// Record how many lines there are for the current item in the Advanced tab.
+extern UINT8 gubDescBoxTotalAdvLines;
+
#endif
\ No newline at end of file
diff --git a/Tactical/Interface Utils.cpp b/Tactical/Interface Utils.cpp
index 16c9447d..fe75ee35 100644
--- a/Tactical/Interface Utils.cpp
+++ b/Tactical/Interface Utils.cpp
@@ -362,7 +362,7 @@ void DrawItemUIBarEx( OBJECTTYPE *pObject, UINT8 ubStatus, INT16 sXPos, INT16 sY
{
sValue = 0;
OBJECTTYPE* pAttachment = (*pObject)[iter]->GetAttachmentAtIndex( ubStatus - DRAW_ITEM_STATUS_ATTACHMENT1 );
- if (pAttachment) {
+ if (pAttachment->exists()) {
sValue = (*pAttachment)[iter]->data.objectStatus;
}
}
diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp
index ffda5003..b5cc6988 100644
--- a/Tactical/Interface.cpp
+++ b/Tactical/Interface.cpp
@@ -56,6 +56,10 @@
#include "gamesettings.h"
#include "Squads.h"
#include "message.h"
+ #include "strategicmap.h"
+ #include "Queen Command.h"
+ // HEADROCK HAM 4: Included for new CTH indicator
+ #include "weapons.h"
#endif
@@ -83,6 +87,10 @@ int INV_INTERFACE_START_Y;// = ( SCREEN_HEIGHT - INV_INTERFACE_HEIGHT );
#define BUTTON_PANEL_WIDTH 78
#define BUTTON_PANEL_HEIGHT 76
+HIDDEN_NAMES_VALUES zHiddenNames[500]; //legion2 Jazz
+ENEMY_NAMES_VALUES zEnemyName[500];
+ENEMY_RANK_VALUES zEnemyRank[500];
+CIV_NAMES_VALUES zCivGroupName[NUM_CIV_GROUPS];
BOOLEAN gfInMovementMenu = FALSE;
INT32 giMenuAnchorX, giMenuAnchorY;
@@ -90,7 +98,15 @@ INT32 giMenuAnchorX, giMenuAnchorY;
#define PROG_BAR_START_X 5
-#define PROG_BAR_START_Y 2
+//*ddd
+//#define PROG_BAR_START_Y 2
+
+//**ddd{
+// 0
+//#define fSmallSizeProgressbar 1
+INT32 HEIGHT_PROGRESSBAR, PROG_BAR_START_Y;
+//ddd}
+
BOOLEAN gfProgBarActive = FALSE;
UINT8 gubProgNumEnemies = 0;
@@ -99,6 +115,8 @@ UINT8 gubProgCurEnemy = 0;
UINT32 guiPORTRAITICONS;
+UINT32 guiPORTRAITICONS_NV; //legion
+UINT32 guiPORTRAITICONS_GAS_MASK; //legion
typedef struct
{
@@ -189,32 +207,6 @@ typedef enum
INT32 iIconImages[ NUM_ICON_IMAGES ];
-typedef enum
-{
- WALK_ICON,
- SNEAK_ICON,
- RUN_ICON,
- CRAWL_ICON,
- LOOK_ICON,
- ACTIONC_ICON,
- TALK_ICON,
- HAND_ICON,
-
- OPEN_DOOR_ICON,
- EXAMINE_DOOR_ICON,
- LOCKPICK_DOOR_ICON,
- BOOT_DOOR_ICON,
- UNTRAP_DOOR_ICON,
- USE_KEY_ICON,
- USE_KEYRING_ICON,
- EXPLOSIVE_DOOR_ICON,
- USE_CROWBAR_ICON,
-
- CANCEL_ICON,
- NUM_ICONS
-};
-
-
INT32 iActionIcons[ NUM_ICONS ];
// GLOBAL INTERFACE SURFACES
@@ -249,6 +241,13 @@ UINT16 gsDownArrowY;
UINT32 giUpArrowRect;
UINT32 giDownArrowRect;
+// HEADROCK HAM 4: Rectangles for the various CTH displays.
+RECT MagRect;
+RECT AimRect;
+RECT ModeRect;
+RECT APRect;
+// HEADROCK HAM 4: Externed this value which tracks whether we've clicked out final aiming click yet.
+extern BOOLEAN gfDisplayFullCountRing;
void DrawBarsInUIBox( SOLDIERTYPE *pSoldier , INT16 sXPos, INT16 sYPos, INT16 sWidth, INT16 sHeight );
void PopupDoorOpenMenu( BOOLEAN fClosingDoor );
@@ -289,6 +288,18 @@ BOOLEAN InitializeTacticalInterface( )
InitializeSMPanelCoordsOld();
}
+//*ddd{
+ if( gGameExternalOptions.fSmallSizeProgressbar )
+ {
+ HEIGHT_PROGRESSBAR = 7;
+ PROG_BAR_START_Y = 0;
+ }
+ else{
+ HEIGHT_PROGRESSBAR = 20;
+ PROG_BAR_START_Y = 2;
+ }
+//*ddd}
+
/* OK i need to initialize coords here
* Isnt it cool
* any questions? joker
@@ -360,7 +371,7 @@ BOOLEAN InitializeTacticalInterface( )
if( !AddVideoObject( &VObjectDesc, &guiHATCH ) )
AssertMsg(0, "Missing INTERFACE\\hatch.sti" );
- THROWIFFALSE( RegisterItemImages(), L"Registering Item Images failed" );
+ SGP_THROW_IFFALSE( RegisterItemImages(), L"Registering Item Images failed" );
// CHRISL:
// LOAD INTERFACE POCKET SILHOUETTES
@@ -401,18 +412,67 @@ BOOLEAN InitializeTacticalInterface( )
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
- FilenameForBPP("INTERFACE\\portraiticons.sti", VObjectDesc.ImageFile);
- if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS ) )
- AssertMsg(0, "Missing INTERFACE\\portraiticons.sti" );
+
+ //legion 2 jazz
+ if (gGameExternalOptions.fShowTacticalFaceIcons == TRUE)
+ {
+ //additional face icons (legion 2)
+ if (gGameExternalOptions.bTacticalFaceIconStyle == 0)
+ {
+ FilenameForBPP("INTERFACE\\portraiticons_a.sti", VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons_a.sti" );
+ }
+ else if (gGameExternalOptions.bTacticalFaceIconStyle == 1)
+ {
+ FilenameForBPP("INTERFACE\\portraiticons_b.sti", VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons_b.sti" );
+ }
+ else if (gGameExternalOptions.bTacticalFaceIconStyle == 2)
+ {
+ FilenameForBPP("INTERFACE\\portraiticons_c.sti", VObjectDesc.ImageFile);
+
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons_c.sti" );
+ }
+ else if (gGameExternalOptions.bTacticalFaceIconStyle == 3)
+ {
+ FilenameForBPP("INTERFACE\\portraiticons_d.sti", VObjectDesc.ImageFile);
+
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons_d.sti" );
+ }
+ }
+ else
+ {
+ // JA2 classic face icons
+ FilenameForBPP("INTERFACE\\portraiticons.sti", VObjectDesc.ImageFile);
+
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons.sti" );
+ }
+
+
+ //legion
+ if (gGameExternalOptions.fShowTacticalFaceGear == TRUE)
+ {
+ FilenameForBPP("INTERFACE\\portraiticons_NV.sti", VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS_NV ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons_NV.sti" );
+
+ FilenameForBPP("INTERFACE\\portraiticons_GAS_MASK.sti", VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &guiPORTRAITICONS_GAS_MASK ) )
+ AssertMsg(0, "Missing INTERFACE\\portraiticons_GAS_MASK.sti" );
+ }
// LOAD RADIO
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\radio.sti", VObjectDesc.ImageFile);
- if( !AddVideoObject( &VObjectDesc, &guiRADIO ) )
- // AssertMsg(0, "Missing INTERFACE\\bracket.sti" );
+ if( !AddVideoObject( &VObjectDesc, &guiRADIO ) )
AssertMsg(0, "Missing INTERFACE\\radio.sti" );
// LOAD RADIO2
@@ -1463,6 +1523,40 @@ void GetSoldierAboveGuyPositions( SOLDIERTYPE *pSoldier, INT16 *psX, INT16 *psY,
}
}
+void DrawCTHPixelToBuffer( UINT16 *pBuffer, UINT32 uiPitch, INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom, INT16 sPixelX, INT16 sPixelY, UINT16 usColor )
+{
+ ///////////////////////////////////////////////////////////
+ // HEADROCK HAM 4:
+ //
+ // This is a specialized drawing function that's used for the CTH indicator. It makes sure that the
+ // pixel is drawn only within the allowed region (the Tactical Viewport), and never drawn in regions
+ // reserved for other parts of the CTH indicator.
+
+ if (sPixelX < sLeft || sPixelX > sRight || sPixelY < sTop || sPixelY > (sBottom-1))
+ {
+ return;
+ }
+ // Do not draw in other CTH rects!
+ if ((sPixelX >= MagRect.left && sPixelX <= MagRect.right) && (sPixelY >= MagRect.top && sPixelY <= MagRect.bottom))
+ {
+ return;
+ }
+ if ((sPixelX >= AimRect.left && sPixelX <= AimRect.right) && (sPixelY >= AimRect.top && sPixelY <= AimRect.bottom))
+ {
+ return;
+ }
+ if ((sPixelX >= ModeRect.left && sPixelX <= ModeRect.right) && (sPixelY >= ModeRect.top && sPixelY <= ModeRect.bottom))
+ {
+ return;
+ }
+ if ((sPixelX >= APRect.left && sPixelX <= APRect.right) && (sPixelY >= APRect.top && sPixelY <= APRect.bottom))
+ {
+ return;
+ }
+
+
+ pBuffer[sPixelX + uiPitch*sPixelY] = usColor;
+}
//QUOTE_SYSTEM_STRUCT soldierTTInfo;
@@ -1474,10 +1568,12 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
INT32 iBack;
TILE_ELEMENT TileElem;
CHAR16 *pStr;
+ //CHAR16 *pStr2;
CHAR16 NameStr[ 50 ];
UINT16 usGraphicToUse = THIRDPOINTERS1;
BOOLEAN fRaiseName = FALSE;
BOOLEAN fDoName = TRUE;
+ UINT16 iCounter2;
GetSoldier( &pSoldier, usSoldierID );
@@ -1692,21 +1788,84 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
{
if ( fRaiseName )
{
- swprintf( NameStr, L"%s", pSoldier->name );
+
+
+ //legion2 jazz
+ if (pSoldier->ubBodyType == ROBOTNOWEAPON && pSoldier->bTeam == ENEMY_TEAM )
+ {
+ swprintf( NameStr, zGrod[0] );
+ }
+ else if (zHiddenNames[pSoldier->ubProfile].Hidden == TRUE)
+ {
+ swprintf( NameStr,L"???" );
+ }
+ else
+ {
+ swprintf( NameStr, L"%s", pSoldier->name );
+ }
+
+ //Legion
+ if (pSoldier->ubBodyType == TANK_NE || pSoldier->ubBodyType == TANK_NW)
+ {
+ swprintf( NameStr, pVehicleStrings[4] );
+ }
+ else if (zHiddenNames[pSoldier->ubProfile].Hidden == TRUE)
+ {
+ swprintf( NameStr,L"???" );
+ }
+ else
+ {
+ swprintf( NameStr, L"%s", pSoldier->name );
+ }
+ //-------
+
+ //swprintf( NameStr, L"%s", pSoldier->name );
FindFontCenterCoordinates( sXPos, (INT16)( sYPos - 10 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
gprintfdirty( sX, sY, NameStr );
mprintf( sX, sY, NameStr );
}
else
{
+
+ //legion Jazz
+ if (pSoldier->ubBodyType == ROBOTNOWEAPON && pSoldier->bTeam == ENEMY_TEAM )
+ {
+ swprintf( NameStr, zGrod[0] );
+ }
+ else if (zHiddenNames[pSoldier->ubProfile].Hidden == TRUE)
+ {
+ swprintf( NameStr,L"???" );
+ }
+ else
+ {
swprintf( NameStr, L"%s", pSoldier->name );
+ }
+
+ //Legion
+ if (pSoldier->ubBodyType == TANK_NE || pSoldier->ubBodyType == TANK_NW)
+ {
+ swprintf( NameStr, pVehicleStrings[4] );
+ }
+ else if (zHiddenNames[pSoldier->ubProfile].Hidden == TRUE)
+ {
+ swprintf( NameStr,L"???" );
+ }
+ else
+ {
+ swprintf( NameStr, L"%s", pSoldier->name );
+ }
+ //---------------
+
+ //swprintf( NameStr, L"%s", pSoldier->name );
FindFontCenterCoordinates( sXPos, sYPos, (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
gprintfdirty( sX, sY, NameStr );
mprintf( sX, sY, NameStr );
}
}
- if ( pSoldier->ubProfile < FIRST_RPC || pSoldier->ubProfile >= GASTON || RPC_RECRUITED( pSoldier ) || AM_AN_EPC( pSoldier ) || ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
+// if ( pSoldier->ubProfile < FIRST_RPC || pSoldier->ubProfile >= GASTON || RPC_RECRUITED( pSoldier ) || AM_AN_EPC( pSoldier ) || ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) )
+ //new profiles by Jazz
+ if ( gProfilesIMP[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile || gProfilesAIM[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile || gProfilesMERC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile || RPC_RECRUITED( pSoldier ) || AM_AN_EPC( pSoldier ) || ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ))
{
// Adjust for bars!
@@ -1769,6 +1928,88 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 10 ), (INT16)(80 ), 1, pStr, TINYFONT1, &sX, &sY );
gprintfdirty( sX, sY, pStr );
mprintf( sX, sY, pStr );
+
+ //-----------------
+ if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
+ {
+ for( iCounter2 = 0; iCounter2 < 500; iCounter2++ )
+ {
+ if (zEnemyName[iCounter2].Enabled == 1)
+ {
+
+ if ((gWorldSectorX == zEnemyName[iCounter2].SectorX && gWorldSectorY == zEnemyName[iCounter2].SectorY ))
+ {
+ if (NumEnemiesInSector( zEnemyName[iCounter2].SectorX , zEnemyName[iCounter2].SectorY ) && pSoldier->ubProfile == NO_PROFILE && pSoldier->bTeam == 1 )
+ {
+
+ swprintf(NameStr, zEnemyName[iCounter2].szCurGroup);
+
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW );
+
+ //legion2
+ FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
+ gprintfdirty( sX, sY, NameStr );
+ mprintf( sX, sY, NameStr );
+
+ }
+ }
+ }
+ }
+ }
+
+ if (gGameExternalOptions.fEnemyNames == FALSE && gGameExternalOptions.fEnemyRank == TRUE)
+ {
+ for( iCounter2 = 1; iCounter2 < 13; iCounter2++ )
+ {
+ if (zEnemyRank[iCounter2].Enabled == 1)
+ {
+
+ if ( zEnemyRank[iCounter2].Stats == 0 && zEnemyRank[iCounter2].ExpLevel > 0 && pSoldier->ubProfile == NO_PROFILE && pSoldier->bTeam == 1 && pSoldier->stats.bExpLevel == zEnemyRank[iCounter2].ExpLevel )
+ {
+
+ swprintf(NameStr, zEnemyRank[iCounter2].szCurRank);
+
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW );
+
+ //legion2
+ FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
+ gprintfdirty( sX, sY, NameStr );
+ mprintf( sX, sY, NameStr );
+ }
+ }
+ }
+
+ }
+
+
+ if (gGameExternalOptions.fCivGroupName == TRUE)
+ {
+ for( iCounter2 = 1; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
+ {
+ if (zCivGroupName[iCounter2].Enabled == 1)
+ {
+ if (pSoldier->ubProfile == NO_PROFILE && pSoldier->ubCivilianGroup == iCounter2 )
+ {
+
+ swprintf(NameStr, zCivGroupName[iCounter2].szCurGroup);
+
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW );
+
+ //legion2
+ FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
+ gprintfdirty( sX, sY, NameStr );
+ mprintf( sX, sY, NameStr );
+ }
+ }
+ }
+ }
+ //------------
}
}
}
@@ -1802,10 +2043,886 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID )
FindFontCenterCoordinates( sXPos, sYPos, (INT16)(80 ), 1, pStr, TINYFONT1, &sX, &sY );
gprintfdirty( sX, sY, pStr );
mprintf( sX, sY, pStr );
+
+ //-----------------
+ if (gGameExternalOptions.fEnemyNames == TRUE && gGameExternalOptions.fEnemyRank == FALSE)
+ {
+ for( iCounter2 = 0; iCounter2 < 500; iCounter2++ )
+ {
+ if (zEnemyName[iCounter2].Enabled == 1 )
+ {
+
+ if ((gWorldSectorX == zEnemyName[iCounter2].SectorX && gWorldSectorY == zEnemyName[iCounter2].SectorY ))
+ {
+ if (NumEnemiesInSector( zEnemyName[iCounter2].SectorX , zEnemyName[iCounter2].SectorY ) && pSoldier->ubProfile == NO_PROFILE && pSoldier->bTeam == 1 )
+ {
+
+ swprintf(NameStr, zEnemyName[iCounter2].szCurGroup);
+
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW );
+
+ //legion2
+ FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
+ gprintfdirty( sX, sY, NameStr );
+ mprintf( sX, sY, NameStr );
+
+ }
+ }
+ }
+ }
+ }
+
+ if (gGameExternalOptions.fEnemyNames == FALSE && gGameExternalOptions.fEnemyRank == TRUE)
+ {
+ for( iCounter2 = 1; iCounter2 < 13; iCounter2++ )
+ {
+ if (zEnemyRank[iCounter2].Enabled == 1)
+ {
+
+ if ( zEnemyRank[iCounter2].Stats == 0 && zEnemyRank[iCounter2].ExpLevel > 0 && pSoldier->ubProfile == NO_PROFILE && pSoldier->bTeam == 1 && pSoldier->stats.bExpLevel == zEnemyRank[iCounter2].ExpLevel )
+ {
+
+ swprintf(NameStr, zEnemyRank[iCounter2].szCurRank);
+
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW );
+
+ //legion2
+ FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
+ gprintfdirty( sX, sY, NameStr );
+ mprintf( sX, sY, NameStr );
+ }
+ }
+ }
+
+ }
+
+ if (gGameExternalOptions.fCivGroupName == TRUE)
+ {
+ for( iCounter2 = 1; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
+ {
+ if (zCivGroupName[iCounter2].Enabled == 1)
+ {
+
+ if (pSoldier->ubProfile == NO_PROFILE && pSoldier->ubCivilianGroup == iCounter2 )
+ {
+ swprintf(NameStr, zCivGroupName[iCounter2].szCurGroup);
+
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_YELLOW );
+
+ //legion2
+ FindFontCenterCoordinates( sXPos, (INT16)( sYPos + 20 ), (INT16)(80 ), 1, NameStr, TINYFONT1, &sX, &sY );
+ gprintfdirty( sX, sY, NameStr );
+ mprintf( sX, sY, NameStr );
+ }
+ }
+ }
+ }
+ //------------
}
}
+BOOLEAN DrawCTHIndicator()
+{
+ ////////////////////////////////////////////
+ // HEADROCK HAM 4: NCTH Indicator
+ //
+ // The NCTH shooting system is radically different from the old CTH, and as a result it requires a completely
+ // new indicator to show hit-probability. The "Hit Percentage" bar we've all gotten used to in JA2 1.13 is not
+ // doable in NCTH since the hit probability is unknown before the bullet reaches the target distance. Instead,
+ // we use a sort of "reticle" to show the margin of error for our current shot.
+ //
+ // The CTH indicator is made up of several parts:
+ // 1. Outer Circle: This circle shows the margin of error that we would have if Muzzle Accuracy was 0%. In other
+ // words, it indicates the "worst" possible shot with the gun we're holding, given the target's distance.
+ // This circle only gets larger or smaller if the shooter moves closer or further from the target (or
+ // changes weapons...).
+ // 2. Inner Circle+Crosshairs: This indicator shows the margin of error for the shot given all the bonuses from
+ // Base CTH and extra aiming clicks. It is a visual representation of where our bullet may end up once fired.
+ // The bullet can end up anywhere within this smaller circle. The circle gets larger or smaller as we change
+ // the number of applied aiming clicks, add magnification bonuses from a scope, change stance, etcetera.
+ // 3. Additional indicators: These are floating graphical and numerical indicators showing various important
+ // data, such as how many aiming clicks we've applied (and how many we can apply), how many bullets we're
+ // going to fire (in burst/auto mode), and how many APs it's going to cost us. These are generally just
+ // relocation and redesign of existing indicators on the OCTH cursor.
+ if (gCTHDisplay.MuzzleSwayPercentage < 0 || gCTHDisplay.MuzzleSwayPercentage > 99 || gCTHDisplay.FinalMagFactor < 1.0)
+ {
+ // Obviously Uninitialized.
+ return 0;
+ }
+
+ INT32 iBack;
+
+ // Find the shooter.
+ SOLDIERTYPE *pSoldier;
+ GetSoldier( &pSoldier, gusSelectedSoldier );
+
+ // Create a Background Rect for us to draw our indicator on. With NCTH, the size and position of this rectangle
+ // is equal exactly to the size of the tactical screen viewport. Unlike the OCTH indicator, the NCTH one can grow
+ // so large as to fill the entire screen.
+ INT16 sLeft = gsVIEWPORT_START_X;
+ INT16 sTop = gsVIEWPORT_WINDOW_START_Y;
+ INT16 sRight = gsVIEWPORT_END_X;
+ INT16 sBottom = gsVIEWPORT_WINDOW_END_Y;
+
+ iBack = RegisterBackgroundRect(BGND_FLAG_SINGLE, NULL, sLeft, sTop, sRight, sBottom);
+
+ if ( iBack != -1 )
+ {
+ SetBackgroundRectFilled( iBack );
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: New CTH, Aperture Size
+ //
+ // As explained above, the most important part of the new indicator is the Aperture circle/crosshairs.
+ // These indicate the size of the "margin of error" for our current shot. The more accurate we are,
+ // the smaller the circle will be.
+ //
+ // The player uses this to determine whether the shot has a good likelyhood to hit the target.
+ // If the circle is the same size or smaller than the target itself, then hit probability is 100%.
+ // The larger it gets, the less hit probability there will be. When adding extra aiming clicks,
+ // the circle gets proportionally smaller. The idea is to try to make it as small as the target
+ // (if possible) to ensure a hit.
+ //
+ // Shot aperture is calculated using the CTH formula (CalcChanceToHitGun). Scopes and lasers
+ // can help decrease the size of the aperture further.
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////
+ // Define colors
+ UINT8 ColorsRed[10] = { 255, 255, 255, 255, 255, 255, 255, 255, 173, 0 };
+ UINT8 ColorsGreen[10] = { 0, 50, 81, 101, 133, 174, 211, 243, 255, 255 };
+
+ // Select the color of the indicator circles
+ UINT16 usCApertureBar;
+ if (pSoldier->bDoAutofire && fAutofireBulletsMode)
+ {
+ // When autofire bullets mode is selected, the CTH display goes greyish. This indicates to the player
+ // that the aiming levels have been set, and further right-clicks will only add bullets to the volley.
+ usCApertureBar = Get16BPPColor( FROMRGB( 180, 180, 180 ) );
+ }
+ else
+ {
+ // Indicator changes color from red to yellow to green, based on how well the gun is aimed.
+ usCApertureBar = Get16BPPColor( FROMRGB( ColorsRed[gCTHDisplay.MuzzleSwayPercentage/10], ColorsGreen[gCTHDisplay.MuzzleSwayPercentage/10], 0 ) ); // Crosshair color shifts from red (longshot) to green (Accurate shot)
+ }
+
+ UINT16 usCApertureBorder = Get16BPPColor( FROMRGB( 10, 10, 10 ) ); // Boundaries in dark color.
+
+ //////////////////////////////////
+ // Calculate Aperture
+
+ // Calculate the center point of the shooter, in world coordinates.
+ FLOAT dStartX = (FLOAT) CenterX( gCTHDisplay.iShooterGridNo );
+ FLOAT dStartY = (FLOAT) CenterY( gCTHDisplay.iShooterGridNo );
+
+ // Calculate the center point of the target, in world coordinates.
+ FLOAT dEndX = (FLOAT) CenterX( gCTHDisplay.iTargetGridNo );
+ FLOAT dEndY = (FLOAT) CenterY( gCTHDisplay.iTargetGridNo );
+
+ // Calculate a delta: the difference between the shooter and target.
+ FLOAT dDeltaX = dEndX - dStartX;
+ FLOAT dDeltaY = dEndY - dStartY;
+
+ // Calculate the distance of the shot, using Pythagorean Theorem
+ DOUBLE d2DDistance = sqrt( (DOUBLE) (dDeltaX * dDeltaX + dDeltaY * dDeltaY ));
+ // Round it upwards.
+ INT32 iDistance = (INT32) d2DDistance;
+ if ( d2DDistance != iDistance )
+ {
+ iDistance += 1;
+ d2DDistance = (FLOAT) ( iDistance);
+ }
+
+ // Calculate the Distance Ratio. This will increase or decrease the size of the Shooting Aperture based
+ // on both distance and Magnification Factor.
+ FLOAT iDistanceRatio = (FLOAT)(d2DDistance / gGameCTHConstants.NORMAL_SHOOTING_DISTANCE);
+ FLOAT iFinalRatio = iDistanceRatio / gCTHDisplay.FinalMagFactor;
+
+ ///////////////////////////////////////////////////////////
+ // Now we calculate the Aperture size. This is done using the same method as the shooting formula uses.
+
+ // Calculate the maximum angle of any shot.
+ DOUBLE ddMaxAngleRadians = (gGameCTHConstants.DEGREES_MAXIMUM_APERTURE * 6.283) / 360;
+
+ // Calculate the size of a "normal" aperture. This is how wide a shot can go at 1x Normal Distance.
+ FLOAT iBasicAperture = (FLOAT)((sin(ddMaxAngleRadians) * gGameCTHConstants.NORMAL_SHOOTING_DISTANCE) * 2); // The *2 compensates for the difference between CellXY and ScreenXY
+
+ // Calculate the Maximum Aperture. This is the margin of error for the "worst" shot we can have given the
+ // target's actual distance. This will later be used to draw the Outer Circle around the target.
+ FLOAT iMaxAperture = iBasicAperture * iDistanceRatio;
+
+ // Calculate the aperture for our shot by applying both distance and scope magnification (which work against each
+ // other) to the size of a normal aperture.
+ FLOAT iAperture = iBasicAperture * iFinalRatio;
+
+ // Apply CTH to the aperture to find out how much smaller it's become thanks to skills and extra aiming.
+ UINT8 actualPct = __min(gCTHDisplay.MuzzleSwayPercentage,99);
+ iAperture = ((100 - actualPct) * iAperture) / 100;
+
+ /////////////////////////////////////////////
+ // Factor in Gun Accuracy. Note that I may remove this at a later time.
+
+ INT16 sAccuracy = GetGunAccuracy( &(pSoldier->inv[ pSoldier->ubAttackingHand ]) );
+
+ sAccuracy = __max(0, sAccuracy);
+ sAccuracy = __min(100, sAccuracy);
+
+ FLOAT iBulletDev = (gGameCTHConstants.MAX_BULLET_DEV * (100-sAccuracy)) / 100;
+ iBulletDev *= iDistanceRatio;
+
+ // Since bullet dev is only affected by distance, we add it last as a flat modifier.
+ iBasicAperture += iBulletDev;
+ iMaxAperture += iBulletDev;
+ iAperture += iBulletDev;
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Calculate Screen Positions
+ //
+ // Aperture Size has to be translated into on-screen size. We also want to track the position of the
+ // mouse so that our indicator moves with it like a cursor.
+
+ // Z Offset is used to move the indicator up or down. It's currently set to 0 since it's not required ATM.
+ FLOAT zOffset = 0;
+
+ // Calculate the position of the mouse cursor and store it.
+ INT16 sStartScreenX;
+ INT16 sStartScreenY;
+
+ POINT MousePos;
+ GetCursorPos(&MousePos);
+ ScreenToClient(ghWindow, &MousePos); // In window coords!
+
+ sStartScreenX = (INT16)MousePos.x;
+ sStartScreenY = (INT16)MousePos.y;
+
+ // Define regions for the various indicators. We need to do this now because the Aperture Circles will want to
+ // avoid being drawn within these regions, otherwise they might make them harder to see.
+
+ MagRect.left = sStartScreenX-50; MagRect.top = sStartScreenY-15; MagRect.right = sStartScreenX-20; MagRect.bottom = sStartScreenY-5;
+ APRect.left = sStartScreenX+22; APRect.top = sStartScreenY-15; APRect.right = sStartScreenX+52; APRect.bottom = sStartScreenY-5;
+ AimRect.left = sStartScreenX-35; AimRect.top = sStartScreenY+22; AimRect.right = sStartScreenX+35; AimRect.bottom = sStartScreenY+30;
+ ModeRect.left = sStartScreenX-28; ModeRect.top = sStartScreenY+31; ModeRect.right = sStartScreenX+28; ModeRect.bottom = sStartScreenY+41;
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // DRAW ADDITIONAL COMPONENTS:
+ //
+ // We now draw additional indicators on top of the circles. There are four indicators:
+ //
+ // 1. AP Cost: The current AP cost for the shot has been moved from the center of the
+ // targeting cursor to avoid obscuring the meeting point of the aperture crosshairs.
+ // It is now displayed in the top right, together with the word "AP".
+ // 2. MAG Factor: The current Magnification or Projection factor for the shot is displayed
+ // in the top-left, followed by an "x". Its color indicates whether we are using the
+ // full potential of our aiming device.
+ // 3. Aiming Pips: The circles on the old indicator shows how many aiming clicks we've
+ // placed into the shot. Now that the circles are used to indicate shot probability,
+ // the aiming clicks are displayed with a series of pips below the targeting cursor
+ // which fill up as we add levels.
+ // 4. Bullet Count: This indicator, now below the Aiming Pips indicator, shows the number
+ // of bullets queues up for a Burst/Autofire volley. For autofire, it starts out by
+ // displaying grey bullets showing how many we CAN add, then fills up with colored
+ // bullets as we add them to the volley. A "+" sign is added if space for bullets runs out.
+
+ CHAR16 pStr[10];
+
+ INT16 curX = 0;
+ INT16 curY = 0;
+
+ /////////////////////////////////////////
+ // Load image STI
+ UINT32 guiCTHImage;
+ VOBJECT_DESC VObjectDesc;
+
+ VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
+ if(UsingNewCTHSystem() == true)
+ FilenameForBPP("CURSORS\\CUR_CTH_NCTH.sti", VObjectDesc.ImageFile);
+ else
+ FilenameForBPP("CURSORS\\CUR_CTH.sti", VObjectDesc.ImageFile);
+ CHECKF(AddVideoObject(&VObjectDesc, &guiCTHImage));
+
+ /////////////// AP COST FOR CURRENT SHOT
+ {
+ // Create a pointer to the Frame Buffer which we are going to draw directly into.
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ // Find coordinates, using the full string ("XX AP")
+ swprintf( pStr, L"%d %s", gsCurrentActionPoints, gzNCTHlabels[ 1 ] );
+ FindFontCenterCoordinates( (INT16)APRect.left, (INT16)APRect.top, (INT16)APRect.right-(INT16)APRect.left, 10, pStr, TINYFONT1, &curX, &curY);
+ // Find width of this string.
+ UINT16 usTotalWidth = StringPixLength ( pStr, TINYFONT1 );
+
+ // Cut string to just the number of APs
+ swprintf( pStr, L"%d", gsCurrentActionPoints );
+ // Find out how wide this string is
+ UINT16 usWidth = StringPixLength( pStr, TINYFONT1 );
+ // Draw to screen
+ gprintfdirty( curX, curY, pStr );
+ mprintf( curX, curY, pStr);
+
+ // Draw the "AP" label 4 pixels forward.
+ SetFontForeground(FONT_MCOLOR_LTYELLOW);
+ swprintf( pStr, L"%s", gzNCTHlabels[ 1 ] );
+ curX += usWidth + 4;
+ gprintfdirty( curX, curY, pStr );
+ mprintf( curX, curY, pStr);
+
+ // Redefine area size based on total width plus a margin of 2 pixels.
+ usTotalWidth = usTotalWidth + 6;
+ INT16 sCenter = (INT16)((APRect.right + APRect.left) / 2);
+ APRect.left = sCenter - (usTotalWidth / 2);
+ APRect.right = sCenter + (usTotalWidth / 2);
+ }
+
+ /////////////// MAG FACTOR
+ {
+ SetFont( TINYFONT1 );
+
+ // Find coordinates, using full string ("X.X x")
+ swprintf( pStr, L"%1.1f x", gCTHDisplay.FinalMagFactor );
+ FindFontCenterCoordinates( (INT16)MagRect.left, (INT16)MagRect.top, (INT16)MagRect.right-(INT16)MagRect.left, 10, pStr, TINYFONT1, &curX, &curY);
+ // Find width of this string.
+ UINT16 usTotalWidth = StringPixLength ( pStr, TINYFONT1 );
+
+ // Cut string to just the float
+ swprintf( pStr, L"%1.1f", gCTHDisplay.FinalMagFactor );
+ // Record the width of the float
+ UINT16 usWidth = StringPixLength( pStr, TINYFONT1 );
+
+ ////////////////////////////
+ // We change the color of this indicator based on whether or not our optical devices are working
+ // at full potential. Remember that scopes below their best range give out penalties!
+
+ // If using a scope below its optimal range...
+ if (gCTHDisplay.ScopeMagFactor > 1.0 && gCTHDisplay.ScopeMagFactor > gCTHDisplay.FinalMagFactor)
+ {
+ // If within projection range...
+ if (gCTHDisplay.ProjectionFactor > 1.0 && gCTHDisplay.ProjectionFactor >= iDistanceRatio )
+ {
+ SetFontForeground( FONT_ORANGE );
+ }
+ // If only using a scope...
+ else
+ {
+ SetRGBFontForeground( 255, 150, 150 ); // Bright Pink
+ }
+ }
+ // If using a scope above its range, or a laser below its range
+ else if ((gCTHDisplay.ScopeMagFactor > 1.0 && gCTHDisplay.ScopeMagFactor <= iDistanceRatio) ||
+ (gCTHDisplay.ProjectionFactor > 1.0 && gCTHDisplay.ProjectionFactor >= iDistanceRatio) )
+ {
+ SetRGBFontForeground( 100,255,100 ); // True Light Green
+ }
+ // In all other circumstances...
+ else
+ {
+ SetFontForeground( FONT_MCOLOR_WHITE );
+ }
+
+ // Print the float
+ gprintfdirty( curX, curY, pStr );
+ mprintf( curX, curY, pStr);
+
+ // Add an "x" 4 pixels forward.
+ SetFontForeground( FONT_MCOLOR_LTYELLOW );
+ swprintf( pStr, L"x" );
+ curX += usWidth + 4;
+ gprintfdirty( curX, curY, pStr );
+ mprintf( curX, curY, pStr);
+
+ // Redefine area size based on total width plus a margin of 2 pixels.
+ usTotalWidth = usTotalWidth + 6;
+ INT16 sCenter = (INT16)((MagRect.right + MagRect.left) / 2);
+ MagRect.left = sCenter - (usTotalWidth / 2);
+ MagRect.right = sCenter + (usTotalWidth / 2);
+ }
+
+ //////////////////// BURST/AUTO LABEL AND BULLETS
+ if (pSoldier->bDoBurst)
+ {
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // We need to calculate how many bullets to display, and how much space they
+ // take, so that we can center them horizontally on the CTH indicator.
+ // This works slightly differently for Autofire and Burst.
+
+ UINT8 ubNumBullets = 0;
+ UINT8 ubBulletWidth = 4;
+ UINT8 ubTotalWidth = 0;
+ UINT32 uiMaxAutofire = 0;
+ UINT32 uiMaxBulletsToDisplay = 0;
+ UINT32 uiSpacesToDisplay = 0;
+
+ if (pSoldier->bDoAutofire)
+ {
+ // Number of COLORED bullets to display is the number of bullets we want to fire.
+ ubNumBullets = pSoldier->bDoAutofire;
+
+ // How many bullets are left in the gun?
+ UINT32 uiBulletsLeft = pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft;
+
+ UINT32 uiCurBullet = uiBulletsLeft;
+ while( uiCurBullet > 0 )
+ {
+ // We work backwards from the total number of bullets left, to find out the number of bullets
+ // that can be fired given the current number of APs left.
+
+ // Store Soldier Autofire variable into a temp. We do this to fool the AP Calculation formula.
+ UINT8 TempDoAutofire = pSoldier->bDoAutofire;
+ pSoldier->bDoAutofire = uiCurBullet;
+
+ //Get AP cost to fire this many bullets
+ INT16 sAPCosts = CalcTotalAPsToAttack( pSoldier, gCTHDisplay.iTargetGridNo, TRUE, pSoldier->aiData.bShownAimTime);
+
+ // Switch back.
+ pSoldier->bDoAutofire = TempDoAutofire;
+
+ // Have we reached a number of bullets that can be fired with the current APs?
+ if( !uiMaxAutofire && EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ // Set it.
+ uiMaxAutofire = uiCurBullet;
+ }
+
+ //Decrement until zero.
+ uiCurBullet--;
+ }
+
+ // Display no more than X bullets on screen!
+ uiMaxBulletsToDisplay = __min(uiMaxAutofire, 15);
+
+ // Calculate how many spaces to display. Currently, a space is displayed after every 5 bullets.
+ uiSpacesToDisplay = (uiMaxBulletsToDisplay-1) / 5;
+
+ // Calculate the total width of this display in pixels. Spaces and bullets have the same width.
+ ubTotalWidth = ubBulletWidth * (uiMaxBulletsToDisplay + uiSpacesToDisplay);
+ }
+ else
+ {
+ // Number of COLORED bullets to display is the number of bullets we want to fire.
+ ubNumBullets = GetShotsPerBurst( &(pSoldier->inv[ pSoldier->ubAttackingHand ]) );
+
+ // Display no more than X bullets on screen!
+ uiMaxBulletsToDisplay = __min(ubNumBullets, 15);
+
+ // Calculate how many spaces to display. Currently, a space is displayed after every 5 bullets.
+ uiSpacesToDisplay = (uiMaxBulletsToDisplay-1) / 5;
+
+ // Calculate the total width of this display in pixels. Spaces and bullets have the same width.
+ ubTotalWidth = ubBulletWidth * (uiMaxBulletsToDisplay + uiSpacesToDisplay);
+ }
+
+ // Tracks the number of spaces we've drawn on screen so far.
+ UINT16 usNumSpacesShown = 0;
+
+ // AUTO FIRE
+ if (pSoldier->bDoAutofire)
+ {
+ // Draw greyed-out bullets, indicating how many bullets CAN be added to the volley given our
+ // current remaining APs.
+ for (UINT8 x = 0; x < (uiMaxBulletsToDisplay); x++)
+ {
+ // Find starting point for drawing
+ INT16 sLeft = (((INT16)ModeRect.left + (INT16)ModeRect.right)/2) - (ubTotalWidth/2);
+ INT16 sTop = (INT16)ModeRect.top;
+
+ // If we've drawn 5,10,15,etc. bullets, add a space.
+ if (x > 0 && x%5 == 0)
+ {
+ usNumSpacesShown++;
+ }
+
+ // Offset adds up the number of bullets and spaces we've already drawn.
+ INT16 sCurOffset = ubBulletWidth * (x+usNumSpacesShown);
+
+ // Draw a bullet here!
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 8, sLeft + sCurOffset, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+
+ // If the number of bullets that can be fired is greater than the number of bullets we can display,
+ // and we've just now drawn the last displayable bullet, then...
+ if (x == uiMaxBulletsToDisplay-1 && uiMaxBulletsToDisplay < uiMaxAutofire)
+ {
+ // Draw a shaded plus sign at the end.
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 9, sLeft + sCurOffset + ubBulletWidth, sTop+2, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+
+ // Draw colored bullets. These show how many bullets we've set to fire with the current volley.
+ usNumSpacesShown = 0;
+ for (UINT8 x = 0; x < ubNumBullets; x++)
+ {
+ // Set start point for drawing
+ INT16 sLeft = (((INT16)ModeRect.left + (INT16)ModeRect.right)/2) - (ubTotalWidth/2);
+ INT16 sTop = (INT16)ModeRect.top;
+
+ // Calculate offset based on the number of bullets and spaces already drawn.
+ INT16 sCurOffset = ubBulletWidth * (x+usNumSpacesShown);
+
+ // If we're drawing more bullets than can be displayed on-screen...
+ if (x == uiMaxBulletsToDisplay)
+ {
+ // Draw a colored plus sign at the end.
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 10, sLeft + sCurOffset, sTop+2, VO_BLT_SRCTRANSPARENCY, NULL );
+ // Set x to NumBullets to end the loop
+ x = ubNumBullets;
+ }
+ else
+ {
+ // If we've drawn 5,10,15,etc. bullets, increase the number of spaces drawn.
+ if (x > 0 && x%5 == 0)
+ {
+ usNumSpacesShown++;
+ }
+ // Recalculate offset to take any new spaces into account.
+ INT16 sCurOffset = ubBulletWidth * (x+usNumSpacesShown);
+ // Draw a colored bullet here.
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 7, sLeft + sCurOffset, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+
+ // Redefine area size based on total width plus a margin of 2 pixels.
+ ubTotalWidth = ubTotalWidth + 6;
+ INT16 sCenter = (INT16)((ModeRect.right + ModeRect.left) / 2);
+ ModeRect.left = sCenter - (ubTotalWidth / 2);
+ ModeRect.right = sCenter + (ubTotalWidth / 2);
+
+ }
+ // BURST FIRE
+ else
+ {
+ // Draw colored bullets. These show how many bullets we've set to fire with the current burst.
+ usNumSpacesShown = 0;
+ UINT16 usTotalWidth = 0;
+ UINT8 x;
+ for (x = 0; x < ubNumBullets; x++)
+ {
+ // Set start point for drawing
+ INT16 sLeft = (((INT16)ModeRect.left + (INT16)ModeRect.right)/2) - (ubTotalWidth/2);
+ INT16 sTop = (INT16)ModeRect.top;
+
+ // Calculate offset based on the number of bullets and spaces already drawn.
+ INT16 sCurOffset = ubBulletWidth * (x+usNumSpacesShown);
+
+ // If we're drawing more bullets than can be displayed on-screen...
+ if (x == uiMaxBulletsToDisplay)
+ {
+ // Draw a colored plus sign at the end.
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 10, sLeft + sCurOffset, sTop+2, VO_BLT_SRCTRANSPARENCY, NULL );
+ // Set x to NumBullets to end the loop
+ x = ubNumBullets;
+ usTotalWidth += 5;
+ }
+ else
+ {
+ // If we've drawn 5,10,15,etc. bullets, increase the number of spaces drawn.
+ if (x > 0 && x%5 == 0)
+ {
+ usNumSpacesShown++;
+ }
+ // Recalculate offset to take any new spaces into account.
+ INT16 sCurOffset = ubBulletWidth * (x+usNumSpacesShown);
+ // Draw a colored bullet here.
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 7, sLeft + sCurOffset, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+ usTotalWidth += ubBulletWidth * ((x+1)+usNumSpacesShown)+4;
+ INT16 sCenter = (INT16)((ModeRect.right + ModeRect.left) / 2);
+ ModeRect.left = sCenter - (ubTotalWidth / 2);
+ ModeRect.right = sCenter + (ubTotalWidth / 2);
+ }
+ }
+
+ /////////////// SINGLE-SHOT.
+ else
+ {
+ // Draw a label that says "SINGLE" instead of bullets.
+ SetFont( TINYFONT1 );
+ SetFontBackground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_MCOLOR_WHITE );
+
+ swprintf( pStr, gzNCTHlabels[ 0 ] );
+ FindFontCenterCoordinates( (INT16)ModeRect.left, (INT16)ModeRect.top, (INT16)ModeRect.right-(INT16)ModeRect.left, 10, pStr, TINYFONT1, &curX, &curY);
+ gprintfdirty( curX, curY, pStr );
+ mprintf( curX, curY, pStr);
+
+ UINT16 usTotalWidth = StringPixLength( pStr, TINYFONT1 ) + 6;
+ INT16 sCenter = (INT16)((ModeRect.right + ModeRect.left) / 2);
+ ModeRect.left = sCenter - (usTotalWidth / 2);
+ ModeRect.right = sCenter + (usTotalWidth / 2);
+ }
+
+ /////////////// AIM LEVELS
+ {
+ // Calculate number of allowed aiming levels on this gun.
+ INT8 ubAllowedLevels = AllowedAimingLevels( pSoldier, gCTHDisplay.iTargetGridNo );
+
+ // Number of ticks to display, and the number of spaces between them.
+ UINT8 ubNumTicks = ((ubAllowedLevels-1)*2)+1;
+ UINT8 ubNumSpaces = ubNumTicks-1;
+
+ // Width of the tick image plus (or minus) a mandatory margin.
+ UINT8 ubAimTickWidth = 5;
+
+ // Total width of the aiming display if using no extra spacing and MAXIMUM allowed aiming levels (currently 8)
+ UINT8 ubAimMaxTotalWidth = ubAimTickWidth * ((8 * 2)-1);
+
+ // Total width of the aiming display if using no extra spacing and as many levels as allowed by the gun.
+ UINT8 ubAimPlainWidth = ubAimTickWidth * ubNumTicks;
+
+ // Find the largest space width possible without exceeding the maximum width. We do this by
+ // finding the difference between MaxTotal width and Plain width, and dividing it by the number of spaces
+ // we've got.
+ UINT8 ubAimFinalOffset = 0;
+ UINT8 ubAimFinalWidth = 0;
+ if (ubNumSpaces > 0)
+ {
+ UINT8 ubAimBestOffset = (ubAimMaxTotalWidth - ubAimPlainWidth) / ubNumSpaces;
+
+ // Final offset is whichever is smallest - the largest width, or the width of a single tick.
+ ubAimFinalOffset = __min(ubAimBestOffset, ubAimTickWidth);
+ }
+ // else leave at 0
+
+ ubAimFinalOffset += ubAimTickWidth;
+
+ // Final width of the entire display, taking all ticks and spaces into account.
+ ubAimFinalWidth = ubAimTickWidth + (ubAimFinalOffset * ubNumSpaces);
+
+ // Find offset from center.
+ UINT8 ubAimLeftOffset = ubAimFinalWidth / 2;
+
+ // Find starting coordinates for this display
+ sTop = (INT16)AimRect.top;
+ sLeft = (INT16)((AimRect.left+AimRect.right)/2) - ubAimLeftOffset;
+
+ // Draw empty ticks.
+ for (UINT8 x = 0; x < (ubAllowedLevels*2)-1; x++)
+ {
+ INT16 sOffset = x * ubAimFinalOffset;
+ if (gfDisplayFullCountRing)
+ {
+ if (ubAllowedLevels - abs((ubAllowedLevels-(x+1))) >= pSoldier->aiData.bShownAimTime)
+ {
+ // Red empty tick - unusable aim level with current AP!
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 6, sLeft + sOffset, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ else
+ {
+ // Orange empty tick - Used aim tick.
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 4, sLeft + sOffset, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+ else
+ {
+ // grey empty tick
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 0, sLeft + sOffset, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+
+ // Draw Filled Ticks
+ if (pSoldier->aiData.bShownAimTime)
+ {
+ // Tick on the left
+ INT16 sNewLeft = sLeft + (ubAimFinalOffset * (pSoldier->aiData.bShownAimTime-1));
+ if (gfDisplayFullCountRing)
+ {
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 5, sNewLeft, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ else
+ {
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 1, sNewLeft, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+
+ // Tick on the right
+ sNewLeft = sLeft + (ubAimFinalOffset * (ubNumSpaces-(pSoldier->aiData.bShownAimTime-1)));
+ if (gfDisplayFullCountRing)
+ {
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 5, sNewLeft, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ else
+ {
+ BltVideoObjectFromIndex( FRAME_BUFFER, guiCTHImage, 1, sNewLeft, sTop, VO_BLT_SRCTRANSPARENCY, NULL );
+ }
+ }
+
+ ubAimFinalWidth += 6;
+ INT16 sCenter = (INT16)((AimRect.right + AimRect.left) / 2);
+ AimRect.left = sCenter - (ubAimFinalWidth / 2);
+ AimRect.right = sCenter + (ubAimFinalWidth / 2);
+
+ }
+
+ // Delete CTH indicator STIs from memory.
+ DeleteVideoObjectFromIndex( guiCTHImage );
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Drawing the CTH indicator to the Frame Buffer
+ //
+ // Early on I ran into issues concerning drawing this indicator on the screen. At first I naturally
+ // wanted to draw it on the Cursor Buffer, the same way as the old indicator. Unfortunately,
+ // the size of the Cursor Buffer is quite limited (~35x35 pixels) and is governed by the size of the STIs used
+ // for the mouse cursor itself. After much trial and error, it became obvious that it was impossible to draw
+ // a large indicator (as required by the NCTH system) directly onto the mouse buffer.
+ //
+ // Fortunately, I found out that it was possible to draw into the Frame Buffer instead, without leaving
+ // graphical glitches behind. I could also dynamically define the area to draw into as I pleased. Furthermore,
+ // I managed to make this drawing behave the same as a mouse cursor would, by having it follow the mouse
+ // position.
+ //
+ // The end result is a bit of an ugly workaround: We're drawing what is essentially a mouse cursor without referring
+ // to ANY part of the mouse cursor system (except the location of the mouse). This is the only way I could make it
+ // work, and so far it works flawlessly.
+
+ // Create a pointer to the Frame Buffer which we are going to draw directly into.
+ UINT32 uiPitch;
+ UINT16 *ptrBuf = (UINT16*)LockVideoSurface( FRAME_BUFFER, &uiPitch );
+ uiPitch >>= 1;
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Begin drawing
+
+ sLeft = gsVIEWPORT_START_X;
+ sTop = gsVIEWPORT_WINDOW_START_Y;
+ sRight = gsVIEWPORT_END_X;
+ sBottom = gsVIEWPORT_WINDOW_END_Y;
+
+ INT16 lastY = 0;
+ INT16 diffY = 0;
+ UINT32 uiAperture = __max(2,(UINT32)iAperture);
+ UINT32 uiMaxAperture = __max(2,(UINT32)iMaxAperture);
+ UINT32 uiApertureBarLength = 10;
+
+ INT32 cnt = 0;
+
+ // Vertical bias makes the circle "flatter" and "wider" in prone and crouched stance.
+ FLOAT dVerticalBias = gGameCTHConstants.VERTICAL_BIAS;
+ switch (gAnimControl[ pSoldier->usAnimState ].ubEndHeight)
+ {
+ case ANIM_STAND:
+ dVerticalBias = 1.0;
+ break;
+ case ANIM_PRONE:
+ // no change
+ break;
+ case ANIM_CROUCH:
+ dVerticalBias = 1.0f + ((dVerticalBias - 1.0f) * 0.66f);
+ break;
+ }
+
+ // Circumference tells us how many pixels to draw, hopefully.
+ FLOAT RADIANS_IN_CIRCLE = (FLOAT)(PI * 2);
+ INT32 Circ = 0;
+
+ Circ = (INT32)((iMaxAperture * RADIANS_IN_CIRCLE) * dVerticalBias);
+ // Draw outer circle
+ for (INT32 iCurPoint = 0; iCurPoint < Circ; iCurPoint++)
+ {
+ curX = (INT16)(iMaxAperture * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ curY = (INT16)((iMaxAperture * dVerticalBias) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ INT16 firstX = curX;
+ INT16 firstY = curY;
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBar );
+
+ // Draw a border circle which is 1 point wider
+ curX = (INT16)((iMaxAperture+1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ curY = (INT16)(((iMaxAperture * dVerticalBias)+1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+
+ if (curX != firstX || curY != firstY)
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder );
+
+ // Draw a border circle which is 1 point narrower
+ curX = (INT16)((iMaxAperture-1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ curY = (INT16)(((iMaxAperture * dVerticalBias)-1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+
+ if (curX != firstX || curY != firstY)
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder );
+ }
+
+ Circ = (INT32)((iAperture * RADIANS_IN_CIRCLE) * dVerticalBias);
+ // Draw inner circle
+ for (INT32 iCurPoint = 0; iCurPoint < Circ; iCurPoint++)
+ {
+ curX = (INT16)(iAperture * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ curY = (INT16)((iAperture * dVerticalBias) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ INT16 firstX = curX;
+ INT16 firstY = curY;
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBar );
+
+ // Draw a border circle which is 1 point wider
+ curX = (INT16)((iAperture+1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ curY = (INT16)(((iAperture * dVerticalBias)+1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+
+ if (curX != firstX || curY != firstY)
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder );
+
+ // Draw a border circle which is 1 point narrower
+ curX = (INT16)((iAperture-1) * cos((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+ curY = (INT16)(((iAperture * dVerticalBias)-1) * sin((iCurPoint * RADIANS_IN_CIRCLE)/Circ));
+
+ if (curX != firstX || curY != firstY)
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+curX, sStartScreenY+curY+(INT16)zOffset, usCApertureBorder );
+ }
+
+ // Aperture Crosshairs
+ for (INT16 cnt = (INT16)(iAperture); cnt <= (INT16)(iAperture + uiApertureBarLength); cnt++)
+ {
+ // Horizontal Aperture Crosshairs
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, sStartScreenY+(INT16)zOffset, usCApertureBar );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, sStartScreenY+(INT16)zOffset, usCApertureBar );
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBar );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+1)+(INT16)zOffset, usCApertureBar );
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBar );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-1)+(INT16)zOffset, usCApertureBar );
+
+ // Darker borders
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY+2)+(INT16)zOffset, usCApertureBorder );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY+2)+(INT16)zOffset, usCApertureBorder );
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+cnt, (sStartScreenY-2)+(INT16)zOffset, usCApertureBorder );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-cnt, (sStartScreenY-2)+(INT16)zOffset, usCApertureBorder );
+
+ }
+ for (INT16 cnt = (INT16)(iAperture * dVerticalBias); cnt <= (INT16)((iAperture * dVerticalBias) + uiApertureBarLength); cnt++)
+ {
+ // Vertical Aperture Crosshairs
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar );
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar );
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBar );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-1, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBar );
+
+ // Darker borders
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+2, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX+2, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder );
+
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-2, (sStartScreenY+cnt)+(INT16)zOffset, usCApertureBorder );
+ DrawCTHPixelToBuffer( ptrBuf, uiPitch, sLeft, sTop, sRight, sBottom, sStartScreenX-2, (sStartScreenY-cnt)+(INT16)zOffset, usCApertureBorder );
+ }
+
+ // Unlock the Frame Buffer.
+ UnLockVideoSurface( FRAME_BUFFER );
+
+ return (TRUE);
+}
void RenderOverlayMessage( VIDEO_OVERLAY *pBlitter )
{
@@ -2303,11 +3420,11 @@ void PopupDoorOpenMenu( BOOLEAN fClosingDoor )
}
else
{
- swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ LOCKPICK_DOOR_ICON ], APBPConstants[AP_PICKLOCK] );
+ swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ LOCKPICK_DOOR_ICON ], GetAPsToPicklock( gOpenDoorMenu.pSoldier ) ); // SANDRO
}
SetButtonFastHelpText( iActionIcons[ LOCKPICK_DOOR_ICON ], zDisp );
- if ( !EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_PICKLOCK], APBPConstants[BP_PICKLOCK], FALSE ) || fClosingDoor || AM_AN_EPC( gOpenDoorMenu.pSoldier ) )
+ if ( !EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToPicklock( gOpenDoorMenu.pSoldier ), APBPConstants[BP_PICKLOCK], FALSE ) || fClosingDoor || AM_AN_EPC( gOpenDoorMenu.pSoldier ) ) // SANDRO
{
DisableButton( iActionIcons[ LOCKPICK_DOOR_ICON ] );
}
@@ -2335,11 +3452,11 @@ void PopupDoorOpenMenu( BOOLEAN fClosingDoor )
}
else
{
- swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ EXPLOSIVE_DOOR_ICON ], APBPConstants[AP_EXPLODE_DOOR] );
+ swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ EXPLOSIVE_DOOR_ICON ], GetAPsToBombDoor( gOpenDoorMenu.pSoldier ) ); // SANDRO
}
SetButtonFastHelpText( iActionIcons[ EXPLOSIVE_DOOR_ICON ], zDisp );
- if ( !EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_EXPLODE_DOOR], APBPConstants[BP_EXPLODE_DOOR], FALSE ) || fClosingDoor || AM_AN_EPC( gOpenDoorMenu.pSoldier ) )
+ if ( !EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToBombDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_EXPLODE_DOOR], FALSE ) || fClosingDoor || AM_AN_EPC( gOpenDoorMenu.pSoldier ) ) // SANDRO
{
DisableButton( iActionIcons[ EXPLOSIVE_DOOR_ICON ] );
}
@@ -2369,7 +3486,7 @@ void PopupDoorOpenMenu( BOOLEAN fClosingDoor )
}
else
{
- swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ CANCEL_ICON + 1 ], APBPConstants[AP_OPEN_DOOR] );
+ swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ CANCEL_ICON + 1 ], GetAPsToOpenDoor( gOpenDoorMenu.pSoldier ) ); // SANDRO
}
}
else
@@ -2380,12 +3497,12 @@ void PopupDoorOpenMenu( BOOLEAN fClosingDoor )
}
else
{
- swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ OPEN_DOOR_ICON ], APBPConstants[AP_OPEN_DOOR] );
+ swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ OPEN_DOOR_ICON ], GetAPsToOpenDoor( gOpenDoorMenu.pSoldier ) ); // SANDRO
}
}
SetButtonFastHelpText( iActionIcons[ OPEN_DOOR_ICON ], zDisp );
- if ( !EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_OPEN_DOOR], APBPConstants[BP_OPEN_DOOR], FALSE ) )
+ if ( !EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToOpenDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_OPEN_DOOR], FALSE ) ) // SANDRO
{
DisableButton( iActionIcons[ OPEN_DOOR_ICON ] );
}
@@ -2456,11 +3573,11 @@ void PopupDoorOpenMenu( BOOLEAN fClosingDoor )
}
else
{
- swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ UNTRAP_DOOR_ICON ], APBPConstants[AP_UNTRAP_DOOR] );
+ swprintf( zDisp, L"%s ( %d )", pTacticalPopupButtonStrings[ UNTRAP_DOOR_ICON ], GetAPsToUntrapDoor( gOpenDoorMenu.pSoldier ) ); // SANDRO
}
SetButtonFastHelpText( iActionIcons[ UNTRAP_DOOR_ICON ], zDisp );
- if ( !EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_UNTRAP_DOOR], APBPConstants[BP_UNTRAP_DOOR], FALSE ) || fClosingDoor || AM_AN_EPC( gOpenDoorMenu.pSoldier ) )
+ if ( !EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToUntrapDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_UNTRAP_DOOR], FALSE ) || fClosingDoor || AM_AN_EPC( gOpenDoorMenu.pSoldier ) ) // SANDRO
{
DisableButton( iActionIcons[ UNTRAP_DOOR_ICON ] );
}
@@ -2577,7 +3694,8 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
{
// Open door normally...
// Check APs
- if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_OPEN_DOOR], APBPConstants[BP_OPEN_DOOR], FALSE ) )
+ // SANDRO - changed APs for opening dorrs calc
+ if ( EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToOpenDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_OPEN_DOOR], FALSE ) )
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
@@ -2635,7 +3753,7 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
if ( uiBtnID == iActionIcons[ LOCKPICK_DOOR_ICON ] )
{
// Lockpick
- if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_PICKLOCK], APBPConstants[BP_PICKLOCK], FALSE ) )
+ if ( EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToPicklock( gOpenDoorMenu.pSoldier ), APBPConstants[BP_PICKLOCK], FALSE ) ) // SANDRO
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
@@ -2669,7 +3787,7 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
if ( uiBtnID == iActionIcons[ EXPLOSIVE_DOOR_ICON ] )
{
// Explode
- if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_EXPLODE_DOOR], APBPConstants[BP_EXPLODE_DOOR], FALSE ) )
+ if ( EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToBombDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_EXPLODE_DOOR], FALSE ) ) // SANDRO
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
@@ -2686,7 +3804,7 @@ void BtnDoorMenuCallback(GUI_BUTTON *btn,INT32 reason)
if ( uiBtnID == iActionIcons[ UNTRAP_DOOR_ICON ] )
{
// Explode
- if ( EnoughPoints( gOpenDoorMenu.pSoldier, APBPConstants[AP_UNTRAP_DOOR], APBPConstants[BP_UNTRAP_DOOR], FALSE ) )
+ if ( EnoughPoints( gOpenDoorMenu.pSoldier, GetAPsToUntrapDoor( gOpenDoorMenu.pSoldier ), APBPConstants[BP_UNTRAP_DOOR], FALSE ) ) // SANDRO
{
// Set UI
SetUIBusy( (UINT8)gOpenDoorMenu.pSoldier->ubID );
@@ -2965,10 +4083,40 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
FLOAT dNumStepsPerEnemy, dLength, dCurSize;
INT16 iProgBarLength = SCREEN_WIDTH - 13;
-
+ //*ddd{
+ STR fn;
+ //*ddd}
memset( &VObjectDesc, 0, sizeof( VObjectDesc ) );
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
+ //* ddd {
+ switch (iResolution)
+ {
+ case 0: //640
+ fn = "INTERFACE\\rect.sti";
+ break;
+ case 1: //800
+ if (gGameExternalOptions.fSmallSizeProgressbar)
+ fn = "INTERFACE\\rect_800x600Thin.sti";
+ else
+ fn = "INTERFACE\\rect_800x600.sti";
+ break;
+ case 2:
+ fn = "INTERFACE\\rect_1024x768.sti";
+ break;
+ default:
+ AssertMsg( 0, "Invalid resolution");
+ return;
+ break;
+ }//switch
+ FilenameForBPP(fn, VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &uiBAR ) ) { sprintf(fn, "Missing %s", fn);
+ AssertMsg(0, fn ); }
+ //*ddd }
+
+
+ //* crappy code commented ddd
+ /*
if (iResolution == 0)
{
FilenameForBPP("INTERFACE\\rect.sti", VObjectDesc.ImageFile);
@@ -2983,11 +4131,38 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
}
if( !AddVideoObject( &VObjectDesc, &uiBAR ) )
- AssertMsg(0, "Missing INTERFACE\\rect.sti" );
+ AssertMsg(0, "Missing INTERFACE\\rect.sti" );
+ */
//if ( gGameOptions.fTurnTimeLimit )
//{
+ //* ddd {
+ switch (iResolution)
+ {
+ case 0: //640
+ fn = "INTERFACE\\timebargreen.sti";
+ break;
+ case 1: //800
+ if (gGameExternalOptions.fSmallSizeProgressbar)
+ fn = "INTERFACE\\timebargreen_800x600Thin.sti";
+ else
+ fn = "INTERFACE\\timebargreen_800x600.sti";
+ break;
+ case 2:
+ fn = "INTERFACE\\timebargreen_1024x768.sti";
+ break;
+ default:
+ AssertMsg( 0, "Invalid resolution");
+ return;
+ break;
+ }//switch
+ FilenameForBPP(fn, VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &uiPLAYERBAR ) ){ sprintf(fn, "Missing %s", fn);
+ AssertMsg(0, fn ); }
+ //*ddd }
+
+ /* commented
if (iResolution == 0)
{
FilenameForBPP("INTERFACE\\timebargreen.sti", VObjectDesc.ImageFile);
@@ -2999,6 +4174,10 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
FilenameForBPP("INTERFACE\\timebargreen_800x600.sti", VObjectDesc.ImageFile);
if( !AddVideoObject( &VObjectDesc, &uiPLAYERBAR ) )
AssertMsg(0, "Missing INTERFACE\\timebargreen_800x600.sti" );
+ if (SMALL_SIZE_PROGRESSBAR)
+ fn = "INTERFACE\\timebargreen_800x600Thin.sti";
+ else
+ fn = "INTERFACE\\timebargreen_800x600.sti";
}
else if (iResolution == 2)
{
@@ -3006,7 +4185,40 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
if( !AddVideoObject( &VObjectDesc, &uiPLAYERBAR ) )
AssertMsg(0, "Missing INTERFACE\\timebargreen_1024x768.sti" );
}
+ else
+ {
+ AssertMsg( 0, "Invalid resolution");
+ return;
+ }
+ */
+
+ //* ddd {
+ switch (iResolution)
+ {
+ case 0: //640
+ fn = "INTERFACE\\timebaryellow.sti";
+ break;
+ case 1: //800
+ if (gGameExternalOptions.fSmallSizeProgressbar)
+ fn = "INTERFACE\\timebaryellow_800x600Thin.sti";
+ else
+ fn = "INTERFACE\\timebaryellow_800x600.sti";
+ break;
+ case 2:
+ fn = "INTERFACE\\timebaryellow_1024x768.sti";
+ break;
+ default:
+ AssertMsg( 0, "Invalid resolution");
+ return;
+ break;
+ }//switch
+ FilenameForBPP(fn, VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &uiINTBAR ) ){ sprintf(fn, "Missing %s", fn);
+ AssertMsg(0, fn ); }
+ //*ddd }
+
+ /*
if (iResolution == 0)
{
FilenameForBPP("INTERFACE\\timebaryellow.sti", VObjectDesc.ImageFile);
@@ -3021,13 +4233,26 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
}
else if (iResolution == 2)
{
- FilenameForBPP("INTERFACE\\timebaryellow_1024x768.sti", VObjectDesc.ImageFile);
- if( !AddVideoObject( &VObjectDesc, &uiINTBAR ) )
- AssertMsg(0, "Missing INTERFACE\\timebaryellow_1024x768.sti" );
+ //*ddd FilenameForBPP("INTERFACE\\timebaryellow_1024x768.sti", VObjectDesc.ImageFile);
+ //*ddd if( !AddVideoObject( &VObjectDesc, &uiINTBAR ) )
+ //*ddd AssertMsg(0, "Missing INTERFACE\\timebaryellow_1024x768.sti" );
+ fn = "INTERFACE\\timebaryellow_1024x768.sti";
}
+ else
+ {
+ AssertMsg( 0, "Invalid resolution");
+ return;
+ }
+
+ FilenameForBPP(fn, VObjectDesc.ImageFile);
+ if( !AddVideoObject( &VObjectDesc, &uiINTBAR ) )
+ AssertMsg(0, String( "Missing %s", VObjectDesc.ImageFile) );
+ */
// Change dest buffer
- SetFontDestBuffer( uiSurface , 0, 0, SCREEN_WIDTH , 20, FALSE );
+ //*ddd
+ //SetFontDestBuffer( uiSurface , 0, 0, SCREEN_WIDTH , 20, FALSE );
+ SetFontDestBuffer( uiSurface , 0, 0, SCREEN_WIDTH , HEIGHT_PROGRESSBAR, FALSE );
SetFont( TINYFONT1 );
switch( ubType )
@@ -3052,7 +4277,7 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
BltVideoObjectFromIndex( uiSurface, uiINTBAR, 0, 0, 0, VO_BLT_SRCTRANSPARENCY, NULL );
SetFontBackground( FONT_MCOLOR_BLACK );
- SetFontForeground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_MCOLOR_WHITE );
SetFontShadow( NO_SHADOW );
uiBarToUseInUpDate = uiINTBAR;
break;
@@ -3069,7 +4294,7 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
// BltVideoObjectFromIndex( uiSurface, uiPLAYERBAR, 13, 0, 0, VO_BLT_SRCTRANSPARENCY, NULL );
//}
SetFontBackground( FONT_MCOLOR_BLACK );
- SetFontForeground( FONT_MCOLOR_BLACK );
+ SetFontForeground( FONT_MCOLOR_WHITE );
SetFontShadow( NO_SHADOW );
uiBarToUseInUpDate = uiPLAYERBAR;
break;
@@ -3194,7 +4419,12 @@ void CreateTopMessage( UINT32 uiSurface, UINT8 ubType, STR16 psString )
}
// Draw text....
- FindFontCenterCoordinates( SCREEN_WIDTH/2, 7, 1, 1, psString, TINYFONT1, &sX, &sY );
+ //*ddd FindFontCenterCoordinates( SCREEN_WIDTH/2, 7, 1, 1, psString, TINYFONT1, &sX, &sY );
+ if(gGameExternalOptions.fSmallSizeProgressbar)
+ FindFontCenterCoordinates( SCREEN_WIDTH/2, 2, 1, 1, psString, TINYFONT1, &sX, &sY );
+ else
+ FindFontCenterCoordinates( SCREEN_WIDTH/2, 7, 1, 1, psString, TINYFONT1, &sX, &sY );
+
mprintf( sX, sY, psString );
// Change back...
@@ -3344,7 +4574,8 @@ void HandleTopMessages( )
}
// Set redner viewport value
- gsVIEWPORT_WINDOW_START_Y = 20;
+ //* ddd gsVIEWPORT_WINDOW_START_Y = 20;
+ gsVIEWPORT_WINDOW_START_Y = HEIGHT_PROGRESSBAR;
// Check if we have scrolled...
if ( gTopMessage.sWorldRenderX != gsRenderCenterX || gTopMessage.sWorldRenderY != gsRenderCenterY )
@@ -3359,9 +4590,15 @@ void HandleTopMessages( )
// Redner!
BltFx.SrcRect.iLeft = 0;
- BltFx.SrcRect.iTop = 20 - gTopMessage.bYPos;
+ //* ddd BltFx.SrcRect.iTop = 20 - gTopMessage.bYPos;
+ if(gGameExternalOptions.fSmallSizeProgressbar)
+ BltFx.SrcRect.iTop = 0;
+ else
+ BltFx.SrcRect.iTop = 20 - gTopMessage.bYPos;
+
BltFx.SrcRect.iRight = SCREEN_WIDTH ;
- BltFx.SrcRect.iBottom = 20;
+ //*ddd BltFx.SrcRect.iBottom = 20;
+ BltFx.SrcRect.iBottom = HEIGHT_PROGRESSBAR;
BltVideoSurface( FRAME_BUFFER, gTopMessage.uiSurface, 0,
0, 0,
@@ -3369,15 +4606,22 @@ void HandleTopMessages( )
// Save to save buffer....
BltFx.SrcRect.iLeft = 0;
- BltFx.SrcRect.iTop = 0;
+ //* ddd BltFx.SrcRect.iTop = 0;
+ if(gGameExternalOptions.fSmallSizeProgressbar)
+ BltFx.SrcRect.iTop = 0;
+ else
+ BltFx.SrcRect.iTop = 20 - gTopMessage.bYPos;
+
BltFx.SrcRect.iRight = SCREEN_WIDTH;
- BltFx.SrcRect.iBottom = 20;
+ //*ddd BltFx.SrcRect.iBottom = 20;
+ BltFx.SrcRect.iBottom = HEIGHT_PROGRESSBAR;
BltVideoSurface( guiSAVEBUFFER, FRAME_BUFFER, 0,
0, 0,
VS_BLT_SRCSUBRECT, &BltFx );
- InvalidateRegion( 0, 0, SCREEN_WIDTH, 20 );
+ //*ddd InvalidateRegion( 0, 0, SCREEN_WIDTH, 20 );
+ InvalidateRegion( 0, 0, SCREEN_WIDTH, HEIGHT_PROGRESSBAR );
gfTopMessageDirty = FALSE;
}
diff --git a/Tactical/Interface.h b/Tactical/Interface.h
index 01b0c80e..9d242e89 100644
--- a/Tactical/Interface.h
+++ b/Tactical/Interface.h
@@ -7,6 +7,80 @@
#define MAX_UICOMPOSITES 4
+enum
+{
+ WALK_ICON,
+ SNEAK_ICON,
+ RUN_ICON,
+ CRAWL_ICON,
+ LOOK_ICON,
+ ACTIONC_ICON,
+ TALK_ICON,
+ HAND_ICON,
+
+ OPEN_DOOR_ICON,
+ EXAMINE_DOOR_ICON,
+ LOCKPICK_DOOR_ICON,
+ BOOT_DOOR_ICON,
+ UNTRAP_DOOR_ICON,
+ USE_KEY_ICON,
+ USE_KEYRING_ICON,
+ EXPLOSIVE_DOOR_ICON,
+ USE_CROWBAR_ICON,
+
+ CANCEL_ICON,
+ NUM_ICONS
+};
+
+#define MAX_ENEMY_NAMES_CHARS 128
+
+typedef struct
+{
+ UINT16 uiIndex; // add
+ BOOLEAN Hidden; //add
+
+} HIDDEN_NAMES_VALUES;
+
+extern HIDDEN_NAMES_VALUES zHiddenNames[500];
+
+typedef struct
+{
+ UINT16 uiIndex;
+ BOOLEAN Enabled;
+ UINT16 ExpLevel;
+ UINT16 Stats;
+ UINT16 StatsMin;
+ UINT16 StatsMax;
+ CHAR16 szCurRank[MAX_ENEMY_NAMES_CHARS];
+
+} ENEMY_RANK_VALUES;
+
+extern ENEMY_RANK_VALUES zEnemyRank[500];
+
+typedef struct
+{
+ UINT16 uiIndex; // add
+ BOOLEAN Enabled; //add
+ UINT16 SectorX; //add
+ UINT16 SectorY; //add
+ CHAR16 szCurGroup[MAX_ENEMY_NAMES_CHARS];
+
+} ENEMY_NAMES_VALUES;
+
+extern ENEMY_NAMES_VALUES zEnemyName[500];
+
+typedef struct
+{
+ UINT16 uiIndex; // add
+ BOOLEAN Enabled; //add
+ BOOLEAN Loyalty;
+ BOOLEAN AddToBattle;
+ CHAR16 szCurGroup[MAX_ENEMY_NAMES_CHARS];
+
+} CIV_NAMES_VALUES;
+
+extern CIV_NAMES_VALUES zCivGroupName[NUM_CIV_GROUPS];
+
extern int INTERFACE_WIDTH; // 640
extern int INTERFACE_HEIGHT; // 120
extern int INV_INTERFACE_HEIGHT; // 140
@@ -84,11 +158,15 @@ extern UINT32 guiSILHOUETTE;
extern UINT32 guiCOMPANEL;
extern UINT32 guiCOMPANELB;
extern UINT32 guiRADIO;
-extern UINT32 guiPORTRAITICONS;
+extern UINT32 guiPORTRAITICONS; // Default JA2 portrait icons (+ additional headgear icons from legion)
extern UINT32 guiBURSTACCUM;
extern UINT32 guiITEMPOINTERHATCHES;
+//legion
+extern UINT32 guiPORTRAITICONS_NV; //legion: NV-Face Graphic
+extern UINT32 guiPORTRAITICONS_GAS_MASK; //legion: GASMASK-Face Graphic
+
extern MOUSE_REGION gViewportRegion;
extern MOUSE_REGION gRadarRegion;
extern MOUSE_REGION gBottomPanalRegion;
@@ -146,9 +224,11 @@ void HandleInterfaceBackgrounds( );
void BeginOverlayMessage( UINT32 uiFont, STR16 pFontString, ... );
void EndOverlayMessage( );
-
void DrawSelectedUIAboveGuy( UINT16 usSoldierID );
+// HEADROCK HAM 4: Draw the CTH indicator, using values grabbed from the global CTH array
+BOOLEAN DrawCTHIndicator();
+
void CreateCurrentTacticalPanelButtons( );
void RemoveCurrentTacticalPanelButtons( );
void SetCurrentTacticalPanelCurrentMerc( UINT8 ubID );
diff --git a/Tactical/InterfaceItemImages.cpp b/Tactical/InterfaceItemImages.cpp
index 76e6195d..ccf6ff76 100644
--- a/Tactical/InterfaceItemImages.cpp
+++ b/Tactical/InterfaceItemImages.cpp
@@ -4,7 +4,7 @@
#include "vobject.h"
#include "utilities.h"
-#include "VFS/vfs.h"
+#include
extern void WriteMessageToFile( const STR16 pString );
@@ -34,7 +34,7 @@ UINT32 MDItemVideoObjects::getVObjectForItem(UINT32 key)
{
return it->second;
}
- THROWEXCEPTION(BuildString().add(L"Item key [").add(key).add(L"] not registered").get());
+ SGP_THROW(_BS(L"Item key not registered : ") << key << _BS::wget);
}
void MDItemVideoObjects::registerItem(UINT32 key, vfs::Path const& sFileName)
@@ -42,7 +42,7 @@ void MDItemVideoObjects::registerItem(UINT32 key, vfs::Path const& sFileName)
std::map::iterator it = m_mapVObjects.find(key);
if(it != m_mapVObjects.end())
{
- THROWEXCEPTION(BuildString().add(L"Item image [").add(key).add(L"] already registered").get());
+ SGP_THROW(_BS(L"Item image already registered : ") << key << _BS::wget);
}
// LOAD INTERFACE GUN PICTURES
UINT32 uiVObject;
@@ -51,7 +51,7 @@ void MDItemVideoObjects::registerItem(UINT32 key, vfs::Path const& sFileName)
FilenameForBPP(const_cast(sFileName.to_string().c_str()), VObjectDesc.ImageFile);
if(! AddVideoObject( &VObjectDesc, &uiVObject ))
{
- THROWEXCEPTION( BuildString().add(L"Could not add video object for file \"").add(sFileName).get() );
+ SGP_THROW(_BS(L"Could not add video object for file \"") << sFileName << _BS::wget);
}
m_mapVObjects.insert(std::make_pair(key,uiVObject));
}
@@ -70,7 +70,7 @@ bool MDItemVideoObjects::registerItemsFromFilePattern(vfs::Path const& sFilePatt
wss.str(it.value()->getName().c_wcs());
if( !(wss >> item) )
{
- std::wstring err = BuildString().add(L"Could not extract item number from file \"").add(wss.str()).add(L"\"").get();
+ std::wstring err = _BS(L"Could not extract item number from file \"") << wss.str() << L"\"" << _BS::wget;
WriteMessageToFile( const_cast(err.c_str()) );
continue;
}
@@ -78,10 +78,9 @@ bool MDItemVideoObjects::registerItemsFromFilePattern(vfs::Path const& sFilePatt
{
this->registerItem(item, it.value()->getPath());
}
- catch(CBasicException& ex)
+ catch(std::exception& ex)
{
- RETHROWEXCEPTION( BuildString().add(L"Registering item from file \"").add(wss.str()).add(L"\" failed").get().c_str(),
- &ex );
+ SGP_RETHROW( _BS(L"Registering item from file \"") << wss.str() << L"\" failed" << _BS::wget, ex );
}
}
return true;
diff --git a/Tactical/InterfaceItemImages.h b/Tactical/InterfaceItemImages.h
index 5dd3d373..1d8c3c62 100644
--- a/Tactical/InterfaceItemImages.h
+++ b/Tactical/InterfaceItemImages.h
@@ -2,8 +2,8 @@
#define _ITERFACEITEMIMAGES_H_
#include "Types.h"
-#include "VFS/vfs_types.h"
-#include "VFS/vfs_path.h"
+#include
+#include
#include
+
+
+
+
@@ -1027,6 +1035,14 @@
RelativePath="XML_EnemyMiscDrops.cpp"
>
+
+
+
+
@@ -1039,6 +1055,10 @@
RelativePath="XML_Explosive.cpp"
>
+
+
@@ -1079,10 +1099,26 @@
RelativePath=".\XML_Profiles.cpp"
>
+
+
+
+
+
+
+
+
diff --git a/Tactical/Tactical_VS2010.vcxproj b/Tactical/Tactical_VS2010.vcxproj
new file mode 100644
index 00000000..8ca6690a
--- /dev/null
+++ b/Tactical/Tactical_VS2010.vcxproj
@@ -0,0 +1,409 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}
+ Win32Proj
+ Tactical
+ Tactical
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters
new file mode 100644
index 00000000..0bf039a5
--- /dev/null
+++ b/Tactical/Tactical_VS2010.vcxproj.filters
@@ -0,0 +1,603 @@
+
+
+
+
+ {b76e83a9-042b-4267-96e0-ffd42052b5d5}
+
+
+ {c1880088-a976-405e-919e-9f1e97ad6701}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp
index 73002e9e..2c5fe004 100644
--- a/Tactical/TeamTurns.cpp
+++ b/Tactical/TeamTurns.cpp
@@ -56,7 +56,6 @@
class OBJECTTYPE;
class SOLDIERTYPE;
#include "connect.h"
-//#include "test_space.h"
extern INT8 STRAIGHT;
//extern UINT8 gubSpeedUpAnimationFactor;
@@ -1023,9 +1022,12 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
// resume interrupted interrupt
//hayden
- if (!is_networked) {
+ if (!is_networked)
+ {
StartInterrupt();
- } else {
+ }
+ else
+ {
UINT8 nubFirstInterrupter;
INT8 nbTeam;
SOLDIERTYPE * npSoldier;
@@ -1043,22 +1045,23 @@ void EndInterrupt( BOOLEAN fMarkInterruptOccurred )
}
else if(is_server && gTacticalStatus.ubCurrentTeam == 1)// against ai
{
-
//hayden
- send_interrupt( npSoldier ); //
- if(nbTeam !=0)intAI(npSoldier);
- else StartInterrupt();//
- //requestAIint( npSoldier );
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"AI is interrupted");
+ send_interrupt( npSoldier );
+
+ if(nbTeam !=0)
+ intAI(npSoldier);
+ else
+ StartInterrupt();
+
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"AI is interrupted");
}
else
{
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for another team"); //may need more work.
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for another team"); //may need more work.
//ClearIntList();
//hayden
StartInterrupt();
send_interrupt( npSoldier ); //
-
}
}
@@ -1565,7 +1568,7 @@ BOOLEAN StandardInterruptConditionsMet( SOLDIERTYPE * pSoldier, UINT8 ubOpponent
// if the soldier isn't currently crouching
if (!PTR_CROUCHED)
{
- ubMinPtsNeeded = APBPConstants[AP_CROUCH];
+ ubMinPtsNeeded = GetAPsCrouch(pSoldier, TRUE); // Changed from APBPConstants[AP_CROUCH] - SANDRO
}
else
{
@@ -1685,7 +1688,7 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
{
if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags &( ANIM_FIREREADY | ANIM_FIRE ) ))
{
- iPoints=(iPoints+WEAPON_READIED_BONUS);
+ iPoints=(iPoints + cWeaponReadyBonus);
}
}
@@ -1734,13 +1737,33 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
iPoints -= 2;
}
- if ( HAS_SKILL_TRAIT( pSoldier, NIGHTOPS ) )
+ if (gGameOptions.fNewTraitSystem) // new/old traits check - SANDRO
{
- bLightLevel = LightTrueLevel(pSoldier->sGridNo, pSoldier->pathing.bLevel);
- if (bLightLevel > NORMAL_LIGHTLEVEL_DAY + 3)
+ if ( HAS_SKILL_TRAIT( pSoldier, NIGHT_OPS_NT ) )
{
- // it's dark, give a bonus for interrupts
- iPoints += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS );
+ bLightLevel = LightTrueLevel(pSoldier->sGridNo, pSoldier->pathing.bLevel);
+ if (bLightLevel > NORMAL_LIGHTLEVEL_DAY + 3)
+ {
+ // it's dark, give a bonus for interrupts
+ iPoints += gSkillTraitValues.ubNOIterruptsBonusInDark;
+ }
+ }
+ // Phlegmatics get a small penalty to interrupts
+ if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
+ {
+ iPoints -= 1;
+ }
+ }
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, NIGHTOPS_OT ) )
+ {
+ bLightLevel = LightTrueLevel(pSoldier->sGridNo, pSoldier->pathing.bLevel);
+ if (bLightLevel > NORMAL_LIGHTLEVEL_DAY + 3)
+ {
+ // it's dark, give a bonus for interrupts
+ iPoints += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS_OT );
+ }
}
}
@@ -2059,9 +2082,12 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter
}
else
{
- if (!is_networked) {
+ if (!is_networked)
+ {
StartInterrupt();
- } else {
+ }
+ else
+ {
UINT8 nubFirstInterrupter;
INT8 nbTeam;
SOLDIERTYPE * npSoldier;
@@ -2072,34 +2098,41 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter
// INTERRUPT is calculated on the server
if ((nbTeam > 0) && (nbTeam <6 ) && is_server) //is for AI and are server
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for AI team");
-
- // Only display the top message if we (the server) got interrupted
- if (pSoldier->bTeam == 0)
- AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ nbTeam ] );
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for AI team");
+
+ // Only display the top message if we (the server) got interrupted
+ if (pSoldier->bTeam == 0)
+ AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ nbTeam ] );
- send_interrupt( npSoldier );
- StartInterrupt();
+ send_interrupt( npSoldier );
+ StartInterrupt();
- }
+ }
// INTERRUPT is calculated on the server
else if(is_server && gTacticalStatus.ubCurrentTeam == 1)// against ai
- {
-
- //hayden
- send_interrupt( npSoldier ); //
- if(nbTeam !=0)intAI(npSoldier);
- else StartInterrupt();//
- //requestAIint( npSoldier );
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"AI is interrupted");
- }
+ {
+ //hayden
+ send_interrupt( npSoldier ); //
+ if(nbTeam !=0)
+ intAI(npSoldier);
+ else
+ StartInterrupt();//
+
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"AI is interrupted");
+ }
// INTERRUPT is calculated on the pure client
else if(gTacticalStatus.ubCurrentTeam == 0)//its our turn (we are moving)
{
+#ifdef BETAVERSION
+
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for another team - pure client - skipping problematic interrupt");
+#endif
+
+ /*
// Only send interrupt if we (the client) got interrupted
send_interrupt( npSoldier );
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for another team");
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"interrupt for another team - PROBLEMATIC");
SOLDIERTYPE* pMerc = MercPtrs[ gusSelectedSoldier ];
//AdjustNoAPToFinishMove( pMerc, TRUE );
@@ -2110,6 +2143,7 @@ void DoneAddingToIntList( SOLDIERTYPE * pSoldier, BOOLEAN fChange, UINT8 ubInter
fInterfacePanelDirty = DIRTYLEVEL2;
AddTopMessage( COMPUTER_INTERRUPT_MESSAGE, TeamTurnString[ nbTeam ] );
gTacticalStatus.fInterruptOccurred = TRUE;
+ */
}
else
{
diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp
index 98bda533..52909be5 100644
--- a/Tactical/Turn Based Input.cpp
+++ b/Tactical/Turn Based Input.cpp
@@ -134,6 +134,9 @@ extern SOLDIERTYPE *gpSMCurrentMerc;
extern INT32 gsOverItemsGridNo;
extern INT16 gsOverItemsLevel;
extern BOOLEAN gfUIShowExitSouth;
+extern BOOLEAN fMiddleButtonDown;
+extern BOOLEAN fX1ButtonDown;
+extern BOOLEAN fX2ButtonDown;
extern INT32 giStartingMemValue;
@@ -149,7 +152,7 @@ extern UINT32 guiVObjectSize;
extern UINT32 guiVSurfaceSize;
extern BOOLEAN gfNextShotKills;
-
+BOOLEAN fAutofireBulletsMode = FALSE; // HEADROCK HAM 4: Track whether we're adjusting aim or number of bullets
UINT32 guiSoldierFlags;
UINT32 guiUITargetSoldierId = NOBODY;
@@ -185,7 +188,7 @@ SOLDIERTYPE *gpExchangeSoldier2;
BOOLEAN ConfirmActionCancel( INT32 usMapPos, INT32 usOldMapPos );
BOOLEAN gfNextFireJam = FALSE;
-
+INT16 brstmode = 0; //dddd
extern INT16 ITEMDESC_START_X;
extern INT16 ITEMDESC_START_Y;
#include "fresh_header.h"
@@ -249,10 +252,19 @@ extern void DetermineWhichMilitiaControlMenusCanBeShown( void ); //lalien
// The_Bob - real time sneaking, 01-06-09
extern BOOLEAN WeSeeNoOne(void); // Needed to control entering turn-based with ctrl-x
+void QueryTBMButton( UINT32 *puiNewEvent );
+void QueryTBWheel( UINT32 *puiNewEvent );
+void QueryTBX1Button( UINT32 *puiNewEvent );
+void QueryTBX2Button( UINT32 *puiNewEvent );
+
void GetTBMouseButtonInput( UINT32 *puiNewEvent )
{
QueryTBLeftButton( puiNewEvent );
QueryTBRightButton( puiNewEvent );
+ QueryTBWheel( puiNewEvent );
+ QueryTBMButton( puiNewEvent );
+ QueryTBX1Button( puiNewEvent );
+ QueryTBX2Button( puiNewEvent );
}
void QueryTBLeftButton( UINT32 *puiNewEvent )
@@ -636,6 +648,8 @@ void QueryTBLeftButton( UINT32 *puiNewEvent )
{
// ATE: Reset refine aim..
pSoldier->aiData.bShownAimTime = 0;
+ // HEADROCK HAM 4: Reset Autofire Bullets mode.
+ fAutofireBulletsMode = FALSE;
if ( gsCurrentActionPoints == 0 )
{
@@ -655,6 +669,13 @@ void QueryTBLeftButton( UINT32 *puiNewEvent )
case CONFIRM_ACTION_MODE:
+ // HEADROCK HAM 4: If in Autofire Mode, first click puts us in bullet adjust mode.
+ if (UsingNewCTHSystem() == true && GetSoldier( &pSoldier, gusSelectedSoldier ))
+ if (pSoldier->bDoAutofire && !fAutofireBulletsMode)
+ fAutofireBulletsMode = TRUE;
+ else
+ *puiNewEvent = CA_MERC_SHOOT;
+ else
*puiNewEvent = CA_MERC_SHOOT;
break;
@@ -1104,6 +1125,8 @@ void GetTBMousePositionInput( UINT32 *puiNewEvent )
if ( MercPtrs[ gusUIFullTargetID ]->bTeam != gbPlayerNum )
{
fOnValidGuy = TRUE;
+ //ddd , \ ( )
+ brstmode = 0;
}
else
{
@@ -1380,31 +1403,30 @@ void GetPolledKeyboardInput( UINT32 *puiNewEvent )
}
- if( _KeyDown( DEL ) )
+ if( _KeyDown( DEL ) && !fDeleteDown)
{
- DisplayCover(TRUE);
+ SwitchToEnemyView();
fDeleteDown = TRUE;
}
if( !_KeyDown( DEL ) && fDeleteDown )
{
- //EMPTY
+ SwitchViewOff();
fDeleteDown = FALSE;
}
- if( _KeyDown( END ) )
+ if( _KeyDown( END ) && !fEndDown)
{
- //EMPTY
+ SwitchToMercView();
fEndDown = TRUE;
}
if( !_KeyDown( END ) && fEndDown )
{
- //EMPTY
- SwitchCoverDrawMode();
+ SwitchViewOff();
fEndDown = FALSE;
}
@@ -1607,23 +1629,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
}
}
-
-
-
- if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == '0') )
- {
- //if( InputEvent.usKeyState & ALT_DOWN )
- {
- if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) )
- {
- test_func2();
- }
- }
- }
-
-
-
if ((InputEvent.usEvent == KEY_DOWN )&& ( InputEvent.usParam == 'e') )
{
@@ -2306,18 +2312,10 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
case '9':
ChangeCurrentSquad( 8 );
-
- if (is_networked)
- cheat_func();
- break;
-
+
case '0':
ChangeCurrentSquad( 9 );
-
- if (is_networked)
- //test_func2();
- break;
-
+
case 'x':
if ( !fCtrl && !fAlt )
@@ -2370,7 +2368,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
if (!is_networked)
{
// ctrl-x: enter turn based while sneaking - check if RT sneak is on, iw we're not already in combat and if we actually see any enemies
- if (gGameExternalOptions.fAllowRealTimeSneak)
+ if (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK]) // changed by SANDRO
{
BOOLEAN fSneakingInRealTime = true;
@@ -2400,9 +2398,10 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
{
if (!is_networked)
{
- if (gGameExternalOptions.fAllowRealTimeSneak)
+ // SANDRO - changed the real time sneak switch to be in the preferences
+ if (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK])
{
- gGameExternalOptions.fAllowRealTimeSneak = false;
+ gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] = false;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_SNEAKING_OFF]);
if( !WeSeeNoOne() ) // if we're sneaking up on someone, enter turn-based
@@ -2410,7 +2409,7 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
else
{
- gGameExternalOptions.fAllowRealTimeSneak = true;
+ gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] = true;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_RTM_SNEAKING_ON]);
}
}
@@ -2579,10 +2578,28 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
}
break;
-
+ case 'J':
case 'j':
+ if ( fShift )
+ {
+ INT8 bDirection;
- if( fAlt )
+ if (gGameExternalOptions.fCanJumpThroughWindows == TRUE )
+ {
+ SOLDIERTYPE *lSoldier;
+
+ if ( GetSoldier( &lSoldier, gusSelectedSoldier ) )
+ {
+ if ( FindWindowJumpDirection( lSoldier, lSoldier->sGridNo, lSoldier->ubDirection, &bDirection ) )
+ {
+ lSoldier->BeginSoldierClimbWindow( );
+ }
+
+ }
+
+ }
+ }
+ else if( fAlt )
{
if ( CHEATER_CHEAT_LEVEL( ) )
{
@@ -2598,6 +2615,47 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
#endif
}
+ //ddd{ .
+// else if(_KeyDown( SHIFT ))
+// {
+//INT16 sGridNo;
+//STRUCTURE * pStructure;
+
+//GetMouseMapPos( &sGridNo );
+//ScreenMsg( FONT_MCOLOR_LTYELLOW,0, L"gubMerkCanSeeThisTile=%d,gubWorldTileInLight=%d,los=%d",gubMerkCanSeeThisTile[sGridNo],gubWorldTileInLight[sGridNo],gGameSettings.ubSizeOfLOS);
+//
+
+ // SOLDIERTYPE *pjSoldier;
+ // BOOLEAN fNearHeigherLevel;
+ // BOOLEAN fNearLowerLevel;
+ // INT8 bDirection;
+
+ // if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) )
+ // {
+ // // CHRISL: Turn off manual jumping while wearing a backpack
+ // if(UsingNewInventorySystem() == true && pjSoldier->inv[BPACKPOCKPOS].exists() == true)
+ // break;
+
+ // // Make sure the merc is not collapsed!
+ // if (!IsValidStance(pjSoldier, ANIM_CROUCH) )
+ // {
+ // if ( pjSoldier->bCollapsed && pjSoldier->bBreath < OKBREATH )
+ // {
+ // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 4 ], pjSoldier->name );
+ // }
+
+ // break;
+ // }
+ // GetMercOknoDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel );
+ // if ( FindOknoDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
+ // {
+ // BeginSoldierOkno( pjSoldier );
+ // }
+
+
+ // }
+
+ //}//ddd}
else
{
SOLDIERTYPE *pjSoldier;
@@ -2637,6 +2695,14 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
{
pjSoldier->BeginSoldierClimbFence( );
}
+
+ if (gGameExternalOptions.fCanClimbOnWalls == TRUE )
+ {
+ if ( FindFenceDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
+ {
+ pjSoldier->BeginSoldierFence( );
+ }
+ }
}
}
break;
@@ -2735,6 +2801,9 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
break;
+ case 'C':
+ ToggleEnemyView();
+ break;
case 'd':
if( gTacticalStatus.uiFlags & TURNBASED && gTacticalStatus.uiFlags & INCOMBAT )
{
@@ -2911,16 +2980,27 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
break;
case 'D':
- if ( gGameSettings.fOptions[TOPTION_DROP_ALL] )
+ // SANDRO - changed from drop all to enable soldier tooltips
+ if ( gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] )
{
- gGameSettings.fOptions[TOPTION_DROP_ALL] = FALSE;
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_OFF ] );
+ gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] = FALSE;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SOLDIER_TOOLTIPS_OFF ] );
}
else
{
- gGameSettings.fOptions[TOPTION_DROP_ALL] = TRUE;
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_ON ] );
+ gGameSettings.fOptions[ TOPTION_ALLOW_SOLDIER_TOOLTIPS ] = TRUE;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SOLDIER_TOOLTIPS_ON ] );
}
+ // if ( gGameSettings.fOptions[TOPTION_DROP_ALL] )
+ // {
+ // gGameSettings.fOptions[TOPTION_DROP_ALL] = FALSE;
+ // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_OFF ] );
+ // }
+ // else
+ // {
+ // gGameSettings.fOptions[TOPTION_DROP_ALL] = TRUE;
+ // ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DROP_ALL_ON ] );
+ // }
break;
case 'q':
if ( gGameSettings.fOptions[TOPTION_GL_HIGH_ANGLE] )
@@ -3593,6 +3673,11 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
}
}
}
+ //CHRISL: if not enough ammo in sector, reload using ammo carried in inventory
+ if ( (*pGun)[0]->data.gun.ubGunShotsLeft < GetMagSize( pGun ) )
+ {
+ AutoReload( pTeamSoldier );
+ }
}
}
}
@@ -3872,6 +3957,8 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
// Get life back
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
pSoldier->bBleeding = 0;
+ // SANDRO - erase insta-healable injury
+ pSoldier->iHealableInjury = 0;
fInterfacePanelDirty = DIRTYLEVEL2;
}
@@ -3906,9 +3993,13 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
DisplayGameSettings( );
break;
+
+ case 'V':
+ ToggleMercView();
+ break;
+
case 'w':
case 'W':
-
if( fAlt )
{
if ( CHEATER_CHEAT_LEVEL( ) )
@@ -5099,7 +5190,7 @@ void HandleHandCursorClick( INT32 usMapPos, UINT32 *puiNewEvent )
}
// Steal!
- sAPCost = GetAPsToStealItem( pSoldier, sActionGridNo );
+ sAPCost = GetAPsToStealItem( pSoldier, MercPtrs[ gusUIFullTargetID ], sActionGridNo ); // SANDRO - added target variable
if ( EnoughPoints( pSoldier, sAPCost, 0, TRUE ) )
{
@@ -5699,35 +5790,40 @@ void PopupMilitiaControlMenu( SOLDIERTYPE *pSoldier )
INT32 PickPocket(MERCPROFILESTRUCT *pProfile, UINT8 ppStart, UINT8 ppStop, UINT16 usItem, UINT8 iNumber, UINT8 * cap);
-bool BadGoggles(SOLDIERTYPE *pTeamSoldier) {
+bool BadGoggles(SOLDIERTYPE *pTeamSoldier)
+{
// WDS - Smart goggle switching
// NOTE: Investigate using GetItemVisionRangeBonus from Items.cpp???
- if (!gGameExternalOptions.smartGoggleSwitch) {
+ if (!gGameExternalOptions.smartGoggleSwitch)
return false;
- } else {
+ else
+ {
// Look through the head slots and find any sort of goggle. Check if it is bad for this time of day.
- for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot) {
- if ( (Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus > 0) && !DayTime() ) {
- return true;
- } else if ( (Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus > 0) && DayTime() ) {
- return true;
+ // silversurfer: also check if we are underground, sun goggles and night vision bonus are useless underground
+ for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot)
+ {
+ // check if we are below ground
+ if ( pTeamSoldier->bSectorZ > 0 )
+ {
+ // we don't want a cave vision penalty
+ if ( Item[pTeamSoldier->inv[headSlot].usItem].cavevisionrangebonus < 0 )
+ return true;
}
- }
-
- // Find the best goggles for the current time of day anywhere in inventory
- OBJECTTYPE * pGoggles = 0;
- if (DayTime()) {
- pGoggles = FindSunGogglesInInv( pTeamSoldier, TRUE );
- } else {
- pGoggles = FindNightGogglesInInv( pTeamSoldier, TRUE );
- }
-
- if (pGoggles) {
- // Check that the player is actually wearing them
- for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot) {
- if (!(pTeamSoldier->inv[headSlot] == *pGoggles)) {
-// return true;
+
+ // if we are above ground
+ else
+ {
+ // at night we don't want a night vision penalty
+ if ( NightTime() )
+ {
+ if ( Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus < 0 )
+ return true;
}
+ // at daytime we don't want a day vision penalty
+ // also if we have a bright light penalty make sure that is doesn't exceed the day vision bonus
+ else if ( Item[pTeamSoldier->inv[headSlot].usItem].dayvisionrangebonus < 0 ||
+ ( Item[pTeamSoldier->inv[headSlot].usItem].dayvisionrangebonus + Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus ) < 0 )
+ return true;
}
}
}
@@ -5745,12 +5841,22 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
for (int headSlot = HEAD1POS; headSlot <= HEAD2POS; ++headSlot)
{
- if ( (Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus > 0) )
+ if ( (Item[pTeamSoldier->inv[headSlot].usItem].brightlightvisionrangebonus != 0) )
{
slotToUse = headSlot;
break;
}
- else if ( (Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus > 0) )
+ if ( (Item[pTeamSoldier->inv[headSlot].usItem].dayvisionrangebonus != 0) )
+ {
+ slotToUse = headSlot;
+ break;
+ }
+ else if ( (Item[pTeamSoldier->inv[headSlot].usItem].nightvisionrangebonus != 0) )
+ {
+ slotToUse = headSlot;
+ break;
+ }
+ else if ( (Item[pTeamSoldier->inv[headSlot].usItem].cavevisionrangebonus != 0) )
{
slotToUse = headSlot;
break;
@@ -5768,8 +5874,9 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
}
// Find the best goggles for the current time of day anywhere in inventory
+ // silversurfer: also check if underground
OBJECTTYPE * pGoggles = 0;
- if (DayTime())
+ if (DayTime() && pTeamSoldier->bSectorZ == 0)
{
pGoggles = FindSunGogglesInInv( pTeamSoldier, TRUE );
}
@@ -5795,8 +5902,8 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
// No goggles to equip, should the current ones be unequiped?
if (pTeamSoldier->inv[slotToUse].exists())
{
- if ((DayTime() && (Item[pTeamSoldier->inv[slotToUse].usItem].nightvisionrangebonus > 0)) ||
- (!DayTime() && (Item[pTeamSoldier->inv[slotToUse].usItem].brightlightvisionrangebonus > 0)))
+ if ((DayTime() && Item[pTeamSoldier->inv[slotToUse].usItem].nightvisionrangebonus > 0 && pTeamSoldier->bSectorZ == 0) ||
+ ((!DayTime() || pTeamSoldier->bSectorZ > 0) && (Item[pTeamSoldier->inv[slotToUse].usItem].brightlightvisionrangebonus > 0)))
{
// It's day and we're wearing night goggles (or vice-versa), find a place to stash them
if (pTeamSoldier->inv[ HELMETPOS ].exists())
@@ -5807,32 +5914,36 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
}
else
{
+ /* //If we're here we already know we can't attach, don't we?
// Try dumping it anywhere in inventory because it doesn't attach to the helmet
- if (ValidAttachment( pTeamSoldier->inv[slotToUse].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
+ if (NASValidAttachment( pTeamSoldier->inv[slotToUse].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
pTeamSoldier->inv[slotToUse][0]->attachments.size() < MAX_ATTACHMENTS)
{
pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE, 0 );
}
else
- {
+ */
+ //{
// Remove sungoggles.
PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE);
- }
+ //}
}
}
else
{
+ /* //again useless?
// Try dumping it anywhere in inventory given there's no helemt
- if (ValidAttachment( pTeamSoldier->inv[slotToUse].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
+ if (NASValidAttachment( pTeamSoldier->inv[slotToUse].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
pTeamSoldier->inv[slotToUse][0]->attachments.size() < MAX_ATTACHMENTS)
{
pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE, 0 );
}
else
- {
+ */
+ //{
// Remove sungoggles.
PlaceInAnyPocket(pTeamSoldier, &pTeamSoldier->inv[slotToUse], FALSE);
- }
+ //}
}
}
}
@@ -5877,7 +5988,7 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
- if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
+ if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
@@ -5893,11 +6004,12 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
// wearing, to avoid situations where a character refuses to remove the wrong set of goggles and
// thus suffers a penalty.
else
- {
- if (ValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
- pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ { //WarmSteel - This has become more complicated to check, it's better to just try and see if it works.
+ //if (NASValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
+ // pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS )
+ if (pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 ) )
{
- pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 );
+ //pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 );
break;
}
else
@@ -5941,11 +6053,11 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
// wearing, to avoid situations where a character refuses to remove the wrong set of goggles and
// thus suffers a penalty.
else
- {
- if (ValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
- pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ { //WarmSteel - Again, better to just try and see if it works.
+ //if (NASValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
+ // pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ if (pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 ))
{
- pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 );
break;
}
else
@@ -5966,6 +6078,7 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
pObj = &(pTeamSoldier->inv[gear]);
for(attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
+ if(iter->exists()){
if(DayTime() == TRUE && Item[iter->usItem].brightlightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
{
pGoggles = &(*iter);
@@ -5976,6 +6089,7 @@ void SwapGoggles(SOLDIERTYPE *pTeamSoldier)
pGoggles = &(*iter);
bestBonus = Item[iter->usItem].nightvisionrangebonus;
}
+ }
}
if(pGoggles)
{
@@ -6057,7 +6171,7 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
- if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
+ if ( Item[ iter->usItem ].nightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].nightvisionrangebonus;
@@ -6070,11 +6184,11 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
break;
}
else if (Item[pTeamSoldier->inv[bSlot1].usItem].nightvisionrangebonus <= 0)
- {
- if (ValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
- pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ { //WarmSteel - just try and see if it works
+ //if (NASValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
+ // pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ if ( pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 ) )
{
- pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 );
break;
}
else
@@ -6105,7 +6219,7 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
pObj = &(pTeamSoldier->inv[gear]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
- if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE )
+ if ( Item[ iter->usItem ].brightlightvisionrangebonus > bestBonus && Item[ iter->usItem ].usItemClass == IC_FACE && iter->exists())
{
pGoggles = &(*iter);
bestBonus = Item[ iter->usItem ].brightlightvisionrangebonus;
@@ -6118,11 +6232,11 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
break;
}
else if (Item[pTeamSoldier->inv[bSlot1].usItem].brightlightvisionrangebonus <= 0)
- {
- if (ValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
- pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ { //WarmSteel - try
+ //if (NASValidAttachment( pTeamSoldier->inv[bSlot1].usItem, pTeamSoldier->inv[HELMETPOS].usItem ) &&
+ // pTeamSoldier->inv[bSlot1][0]->attachments.size() < MAX_ATTACHMENTS)
+ if ( pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 ) )
{
- pTeamSoldier->inv[HELMETPOS].AttachObject( pTeamSoldier, &pTeamSoldier->inv[bSlot1], FALSE, 0 );
break;
}
else
@@ -6144,15 +6258,17 @@ void SwapGogglesUniformly(SOLDIERTYPE *pTeamSoldier, BOOLEAN fToNightVision)
pObj = &(pTeamSoldier->inv[gear]);
for(attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter)
{
- if(fToNightVision == FALSE && Item[iter->usItem].brightlightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
- {
- pGoggles = &(*iter);
- bestBonus = Item[iter->usItem].brightlightvisionrangebonus;
- }
- else if(fToNightVision == TRUE && Item[iter->usItem].nightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
- {
- pGoggles = &(*iter);
- bestBonus = Item[iter->usItem].nightvisionrangebonus;
+ if(iter->exists()){
+ if(fToNightVision == FALSE && Item[iter->usItem].brightlightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
+ {
+ pGoggles = &(*iter);
+ bestBonus = Item[iter->usItem].brightlightvisionrangebonus;
+ }
+ else if(fToNightVision == TRUE && Item[iter->usItem].nightvisionrangebonus > bestBonus && Item[iter->usItem].usItemClass == IC_FACE)
+ {
+ pGoggles = &(*iter);
+ bestBonus = Item[iter->usItem].nightvisionrangebonus;
+ }
}
}
if(pGoggles)
@@ -6214,6 +6330,9 @@ void SeperateItems()
}
//remove attachments
+ //WarmSteel - This causes a crash when unloading attachments, then sorting, then selling all items in the sector in the map screen.
+ //It is likely to be caused here because when i accidentally broke this part the bug didn't occur.
+ //TODO : fix this.
if ( gGameExternalOptions.gfShiftFRemoveAttachments == TRUE )
{
//CHRISL: We run into a problem here because GetFreeWorldItemIndex, which gets called
@@ -6227,6 +6346,8 @@ void SeperateItems()
while(gWorldItems[uiLoop].object[x]->attachments.size() != cnt)
{
gTempObject = *gWorldItems[uiLoop].object[x]->GetAttachmentAtIndex(cnt);
+
+ //WarmSteel - This actually still works with NAS, be it by accident
if (gWorldItems[ uiLoop ].object.RemoveAttachment(&gTempObject,0,x))
{
AddItemToPool( gWorldItems[ uiLoop ].sGridNo, &gTempObject, 1, gWorldItems[ uiLoop ].ubLevel, WORLD_ITEM_REACHABLE , -1 );
@@ -6236,6 +6357,7 @@ void SeperateItems()
{
cnt++;
}
+
uiLoopCnt ++;
if(uiLoopCnt > 100)
break;
@@ -6327,4 +6449,309 @@ void StackAndSort( BOOLEAN fRestrictToAmmo )
//HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pImpButtonText[11] );
}
-}
\ No newline at end of file
+}
+
+
+
+void QueryTBMButton( UINT32 *puiNewEvent )
+{
+ INT32 sMapPos;
+
+ if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
+ {
+ if (!GetMouseMapPos( &sMapPos ) )
+ return;
+
+ if (gViewportRegion.ButtonState & MSYS_MIDDLE_BUTTON) // MID MOUSE BUTTON
+ {
+ if ( !fMiddleButtonDown )
+ {
+ fMiddleButtonDown = TRUE;
+ //RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
+ }
+ }
+ else if ( fMiddleButtonDown )
+ {
+ if ( _KeyDown( ALT ) )
+ {
+ //
+ if ( ( gpItemPointer == NULL ) &&
+ ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ BURSTMODE_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
+ SetBurstMode();
+ }
+ else
+ {//*puiNewEvent = LC_LOOK;
+ if(gCurrentUIMode == CONFIRM_ACTION_MODE)
+ brstmode=(brstmode==1)?0:1;
+ else{
+ ErasePath( TRUE );
+ *puiNewEvent = LC_ON_TERRAIN;
+ }
+ }
+
+ fMiddleButtonDown = FALSE;
+ // Reset counter
+ //RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
+ }
+ }
+}//void QueryTBMButton( UINT32 *puiNewEvent )
+
+void QueryTBWheel( UINT32 *puiNewEvent )
+{
+ SOLDIERTYPE *pSoldier;
+ INT32 usMapPos=0;
+ UINT8 bID;
+
+ // stub
+ if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
+ {
+ if ( gViewportRegion.WheelState != 0 )
+ {
+ //printf("wheel %d\n", gViewportRegion.WheelState);
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"wheel %d", gViewportRegion.WheelState);
+ if ( gpItemPointer == NULL )
+ {
+ // ATE:
+ if ( gusSelectedSoldier != NOBODY )
+ {
+ // Switch on UI mode
+ switch( gCurrentUIMode )
+ {
+
+ case MOVE_MODE:
+ case CONFIRM_MOVE_MODE:
+
+ if ( !( gTacticalStatus.uiFlags & ENGAGED_IN_CONV ) &&
+ ( ( gsCurInterfacePanel != SM_PANEL ) || ( ButtonList[ iSMPanelButtons[ NEXTMERC_BUTTON ] ]->uiFlags & BUTTON_ENABLED ) ) )
+ {
+ if ( gViewportRegion.WheelState > 0 )
+ {
+ //change stance ->DOWN
+ if ( _KeyDown( ALT ) )
+ { if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
+ GotoLowerStance(MercPtrs[ gusSelectedSoldier ]);
+ break;
+ }
+ if ( gusSelectedSoldier != NOBODY )
+ {
+ bID = FindPrevActiveAndAliveMerc( MercPtrs[ gusSelectedSoldier ], TRUE, TRUE );
+ HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
+ // Center to guy....
+ LocateSoldier( gusSelectedSoldier, SETLOCATOR );
+ }
+ }
+ else
+ {
+
+ //change stance ->UP
+ if ( _KeyDown( ALT ) )
+ { if ( (gusSelectedSoldier != NOBODY) && ( gpItemPointer == NULL ) )
+ GotoHeigherStance( MercPtrs[ gusSelectedSoldier ] );
+ break;
+ }
+
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"wheel %d", gViewportRegion.WheelState);
+ if ( gusSelectedSoldier != NOBODY )
+ { //Select next merc
+ bID = FindNextMercInTeamPanel( MercPtrs[ gusSelectedSoldier ], FALSE, FALSE );
+ HandleLocateSelectMerc( bID, LOCATEANDSELECT_MERC );
+ // Center to guy....
+ LocateSoldier( gusSelectedSoldier, SETLOCATOR );
+ }
+ }
+ //*puiNewEvent = M_ON_TERRAIN; ????????????????
+ }
+
+ case IDLE_MODE:
+ case ACTION_MODE:
+ case LOCKOURTURN_UI_MODE:
+ case LOOKCURSOR_MODE:
+ case LOCKUI_MODE:
+ case TALKCURSOR_MODE:
+ case MENU_MODE:
+ case HANDCURSOR_MODE:
+
+ break;
+
+ case CONFIRM_ACTION_MODE:
+
+ if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
+ {
+ if( gGameExternalOptions.bAimedBurstEnabled )
+ HandleWheelAdjustCursor( pSoldier, usMapPos, -gViewportRegion.WheelState,brstmode );
+ else
+ HandleWheelAdjustCursorWOAB( pSoldier, usMapPos, -gViewportRegion.WheelState);
+ }
+ break;
+ }
+ }
+ }
+ ResetWheelState( &gViewportRegion );
+ }
+ }
+}
+
+void QueryTBX1Button( UINT32 *puiNewEvent )
+{
+ INT32 sMapPos;
+ if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
+ {
+ if (!GetMouseMapPos( &sMapPos ) )
+ return;
+
+ if (gViewportRegion.ButtonState & MSYS_X1_BUTTON) // MID MOUSE BUTTON
+ {
+ if ( !fX1ButtonDown )
+ {
+ fX1ButtonDown = TRUE;
+ //RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
+ }
+ }
+ else if ( fX1ButtonDown )
+ {
+ //*puiNewEvent = LC_LOOK;
+ fX1ButtonDown = FALSE;
+ if ( !_KeyDown( ALT ) && !_KeyDown( SHIFT ))
+ UIHandleChangeLevel( NULL );
+ else if( _KeyDown( SHIFT ) )
+ {
+ SOLDIERTYPE *pjSoldier;
+ BOOLEAN fNearHeigherLevel;
+ BOOLEAN fNearLowerLevel;
+ INT8 bDirection;
+
+ if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) )
+ {
+ // CHRISL: Turn off manual jumping while wearing a backpack
+ if(UsingNewInventorySystem() == true && pjSoldier->inv[BPACKPOCKPOS].exists() == true)
+ return;
+
+ // Make sure the merc is not collapsed!
+ if (!IsValidStance(pjSoldier, ANIM_CROUCH) )
+ {
+ if ( pjSoldier->bCollapsed && pjSoldier->bBreath < OKBREATH )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 4 ], pjSoldier->name );
+ }
+
+ return;
+ }
+ GetMercOknoDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel );
+ if ( FindWindowJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
+ {
+ pjSoldier->BeginSoldierClimbWindow();
+ }
+
+
+ }
+ }
+ else if (_KeyDown( ALT ) )
+ {
+ SOLDIERTYPE *pjSoldier;
+ if ( GetSoldier( &pjSoldier, gusSelectedSoldier ) )
+ {
+ BOOLEAN fNearHeigherLevel;
+ BOOLEAN fNearLowerLevel;
+ INT8 bDirection;
+ // CHRISL: Turn off manual jumping while wearing a backpack
+ if(UsingNewInventorySystem() == true && pjSoldier->inv[BPACKPOCKPOS].exists() == true)
+ return;
+
+ // Make sure the merc is not collapsed!
+ if (!IsValidStance(pjSoldier, ANIM_CROUCH) )
+ {
+ if ( pjSoldier->bCollapsed && pjSoldier->bBreath < OKBREATH )
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[ 4 ], pjSoldier->name );
+ return;
+ }
+
+ GetMercClimbDirection( pjSoldier->ubID, &fNearLowerLevel, &fNearHeigherLevel );
+
+ if ( fNearLowerLevel )
+ pjSoldier->BeginSoldierClimbDownRoof( );
+
+ if ( fNearHeigherLevel )
+ pjSoldier->BeginSoldierClimbUpRoof( );
+
+ if ( FindFenceJumpDirection( pjSoldier, pjSoldier->sGridNo, pjSoldier->ubDirection, &bDirection ) )
+ pjSoldier->BeginSoldierClimbFence( );
+ }
+
+ }//else
+
+ }
+ }
+}
+void QueryTBX2Button( UINT32 *puiNewEvent )
+{
+ INT32 sMapPos;
+ if ( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA )
+ {
+ if (!GetMouseMapPos( &sMapPos ) )
+ return;
+
+ if (gViewportRegion.ButtonState & MSYS_X2_BUTTON) // MID MOUSE BUTTON
+ {
+ if ( !fX2ButtonDown )
+ {
+ fX2ButtonDown = TRUE;
+ //RESETCOUNTER( RMOUSECLICK_DELAY_COUNTER );
+ }
+ }
+ else if ( fX2ButtonDown )
+ {
+ fX2ButtonDown = FALSE;
+
+ if ( _KeyDown( ALT ) )
+ AutoReload( MercPtrs[ gusSelectedSoldier ] );
+ else
+ // Toggle squad's stealth mode.....
+ // For each guy on squad...
+ {
+ SOLDIERTYPE *pTeamSoldier;
+ INT8 bLoop;
+ BOOLEAN fStealthOn = FALSE;
+
+ // Check if at least one guy is on stealth....
+ for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
+ {
+ if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) )
+ {
+ if ( pTeamSoldier->bStealthMode )
+ {
+ fStealthOn = TRUE;
+ }
+ }
+ }
+
+ fStealthOn = !fStealthOn;
+
+ for (bLoop=gTacticalStatus.Team[gbPlayerNum].bFirstID, pTeamSoldier=MercPtrs[bLoop]; bLoop <= gTacticalStatus.Team[gbPlayerNum].bLastID; bLoop++, pTeamSoldier++)
+ {
+ if ( OK_CONTROLLABLE_MERC( pTeamSoldier ) && pTeamSoldier->bAssignment == CurrentSquad( ) && !AM_A_ROBOT( pTeamSoldier ) )
+ {
+ if ( gpSMCurrentMerc != NULL && bLoop == gpSMCurrentMerc->ubID )
+ {
+ gfUIStanceDifferent = TRUE;
+ }
+
+ pTeamSoldier->bStealthMode = fStealthOn;
+ }
+ }
+
+ fInterfacePanelDirty = DIRTYLEVEL2;
+
+ // OK, display message
+ if ( fStealthOn )
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_ON_STEALTHMODE ] );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_SQUAD_OFF_STEALTHMODE ] );
+ }
+ }
+ }
+
+ }
+}
diff --git a/Tactical/UI Cursors.cpp b/Tactical/UI Cursors.cpp
index 0479d085..a7da93ab 100644
--- a/Tactical/UI Cursors.cpp
+++ b/Tactical/UI Cursors.cpp
@@ -29,6 +29,8 @@
#include "GameSettings.h"
#include "Interactive Tiles.h"
#include "PATHAI.H"
+ #include "SkillCheck.h" // added by SANDRO
+ #include "message.H" //ddd
#endif
//forward declarations of common classes to eliminate includes
@@ -334,7 +336,8 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
UINT16 reverse = 0;
- UINT8 maxAimLevels = AllowedAimingLevels(pSoldier);
+ // HEADROCK HAM 4: Required for new Aiming Level Limit function
+ UINT8 maxAimLevels = AllowedAimingLevels(pSoldier, usMapPos);
usInHand = pSoldier->inv[ HANDPOS ].usItem;
@@ -579,26 +582,83 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
// and also a Targetted Bodypart indicator.
if(pSoldier->bDoAutofire == 0 && gGameSettings.fOptions[ TOPTION_CTH_CURSOR ])
{
- if (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 2)
+ if(UsingNewCTHSystem() == true)
{
- // Burst mode only
- OBJECTTYPE * pInHand;
- pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
- // Burst size
- gbCtHBurstCount = GetShotsPerBurst(pInHand);
- UINT8 i, saveDoBurst;
- // Save original burst value (should be 1 always, before the burst has been fired, but
- // this is just a failsafe
- saveDoBurst = pSoldier->bDoBurst;
+ //AXP 29.03.2007: Rooftop CtH fix. See below.
+ INT8 bTempTargetLevel = pSoldier->bTargetLevel;
+ pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
- // For each bullet in the burst
- for (i=0;iaiData.bShownAimTime, pSoldier->bAimShotLocation );
+ // HEADROCK HAM B2.7: CTH approximation?
+ if (gGameExternalOptions.fApproximateCTH)
+ {
+ uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
+ }
+ gfUICtHBar = TRUE;
+ gCTHDisplay.MuzzleSwayPercentage = (gCTHDisplay.MuzzleSwayPercentage + uiHitChance)/2;
+ gCTHDisplay.iShooterGridNo = pSoldier->sGridNo;
+ gCTHDisplay.iTargetGridNo = usMapPos;
+
+ // Calculate distance to target
+ FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( usMapPos ));
+ FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( usMapPos ));
+ FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
+
+ CalcMagFactorSimple( pSoldier, d2DDistance, pSoldier->aiData.bShownAimTime );
+
+ pSoldier->bTargetLevel = bTempTargetLevel;
+ }
+ else
+ {
+ if (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 2)
+ {
+ // Burst mode only
+ OBJECTTYPE * pInHand;
+ pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+ // Burst size
+ gbCtHBurstCount = GetShotsPerBurst(pInHand);
+ UINT8 i, saveDoBurst;
+ // Save original burst value (should be 1 always, before the burst has been fired, but
+ // this is just a failsafe
+ saveDoBurst = pSoldier->bDoBurst;
+
+ // For each bullet in the burst
+ for (i=0;ibTargetLevel;
+ pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
+
+ // Calculate hit chance (using the current bDoBurst for burst-penalty calculations)
+ UINT32 uiHitChance;
+ uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
+ // HEADROCK HAM B2.7: CTH approximation?
+ if (gGameExternalOptions.fApproximateCTH)
+ {
+ uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
+ }
+
+ pSoldier->bTargetLevel = bTempTargetLevel;
+
+ // Put result (burst CTH) into the array
+ gbCtH[i] = (gbCtH[i]+uiHitChance)/2;
+
+ // Increase burst size, so that the next time we run CalcChanceToHitGun we'll get a lower
+ // result, based on our Burst Penalty
+ pSoldier->bDoBurst++;
+ }
+ // Reset original burst status
+ pSoldier->bDoBurst = saveDoBurst;
+ // Activate CTH bar display
+ gfUICtHBar = TRUE;
+ }
+ else // One "BASE CTH" bar, JA2 1.13 vanilla
{
//AXP 29.03.2007: Rooftop CtH fix. See below.
INT8 bTempTargetLevel = pSoldier->bTargetLevel;
pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
- // Calculate hit chance (using the current bDoBurst for burst-penalty calculations)
UINT32 uiHitChance;
uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
// HEADROCK HAM B2.7: CTH approximation?
@@ -609,37 +669,10 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
pSoldier->bTargetLevel = bTempTargetLevel;
- // Put result (burst CTH) into the array
- gbCtH[i] = (gbCtH[i]+uiHitChance)/2;
-
- // Increase burst size, so that the next time we run CalcChanceToHitGun we'll get a lower
- // result, based on our Burst Penalty
- pSoldier->bDoBurst++;
+ gfUICtHBar = TRUE;
+ gbCtH[0] = (gbCtH[0]+uiHitChance)/2;
+ gbCtHBurstCount = 1;
}
- // Reset original burst status
- pSoldier->bDoBurst = saveDoBurst;
- // Activate CTH bar display
- gfUICtHBar = TRUE;
- }
- else // One "BASE CTH" bar, JA2 1.13 vanilla
- {
- //AXP 29.03.2007: Rooftop CtH fix. See below.
- INT8 bTempTargetLevel = pSoldier->bTargetLevel;
- pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
-
- UINT32 uiHitChance;
- uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
- // HEADROCK HAM B2.7: CTH approximation?
- if (gGameExternalOptions.fApproximateCTH)
- {
- uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
- }
-
- pSoldier->bTargetLevel = bTempTargetLevel;
-
- gfUICtHBar = TRUE;
- gbCtH[0] = (gbCtH[0]+uiHitChance)/2;
- gbCtHBurstCount = 1;
}
}
@@ -648,17 +681,15 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
else if(pSoldier->bDoAutofire > 0 && gGameSettings.fOptions[ TOPTION_CTH_CURSOR ])
{
- if (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 3)
+ if(UsingNewCTHSystem() == true)
{
- gbCtHBurstCount = 1;
-
//AXP 29.03.2007: Rooftop CtH fix. See below.
INT8 bTempTargetLevel = pSoldier->bTargetLevel;
pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
-
+
UINT32 uiHitChance;
// Calculate CTH for the first bullet
- uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
+ uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, pSoldier->aiData.bShownAimTime, pSoldier->bAimShotLocation );
// HEADROCK HAM B2.7: CTH approximation?
if (gGameExternalOptions.fApproximateCTH)
{
@@ -666,31 +697,68 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
}
// CTH for the first bullet is entered into this array, and later displayed
- gbCtH[0] = (gbCtH[0]+uiHitChance)/2;
+ gCTHDisplay.MuzzleSwayPercentage = (gCTHDisplay.MuzzleSwayPercentage + uiHitChance)/2;
+ gCTHDisplay.iShooterGridNo = pSoldier->sGridNo;
+ gCTHDisplay.iTargetGridNo = usMapPos;
- // Fool the CTH formula into thinking we're already firing the last bullet in the volley,
- // by artificially altering bDoBurst (which tracks actual burst progression). The CTH formula
- // calculates Auto Penalty based on bDoBurst - (Autopen * (bDoBurst-1), basically).
- UINT8 saveDoBurst = pSoldier->bDoBurst;
- pSoldier->bDoBurst = pSoldier->bDoAutofire;
-
- uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
- // HEADROCK HAM B2.7: CTH approximation?
- if (gGameExternalOptions.fApproximateCTH)
- {
- uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
- }
+ // Flag to tell the program to draw two CTH bars.
+ gfUICtHBar = TRUE;
+
+ // Calculate distance to target
+ FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( usMapPos ));
+ FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( usMapPos ));
+ FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
+
+ CalcMagFactorSimple( pSoldier, d2DDistance, pSoldier->aiData.bShownAimTime );
pSoldier->bTargetLevel = bTempTargetLevel;
- // Return Burst State to original value
- pSoldier->bDoBurst = saveDoBurst;
+ }
+ else
+ {
+ if (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 3)
+ {
+ gbCtHBurstCount = 1;
- // CTH for the last bullet is entered into this array and later displayed.
- gbCtH[1] = (gbCtH[1]+uiHitChance)/2;
-
- // Flag to tell the program to draw two CTH bars.
- gbCtHAutoFire = TRUE;
- gfUICtHBar = TRUE;
+ //AXP 29.03.2007: Rooftop CtH fix. See below.
+ INT8 bTempTargetLevel = pSoldier->bTargetLevel;
+ pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
+
+ UINT32 uiHitChance;
+ // Calculate CTH for the first bullet
+ uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
+ // HEADROCK HAM B2.7: CTH approximation?
+ if (gGameExternalOptions.fApproximateCTH)
+ {
+ uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
+ }
+
+ // CTH for the first bullet is entered into this array, and later displayed
+ gbCtH[0] = (gbCtH[0]+uiHitChance)/2;
+
+ // Fool the CTH formula into thinking we're already firing the last bullet in the volley,
+ // by artificially altering bDoBurst (which tracks actual burst progression). The CTH formula
+ // calculates Auto Penalty based on bDoBurst - (Autopen * (bDoBurst-1), basically).
+ UINT8 saveDoBurst = pSoldier->bDoBurst;
+ pSoldier->bDoBurst = pSoldier->bDoAutofire;
+
+ uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, 0, pSoldier->bAimShotLocation );
+ // HEADROCK HAM B2.7: CTH approximation?
+ if (gGameExternalOptions.fApproximateCTH)
+ {
+ uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
+ }
+
+ pSoldier->bTargetLevel = bTempTargetLevel;
+ // Return Burst State to original value
+ pSoldier->bDoBurst = saveDoBurst;
+
+ // CTH for the last bullet is entered into this array and later displayed.
+ gbCtH[1] = (gbCtH[1]+uiHitChance)/2;
+
+ // Flag to tell the program to draw two CTH bars.
+ gbCtHAutoFire = TRUE;
+ gfUICtHBar = TRUE;
+ }
}
}
}
@@ -706,20 +774,54 @@ UINT8 HandleActivatedTargetCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, BOOLEA
pSoldier->bTargetLevel = (INT8) gsInterfaceLevel;
UINT32 uiHitChance;
- uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, (INT8)(pSoldier->aiData.bShownAimTime ), pSoldier->bAimShotLocation );
+ // SANDRO - precise calculation for throwing knives added
+ if(UsingNewCTHSystem() == true)
+ {
+ uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, (INT8)(pSoldier->aiData.bShownAimTime ), pSoldier->bAimShotLocation );
+ }
+ else
+ {
+ if ( Item[ usInHand ].usItemClass == IC_THROWING_KNIFE )
+ {
+ uiHitChance = CalcThrownChanceToHit( pSoldier, usMapPos, (INT8)(pSoldier->aiData.bShownAimTime ), pSoldier->bAimShotLocation );
+ }
+ else
+ {
+ uiHitChance = CalcChanceToHitGun( pSoldier, usMapPos, (INT8)(pSoldier->aiData.bShownAimTime ), pSoldier->bAimShotLocation );
+ }
+ }
// HEADROCK HAM B2.7: CTH approximation?
if (gGameExternalOptions.fApproximateCTH)
{
uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
}
+ if(UsingNewCTHSystem() == true)
+ {
+ gfUICtHBar = TRUE;
+
+ // CTH for the first bullet is entered into this array, and later displayed
+ gCTHDisplay.MuzzleSwayPercentage = (gCTHDisplay.MuzzleSwayPercentage + uiHitChance)/2;
+ gCTHDisplay.iShooterGridNo = pSoldier->sGridNo;
+ gCTHDisplay.iTargetGridNo = usMapPos;
+
+ // Calculate distance to target
+ FLOAT dDeltaX = (FLOAT)(CenterX( pSoldier->sGridNo ) - CenterX( usMapPos ));
+ FLOAT dDeltaY = (FLOAT)(CenterY( pSoldier->sGridNo ) - CenterY( usMapPos ));
+ FLOAT d2DDistance = sqrt((dDeltaX*dDeltaX)+(dDeltaY*dDeltaY));
+
+ CalcMagFactorSimple( pSoldier, d2DDistance, pSoldier->aiData.bShownAimTime );
+ }
+
pSoldier->bTargetLevel = bTempTargetLevel;
- gfUICtHBar = TRUE;
- gbCtHBurstCount = 1;
- gbCtH[0] = (gbCtH[0]+uiHitChance)/2;
+ if(UsingNewCTHSystem() == false)
+ {
+ gfUICtHBar = TRUE;
+ gbCtHBurstCount = 1;
+ gbCtH[0] = (gbCtH[0]+uiHitChance)/2;
+ }
}
-
switchVal = pSoldier->aiData.bShownAimTime;
switch( switchVal )
@@ -1512,7 +1614,8 @@ UINT8 HandleKnifeCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivate
}
}
- bFutureAim = (INT8)( REFINE_KNIFE_2 );
+ // SANDRO - changed this
+ bFutureAim = (INT8)( gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : REFINE_KNIFE_2 );
sAPCosts = CalcTotalAPsToAttack( pSoldier, sGridNo, TRUE, (INT8)(bFutureAim / 2) );
@@ -1545,46 +1648,45 @@ UINT8 HandleKnifeCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivate
}
- switch( pSoldier->aiData.bShownAimTime )
+ //////////////////////////////////////////////////////////////
+ // SANDRO - slightly changed the formula here
+ if( pSoldier->aiData.bShownAimTime == REFINE_KNIFE_1 )
{
- case REFINE_KNIFE_1:
-
- if ( gfDisplayFullCountRing )
- {
- return( KNIFE_YELLOW_AIM1_UICURSOR );
- }
- else if ( fEnoughPoints )
- {
- return( KNIFE_HIT_AIM1_UICURSOR );
- }
- else
- {
- return( KNIFE_NOGO_AIM1_UICURSOR );
- }
- break;
-
- case REFINE_KNIFE_2:
-
- if ( gfDisplayFullCountRing )
- {
- return( KNIFE_YELLOW_AIM2_UICURSOR );
- }
- else if ( fEnoughPoints )
- {
- return( KNIFE_HIT_AIM2_UICURSOR );
- }
- else
- {
- return( KNIFE_NOGO_AIM2_UICURSOR );
- }
- break;
-
- default:
- Assert( FALSE );
- // no return value!
- return(0);
- break;
+ if ( gfDisplayFullCountRing )
+ {
+ return( KNIFE_YELLOW_AIM1_UICURSOR );
+ }
+ else if ( fEnoughPoints )
+ {
+ return( KNIFE_HIT_AIM1_UICURSOR );
+ }
+ else
+ {
+ return( KNIFE_NOGO_AIM1_UICURSOR );
+ }
}
+ else if( pSoldier->aiData.bShownAimTime == ( gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : REFINE_KNIFE_2 ) )
+ {
+ if ( gfDisplayFullCountRing )
+ {
+ return( KNIFE_YELLOW_AIM2_UICURSOR );
+ }
+ else if ( fEnoughPoints )
+ {
+ return( KNIFE_HIT_AIM2_UICURSOR );
+ }
+ else
+ {
+ return( KNIFE_NOGO_AIM2_UICURSOR );
+ }
+ }
+ else
+ {
+ Assert( FALSE );
+ // no return value!
+ return(0);
+ }
+ //////////////////////////////////////////////////////////////
}
else
{
@@ -1666,52 +1768,52 @@ UINT8 HandlePunchCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivate
PlayJA2Sample( TARG_REFINE_BEEP, RATE_11025, MIDVOLUME, 1, MIDDLEPAN );
}
- pSoldier->aiData.bShownAimTime = REFINE_PUNCH_2;
+ // SANDRO - make aimed punch less expensive for APS
+ pSoldier->aiData.bShownAimTime = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : REFINE_PUNCH_2);
}
}
}
- switch( pSoldier->aiData.bShownAimTime )
+ //////////////////////////////////////////////////////////////
+ // SANDRO - slightly changed the formula here
+ if( pSoldier->aiData.bShownAimTime == REFINE_PUNCH_1)
{
- case REFINE_PUNCH_1:
-
- if ( gfDisplayFullCountRing )
- {
- return( ACTION_PUNCH_YELLOW_AIM1_UICURSOR );
- }
- else if ( fEnoughPoints )
- {
- return( ACTION_PUNCH_RED_AIM1_UICURSOR );
- }
- else
- {
- return( ACTION_PUNCH_NOGO_AIM1_UICURSOR );
- }
- break;
-
- case REFINE_PUNCH_2:
-
- if ( gfDisplayFullCountRing )
- {
- return( ACTION_PUNCH_YELLOW_AIM2_UICURSOR );
- }
- else if ( fEnoughPoints )
- {
- return( ACTION_PUNCH_RED_AIM2_UICURSOR );
- }
- else
- {
- return( ACTION_PUNCH_NOGO_AIM2_UICURSOR );
- }
- break;
-
- default:
- Assert( FALSE );
- // no return value!
- return(0);
- break;
+ if ( gfDisplayFullCountRing )
+ {
+ return( ACTION_PUNCH_YELLOW_AIM1_UICURSOR );
+ }
+ else if ( fEnoughPoints )
+ {
+ return( ACTION_PUNCH_RED_AIM1_UICURSOR );
+ }
+ else
+ {
+ return( ACTION_PUNCH_NOGO_AIM1_UICURSOR );
+ }
}
+ else if ( pSoldier->aiData.bShownAimTime == (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : REFINE_PUNCH_2) )
+ {
+ if ( gfDisplayFullCountRing )
+ {
+ return( ACTION_PUNCH_YELLOW_AIM2_UICURSOR );
+ }
+ else if ( fEnoughPoints )
+ {
+ return( ACTION_PUNCH_RED_AIM2_UICURSOR );
+ }
+ else
+ {
+ return( ACTION_PUNCH_NOGO_AIM2_UICURSOR );
+ }
+ }
+ else
+ {
+ Assert( FALSE );
+ // no return value!
+ return(0);
+ }
+ //////////////////////////////////////////////////////////////
}
else
{
@@ -1859,7 +1961,7 @@ UINT8 HandleNonActivatedTossCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEA
// Do we have a launcable?
pObj = &(pSoldier->inv[HANDPOS]);
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
- if ( Item[ iter->usItem ].usItemClass & IC_EXPLOSV )
+ if ( Item[ iter->usItem ].usItemClass & IC_EXPLOSV && iter->exists())
{
pObject = &(*iter);
break;
@@ -2087,11 +2189,15 @@ void HandleLeftClickCursor( SOLDIERTYPE *pSoldier )
if ( gTacticalStatus.uiFlags & TURNBASED && (gTacticalStatus.uiFlags & INCOMBAT ) )
{
pSoldier->aiData.bShownAimTime = REFINE_AIM_1;
+ // HEADROCK HAM 4: Reset Bullet Count for Autofire
+ fAutofireBulletsMode = FALSE;
pSoldier->flags.fPauseAim = FALSE;
}
else
{
pSoldier->aiData.bShownAimTime = REFINE_AIM_1;
+ // HEADROCK HAM 4: Reset Bullet Count for Autofire
+ fAutofireBulletsMode = FALSE;
pSoldier->flags.fPauseAim = FALSE;
}
// Reset counter
@@ -2156,15 +2262,19 @@ void HandleRightClickAdjustCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos )
INT8 bFutureAim;
UINT8 ubCursor;
SOLDIERTYPE *pTSoldier;
- INT32 sGridNo;
+ INT32 sGridNo;
INT8 bTargetLevel;
+ // SANDRO - added these two
+ INT8 bAimTimeAddedForPunch = 2;
+ INT8 bAimTimeAddedForKnife = 2;
usInHand = pSoldier->inv[HANDPOS].usItem;
ubCursor = GetActionModeCursor( pSoldier );
- UINT8 maxAimLevels = AllowedAimingLevels(pSoldier);
+ // HEADROCK HAM 4: Required for new Aiming Level Limit function
+ UINT8 maxAimLevels = AllowedAimingLevels(pSoldier, usMapPos);
// 'snap' cursor to target tile....
if ( gfUIFullTargetFound )
@@ -2298,20 +2408,23 @@ void HandleRightClickAdjustCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos )
case PUNCHCURS:
- bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + REFINE_PUNCH_2 );
+ // SANDRO - changed the formula here to make aimed punch less expensive for APS
+ bAimTimeAddedForPunch = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : REFINE_PUNCH_2);
- if ( bFutureAim <= REFINE_PUNCH_2 )
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + bAimTimeAddedForPunch );
+
+ if ( bFutureAim <= bAimTimeAddedForPunch )
{
sAPCosts = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, (INT8)(bFutureAim / 2) );
// Determine if we can afford!
if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
{
- pSoldier->aiData.bShownAimTime+= REFINE_PUNCH_2;
+ pSoldier->aiData.bShownAimTime+= bAimTimeAddedForPunch;
- if ( pSoldier->aiData.bShownAimTime > REFINE_PUNCH_2 )
+ if ( pSoldier->aiData.bShownAimTime > bAimTimeAddedForPunch )
{
- pSoldier->aiData.bShownAimTime = REFINE_PUNCH_2;
+ pSoldier->aiData.bShownAimTime = bAimTimeAddedForPunch;
}
}
// Else - goto first level!
@@ -2345,20 +2458,23 @@ void HandleRightClickAdjustCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos )
case KNIFECURS:
- bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + REFINE_KNIFE_2 );
+ // SANDRO - changed the formula here to make aimed blade attack less expensive for APS
+ bAimTimeAddedForKnife = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : REFINE_KNIFE_2);
- if ( bFutureAim <= REFINE_KNIFE_2 )
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + bAimTimeAddedForKnife );
+
+ if ( bFutureAim <= bAimTimeAddedForKnife )
{
sAPCosts = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, (INT8)(bFutureAim / 2) );
// Determine if we can afford!
if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
{
- pSoldier->aiData.bShownAimTime+= REFINE_KNIFE_2;
+ pSoldier->aiData.bShownAimTime+= bAimTimeAddedForKnife;
- if ( pSoldier->aiData.bShownAimTime > REFINE_KNIFE_2 )
+ if ( pSoldier->aiData.bShownAimTime > bAimTimeAddedForKnife )
{
- pSoldier->aiData.bShownAimTime = REFINE_KNIFE_2;
+ pSoldier->aiData.bShownAimTime = bAimTimeAddedForKnife;
}
}
// Else - goto first level!
@@ -2524,12 +2640,194 @@ void HandleUICursorRTFeedback( SOLDIERTYPE *pSoldier )
}
}
+
+
+/* good code from lesh
+BOOLEAN CanSoldierAffordAimTime( SOLDIERTYPE *pSoldier, INT16 usMapPos, INT8 bAimTime )
+{
+ INT8 maxAimLevels;
+ INT16 sAPCosts;
+
+ maxAimLevels = AllowedAimingLevels(pSoldier);
+
+ if ( bAimTime < REFINE_AIM_1 || bAimTime > maxAimLevels )
+ return FALSE;
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, bAimTime );
+
+ if ( !EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOLEAN CanSoldierAffordPunching( SOLDIERTYPE *pSoldier, INT16 usMapPos, INT8 bRefineTime )
+{
+ INT16 sAPCosts;
+
+ if ( bRefineTime < REFINE_PUNCH_1 || bRefineTime > REFINE_PUNCH_2 )
+ return FALSE;
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, bRefineTime );
+
+ if ( !EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOLEAN CanSoldierAffordKnifing( SOLDIERTYPE *pSoldier, INT16 usMapPos, INT8 bRefineTime )
+{
+ INT16 sAPCosts;
+
+ if ( bRefineTime < REFINE_KNIFE_1 || bRefineTime > REFINE_KNIFE_2 )
+ return FALSE;
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, bRefineTime );
+
+ if ( !EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+BOOLEAN CanSoldierAffordBurstBullets( SOLDIERTYPE *pSoldier, INT16 usMapPos )
+{
+ INT16 sAPCosts;
+ INT8 bSaveDoAutofire;
+
+ if ( pSoldier->bDoAutofire < 1 )
+ {
+ pSoldier->bDoAutofire = 1;
+ return FALSE;
+ }
+
+ if ( pSoldier->bDoAutofire > pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft )
+ {
+ pSoldier->bDoAutofire = pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft;
+ return FALSE;
+ }
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, usMapPos, TRUE, 0);
+
+ if ( !EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+
+void HandleWheelAdjustCursor( SOLDIERTYPE *pSoldier, INT16 sMapPos, INT16 sDelta )
+{
+ UINT8 ubCursor;
+ INT8 bFutureAim;
+
+ ubCursor = GetActionModeCursor( pSoldier );
+
+ // 'snap' cursor to target tile....
+ if ( gfUIFullTargetFound )
+ {
+ sMapPos = MercPtrs[ gusUIFullTargetID ]->sGridNo;
+ }
+
+ switch( ubCursor )
+ {
+ case TARGETCURS:
+ // warn if bad chance to get through
+ if ( gfUIFullTargetFound &&
+ !HandleCheckForBadChangeToGetThrough( pSoldier, MercPtrs[ gusUIFullTargetID ],
+ MercPtrs[ gusUIFullTargetID ]->sGridNo , MercPtrs[ gusUIFullTargetID ]->pathing.bLevel ) )
+ {
+ return;
+ }
+
+ if ( pSoldier->bDoBurst && !pSoldier->bDoAutofire )
+ {
+ }
+ else if( pSoldier->bDoAutofire )
+ {
+ // AUTOFIRE section
+ INT16 sCurAPCosts, sFutureAPCost;
+
+ if(pSoldier->flags.autofireLastStep)
+ {
+ pSoldier->flags.autofireLastStep = FALSE;
+ }
+
+ // change burst length until AP difference is shown
+ sCurAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ do
+ {
+ pSoldier->bDoAutofire += sDelta;
+ sFutureAPCost = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ } while ( CanSoldierAffordBurstBullets( pSoldier, sMapPos ) && (sFutureAPCost - sCurAPCosts) == 0 );
+
+ // complement burst by adding bullets, until next bullet produce AP difference
+ sFutureAPCost = sCurAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ while ( CanSoldierAffordBurstBullets( pSoldier, sMapPos ) && (sFutureAPCost - sCurAPCosts) == 0 )
+ {
+ pSoldier->bDoAutofire += 1; // now it goes as future burst length
+ sFutureAPCost = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+
+ // display red numbers, if it is last possible burst ap spenditure
+ pSoldier->flags.autofireLastStep = !CanSoldierAffordBurstBullets( pSoldier, sMapPos );
+
+ // restore last iteration bullet count (before ap difference)
+ pSoldier->bDoAutofire--;
+ }
+ else
+ {
+ // SINGLE SHOT section
+ bFutureAim = pSoldier->aiData.bShownAimTime + sDelta;
+
+ if ( CanSoldierAffordAimTime( pSoldier, sMapPos, bFutureAim) )
+ {
+ pSoldier->aiData.bShownAimTime += sDelta;
+ // display yellow circle, if it is last possible aim level
+ gfDisplayFullCountRing = !CanSoldierAffordAimTime( pSoldier, sMapPos, bFutureAim + 1);
+
+ }
+ }
+ break;
+
+ case PUNCHCURS:
+ // PUNCHING section
+ bFutureAim = pSoldier->aiData.bShownAimTime + sDelta * REFINE_PUNCH_2; // possibly dirty hack
+
+ if ( CanSoldierAffordPunching( pSoldier, sMapPos, bFutureAim) )
+ {
+ pSoldier->aiData.bShownAimTime += sDelta * REFINE_PUNCH_2;
+ // display yellow circle, if it is last possible aim level
+ gfDisplayFullCountRing = !CanSoldierAffordPunching( pSoldier, sMapPos, bFutureAim + 1);
+ }
+ break;
+
+ case KNIFECURS:
+ // KNIFING section
+ bFutureAim = pSoldier->aiData.bShownAimTime + sDelta * REFINE_KNIFE_2; // possibly dirty hack
+
+ if ( CanSoldierAffordKnifing( pSoldier, sMapPos, bFutureAim) )
+ {
+ pSoldier->aiData.bShownAimTime += sDelta * REFINE_KNIFE_2;
+ // display yellow circle, if it is last possible aim level
+ gfDisplayFullCountRing = !CanSoldierAffordKnifing( pSoldier, sMapPos, bFutureAim + 1);
+ }
+ break;
+
+ };
+}
+
+
+
+
+*/
// HEADROCK HAM B2.7: This function gives us an "approximate" CTH bar, that doesn't show the exact value of
// CTH unless the character is well-trained. The worse trained a character is, the wilder the speculation.
UINT32 ChanceToHitApproximation( SOLDIERTYPE * pSoldier, UINT32 uiChance )
{
- UINT16 bExpLevel = pSoldier->stats.bExpLevel;
+ UINT16 bExpLevelValue = EffectiveExpLevel(pSoldier); // SANDRO - changed to effective level calc
UINT16 bMarksmanship = pSoldier->stats.bMarksmanship;
UINT16 bWisdom = pSoldier->stats.bWisdom;
UINT16 iNumStages, iNumStagesBase, StageSize, SubStageSize;
@@ -2539,7 +2837,10 @@ UINT32 ChanceToHitApproximation( SOLDIERTYPE * pSoldier, UINT32 uiChance )
if ( pSoldier->ubProfile != NO_PROFILE )
{
- iSniper = NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER );
+ if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
+ iSniper = NUM_SKILL_TRAITS( pSoldier, SNIPER_NT );
+ else
+ iSniper = NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT );
}
else
{
@@ -2561,7 +2862,7 @@ UINT32 ChanceToHitApproximation( SOLDIERTYPE * pSoldier, UINT32 uiChance )
}
uiNewChance = uiChance;
- iNumStagesBase = __min(165,__max(0, ((bExpLevel * 10) - 30) + (bMarksmanship - 25) + (bWisdom - 50)));
+ iNumStagesBase = __min(165,__max(0, ((bExpLevelValue * 10) - 30) + (bMarksmanship - 25) + (bWisdom - 50)));
//iNumStagesBase = __max(255, iNumStagesBase);
iNumStagesBase = __min(165, iNumStagesBase + (10 * iSniper));
@@ -2601,3 +2902,642 @@ UINT32 ChanceToHitApproximation( SOLDIERTYPE * pSoldier, UINT32 uiChance )
// Something went wrong. Return 50, as in "God Knows"
return (50);
}
+
+
+/* // .
+void HandleWheelAdjustCursor( SOLDIERTYPE *pSoldier, INT16 sMapPos, INT16 sDelta )
+{
+ UINT16 usInHand;
+ INT16 sAPCosts;
+ INT8 bFutureAim;
+ UINT8 ubCursor;
+ SOLDIERTYPE *pTSoldier;
+ INT16 sGridNo;
+ INT8 bTargetLevel;
+
+
+ usInHand = pSoldier->inv[HANDPOS].usItem;
+
+ ubCursor = GetActionModeCursor( pSoldier );
+
+ UINT8 maxAimLevels = AllowedAimingLevels(pSoldier);
+
+ // 'snap' cursor to target tile....
+ if ( gfUIFullTargetFound )
+ {
+ sMapPos = MercPtrs[ gusUIFullTargetID ]->sGridNo;
+ }
+
+
+ switch( ubCursor )
+ {
+ case TARGETCURS:
+
+ // CHECK IF GUY HAS IN HAND A WEAPON
+ if ( pSoldier->bDoBurst && !pSoldier->bDoAutofire)
+ {
+ // Do nothing!
+ // pSoldier->aiData.bShownAimTime = REFINE_AIM_BURST;
+ }
+ else if(pSoldier->bDoAutofire)
+ {
+ INT16 sCurAPCosts;
+
+ if(pSoldier->bDoAutofire==1 && sDelta<0) return;
+
+ if(pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft > pSoldier->bDoAutofire )
+ {
+ //Calculate how many bullets we need to fire to add at least one more AP
+ sAPCosts = sCurAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ while(EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) && sAPCosts <= sCurAPCosts && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft > pSoldier->bDoAutofire) //Increment the bullet count until we run out of APs or we spend the whole AP
+ {
+ pSoldier->bDoAutofire++;
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+
+ //we've stepped over the border and used up one more ap, now let's make sure that it is spent to maximize the bullets
+
+ sCurAPCosts = sAPCosts;
+
+ do
+ {
+ pSoldier->bDoAutofire+=sDelta;
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+ while(EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) && sAPCosts == sCurAPCosts && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire);
+ pSoldier->bDoAutofire--;
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+
+ if(!EnoughPoints( pSoldier, sAPCosts, 0, FALSE )) //We've not enough points to fire those bullets
+ {
+ pSoldier->flags.autofireLastStep = TRUE;
+ pSoldier->bDoAutofire--;
+ }
+ else
+ pSoldier->flags.autofireLastStep = FALSE; //both last step conditions are false
+ }
+ else
+ {
+ if(sDelta<0)
+ {
+ pSoldier->flags.autofireLastStep = FALSE;
+ pSoldier->bDoAutofire--;
+ }
+ else
+ pSoldier->flags.autofireLastStep = TRUE;
+ }
+ }
+ else //single shoot
+ {
+ sGridNo = sMapPos;
+ bTargetLevel = (INT8)gsInterfaceLevel;
+
+ // Look for a target here...
+ if ( gfUIFullTargetFound )
+ {
+ // Get target soldier, if one exists
+ pTSoldier = MercPtrs[ gusUIFullTargetID ];
+ sGridNo = pTSoldier->sGridNo;
+ bTargetLevel = pSoldier->pathing.bLevel;
+
+ if ( !HandleCheckForBadChangeToGetThrough( pSoldier, pTSoldier, sGridNo , bTargetLevel ) )
+ return;
+ }
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + sDelta );
+ if(bFutureAim <0)return;
+
+ if ( bFutureAim <= maxAimLevels )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim ) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= sDelta;
+ if ( pSoldier->aiData.bShownAimTime > maxAimLevels )
+ pSoldier->aiData.bShownAimTime = maxAimLevels;
+ gfDisplayFullCountRing = FALSE;
+ }
+
+ else // Else - goto first level!
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+
+ }
+ break;
+
+
+ case PUNCHCURS:
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + REFINE_PUNCH_2 );
+
+ if ( bFutureAim <= REFINE_PUNCH_2 )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim / 2) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= (sDelta*REFINE_PUNCH_2);
+
+ if ( pSoldier->aiData.bShownAimTime > REFINE_PUNCH_2 )
+ {
+ pSoldier->aiData.bShownAimTime = REFINE_PUNCH_2;
+ }
+ }
+ // Else - goto first level!
+ else
+ {
+ if ( !gfDisplayFullCountRing )
+ {
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ {
+ pSoldier->aiData.bShownAimTime = REFINE_PUNCH_1;
+ gfDisplayFullCountRing = FALSE;
+ }
+ }
+ }
+ else
+ {
+ if ( !gfDisplayFullCountRing )
+ {
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ {
+ pSoldier->aiData.bShownAimTime = REFINE_PUNCH_1;
+ gfDisplayFullCountRing = FALSE;
+ }
+ }
+ break;
+
+
+ case KNIFECURS:
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + (sDelta*REFINE_KNIFE_2) );
+
+ if ( bFutureAim <= REFINE_KNIFE_2 )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim / 2) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= REFINE_KNIFE_2;
+
+ if ( pSoldier->aiData.bShownAimTime > REFINE_KNIFE_2 )
+ {
+ pSoldier->aiData.bShownAimTime = REFINE_KNIFE_2;
+ }
+ }
+ // Else - goto first level!
+ else
+ {
+ if ( !gfDisplayFullCountRing )
+ {
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ {
+ pSoldier->aiData.bShownAimTime = REFINE_KNIFE_1;
+ gfDisplayFullCountRing = FALSE;
+ }
+ }
+ }
+ else
+ {
+ if ( !gfDisplayFullCountRing )
+ {
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ {
+ pSoldier->aiData.bShownAimTime = REFINE_KNIFE_1;
+ gfDisplayFullCountRing = FALSE;
+ }
+ }
+ break;
+
+ case TOSSCURS:
+
+ //IncrementAimCubeUI( );
+ break;
+
+ default:
+
+ ErasePath( TRUE );
+
+ }
+}
+*/
+
+
+
+void HandleWheelAdjustCursor( SOLDIERTYPE *pSoldier, INT32 sMapPos, INT32 sDelta, INT16 brstmode )
+{
+ UINT16 usInHand;
+ INT16 sAPCosts;
+ INT8 bFutureAim;
+ UINT8 ubCursor;
+ SOLDIERTYPE *pTSoldier;
+ INT32 sGridNo;
+ INT8 bTargetLevel;
+
+
+ usInHand = pSoldier->inv[HANDPOS].usItem;
+
+ ubCursor = GetActionModeCursor( pSoldier );
+
+ UINT8 maxAimLevels = AllowedAimingLevels(pSoldier, sMapPos);
+
+ // 'snap' cursor to target tile....
+ if ( gfUIFullTargetFound )
+ sMapPos = MercPtrs[ gusUIFullTargetID ]->sGridNo;
+
+ int aimlevelchange = 1;
+ int maxAimCanAfford = 0;
+ int oldAim = pSoldier->aiData.bShownAimTime;
+ int hitChance = 0;
+ int maxCtH = 0; //maximum chance to hit
+ int minAimForCtH = 0; //minimum AP needed to get maximum CtH
+ switch( ubCursor )
+ {
+ case TARGETCURS:
+
+//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"cbef=%d",CalcChanceToHitGun( pSoldier, sMapPos, pSoldier->aiData.bShownAimTime, pSoldier->bAimShotLocation ) );
+ if(pSoldier->bDoAutofire && (gfKeyState[18] || brstmode) ) // -
+ {
+ INT16 sCurAPCosts;
+
+ if(pSoldier->bDoAutofire==1 && sDelta<0) return;
+
+ if(pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft > pSoldier->bDoAutofire )
+ {
+ //Calculate how many bullets we need to fire to add at least one more AP
+ sAPCosts = sCurAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ while(EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) && sAPCosts <= sCurAPCosts && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft > pSoldier->bDoAutofire) //Increment the bullet count until we run out of APs or we spend the whole AP
+ {
+ pSoldier->bDoAutofire++;
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+
+ //we've stepped over the border and used up one more ap, now let's make sure that it is spent to maximize the bullets
+
+ sCurAPCosts = sAPCosts;
+
+ do
+ {
+ pSoldier->bDoAutofire+=sDelta;
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+ while(EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) && sAPCosts == sCurAPCosts && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire);
+ pSoldier->bDoAutofire--;
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+
+ if(!EnoughPoints( pSoldier, sAPCosts, 0, FALSE )) //We've not enough points to fire those bullets
+ {
+ pSoldier->flags.autofireLastStep = TRUE;
+ pSoldier->bDoAutofire--;
+ }
+ else
+ pSoldier->flags.autofireLastStep = FALSE; //both last step conditions are false
+ }
+ else
+ {
+ if(sDelta<0)
+ {
+ pSoldier->flags.autofireLastStep = FALSE;
+ pSoldier->bDoAutofire--;
+ }
+ else
+ pSoldier->flags.autofireLastStep = TRUE;
+ }
+ return;
+ }
+///////////////////////////////
+ sGridNo = sMapPos;
+ bTargetLevel = (INT8)gsInterfaceLevel;
+
+ // Look for a target here...
+ if ( gfUIFullTargetFound )
+ {
+ // Get target soldier, if one exists
+ pTSoldier = MercPtrs[ gusUIFullTargetID ];
+ sGridNo = pTSoldier->sGridNo;
+ bTargetLevel = pSoldier->pathing.bLevel;
+
+ if ( !HandleCheckForBadChangeToGetThrough( pSoldier, pTSoldier, sGridNo , bTargetLevel ) )
+ {
+ return;
+ }
+ }
+
+
+ bFutureAim = maxAimLevels;
+
+ //Find the actual maximum aim that can be done.
+ while( bFutureAim > 0 ){
+ //Can afford this many?
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, bFutureAim );
+ if( !maxAimCanAfford && EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) ){
+ maxAimCanAfford = bFutureAim;
+ }
+ //Find the least amount of aiming needed to get maximum CtH
+ //Give some slack, but don't let the slack accumulate.
+ //dd???{
+ //hitChance = CalcChanceToHitGun( pSoldier, sMapPos, bFutureAim, pSoldier->bAimShotLocation );
+ //if( hitChance >= maxCtH - 3){
+ // minAimForCtH = bFutureAim;
+ // if(hitChance >= maxCtH) maxCtH = hitChance;
+ //}
+ //ddd???}
+ //Loop to 0.
+ --bFutureAim;
+ }
+
+ bFutureAim = oldAim + sDelta;
+ if( bFutureAim < REFINE_AIM_1 ) return;
+
+
+ //Do it.
+ if( bFutureAim < REFINE_AIM_1 ){
+ //Went too low. Set to max aim.
+ bFutureAim = maxAimCanAfford;
+ gfDisplayFullCountRing = TRUE;
+ }else if( bFutureAim <= maxAimCanAfford ){
+ //Aim level is doable. No modification needed.
+ gfDisplayFullCountRing = FALSE;
+ }else{
+ //Aim too high. Give indicator that is is maxed, then reset aim refinement.
+ if ( gfDisplayFullCountRing )
+ return;
+ else{
+ //Display ring to indicate maximum aim reached.
+ bFutureAim = oldAim;
+ gfDisplayFullCountRing = TRUE;
+ }
+ }
+ //Apply.
+ pSoldier->aiData.bShownAimTime = bFutureAim;
+
+//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"caft=%d",CalcChanceToHitGun( pSoldier, sMapPos, pSoldier->aiData.bShownAimTime, pSoldier->bAimShotLocation ) );
+ break;
+
+
+ case PUNCHCURS:
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + (sDelta*REFINE_PUNCH_2) );
+if(bFutureAim<0) return;
+ if ( bFutureAim <= REFINE_PUNCH_2 )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim / 2) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= (sDelta*REFINE_PUNCH_2);
+ if ( pSoldier->aiData.bShownAimTime > REFINE_PUNCH_2 )
+ pSoldier->aiData.bShownAimTime = REFINE_PUNCH_2;
+ gfDisplayFullCountRing = FALSE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+
+ break;
+
+
+
+ case KNIFECURS:
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + (sDelta*REFINE_KNIFE_2) );
+if(bFutureAim<0) return;
+ if ( bFutureAim <= REFINE_KNIFE_2 )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim / 2) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= REFINE_KNIFE_2;
+ if ( pSoldier->aiData.bShownAimTime > REFINE_KNIFE_2 )
+ pSoldier->aiData.bShownAimTime = REFINE_KNIFE_2;
+ gfDisplayFullCountRing = FALSE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+
+ break;
+
+ case TOSSCURS:
+
+ //IncrementAimCubeUI( );
+ break;
+
+ default:
+
+ ErasePath( TRUE );
+
+ }
+
+}
+
+// if .
+void HandleWheelAdjustCursorWOAB( SOLDIERTYPE *pSoldier, INT32 sMapPos, INT32 sDelta )
+{
+ UINT16 usInHand;
+ INT16 sAPCosts;
+ INT8 bFutureAim;
+ UINT8 ubCursor;
+ SOLDIERTYPE *pTSoldier;
+ INT32 sGridNo;
+ INT8 bTargetLevel;
+
+
+ usInHand = pSoldier->inv[HANDPOS].usItem;
+
+ ubCursor = GetActionModeCursor( pSoldier );
+
+ UINT8 maxAimLevels = AllowedAimingLevels(pSoldier, sMapPos);
+
+ // 'snap' cursor to target tile....
+ if ( gfUIFullTargetFound )
+ {
+ sMapPos = MercPtrs[ gusUIFullTargetID ]->sGridNo;
+ }
+
+
+ switch( ubCursor )
+ {
+ case TARGETCURS:
+
+ // CHECK IF GUY HAS IN HAND A WEAPON
+ if ( pSoldier->bDoBurst && !pSoldier->bDoAutofire)
+ {
+ // Do nothing!
+ // pSoldier->aiData.bShownAimTime = REFINE_AIM_BURST;
+ }
+ else if(pSoldier->bDoAutofire)
+ {
+ INT16 sCurAPCosts;
+
+ if(pSoldier->bDoAutofire==1 && sDelta<0) return;
+
+ if(pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft > pSoldier->bDoAutofire )
+ {
+ //Calculate how many bullets we need to fire to add at least one more AP
+ sAPCosts = sCurAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ while(EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) && sAPCosts <= sCurAPCosts && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft > pSoldier->bDoAutofire) //Increment the bullet count until we run out of APs or we spend the whole AP
+ {
+ pSoldier->bDoAutofire++;
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+
+ //we've stepped over the border and used up one more ap, now let's make sure that it is spent to maximize the bullets
+
+ sCurAPCosts = sAPCosts;
+
+ do
+ {
+ pSoldier->bDoAutofire+=sDelta;
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+ }
+ while(EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) && sAPCosts == sCurAPCosts && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire);
+ pSoldier->bDoAutofire--;
+
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, 0);
+
+ if(!EnoughPoints( pSoldier, sAPCosts, 0, FALSE )) //We've not enough points to fire those bullets
+ {
+ pSoldier->flags.autofireLastStep = TRUE;
+ pSoldier->bDoAutofire--;
+ }
+ else
+ pSoldier->flags.autofireLastStep = FALSE; //both last step conditions are false
+ }
+ else
+ {
+ if(sDelta<0)
+ {
+ pSoldier->flags.autofireLastStep = FALSE;
+ pSoldier->bDoAutofire--;
+ }
+ else
+ pSoldier->flags.autofireLastStep = TRUE;
+ }
+ }
+ else //single shoot
+ {
+ sGridNo = sMapPos;
+ bTargetLevel = (INT8)gsInterfaceLevel;
+
+ // Look for a target here...
+ if ( gfUIFullTargetFound )
+ {
+ // Get target soldier, if one exists
+ pTSoldier = MercPtrs[ gusUIFullTargetID ];
+ sGridNo = pTSoldier->sGridNo;
+ bTargetLevel = pSoldier->pathing.bLevel;
+
+ if ( !HandleCheckForBadChangeToGetThrough( pSoldier, pTSoldier, sGridNo , bTargetLevel ) )
+ return;
+ }
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + sDelta );
+ if(bFutureAim <0)return;
+
+ if ( bFutureAim <= maxAimLevels )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim ) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= sDelta;
+ if ( pSoldier->aiData.bShownAimTime > maxAimLevels )
+ pSoldier->aiData.bShownAimTime = maxAimLevels;
+ gfDisplayFullCountRing = FALSE;
+ }
+
+ else // Else - goto first level!
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+
+ }
+ break;
+
+ case PUNCHCURS:
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + (sDelta*REFINE_PUNCH_2) );
+if(bFutureAim<0) return;
+ if ( bFutureAim <= REFINE_PUNCH_2 )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim / 2) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= (sDelta*REFINE_PUNCH_2);
+ if ( pSoldier->aiData.bShownAimTime > REFINE_PUNCH_2 )
+ pSoldier->aiData.bShownAimTime = REFINE_PUNCH_2;
+ gfDisplayFullCountRing = FALSE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+
+ break;
+
+
+
+ case KNIFECURS:
+
+ bFutureAim = (INT8)( pSoldier->aiData.bShownAimTime + (sDelta*REFINE_KNIFE_2) );
+if(bFutureAim<0) return;
+ if ( bFutureAim <= REFINE_KNIFE_2 )
+ {
+ sAPCosts = CalcTotalAPsToAttack( pSoldier, sMapPos, TRUE, (INT8)(bFutureAim / 2) );
+
+ // Determine if we can afford!
+ if ( EnoughPoints( pSoldier, sAPCosts, 0, FALSE ) )
+ {
+ pSoldier->aiData.bShownAimTime+= REFINE_KNIFE_2;
+ if ( pSoldier->aiData.bShownAimTime > REFINE_KNIFE_2 )
+ pSoldier->aiData.bShownAimTime = REFINE_KNIFE_2;
+ gfDisplayFullCountRing = FALSE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+ }
+ else
+ gfDisplayFullCountRing = TRUE;
+
+ break;
+
+ case TOSSCURS:
+
+ //IncrementAimCubeUI( );
+ break;
+
+ default:
+
+ ErasePath( TRUE );
+
+ }
+}
\ No newline at end of file
diff --git a/Tactical/UI Cursors.h b/Tactical/UI Cursors.h
index fb1c9437..7f74a4d1 100644
--- a/Tactical/UI Cursors.h
+++ b/Tactical/UI Cursors.h
@@ -14,6 +14,8 @@ void DetermineCursorBodyLocation( UINT8 ubSoldierID, BOOLEAN fDisplay, BOOLEAN f
void HandleLeftClickCursor( SOLDIERTYPE *pSoldier );
void HandleRightClickAdjustCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos );
+void HandleWheelAdjustCursor( SOLDIERTYPE *pSoldier, INT32 usMapPos, INT32 sDelta, INT16 brstmode );
+void HandleWheelAdjustCursorWOAB( SOLDIERTYPE *pSoldier, INT32 sMapPos, INT32 sDelta );
UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier );
diff --git a/Tactical/Vehicles.cpp b/Tactical/Vehicles.cpp
index a5a40c89..101868eb 100644
--- a/Tactical/Vehicles.cpp
+++ b/Tactical/Vehicles.cpp
@@ -39,6 +39,7 @@
#include "opplist.h"
#include "Soldier ani.h"
#include "GameSettings.h"
+ #include "Queen Command.h"
#endif
//INT8 gubVehicleMovementGroups[ MAX_VEHICLES ];
@@ -618,14 +619,44 @@ BOOLEAN AddSoldierToVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
}
-void SetSoldierExitVehicleInsertionData( SOLDIERTYPE *pSoldier, INT32 iId )
+void SetSoldierExitVehicleInsertionData( SOLDIERTYPE *pSoldier, INT32 iId, UINT8 iOldGroupID )
{
+ GROUP *pGroup;
+
if ( iId == iHelicopterVehicleId && !pSoldier->bInSector )
{
if( pSoldier->sSectorX != BOBBYR_SHIPPING_DEST_SECTOR_X || pSoldier->sSectorY != BOBBYR_SHIPPING_DEST_SECTOR_Y || pSoldier->bSectorZ != BOBBYR_SHIPPING_DEST_SECTOR_Z )
{
- // Not anything different here - just use center gridno......
- pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CENTER;
+ if( NumHostilesInSector( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ) > 0 && iOldGroupID != 0 && gGameExternalOptions.ubSkyriderHotLZ == 2 )
+ {
+ pGroup = GetGroup( iOldGroupID );
+ if( pGroup->ubSectorX < pGroup->ubPrevX )
+ {
+ pSoldier->ubStrategicInsertionCode = INSERTION_CODE_EAST;
+ }
+ else if( pGroup->ubSectorX > pGroup->ubPrevX )
+ {
+ pSoldier->ubStrategicInsertionCode = INSERTION_CODE_WEST;
+ }
+ else if( pGroup->ubSectorY < pGroup->ubPrevY )
+ {
+ pSoldier->ubStrategicInsertionCode = INSERTION_CODE_SOUTH;
+ }
+ else if( pGroup->ubSectorY > pGroup->ubPrevY )
+ {
+ pSoldier->ubStrategicInsertionCode = INSERTION_CODE_NORTH;
+ }
+ else
+ {
+ Assert(0);
+ return;
+ }
+ }
+ else
+ {
+ // Not anything different here - just use center gridno......
+ pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CENTER;
+ }
}
else
{
@@ -643,6 +674,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
BOOLEAN fSoldierLeft = FALSE;
BOOLEAN fSoldierFound = FALSE;
SOLDIERTYPE *pVehicleSoldier;
+ UINT8 iOldGroupID=0;
if( ( iId >= ubNumberOfVehicles ) || ( iId < 0 ) )
@@ -663,6 +695,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
{
fSoldierFound = TRUE;
+ iOldGroupID = pVehicleList[ iId ].pPassengers[ iCounter ]->ubGroupID;
pVehicleList[ iId ].pPassengers[ iCounter ]->ubGroupID = 0;
pVehicleList[ iId ].pPassengers[ iCounter ]->sSectorY = pVehicleList[ iId ].sSectorY;
pVehicleList[ iId ].pPassengers[ iCounter ]->sSectorX = pVehicleList[ iId ].sSectorX;
@@ -772,7 +805,7 @@ BOOLEAN RemoveSoldierFromVehicle( SOLDIERTYPE *pSoldier, INT32 iId )
SetSectorFlag( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, SF_ALREADY_VISITED );
}
- SetSoldierExitVehicleInsertionData( pSoldier, iId );
+ SetSoldierExitVehicleInsertionData( pSoldier, iId, iOldGroupID );
// Update in sector if this is the current sector.....
if ( pSoldier->sSectorX == gWorldSectorX && pSoldier->sSectorY == gWorldSectorY && pSoldier->bSectorZ == gbWorldSectorZ )
diff --git a/Tactical/Vehicles.h b/Tactical/Vehicles.h
index 650ef12e..7cc2cebe 100644
--- a/Tactical/Vehicles.h
+++ b/Tactical/Vehicles.h
@@ -232,7 +232,7 @@ SOLDIERTYPE* PickRandomPassengerFromVehicle( SOLDIERTYPE *pSoldier );
BOOLEAN DoesVehicleHaveAnyPassengers( INT32 iVehicleID );
BOOLEAN DoesVehicleGroupHaveAnyPassengers( GROUP *pGroup );
-void SetSoldierExitVehicleInsertionData( SOLDIERTYPE *pSoldier, INT32 iId );
+void SetSoldierExitVehicleInsertionData( SOLDIERTYPE *pSoldier, INT32 iId, UINT8 iOldGroupID );
void InitAVehicle(int index, int x, int y);
diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp
index e6436c08..cfb91533 100644
--- a/Tactical/Weapons.cpp
+++ b/Tactical/Weapons.cpp
@@ -46,6 +46,9 @@
#include "SmokeEffects.h"
#include "lighting.h"
#include "Auto Resolve.h"
+ #include "Soldier Functions.h" // added by SANDRO
+ #include "Drugs And Alcohol.h" // HEADROCK HAM 4: Get drunk level
+ #include "LOS.h" // HEADROCK HAM 4: Required for new shooting mechanism. Alternately, maybe move the functions to LOS.h.
#endif
//forward declarations of common classes to eliminate includes
@@ -97,6 +100,7 @@ extern BOOLEAN gfNextFireJam;
BOOLEAN WillExplosiveWeaponFail( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj );
BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo );
+BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo );
BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo );
BOOLEAN UseThrown( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo );
BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo );
@@ -326,6 +330,9 @@ AMMOTYPE AmmoTypes[MAXITEMS];
// used to determine whether the bullet will go through someone
UINT8 BodyImpactReduction[4] = { 0, 15, 30, 23 };
+bool gbForceWeaponNotReady = false;
+bool gbForceWeaponReady = false;
+
@@ -389,6 +396,7 @@ weaponStartElementHandle(void *userData, const XML_Char *name, const XML_Char **
strcmp(name, "ubImpact") == 0 ||
strcmp(name, "ubDeadliness") == 0 ||
strcmp(name, "bAccuracy") == 0 ||
+ strcmp(name, "nAccuracy") == 0 ||
strcmp(name, "ubMagSize") == 0 ||
strcmp(name, "usRange") == 0 ||
strcmp(name, "usReloadDelay") == 0 ||
@@ -405,12 +413,16 @@ weaponStartElementHandle(void *userData, const XML_Char *name, const XML_Char **
strcmp(name, "SwapClips") == 0 ||
strcmp(name, "AutoPenalty") == 0 ||
strcmp(name, "NoSemiAuto") == 0 ||
+ strcmp(name, "EasyUnjam") == 0 ||
strcmp(name, "MaxDistForMessyDeath") == 0 ||
strcmp(name, "SilencedSound") == 0 || // Lesh: add new field (OR operand)
strcmp(name, "BurstAniDelay") == 0 || // Lesh: add new field (field itself)
strcmp(name, "APsToReloadManually") == 0 ||
- strcmp(name, "ManualReloadSound") == 0)
- )
+ strcmp(name, "ManualReloadSound") == 0 ||
+ strcmp(name, "ubAimLevels") == 0 ||// HEADROCK HAM 4: Allowed aiming levels for this gun.
+ strcmp(name, "bRecoilX") == 0 || // HEADROCK HAM 4:
+ strcmp(name, "bRecoilY") == 0 || // HEADROCK HAM 4:
+ strcmp(name, "ubRecoilDelay") == 0)) // HEADROCK HAM 4:
{
pData->curElement = WEAPON_ELEMENT_WEAPON_PROPERY;
@@ -530,6 +542,11 @@ weaponEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = WEAPON_ELEMENT_WEAPON;
pData->curWeapon.bAccuracy = (INT8) atol(pData->szCharData);
}
+ else if(strcmp(name, "nAccuracy") == 0)
+ {
+ pData->curElement = WEAPON_ELEMENT_WEAPON;
+ pData->curWeapon.nAccuracy = (INT8) atol(pData->szCharData);
+ }
else if(strcmp(name, "ubMagSize") == 0)
{
pData->curElement = WEAPON_ELEMENT_WEAPON;
@@ -640,6 +657,31 @@ weaponEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = WEAPON_ELEMENT_WEAPON;
pData->curWeapon.ManualReloadSound = (UINT16) atol(pData->szCharData);
}
+ else if(strcmp(name, "EasyUnjam") == 0)
+ {
+ pData->curElement = WEAPON_ELEMENT_WEAPON;
+ pData->curWeapon.EasyUnjam = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubAimLevels") == 0)
+ {
+ pData->curElement = WEAPON_ELEMENT_WEAPON;
+ pData->curWeapon.ubAimLevels = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bRecoilX") == 0)
+ {
+ pData->curElement = WEAPON_ELEMENT_WEAPON;
+ pData->curWeapon.bRecoilX = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bRecoilY") == 0)
+ {
+ pData->curElement = WEAPON_ELEMENT_WEAPON;
+ pData->curWeapon.bRecoilY = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubRecoilDelay") == 0)
+ {
+ pData->curElement = WEAPON_ELEMENT_WEAPON;
+ pData->curWeapon.ubRecoilDelay = (INT8) atol(pData->szCharData);
+ }
pData->maxReadDepth--;
}
@@ -710,7 +752,7 @@ BOOLEAN ReadInWeaponStats(STR fileName)
//Debug code; make sure that what we got from the file is the same as what's there
// Open a new file
hFile = FileOpen( "TABLEDATA\\~Weapons out.xml", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
- THROWIFFALSE(hFile, BuildString().add(L"Couls not open/create file : ").add(L"TABLEDATA\\~Weapons out.xml").get());
+ SGP_THROW_IFFALSE(hFile, _BS(L"Couls not open/create file : ") << L"TABLEDATA\\~Weapons out.xml" << _BS::wget);
//if ( !hFile )
// return( FALSE );
@@ -781,6 +823,7 @@ BOOLEAN ReadInWeaponStats(STR fileName)
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubImpact);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubDeadliness);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].bAccuracy);
+ FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].nAccuracy);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubMagSize);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].usRange);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].usReloadDelay);
@@ -795,6 +838,10 @@ BOOLEAN ReadInWeaponStats(STR fileName)
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].bAutofireShotsPerFiveAP);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].APsToReloadManually);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ManualReloadSound);
+ FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubAimLevels);
+ FilePrintf(hFile,"\t\t%d<\bRecoilX>\r\n", Weapon[cnt].bRecoilX);
+ FilePrintf(hFile,"\t\t%d<\bRecoilY>\r\n", Weapon[cnt].bRecoilY);
+ FilePrintf(hFile,"\t\t%d<\ubRecoilDelay>\r\n", Weapon[cnt].ubRecoilDelay);
FilePrintf(hFile,"\t\r\n");
}
FilePrintf(hFile,"\r\n");
@@ -880,10 +927,13 @@ BOOLEAN WriteWeaponStats()
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubShotsPer4Turns);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubShotsPerBurst);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubBurstPenalty);
+ FilePrintf(hFile,"\t\t%d<\bRecoilX>", Weapon[cnt].bRecoilX);
+ FilePrintf(hFile,"\t\t%d<\bRecoilY>", Weapon[cnt].bRecoilY);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubBulletSpeed);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubImpact);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubDeadliness);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].bAccuracy);
+ FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].nAccuracy);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubMagSize);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].usRange);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].usReloadDelay);
@@ -903,6 +953,8 @@ BOOLEAN WriteWeaponStats()
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].maxdistformessydeath);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].AutoPenalty);
FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].NoSemiAuto);
+ FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].ubAimLevels );
+ FilePrintf(hFile,"\t\t%d\r\n", Weapon[cnt].EasyUnjam);
@@ -915,7 +967,7 @@ BOOLEAN WriteWeaponStats()
return( TRUE );
}
-UINT16 GunRange( OBJECTTYPE * pObj )
+UINT16 GunRange( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier ) // SANDRO - added argument
{
//INT8 bAttachPos;
UINT16 rng;
@@ -953,8 +1005,20 @@ UINT16 GunRange( OBJECTTYPE * pObj )
//}
+ UINT16 usRange = GetModifiedGunRange(pObj->usItem);
+
// Snap: attachment status is factored into the range bonus calculation
- rng = Weapon[ pObj->usItem ].usRange + GetRangeBonus(pObj);
+ rng = usRange + GetRangeBonus(pObj);
+
+ // SANDRO - STOMP traits - Gunslinger bonus range with pistols
+ if ( pSoldier != NULL && Item[ pObj->usItem ].usItemClass & IC_GUN )
+ {
+ if ((Weapon[ pObj->usItem ].ubWeaponType == GUN_PISTOL || Weapon[ pObj->usItem ].ubWeaponType == GUN_M_PISTOL) &&
+ gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) )
+ {
+ rng += (rng * gSkillTraitValues.ubGSEffectiveRangeBonusPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ) / 100 );
+ }
+ }
return rng;
}
@@ -977,7 +1041,7 @@ INT32 EffectiveArmour( OBJECTTYPE * pObj )
iValue = iValue * (*pObj)[0]->data.objectStatus * Armour[ Item[pObj->usItem].ubClassIndex ].ubCoverage / 10000;
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
- if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
+ if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists())
{
INT32 iValue2;
@@ -1077,7 +1141,7 @@ INT32 ExplosiveEffectiveArmour( OBJECTTYPE * pObj )
}
for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
- if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
+ if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists())
{
INT32 iValue2;
@@ -1136,7 +1200,8 @@ void AdjustImpactByHitLocation( INT32 iImpact, UINT8 ubHitLocation, INT32 * piNe
{
case AIM_SHOT_HEAD:
// 1.5x damage from successful hits to the head!
- *piImpactForCrits = HEAD_DAMAGE_ADJUSTMENT( iImpact );
+ //*piImpactForCrits = HEAD_DAMAGE_ADJUSTMENT( iImpact ); //comm by ddd
+ *piImpactForCrits = INT32(gGameExternalOptions.fShotHeadDivisor*iImpact);
*piNewImpact = *piImpactForCrits;
break;
case AIM_SHOT_LEGS:
@@ -1173,7 +1238,7 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier )
{
// Algorithm for jamming
int maxJamChance = 50; // Externalize this?
- int reliability = Item[pObj->usItem].bReliability;
+ int reliability = GetReliability( pObj );
int condition = (*pObj)[0]->data.gun.bGunStatus;
int invertedBaseJamChance = condition + (reliability * 2) -
gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity * gbCurrentRainIntensity;
@@ -1242,15 +1307,27 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier )
if(EnoughPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM], FALSE))
{
DeductPoints(pSoldier, APBPConstants[AP_UNJAM], APBPConstants[BP_UNJAM]);
- int iResult = SkillCheck( pSoldier, UNJAM_GUN_CHECK, (INT8) ((Item[pObj->usItem].bReliability + Item[(*pObj)[0]->data.gun.usGunAmmoItem].bReliability)* 4) );
+ INT8 bChanceMod;
+
+ if ( Weapon[pSoldier->inv[pSoldier->ubAttackingHand].usItem].EasyUnjam )
+ bChanceMod = 100;
+ else
+ bChanceMod = (INT8) (GetReliability( pObj )* 4);
+
+ int iResult = SkillCheck( pSoldier, UNJAM_GUN_CHECK, bChanceMod);
+
if (iResult > 0)
{
// yay! unjammed the gun
(*pObj)[0]->data.gun.bGunAmmoStatus *= -1;
// MECHANICAL/DEXTERITY GAIN: Unjammed a gun
- StatChange( pSoldier, MECHANAMT, 5, FALSE );
- StatChange( pSoldier, DEXTAMT, 5, FALSE );
+
+ if (bChanceMod < 100) // don't give exp for unjamming an easily unjammable gun
+ {
+ StatChange( pSoldier, MECHANAMT, 5, FALSE );
+ StatChange( pSoldier, DEXTAMT, 5, FALSE );
+ }
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
@@ -1400,9 +1477,9 @@ BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
break;
case IC_LAUNCHER:
- if ( Item[pSoldier->usAttackingWeapon].rocketlauncher )
+ if ( Item[pSoldier->usAttackingWeapon].rocketlauncher ){
UseGun( pSoldier, sTargetGridNo );
- else
+ } else {
// ATE: PAtch up - bookkeeping for spreading done out of whak
if ( pSoldier->flags.fDoSpread)
{
@@ -1440,6 +1517,7 @@ BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
UseLauncher( pSoldier, sTargetGridNo );
}
+ }
break;
@@ -1559,9 +1637,573 @@ void GetTargetWorldPositions( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, FLOAT
*pdZPos = dTargetZ;
}
+// HEADROCK HAM 4: The CTH formula has been radically altered, and the value it returns is used very differently.
+// This function now no longer rolls any random variables - that is relegated to other functions. However, this
+// function is now responsible for altering the "center point" for the attack, given target movement and previous
+// bullets fired in a volley.
+BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
+{
+ // CTH is now used as a Muzzle Sway value. That is, it determines how wide our shot can go off the "center point"
+ // of the attack. Later on, we'll randomize just how far the shot actually goes within that sway radius.
+ UINT32 uiMuzzleSway;
+ INT16 sXMapPos, sYMapPos;
+ INT16 sAPCost;
+ FLOAT dTargetX;
+ FLOAT dTargetY;
+ FLOAT dTargetZ;
+ UINT16 usItemNum;
+ BOOLEAN fBuckshot;
+ UINT8 ubVolume;
+ CHAR8 zBurstString[512];
+ UINT8 ubDirection;
+ INT32 sNewGridNo;
+ UINT8 ubMerc;
+ BOOLEAN fGonnaHit = FALSE;
+ FLOAT dExpGain = 0;
+ UINT32 uiDepreciateTest;
+
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("UseGun") );
+
+ // Calculate total APs required to complete the entire attack, including all relevant weapon AP costs
+ // with possible turning and gun-raising costs as well.
+ sAPCost = CalcTotalAPsToAttack( pSoldier, sTargetGridNo, FALSE, pSoldier->aiData.bAimTime );
+
+ usItemNum = pSoldier->usAttackingWeapon;
+
+ // CALC MUZZLE SWAY
+ if ( Item[ usItemNum ].usItemClass == IC_THROWING_KNIFE )
+ {
+ uiMuzzleSway = 100 - CalcThrownChanceToHit( pSoldier, sTargetGridNo, pSoldier->aiData.bAimTime, pSoldier->bAimShotLocation );
+ }
+ else
+ {
+ uiMuzzleSway = 100 - CalcChanceToHitGun( pSoldier, sTargetGridNo, pSoldier->aiData.bAimTime, pSoldier->bAimShotLocation );
+ }
+
+ //ATE: Added if we are in meanwhile, we always hit...
+ if ( AreInMeanwhile( ) )
+ {
+ uiMuzzleSway = 0; // HEADROCK HAM 4: This ensures a direct shot at the target.
+ }
+
+ #ifdef JA2BETAVERSION
+ if ( gfReportHitChances )
+ {
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Hit chance was %ld, roll %ld (range %d)", uiHitChance, uiDiceRoll, PythSpacesAway( pSoldier->sGridNo, pSoldier->sTargetGridNo ) );
+ }
+ #endif
+
+ if ( pSoldier->bDoBurst )
+ {
+ // Only deduct points once for Burst and Autofire (on firing the first bullet).
+ if ( pSoldier->bDoBurst == 1 )
+ {
+ INT8 bShotsToFire = pSoldier->bDoAutofire ?
+ pSoldier->bDoAutofire :
+ GetShotsPerBurst(&pSoldier->inv[HANDPOS]);
+
+ if ( Weapon[ usItemNum ].sBurstSound != NO_WEAPON_SOUND )
+ {
+ // IF we are silenced?
+ UINT16 noisefactor = GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
+ if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ usItemNum ].ubAttackVolume <= 10 )
+ {
+ // Pick sound file baed on how many bullets we are going to fire...
+ sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sSilencedBurstSound ], bShotsToFire );
+
+ // Try playing sound...
+ pSoldier->iBurstSoundID = PlayJA2SampleFromFile( zBurstString, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
+ }
+ else
+ {
+ // Pick sound file baed on how many bullets we are going to fire...
+ // Lesh: changed next line
+ sprintf( zBurstString, gzBurstSndStrings[ Weapon[ usItemNum ].sBurstSound ], bShotsToFire );
+
+ INT8 volume = HIGHVOLUME;
+ if ( noisefactor < 100 ) volume = (INT8) ((volume * noisefactor) / 100);
+ // Try playing sound...
+ pSoldier->iBurstSoundID = PlayJA2SampleFromFile( zBurstString, RATE_11025, SoundVolume( (INT8) volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
+ }
+
+ /*
+ //DIGICRAB: We don't need this anymore, because of the burst sound modification
+ // If we don't have the burst sound, a normal shot will be played for each shot
+ if ( pSoldier->iBurstSoundID == NO_SAMPLE )
+ {
+ // If failed, play normal default....
+ pSoldier->iBurstSoundID = PlayJA2Sample( Weapon[ usItemNum ].sBurstSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
+ }
+ */
+ }
+
+ DeductPoints( pSoldier, sAPCost, 0 );
+ }
+
+ }
+ else
+ {
+ // ONLY DEDUCT FOR THE FIRST HAND when doing two-pistol attacks
+ if ( pSoldier->IsValidSecondHandShot( ) && pSoldier->inv[ HANDPOS ][0]->data.gun.bGunStatus >= USABLE && pSoldier->inv[HANDPOS][0]->data.gun.bGunAmmoStatus > 0 )
+ {
+ // only deduct APs when the main gun fires
+ if ( pSoldier->ubAttackingHand == HANDPOS )
+ {
+ DeductPoints( pSoldier, sAPCost, 0 );
+ }
+ }
+ else
+ {
+ DeductPoints( pSoldier, sAPCost, 0 );
+ }
+
+ //PLAY SOUND
+ // ( For throwing knife.. it's earlier in the animation
+ if ( Weapon[ usItemNum ].sSound != NO_WEAPON_SOUND && Item[ usItemNum ].usItemClass != IC_THROWING_KNIFE )
+ {
+ // Switch on silencer...
+ UINT16 noisefactor = GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
+ if( noisefactor < MAX_PERCENT_NOISE_VOLUME_FOR_SILENCED_SOUND || Weapon[ usItemNum ].ubAttackVolume <= 10 )
+ {
+ INT32 uiSound;
+
+ uiSound = Weapon [ usItemNum ].silencedSound ;
+ //if ( Weapon[ usItemNum ].ubCalibre == AMMO9 || Weapon[ usItemNum ].ubCalibre == AMMO38 || Weapon[ usItemNum ].ubCalibre == AMMO57 )
+ //{
+ // uiSound = S_SILENCER_1;
+ //}
+ //else
+ //{
+ // uiSound = S_SILENCER_2;
+ //}
+
+ PlayJA2Sample( uiSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
+
+ }
+ else
+ {
+ INT8 volume = HIGHVOLUME;
+ if ( noisefactor < 100 ) volume = (volume * noisefactor) / 100;
+ PlayJA2Sample( Weapon[ usItemNum ].sSound, RATE_11025, SoundVolume( volume, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
+ }
+ }
+ }
+
+//ddd{ . silencer
+ if ( (Item[ usItemNum ].usItemClass == IC_GUN) && gGameExternalOptions.bAllowWearSuppressor)
+ {
+ OBJECTTYPE * pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+ if ( IsFlashSuppressor(&pSoldier->inv[ pSoldier->ubAttackingHand ], pSoldier ) )
+ {
+ for (attachmentList::iterator iter = (*pInHand)[0]->attachments.begin(); iter != (*pInHand)[0]->attachments.end(); ++iter)
+ {
+ if (Item[iter->usItem].hidemuzzleflash )
+ {
+ OBJECTTYPE* pA= &(*iter);
+ if ( (*pA)[0]->data.objectStatus >=USABLE)
+ {
+ INT16 ammoReliability = Item[(*pInHand)[0]->data.gun.usGunAmmoItem].bReliability;
+ INT16 uiDepreciateTest = BASIC_DEPRECIATE_CHANCE + 3 *
+ (Item[ iter->usItem ].bReliability + ammoReliability);
+ if ( !PreRandom( uiDepreciateTest ) && ( pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.objectStatus > 1) )
+ (*pA)[0]->data.objectStatus--;
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"rel =%d ",Item[ iter->usItem ].bReliability );
+ }
+ }
+ }
+ }
+ } //if ( Item[ usItemNum ].usItemClass == IC_GUN )
+//ddd}
+
+ //DIGICRAB: Barrel extender wear code
+ // Relocated from CalcChanceToHitGun
+ if ( Item[ usItemNum ].usItemClass == IC_GUN )
+ {
+ OBJECTTYPE * pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+
+ // lalien: search for barrel extender not for any item with range bonus. (else barrel extender will fall off even when none is attached)
+ OBJECTTYPE* pAttachment = FindAttachment( pInHand, GUN_BARREL_EXTENDER );
+
+ if ( pAttachment )
+ {
+ // reduce status and see if it falls off
+ (*pAttachment)[0]->data.objectStatus -= (INT8) Random( 2 );
+
+ if ( (*pAttachment)[0]->data.objectStatus - Random( 35 ) - Random( 35 ) < USABLE )
+ {
+ //CHRISL: This setup assumes that remove() will work successfully, but if it doesn't we'll duplicate the item.
+ // barrel extender falls off!
+ // drop it to ground
+ //AddItemToPool( pSoldier->sGridNo, pAttachment, 1, pSoldier->pathing.bLevel, 0, -1 );
+
+ // since barrel extenders are not removable we cannot call RemoveAttachment here
+ // and must create the item by hand
+ //(*pInHand)[0]->attachments.remove(*pAttachment);
+ //ADB ubWeight has been removed, see comments in OBJECTTYPE
+ //pInHand->ubWeight = CalculateObjectWeight( pInHand );
+
+ //CHRISL: Instead of the above, use this function which is basially redundant to what remove() does, but includes
+ // a failsafe so we don't cause an item duplication.
+ for(std::list::iterator iter = (*pInHand)[0]->attachments.begin();
+ iter != (*pInHand)[0]->attachments.end(); ++iter){
+ if(*iter == *pAttachment)
+ {
+ AddItemToPool( pSoldier->sGridNo, pAttachment, 1, pSoldier->pathing.bLevel, 0, -1 );
+
+ iter = (*pInHand)[0]->RemoveAttachmentAtIter(iter);
+
+ break;
+ }
+ }
+
+ // big penalty to hit
+ // HEADROCK HAM 4: Muzzle sway INCREASES when a barrel extender falls off.
+ if(uiMuzzleSway > 70)
+ {
+ uiMuzzleSway = 100;
+ }
+ else
+ {
+ uiMuzzleSway += 30;
+ }
+
+ // curse!
+ if ( pSoldier->bTeam == OUR_TEAM )
+ {
+ pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
+
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 46 ], pSoldier->name );
+ }
+ }
+ }
+ }
+
+ // Some things we don't do for knives...
+ if ( Item[ usItemNum ].usItemClass != IC_THROWING_KNIFE )
+ {
+ // If realtime - set counter to freeup from attacking once done
+ if ( ( ( gTacticalStatus.uiFlags & REALTIME ) || !( gTacticalStatus.uiFlags & INCOMBAT ) ) )
+ {
+
+ // Set delay based on stats, weapon type, etc
+ pSoldier->sReloadDelay = (INT16)( Weapon[ usItemNum ].usReloadDelay + MANDATORY_WEAPON_DELAY );
+
+ // If a bad guy, double the delay!
+ if ( (pSoldier->flags.uiStatusFlags & SOLDIER_ENEMY ) )
+ {
+ pSoldier->sReloadDelay = ( pSoldier->sReloadDelay * 2 );
+ }
+
+
+ // slow down demo mode!
+ if ( gTacticalStatus.uiFlags & DEMOMODE )
+ {
+ pSoldier->sReloadDelay *= 2;
+ }
+
+ //pSoldier->flags.fReloading = TRUE;
+ //RESETTIMECOUNTER( pSoldier->timeCounters.ReloadCounter, pSoldier->sReloadDelay );
+ }
+
+ // Deduct AMMO!
+ DeductAmmo( pSoldier, pSoldier->ubAttackingHand );
+
+ // ATE: Check if we should say quote...
+ if ( pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft == 0 && !Item[pSoldier->usAttackingWeapon].rocketlauncher )
+ {
+ if ( pSoldier->bTeam == gbPlayerNum )
+ {
+ pSoldier->flags.fSayAmmoQuotePending = TRUE;
+ }
+ }
+
+ // set buckshot and muzzle flash
+ fBuckshot = FALSE;
+ if (!CREATURE_OR_BLOODCAT( pSoldier ) )
+ {
+ if ( IsFlashSuppressor(&pSoldier->inv[ pSoldier->ubAttackingHand ], pSoldier ) )
+ pSoldier->flags.fMuzzleFlash = FALSE;
+ else
+ pSoldier->flags.fMuzzleFlash = TRUE;
+
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("UseGun: Muzzle flash = %d",pSoldier->flags.fMuzzleFlash));
+
+ if ( AmmoTypes[pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunAmmoType].numberOfBullets > 1 )
+ fBuckshot = TRUE;
+
+ //switch ( pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunAmmoType )
+ //{
+ // case AMMO_BUCKSHOT:
+ // fBuckshot = TRUE;
+ // break;
+ // case AMMO_SLEEP_DART:
+ // pSoldier->flags.fMuzzleFlash = FALSE;
+ // break;
+ // default:
+ // break;
+ //}
+ }
+ }
+ else // throwing knife
+ {
+ fBuckshot = FALSE;
+ pSoldier->flags.fMuzzleFlash = FALSE;
+
+ // Deduct knife from inv! (not here, later?)
+ }
+
+ if ( Item[usItemNum].rocketlauncher )
+ {
+ if ( WillExplosiveWeaponFail( pSoldier, &( pSoldier->inv[ HANDPOS ] ) ) )
+ {
+ if ( Item[usItemNum].singleshotrocketlauncher )
+ {
+ CreateItem( Item[usItemNum].discardedlauncheritem , pSoldier->inv[ HANDPOS ][0]->data.objectStatus,&(pSoldier->inv[ HANDPOS ] ) );
+ DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
+ IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, C1, pSoldier->pathing.bLevel );
+ }
+ else
+ {
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("StructureHit: RPG7 item: %d, Ammo: %d",pSoldier->inv[HANDPOS].usItem , pSoldier->inv[HANDPOS][0]->data.gun.usGunAmmoItem ) );
+
+ IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem, pSoldier->pathing.bLevel );
+ pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+ }
+ // Reduce again for attack end 'cause it has been incremented for a normal attack
+ //
+ // Not anymore. Only the attack animation was increased, and it will decrease itself.
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK, Now %d", gAnimControl[ pSoldier->usAnimState ].zAnimStr, gTacticalStatus.ubAttackBusyCount ) );
+ DebugAttackBusy( String("@@@@@@@ Freeing up attacker - ATTACK ANIMATION %s ENDED BY BAD EXPLOSIVE CHECK\n", gAnimControl[ pSoldier->usAnimState ].zAnimStr ) );
+ // ReduceAttackBusyCount( pSoldier->ubID, FALSE );
+
+ return( FALSE );
+ }
+ }
+
+ // GET TARGET XY VALUES
+ ConvertGridNoToCenterCellXY( sTargetGridNo, &sXMapPos, &sYMapPos );
+
+ // ATE; Moved a whole blotch if logic code for finding target positions to a function
+ // so other places can use it
+ // If the target contains a soldier, this function determines the x,y,z coordinates of the center of the
+ // targeted bodypart.
+ GetTargetWorldPositions( pSoldier, sTargetGridNo, &dTargetX, &dTargetY, &dTargetZ );
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: New Shooting Mechanism
+ //
+ // This single function is now responsible for determining the point where the bullet will go. It adjusts
+ // the target x/y/z coordinates autonomously, based on the various effects of the new shooting mechanism.
+ //
+ // Therefore, once we reach FireBulletGivenTarget, the coordinates passed to that function are the ABSOLUTE
+ // final coordinates of the bullet, so FireBullet doesn't actually need to calculate anything beyond that except
+ // the angle increments required to put the bullet through those coordinates.
+
+ INT16 sApertureRatio = 0;
+ if ( !AreInMeanwhile() )
+ {
+ AdjustTargetCenterPoint( pSoldier, sTargetGridNo, &dTargetX, &dTargetY, &dTargetZ, &pSoldier->inv[ pSoldier->ubAttackingHand ], uiMuzzleSway, &sApertureRatio );
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Basic Experience Gain
+ //
+ // This part gives out basic experience gain for taking a shot or throwing a knife. It gives a few number of
+ // "free" points for any attack, and then an additional number of points based on how difficult the shot is,
+ // and how well the gun is being aimed.
+ // All points given here are FAILURE type, and cannot cause level gain.
+ // In addition, once the target is HIT, the shooter receives an additional number of points.
+
+ if ( Item[ usItemNum ].usItemClass != IC_THROWING_KNIFE )
+ {
+ // NB bDoBurst will be 2 at this point for the first shot since it was incremented
+ // above
+ // HEADROCK: Actually, it's 1 for the first shot. Works fine regardless though.
+ // HEADROCK HAM 4: Extra experience gain now given when the target is hit. This part only gives basic points
+ // for the attack (FAILURE type).
+ if ( PTR_OURTEAM && pSoldier->ubTargetID != NOBODY && (!pSoldier->bDoBurst || pSoldier->bDoBurst == 2 ) && (gTacticalStatus.uiFlags & INCOMBAT ) && ( SoldierToSoldierBodyPartChanceToGetThrough( pSoldier, MercPtrs[ pSoldier->ubTargetID ], pSoldier->bAimShotLocation ) > 0 ) )
+ {
+ // add base pts for taking a shot, whether it hits or misses
+ dExpGain = 2.0f;
+
+ if ( pSoldier->IsValidSecondHandShot( ) && pSoldier->inv[ HANDPOS ][0]->data.gun.bGunStatus >= USABLE && pSoldier->inv[HANDPOS][0]->data.gun.bGunAmmoStatus > 0 )
+ {
+ // reduce exp gain for two pistol shooting since both shots give xp
+ dExpGain = (dExpGain * 2) / 3;
+ }
+
+ if ( MercPtrs[ pSoldier->ubTargetID ]->ubBodyType == COW || MercPtrs[ pSoldier->ubTargetID ]->ubBodyType == CROW )
+ {
+ dExpGain /= 2;
+ }
+ else if ( MercPtrs[ pSoldier->ubTargetID ]->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( MercPtrs[ pSoldier->ubTargetID ] ) || TANK( MercPtrs[ pSoldier->ubTargetID ] ) )
+ {
+ // no exp from shooting a vehicle that you can't damage and can't move!
+ dExpGain = 0;
+ }
+
+ UINT16 usDextGain = (UINT16)(dExpGain / 2);
+ UINT16 usAgilGain = (UINT16)(dExpGain / 2);
+ UINT16 usMrksGain = 0;
+
+ // Extra marksmanship/dexterity bonus for aiming.
+ if (pSoldier->aiData.bAimTime)
+ {
+ dExpGain += (3 * sApertureRatio) / 100; // At this point, usExpGain could equal up to 5.
+ usDextGain += (UINT16)(dExpGain / 3);
+ usMrksGain += (UINT16)((dExpGain * 2) / 3);
+ }
+
+ // DEXTERITY/AGILITY/MARKSMANSHIP GAIN: gun attack
+ StatChange( pSoldier, AGILAMT, usAgilGain, FROM_FAILURE );
+ StatChange( pSoldier, DEXTAMT, usDextGain, FROM_FAILURE );
+ StatChange( pSoldier, MARKAMT, usMrksGain, FROM_FAILURE );
+ }
+ }
+ else
+ {
+ // HEADROCK HAM 4: Extra experience gain now done when the bullet hits the target. This part only
+ // gives basic experience for the attack (FAILURE type).
+ // Improve for using a throwing knife....
+ if (PTR_OURTEAM && pSoldier->ubTargetID != NOBODY)
+ {
+ // add base pts for taking a shot, whether it hits or misses
+ dExpGain = 5.0f;
+
+ if ( MercPtrs[ pSoldier->ubTargetID ]->ubBodyType == COW || MercPtrs[ pSoldier->ubTargetID ]->ubBodyType == CROW )
+ {
+ dExpGain /= 2;
+ }
+ else if ( MercPtrs[ pSoldier->ubTargetID ]->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( MercPtrs[ pSoldier->ubTargetID ] ) || TANK( MercPtrs[ pSoldier->ubTargetID ] ) )
+ {
+ // no exp from shooting a vehicle that you can't damage and can't move!
+ dExpGain = 0;
+ }
+
+ UINT16 usDextGain = (UINT16)(dExpGain / 2);
+ UINT16 usAgilGain = (UINT16)(dExpGain / 2);
+ UINT16 usMrksGain = 0;
+
+ // Extra marksmanship/dexterity bonus for aiming.
+ if (pSoldier->aiData.bAimTime)
+ {
+ dExpGain += (5 * sApertureRatio) / 100; // At this point, usExpGain could equal up to 10.
+ usDextGain += (UINT16)(dExpGain / 3);
+ usMrksGain += (UINT16)((dExpGain * 2) / 3);
+ }
+
+ // DEXTERITY/AGILITY/MARKSMANSHIP GAIN: gun attack
+ StatChange( pSoldier, AGILAMT, usAgilGain, FROM_FAILURE );
+ StatChange( pSoldier, DEXTAMT, usDextGain, FROM_FAILURE );
+ StatChange( pSoldier, MARKAMT, usMrksGain, FROM_FAILURE );
+ }
+ }
+
+ /////////////////////////////// Fire bullet at the target coordinates.
+ //hayden
+ if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) )
+ {
+ FireBulletGivenTarget( pSoldier, dTargetX, dTargetY, dTargetZ, pSoldier->usAttackingWeapon, sApertureRatio, fBuckshot, FALSE );
+ }
+ else
+ {
+ FireBulletGivenTarget( pSoldier, dTargetX, dTargetY, dTargetZ, pSoldier->usAttackingWeapon, sApertureRatio, fBuckshot, TRUE );
+ }
+ //bottom one is fake (ie not in my control)
+
+ ubVolume = Weapon[ pSoldier->usAttackingWeapon ].ubAttackVolume;
+
+ if ( Item[ usItemNum ].usItemClass == IC_THROWING_KNIFE )
+ {
+ // Here, remove the knife... or (for now) rocket launcher
+ pSoldier->inv[ HANDPOS ].RemoveObjectsFromStack(1);
+ DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
+ }
+ else if ( Item[usItemNum].rocketlauncher )
+ {
+ if ( Item[usItemNum].singleshotrocketlauncher )
+ {
+ CreateItem( Item[usItemNum].discardedlauncheritem, pSoldier->inv[ HANDPOS ][0]->data.objectStatus, &(pSoldier->inv[ HANDPOS ] ) );
+ DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
+ }
+
+ // Direction to center of explosion
+ ubDirection = gOppositeDirection[ pSoldier->ubDirection ];
+ sNewGridNo = NewGridNo( pSoldier->sGridNo, (UINT16)(1 * DirectionInc( ubDirection ) ) );
+
+ // Check if a person exists here and is not prone....
+ ubMerc = WhoIsThere2( sNewGridNo, pSoldier->pathing.bLevel );
+
+ if ( ubMerc != NOBODY )
+ {
+ if ( gAnimControl[ MercPtrs[ ubMerc ]->usAnimState ].ubHeight != ANIM_PRONE )
+ {
+ // Increment attack counter...
+// gTacticalStatus.ubAttackBusyCount++;
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Incrementing Attack: Exaust from LAW", gTacticalStatus.ubAttackBusyCount ) );
+ DebugAttackBusy( "Incrementing Attack: Exaust from LAW\n" );
+
+ MercPtrs[ ubMerc ]->EVENT_SoldierGotHit( MINI_GRENADE, 10, 200, pSoldier->ubDirection, 0, pSoldier->ubID, 0, ANIM_CROUCH, 0, sNewGridNo );
+ }
+ }
+ }
+ else
+ {
+ // Snap: get cumulative noise reduction from the weapon and its attachments
+ UINT16 noisefactor = GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] );
+ if ( ubVolume * noisefactor > 25000 )
+ { // Snap: hack this to prevent overflow (damn miserly programmers!)
+ ubVolume = 250;
+ }
+ else
+ {
+ ubVolume = __max( 1, ( ubVolume * GetPercentNoiseVolume( &pSoldier->inv[ pSoldier->ubAttackingHand ] ) ) / 100 );
+ }
+ }
+
+ MakeNoise( pSoldier->ubID, pSoldier->sGridNo, pSoldier->pathing.bLevel, pSoldier->bOverTerrainType, ubVolume, NOISE_GUNFIRE );
+
+ if ( pSoldier->bDoBurst )
+ {
+ // done, if bursting, increment
+ pSoldier->bDoBurst++;
+ }
+
+ // CJC: since jamming is no longer affected by reliability, increase chance of status going down for really unreliabile guns
+ //INT16 ammoReliability = 0; // Madd: ammo reliability affects gun
+
+ //if ( Item[usItemNum].usItemClass == IC_GUN )
+ //{
+ // OBJECTTYPE *pGun = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+ // ammoReliability = Item[(*pGun)[0]->data.gun.usGunAmmoItem].bReliability;
+ //}
+
+ uiDepreciateTest = BASIC_DEPRECIATE_CHANCE + 3 * GetReliability( &(pSoldier->inv[pSoldier->ubAttackingHand]) );
+
+ if ( !PreRandom( uiDepreciateTest ) && ( pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.objectStatus > 1) )
+ {
+ pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.objectStatus--;
+ }
+
+ // reduce monster smell (gunpowder smell)
+ if ( pSoldier->aiData.bMonsterSmell > 0 && Random( 2 ) == 0 )
+ {
+ pSoldier->aiData.bMonsterSmell--;
+ }
+
+// manual recharge
+ if (Weapon[Item[usItemNum].ubClassIndex].APsToReloadManually > 0)
+ pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunState &= ~GS_CARTRIDGE_IN_CHAMBER;
+//
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("UseGun: done"));
+ return( TRUE );
+}
BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
+ if(UsingNewCTHSystem() == true)
+ return UseGunNCTH(pSoldier, sTargetGridNo);
+
UINT32 uiHitChance, uiDiceRoll;
INT16 sXMapPos, sYMapPos;
INT16 sAPCost;
@@ -1691,9 +2333,39 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
{
fCalculateCTHDuringGunfire = TRUE;
uiHitChance = CalcChanceToHitGun( pSoldier, sTargetGridNo, pSoldier->aiData.bAimTime, pSoldier->bAimShotLocation );
+ //CHRISL:
+ //pSoldier->CTH.push_back(uiHitChance);
+ //if(pSoldier->bDoAutofire == pSoldier->bDoBurst && pSoldier->CTH.size() > 0)
+ // pSoldier->CTH.clear();
}
fCalculateCTHDuringGunfire = FALSE;
+//ddd{ . silencer
+ if ( (Item[ usItemNum ].usItemClass == IC_GUN) && gGameExternalOptions.bAllowWearSuppressor)
+ {
+ OBJECTTYPE * pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+ if ( IsFlashSuppressor(&pSoldier->inv[ pSoldier->ubAttackingHand ], pSoldier ) )
+ {
+ for (attachmentList::iterator iter = (*pInHand)[0]->attachments.begin(); iter != (*pInHand)[0]->attachments.end(); ++iter)
+ {
+ if (Item[iter->usItem].hidemuzzleflash )
+ {
+ OBJECTTYPE* pA= &(*iter);
+ if ( (*pA)[0]->data.objectStatus >=USABLE)
+ {
+ INT16 ammoReliability = Item[(*pInHand)[0]->data.gun.usGunAmmoItem].bReliability;
+ INT16 uiDepreciateTest = BASIC_DEPRECIATE_CHANCE + 3 *
+ (Item[ iter->usItem ].bReliability + ammoReliability);
+ if ( !PreRandom( uiDepreciateTest ) && ( pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.objectStatus > 1) )
+ (*pA)[0]->data.objectStatus--;
+ //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"rel =%d ",Item[ iter->usItem ].bReliability );
+ }
+ }
+ }
+ }
+ } //if ( Item[ usItemNum ].usItemClass == IC_GUN )
+//ddd}
+
//DIGICRAB: Barrel extender wear code
// Relocated from CalcChanceToHitGun
if ( Item[ usItemNum ].usItemClass == IC_GUN )
@@ -1703,7 +2375,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
// lalien: search for barrel extender not for any item with range bonus. (else barrel extender will fall off even when none is attached)
OBJECTTYPE* pAttachment = FindAttachment( pInHand, GUN_BARREL_EXTENDER );
- if ( pAttachment )
+ if ( pAttachment->exists() )
{
// reduce status and see if it falls off
(*pAttachment)[0]->data.objectStatus -= (INT8) Random( 2 );
@@ -1728,7 +2400,9 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
if(*iter == *pAttachment)
{
AddItemToPool( pSoldier->sGridNo, pAttachment, 1, pSoldier->pathing.bLevel, 0, -1 );
- iter = (*pInHand)[0]->attachments.erase(iter);
+
+ iter = (*pInHand)[0]->RemoveAttachmentAtIter(iter);
+
break;
}
}
@@ -1958,7 +2632,13 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("StructureHit: RPG7 item: %d, Ammo: %d",pSoldier->inv[HANDPOS].usItem , pSoldier->inv[HANDPOS][0]->data.gun.usGunAmmoItem ) );
IgniteExplosion( pSoldier->ubID, CenterX( pSoldier->sGridNo ), CenterY( pSoldier->sGridNo ), 0, pSoldier->sGridNo, pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem, pSoldier->pathing.bLevel );
- pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+
+ OBJECTTYPE * pLaunchable = FindLaunchableAttachment( &(pSoldier->inv[pSoldier->ubAttackingHand ]), pSoldier->inv[pSoldier->ubAttackingHand ].usItem );
+ if(pLaunchable){
+ pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = pLaunchable->usItem;
+ } else {
+ pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+ }
}
// Reduce again for attack end 'cause it has been incremented for a normal attack
//
@@ -2039,16 +2719,19 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
pSoldier->bDoBurst++;
}
+ /* //WarmSteel - Replaced with GetReliability( pObj )
// CJC: since jamming is no longer affected by reliability, increase chance of status going down for really unreliabile guns
INT16 ammoReliability = 0; // Madd: ammo reliability affects gun
+
if ( Item[usItemNum].usItemClass == IC_GUN )
{
OBJECTTYPE *pGun = &(pSoldier->inv[pSoldier->ubAttackingHand]);
ammoReliability = Item[(*pGun)[0]->data.gun.usGunAmmoItem].bReliability;
}
+ */
- uiDepreciateTest = BASIC_DEPRECIATE_CHANCE + 3 * (Item[ usItemNum ].bReliability + ammoReliability);
+ uiDepreciateTest = BASIC_DEPRECIATE_CHANCE + 3 * ( GetReliability( &(pSoldier->inv[ pSoldier->ubAttackingHand ]) ) );
if ( !PreRandom( uiDepreciateTest ) && ( pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.objectStatus > 1) )
{
@@ -2117,6 +2800,15 @@ BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
iDiceRoll = (INT32) PreRandom( 100 );
//sprintf( gDebugStr, "Hit Chance: %d %d", (int)uiHitChance, uiDiceRoll );
+ // SANDRO - new mercs' records
+ if ( pSoldier->bTeam == gbPlayerNum && pSoldier->ubProfile != NO_PROFILE )
+ {
+ gMercProfiles[ pSoldier->ubProfile ].records.usBladeAttacks++;
+ if ( iDiceRoll < iHitChance )
+ {
+ gMercProfiles[ pSoldier->ubProfile ].records.usShotsHit++;
+ }
+ }
// WDS 07/19/2008 - Random number use fix
if ( iDiceRoll < iHitChance )
@@ -2158,6 +2850,10 @@ BOOLEAN UseBlade( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo )
pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.objectStatus -= (INT8) Random( bMaxDrop ); // 0 to (maxDrop - 1)
}
+ // SANDRO - new merc records - times wounded (stabbed)
+ if ( pTargetSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pTargetSoldier->ubProfile ].records.usTimesWoundedStabbed++;
+
// Send event for getting hit
memset( &(SWeaponHit), 0, sizeof( SWeaponHit ) );
SWeaponHit.usSoldierID = pTargetSoldier->ubID;
@@ -2263,6 +2959,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
BOOLEAN fNoMoreItems = FALSE; // The enemy has no more items to steal!
BOOLEAN fNoMoreItemInHand = FALSE;
BOOLEAN fSoldierCollapsed = FALSE;
+ BOOLEAN fStealAttempt = FALSE; // added - SANDRO
// Deduct points!
// August 13 2002: unless stealing - APs already deducted elsewhere
@@ -2276,6 +2973,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
else
{
// APs were already reduced!
+ //SANDRO - actually we will redure them here, but lower and based on number of items stolen.
}
// See if a guy is here!
@@ -2292,7 +2990,7 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
if (fStealing)
{
// Calculate the possible chance to steal!
- if ( AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || TANK( pTargetSoldier ) )
+ if ( AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) || CREATURE_OR_BLOODCAT( pTargetSoldier ) || TANK( pTargetSoldier ) || (SOLDIER_CLASS_MILITIA(pTargetSoldier->ubSoldierClass) && (gGameExternalOptions.ubMilitiaDropEquipment != 2)) ) // added militia here - SANDRO
{
iHitChance = 0;
}
@@ -2342,75 +3040,168 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
// -----------------------------------
if (fStealing )
{
+ // SANDRO - unable to steal from militia if they are not allowed to drop equipment
+ if (SOLDIER_CLASS_MILITIA(pTargetSoldier->ubSoldierClass) && (gGameExternalOptions.ubMilitiaDropEquipment != 2) )
+ {
+ DeductPoints( pSoldier, (APBPConstants[AP_STEAL_ITEM] / 5), 0 );
+ pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
+ return ( TRUE );
+ }
+
fFailure=FALSE;
+ // WDS 07/19/2008 - Random number use fix
+ // Do we have the chance to steal more than 1 item?
+ // SANDRO - taking items from collapsed soldiers is treated differently
+ if (( fSoldierCollapsed || (!gGameExternalOptions.fEnhancedCloseCombatSystem && iDiceRoll < (iHitChance * 2 / 3))) && pSoldier->bTeam == gbPlayerNum )
+ {
+ // first, charge extra Aps, because it's difficlut to pickup from other soldier
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ DeductPoints( pSoldier, (GetBasicAPsToPickupItem( pSoldier ) * 2), 0 );
+
+ // The item that the enemy holds in his hand before the stealing
+ usOldItem = pTargetSoldier->inv[HANDPOS].usItem;
+
+ INT16 sNumStolenItems = StealItems(pSoldier, pTargetSoldier,&ubIndexRet);
+
+ // We have only stolen 1 item, because the enemy has not more than one item.
+ if ( sNumStolenItems == 1)
+ {
+ // charge Aps
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 );
+
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[ STR_STOLE_SOMETHING ], pSoldier->name, ShortItemNames[ pTargetSoldier->inv[ubIndexRet].usItem ] );
+ if (pTargetSoldier->inv[ubIndexRet].MoveThisObjectTo(gTempObject, 1) == 0) {
+
+ // Try to place the item in the merc inventory
+ if (!AutoPlaceObject( pSoldier, &gTempObject, TRUE ))
+ {
+ // Place the item on the ground
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
+ }
+
+ // The item that the enemy holds in his hand before the stealing
+ usNewItem = pTargetSoldier->inv[HANDPOS].usItem;
+
+ if (usOldItem != usNewItem)
+ {
+ pTargetSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldItem, usNewItem );
+ }
+ }
+ // The enemy has no more items to steal
+ else if (sNumStolenItems == 0)
+ {
+ fNoMoreItems = TRUE;
+ }
+ }
// WDS 07/19/2008 - Random number use fix
// Do we have luck on stealing?
- if ( iDiceRoll < iHitChance && iHitChance > 0 )
+ else if ( iDiceRoll < iHitChance && iHitChance > 0 )
{
- // WDS 07/19/2008 - Random number use fix
- // Do we have the chance to steal more than 1 item?
- if (( iDiceRoll < iHitChance * 2 / 3) || (pTargetSoldier->bCollapsed))
+ if ( pTargetSoldier->inv[HANDPOS].exists() == true )
{
- // The item that the enemy holds in his hand before the stealing
- usOldItem = pTargetSoldier->inv[HANDPOS].usItem;
+ UINT16 usOldItemTarget = pTargetSoldier->inv[HANDPOS].usItem;
- INT16 sNumStolenItems = StealItems(pSoldier, pTargetSoldier,&ubIndexRet);
+ fStealAttempt = TRUE; // added for check
- // We have only stolen 1 item, because the enemy has not more than one item.
- if ( sNumStolenItems == 1)
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[ STR_STOLE_SOMETHING ], pSoldier->name, ShortItemNames[ pTargetSoldier->inv[HANDPOS].usItem ] );
+
+ // if successful - place the item to our hands
+ if (iDiceRoll < (iHitChance * 2 / 3) && gGameExternalOptions.fEnhancedCloseCombatSystem)
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[ STR_STOLE_SOMETHING ], pSoldier->name, ShortItemNames[ pTargetSoldier->inv[ubIndexRet].usItem ] );
- if (pTargetSoldier->inv[ubIndexRet].MoveThisObjectTo(gTempObject, 1) == 0) {
+ usOldItem = pSoldier->inv[HANDPOS].usItem;
+ OBJECTTYPE oTempObjectSecondHand;
+ INT8 bEmptySl;
+ oTempObjectSecondHand.usItem = 0;
- // Try to place the item in the merc inventory
- if (!AutoPlaceObject( pSoldier, &gTempObject, TRUE ))
+ // if we have something in main hand, place it into inventory or on the ground
+ if (pSoldier->inv[HANDPOS].exists() == true )
+ {
+ if( pSoldier->bTeam != gbPlayerNum ) // for enemies, ignore rules and place it anywhere
+ {
+ bEmptySl = FindEmptySlotWithin( pSoldier, BIGPOCKSTART, NUM_INV_SLOTS );
+ SwapObjs( pSoldier, HANDPOS, bEmptySl, TRUE );
+ }
+ else if (!PlaceInAnyPocket( pSoldier, &pSoldier->inv[HANDPOS], FALSE, 5))
+ {
+ if (!AutoPlaceObject( pSoldier, &pSoldier->inv[HANDPOS], FALSE, 5))
+ AddItemToPool( pSoldier->sGridNo, &pSoldier->inv[HANDPOS], 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
+ }
+ // if twohanded item, place the secondhand item if any to temp space
+ if (pSoldier->inv[SECONDHANDPOS].exists() == true && Item[pTargetSoldier->inv[HANDPOS].usItem].twohanded)
+ {
+ if( pSoldier->bTeam != gbPlayerNum ) // for enemies, ignore rules and place it anywhere
+ {
+ bEmptySl = FindEmptySlotWithin( pSoldier, BIGPOCKSTART, NUM_INV_SLOTS );
+ SwapObjs( pSoldier, SECONDHANDPOS, bEmptySl, TRUE );
+ }
+ else
+ {
+ pSoldier->inv[SECONDHANDPOS].MoveThisObjectTo(oTempObjectSecondHand, 1);
+ }
+ }
+ // now take the item
+ if (pTargetSoldier->inv[HANDPOS].MoveThisObjectTo(gTempObject, 1) == 0)
+ {
+ if (PlaceObject( pSoldier, HANDPOS, &gTempObject ))
+ {
+ pSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldItem, gTempObject.usItem );
+ if( pSoldier->bTeam != gbPlayerNum ) // make sure item is droppable now, so we don't lose our gun if killed this enemy
+ {
+ pSoldier->inv[HANDPOS].fFlags &= ~OBJECT_UNDROPPABLE;
+ }
+ }
+ else
{
- // Place the item on the ground
AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
}
}
-
- // The item that the enemy holds in his hand before the stealing
- usNewItem = pTargetSoldier->inv[HANDPOS].usItem;
-
- if (usOldItem != usNewItem)
+ // if second hand item was removed place it now somewhere
+ if (oTempObjectSecondHand.usItem != 0 )
{
- pTargetSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldItem, usNewItem );
+ if (!PlaceInAnyPocket( pSoldier, &pSoldier->inv[HANDPOS], FALSE, 5))
+ {
+ if (!AutoPlaceObject( pSoldier, &oTempObjectSecondHand, FALSE ))
+ {
+ AddItemToPool( pSoldier->sGridNo, &oTempObjectSecondHand, 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
+ }
}
- }
- // The enemy has no more items to steal
- else if (sNumStolenItems == 0)
- {
- fNoMoreItems = TRUE;
- }
- }
- // We had not much luck, so we can only steal 1 item.
- else if ( pTargetSoldier->inv[HANDPOS].exists() == true )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[ STR_STOLE_SOMETHING ], pSoldier->name, ShortItemNames[ pTargetSoldier->inv[HANDPOS].usItem ] );
- usOldItem = pTargetSoldier->inv[HANDPOS].usItem;
- if ( pSoldier->bTeam == gbPlayerNum )
- {
- pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
- }
+ // add to merc records
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pSoldier->ubProfile ].records.usItemsStolen++;
+ }
// Item dropped somewhere... roll based on the same chance to determine where!
- if (pTargetSoldier->inv[HANDPOS].MoveThisObjectTo(gTempObject, 1) == 0) {
- iDiceRoll = (INT32) PreRandom( 100 );
- if (iDiceRoll < iHitChance)
+ else
+ {
+ if ( pSoldier->bTeam == gbPlayerNum )
{
- // Drop item in the our tile
- AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ pSoldier->DoMercBattleSound( BATTLE_SOUND_CURSE1 );
}
- else
+ if (pTargetSoldier->inv[HANDPOS].MoveThisObjectTo(gTempObject, 1) == 0)
{
- // Drop item in the target's tile
- AddItemToPool( pTargetSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ iDiceRoll = (INT32) PreRandom( 100 );
+ if (iDiceRoll < iHitChance)
+ {
+ // Drop item in the our tile
+ AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
+ else
+ {
+ // Drop item in the target's tile
+ AddItemToPool( pTargetSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, 0, -1 );
+ }
}
+ // add to merc records
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pSoldier->ubProfile ].records.usItemsStolen++;
}
// Reload buddy's animation...
- pTargetSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldItem, NOTHING );
+ pTargetSoldier->ReLoadSoldierAnimationDueToHandItemChange( usOldItemTarget, NOTHING );
}
// Enemy has no item in his hand.
else
@@ -2426,6 +3217,44 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
fFailure=TRUE;
}
+ // SANDRO - Enhanced Close Combat System
+ // Deduct APs for stealing now (moved from Soldier Control.cpp) - SANDRO
+ // If stolen something or fail to steal, reduce APs by the full amount
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ if (fSoldierCollapsed)
+ {
+ // APs are reduced in Handle Items.cpp in "SoldierStealItemFromSoldier"
+ }
+ else if ( fStealAttempt || (fFailure == TRUE))
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && ( gGameOptions.fNewTraitSystem ))
+ {
+ DeductPoints( pSoldier, max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5)), 200);
+ }
+ else
+ {
+ DeductPoints( pSoldier, APBPConstants[AP_STEAL_ITEM], 200 );
+ }
+ }
+ // Only 1/7 of original AP cost, if the enemy has nothing to steal
+ else if ((fNoMoreItems == TRUE) || (fNoMoreItemInHand == TRUE))
+ {
+ DeductPoints( pSoldier, (APBPConstants[AP_STEAL_ITEM] / 7), 0 );
+ }
+ }
+ else
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) && ( gGameOptions.fNewTraitSystem ))
+ {
+ DeductPoints( pSoldier, max( 1, (INT16)((APBPConstants[AP_STEAL_ITEM] * (100 - gSkillTraitValues.ubMAReducedAPsToSteal * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ))/ 100) + 0.5)), 0);
+ }
+ else
+ {
+ DeductPoints( pSoldier, APBPConstants[AP_STEAL_ITEM], 0 );
+ }
+ }
+
// We failed to steal something!
if (fFailure)
{
@@ -2466,20 +3295,54 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{
if (fFailure == FALSE)
{
- // We were successfull in stealing. Give some experience
- StatChange( pSoldier, STRAMT, 8, FALSE );
- StatChange( pSoldier, DEXTAMT, 3, FALSE );
- StatChange( pSoldier, AGILAMT, 3, FALSE );
+ // SANDRO - Enhanced Close Combat System - experience for stealing changed
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ // stealing from unconsious opponents is not rewarded much
+ if (fSoldierCollapsed)
+ {
+ StatChange( pSoldier, DEXTAMT, 1, FALSE );
+ }
+ else
+ {
+ // We were successfull in stealing. Give some experience
+ StatChange( pSoldier, STRAMT, 6, FALSE );
+ StatChange( pSoldier, DEXTAMT, 10, FALSE );
+ StatChange( pSoldier, AGILAMT, 10, FALSE );
+ }
+ }
+ else
+ {
+ // We were successfull in stealing. Give some experience
+ StatChange( pSoldier, STRAMT, 8, FALSE );
+ StatChange( pSoldier, DEXTAMT, 3, FALSE );
+ StatChange( pSoldier, AGILAMT, 3, FALSE );
+ }
}
else
{
- // failed a steal; give some experience
- StatChange( pSoldier, STRAMT, 4, FROM_FAILURE );
- StatChange( pSoldier, DEXTAMT, 1, FROM_FAILURE );
- StatChange( pSoldier, AGILAMT, 1, FROM_FAILURE );
+ // SANDRO - Enhanced Close Combat System - experience for stealing changed
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ // failed a steal; give some experience - slightly changed by SANDRO
+ StatChange( pSoldier, STRAMT, 2, FROM_FAILURE );
+ StatChange( pSoldier, DEXTAMT, 4, FROM_FAILURE );
+ StatChange( pSoldier, AGILAMT, 4, FROM_FAILURE );
+ }
+ else
+ {
+ // failed a steal; give some experience
+ StatChange( pSoldier, STRAMT, 4, FROM_FAILURE );
+ StatChange( pSoldier, DEXTAMT, 1, FROM_FAILURE );
+ StatChange( pSoldier, AGILAMT, 1, FROM_FAILURE );
+ }
}
}
+ // SANDRO - Enhanced Close Combat System - Notice merc after stealing
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ pTargetSoldier->EVENT_SetSoldierDesiredDirection( GetDirectionFromGridNo( pSoldier->sGridNo, pTargetSoldier ) );
+
// 0verhaul: Also handled in the animation transition
// #ifdef JA2BETAVERSION
// DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("@@@@@@@ Freeing up attacker - steal") );
@@ -2492,11 +3355,25 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
// -----------------------------------
else
{
- // ATE/CC: if doing ninja spin kick (only), automatically make it a hit
- if ( pSoldier->usAnimState == NINJA_SPINKICK)
+ // SANDRO - new mercs' records
+ if ( pSoldier->bTeam == gbPlayerNum && pSoldier->ubProfile != NO_PROFILE )
{
- // Let him to succeed by a random amount
- iDiceRoll = PreRandom( iHitChance );
+ gMercProfiles[ pSoldier->ubProfile ].records.usHtHAttacks++;
+ if ( iDiceRoll < iHitChance )
+ {
+ gMercProfiles[ pSoldier->ubProfile ].records.usShotsHit++;
+ }
+ }
+
+ // SANDRO - Enhanced Close Combat System - spinning kick is not automatic but just more damaging
+ if (!gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ // ATE/CC: if doing ninja spin kick (only), automatically make it a hit
+ if ( pSoldier->usAnimState == NINJA_SPINKICK)
+ {
+ // Let him to succeed by a random amount
+ iDiceRoll = PreRandom( iHitChance );
+ }
}
if ( pSoldier->bTeam == gbPlayerNum && pTargetSoldier->bTeam != gbPlayerNum )
@@ -2507,6 +3384,28 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
{
ubExpGain = 8;
+ // SANDRO - Enhanced Close Combat System - EXP given based on type of attack
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ // Increased EXP for head strike
+ if (pSoldier->bAimShotLocation == AIM_SHOT_HEAD)
+ {
+ ubExpGain += 2;
+ }
+ // Decreased EXP for leg strike
+ else if (pSoldier->bAimShotLocation == AIM_SHOT_LEGS)
+ {
+ ubExpGain -= 4;
+ }
+
+ // Double EXP for focused attack
+ if ( (pSoldier->usAnimState == NINJA_SPINKICK || pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6)) &&
+ ((HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT)) && gGameOptions.fNewTraitSystem ))
+ {
+ ubExpGain *= 2;
+ }
+ }
+
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) )
{
ubExpGain = 0;
@@ -2516,15 +3415,47 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
ubExpGain /= 2;
}
-
- StatChange( pSoldier, DEXTAMT, ubExpGain, FALSE );
- StatChange( pSoldier, STRAMT, (ubExpGain+1)/3, FALSE );
- StatChange( pSoldier, AGILAMT, (ubExpGain+1)/3, FALSE );
+ // SANDRO - Enhanced Close Combat System
+ if ( gGameExternalOptions.fEnhancedCloseCombatSystem && pTargetSoldier->bCollapsed)
+ {
+ // beating unconscious enemy is a matter of brute strength, so give exp mostly to Stregnth
+ StatChange( pSoldier, DEXTAMT, (ubExpGain+1)/3, FALSE );
+ StatChange( pSoldier, STRAMT, ubExpGain + 1, FALSE );
+ StatChange( pSoldier, AGILAMT, (ubExpGain+1)/3, FALSE );
+ }
+ else
+ {
+ StatChange( pSoldier, DEXTAMT, ubExpGain, FALSE );
+ StatChange( pSoldier, STRAMT, (ubExpGain+1)/3, FALSE );
+ StatChange( pSoldier, AGILAMT, (ubExpGain+1)/3, FALSE );
+ }
}
else
{
ubExpGain = 4;
+ // SANDRO - Enhanced Close Combat System - EXP given based on type of attack
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ // Increased EXP for head strike
+ if (pSoldier->bAimShotLocation == AIM_SHOT_HEAD)
+ {
+ ubExpGain += 1;
+ }
+ // Decreased EXP for leg strike
+ else if (pSoldier->bAimShotLocation == AIM_SHOT_LEGS)
+ {
+ ubExpGain -= 2;
+ }
+
+ // Double EXP for focused attack
+ if ( (pSoldier->usAnimState == NINJA_SPINKICK || pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6)) &&
+ ((HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT)) && gGameOptions.fNewTraitSystem ) )
+ {
+ ubExpGain *= 2;
+ }
+ }
+
if ( pTargetSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || AM_A_ROBOT( pTargetSoldier ) || TANK( pTargetSoldier ) )
{
ubExpGain = 0;
@@ -2534,7 +3465,6 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
ubExpGain /= 2;
}
-
StatChange( pSoldier, DEXTAMT, ubExpGain, FALSE );
StatChange( pSoldier, STRAMT, (ubExpGain+1)/3, FALSE );
StatChange( pSoldier, AGILAMT, (ubExpGain+1)/3, FALSE );
@@ -2545,12 +3475,48 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
// being attacked... if successfully dodged, give experience
if ( iDiceRoll > iHitChance )
{
- StatChange( pTargetSoldier, DEXTAMT, 8, FALSE );
- StatChange( pTargetSoldier, STRAMT, 3, FALSE );
- StatChange( pTargetSoldier, AGILAMT, 3, FALSE );
+ // SANDRO - Enhanced Close Combat System - More logical - give EXP for dodging to Agility most
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ StatChange( pTargetSoldier, DEXTAMT, 5, FALSE ); // 4 istead of 8
+ StatChange( pTargetSoldier, STRAMT, 2, FALSE ); // 2 instead of 3
+ StatChange( pTargetSoldier, AGILAMT, 8, FALSE ); // 8 instead of 3
+ }
+ else
+ {
+ StatChange( pTargetSoldier, DEXTAMT, 8, FALSE );
+ StatChange( pTargetSoldier, STRAMT, 3, FALSE );
+ StatChange( pTargetSoldier, AGILAMT, 3, FALSE );
+ }
}
}
+ // SANDRO - Enhanced Close Combat System - Add dodge animation of target if missed ninja spin kick
+ if ( (iDiceRoll >= iHitChance) && pSoldier->usAnimState == NINJA_SPINKICK && gGameExternalOptions.fEnhancedCloseCombatSystem
+ && gAnimControl[ pTargetSoldier->usAnimState ].ubHeight == ANIM_STAND && IS_MERC_BODY_TYPE( pTargetSoldier ))
+ {
+ pTargetSoldier->ChangeSoldierState( DODGE_ONE, 0 , FALSE );
+ // after dodging melee attack go to apropriate stance
+ if ( (gAnimControl[ pTargetSoldier->usAnimState ].ubHeight == ANIM_STAND) && (Item[pTargetSoldier->inv[HANDPOS].usItem].usItemClass == IC_PUNCH))
+ {
+ if ((((NUM_SKILL_TRAITS( pTargetSoldier, MARTIAL_ARTS_NT ) >= ((gSkillTraitValues.fPermitExtraAnimationsOnlyToMA) ? 2 : 1 )) && gGameOptions.fNewTraitSystem ) ||
+ (HAS_SKILL_TRAIT( pTargetSoldier, MARTIALARTS_OT ) && !gGameOptions.fNewTraitSystem ) ) &&
+ pTargetSoldier->ubBodyType == REGMALE )
+ {
+ //pTSoldier->usPendingAnimation = NINJA_GOTOBREATH;
+ pTargetSoldier->usPendingAnimation = NINJA_BREATH ;
+ }
+ else
+ {
+ pTargetSoldier->usPendingAnimation = PUNCH_BREATH ;
+ }
+ }
+ else if ( (gAnimControl[ pTargetSoldier->usAnimState ].ubHeight == ANIM_STAND) && (Item[pTargetSoldier->inv[HANDPOS].usItem].usItemClass == IC_BLADE))
+ {
+ //pTSoldier->usPendingAnimation = KNIFE_GOTOBREATH;
+ pTargetSoldier->usPendingAnimation = KNIFE_BREATH ;
+ }
+ }
// WDS 07/19/2008 - Random number use fix
if ( iDiceRoll < iHitChance || AreInMeanwhile( ) )
@@ -2558,6 +3524,10 @@ BOOLEAN UseHandToHand( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo, BOOLEAN fStea
// CALCULATE DAMAGE!
iImpact = HTHImpact( pSoldier, pTargetSoldier, (iHitChance - iDiceRoll), FALSE );
+ // SANDRO - new merc records - times wounded (punched)
+ if ( pTargetSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pTargetSoldier->ubProfile ].records.usTimesWoundedPunched++;
+
// Send event for getting hit
memset( &(SWeaponHit), 0, sizeof( SWeaponHit ) );
SWeaponHit.usSoldierID = pTargetSoldier->ubID;
@@ -2687,6 +3657,14 @@ BOOLEAN UseThrown( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
}
+ /////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - new mercs' records
+ if ( Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_GRENADE || Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_BOMB || Item[ pSoldier->inv[HANDPOS].usItem ].usItemClass == IC_THROWN)
+ {
+ gMercProfiles[ pSoldier->ubProfile ].records.usGrenadesThrown++;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
CalculateLaunchItemParamsForThrow( pSoldier, sTargetGridNo, pSoldier->bTargetLevel, (INT16)(pSoldier->bTargetLevel * 256 ), &(pSoldier->inv[ HANDPOS ] ), (INT8)(uiDiceRoll - uiHitChance), THROW_ARM_ITEM, 0 );
//AXP 25.03.2007: Cleaned up throwing AP costs. Now only turning + stance change AP
@@ -2737,7 +3715,7 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
pObj = &(pSoldier->inv[HANDPOS]);
attachmentList::iterator iter;
for (iter = (*pObj)[0]->attachments.begin(); iter != (*pObj)[0]->attachments.end(); ++iter) {
- if ( Item[ iter->usItem ].usItemClass & IC_EXPLOSV )
+ if ( Item[ iter->usItem ].usItemClass & IC_EXPLOSV && iter->exists())
{
break;
}
@@ -2748,7 +3726,10 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
return( FALSE );
}
- if ( Weapon[GetAttachedGrenadeLauncher(pObj)].ubMagSize > 1 || ( Item[pObj->usItem].grenadelauncher && GetMagSize(pObj) > 1 ))
+ //CHRISL: Added a magsize value to Explosives.xml which is checked by GetExpMagSize. This will allow OAS to load individual grenades into
+ // multi-launch grenades and fire correctly
+ //if ( Weapon[GetAttachedGrenadeLauncher(pObj)].ubMagSize > 1 || ( Item[pObj->usItem].grenadelauncher && GetMagSize(pObj) > 1 ))
+ if(GetExpMagSize(&(*iter)) > 1)
CreateItem( iter->usItem, 100, &Launchable );
else
CreateItem( iter->usItem, (*iter)[0]->data.objectStatus, &Launchable );
@@ -2831,6 +3812,15 @@ BOOLEAN UseLauncher( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
DeductPoints( pSoldier, sAPCost, 0 );
}
+ /////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - new mercs' records
+ if ( Item[ usItemNum ].usItemClass == IC_LAUNCHER || Item[usItemNum].grenadelauncher ||
+ Item[usItemNum].rocketlauncher || Item[usItemNum].singleshotrocketlauncher || Item[usItemNum].mortar )
+ {
+ gMercProfiles[ pSoldier->ubProfile ].records.usMissilesLaunched++;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
CalculateLaunchItemParamsForThrow( pSoldier, sTargetGridNo, pSoldier->bTargetLevel, 0, &Launchable, (INT8)(uiDiceRoll - uiHitChance), THROW_ARM_ITEM, 0 );
iID = CreatePhysicalObject( pSoldier->pTempObject, pSoldier->pThrowParams->dLifeSpan, pSoldier->pThrowParams->dX, pSoldier->pThrowParams->dY, pSoldier->pThrowParams->dZ, pSoldier->pThrowParams->dForceX, pSoldier->pThrowParams->dForceY, pSoldier->pThrowParams->dForceZ, pSoldier->ubID, pSoldier->pThrowParams->ubActionCode, pSoldier->pThrowParams->uiActionData, FALSE );
@@ -3051,7 +4041,14 @@ void WeaponHit( UINT16 usSoldierID, UINT16 usWeaponIndex, INT16 sDamage, INT16 s
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("WeaponHit: RPG7 item: %d, Ammo: %d",pSoldier->inv[HANDPOS].usItem , pSoldier->inv[HANDPOS][0]->data.gun.usGunAmmoItem ) );
IgniteExplosion( ubAttackerID, sXPos, sYPos, 0, GETWORLDINDEXFROMWORLDCOORDS( sYPos, sXPos ), pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem, pTargetSoldier->pathing.bLevel );
- pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+
+ //This is just to make multishot launchers work in semi auto. It's not really a permanent solution because it still doesn't allow autofire, but it will do for now.
+ OBJECTTYPE * pLaunchable = FindLaunchableAttachment( &(pSoldier->inv[pSoldier->ubAttackingHand ]), pSoldier->inv[pSoldier->ubAttackingHand ].usItem );
+ if(pLaunchable){
+ pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = pLaunchable->usItem;
+ } else {
+ pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+ }
}
else if ( AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.ubGunAmmoType].explosionSize > 1)
{
@@ -3172,7 +4169,14 @@ void StructureHit( INT32 iBullet, UINT16 usWeaponIndex, INT16 bWeaponStatus, UIN
{
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("StructureHit: RPG7 item: %d, Ammo: %d",pAttacker->inv[HANDPOS].usItem , pAttacker->inv[HANDPOS][0]->data.gun.usGunAmmoItem ) );
IgniteExplosion( ubAttackerID, CenterX( sGridNo ), CenterY( sGridNo ), 0, sGridNo, pAttacker->inv[pAttacker->ubAttackingHand ][0]->data.gun.usGunAmmoItem , (INT8)( sZPos >= WALL_HEIGHT ) );
- pAttacker->inv[pAttacker->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+
+ //This is just to make multishot launchers work in semi auto. It's not really a permanent solution because it still doesn't allow autofire, but it will do for now.
+ OBJECTTYPE * pLaunchable = FindLaunchableAttachment( &(pAttacker->inv[pAttacker->ubAttackingHand ]), pAttacker->inv[pAttacker->ubAttackingHand ].usItem );
+ if(pLaunchable){
+ pAttacker->inv[pAttacker->ubAttackingHand ][0]->data.gun.usGunAmmoItem = pLaunchable->usItem;
+ } else {
+ pAttacker->inv[pAttacker->ubAttackingHand ][0]->data.gun.usGunAmmoItem = NONE;
+ }
}
else if ( AmmoTypes[pSoldier->inv[pSoldier->ubAttackingHand ][0]->data.gun.ubGunAmmoType].explosionSize > 1)
{
@@ -3513,7 +4517,9 @@ void WindowHit( INT32 sGridNo, UINT16 usStructureID, BOOLEAN fBlowWindowSouth, B
AniParams.uiFlags = ANITILE_FORWARD;
pNode = CreateAnimationTile( &AniParams );
-
+ //dddokno{
+CompileWorldMovementCosts();
+//dddokno}
PlayJA2Sample( GLASS_SHATTER1 + Random(2), RATE_11025, MIDVOLUME, 1, SoundDir( sGridNo ) );
}
@@ -3544,7 +4550,7 @@ BOOLEAN InRange( SOLDIERTYPE *pSoldier, INT32 sGridNo )
else
{
// For given weapon, check range
- if ( sRange <= GunRange( &(pSoldier->inv[HANDPOS]) ) )
+ if ( sRange <= GunRange( &(pSoldier->inv[HANDPOS]), pSoldier ) ) // SANDRO - added argument
{
return( TRUE );
}
@@ -3553,205 +4559,974 @@ BOOLEAN InRange( SOLDIERTYPE *pSoldier, INT32 sGridNo )
return( FALSE );
}
-UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos )
+UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos )
{
- //SOLDIERTYPE *vicpSoldier;
- SOLDIERTYPE * pTarget;
- INT32 iChance, iRange, iSightRange, iMaxRange, iBonus; //, minRange;
- //rain
- //INT32 iScopeBonus;
- //end rain
- INT32 iGunCondition, iMarksmanship;
- INT32 iPenalty;
+ //////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4:
+ //
+ // The CTH/Firing system has been completely revamped. CTH is now the result of
+ // two completely separate calculations. One takes into account skill and conditions,
+ // the other relies on gun accuracy.
+ // See also UseGun() for further notes.
+ //
+ //////////////////////////////////////////////////////////////////////////////////
+
+ // Basic defines
+ SOLDIERTYPE * pTarget;
+ INT32 iChance, iRange, iSightRange; //, minRange;
+
UINT16 usInHand;
OBJECTTYPE * pInHand;
-// INT8 bAttachPos;
- INT8 bBandaged;
- INT16 sDistVis;
- UINT8 ubAdjAimPos;
+ INT8 bBandaged, iTraitModifier;
+ INT16 sDistVis, sDistVisNoScope;
UINT8 ubTargetID;
bool highPowerScope = false;
- UINT32 pScope;
-
- // HEADROCK HAM 3.5: Variable holds total autofire penalty.
INT16 sTotalAutofirePenalty = 0;
-
- DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun"));
-
- if ( pSoldier->stats.bMarksmanship == 0 )
- {
- // HEADROCK: (HAM) Altered to accept external arguments
- // return( MINCHANCETOHIT );
- return( gGameExternalOptions.ubMinimumCTH );
- }
-
+ bool fCantSeeTarget = false;
+ FLOAT scopeRangeMod;
+
// make sure the guy's actually got a weapon in his hand!
pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
usInHand = pSoldier->usAttackingWeapon;
- //CHRISL: We have new modifiers when using a high power scope so find out if we have one from the start
- for(attachmentList::iterator iter = (*pInHand)[0]->attachments.begin(); iter != (*pInHand)[0]->attachments.end(); iter++)
- {
- if(Item[iter->usItem].aimbonus > HIGH_POWER_SCOPE)
- {
- highPowerScope = true;
- pScope = iter->usItem;
- break;
- }
- }
-
- // DETERMINE BASE CHANCE OF HITTING
- iGunCondition = WEAPON_STATUS_MOD( (*pInHand)[0]->data.gun.bGunStatus );
-
- if (Item[usInHand].rocketlauncher )
- {
- // use the same calculation as for mechanical thrown weapons
- iMarksmanship = ( EffectiveDexterity( pSoldier ) + EffectiveMarksmanship( pSoldier ) + EffectiveWisdom( pSoldier ) + (10 * EffectiveExpLevel( pSoldier ) )) / 4;
- // heavy weapons trait helps out
- if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPS ))
- {
- iMarksmanship += gbSkillTraitBonus[HEAVY_WEAPS] * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS );
- }
- }
- else
- {
- iMarksmanship = EffectiveMarksmanship( pSoldier );
-
- if ( AM_A_ROBOT( pSoldier ) )
- {
- SOLDIERTYPE * pSoldier2;
-
- pSoldier2 = pSoldier->GetRobotController( );
- if ( pSoldier2 )
- {
- iMarksmanship = __max( iMarksmanship, EffectiveMarksmanship( pSoldier2 ) );
- }
- }
- }
-
- // modify chance to hit by morale
- iMarksmanship += GetMoraleModifier( pSoldier );
-
- // penalize marksmanship for fatigue
- iMarksmanship -= GetSkillCheckPenaltyForFatigue( pSoldier, iMarksmanship );
-
- //if ( PTR_OURTEAM )
- //{
- // iChance = ( iMarksmanship * iGunCondition ) / 100;
- //}
- //else
- {
- if (iGunCondition >= iMarksmanship)
- // base chance is equal to the shooter's marksmanship skill
- iChance = iMarksmanship;
- else
- // base chance is equal to the average of marksmanship & gun's condition!
- iChance = (iMarksmanship + iGunCondition) / 2;
- }
- // if shooting same target as the last shot
- if (sGridNo == pSoldier->sLastTarget )
- iChance += AIM_BONUS_SAME_TARGET; // give a bonus to hit
-
- if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == PSYCHO )
- {
- iChance += AIM_BONUS_PSYCHO;
- }
// calculate actual range (in units, 10 units = 1 tile)
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
- if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_STAND )
- {
- //CHRISL: Incur a penalty if using a highPowerScope
- if(highPowerScope == true && iRange > Item[pScope].minrangeforaimbonus)
- {
- iPenalty = (Item[pScope].aimbonus * (iRange-Item[pScope].minrangeforaimbonus)) / 1000;
- if (iPenalty > AIM_BONUS_PRONE)
- {
- iPenalty = AIM_BONUS_PRONE;
+ // Find a target in the tile
+ ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel ); // Target ubID
+ pTarget = SimpleFindSoldier( sGridNo, pSoldier->bTargetLevel ); // Target Pointer
+
+ // Calculate how easy it is to handle this gun.
+ FLOAT iGunDifficulty = (FLOAT)(( Weapon[ usInHand ].ubReadyTime * (100 - GetPercentReadyTimeAPReduction(pInHand) )) / 100);
+ iGunDifficulty *= (FLOAT)(100 / APBPConstants[AP_MAXIMUM]); // Adjust for 100AP/25AP
+ FLOAT iGunBaseDifficulty = iGunDifficulty;
+ FLOAT iGunAimDifficulty = iGunDifficulty;
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ //
+ // CALCULATE LINE OF SIGHT
+ //
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ //CHRISL: We have a new way to do this using a global variable
+ gbForceWeaponReady = true;
+
+ sDistVis = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
+
+ iSightRange = 0;
+
+ if (ubTargetID != NOBODY && pSoldier->aiData.bOppList[ubTargetID] == SEEN_CURRENTLY || gbPublicOpplist[pSoldier->bTeam][ubTargetID] == SEEN_CURRENTLY)
+ iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false );
+ if (iSightRange == 0) { // didn't do a bodypart-based test or can't see specific body part aimed at
+ iSightRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, TRUE, NO_DISTANCE_LIMIT, false );
+ }
+ if (iSightRange == 0) { // Can't see the target but we still need to know what the sight range would be if we could so we can deal with cover penalties
+ iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false, true );
+ fCantSeeTarget = true;
+ }
+
+ gbForceWeaponReady = false;
+
+ //CHRIS: This next value needs to be determined with no vision modifiers from our weapon
+ gbForceWeaponNotReady = true;
+ sDistVisNoScope = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
+ gbForceWeaponNotReady = false;
+ scopeRangeMod = (float)sDistVis / (float)sDistVisNoScope; // percentage DistVis has been enhanced due to an attached scope
+ iSightRange = (INT32)(iSightRange / scopeRangeMod);
+ if(iSightRange > 0){
+ iSightRange -= GetGearAimBonus ( pSoldier, iSightRange, ubAimTime ) * iSightRange / 100;
+ if ( gGameOptions.fNewTraitSystem ) {
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) ) {
+ iSightRange -= ((gSkillTraitValues.ubSNEffRangeToTargetReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )) * iSightRange) /100;
}
- iChance -= iPenalty;
+ }
+ else if ( HAS_SKILL_TRAIT( pSoldier, PROF_SNIPER_OT ) ) {
+ iSightRange -= ((gbSkillTraitBonus[ PROF_SNIPER_OT ] * NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )) * iSightRange) /100;
+ }
+ if (iSightRange < 1) {
+ iSightRange = 1;
}
}
- // if shooter is crouched, he aims slightly better (to max of AIM_BONUS_CROUCHING)
- else if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH )
+ if(iSightRange > sDistVis)
+ fCantSeeTarget = true;
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // First step: Calculate a base CTH value
+ //
+ // This "Base" CTH is a percentage value describing how well our gun's muzzle is aimed
+ // when not spending any extra effort on aiming. In other words, it's the most basic state,
+ // where the shooter only brings up the gun into the general direction of the target, and
+ // pulls the trigger.
+ //
+ // This is calculated first by factoring in skills, and later by adding up various conditional
+ // factors into a percentage which is then applied to those skills.
+ //
+ // The most important skill here is EXPERIENCE.
+
+ FLOAT iBaseModifier = 0;
+
+ INT8 bExperience = EffectiveExpLevel( pSoldier );
+ INT8 bMarksmanship = EffectiveMarksmanship( pSoldier );
+ INT8 bDexterity = EffectiveDexterity( pSoldier );;
+ INT8 bWisdom = EffectiveWisdom( pSoldier );
+
+ if ( bMarksmanship == 0 || bDexterity == 0 )
{
- iBonus = iRange / 10;
- if (iBonus > AIM_BONUS_CROUCHING)
- {
- iBonus = AIM_BONUS_CROUCHING;
- }
- iChance += iBonus;
- //CHRISL: Incur a penalty if using a highPowerScope
- if(highPowerScope == true && iRange > Item[pScope].minrangeforaimbonus)
- {
- iPenalty = ((Item[pScope].aimbonus/2) * (iRange-Item[pScope].minrangeforaimbonus)) / 1000;
- if (iPenalty > AIM_BONUS_CROUCHING)
- {
- iPenalty = AIM_BONUS_CROUCHING;
- }
- iChance -= iPenalty;
- }
+ return( gGameExternalOptions.ubMinimumCTH );
}
- // if shooter is prone, he aims even better, except at really close range
- else if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE )
+
+ // Calculate the basic value for BASE CTH by factoring in all the character's skills.
+ FLOAT iCombinedSkill = (FLOAT)(gGameCTHConstants.BASE_EXP*(bExperience*10));
+ iCombinedSkill += (FLOAT)(gGameCTHConstants.BASE_MARKS * bMarksmanship);
+ iCombinedSkill += (FLOAT)(gGameCTHConstants.BASE_WIS * bWisdom);
+ iCombinedSkill += (FLOAT)(gGameCTHConstants.BASE_DEX * bDexterity);
+
+ // Divide by the total coefficient value.
+ iCombinedSkill = (FLOAT)(iCombinedSkill /
+ (gGameCTHConstants.BASE_EXP+
+ gGameCTHConstants.BASE_MARKS+
+ gGameCTHConstants.BASE_WIS+
+ gGameCTHConstants.BASE_DEX));
+
+ // At this point we have a value of 1 to 100. Divide by 3.
+ iCombinedSkill /= 3;
+
+ // iCombinedSkill is now our basic CTH. Its range is 0 to 33.
+ iChance = (INT32)iCombinedSkill;
+
+ // Add a flat Base bonus from the item and its attachments.
+ iChance += GetFlatBaseModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight );
+
+ // We now begin adding up factors that may increase or decrease Base CTH. They are pooled together to form a percentage
+ // value.
+
+ // MORALE
+ INT8 iCurrentMorale = GetMoraleModifier(pSoldier);
+ if (iCurrentMorale > 0)
{
- if (iRange > MIN_PRONE_RANGE)
+ iBaseModifier += (FLOAT)(iCurrentMorale * gGameCTHConstants.BASE_HIGH_MORALE);
+ }
+ else if (iCurrentMorale < 0)
+ {
+ iBaseModifier += (FLOAT)(iCurrentMorale * gGameCTHConstants.BASE_LOW_MORALE);
+ }
+
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ iTraitModifier = 0;
+ // Bonus for heavy weapons moved here from above to get instant CtH bonus and not marksmanship bonus,
+ // which is supressed by weapon condition
+ if (Item[usInHand].rocketlauncher || Item[usInHand].singleshotrocketlauncher)
{
- iBonus = iRange / 10;
- if (iBonus > AIM_BONUS_PRONE)
- {
- iBonus = AIM_BONUS_PRONE;
+ iTraitModifier += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!!
+
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ))
+ iTraitModifier += gSkillTraitValues.ubHWBonusCtHRocketLaunchers * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ); // +25% per trait
+ }
+ // Added CtH bonus for Gunslinger trait on pistols and machine-pistols
+ else if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierPistols; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iTraitModifier += gSkillTraitValues.ubGSBonusCtHPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +10% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_M_PISTOL )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierMachinePistols; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && ((pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0) || !gSkillTraitValues.ubGSCtHMPExcludeAuto))
+ iTraitModifier += gSkillTraitValues.ubGSBonusCtHMachinePistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Machinegunner skill on assault rifles, SMGs and LMGs
+ else if ( Weapon[usInHand].ubWeaponType == GUN_AS_RIFLE )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierAssaultRifles; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iTraitModifier += gSkillTraitValues.ubAWBonusCtHAssaultRifles * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SMG )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierSMGs; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iTraitModifier += gSkillTraitValues.ubAWBonusCtHSMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_LMG )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierLMGs; // -10% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iTraitModifier += gSkillTraitValues.ubAWBonusCtHLMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Gunslinger trait on pistols and machine-pistols
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierSniperRifles; // -10% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iTraitModifier += gSkillTraitValues.ubSNBonusCtHSniperRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Ranger skill on rifles and shotguns
+ else if ( Weapon[usInHand].ubWeaponType == GUN_RIFLE )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierRifles; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iTraitModifier += gSkillTraitValues.ubRABonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +5% per trait
+ //CHRISL: Why wouldn't sniper training include standard rifles which are often used as "poor-man sniper rifles"
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iTraitModifier += gSkillTraitValues.ubSNBonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SHOTGUN )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierShotguns; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) )
+ iTraitModifier += gSkillTraitValues.ubRABonusCtHShotguns * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +10% per trait
+ }
+
+ // Added small CtH penalty for robot if controller hasn't the Technician trait
+ if( AM_A_ROBOT( pSoldier ) )
+ {
+ iTraitModifier += gSkillTraitValues.bCtHModifierRobot; // -10%
+
+ if ( HAS_SKILL_TRAIT( pSoldier->GetRobotController(), TECHNICIAN_NT ) )
+ iTraitModifier += gSkillTraitValues.ubTECtHControlledRobotBonus * NUM_SKILL_TRAITS( pSoldier->GetRobotController(), TECHNICIAN_NT ); // +10% per trait
+ }
+
+ // Added character traits influence
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ {
+ // Sociable - better performance in groups
+ if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SOCIABLE );
+ if ( bNumMercs > 2 )
+ iTraitModifier += 5;
+ else if ( bNumMercs > 0 )
+ iTraitModifier += 2;
}
- // Snap: bipod bonus is now calculated in GetToHitBonus
- //bAttachPos = FindAttachment( pInHand, BIPOD );
- //if (bAttachPos != ITEM_NOT_FOUND)
- //{ // extra bonus to hit for a bipod, up to half the prone bonus itself
- // iBonus += (iBonus * WEAPON_STATUS_MOD(GetBipodStatus(pInHand)) / 100) / 2;
- //}
- iChance += iBonus;
+ // Loner - better performance when alone
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_LONER );
+ if ( bNumMercs == 0 )
+ iTraitModifier += 5;
+ else if ( bNumMercs <= 1 )
+ iTraitModifier += 2;
+ }
+ // Aggressive - bonus on bursts/autofire
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
+ {
+ if (( pSoldier->bDoBurst || pSoldier->bDoAutofire ) && !ubAimTime )
+ iTraitModifier += 5;
+ }
+ // Show-off - better performance if some babes around to impress
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SHOWOFF );
+ if ( bNumMercs > 1 )
+ iTraitModifier += 5;
+ else if ( bNumMercs > 0 )
+ iTraitModifier += 2;
+ }
+ // Added disabilities
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ {
+ // Heat intolerant penalty
+ if ( MercIsHot( pSoldier ) )
+ {
+ iTraitModifier -= 15;
+ }
+ // Small penalty for fear of insects in tropical sectors
+ else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ) )
+ {
+ // fear of insects, and we are in tropical sector
+ iTraitModifier -= 5;
+ }
+ }
+ }
+ // Dauntless - penalty for not taking proper cover
+ if (pTarget != NULL)
+ {
+ if ( pTarget->ubProfile != NO_PROFILE )
+ {
+ if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
+ iTraitModifier += 5;
+ }
+ }
+ //Give 40% the normal stomp modifier as a base mod
+ iBaseModifier += (FLOAT)iTraitModifier * 0.4f;
+ }
+ else
+ {
+ // PSYCHO
+ if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
+ {
+ iBaseModifier += (FLOAT)gGameCTHConstants.BASE_PSYCHO;
}
}
- //Madd: inherent weapon accuracy bonus
- iChance += Weapon[usInHand].bAccuracy;
+ // SHOOTING AT SAME TARGET AGAIN
+ if (sGridNo == pSoldier->sLastTarget )
+ iBaseModifier += (FLOAT)gGameCTHConstants.BASE_SAME_TARGET;
-// if ( !(Item[ usInHand ].fFlags & ITEM_TWO_HANDED) )
+ /////////////////////////////////////////////
+ // Gun Difficulty Modifiers
+
+ // FIRING 1-HANDED WEAPONS
if ( !(Item[ usInHand ].twohanded ) )
{
- if (pSoldier->inv[SECONDHANDPOS].exists() == false)
+ if (pSoldier->inv[SECONDHANDPOS].exists() != false)
{
- // firing with gun in right hand, and second hand empty (ie: no grenade, med kit or anything there)
- // Madd: easier to fire pistol/smg w/one hand free, essentially this will make pistols a little bit more accurate, and hopefully still useful later in the game
- if (Weapon[usInHand].ubWeaponClass == HANDGUNCLASS)
- iChance += AIM_BONUS_TWO_HANDED_PISTOL;
+ if ( pSoldier->IsValidSecondHandShot( ) )
+ {
+ // Penalty for shooting two pistols. Ambidextrous trait halves this, once per skill level.
+ FLOAT iTempPenalty = (gGameCTHConstants.BASE_TWO_GUNS * iGunBaseDifficulty) - iGunBaseDifficulty;
+ INT8 traitLoop = (gGameOptions.fNewTraitSystem?NUM_SKILL_TRAITS( pSoldier, AMBIDEXTROUS_NT ):NUM_SKILL_TRAITS( pSoldier, AMBIDEXT_OT ));
+
+ for (INT32 x = 0; x < traitLoop; x++)
+ {
+ iTempPenalty /= 2;
+ }
+
+ iGunBaseDifficulty += iTempPenalty;
+ }
+ else
+ {
+ // Penalty for shooting a pistol with just one hand
+ iGunBaseDifficulty *= gGameCTHConstants.BASE_ONE_HANDED;
+ }
+ }
+ }
+
+ // HEAVY WEAPON
+ if (Item[usInHand].rocketlauncher && !(gGameOptions.fNewTraitSystem) )
+ {
+ // Penalty for shooting heavy weapons (launchers). Heavy Weapons skill halves this, once per skill level.
+ FLOAT iTempPenalty = (gGameCTHConstants.BASE_HEAVY_WEAPON * iGunBaseDifficulty) - iGunBaseDifficulty;
+
+ for (INT32 x=0; x < NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS_OT ); x++)
+ {
+ iTempPenalty /= 2;
+ }
+
+ iGunBaseDifficulty += iTempPenalty;
+ }
+
+ // STANCE
+ switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
+ {
+ case ANIM_CROUCH:
+ iGunBaseDifficulty *= gGameCTHConstants.BASE_CROUCHING_STANCE;
+ break;
+ case ANIM_PRONE:
+ iGunBaseDifficulty *= gGameCTHConstants.BASE_PRONE_STANCE;
+ break;
+ }
+
+ // Percent based modifier from the gun and its attachments
+ iGunBaseDifficulty += (iGunBaseDifficulty * GetPercentHandlingModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight )) / 100;
+
+ // End gun difficulty modifiers
+ /////////////////////////////////////////////
+
+ // Now apply Gun Difficulty to the Base Modifier.
+ iBaseModifier += iGunBaseDifficulty * gGameCTHConstants.BASE_DRAW_COST;
+
+ // INJURY
+ if (pSoldier->stats.bLife < pSoldier->stats.bLifeMax)
+ {
+ FLOAT iTempPenalty = gGameCTHConstants.BASE_INJURY;
+
+ // Bleeding damage is used as a percentage off the Max Life, giving a penalty of up to BASE_INJURY.
+ iBaseModifier += (pSoldier->bBleeding * iTempPenalty) / pSoldier->stats.bLifeMax;
+
+ // Bandage damage is used similarly, but is only 1/3 as bad.
+ bBandaged = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
+ iBaseModifier += ((bBandaged * iTempPenalty) / pSoldier->stats.bLifeMax) / 3;
+ }
+
+ // FATIGUE
+ iBaseModifier += (gGameCTHConstants.BASE_FATIGUE * (100 - pSoldier->bBreath)) / 100;
+
+ // DRUNKNESS
+ INT8 iDrunkness = GetDrunkLevel(pSoldier);
+ if (iDrunkness > 0)
+ {
+ iDrunkness -= 1;
+ iBaseModifier += gGameCTHConstants.BASE_DRUNK[iDrunkness];
+ }
+
+ // GASSED
+ if ( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED )
+ {
+ iBaseModifier += gGameCTHConstants.BASE_GASSED;
+ }
+
+ // BEING BANDAGED
+ if (pSoldier->ubServiceCount > 0)
+ {
+ iBaseModifier += gGameCTHConstants.BASE_BEING_BANDAGED;
+ }
+
+ // SHOCK (SHOOTER)
+ if (pSoldier->aiData.bShock)
+ {
+ FLOAT iTempPenalty = gGameCTHConstants.BASE_SHOCK;
+ INT32 iShockPercentage = (pSoldier->aiData.bShock * 100) / gGameExternalOptions.ubMaxSuppressionShock;
+
+ iBaseModifier += (iTempPenalty * iShockPercentage) / 100;
+ }
+
+ /////////////
+ // Target-specific tests
+
+ INT32 iHeightDifference = 0;
+ if ( pTarget == NULL )
+ {
+ // Shooting to roof.
+ if ( pSoldier->bTargetLevel > pSoldier->pathing.bLevel )
+ {
+ iHeightDifference = 3 * pSoldier->bTargetLevel;
+ }
+ }
+ else
+ {
+ // HEIGHT DIFFERENCE
+
+ UINT32 uiShooterHeight = 0;
+ UINT32 uiTargetHeight = 0;
+
+ if ( pSoldier->pathing.bLevel > 0 )
+ {
+ uiShooterHeight += 3 * pSoldier->pathing.bLevel;
+ }
+
+ switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
+ {
+ case ANIM_STAND:
+ uiShooterHeight += 2;
+ break;
+ case ANIM_CROUCH:
+ uiShooterHeight += 1;
+ break;
+ }
+
+ if (pTarget->pathing.bLevel > 0)
+ {
+ uiTargetHeight += 3 * pTarget->pathing.bLevel;
+ }
+
+ switch ( gAnimControl[ pTarget->usAnimState ].ubEndHeight )
+ {
+ case ANIM_STAND:
+ switch (ubAimPos)
+ {
+ case AIM_SHOT_HEAD:
+ uiTargetHeight += 2;
+ break;
+ case AIM_SHOT_TORSO:
+ case AIM_SHOT_RANDOM:
+ case AIM_SHOT_GLAND:
+ uiTargetHeight += 1;
+ break;
+ }
+ break;
+ case ANIM_CROUCH:
+ switch (ubAimPos)
+ {
+ case AIM_SHOT_HEAD:
+ uiTargetHeight += 1;
+ break;
+ }
+ break;
+ }
+
+ iHeightDifference = uiShooterHeight - uiTargetHeight;
+ if (iHeightDifference < 0)
+ {
+ iHeightDifference *= -1;
}
else
{
- // Madd: harder to fire smgs w/something in other hand
- // SMGs are treated as pistols for these purpose except there is a -5 penalty;
- if (Weapon[usInHand].ubWeaponClass == SMGCLASS)
- {
- iChance -= AIM_PENALTY_SMG;
- }
+ iHeightDifference = 0;
+ }
- if ( !HAS_SKILL_TRAIT( pSoldier, AMBIDEXT ) )
+ // AGILITY OR EXPERIENCE
+ FLOAT iTempPenalty = __max((pTarget->stats.bExpLevel*10), pTarget->stats.bAgility);
+ iBaseModifier += (iTempPenalty * gGameCTHConstants.BASE_AGILE_TARGET) / 100;
+ }
+
+ // Height difference is mitigated by range. A LONGER range reduces this penalty!
+ if (iRange > 0 && iHeightDifference > 0)
+ {
+ FLOAT iTempPenalty = gGameCTHConstants.BASE_SHOOTING_UPWARDS * iHeightDifference;
+ iTempPenalty /= iRange;
+
+ iBaseModifier += iTempPenalty;
+ }
+
+ // INVIS TARGET
+ if (fCantSeeTarget)
+ {
+ iBaseModifier += gGameCTHConstants.BASE_TARGET_INVISIBLE;
+ }
+
+ // GAME DIFFICULTY
+ if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_PC ) && (pSoldier->bSide != gbPlayerNum) )
+ {
+ iBaseModifier += gGameCTHConstants.BASE_DIFFICULTY[gGameOptions.ubDifficultyLevel];
+ }
+
+ // Percentage based-modifier from the weapon and its attachments
+ iBaseModifier += GetPercentBaseModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight );
+
+
+ ////////////////////////////////////
+ // Finish BASE CTH calculation:
+
+
+
+ iChance = (INT32)(iChance * (100+iBaseModifier)) / 100;
+ iChance = __max( iChance, 0 );
+ iChance = __min( iChance, 100 );
+
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // Second step: Calculate bonuses from aiming
+ //
+ // In this step, we figure out how much CTH we get from aiming. Naturally, we
+ // need extra aiming (bAimTime) to be applied.
+ //
+ // CTH is capped by a value determined by the shooter's skills. The better
+ // your skills, the higher CTH can go. A steady hand (DEX) and training
+ // (MRK) are paramount here.
+ // After that, the cap is raised or lowered by other factors, like fatigue
+ // or the size of the gun.
+ //
+ // Finally, we determine how much each Aim Click will give us. Returns are
+ // diminishing, so the more clicks we put in, the less CTH for each additional
+ // click. However, the last few points can be absolutely crucial for long-range
+ // shooting.
+ //
+ // Scope magnification can be important here, but only if the target is closer
+ // than the scope's minimum aiming range. If it is closer, the shooter begins
+ // to suffer aiming penalties which can render aiming almost useless.
+
+ if (ubAimTime > 0)
+ {
+
+ // Are we using a scope? If so, what's the range factor?
+ FLOAT iScopeMagFactor = GetBestScopeMagnificationFactor( pInHand, (UINT32)iRange );
+ //CHRISL: This does make sense but it effectively makes high powered scopes worthless if a target is actually visible. As an example, a Battle Scope
+ // is going to have a iScopeMagFactor of 7. With a "NORMAL_SHOOTING_DISTANCE" also of 7, we're going to end up with uiBestScopeRange of 49. That's
+ // effectilvey saying that any target within 490m is "too close" for the scope to be effective. That by itself isn't realistic. But in JA2 it's also
+ // a big drawback. Consider that normally (excluding terrain, lighting and environment) you can see 26 tiles. The Battle Scope increases that by 50%
+ // in bright light, meaning you can see up to 39 tiles away. A target standing 49 tiles is considered "invisible" to you because the target is beyond
+ // your 39 tile vision range. Sniper scopes (10 iScopeMagFactor) are even worse (uiBestScopeRange = 70 but visible range limited to 49 tiles). So the
+ // only way to get the full benefit of a higher powered scope is to have a spotter AND to suffer the various "TARGET_INVISIBLE" penalties. This makes
+ // no sense. Admittedly, higher powered scopes should be less efficienct at "close range" but is 490m (700m for sniper scope) really "close range"?
+ // Also, we can't simply change NORMAL_SHOOTING_DISTANCE because this value also effects shooting without a scope. We don't want ot make it harder for
+ // "scopeless" shooting. So to try and counter some of this, while still showing that scopes are less effecient at "close range", I'm going to cut the
+ // uiBestScopeRange value in half. This should allow a Battle Scope to reach full effeciency at 24 tiles and a Sniper scope will be fully effecient at
+ // 35 tiles. ACOG becomes fully effecient at 14 tiles and 2x is fully effeciency at 7 tiles (compared to 28 and 14 respectively). This does mean that a
+ // 2x scope reaches full effeciency at the same point as "scopeless" shooting, but I don't think this will be a serious problem.
+ FLOAT rangeModifier = gGameCTHConstants.SCOPE_RANGE_MULTIPLIER;
+ if( gGameOptions.fNewTraitSystem )
+ {
+ if(iScopeMagFactor > .5)
+ rangeModifier -= (NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ) * 0.05f);
+ else
+ rangeModifier -= (NUM_SKILL_TRAITS( pSoldier, RANGER_NT ) * 0.05f);
+ }
+ else
+ rangeModifier -= (NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT ) * 0.05f);
+ UINT32 uiBestScopeRange = (UINT32)(iScopeMagFactor * gGameCTHConstants.NORMAL_SHOOTING_DISTANCE * rangeModifier);
+
+ FLOAT iAimModifier = 0;
+
+ // WEAPON CONDITION
+ if ( pSoldier->inv[HANDPOS][0]->data.objectStatus < 50 )
+ {
+ iAimModifier += gGameCTHConstants.AIM_GUN_CONDITION * (50 - pSoldier->inv[HANDPOS][0]->data.objectStatus);
+ }
+
+ // MORALE
+ INT32 iTempModifier = GetMoraleModifier( pSoldier );
+ if ( iTempModifier > 0 )
+ {
+ iAimModifier += gGameCTHConstants.AIM_HIGH_MORALE * iTempModifier;
+ }
+ else if ( iTempModifier < 0 )
+ {
+ iAimModifier += gGameCTHConstants.AIM_LOW_MORALE * iTempModifier;
+ }
+
+ if(gGameOptions.fNewTraitSystem)
+ {
+ //Give 60% the normal stomp modifier as the aim mod
+ iAimModifier += (FLOAT)iTraitModifier * 0.6f;
+ }
+ else
+ {
+ if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
+ {
+ iAimModifier += gGameCTHConstants.AIM_PSYCHO;
+ }
+ }
+
+ //////////////////////////////////////////
+ // Gun Handling modifiers
+
+ switch (gAnimControl[ pSoldier->usAnimState ].ubEndHeight)
+ {
+ case ANIM_STAND:
+ iGunAimDifficulty *= gGameCTHConstants.AIM_STANDING_STANCE;
+ break;
+
+ case ANIM_CROUCH:
+ iGunAimDifficulty *= gGameCTHConstants.AIM_CROUCHING_STANCE;
+ break;
+
+ case ANIM_PRONE:
+ iGunAimDifficulty *= gGameCTHConstants.AIM_PRONE_STANCE;
+ break;
+ }
+
+ // FIRING 1-HANDED WEAPONS
+ if ( !(Item[ usInHand ].twohanded ) )
+ {
+ if (pSoldier->inv[SECONDHANDPOS].exists() != false)
{
if ( pSoldier->IsValidSecondHandShot( ) )
{
- // penalty to aim when firing two pistols
- iChance -= AIM_PENALTY_DUAL_PISTOLS;
+ // Penalty for shooting two pistols. Ambidextrous trait halves this, once per skill level.
+ FLOAT iTempPenalty = (gGameCTHConstants.AIM_TWO_GUNS * iGunAimDifficulty) - iGunAimDifficulty;
+ INT8 traitLoop = (gGameOptions.fNewTraitSystem?NUM_SKILL_TRAITS( pSoldier, AMBIDEXTROUS_NT ):NUM_SKILL_TRAITS( pSoldier, AMBIDEXT_OT ));
+
+ for (INT32 x = 0; x < traitLoop; x++)
+ {
+ iTempPenalty /= 2;
+ }
+
+ iGunAimDifficulty += iTempPenalty;
}
- /*
else
{
- // penalty to aim with pistol being fired one-handed
- iChance -= AIM_PENALTY_ONE_HANDED_PISTOL;
+ // Penalty for shooting a pistol with just one hand
+ iGunAimDifficulty *= gGameCTHConstants.AIM_ONE_HANDED;
}
- */
}
}
+
+ // HEAVY WEAPON
+ if (Item[usInHand].rocketlauncher && !(gGameOptions.fNewTraitSystem) )
+ {
+ // Penalty for shooting heavy weapons (launchers). Heavy Weapons skill halves this, once per skill level.
+ FLOAT iTempPenalty = (gGameCTHConstants.AIM_HEAVY_WEAPON * iGunAimDifficulty) - iGunAimDifficulty;
+
+ for (INT32 x=0; x < NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS_OT ); x++)
+ {
+ iTempPenalty /= 2;
+ }
+
+ iGunAimDifficulty += iTempPenalty;
+ }
+
+ iGunAimDifficulty += (iGunAimDifficulty * GetPercentHandlingModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight )) / 100;
+
+ // End Gun Handling modifiers
+ //////////////////////////////////////////
+
+ iAimModifier += gGameCTHConstants.AIM_DRAW_COST * iGunAimDifficulty;
+
+ // VISIBILITY
+ if (iRange > 0 && iSightRange > iRange)
+ {
+ FLOAT iTempPenalty = (FLOAT)((FLOAT)iSightRange / (FLOAT)iRange);
+ iTempPenalty = (FLOAT)(100 / iTempPenalty);
+ iAimModifier += ((100-iTempPenalty) * gGameCTHConstants.AIM_VISIBILITY)/100;
+ iAimModifier = __max( gGameCTHConstants.AIM_TARGET_INVISIBLE, iAimModifier );
+ }
+ //if (iSightRange == -1)
+ if(fCantSeeTarget)
+ {
+ iAimModifier += gGameCTHConstants.AIM_TARGET_INVISIBLE;
+ }
+
+ // INJURY
+ if (pSoldier->stats.bLife < pSoldier->stats.bLifeMax)
+ {
+ FLOAT iTempPenalty = gGameCTHConstants.AIM_INJURY;
+
+ // Bleeding damage is used as a percentage off the Max Life, giving a penalty of up to BASE_INJURY.
+ iAimModifier += (pSoldier->bBleeding * iTempPenalty) / pSoldier->stats.bLifeMax;
+
+ // Bandage damage is used similarly, but is only 1/3 as bad.
+ bBandaged = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
+ iAimModifier += ((bBandaged * iTempPenalty) / pSoldier->stats.bLifeMax) / 3;
+ }
+
+ // FATIGUE
+ iAimModifier += (gGameCTHConstants.AIM_FATIGUE * (100 - pSoldier->bBreath)) / 100;
+
+ // DRUNKNESS
+ INT8 iDrunkness = GetDrunkLevel(pSoldier);
+ if (iDrunkness > 0)
+ {
+ iDrunkness -= 1;
+ iAimModifier += gGameCTHConstants.AIM_DRUNK[iDrunkness];
+ }
+
+ // GASSED
+ if ( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED )
+ {
+ iAimModifier += gGameCTHConstants.AIM_GASSED;
+ }
+
+ // BEING BANDAGED
+ if (pSoldier->ubServiceCount > 0)
+ {
+ iAimModifier += gGameCTHConstants.AIM_BEING_BANDAGED;
+ }
+
+ // SHOCK (SHOOTER)
+ if (pSoldier->aiData.bShock)
+ {
+ FLOAT iTempPenalty = gGameCTHConstants.AIM_SHOCK;
+ INT32 iShockPercentage = (pSoldier->aiData.bShock * 100) / gGameExternalOptions.ubMaxSuppressionShock;
+
+ iAimModifier += (iTempPenalty * iShockPercentage) / 100;
+ }
+
+ /////////////
+ // Target-specific tests
+
+ INT32 iHeightDifference = 0;
+ if ( pTarget == NULL )
+ {
+ // Shooting to roof.
+ if ( pSoldier->bTargetLevel > pSoldier->pathing.bLevel )
+ {
+ iHeightDifference = 3 * pSoldier->bTargetLevel;
+ }
+ }
+ else
+ {
+ // HEIGHT DIFFERENCE
+
+ UINT32 uiShooterHeight = 0;
+ UINT32 uiTargetHeight = 0;
+
+ if ( pSoldier->pathing.bLevel > 0 )
+ {
+ uiShooterHeight += 3 * pSoldier->pathing.bLevel;
+ }
+
+ switch ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight )
+ {
+ case ANIM_STAND:
+ uiShooterHeight += 2;
+ break;
+ case ANIM_CROUCH:
+ uiShooterHeight += 1;
+ break;
+ }
+
+ if (pTarget->pathing.bLevel > 0)
+ {
+ uiTargetHeight += 3 * pTarget->pathing.bLevel;
+ }
+
+ switch ( gAnimControl[ pTarget->usAnimState ].ubEndHeight )
+ {
+ case ANIM_STAND:
+ switch (ubAimPos)
+ {
+ case AIM_SHOT_HEAD:
+ uiTargetHeight += 2;
+ break;
+ case AIM_SHOT_TORSO:
+ case AIM_SHOT_RANDOM:
+ case AIM_SHOT_GLAND:
+ uiTargetHeight += 1;
+ break;
+ }
+ break;
+ case ANIM_CROUCH:
+ switch (ubAimPos)
+ {
+ case AIM_SHOT_HEAD:
+ uiTargetHeight += 1;
+ break;
+ }
+ break;
+ }
+
+ iHeightDifference = uiShooterHeight - uiTargetHeight;
+ if (iHeightDifference < 0)
+ {
+ iHeightDifference *= -1;
+ }
+ else
+ {
+ iHeightDifference = 0;
+ }
+ }
+
+ // Height difference is mitigated by range. A LONGER range reduces this penalty!
+ if (iRange > 0 && iHeightDifference > 0)
+ {
+ FLOAT iTempPenalty = gGameCTHConstants.AIM_SHOOTING_UPWARDS * iHeightDifference;
+ iTempPenalty /= iRange;
+
+ iAimModifier += iTempPenalty;
+ }
+
+ // GAME DIFFICULTY
+ if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_PC ) && (pSoldier->bSide != gbPlayerNum) )
+ {
+ iAimModifier += gGameCTHConstants.AIM_DIFFICULTY[gGameOptions.ubDifficultyLevel];
+ }
+
+ // Percent modifier from the weapon and its attachments
+ iAimModifier += GetPercentAimModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight );
+
+ // Calculate final max aiming
+
+
+ //////////////////////////////////////////
+ // Start by calculating the CTH cap, the absolute maximum CTH a shooter can get.
+ iCombinedSkill = ( gGameCTHConstants.AIM_EXP * bExperience * 10 );
+ iCombinedSkill += ( gGameCTHConstants.AIM_MARKS * bMarksmanship );
+ iCombinedSkill += ( gGameCTHConstants.AIM_WIS * bWisdom );
+ iCombinedSkill += ( gGameCTHConstants.AIM_DEX * bDexterity );
+
+ iCombinedSkill /= (gGameCTHConstants.AIM_EXP + gGameCTHConstants.AIM_MARKS + gGameCTHConstants.AIM_WIS + gGameCTHConstants.AIM_DEX);
+
+ UINT32 uiCap = (UINT32)iCombinedSkill;
+ // Add percent-based modifier from the gun and its attachments
+ uiCap += (uiCap * GetPercentCapModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight )) / 100;
+
+ // Add bonuses from Sniper Skill. Applies only when using a scope at or above its "best" range.
+ INT16 sDifference = 99 - uiCap;
+ INT16 sSniperSkillBonus = 0;
+ if (uiCap < gGameExternalOptions.ubMaximumCTH && iScopeMagFactor > 1.0 && iRange >= (INT32)uiBestScopeRange )
+ {
+ INT8 loop;
+ if(gGameOptions.fNewTraitSystem)
+ {
+ if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL || Weapon[usInHand].ubWeaponType == GUN_M_PISTOL )
+ loop = NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT );
+ else
+ loop = NUM_SKILL_TRAITS( pSoldier, SNIPER_NT );
+ }
+ else
+ loop = NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT );
+
+ for (INT8 cnt = 0; cnt < loop; cnt++)
+ {
+ // For each level of the sniper skill, cover a defined distance between the current CTH Cap and 99 (the
+ // maximum...
+ if(gGameOptions.fNewTraitSystem)
+ {
+ if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL || Weapon[usInHand].ubWeaponType == GUN_M_PISTOL )
+ sSniperSkillBonus += (INT16)((sDifference * gSkillTraitValues.ubGSAimingBonusPerClick) / gGameExternalOptions.ubMaximumCTH);
+ else
+ sSniperSkillBonus += (INT16)((sDifference * gSkillTraitValues.ubSNAimingBonusPerClick) / gGameExternalOptions.ubMaximumCTH);
+ }
+ else
+ sSniperSkillBonus += (INT16)((sDifference * gGameCTHConstants.AIM_SNIPER_SKILL) / gGameExternalOptions.ubMaximumCTH);
+ sDifference -= sSniperSkillBonus;
+ }
+
+ uiCap += sSniperSkillBonus;
+ }
+
+ // Make sure cap is within limits
+ uiCap = __max(uiCap, __max(0,(UINT32)iChance));
+ uiCap = __min(uiCap, gGameExternalOptions.ubMaximumCTH);
+
+ // Now figure out the distance between the Base CTH and the CTH Cap. This is the distance we'll potentially
+ // cover when applying the maximum number of aiming clicks for this gun.
+ INT32 iMaxAimBonus = uiCap - iChance;
+
+ iMaxAimBonus = (UINT32)((iMaxAimBonus * (100+iAimModifier)) / 100);
+ iMaxAimBonus = __max(0, iMaxAimBonus); // can't get less than 0 points for aiming...
+
+ // factor in scopes under their range
+ if (iScopeMagFactor > 1.0 && iRange < (INT32)uiBestScopeRange)
+ {
+ // Calculate how much penalty this scope should give at this range
+ FLOAT dScopePenaltyRatio = ((FLOAT)uiBestScopeRange / (FLOAT)iRange);
+ INT32 iScopePenalty = (INT32)(dScopePenaltyRatio * gGameCTHConstants.AIM_TOO_CLOSE_SCOPE * (iScopeMagFactor /2));
+ iMaxAimBonus += iScopePenalty;
+ }
+ else if (iScopeMagFactor == 1.0f && GetHighestScopeMagnificationFactor( pInHand ) > 1.0f )
+ {
+ // Not using a scope, but it's still there. Give half the penalty based on the size of the scope.
+ INT32 iScopePenalty = (INT32)(((GetHighestScopeMagnificationFactor( pInHand )/2) * gGameCTHConstants.AIM_TOO_CLOSE_SCOPE)/2);
+ iMaxAimBonus += iScopePenalty;
+ }
+
+ // Now let's find out how many CTH points we get per aiming level.
+ UINT8 ubAllowedAimingLevels = AllowedAimingLevels( pSoldier, sGridNo );
+ FLOAT dAimFractionsDivisor = 0.0;
+ for (UINT8 cnt = 0; cnt < ubAllowedAimingLevels; cnt++)
+ {
+ dAimFractionsDivisor += (cnt+1);
+ }
+
+ FLOAT iAimPoints = 0;
+ FLOAT iAimPointFraction = (FLOAT)((FLOAT)iMaxAimBonus / dAimFractionsDivisor);
+ for (UINT8 x = 0; x < ubAimTime; x++)
+ {
+ iAimPoints += iAimPointFraction * (ubAllowedAimingLevels-x);
+ // Add Flat Modifier from the weapon and its attachments
+ iAimPoints += GetFlatAimModifier( pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight );
+ }
+
+ // Finally, add the appropriate number of CTH points to our chance-to-hit, and limit it into good values.
+ iChance = __max(iChance + (INT32)iAimPoints, iChance);
+ iChance = __min(iChance, (INT32)uiCap);
}
+
+ // Impose global limits.
+ iChance = __min(iChance, gGameExternalOptions.ubMaximumCTH);
+ iChance = __max(iChance, gGameExternalOptions.ubMinimumCTH);
+
+ return (iChance);
+}
+
+/*
+
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun"));
+
+
+ if ( AM_A_ROBOT( pSoldier ) )
+ {
+ SOLDIERTYPE * pSoldier2;
+ pSoldier2 = pSoldier->GetRobotController( );
+ if ( pSoldier2 )
+ {
+ uiExperience = EffectiveExpLevel( pSoldier2 );
+ uiMarksmanship = EffectiveMarksmanship( pSoldier2 );
+ uiDexterity = EffectiveDexterity( pSoldier2 );;
+ uiWisdom = EffectiveWisdom( pSoldier2 );
+ }
+ }
+
+ // calculate actual range (in units, 10 units = 1 tile)
+ iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
// If in burst mode, deduct points for change to hit for each shot after the first
if ( pSoldier->bDoBurst && pSoldier->bDoAutofire == 0 )
@@ -3783,137 +5558,6 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
sTotalAutofirePenalty = iPenalty;
}
- //ADB we need to calculate the distance visible and SoldierTo...LOSTests that we want to
- //calculate it when firing, so the scope can be accounted for when the weapon is raised
- //I consider this a hack to change the global, but passing a var alllll the way down to GetVisionBonus was worse
- //if anyone wants to change it go for it, I don't know what usAnimState should be set
-
- //store old flag
- UINT32 oldFlag = gAnimControl[ pSoldier->usAnimState ].uiFlags;
- //add the necessary bits to the flag
- gAnimControl[ pSoldier->usAnimState ].uiFlags |= (ANIM_FIREREADY | ANIM_FIRE);
-
- // 0verhaul: Changed to take expanded range from shooting at different levels into account
- //ADB this change does nothing - either way it is random - we don't know what level we are shooting to, which is
- //what the last parameter is, and the soldier's current level is as good a guess as ground level.
- //so if you really want to fix this, pass in a value
- sDistVis = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS );
-
- // CJC August 13 2002: Wow, this has been wrong the whole time. bTargetCubeLevel seems to be generally set to 2 -
- // but if a character is shooting at an enemy in a particular spot, then we should be using the target position on the body.
-
- // CJC August 13, 2002
- // If the start soldier has a body part they are aiming at, and know about the person in the tile, then use that height instead
- iSightRange = -1;
-
- // give some leeway to allow people to spot for each other...
- //so make the range to calculate the bullet at 255+
- ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel );
- // best to use team knowledge as well, in case of spotting for someone else
- // 0verhaul: Why not use the distance visible as the max for line of sight testing?
- //ADB because A) the bullet can travel farther than I can see and B) I might have a spotter
-
- //We are firing a gun, and so the gun will be pointed and the scope will be used, even if it isn't now, so don't forget that we are in a firing animation
- if (ubTargetID != NOBODY && pSoldier->aiData.bOppList[ubTargetID] == SEEN_CURRENTLY || gbPublicOpplist[pSoldier->bTeam][ubTargetID] == SEEN_CURRENTLY)
- {
- iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false );
- }
- if (iSightRange == -1) // didn't do a bodypart-based test
- {
- iSightRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, TRUE, NO_DISTANCE_LIMIT, false );
- }
-
- //restore old flag
- gAnimControl[ pSoldier->usAnimState ].uiFlags = oldFlag;
-
- if ( iSightRange > (sDistVis * CELL_X_SIZE) )
- {
- //CHRISL: Because of the changes I've made to how scopes modify iSightRange, this penalty makes it basically impossible
- // to shot at targets you can't see yourself. While this isn't an issue for most weapons, it overly restricts the
- // effectiveness of sniper rifles. So pull this penalty but leave the one that comes later in the code.
- // shooting beyond max normal vision... penalize such distance at double (also later we halve the remaining chance)
- //iSightRange += (iSightRange - sDistVis * CELL_X_SIZE);
- }
-
- // if shooter spent some extra time aiming and can see the target
- if (iSightRange > 0 && ubAimTime && !pSoldier->bDoBurst )
- {
- // CHRISL: Rather then a flat +10/click bonus, we're going to try a bonus that's based on MRK and Lvl which gets
- // progressivly less the more we aim. Everything is based on the maxBonus that a merc can possibly get which
- // uses the equation: 20+(MRK/20*LVL)+Accuracy+(Sniper trait * 10). This value is then split between the 8
- // possible AimTime's using a max aimTime bonus of 10.
- INT16 bonusProgression[8] = {500,500,600,600,750,750,750,1000};
- FLOAT maxBonus = 20+((FLOAT)iMarksmanship/20*pSoldier->stats.bExpLevel)+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER )*10);
- INT8 maxClickBonus = 10;
- FLOAT aimTimeBonus;
- for(int i = 0; i < ubAimTime; i++)
- {
- aimTimeBonus = __min((maxBonus*bonusProgression[i]/1000),maxClickBonus);
- maxBonus -= aimTimeBonus;
- iChance += (INT32)floor(aimTimeBonus+.5);
- }
-/* if(highPowerScope == true)
- {
- {
- if ( NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER ) == 2 )
- aimTimeBonus = -((__max(0,75-pSoldier->stats.bMarksmanship))/(pSoldier->stats.bExpLevel*2));
- else if( NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER ) == 1 )
- aimTimeBonus = -((__max(0,85-pSoldier->stats.bMarksmanship))/(pSoldier->stats.bExpLevel*2));
- else
- aimTimeBonus = -((__max(0,100-pSoldier->stats.bMarksmanship))/(pSoldier->stats.bExpLevel));
- aimTimeBonus = __max(-9, aimTimeBonus);
- aimTimeBonus = __min(0, aimTimeBonus);
- aimTimeBonus += AIM_BONUS_PER_AP;
- }
- else
- aimTimeBonus = AIM_BONUS_PER_AP;
- iChance += (aimTimeBonus * ubAimTime); // bonus for every pt of aiming*/
- }
-
- if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_PC ) ) // if this is a computer AI controlled enemy
- {
- if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
- {
- // On easy, penalize all enemies by 5%
- iChance -= 5;
- }
- else
- {
- // max with 0 to prevent this being a bonus, for JA2 it's just a penalty to make early enemies easy
- // CJC note: IDIOT! This should have been a min. It's kind of too late now...
- // CJC 2002-05-17: changed the max to a min to make this work.
- iChance += __min( 0, gbDiff[ DIFF_ENEMY_TO_HIT_MOD ][ SoldierDifficultyLevel( pSoldier ) ] );
- }
- }
-
- // if shooter is being affected by gas
- if ( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED )
- {
- iChance -= AIM_PENALTY_GASSED;
- }
-
- // if shooter is being bandaged at the same time, his concentration is off
- if (pSoldier->ubServiceCount > 0)
- iChance -= AIM_PENALTY_GETTINGAID;
-
- // if shooter is still in shock
- if (pSoldier->aiData.bShock)
- {
- // HEADROCK HAM B2.8: Placed a maximum here, as shock is now also used in suppression.
- UINT16 usShockPenalty;
-
- usShockPenalty = pSoldier->aiData.bShock * AIM_PENALTY_PER_SHOCK;
-
- if (gGameExternalOptions.usMaxShooterCoweringPenalty > 0)
- {
- if ( usShockPenalty > gGameExternalOptions.usMaxShooterCoweringPenalty )
- usShockPenalty = gGameExternalOptions.usMaxShooterCoweringPenalty;
- }
- if ( usShockPenalty < 1 )
- usShockPenalty = 1;
-
- iChance -= usShockPenalty;
- }
// WANNE: Changed this, because RPGs are not in the calculation, only guns
//if ( Item[ usInHand ].usItemClass == IC_GUN )
@@ -3926,89 +5570,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iMaxRange = CELL_X_SIZE; // one tile
}
- if ( iSightRange > 0 )
- {
- // Madd: Spacific item bonuses are no longer hard-coded
-
- // Snap: use tohitbonus or aimbonus instead
- /*if (pSoldier->inv[HEAD1POS].usItem == SUNGOGGLES || pSoldier->inv[HEAD2POS].usItem == SUNGOGGLES)
- {
- // decrease effective range by 10% when using sungoggles (w or w/o scope)
- iSightRange -= iRange / 10; //basically, +1% to hit per every 2 squares
- }*/
-
- //bAttachPos = FindAttachment( pInHand, SNIPERSCOPE );
-
- //// does gun have scope, long range recommends its use, and shooter's aiming?
- //if (bAttachPos != NO_SLOT && (iRange > MIN_SCOPE_RANGE) && (ubAimTime > 0))
- //{
- // // reduce effective sight range by 20% per extra aiming time AP of the distance
- // // beyond MIN_SCOPE_RANGE. Max reduction is 80% of the range beyond.
- // iScopeBonus = ((SNIPERSCOPE_AIM_BONUS * ubAimTime) * (iRange - MIN_SCOPE_RANGE)) / 100;
-
- // // adjust for scope condition, only has full affect at 100%
- // iScopeBonus = (iScopeBonus * WEAPON_STATUS_MOD(pInHand->bAttachStatus[bAttachPos])) / 100;
-
- //rain
- // reduce scope effectiveness when it's raining
- // iScopeBonus /= 1 + gbCurrentRainIntensity; //madd: commented out -- didn't do anything but cause a warning :S
- //end rain
-
- // // reduce effective range by the bonus obtained from the scope
- // iSightRange -= iScopeBonus;
- // if (iSightRange < 1)
- // {
- // iSightRange = 1;
- // }
- //}
-
- //bAttachPos = FindAttachment( pInHand, LASERSCOPE );
- //if (usInHand == ROCKET_RIFLE || usInHand == AUTO_ROCKET_RIFLE || bAttachPos != NO_SLOT) // rocket rifle has one built in
- //{
- // INT8 bLaserStatus;
-
- // if ( usInHand == ROCKET_RIFLE || usInHand == AUTO_ROCKET_RIFLE )
- // {
- // bLaserStatus = WEAPON_STATUS_MOD((*pInHand)[0]->data.gun.bGunStatus);
- // }
- // else
- // {
- // bLaserStatus = WEAPON_STATUS_MOD(pInHand->bAttachStatus[ bAttachPos ]);
- // }
- //
- // // laser scope isn't of much use in high light levels; add something for that
- // if (bLaserStatus > 50)
- // {
- // iScopeBonus = LASERSCOPE_BONUS * (bLaserStatus - 50) / 50;
- // }
- // else
- // {
- // // laser scope in bad condition creates aim penalty!
- // iScopeBonus = - LASERSCOPE_BONUS * (50 - bLaserStatus) / 50;
- // }
- //
- // iChance += iScopeBonus;
-
- //}
-
- //Madd: Some gear can affect the to-hit bonus and the bonus from aiming
- DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: before bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
- iSightRange -= GetGearAimBonus ( pSoldier, iRange, ubAimTime );
- iChance += GetGearToHitBonus ( pSoldier );
- DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: after gear bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
-
- // Reduce effective range by the aiming bonus (e.g. from sniper scope)
- iSightRange -= GetAimBonus( pInHand, iRange, ubAimTime );
- //CHRISL: If we have the Sniper skill, reduce effective range
- if ( HAS_SKILL_TRAIT( pSoldier, PROF_SNIPER ) )
- {
- iSightRange -= ((gbSkillTraitBonus[ PROF_SNIPER ] * NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER )) * iRange) /100;
- }
- if (iSightRange < 1)
- {
- iSightRange = 1;
- }
// HEADROCK HAM B2.1 : The TARGET's shock now also affects aiming. If the target is prone
// and in shock, they are harder to hit! This represents a target that's cowering as close
// to the ground (and as close to any possible cover, like a small dune or a fold of earth
@@ -4105,35 +5667,6 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: after to hit bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
}
- // if aiming at the head, reduce chance to hit
- if (ubAimPos == AIM_SHOT_HEAD)
- {
- // penalty of 3% per tile
- iPenalty = 3 * iSightRange / 10;
- iChance -= iPenalty;
- }
- else if (ubAimPos == AIM_SHOT_LEGS)
- {
- // penalty of 1% per tile
- iPenalty = iSightRange / 10;
- iChance -= iPenalty;
- }
-
- //NumMessage("EFFECTIVE RANGE = ",range);
-
- // ADJUST FOR RANGE
- // bonus if range is less than normal range, penalty if it's more
- //iChance += (NORMAL_RANGE - iRange) / (CELL_X_SIZE / 5); // 5% per tile
-
- // Effects of actual gun max range... the numbers are based on wanting -40%
- // at range 26for a pistol with range 13, and -0 for a sniper rifle with range 80
- iPenalty = ((iMaxRange - iRange * 3) * 10) / (17 * CELL_X_SIZE);
- if ( iPenalty < 0 )
- {
- iChance += iPenalty;
- }
- //iChance -= 20 * iRange / iMaxRange;
-
if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
{
// tank; penalize at close range!
@@ -4146,27 +5679,6 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// firing blind!
iChance -= AIM_PENALTY_BLIND;
}
- else
- {
- // Effects based on aiming & sight
- // From for JA2.5: 3% bonus/penalty for each tile different from range NORMAL_RANGE.
- // This doesn't provide a bigger bonus at close range, but stretches it out, making medium
- // range less penalized, and longer range more penalized
- iChance += 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
- /*
- if (iSightRange < NORMAL_RANGE)
- {
- // bonus to hit of 20% at point blank (would be 25% at range 0);
- //at NORMAL_RANGE, bonus is 0
- iChance += 25 * (NORMAL_RANGE - iSightRange) / NORMAL_RANGE;
- }
- else
- {
- // penalty of 2% / tile
- iChance -= (iSightRange - NORMAL_RANGE) / 5;
- }
- */
- }
// HEADROCK HAM 3.5: Moved this here for now.
// HEADROCK HAM B2.5: One of every X bullets in a tracer magazine is a tracer round, which will
@@ -4250,23 +5762,6 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
}
}
- // adjust for roof/not on roof
- if ( pSoldier->pathing.bLevel == 0 )
- {
- if ( pSoldier->bTargetLevel > 0 )
- {
- // penalty for firing up
- iChance -= AIM_PENALTY_FIRING_UP;
- }
- }
- else // pSoldier->pathing.bLevel > 0 )
- {
- if ( pSoldier->bTargetLevel == 0 )
- {
- iChance += AIM_BONUS_FIRING_DOWN;
- }
- }
-
pTarget = SimpleFindSoldier( sGridNo, pSoldier->bTargetLevel );
if (pTarget != NULL)
@@ -4340,6 +5835,2048 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// penalty for amount that enemy has moved
// HEADROCK HAM B2.6: Externalized the value
iPenalty = __min( (UINT16)((float)pTarget->bTilesMoved * (float)gGameExternalOptions.iMovementEffectOnAiming), 30 );
+ iChance -= iPenalty;
+
+ // reduce dodge ability by the attacker's stats
+ iBonus = ( EffectiveDexterity( pSoldier ) / 5 + EffectiveExpLevel( pSoldier ) * 2);
+ if ( TANK( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) )
+ {
+ // reduce ability to track shots
+ iBonus = iBonus / 2;
+ }
+
+ if ( iPenalty > iBonus )
+ {
+ iChance -= (iPenalty - iBonus);
+ }
+ }
+ }
+
+
+
+ // CHECK IF TARGET IS WITHIN GUN'S EFFECTIVE MAXIMUM RANGE
+ if ( iRange > iMaxRange )
+ {
+ // a bullet WILL travel that far if not blocked, but it's NOT accurate,
+ // because beyond maximum range, the bullet drops rapidly
+
+ // This won't cause the bullet to be off to the left or right, only make it
+ // drop in flight.
+ iChance /= 2;
+ }
+
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: ichance = %d",iChance));
+ return (iChance);
+}*/
+
+UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos )
+{
+ if(UsingNewCTHSystem() == true)
+ return CalcNewChanceToHitGun(pSoldier, sGridNo, ubAimTime, ubAimPos);
+
+ //CHRISL: I've tried to sort and reorganize this function to make it a little easier to follow. I've removed most of the unused code fragments and removed
+ // alot of the notes. I've also tried to sort the various portions of the function so that similar actions orrucr at the same place in the code. The
+ // following is the newly written function
+ SOLDIERTYPE * pTarget;
+ OBJECTTYPE * pInHand;
+ INT32 iChance; //CTH
+ INT32 iRange; //Actual range to target
+ INT32 iSightRange = 0; //LOS range
+ INT32 iCoverRange; //Amount sight range is modified due to cover
+ INT32 iMaxRange; //Weapon maximum range
+ INT32 iMinRange; //Minimum effective range
+ INT32 iGunCondition; //Weapons effective condition
+ INT32 iMarksmanship; //Mercs effective marksmanship
+ INT32 iAccRangeMod; //Range modifier granted from weapon accuracy
+ INT32 iBonus, iPenalty;
+ INT16 sDistVis, sDistVisNoScope, iMaxNormRange, iScopeVisionRangeBonus, sCoweringPenalty = 0, sTotalAutofirePenalty = 0;
+ INT16 bonusProgression[8] = {500,500,600,600,750,750,750,1000}; //Aiming progression
+ UINT16 usInHand, usShockPenalty, MIN_RANGE_FOR_FULL_COWER, MAX_TARGET_COWERING_PENALTY;
+ UINT16 iBulletsLeft, iTracersFired = 0, iBulletsPerTracer, iBulletsSinceLastTracer=0, iRoundsFiredPreviously;
+ INT8 bBandaged, maxClickBonus = 10, AIM_PENALTY_PER_TARGET_SHOCK;
+ UINT8 ubAdjAimPos, ubTargetID, bLightLevel, ubCoweringDivisor, ubAutoPenaltySinceLastTracer=0;
+ FLOAT maxBonus, aimTimeBonus, scopeRangeMod, iAimBonus;
+ bool fCantSeeTarget = false, fCoverObscured = false;
+
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun"));
+ if ( pSoldier->stats.bMarksmanship == 0 ) {
+ return( gGameExternalOptions.ubMinimumCTH );
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Assign basic variables
+ pTarget = SimpleFindSoldier( sGridNo, pSoldier->bTargetLevel );
+ pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+ iGunCondition = WEAPON_STATUS_MOD( (*pInHand)[0]->data.gun.bGunStatus );
+ usInHand = pSoldier->usAttackingWeapon;
+ ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel );
+ bLightLevel = LightTrueLevel(sGridNo, pSoldier->bTargetLevel);
+ usShockPenalty = pSoldier->aiData.bShock * AIM_PENALTY_PER_SHOCK;
+ iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
+ AIM_PENALTY_PER_TARGET_SHOCK = gGameExternalOptions.ubAimPenaltyPerTargetShock;
+ MIN_RANGE_FOR_FULL_COWER = gGameExternalOptions.usMinRangeForFullCoweringPenalty;
+ MAX_TARGET_COWERING_PENALTY = gGameExternalOptions.usMaxTargetCoweringPenalty;
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Assign range variables -- all range values are in units (10 units = 1 tile)
+ iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo ); // calculate actual range
+ gbForceWeaponReady = true;
+ sDistVis = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
+ iScopeVisionRangeBonus = GetTotalVisionRangeBonus(pSoldier, bLightLevel); // not an actual range value, simply a modifier for range calculations
+ if (ubTargetID != NOBODY && pSoldier->aiData.bOppList[ubTargetID] == SEEN_CURRENTLY || gbPublicOpplist[pSoldier->bTeam][ubTargetID] == SEEN_CURRENTLY)
+ iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false );
+ if (iSightRange == 0) { // didn't do a bodypart-based test or can't see specific body part aimed at
+ iSightRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, TRUE, NO_DISTANCE_LIMIT, false );
+ fCoverObscured = true;
+ }
+ if (iSightRange == 0) { // Can't see the target but we still need to know what the sight range would be if we could so we can deal with cover penalties
+ iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false, true );
+ fCantSeeTarget = true;
+ fCoverObscured = false;
+ }
+ gbForceWeaponReady = false;
+ gbForceWeaponNotReady = true;
+ sDistVisNoScope = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS ) * CELL_X_SIZE;
+ gbForceWeaponNotReady = false;
+ scopeRangeMod = (float)sDistVis / (float)sDistVisNoScope; // percentage DistVis has been enhanced due to an attached scope
+ iMaxNormRange = MaxNormalDistanceVisible() * CELL_X_SIZE;
+ if ( Item[ usInHand ].usItemClass == IC_GUN || Item[ usInHand ].usItemClass == IC_LAUNCHER)
+ iMaxRange = GunRange( pInHand, pSoldier ); // SANDRO - added argument
+ else
+ iMaxRange = CELL_X_SIZE; // one tile
+ iCoverRange = iSightRange - iRange;
+ iMinRange = iMaxRange / 10;
+ iAccRangeMod = iRange * Weapon[usInHand].bAccuracy / 100;
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Modify Sight and Physical Range
+ iSightRange = (INT32)(iSightRange / scopeRangeMod);
+ if(iSightRange > 0){
+ iSightRange -= GetGearAimBonus ( pSoldier, iSightRange, ubAimTime ) * iSightRange / 100;
+ if ( gGameOptions.fNewTraitSystem ) {
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) ) {
+ iSightRange -= ((gSkillTraitValues.ubSNEffRangeToTargetReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )) * iSightRange) /100;
+ }
+ }
+ else if ( HAS_SKILL_TRAIT( pSoldier, PROF_SNIPER_OT ) ) {
+ iSightRange -= ((gbSkillTraitBonus[ PROF_SNIPER_OT ] * NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )) * iSightRange) /100;
+ }
+ if (iRange < GetMinRangeForAimBonus(pInHand) && iScopeVisionRangeBonus > 50){ // iSightRange penalty for using a high power scope within min range due to poor focus
+ for(UINT8 loop = 0; loop < ((GetMinRangeForAimBonus(pInHand) - iRange)/CELL_X_SIZE); loop++){
+ iSightRange += iSightRange * iScopeVisionRangeBonus / 100;
+ }
+ }
+ if (iSightRange < 1) {
+ iSightRange = 1;
+ }
+ }
+ if(iSightRange > sDistVis)
+ fCantSeeTarget = true;
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Determine iMarksmanship and Base CTH
+ if (Item[usInHand].rocketlauncher ){
+ // use the same calculation as for mechanical thrown weapons
+ iMarksmanship = ( EffectiveDexterity( pSoldier ) + EffectiveMarksmanship( pSoldier ) + EffectiveWisdom( pSoldier ) + (10 * EffectiveExpLevel( pSoldier ) )) / 4;
+ // heavy weapons trait helps out
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPS_OT ) && !( gGameOptions.fNewTraitSystem )) // SANDRO - old/new traits
+ iMarksmanship += gbSkillTraitBonus[HEAVY_WEAPS_OT] * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS_OT );
+ } else {
+ iMarksmanship = EffectiveMarksmanship( pSoldier );
+ if ( AM_A_ROBOT( pSoldier ) ) {
+ SOLDIERTYPE * pSoldier2;
+ pSoldier2 = pSoldier->GetRobotController( );
+ if ( pSoldier2 )
+ iMarksmanship = __max( iMarksmanship, EffectiveMarksmanship( pSoldier2 ) );
+ }
+ }
+ // modify chance to hit by morale
+ iMarksmanship += GetMoraleModifier( pSoldier );
+ // penalize marksmanship for fatigue
+ iMarksmanship -= GetSkillCheckPenaltyForFatigue( pSoldier, iMarksmanship );
+ if (iGunCondition >= iMarksmanship) // base chance is equal to the shooter's marksmanship skill
+ iChance = iMarksmanship;
+ else // base chance is equal to the average of marksmanship & gun's condition!
+ iChance = (iMarksmanship + iGunCondition) / 2;
+ // if shooting same target as the last shot
+ if (sGridNo == pSoldier->sLastTarget ) // give a bonus to hit
+ iChance += AIM_BONUS_SAME_TARGET;
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Range and Size modifiers
+
+ // Effects of actual gun max range... the numbers are based on wanting -40%
+ // at range 26for a pistol with range 13, and -0 for a sniper rifle with range 80
+ // The result is about 1.5% penalty per tile but only after about 30% of max range. Within 30% max range, there is no modifier
+ iPenalty = ((iMaxRange - (iRange-iAccRangeMod) * 3) * 10) / (17 * CELL_X_SIZE);
+ if ( iPenalty < 0 )
+ iChance += iPenalty;
+ if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
+ iChance -= 2 * ( MaxNormalDistanceVisible() - (iRange / CELL_X_SIZE) );
+ // Like the above modifier, only this applies to long range weapons trying to be used in close quater. Penalty will result when within 10% of max range
+ iPenalty = (((iRange - iMinRange - iAccRangeMod) * 12) * 10) / (17 * CELL_X_SIZE);
+ if ( iPenalty < 0 )
+ iChance += iPenalty;
+
+ // Effects of visual range
+ // From for JA2.5: 3% bonus/penalty for each tile different from range NORMAL_RANGE.
+ if (!TANK(pSoldier)) // WANNE: No penalty on the tank
+ iPenalty = 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
+ if ( fCantSeeTarget )
+ iPenalty = min(iPenalty, -gGameExternalOptions.iPenaltyShootUnSeen);
+ iChance += iPenalty;
+ //CHRISL: We should probably include these target size penalties even if we can't see the target so that shooting a "hidden" head is harder then a "hidden" body
+ // if aiming at the head, reduce chance to hit
+ if (ubAimPos == AIM_SHOT_HEAD)
+ {
+ // penalty of 3% per tile
+ //iPenalty = 3 * iSightRange / 10; //comm by ddd
+ iPenalty = INT32(gGameExternalOptions.uShotHeadPenalty * iSightRange / 10);
+ iChance -= iPenalty;
+ }
+ else if (ubAimPos == AIM_SHOT_LEGS)
+ {
+ // penalty of 1% per tile
+ iPenalty = iSightRange / 10;
+ iChance -= iPenalty;
+ }
+ //CHRISL: A target's stance should have no impact on an aimed, headshot. The head doesn't get any smaller just because the target is crouching down.
+ if (pTarget != NULL && ubAimPos != AIM_SHOT_HEAD)
+ {
+ // targeting a merc
+ // adjust for crouched/prone target
+ switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
+ {
+ case ANIM_CROUCH:
+ if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
+ {
+ // 13% penalty per tile closer than min range
+ iChance -= 13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
+ }
+ else
+ {
+ // at anything other than point-blank range
+ if (iRange > POINT_BLANK_RANGE + 10 * (AIM_PENALTY_TARGET_CROUCHED / 3) )
+ {
+ iChance -= AIM_PENALTY_TARGET_CROUCHED;
+ }
+ else if (iRange > POINT_BLANK_RANGE)
+ {
+ // at close range give same bonus as prone, up to maximum of AIM_PENALTY_TARGET_CROUCHED
+ iChance -= 3 * ((iRange - POINT_BLANK_RANGE) / CELL_X_SIZE); // penalty -3%/tile
+ }
+ }
+ break;
+ case ANIM_PRONE:
+ if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
+ {
+ // 25% penalty per tile closer than min range
+ iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
+ }
+ else
+ {
+ // at anything other than point-blank range
+ if (iRange > POINT_BLANK_RANGE)
+ {
+ // reduce chance to hit with distance to the prone/immersed target
+ iPenalty = 3 * ((iRange - POINT_BLANK_RANGE) / CELL_X_SIZE); // penalty -3%/tile
+ iPenalty = __min( iPenalty, AIM_PENALTY_TARGET_PRONE );
+
+ iChance -= iPenalty;
+ }
+ }
+ break;
+ case ANIM_STAND:
+ // if we are prone and at close range, then penalize shots to the torso or head!
+ if ( iRange <= MIN_PRONE_RANGE && gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE )
+ {
+ if ( ubAimPos == AIM_SHOT_RANDOM || ubAimPos == AIM_SHOT_GLAND )
+ {
+ ubAdjAimPos = AIM_SHOT_TORSO;
+ }
+ else
+ {
+ ubAdjAimPos = ubAimPos;
+ }
+ // lose 10% per height difference, lessened by distance
+ // e.g. 30% to aim at head at range 1, only 10% at range 3
+ // or 20% to aim at torso at range 1, no penalty at range 3
+ // NB torso aim position is 2, so (5-aimpos) is 3, for legs it's 2, for head 4
+ iChance -= (5 - ubAdjAimPos - iRange / CELL_X_SIZE) * 10;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pTarget != NULL)
+ {
+ // penalty for amount that enemy has moved
+ // HEADROCK HAM B2.6: Externalized the value
+ iPenalty = __min( (UINT16)((float)pTarget->bTilesMoved * (float)gGameExternalOptions.iMovementEffectOnAiming), 30 );
+ ///////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - fearless characters do not even take their head down no matter what
+ if ( gGameOptions.fNewTraitSystem && pTarget->ubProfile != NO_PROFILE )
+ {
+ if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
+ iPenalty -= (iPenalty * 2 / 3); // two thirds only
+ }
+ ///////////////////////////////////////////////////////////////////////////////////
+ iChance -= iPenalty;
+
+ // if target sees us, he may have a chance to dodge before the gun goes off
+ // but ability to dodge is reduced if crouched or prone!
+ if (pTarget->aiData.bOppList[pSoldier->ubID] == SEEN_CURRENTLY && !TANK( pTarget ) && !(pSoldier->ubBodyType != QUEENMONSTER) )
+ {
+ iPenalty = ( EffectiveAgility( pTarget ) / 5 + EffectiveExpLevel( pTarget ) * 2);
+ switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
+ {
+ case ANIM_CROUCH:
+ iPenalty = iPenalty * 2 / 3;
+ break;
+ case ANIM_PRONE:
+ iPenalty /= 3;
+ break;
+ }
+
+ // reduce dodge ability by the attacker's stats
+ iBonus = ( EffectiveDexterity( pSoldier ) / 5 + EffectiveExpLevel( pSoldier ) * 2);
+ if ( TANK( pTarget ) || (pSoldier->ubBodyType != QUEENMONSTER) )
+ {
+ // reduce ability to track shots
+ iBonus = iBonus / 2;
+ }
+
+ if ( iPenalty > iBonus )
+ {
+ iChance -= (iPenalty - iBonus);
+ }
+ }
+ if(fCoverObscured){ // If we can't see the body part but can see the tile include a -1%/tile penalty
+ iPenalty = iCoverRange / CELL_X_SIZE;
+ iChance -= iPenalty;
+ }
+ }
+ else if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
+ {
+ // 25% penalty per tile closer than min range
+ iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
+ }
+ for(attachmentList::iterator iter = (*pInHand)[0]->attachments.begin(); iter != (*pInHand)[0]->attachments.end(); iter++)
+ {
+ if(iter->exists() && Item[iter->usItem].aimbonus >= gGameExternalOptions.sHighPowerScope && iRange > Item[iter->usItem].minrangeforaimbonus)
+ {
+ iPenalty = (Item[iter->usItem].aimbonus * (iRange - Item[iter->usItem].minrangeforaimbonus)) / 1000;
+ iPenalty = min(AIM_BONUS_PRONE, iPenalty);
+ iChance -= iPenalty;
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Modify for traits
+ if( gGameOptions.fNewTraitSystem )
+ {
+ // Bonus for heavy weapons moved here from above to get instant CtH bonus and not marksmanship bonus,
+ // which is supressed by weapon condition
+ if (Item[usInHand].rocketlauncher || Item[usInHand].singleshotrocketlauncher)
+ {
+ iChance += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!!
+
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ))
+ iChance += gSkillTraitValues.ubHWBonusCtHRocketLaunchers * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ); // +25% per trait
+ }
+ // Added CtH bonus for Gunslinger trait on pistols and machine-pistols
+ else if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL )
+ {
+ iChance += gSkillTraitValues.bCtHModifierPistols; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubGSBonusCtHPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +10% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_M_PISTOL )
+ {
+ iChance += gSkillTraitValues.bCtHModifierMachinePistols; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && ((pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0) || !gSkillTraitValues.ubGSCtHMPExcludeAuto))
+ iChance += gSkillTraitValues.ubGSBonusCtHMachinePistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Machinegunner skill on assault rifles, SMGs and LMGs
+ else if ( Weapon[usInHand].ubWeaponType == GUN_AS_RIFLE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierAssaultRifles; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iChance += gSkillTraitValues.ubAWBonusCtHAssaultRifles * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SMG )
+ {
+ iChance += gSkillTraitValues.bCtHModifierSMGs; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iChance += gSkillTraitValues.ubAWBonusCtHSMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_LMG )
+ {
+ iChance += gSkillTraitValues.bCtHModifierLMGs; // -10% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iChance += gSkillTraitValues.ubAWBonusCtHLMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Gunslinger trait on pistols and machine-pistols
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierSniperRifles; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubSNBonusCtHSniperRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Ranger skill on rifles and shotguns
+ else if ( Weapon[usInHand].ubWeaponType == GUN_RIFLE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierRifles; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubRABonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +5% per trait
+ //CHRISL: Why wouldn't sniper training include standard rifles which are often used as "poor-man sniper rifles"
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubSNBonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SHOTGUN )
+ {
+ iChance += gSkillTraitValues.bCtHModifierShotguns; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) )
+ iChance += gSkillTraitValues.ubRABonusCtHShotguns * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +10% per trait
+ }
+
+ // Added small CtH penalty for robot if controller hasn't the Technician trait
+ if( AM_A_ROBOT( pSoldier ) )
+ {
+ iChance += gSkillTraitValues.bCtHModifierRobot; // -10%
+
+ if ( HAS_SKILL_TRAIT( pSoldier->GetRobotController(), TECHNICIAN_NT ) )
+ iChance += gSkillTraitValues.ubTECtHControlledRobotBonus * NUM_SKILL_TRAITS( pSoldier->GetRobotController(), TECHNICIAN_NT ); // +10% per trait
+ }
+
+ // Added character traits influence
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ {
+ // Sociable - better performance in groups
+ if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SOCIABLE );
+ if ( bNumMercs > 2 )
+ iChance += 5;
+ else if ( bNumMercs > 0 )
+ iChance += 2;
+ }
+ // Loner - better performance when alone
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_LONER );
+ if ( bNumMercs == 0 )
+ iChance += 5;
+ else if ( bNumMercs <= 1 )
+ iChance += 2;
+ }
+ // Aggressive - bonus on bursts/autofire
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
+ {
+ if (( pSoldier->bDoBurst || pSoldier->bDoAutofire ) && !ubAimTime )
+ iChance += 5;
+ }
+ // Show-off - better performance if some babes around to impress
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SHOWOFF );
+ if ( bNumMercs > 1 )
+ iChance += 5;
+ else if ( bNumMercs > 0 )
+ iChance += 2;
+ }
+ // Added disabilities
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ {
+ // Heat intolerant penalty
+ if ( MercIsHot( pSoldier ) )
+ {
+ iChance -= 15;
+ }
+ // Small penalty for fear of insects in tropical sectors
+ else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ) )
+ {
+ // fear of insects, and we are in tropical sector
+ iChance -= 5;
+ }
+ }
+ }
+ // Dauntless - penalty for not taking proper cover
+ if (pTarget != NULL)
+ {
+ if ( pTarget->ubProfile != NO_PROFILE )
+ {
+ if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
+ iChance += 5;
+ }
+ }
+ }
+ else
+ {
+ // this rather unlogical bonus for psychotic characters applies only with old traits
+ if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
+ {
+ iChance += AIM_BONUS_PSYCHO;
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Modify for stance and weapon
+ // if shooter is crouched, he aims slightly better (to max of AIM_BONUS_CROUCHING)
+ if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH )
+ {
+ iBonus = iRange / 10;
+ if (iBonus > AIM_BONUS_CROUCHING)
+ {
+ iBonus = AIM_BONUS_CROUCHING;
+ }
+ iChance += iBonus;
+ }
+ // if shooter is prone, he aims even better, except at really close range
+ else if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE )
+ {
+ if (iRange > MIN_PRONE_RANGE)
+ {
+ iBonus = iRange / 10;
+ if (iBonus > AIM_BONUS_PRONE)
+ {
+ iBonus = AIM_BONUS_PRONE;
+ }
+ iChance += iBonus;
+ }
+ }
+ //Madd: inherent weapon accuracy bonus
+ //iChance += Weapon[usInHand].bAccuracy;
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Modify for using one hand
+ if ( !(Item[ usInHand ].twohanded ) )
+ {
+ if (pSoldier->inv[SECONDHANDPOS].exists() == false)
+ {
+ // firing with gun in right hand, and second hand empty (ie: no grenade, med kit or anything there)
+ // Madd: easier to fire pistol/smg w/one hand free, essentially this will make pistols a little bit more accurate, and hopefully still useful later in the game
+ if (Weapon[usInHand].ubWeaponClass == HANDGUNCLASS)
+ iChance += AIM_BONUS_TWO_HANDED_PISTOL;
+ }
+ else
+ {
+ // Madd: harder to fire smgs w/something in other hand
+ // SMGs are treated as pistols for these purpose except there is a -5 penalty;
+ if (Weapon[usInHand].ubWeaponClass == SMGCLASS)
+ {
+ iChance -= AIM_PENALTY_SMG;
+ }
+ if (gGameOptions.fNewTraitSystem)
+ {
+ // Okay, we will shoot from both weapons, calculate penalty to CtH
+ if ( pSoldier->IsValidSecondHandShot() )
+ {
+ // penaly to shoot from dual weapons
+ iChance -= (INT32)(gSkillTraitValues.ubCtHPenaltyDualShot * (HAS_SKILL_TRAIT( pSoldier, AMBIDEXTROUS_NT ) ? ((100 - gSkillTraitValues.ubAMPenaltyDoubleReduction)/100) : 1 ));
+ }
+ }
+ else // original code
+ {
+ if ( !HAS_SKILL_TRAIT( pSoldier, AMBIDEXT_OT ) )
+ {
+ if ( pSoldier->IsValidSecondHandShot( ) )
+ {
+ // penalty to aim when firing two pistols
+ iChance -= AIM_PENALTY_DUAL_PISTOLS;
+ }
+ /*
+ else
+ {
+ // penalty to aim with pistol being fired one-handed
+ iChance -= AIM_PENALTY_ONE_HANDED_PISTOL;
+ }
+ */
+ }
+ }
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Modify for Recoil and Tracer effects
+ if ( pSoldier->bDoBurst && pSoldier->bDoAutofire == 0 )
+ {
+ /*CHRISL: At this point in the calculation, Bipods, Foregrips and other "recoil stabalizing" bonuses should reduce the weapons "recoil penalty"
+ (BurstPenalty) by a percentage. This reduction should apply the the recoil per shot and not as a "flat" initial reduction. Later in the code,
+ Bipods also grant their flat CTH bonus so we don't need to mess this that here*/
+ if(gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier)
+ {
+ iBonus = GetBurstToHitBonus(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier;
+ iPenalty = Weapon[pInHand->usItem].ubBurstPenalty * (pSoldier->bDoBurst - 1) * (gGameExternalOptions.bAimedBurstEnabled?gGameExternalOptions.uAimedBurstPenalty:1);
+ iPenalty = max(0, (iPenalty * (100 - iBonus))/100 );
+ }
+ else
+ {
+ // Snap: bipod may reduce burst penalty
+ iPenalty = GetBurstPenalty(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * (pSoldier->bDoBurst - 1);
+ if(gGameExternalOptions.bAimedBurstEnabled)
+ iPenalty += Weapon[usInHand].ubBurstPenalty * (pSoldier->bDoBurst - 1) * gGameExternalOptions.uAimedBurstPenalty;
+ }
+
+ // halve the penalty for people with the autofire trait
+ if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ {
+ iPenalty = max(0, ((iPenalty * (100 - gSkillTraitValues.ubAWAutoFirePenaltyReduction * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/100));
+ }
+ }
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS_OT ) )
+ {
+ iPenalty /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT );
+ }
+ }
+ iChance -= iPenalty;
+ }
+ else if ( pSoldier->bDoAutofire > 0 )
+ {
+ /*CHRISL: At this point in the calculation, Bipods, Foregrips and other "recoil stabalizing" bonuses should reduce the weapons "recoil penalty"
+ (AutoPenalty) by a percentage. This reduction should apply the the recoil per shot and not as a "flat" initial reduction. Later in the code,
+ Bipods also grant their flat CTH bonus so we don't need to mess this that here*/
+ if(gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier)
+ {
+ iBonus = GetAutoToHitBonus(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier;
+ iPenalty = Weapon[pInHand->usItem].AutoPenalty * (pSoldier->bDoBurst - 1) * (gGameExternalOptions.bAimedBurstEnabled?gGameExternalOptions.uAimedBurstPenalty:1);
+ iPenalty = max(0, (iPenalty * (100 - iBonus))/100 );
+ }
+ else
+ {
+ // Snap: bipod may reduce auto penalty
+ iPenalty = GetAutoPenalty(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * (pSoldier->bDoBurst - 1);
+ if(gGameExternalOptions.bAimedBurstEnabled)
+ iPenalty += Weapon[usInHand].AutoPenalty * (pSoldier->bDoBurst - 1) * gGameExternalOptions.uAimedBurstPenalty;
+ }
+
+ // halve the penalty for people with the autofire trait
+ if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ {
+ iPenalty = max(0, ((iPenalty * (100 - gSkillTraitValues.ubAWAutoFirePenaltyReduction * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/100));
+ }
+ }
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS_OT ) )
+ {
+ iPenalty /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT );
+ }
+ }
+ iChance -= iPenalty;
+ // HEADROCK HAM 3.5: Store the penalty
+ sTotalAutofirePenalty = iPenalty;
+ }
+ if (AmmoTypes[(*pInHand)[0]->data.gun.ubGunAmmoType].tracerEffect == 1 && gGameExternalOptions.ubRealisticTracers > 0 )
+ {
+ /*CHRISL: We want to know here is how many tracers have been fired during this autofire sequence. But we also want to figure that based on how
+ much ammo we've used from the current mag. If every 3rd round is a tracer, and we previously fired 5 rounds from our "mag", then the first
+ round of this burst is a tracer, the 2nd & 3rd are normal, the 4th is a tracer, 5th & 6th are normal, etc.*/
+ if (fCalculateCTHDuringGunfire) // Calculate number of bullets left right before firing this burst
+ iBulletsLeft = (*pInHand)[0]->data.gun.ubGunShotsLeft + (pSoldier->bDoBurst - 1);
+ else
+ iBulletsLeft = (*pInHand)[0]->data.gun.ubGunShotsLeft;
+ iRoundsFiredPreviously = GetMagSize(pInHand) - iBulletsLeft; //How many rounds had been fired before this autofire sequence
+ for( UINT8 cnt = 1; cnt <= pSoldier->bDoBurst; cnt++ ){ //How many tracers have been fired prior to this bullet in this autofire sequence
+ if((iRoundsFiredPreviously+cnt)%iBulletsPerTracer == 0)
+ iTracersFired++;
+ }
+ if ( iTracersFired > 0 ) {
+ if(sTotalAutofirePenalty > 0){
+ INT16 sChanceLimit = min(gGameExternalOptions.ubCTHBumpPerTracer, ((iRange-(gGameExternalOptions.ubMinRangeTracerEffect*CELL_X_SIZE)) / CELL_X_SIZE) * gGameExternalOptions.ubRangeDifficultyAimingWithTracers);
+ sChanceLimit = max(0, sChanceLimit);
+ iBonus = sChanceLimit * iTracersFired;
+ iBonus = min(iBonus, sTotalAutofirePenalty);
+ }
+
+ iChance += iBonus;
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Modify for Aim
+ if(ubAimTime)
+ {
+ // CHRISL: Rather then a flat +10/click bonus, we're going to try a bonus that's based on MRK and Lvl which gets
+ // progressivly less the more we aim. Everything is based on the maxBonus that a merc can possibly get which
+ // uses the equation: 20+(MRK/20*LVL)+Accuracy+(Sniper trait * 10). This value is then split between the 8
+ // possible AimTime's using a max aimTime bonus of 10.
+ if ( gGameOptions.fNewTraitSystem ) {
+ // bonus to snipers and gunslingers
+ if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL || Weapon[usInHand].ubWeaponType == GUN_M_PISTOL )
+ maxBonus = 20+((FLOAT)iMarksmanship/20*(EffectiveExpLevel(pSoldier)))+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT )*gSkillTraitValues.ubGSAimingBonusPerClick);
+ else
+ maxBonus = 20+((FLOAT)iMarksmanship/20*(EffectiveExpLevel(pSoldier)))+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )*gSkillTraitValues.ubSNAimingBonusPerClick);
+ } else {
+ if(gGameExternalOptions.bAltAimEnabled)
+ maxBonus = (20*(iMarksmanship/100))+((FLOAT)iMarksmanship/20*pSoldier->stats.bExpLevel)+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )*10);
+ else
+ maxBonus = 20+((FLOAT)iMarksmanship/20*pSoldier->stats.bExpLevel)+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )*10);
+ }
+ iAimBonus = (float)GetAimBonus( pInHand, 100, 1 );
+ for(int i = 0; i < ubAimTime; i++) {
+ aimTimeBonus = __min((maxBonus*bonusProgression[i]/1000),maxClickBonus);
+ maxBonus -= aimTimeBonus;
+ iChance += (INT32)floor(aimTimeBonus+.5);
+ //CHRISL: This is a slight extra bonus granted from a scopes AimBonus score
+ aimTimeBonus = __min(ceil((float)(iAimBonus * bonusProgression[i] / 1000)), 3);
+ iAimBonus -= aimTimeBonus;
+ iChance+= (INT32)floor(aimTimeBonus+.5);
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // AI Modifiers
+ if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_PC ) ) // if this is a computer AI controlled enemy
+ {
+ if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
+ {
+ // On easy, penalize all enemies by 5%
+ iChance -= 5;
+ }
+ else
+ {
+ iChance += __min( 0, gbDiff[ DIFF_ENEMY_TO_HIT_MOD ][ SoldierDifficultyLevel( pSoldier ) ] );
+ }
+ }
+ // SANDRO - Bonus CtH for Militia
+ if (pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.sGreenMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sGreenMilitiaCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.sRegularMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sRegularMilitiaCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
+ // bonus for enemy
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyEliteCtHBonusPercent) /100);
+ // SANDRO - option to make special NPCs stronger - chance to hit
+ if (gGameExternalOptions.usSpecialNPCStronger > 0)
+ {
+ switch( pSoldier->ubProfile )
+ {
+ case CARMEN:
+ case QUEEN:
+ case JOE:
+ case ANNIE:
+ case CHRIS:
+ case KINGPIN:
+ case TIFFANY:
+ case T_REX:
+ case DRUGGIST:
+ case GENERAL:
+ case JACK:
+ case OLAF:
+ case RAY:
+ case OLGA:
+ case TYRONE:
+ case MIKE:
+ iChance += (iChance * gGameExternalOptions.usSpecialNPCStronger / 100);
+ break;
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Situational modifiers
+ if ( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED )
+ iChance -= AIM_PENALTY_GASSED;
+ if (pSoldier->ubServiceCount > 0)
+ iChance -= AIM_PENALTY_GETTINGAID;
+ if (pSoldier->aiData.bShock)
+ {
+ if (gGameExternalOptions.usMaxShooterCoweringPenalty > 0)
+ {
+ if ( usShockPenalty > gGameExternalOptions.usMaxShooterCoweringPenalty )
+ usShockPenalty = gGameExternalOptions.usMaxShooterCoweringPenalty;
+ }
+ if ( usShockPenalty < 1 )
+ usShockPenalty = 1;
+
+ iChance -= usShockPenalty;
+ }
+ // adjust for roof/not on roof
+ if ( pSoldier->pathing.bLevel == 0 )
+ {
+ if ( pSoldier->bTargetLevel > 0 )
+ {
+ // penalty for firing up
+ iChance -= AIM_PENALTY_FIRING_UP;
+ }
+ }
+ else // pSoldier->pathing.bLevel > 0 )
+ {
+ if ( pSoldier->bTargetLevel == 0 )
+ {
+ iChance += AIM_BONUS_FIRING_DOWN;
+ }
+ }
+ // IF CHANCE EXISTS, BUT SHOOTER IS INJURED
+ if ((iChance > 0) && (pSoldier->stats.bLife < pSoldier->stats.bLifeMax))
+ {
+ // if bandaged, give 1/2 of the bandaged life points back into equation
+ bBandaged = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
+
+ // injury penalty is based on % damage taken (max 2/3rds chance)
+ iPenalty = (iChance * 2 * (pSoldier->stats.bLifeMax - pSoldier->stats.bLife + (bBandaged / 2))) /
+ (3 * pSoldier->stats.bLifeMax);
+
+ // reduce injury penalty due to merc's experience level (he can take it!)
+ iChance -= (iPenalty * (100 - (10 * ( EffectiveExpLevel( pSoldier ) - 1)))) / 100;
+ }
+
+ // IF CHANCE EXISTS, BUT SHOOTER IS LOW ON BREATH
+ if ((iChance > 0) && (pSoldier->bBreath < 100))
+ {
+ // breath penalty is based on % breath missing (max 1/2 chance)
+ iPenalty = (iChance * (100 - pSoldier->bBreath)) / 200;
+ // reduce breath penalty due to merc's dexterity (he can compensate!)
+ iChance -= (iPenalty * (100 - ( EffectiveDexterity( pSoldier ) - 10))) / 100;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Equipment Modifiers
+ iChance += GetGearToHitBonus ( pSoldier );
+ iChance += GetToHitBonus( pInHand, iRange, bLightLevel,gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && iRange > MIN_PRONE_RANGE );
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Suppression modifiers
+ if ( gGameExternalOptions.ubAimPenaltyPerTargetShock > 0 )
+ {
+ if (pTarget != NULL)
+ {
+ if (pTarget->aiData.bShock )
+ {
+ if (gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_PRONE)
+ {
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorProne;
+
+ sCoweringPenalty = (pTarget->aiData.bShock * AIM_PENALTY_PER_TARGET_SHOCK);
+ sCoweringPenalty = sCoweringPenalty / ubCoweringDivisor;
+ sCoweringPenalty = (sCoweringPenalty * __min(iSightRange,MIN_RANGE_FOR_FULL_COWER)) / MIN_RANGE_FOR_FULL_COWER;
+
+ if (gGameExternalOptions.usMaxTargetCoweringPenalty > 0)
+ {
+ if ( sCoweringPenalty > gGameExternalOptions.usMaxTargetCoweringPenalty )
+ sCoweringPenalty = gGameExternalOptions.usMaxTargetCoweringPenalty;
+ }
+ if ( sCoweringPenalty < 1 )
+ sCoweringPenalty = 1;
+
+ iChance -= sCoweringPenalty;
+ }
+ else if (gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_CROUCH)
+ {
+ switch ( ubAimPos )
+ {
+ case AIM_SHOT_HEAD:
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedHead;
+ break;
+ case AIM_SHOT_TORSO:
+ case AIM_SHOT_RANDOM:
+ case AIM_SHOT_GLAND:
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedTorso;
+ break;
+ case AIM_SHOT_LEGS:
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedLegs;
+ break;
+ }
+
+ sCoweringPenalty = (pTarget->aiData.bShock * AIM_PENALTY_PER_TARGET_SHOCK);
+ sCoweringPenalty = sCoweringPenalty / ubCoweringDivisor;
+ sCoweringPenalty = (sCoweringPenalty * __min(iSightRange,MIN_RANGE_FOR_FULL_COWER)) / MIN_RANGE_FOR_FULL_COWER;
+
+ if (gGameExternalOptions.usMaxTargetCoweringPenalty > 0)
+ {
+ if ( sCoweringPenalty > gGameExternalOptions.usMaxTargetCoweringPenalty )
+ sCoweringPenalty = gGameExternalOptions.usMaxTargetCoweringPenalty;
+ }
+ if ( sCoweringPenalty < 1 )
+ sCoweringPenalty = 1;
+
+ // HEADROCK HAM B2.8.1: Added formula to make sure that cowering target penalties
+ // are not given when on the roof.
+
+ if (pSoldier->pathing.bLevel == pTarget->pathing.bLevel && pSoldier->pathing.bLevel > 0)
+ sCoweringPenalty = 0; // No cowering penalties when both are on the roof!
+ else if (pSoldier->pathing.bLevel < pSoldier->pathing.bLevel && gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_PRONE)
+ sCoweringPenalty *= 2; // Much harder to shoot at anyone cowering above you.
+ else if (pSoldier->pathing.bLevel > pSoldier->pathing.bLevel)
+ sCoweringPenalty /= 2; // Much easier to shoot at cowerers below you.
+ iChance -= sCoweringPenalty;
+ }
+ }
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Max range modifier. This needs to be here, near the end of the function to
+ // guarantee that the max range penalty is properly calculated.
+ /////////////////////////////////////////////////////////////////////////////////////
+ if ( iRange > iMaxRange )
+ {
+ // a bullet WILL travel that far if not blocked, but it's NOT accurate,
+ // because beyond maximum range, the bullet drops rapidly
+
+ // This won't cause the bullet to be off to the left or right, only make it
+ // drop in flight.
+ //iChance /= 2; //ddd
+ iChance = (INT32)(iChance / gGameExternalOptions.fOutOfGunRangeOrSight);
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // Adjust for Max and Min values
+ // HEADROCK: (HAM) Altered so called "Defined Limits" to accept external arguments.
+ // The divisor argument only works when the minimum is set to 0. It has a chance of 1 in X to
+ // bump the minimum back to 1, where X = the Divisor value. So a divisor value of 50 gives a 1/50
+ // chance of getting some actual chance to hit despite the 0 minimum. The overall total would then
+ // be an effective CTH of only 1/5000 (50 chances to get a 1 out of 100 CTH, hehehe)
+ if (iChance <= gGameExternalOptions.ubMinimumCTH)
+ {
+ if ( TANK( pSoldier ) )
+ {
+ // allow absolute minimums
+ iChance = 0;
+ }
+ else
+ {
+ iChance = gGameExternalOptions.ubMinimumCTH;
+ if ( gGameExternalOptions.ubMinimumCTH == 0 )
+ {
+ if ( PreRandom( gGameExternalOptions.usMinimumCTHDivisor ) == (gGameExternalOptions.usMinimumCTHDivisor - 1) )
+ {
+ iChance = 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ // HEADROCK (HAM): Externalized maximum to JA2_OPTIONS.INI
+ // if (iChance > MAXCHANCETOHIT)
+ // iChance = MAXCHANCETOHIT;
+ if (iChance > gGameExternalOptions.ubMaximumCTH)
+ iChance = gGameExternalOptions.ubMaximumCTH;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: ichance = %d",iChance));
+ return (iChance);
+ /*CHRISL: I've tried to sort and reorganize this function to make it a little easier to follow. All of this is the original function
+ //SOLDIERTYPE *vicpSoldier;
+ SOLDIERTYPE * pTarget;
+ INT32 iChance; //CTH
+ INT32 iRange; //Actual range to target
+ INT32 iSightRange; //LOS range
+ INT32 iTileRange; //LOS range to the tile target is in - in case we can't see the target
+ INT32 iVisionRange; //Effective visual range
+ INT32 iMaxRange; //Weapon maximum range
+ INT32 iGunCondition; //Weapons effective condition
+ INT32 iMarksmanship; //Mercs effective marksmanship
+ INT32 iBonus, iPenalty;
+ //rain
+ //INT32 iScopeBonus;
+ //end rain
+ UINT16 usInHand;
+ OBJECTTYPE * pInHand;
+// INT8 bAttachPos;
+ INT8 bBandaged;
+ INT16 sDistVis;
+ UINT8 ubAdjAimPos;
+ UINT8 ubTargetID;
+ bool highPowerScope = false;
+ UINT32 pScope;
+ UINT8 bLightLevel = LightTrueLevel(sGridNo, pSoldier->bTargetLevel);
+
+ // HEADROCK HAM 3.5: Variable holds total autofire penalty.
+ INT16 sTotalAutofirePenalty = 0;
+
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun"));
+
+ if ( pSoldier->stats.bMarksmanship == 0 )
+ {
+ // HEADROCK: (HAM) Altered to accept external arguments
+ // return( MINCHANCETOHIT );
+ return( gGameExternalOptions.ubMinimumCTH );
+ }
+
+ // make sure the guy's actually got a weapon in his hand!
+ pInHand = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+ usInHand = pSoldier->usAttackingWeapon;
+ //CHRISL: We have new modifiers when using a high power scope so find out if we have one from the start
+ for(attachmentList::iterator iter = (*pInHand)[0]->attachments.begin(); iter != (*pInHand)[0]->attachments.end(); iter++)
+ {
+ if(Item[iter->usItem].aimbonus >= gGameExternalOptions.sHighPowerScope && iter->exists())
+ {
+ highPowerScope = true;
+ pScope = iter->usItem;
+ break;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // DETERMINE BASE CHANCE OF HITTING
+ iGunCondition = WEAPON_STATUS_MOD( (*pInHand)[0]->data.gun.bGunStatus );
+
+ if (Item[usInHand].rocketlauncher )
+ {
+ // use the same calculation as for mechanical thrown weapons
+ iMarksmanship = ( EffectiveDexterity( pSoldier ) + EffectiveMarksmanship( pSoldier ) + EffectiveWisdom( pSoldier ) + (10 * EffectiveExpLevel( pSoldier ) )) / 4;
+ // heavy weapons trait helps out
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPS_OT ) && !( gGameOptions.fNewTraitSystem )) // SANDRO - old/new traits
+ {
+ iMarksmanship += gbSkillTraitBonus[HEAVY_WEAPS_OT] * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS_OT );
+ }
+ }
+ else
+ {
+ iMarksmanship = EffectiveMarksmanship( pSoldier );
+
+ if ( AM_A_ROBOT( pSoldier ) )
+ {
+ SOLDIERTYPE * pSoldier2;
+
+ pSoldier2 = pSoldier->GetRobotController( );
+ if ( pSoldier2 )
+ {
+ iMarksmanship = __max( iMarksmanship, EffectiveMarksmanship( pSoldier2 ) );
+ }
+ }
+ }
+
+ // modify chance to hit by morale
+ iMarksmanship += GetMoraleModifier( pSoldier );
+
+ // penalize marksmanship for fatigue
+ iMarksmanship -= GetSkillCheckPenaltyForFatigue( pSoldier, iMarksmanship );
+
+ //if ( PTR_OURTEAM )
+ //{
+ // iChance = ( iMarksmanship * iGunCondition ) / 100;
+ //}
+ //else
+ {
+ if (iGunCondition >= iMarksmanship)
+ // base chance is equal to the shooter's marksmanship skill
+ iChance = iMarksmanship;
+ else
+ // base chance is equal to the average of marksmanship & gun's condition!
+ iChance = (iMarksmanship + iGunCondition) / 2;
+ }
+ /////////////////////////////////////////////////////////////////////////////////////
+
+ // if shooting same target as the last shot
+ if (sGridNo == pSoldier->sLastTarget )
+ iChance += AIM_BONUS_SAME_TARGET; // give a bonus to hit
+
+ /////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - STOMP traits
+ ////////////////////////////////////////////////////
+ // For every type of gun, there was added a penalty for untrained mercs. This penalty
+ // is rather small and is often compensated by single trait of that type
+ if( gGameOptions.fNewTraitSystem )
+ {
+ // Bonus for heavy weapons moved here from above to get instant CtH bonus and not marksmanship bonus,
+ // which is supressed by weapon condition
+ if (Item[usInHand].rocketlauncher || Item[usInHand].singleshotrocketlauncher)
+ {
+ iChance += gSkillTraitValues.bCtHModifierRocketLaunchers; // -25% for untrained mercs !!!
+
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ))
+ iChance += gSkillTraitValues.ubHWBonusCtHRocketLaunchers * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ); // +25% per trait
+ }
+ // Added CtH bonus for Gunslinger trait on pistols and machine-pistols
+ else if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL )
+ {
+ iChance += gSkillTraitValues.bCtHModifierPistols; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubGSBonusCtHPistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +10% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_M_PISTOL )
+ {
+ iChance += gSkillTraitValues.bCtHModifierMachinePistols; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) && ((pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0) || !gSkillTraitValues.ubGSCtHMPExcludeAuto))
+ iChance += gSkillTraitValues.ubGSBonusCtHMachinePistols * NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Machinegunner skill on assault rifles, SMGs and LMGs
+ else if ( Weapon[usInHand].ubWeaponType == GUN_AS_RIFLE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierAssaultRifles; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iChance += gSkillTraitValues.ubAWBonusCtHAssaultRifles * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SMG )
+ {
+ iChance += gSkillTraitValues.bCtHModifierSMGs; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iChance += gSkillTraitValues.ubAWBonusCtHSMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_LMG )
+ {
+ iChance += gSkillTraitValues.bCtHModifierLMGs; // -10% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ iChance += gSkillTraitValues.ubAWBonusCtHLMGs * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Gunslinger trait on pistols and machine-pistols
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SN_RIFLE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierSniperRifles; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubSNBonusCtHSniperRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait
+ }
+ // Added CtH bonus for Ranger skill on rifles and shotguns
+ else if ( Weapon[usInHand].ubWeaponType == GUN_RIFLE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierRifles; // -5% for untrained mercs.
+
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubRABonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +5% per trait
+ //CHRISL: Why wouldn't sniper training include standard rifles which are often used as "poor-man sniper rifles"
+ // this bonus is applied only on single shots!
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) && pSoldier->bDoBurst == 0 && pSoldier->bDoAutofire == 0 )
+ iChance += gSkillTraitValues.ubSNBonusCtHRifles * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT ); // +5% per trait
+ }
+ else if ( Weapon[usInHand].ubWeaponType == GUN_SHOTGUN )
+ {
+ iChance += gSkillTraitValues.bCtHModifierShotguns; // -5% for untrained mercs.
+
+ if ( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) )
+ iChance += gSkillTraitValues.ubRABonusCtHShotguns * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); // +10% per trait
+ }
+
+ // Added small CtH penalty for robot if controller hasn't the Technician trait
+ if( AM_A_ROBOT( pSoldier ) )
+ {
+ iChance += gSkillTraitValues.bCtHModifierRobot; // -10%
+
+ if ( HAS_SKILL_TRAIT( pSoldier->GetRobotController(), TECHNICIAN_NT ) )
+ iChance += gSkillTraitValues.ubTECtHControlledRobotBonus * NUM_SKILL_TRAITS( pSoldier->GetRobotController(), TECHNICIAN_NT ); // +10% per trait
+ }
+
+ // Added character traits influence
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ {
+ // Sociable - better performance in groups
+ if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SOCIABLE );
+ if ( bNumMercs > 2 )
+ iChance += 5;
+ else if ( bNumMercs > 0 )
+ iChance += 2;
+ }
+ // Loner - better performance when alone
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_LONER );
+ if ( bNumMercs == 0 )
+ iChance += 5;
+ else if ( bNumMercs <= 1 )
+ iChance += 2;
+ }
+ // Aggressive - bonus on bursts/autofire
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
+ {
+ if (( pSoldier->bDoBurst || pSoldier->bDoAutofire ) && !ubAimTime )
+ iChance += 5;
+ }
+ // Show-off - better performance if some babes around to impress
+ else if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pSoldier->ubProfile, CHAR_TRAIT_SHOWOFF );
+ if ( bNumMercs > 1 )
+ iChance += 5;
+ else if ( bNumMercs > 0 )
+ iChance += 2;
+ }
+ // Added disabilities
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ {
+ // Heat intolerant penalty
+ if ( MercIsHot( pSoldier ) )
+ {
+ iChance -= 15;
+ }
+ // Small penalty for fear of insects in tropical sectors
+ else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ) )
+ {
+ // fear of insects, and we are in tropical sector
+ iChance -= 5;
+ }
+ }
+ }
+ // Dauntless - penalty for not taking proper cover
+ pTarget = SimpleFindSoldier( sGridNo, pSoldier->bTargetLevel );
+ if (pTarget != NULL)
+ {
+ if ( pTarget->ubProfile != NO_PROFILE )
+ {
+ if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
+ iChance += 5;
+ }
+ }
+ }
+ else
+ {
+ // this rather unlogical bonus for psychotic characters applies only with old traits
+ if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
+ {
+ iChance += AIM_BONUS_PSYCHO;
+ }
+ }
+
+ // calculate actual range (in units, 10 units = 1 tile)
+ iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sGridNo );
+
+ //CHRISL: Incur a penalty if using a highPowerScope
+ if(highPowerScope == true && iRange > Item[pScope].minrangeforaimbonus)
+ {
+ iPenalty = (Item[pScope].aimbonus * (iRange-Item[pScope].minrangeforaimbonus)) / 1000;
+ if (iPenalty > AIM_BONUS_PRONE)
+ {
+ iPenalty = AIM_BONUS_PRONE;
+ }
+ iChance -= iPenalty;
+ }
+ // if shooter is crouched, he aims slightly better (to max of AIM_BONUS_CROUCHING)
+ if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_CROUCH )
+ {
+ iBonus = iRange / 10;
+ if (iBonus > AIM_BONUS_CROUCHING)
+ {
+ iBonus = AIM_BONUS_CROUCHING;
+ }
+ iChance += iBonus;
+ }
+ // if shooter is prone, he aims even better, except at really close range
+ else if ( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE )
+ {
+ if (iRange > MIN_PRONE_RANGE)
+ {
+ iBonus = iRange / 10;
+ if (iBonus > AIM_BONUS_PRONE)
+ {
+ iBonus = AIM_BONUS_PRONE;
+ }
+ // Snap: bipod bonus is now calculated in GetToHitBonus
+ //bAttachPos = FindAttachment( pInHand, BIPOD );
+ //if (bAttachPos != ITEM_NOT_FOUND)
+ //{ // extra bonus to hit for a bipod, up to half the prone bonus itself
+ // iBonus += (iBonus * WEAPON_STATUS_MOD(GetBipodStatus(pInHand)) / 100) / 2;
+ //}
+ iChance += iBonus;
+ }
+ }
+
+ //Madd: inherent weapon accuracy bonus
+ iChance += Weapon[usInHand].bAccuracy;
+
+// if ( !(Item[ usInHand ].fFlags & ITEM_TWO_HANDED) )
+ if ( !(Item[ usInHand ].twohanded ) )
+ {
+ if (pSoldier->inv[SECONDHANDPOS].exists() == false)
+ {
+ // firing with gun in right hand, and second hand empty (ie: no grenade, med kit or anything there)
+ // Madd: easier to fire pistol/smg w/one hand free, essentially this will make pistols a little bit more accurate, and hopefully still useful later in the game
+ if (Weapon[usInHand].ubWeaponClass == HANDGUNCLASS)
+ iChance += AIM_BONUS_TWO_HANDED_PISTOL;
+ }
+ else
+ {
+ // Madd: harder to fire smgs w/something in other hand
+ // SMGs are treated as pistols for these purpose except there is a -5 penalty;
+ if (Weapon[usInHand].ubWeaponClass == SMGCLASS)
+ {
+ iChance -= AIM_PENALTY_SMG;
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if (gGameOptions.fNewTraitSystem)
+ {
+ // Okay, we will shoot from both weapons, calculate penalty to CtH
+ if ( pSoldier->IsValidSecondHandShot() )
+ {
+ // penaly to shoot from dual weapons
+ iChance -= (INT32)(gSkillTraitValues.ubCtHPenaltyDualShot * (HAS_SKILL_TRAIT( pSoldier, AMBIDEXTROUS_NT ) ? ((100 - gSkillTraitValues.ubAMPenaltyDoubleReduction)/100) : 1 ));
+ }
+ }
+ else // original code
+ {
+ if ( !HAS_SKILL_TRAIT( pSoldier, AMBIDEXT_OT ) )
+ {
+ if ( pSoldier->IsValidSecondHandShot( ) )
+ {
+ // penalty to aim when firing two pistols
+ iChance -= AIM_PENALTY_DUAL_PISTOLS;
+ }
+// else
+// {
+// // penalty to aim with pistol being fired one-handed
+// iChance -= AIM_PENALTY_ONE_HANDED_PISTOL;
+// }
+ }
+ }
+ //////////////////////////////////////////////////////////////////
+ }
+ }
+
+ // If in burst mode, deduct points for chance to hit for each shot after the first
+ if ( pSoldier->bDoBurst && pSoldier->bDoAutofire == 0 )
+ {
+// CHRISL: At this point in the calculation, Bipods, Foregrips and other "recoil stabalizing" bonuses should reduce the weapons "recoil penalty"
+// (BurstPenalty) by a percentage. This reduction should apply the the recoil per shot and not as a "flat" initial reduction. Later in the code,
+// Bipods also grant their flat CTH bonus so we don't need to mess this that here
+ if(gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier)
+ {
+ iBonus = GetBurstToHitBonus(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier;
+ iPenalty = Weapon[pInHand->usItem].ubBurstPenalty * (pSoldier->bDoBurst - 1) * (gGameExternalOptions.bAimedBurstEnabled?gGameExternalOptions.uAimedBurstPenalty:1);
+ iPenalty = max(0, (iPenalty * (100 - iBonus))/100 );
+ }
+ else
+ {
+ // Snap: bipod may reduce burst penalty
+ iPenalty = GetBurstPenalty(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * (pSoldier->bDoBurst - 1);
+ if(gGameExternalOptions.bAimedBurstEnabled)
+ iPenalty += Weapon[usInHand].ubBurstPenalty * (pSoldier->bDoBurst - 1) * gGameExternalOptions.uAimedBurstPenalty;
+ }
+
+ // halve the penalty for people with the autofire trait
+ //////////////////////////////////////////////////////////////////
+ if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ {
+ iPenalty = max(0, ((iPenalty * (100 - gSkillTraitValues.ubAWAutoFirePenaltyReduction * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/100));
+ }
+ }
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS_OT ) )
+ {
+ iPenalty /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT );
+ }
+ }
+ //////////////////////////////////////////////////////////////////
+ iChance -= iPenalty;
+ }
+ else if ( pSoldier->bDoAutofire > 0 )
+ {
+// CHRISL: At this point in the calculation, Bipods, Foregrips and other "recoil stabalizing" bonuses should reduce the weapons "recoil penalty"
+// (AutoPenalty) by a percentage. This reduction should apply the the recoil per shot and not as a "flat" initial reduction. Later in the code,
+// Bipods also grant their flat CTH bonus so we don't need to mess this that here
+ if(gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier)
+ {
+ iBonus = GetAutoToHitBonus(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * gGameExternalOptions.ubFlatAFTHBtoPrecentMultiplier;
+ iPenalty = Weapon[pInHand->usItem].AutoPenalty * (pSoldier->bDoBurst - 1) * (gGameExternalOptions.bAimedBurstEnabled?gGameExternalOptions.uAimedBurstPenalty:1);
+ iPenalty = max(0, (iPenalty * (100 - iBonus))/100 );
+ }
+ else
+ {
+ // Snap: bipod may reduce auto penalty
+ iPenalty = GetAutoPenalty(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * (pSoldier->bDoBurst - 1);
+ if(gGameExternalOptions.bAimedBurstEnabled)
+ iPenalty += Weapon[usInHand].AutoPenalty * (pSoldier->bDoBurst - 1) * gGameExternalOptions.uAimedBurstPenalty;
+ }
+
+ // halve the penalty for people with the autofire trait
+ //////////////////////////////////////////////////////////////////
+ if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ {
+ iPenalty = max(0, ((iPenalty * (100 - gSkillTraitValues.ubAWAutoFirePenaltyReduction * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/100));
+ }
+ }
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS_OT ) )
+ {
+ iPenalty /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT );
+ }
+ }
+ //////////////////////////////////////////////////////////////////
+
+ iChance -= iPenalty;
+ // HEADROCK HAM 3.5: Store the penalty
+ sTotalAutofirePenalty = iPenalty;
+ }
+
+ //ADB we need to calculate the distance visible and SoldierTo...LOSTests that we want to
+ //calculate it when firing, so the scope can be accounted for when the weapon is raised
+ //I consider this a hack to change the global, but passing a var alllll the way down to GetVisionBonus was worse
+ //if anyone wants to change it go for it, I don't know what usAnimState should be set
+
+ //store old flag
+ UINT32 oldFlag = gAnimControl[ pSoldier->usAnimState ].uiFlags;
+ //add the necessary bits to the flag
+ gAnimControl[ pSoldier->usAnimState ].uiFlags |= (ANIM_FIREREADY | ANIM_FIRE);
+
+ // 0verhaul: Changed to take expanded range from shooting at different levels into account
+ //ADB this change does nothing - either way it is random - we don't know what level we are shooting to, which is
+ //what the last parameter is, and the soldier's current level is as good a guess as ground level.
+ //so if you really want to fix this, pass in a value
+ sDistVis = pSoldier->GetMaxDistanceVisible(sGridNo, pSoldier->bTargetLevel, CALC_FROM_ALL_DIRS );
+
+ // CJC August 13 2002: Wow, this has been wrong the whole time. bTargetCubeLevel seems to be generally set to 2 -
+ // but if a character is shooting at an enemy in a particular spot, then we should be using the target position on the body.
+
+ // CJC August 13, 2002
+ // If the start soldier has a body part they are aiming at, and know about the person in the tile, then use that height instead
+ iSightRange = -1;
+
+ // give some leeway to allow people to spot for each other...
+ //so make the range to calculate the bullet at 255+
+ ubTargetID = WhoIsThere2( sGridNo, pSoldier->bTargetLevel );
+ // best to use team knowledge as well, in case of spotting for someone else
+ // 0verhaul: Why not use the distance visible as the max for line of sight testing?
+ //ADB because A) the bullet can travel farther than I can see and B) I might have a spotter
+
+ //We are firing a gun, and so the gun will be pointed and the scope will be used, even if it isn't now, so don't forget that we are in a firing animation
+ if (ubTargetID != NOBODY && pSoldier->aiData.bOppList[ubTargetID] == SEEN_CURRENTLY || gbPublicOpplist[pSoldier->bTeam][ubTargetID] == SEEN_CURRENTLY)
+ {
+ iSightRange = SoldierToSoldierLineOfSightTest( pSoldier, MercPtrs[ubTargetID], TRUE, NO_DISTANCE_LIMIT, pSoldier->bAimShotLocation, false );
+ }
+ //CHRISL: This is useful if we're trying to target an opponent we can't actually see
+ iTileRange = SoldierTo3DLocationLineOfSightTest( pSoldier, sGridNo, pSoldier->bTargetLevel, pSoldier->bTargetCubeLevel, TRUE, NO_DISTANCE_LIMIT, false );
+ if (iSightRange == -1) // didn't do a bodypart-based test
+ {
+ iSightRange = iTileRange;
+ }
+ // WANNE: Changed this, because RPGs are not in the calculation, only guns
+ //if ( Item[ usInHand ].usItemClass == IC_GUN )
+ if ( Item[ usInHand ].usItemClass == IC_GUN || Item[ usInHand ].usItemClass == IC_LAUNCHER)
+ {
+ iMaxRange = GunRange( pInHand, pSoldier ); // SANDRO - added argument
+ }
+ else
+ {
+ iMaxRange = CELL_X_SIZE; // one tile
+ }
+
+ if(iSightRange > 0){
+ //Madd: Some gear can affect the to-hit bonus and the bonus from aiming
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: before bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
+ //CHRISL: This is supposed to be a percentage increase/decrease
+ //iSightRange -= GetGearAimBonus ( pSoldier, iRange, ubAimTime );
+ iSightRange -= GetGearAimBonus ( pSoldier, iRange, ubAimTime ) * iSightRange / 100;
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: after gear bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
+
+ //CHRISL: We want our AimBonus to be based on our visual range, not our actual range
+ // Reduce effective range by the aiming bonus (e.g. from sniper scope)
+ //iSightRange -= GetAimBonus( pInHand, iRange, ubAimTime );
+ iSightRange -= GetAimBonus( pInHand, iSightRange, ubAimTime );
+ //CHRISL: If we have the Sniper skill, reduce effective range
+ //////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ) )
+ {
+ iSightRange -= ((gSkillTraitValues.ubSNEffRangeToTargetReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )) * iSightRange) /100;
+ }
+ }
+ else if ( HAS_SKILL_TRAIT( pSoldier, PROF_SNIPER_OT ) )
+ {
+ iSightRange -= ((gbSkillTraitBonus[ PROF_SNIPER_OT ] * NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )) * iSightRange) /100;
+ }
+ //////////////////////////////////////////////////////////////////
+ if (iSightRange < 1)
+ {
+ iSightRange = 1;
+ }
+ }
+
+ //restore old flag
+ gAnimControl[ pSoldier->usAnimState ].uiFlags = oldFlag;
+
+ //CHRISL: Because of the changes I've made to how scopes modify iSightRange, this penalty makes it basically impossible
+ // to shot at targets you can't see yourself. While this isn't an issue for most weapons, it overly restricts the
+ // effectiveness of sniper rifles. So pull this penalty but leave the one that comes later in the code.
+ //if ( iSightRange > (sDistVis * CELL_X_SIZE) )
+ //{
+ // shooting beyond max normal vision... penalize such distance at double (also later we halve the remaining chance)
+ //iSightRange += (iSightRange - sDistVis * CELL_X_SIZE);
+ //}
+
+ //CHRISL: Not being able to actually see the target should not restrict out ability to aim a weapon. Aiming is more then just sighting a specific target. It's
+ // also steadying the weapon and aiming where you think the target is. We will eventually get hit with a serious "Can't See the Target" penalty and aiming is
+ // the only way to even attempt to counter that. This is one reason for "Kevlar Grass"
+ // if shooter spent some extra time aiming and can see the target
+ //if (iSightRange > 0 && ubAimTime && !pSoldier->bDoBurst ) //comm by ddd
+ //if (iSightRange > 0 && ubAimTime )
+ //////////////////////////////////////////////////////////////////
+ if(ubAimTime)
+ {
+ // CHRISL: Rather then a flat +10/click bonus, we're going to try a bonus that's based on MRK and Lvl which gets
+ // progressivly less the more we aim. Everything is based on the maxBonus that a merc can possibly get which
+ // uses the equation: 20+(MRK/20*LVL)+Accuracy+(Sniper trait * 10). This value is then split between the 8
+ // possible AimTime's using a max aimTime bonus of 10.
+ INT16 bonusProgression[8] = {500,500,600,600,750,750,750,1000};
+ //FLOAT maxBonus = 20+((FLOAT)iMarksmanship/20*pSoldier->stats.bExpLevel)+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER )*10);
+
+ //////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ FLOAT maxBonus;
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ // bonus to snipers and gunslingers
+ if ( Weapon[usInHand].ubWeaponType == GUN_PISTOL || Weapon[usInHand].ubWeaponType == GUN_PISTOL )
+ maxBonus = 20+((FLOAT)iMarksmanship/20*(EffectiveExpLevel(pSoldier)))+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, GUNSLINGER_NT )*gSkillTraitValues.ubGSAimingBonusPerClick);
+ else
+ maxBonus = 20+((FLOAT)iMarksmanship/20*(EffectiveExpLevel(pSoldier)))+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )*gSkillTraitValues.ubSNAimingBonusPerClick);
+ }
+ else
+ {
+ if(gGameExternalOptions.bAltAimEnabled)
+ maxBonus = (20*(iMarksmanship/100))+((FLOAT)iMarksmanship/20*pSoldier->stats.bExpLevel)+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )*10);
+ else
+ maxBonus = 20+((FLOAT)iMarksmanship/20*pSoldier->stats.bExpLevel)+(Weapon[Item[pInHand->usItem].ubClassIndex].bAccuracy*2)+(NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER_OT )*10);
+ }
+ //}ddd
+ //////////////////////////////////////////////////////////////////
+ INT8 maxClickBonus = 10;
+ FLOAT aimTimeBonus;
+ for(int i = 0; i < ubAimTime; i++)
+ {
+ aimTimeBonus = __min((maxBonus*bonusProgression[i]/1000),maxClickBonus);
+ maxBonus -= aimTimeBonus;
+ iChance += (INT32)floor(aimTimeBonus+.5);
+ }
+ ///ddd{
+ //zilpin: aimed burst
+ //Reduce the aim time bonus based on weapon burst penalty, after the first shot.
+ //The burst penalty was already applied, but it also reduces the benefit of aiming.
+// CHRISL: This is actaully applying the weapons AutoPenalty a second time. We already apply AutoPenalty/round (after the first) in the autofire
+// section earlier in this code. We shouldn't be applying this again here. Plus, this modification should occur regardless of whether we aim
+// or not. I've moved this condition to the burst/autofire portion of the code above.
+// if(gGameExternalOptions.bAimedBurstEnabled)
+// {
+// //if( pSoldier->bDoAutofire )
+// // iChance -= Weapon[usInHand].AutoPenalty * pSoldier->bDoBurst * gGameExternalOptions.uAimedBurstPenalty;
+// //else if( pSoldier->bDoBurst>1 )
+// // iChance -= Weapon[usInHand].ubBurstPenalty * pSoldier->bDoBurst * gGameExternalOptions.uAimedBurstPenalty;
+// if( pSoldier->bDoAutofire>0 && pSoldier->bDoBurst>1)
+// iChance -= Weapon[usInHand].AutoPenalty * pSoldier->bDoBurst * gGameExternalOptions.uAimedBurstPenalty;
+// //if( pSoldier->bDoAutofire>10 )
+// // iChance -= Weapon[usInHand].AutoPenalty * pSoldier->bDoBurst * gGameExternalOptions.uAimedBurstPenalty;
+// //else
+// if( pSoldier->bDoBurst>1 && pSoldier->bDoAutofire==0)
+// iChance -= Weapon[usInHand].ubBurstPenalty * pSoldier->bDoBurst * gGameExternalOptions.uAimedBurstPenalty;
+//
+// }
+ ///ddd}
+
+// if(highPowerScope == true)
+// {
+// {
+// if ( NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER ) == 2 )
+// aimTimeBonus = -((__max(0,75-pSoldier->stats.bMarksmanship))/(pSoldier->stats.bExpLevel*2));
+// else if( NUM_SKILL_TRAITS( pSoldier, PROF_SNIPER ) == 1 )
+// aimTimeBonus = -((__max(0,85-pSoldier->stats.bMarksmanship))/(pSoldier->stats.bExpLevel*2));
+// else
+// aimTimeBonus = -((__max(0,100-pSoldier->stats.bMarksmanship))/(pSoldier->stats.bExpLevel));
+// aimTimeBonus = __max(-9, aimTimeBonus);
+// aimTimeBonus = __min(0, aimTimeBonus);
+// aimTimeBonus += AIM_BONUS_PER_AP;
+// }
+// else
+// aimTimeBonus = AIM_BONUS_PER_AP;
+// iChance += (aimTimeBonus * ubAimTime); // bonus for every pt of aiming
+ }
+ //////////////////////////////////////////////////////////////////
+
+ if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_PC ) ) // if this is a computer AI controlled enemy
+ {
+ if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
+ {
+ // On easy, penalize all enemies by 5%
+ iChance -= 5;
+ }
+ else
+ {
+ // max with 0 to prevent this being a bonus, for JA2 it's just a penalty to make early enemies easy
+ // CJC note: IDIOT! This should have been a min. It's kind of too late now...
+ // CJC 2002-05-17: changed the max to a min to make this work.
+ iChance += __min( 0, gbDiff[ DIFF_ENEMY_TO_HIT_MOD ][ SoldierDifficultyLevel( pSoldier ) ] );
+ }
+ }
+
+ // if shooter is being affected by gas
+ if ( pSoldier->flags.uiStatusFlags & SOLDIER_GASSED )
+ {
+ iChance -= AIM_PENALTY_GASSED;
+ }
+
+ // if shooter is being bandaged at the same time, his concentration is off
+ if (pSoldier->ubServiceCount > 0)
+ iChance -= AIM_PENALTY_GETTINGAID;
+
+ // if shooter is still in shock
+ if (pSoldier->aiData.bShock)
+ {
+ // HEADROCK HAM B2.8: Placed a maximum here, as shock is now also used in suppression.
+ UINT16 usShockPenalty;
+
+ usShockPenalty = pSoldier->aiData.bShock * AIM_PENALTY_PER_SHOCK;
+
+ if (gGameExternalOptions.usMaxShooterCoweringPenalty > 0)
+ {
+ if ( usShockPenalty > gGameExternalOptions.usMaxShooterCoweringPenalty )
+ usShockPenalty = gGameExternalOptions.usMaxShooterCoweringPenalty;
+ }
+ if ( usShockPenalty < 1 )
+ usShockPenalty = 1;
+
+ iChance -= usShockPenalty;
+ }
+
+ //CHRISL: Just because we can't see a target, doesn't mean these armor/helmet modifiers should be ignored
+ iChance += GetGearToHitBonus ( pSoldier );
+
+ if ( iSightRange > 0 )
+ {
+ //CHRISL: Moved iSightRange modifications to the range section above
+ // SANDRO - DELETED POINTLESS UNUSED PARTS OF CODE
+
+ // HEADROCK HAM B2.1 : The TARGET's shock now also affects aiming. If the target is prone
+ // and in shock, they are harder to hit! This represents a target that's cowering as close
+ // to the ground (and as close to any possible cover, like a small dune or a fold of earth
+ // or anything like that).
+ if ( gGameExternalOptions.ubAimPenaltyPerTargetShock > 0 )
+ {
+ // HEADROCK HAM B2.1 : This value determines how much penalty the target's shock-value gives the shooter.
+ // As of HAM B2.3: There's a maximum range at which 100% penalty is given.
+ // As of HAM B2.8: Target's stance and the targetted bodypart will affect the end result.
+
+ INT8 AIM_PENALTY_PER_TARGET_SHOCK;
+ INT16 sCoweringPenalty = 0;
+ UINT8 ubCoweringDivisor;
+ UINT16 MIN_RANGE_FOR_FULL_COWER;
+ UINT16 MAX_TARGET_COWERING_PENALTY;
+
+ AIM_PENALTY_PER_TARGET_SHOCK = gGameExternalOptions.ubAimPenaltyPerTargetShock;
+ MIN_RANGE_FOR_FULL_COWER = gGameExternalOptions.usMinRangeForFullCoweringPenalty;
+ MAX_TARGET_COWERING_PENALTY = gGameExternalOptions.usMaxTargetCoweringPenalty;
+
+ pTarget = SimpleFindSoldier( sGridNo, pSoldier->bTargetLevel );
+ if (pTarget != NULL)
+ {
+ if (pTarget->aiData.bShock )
+ {
+ if (gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_PRONE)
+ {
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorProne;
+
+ sCoweringPenalty = (pTarget->aiData.bShock * AIM_PENALTY_PER_TARGET_SHOCK);
+ sCoweringPenalty = sCoweringPenalty / ubCoweringDivisor;
+ sCoweringPenalty = (sCoweringPenalty * __min(iSightRange,MIN_RANGE_FOR_FULL_COWER)) / MIN_RANGE_FOR_FULL_COWER;
+
+ if (gGameExternalOptions.usMaxTargetCoweringPenalty > 0)
+ {
+ if ( sCoweringPenalty > gGameExternalOptions.usMaxTargetCoweringPenalty )
+ sCoweringPenalty = gGameExternalOptions.usMaxTargetCoweringPenalty;
+ }
+ if ( sCoweringPenalty < 1 )
+ sCoweringPenalty = 1;
+
+ iChance -= sCoweringPenalty;
+ }
+ else if (gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_CROUCH)
+ {
+ switch ( ubAimPos )
+ {
+ case AIM_SHOT_HEAD:
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedHead;
+ break;
+ case AIM_SHOT_TORSO:
+ case AIM_SHOT_RANDOM:
+ case AIM_SHOT_GLAND:
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedTorso;
+ break;
+ case AIM_SHOT_LEGS:
+ ubCoweringDivisor = gGameExternalOptions.ubCoweringPenaltyDivisorCrouchedLegs;
+ break;
+ }
+
+ sCoweringPenalty = (pTarget->aiData.bShock * AIM_PENALTY_PER_TARGET_SHOCK);
+ sCoweringPenalty = sCoweringPenalty / ubCoweringDivisor;
+ sCoweringPenalty = (sCoweringPenalty * __min(iSightRange,MIN_RANGE_FOR_FULL_COWER)) / MIN_RANGE_FOR_FULL_COWER;
+
+ if (gGameExternalOptions.usMaxTargetCoweringPenalty > 0)
+ {
+ if ( sCoweringPenalty > gGameExternalOptions.usMaxTargetCoweringPenalty )
+ sCoweringPenalty = gGameExternalOptions.usMaxTargetCoweringPenalty;
+ }
+ if ( sCoweringPenalty < 1 )
+ sCoweringPenalty = 1;
+
+ // HEADROCK HAM B2.8.1: Added formula to make sure that cowering target penalties
+ // are not given when on the roof.
+
+ if (pSoldier->pathing.bLevel == pTarget->pathing.bLevel && pSoldier->pathing.bLevel > 0)
+ sCoweringPenalty = 0; // No cowering penalties when both are on the roof!
+ else if (pSoldier->pathing.bLevel < pSoldier->pathing.bLevel && gAnimControl[ pTarget->usAnimState ].ubHeight == ANIM_PRONE)
+ sCoweringPenalty *= 2; // Much harder to shoot at anyone cowering above you.
+ else if (pSoldier->pathing.bLevel > pSoldier->pathing.bLevel)
+ sCoweringPenalty /= 2; // Much easier to shoot at cowerers below you.
+ iChance -= sCoweringPenalty;
+ }
+ }
+ }
+ }
+ }
+
+ //CHRISL: This should effect us regardless of whether we can see the target or not
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: after scope bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
+ // Apply flat to-hit bonus (e.g. from laser scope)
+ // Snap: If prone and range is good, apply bipod bonus here as well
+ iChance += GetToHitBonus( pInHand, iRange, bLightLevel,gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && iRange > MIN_PRONE_RANGE );
+ DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: after to hit bonus - ubAimTime = %d, iSightRange = %d, iChance = %d ", ubAimTime, iSightRange, iChance));
+
+ //NumMessage("EFFECTIVE RANGE = ",range);
+
+ // ADJUST FOR RANGE
+ // bonus if range is less than normal range, penalty if it's more
+ //iChance += (NORMAL_RANGE - iRange) / (CELL_X_SIZE / 5); // 5% per tile
+
+ // Effects of actual gun max range... the numbers are based on wanting -40%
+ // at range 26for a pistol with range 13, and -0 for a sniper rifle with range 80
+ iPenalty = ((iMaxRange - iRange * 3) * 10) / (17 * CELL_X_SIZE);
+ if ( iPenalty < 0 )
+ {
+ // No penalty on tanks
+ //if (!TANK(pSoldier))
+ iChance += iPenalty;
+ }
+ //iChance -= 20 * iRange / iMaxRange;
+
+ if ( TANK( pSoldier ) && ( iRange / CELL_X_SIZE < MaxNormalDistanceVisible() ) )
+ {
+ // tank; penalize at close range!
+ // 2 percent per tile closer than max visible distance
+ iChance -= 2 * ( MaxNormalDistanceVisible() - (iRange / CELL_X_SIZE) );
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Target Size Penalties
+ //if (iSightRange == 0)
+ //{
+ // firing blind!
+ //iChance -= AIM_PENALTY_BLIND;
+ //}
+ if ( pSoldier->aiData.bOppList[ubTargetID] != SEEN_CURRENTLY &&(pSoldier->flags.uiStatusFlags & SOLDIER_PC) )
+ iChance -=gGameExternalOptions.iPenaltyShootUnSeen;
+ else
+ {
+ // Effects based on aiming & sight
+ // From for JA2.5: 3% bonus/penalty for each tile different from range NORMAL_RANGE.
+ // This doesn't provide a bigger bonus at close range, but stretches it out, making medium
+ // range less penalized, and longer range more penalized
+
+ // WANNE: No penalty on the tank
+ if (!TANK(pSoldier))
+ iChance += 3 * ( NORMAL_RANGE - iSightRange ) / CELL_X_SIZE;
+ // if aiming at the head, reduce chance to hit
+ if (ubAimPos == AIM_SHOT_HEAD)
+ {
+ // penalty of 3% per tile
+ //iPenalty = 3 * iSightRange / 10; //comm by ddd
+ iPenalty = INT32(gGameExternalOptions.uShotHeadPenalty * iSightRange / 10);
+ iChance -= iPenalty;
+ }
+ else if (ubAimPos == AIM_SHOT_LEGS)
+ {
+ // penalty of 1% per tile
+ iPenalty = iSightRange / 10;
+ iChance -= iPenalty;
+ }
+
+// if (iSightRange < NORMAL_RANGE)
+// {
+// // bonus to hit of 20% at point blank (would be 25% at range 0);
+// //at NORMAL_RANGE, bonus is 0
+// iChance += 25 * (NORMAL_RANGE - iSightRange) / NORMAL_RANGE;
+// }
+// else
+// {
+// // penalty of 2% / tile
+// iChance -= (iSightRange - NORMAL_RANGE) / 5;
+// }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+ /////////////////////////////////////////////////////////////////////////////////////////
+ // Tracer effects
+ // HEADROCK HAM 3.5: Moved this here for now.
+ // HEADROCK HAM B2.5: One of every X bullets in a tracer magazine is a tracer round, which will
+ // bump the CTH up by a certain amount.
+
+ if (AmmoTypes[(*pInHand)[0]->data.gun.ubGunAmmoType].tracerEffect == 1 && gGameExternalOptions.ubRealisticTracers > 0 )
+ {
+ UINT16 iBulletsLeft, iTracersFired, iBulletsPerTracer, iBulletsSinceLastTracer=0, iRoundsFiredPreviously;
+ UINT8 cnt;
+ UINT8 ubAutoPenaltySinceLastTracer=0;
+ //UINT16 iAutoPenaltySinceLastTracer;
+ iTracersFired = 0;
+ iBulletsPerTracer = gGameExternalOptions.ubNumBulletsPerTracer;
+
+ // Calculate number of bullets left right before firing this burst
+ if (fCalculateCTHDuringGunfire)
+ {
+ iBulletsLeft = (*pInHand)[0]->data.gun.ubGunShotsLeft + (pSoldier->bDoBurst - 1);
+ }
+ else
+ {
+ iBulletsLeft = (*pInHand)[0]->data.gun.ubGunShotsLeft;
+ }
+
+// CHRISL: What we want to know here is how many tracers have been fired during this autofire sequence. But we also want to figure that based on how
+// much ammo we've used from the current load. If every 3rd round is a tracer, and we previously fired 5 rounds from our "mag", then the first
+// round of this burst is a tracer, the 2nd & 3rd are normal, the 4th is a tracer, 5th & 6th are normal, etc.
+ iRoundsFiredPreviously = GetMagSize(pInHand) - iBulletsLeft; //How many rounds had been fired before this autofire sequence
+ for( cnt = 1; cnt <= pSoldier->bDoBurst; cnt++ ){
+ if((iRoundsFiredPreviously+cnt)%iBulletsPerTracer == 0)
+ iTracersFired++;
+ }
+
+// iBulletsSinceLastTracer = 0;
+// for (cnt=0;cntbDoBurst;cnt++)
+// {
+// iBulletsSinceLastTracer++;
+// if ((( iBulletsLeft - (cnt - 1) ) / iBulletsPerTracer) - ((iBulletsLeft - cnt) / iBulletsPerTracer) == 1)
+// {
+// iBulletsSinceLastTracer = 0;
+// }
+// }
+//
+// iTracersFired = ((iBulletsLeft+1) / iBulletsPerTracer) - (((iBulletsLeft+1) - (pSoldier->bDoBurst)) / iBulletsPerTracer);
+
+ if ( iTracersFired > 0 )
+ {
+ // HEADROCK HAM 3.5: I'm going to revise this - my current system makes no sense at all. What was I
+ // thinking?!
+// CHRISL: Headrock may come around later and revise this again, but for the time being, I'm making some adjustments. With the current code
+// the number of tracer rounds fired doesn't really matter. In most cases, the range is going to limit the max bonus so much that 1 tracer or
+// 20 will have the same effect because we currently look at the "bump" value times the number of rouns and THEN modify for range. What we
+// should be doing is modify the bump for range, multiply that by the number of tracer rounds fired, then make sure the bonus isn't more then
+// our combined autofire penalty.
+
+ // Correct all autofire penalty so far
+ //iBonus = iPenalty;
+
+ // Add Tracer Bump if previous bullet was a tracer
+ //iBonus += (gGameExternalOptions.ubCTHBumpPerTracer * iTracersFired);
+ //iBonus = (gGameExternalOptions.ubCTHBumpPerTracer * iTracersFired);
+
+ // Calculate penalty since last tracer was fired
+ // CHRISL: We already look at GetAutoPenalty earlier in the code, and that result was stored as sTotalAutofirePenalty so why this wonky recalculation?
+ //UINT8 ubAutoPenaltySinceLastTracer = GetAutoPenalty(pInHand, gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) * iBulletsSinceLastTracer;
+ //////////////////////////////////////////////////////////////////
+// if ( gGameOptions.fNewTraitSystem ) // old/new traits - SANDRO
+// {
+// if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+// {
+// ubAutoPenaltySinceLastTracer = max(0, ((ubAutoPenaltySinceLastTracer * (100 - gSkillTraitValues.ubAWAutoFirePenaltyReduction * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/100));
+// }
+// }
+// else
+// {
+// if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS_OT ) )
+// {
+// ubAutoPenaltySinceLastTracer /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT );
+// }
+// }
+// //////////////////////////////////////////////////////////////////
+// // Add penalty to bonus.
+// //iBonus -= iAutoPenaltySinceLastTracer;
+
+ ///////////////////////////////////////////////////
+ // HEADROCK HAM 3.5: Limit maximum bonus by range.
+// CHRISL: We want to limit the maximum bonus "per round" by range. The way we have been doing it, it's max bonus by range, regardless of the
+// number of rounds fired. This means firing 1 tracer or 20 makes no difference. And we can run this calculation directly again
+// sTotalAutofirePenalty.
+
+ if(sTotalAutofirePenalty > 0){
+ INT16 sChanceLimit = min(gGameExternalOptions.ubCTHBumpPerTracer, ((iRange-(gGameExternalOptions.ubMinRangeTracerEffect*CELL_X_SIZE)) / CELL_X_SIZE) * gGameExternalOptions.ubRangeDifficultyAimingWithTracers);
+ sChanceLimit = max(0, sChanceLimit);
+ iBonus = sChanceLimit * iTracersFired;
+ iBonus = min(iBonus, sTotalAutofirePenalty);
+ }
+
+ //INT16 sChanceLimit = __min(0, sTotalAutofirePenalty+(((iRange-100) / CELL_X_SIZE) * gGameExternalOptions.ubRangeDifficultyAimingWithTracers));
+
+ //INT16 sBaseChance = iChance + sTotalAutofirePenalty;
+
+ // We don't want to enforce a limit unless the tracers have actually put us over the original CtH.
+// if (sBaseChance <= iChance+iBonus) // Base_Chance without AutoPen, less or equal to Current_Chance plus tracer bumps
+// {
+// // store lowest: Chance+Tracer bumps, or Range-enforced limit
+// INT16 sChanceLimit = __min(iChance+iBonus, sBaseChance+(((iRange-100) / CELL_X_SIZE) * gGameExternalOptions.ubRangeDifficultyAimingWithTracers));
+// // store highest: Chance Delta or base CtH
+// //sChanceDelta = __max(sChanceDelta, sBaseChance);
+//
+// // iBonus is the distance between the enforced limit (if any) and the current chance with all penalties so far.
+// // But it can't be negative, 'cause it's a bonus.
+// iBonus = __max(0,sChanceLimit - iChance);
+// // Add autopenalty since last tracer
+// if (iBulletsSinceLastTracer < iBulletsPerTracer)
+// {
+// iBonus -= ubAutoPenaltySinceLastTracer;
+// }
+//
+// }
+ iChance += iBonus;
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////
+
+ // adjust for roof/not on roof
+ if ( pSoldier->pathing.bLevel == 0 )
+ {
+ if ( pSoldier->bTargetLevel > 0 )
+ {
+ // penalty for firing up
+ iChance -= AIM_PENALTY_FIRING_UP;
+ }
+ }
+ else // pSoldier->pathing.bLevel > 0 )
+ {
+ if ( pSoldier->bTargetLevel == 0 )
+ {
+ iChance += AIM_BONUS_FIRING_DOWN;
+ }
+ }
+
+
+ pTarget = SimpleFindSoldier( sGridNo, pSoldier->bTargetLevel );
+ //CHRISL: A target's stance should have no impact on an aimed, headshot. The head doesn't get any smaller just because the target is crouching down.
+ if (pTarget != NULL && ubAimPos != AIM_SHOT_HEAD)
+ {
+ // targeting a merc
+ // adjust for crouched/prone target
+ switch( gAnimControl[ pTarget->usAnimState ].ubHeight )
+ {
+ case ANIM_CROUCH:
+ if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
+ {
+ // 13% penalty per tile closer than min range
+ iChance -= 13 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
+ }
+ else
+ {
+ // at anything other than point-blank range
+ if (iRange > POINT_BLANK_RANGE + 10 * (AIM_PENALTY_TARGET_CROUCHED / 3) )
+ {
+ iChance -= AIM_PENALTY_TARGET_CROUCHED;
+ }
+ else if (iRange > POINT_BLANK_RANGE)
+ {
+ // at close range give same bonus as prone, up to maximum of AIM_PENALTY_TARGET_CROUCHED
+ iChance -= 3 * ((iRange - POINT_BLANK_RANGE) / CELL_X_SIZE); // penalty -3%/tile
+ }
+ }
+ break;
+ case ANIM_PRONE:
+ if ( TANK( pSoldier ) && iRange < MIN_TANK_RANGE )
+ {
+ // 25% penalty per tile closer than min range
+ iChance -= 25 * ( ( MIN_TANK_RANGE - iRange ) / CELL_X_SIZE );
+ }
+ else
+ {
+ // at anything other than point-blank range
+ if (iRange > POINT_BLANK_RANGE)
+ {
+ // reduce chance to hit with distance to the prone/immersed target
+ iPenalty = 3 * ((iRange - POINT_BLANK_RANGE) / CELL_X_SIZE); // penalty -3%/tile
+ iPenalty = __min( iPenalty, AIM_PENALTY_TARGET_PRONE );
+
+ iChance -= iPenalty;
+ }
+ }
+ break;
+ case ANIM_STAND:
+ // if we are prone and at close range, then penalize shots to the torso or head!
+ if ( iRange <= MIN_PRONE_RANGE && gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE )
+ {
+ if ( ubAimPos == AIM_SHOT_RANDOM || ubAimPos == AIM_SHOT_GLAND )
+ {
+ ubAdjAimPos = AIM_SHOT_TORSO;
+ }
+ else
+ {
+ ubAdjAimPos = ubAimPos;
+ }
+ // lose 10% per height difference, lessened by distance
+ // e.g. 30% to aim at head at range 1, only 10% at range 3
+ // or 20% to aim at torso at range 1, no penalty at range 3
+ // NB torso aim position is 2, so (5-aimpos) is 3, for legs it's 2, for head 4
+ iChance -= (5 - ubAdjAimPos - iRange / CELL_X_SIZE) * 10;
+ }
+ break;
+ default:
+ break;
+ }
+
+ // penalty for amount that enemy has moved
+ // HEADROCK HAM B2.6: Externalized the value
+ iPenalty = __min( (UINT16)((float)pTarget->bTilesMoved * (float)gGameExternalOptions.iMovementEffectOnAiming), 30 );
+ ///////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - fearless characters do not even take their head down no matter what
+ if ( gGameOptions.fNewTraitSystem && pTarget->ubProfile != NO_PROFILE )
+ {
+ if ( gMercProfiles[ pTarget->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
+ iPenalty -= (iPenalty * 2 / 3); // two thirds only
+ }
+ ///////////////////////////////////////////////////////////////////////////////////
iChance -= iPenalty;
// if target sees us, he may have a chance to dodge before the gun goes off
@@ -4442,7 +7979,8 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// This won't cause the bullet to be off to the left or right, only make it
// drop in flight.
- iChance /= 2;
+ //iChance /= 2; //ddd
+ iChance /= gGameExternalOptions.fOutOfGunRangeOrSight;
}
if ( iSightRange > (sDistVis * CELL_X_SIZE) )
{
@@ -4450,6 +7988,51 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iChance /= 2;
}
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Bonus CtH for Militia
+ if (pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.sGreenMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sGreenMilitiaCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.sRegularMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sRegularMilitiaCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
+ // bonus for enemy
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyEliteCtHBonusPercent) /100);
+ //////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - option to make special NPCs stronger - chance to hit
+ if (gGameExternalOptions.usSpecialNPCStronger > 0)
+ {
+ switch( pSoldier->ubProfile )
+ {
+ case CARMEN:
+ case QUEEN:
+ case JOE:
+ case ANNIE:
+ case CHRIS:
+ case KINGPIN:
+ case TIFFANY:
+ case T_REX:
+ case DRUGGIST:
+ case GENERAL:
+ case JACK:
+ case OLAF:
+ case RAY:
+ case OLGA:
+ case TYRONE:
+ case MIKE:
+ iChance += (iChance * gGameExternalOptions.usSpecialNPCStronger / 100);
+ break;
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////
+
// MAKE SURE CHANCE TO HIT IS WITHIN DEFINED LIMITS
// HEADROCK: (HAM) Altered so called "Defined Limits" to accept external arguments.
// The divisor argument only works when the minimum is set to 0. It has a chance of 1 in X to
@@ -4486,7 +8069,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
// NumMessage("ChanceToHit = ",chance);
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CalcChanceToHitGun: ichance = %d",iChance));
- return (iChance);
+ return (iChance);*/
}
UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos )
@@ -4499,6 +8082,49 @@ UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTim
pSoldier->usAnimState = STANDING;
uiChance = CalcChanceToHitGun( pSoldier, sGridNo, ubAimTime, ubAimPos );
pSoldier->usAnimState = usTrueState;
+ if(UsingNewCTHSystem() == true)
+ {
+ ////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: NCTH calculation
+ //
+ // In the new CTH system, the value returned by CalcChanceToHitGun is not an actual
+ // chance to hit the target. In fact, it is simply a measure of how well the gun is
+ // aimed. To get a good idea of whether or not a shot is likely to hit the target,
+ // we need to take other factors into consideration.
+
+ FLOAT d2DDistance = (FLOAT) PythSpacesAway( pSoldier->sGridNo, sGridNo ) * 10.0f;
+ FLOAT dMagFactor = CalcMagFactor( pSoldier, &(pSoldier->inv[pSoldier->ubAttackingHand]), d2DDistance, (UINT8)ubAimTime );
+ FLOAT dDistanceFactor = (d2DDistance / gGameCTHConstants.NORMAL_SHOOTING_DISTANCE);
+
+ uiChance = (UINT32)((uiChance * dMagFactor) / dDistanceFactor);
+
+ FLOAT dBasicAperture = CalcBasicAperture( );
+ FLOAT dAperture = (dBasicAperture * (100-uiChance)) / 100.0f;
+
+ if (dAperture == 0)
+ {
+ return 100;
+ }
+ else
+ {
+ FLOAT dTargetArea = 28.26f; // Calculated area of a target given known homan body size.
+ FLOAT dApertureArea = (FLOAT)(PI * (dAperture * dAperture));
+
+ uiChance = (UINT32)__min(100, (dTargetArea / dApertureArea) * 100);
+ }
+
+ FLOAT dGunRange = (FLOAT)(GunRange( &(pSoldier->inv[pSoldier->ubAttackingHand]), pSoldier ) );
+ if ( (dGunRange * 1.1f) < d2DDistance)
+ {
+ // Weapon out of conceivable hit range. Reduce chance to hit to 0!
+ return (0);
+ }
+ else if ( dGunRange < d2DDistance)
+ {
+ // Just outside range. Reduce considerably!
+ return (uiChance / 2);
+ }
+ }
return( uiChance );
}
@@ -4662,7 +8288,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 u
if (pArmour->exists() == true)
{
for (attachmentList::iterator iter = (*pArmour)[0]->attachments.begin(); iter != (*pArmour)[0]->attachments.end(); ++iter) {
- if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
+ if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists())
{
// bullet got through jacket; apply ceramic plate armour
iTotalProtection += ArmourProtection( pTarget, Item[iter->usItem].ubClassIndex, &((*iter)[0]->data.objectStatus), iImpact, ubAmmoType, &plateHit );
@@ -4692,7 +8318,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 u
{
//Madd: put any attachments that someone might have added to the armour in the merc's inventory
for (attachmentList::iterator iter = (*pArmour)[0]->attachments.begin(); iter != (*pArmour)[0]->attachments.end(); ++iter) {
- if ( !AutoPlaceObject( pTarget, &(*iter), FALSE ) )
+ if ( !AutoPlaceObject( pTarget, &(*iter), FALSE ) && iter->exists())
{ // put it on the ground
AddItemToPool( pTarget->sGridNo, &(*iter), 1, pTarget->pathing.bLevel, 0 , -1 );
}
@@ -4710,7 +8336,7 @@ INT32 TotalArmourProtection( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 u
INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocation, INT32 iOrigImpact, INT16 sHitBy, UINT8 * pubSpecial )
{
INT32 iImpact, iFluke, iBonus, iImpactForCrits = 0;
- INT8 bStatLoss;
+ INT8 bStatLoss = 0;
UINT8 ubAmmoType;
// NOTE: reduction of bullet impact due to range and obstacles is handled
@@ -4821,6 +8447,81 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocat
// iImpact = AMMO_DAMAGE_ADJUSTMENT_HP( iImpact );
//}
+ ////////////////////////////////////////////////////////////////////////////////////
+ if ( gGameOptions.fNewTraitSystem ) // new traits bonuses - SANDRO
+ {
+ // Throwing skill increases damage of knives here
+ if ( (ubAmmoType == AMMO_KNIFE) && HAS_SKILL_TRAIT( pFirer, THROWING_NT ))
+ {
+ iImpact += (INT32)(iImpact * (gSkillTraitValues.ubTHBladesDamageBonus + (gSkillTraitValues.ubTHBladesDamageBonusPerClick * pFirer->aiData.bAimTime))/100);
+ }
+
+ // Sniper trait adds bonus damage per aim click
+ if (HAS_SKILL_TRAIT( pFirer, SNIPER_NT ) && (pFirer->aiData.bAimTime >= gSkillTraitValues.ubSNDamageBonusFromNumClicks))
+ {
+ iImpact += (INT32)(iImpact * (pFirer->aiData.bAimTime - gSkillTraitValues.ubSNDamageBonusFromNumClicks + 1) * gSkillTraitValues.ubSNDamageBonusPerClick * NUM_SKILL_TRAITS( pFirer, SNIPER_NT ))/100; // +5% per trait
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Damage resistance for Militia
+ if (!IsAutoResolveActive())
+ {
+ if (pTarget->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
+ // bonus for enemy too
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
+
+
+ iImpact = max( 1, iImpact);
+ }
+ //////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - option to make special NPCs stronger - damage resistance
+ if (gGameExternalOptions.usSpecialNPCStronger > 0)
+ {
+ switch( pTarget->ubProfile )
+ {
+ case CARMEN:
+ case QUEEN:
+ case JOE:
+ case ANNIE:
+ case CHRIS:
+ case KINGPIN:
+ case TIFFANY:
+ case T_REX:
+ case DRUGGIST:
+ case GENERAL:
+ case JACK:
+ case OLAF:
+ case RAY:
+ case OLGA:
+ case TYRONE:
+ case MIKE:
+ // Only 1/2 of the bonus
+ iImpact -= (INT32)(iImpact * gGameExternalOptions.usSpecialNPCStronger / 200);
+ iImpact = max( 1, iImpact);
+ break;
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // STOMP traits - Bodybuilding damage resistance
+ if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pTarget, BODYBUILDING_NT ) )
+ iImpact = max( 1, (INT32)(iImpact * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
+ ////////////////////////////////////////////////////////////////////////////////////
+
AdjustImpactByHitLocation( iImpact, ubHitLocation, &iImpact, &iImpactForCrits );
switch( ubHitLocation )
@@ -4835,7 +8536,11 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocat
{
// blow to the head is so deadly that it causes instant death;
// the target has more life than iImpact so we increase it
- iImpact = pTarget->stats.bLife + Random( 10 );
+ if( iImpact < pTarget->stats.bLife ) // Added check here to see the real impact in game if bigger than life - SANDRO
+ iImpact = pTarget->stats.bLife + Random( 10 );
+ else
+ iImpact += Random( 10 );
+
iImpactForCrits = iImpact;
}
@@ -4884,13 +8589,21 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocat
{
// blow to the chest is so deadly that it causes instant death;
// the target has more life than iImpact so we increase it
- iImpact = pTarget->stats.bLife + Random( 10 );
+ if( iImpact < pTarget->stats.bLife ) // Added check here to see the real impact in game if bigger than life - SANDRO
+ iImpact = pTarget->stats.bLife + Random( 10 );
+ else
+ iImpact += Random( 10 );
+
iImpactForCrits = iImpact;
}
// special thing for hitting chest - allow cumulative damage to count
else if ( (iImpact + pTarget->sDamage) > (MIN_DAMAGE_FOR_BLOWN_AWAY + MIN_DAMAGE_FOR_INSTANT_KILL) )
{
- iImpact = pTarget->stats.bLife + Random( 10 );
+ if( iImpact < pTarget->stats.bLife ) // Added check here to see the real impact in game if bigger than life - SANDRO
+ iImpact = pTarget->stats.bLife + Random( 10 );
+ else
+ iImpact += Random( 10 );
+
iImpactForCrits = iImpact;
}
@@ -4919,168 +8632,295 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocat
if ( AmmoTypes[ubAmmoType].knife && pFirer->aiData.bOppList[ pTarget->ubID ] == SEEN_CURRENTLY )
{
// is this a stealth attack?
- if ( pTarget->aiData.bOppList[ pFirer->ubID ] == NOT_HEARD_OR_SEEN && !CREATURE_OR_BLOODCAT( pTarget ) && (ubHitLocation == AIM_SHOT_HEAD || ubHitLocation == AIM_SHOT_TORSO ) )
+ if ( pTarget->aiData.bOppList[ pFirer->ubID ] == NOT_HEARD_OR_SEEN && !CREATURE_OR_BLOODCAT( pTarget )
+ && (ubHitLocation == AIM_SHOT_HEAD || ubHitLocation == AIM_SHOT_TORSO ) && (pTarget->aiData.bAlertStatus < STATUS_RED || !gGameExternalOptions.fEnhancedCloseCombatSystem) ) // Added check if enemy is alerted - SANDRO
{
- if ( PreRandom( 100 ) < (UINT32)(sHitBy + 10 * NUM_SKILL_TRAITS( pFirer, THROWING )) )
+ // HEADROCK HAM 4: With the original CTH system, the HitBy value represented a randomal margin by
+ // which the shooter surpassed his CTH value. Therefore, only a high CTH shot which randomly succeeded
+ // by a wide margin could reach values of 80 and above, and even then they were rare.
+ // In the new system, HitBy represents a shooter's effort to make his shot more accurate, so shots
+ // done with large amounts of aiming and skill would always result in high HitBy values (up to ~70-80%
+ // regularly for the average shooting using maximum aiming). This means that high HitBy values are now
+ // somewhat more common.
+ // With regards to this bit of code, an increase in average HitBy means that its effect on the formula
+ // should be lessened a little to maintain the same ratio of instant-deaths as in JA2. However, I am
+ // reluctant to make any changes, mainly because I think there's no problem with stealth knife hits
+ // being deadlier. If, however, it is discovered that stealth insta-kills are too common and too powerful,
+ // reduce the effect of this sHitBy, possibly by dividing it here.
+
+ //////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if( !gGameOptions.fNewTraitSystem )
{
- // instant death!
- iImpact = pTarget->stats.bLife + Random( 10 );
- iImpactForCrits = iImpact;
+ if ( PreRandom( 100 ) < (UINT32)(sHitBy + 10 * NUM_SKILL_TRAITS( pFirer, THROWING_OT )) )
+ {
+ // instant death!
+ if( iImpact < pTarget->stats.bLife ) // Added check here to see the real impact in game if bigger than life - SANDRO
+ iImpact = pTarget->stats.bLife + Random( 10 );
+ else
+ iImpact += Random( 10 );
+
+ iImpactForCrits = iImpact;
+ }
}
+ else
+ {
+ // Throwing trait increases chance to silent critical hit
+ if ( PreRandom( 100 ) < (UINT32)(sHitBy + (HAS_SKILL_TRAIT( pFirer, THROWING_NT ) ? gSkillTraitValues.ubTHBladesSilentCriticalHitChance : 0)) )
+ {
+ // No no no, we don't want instant kill in this case,
+ // but rather tripled damage, so it also always matters what knife we use - SANDRO
+ iImpact *= ( 3 + gSkillTraitValues.ubTHBladesCriticalHitMultiplierBonus);
+
+ iImpactForCrits = iImpact;
+ }
+ }
+ //////////////////////////////////////////////////////////////////////////////////
}
}
- if (iImpactForCrits > 0 && iImpactForCrits < pTarget->stats.bLife )
+ if (iImpactForCrits > 0 && iImpactForCrits < pTarget->stats.bLife && !(pTarget->flags.uiStatusFlags & SOLDIER_MONSTER) ) // not to monsters - SANDRO
{
- if (PreRandom( iImpactForCrits / 2 + pFirer->aiData.bAimTime * 5) + 1 > CRITICAL_HIT_THRESHOLD)
+ UINT32 uiCritChance = (iImpactForCrits / 2) + (pFirer->aiData.bAimTime * 5);
+ BOOLEAN fMaliciousHit = FALSE;
+ // SANDRO - Malicious characters inflict stat loss more often
+ if ( gGameOptions.fNewTraitSystem && pFirer->ubProfile != NO_PROFILE )
+ {
+ if ( gMercProfiles[ pFirer->ubProfile ].bCharacterTrait == CHAR_TRAIT_MALICIOUS )
+ {
+ uiCritChance += 8;
+ fMaliciousHit = TRUE;
+ }
+ }
+ // SANDRO - with new traits, the chance for stat loss is higher as we are now able to repair it
+ if ((PreRandom( uiCritChance ) + 1) > (UINT8)(gGameOptions.fNewTraitSystem ? gSkillTraitValues.ubDamageNeededToLoseStats : CRITICAL_HIT_THRESHOLD))
{
bStatLoss = (INT8) PreRandom( iImpactForCrits / 2 ) + 1;
- switch( ubHitLocation )
+ // SANDRO - malicious hit
+ if ( fMaliciousHit && Chance( max( 15, uiCritChance )) && ( ubHitLocation == AIM_SHOT_TORSO || ubHitLocation == AIM_SHOT_LEGS ) &&
+ ( sHitBy >= 20 ) && ( pTarget->ubBodyType <= STOCKYMALE ) && ( gAnimControl[ pTarget->usAnimState ].ubHeight != ANIM_PRONE ) )
{
- case AIM_SHOT_HEAD:
- if (bStatLoss >= pTarget->stats.bWisdom)
- {
- bStatLoss = pTarget->stats.bWisdom - 1;
- }
- if ( bStatLoss > 0 )
- {
- pTarget->stats.bWisdom -= bStatLoss;
+ // no stats to lose, but drain breath a lot
+ DeductPoints( pTarget, 0, (5 * APBPConstants[BP_GET_HIT]) );
+ SoldierCollapse( pTarget );
- if (pTarget->ubProfile != NO_PROFILE)
+ if (pTarget->name[0] && pTarget->bVisible == TRUE)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_SOLDIER_HIT_TO_GROIN], pTarget->name );
+ }
+ // Gain morale for inflicting critical hit
+ HandleMoraleEvent( pFirer, MORALE_MALICIOUS_HIT, pFirer->sSectorX, pFirer->sSectorY, pFirer->bSectorZ );
+
+ }
+ else
+ {
+ switch( ubHitLocation )
+ {
+ case AIM_SHOT_HEAD:
+ if (bStatLoss >= pTarget->stats.bWisdom)
{
- gMercProfiles[ pTarget->ubProfile ].bWisdom = pTarget->stats.bWisdom;
- }
-
-
- if (pTarget->name[0] && pTarget->bVisible == TRUE)
- {
- // make stat RED for a while...
- pTarget->timeChanges.uiChangeWisdomTime = GetJA2Clock();
- pTarget->usValueGoneUp &= ~( WIS_INCREASE );
-
- if (bStatLoss == 1)
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_WISDOM], pTarget->name );
- }
- else
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_WISDOM], pTarget->name, bStatLoss );
- }
- }
- }
- else if ( pTarget->bNumPelletsHitBy == 0 )
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_HEAD_HIT], pTarget->name );
- }
-
- // HEADROCK HAM 3.2: Critical headshots may now cause blindness, based on shot damage.
- if (gGameExternalOptions.ubChanceBlindedByHeadshot)
- {
- if (__min(100,(PreRandom(100)+1 + iImpact)) <= gGameExternalOptions.ubChanceBlindedByHeadshot)
- {
- if (pTarget->bBlindedCounter < iImpact / 10 )
- pTarget->bBlindedCounter = iImpact / 10;
- }
- }
-
- break;
- case AIM_SHOT_TORSO:
- if (PreRandom( 1 ) == 0 && !(pTarget->flags.uiStatusFlags & SOLDIER_MONSTER) )
- {
- if (bStatLoss >= pTarget->stats.bDexterity)
- {
- bStatLoss = pTarget->stats.bDexterity - 1;
+ bStatLoss = pTarget->stats.bWisdom - 1;
}
if ( bStatLoss > 0 )
{
- pTarget->stats.bDexterity -= bStatLoss;
+ pTarget->stats.bWisdom -= bStatLoss;
+ // SANDRO - added this for healing lost stats feature
+ pTarget->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] += bStatLoss;
if (pTarget->ubProfile != NO_PROFILE)
{
- gMercProfiles[ pTarget->ubProfile ].bDexterity = pTarget->stats.bDexterity;
+ gMercProfiles[ pTarget->ubProfile ].bWisdom = pTarget->stats.bWisdom;
}
if (pTarget->name[0] && pTarget->bVisible == TRUE)
{
// make stat RED for a while...
- pTarget->timeChanges.uiChangeDexterityTime = GetJA2Clock();
- pTarget->usValueGoneUp &= ~( DEX_INCREASE );
+ pTarget->timeChanges.uiChangeWisdomTime = GetJA2Clock();
+ pTarget->usValueGoneUp &= ~( WIS_INCREASE );
if (bStatLoss == 1)
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_DEX], pTarget->name );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_WISDOM], pTarget->name );
}
else
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_DEX], pTarget->name, bStatLoss );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_WISDOM], pTarget->name, bStatLoss );
}
}
}
- }
- else
- {
- if (bStatLoss >= pTarget->stats.bStrength)
+ else if ( pTarget->bNumPelletsHitBy == 0 )
{
- bStatLoss = pTarget->stats.bStrength - 1;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_HEAD_HIT], pTarget->name );
+ }
+
+ // HEADROCK HAM 3.2: Critical headshots may now cause blindness, based on shot damage.
+ if (gGameExternalOptions.ubChanceBlindedByHeadshot)
+ {
+ if (PreRandom(gGameExternalOptions.ubChanceBlindedByHeadshot) == 0)
+ {
+ if (pTarget->bBlindedCounter < iImpact / 10 )
+ pTarget->bBlindedCounter = iImpact / 10;
+ }
+ }
+
+ break;
+ case AIM_SHOT_TORSO:
+ // SANDRO - added a 20% chance to loose maximum health
+ if ( PreRandom( 5 ) == 0 )
+ {
+ if (bStatLoss >= (pTarget->stats.bLifeMax - OKLIFE))
+ {
+ bStatLoss = pTarget->stats.bLifeMax - OKLIFE - 1;
+ }
+ if ( bStatLoss > iImpact)
+ {
+ bStatLoss = iImpact;
+ }
+ if ( bStatLoss > 0 )
+ {
+ pTarget->stats.bLifeMax -= bStatLoss;
+ // SANDRO - added this for healing lost stats feature
+ pTarget->ubCriticalStatDamage[DAMAGED_STAT_HEALTH] += bStatLoss;
+
+ if (pTarget->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pTarget->ubProfile ].bLifeMax = pTarget->stats.bLifeMax;
+ }
+
+ if (pTarget->name[0] && pTarget->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pTarget->timeChanges.uiChangeDexterityTime = GetJA2Clock();
+ pTarget->usValueGoneUp &= ~( HEALTH_INCREASE );
+
+ if (bStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_LOSES_ONE_POINT_MAX_HEALTH], pTarget->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_LOSES_X_POINTS_MAX_HEALTH], pTarget->name, bStatLoss );
+ }
+ }
+ }
+ }
+ else
+ {
+ // 50:50 to lose strength or dexterity
+ if (PreRandom( 3 ) < 4 )
+ {
+ if (bStatLoss >= pTarget->stats.bDexterity)
+ {
+ bStatLoss = pTarget->stats.bDexterity - 1;
+ }
+ if ( bStatLoss > 0 )
+ {
+ pTarget->stats.bDexterity -= bStatLoss;
+ // SANDRO - added this for healing lost stats feature
+ pTarget->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] += bStatLoss;
+
+ if (pTarget->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pTarget->ubProfile ].bDexterity = pTarget->stats.bDexterity;
+ }
+
+ if (pTarget->name[0] && pTarget->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pTarget->timeChanges.uiChangeDexterityTime = GetJA2Clock();
+ pTarget->usValueGoneUp &= ~( DEX_INCREASE );
+
+ if (bStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_DEX], pTarget->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_DEX], pTarget->name, bStatLoss );
+ }
+ }
+ }
+ }
+ else
+ {
+ if (bStatLoss >= pTarget->stats.bStrength)
+ {
+ bStatLoss = pTarget->stats.bStrength - 1;
+ }
+ if ( bStatLoss > 0 )
+ {
+ pTarget->stats.bStrength -= bStatLoss;
+ // SANDRO - added this for healing lost stats feature
+ pTarget->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] += bStatLoss;
+
+ if (pTarget->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pTarget->ubProfile ].bStrength = pTarget->stats.bStrength;
+ }
+
+ if (pTarget->name[0] && pTarget->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pTarget->timeChanges.uiChangeStrengthTime = GetJA2Clock();
+ pTarget->usValueGoneUp &= ~( STRENGTH_INCREASE );
+
+ if (bStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_STRENGTH], pTarget->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_STRENGTH], pTarget->name, bStatLoss );
+ }
+ }
+ }
+ }
+ }
+ break;
+ case AIM_SHOT_LEGS:
+ if (bStatLoss >= pTarget->stats.bAgility)
+ {
+ bStatLoss = pTarget->stats.bAgility - 1;
}
if ( bStatLoss > 0 )
{
- pTarget->stats.bStrength -= bStatLoss;
+ pTarget->stats.bAgility -= bStatLoss;
+ // SANDRO - added this for healing lost stats feature
+ pTarget->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] += bStatLoss;
if (pTarget->ubProfile != NO_PROFILE)
{
- gMercProfiles[ pTarget->ubProfile ].bStrength = pTarget->stats.bStrength;
+ gMercProfiles[ pTarget->ubProfile ].bAgility = pTarget->stats.bAgility;
}
if (pTarget->name[0] && pTarget->bVisible == TRUE)
{
// make stat RED for a while...
- pTarget->timeChanges.uiChangeStrengthTime = GetJA2Clock();
- pTarget->usValueGoneUp &= ~( STRENGTH_INCREASE );
+ pTarget->timeChanges.uiChangeAgilityTime = GetJA2Clock();
+ pTarget->usValueGoneUp &= ~( AGIL_INCREASE );
if (bStatLoss == 1)
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_STRENGTH], pTarget->name );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_AGIL], pTarget->name );
}
else
{
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_STRENGTH], pTarget->name, bStatLoss );
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_AGIL], pTarget->name, bStatLoss );
}
}
}
- }
- break;
- case AIM_SHOT_LEGS:
- if (bStatLoss >= pTarget->stats.bAgility)
- {
- bStatLoss = pTarget->stats.bAgility - 1;
- }
- if ( bStatLoss > 0 )
- {
- pTarget->stats.bAgility -= bStatLoss;
+ break;
+ }
- if (pTarget->ubProfile != NO_PROFILE)
- {
- gMercProfiles[ pTarget->ubProfile ].bAgility = pTarget->stats.bAgility;
- }
+ // SANDRO - Gain morale for inflicting critical hit if malicious character
+ if ( fMaliciousHit )
+ {
+ HandleMoraleEvent( pFirer, MORALE_MALICIOUS_HIT, pFirer->sSectorX, pFirer->sSectorY, pFirer->bSectorZ );
+ }
- if (pTarget->name[0] && pTarget->bVisible == TRUE)
- {
- // make stat RED for a while...
- pTarget->timeChanges.uiChangeAgilityTime = GetJA2Clock();
- pTarget->usValueGoneUp &= ~( AGIL_INCREASE );
-
- if (bStatLoss == 1)
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_AGIL], pTarget->name );
- }
- else
- {
- ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_AGIL], pTarget->name, bStatLoss );
- }
- }
- }
- break;
+ // SANDRO - new merc records - times stat damaged
+ if ( bStatLoss > 0 && pTarget->ubProfile != NO_PROFILE )
+ gMercProfiles[ pTarget->ubProfile ].records.usTimesStatDamaged++;
}
}
else if ( ubHitLocation == AIM_SHOT_HEAD && pTarget->bNumPelletsHitBy == 0 )
@@ -5095,6 +8935,10 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubHitLocat
INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BOOLEAN fBladeAttack )
{
+ ////////////////////////////////////////////
+ // SANDRO - this all was somehow messed up
+ ////////////////////////////////////////////
+
INT32 iImpact, iFluke, iBonus;
if (fBladeAttack)
@@ -5113,29 +8957,55 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
iImpact = ( EffectiveExpLevel( pSoldier ) / 2); // 0 to 4 for level
iImpact += EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
- // NB martial artists don't get a bonus for using brass knuckles!
- if (pSoldier->usAttackingWeapon && !( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS ) ) )
+ // NB martial artists don't get a bonus for using brass knuckles! - oh, they do in STOMP - SANDRO
+ if (pSoldier->usAttackingWeapon )
{
- iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
-
- if ( AM_A_ROBOT( pTarget ) )
+ if ( gGameOptions.fNewTraitSystem )
{
- iImpact /= 2;
+ iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
+
+ if ( AM_A_ROBOT( pTarget ) )
+ {
+ iImpact /= 2;
+ }
+ }
+ else
+ {
+ if (!HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ))
+ {
+ iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
+ }
+ if ( AM_A_ROBOT( pTarget ) )
+ {
+ iImpact /= 2;
+ }
}
}
else
{
// base HTH damage
- iImpact += 5;
+ // Enhanced Close Combat System - Slightly reduced for we can now attack to head for bigger damage
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ iImpact += 4;
+ }
+ else
+ {
+ iImpact += 5;
+ }
+
+ // Add melee damage multiplier to HtH attacks as well - SANDRO
+ // actually I make the influence a little lesser, because to the blades and so,
+ // only the item impact is multiplied, not the level and strength bonus, but here it does
+ iImpact = (INT32)(iImpact * gGameExternalOptions.iMeleeDamageModifier / 100 );
+
if ( AM_A_ROBOT( pTarget ) )
{
iImpact = 0;
}
}
-
}
-
iFluke = PreRandom( 51 ) - 25; // +/-25% bonus due to random factors
iBonus = iHitBy / 2; // up to 50% extra impact for accurate attacks
@@ -5143,22 +9013,165 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
if (!fBladeAttack)
{
- // add bonuses for hand-to-hand and martial arts
- if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS ) )
+ if ( gGameOptions.fNewTraitSystem )
{
- iImpact = iImpact * ( 100 + gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS ) ) / 100;
- if (pSoldier->usAnimState == NINJA_SPINKICK)
+ if (!pSoldier->usAttackingWeapon || Item[pSoldier->inv[HANDPOS].usItem].brassknuckles)
{
- iImpact *= 2;
+ // add bonuses for martial arts
+ if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
+ {
+ iImpact = (INT32)((iImpact * (100 + gSkillTraitValues.ubMABonusDamageHandToHand * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100) + 0.5);
+
+ // The Spinning kicks or aimed punch bonus - SANDRO
+ if (pSoldier->usAnimState == NINJA_SPINKICK || (pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6)))
+ {
+ iImpact = (INT32)((iImpact * (100 + gSkillTraitValues.usMAAimedPunchDamageBonus * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100) + 0.5); // +75% damage per trait
+ }
+ }
+ }
+ else
+ {
+ // +30% damage of blunt weapons for melee character
+ if (HAS_SKILL_TRAIT( pSoldier, MELEE_NT ))
+ {
+ iImpact = (INT32)(iImpact * (100 + gSkillTraitValues.ubMEDamageBonusBlunt)/100);
+
+ if (pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : 6))
+ {
+ iImpact = (INT32)(iImpact * (100 + gSkillTraitValues.usMEAimedMeleeAttackDamageBonus) / 100); // 50% incresed damage if focused melee attack
+ }
+ }
}
}
- if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND ) )
+ else // original code
{
- // SPECIAL - give TRIPLE bonus for damage for hand-to-hand trait
- // because the HTH bonus is half that of martial arts, and gets only 1x for to-hit bonus
- iImpact = iImpact * ( 100 + 3 * gbSkillTraitBonus[HANDTOHAND] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND ) ) / 100;
+ // add bonuses for hand-to-hand and martial arts
+ if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) )
+ {
+ iImpact = iImpact * ( 100 + gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) ) / 100;
+ if (pSoldier->usAnimState == NINJA_SPINKICK)
+ {
+ iImpact *= 2;
+ }
+ }
+ if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
+ {
+ // SPECIAL - give TRIPLE bonus for damage for hand-to-hand trait
+ // because the HTH bonus is half that of martial arts, and gets only 1x for to-hit bonus
+ iImpact = iImpact * ( 100 + 3 * gbSkillTraitBonus[HANDTOHAND_OT] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) ) / 100;
+ }
+ }
+
+ // Enhanced Close Combat System - aiming at body parts makes difference
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ if (pSoldier->bAimShotLocation == AIM_SHOT_HEAD)
+ {
+ iImpact = (INT32)((iImpact * 125 / 100) + 0.5); // Punch or kick to head deal more damage (as bonus for -20% accuracy )
+ }
+ else if ( pSoldier->bAimShotLocation == AIM_SHOT_LEGS )
+ {
+ // Punch or kick to legs deal less damage but takes some AP per damage out of target adjusted by AP_MAXIMUM
+ // NO, better to make hit to legs have a much better chance to hit, while only 50% damage
+ iImpact = (INT32)((iImpact * 60 / 100) + 0.5);
+ //DeductPoints( pTarget, (APBPConstants[AP_MAXIMUM] / 10), 0 );
+ }
+ else if (gAnimControl[ pTarget->usAnimState ].ubEndHeight == ANIM_PRONE)
+ {
+ iImpact = (INT32)((iImpact * 130 / 100) + 0.5); // 30% incresed damage to lying characters
+ }
+
+ // Surprising attack deals more damage
+ if (pTarget->aiData.bOppList[ pSoldier->ubID ] == NOT_HEARD_OR_SEEN && !CREATURE_OR_BLOODCAT( pTarget ) )
+ {
+ iImpact = (INT32)((iImpact * 140 / 100) + 0.5); // 30% incresed damage on suprising attacks
+ }
}
}
+ // DAMAGE BONUS TO KNIFE ATTACK WITH MELEE SKILL
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, MELEE_NT ) && ( gGameOptions.fNewTraitSystem ))
+ {
+ iImpact = (INT32)(iImpact * ( 100 + gSkillTraitValues.ubMEDamageBonusBlades ) / 100); // +30% damage
+
+ if (pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : 6))
+ {
+ iImpact = (INT32)(iImpact * ( 100 + gSkillTraitValues.usMEAimedMeleeAttackDamageBonus ) / 100); // 50% incresed damage if focused melee attack
+ }
+ }
+ // Enhanced Close Combat System
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ if (gAnimControl[ pTarget->usAnimState ].ubEndHeight == ANIM_PRONE)
+ {
+ iImpact = (INT32)(iImpact * 125 / 100); // 40% incresed damage to lying characters
+ }
+ }
+ }
+
+ // bonus damage for aggressive characters
+ if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_AGGRESSIVE )
+ {
+ iImpact = (INT32)((iImpact * 11 / 10) + 0.5); // +10%
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Damage resistance for Militia
+ if (!IsAutoResolveActive())
+ {
+ if (pTarget->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
+ // bonus for enemy too
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
+ else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
+ iImpact -= ((iImpact * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
+
+ iImpact = max( 1, iImpact);
+ }
+ //////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - option to make special NPCs stronger - damage resistance
+ if (gGameExternalOptions.usSpecialNPCStronger > 0)
+ {
+ switch( pTarget->ubProfile )
+ {
+ case CARMEN:
+ case QUEEN:
+ case JOE:
+ case ANNIE:
+ case CHRIS:
+ case KINGPIN:
+ case TIFFANY:
+ case T_REX:
+ case DRUGGIST:
+ case GENERAL:
+ case JACK:
+ case OLAF:
+ case RAY:
+ case OLGA:
+ case TYRONE:
+ case MIKE:
+ iImpact -= (INT32)(iImpact * gGameExternalOptions.usSpecialNPCStronger / 200);
+ iImpact = max( 1, iImpact);
+ break;
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // STOMP traits - Bodybuilding damage resistance
+ if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pTarget, BODYBUILDING_NT ) )
+ iImpact = max( 1, (INT32)(iImpact * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
+ ////////////////////////////////////////////////////////////////////////////////////
return( iImpact );
}
@@ -5238,12 +9251,12 @@ void ShotMiss( UINT8 ubAttackerID, INT32 iBullet )
UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAimTime, UINT8 ubMode )
{
- UINT16 usInHand;
+ UINT16 usInHand;
UINT8 ubBandaged;
- INT32 iAttRating, iDefRating;
+ INT32 iAttRating, iDefRating;
INT32 iChance;
- usInHand = pAttacker->usAttackingWeapon;
+ usInHand = pAttacker->usAttackingWeapon;
if ( (usInHand != CREATURE_QUEEN_TENTACLES ) && (pDefender->stats.bLife < OKLIFE || pDefender->bBreath < OKBREATH) )
{
@@ -5270,14 +9283,28 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
}
}
- // CALCULATE ATTACKER'S CLOSE COMBAT RATING (1-100)
+ // CALCULATE ATTACKER'S CLOSE COMBAT RATING (1-100)
if (ubMode == HTH_MODE_STEAL)
{
- // this is more of a brute force strength-vs-strength check
- iAttRating = ( EffectiveDexterity( pAttacker ) + // coordination, accuracy
- EffectiveAgility( pAttacker ) + // speed & reflexes
- 3 * pAttacker->stats.bStrength + // physical strength (TRIPLED!)
- (10 * EffectiveExpLevel( pAttacker ) ) ); // experience, knowledge
+ ///////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Enhanced Close Combat System - different calculation for stealing
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ // We need to be agile and dexterous
+ iAttRating = ( 2 * EffectiveDexterity( pAttacker ) + // coordination, accuracy *
+ 2 * EffectiveAgility( pAttacker ) + // speed & reflexes
+ pAttacker->stats.bStrength + // physical strength
+ (10 * EffectiveExpLevel( pAttacker ) ) ); // experience, knowledge
+ }
+ else
+ {
+ // this is more of a brute force strength-vs-strength check
+ iAttRating = ( EffectiveDexterity( pAttacker ) + // coordination, accuracy
+ EffectiveAgility( pAttacker ) + // speed & reflexes
+ 3 * pAttacker->stats.bStrength + // physical strength (TRIPLED!)
+ (10 * EffectiveExpLevel( pAttacker ) ) ); // experience, knowledge
+ }
+ ///////////////////////////////////////////////////////////////////////////////////////
}
else
{
@@ -5287,10 +9314,10 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
(10 * EffectiveExpLevel( pAttacker ) ) ); // experience, knowledge
}
- iAttRating /= 6; // convert from 6-600 to 1-100
+ iAttRating /= 6; // convert from 6-600 to 1-100
- // psycho bonus
- if ( pAttacker->ubProfile != NO_PROFILE && gMercProfiles[ pAttacker->ubProfile ].bPersonalityTrait == PSYCHO )
+ // psycho bonus - only with old traits - SANDRO
+ if ( !( gGameOptions.fNewTraitSystem ) && pAttacker->ubProfile != NO_PROFILE && gMercProfiles[ pAttacker->ubProfile ].bDisability == PSYCHO )
{
iAttRating += AIM_BONUS_PSYCHO;
}
@@ -5301,87 +9328,163 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
// modify for fatigue
iAttRating -= GetSkillCheckPenaltyForFatigue( pAttacker, iAttRating );
- // if attacker spent some extra time aiming
- if (ubAimTime)
- {
- // use only HALF of the normal aiming bonus for knife aiming.
- // since there's no range penalty, the bonus is otherwise too generous
- iAttRating += ((AIM_BONUS_PER_AP * ubAimTime) / 2); //bonus for aiming
- }
-
- if (! (pAttacker->flags.uiStatusFlags & SOLDIER_PC) ) // if attacker is a computer AI controlled enemy
+ // if attacker spent some extra time aiming
+ if (ubAimTime)
{
- iAttRating += gbDiff[ DIFF_ENEMY_TO_HIT_MOD ][ SoldierDifficultyLevel( pAttacker ) ];
+ // use only HALF of the normal aiming bonus for knife aiming.
+ // since there's no range penalty, the bonus is otherwise too generous
+ // SANDRO - Enhanced Close Combat System - Because you can only aim once, I've rather put here a flat number
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ iAttRating += 20;
+ else
+ iAttRating += ((AIM_BONUS_PER_AP * ubAimTime) / 2); //bonus for aiming
}
- // if attacker is being affected by gas
- if ( pAttacker->flags.uiStatusFlags & SOLDIER_GASSED )
- iAttRating -= AIM_PENALTY_GASSED;
-
- // if attacker is being bandaged at the same time, his concentration is off
- if (pAttacker->ubServiceCount > 0)
- iAttRating -= AIM_PENALTY_GETTINGAID;
-
- // if attacker is still in shock
- if (pAttacker->aiData.bShock)
- iAttRating -= (pAttacker->aiData.bShock * AIM_PENALTY_PER_SHOCK);
-
-/*
- // if the attacker is an A.I.M. mercenary
- if (pAttacker->characternum < MAX_AIM_MERCS) // exclude Gus
- iAttRating += AdjustChanceForProfile(pAttacker,pDefender);
-*/
-
- // If attacker injured, reduce chance accordingly (by up to 2/3rds)
- if ((iAttRating > 0) && (pAttacker->stats.bLife < pAttacker->stats.bLifeMax))
- {
- // if bandaged, give 1/2 of the bandaged life points back into equation
- ubBandaged = pAttacker->stats.bLifeMax - pAttacker->stats.bLife - pAttacker->bBleeding;
-
- iAttRating -= (2 * iAttRating * (pAttacker->stats.bLifeMax - pAttacker->stats.bLife + (ubBandaged / 2))) /
- (3 * pAttacker->stats.bLifeMax);
- }
-
- // If attacker tired, reduce chance accordingly (by up to 1/2)
- if ((iAttRating > 0) && (pAttacker->bBreath < 100))
- iAttRating -= (iAttRating * (100 - pAttacker->bBreath)) / 200;
-
- if (pAttacker->ubProfile != NO_PROFILE)
+ if (! (pAttacker->flags.uiStatusFlags & SOLDIER_PC) ) // if attacker is a computer AI controlled enemy
{
- if (ubMode == HTH_MODE_STAB)
+ iAttRating += gbDiff[ DIFF_ENEMY_TO_HIT_MOD ][ SoldierDifficultyLevel( pAttacker ) ];
+ }
+
+ // if attacker is being affected by gas
+ if ( pAttacker->flags.uiStatusFlags & SOLDIER_GASSED )
+ iAttRating -= AIM_PENALTY_GASSED;
+
+ // if attacker is being bandaged at the same time, his concentration is off
+ if (pAttacker->ubServiceCount > 0)
+ iAttRating -= AIM_PENALTY_GETTINGAID;
+
+ // if attacker is still in shock
+ if (pAttacker->aiData.bShock)
+ iAttRating -= (pAttacker->aiData.bShock * AIM_PENALTY_PER_SHOCK);
+
+ // if the attacker is an A.I.M. mercenary
+ //if (pAttacker->characternum < MAX_AIM_MERCS) // exclude Gus
+ // iAttRating += AdjustChanceForProfile(pAttacker,pDefender);
+
+ // If attacker injured, reduce chance accordingly (by up to 2/3rds)
+ if ((iAttRating > 0) && (pAttacker->stats.bLife < pAttacker->stats.bLifeMax))
+ {
+ // if bandaged, give 1/2 of the bandaged life points back into equation
+ ubBandaged = pAttacker->stats.bLifeMax - pAttacker->stats.bLife - pAttacker->bBleeding;
+
+ iAttRating -= (2 * iAttRating * (pAttacker->stats.bLifeMax - pAttacker->stats.bLife + (ubBandaged / 2))) / (3 * pAttacker->stats.bLifeMax);
+ }
+
+ // If attacker tired, reduce chance accordingly (by up to 1/2)
+ if ((iAttRating > 0) && (pAttacker->bBreath < 100))
+ iAttRating -= (iAttRating * (100 - pAttacker->bBreath)) / 200;
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if (ubMode == HTH_MODE_STAB)
+ {
+ // add bonus for melee/knifing
+ if ( gGameOptions.fNewTraitSystem )
{
- if (HAS_SKILL_TRAIT( pAttacker, KNIFING ))
+ iAttRating += gSkillTraitValues.bCtHModifierKnifeAttack; // Make melee attacks a little more problematic for untrained mercs
+
+ if (HAS_SKILL_TRAIT( pAttacker, MELEE_NT ))
{
- iAttRating += gbSkillTraitBonus[KNIFING] * NUM_SKILL_TRAITS( pAttacker, KNIFING );
+ iAttRating += gSkillTraitValues.ubMECtHBladesBonus;
}
}
+ else if (HAS_SKILL_TRAIT( pAttacker, KNIFING_OT ))
+ {
+ iAttRating += gbSkillTraitBonus[KNIFING_OT] * NUM_SKILL_TRAITS( pAttacker, KNIFING_OT );
+ }
+ }
+ else
+ {
+ // add bonus for martial arts/melee
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ iAttRating += gSkillTraitValues.bCtHModifierHtHAttack; // Make HtH attacks a little more problematic for untrained mercs
+
+ // bare hands - bonus for Martial arts
+ if (!pAttacker->usAttackingWeapon && HAS_SKILL_TRAIT( pAttacker, MARTIAL_ARTS_NT ))
+ {
+ iAttRating += gSkillTraitValues.ubMABonusCtHBareHands * NUM_SKILL_TRAITS( pAttacker, MARTIAL_ARTS_NT );
+ }
+ // brass knuckles - bonus for Martial Arts (but a little lesser)
+ else if (Item[pAttacker->inv[HANDPOS].usItem].brassknuckles && HAS_SKILL_TRAIT( pAttacker, MARTIAL_ARTS_NT ))
+ {
+ iAttRating += gSkillTraitValues.ubMABonusCtHBrassKnuckles * NUM_SKILL_TRAITS( pAttacker, MARTIAL_ARTS_NT );
+ }
+ // blunt melee weapons - bonus for Melee
+ else if (HAS_SKILL_TRAIT( pAttacker, MELEE_NT ))
+ {
+ iAttRating += gSkillTraitValues.ubMECtHBluntBonus;
+ }
+ }
+ else // original code
+ {
+ if (HAS_SKILL_TRAIT( pAttacker, MARTIALARTS_OT ))
+ {
+ iAttRating += gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pAttacker, MARTIALARTS_OT );
+ }
+ if ( HAS_SKILL_TRAIT( pAttacker, HANDTOHAND_OT ) )
+ {
+ iAttRating += gbSkillTraitBonus[HANDTOHAND_OT] * NUM_SKILL_TRAITS( pAttacker, HANDTOHAND_OT );
+ }
+ }
+ }
+
+ // Added character traits influence
+ if ( gGameOptions.fNewTraitSystem && pAttacker->ubProfile != NO_PROFILE )
+ {
+ // Sociable - better performance in groups
+ if ( gMercProfiles[ pAttacker->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pAttacker->ubProfile, CHAR_TRAIT_SOCIABLE );
+ if ( bNumMercs > 2 )
+ iAttRating += 5;
+ else if ( bNumMercs > 0 )
+ iAttRating += 2;
+ }
+ // Loner - better performance when alone
+ else if ( gMercProfiles[ pAttacker->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pAttacker->ubProfile, CHAR_TRAIT_LONER );
+ if ( bNumMercs == 0 )
+ iAttRating += 5;
+ else if ( bNumMercs <= 1 )
+ iAttRating += 2;
+ }
+ // Show-off - better performance if some babes around to impress
+ else if ( gMercProfiles[ pAttacker->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pAttacker->ubProfile, CHAR_TRAIT_SHOWOFF );
+ if ( bNumMercs > 1 )
+ iAttRating += 5;
+ else if ( bNumMercs > 0 )
+ iAttRating += 2;
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////
+
+ if (iAttRating < 1)
+ iAttRating = 1;
+
+
+ // CALCULATE DEFENDER'S CLOSE COMBAT RATING (0-100)
+ if (ubMode == HTH_MODE_STEAL)
+ {
+ // SANDRO - Enhanced Close Combat System - stealing defence based on dexterity and strength
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ iDefRating = ( EffectiveAgility( pDefender )) + // speed & reflexes
+ 2 * EffectiveDexterity( pDefender ) + // coordination, accuracy
+ 2 * pDefender->stats.bStrength + // physical strength
+ (10 * EffectiveExpLevel( pDefender ) ); // experience, knowledge
+ }
else
{
- // add bonuses for hand-to-hand and martial arts
- if (HAS_SKILL_TRAIT( pAttacker, MARTIALARTS ))
- {
- iAttRating += gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pAttacker, MARTIALARTS );
- }
- if ( HAS_SKILL_TRAIT( pAttacker, HANDTOHAND ) )
- {
- iAttRating += gbSkillTraitBonus[HANDTOHAND] * NUM_SKILL_TRAITS( pAttacker, HANDTOHAND );
- }
+ iDefRating = (EffectiveAgility( pDefender )) + // speed & reflexes
+ EffectiveDexterity( pDefender ) + // coordination, accuracy
+ 3 * pDefender->stats.bStrength + // physical strength (TRIPLED!)
+ (10 * EffectiveExpLevel( pDefender ) ); // experience, knowledge
}
}
-
-
- if (iAttRating < 1)
- iAttRating = 1;
-
-
- // CALCULATE DEFENDER'S CLOSE COMBAT RATING (0-100)
- if (ubMode == HTH_MODE_STEAL)
- {
- iDefRating = (EffectiveAgility( pDefender )) + // speed & reflexes
- EffectiveDexterity( pDefender ) + // coordination, accuracy
- 3 * pDefender->stats.bStrength + // physical strength (TRIPLED!)
- (10 * EffectiveExpLevel( pDefender ) ); // experience, knowledge
- }
else
{
iDefRating = (3 * EffectiveAgility( pDefender ) ) + // speed & reflexes (TRIPLED!)
@@ -5390,7 +9493,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
(10 * EffectiveExpLevel( pDefender ) ); // experience, knowledge
}
- iDefRating /= 6; // convert from 6-600 to 1-100
+ iDefRating /= 6; // convert from 6-600 to 1-100
// modify chance to dodge by morale
iDefRating += GetMoraleModifier( pDefender );
@@ -5398,38 +9501,30 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
// modify for fatigue
iDefRating -= GetSkillCheckPenaltyForFatigue( pDefender, iDefRating );
- // if attacker is being affected by gas
- if ( pDefender->flags.uiStatusFlags & SOLDIER_GASSED )
- iDefRating -= AIM_PENALTY_GASSED;
+ // if attacker is being affected by gas
+ if ( pDefender->flags.uiStatusFlags & SOLDIER_GASSED )
+ iDefRating -= AIM_PENALTY_GASSED;
- // if defender is being bandaged at the same time, his concentration is off
+ // if defender is being bandaged at the same time, his concentration is off
if (pDefender->ubServiceCount > 0)
- iDefRating -= AIM_PENALTY_GETTINGAID;
+ iDefRating -= AIM_PENALTY_GETTINGAID;
- // if defender is still in shock
- if (pDefender->aiData.bShock)
- iDefRating -= (pDefender->aiData.bShock * AIM_PENALTY_PER_SHOCK);
+ // if defender is still in shock
+ if (pDefender->aiData.bShock)
+ iDefRating -= (pDefender->aiData.bShock * AIM_PENALTY_PER_SHOCK);
-/*
- // if the defender is an A.I.M. mercenary
- if (pDefender->characternum < MAX_AIM_MERCS) // exclude Gus
- iDefRating += AdjustChanceForProfile(pDefender,pAttacker);
-*/
+ // If defender injured, reduce chance accordingly (by up to 2/3rds)
+ if ((iDefRating > 0) && (pDefender->stats.bLife < pDefender->stats.bLifeMax))
+ {
+ // if bandaged, give 1/2 of the bandaged life points back into equation
+ ubBandaged = pDefender->stats.bLifeMax - pDefender->stats.bLife - pDefender->bBleeding;
- // If defender injured, reduce chance accordingly (by up to 2/3rds)
- if ((iDefRating > 0) && (pDefender->stats.bLife < pDefender->stats.bLifeMax))
- {
- // if bandaged, give 1/2 of the bandaged life points back into equation
- ubBandaged = pDefender->stats.bLifeMax - pDefender->stats.bLife - pDefender->bBleeding;
+ iDefRating -= (2 * iDefRating * (pDefender->stats.bLifeMax - pDefender->stats.bLife + (ubBandaged / 2))) / (3 * pDefender->stats.bLifeMax);
+ }
- iDefRating -= (2 * iDefRating * (pDefender->stats.bLifeMax - pDefender->stats.bLife + (ubBandaged / 2))) /
- (3 * pDefender->stats.bLifeMax);
-
- }
-
- // If defender tired, reduce chance accordingly (by up to 1/2)
- if ((iDefRating > 0) && (pDefender->bBreath < 100))
- iDefRating -= (iDefRating * (100 - pDefender->bBreath)) / 200;
+ // If defender tired, reduce chance accordingly (by up to 1/2)
+ if ((iDefRating > 0) && (pDefender->bBreath < 100))
+ iDefRating -= (iDefRating * (100 - pDefender->bBreath)) / 200;
if ( usInHand == CREATURE_QUEEN_TENTACLES && pDefender->ubBodyType == LARVAE_MONSTER || pDefender->ubBodyType == INFANT_MONSTER )
{
@@ -5463,71 +9558,175 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
}
}
-
- if (pDefender->ubProfile != NO_PROFILE)
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if (ubMode == HTH_MODE_STAB)
{
- if (ubMode == HTH_MODE_STAB)
+ if ( gGameOptions.fNewTraitSystem )
{
- if (Item[pDefender->inv[HANDPOS].usItem].usItemClass == IC_BLADE)
+ iDefRating += gSkillTraitValues.bModifierDodgeKnifeChance; // Make HtH dodging a little more problematic for untrained mercs
+
+ // Give bonus to dodge melee blade to MA and/or Melee trait - SANDRO
+ // Note that it is no longer dependant on what you have in hands
+ if (HAS_SKILL_TRAIT( pDefender, MARTIAL_ARTS_NT ))
{
- if ( HAS_SKILL_TRAIT( pDefender, KNIFING ) )
- {
- // good with knives, got one, so we're good at parrying
- iDefRating += gbSkillTraitBonus[KNIFING] * NUM_SKILL_TRAITS( pDefender, KNIFING );
- }
- if (HAS_SKILL_TRAIT( pDefender, MARTIALARTS ))
- {
- // the knife gets in the way but we're still better than nobody
- iDefRating += ( gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pDefender, MARTIALARTS ) ) / 3;
- }
+ iDefRating += ( gSkillTraitValues.ubMAChanceToDodgeMelee * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ) );
}
- else
+ if (HAS_SKILL_TRAIT( pDefender, MELEE_NT ))
{
- if ( HAS_SKILL_TRAIT( pDefender, KNIFING ) )
+ iDefRating += gSkillTraitValues.ubMEDodgeBladesBonus;
+
+ if (Item[pDefender->inv[HANDPOS].usItem].usItemClass == IC_BLADE)
{
- // good with knives, don't have one, but we know a bit about dodging
- iDefRating += ( gbSkillTraitBonus[KNIFING] * NUM_SKILL_TRAITS( pDefender, KNIFING ) ) / 3;
- }
- if (HAS_SKILL_TRAIT( pDefender, MARTIALARTS ))
- {
- // bonus for dodging knives
- iDefRating += ( gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pDefender, MARTIALARTS ) )/ 2;
+ // knife-to-knife combat, we are the best around at this
+ iDefRating += gSkillTraitValues.ubMECtDBladesOnTopWithBladeInHands;
}
}
}
else
- { // punch/hand-to-hand/martial arts attack/steal
- if (Item[pDefender->inv[HANDPOS].usItem].usItemClass == IC_BLADE && ubMode != HTH_MODE_STEAL)
+ {
+ if ( HAS_SKILL_TRAIT( pDefender, KNIFING_OT ) )
{
- if (HAS_SKILL_TRAIT( pDefender, KNIFING ))
+ if (Item[pDefender->inv[HANDPOS].usItem].usItemClass == IC_BLADE)
{
- // with our knife, we get some bonus at defending from HTH attacks
- iDefRating += ( gbSkillTraitBonus[KNIFING] * NUM_SKILL_TRAITS( pDefender, KNIFING ) ) / 2;
+ // good with knives, got one, so we're good at parrying
+ iDefRating += gbSkillTraitBonus[KNIFING_OT] * NUM_SKILL_TRAITS( pDefender, KNIFING_OT );
+ }
+ else
+ {
+ // good with knives, don't have one, but we know a bit about dodging
+ iDefRating += ( gbSkillTraitBonus[KNIFING_OT] * NUM_SKILL_TRAITS( pDefender, KNIFING_OT ) ) / 3;
+ }
+ }
+ if (HAS_SKILL_TRAIT( pDefender, MARTIALARTS_OT ))
+ {
+ // bonus for dodging knives
+ iDefRating += ( gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pDefender, MARTIALARTS_OT ) )/ 2;
+ }
+ }
+ }
+ else
+ { // punch/hand-to-hand/martial arts attack/steal
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ iDefRating += gSkillTraitValues.bModifierDodgeHtHChance; // Make HtH dodging a little more problematic for untrained mercs
+
+ if ( !pAttacker->usAttackingWeapon || Item[pAttacker->inv[HANDPOS].usItem].brassknuckles )
+ {
+ if (HAS_SKILL_TRAIT( pDefender, MARTIAL_ARTS_NT ))
+ {
+ // Bonus to dodge to MA trait - SANDRO
+ // Note that it no longer depends on whatever having in hands, because before
+ // you would have unlogicaly lesser chance to dodge with a knife in hands than with a gun
+ iDefRating += gSkillTraitValues.ubMAChanceToDodgeHtH * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ); // +35% per trait
+
+ if ( !pDefender->inv[HANDPOS].exists() )
+ {
+ iDefRating += ( gSkillTraitValues.ubMAOnTopCTDHtHBareHanded * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ) );
+ }
+ else if ( Item[pDefender->inv[HANDPOS].usItem].brassknuckles )
+ {
+ iDefRating += ( gSkillTraitValues.ubMAOnTopCTDHtHBrassKnuckles * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ) );
+ }
}
}
else
{
- if (HAS_SKILL_TRAIT( pDefender, MARTIALARTS ))
+ if (HAS_SKILL_TRAIT( pDefender, MARTIAL_ARTS_NT ))
{
- iDefRating += gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pDefender, MARTIALARTS );
+ iDefRating += gSkillTraitValues.ubMAChanceToDodgeMelee * NUM_SKILL_TRAITS( pDefender, MARTIAL_ARTS_NT ); // +35% per trait
}
- if (HAS_SKILL_TRAIT( pDefender, HANDTOHAND ))
+ if (HAS_SKILL_TRAIT( pDefender, MELEE_NT ))
{
- iDefRating += gbSkillTraitBonus[HANDTOHAND] * NUM_SKILL_TRAITS( pDefender, HANDTOHAND );
+ iDefRating += gSkillTraitValues.ubMEDodgeBluntBonus;
+
+ if (Item[pDefender->inv[HANDPOS].usItem].usItemClass == IC_BLADE)
+ {
+ // bonus, when we have our knife in hands
+ iDefRating += gSkillTraitValues.ubMECtDBluntOnTopWithBladeInHands;
+ }
}
}
}
+ else
+ {
+ // SANDRO - this is so idiotic, it actiually means, that martial artists and HtH
+ // soldiers do not get their dodging bonus if they have a knife in hands, but do
+ // have it if having anything else! I just had to change it, for it is a bug more
+ // than an intended feature
+ if (HAS_SKILL_TRAIT( pDefender, KNIFING_OT ) && Item[pDefender->inv[HANDPOS].usItem].usItemClass == IC_BLADE && ubMode != HTH_MODE_STEAL)
+ {
+ // with our knife, we get some bonus at defending from HTH attacks
+ iDefRating += ( gbSkillTraitBonus[KNIFING_OT] * NUM_SKILL_TRAITS( pDefender, KNIFING_OT ) ) / 2;
+
+ }
+ if (HAS_SKILL_TRAIT( pDefender, MARTIALARTS_OT ))
+ {
+ // now the bonus depends on what we have in hands
+ if ( pDefender->inv[HANDPOS].exists() )
+ {
+ // if we have something in hands, the chance is reduced
+ iDefRating += gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pDefender, MARTIALARTS_OT )*2/3;
+ }
+ else
+ {
+ // else we are unbeatable
+ iDefRating += gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pDefender, MARTIALARTS_OT );
+ }
+ }
+ if (HAS_SKILL_TRAIT( pDefender, HANDTOHAND_OT ))
+ {
+ iDefRating += gbSkillTraitBonus[HANDTOHAND_OT] * NUM_SKILL_TRAITS( pDefender, HANDTOHAND_OT );
+ }
+ }
}
- if (iDefRating < 1)
- iDefRating = 1;
+ // Added character traits influence
+ if ( gGameOptions.fNewTraitSystem && pDefender->ubProfile != NO_PROFILE )
+ {
+ // Sociable - better performance in groups
+ if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_SOCIABLE )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pDefender->ubProfile, CHAR_TRAIT_SOCIABLE );
+ if ( bNumMercs > 2 )
+ iDefRating += 5;
+ else if ( bNumMercs > 0 )
+ iDefRating += 2;
+ }
+ // Loner - better performance when alone
+ else if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_LONER )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pDefender->ubProfile, CHAR_TRAIT_LONER );
+ if ( bNumMercs == 0 )
+ iDefRating += 5;
+ else if ( bNumMercs <= 1 )
+ iDefRating += 2;
+ }
+ // Show-off - better performance if some babes around to impress
+ else if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_SHOWOFF )
+ {
+ INT8 bNumMercs = CheckMercsNearForCharTraits( pDefender->ubProfile, CHAR_TRAIT_SHOWOFF );
+ if ( bNumMercs > 1 )
+ iDefRating += 5;
+ else if ( bNumMercs > 0 )
+ iDefRating += 2;
+ }
+ else if ( gMercProfiles[ pDefender->ubProfile ].bCharacterTrait == CHAR_TRAIT_DAUNTLESS )
+ {
+ iDefRating -= 5;
+ }
+ }
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ if (iDefRating < 1)
+ iDefRating = 1;
- //NumMessage("CalcChanceToStab - Attacker's Rating = ",iAttRating);
- //NumMessage("CalcChanceToStab - Defender's Rating = ",iDefRating);
+ //NumMessage("CalcChanceToStab - Attacker's Rating = ",iAttRating);
+ //NumMessage("CalcChanceToStab - Defender's Rating = ",iDefRating);
- // calculate chance to hit by comparing the 2 opponent's ratings
-// iChance = (100 * iAttRating) / (iAttRating + iDefRating);
+ // calculate chance to hit by comparing the 2 opponent's ratings
+ // iChance = (100 * iAttRating) / (iAttRating + iDefRating);
if (ubMode == HTH_MODE_STEAL)
@@ -5541,14 +9740,53 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
// Changed from DG by CJC to give higher chances of hitting with a stab or punch
iChance = 67 + (iAttRating - iDefRating) / 3;
- if ( pAttacker->bAimShotLocation == AIM_SHOT_HEAD )
+ // SANDRO - Enhanced Close Combat System - chances to hit for punches aimed at body parts
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
{
- // make this harder!
- iChance -= 20;
- }
+ if( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pAttacker, MARTIAL_ARTS_NT ) &&
+ ((pAttacker->usAnimState == NINJA_SPINKICK) || (pAttacker->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6))) )
+ {
+ // spinning kick or focused punch modifier
+ iChance += gSkillTraitValues.bMAAimedPunchCtHModifier * NUM_SKILL_TRAITS( pAttacker, MARTIAL_ARTS_NT );
+ }
+ if ( pAttacker->bAimShotLocation == AIM_SHOT_HEAD )
+ {
+ // Harder to hit head (but higher damage there)
+ iChance -= 20;
+ }
+ else if( pAttacker->bAimShotLocation == AIM_SHOT_LEGS )
+ {
+ // easy to hit legs (but low damage there)
+ iChance += 25;
+ }
+ }
+ else
+ {
+ if ( pAttacker->bAimShotLocation == AIM_SHOT_HEAD )
+ {
+ // make this harder!
+ iChance -= 20;
+ }
+ }
}
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Bonus CtH for Militia
+ if (pAttacker->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.sGreenMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sGreenMilitiaCtHBonusPercent) /100);
+ else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.sRegularMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sRegularMilitiaCtHBonusPercent) /100);
+ else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
+ // bonus for enemy
+ else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
+ else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
+ else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyEliteCtHBonusPercent) /100);
+ //////////////////////////////////////////////////////////////////////////////////////
// MAKE SURE CHANCE TO HIT IS WITHIN DEFINED LIMITS
// HEADROCK: I urinate on your Defined Limits! Power Rangers, Externalize!
@@ -5764,7 +10002,7 @@ INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed )
if ( EXPLOSIVE_GUN( usItem ) )
{
// oops! return value in weapons table
- return( Weapon[ usItem ].usRange / CELL_X_SIZE );
+ return( GetModifiedGunRange(usItem) / CELL_X_SIZE );
}
// if item's fired mechanically
@@ -5779,7 +10017,7 @@ INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed )
if ( Item[ usItem ].usItemClass == IC_LAUNCHER && fArmed )
{
// this function returns range in tiles so, stupidly, we have to divide by 10 here
- iRange = Weapon[usItem].usRange / CELL_X_SIZE;
+ iRange = GetModifiedGunRange(usItem) / CELL_X_SIZE;
}
else
{
@@ -5807,11 +10045,30 @@ INT32 CalcMaxTossRange( SOLDIERTYPE * pSoldier, UINT16 usItem, BOOLEAN fArmed )
// adjust for thrower's remaining breath (lose up to 1/2 of range)
iRange -= (iRange * (100 - pSoldier->bBreath)) / 200;
- if ( HAS_SKILL_TRAIT( pSoldier, THROWING ) )
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if( gGameOptions.fNewTraitSystem )
{
- // better max range due to expertise
- iRange = iRange * (100 + gbSkillTraitBonus[THROWING] * NUM_SKILL_TRAITS( pSoldier, THROWING ) ) / 100;
+ if ( (Item[ usItem ].usItemClass == IC_THROWING_KNIFE) && (HAS_SKILL_TRAIT( pSoldier, THROWING_NT )) )
+ {
+ // better max range due to expertise
+ iRange += ((iRange * gSkillTraitValues.ubTHBladesMaxRange ) / 100);
+ }
+ else if ( (Item[ usItem ].usItemClass == IC_GRENADE) && (HAS_SKILL_TRAIT( pSoldier, DEMOLITIONS_NT )) )
+ {
+ // better max range due to expertise
+ iRange += ((iRange * gSkillTraitValues.ubDEMaxRangeToThrowGrenades) / 100);
+ }
}
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, THROWING_OT ) )
+ {
+ // better max range due to expertise
+ iRange = iRange * (100 + gbSkillTraitBonus[THROWING_OT] * NUM_SKILL_TRAITS( pSoldier, THROWING_OT ) ) / 100;
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////
// Adjust for thrower's stance
if (gAnimControl[ pSoldier->usAnimState ].ubEndHeight < ANIM_STAND)
@@ -5863,11 +10120,32 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// PHYSICALLY THROWN arced projectile (ie. grenade)
// for lack of anything better, base throwing accuracy on dex & marskmanship
iChance = ( EffectiveDexterity( pSoldier ) + EffectiveMarksmanship( pSoldier ) ) / 2;
- // throwing trait helps out
- if ( HAS_SKILL_TRAIT( pSoldier, THROWING ) )
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if ( gGameOptions.fNewTraitSystem )
{
- iChance += gbSkillTraitBonus[THROWING] * NUM_SKILL_TRAITS( pSoldier, THROWING );
+ // throwing trait helps out on grenades and knives
+ if ( Item[ usHandItem ].usItemClass == IC_THROWING_KNIFE )
+ {
+ iChance += gSkillTraitValues.bCtHModifierThrowingKnives; // -15% for untrained mercs
+
+ if ( HAS_SKILL_TRAIT( pSoldier, THROWING_NT ) )
+ iChance += (gSkillTraitValues.ubTHBladesCtHBonus + (gSkillTraitValues.ubTHBladesCtHBonusPerClick * pSoldier->aiData.bAimTime) );
+ }
+ else
+ {
+ iChance += gSkillTraitValues.bCtHModifierThrowingGrenades; // -10% for untrained mercs
+
+ if ( HAS_SKILL_TRAIT( pSoldier, DEMOLITIONS_NT ) )
+ iChance += gSkillTraitValues.ubDECtHWhenThrowingGrenades; // +30% chance
+ }
}
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, THROWING_OT ) )
+ iChance += gbSkillTraitBonus[THROWING_OT] * NUM_SKILL_TRAITS( pSoldier, THROWING_OT );
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////
}
else
{
@@ -5875,24 +10153,68 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
// MECHANICALLY FIRED arced projectile (ie. mortar), need brains & know-how
iChance = ( EffectiveDexterity( pSoldier ) + EffectiveMarksmanship( pSoldier ) + EffectiveWisdom( pSoldier ) + pSoldier->stats.bExpLevel ) / 4;
- // heavy weapons trait helps out
- if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPS ))
+ ////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if ( gGameOptions.fNewTraitSystem )
{
- iChance += gbSkillTraitBonus[HEAVY_WEAPS] * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS );
+ if ( Item[ usHandItem ].mortar )
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ))
+ iChance += (gSkillTraitValues.sCtHModifierMortar * max( 0, ((100 - gSkillTraitValues.ubHWMortarCtHPenaltyReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ))/100)));
+ else
+ iChance += gSkillTraitValues.sCtHModifierMortar; // -60% for untrained mercs
+ }
+ else
+ {
+ iChance += gSkillTraitValues.bCtHModifierGrenadeLaunchers; // -25% for untrained mercs
+
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ))
+ iChance += gSkillTraitValues.ubHWBonusCtHGrenadeLaunchers * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ); // +25% per trait - SANDRO
+ }
}
+ else
+ {
+ // This feature is available only if not having new traits on - SANDRO
+ // Also.. this was moved here before the Heavy Weapons bonus
+ // HEADROCK HAM 3.2: External divisor for CTH with mortars, now that they are more prevalent in the battlefield.
+ if ( Item[ usHandItem ].mortar )
+ {
+ iChance = iChance / gGameExternalOptions.ubMortarCTHDivisor;
+ }
+
+ // heavy weapons trait helps out
+ if (HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPS_OT ))
+ {
+ iChance += gbSkillTraitBonus[HEAVY_WEAPS_OT] * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPS_OT );
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////
}
- if ( pSoldier->bDoBurst )
+ if ( UsingNewCTHSystem() == false && pSoldier->bDoBurst )
{
int iPenalty = ( Weapon[usHandItem].ubBurstPenalty
- GetBurstToHitBonus(&pSoldier->inv[HANDPOS], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE) )
* (pSoldier->bDoBurst - 1);
// halve the penalty for people with the autofire trait
- if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS ) )
+ /////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if ( gGameOptions.fNewTraitSystem )
{
- iPenalty /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS );
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPONS_NT ) )
+ {
+ iPenalty = max(0, ((iPenalty * (100 - gSkillTraitValues.ubAWAutoFirePenaltyReduction * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPONS_NT )))/100));
+ }
}
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, AUTO_WEAPS_OT ) )
+ {
+ iPenalty /= 2 * NUM_SKILL_TRAITS( pSoldier, AUTO_WEAPS_OT );
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////
iChance -= iPenalty;
}
@@ -6020,10 +10342,28 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
iChance = (iChance * WEAPON_STATUS_MOD(pSoldier->inv[HANDPOS][0]->data.objectStatus)) / 100;
// HEADROCK HAM 3.2: External divisor for CTH with mortars, now that they are more prevalent in the battlefield.
- if ( Item[ usHandItem ].mortar )
- {
- iChance = iChance / gGameExternalOptions.ubMortarCTHDivisor;
- }
+ // SANDRO - moved this up
+ //if ( Item[ usHandItem ].mortar )
+ //{
+ // iChance = iChance / gGameExternalOptions.ubMortarCTHDivisor;
+ //}
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - Bonus CtH for Militia
+ if (pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.sGreenMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sGreenMilitiaCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.sRegularMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sRegularMilitiaCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
+ // bonus for enemy
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteCtHBonusPercent != 0)
+ iChance += ((iChance * gGameExternalOptions.sEnemyEliteCtHBonusPercent) /100);
+ //////////////////////////////////////////////////////////////////////////////////////
// What's with all these defined limits? Let's think out of the box for a minute, shall we?
// HEADROCK (HAM): externalized, effective immediately.
@@ -6115,8 +10455,10 @@ void DishoutQueenSwipeDamage( SOLDIERTYPE *pQueenSoldier )
// ATE: Ok, lets check for some basic things here!
if ( pSoldier->stats.bLife >= OKLIFE && !TileIsOutOfBounds(pSoldier->sGridNo) && pSoldier->bActive && pSoldier->bInSector )
{
+ UINT16 usRange = GetModifiedGunRange(CREATURE_QUEEN_TENTACLES);
+
// Get Pyth spaces away....
- if ( GetRangeInCellCoordsFromGridNoDiff( pQueenSoldier->sGridNo, pSoldier->sGridNo ) <= Weapon[ CREATURE_QUEEN_TENTACLES].usRange )
+ if ( GetRangeInCellCoordsFromGridNoDiff( pQueenSoldier->sGridNo, pSoldier->sGridNo ) <= usRange )
{
// get direction
bDir = (INT8)GetDirectionFromGridNo( pSoldier->sGridNo, pQueenSoldier );
@@ -6135,6 +10477,10 @@ void DishoutQueenSwipeDamage( SOLDIERTYPE *pQueenSoldier )
{
// Hit!
iImpact = HTHImpact( pQueenSoldier, pSoldier, iHitBy, TRUE );
+ // SANDRO - new merc records - well, crepitus queen's tentackles are brutal, count them as "stabbed"
+ if ( pSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pSoldier->ubProfile ].records.usTimesWoundedStabbed++;
+
pSoldier->EVENT_SoldierGotHit( CREATURE_QUEEN_TENTACLES, (INT16) iImpact, (INT16) iImpact, gOppositeDirection[ bDir ], 50, pQueenSoldier->ubID, 0, ANIM_CROUCH, 0, 0 );
}
}
@@ -6181,27 +10527,66 @@ UINT8 GetDamage ( OBJECTTYPE *pObj )
if ( Item[pObj->usItem].usItemClass == IC_BLADE || Item[pObj->usItem].usItemClass == IC_PUNCH || Item[pObj->usItem].usItemClass == IC_TENTACLES )
{
+ UINT8 ubDamage;
// HEADROCK HAM 3.6: Can now take a negative modifier
- UINT8 ubDamage = (UINT8)GetModifiedMeleeDamage( Weapon[ pObj->usItem ].ubImpact );
- ubDamage += GetMeleeDamageBonus(pObj);
- //return min(255, (UINT8)( (ubDamage) + ( (double)ubDamage / 100) * gGameExternalOptions.ubMeleeDamageMultiplier ) );
+ if(UsingNewCTHSystem() == true)
+ {
+ ubDamage = Weapon[ pObj->usItem ].ubImpact;
+ ubDamage += GetMeleeDamageBonus(pObj);
+ ubDamage = (UINT8)GetModifiedMeleeDamage( ubDamage );
+ }
+ else
+ {
+ ubDamage = (UINT8)GetModifiedMeleeDamage( Weapon[ pObj->usItem ].ubImpact );
+ ubDamage += GetMeleeDamageBonus(pObj);
+ }
+ //return min(255, (UINT8)( (ubDamage) + ( (double)ubDamage / 100) * gGameExternalOptions.iMeleeDamageModifier ) );
return min(255, (UINT8)ubDamage);
}
else
{
+ UINT8 ubDamage;
// HEADROCK HAM 3.6: Can now take a negative modifier
- UINT8 ubDamage = (UINT8)GetModifiedMeleeDamage( Weapon[ pObj->usItem ].ubImpact );
-
- // WTF? Why do only small weapons get their damage bonus?!
- if (FitsInSmallPocket(pObj) == true)
+ if(UsingNewCTHSystem() == true)
{
- ubDamage += GetDamageBonus(pObj);
+ ubDamage = Weapon[ pObj->usItem ].ubImpact;
+ // HEADROCK HAM 4: I've decided to remove this condition. It makes no friggin sense.
+ //if (FitsInSmallPocket(pObj) == true)
+ //{
+ ubDamage += GetDamageBonus(pObj);
+ //}
+ ubDamage = (UINT8)GetModifiedGunDamage( ubDamage );
+ }
+ else
+ {
+ ubDamage = (UINT8)GetModifiedGunDamage( Weapon[ pObj->usItem ].ubImpact );
+
+ // WTF? Why do only small weapons get their damage bonus?!
+ if (FitsInSmallPocket(pObj) == true)
+ {
+ ubDamage += GetDamageBonus(pObj);
+ }
}
return min(255, (UINT8)ubDamage );
}
}
-
+// HEADROCK HAM 4: Same function as above, but without modifiers from attached items.
+UINT8 GetBasicDamage ( OBJECTTYPE *pObj )
+{
+ if ( Item[pObj->usItem].usItemClass == IC_BLADE || Item[pObj->usItem].usItemClass == IC_PUNCH || Item[pObj->usItem].usItemClass == IC_TENTACLES )
+ {
+ // HEADROCK HAM 3.6: Can now take a negative modifier
+ UINT8 ubDamage = (UINT8)GetModifiedMeleeDamage( Weapon[ pObj->usItem ].ubImpact );
+ return ubDamage;
+ }
+ else
+ {
+ // HEADROCK HAM 3.6: Can now take a negative modifier
+ UINT8 ubDamage = (UINT8)GetModifiedGunDamage( Weapon[ pObj->usItem ].ubImpact );
+ return ubDamage;
+ }
+}
UINT8 GetShotsPerBurst( OBJECTTYPE *pObj )
{
@@ -6232,6 +10617,42 @@ UINT8 GetAutoPenalty( OBJECTTYPE *pObj, BOOLEAN fProneStance )
return Weapon[ pObj->usItem ].AutoPenalty - bns;
}
+
+// HEADROCK HAM 4: This determines whether the previous bullet in a volley was a tracer bullet.
+BOOLEAN WasPrevBulletATracer( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon )
+{
+
+ if (!AmmoTypes[ (*pWeapon)[0]->data.gun.ubGunAmmoType ].tracerEffect)
+ {
+ // Not a tracer magazine
+ return (FALSE);
+ }
+ if (pSoldier->bDoBurst == 0)
+ {
+ // No volley? Tracers are irrelevant
+ return (FALSE);
+ }
+
+ if (gGameExternalOptions.ubRealisticTracers == 0 || gGameExternalOptions.ubNumBulletsPerTracer == 1)
+ {
+ // All bullets are tracers anyway.
+ return (TRUE);
+ }
+
+ UINT16 usShotsLeft = (*pWeapon)[0]->data.gun.ubGunShotsLeft;
+ UINT16 usMagSize = GetMagSize(pWeapon);
+ UINT16 usBulletsFired = usMagSize-usShotsLeft;
+ UINT16 usBulletsSinceTracer = (usBulletsFired+1)%gGameExternalOptions.ubNumBulletsPerTracer;
+ if (usBulletsSinceTracer == 1)
+ {
+ return (TRUE);
+ }
+ else
+ {
+ return (FALSE);
+ }
+ }
+
UINT8 GetAutofireShotsPerFiveAPs( OBJECTTYPE *pObj )
{
// DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("GetAutofireShotsPerFiveAPs"));
@@ -6239,18 +10660,34 @@ UINT8 GetAutofireShotsPerFiveAPs( OBJECTTYPE *pObj )
// HEADROCK HAM B2.6: Added overall modifier
if (Weapon[ pObj->usItem ].bAutofireShotsPerFiveAP > 0)
{
- return __max((Weapon[ pObj->usItem ].bAutofireShotsPerFiveAP + gGameExternalOptions.bAutofireBulletsPer5APModifier), 0);
+ // WANNE: Fix by Headrock
+ // Weapons shouldn't ever lose their Bp5AP due to this modifier.
+ return __max((Weapon[ pObj->usItem ].bAutofireShotsPerFiveAP + gGameExternalOptions.bAutofireBulletsPer5APModifier), 1);
+
+ //return __max((Weapon[ pObj->usItem ].bAutofireShotsPerFiveAP + gGameExternalOptions.bAutofireBulletsPer5APModifier), 0);
}
else
return 0;
}
-UINT16 GetMagSize( OBJECTTYPE *pObj )
+UINT16 GetMagSize( OBJECTTYPE *pObj, UINT8 subObject )
{
// DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("GetMagSize"));
- return Weapon[ pObj->usItem ].ubMagSize + GetMagSizeBonus(pObj);
+ return Weapon[ pObj->usItem ].ubMagSize + GetMagSizeBonus(pObj, subObject);
+}
+UINT16 GetExpMagSize( OBJECTTYPE *pObj )
+{
+// DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("GetMagSize"));
+ UINT8 magSize = 0;
+ if(Item[pObj->usItem].usItemClass & IC_EXPLOSV)
+ magSize = Explosive[Item[pObj->usItem].ubClassIndex].ubMagSize;
+ else
+ magSize = Weapon[pObj->usItem].ubMagSize;
+
+ //return Weapon[ pObj->usItem ].ubMagSize + GetMagSizeBonus(pObj);
+ return magSize;
}
// HEADROCK HAM 3.3: Function to get a weapon's current ammotype.
@@ -6265,6 +10702,10 @@ bool WeaponReady(SOLDIERTYPE * pSoldier)
if ( AM_A_ROBOT( pSoldier) )
return true;
#endif
+ if (gbForceWeaponNotReady)
+ return false;
+ if (gbForceWeaponReady)
+ return true;
if ( (gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIREREADY ) ||
(gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIRE ) )
return true;
@@ -6317,7 +10758,7 @@ void EstimateBulletsLeft( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj )
}
// Is this Soldier a psycho?
- if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == PSYCHO )
+ if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
{
fPsycho = TRUE;
}
@@ -6417,3 +10858,48 @@ void EstimateBulletsLeft( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj )
return;
}
+
+// HEADROCK HAM 4: Calculate the ratio between current Mag Factor and Target Factor. Used for the CTH bars.
+void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTime )
+{
+ OBJECTTYPE *pWeapon = &(pSoldier->inv[pSoldier->ubAttackingHand]);
+
+ FLOAT iActualMagFactor = 0;
+ FLOAT iHighestMagFactor = 0;
+ FLOAT iScopeFactor = 0;
+ FLOAT iProjectionFactor = 0;
+ FLOAT iTargetMagFactor = 0;
+ BOOLEAN isScopeBetter = FALSE;
+
+ // Calculate the optimal magnification that would be required for the target's current distance.
+ iTargetMagFactor = d2DDistance / gGameCTHConstants.NORMAL_SHOOTING_DISTANCE;
+
+ if (bAimTime > 0)
+ {
+ iScopeFactor = GetBestScopeMagnificationFactor( pWeapon, (UINT32)d2DDistance );
+ // Set a display variable
+ gCTHDisplay.ScopeMagFactor = iScopeFactor;
+
+ iScopeFactor = __min(iScopeFactor, iTargetMagFactor);
+ iProjectionFactor = GetProjectionFactor( pWeapon );
+
+ // Set a display variable
+ gCTHDisplay.ProjectionFactor = iProjectionFactor;
+
+ // The final factor is the largest of the two.
+
+ if (iScopeFactor > iProjectionFactor)
+ isScopeBetter=TRUE;
+
+ iHighestMagFactor = __max( iScopeFactor, iProjectionFactor );
+ }
+ else
+ {
+ gCTHDisplay.ScopeMagFactor = 1.0;
+ gCTHDisplay.ProjectionFactor = 1.0;
+ iHighestMagFactor = 1.0;
+ }
+
+ gCTHDisplay.FinalMagFactor = iHighestMagFactor;
+
+}
diff --git a/Tactical/Weapons.h b/Tactical/Weapons.h
index d1d57b6a..98443c8f 100644
--- a/Tactical/Weapons.h
+++ b/Tactical/Weapons.h
@@ -250,7 +250,7 @@ enum
#define AIM_PENALTY_TARGET_PRONE 40
#define AIM_PENALTY_BLIND 80
#define AIM_PENALTY_FIRING_UP 25
-#define HIGH_POWER_SCOPE 14
+//#define HIGH_POWER_SCOPE 14 //Externalized
#define MAX_WEAPON_NAME_LENGTH 20
@@ -268,7 +268,8 @@ typedef struct
UINT8 ubBulletSpeed; // bullet's travelling speed
UINT8 ubImpact; // weapon's max damage impact (size & speed)
UINT8 ubDeadliness; // comparative ratings of guns
- INT8 bAccuracy; // accuracy or penalty
+ INT8 bAccuracy; // accuracy or penalty used by OCTH
+ INT8 nAccuracy; // accuracy or penalty used by NCTH
UINT8 ubMagSize;
UINT16 usRange;
UINT16 usReloadDelay;
@@ -294,6 +295,17 @@ typedef struct
INT16 sAniDelay; // Lesh: for burst animation delay
UINT8 APsToReloadManually;
UINT16 ManualReloadSound;
+ BOOLEAN EasyUnjam; // Guns where each bullet has its own chamber (like revolvers) are easyer to unjam
+
+ INT8 bRecoilX; // HEADROCK HAM 4: Recoil now measured in points of muzzle deviation X and Y.
+ INT8 bRecoilY; // Positive values indicated upwards (Y) and rightwards (X). Negatives are down (-Y) and left (-X).
+ // Note that each value is an array. Each item in the array determines recoil
+ // for a different bullet in the sequence. Not all values have to be filled,
+ // but the last filled value will determine the recoil for longer volleys.
+ UINT8 ubRecoilDelay;
+
+ UINT8 ubAimLevels; // HEADROCK HAM 4: Dictates how many aiming levels this gun supports. If 0, the program
+ // chooses automatically based on the type of gun (see AllowedAimingLevels() ).
} WEAPONTYPE;
typedef struct
@@ -326,6 +338,7 @@ typedef struct
UINT32 uiIndex;
UINT16 ubDuration;
UINT16 ubStartRadius;
+ UINT8 ubMagSize;
} EXPLOSIVETYPE;
//GLOBALS
@@ -340,6 +353,9 @@ extern AMMOTYPE AmmoTypes[MAXITEMS];
extern BOOLEAN ReadInWeaponStats(STR fileName);
extern BOOLEAN WriteWeaponStats();
+extern bool gbForceWeaponNotReady;
+extern bool gbForceWeaponReady;
+
extern INT32 EffectiveArmour( OBJECTTYPE * pObj );
extern INT8 ArmourVersusExplosivesPercent( SOLDIERTYPE * pSoldier );
extern BOOLEAN FireWeapon( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo );
@@ -350,6 +366,7 @@ extern INT32 BulletImpact( SOLDIERTYPE *pFirer, SOLDIERTYPE * pTarget, UINT8 ubH
extern BOOLEAN InRange( SOLDIERTYPE *pSoldier, INT32 sGridNo );
extern void ShotMiss( UINT8 ubAttackerID, INT32 iBullet );
extern UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos );
+extern UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos );
extern UINT32 AICalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, UINT8 ubAimPos );
extern UINT32 CalcChanceToPunch(SOLDIERTYPE *pAttacker, SOLDIERTYPE * pDefender, INT16 ubAimTime);
extern UINT32 CalcChanceToStab(SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAimTime);
@@ -382,15 +399,18 @@ void DishoutQueenSwipeDamage( SOLDIERTYPE *pQueenSoldier );
INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BOOLEAN fBladeAttack );
-UINT16 GunRange( OBJECTTYPE * pObj );
+UINT16 GunRange( OBJECTTYPE * pObj, SOLDIERTYPE * pSoldier ); // SANDRO - added argument
BOOLEAN IsWeapon ( UINT16 itemIndex );
UINT8 GetDamage ( OBJECTTYPE *pObj );
+// HEADROCK HAM 4: Same function as above, but without modifiers from attached items.
+UINT8 GetBasicDamage ( OBJECTTYPE *pObj );
UINT8 GetAutofireShotsPerFiveAPs( OBJECTTYPE *pObj );
UINT8 GetBaseAutoFireCost( OBJECTTYPE *pObj );
UINT8 GetBurstPenalty( OBJECTTYPE *pObj, BOOLEAN fProneStance = FALSE );
UINT8 GetAutoPenalty( OBJECTTYPE *pObj, BOOLEAN fProneStance = FALSE );
UINT8 GetShotsPerBurst( OBJECTTYPE *pObj );
-UINT16 GetMagSize( OBJECTTYPE *pObj );
+UINT16 GetMagSize( OBJECTTYPE *pObj, UINT8 subObject = 0 );
+UINT16 GetExpMagSize( OBJECTTYPE *pObj );
UINT8 GetAmmoType( OBJECTTYPE *pObj );
bool WeaponReady(SOLDIERTYPE * pSoldier);
INT8 GetAPsToReload( OBJECTTYPE *pObj );
@@ -400,5 +420,9 @@ INT8 GetAPsToReload( OBJECTTYPE *pObj );
void EstimateBulletsLeft( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj );
extern CHAR16 gBulletCount[10];
+// HEADROCK HAM 4: This function generates a mag-factor bar percentage.
+void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTime );
+// HEADROCK HAM 4: This gets the Z of a target regardless of what's there.
+FLOAT GetTargetZPos( SOLDIERTYPE *pShooter, INT32 sTargetGridNo );
#endif
diff --git a/Tactical/World Items.h b/Tactical/World Items.h
index 3f69b753..1be0dc4c 100644
--- a/Tactical/World Items.h
+++ b/Tactical/World Items.h
@@ -43,6 +43,7 @@ public:
bool operator<(WORLDITEM& compare);
BOOLEAN Save( HWFILE hFile, bool fSavingMap );
BOOLEAN Load( HWFILE hFile );
+ BOOLEAN Load( HWFILE hFile, float dMajorMapVersion, UINT8 ubMinorMapVersion );
BOOLEAN Load( INT8** hBuffer, float dMajorMapVersion, UINT8 ubMinorMapVersion );
void initialize();
BOOLEAN fExists;
diff --git a/Tactical/XML.h b/Tactical/XML.h
index 584262ed..e2761513 100644
--- a/Tactical/XML.h
+++ b/Tactical/XML.h
@@ -4,7 +4,10 @@
#include "armsdealerinvinit.h"
#include "EnemyItemDrops.h"
#include "Loading Screen.h"
-
+#include "faces.h"
+#include "Interface.h"
+#include "XML_SenderNameList.h"
+#include "qarray.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -16,6 +19,8 @@ enum
ELEMENT_LIST,
ELEMENT,
ELEMENT_PROPERTY,
+ ELEMENT_SUBLIST,
+ ELEMENT_SUBLIST_PROPERTY,
// For new merchant inventory
MERCHANT_CONTROL,
@@ -37,7 +42,7 @@ typedef PARSE_STAGE;
#define POLISH_PREFIX "Polish."
#define FRENCH_PREFIX "French."
#define ITALIAN_PREFIX "Italian."
-#define TAIWANESE_PREFIX "Tiawanese."
+#define TAIWANESE_PREFIX "Taiwanese."
#define CHINESE_PREFIX "Chinese."
#define ATTACHMENTSFILENAME "Attachments.xml"
@@ -54,6 +59,7 @@ typedef PARSE_STAGE;
#define AMMOFILENAME "AmmoStrings.xml"
#define AMMOTYPESFILENAME "AmmoTypes.xml"
#define INCOMPATIBLEATTACHMENTSFILENAME "IncompatibleAttachments.xml"
+#define ATTACHMENTSLOTSFILENAME "AttachmentSlots.xml"
#define ENEMYGUNCHOICESFILENAME "EnemyGunChoices.xml"
#define ENEMYITEMCHOICESFILENAME "EnemyItemChoices.xml"
#define IMPITEMCHOICESFILENAME "IMPItemChoices.xml"
@@ -69,7 +75,7 @@ typedef PARSE_STAGE;
#define KEITHINVENTORYFILENAME "NPCInventory\\KeithInventory.xml"
#define SAMINVENTORYFILENAME "NPCInventory\\SamInventory.xml"
#define JAKEINVENTORYFILENAME "NPCInventory\\JakeInventory.xml"
-#define HOWARDINVENTORYFILENAME "NPCInventory\\HowardInventory.xml"
+#define HOWARDINVENTORYFILENAME "NPCInventory\\HowardInventory.xml"
#define GABBYINVENTORYFILENAME "NPCInventory\\GabbyInventory.xml"
#define FRANKINVENTORYFILENAME "NPCInventory\\FrankInventory.xml"
#define ELGININVENTORYFILENAME "NPCInventory\\ElginInventory.xml"
@@ -78,16 +84,16 @@ typedef PARSE_STAGE;
#define PETERINVENTORYFILENAME "NPCInventory\\PeterInventory.xml"
#define ALBERTOINVENTORYFILENAME "NPCInventory\\AlbertoInventory.xml"
#define CARLOINVENTORYFILENAME "NPCInventory\\CarloInventory.xml"
-#define MICKEYINVENTORYFILENAME "NPCInventory\\MickeyInventory.xml"
+#define MICKEYINVENTORYFILENAME "NPCInventory\\MickeyInventory.xml"
#define ARNIEINVENTORYFILENAME "NPCInventory\\ArnieInventory.xml"
#define PERKOINVENTORYFILENAME "NPCInventory\\PerkoInventory.xml"
#define FREDOINVENTORYFILENAME "NPCInventory\\FredoInventory.xml"
-#define BOBBYRAYSTRINGSFILENAME "BobbyRayStrings.xml"
+#define BOBBYRAYSTRINGSFILENAME "BobbyRayStrings.xml"
#define AMMOCALIBERSTRINGSFILENAME "AmmoCaliberStrings.xml"
#define SOUNDSFILENAME "Sounds\\Sounds.xml"
-#define BURSTSOUNDSFILENAME "Sounds\\BurstSounds.xml"
+#define BURSTSOUNDSFILENAME "Sounds\\BurstSounds.xml"
#define EXPLOSIONDATAFILENAME "ExplosionData.xml"
@@ -96,20 +102,17 @@ typedef PARSE_STAGE;
#define ALTSECTORSFILENAME "Map\\AltSectors.xml"
#define SAMSITESFILENAME "Map\\SamSites.xml"
#define ROAMINGMILITIAFILENAME "Map\\RestrictedRoamingMilitia.xml"
-#define EXTRAITEMSFILENAME "Map\\A9_0_ExtraItems.xml"
-#define EXTRAITEMSFILENAME2 "Map\\A11_0_ExtraItems.xml"
-
-// Gotthard: Strategic Text Files [2007-10-19]
-#define STRATEGICSECTORNAMETEXTFILENAME "Map\\SectorNames.xml"
+#define EXTRAITEMSFILENAME "Map\\A9_0_ExtraItems" // ".xml" will be added @runtime
+#define EXTRAITEMSFILENAME2 "Map\\A11_0_ExtraItems" // ".xml" will be added @runtime
#define GARRISONFILENAME "Army\\GarrisonGroups.xml"
#define PATROLFILENAME "Army\\PatrolGroups.xml"
-#define COMPOSITIONFILENAME "Army\\ArmyComposition.xml"
+#define COMPOSITIONFILENAME "Army\\ArmyComposition.xml"
// WANNE: drops filename
#define ENEMYWEAPONDROPSFILENAME "EnemyWeaponDrops.xml"
#define ENEMYAMMODROPSFILENAME "EnemyAmmoDrops.xml"
-#define ENEMYEXPLOSIVEDROPSFILENAME "EnemyExplosiveDrops.xml"
+#define ENEMYEXPLOSIVEDROPSFILENAME "EnemyExplosiveDrops.xml"
#define ENEMYARMOURDROPSFILENAME "EnemyArmourDrops.xml"
#define ENEMYMISCDROPSFILENAME "EnemyMiscDrops.xml"
@@ -117,7 +120,7 @@ typedef PARSE_STAGE;
#define SECTORLOADSCREENSFILENAME "Map\\SectorLoadscreens.xml"
//zilpin: pellet spread patterns externalized in XML
-#define SPREADPATTERNSFILENAME "SpreadPatterns.xml"
+#define SPREADPATTERNSFILENAME "SpreadPatterns.xml"
#define DELIVERYMETHODSFILENAME "Map\\DeliveryMethods.xml"
// Dealtar: Shipping destinations and delivery methods
@@ -147,10 +150,45 @@ typedef PARSE_STAGE;
// HEADROCK PROFEX: Merc Opinions [2009-07-27]
#define MERCOPINIONSFILENAME "MercOpinions.xml"
// HEADROCK HAM 3.6: Bloodcat Placements [2009-07-31]
-#define BLOODCATPLACEMENTSFILENAME "Map\\BloodcatPlacements.xml"
+#define BLOODCATPLACEMENTSFILENAME "Map\\BloodcatPlacements.xml"
// HEADROCK HAM 3.6: Uniform Colors [2009-09-29]
#define UNIFORMCOLORSFILENAME "Army\\UniformColors.xml"
+//SMALL FACES
+#define RPCFACESSMALLFILENAME "RPCFacesSmall.xml"
+
+//Hidden Names
+#define HIDDENNAMESFILENAME "HiddenNames.xml"
+
+//Enemy Names
+#define ENEMYNAMESFILENAME "EnemyNames.xml"
+
+//Enemy RANK
+#define ENEMYRANKFILENAME "EnemyRank.xml"
+
+//CIV Names
+#define CIVGROUPNAMESFILENAME "CivGroupNames.xml"
+
+//Sender Name List
+#define SENDERNAMELISTFILENAME "SenderNameList.xml"
+
+
+#define IMPPORTRAITS "IMPPortraits.xml"
+
+#define SOUNDPROFILE "SoundsProfiles.xml"
+
+#define RANDOMSTATS "RandomStats.xml"
+
+#define SECTORLEVEL1NAMESFILENAME "Map\\SectorNamesLevel_1.xml"
+#define SECTORLEVEL2NAMESFILENAME "Map\\SectorNamesLevel_2.xml"
+#define SECTORLEVEL3NAMESFILENAME "Map\\SectorNamesLevel_3.xml"
+
+#define MERCAVAILABILITY "MercAvailability.xml"
+
+#define AIMAVAILABILITY "AimAvailability.xml"
+
+#define QUOTEARRAYFILENAME "MercQuote.xml"
+
extern BOOLEAN ReadInItemStats(STR fileName, BOOLEAN localizedVersion);
extern BOOLEAN WriteItemStats();
@@ -199,6 +237,9 @@ extern BOOLEAN WriteAmmoStats();
extern BOOLEAN WriteIncompatibleAttachmentStats();
extern BOOLEAN ReadInIncompatibleAttachmentStats(STR fileName);
+//WarmSteel - for New Attachment System
+extern BOOLEAN WriteAttachmentSlotsStats();
+extern BOOLEAN ReadInAttachmentSlotsStats(STR fileName);
extern BOOLEAN WriteExtendedArmyGunChoicesStats();
extern BOOLEAN ReadInExtendedArmyGunChoicesStats(STR fileName);
@@ -294,13 +335,13 @@ extern BOOLEAN ReadInSectorFacilities(STR fileName);
extern BOOLEAN ReadInDynamicRoamingRestrictions(STR fileName);
// HEADROCK HAM 3.5: Facility Types and bonuses
-extern BOOLEAN ReadInFacilityTypes(STR fileName);
+extern BOOLEAN ReadInFacilityTypes(STR fileName, BOOLEAN localizedVersion);
// HEADROCK HAM 3.6: Customized Sector Names
-extern BOOLEAN ReadInSectorNames(STR fileName);
+extern BOOLEAN ReadInSectorNames(STR fileName, BOOLEAN localizedVersion, INT8 Level );
// HEADROCK PROFEX: Merc Profiles
-extern BOOLEAN ReadInMercProfiles(STR fileName);
+extern BOOLEAN ReadInMercProfiles(STR fileName, BOOLEAN localizedVersion);
// HEADROCK PROFEX: Merc Opinions
extern BOOLEAN ReadInMercOpinions(STR fileName);
@@ -311,4 +352,41 @@ extern BOOLEAN ReadInBloodcatPlacements(STR fileName);
// HEADROCK HAM 3.6: Customized Uniform Colors
extern BOOLEAN ReadInUniforms(STR fileName);
+//Jazz Small Faces
+extern BOOLEAN ReadInSmallFacesStats(RPC_SMALL_FACE_VALUES *pSmallFaces, STR fileName);
+extern BOOLEAN WriteSmallFacesStats(RPC_SMALL_FACE_VALUES *pSmallFaces, STR fileName);
+
+//Hidden Names
+extern BOOLEAN ReadInHiddenNamesStats(HIDDEN_NAMES_VALUES *pHiddenNames, STR fileName);
+extern BOOLEAN WriteHiddenNamesStats(HIDDEN_NAMES_VALUES *pHiddenNames, STR fileName);
+extern void LoadHiddenNames();
+
+extern BOOLEAN ReadInEnemyNames(STR fileName, BOOLEAN localizedVersion);
+extern BOOLEAN ReadInCivGroupNamesStats(STR fileName, BOOLEAN localizedVersion);
+
+// the list of email sender names by Jazz
+extern BOOLEAN ReadInSenderNameList(STR fileName, BOOLEAN localizedVersion);
+extern BOOLEAN ReadInEnemyRank(STR fileName, BOOLEAN localizedVersion);
+extern BOOLEAN WriteEnemyRank( STR fileName);
+extern BOOLEAN ReadInIMPPortraits(STR fileName, BOOLEAN localizedVersion);
+extern void LoadIMPPortraitsTEMP();
+
+//Enabled\Disabled profile sound by Jazz
+extern BOOLEAN ReadInSoundProfile( STR fileName );
+extern BOOLEAN WriteSoundProfile( STR fileName );
+
+//Random stats by Jazz
+extern BOOLEAN WriteRandomStats( STR fileName );
+extern BOOLEAN ReadInRandomStats( STR fileName );
+
+//new profiles by Jazz
+extern BOOLEAN ReadInMercAvailability(STR fileName, BOOLEAN localizedVersion);
+extern BOOLEAN WriteMercAvailability(STR fileName);
+
+extern BOOLEAN ReadInAimAvailability(STR fileName, BOOLEAN localizedVersion);
+extern BOOLEAN WriteAimAvailability(STR fileName);
+
+extern BOOLEAN WriteQarray(QARRAY_VALUES *pQarray, STR fileName);
+extern BOOLEAN ReadInQarray(QARRAY_VALUES *pQarray, STR fileName);
+
#endif
diff --git a/Tactical/XML_AttachmentSlots.cpp b/Tactical/XML_AttachmentSlots.cpp
new file mode 100644
index 00000000..63ed4db9
--- /dev/null
+++ b/Tactical/XML_AttachmentSlots.cpp
@@ -0,0 +1,264 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "overhead.h"
+ #include "weapons.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+#endif
+
+UINT16 LAST_SLOT_INDEX = 0;
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+
+ AttachmentSlotStruct curAttachmentSlot;
+ AttachmentSlotStruct * curArray;
+
+ UINT32 maxArraySize;
+
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef attachmentslotParseData;
+
+static void XMLCALL
+attachmentslotStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ attachmentslotParseData * pData = (attachmentslotParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "ATTACHMENTSLOTLIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(AttachmentSlotStruct)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "ATTACHMENTSLOT") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curAttachmentSlot,0,sizeof(AttachmentSlotStruct));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiSlotIndex") == 0 ||
+ strcmp(name, "szSlotName") == 0 ||
+ strcmp(name, "nasAttachmentClass") == 0 ||
+ strcmp(name, "nasLayoutClass") == 0 ||
+ strcmp(name, "usDescPanelPosX") == 0 ||
+ strcmp(name, "usDescPanelPosY") == 0 ||
+ strcmp(name, "fMultiShot") == 0 ||
+ strcmp(name, "fBigSlot") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+attachmentslotCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ attachmentslotParseData * pData = (attachmentslotParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+attachmentslotEndElementHandle(void *userData, const XML_Char *name)
+{
+ attachmentslotParseData * pData = (attachmentslotParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "ATTACHMENTSLOTLIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "ATTACHMENTSLOT") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curAttachmentSlot.uiSlotIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curAttachmentSlot.uiSlotIndex] = pData->curAttachmentSlot; //write the attachmentinfo into the table
+ //Save the highest known index up till now.
+ if(LAST_SLOT_INDEX < pData->curAttachmentSlot.uiSlotIndex){
+ LAST_SLOT_INDEX = (UINT16) pData->curAttachmentSlot.uiSlotIndex;
+ }
+ }
+ }
+ else if(strcmp(name, "uiSlotIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.uiSlotIndex = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "szSlotName") == 0)
+ {
+ pData->curElement = ELEMENT;
+ MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curAttachmentSlot.szSlotName, sizeof(pData->curAttachmentSlot.szSlotName)/sizeof(pData->curAttachmentSlot.szSlotName[0]) );
+ pData->curAttachmentSlot.szSlotName[sizeof(pData->curAttachmentSlot.szSlotName)/sizeof(pData->curAttachmentSlot.szSlotName[0]) - 1] = '\0';
+ }
+ else if(strcmp(name, "nasAttachmentClass") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.nasAttachmentClass = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "nasLayoutClass") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.nasLayoutClass = (UINT128) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usDescPanelPosX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.usDescPanelPosX = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "usDescPanelPosY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.usDescPanelPosY = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "fMultiShot") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.fMultiShot = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "fBigSlot") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachmentSlot.fBigSlot = (BOOLEAN) atol(pData->szCharData);
+ }
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+BOOLEAN ReadInAttachmentSlotsStats(STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ attachmentslotParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading AttachmentSlots.xml" );
+
+ // Open attachmentinfo file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, attachmentslotStartElementHandle, attachmentslotEndElementHandle);
+ XML_SetCharacterDataHandler(parser, attachmentslotCharacterDataHandle);
+
+
+ // This should fix the crash in a Release Version with VS 2008
+ //memset(&pData,0,sizeof(pData));
+ pData.curElement = ELEMENT_NONE;
+ pData.szCharData[0] = 0;
+ pData.currentDepth = 0;
+ pData.maxReadDepth = 0;
+ pData.curArray = AttachmentSlots;
+ pData.maxArraySize = MAXITEMS;
+
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in AttachmentSlots.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+BOOLEAN WriteAttachmentSlotsStats()
+{
+ //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"writeattachmentslotstats");
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( "TABLEDATA\\AttachmentSlots out.xml", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < MAXITEMS;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].uiSlotIndex );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].szSlotName );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].nasAttachmentClass );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].nasLayoutClass );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].usDescPanelPosX );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].usDescPanelPosY );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].fMultiShot );
+ FilePrintf(hFile,"\t\t%d\r\n", AttachmentSlots[cnt].fBigSlot );
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
diff --git a/Tactical/XML_Attachments.cpp b/Tactical/XML_Attachments.cpp
index 2de3fa94..edda40d1 100644
--- a/Tactical/XML_Attachments.cpp
+++ b/Tactical/XML_Attachments.cpp
@@ -16,7 +16,7 @@ struct
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
- UINT16 curAttachment[3];
+ UINT16 curAttachment[4];
UINT32 maxArraySize;
UINT32 curIndex;
UINT32 currentDepth;
@@ -51,6 +51,7 @@ attachmentStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
else if(pData->curElement == ELEMENT &&
(strcmp(name, "attachmentIndex") == 0 ||
strcmp(name, "APCost") == 0 ||
+ strcmp(name, "NASOnly") == 0 ||
strcmp(name, "itemIndex") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
@@ -117,6 +118,11 @@ attachmentEndElementHandle(void *userData, const XML_Char *name)
pData->curAttachment[2] = (UINT16) atol(pData->szCharData);
pData->curAttachment[2] = (UINT16)DynamicAdjustAPConstants(pData->curAttachment[2], pData->curAttachment[2]);
}
+ else if(strcmp(name, "NASOnly") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curAttachment[3] = (UINT16) atol(pData->szCharData);
+ }
pData->maxReadDepth--;
}
@@ -209,6 +215,7 @@ BOOLEAN WriteAttachmentStats()
FilePrintf(hFile,"\t\t%d\r\n", Attachment[cnt][0]);
FilePrintf(hFile,"\t\t%d\r\n", Attachment[cnt][1]);
FilePrintf(hFile,"\t\t%d\r\n", Attachment[cnt][2]);
+ FilePrintf(hFile,"\t\t%d\r\n", Attachment[cnt][3]);
FilePrintf(hFile,"\t\r\n");
}
diff --git a/Tactical/XML_CivGroupNames.cpp b/Tactical/XML_CivGroupNames.cpp
new file mode 100644
index 00000000..ea38ff61
--- /dev/null
+++ b/Tactical/XML_CivGroupNames.cpp
@@ -0,0 +1,206 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+ #include "EditorMercs.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ CIV_NAMES_VALUES curCivGroupNames;
+ CIV_NAMES_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef civGroupNamesParseData;
+
+BOOLEAN CivGroupNames_TextOnly;
+
+static void XMLCALL
+civGroupNamesStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ civGroupNamesParseData * pData = (civGroupNamesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "CIV_GROUP_NAMES") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "NAME") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "Enabled") == 0 ||
+ strcmp(name, "Loyalty") == 0 ||
+ strcmp(name, "AddToBattle") == 0 ||
+ strcmp(name, "szGroup") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+civGroupNamesCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ civGroupNamesParseData * pData = (civGroupNamesParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+civGroupNamesEndElementHandle(void *userData, const XML_Char *name)
+{
+ civGroupNamesParseData * pData = (civGroupNamesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "CIV_GROUP_NAMES") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "NAME") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if (!CivGroupNames_TextOnly)
+ {
+ wcscpy(zCivGroupName[pData->curCivGroupNames.uiIndex].szCurGroup, pData->curCivGroupNames.szCurGroup);
+ zCivGroupName[pData->curCivGroupNames.uiIndex].Enabled = pData->curCivGroupNames.Enabled;
+
+ zCivGroupName[pData->curCivGroupNames.uiIndex].AddToBattle = pData->curCivGroupNames.AddToBattle;
+ zCivGroupName[pData->curCivGroupNames.uiIndex].Loyalty = pData->curCivGroupNames.Loyalty;
+ }
+ else
+ {
+ wcscpy(zCivGroupName[pData->curCivGroupNames.uiIndex].szCurGroup, pData->curCivGroupNames.szCurGroup);
+ }
+
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curCivGroupNames.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Enabled") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curCivGroupNames.Enabled = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Loyalty") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curCivGroupNames.Loyalty = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "AddToBattle") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curCivGroupNames.AddToBattle = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "szGroup") == 0 )
+ {
+ pData->curElement = ELEMENT;
+
+ MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curCivGroupNames.szCurGroup, sizeof(pData->curCivGroupNames.szCurGroup)/sizeof(pData->curCivGroupNames.szCurGroup[0]) );
+ pData->curCivGroupNames.szCurGroup[sizeof(pData->curCivGroupNames.szCurGroup)/sizeof(pData->curCivGroupNames.szCurGroup[0]) - 1] = '\0';
+
+ #ifdef JA2EDITOR
+ wcscpy(gszCivGroupNames[pData->curCivGroupNames.uiIndex], pData->curCivGroupNames.szCurGroup);
+ #endif
+
+ }
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInCivGroupNamesStats( STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ civGroupNamesParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading CivGroupNames.xml" );
+
+ CivGroupNames_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, civGroupNamesStartElementHandle, civGroupNamesEndElementHandle);
+ XML_SetCharacterDataHandler(parser, civGroupNamesCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in CivGroupNames.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_EnemyNames.cpp b/Tactical/XML_EnemyNames.cpp
new file mode 100644
index 00000000..8eb16beb
--- /dev/null
+++ b/Tactical/XML_EnemyNames.cpp
@@ -0,0 +1,205 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ ENEMY_NAMES_VALUES curEnemyNames;
+ ENEMY_NAMES_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+ CHAR16 gzEnemyNames[MAX_ENEMY_NAMES_CHARS];
+}
+typedef enemyNamesParseData;
+
+BOOLEAN EnemyName_TextOnly;
+
+static void XMLCALL
+enemyNamesStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ enemyNamesParseData * pData = (enemyNamesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "ENEMY_NAMES") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "NAME") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "Sector") == 0 ||
+ strcmp(name, "Enabled") == 0 ||
+ strcmp(name, "szGroup") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+enemyNamesCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ enemyNamesParseData * pData = (enemyNamesParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+enemyNamesEndElementHandle(void *userData, const XML_Char *name)
+{
+ enemyNamesParseData * pData = (enemyNamesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth)
+ {
+ if(strcmp(name, "ENEMY_NAMES") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "NAME") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if (!EnemyName_TextOnly)
+ {
+ wcscpy(zEnemyName[pData->curEnemyNames.uiIndex].szCurGroup, pData->curEnemyNames.szCurGroup);
+ zEnemyName[pData->curEnemyNames.uiIndex].Enabled = pData->curEnemyNames.Enabled;
+ zEnemyName[pData->curEnemyNames.uiIndex].SectorX = pData->curEnemyNames.SectorX;
+ zEnemyName[pData->curEnemyNames.uiIndex].SectorY = pData->curEnemyNames.SectorY;
+ }
+ else
+ {
+ wcscpy(zEnemyName[pData->curEnemyNames.uiIndex].szCurGroup, pData->curEnemyNames.szCurGroup);
+ }
+
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyNames.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Enabled") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyNames.Enabled = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Sector") == 0 )
+ {
+ UINT8 x, y;
+ pData->curElement = ELEMENT;
+
+ y = (UINT8)pData->szCharData[0] & 0x1F;
+ x = (UINT8)atol(&pData->szCharData[1]);
+ if ( x > 0 && x <= 16 && y > 0 && y <= 16 )
+ {
+ pData->curEnemyNames.SectorX = x;
+ pData->curEnemyNames.SectorY = y;
+ }
+ }
+ else if(strcmp(name, "szGroup") == 0 )
+ {
+ pData->curElement = ELEMENT;
+
+ MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curEnemyNames.szCurGroup, sizeof(pData->curEnemyNames.szCurGroup)/sizeof(pData->curEnemyNames.szCurGroup[0]) );
+ pData->curEnemyNames.szCurGroup[sizeof(pData->curEnemyNames.szCurGroup)/sizeof(pData->curEnemyNames.szCurGroup[0]) - 1] = '\0';
+ }
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInEnemyNames(STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ enemyNamesParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyNames.xml" );
+
+ EnemyName_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, enemyNamesStartElementHandle, enemyNamesEndElementHandle);
+ XML_SetCharacterDataHandler(parser, enemyNamesCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyNames.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
diff --git a/Tactical/XML_EnemyRank.cpp b/Tactical/XML_EnemyRank.cpp
new file mode 100644
index 00000000..9980970b
--- /dev/null
+++ b/Tactical/XML_EnemyRank.cpp
@@ -0,0 +1,247 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ ENEMY_RANK_VALUES curEnemyRank;
+ ENEMY_RANK_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+ CHAR16 gzEnemyRank[MAX_ENEMY_NAMES_CHARS];
+}
+typedef enemyRankParseData;
+
+BOOLEAN EnemyRank_TextOnly;
+
+static void XMLCALL
+enemyRankStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ enemyRankParseData * pData = (enemyRankParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "ENEMY_RANK") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "RANK") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "ExpLevel") == 0 ||
+ strcmp(name, "Stats") == 0 ||
+ strcmp(name, "StatsMin") == 0 ||
+ strcmp(name, "StatsMax") == 0 ||
+ strcmp(name, "Enabled") == 0 ||
+ strcmp(name, "szRank") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+enemyRankCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ enemyRankParseData * pData = (enemyRankParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+enemyRankEndElementHandle(void *userData, const XML_Char *name)
+{
+ enemyRankParseData * pData = (enemyRankParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth)
+ {
+ if(strcmp(name, "ENEMY_RANK") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "RANK") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if (!EnemyRank_TextOnly)
+ {
+ wcscpy(zEnemyRank[pData->curEnemyRank.uiIndex].szCurRank, pData->curEnemyRank.szCurRank);
+ zEnemyRank[pData->curEnemyRank.uiIndex].Enabled = pData->curEnemyRank.Enabled;
+ zEnemyRank[pData->curEnemyRank.uiIndex].Stats = pData->curEnemyRank.Stats;
+ zEnemyRank[pData->curEnemyRank.uiIndex].StatsMax = pData->curEnemyRank.StatsMax;
+ zEnemyRank[pData->curEnemyRank.uiIndex].StatsMin = pData->curEnemyRank.StatsMin;
+ zEnemyRank[pData->curEnemyRank.uiIndex].ExpLevel = pData->curEnemyRank.ExpLevel;
+ }
+ else
+ {
+ wcscpy(zEnemyRank[pData->curEnemyRank.uiIndex].szCurRank, pData->curEnemyRank.szCurRank);
+ }
+
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyRank.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Enabled") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyRank.Enabled = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ExpLevel") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyRank.ExpLevel = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Stats") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyRank.Stats = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "StatsMax") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyRank.StatsMax = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "StatsMin") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curEnemyRank.StatsMin = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "szRank") == 0 )
+ {
+ pData->curElement = ELEMENT;
+
+ MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curEnemyRank.szCurRank, sizeof(pData->curEnemyRank.szCurRank)/sizeof(pData->curEnemyRank.szCurRank[0]) );
+ pData->curEnemyRank.szCurRank[sizeof(pData->curEnemyRank.szCurRank)/sizeof(pData->curEnemyRank.szCurRank[0]) - 1] = '\0';
+ }
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInEnemyRank(STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ enemyRankParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading EnemyRank.xml" );
+
+ EnemyRank_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, enemyRankStartElementHandle, enemyRankEndElementHandle);
+ XML_SetCharacterDataHandler(parser, enemyRankCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in EnemyRank.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+
+BOOLEAN WriteEnemyRank( STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < 500;cnt++)
+ {
+ FilePrintf(hFile,"\t\r\n");
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", zEnemyRank[cnt].Enabled);
+ FilePrintf(hFile,"\t\t%d\r\n", zEnemyRank[cnt].ExpLevel);
+ FilePrintf(hFile,"\t\t%d\r\n", zEnemyRank[cnt].Stats);
+ FilePrintf(hFile,"\t\t%d\r\n", zEnemyRank[cnt].StatsMax);
+ FilePrintf(hFile,"\t\t%d\r\n", zEnemyRank[cnt].StatsMin);
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
diff --git a/Tactical/XML_Explosive.cpp b/Tactical/XML_Explosive.cpp
index cc1a7a68..2ff644b2 100644
--- a/Tactical/XML_Explosive.cpp
+++ b/Tactical/XML_Explosive.cpp
@@ -55,6 +55,7 @@ explosiveStartElementHandle(void *userData, const XML_Char *name, const XML_Char
strcmp(name, "ubVolume") == 0 ||
strcmp(name, "ubVolatility") == 0 ||
strcmp(name, "ubStartRadius") == 0 ||
+ strcmp(name, "ubMagSize") == 0 ||
strcmp(name, "ubDuration") == 0 ||
strcmp(name, "ubAnimationID") == 0 ))
{
@@ -148,6 +149,11 @@ explosiveEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curExplosive.ubStartRadius = (UINT8) atol(pData->szCharData);
}
+ else if(strcmp(name, "ubMagSize") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curExplosive.ubMagSize = (UINT8) atol(pData->szCharData);
+ }
else if(strcmp(name, "ubDuration") == 0)
{
pData->curElement = ELEMENT;
@@ -255,6 +261,7 @@ BOOLEAN WriteExplosiveStats()
FilePrintf(hFile,"\t\t%d\r\n", Explosive[cnt].ubAnimationID );
FilePrintf(hFile,"\t\t%d\r\n", Explosive[cnt].ubDuration );
FilePrintf(hFile,"\t\t%d\r\n", Explosive[cnt].ubStartRadius );
+ FilePrintf(hFile,"\t\t%d\r\n", Explosive[cnt].ubMagSize );
FilePrintf(hFile,"\t\r\n");
}
diff --git a/Tactical/XML_HiddenNames.cpp b/Tactical/XML_HiddenNames.cpp
new file mode 100644
index 00000000..b072905b
--- /dev/null
+++ b/Tactical/XML_HiddenNames.cpp
@@ -0,0 +1,219 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ HIDDEN_NAMES_VALUES curHiddenNames;
+ HIDDEN_NAMES_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef hiddenNamesParseData;
+
+static void XMLCALL
+hiddenNamesStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ hiddenNamesParseData * pData = (hiddenNamesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "HIDDENNAMES") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(HIDDEN_NAMES_VALUES)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "NAME") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curHiddenNames,0,sizeof(HIDDEN_NAMES_VALUES));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "Hidden") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+hiddenNamesCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ hiddenNamesParseData * pData = (hiddenNamesParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+hiddenNamesEndElementHandle(void *userData, const XML_Char *name)
+{
+ hiddenNamesParseData * pData = (hiddenNamesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "HIDDENNAMES") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "NAME") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curHiddenNames.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curHiddenNames.uiIndex] = pData->curHiddenNames; //write the hidden names into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curHiddenNames.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Hidden") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curHiddenNames.Hidden = (BOOLEAN) atol(pData->szCharData);
+ }
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInHiddenNamesStats(HIDDEN_NAMES_VALUES *pHiddenNames, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ hiddenNamesParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading HiddenNames.xml" );
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, hiddenNamesStartElementHandle, hiddenNamesEndElementHandle);
+ XML_SetCharacterDataHandler(parser, hiddenNamesCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pHiddenNames;
+ pData.maxArraySize = 500;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in HiddenNames.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+BOOLEAN WriteHiddenNamesStats(HIDDEN_NAMES_VALUES *pHiddenNames, STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < 500;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pHiddenNames[cnt].Hidden);
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
+
+//Restart Game and New Game
+void LoadHiddenNames()
+{
+ char fileName[MAX_PATH];
+
+ strcpy(fileName, TABLEDATA_DIRECTORY);
+ strcat(fileName, HIDDENNAMESFILENAME);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName));
+ SGP_THROW_IFFALSE(ReadInHiddenNamesStats(zHiddenNames,fileName), HIDDENNAMESFILENAME);
+}
\ No newline at end of file
diff --git a/Tactical/XML_MercStartingGear.cpp b/Tactical/XML_MercStartingGear.cpp
index e8e15b6b..99496899 100644
--- a/Tactical/XML_MercStartingGear.cpp
+++ b/Tactical/XML_MercStartingGear.cpp
@@ -16,7 +16,9 @@ struct
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
MERCPROFILEGEAR curMercStartingGear;
- MERCPROFILEGEAR * curArray;
+ MERCPROFILEGEAR (*curArray)[NUM_MERCSTARTINGGEAR_KITS];
+ UINT8 curIndex; // Holds the number of the current profile for whom we're reading gear.
+ UINT8 curGears; // Holds the number of gears read so far for one index number.
UINT32 maxArraySize;
UINT32 currentDepth;
@@ -39,6 +41,8 @@ MercStartingGearStartElementHandle(void *userData, const XML_Char *name, const X
//memset(pData->curArray,0,sizeof(MERCPROFILEGEAR)*pData->maxArraySize);
pData->maxReadDepth++; //we are not skipping this element
+
+ pData->curIndex = 0;
}
else if(strcmp(name, "MERCGEAR") == 0 && pData->curElement == ELEMENT_LIST)
{
@@ -48,10 +52,25 @@ MercStartingGearStartElementHandle(void *userData, const XML_Char *name, const X
//memset(&pData->curMercStartingGear,0,sizeof(MERCPROFILEGEAR));
pData->maxReadDepth++; //we are not skipping this element
+
+ pData->curGears = 0;
}
else if(pData->curElement == ELEMENT &&
- (strcmp(name, "mIndex") == 0 ||
- strcmp(name, "mName") == 0 ||
+ (strcmp(name, "mIndex") == 0 ||
+ strcmp(name, "mName") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++;
+ }
+ else if(strcmp(name, "GEARKIT") == 0 && pData->curElement == ELEMENT)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+
+ pData->maxReadDepth++;
+ }
+ else if(pData->curElement == ELEMENT_SUBLIST &&
+ (strcmp(name, "mPriceMod") == 0 ||
strcmp(name, "mHelmet") == 0 ||
strcmp(name, "mHelmetStatus") == 0 ||
strcmp(name, "mHelmetDrop") == 0 ||
@@ -115,7 +134,7 @@ MercStartingGearStartElementHandle(void *userData, const XML_Char *name, const X
strcmp(name, "lBPack") == 0 ||
strcmp(name, "lBPackStatus") == 0 ))
{
- pData->curElement = ELEMENT_PROPERTY;
+ pData->curElement = ELEMENT_SUBLIST_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
@@ -155,16 +174,12 @@ MercStartingGearEndElementHandle(void *userData, const XML_Char *name)
else if(strcmp(name, "MERCGEAR") == 0)
{
pData->curElement = ELEMENT_LIST;
-
- if(pData->curMercStartingGear.mIndex < pData->maxArraySize)
- {
- pData->curArray[pData->curMercStartingGear.mIndex] = pData->curMercStartingGear; //write the armour into the table
- }
}
else if(strcmp(name, "mIndex") == 0)
{
pData->curElement = ELEMENT;
pData->curMercStartingGear.mIndex = (UINT16) atol(pData->szCharData);
+ pData->curIndex = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "mName") == 0)
{
@@ -183,314 +198,331 @@ MercStartingGearEndElementHandle(void *userData, const XML_Char *name)
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("itemEndElementHandle: itemname[%d] = %s, temp = %s",i,&pData->curItem.szItemName[i],&temp));
}
}
+ else if(strcmp(name, "GEARKIT") == 0 )
+ {
+ // Write the gear into memory.
+ if(pData->curIndex < pData->maxArraySize && pData->curGears < NUM_MERCSTARTINGGEAR_KITS)
+ {
+ pData->curArray[pData->curIndex][pData->curGears] = pData->curMercStartingGear; //write the armour into the table
+ }
+
+ pData->curElement = ELEMENT;
+ // Increase the number of gears read.
+ pData->curGears++;
+ }
+ else if(strcmp(name, "mPriceMod") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curMercStartingGear.PriceModifier = (int) atol(pData->szCharData);
+ }
else if(strcmp(name, "mHelmet") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[HELMETPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mVest") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[VESTPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mLeg") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[LEGPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mWeapon") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[HANDPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig0") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[BIGPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig1") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[BIGPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig2") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[BIGPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig3") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[BIGPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall0") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall1") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall2") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall3") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall4") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK5POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall5") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK6POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall6") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK7POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall7") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.inv[SMALLPOCK8POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mHelmetStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[HELMETPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mVestStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[VESTPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mLegStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[LEGPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mWeaponStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[HANDPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig0Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[BIGPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig1Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[BIGPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig2Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[BIGPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig3Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[BIGPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall0Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall1Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall2Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall3Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall4Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK5POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall5Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK6POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall6Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK7POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall7Status") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iStatus[SMALLPOCK8POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mHelmetDrop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[HELMETPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mVestDrop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[VESTPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mLegDrop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[LEGPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mWeaponDrop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[HANDPOS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig0Drop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[BIGPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig1Drop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[BIGPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig2Drop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[BIGPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig3Drop") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iDrop[BIGPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig0Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[BIGPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig1Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[BIGPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig2Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[BIGPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mBig3Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[BIGPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall0Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK1POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall1Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK2POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall2Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK3POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall3Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK4POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall4Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK5POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall5Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK6POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall6Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK7POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "mSmall7Quantity") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.iNumber[SMALLPOCK8POS] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lVest") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lbe[0] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lLeftThigh") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lbe[1] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lRightThigh") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lbe[2] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lCPack") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lbe[3] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lBPack") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lbe[4] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lVestStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lStatus[0] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lLeftThighStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lStatus[1] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lRightThighStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lStatus[2] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lCPackStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lStatus[3] = (int) atol(pData->szCharData);
}
else if(strcmp(name, "lBPackStatus") == 0)
{
- pData->curElement = ELEMENT;
+ pData->curElement = ELEMENT_SUBLIST;
pData->curMercStartingGear.lStatus[4] = (int) atol(pData->szCharData);
}
@@ -540,14 +572,19 @@ BOOLEAN ReadInMercStartingGearStats(STR fileName)
memset(&pData,0,sizeof(pData));
+
pData.curArray = gMercProfileGear;
+
pData.maxArraySize = NUM_PROFILES;
XML_SetUserData(parser, &pData);
for(int i=0; i\r\n");
@@ -588,18 +627,17 @@ BOOLEAN WriteMercStartingGearStats()
{
FilePrintf(hFile,"\t\r\n");
-
FilePrintf(hFile,"\t\t%d\r\n", cnt );
-// FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].mName );
+ //FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].mName );
int j = -1;
for (int i=0;i<80;i++)
{
j++;
- if ( i<(int)strlen(gMercProfileGear[cnt].mName))
+ if ( i<(int)strlen(gMercProfileGear[cnt][gearkit].mName))
{
- str[i] = gMercProfileGear[cnt].mName [j];
+ str[i] = gMercProfileGear[cnt][gearkit].mName [j];
}
else
{
@@ -651,69 +689,71 @@ BOOLEAN WriteMercStartingGearStats()
}
}
FilePrintf(hFile,"\r\n");
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[HELMETPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[VESTPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[LEGPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[HANDPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[HELMETPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[VESTPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[LEGPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[HANDPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[HELMETPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[VESTPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[LEGPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[HANDPOS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[BIGPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[BIGPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[BIGPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[BIGPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[BIGPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[BIGPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[BIGPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[BIGPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[BIGPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[BIGPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[BIGPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[BIGPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[BIGPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[BIGPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[BIGPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iDrop[BIGPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK5POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK6POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK7POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].inv[SMALLPOCK8POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK5POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK6POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK7POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iNumber[SMALLPOCK8POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK1POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK2POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK3POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK4POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK5POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK6POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK7POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].iStatus[SMALLPOCK8POS] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lbe[0] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lbe[1] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lbe[2] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lbe[3] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lbe[4] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lStatus[0] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lStatus[1] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lStatus[2] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lStatus[3] );
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt].lStatus[4] );
-
+ for(gearkit = 0; gearkit < NUM_MERCSTARTINGGEAR_KITS; gearkit++)
+ {
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[HELMETPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[VESTPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[LEGPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[HANDPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[HELMETPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[VESTPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[LEGPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[HANDPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[HELMETPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[VESTPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[LEGPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[HANDPOS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[BIGPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[BIGPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[BIGPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[BIGPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[BIGPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[BIGPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[BIGPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[BIGPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[BIGPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[BIGPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[BIGPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[BIGPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[BIGPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[BIGPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[BIGPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iDrop[BIGPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK5POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK6POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK7POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].inv[SMALLPOCK8POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK5POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK6POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK7POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iNumber[SMALLPOCK8POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK1POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK2POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK3POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK4POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK5POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK6POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK7POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].iStatus[SMALLPOCK8POS] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lbe[0] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lbe[1] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lbe[2] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lbe[3] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lbe[4] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lStatus[0] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lStatus[1] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lStatus[2] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lStatus[3] );
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfileGear[cnt][gearkit].lStatus[4] );
+ }
FilePrintf(hFile,"\t\r\n");
}
FilePrintf(hFile,"\r\n");
@@ -722,3 +762,4 @@ BOOLEAN WriteMercStartingGearStats()
return( TRUE );
}
+*/
diff --git a/Tactical/XML_Profiles.cpp b/Tactical/XML_Profiles.cpp
index 189eaaec..e2a2f65b 100644
--- a/Tactical/XML_Profiles.cpp
+++ b/Tactical/XML_Profiles.cpp
@@ -20,7 +20,7 @@
#include "XML.h"
#include "Soldier Profile.h"
#endif
-
+ #include "Soldier Profile.h"
//#define MAX_PROFILE_NAME_LENGTH 30
struct
@@ -39,7 +39,7 @@ typedef profileParseData;
TEMPPROFILETYPE tempProfiles[NUM_PROFILES+1];
-
+BOOLEAN MercProfiles_TextOnly;
static void XMLCALL
profileStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
@@ -87,7 +87,8 @@ profileStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
strcmp(name, "ubBodyType") == 0 ||
strcmp(name, "uiBodyTypeSubFlags") == 0 ||
strcmp(name, "bAttitude") == 0 ||
- strcmp(name, "bPersonalityTrait") == 0 ||
+ strcmp(name, "bCharacterTrait") == 0 || // added by SANDRO
+ strcmp(name, "bDisability") == 0 ||
strcmp(name, "ubNeedForSleep") == 0 ||
strcmp(name, "bReputationTolerance") == 0 ||
strcmp(name, "bDeathRate") == 0 ||
@@ -104,8 +105,40 @@ profileStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
strcmp(name, "bMechanical") == 0 ||
strcmp(name, "bExpLevel") == 0 ||
strcmp(name, "bEvolution") == 0 ||
- strcmp(name, "bSkillTrait") == 0 ||
- strcmp(name, "bSkillTrait2") == 0 ||
+ // added by SANDRO
+ strcmp(name, "bOldSkillTrait") == 0 ||
+ strcmp(name, "bOldSkillTrait2") == 0 ||
+ strcmp(name, "bNewSkillTrait1") == 0 ||
+ strcmp(name, "bNewSkillTrait2") == 0 ||
+ strcmp(name, "bNewSkillTrait3") == 0 ||
+ strcmp(name, "bNewSkillTrait4") == 0 ||
+ strcmp(name, "bNewSkillTrait5") == 0 ||
+ strcmp(name, "bNewSkillTrait6") == 0 ||
+ strcmp(name, "bNewSkillTrait7") == 0 ||
+ strcmp(name, "bNewSkillTrait8") == 0 ||
+ strcmp(name, "bNewSkillTrait9") == 0 ||
+ strcmp(name, "bNewSkillTrait10") == 0 ||
+ strcmp(name, "bNewSkillTrait11") == 0 ||
+ strcmp(name, "bNewSkillTrait12") == 0 ||
+ strcmp(name, "bNewSkillTrait13") == 0 ||
+ strcmp(name, "bNewSkillTrait14") == 0 ||
+ strcmp(name, "bNewSkillTrait15") == 0 ||
+ strcmp(name, "bNewSkillTrait16") == 0 ||
+ strcmp(name, "bNewSkillTrait17") == 0 ||
+ strcmp(name, "bNewSkillTrait18") == 0 ||
+ strcmp(name, "bNewSkillTrait19") == 0 ||
+ strcmp(name, "bNewSkillTrait20") == 0 ||
+ strcmp(name, "bNewSkillTrait21") == 0 ||
+ strcmp(name, "bNewSkillTrait22") == 0 ||
+ strcmp(name, "bNewSkillTrait23") == 0 ||
+ strcmp(name, "bNewSkillTrait24") == 0 ||
+ strcmp(name, "bNewSkillTrait25") == 0 ||
+ strcmp(name, "bNewSkillTrait26") == 0 ||
+ strcmp(name, "bNewSkillTrait27") == 0 ||
+ strcmp(name, "bNewSkillTrait28") == 0 ||
+ strcmp(name, "bNewSkillTrait29") == 0 ||
+ strcmp(name, "bNewSkillTrait30") == 0 ||
+
strcmp(name, "bBuddy1") == 0 ||
strcmp(name, "bBuddy2") == 0 ||
strcmp(name, "bBuddy3") == 0 ||
@@ -137,7 +170,17 @@ profileStartElementHandle(void *userData, const XML_Char *name, const XML_Char *
strcmp(name, "usApproachFactorFriendly") == 0 ||
strcmp(name, "usApproachFactorDirect") == 0 ||
strcmp(name, "usApproachFactorThreaten") == 0 ||
- strcmp(name, "usApproachFactorRecruit") == 0
+ strcmp(name, "usApproachFactorRecruit") == 0 ||
+
+ //new tag
+ strcmp(name, "Type") == 0 ||
+ strcmp(name, "sSectorX") == 0 ||
+ strcmp(name, "sSectorY") == 0 ||
+ strcmp(name, "sSectorZ") == 0 ||
+ strcmp(name, "ubCivilianGroup") == 0 ||
+ strcmp(name, "bTown") == 0 ||
+ strcmp(name, "bTownAttachment") == 0
+
))
{
pData->curElement = ELEMENT_PROPERTY;
@@ -182,75 +225,126 @@ profileEndElementHandle(void *userData, const XML_Char *name)
if(pData->curIndex < pData->maxArraySize)
{
-
// Write data into a temporary array that holds profiles. We will later copy data from that
// temp array into the REAL profile array, one item at a time, replacing PROF.DAT data.
- wcscpy(tempProfiles[pData->curIndex].zName, pData->curProfile.zName);
- wcscpy(tempProfiles[pData->curIndex].zNickname, pData->curProfile.zNickname);
-
- tempProfiles[pData->curIndex].ubFaceIndex = pData->curProfile.ubFaceIndex;
- tempProfiles[pData->curIndex].usEyesX = pData->curProfile.usEyesX;
- tempProfiles[pData->curIndex].usEyesY = pData->curProfile.usEyesY;
- tempProfiles[pData->curIndex].usMouthX = pData->curProfile.usMouthX;
- tempProfiles[pData->curIndex].usMouthY = pData->curProfile.usMouthY;
- tempProfiles[pData->curIndex].uiEyeDelay = pData->curProfile.uiEyeDelay;
- tempProfiles[pData->curIndex].uiMouthDelay = pData->curProfile.uiMouthDelay;
- tempProfiles[pData->curIndex].uiBlinkFrequency = pData->curProfile.uiBlinkFrequency;
- tempProfiles[pData->curIndex].uiExpressionFrequency = pData->curProfile.uiExpressionFrequency;
+
+ if (!MercProfiles_TextOnly)
+ {
+ wcscpy(tempProfiles[pData->curIndex].zName, pData->curProfile.zName);
+ wcscpy(tempProfiles[pData->curIndex].zNickname, pData->curProfile.zNickname);
+
+ tempProfiles[pData->curIndex].ubFaceIndex = pData->curProfile.ubFaceIndex;
+ tempProfiles[pData->curIndex].usEyesX = pData->curProfile.usEyesX;
+ tempProfiles[pData->curIndex].usEyesY = pData->curProfile.usEyesY;
+ tempProfiles[pData->curIndex].usMouthX = pData->curProfile.usMouthX;
+ tempProfiles[pData->curIndex].usMouthY = pData->curProfile.usMouthY;
+ tempProfiles[pData->curIndex].uiEyeDelay = pData->curProfile.uiEyeDelay;
+ tempProfiles[pData->curIndex].uiMouthDelay = pData->curProfile.uiMouthDelay;
+ tempProfiles[pData->curIndex].uiBlinkFrequency = pData->curProfile.uiBlinkFrequency;
+ tempProfiles[pData->curIndex].uiExpressionFrequency = pData->curProfile.uiExpressionFrequency;
- memcpy( &(tempProfiles[pData->curIndex].PANTS), &(pData->curProfile.PANTS), sizeof(PaletteRepID) );
- memcpy( &(tempProfiles[pData->curIndex].VEST), &(pData->curProfile.VEST), sizeof(PaletteRepID) );
- memcpy( &(tempProfiles[pData->curIndex].SKIN), &(pData->curProfile.SKIN), sizeof(PaletteRepID) );
- memcpy( &(tempProfiles[pData->curIndex].HAIR), &(pData->curProfile.HAIR), sizeof(PaletteRepID) );
+ memcpy( &(tempProfiles[pData->curIndex].PANTS), &(pData->curProfile.PANTS), sizeof(PaletteRepID) );
+ memcpy( &(tempProfiles[pData->curIndex].VEST), &(pData->curProfile.VEST), sizeof(PaletteRepID) );
+ memcpy( &(tempProfiles[pData->curIndex].SKIN), &(pData->curProfile.SKIN), sizeof(PaletteRepID) );
+ memcpy( &(tempProfiles[pData->curIndex].HAIR), &(pData->curProfile.HAIR), sizeof(PaletteRepID) );
- tempProfiles[pData->curIndex].bSex = pData->curProfile.bSex;
- tempProfiles[pData->curIndex].ubBodyType = pData->curProfile.ubBodyType;
- tempProfiles[pData->curIndex].uiBodyTypeSubFlags = pData->curProfile.uiBodyTypeSubFlags;
+ tempProfiles[pData->curIndex].bSex = pData->curProfile.bSex;
+ tempProfiles[pData->curIndex].ubBodyType = pData->curProfile.ubBodyType;
+ tempProfiles[pData->curIndex].uiBodyTypeSubFlags = pData->curProfile.uiBodyTypeSubFlags;
- tempProfiles[pData->curIndex].bAttitude = pData->curProfile.bAttitude;
- tempProfiles[pData->curIndex].bPersonalityTrait = pData->curProfile.bPersonalityTrait;
- tempProfiles[pData->curIndex].ubNeedForSleep = pData->curProfile.ubNeedForSleep;
- tempProfiles[pData->curIndex].bReputationTolerance = pData->curProfile.bReputationTolerance;
- tempProfiles[pData->curIndex].bDeathRate = pData->curProfile.bDeathRate;
+ tempProfiles[pData->curIndex].bAttitude = pData->curProfile.bAttitude;
+ tempProfiles[pData->curIndex].bCharacterTrait = pData->curProfile.bCharacterTrait; // added by SANDRO
+ tempProfiles[pData->curIndex].bDisability = pData->curProfile.bDisability;
+ tempProfiles[pData->curIndex].ubNeedForSleep = pData->curProfile.ubNeedForSleep;
+ tempProfiles[pData->curIndex].bReputationTolerance = pData->curProfile.bReputationTolerance;
+ tempProfiles[pData->curIndex].bDeathRate = pData->curProfile.bDeathRate;
- tempProfiles[pData->curIndex].bLifeMax = pData->curProfile.bLifeMax;
- tempProfiles[pData->curIndex].bLife = pData->curProfile.bLife;
- tempProfiles[pData->curIndex].bStrength = pData->curProfile.bStrength;
- tempProfiles[pData->curIndex].bAgility = pData->curProfile.bAgility;
- tempProfiles[pData->curIndex].bDexterity = pData->curProfile.bDexterity;
- tempProfiles[pData->curIndex].bWisdom = pData->curProfile.bWisdom;
- tempProfiles[pData->curIndex].bMarksmanship = pData->curProfile.bMarksmanship;
- tempProfiles[pData->curIndex].bExplosive = pData->curProfile.bExplosive;
- tempProfiles[pData->curIndex].bLeadership = pData->curProfile.bLeadership;
- tempProfiles[pData->curIndex].bMedical = pData->curProfile.bMedical;
- tempProfiles[pData->curIndex].bMechanical = pData->curProfile.bMechanical;
- tempProfiles[pData->curIndex].bExpLevel = pData->curProfile.bExpLevel;
+ tempProfiles[pData->curIndex].bLifeMax = pData->curProfile.bLifeMax;
+ tempProfiles[pData->curIndex].bLife = pData->curProfile.bLife;
+ tempProfiles[pData->curIndex].bStrength = pData->curProfile.bStrength;
+ tempProfiles[pData->curIndex].bAgility = pData->curProfile.bAgility;
+ tempProfiles[pData->curIndex].bDexterity = pData->curProfile.bDexterity;
+ tempProfiles[pData->curIndex].bWisdom = pData->curProfile.bWisdom;
+ tempProfiles[pData->curIndex].bMarksmanship = pData->curProfile.bMarksmanship;
+ tempProfiles[pData->curIndex].bExplosive = pData->curProfile.bExplosive;
+ tempProfiles[pData->curIndex].bLeadership = pData->curProfile.bLeadership;
+ tempProfiles[pData->curIndex].bMedical = pData->curProfile.bMedical;
+ tempProfiles[pData->curIndex].bMechanical = pData->curProfile.bMechanical;
+ tempProfiles[pData->curIndex].bExpLevel = pData->curProfile.bExpLevel;
- tempProfiles[pData->curIndex].bEvolution = pData->curProfile.bEvolution;
- tempProfiles[pData->curIndex].bSkillTrait = pData->curProfile.bSkillTrait;
- tempProfiles[pData->curIndex].bSkillTrait2 = pData->curProfile.bSkillTrait2;
+ tempProfiles[pData->curIndex].bEvolution = pData->curProfile.bEvolution;
+ // added by SANDRO
+ tempProfiles[pData->curIndex].bOldSkillTrait = pData->curProfile.bOldSkillTrait;
+ tempProfiles[pData->curIndex].bOldSkillTrait2 = pData->curProfile.bOldSkillTrait2;
+ tempProfiles[pData->curIndex].bNewSkillTrait1 = pData->curProfile.bNewSkillTrait1;
+ tempProfiles[pData->curIndex].bNewSkillTrait2 = pData->curProfile.bNewSkillTrait2;
+ tempProfiles[pData->curIndex].bNewSkillTrait3 = pData->curProfile.bNewSkillTrait3;
+ tempProfiles[pData->curIndex].bNewSkillTrait4 = pData->curProfile.bNewSkillTrait4;
+ tempProfiles[pData->curIndex].bNewSkillTrait5 = pData->curProfile.bNewSkillTrait5;
+ tempProfiles[pData->curIndex].bNewSkillTrait6 = pData->curProfile.bNewSkillTrait6;
+ tempProfiles[pData->curIndex].bNewSkillTrait7 = pData->curProfile.bNewSkillTrait7;
+ tempProfiles[pData->curIndex].bNewSkillTrait8 = pData->curProfile.bNewSkillTrait8;
+ tempProfiles[pData->curIndex].bNewSkillTrait9 = pData->curProfile.bNewSkillTrait9;
+ tempProfiles[pData->curIndex].bNewSkillTrait10 = pData->curProfile.bNewSkillTrait10;
+ tempProfiles[pData->curIndex].bNewSkillTrait11 = pData->curProfile.bNewSkillTrait11;
+ tempProfiles[pData->curIndex].bNewSkillTrait12 = pData->curProfile.bNewSkillTrait12;
+ tempProfiles[pData->curIndex].bNewSkillTrait13 = pData->curProfile.bNewSkillTrait13;
+ tempProfiles[pData->curIndex].bNewSkillTrait14 = pData->curProfile.bNewSkillTrait14;
+ tempProfiles[pData->curIndex].bNewSkillTrait15 = pData->curProfile.bNewSkillTrait15;
+ tempProfiles[pData->curIndex].bNewSkillTrait16 = pData->curProfile.bNewSkillTrait16;
+ tempProfiles[pData->curIndex].bNewSkillTrait17 = pData->curProfile.bNewSkillTrait17;
+ tempProfiles[pData->curIndex].bNewSkillTrait18 = pData->curProfile.bNewSkillTrait18;
+ tempProfiles[pData->curIndex].bNewSkillTrait19 = pData->curProfile.bNewSkillTrait19;
+ tempProfiles[pData->curIndex].bNewSkillTrait20 = pData->curProfile.bNewSkillTrait20;
+ tempProfiles[pData->curIndex].bNewSkillTrait21 = pData->curProfile.bNewSkillTrait21;
+ tempProfiles[pData->curIndex].bNewSkillTrait22 = pData->curProfile.bNewSkillTrait22;
+ tempProfiles[pData->curIndex].bNewSkillTrait23 = pData->curProfile.bNewSkillTrait23;
+ tempProfiles[pData->curIndex].bNewSkillTrait24 = pData->curProfile.bNewSkillTrait24;
+ tempProfiles[pData->curIndex].bNewSkillTrait25 = pData->curProfile.bNewSkillTrait25;
+ tempProfiles[pData->curIndex].bNewSkillTrait26 = pData->curProfile.bNewSkillTrait26;
+ tempProfiles[pData->curIndex].bNewSkillTrait27 = pData->curProfile.bNewSkillTrait27;
+ tempProfiles[pData->curIndex].bNewSkillTrait28 = pData->curProfile.bNewSkillTrait28;
+ tempProfiles[pData->curIndex].bNewSkillTrait29 = pData->curProfile.bNewSkillTrait29;
+ tempProfiles[pData->curIndex].bNewSkillTrait30 = pData->curProfile.bNewSkillTrait30;
- memcpy( &(tempProfiles[pData->curIndex].bBuddy), &(pData->curProfile.bBuddy), 5 * sizeof (INT8));
- tempProfiles[pData->curIndex].bLearnToLike = pData->curProfile.bLearnToLike;
- tempProfiles[pData->curIndex].bLearnToLikeTime = pData->curProfile.bLearnToLikeTime;
- memcpy( &(tempProfiles[pData->curIndex].bHated), &(pData->curProfile.bHated), 5 * sizeof (INT8));
- memcpy( &(tempProfiles[pData->curIndex].bHatedTime), &(pData->curProfile.bHatedTime), 5 * sizeof (INT8));
- tempProfiles[pData->curIndex].bLearnToHate = pData->curProfile.bLearnToHate;
- tempProfiles[pData->curIndex].bLearnToHateTime = pData->curProfile.bLearnToHateTime;
+ memcpy( &(tempProfiles[pData->curIndex].bBuddy), &(pData->curProfile.bBuddy), 5 * sizeof (INT8));
+ tempProfiles[pData->curIndex].bLearnToLike = pData->curProfile.bLearnToLike;
+ tempProfiles[pData->curIndex].bLearnToLikeTime = pData->curProfile.bLearnToLikeTime;
- tempProfiles[pData->curIndex].sSalary = pData->curProfile.sSalary;
- tempProfiles[pData->curIndex].uiWeeklySalary = pData->curProfile.uiWeeklySalary;
- tempProfiles[pData->curIndex].uiBiWeeklySalary = pData->curProfile.uiBiWeeklySalary;
- tempProfiles[pData->curIndex].bMedicalDeposit = pData->curProfile.bMedicalDeposit;
- tempProfiles[pData->curIndex].sMedicalDepositAmount = pData->curProfile.sMedicalDepositAmount;
- tempProfiles[pData->curIndex].usOptionalGearCost = pData->curProfile.usOptionalGearCost;
+ memcpy( &(tempProfiles[pData->curIndex].bHated), &(pData->curProfile.bHated), 5 * sizeof (INT8));
+ memcpy( &(tempProfiles[pData->curIndex].bHatedTime), &(pData->curProfile.bHatedTime), 5 * sizeof (INT8));
+ tempProfiles[pData->curIndex].bLearnToHate = pData->curProfile.bLearnToHate;
+ tempProfiles[pData->curIndex].bLearnToHateTime = pData->curProfile.bLearnToHateTime;
- tempProfiles[pData->curIndex].bArmourAttractiveness = pData->curProfile.bArmourAttractiveness;
- tempProfiles[pData->curIndex].bMainGunAttractiveness = pData->curProfile.bMainGunAttractiveness;
+ tempProfiles[pData->curIndex].sSalary = pData->curProfile.sSalary;
+ tempProfiles[pData->curIndex].uiWeeklySalary = pData->curProfile.uiWeeklySalary;
+ tempProfiles[pData->curIndex].uiBiWeeklySalary = pData->curProfile.uiBiWeeklySalary;
+ tempProfiles[pData->curIndex].bMedicalDeposit = pData->curProfile.bMedicalDeposit;
+ tempProfiles[pData->curIndex].sMedicalDepositAmount = pData->curProfile.sMedicalDepositAmount;
+ tempProfiles[pData->curIndex].usOptionalGearCost = pData->curProfile.usOptionalGearCost;
- tempProfiles[pData->curIndex].fGoodGuy = pData->curProfile.fGoodGuy;
- memcpy( &(tempProfiles[pData->curIndex].usApproachFactor), &(pData->curProfile.usApproachFactor), 4 * sizeof (UINT16));
+ tempProfiles[pData->curIndex].bArmourAttractiveness = pData->curProfile.bArmourAttractiveness;
+ tempProfiles[pData->curIndex].bMainGunAttractiveness = pData->curProfile.bMainGunAttractiveness;
+
+ tempProfiles[pData->curIndex].Type = pData->curProfile.Type;
+
+ tempProfiles[pData->curIndex].sSectorX = pData->curProfile.sSectorX;
+ tempProfiles[pData->curIndex].sSectorY = pData->curProfile.sSectorY;
+ tempProfiles[pData->curIndex].bSectorZ = pData->curProfile.bSectorZ;
+ tempProfiles[pData->curIndex].ubCivilianGroup = pData->curProfile.ubCivilianGroup;
+ tempProfiles[pData->curIndex].bTown = pData->curProfile.bTown;
+ tempProfiles[pData->curIndex].bTownAttachment = pData->curProfile.bTownAttachment;
+
+ tempProfiles[pData->curIndex].fGoodGuy = pData->curProfile.fGoodGuy;
+ memcpy( &(tempProfiles[pData->curIndex].usApproachFactor), &(pData->curProfile.usApproachFactor), 4 * sizeof (UINT16));
+
+ }
+ else
+ {
+ wcscpy(tempProfiles[pData->curIndex].zName, pData->curProfile.zName);
+ wcscpy(tempProfiles[pData->curIndex].zNickname, pData->curProfile.zNickname);
+ }
}
}
@@ -371,11 +465,17 @@ profileEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curProfile.bAttitude = (UINT32) atol(pData->szCharData);
}
-
- else if(strcmp(name, "bPersonalityTrait") == 0)
+ // SANDRO - added Character Trait
+ else if(strcmp(name, "bCharacterTrait") == 0)
{
pData->curElement = ELEMENT;
- pData->curProfile.bPersonalityTrait = (UINT32) atol(pData->szCharData);
+ pData->curProfile.bCharacterTrait = (UINT32) atol(pData->szCharData);
+ }
+
+ else if(strcmp(name, "bDisability") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bDisability = (UINT32) atol(pData->szCharData);
}
else if(strcmp(name, "ubNeedForSleep") == 0)
@@ -473,19 +573,172 @@ profileEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curProfile.bEvolution = (UINT32) atol(pData->szCharData);
}
-
- else if(strcmp(name, "bSkillTrait") == 0)
+ ////////////////////////////////////////////////////////////////////////////
+ // SANDRO was here - messed this a bit
+ else if(strcmp(name, "bOldSkillTrait") == 0)
{
pData->curElement = ELEMENT;
- pData->curProfile.bSkillTrait = (UINT32) atol(pData->szCharData);
+ pData->curProfile.bOldSkillTrait = (UINT32) atol(pData->szCharData);
}
- else if(strcmp(name, "bSkillTrait2") == 0)
+ else if(strcmp(name, "bOldSkillTrait2") == 0)
{
pData->curElement = ELEMENT;
- pData->curProfile.bSkillTrait2 = (UINT32) atol(pData->szCharData);
+ pData->curProfile.bOldSkillTrait2 = (UINT32) atol(pData->szCharData);
}
+ else if(strcmp(name, "bNewSkillTrait1") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait1 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait2") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait2 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait3") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait3 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait4") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait4 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait5") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait5 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait6") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait6 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait7") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait7 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait8") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait8 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait9") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait9 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait10") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait10 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait11") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait11 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait12") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait12 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait13") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait13 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait14") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait14 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait15") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait15 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait16") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait16 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait17") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait17 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait18") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait18 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait19") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait19 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait20") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait20 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait21") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait21 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait22") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait22 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait23") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait23 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait24") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait24 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait25") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait25 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait26") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait26 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait27") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait27 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait28") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait28 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait29") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait29 = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bNewSkillTrait30") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bNewSkillTrait30 = (UINT32) atol(pData->szCharData);
+ }
+ ////////////////////////////////////////////////////////////////////////////
+
else if(strcmp(name, "bBuddy1") == 0)
{
pData->curElement = ELEMENT;
@@ -686,6 +939,44 @@ profileEndElementHandle(void *userData, const XML_Char *name)
// Sets new index for writing.
pData->curIndex = (UINT32) atol(pData->szCharData);
}
+
+ else if(strcmp(name, "Type") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.Type = (UINT32) atol(pData->szCharData);
+ }
+
+ else if(strcmp(name, "sSectorX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.sSectorX = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "sSectorY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.sSectorY = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "sSectorZ") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bSectorZ = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ubCivilianGroup") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.ubCivilianGroup = (UINT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bTown") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bTown = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "bTownAttachment") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curProfile.bTownAttachment = (INT8) atol(pData->szCharData);
+ }
+
pData->maxReadDepth--;
}
@@ -696,7 +987,7 @@ profileEndElementHandle(void *userData, const XML_Char *name)
-BOOLEAN ReadInMercProfiles(STR fileName)
+BOOLEAN ReadInMercProfiles(STR fileName, BOOLEAN localizedVersion)
{
HWFILE hFile;
UINT32 uiBytesRead;
@@ -706,12 +997,13 @@ BOOLEAN ReadInMercProfiles(STR fileName)
profileParseData pData;
+ MercProfiles_TextOnly = localizedVersion;
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading MercProfiles.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);
@@ -778,6 +1070,44 @@ BOOLEAN WriteMercProfiles()
FilePrintf(hFile,"\t\r\n");
FilePrintf(hFile,"\t\t%d\r\n", cnt);
+
+ if (cnt >= 0 && cnt < 40 )
+ {
+ FilePrintf(hFile,"\t\t1\r\n");
+ }
+ else if (cnt >= 40 && cnt < 51 )
+ {
+ FilePrintf(hFile,"\t\t2\r\n");
+ }
+ else if ( cnt >= FIRST_RPC && cnt < FIRST_NPC )
+ {
+ FilePrintf(hFile,"\t\t3\r\n");
+ }
+ else if ( cnt >= FIRST_NPC && cnt < 160 )
+ {
+ FilePrintf(hFile,"\t\t4\r\n");
+ }
+ else if ( cnt == 169 )
+ {
+ FilePrintf(hFile,"\t\t4\r\n");
+ }
+ else if ( cnt == 165 || cnt == 166 || cnt == 167 || cnt == 168 )
+ {
+ FilePrintf(hFile,"\t\t2\r\n");
+ }
+ else if ( cnt == 51 || cnt == 52 || cnt == 53 || cnt == 54 || cnt == 55 || cnt == 56 )
+ {
+ FilePrintf(hFile,"\t\t6\r\n");
+ }
+ else if ( cnt == 160 || cnt == 161 || cnt == 162 || cnt == 163 || cnt == 164 )
+ {
+ FilePrintf(hFile,"\t\t5\r\n");
+ }
+ else
+ {
+ FilePrintf(hFile,"\t\t0\r\n");
+ }
+
//////////////////////////////
// Write Character Name
@@ -1117,7 +1447,9 @@ BOOLEAN WriteMercProfiles()
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].uiBodyTypeSubFlags);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bAttitude);
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bPersonalityTrait);
+ // Added by SANDRO
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bCharacterTrait);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bDisability);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].ubNeedForSleep);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bReputationTolerance);
@@ -1136,8 +1468,30 @@ BOOLEAN WriteMercProfiles()
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bMechanical);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bExpLevel);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bEvolution);
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTrait);
- FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTrait2);
+ ////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - old/new traits
+ if (gGameOptions.fNewTraitSystem)
+ {
+ FilePrintf(hFile,"\t\t%d\r\n", 0);
+ FilePrintf(hFile,"\t\t%d\r\n", 0);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTraits[0]);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTraits[1]);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTraits[2]);
+ for ( INT8 bCnt2 = 3; bCnt2 < 30; bCnt2++ )
+ {
+ if ( gMercProfiles[ cnt ].bSkillTraits[ bCnt2 ] > 0 )
+ FilePrintf(hFile,"\t\t%d\r\n", (bCnt2+1), gMercProfiles[ cnt ].bSkillTraits[bCnt2], (bCnt2+1));
+ }
+ }
+ else
+ {
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTraits[0]);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSkillTraits[1]);
+ FilePrintf(hFile,"\t\t%d\r\n", 0);
+ FilePrintf(hFile,"\t\t%d\r\n", 0);
+ FilePrintf(hFile,"\t\t%d\r\n", 0);
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bBuddy[0]);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bBuddy[1]);
@@ -1178,6 +1532,14 @@ BOOLEAN WriteMercProfiles()
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].usApproachFactor[1]);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].usApproachFactor[2]);
FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].usApproachFactor[3]);
+
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].sSectorX);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].sSectorY);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bSectorZ);
+
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].ubCivilianGroup);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bTown);
+ FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bTownAttachment);
FilePrintf(hFile,"\t\r\n");
diff --git a/Tactical/XML_Qarray.cpp b/Tactical/XML_Qarray.cpp
new file mode 100644
index 00000000..0e805b74
--- /dev/null
+++ b/Tactical/XML_Qarray.cpp
@@ -0,0 +1,258 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+ #include "qarray.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+ #include "qarray.h"
+#endif
+
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ QARRAY_VALUES curQarray;
+ QARRAY_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef qarrayParseData;
+
+static void XMLCALL
+qarrayStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ qarrayParseData * pData = (qarrayParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "QARRAY") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(QARRAY_VALUES)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "PROFILE") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curQarray,0,sizeof(QARRAY_VALUES));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "QuoteExpHeadShotOnly") == 0 ||
+ strcmp(name, "QuoteExpTeamSpecific") == 0 ||
+ strcmp(name, "QuoteExpGenderCode") == 0 ||
+ strcmp(name, "QuoteExpGotGunOrUsedGun") == 0 ||
+ strcmp(name, "QuoteExpPassingDislike") == 0 ||
+ strcmp(name, "QuoteExpWitnessDeidrannaDeath") == 0 ||
+ strcmp(name, "QuoteExpWitnessQueenBugDeath") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+
+ }
+ pData->currentDepth++;
+ }
+
+
+
+static void XMLCALL
+qarrayCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ qarrayParseData * pData = (qarrayParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+qarrayEndElementHandle(void *userData, const XML_Char *name)
+{
+ qarrayParseData * pData = (qarrayParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "QARRAY") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "PROFILE") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curQarray.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curQarray.uiIndex] = pData->curQarray;
+ }
+
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpHeadShotOnly") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpHeadShotOnly = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpTeamSpecific") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpTeamSpecific = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpGenderCode") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpGenderCode = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpGotGunOrUsedGun") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpGotGunOrUsedGun = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpPassingDislike") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpPassingDislike = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpWitnessDeidrannaDeath") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpWitnessDeidrannaDeath = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "QuoteExpWitnessQueenBugDeath") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curQarray.QuoteExpWitnessQueenBugDeath = (BOOLEAN) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInQarray(QARRAY_VALUES *pQarray, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ qarrayParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading Qarray.xml" );
+
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, qarrayStartElementHandle, qarrayEndElementHandle);
+ XML_SetCharacterDataHandler(parser, qarrayCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pQarray;
+ pData.maxArraySize = NUM_PROFILES;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in Quotearray.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+
+
+BOOLEAN WriteQarray(QARRAY_VALUES *pQarray, STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < NUM_PROFILES;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpHeadShotOnly);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpTeamSpecific);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpGenderCode);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpGotGunOrUsedGun);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpPassingDislike);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpWitnessQueenBugDeath);
+ FilePrintf(hFile,"\t\t%d\r\n", pQarray[cnt].QuoteExpWitnessDeidrannaDeath);
+
+
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
diff --git a/Tactical/XML_RPCFacesSmall.cpp b/Tactical/XML_RPCFacesSmall.cpp
new file mode 100644
index 00000000..b0b3946b
--- /dev/null
+++ b/Tactical/XML_RPCFacesSmall.cpp
@@ -0,0 +1,238 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "faces.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ RPC_SMALL_FACE_VALUES curSmallFaces;
+ RPC_SMALL_FACE_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef smallFacesParseData;
+
+static void XMLCALL
+smallFacesStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ smallFacesParseData * pData = (smallFacesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "SMALLFACE") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ memset(pData->curArray,0,sizeof(RPC_SMALL_FACE_VALUES)*pData->maxArraySize);
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "FACE") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ memset(&pData->curSmallFaces,0,sizeof(RPC_SMALL_FACE_VALUES));
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "FaceIndex") == 0 ||
+ strcmp(name, "EyesX") == 0 ||
+ strcmp(name, "EyesY") == 0 ||
+ strcmp(name, "MouthX") == 0 ||
+ strcmp(name, "MouthY") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+smallFacesCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ smallFacesParseData * pData = (smallFacesParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+smallFacesEndElementHandle(void *userData, const XML_Char *name)
+{
+ smallFacesParseData * pData = (smallFacesParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "SMALLFACE") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "FACE") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ if(pData->curSmallFaces.uiIndex < pData->maxArraySize)
+ {
+ pData->curArray[pData->curSmallFaces.uiIndex] = pData->curSmallFaces; //write the small faces into the table
+ }
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSmallFaces.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "FaceIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSmallFaces.FaceIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "EyesX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSmallFaces.bEyesX = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "EyesY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSmallFaces.bEyesY = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "MouthX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSmallFaces.bMouthX = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "MouthY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSmallFaces.bMouthY = (INT8) atol(pData->szCharData);
+ }
+
+
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInSmallFacesStats(RPC_SMALL_FACE_VALUES *pSmallFaces, STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ smallFacesParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading SmallFaces.xml" );
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, smallFacesStartElementHandle, smallFacesEndElementHandle);
+ XML_SetCharacterDataHandler(parser, smallFacesCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ pData.curArray = pSmallFaces;
+ pData.maxArraySize = 200;
+
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in RPCFacesSmall.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+BOOLEAN WriteSmallFacesStats(RPC_SMALL_FACE_VALUES *pSmallFaces, STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < 201;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n", pSmallFaces[cnt].FaceIndex);
+ FilePrintf(hFile,"\t\t%d\r\n", pSmallFaces[cnt].bEyesX);
+ FilePrintf(hFile,"\t\t%d\r\n", pSmallFaces[cnt].bEyesY);
+ FilePrintf(hFile,"\t\t%d\r\n", pSmallFaces[cnt].bMouthX);
+ FilePrintf(hFile,"\t\t%d\r\n", pSmallFaces[cnt].bMouthY);
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_RandomStats.cpp b/Tactical/XML_RandomStats.cpp
new file mode 100644
index 00000000..75a9332a
--- /dev/null
+++ b/Tactical/XML_RandomStats.cpp
@@ -0,0 +1,304 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+#endif
+
+#include "soldier profile type.h"
+#include "Soldier Profile.h"
+#include "Random.h"
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ RANDOM_STATS_VALUES curRandomStats;
+ RANDOM_STATS_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef RandomStatsParseData;
+
+BOOLEAN RandomStats_TextOnly;
+
+static void XMLCALL
+RandomStatsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ RandomStatsParseData * pData = (RandomStatsParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "RANDOM_STATS") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "PROFIL") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ ( strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "Enabled") == 0 ||
+ strcmp(name, "BaseAttribute") == 0 ||
+ strcmp(name, "ExpLevel") == 0 ||
+ strcmp(name, "RandomLife") == 0 ||
+ strcmp(name, "RandomAgility") == 0 ||
+ strcmp(name, "RandomLeadership") == 0 ||
+ strcmp(name, "RandomDexterity") == 0 ||
+ strcmp(name, "RandomWisdom") == 0 ||
+ strcmp(name, "RandomMarksmanship") == 0 ||
+ strcmp(name, "RandomMedical") == 0 ||
+ strcmp(name, "RandomMechanical") == 0 ||
+ strcmp(name, "RandomExplosive") == 0 ||
+ strcmp(name, "RandomScientific") == 0 ||
+ strcmp(name, "RandomStrength") == 0 ) )
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+RandomStatsCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ RandomStatsParseData * pData = (RandomStatsParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+RandomStatsEndElementHandle(void *userData, const XML_Char *name)
+{
+ RandomStatsParseData * pData = (RandomStatsParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth)
+ {
+ if(strcmp(name, "RANDOM_STATS") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "PROFIL") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ gRandomStatsValue[pData->curRandomStats.uiIndex].Enabled = pData->curRandomStats.Enabled;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].BaseAttribute = pData->curRandomStats.BaseAttribute;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].ExpLevel = pData->curRandomStats.ExpLevel;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomLife = pData->curRandomStats.RandomLife;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomStrength = pData->curRandomStats.RandomStrength;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomAgility = pData->curRandomStats.RandomAgility;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomLeadership = pData->curRandomStats.RandomLeadership;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomDexterity = pData->curRandomStats.RandomDexterity;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomWisdom = pData->curRandomStats.RandomWisdom;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomMarksmanship = pData->curRandomStats.RandomMarksmanship;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomMedical = pData->curRandomStats.RandomMedical;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomMechanical = pData->curRandomStats.RandomMechanical;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomExplosive = pData->curRandomStats.RandomExplosive;
+ gRandomStatsValue[pData->curRandomStats.uiIndex].RandomScientific = pData->curRandomStats.RandomScientific;
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Enabled") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.Enabled = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "BaseAttribute") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.BaseAttribute = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "ExpLevel") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.ExpLevel = (INT8) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomLife") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomLife = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomAgility") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomAgility = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomLeadership") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomLeadership = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomDexterity") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomDexterity = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomWisdom") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomWisdom = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomMarksmanship") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomMarksmanship = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomMedical") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomMedical = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomMechanical") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomMechanical = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomExplosive") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomExplosive = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomScientific") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomScientific = (BOOLEAN) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RandomStrength") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curRandomStats.RandomStrength = (BOOLEAN) atol(pData->szCharData);
+ }
+
+ pData->maxReadDepth--;
+ }
+ pData->currentDepth--;
+}
+
+BOOLEAN ReadInRandomStats(STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ RandomStatsParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading RandomStats.xml" );
+
+// RandomStats_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ //if ( !hFile )
+ // return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, RandomStatsStartElementHandle, RandomStatsEndElementHandle);
+ XML_SetCharacterDataHandler(parser, RandomStatsCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in RandomStats.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+BOOLEAN WriteRandomStats( STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for ( cnt = 0; cnt < NUM_PROFILES; cnt++ )
+ {
+ FilePrintf(hFile,"\t\r\n");
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].Enabled);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].BaseAttribute);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].ExpLevel);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomLife);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomAgility);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomLeadership);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomDexterity);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomWisdom);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomMarksmanship);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomMedical);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomMechanical);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomExplosive);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomScientific);
+ FilePrintf(hFile,"\t\t%d\r\n",gRandomStatsValue[cnt].RandomStrength);
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/XML_SoundProfile.cpp b/Tactical/XML_SoundProfile.cpp
new file mode 100644
index 00000000..e6fd46bc
--- /dev/null
+++ b/Tactical/XML_SoundProfile.cpp
@@ -0,0 +1,200 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+#endif
+
+#include "Dialogue Control.h"
+#include "soldier profile type.h"
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ SOUND_PROFILE_VALUES curSoundProfile;
+ SOUND_PROFILE_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef SoundProfileParseData;
+
+static void XMLCALL
+SoundProfileStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ SoundProfileParseData * pData = (SoundProfileParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "SOUNDPROFILE") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "PROFILE") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "EnabledSound") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+SoundProfileCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ SoundProfileParseData * pData = (SoundProfileParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+SoundProfileEndElementHandle(void *userData, const XML_Char *name)
+{
+ SoundProfileParseData * pData = (SoundProfileParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "SOUNDPROFILE") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "PROFILE") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ gSoundProfileValue[pData->curSoundProfile.uiIndex].EnabledSound = pData->curSoundProfile.EnabledSound;
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSoundProfile.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "EnabledSound") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSoundProfile.EnabledSound = (BOOLEAN) atol(pData->szCharData);
+ }
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInSoundProfile(STR fileName)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ SoundProfileParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading SoundsProfiles.xml" );
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, SoundProfileStartElementHandle, SoundProfileEndElementHandle);
+ XML_SetCharacterDataHandler(parser, SoundProfileCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in SoundsProfiles.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
+
+BOOLEAN WriteSoundProfile(STR fileName)
+{
+ HWFILE hFile;
+
+ //Debug code; make sure that what we got from the file is the same as what's there
+ // Open a new file
+ hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
+ if ( !hFile )
+ return( FALSE );
+
+ {
+ UINT32 cnt;
+
+ FilePrintf(hFile,"\r\n");
+ for(cnt = 0;cnt < NUM_PROFILES;cnt++)
+ {
+
+ FilePrintf(hFile,"\t\r\n");
+
+ FilePrintf(hFile,"\t\t%d\r\n", cnt);
+ FilePrintf(hFile,"\t\t1\r\n");
+ FilePrintf(hFile,"\t\r\n");
+ }
+ FilePrintf(hFile,"\r\n");
+ }
+ FileClose( hFile );
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Tactical/bullets.cpp b/Tactical/bullets.cpp
index 1542fb60..2b83f7b1 100644
--- a/Tactical/bullets.cpp
+++ b/Tactical/bullets.cpp
@@ -29,8 +29,6 @@
#include "lighting.h"
#include "Buildings.h"
#endif
-#include "test_space.h"
-
// Defines
#define NUM_BULLET_SLOTS 50
@@ -366,7 +364,7 @@ void UpdateBullets( )
pNode->sRelativeZ = (INT16) CONVERT_HEIGHTUNITS_TO_PIXELS( FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrZ ) );
//afp-start - add new tail /tracer
- if (gGameExternalOptions.gbBulletTracer)
+ if (gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS])
{
if ((lastX != 0) || (lastY != 0))
{
@@ -413,15 +411,15 @@ void UpdateBullets( )
//afp-end
// Display shadow
// afp - no more shadow if tracer enabled
- if (!gGameExternalOptions.gbBulletTracer)
+ if (!gGameSettings.fOptions[TOPTION_ALTERNATE_BULLET_GRAPHICS])
{
- pNode = AddStructToTail( gBullets[ uiCount ].sGridNo, BULLETTILE2 );
- pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
- pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
- pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT );
- pNode->sRelativeX = (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX );
- pNode->sRelativeY = (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY );
- pNode->sRelativeZ = (INT16)gpWorldLevelData[ gBullets[ uiCount ].sGridNo ].sHeight;
+ pNode = AddStructToTail( gBullets[ uiCount ].sGridNo, BULLETTILE2 );
+ pNode->ubShadeLevel=DEFAULT_SHADE_LEVEL;
+ pNode->ubNaturalShadeLevel=DEFAULT_SHADE_LEVEL;
+ pNode->uiFlags |= ( LEVELNODE_USEABSOLUTEPOS | LEVELNODE_IGNOREHEIGHT );
+ pNode->sRelativeX = (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrX );
+ pNode->sRelativeY = (INT16) FIXEDPT_TO_INT32( gBullets[ uiCount ].qCurrY );
+ pNode->sRelativeZ = (INT16)gpWorldLevelData[ gBullets[ uiCount ].sGridNo ].sHeight;
}
}
}
diff --git a/Tactical/faces.h b/Tactical/faces.h
index 184cdcfe..902df31e 100644
--- a/Tactical/faces.h
+++ b/Tactical/faces.h
@@ -17,6 +17,31 @@ struct audio_gap
struct audio_gap *pNext;
};
+typedef struct
+{
+ BOOLEAN gCamoface;
+ BOOLEAN gUrbanCamoface;
+ BOOLEAN gDesertCamoface;
+ BOOLEAN gSnowCamoface;
+} CAMO_FACE;
+
+extern CAMO_FACE gCamoFace[255];
+
+
+typedef struct
+{
+ INT8 bEyesX;
+ INT8 bEyesY;
+ INT8 bMouthX;
+ INT8 bMouthY;
+ UINT16 uiIndex; // add
+ UINT16 FaceIndex; //add
+
+} RPC_SMALL_FACE_VALUES;
+
+extern RPC_SMALL_FACE_VALUES gRPCSmallFaceValues[200];
+extern UINT8 gubRPCSmallFaceProfileNum[200];
+
#define FACE_AUTO_DISPLAY_BUFFER 0xFFFFF000
#define FACE_AUTO_RESTORE_BUFFER 0xFFFFFF00
#define FACE_NO_RESTORE_BUFFER 0xFFFFFFF0
@@ -240,7 +265,9 @@ BOOLEAN ExternRenderFaceFromSoldier( UINT32 uiBuffer, UINT8 ubSoldierID, INT16 s
-
+//legion2 Jazz
+extern void FacesSmalllegion ();
+extern void RecountFaces(void);
diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp
index b73e0a5d..94c6127e 100644
--- a/Tactical/opplist.cpp
+++ b/Tactical/opplist.cpp
@@ -327,7 +327,17 @@ INT16 AdjustMaxSightRangeForEnvEffects( SOLDIERTYPE *pSoldier, INT8 bLightLevel,
{
//sNewDist = sNewDist * 70 / 100;
//rain
- sNewDist = sNewDist * ( 100 - min( gGameExternalOptions.ubVisDistDecreasePerRainIntensity * gbCurrentRainIntensity, 100) ) / 100;
+ //Added a feature reducing weather penalty for ranger trait - SANDRO
+ INT16 sWeatherPenalty = 0; // percent vision reduction 0-100%
+ sWeatherPenalty = min( (max( 0, (gGameExternalOptions.ubVisDistDecreasePerRainIntensity * gbCurrentRainIntensity))), 100) ;
+ if( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, RANGER_NT ) )
+ {
+ sWeatherPenalty = (sWeatherPenalty * ( 100 - (gSkillTraitValues.ubRAWeatherPenaltiesReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ) / 100;
+ sWeatherPenalty = min( (max( 0, sWeatherPenalty)), 100 ); // keep it in 0-100 range
+ }
+
+ sNewDist = (sNewDist * ( 100 - sWeatherPenalty )) / 100;
+
//end rain
}
@@ -487,7 +497,8 @@ void HandleBestSightingPositionInRealtime( void )
if (gubBestToMakeSighting[ 1 ] == NOBODY)
{ // The_Bob - real time sneaking code 01/06/09
// if real time sneaking conditions are met...
- if (gGameExternalOptions.fAllowRealTimeSneak && MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam == OUR_TEAM && NobodyAlerted() )
+ // this is now in the preferences window - SANDRO
+ if (gGameSettings.fOptions[TOPTION_ALLOW_REAL_TIME_SNEAK] && MercPtrs[gubBestToMakeSighting[ 0 ]]->bTeam == OUR_TEAM && NobodyAlerted() )
{
// get rid of the item under cursor (we gotta react FAST)
CancelItemPointer();
@@ -870,11 +881,15 @@ void HandleSight(SOLDIERTYPE *pSoldier, UINT8 ubSightFlags)
{
// update our team's public knowledge
RadioSightings(pSoldier,EVERYBODY, pSoldier->bTeam );
-
+/* comm by ddd
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
RadioSightings(pSoldier,EVERYBODY, MILITIA_TEAM);
-#endif
-
+#endif*/
+//ddd{
+if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+RadioSightings(pSoldier,EVERYBODY, MILITIA_TEAM);
+
+//ddd}
// if it's our local player's merc
if (PTR_OURTEAM)
// revealing roofs and looking for items handled here, too
@@ -1049,6 +1064,7 @@ INT16 TeamNoLongerSeesMan( UINT8 ubTeam, SOLDIERTYPE *pOpponent, UINT8 ubExclude
return(FALSE); // that's all I need to know, get out of here
}
+/* comm by ddd
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
if ( bIteration == 0 )
{
@@ -1064,6 +1080,26 @@ INT16 TeamNoLongerSeesMan( UINT8 ubTeam, SOLDIERTYPE *pOpponent, UINT8 ubExclude
}
}
#endif
+*/
+//ddd
+if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+{
+ if ( bIteration == 0 )
+ {
+ if ( ubTeam == gbPlayerNum && gTacticalStatus.Team[ MILITIA_TEAM ].bTeamActive )
+ {
+ // check militia team as well
+ return( TeamNoLongerSeesMan( MILITIA_TEAM, pOpponent, ubExcludeID, 1 ) );
+ }
+ else if ( ubTeam == MILITIA_TEAM && gTacticalStatus.Team[ gbPlayerNum ].bTeamActive )
+ {
+ // check player team as well
+ return( TeamNoLongerSeesMan( gbPlayerNum, pOpponent, ubExcludeID, 1 ) );
+ }
+ }
+
+}
+//ddd
// none of my friends is currently seeing the guy, so return success
return(TRUE);
@@ -1257,7 +1293,9 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
sDistVisible += sDistVisible * GetTotalVisionRangeBonus(pSoldier, bLightLevel) / 100;
// HEADROCK HAM 3.2: Further reduce sightrange for cowering characters.
- if (gGameExternalOptions.ubCoweringReducesSightRange == 1 || gGameExternalOptions.ubCoweringReducesSightRange == 2)
+ // SANDRO - this calls many sub-functions over and over, we should at least skip this for civilians and such
+ if ((gGameExternalOptions.ubCoweringReducesSightRange == 1 || gGameExternalOptions.ubCoweringReducesSightRange == 2) &&
+ IS_MERC_BODY_TYPE(pSoldier) && (pSoldier->bTeam == ENEMY_TEAM || pSoldier->bTeam == MILITIA_TEAM || pSoldier->bTeam == gbPlayerNum) )
{
INT8 bTolerance = CalcSuppressionTolerance( pSoldier );
@@ -1272,12 +1310,19 @@ INT16 DistanceVisible( SOLDIERTYPE *pSoldier, INT8 bFacingDir, INT8 bSubjectDir,
// give one step better vision for people with nightops
- if (HAS_SKILL_TRAIT( pSoldier, NIGHTOPS ))
+ // old/new traits check - SANDRO
+ if (gGameOptions.fNewTraitSystem)
{
- sDistVisible += NightBonusScale( 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS ), bLightLevel);
+ if (HAS_SKILL_TRAIT( pSoldier, NIGHT_OPS_NT ))
+ sDistVisible += NightBonusScale( gSkillTraitValues.ubNOeSightRangeBonusInDark, bLightLevel);
+ }
+ else
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, NIGHTOPS_OT ))
+ sDistVisible += NightBonusScale( 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS_OT ), bLightLevel);
}
// Bloodcat bonus only works above ground
- else if ( pSoldier->ubBodyType == BLOODCAT && gbWorldSectorZ == 0 )
+ if ( pSoldier->ubBodyType == BLOODCAT && gbWorldSectorZ == 0 )
{
sDistVisible += NightBonusScale( UVGOGGLES_BONUS, bLightLevel);
}
@@ -1335,16 +1380,30 @@ void EndMuzzleFlash( SOLDIERTYPE * pSoldier )
SOLDIERTYPE * pOtherSoldier;
pSoldier->flags.fMuzzleFlash = FALSE;
-
+/*comm by ddd
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
if ( pSoldier->bTeam != gbPlayerNum && pSoldier->bTeam != MILITIA_TEAM )
#else
if ( pSoldier->bTeam != gbPlayerNum )
#endif
+
{
pSoldier->bVisible = 0; // indeterminate state
}
+*/
+//ddd{
+if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+{ if ( pSoldier->bTeam != gbPlayerNum && pSoldier->bTeam != MILITIA_TEAM )
+ pSoldier->bVisible = 0; // indeterminate state
+}
+else
+{
+ if ( pSoldier->bTeam != gbPlayerNum )
+ pSoldier->bVisible = 0; // indeterminate state
+}
+//ddd}
+
for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++)
{
pOtherSoldier = MercSlots[ uiLoop ];
@@ -1362,6 +1421,7 @@ void EndMuzzleFlash( SOLDIERTYPE * pSoldier )
}
// else this person is still seen, if the looker is on our side or the militia the person should stay visible
+/* comm by ddd
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
else if ( pOtherSoldier->bTeam == gbPlayerNum || pOtherSoldier->bTeam == MILITIA_TEAM )
#else
@@ -1371,6 +1431,19 @@ void EndMuzzleFlash( SOLDIERTYPE * pSoldier )
{
pSoldier->bVisible = TRUE; // yes, still seen
}
+*/
+ //ddd{
+ else if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+ {
+ if ( pOtherSoldier->bTeam == gbPlayerNum || pOtherSoldier->bTeam == MILITIA_TEAM )
+ {pSoldier->bVisible = TRUE;} // yes, still seen
+ }
+ else
+ {
+ if ( pOtherSoldier->bTeam == gbPlayerNum )
+ pSoldier->bVisible = TRUE; // yes, still seen
+ }
+ //ddd}
}
}
}
@@ -1429,15 +1502,21 @@ INT8 DecideHearing( SOLDIERTYPE * pSoldier )
bHearing = 0;
- if (pSoldier->stats.bExpLevel > 3)
+ if (EffectiveExpLevel( pSoldier ) > 3) // SANDRO - changed to calculate effective level
{
bHearing++;
}
- if (HAS_SKILL_TRAIT( pSoldier, NIGHTOPS ))
+ // old/new traits check - SANDRO
+ if (gGameOptions.fNewTraitSystem)
{
- // sharper hearing generally
- bHearing += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS );
+ if (HAS_SKILL_TRAIT( pSoldier, NIGHT_OPS_NT ))
+ bHearing += gSkillTraitValues.ubNOHearingRangeBonus;
+ }
+ else
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, NIGHTOPS_OT ))
+ bHearing += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS_OT );
}
//bSlot = FindObj( pSoldier, EXTENDEDEAR );
@@ -1465,10 +1544,17 @@ INT8 DecideHearing( SOLDIERTYPE * pSoldier )
case 14:
case 15:
bHearing += 3;
- if (HAS_SKILL_TRAIT( pSoldier, NIGHTOPS ))
+ // yet another bonus for nighttime
+ // old/new traits check - SANDRO
+ if (gGameOptions.fNewTraitSystem)
{
- // yet another bonus for nighttime
- bHearing += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS );
+ if (HAS_SKILL_TRAIT( pSoldier, NIGHT_OPS_NT ))
+ bHearing += gSkillTraitValues.ubNOHearingRangeBonusInDark;
+ }
+ else
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, NIGHTOPS_OT ))
+ bHearing += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS_OT );
}
break;
default:
@@ -1707,6 +1793,7 @@ void HandleManNoLongerSeen( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent, INT
*pbPublOL = SEEN_THIS_TURN;
// ATE: Set visiblity to 0
+/*comm by ddd
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
if ( (pSoldier->bTeam == gbPlayerNum || pSoldier->bTeam == MILITIA_TEAM) && !(pOpponent->bTeam == gbPlayerNum || pOpponent->bTeam == MILITIA_TEAM ) )
#else
@@ -1715,6 +1802,18 @@ void HandleManNoLongerSeen( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent, INT
{
pOpponent->bVisible = 0;
}
+*/
+//ddd{
+if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+{ if ( (pSoldier->bTeam == gbPlayerNum || pSoldier->bTeam == MILITIA_TEAM) && !(pOpponent->bTeam == gbPlayerNum || pOpponent->bTeam == MILITIA_TEAM ) )
+ pOpponent->bVisible = 0;
+}
+else
+{ if ( pSoldier->bTeam == gbPlayerNum && pOpponent->bTeam != gbPlayerNum )
+ pOpponent->bVisible = 0;
+}
+//ddd}
+
}
}
#ifdef TESTOPPLIST
@@ -2304,7 +2403,8 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
}
*/
- PlayJA2Sample( BLOODCAT_ROAR, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
+ //PlayJA2Sample( BLOODCAT_ROAR, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
+ PlayJA2Sample( BLOODCAT_ROAR, RATE_11025, MIDVOLUME +10, 1, MIDDLEPAN );
}
else
{
@@ -2312,7 +2412,8 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
{
if ( Random( 2 ) == 0 )
{
- PlayJA2Sample( BLOODCAT_ROAR, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
+ //PlayJA2Sample( BLOODCAT_ROAR, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
+ PlayJA2Sample( BLOODCAT_ROAR, RATE_11025, MIDVOLUME + 10, 1, MIDDLEPAN );
}
}
}
@@ -2445,8 +2546,22 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
// man is seeing an opponent AGAIN whom he has seen at least once before
gbSeenOpponents[pSoldier->ubID][pOpponent->ubID] = TRUE;
+//ddd{
+BOOLEAN SEE_MENT = FALSE;
+if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+{
+ if ( ( PTR_OURTEAM || (pSoldier->bTeam == MILITIA_TEAM) ) && (pOpponent->bVisible <= 0))
+ SEE_MENT = TRUE;
+}
+else
+{
+ if (PTR_OURTEAM && (pOpponent->bVisible <= 0))
+ SEE_MENT = TRUE;
+}
+//ddd}
+/*comm by ddd
// if looker is on local team, and the enemy was invisible or "maybe"
// visible just prior to this
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
@@ -2454,6 +2569,8 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo,
#else
if (PTR_OURTEAM && (pOpponent->bVisible <= 0))
#endif
+*/
+if(SEE_MENT)
{
// if opponent was truly invisible, not just turned off temporarily (FALSE)
if (pOpponent->bVisible == -1)
@@ -2608,6 +2725,7 @@ void OtherTeamsLookForMan(SOLDIERTYPE *pOpponent)
//NumMessage("OtherTeamsLookForMan, guy#",oppPtr->guynum);
+/* comm by ddd
// if the guy we're looking for is NOT on our team AND is currently visible
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
if ((pOpponent->bTeam != gbPlayerNum && pOpponent->bTeam != MILITIA_TEAM) && (pOpponent->bVisible >= 0 && pOpponent->bVisible < 2) && pOpponent->stats.bLife)
@@ -2618,7 +2736,19 @@ void OtherTeamsLookForMan(SOLDIERTYPE *pOpponent)
// assume he's no longer visible, until one of our mercs sees him again
pOpponent->bVisible = 0;
}
-
+*/
+//ddd{
+if(gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+{
+ if ((pOpponent->bTeam != gbPlayerNum && pOpponent->bTeam != MILITIA_TEAM) && (pOpponent->bVisible >= 0 && pOpponent->bVisible < 2) && pOpponent->stats.bLife)
+ pOpponent->bVisible = 0;
+}
+else
+{
+if ((pOpponent->bTeam != gbPlayerNum) && (pOpponent->bVisible >= 0 && pOpponent->bVisible < 2) && pOpponent->stats.bLife)
+pOpponent->bVisible = 0;
+}
+//ddd}
#ifdef TESTOPPLIST
DebugMsg( TOPIC_JA2OPPLIST, DBG_LEVEL_3,
String("OTHERTEAMSLOOKFORMAN ID %d(%S) team %d side %d",pOpponent->ubID,pOpponent->name,pOpponent->bTeam,pOpponent->bSide ));
@@ -3105,11 +3235,24 @@ void BetweenTurnsVisibilityAdjustments(void)
{
if (pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife)
{
+ //ddd{
+ BOOLEAN SEE_MENT = FALSE;
+ if (gGameExternalOptions.bWeSeeWhatMilitiaSeesAndViceVersa)
+ {if (!PTR_OURTEAM && pSoldier->bTeam != MILITIA_TEAM)
+ SEE_MENT = TRUE;
+ }
+ else
+ { if (!PTR_OURTEAM) SEE_MENT = TRUE;
+ }
+ //ddd}
+/*comm by ddd
#ifdef WE_SEE_WHAT_MILITIA_SEES_AND_VICE_VERSA
if (!PTR_OURTEAM && pSoldier->bTeam != MILITIA_TEAM)
#else
if (!PTR_OURTEAM)
#endif
+ */
+ if(SEE_MENT)
{
// check if anyone on our team currently sees him (exclude NOBODY)
if (TeamNoLongerSeesMan(gbPlayerNum,pSoldier,NOBODY,0))
@@ -3266,6 +3409,8 @@ void SaySeenQuote( SOLDIERTYPE *pSoldier, BOOLEAN fSeenCreature, BOOLEAN fVirgin
TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
}
#else
+ //ddd TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
+ if(Chance(gGameExternalOptions.iChanceSayAnnoyingPhrase) )
TacticalCharacterDialogue( pSoldier, QUOTE_SEE_ENEMY );
#endif
}
@@ -3328,7 +3473,7 @@ void OurTeamSeesSomeone( SOLDIERTYPE * pSoldier, INT8 bNumReRevealed, INT8 bNumN
if ( ( gTacticalStatus.uiFlags & INCOMBAT ) )
{
// If we are NOT in any music mode...
- if ( gubMusicMode == MUSIC_NONE )
+ if ( GetMusicMode() == MUSIC_NONE )
{
SetMusicMode( MUSIC_TACTICAL_BATTLE );
}
@@ -4309,7 +4454,9 @@ void DebugSoldierPage3( )
ubLine++;
// OPIONION OF SELECTED MERC
- if ( gusSelectedSoldier != NOBODY && ( MercPtrs[ gusSelectedSoldier ]->ubProfile < FIRST_NPC ) && pSoldier->ubProfile != NO_PROFILE )
+ //if ( gusSelectedSoldier != NOBODY && ( MercPtrs[ gusSelectedSoldier ]->ubProfile < FIRST_NPC ) && pSoldier->ubProfile != NO_PROFILE )
+ //new profiles by Jazz
+ if ( gusSelectedSoldier != NOBODY && ( gProfilesIMP[MercPtrs[ gusSelectedSoldier ]->ubProfile].ProfilId == MercPtrs[ gusSelectedSoldier ]->ubProfile || gProfilesRPC[MercPtrs[ gusSelectedSoldier ]->ubProfile].ProfilId == MercPtrs[ gusSelectedSoldier ]->ubProfile || gProfilesAIM[MercPtrs[ gusSelectedSoldier ]->ubProfile].ProfilId == MercPtrs[ gusSelectedSoldier ]->ubProfile || gProfilesMERC[MercPtrs[ gusSelectedSoldier ]->ubProfile].ProfilId == MercPtrs[ gusSelectedSoldier ]->ubProfile ) && pSoldier->ubProfile != NO_PROFILE )
{
SetFontShade(LARGEFONT1, FONT_SHADE_GREEN);
gprintf( 0, LINE_HEIGHT * ubLine, L"NPC Opinion:");
@@ -4447,12 +4594,13 @@ void WriteQuantityAndAttachments( OBJECTTYPE *pObject, INT32 yp )
return;
//Build attachment string
fAttachments = FALSE;
- if( (*pObject)[0]->attachments.empty() == false )
+ if( (*pObject)[0]->AttachmentListSize() > 0 )
{
fAttachments = TRUE;
swprintf( szAttach, L"(" );
for (attachmentList::iterator iter = (*pObject)[0]->attachments.begin(); iter != (*pObject)[0]->attachments.end(); ++iter) {
- AppendAttachmentCode( iter->usItem, szAttach );
+ if(iter->exists())
+ AppendAttachmentCode( iter->usItem, szAttach );
}
wcscat( szAttach, L" )" );
}
@@ -4519,7 +4667,7 @@ void DebugSoldierPage4( )
SetFontShade(LARGEFONT1, FONT_SHADE_GREEN);
gprintf( 0, LINE_HEIGHT * ubLine, L"Exp. Level:");
SetFontShade(LARGEFONT1, FONT_SHADE_NEUTRAL);
- gprintf( 150, LINE_HEIGHT * ubLine, L"%d", pSoldier->stats.bExpLevel );
+ gprintf( 150, LINE_HEIGHT * ubLine, L"%d ( %d )", pSoldier->stats.bExpLevel, EffectiveExpLevel(pSoldier) ); // SANDRO - added effective level calc
switch( pSoldier->ubSoldierClass )
{
case SOLDIER_CLASS_ADMINISTRATOR: gprintf( 320, LINE_HEIGHT * ubLine, L"(Administrator)" ); break;
@@ -4998,16 +5146,23 @@ UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
return( (UINT8) (MAX_MOVEMENT_NOISE - PreRandom( 2 )) );
}
- iStealthSkill = 20 + 4 * EffectiveExpLevel( pSoldier ) + ((EffectiveDexterity( pSoldier ) * 4) / 10); // 24-100
+ // CHANGED BY SANDRO - LET'S MAKE THE STEALTH BASED ON AGILITY LIKE IT SHOULD BE
+ //iStealthSkill = 20 + 4 * EffectiveExpLevel( pSoldier ) + ((EffectiveDexterity( pSoldier ) * 4) / 10); // 24-100
+ iStealthSkill = 20 + 4 * EffectiveExpLevel( pSoldier ) + ((EffectiveAgility( pSoldier ) * 4) / 10); // 24-100
// big bonus for those "extra stealthy" mercs
if ( pSoldier->ubBodyType == BLOODCAT )
{
iStealthSkill += 50;
}
- else if (HAS_SKILL_TRAIT( pSoldier, STEALTHY ))
+ // SANDRO - new/old traits
+ else if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_NT ))
{
- iStealthSkill += 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY );
+ iStealthSkill += gSkillTraitValues.ubSTBonusToMoveQuietly;
+ }
+ else if ( !gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_OT ))
+ {
+ iStealthSkill += 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_OT );
}
if ( GetWornStealth(pSoldier) > 0 )
@@ -5618,9 +5773,18 @@ void ProcessNoise(UINT8 ubNoiseMaker, INT32 sGridNo, INT8 bLevel, UINT8 ubTerrTy
case WARDEN:
case GENERAL:
case SERGEANT:
- case CONRAD:
- // ignore soldier team
- continue;
+ case CONRAD:
+ // WANNE: This fixes the bug, that Conrad, when he is in OUR team, cannot interrupt enemies!!!
+ if (pSoldier->bTeam == OUR_TEAM)
+ {
+ // WANNE: Allow interrupt, if one of those guys is in OUR team!
+ break;
+ }
+ else
+ {
+ // No interrupt for those 4 guys
+ continue;
+ }
default:
break;
}
@@ -5865,6 +6029,13 @@ UINT8 CalcEffVolume(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT8 ubN
// effective volume fades over distance beyond 1 tile away
iEffVolume -= (iDistance - 1);
+ //ddd{ ;)
+ if(gGameExternalOptions.bLazyCivilians)
+ if (pSoldier->bTeam == CIV_TEAM && pSoldier->ubBodyType != CROW )
+ if (pSoldier->ubCivilianGroup == 0 && pSoldier->ubProfile == NO_PROFILE)
+ iEffVolume =-100;
+ //ddd}
+
/*
if (pSoldier->bTeam == CIV_TEAM && pSoldier->ubBodyType != CROW )
{
diff --git a/Tactical/opplist.h b/Tactical/opplist.h
index c1c9a09a..95559a88 100644
--- a/Tactical/opplist.h
+++ b/Tactical/opplist.h
@@ -79,6 +79,7 @@ extern INT32 gsWatchedLoc[ TOTAL_SOLDIERS ][ NUM_WATCHED_LOCS ];
extern INT8 gbWatchedLocLevel[ TOTAL_SOLDIERS ][ NUM_WATCHED_LOCS ];
extern UINT8 gubWatchedLocPoints[ TOTAL_SOLDIERS ][ NUM_WATCHED_LOCS ];
extern BOOLEAN gfWatchedLocReset[ TOTAL_SOLDIERS ][ NUM_WATCHED_LOCS ];
+extern INT8 STRAIGHT;
#define BEST_SIGHTING_ARRAY_SIZE 6
#define BEST_SIGHTING_ARRAY_SIZE_ALL_TEAMS_LOOK_FOR_ALL 6
diff --git a/Tactical/qarray.h b/Tactical/qarray.h
index 625315d1..58fdbc36 100644
--- a/Tactical/qarray.h
+++ b/Tactical/qarray.h
@@ -11,6 +11,21 @@ extern BOOLEAN QuoteExp_PassingDislike[NUM_PROFILES];
extern BOOLEAN QuoteExp_WitnessQueenBugDeath[NUM_PROFILES];
extern BOOLEAN QuoteExp_WitnessDeidrannaDeath[NUM_PROFILES];
+typedef struct
+{
+ UINT16 uiIndex;
+ BOOLEAN QuoteExpHeadShotOnly;
+ BOOLEAN QuoteExpTeamSpecific;
+ BOOLEAN QuoteExpGenderCode;
+ BOOLEAN QuoteExpGotGunOrUsedGun;
+ BOOLEAN QuoteExpPassingDislike;
+ BOOLEAN QuoteExpWitnessQueenBugDeath;
+ BOOLEAN QuoteExpWitnessDeidrannaDeath;
+
+} QARRAY_VALUES;
+
+extern QARRAY_VALUES QuoteExp[NUM_PROFILES];
+
#endif
\ No newline at end of file
diff --git a/Tactical/soldier profile type.h b/Tactical/soldier profile type.h
index 89571ca6..480bf111 100644
--- a/Tactical/soldier profile type.h
+++ b/Tactical/soldier profile type.h
@@ -4,7 +4,9 @@
#include "overhead types.h"
#include "Soldier Control.h"
-#define NUM_PROFILES 170
+#define NUM_PROFILES 255 //170 new profiles by Jazz
+//tais: maximum amount of starting gear kits
+#define NUM_MERCSTARTINGGEAR_KITS 5
#define FIRST_RPC 57
#define FIRST_NPC 75
@@ -92,34 +94,100 @@ inline bool OKToCheckOpinion(int profileNumber) {
return (profileNumber < DontUseMeDirectly::MaxIDToCheckForMorale);
}
-
+// SANDRO - replaced this list to represent the old traits only
typedef enum
{
- NO_SKILLTRAIT = 0,
- LOCKPICKING,
- HANDTOHAND,
- ELECTRONICS,
- NIGHTOPS,
- THROWING,
- TEACHING,
- HEAVY_WEAPS,
- AUTO_WEAPS,
- STEALTHY,
- AMBIDEXT,
- THIEF,
- MARTIALARTS,
- KNIFING,
- PROF_SNIPER,
- CAMOUFLAGED,
- CAMOUFLAGED_URBAN,
- CAMOUFLAGED_DESERT,
- CAMOUFLAGED_SNOW,
- NUM_SKILLTRAITS
+ NO_SKILLTRAIT_OT = 0,
+ LOCKPICKING_OT,
+ HANDTOHAND_OT,
+ ELECTRONICS_OT,
+ NIGHTOPS_OT,
+ THROWING_OT,
+ TEACHING_OT,
+ HEAVY_WEAPS_OT,
+ AUTO_WEAPS_OT,
+ STEALTHY_OT,
+ AMBIDEXT_OT,
+ THIEF_OT,
+ MARTIALARTS_OT,
+ KNIFING_OT,
+ PROF_SNIPER_OT,
+ CAMOUFLAGED_OT,
+ // SANDRO - I dared to remove these for it is really useless,
+ // with the camo removing/repainting feature you only need the basic camouflage trait anyway
+ //CAMOUFLAGED_URBAN,
+ //CAMOUFLAGED_DESERT,
+ //CAMOUFLAGED_SNOW,
+ EXPERT,
+ NUM_SKILLTRAITS_OT
} SkillTrait;
+//////////////////////////////////////////////////////////////////////
+// SANDRO - the list for new traits
typedef enum
{
- NO_PERSONALITYTRAIT = 0,
+ NO_SKILLTRAIT_NT = 0,
+ // MAJOR TRAITS
+ AUTO_WEAPONS_NT, // 1
+ HEAVY_WEAPONS_NT, // 2
+ SNIPER_NT, // 3
+ RANGER_NT, // 4
+ GUNSLINGER_NT, // 5
+ MARTIAL_ARTS_NT, // 6
+ SQUADLEADER_NT, // 7
+ TECHNICIAN_NT, // 8
+ DOCTOR_NT, // 9
+ // MINOR TRAITS
+ AMBIDEXTROUS_NT, // 10
+ MELEE_NT, // 11
+ THROWING_NT, // 12
+ NIGHT_OPS_NT, // 13
+ STEALTHY_NT, // 14
+ ATHLETICS_NT, // 15
+ BODYBUILDING_NT, // 16
+ DEMOLITIONS_NT, // 17
+ TEACHING_NT, // 18
+ SCOUTING_NT, // 19
+ NUM_SKILLTRAITS_NT
+} SkillTraitNew;
+
+#define NUM_MAJOR_TRAITS 9
+#define NUM_MINOR_TRAITS 10
+
+// SANDRO - new set of character traits
+typedef enum
+{
+ CHAR_TRAIT_NORMAL = 0,
+ CHAR_TRAIT_SOCIABLE,
+ CHAR_TRAIT_LONER,
+ CHAR_TRAIT_OPTIMIST,
+ CHAR_TRAIT_ASSERTIVE,
+ CHAR_TRAIT_INTELLECTUAL,
+ CHAR_TRAIT_PRIMITIVE,
+ CHAR_TRAIT_AGGRESSIVE,
+ CHAR_TRAIT_PHLEGMATIC,
+ CHAR_TRAIT_DAUNTLESS,
+ CHAR_TRAIT_PACIFIST,
+ CHAR_TRAIT_MALICIOUS,
+ CHAR_TRAIT_SHOWOFF,
+ NUM_CHAR_TRAITS
+} CharacterTraits;
+
+// SANDRO - appearances
+typedef enum
+{
+ APPEARANCE_AVARAGE = 0,
+ APPEARANCE_UGLY,
+ APPEARANCE_HOMELY,
+ APPEARANCE_ATTRACTIVE,
+ APPEARANCE_BABE,
+ NUM_APPEARANCES
+} Appearances;
+//////////////////////////////////////////////////////////////////////
+
+typedef enum
+{
+ NO_DISABILITY = 0,
HEAT_INTOLERANT,
NERVOUS,
CLAUSTROPHOBIC,
@@ -127,7 +195,7 @@ typedef enum
FEAR_OF_INSECTS,
FORGETFUL,
PSYCHO,
- NUM_PERSONALITYTRAIT
+ NUM_DISABILITIES
} PersonalityTrait;
#define NERVOUS_RADIUS 10
@@ -176,6 +244,73 @@ typedef enum{
#define BUDDY_OPINION +25
#define HATED_OPINION -25
+///////////////////////////////////////////////////////////////////////////////////////////////
+// SANDRO - Let's add a nice new struct for records, as there are just too many of them
+class STRUCT_Records
+{
+public:
+
+ UINT16 usKillsElites;
+ UINT16 usKillsRegulars;
+ UINT16 usKillsAdmins;
+ UINT16 usKillsHostiles;
+ UINT16 usKillsCreatures;
+ UINT16 usKillsTanks;
+ UINT16 usKillsOthers;
+
+ UINT16 usAssistsMercs;
+ UINT16 usAssistsMilitia;
+ UINT16 usAssistsOthers;
+
+ UINT16 usShotsFired;
+ UINT16 usMissilesLaunched;
+ UINT16 usGrenadesThrown;
+ UINT16 usKnivesThrown;
+ UINT16 usBladeAttacks;
+ UINT16 usHtHAttacks;
+ UINT16 usShotsHit;
+
+ UINT16 usBattlesTactical;
+ UINT16 usBattlesAutoresolve;
+ UINT16 usBattlesRetreated;
+ UINT16 usAmbushesExperienced;
+ UINT16 usLargestBattleFought;
+
+ UINT16 usTimesWoundedShot;
+ UINT16 usTimesWoundedStabbed;
+ UINT16 usTimesWoundedPunched;
+ UINT16 usTimesWoundedBlasted;
+ UINT16 usTimesStatDamaged;
+ UINT16 usTimesSurgeryUndergoed;
+ UINT16 usFacilityAccidents;
+
+ UINT16 usLocksPicked;
+ UINT16 usLocksBreached;
+ UINT16 usTrapsRemoved;
+ UINT16 usExpDetonated;
+ UINT16 usItemsRepaired;
+ UINT16 usItemsCombined;
+ UINT16 usItemsStolen;
+ UINT16 usMercsBandaged;
+ UINT16 usSurgeriesMade;
+ UINT16 usMilitiaTrained;
+ UINT16 usNPCsDiscovered;
+ UINT16 usSectorsDiscovered;
+ UINT8 ubQuestsHandled;
+
+ UINT16 zFiller1;
+ UINT16 zFiller2;
+ UINT16 zFiller3;
+ UINT16 zFiller4;
+ UINT16 zFiller5;
+ UINT16 zFiller6;
+ UINT16 zFiller7;
+ UINT16 zFiller8;
+ UINT8 zFiller9;
+
+}; // RECORDS
+//////////////////////////////////////////////////////////////////////////////
+
// CHRISL: Class to handle profile equipment from XML_MercStartingGear
class MERCPROFILEGEAR {
public:
@@ -193,6 +328,7 @@ public:
void clearInventory();
public:
UINT16 mIndex;
+ INT16 PriceModifier;
CHAR8 mName[80];
char endOfPOD; // marker for end of POD (plain old data)
std::vector inv;
@@ -300,7 +436,7 @@ public:
INT16 sSalary;
INT8 bLife;
INT8 bDexterity; // dexterity (hand coord) value
- INT8 bPersonalityTrait;
+ INT8 bDisability;
INT8 bSkillTrait;
INT8 bReputationTolerance;
@@ -524,12 +660,16 @@ public:
INT8 bExplosivesDelta;
INT8 bStrengthDelta;
INT8 bLeadershipDelta;
- UINT16 usKills;
- UINT16 usAssists;
- UINT16 usShotsFired;
- UINT16 usShotsHit;
- UINT16 usBattlesFought;
- UINT16 usTimesWounded;
+ /////////////////////////////////////////////////////////////
+ // SANDRO - converted to it's own structure
+ //UINT16 usKills;
+ //UINT16 usAssists;
+ //UINT16 usShotsFired;
+ //UINT16 usShotsHit;
+ //UINT16 usBattlesFought;
+ //UINT16 usTimesWounded;
+ /////////////////////////////////////////////////////////////
+
UINT16 usTotalDaysServed;
INT16 sLeadershipGain;
@@ -543,12 +683,13 @@ public:
INT16 sSalary;
INT8 bLife;
INT8 bDexterity; // dexterity (hand coord) value
- INT8 bPersonalityTrait;
- INT8 bSkillTrait;
+ INT8 bDisability;
+ INT8 bSkillTraits[30];
INT8 bReputationTolerance;
INT8 bExplosive;
- INT8 bSkillTrait2;
+ //INT8 bSkillTrait2;
+ //INT8 bSkillTrait3; // added by SANDRO
INT8 bLeadership;
INT8 bBuddy[5];
@@ -598,6 +739,7 @@ public:
UINT32 uiBiWeeklySalary;
INT8 bMedicalDeposit;
INT8 bAttitude;
+ INT8 bCharacterTrait; // added by SANDRO
INT8 bBaseMorale;
UINT16 sMedicalDepositAmount;
@@ -660,6 +802,10 @@ public:
std::vector inv;
std::vector bInvStatus;
std::vector bInvNumber;
+
+ // SANDRO - merc records
+ STRUCT_Records records;
+
}; // MERCPROFILESTRUCT;
// WANNE - BMP: DONE!
@@ -753,7 +899,7 @@ public:
INT16 sSalary;
INT8 bLife;
INT8 bDexterity; // dexterity (hand coord) value
- INT8 bPersonalityTrait;
+ INT8 bDisability;
INT8 bSkillTrait;
INT8 bReputationTolerance;
diff --git a/TacticalAI/AIInternals.h b/TacticalAI/AIInternals.h
index 711d295a..7964c0f1 100644
--- a/TacticalAI/AIInternals.h
+++ b/TacticalAI/AIInternals.h
@@ -236,3 +236,14 @@ INT8 FindDirectionForClimbing( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel
INT16 AssessTacticalSituation( INT8 bSide );
BOOLEAN TeamSeesOpponent( INT8 bSide, SOLDIERTYPE * pOpponent );
INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy );
+
+// SANDRO - added following functions
+BOOLEAN DoctorIsPresent( SOLDIERTYPE * pPatient, BOOLEAN fOnDoctorAssignmentCheck );
+BOOLEAN AIDetermineStealingWeaponAttempt( SOLDIERTYPE * pSoldier, SOLDIERTYPE * ubOpponent );
+
+// HEADROCK HAM 4: Calculate average recoil offset for a shot.
+FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum);
+
+
+// HEADROCK HAM 4: Calculate average recoil offset for a shot.
+FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum);
diff --git a/TacticalAI/AIMain.cpp b/TacticalAI/AIMain.cpp
index 2122cd3c..43385103 100644
--- a/TacticalAI/AIMain.cpp
+++ b/TacticalAI/AIMain.cpp
@@ -55,6 +55,7 @@
#include "Queen Command.h"
#include "cheats.h"
#include "points.h"
+#include "Soldier Functions.h" // added by SANDRO
#endif
#include "connect.h"
@@ -2043,6 +2044,23 @@ void AIDecideRadioAnimation( SOLDIERTYPE *pSoldier )
}
}
+UINT32 GetTankCannonIndex()
+{
+ UINT32 tankCannonIndex = 0;
+
+ for (UINT32 i = 0; i < MAXITEMS; i++)
+ {
+ if (Item[i].cannon)
+ {
+ tankCannonIndex = Item[i].uiIndex;
+ break;
+ }
+ }
+
+ return tankCannonIndex;
+}
+
+
INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
{
@@ -2056,8 +2074,29 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
// reset this field, too
pSoldier->aiData.bLastAttackHit = FALSE;
+ // WANNE.TANK: Choose cannon or rocket
UINT16 usHandItem = pSoldier->inv[HANDPOS].usItem;
+ if (TANK(pSoldier))
+ {
+ // No cannon selected to fire
+ if (!Item[pSoldier->inv[HANDPOS].usItem].cannon)
+ {
+ // 50 % chance, that the tank fires with the explosive cannon
+ UINT32 fireWithCannon = GetRndNum(2);
+ if (fireWithCannon)
+ {
+ UINT32 tankCannonIndex = GetTankCannonIndex();
+ if (tankCannonIndex > 0)
+ {
+ usHandItem = tankCannonIndex;
+ }
+ }
+ }
+ }
+
+ UINT16 usSoldierIndex; // added by SANDRO
+
#ifdef TESTAICONTROL
if (gfTurnBasedAI || gTacticalStatus.fAutoBandageMode)
{
@@ -2065,7 +2104,7 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
}
#endif
- DebugAI( String( "%d does %s (a.d. %d) at time %ld", pSoldier->ubID, gzActionStr[pSoldier->aiData.bAction], pSoldier->aiData.usActionData, GetJA2Clock() ) );
+ DebugAI( String( "%d does %s (a.d. %d) at time %lu", pSoldier->ubID, gzActionStr[pSoldier->aiData.bAction], pSoldier->aiData.usActionData, GetJA2Clock() ) );
// 0verhaul: The decideaction stage does so many path plots and overrides that
// relying on a stored path from there is a bad idea.
@@ -2183,7 +2222,17 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
case AI_ACTION_LEAVE_WATER_GAS: // seek nearest spot of ungassed land
case AI_ACTION_SEEK_NOISE: // seek most important noise heard
case AI_ACTION_RUN_AWAY: // run away from nearby opponent(s)
-
+ // SANDRO - ENEMY TAUNTS
+ if (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] == TRUE && pSoldier->bTeam == ENEMY_TEAM && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) && pSoldier->bVisible != -1 )
+ {
+ if ( Random( 5 ) == 0 )
+ {
+ if (pSoldier->aiData.bAction == AI_ACTION_SEEK_NOISE )
+ StartEnemyTaunt( pSoldier, TAUNT_SEEK_NOISE );
+ else if (pSoldier->aiData.bAction == AI_ACTION_RUN_AWAY )
+ StartEnemyTaunt( pSoldier, TAUNT_RUN_AWAY );
+ }
+ }
case AI_ACTION_APPROACH_MERC: // walk up to someone to talk
case AI_ACTION_TRACK: // track by ground scent
case AI_ACTION_EAT: // monster approaching corpse
@@ -2400,8 +2449,28 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
// ATE: Make sure it's a person :)
if ( IS_MERC_BODY_TYPE( pSoldier ) && pSoldier->ubProfile == NO_PROFILE )
{
+ // SANDRO - SOLDIER TAUNTS
+ if (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] == TRUE && pSoldier->bTeam == ENEMY_TEAM && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) )
+ {
+ if ( Random( 8 ) == 0 )
+ {
+ if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_GUN )
+ StartEnemyTaunt( pSoldier, TAUNT_FIRE_GUN );
+ else if (Item[pSoldier->inv[HANDPOS].usItem].grenadelauncher || Item[pSoldier->inv[HANDPOS].usItem].mortar || Item[pSoldier->inv[HANDPOS].usItem].rocketlauncher )
+ StartEnemyTaunt( pSoldier, TAUNT_FIRE_LAUNCHER );
+ else if (pSoldier->aiData.bAction == AI_ACTION_TOSS_PROJECTILE && Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_THROWN && !Item[pSoldier->inv[HANDPOS].usItem].flare )
+ StartEnemyTaunt( pSoldier, TAUNT_THROW );
+ else if (pSoldier->aiData.bAction == AI_ACTION_KNIFE_MOVE )
+ {
+ if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_BLADE )
+ StartEnemyTaunt( pSoldier, TAUNT_CHARGE_KNIFE );
+ //else if (Item[pSoldier->inv[HANDPOS].usItem].usItemClass == IC_PUNCH )
+ // StartEnemyTaunt( pSoldier, TAUNT_CHARGE_HTH );
+ }
+ }
+ }
// CC, ATE here - I put in some TEMP randomness...
- if ( Random( 50 ) == 0 )
+ else if ( Random( 50 ) == 0 )
{
StartCivQuote( pSoldier );
}
@@ -2489,6 +2558,15 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
{
HandleInitialRedAlert(pSoldier->bTeam, TRUE);
}
+
+ // SANDRO - ENEMY TAUNTS
+ if (gGameSettings.fOptions[TOPTION_ALLOW_TAUNTS] == TRUE && pSoldier->bTeam == ENEMY_TEAM && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) && pSoldier->bVisible != -1 )
+ {
+ if ( Random( 4 ) == 0 )
+ {
+ StartEnemyTaunt( pSoldier, TAUNT_ALERT );
+ }
+ }
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Debug: AI radios your position!" );
// DROP THROUGH HERE!
case AI_ACTION_YELLOW_ALERT: // tell friends opponent(s) heard
@@ -2679,6 +2757,18 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier)
// start the offer of surrender!
StartCivQuote( pSoldier );
break;
+ /////////////////////////////////////////////////////////////
+ // SANDRO - added a possibility for enemies to try to steal your gun
+ case AI_ACTION_STEAL_MOVE: // preparing to steal opponents weapon
+
+ pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
+ pSoldier->usUIMovementMode = DetermineMovementMode( pSoldier, AI_ACTION_KNIFE_MOVE );
+ usSoldierIndex = WhoIsThere2( pSoldier->aiData.usActionData, pSoldier->bTargetLevel);
+ if ( usSoldierIndex != NOBODY )
+ MercStealFromMerc( pSoldier, MercPtrs[usSoldierIndex] );
+
+ break;
+ /////////////////////////////////////////////////////////////
default:
#ifdef BETAVERSION
diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp
index 9edd44f0..c67dd728 100644
--- a/TacticalAI/AIUtils.cpp
+++ b/TacticalAI/AIUtils.cpp
@@ -23,8 +23,14 @@
#include "environment.h"
#include "lighting.h"
#include "Soldier Create.h"
+ #include "SkillCheck.h" // added by SANDRO
#endif
+//////////////////////////////////////////////////////////////////////////////
+// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
+// On the bottom here, there are these functions made
+//////////////////////////////////////////////////////////////////////
+
//
// CJC's DG->JA2 conversion notes
//
@@ -151,9 +157,9 @@ UINT8 StanceChange( SOLDIERTYPE * pSoldier, INT16 ubAttackAPCost )
if (PTR_STANDING)
{
- if (pSoldier->bActionPoints - ubAttackAPCost >= APBPConstants[AP_CROUCH])
+ if (pSoldier->bActionPoints - ubAttackAPCost >= GetAPsCrouch(pSoldier, TRUE))
{
- if ( (pSoldier->bActionPoints - ubAttackAPCost >= APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE]) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
+ if ( (pSoldier->bActionPoints - ubAttackAPCost >= GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE)) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
{
return( ANIM_PRONE );
}
@@ -165,7 +171,7 @@ UINT8 StanceChange( SOLDIERTYPE * pSoldier, INT16 ubAttackAPCost )
}
else if (PTR_CROUCHED)
{
- if ( (pSoldier->bActionPoints - ubAttackAPCost >= APBPConstants[AP_PRONE]) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
+ if ( (pSoldier->bActionPoints - ubAttackAPCost >= GetAPsProne(pSoldier, TRUE)) && IsValidStance( pSoldier, ANIM_PRONE ) && ConsiderProne( pSoldier ) )
{
return( ANIM_PRONE );
}
@@ -192,7 +198,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b
uiCurrChanceOfDamage = 0;
bAPsAfterAttack = pSoldier->bActionPoints - MinAPsToAttack( pSoldier, pAttack->sTarget, ADDTURNCOST, 1);
- if (bAPsAfterAttack < APBPConstants[AP_CROUCH])
+ if (bAPsAfterAttack < GetAPsCrouch(pSoldier, TRUE))
{
return( 0 );
}
@@ -220,7 +226,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b
for (bLoop = 0; bLoop < 3; bLoop++)
{
bStanceDiff = abs( bLoop - bStanceNum );
- if (bStanceDiff == 2 && bAPsAfterAttack < APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE])
+ if (bStanceDiff == 2 && bAPsAfterAttack < GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE))
{
// can't consider this!
continue;
@@ -487,7 +493,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
break;
case AI_ACTION_PICKUP_ITEM: // grab things lying on the ground
- bMinPointsNeeded = __max( MinPtsToMove( pSoldier ), APBPConstants[AP_PICKUP_ITEM] );
+ bMinPointsNeeded = __max( MinPtsToMove( pSoldier ), GetBasicAPsToPickupItem( pSoldier ) ); // SANDRO
break;
case AI_ACTION_OPEN_OR_CLOSE_DOOR:
@@ -497,7 +503,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
break;
case AI_ACTION_DROP_ITEM:
- bMinPointsNeeded = APBPConstants[AP_PICKUP_ITEM];
+ bMinPointsNeeded = GetBasicAPsToPickupItem( pSoldier ); // SANDRO
break;
case AI_ACTION_FIRE_GUN: // shoot at nearby opponent
@@ -534,7 +540,7 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
break;
case AI_ACTION_CHANGE_STANCE: // crouch
- bMinPointsNeeded = APBPConstants[AP_CROUCH];
+ bMinPointsNeeded = GetAPsCrouch(pSoldier, TRUE);
break;
case AI_ACTION_GIVE_AID: // help injured/dying friend
@@ -542,16 +548,17 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
break;
case AI_ACTION_CLIMB_ROOF:
+ // SANDRO - improved this a bit
if (pSoldier->pathing.bLevel == 0)
{
- if( PTR_CROUCHED ) bAPForStandUp = 2;
- if( PTR_PRONE ) bAPForStandUp = 4;
- bMinPointsNeeded = APBPConstants[AP_CLIMBROOF] + bAPForStandUp + bAPToLookAtWall;
+ if( PTR_CROUCHED ) bAPForStandUp = (INT8)(GetAPsCrouch(pSoldier, TRUE));
+ if( PTR_PRONE ) bAPForStandUp = GetAPsCrouch(pSoldier, TRUE) + GetAPsProne(pSoldier, TRUE);
+ bMinPointsNeeded = GetAPsToClimbRoof( pSoldier, FALSE ) + bAPForStandUp + bAPToLookAtWall;
}
else
{
- if( !PTR_CROUCHED ) bAPForStandUp = 2;
- bMinPointsNeeded = APBPConstants[AP_CLIMBOFFROOF] + bAPForStandUp + bAPToLookAtWall;
+ if( !PTR_CROUCHED ) bAPForStandUp = (INT8)(GetAPsCrouch(pSoldier, TRUE));
+ bMinPointsNeeded = GetAPsToClimbRoof( pSoldier, TRUE ) + bAPForStandUp + bAPToLookAtWall;
}
break;
@@ -564,6 +571,10 @@ BOOLEAN IsActionAffordable(SOLDIERTYPE *pSoldier)
bMinPointsNeeded = 0;
break;
+ case AI_ACTION_STEAL_MOVE: // added by SANDRO
+ //bMinPointsNeeded = GetAPsToStealItem( pSoldier, NULL, pSoldier->aiData.usActionData );;
+ break;
+
default:
#ifdef BETAVERSION
//NumMessage("AffordableAction - Illegal action type = ",pSoldier->aiData.bAction);
@@ -2084,6 +2095,9 @@ INT8 CalcMorale(SOLDIERTYPE *pSoldier)
(pSoldier->aiData.bAttitude == BRAVESOLO || pSoldier->aiData.bAttitude == BRAVEAID))
bMoraleCategory = MORALE_WORRIED;
+ // SANDRO - on Insane difficulty enemy morale cannot go below worried
+ if (bMoraleCategory == MORALE_HOPELESS && gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
+ bMoraleCategory = MORALE_WORRIED;
#ifdef DEBUGDECISIONS
STR tempstr;
@@ -2128,7 +2142,7 @@ INT32 CalcManThreatValue( SOLDIERTYPE *pEnemy, INT32 sMyGrid, UINT8 ubReduceForC
else
{
// ADD twice the man's level (2-20)
- iThreatValue += pEnemy->stats.bExpLevel;
+ iThreatValue += EffectiveExpLevel(pEnemy); // SANDRO - find precise effective exp level
// ADD man's total action points (10-35)
iThreatValue += pEnemy->CalcActionPoints();
@@ -2725,7 +2739,7 @@ INT32 CalcStraightThreatValue( SOLDIERTYPE *pEnemy )
else
{
// ADD twice the man's level (2-20)
- iThreatValue += pEnemy->stats.bExpLevel;
+ iThreatValue += EffectiveExpLevel(pEnemy); // SANDRO - find precise effective exp level
// ADD man's total action points (10-35)
iThreatValue += pEnemy->CalcActionPoints();
diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp
index a60b864d..75c257a4 100644
--- a/TacticalAI/Attacks.cpp
+++ b/TacticalAI/Attacks.cpp
@@ -21,6 +21,7 @@
#include "environment.h"
#include "lighting.h"
#include "Sound Control.h"
+#include "message.h"
#endif
extern INT16 DirIncrementer[8];
@@ -115,6 +116,36 @@ void LoadWeaponIfNeeded(SOLDIERTYPE *pSoldier)
}
}
+// FROM SB JA2005
+void ResetWeaponMode( SOLDIERTYPE * pSoldier )
+{
+ // ATE: Don't do this if in a fire amimation.....
+ if ( gAnimControl[ pSoldier->usAnimState ].uiFlags & ANIM_FIRE )
+ {
+ return;
+ }
+
+ pSoldier->bWeaponMode = WM_NORMAL;
+
+//
+ pSoldier->aiData.bShownAimTime = REFINE_AIM_1;
+
+ //!pSoldier->aiData.ubBurstAP = 0; //SB reset long burst length
+ //^^^^ , .
+// gfDisplayFullCountRing = FALSE;
+// gfDisplayFullCountRingBurst = FALSE;
+//
+// pSoldier->bDoBurst = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].mode[WM_NORMAL].usROF > 0;
+
+// DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
+// gfUIForceReExamineCursorData = TRUE;
+
+// gfShowBurstLength = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].mode[pSoldier->bWeaponMode].usROF > 0;
+// gfShowBurstLength = Weapon[Item[pSoldier->inv[HANDPOS].usItem].ubClassIndex].mode[pSoldier->bWeaponMode].ubBullets > 1;
+
+}
+//
+
void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUnseen)
{
UINT32 uiLoop;
@@ -254,9 +285,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
if ( TANK( pSoldier ) )
{
- // HEADROCK HAM 3.6: Calculation must take into account APBP constants and other aiming modifications!
- INT8 bAPsLeft = pSoldier->bActionPoints - ubMinAPcost;
- ubMaxPossibleAimTime = CalcAimingLevelsAvailableWithAP( pSoldier, pOpponent->sGridNo, bAPsLeft );
+ ubMaxPossibleAimTime = pSoldier->bActionPoints - ubMinAPcost;
// always burst
if ( ubMaxPossibleAimTime < ubBurstAPs )
@@ -291,11 +320,7 @@ void CalcBestShot(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN shootUns
//sprintf(tempstr,"Vs. %s, at AimTime %d, ubChanceToHit = %d",ExtMen[pOpponent->ubID].name,ubAimTime,ubChanceToHit);
//PopMessage(tempstr);
- // HEADROCK HAM 3.6: Actual aiming time is no longer 1AP per level... Failure to take this into account
- // may yield skewed results in favour of high-aim targets.
- INT16 sActualAimTime = CalcAPCostForAiming( pSoldier, pOpponent->sGridNo, (INT8)ubAimTime );
-
- iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + sActualAimTime);
+ iHitRate = (pSoldier->bActionPoints * ubChanceToHit) / (ubRawAPCost + ubAimTime);
//NumMessage("hitRate = ",iHitRate);
// if aiming for this amount of time produces a better hit rate
@@ -501,7 +526,7 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
if ( EXPLOSIVE_GUN( usInHand ) )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"explosive gun");
- iTossRange = Weapon[ usInHand ].usRange / CELL_X_SIZE;
+ iTossRange = GetModifiedGunRange(usInHand) / CELL_X_SIZE;
}
else
{
@@ -1068,7 +1093,8 @@ void CalcBestThrow(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestThrow)
}
// calculate the maximum possible aiming time
- ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPcost);
+ // HEADROCK HAM 4: Required for new Aiming Level Limits function
+ ubMaxPossibleAimTime = min( AllowedAimingLevels(pSoldier, sGridNo), pSoldier->bActionPoints - ubMinAPcost);
DebugMsg(TOPIC_JA2 , DBG_LEVEL_3 , String("Max Possible Aim Time = %d",ubMaxPossibleAimTime ));
// calc next attack's minimum AP cost (excludes readying & turning)
@@ -1282,7 +1308,8 @@ void CalcBestStab(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab, BOOLEAN fBladeAt
iBestHitRate = 0; // reset best hit rate to minimum
// calculate the maximum possible aiming time
- ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier),pSoldier->bActionPoints - ubMinAPCost);
+ // HEADROCK HAM 4: Required for new Aiming Level Limits function
+ ubMaxPossibleAimTime = min(AllowedAimingLevels(pSoldier, pOpponent->sGridNo),pSoldier->bActionPoints - ubMinAPCost);
//NumMessage("Max Possible Aim Time = ",ubMaxPossibleAimTime);
// consider the various aiming times
@@ -1433,8 +1460,9 @@ void CalcTentacleAttack(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestStab )
if (pSoldier->pathing.bLevel != pOpponent->pathing.bLevel)
continue; // next merc
+ UINT16 usRange = GetModifiedGunRange(CREATURE_QUEEN_TENTACLES);
// if this opponent is outside the range of our tentacles
- if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ) > Weapon[ CREATURE_QUEEN_TENTACLES].usRange )
+ if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo ) > usRange )
{
continue; // next merc
}
@@ -1609,10 +1637,16 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT16 ub
// calculate distance to target, obtain his gun's maximum range rating
iRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, pOpponent->sGridNo );
- iMaxRange = Weapon[usItem].usRange;
+ // SANDRO - added specific range calculation
+ if ( Item[ usItem ].usItemClass & IC_GUN )
+ iMaxRange = GunRange( pObj, pSoldier );
+ else
+ iMaxRange = GetModifiedGunRange(usItem);
// bullet loses speed and penetrating power, 50% loss per maximum range
- iPowerLost = ((50 * iRange) / iMaxRange);
+ // SANDRO - you know, 50% is a lot, it often leads to negative damage values in the end
+ // while there is no true effect of this in game !!! Made it 25%!
+ iPowerLost = ((25 * iRange) / iMaxRange);
// up to 50% extra impact for making particularly accurate successful shots
ubBonus = ubChanceToHit / 4; // /4 is really /2 and /2 again
@@ -1641,7 +1675,7 @@ INT32 EstimateShotDamage(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT16 ub
// check for ceramic plates; these do affect monster spit
for (attachmentList::iterator iter = pOpponent->inv[VESTPOS][0]->attachments.begin(); iter != pOpponent->inv[VESTPOS][0]->attachments.end(); ++iter) {
- if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 )
+ if (Item[iter->usItem].usItemClass == IC_ARMOUR && (*iter)[0]->data.objectStatus > 0 && iter->exists() )
{
iTorsoProt += (INT32) Armour[Item[iter->usItem].ubClassIndex].ubProtection *
(INT32) (*iter)[0]->data.objectStatus / 100;
@@ -1745,7 +1779,7 @@ INT32 EstimateThrowDamage( SOLDIERTYPE *pSoldier, UINT8 ubItemPos, SOLDIERTYPE *
else if ( Item[pSoldier->inv[ ubItemPos ].usItem].rocketlauncher || Item[pSoldier->inv[ ubItemPos ].usItem].grenadelauncher || Item[pSoldier->inv[ ubItemPos ].usItem].mortar )
{
OBJECTTYPE* pAttachment = FindLaunchableAttachment(&pSoldier->inv[ ubItemPos ],pSoldier->inv[ ubItemPos ].usItem ) ;
- if ( pAttachment )
+ if ( pAttachment->exists() )
ubExplosiveIndex = Item[pAttachment->usItem].ubClassIndex;
else
return 0;
@@ -1843,21 +1877,44 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
}
else
{
- // NB martial artists don't get a bonus for using brass knuckles!
- if (pSoldier->usAttackingWeapon && !( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS ) ) )
+ // this all was a little changed for enhanced close combat system - SANDRO
+ if ( gGameExternalOptions.fEnhancedCloseCombatSystem )
{
- iImpact = GetDamage(&pSoldier->inv[HANDPOS]);
+ iImpact = EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
+
+ if ( pSoldier->usAttackingWeapon )
+ {
+ iImpact += GetDamage(&pSoldier->inv[HANDPOS]);
+ }
+ else
+ {
+ // base HTH damage
+ iImpact += 4; // Slightly reduced for we can now attack to head for bigger damage - SANDRO
+ // Add melee damage multiplier to bare HtH attacks as well - SANDRO
+ // actually I make the influence a little lesser, because to the blades and so,
+ // only the item impact is multiplied, not the level and strength bonus, but here it does
+ iImpact += iImpact * gGameExternalOptions.iMeleeDamageModifier / 120;
+ }
}
else
{
- // base HTH damage
- iImpact = 5;
+
+ // NB martial artists don't get a bonus for using brass knuckles!
+ if (pSoldier->usAttackingWeapon && !( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) ) )
+ {
+ iImpact = GetDamage(&pSoldier->inv[HANDPOS]);
+ }
+ else
+ {
+ // base HTH damage
+ iImpact = 5;
+ }
+ iImpact += EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
}
- iImpact += EffectiveStrength( pSoldier ) / 5; // 0 to 20 for strength, adjusted by damage taken
}
- iImpact += (pSoldier->stats.bExpLevel / 2); // 0 to 4 for level
+ iImpact += (EffectiveExpLevel( pSoldier ) / 2); // 0 to 4 for level // SANDRO - added effective level calc
iFluke = 0;
iBonus = ubChanceToHit / 4; // up to 50% extra impact for accurate attacks
@@ -1867,17 +1924,81 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent,
if (!fBladeAttack)
{
// add bonuses for hand-to-hand and martial arts
- if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS ) )
+ // Check for new traits - SANDRO
+ if ( gGameOptions.fNewTraitSystem )
{
- iImpact = iImpact * (100 + gbSkillTraitBonus[MARTIALARTS] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS ) ) / 100;
+ if (!pSoldier->usAttackingWeapon || Item[pSoldier->inv[HANDPOS].usItem].brassknuckles)
+ {
+ // add bonuses for martial arts
+ if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
+ {
+ // also add breath damage bonus into consideration
+ iImpact = (INT32)((iImpact * ( 100 + (gSkillTraitValues.ubMABonusDamageHandToHand + gSkillTraitValues.ubMABonusBreathDamageHandToHand) * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100) + 0.5);
+
+
+ // The Spinning kicks or aimed punch bonus - SANDRO
+ //if (pSoldier->usAnimState == NINJA_SPINKICK || (pSoldier->aiData.bAimTime > 0))
+ //{
+ // iImpact += (iImpact * gSkillTraitValues.usMAAimedPunchDamageBonus * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100; // +75% damage per trait
+ //}
+ }
+ }
+ else
+ {
+ // +30% damage of blunt weapons for melee character
+ if (HAS_SKILL_TRAIT( pSoldier, MELEE_NT ))
+ {
+ iImpact = (INT32)((iImpact * (100 + gSkillTraitValues.ubMEDamageBonusBlunt)/100) + 0.5);
+
+ //if (pSoldier->aiData.bAimTime > 0)
+ //{
+ // iImpact += (iImpact * (100 + gSkillTraitValues.usMEAimedMeleeAttackDamageBonus) / 100); // 50% incresed damage if focused melee attack
+ //}
+ }
+ }
}
- if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND ) )
+ else
{
- iImpact = iImpact * (100 + gbSkillTraitBonus[HANDTOHAND] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND ) ) / 100;
+ if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) )
+ {
+ iImpact = (INT32)((iImpact * (100 + gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) ) / 100) + 0.5);
+ }
+ if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
+ {
+ iImpact = (INT32)((iImpact * (100 + gbSkillTraitBonus[HANDTOHAND_OT] * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) ) / 100) + 0.5);
+ }
+ }
+ // SANDRO - Enhanced Close Combat System - aiming at body parts makes difference
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem && (gAnimControl[ pOpponent->usAnimState ].ubEndHeight == ANIM_PRONE))
+ {
+ iImpact = (INT32)(iImpact * 150 / 100); // 50% incresed damage to lying characters
}
// Here, if we're doing a bare-fisted attack,
// we want to pay attention just to wounds inflicted
- iImpact = iImpact / PUNCH_REAL_DAMAGE_PORTION;
+ // SANDRO - No, we may consider the breath damage as asort of "real" damage too, so only reduce it by half
+ iImpact = iImpact / 2;
+ //iImpact = iImpact / PUNCH_REAL_DAMAGE_PORTION;
+ }
+ // SANDRO - damage bonus to melee trait
+ else
+ {
+ if ( HAS_SKILL_TRAIT( pSoldier, MELEE_NT ) && (gGameOptions.fNewTraitSystem) )
+ {
+ iImpact += (iImpact * (100 + gSkillTraitValues.ubMEDamageBonusBlades ) / 100); // +30% damage
+
+ //if (pSoldier->aiData.bAimTime > 0)
+ //{
+ // iImpact += (iImpact * ( 100 + gSkillTraitValues.usMEAimedMeleeAttackDamageBonus ) / 100); // 50% incresed damage if focused melee attack
+ //}
+ }
+ // SANDRO - Enhanced Close Combat System
+ if (gGameExternalOptions.fEnhancedCloseCombatSystem)
+ {
+ if (gAnimControl[ pOpponent->usAnimState ].ubEndHeight == ANIM_PRONE)
+ {
+ iImpact = (INT32)(iImpact * 140 / 100); // 40% incresed damage to lying characters
+ }
+ }
}
if (iImpact < 1)
@@ -1914,7 +2035,24 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier )
{
(*pObj)[0]->data.gun.ubGunState |= GS_CARTRIDGE_IN_CHAMBER;
- DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0);
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STOMP traits - SANDRO
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ // Sniper trait makes chambering a round faster
+ if (( Weapon[Item[(pObj)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE || Weapon[Item[(pObj)->usItem].ubClassIndex].ubWeaponType == GUN_RIFLE ) && HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ))
+ DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubSNChamberRoundAPsReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )))/100) + 0.5), 0);
+ // Ranger trait makes pumping shotguns faster
+ else if (( Weapon[Item[(pObj)->usItem].ubClassIndex].ubWeaponType == GUN_SHOTGUN ) && HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
+ DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubRAPumpShotgunsAPsReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT )))/100) + 0.5), 0);
+ else
+ DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0);
+ }
+ else
+ {
+ DeductPoints(pSoldier, Weapon[Item[(pObj)->usItem].ubClassIndex].APsToReloadManually, 0);
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
PlayJA2Sample( Weapon[ Item[pObj->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
@@ -1942,7 +2080,24 @@ INT8 TryToReload( SOLDIERTYPE * pSoldier )
{
(*pObj2)[0]->data.gun.ubGunState |= GS_CARTRIDGE_IN_CHAMBER;
- DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0);
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
+ // STOMP traits - SANDRO (well, I don't know any one-handed sniper rifle, but what the hell...)
+ if ( gGameOptions.fNewTraitSystem )
+ {
+ // Sniper trait makes chambering a round faster
+ if (( Weapon[Item[(pObj2)->usItem].ubClassIndex].ubWeaponType == GUN_SN_RIFLE || Weapon[Item[(pObj2)->usItem].ubClassIndex].ubWeaponType == GUN_RIFLE ) && HAS_SKILL_TRAIT( pSoldier, SNIPER_NT ))
+ DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubSNChamberRoundAPsReduction * NUM_SKILL_TRAITS( pSoldier, SNIPER_NT )))/100) + 0.5), 0);
+ // Ranger trait makes pumping shotguns faster
+ else if (( Weapon[Item[(pObj2)->usItem].ubClassIndex].ubWeaponType == GUN_SHOTGUN ) && HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
+ DeductPoints(pSoldier, (INT16)(((Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually * (100 - gSkillTraitValues.ubRAPumpShotgunsAPsReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT )))/100) + 0.5), 0);
+ else
+ DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0);
+ }
+ else
+ {
+ DeductPoints(pSoldier, Weapon[Item[(pObj2)->usItem].ubClassIndex].APsToReloadManually, 0);
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////
PlayJA2Sample( Weapon[ Item[pObj2->usItem].ubClassIndex ].ManualReloadSound, RATE_11025, SoundVolume( HIGHVOLUME, pSoldier->sGridNo ), 1, SoundDir( pSoldier->sGridNo ) );
@@ -2492,10 +2647,10 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s
// (suppressionFire && IsGunAutofireCapable(&pSoldier->inv[pBestShot->bWeaponIn] ) && GetMagSize(pObj) > 30 && (*pObj)[0]->data.gun.ubGunShotsLeft > 20 ))
BOOLEAN fEnableAISuppression = FALSE;
- if ( gGameExternalOptions.fIncreaseAISuppressionFire && ((!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) ||
+ if ( gGameExternalOptions.fIncreaseAISuppressionFire && ((!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj, pSoldier) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) || // SANDRO - added argument to GunRange()
(suppressionFire && IsGunAutofireCapable(&pSoldier->inv[pBestShot->bWeaponIn]))) )
fEnableAISuppression = TRUE;
- else if ( !gGameExternalOptions.fIncreaseAISuppressionFire && ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) ||
+ else if ( !gGameExternalOptions.fIncreaseAISuppressionFire && ( (!suppressionFire && ( (IsScoped(pObj) && GunRange(pObj, pSoldier) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) ) || // SANDRO - added argument
(suppressionFire && IsGunAutofireCapable(&pSoldier->inv[pBestShot->bWeaponIn] ) && GetMagSize(pObj) > 30 && (*pObj)[0]->data.gun.ubGunShotsLeft > 20 )))
fEnableAISuppression = TRUE;
@@ -2523,3 +2678,142 @@ void CheckIfShotPossible(SOLDIERTYPE *pSoldier, ATTACKTYPE *pBestShot, BOOLEAN s
}
}
}
+
+// SANDRO - function to determine if we should try to steal the enemy gun
+BOOLEAN AIDetermineStealingWeaponAttempt( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pOpponent )
+{
+ INT16 sChance = 0;
+ UINT32 uiSuccessChance = 0;
+
+ if( pOpponent == NULL )
+ {
+ return( FALSE );
+ }
+
+ if( pOpponent->bTeam != gbPlayerNum )
+ {
+ return( FALSE );
+ }
+
+ if( pOpponent->bCollapsed || pOpponent->bBreathCollapsed )
+ {
+ return( FALSE );
+ }
+ pSoldier->usUIMovementMode = RUNNING;
+ if( pSoldier->bActionPoints < GetAPsToStealItem( pSoldier, NULL, pOpponent->sGridNo ) )
+ {
+ return( FALSE );
+ }
+
+ if( (pOpponent->inv[HANDPOS].exists() != true) )
+ {
+ return( FALSE );
+ }
+ if ( !(Item[pOpponent->inv[HANDPOS].usItem].usItemClass & IC_WEAPON) )
+ {
+ UINT16 dfgvdfv = Item[pOpponent->inv[HANDPOS].usItem].usItemClass;
+ return( FALSE );
+ }
+
+ uiSuccessChance = CalcChanceToSteal(pSoldier, pOpponent, 0);
+ if ( uiSuccessChance >= 100 )
+ {
+ sChance = 90;
+ }
+ else if ( uiSuccessChance >= 85 )
+ {
+ sChance = 75;
+ }
+ else if ( uiSuccessChance >= 70 )
+ {
+ sChance = 60;
+ }
+ else if ( uiSuccessChance >= 50 )
+ {
+ sChance = 40;
+ }
+ else if ( uiSuccessChance >= 25 )
+ {
+ sChance = 15;
+ }
+ else
+ {
+ return( FALSE );
+ }
+
+ if( gGameOptions.fNewTraitSystem )
+ {
+ if( !HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
+ {
+ return( FALSE );
+ }
+ else if( NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) > 1 )
+ {
+ sChance += 50;
+ }
+ }
+ else
+ {
+ if( !HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) && !HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
+ {
+ return( FALSE );
+ }
+ else if(( NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) > 1 ) || ( NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) > 1 ))
+ {
+ sChance += 25;
+ }
+ }
+
+ if( pSoldier->stats.bLife < pSoldier->stats.bLifeMax )
+ {
+ sChance -= (pSoldier->stats.bLifeMax - pSoldier->stats.bLife);
+ }
+ if( pSoldier->bBreath < pSoldier->bBreathMax )
+ {
+ sChance -= ((pSoldier->bBreathMax - pSoldier->bBreath) / 2);
+ }
+
+ if( pOpponent->stats.bLife < pOpponent->stats.bLifeMax )
+ {
+ sChance += (pOpponent->stats.bLifeMax - pOpponent->stats.bLife);
+ }
+ if( pOpponent->bBreath < pOpponent->bBreathMax )
+ {
+ sChance += ((pOpponent->bBreathMax - pOpponent->bBreath) / 2);
+ }
+
+ if( pSoldier->bActionPoints > (GetAPsToStealItem( pSoldier, NULL, pOpponent->sGridNo ) + (2 * ApsToPunch( pSoldier ))) )
+ {
+ sChance += 35;
+ }
+ else if ( pSoldier->bActionPoints > (GetAPsToStealItem( pSoldier, NULL, pOpponent->sGridNo ) + ApsToPunch( pSoldier )) )
+ {
+ sChance += 20;
+ }
+ else
+ {
+ sChance -= 10;
+ }
+
+ if( Chance( sChance ) )
+ {
+ return( TRUE );
+ }
+ else
+ {
+ return( FALSE );
+ }
+}
+
+// HEADROCK HAM 4: This is required for the AI to be able to assess the length of autofire volleys using the new
+// recoil system.
+FLOAT AICalcRecoilForShot( SOLDIERTYPE *pSoldier, OBJECTTYPE *pWeapon, UINT8 ubShotNum)
+{
+ INT8 bRecoilX = 0;
+ INT8 bRecoilY = 0;
+ GetRecoil( pWeapon, &bRecoilX, &bRecoilY, ubShotNum );
+ // Return average shooter's ability to control this gun.
+ // HEADROCK HAM 4: TODO: Incorporate items that alter max counter-force.
+ FLOAT AverageRecoil = __max(0, ((FLOAT)sqrt( (FLOAT)(bRecoilX * bRecoilX) + (FLOAT)(bRecoilY * bRecoilY) ) - (gGameCTHConstants.RECOIL_MAX_COUNTER_FORCE * 0.7f) ) );
+ return AverageRecoil;
+}
\ No newline at end of file
diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp
index d4c0add4..3ec91e00 100644
--- a/TacticalAI/DecideAction.cpp
+++ b/TacticalAI/DecideAction.cpp
@@ -36,6 +36,11 @@
#include "connect.h"
#include "Text.h"
+//////////////////////////////////////////////////////////////////////////////
+// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
+// On the bottom here, there are these functions made
+//////////////////////////////////////////////////////////////////////
+
extern BOOLEAN gfHiddenInterrupt;
extern BOOLEAN gfUseAlternateQueenPosition;
@@ -845,9 +850,36 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier)
}
+//ddd{
+ if(gGameExternalOptions.bNewTacticalAIBehavior
+ && !( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT) )
+ && pSoldier->bTeam == ENEMY_TEAM)
+ {
+ INT32 cnt;
+ ROTTING_CORPSE * pCorpse;
-
+ for ( cnt = 0; cnt < giNumRottingCorpse; cnt++ )
+ {
+ pCorpse = &(gRottingCorpse[ cnt ] );
+
+ if ( pCorpse->fActivated && pCorpse->def.ubAIWarningValue > 0 )
+ if ( PythSpacesAway( pSoldier->sGridNo, pCorpse->def.sGridNo ) <= 5 )// (smaxvid ?)
+ {
+ //, .?
+ //CHRISL: Shouldn't we be using the corpse's bLevel? Otherwise a soldier inside a building can see a corpse on the roof of that building
+ //if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
+ if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pCorpse->def.sGridNo, pCorpse->def.bLevel, 3, TRUE, CALC_FROM_WANTED_DIR ) )
+ {
+ ScreenMsg( MSG_FONT_YELLOW, MSG_INTERFACE, L"Warning: enemy corpse found!!!" );
+ //pCorpse->def.ubAIWarningValue=0;
+ gRottingCorpse[ cnt ].def.ubAIWarningValue=0;
+ return( AI_ACTION_RED_ALERT );
+ }
+ }
+ }
+ }
+//ddd}
////////////////////////////////////////////////////////////////////////////
// POINT PATROL: move towards next point unless getting a bit winded
@@ -2204,7 +2236,10 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if (BestThrow.ubPossible)
{
// if firing mortar make sure we have room
- if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar )
+ //if ( Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar ) //comm by ddd
+ if (Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].mortar
+ || Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].grenadelauncher
+ || Item[pSoldier->inv[ BestThrow.bWeaponIn ].usItem].flare )
{
ubOpponentDir = GetDirectionFromGridNo( BestThrow.sTarget, pSoldier );
@@ -2311,7 +2346,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
OBJECTTYPE * gun = &pSoldier->inv[BestShot.bWeaponIn];
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("decideactionred: men in sector %d, ubspotters called by %d, nobody %d",gTacticalStatus.Team[pSoldier->bTeam].bMenInSector,gTacticalStatus.ubSpottersCalledForBy,NOBODY ));
//if ( ( ( IsScoped(gun) && GunRange(gun) > pSoldier->GetMaxDistanceVisible(BestShot.sTarget, BestShot.bTargetLevel) ) || pSoldier->aiData.bOrders == SNIPER ) &&
- if ( ( ( IsScoped(gun) && GunRange(gun) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) &&
+ if ( ( ( IsScoped(gun) && GunRange(gun, pSoldier) > MaxNormalDistanceVisible() ) || pSoldier->aiData.bOrders == SNIPER ) && // SANDRO - added argument
(gTacticalStatus.Team[pSoldier->bTeam].bMenInSector > 1) &&
(gTacticalStatus.ubSpottersCalledForBy == NOBODY))
@@ -2360,17 +2395,30 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
pSoldier->aiData.usActionData = BestShot.sTarget;
//pSoldier->aiData.bAimTime = BestShot.ubAimTime;
INT16 ubBurstAPs = 0;
+ FLOAT dTotalRecoil = 0;
pSoldier->bDoAutofire = 0;
- do
- {
- pSoldier->bDoAutofire++;
- ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
+ if(UsingNewCTHSystem() == true){
+ do
+ {
+ INT8 bRecoilX = 0;
+ INT8 bRecoilY = 0;
+ pSoldier->bDoAutofire++;
+ dTotalRecoil += AICalcRecoilForShot( pSoldier, &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
+ ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
+ }
+ while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire
+ && dTotalRecoil <= 10.0f );
+ } else {
+ do
+ {
+ pSoldier->bDoAutofire++;
+ ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
+ }
+ while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs &&
+ pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
+ GetAutoPenalty(&pSoldier->inv[ pSoldier->ubAttackingHand ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80 );
}
- while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs &&
- pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
- GetAutoPenalty(&pSoldier->inv[ pSoldier->ubAttackingHand ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80 );
-
pSoldier->bDoAutofire--;
@@ -2385,7 +2433,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
pSoldier->bDoBurst = 1;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[ MSG113_SUPPRESSIONFIRE ] );
- Menptr[BestShot.ubOpponent].ubSuppressionPoints += pSoldier->bDoAutofire;
+ // HEADROCK HAM 4: This is the stupidest thing ever.
+ // Menptr[BestShot.ubOpponent].ubSuppressionPoints += pSoldier->bDoAutofire;
Menptr[BestShot.ubOpponent].ubSuppressorID = pSoldier->ubID;
return( AI_ACTION_FIRE_GUN );
}
@@ -2463,6 +2512,11 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
////////////////////////////////////////////////////////////////////////////
if ( ubCanMove && InLightAtNight( pSoldier->sGridNo, pSoldier->pathing.bLevel ) && pSoldier->aiData.bOrders != STATIONARY )
{
+ //ddd ,
+ if(gGameExternalOptions.bNewTacticalAIBehavior)
+ pSoldier->aiData.bAction = AI_ACTION_LEAVE_WATER_GAS;
+ //ddd
+
pSoldier->aiData.usActionData = FindNearbyDarkerSpot( pSoldier );
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
@@ -2687,12 +2741,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: stop flanking");
if (PythSpacesAway ( pSoldier->sGridNo, tempGridNo ) > MIN_FLANK_DIST_RED * 2 )
{
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,APBPConstants[AP_PRONE],AI_ACTION_SEEK_OPPONENT,0);
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,tempGridNo,GetAPsProne( pSoldier, TRUE),AI_ACTION_SEEK_OPPONENT,0);
if ( LocationToLocationLineOfSightTest( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel, tempGridNo, pSoldier->pathing.bLevel, TRUE) )
{
// reserve APs for a possible crouch plus a shot
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, tempGridNo, (INT8) (MinAPsToAttack( pSoldier, tempGridNo, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
@@ -2815,7 +2869,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
//////////////////////////////////////////////////////////////////////
// try to move towards him
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,APBPConstants[AP_CROUCH],AI_ACTION_SEEK_OPPONENT,0);
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,GetAPsCrouch( pSoldier, TRUE),AI_ACTION_SEEK_OPPONENT,0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
@@ -2917,12 +2971,12 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if (TileIsOutOfBounds(pSoldier->aiData.usActionData) || pSoldier->numFlanks >= MAX_FLANKS_RED )
{
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,APBPConstants[AP_CROUCH], AI_ACTION_SEEK_OPPONENT,0);
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestDisturbance,GetAPsCrouch( pSoldier, TRUE), AI_ACTION_SEEK_OPPONENT,0);
//pSoldier->numFlanks = 0;
if ( PythSpacesAway( pSoldier->aiData.usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel, sClosestDisturbance, pSoldier->pathing.bLevel, TRUE ) )
{
// reserve APs for a possible crouch plus a shot
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
@@ -2960,7 +3014,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if ( PythSpacesAway( pSoldier->aiData.usActionData, sClosestDisturbance ) < 5 || LocationToLocationLineOfSightTest( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel, sClosestDisturbance, pSoldier->pathing.bLevel, TRUE ) )
{
// reserve APs for a possible crouch plus a shot
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier, sClosestDisturbance, (INT8) (MinAPsToAttack( pSoldier, sClosestDisturbance, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_SEEK_OPPONENT, FLAG_CAUTIOUS );
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
@@ -3058,7 +3112,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
//////////////////////////////////////////////////////////////////////
// GO DIRECTLY TOWARDS CLOSEST FRIEND UNDER FIRE OR WHO LAST RADIOED
//////////////////////////////////////////////////////////////////////
- pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestFriend,APBPConstants[AP_CROUCH], AI_ACTION_SEEK_OPPONENT,0);
+ pSoldier->aiData.usActionData = InternalGoAsFarAsPossibleTowards(pSoldier,sClosestFriend,GetAPsCrouch( pSoldier, TRUE), AI_ACTION_SEEK_OPPONENT,0);
if (!TileIsOutOfBounds(pSoldier->aiData.usActionData))
{
@@ -3148,7 +3202,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
{
// either moving significantly closer or into very close range
// ensure will we have enough APs for a possible crouch plus a shot
- if ( InternalGoAsFarAsPossibleTowards( pSoldier, pSoldier->aiData.usActionData, (INT8) (MinAPsToAttack( pSoldier, sClosestOpponent, ADDTURNCOST) + APBPConstants[AP_CROUCH]), AI_ACTION_TAKE_COVER, 0 ) == pSoldier->aiData.usActionData )
+ if ( InternalGoAsFarAsPossibleTowards( pSoldier, pSoldier->aiData.usActionData, (INT8) (MinAPsToAttack( pSoldier, sClosestOpponent, ADDTURNCOST) + GetAPsCrouch( pSoldier, TRUE)), AI_ACTION_TAKE_COVER, 0 ) == pSoldier->aiData.usActionData )
{
return(AI_ACTION_TAKE_COVER);
}
@@ -3425,7 +3479,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK)
if ( pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD )
{
// reduce bleeding by 1 point per AP (in RT, APs will get recalculated so it's okay)
- pSoldier->bBleeding = __max( 0, pSoldier->bBleeding - pSoldier->bActionPoints );
+ pSoldier->bBleeding = __max( 0, pSoldier->bBleeding - (pSoldier->bActionPoints/2) );
return( AI_ACTION_NONE ); // will end-turn/wait depending on whether we're in TB or realtime
}
#ifdef RECORDNET
@@ -3936,7 +3990,9 @@ INT16 ubMinAPCost;
{
// look around for a worthy target (which sets BestShot.ubPossible)
BOOLEAN shootUnseen = FALSE;
- if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM )
+ ///ddd
+ //if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM ) //comm by ddd
+ if (gGameOptions.ubDifficultyLevel > DIF_LEVEL_MEDIUM || gGameExternalOptions.bNewTacticalAIBehavior)
shootUnseen = TRUE;
CalcBestShot(pSoldier,&BestShot,shootUnseen);
@@ -4125,6 +4181,107 @@ INT16 ubMinAPCost;
RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY);
}
}
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - even if we don't have any blade, calculate how much damage we could do unarmed
+ else if ( !TANK( pSoldier) )
+ {
+ bWeaponIn = FindAIUsableObjClass( pSoldier, IC_PUNCH );
+ if (bWeaponIn == NO_SLOT) // if no punch-type weapon found, just calculate it with empty hands
+ {
+ bWeaponIn = FindEmptySlotWithin( pSoldier, HANDPOS, NUM_INV_SLOTS );
+ }
+ if (bWeaponIn != NO_SLOT)
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"try to punch");
+ BestStab.bWeaponIn = bWeaponIn;
+ // if it's in his holster, swap it into his hand temporarily
+ if (bWeaponIn != HANDPOS)
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionblack: about to rearrange pocket before punch check");
+ RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY);
+ }
+
+ // get the minimum cost to attack with punch
+ ubMinAPCost = MinAPsToAttack(pSoldier,pSoldier->sLastTarget,DONTADDTURNCOST);
+ // if we can afford the minimum AP cost to punch
+ if (pSoldier->bActionPoints >= ubMinAPCost)
+ {
+ // then look around for a worthy target (which sets BestStab.ubPossible)
+ CalcBestStab(pSoldier,&BestStab, FALSE);
+
+ if (BestStab.ubPossible)
+ {
+ // if we have not enough APs to deal at least two or three punches,
+ // reduce the attack value as one punch ain't much
+ if( gGameOptions.fNewTraitSystem )
+ {
+ // if we are not specialized, reduce the attack attractiveness generaly
+ if ( !HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
+ {
+ BestStab.iAttackValue /= 4;
+ // if too far and not having APs for at least 3 hits no way to attack
+ if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + (2 * (ApsToPunch( pSoldier )))) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1) )
+ {
+ BestStab.ubPossible = 0;
+ BestStab.iAttackValue = 0;
+ }
+ }
+ else
+ {
+ if (PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1)
+ {
+ BestStab.iAttackValue = (BestStab.iAttackValue * 2);
+ }
+ // if too far and not having APs for at least 2 hits
+ else if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + ApsToPunch( pSoldier )) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1))
+ {
+ BestStab.iAttackValue /= 3;
+ }
+ }
+ }
+ else
+ {
+ if ( !HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) && !HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
+ {
+ // if we are not specialized, reduce the attack attractiveness generaly
+ BestStab.iAttackValue /= 4;
+ // if too far and not having APs for at least 3 hits
+ if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + (2 * (ApsToPunch( pSoldier )))) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget <= 1)) )
+ {
+ BestStab.ubPossible = 0;
+ BestStab.iAttackValue = 0;
+ }
+ }
+ else
+ {
+ BestStab.iAttackValue = ((BestStab.iAttackValue * 3)/2);
+
+ if (PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget) <= 1)
+ {
+ BestStab.iAttackValue = ((BestStab.iAttackValue * 3)/2);
+ }
+ // if too far and not having APs for at least 2 hits
+ else if (((CalcTotalAPsToAttack( pSoldier,BestStab.sTarget,ADDTURNCOST, 0 ) + ApsToPunch( pSoldier )) > pSoldier->bActionPoints) && !(PythSpacesAway(pSoldier->sGridNo, BestStab.sTarget <= 1)) )
+ {
+ BestStab.iAttackValue /= 3;
+ }
+ }
+ }
+ // now we KNOW FOR SURE that we will do something (stab, at least)
+ NPCDoesAct(pSoldier);
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"NPC decided to punch");
+ }
+
+ }
+ // if it was in his holster, swap it back into his holster for now
+ if (bWeaponIn != HANDPOS)
+ {
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"about to rearrange pocket after punch check");
+ RearrangePocket(pSoldier,HANDPOS,bWeaponIn,TEMPORARILY);
+ }
+ }
+ }
+ /////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// CHOOSE THE BEST TYPE OF ATTACK OUT OF THOSE FOUND TO BE POSSIBLE
@@ -4148,11 +4305,27 @@ INT16 ubMinAPCost;
ubBestAttackAction = AI_ACTION_THROW_KNIFE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = throw knife");
}
- else
+ else if ( Item[ pSoldier->inv[BestStab.bWeaponIn].usItem ].usItemClass & IC_BLADE ) // SANDRO - check specifically for blade attack
{
ubBestAttackAction = AI_ACTION_KNIFE_MOVE;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to stab");
}
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - added a chance to try to steal merc's gun from hands
+ else
+ {
+ if (AIDetermineStealingWeaponAttempt( pSoldier, MercPtrs[BestStab.ubOpponent] ) == TRUE)
+ {
+ ubBestAttackAction = AI_ACTION_STEAL_MOVE;
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to steal weapon");
+ }
+ else
+ {
+ ubBestAttackAction = AI_ACTION_KNIFE_MOVE;
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"best action = move to punch");
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////
}
if (BestThrow.ubPossible && ((BestThrow.iAttackValue > BestAttack.iAttackValue) || (ubBestAttackAction == AI_ACTION_NONE)))
{
@@ -4223,6 +4396,10 @@ INT16 ubMinAPCost;
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = stab with a knife");
memcpy(&BestAttack,&BestStab,sizeof(BestAttack));
break;
+ case AI_ACTION_STEAL_MOVE: // added by SANDRO
+ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: best attack = try to steal weapon");
+ memcpy(&BestAttack,&BestStab,sizeof(BestAttack));
+ break;
default:
// set to empty
@@ -4233,12 +4410,14 @@ INT16 ubMinAPCost;
}
// NB a desire of 4 or more is only achievable by brave/aggressive guys with high morale
+ UINT16 usRange = GetModifiedGunRange(pSoldier->inv[ BestAttack.bWeaponIn ].usItem);
+
if ( (pSoldier->bActionPoints == pSoldier->bInitialActionPoints) &&
(ubBestAttackAction == AI_ACTION_FIRE_GUN) &&
(pSoldier->aiData.bShock == 0) &&
(pSoldier->stats.bLife >= pSoldier->stats.bLifeMax / 2) &&
(BestAttack.ubChanceToReallyHit < 30) &&
- (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) > Weapon[ pSoldier->inv[ BestAttack.bWeaponIn ].usItem ].usRange / CELL_X_SIZE ) &&
+ (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) > usRange / CELL_X_SIZE ) &&
(RangeChangeDesire( pSoldier ) >= 4) )
{
// okay, really got to wonder about this... could taking cover be an option?
@@ -4383,7 +4562,7 @@ INT16 ubMinAPCost;
if (ubBestAttackAction == AI_ACTION_FIRE_GUN)
{
// Do we need to change stance? NB We'll have to ready our gun again
- if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + APBPConstants[AP_CROUCH] + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1 ) ) )
+ if ( !TANK( pSoldier ) && ( pSoldier->bActionPoints >= BestAttack.ubAPCost + GetAPsCrouch( pSoldier, TRUE) + MinAPsToAttack( pSoldier, BestAttack.sTarget, ADDTURNCOST, 1 ) ) )
{
// since the AI considers shooting chance from standing primarily, if we are not
// standing we should always consider a stance change
@@ -4484,13 +4663,13 @@ INT16 ubMinAPCost;
iChance = (25 / max((BestAttack.ubAimTime + 1),1));
switch (pSoldier->aiData.bAttitude)
{
- case DEFENSIVE: iChance += -5; break;
- case BRAVESOLO: iChance += 5; break;
- case BRAVEAID: iChance += 5; break;
- case CUNNINGSOLO: iChance += 0; break;
- case CUNNINGAID: iChance += 0; break;
- case AGGRESSIVE: iChance += 10; break;
- case ATTACKSLAYONLY:iChance += 30; break;
+ case DEFENSIVE: iChance += -5; break;
+ case BRAVESOLO: iChance += 5; break;
+ case BRAVEAID: iChance += 5; break;
+ case CUNNINGSOLO: iChance += 0; break;
+ case CUNNINGAID: iChance += 0; break;
+ case AGGRESSIVE: iChance += 10; break;
+ case ATTACKSLAYONLY:iChance += 30; break;
}
// HEADROCK HAM B2.6: Allows control over increased enemy burstfire.
@@ -4510,10 +4689,10 @@ INT16 ubMinAPCost;
iChance += 5 * ( 15 - PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) );
}
}
+
// HEADROCK HAM 3.6: due to the "else", this part of the formula is NEVER hit. Removing.
//else if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY )
if (PythSpacesAway( pSoldier->sGridNo, BestAttack.sTarget ) < 10 && gGameOptions.ubDifficultyLevel > DIF_LEVEL_EASY )
-
{
iChance += 100;
}
@@ -4535,20 +4714,33 @@ INT16 ubMinAPCost;
if (IsGunAutofireCapable( &pSoldier->inv[BestAttack.bWeaponIn] ) &&
!(Menptr[BestShot.ubOpponent].stats.bLife < OKLIFE) && // don't burst at downed targets
(( pSoldier->inv[BestAttack.bWeaponIn][0]->data.gun.ubGunShotsLeft > 1 &&
- BestAttack.ubAimTime != BURSTING ) || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) )
+ !pSoldier->bDoBurst ) || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto) )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"DecideActionBlack: ENOUGH APs TO AUTOFIRE, RANDOM CHANCE OF DOING SO");
+
+ FLOAT dTotalRecoil = 0.0f;
pSoldier->bDoAutofire = 0;
- do
- {
- pSoldier->bDoAutofire++;
- ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire );
+ if(UsingNewCTHSystem() == true){
+ do
+ {
+ INT8 bRecoilX = 0;
+ INT8 bRecoilY = 0;
+ pSoldier->bDoAutofire++;
+ dTotalRecoil += AICalcRecoilForShot( pSoldier, &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
+ ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestShot.bWeaponIn]), pSoldier->bDoAutofire );
+ }
+ while( pSoldier->bActionPoints >= BestShot.ubAPCost + ubBurstAPs + sActualAimTime && pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire
+ && dTotalRecoil <= 10.0f );
+ } else {
+ do
+ {
+ pSoldier->bDoAutofire++;
+ ubBurstAPs = CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire );
+ }
+ while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs &&
+ pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
+ GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80);
}
- while( pSoldier->bActionPoints >= BestAttack.ubAPCost + ubBurstAPs &&
- pSoldier->inv[ pSoldier->ubAttackingHand ][0]->data.gun.ubGunShotsLeft >= pSoldier->bDoAutofire &&
- GetAutoPenalty(&pSoldier->inv[ BestAttack.bWeaponIn ], gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE)*pSoldier->bDoAutofire <= 80);
-
-
pSoldier->bDoAutofire--;
if (pSoldier->bDoAutofire > 0)
@@ -4606,20 +4798,24 @@ INT16 ubMinAPCost;
if ((INT32) PreRandom( 100 ) < iChance || Weapon[pSoldier->inv[BestAttack.bWeaponIn].usItem].NoSemiAuto)
{
- BestAttack.ubAimTime = AUTOFIRING + pSoldier->bDoAutofire;
- BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire );
+ pSoldier->aiData.bAimTime = BestAttack.ubAimTime ;
+ pSoldier->bDoBurst = 1;
+ BestAttack.ubAPCost = BestAttack.ubAPCost + CalcAPsToAutofire( pSoldier->CalcActionPoints(), &(pSoldier->inv[BestAttack.bWeaponIn]), pSoldier->bDoAutofire ) + sActualAimTime;
+ }
+ else
+ {
+ pSoldier->bDoAutofire = 0;
+ pSoldier->bDoBurst = 0;
}
}
}
- else
- {
- // HEADROCK HAM 3.6: No no no! This line removes all aiming from a potentially deadly single-shot! Commenting out.
- //pSoldier->aiData.bAimTime = 0;
- pSoldier->aiData.bAimTime = BestAttack.ubAimTime;
- pSoldier->bDoBurst = 0;
- pSoldier->bDoAutofire = 0;
- // not enough aps - do somthing else
- }
+ }
+
+ if (!pSoldier->bDoBurst)
+ {
+ pSoldier->aiData.bAimTime = BestAttack.ubAimTime;
+ pSoldier->bDoBurst = 0;
+ pSoldier->bDoAutofire = 0;
}
//////////////////////////////////////////////////////////////////////////
@@ -4629,6 +4825,10 @@ INT16 ubMinAPCost;
+ // HEADROCK HAM 4: No longer necessary to do here. The conditions above already handle this, specifically
+ // WITHOUT messing with the BestAttack.ubAimTime variable, since that can apply now even when bursting
+ // or autofiring!!
+ /*
if (BestAttack.ubAimTime == BURSTING)
{
pSoldier->aiData.bAimTime = 0;
@@ -4642,7 +4842,7 @@ INT16 ubMinAPCost;
pSoldier->bDoAutofire = BestAttack.ubAimTime-AUTOFIRING;
BestAttack.ubAimTime = AUTOFIRING;
- }
+ }*/
/*
else // defaults already set
@@ -4669,6 +4869,32 @@ INT16 ubMinAPCost;
}
}
+ // SANDRO - chance to make aimed punch/stab for martial arts/melee
+ else if (ubBestAttackAction == AI_ACTION_KNIFE_MOVE && gGameOptions.fNewTraitSystem)
+ {
+ pSoldier->aiData.bAimTime = 0;
+
+ if (Item[pSoldier->inv[BestAttack.bWeaponIn].usItem].usItemClass == IC_PUNCH)
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT))
+ {
+ if( PreRandom( (gGameExternalOptions.fEnhancedCloseCombatSystem ? 2 : 0) + 2 * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT) ) > 2 )
+ {
+ pSoldier->aiData.bAimTime = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6);
+ }
+ }
+ }
+ else
+ {
+ if (HAS_SKILL_TRAIT( pSoldier, MELEE_NT))
+ {
+ if( PreRandom( gGameExternalOptions.fEnhancedCloseCombatSystem ? 3 : 1 ) > 0 )
+ {
+ pSoldier->aiData.bAimTime = (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : 6);
+ }
+ }
+ }
+ }
//////////////////////////////////////////////////////////////////////////
// OTHERWISE, JUST GO AHEAD & ATTACK!
@@ -4889,59 +5115,63 @@ INT16 ubMinAPCost;
// if not in water and not already crouched, try to crouch down first
if (!gfTurnBasedAI || GetAPsToChangeStance( pSoldier, ANIM_CROUCH ) <= pSoldier->bActionPoints)
{
- if ( !fCivilian && !gfHiddenInterrupt && IsValidStance( pSoldier, ANIM_CROUCH ) )
+ if ( !fCivilian && !gfHiddenInterrupt && IsValidStance( pSoldier, ANIM_CROUCH ) && ubBestAttackAction != AI_ACTION_KNIFE_MOVE && ubBestAttackAction != AI_ACTION_KNIFE_STAB && ubBestAttackAction != AI_ACTION_STEAL_MOVE) // SANDRO - if knife attack don't crouch
{
- pSoldier->aiData.usActionData = StanceChange( pSoldier, BestAttack.ubAPCost );
- if (pSoldier->aiData.usActionData != 0)
+ // determine the location of the known closest opponent
+ // (don't care if he's conscious, don't care if he's reachable at all)
+
+ sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL);
+ // SANDRO - don't crouch if in close combat distance (we got penalties that way)
+ if (PythSpacesAway(pSoldier->sGridNo, sClosestOpponent) > 1 )
{
- if (pSoldier->aiData.usActionData == ANIM_PRONE)
+ pSoldier->aiData.usActionData = StanceChange( pSoldier, BestAttack.ubAPCost );
+ if (pSoldier->aiData.usActionData != 0)
{
- // we might want to turn before lying down!
- if ( (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints - GetAPsToChangeStance( pSoldier, (INT8) pSoldier->aiData.usActionData )) &&
- (((pSoldier->aiData.bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) )
+ if (pSoldier->aiData.usActionData == ANIM_PRONE)
{
- // determine the location of the known closest opponent
- // (don't care if he's conscious, don't care if he's reachable at all)
-
- sClosestOpponent = ClosestSeenOpponent(pSoldier, NULL, NULL);
- // if we have a closest seen opponent
- if (!TileIsOutOfBounds(sClosestOpponent))
+ // we might want to turn before lying down!
+ if ( (!gfTurnBasedAI || GetAPsToLook( pSoldier ) <= pSoldier->bActionPoints - GetAPsToChangeStance( pSoldier, (INT8) pSoldier->aiData.usActionData )) &&
+ (((pSoldier->aiData.bAIMorale > MORALE_HOPELESS) || ubCanMove) && !AimingGun(pSoldier)) )
{
- bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
-
- // if we're not facing towards him
- if (pSoldier->ubDirection != bDirection)
+ // if we have a closest seen opponent
+ if (!TileIsOutOfBounds(sClosestOpponent))
{
- if ( pSoldier->InternalIsValidStance( bDirection, (INT8) pSoldier->aiData.usActionData) )
+ bDirection = atan8(CenterX(pSoldier->sGridNo),CenterY(pSoldier->sGridNo),CenterX(sClosestOpponent),CenterY(sClosestOpponent));
+
+ // if we're not facing towards him
+ if (pSoldier->ubDirection != bDirection)
{
- // change direction, THEN change stance!
- pSoldier->aiData.bNextAction = AI_ACTION_CHANGE_STANCE;
- pSoldier->aiData.usNextActionData = pSoldier->aiData.usActionData;
- pSoldier->aiData.usActionData = bDirection;
+ if ( pSoldier->InternalIsValidStance( bDirection, (INT8) pSoldier->aiData.usActionData) )
+ {
+ // change direction, THEN change stance!
+ pSoldier->aiData.bNextAction = AI_ACTION_CHANGE_STANCE;
+ pSoldier->aiData.usNextActionData = pSoldier->aiData.usActionData;
+ pSoldier->aiData.usActionData = bDirection;
#ifdef DEBUGDECISIONS
- sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->aiData.usActionData);
- AIPopMessage(tempstr);
+ sprintf(tempstr,"%s - TURNS to face CLOSEST OPPONENT in direction %d",pSoldier->name,pSoldier->aiData.usActionData);
+ AIPopMessage(tempstr);
#endif
- return(AI_ACTION_CHANGE_FACING);
- }
- else if ( (pSoldier->aiData.usActionData == ANIM_PRONE) && (pSoldier->InternalIsValidStance( bDirection, ANIM_CROUCH) ) )
- {
- // we shouldn't go prone, since we can't turn to shoot
- pSoldier->aiData.usActionData = ANIM_CROUCH;
- pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
- return( AI_ACTION_CHANGE_STANCE );
+ return(AI_ACTION_CHANGE_FACING);
+ }
+ else if ( (pSoldier->aiData.usActionData == ANIM_PRONE) && (pSoldier->InternalIsValidStance( bDirection, ANIM_CROUCH) ) )
+ {
+ // we shouldn't go prone, since we can't turn to shoot
+ pSoldier->aiData.usActionData = ANIM_CROUCH;
+ pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
+ return( AI_ACTION_CHANGE_STANCE );
+ }
}
+ // else we are facing in the right direction
+
}
- // else we are facing in the right direction
-
+ // else we don't know any enemies
}
- // else we don't know any enemies
- }
- // we don't want to turn
+ // we don't want to turn
+ }
+ pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
+ return( AI_ACTION_CHANGE_STANCE );
}
- pSoldier->aiData.bNextAction = AI_ACTION_END_TURN;
- return( AI_ACTION_CHANGE_STANCE );
}
}
}
diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp
index 02a4d30f..aac2f01e 100644
--- a/TacticalAI/FindLocations.cpp
+++ b/TacticalAI/FindLocations.cpp
@@ -33,6 +33,12 @@
#include "PathAIDebug.h"
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SANDRO - all "APBPConstants[AP_CROUCH]" and "APBPConstants[AP_PRONE]" here
+// were changed to GetAPsCrouch() and GetAPsProne()
+// - also all "APBPConstants[AP_PICKUP_ITEM]" were replaced by GetBasicAPsToPickupItem()
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+
INT16 * gsCoverValue = NULL;
#ifdef _DEBUG
@@ -128,13 +134,13 @@ INT8 CalcWorstCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sOpp
switch (bCubeLevel)
{
case 1:
- if (iMyAPsLeft < APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE])
+ if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE) + GetAPsProne(pSoldier,TRUE))
{
continue;
}
break;
case 2:
- if (iMyAPsLeft < APBPConstants[AP_CROUCH])
+ if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE))
{
continue;
}
@@ -168,13 +174,13 @@ INT8 CalcAverageCTGTForPosition( SOLDIERTYPE * pSoldier, UINT8 ubOppID, INT32 sO
switch (bCubeLevel)
{
case 1:
- if (iMyAPsLeft < APBPConstants[AP_CROUCH] + APBPConstants[AP_PRONE])
+ if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE) + GetAPsProne(pSoldier,TRUE))
{
continue;
}
break;
case 2:
- if (iMyAPsLeft < APBPConstants[AP_CROUCH])
+ if (iMyAPsLeft < GetAPsCrouch(pSoldier,TRUE))
{
continue;
}
@@ -430,7 +436,7 @@ INT32 CalcCoverValue(SOLDIERTYPE *pMe, INT32 sMyGridNo, INT32 iMyThreat, INT32 i
{
// if I CAN'T crouch when I get there, that makes it significantly less
// appealing a spot (how much depends on range), so that's a penalty to me
- if (iMyAPsLeft < APBPConstants[AP_CROUCH])
+ if (iMyAPsLeft < GetAPsCrouch(pMe,TRUE))
// subtract another 1 % penalty for NOT being able to crouch per tile
// the farther away we are, the bigger a difference crouching will make!
iMyPosValue -= ((iMyPosValue * (AIM_PENALTY_TARGET_CROUCHED + (iRange / CELL_X_SIZE))) / 100);
@@ -1662,7 +1668,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
return AI_ACTION_NONE;
}
- if (pSoldier->bActionPoints < APBPConstants[AP_PICKUP_ITEM])
+ if (pSoldier->bActionPoints < GetBasicAPsToPickupItem( pSoldier ))
{
return( AI_ACTION_NONE );
}
@@ -1719,7 +1725,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
// set an AP limit too, to our APs less the cost of picking up an item
// and less the cost of dropping an item since we might need to do that
- gubNPCAPBudget = pSoldier->bActionPoints - APBPConstants[AP_PICKUP_ITEM];
+ gubNPCAPBudget = pSoldier->bActionPoints - GetBasicAPsToPickupItem( pSoldier );
// reset the "reachable" flags in the region we're looking at
for (sYOffset = -sMaxUp; sYOffset <= sMaxDown; sYOffset++)
@@ -1922,7 +1928,12 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
// WANNE: Fix a vanilla bug: When an enemy soldier is looking for items and finds a non-helmet/vest/leggings piece of armour it was incorrectly considered for pickup.
// Fixed by Tron (Stracciatella): Revision: 5719
// break;
- continue;
+ // continue; <- silversurfer: bad idea, this causes the game to hang
+ // to make sure that the item isn't considered set iTempValue to zero and get out
+ {
+ iTempValue = 0;
+ break;
+ }
}
}
else
@@ -1959,7 +1970,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
//if (pSoldier->inv[HANDPOS].exists() == true && PlaceInAnyPocket(pSoldier, &pSoldier->inv[HANDPOS], false) == false)
if (FindBetterSpotForItem( pSoldier, HANDPOS ) == FALSE)
{
- if (pSoldier->bActionPoints < APBPConstants[AP_PICKUP_ITEM] + APBPConstants[AP_PICKUP_ITEM])
+ if (pSoldier->bActionPoints < GetBasicAPsToPickupItem( pSoldier ) + GetBasicAPsToPickupItem( pSoldier ))
{
return( AI_ACTION_NONE );
}
@@ -1968,7 +1979,7 @@ INT8 SearchForItems( SOLDIERTYPE * pSoldier, INT8 bReason, UINT16 usItem )
// destroy this item!
DebugAI( String( "%d decides he must drop %S first so destroys it", pSoldier->ubID, ItemNames[ pSoldier->inv[HANDPOS].usItem ] ) );
DeleteObj( &(pSoldier->inv[HANDPOS]) );
- DeductPoints( pSoldier, APBPConstants[AP_PICKUP_ITEM], 0 );
+ DeductPoints( pSoldier, GetBasicAPsToPickupItem( pSoldier ), 0 );
}
else
{
diff --git a/TacticalAI/Medical.cpp b/TacticalAI/Medical.cpp
index 6ad26b7c..2e4eeb3e 100644
--- a/TacticalAI/Medical.cpp
+++ b/TacticalAI/Medical.cpp
@@ -15,6 +15,9 @@
#include "Buildings.h"
#include "worldman.h"
#include "Assignments.h"
+ // added by SANDRO
+ #include "Soldier Profile.h"
+ #include "GameSettings.h"
#endif
//forward declarations of common classes to eliminate includes
@@ -465,3 +468,47 @@ INT8 DecideAutoBandage( SOLDIERTYPE * pSoldier )
// do nothing
return( AI_ACTION_NONE );
}
+
+// SANDRO - added a function
+BOOLEAN DoctorIsPresent( SOLDIERTYPE * pPatient, BOOLEAN fOnDoctorAssignmentCheck )
+{
+ SOLDIERTYPE * pMedic = NULL;
+ UINT8 cnt;
+ INT8 bSlot;
+ BOOLEAN fDoctorHasBeenFound = FALSE;
+
+ cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
+ for ( pMedic = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pMedic++)
+ {
+ if ( !(pMedic->bActive) || !(pMedic->bInSector) || ( pMedic->flags.uiStatusFlags & SOLDIER_VEHICLE ) || (pMedic->bAssignment == VEHICLE ) )
+ {
+ // is nowhere around!
+ continue; // NEXT!!!
+ }
+
+ if ( pPatient->ubID == pMedic->ubID )
+ {
+ // cannot make surgery on self!
+ continue; // NEXT!!!
+ }
+ if ( fOnDoctorAssignmentCheck && pMedic->bAssignment != DOCTOR )
+ {
+ // not on the right assignment!
+ continue; // NEXT!!!
+ }
+
+ bSlot = FindMedKit( pMedic );
+ if (bSlot == NO_SLOT)
+ {
+ // no medical kit!
+ continue; // NEXT!!!
+ }
+
+ if (pMedic->stats.bLife > OKLIFE && !(pMedic->bCollapsed) && pMedic->stats.bMedical > 0 && (NUM_SKILL_TRAITS( pMedic, DOCTOR_NT ) >= gSkillTraitValues.ubDONumberTraitsNeededForSurgery))
+ {
+ fDoctorHasBeenFound = TRUE;
+ }
+ }
+
+ return( fDoctorHasBeenFound );
+}
diff --git a/TacticalAI/Movement.cpp b/TacticalAI/Movement.cpp
index 7e60dbf4..6483c671 100644
--- a/TacticalAI/Movement.cpp
+++ b/TacticalAI/Movement.cpp
@@ -7,7 +7,7 @@
#include "overhead.h"
#include "worldman.h"
#include "pathai.h"
- #include "points.h"
+ //#include "points.h"
#include "message.h"
#include "Smell.h"
#include "mapscreen.h"
@@ -720,7 +720,7 @@ INT32 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT32 sDesGrid, IN
if (pSoldier->usUIMovementMode == RUNNING)
{
- sAPCost += APBPConstants[AP_START_RUN_COST];
+ sAPCost += GetAPsStartRun( pSoldier ); // changed by SANDRO
}
}
diff --git a/TacticalAI/NPC.cpp b/TacticalAI/NPC.cpp
index 16b3337d..3fb618e1 100644
--- a/TacticalAI/NPC.cpp
+++ b/TacticalAI/NPC.cpp
@@ -47,15 +47,21 @@
#include "Scheduling.h"
#include "Tactical Save.h"
#include "Campaign Types.h"
+ #include "GameSettings.h" // added by SANDRO
+ #include "Soldier Profile.h"
#endif
-
+ #include "Soldier Profile.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
// WANNE - BMP: DONE!
//SB: new .npc format
-#define NPCEX_SIGNATURE 0x00070000
+#define _MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((UINT32)(UINT8)(ch0) | ((UINT32)(UINT8)(ch1) << 8) | \
+ ((UINT32)(UINT8)(ch2) << 16) | ((UINT32)(UINT8)(ch3) << 24 ))
+
+#define NPCEX_SIGNATURE _MAKEFOURCC('B','1','1','3')
#define NUM_CIVQUOTE_SECTORS 20
#define MINERS_CIV_QUOTE_INDEX 16
@@ -143,7 +149,9 @@ NPCQuoteInfo * LoadQuoteFile( UINT8 ubNPC )
// use a copy of Herve's data file instead!
sprintf( zFileName, "NPCData\\%03d.npc", HERVE );
}
- else if ( ubNPC < FIRST_RPC || ubNPC >= GASTON || (ubNPC < FIRST_NPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
+ //else if ( ubNPC < FIRST_RPC || ubNPC >= GASTON || (ubNPC < FIRST_NPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
+ //new profiles by Jazz
+ else if ( gProfilesIMP[ubNPC].ProfilId == ubNPC || gProfilesAIM[ubNPC].ProfilId == ubNPC || gProfilesMERC[ubNPC].ProfilId == ubNPC || ( gProfilesRPC[ubNPC].ProfilId == ubNPC && gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED ) )
{
sprintf( zFileName, "NPCData\\000.npc", ubNPC );
}
@@ -257,7 +265,7 @@ NPCQuoteInfo& NPCQuoteInfo::operator=(const _old_NPCQuoteInfo& src)
ubLastDay = src.ubLastDay;
ubApproachRequired = src.ubApproachRequired;
ubOpinionRequired = src.ubOpinionRequired;
- ubUnused = 0;
+ usUnused = 0;
ubQuoteNum = src.ubQuoteNum;
ubNumQuotes = src.ubNumQuotes;
ubStartQuest = src.ubStartQuest;
@@ -305,7 +313,9 @@ BOOLEAN EnsureQuoteFileLoaded( UINT8 ubNPC )
fLoadFile = TRUE;
}
- if ( ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC )
+// if ( ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC )
+ //new profiles by Jazz
+ if ( ( gProfilesRPC[ubNPC].ProfilId == ubNPC ) )
{
if (gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED)
{
@@ -415,20 +425,31 @@ BOOLEAN RefreshNPCScriptRecord( UINT8 ubNPC, UINT8 ubRecord )
{
// we have some work to do...
// loop through all PCs, and refresh their copy of this record
- for ( ubLoop = 0; ubLoop < FIRST_RPC; ubLoop++ ) // need more finesse here
+ //for ( ubLoop = 0; ubLoop < FIRST_RPC; ubLoop++ ) // need more finesse here
+ //new profiles by Jazz
+ for ( ubLoop = 0; ubLoop < NUM_PROFILES; ubLoop++ ) // need more finesse here
{
+ //new profiles by Jazz
+ if ( gProfilesIMP[ubLoop].ProfilId == ubLoop || gProfilesAIM[ubLoop].ProfilId == ubLoop || gProfilesMERC[ubLoop].ProfilId == ubLoop )
RefreshNPCScriptRecord( ubLoop, ubRecord );
}
- for ( ubLoop = GASTON; ubLoop < NUM_PROFILES; ubLoop++ ) // need more finesse here
- {
- RefreshNPCScriptRecord( ubLoop, ubRecord );
- }
- for ( ubLoop = FIRST_RPC; ubLoop < FIRST_NPC; ubLoop++ )
+
+ //for ( ubLoop = GASTON; ubLoop < NUM_PROFILES; ubLoop++ ) // need more finesse here
+ //{
+ // RefreshNPCScriptRecord( ubLoop, ubRecord );
+ //}
+
+ //new profiles by Jazz
+ //for ( ubLoop = FIRST_RPC; ubLoop < FIRST_NPC; ubLoop++ )
+ for ( ubLoop = 0; ubLoop < NUM_PROFILES; ubLoop++ )
{
+ if ( gProfilesRPC[ubLoop].ProfilId == ubLoop )
+ {
if ( gMercProfiles[ ubNPC ].ubMiscFlags & PROFILE_MISC_FLAG_RECRUITED && gpBackupNPCQuoteInfoArray[ ubNPC ] != NULL )
{
RefreshNPCScriptRecord( ubLoop, ubRecord );
}
+ }
}
return( TRUE );
}
@@ -462,21 +483,87 @@ NPCQuoteInfo * LoadCivQuoteFile( UINT8 ubIndex )
NPCQuoteInfo * pFileData;
UINT32 uiBytesRead;
UINT32 uiFileSize;
+ DWORD uiSignature = 0; // SB // WANNE - BMP: DONE!
- if ( ubIndex == MINERS_CIV_QUOTE_INDEX )
- {
- sprintf( zFileName, "NPCData\\miners.npc" );
- }
- else
- {
- sprintf( zFileName, "NPCData\\%c%d.npc", 'A' + ( gsCivQuoteSector[ ubIndex ][ 1 ] - 1 ), gsCivQuoteSector[ ubIndex ][ 0 ] );
- }
+ if ( ubIndex == MINERS_CIV_QUOTE_INDEX )
+ {
+ sprintf( zFileName, "NPCData\\miners.npc" );
+ }
+ else
+ {
+ sprintf( zFileName, "NPCData\\%c%d.npc", 'A' + ( gsCivQuoteSector[ ubIndex ][ 1 ] - 1 ), gsCivQuoteSector[ ubIndex ][ 0 ] );
+ }
CHECKN( FileExists( zFileName ) );
hFile = FileOpen( zFileName, FILE_ACCESS_READ, FALSE );
CHECKN( hFile );
+ // -----------------------------------------------------------
+ // WANNE: This fixes the bug, that NPCs do not give hints
+ // Problem was, the missing conversion from old to new NPC structure!
+ if (!FileRead( hFile, &uiSignature, sizeof(uiSignature), &uiBytesRead ) || uiBytesRead != sizeof(uiSignature) )
+ return NULL;
+
+ if(uiSignature == NPCEX_SIGNATURE)//new fmt
+ {
+ uiFileSize = sizeof( NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS;
+ pFileData = (NPCQuoteInfo *)MemAlloc( uiFileSize );
+ if (pFileData)
+ {
+ if (!FileRead( hFile, pFileData, uiFileSize, &uiBytesRead ) || uiBytesRead != uiFileSize )
+ {
+ MemFree( pFileData );
+ pFileData = NULL;
+ }
+ }
+
+ FileClose( hFile );
+ }
+ else //old fmt - make conversion
+ {
+ int iRecord;
+ _old_NPCQuoteInfo * pFileData_old_;
+ uiFileSize = sizeof( _old_NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS;
+ pFileData_old_ = ( _old_NPCQuoteInfo * )MemAlloc( uiFileSize );
+ FileSeek(hFile, 0, FILE_SEEK_FROM_START);
+ if (pFileData_old_)
+ {
+ if (!FileRead( hFile, pFileData_old_, uiFileSize, &uiBytesRead ) || uiBytesRead != uiFileSize )
+ {
+ MemFree( pFileData_old_ );
+ pFileData_old_ = NULL;
+ }
+ }
+
+ FileClose( hFile );
+ //check for Russian script & make a runtime conversion of it to International
+ if( *(DWORD*)pFileData_old_ == 0x00350039 )
+ {
+ //just offset records 4 bytes backward
+ _old_NPCQuoteInfo * pEnglishScript = ( _old_NPCQuoteInfo * )MemAlloc( uiFileSize );
+ memcpy( pEnglishScript, ((char*)pFileData_old_)+4, uiFileSize-4 );
+ MemFree( pFileData_old_ );
+ pFileData_old_ = pEnglishScript;
+ }
+
+ // Now it's time for conversion
+ uiFileSize = sizeof(NPCQuoteInfo) * NUM_NPC_QUOTE_RECORDS;
+ pFileData = (NPCQuoteInfo*)MemAlloc(uiFileSize);
+ for(iRecord=0; iRecord new script format
+ return( pFileData );
+
+ // -----------------------------------------------------------
+ // WANNE: This is old vanilla JA2 code without conversion of NPC data to new format used for Big Maps project
+ /*
uiFileSize = sizeof( NPCQuoteInfo ) * NUM_NPC_QUOTE_RECORDS;
pFileData = (NPCQuoteInfo *)MemAlloc( uiFileSize );
if (pFileData)
@@ -491,6 +578,8 @@ NPCQuoteInfo * LoadCivQuoteFile( UINT8 ubIndex )
FileClose( hFile );
return( pFileData );
+ // -----------------------------------------------------------
+ */
}
@@ -578,8 +667,12 @@ BOOLEAN ReloadAllQuoteFiles( void )
{
UINT8 ubProfile, ubLoop;
- 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 )
+ {
// zap backup if any
if ( gpBackupNPCQuoteInfoArray[ ubProfile ] != NULL )
{
@@ -587,6 +680,7 @@ BOOLEAN ReloadAllQuoteFiles( void )
gpBackupNPCQuoteInfoArray[ ubProfile ] = NULL;
}
ReloadQuoteFileIfLoaded( ubProfile );
+ }
}
// reload all civ quote files
for ( ubLoop = 0; ubLoop < NUM_CIVQUOTE_SECTORS; ubLoop++ )
@@ -642,6 +736,12 @@ INT32 CalcThreateningEffectiveness( UINT8 ubMerc )
iDeadliness = -30;
}
+ // SANDRO - bonus for threatening for assertive people
+ if ( gGameOptions.fNewTraitSystem && gMercProfiles[pSoldier->ubProfile].bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
+ {
+ iDeadliness += 50;
+ }
+
return( (EffectiveLeadership( pSoldier ) + iStrength + iDeadliness) / 3 ); //Trail minor bug fix.
}
@@ -661,6 +761,15 @@ UINT8 CalcDesireToTalk( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach )
iPersonalVal += pNPCProfile->bMercOpinion[ubMerc];
}
+ // SANDRO - bonus for communication with people for assertive people
+ if ( gGameOptions.fNewTraitSystem && bApproach != APPROACH_THREATEN)
+ {
+ if ( pMercProfile->bCharacterTrait == CHAR_TRAIT_ASSERTIVE )
+ iPersonalVal += 50;
+ else if ( pMercProfile->bCharacterTrait == CHAR_TRAIT_MALICIOUS )
+ iPersonalVal -= 50;
+ }
+
// ARM: NOTE - for towns which don't use loyalty (San Mona, Estoni, Tixa, Orta )
// loyalty will always remain 0 (this was OKed by Ian)
iTownVal = gTownLoyalty[ pNPCProfile->bTown ].ubRating;
@@ -1215,7 +1324,9 @@ UINT8 NPCConsiderReceivingItemFromMerc( UINT8 ubNPC, UINT8 ubMerc, OBJECTTYPE *
}
break;
default:
- if ( usItemToConsider == MONEY && (ubNPC == SKYRIDER || (ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC) ) )
+ //if ( usItemToConsider == MONEY && (ubNPC == SKYRIDER || (ubNPC >= FIRST_RPC && ubNPC < FIRST_NPC) ) )
+ //new profiles by Jazz
+ if ( usItemToConsider == MONEY && (ubNPC == SKYRIDER || ( gProfilesRPC[ubNPC].ProfilId == ubNPC ) ) )
{
if ( gMercProfiles[ ubNPC ].iBalance < 0 && pNPCQuoteInfo->sActionData != NPC_ACTION_DONT_ACCEPT_ITEM )
{
@@ -1603,14 +1714,23 @@ void ResetOncePerConvoRecordsForNPC( UINT8 ubNPC )
void ResetOncePerConvoRecordsForAllNPCsInLoadedSector( void )
{
UINT8 ubLoop;
-
+ UINT8 IDnpc;
+
if ( gWorldSectorX == 0 || gWorldSectorY == 0 )
{
return;
}
- for ( ubLoop = FIRST_RPC; ubLoop < GASTON; ubLoop++ )
+ //for ( ubLoop = FIRST_RPC; ubLoop < GASTON; ubLoop++ )
+ //new profiles by Jazz
+ for ( IDnpc = 0; IDnpc < NUM_PROFILES; IDnpc++ )
{
+
+ if ( gProfilesRPC[IDnpc].ProfilId == IDnpc || gProfilesNPC[IDnpc].ProfilId == IDnpc)
+ {
+ ubLoop = IDnpc;
+
+
if ( gMercProfiles[ ubLoop ].sSectorX == gWorldSectorX &&
gMercProfiles[ ubLoop ].sSectorY == gWorldSectorY &&
gMercProfiles[ ubLoop ].bSectorZ == gbWorldSectorZ &&
@@ -1618,6 +1738,9 @@ void ResetOncePerConvoRecordsForAllNPCsInLoadedSector( void )
{
ResetOncePerConvoRecordsForNPC( ubLoop );
}
+
+ }
+
}
}
@@ -1695,7 +1818,15 @@ void Converse( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach, UINT32 uiApproachData
}
return;
}
+
pNPCQuoteInfoArray = gpNPCQuoteInfoArray[ubNPC];
+
+ //Legion jazz
+ if (zHiddenNames[ubNPC].Hidden == TRUE)
+ {
+ zHiddenNames[ubNPC].Hidden = FALSE;
+ }
+
pProfile = &(gMercProfiles[ubNPC]);
switch( bApproach )
@@ -1849,7 +1980,7 @@ void Converse( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach, UINT32 uiApproachData
break;
case TRIGGER_NPC:
// if triggering, pass in the approach data as the record to consider
- DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "Handling trigger %S/%d at %ld", gMercProfiles[ ubNPC ].zNickname, (UINT8)uiApproachData, GetJA2Clock() ) );
+ DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "Handling trigger %S/%d at %lu", gMercProfiles[ ubNPC ].zNickname, (UINT8)uiApproachData, GetJA2Clock() ) );
NPCConsiderTalking( ubNPC, ubMerc, bApproach, (UINT8)uiApproachData, pNPCQuoteInfoArray, &pQuotePtr, &ubRecordNum );
break;
default:
@@ -2242,6 +2373,11 @@ void Converse( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach, UINT32 uiApproachData
case APPROACH_DECLARATION_OF_HOSTILITY:
case APPROACH_INITIAL_QUOTE:
case APPROACH_GIVINGITEM:
+ // SANDRO - new records - NPCs discovered
+ if ( pProfile->ubLastDateSpokenTo == 0 && FindSoldierByProfileID( ubMerc, TRUE ) != NULL )
+ {
+ gMercProfiles[ubMerc].records.usNPCsDiscovered++;
+ }
pProfile->ubLastDateSpokenTo = (UINT8) GetWorldDay();
break;
default:
diff --git a/TacticalAI/NPC.h b/TacticalAI/NPC.h
index 9735c6bd..1bc365fc 100644
--- a/TacticalAI/NPC.h
+++ b/TacticalAI/NPC.h
@@ -90,8 +90,6 @@ public:
// conditions
INT16 sRequiredItem; // item NPC must have to say quote
- INT32 sRequiredGridNo; // location for NPC req'd to say quote
-
UINT16 usFactMustBeTrue; // ...before saying quote
UINT16 usFactMustBeFalse; // ...before saying quote
UINT8 ubQuest; // quest must be current to say quote
@@ -99,7 +97,6 @@ public:
UINT8 ubLastDay; // last day quote can be said
UINT8 ubApproachRequired; // must use this approach to generate quote
UINT8 ubOpinionRequired; // opinion needed for this quote
- UINT8 ubUnused;
// quote to say (if any)
UINT8 ubQuoteNum; // this is the quote to say
@@ -110,10 +107,17 @@ public:
UINT8 ubEndQuest;
UINT8 ubTriggerNPC;
UINT8 ubTriggerNPCRec;
+ UINT8 ubFiller;
UINT16 usSetFactTrue;
UINT16 usGiftItem; // item NPC gives to merc after saying quote
+ UINT16 usUnused;
INT16 sActionData; // special action value
+
+ INT32 sRequiredGridNo; // location for NPC req'd to say quote
INT32 usGoToGridNo;
+ UINT16 usSourceDialogueLevel; // reserved for future use
+ UINT16 usDestDialogueLevel; // reserved for future use
+
public:
NPCQuoteInfo& operator=(const _old_NPCQuoteInfo& src);
};
diff --git a/TacticalAI/TacticalAI_VS2005.vcproj b/TacticalAI/TacticalAI_VS2005.vcproj
new file mode 100644
index 00000000..c76ab393
--- /dev/null
+++ b/TacticalAI/TacticalAI_VS2005.vcproj
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TacticalAI/TacticalAI_VS2008.vcproj b/TacticalAI/TacticalAI_VS2008.vcproj
index 3be2d51d..916cf2ec 100644
--- a/TacticalAI/TacticalAI_VS2008.vcproj
+++ b/TacticalAI/TacticalAI_VS2008.vcproj
@@ -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"
>
@@ -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"
>
diff --git a/TacticalAI/TacticalAI_VS2010.vcxproj b/TacticalAI/TacticalAI_VS2010.vcxproj
new file mode 100644
index 00000000..157d03bd
--- /dev/null
+++ b/TacticalAI/TacticalAI_VS2010.vcxproj
@@ -0,0 +1,233 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {B369A125-E62E-46AE-9285-58003D688301}
+ Win32Proj
+ TacticalAI
+ TacticalAI
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+
+
+ MultiThreaded
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TacticalAI/TacticalAI_VS2010.vcxproj.filters b/TacticalAI/TacticalAI_VS2010.vcxproj.filters
new file mode 100644
index 00000000..d2be0d58
--- /dev/null
+++ b/TacticalAI/TacticalAI_VS2010.vcxproj.filters
@@ -0,0 +1,75 @@
+
+
+
+
+ {2552d0a1-b3ed-43af-a06c-d0737ce6a63f}
+
+
+ {0f98d0d9-dbab-4dc2-8aa6-ee517a6ceab6}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/TacticalAI/ai.h b/TacticalAI/ai.h
index 773e77e9..f82d04b4 100644
--- a/TacticalAI/ai.h
+++ b/TacticalAI/ai.h
@@ -97,6 +97,7 @@ typedef enum
AI_ACTION_TRAVERSE_DOWN, // move down a level
AI_ACTION_OFFER_SURRENDER, // offer surrender to the player
AI_ACTION_RAISE_GUN,
+ AI_ACTION_STEAL_MOVE, // added by SANDRO
} ActionType;
diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp
index e825fb04..82066367 100644
--- a/TileEngine/Explosion Control.cpp
+++ b/TileEngine/Explosion Control.cpp
@@ -67,6 +67,8 @@
#include "fov.h"
#include "Map Information.h"
#include "Soldier Functions.h"//dnl ch40 200909
+#include "Text.h" // added by SANDRO
+#include "campaign.h" // yet another one added
#endif
#include "Soldier Macros.h"
@@ -1477,6 +1479,294 @@ BOOLEAN DamageSoldierFromBlast( UINT8 ubPerson, UINT8 ubOwner, INT32 sBombGridNo
{
sNewWoundAmt = 0;
}
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - STOMP traits
+ else
+ {
+ if ( (MercPtrs[ ubOwner ] != NULL) && gGameOptions.fNewTraitSystem)
+ {
+ // Demolitions damage bonus with bombs and mines
+ if ( HAS_SKILL_TRAIT( MercPtrs[ ubOwner ], DEMOLITIONS_NT ) &&
+ Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL && Item[usItem].usItemClass == IC_BOMB &&
+ (!Item[usItem].attachment || Item[usItem].mine ))
+ {
+ sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubDEDamageOfBombsAndMines)) / 100) + 0.5);
+ }
+ // Heavy Weapons trait bonus damage to tanks
+ if ( HAS_SKILL_TRAIT( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ) && TANK( pSoldier ) &&
+ Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL )
+ {
+ sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubHWDamageTanksBonusPercent * NUM_SKILL_TRAITS( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ))) / 100) + 0.5); // +30%
+ }
+ // Heavy Weapons trait bonus damage with rocket, grenade launchers and mortar
+ else if ( HAS_SKILL_TRAIT( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ) &&
+ Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL &&
+ ((Item[usItem].usItemClass == IC_BOMB && Item[usItem].attachment && !Item[usItem].mine ) || // mortar shells
+ (Item[usItem].usItemClass == IC_GRENADE && (Item[usItem].glgrenade || Item[usItem].electronic) ) || // rockets for rocketlaunchers (I haven't found any other way)
+ (Item[usItem].usItemClass == IC_LAUNCHER ) || Item[usItem].rocketlauncher || Item[usItem].singleshotrocketlauncher ) )
+ {
+ sNewWoundAmt = (INT16)(((sNewWoundAmt * (100 + gSkillTraitValues.ubHWDamageBonusPercentForHW * NUM_SKILL_TRAITS( MercPtrs[ ubOwner ], HEAVY_WEAPONS_NT ))) / 100) + 0.5); // +15%
+ }
+ }
+ // adjust damage resistance of TANKS
+ if ( TANK( pSoldier ) && gGameOptions.fNewTraitSystem )
+ {
+ sNewWoundAmt = (INT16)(sNewWoundAmt * (100 - gSkillTraitValues.bTanksDamageResistanceModifier) / 100);
+ // another half of this for ordinary grenades
+ if ( (( Item[usItem].usItemClass == IC_GRENADE ) || Item[usItem].glgrenade ) && !Item[usItem].electronic )
+ sNewWoundAmt = (INT16)(sNewWoundAmt * (100 - (gSkillTraitValues.bTanksDamageResistanceModifier / 2)) / 100);
+ }
+
+ // Bodybuilding damage resistance
+ if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, BODYBUILDING_NT ) )
+ sNewWoundAmt = max( 1, (INT16)(sNewWoundAmt * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
+
+ // Damage resistance for Militia
+ if (pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
+ sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
+ sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
+ sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
+ // bonus for enemy too
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
+ sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
+ sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
+ else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
+ sNewWoundAmt -= ((sNewWoundAmt * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
+
+ // we can loose stats due to being hit by the blast
+ else if ( gGameOptions.fNewTraitSystem && Explosive[Item[usItem].ubClassIndex].ubType == EXPLOSV_NORMAL &&
+ !AM_A_ROBOT( pSoldier ) && !(pSoldier->flags.uiStatusFlags & SOLDIER_MONSTER) &&
+ sNewWoundAmt > 2 && sNewWoundAmt < pSoldier->stats.bLife )
+ {
+ if ( PreRandom( sNewWoundAmt ) > gSkillTraitValues.ubDamageNeededToLoseStats )
+ {
+ UINT8 ubStatLoss = PreRandom( sNewWoundAmt ) + 1;
+ UINT8 ubPickStat = PreRandom( 20 );
+ if (ubPickStat < 3 ) // 15% chance to lose Wisdom
+ {
+ if (ubStatLoss >= pSoldier->stats.bWisdom)
+ {
+ ubStatLoss = pSoldier->stats.bWisdom - 1;
+ }
+ if ( ubStatLoss > 0 )
+ {
+ pSoldier->stats.bWisdom -= ubStatLoss;
+ pSoldier->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] += ubStatLoss;
+
+ if (pSoldier->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pSoldier->ubProfile ].bWisdom = pSoldier->stats.bWisdom;
+ }
+
+ if (pSoldier->name[0] && pSoldier->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
+
+ if (ubStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_WISDOM], pSoldier->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_WISDOM], pSoldier->name, ubStatLoss );
+ }
+ }
+ }
+ }
+ else if (ubPickStat < 7 ) // 20% chance to lose Dexterity
+ {
+ if (ubStatLoss >= pSoldier->stats.bDexterity)
+ {
+ ubStatLoss = pSoldier->stats.bDexterity - 1;
+ }
+ if ( ubStatLoss > 0 )
+ {
+ pSoldier->stats.bDexterity -= ubStatLoss;
+ pSoldier->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] += ubStatLoss;
+
+ if (pSoldier->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pSoldier->ubProfile ].bDexterity = pSoldier->stats.bDexterity;
+ }
+
+ if (pSoldier->name[0] && pSoldier->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
+
+ if (ubStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_DEX], pSoldier->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_DEX], pSoldier->name, ubStatLoss );
+ }
+ }
+ }
+ }
+ else if (ubPickStat < 11 ) // 20% chance to lose Strength
+ {
+ if (ubStatLoss >= pSoldier->stats.bStrength)
+ {
+ ubStatLoss = pSoldier->stats.bStrength - 1;
+ }
+ if ( ubStatLoss > 0 )
+ {
+ pSoldier->stats.bStrength -= ubStatLoss;
+ // added this for healing lost stats feature
+ pSoldier->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] += ubStatLoss;
+
+ if (pSoldier->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pSoldier->ubProfile ].bStrength = pSoldier->stats.bStrength;
+ }
+
+ if (pSoldier->name[0] && pSoldier->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
+
+ if (ubStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_STRENGTH], pSoldier->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_STRENGTH], pSoldier->name, ubStatLoss );
+ }
+ }
+ }
+ }
+ else if (ubPickStat < 15 ) // 20% chance to lose Agility
+ {
+ if (ubStatLoss >= pSoldier->stats.bAgility)
+ {
+ ubStatLoss = pSoldier->stats.bAgility - 1;
+ }
+ if ( ubStatLoss > 0 )
+ {
+ pSoldier->stats.bAgility -= ubStatLoss;
+ // added this for healing lost stats feature
+ pSoldier->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] += ubStatLoss;
+
+ if (pSoldier->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pSoldier->ubProfile ].bAgility = pSoldier->stats.bAgility;
+ }
+
+ if (pSoldier->name[0] && pSoldier->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
+
+ if (ubStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_1_AGIL], pSoldier->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_LOSES_AGIL], pSoldier->name, ubStatLoss );
+ }
+ }
+ }
+ }
+ else if (ubPickStat < 18 ) // 15% chance to lose Health
+ {
+ if (ubStatLoss >= (pSoldier->stats.bLifeMax - OKLIFE))
+ {
+ ubStatLoss = pSoldier->stats.bLifeMax - OKLIFE - 1;
+ }
+ if ( ubStatLoss > sNewWoundAmt)
+ {
+ ubStatLoss = (UINT8)sNewWoundAmt;
+ }
+ if ( ubStatLoss > 0 )
+ {
+ pSoldier->stats.bLifeMax -= ubStatLoss;
+ pSoldier->ubCriticalStatDamage[DAMAGED_STAT_HEALTH] += ubStatLoss;
+
+ if (pSoldier->ubProfile != NO_PROFILE)
+ {
+ gMercProfiles[ pSoldier->ubProfile ].bLifeMax = pSoldier->stats.bLifeMax;
+ }
+
+ if (pSoldier->name[0] && pSoldier->bVisible == TRUE)
+ {
+ // make stat RED for a while...
+ pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
+ pSoldier->usValueGoneUp &= ~( HEALTH_INCREASE );
+
+ if (ubStatLoss == 1)
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_LOSES_ONE_POINT_MAX_HEALTH], pSoldier->name );
+ }
+ else
+ {
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_LOSES_X_POINTS_MAX_HEALTH], pSoldier->name, ubStatLoss );
+ }
+ }
+ }
+ }
+ else // 10% chance to be blinded
+ {
+ if (pSoldier->bBlindedCounter < ubStatLoss )
+ {
+ pSoldier->bBlindedCounter = ubStatLoss ;
+ ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s was blinded by the blast!", pSoldier->name );
+ }
+ }
+ // SANDRO - new merc records - times stat damaged
+ if ( ubStatLoss > 0 && pSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
+ }
+ }
+
+ sNewWoundAmt = max(1, sNewWoundAmt);
+ }
+ //////////////////////////////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////////////////////////////
+ // SANDRO - option to make special NPCs stronger - damage resistance
+ if (gGameExternalOptions.usSpecialNPCStronger > 0)
+ {
+ switch( pSoldier->ubProfile )
+ {
+ case CARMEN:
+ case QUEEN:
+ case JOE:
+ case ANNIE:
+ case CHRIS:
+ case KINGPIN:
+ case TIFFANY:
+ case T_REX:
+ case DRUGGIST:
+ case GENERAL:
+ case JACK:
+ case OLAF:
+ case RAY:
+ case OLGA:
+ case TYRONE:
+ case MIKE:
+ sNewWoundAmt -= (sNewWoundAmt * gGameExternalOptions.usSpecialNPCStronger / 200);
+ sNewWoundAmt = max( 1, sNewWoundAmt);
+ break;
+ }
+ }
+
+ // SANDRO - new merc records - times wounded (blasted by explosion)
+ if ( ( sNewWoundAmt > 1 || sBreathAmt > 1000 ) && pSoldier->ubProfile != NO_PROFILE )
+ gMercProfiles[ pSoldier->ubProfile ].records.usTimesWoundedBlasted++;
+ ////////////////////////////////////////////////////////////////////////////////////
+
// Lesh: flashbang does affect on soldier or not - check it
if ( (Item[usItem].usItemClass & IC_EXPLOSV) && fFlashbang )
@@ -3359,12 +3649,18 @@ void DecayBombTimers( void )
if ( (*pObj)[0]->data.misc.ubBombOwner > 1 )
{
gubPersonToSetOffExplosions = (UINT8) ((*pObj)[0]->data.misc.ubBombOwner - 2);
+ // SANDRO - merc records - detonating explosives
+ if ( MercPtrs[ gubPersonToSetOffExplosions ]->ubProfile != NO_PROFILE && MercPtrs[ gubPersonToSetOffExplosions ]->bTeam == gbPlayerNum )
+ {
+ gMercProfiles[ MercPtrs[ gubPersonToSetOffExplosions ]->ubProfile ].records.usExpDetonated++;
+ }
}
else
{
gubPersonToSetOffExplosions = NOBODY;
}
+
// put this bomb on the queue
AddBombToQueue( uiWorldBombIndex, uiTimeStamp );
@@ -3397,6 +3693,17 @@ void SetOffBombsByFrequency( UINT8 ubID, INT8 bFrequency )
// Found a remote bomb, so check to see if it has the same frequency
if ((*pObj)[0]->data.misc.bFrequency == bFrequency)
{
+ // SANDRO - added merc records and some exp
+ if ( ((*pObj)[0]->data.misc.ubBombOwner) > 1 )
+ {
+ if ( MercPtrs[((*pObj)[0]->data.misc.ubBombOwner - 2)]->ubProfile != NO_PROFILE &&
+ MercPtrs[((*pObj)[0]->data.misc.ubBombOwner - 2)]->bTeam == gbPlayerNum )
+ {
+ gMercProfiles[MercPtrs[((*pObj)[0]->data.misc.ubBombOwner - 2)]->ubProfile].records.usExpDetonated++;
+
+ StatChange( MercPtrs[((*pObj)[0]->data.misc.ubBombOwner - 2)], EXPLODEAMT, ( 5 ), FALSE );
+ }
+ }
gubPersonToSetOffExplosions = ubID;
@@ -3497,6 +3804,14 @@ BOOLEAN SetOffBombsInGridNo( UINT8 ubID, INT32 sGridNo, BOOLEAN fAllBombs, INT8
{
gubPersonToSetOffExplosions = ubID;
+ // SANDRO - merc records
+ // only if we blew up somebody not in our team(no achievement for blowing our guys :)), only if owner exists and have profile
+ if ( (MercPtrs[ubID]->bTeam != gbPlayerNum) && ((*pObj)[0]->data.misc.ubBombOwner > 1) )
+ {
+ if ( MercPtrs[ ((*pObj)[0]->data.misc.ubBombOwner - 2) ]->ubProfile != NO_PROFILE && MercPtrs[ ((*pObj)[0]->data.misc.ubBombOwner - 2) ]->bTeam == gbPlayerNum )
+ gMercProfiles[ MercPtrs[ ((*pObj)[0]->data.misc.ubBombOwner - 2) ]->ubProfile ].records.usExpDetonated++;
+ }
+
// put this bomb on the queue
AddBombToQueue( uiWorldBombIndex, uiTimeStamp );
if (pObj->usItem != ACTION_ITEM || (*pObj)[0]->data.misc.bActionValue == ACTION_ITEM_BLOW_UP)
diff --git a/TileEngine/Explosion Control.h b/TileEngine/Explosion Control.h
index 5af67d2d..79b205b1 100644
--- a/TileEngine/Explosion Control.h
+++ b/TileEngine/Explosion Control.h
@@ -133,4 +133,12 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN
void SpreadEffect( INT32 sGridNo, UINT8 ubRadius, UINT16 usItem, UINT8 ubOwner, BOOLEAN fSubsequent, INT8 bLevel, INT32 iSmokeEffectNum , BOOL fFromRemoteClient = FALSE , BOOL fNewSmokeEffect = FALSE );
void AddBombToQueue( UINT32 uiWorldBombIndex, UINT32 uiTimeStamp, BOOL fFromRemoteClient = FALSE );
+extern void ToggleActionItemsByFrequency( INT8 bFrequency );
+extern void PerformItemAction( INT32 sGridNo, OBJECTTYPE * pObj );
+extern BOOLEAN gfExplosionQueueMayHaveChangedSight;
+extern void TogglePressureActionItemsInGridNo( INT32 sGridNo );
+
+extern BOOLEAN DoesSAMExistHere( INT16 sSectorX, INT16 sSectorY, INT16 sSectorZ, INT32 sGridNo );
+
+extern BOOLEAN HookerInRoom( UINT8 ubRoom );
#endif
\ No newline at end of file
diff --git a/TileEngine/Interactive Tiles.cpp b/TileEngine/Interactive Tiles.cpp
index f11c2708..20f0c9fb 100644
--- a/TileEngine/Interactive Tiles.cpp
+++ b/TileEngine/Interactive Tiles.cpp
@@ -144,7 +144,7 @@ BOOLEAN StartInteractiveObject( INT32 sGridNo, UINT16 usStructureID, SOLDIERTYPE
}
-BOOLEAN CalcInteractiveObjectAPs( INT32 sGridNo, STRUCTURE * pStructure, INT16 *psAPCost, INT16 *psBPCost )
+BOOLEAN CalcInteractiveObjectAPs( SOLDIERTYPE * pSoldier, INT32 sGridNo, STRUCTURE * pStructure, INT16 *psAPCost, INT16 *psBPCost ) // SANDRO - added argument
{
if (pStructure == NULL)
{
@@ -156,7 +156,8 @@ BOOLEAN CalcInteractiveObjectAPs( INT32 sGridNo, STRUCTURE * pStructure, INT16 *
// If closed, we do not know what to do yet...
//if ( pStructure->fFlags & STRUCTURE_OPEN )
//{
- *psAPCost = APBPConstants[AP_OPEN_DOOR];
+ // SANDRO - changed this
+ *psAPCost = GetAPsToOpenDoor( pSoldier );
*psBPCost = APBPConstants[AP_OPEN_DOOR];
//}
//else
@@ -167,7 +168,8 @@ BOOLEAN CalcInteractiveObjectAPs( INT32 sGridNo, STRUCTURE * pStructure, INT16 *
}
else
{
- *psAPCost = APBPConstants[AP_OPEN_DOOR];
+ // SANDRO - changed this
+ *psAPCost = GetAPsToOpenDoor( pSoldier );
*psBPCost = APBPConstants[AP_OPEN_DOOR];
}
diff --git a/TileEngine/Interactive Tiles.h b/TileEngine/Interactive Tiles.h
index ebbad98d..51426ff2 100644
--- a/TileEngine/Interactive Tiles.h
+++ b/TileEngine/Interactive Tiles.h
@@ -25,7 +25,7 @@ UINT32 GetInteractiveTileCursor( UINT32 uiOldCursor, BOOLEAN fConfirm );
BOOLEAN InteractWithInteractiveObject( SOLDIERTYPE *pSoldier, STRUCTURE *pStructure, UINT8 ubDirection );
BOOLEAN SoldierHandleInteractiveObject( SOLDIERTYPE *pSoldier );
-BOOLEAN CalcInteractiveObjectAPs( INT32 sGridNo, STRUCTURE * pStructure, INT16 *psAPCost, INT16 *psBPCost );
+BOOLEAN CalcInteractiveObjectAPs( SOLDIERTYPE * pSoldier, INT32 sGridNo, STRUCTURE * pStructure, INT16 *psAPCost, INT16 *psBPCost ); // SANDRO - added argument
void HandleStructChangeFromGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo );
diff --git a/TileEngine/Isometric Utils.cpp b/TileEngine/Isometric Utils.cpp
index 1a5bb5c7..be4ec71c 100644
--- a/TileEngine/Isometric Utils.cpp
+++ b/TileEngine/Isometric Utils.cpp
@@ -185,6 +185,344 @@ UINT8 gPurpendicularDirection[ NUM_WORLD_DIRECTIONS ][ NUM_WORLD_DIRECTIONS ] =
};
+//----------------------legion by Jazz-----------------
+
+BOOLEAN FindWindowJumpDirection( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStartingDir, INT8 *pbDirection )
+{
+ INT32 cnt;
+ INT32 sNewGridNo, sOtherSideOfFence;
+ BOOLEAN fFound = FALSE;
+ UINT8 bMinNumTurns = 100;
+ INT8 bNumTurns;
+ INT8 bMinDirection = 0;
+ INT8 direction2 = -1;
+
+ if ( pSoldier->ubDirection == NORTH )
+ direction2 = NORTH;
+ else if ( pSoldier->ubDirection == EAST )
+ direction2 = EAST;
+ else if ( pSoldier->ubDirection == SOUTH )
+ direction2 = SOUTH;
+ else if ( pSoldier->ubDirection == WEST )
+ direction2 = WEST;
+
+ // WANNE: No need to check on SOUTH and EAST tile, because it is the tile that has the fence we are standing on!
+ if (direction2 == NORTH || direction2 == WEST)
+ {
+ // IF there is a fence in this gridno, return false!
+ if ( IsJumpableWindowPresentAtGridNo( sGridNo, direction2 ) )
+ {
+ return( FALSE );
+ }
+ }
+
+ // LOOP THROUGH ALL 8 DIRECTIONS
+ for ( cnt = 0; cnt < 8; cnt+= 2 )
+ {
+ if (cnt != direction2)
+ continue;
+
+ // get the fence tile
+ if (cnt == NORTH || cnt == WEST)
+ {
+ sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+ sOtherSideOfFence = sNewGridNo;
+ }
+ // current tile we are standing is the fence tile
+ else
+ {
+ sNewGridNo = sGridNo;
+ sOtherSideOfFence = NewGridNo( sNewGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+ }
+
+ //if ( NewOKDestination( pSoldier, sOtherSideOfFence, TRUE, 0 ) && validDestTile)
+ if ( NewOKDestination( pSoldier, sOtherSideOfFence, TRUE, 0 ) /*&& validDestTile*/)
+ {
+ // ATE: Check if there is somebody waiting here.....
+
+ // Check if we have a fence here
+ if ( IsJumpableWindowPresentAtGridNo( sNewGridNo , direction2) )
+ {
+ fFound = TRUE;
+
+ // FInd how many turns we should go to get here
+ bNumTurns = FindNumTurnsBetweenDirs( (INT8)cnt, bStartingDir );
+
+ if ( bNumTurns < bMinNumTurns )
+ {
+ bMinNumTurns = bNumTurns;
+ bMinDirection = (INT8)cnt;
+ }
+
+ break;
+ }
+ }
+ }
+
+ if ( fFound )
+ {
+ *pbDirection = bMinDirection;
+ return( TRUE );
+ }
+
+ return( FALSE );
+}
+
+BOOLEAN FindFenceDirection( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStartingDir, INT8 *pbDirection )
+{
+ INT32 cnt;
+ INT32 sNewGridNo, sOtherSideOfFence;
+ BOOLEAN fFound = FALSE;
+ UINT8 bMinNumTurns = 100;
+ INT8 bNumTurns;
+ INT8 bMinDirection = 0;
+
+ // IF there is a fence in this gridno, return false!
+ if ( IsLegionFencePresentAtGridno( sGridNo ) )
+ {
+ return( FALSE );
+ }
+
+ // LOOP THROUGH ALL 8 DIRECTIONS
+ for ( cnt = 0; cnt < 8; cnt+= 2 )
+ {
+ // go out *2* tiles
+ sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+ sOtherSideOfFence = NewGridNo( sNewGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+
+ if ( NewOKDestination( pSoldier, sOtherSideOfFence, TRUE, 0 ) )
+ {
+ // ATE: Check if there is somebody waiting here.....
+
+
+ // Check if we have a fence here
+ if ( IsLegionFencePresentAtGridno( sNewGridNo ) )
+ {
+ fFound = TRUE;
+
+ // FInd how many turns we should go to get here
+ bNumTurns = FindNumTurnsBetweenDirs( (INT8)cnt, bStartingDir );
+
+ if ( bNumTurns < bMinNumTurns )
+ {
+ bMinNumTurns = bNumTurns;
+ bMinDirection = (INT8)cnt;
+ }
+ }
+ }
+
+ }
+
+ if ( fFound )
+ {
+ *pbDirection = bMinDirection;
+ return( TRUE );
+ }
+
+ return( FALSE );
+}
+
+BOOLEAN FindHeigherLevelOkno( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStartingDir, INT8 *pbDirection )
+{
+
+ INT32 cnt;
+ INT32 sNewGridNo;
+ BOOLEAN fFound = FALSE;
+ UINT8 bMinNumTurns = 100;
+ INT8 bNumTurns;
+ INT8 bMinDirection = 0;
+
+ // LOOP THROUGH ALL 8 DIRECTIONS
+ for ( cnt = 0; cnt < 8; cnt+= 2 )
+ {
+ sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+
+ // Make sure there is NOT a roof here...
+ // Check OK destination
+ if ( NewOKDestination( pSoldier, sNewGridNo, TRUE, 0 ) )
+ {
+ if ( FindStructure( sNewGridNo, STRUCTURE_WALLNWINDOW ) == NULL )
+ {
+ {
+ fFound = TRUE;
+
+ // FInd how many turns we should go to get here
+ bNumTurns = FindNumTurnsBetweenDirs( (INT8)cnt, bStartingDir );
+
+ if ( bNumTurns < bMinNumTurns )
+ {
+ bMinNumTurns = bNumTurns;
+ bMinDirection = (INT8)cnt;
+ }
+
+ }
+ }
+ }
+ }
+
+ if ( fFound )
+ {
+ *pbDirection = bMinDirection;
+ return( TRUE );
+ }
+
+ return( FALSE );
+
+/* INT32 cnt;
+ INT32 sNewGridNo;
+ BOOLEAN fFound = FALSE;
+ UINT8 bMinNumTurns = 100;
+ INT8 bNumTurns;
+ INT8 bMinDirection = 0;
+
+ //STRUCTURE * pStructure;
+
+ // IF there is a roof over our heads, this is an ivalid....
+ // return ( FALSE );l
+ if ( FindStructure( sGridNo, STRUCTURE_WALLNWINDOW ) != NULL )
+ {
+
+ return( FALSE );
+ }
+
+ for ( cnt = 0; cnt < 8; cnt+= 2 )
+ {
+ sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+
+ if ( NewOKDestination( pSoldier, sNewGridNo, TRUE, 0 ) )
+ {
+ // Check if this tile has a higher level
+ if ( IsOknoLevel( sNewGridNo ) )
+ {
+ fFound = TRUE;
+
+ // FInd how many turns we should go to get here
+ bNumTurns = FindNumTurnsBetweenDirs( (INT8)cnt, bStartingDir );
+
+ if ( bNumTurns < bMinNumTurns )
+ {
+ bMinNumTurns = bNumTurns;
+ bMinDirection = (INT8)cnt;
+ }
+ }
+ }
+
+ }
+
+
+
+ if ( fFound )
+ {
+ *pbDirection = bMinDirection;
+ return( TRUE );
+ }
+
+ return( FALSE );
+*/
+}
+
+BOOLEAN FindHeigherLevelFence( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStartingDir, INT8 *pbDirection )
+{
+ INT32 cnt;
+ INT32 sNewGridNo;
+ BOOLEAN fFound = FALSE;
+ UINT8 bMinNumTurns = 100;
+ INT8 bNumTurns;
+ INT8 bMinDirection = 0;
+
+ //STRUCTURE * pStructure;
+
+ // IF there is a roof over our heads, this is an ivalid....
+ // return ( FALSE );l
+ if ( FindStructure( sGridNo, STRUCTURE_FENCE ) != NULL )
+ {
+
+ return( FALSE );
+ }
+
+ for ( cnt = 0; cnt < 8; cnt+= 2 )
+ {
+ sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+
+ if ( NewOKDestination( pSoldier, sNewGridNo, TRUE, 0 ) )
+ {
+ // Check if this tile has a higher level
+ if ( IsLegionLevel( sNewGridNo ) )
+ {
+ fFound = TRUE;
+
+ // FInd how many turns we should go to get here
+ bNumTurns = FindNumTurnsBetweenDirs( (INT8)cnt, bStartingDir );
+
+ if ( bNumTurns < bMinNumTurns )
+ {
+ bMinNumTurns = bNumTurns;
+ bMinDirection = (INT8)cnt;
+ }
+ }
+ }
+
+ }
+
+
+
+ if ( fFound )
+ {
+ *pbDirection = bMinDirection;
+ return( TRUE );
+ }
+
+ return( FALSE );
+}
+
+BOOLEAN FindLowerLevelFence( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bStartingDir, INT8 *pbDirection )
+{
+ INT32 cnt;
+ INT32 sNewGridNo;
+ BOOLEAN fFound = FALSE;
+ UINT8 bMinNumTurns = 100;
+ INT8 bNumTurns;
+ INT8 bMinDirection = 0;
+
+ // LOOP THROUGH ALL 8 DIRECTIONS
+ for ( cnt = 0; cnt < 8; cnt+= 2 )
+ {
+ sNewGridNo = NewGridNo( sGridNo, (UINT16)DirectionInc( (UINT8)cnt ) );
+
+ // Make sure there is NOT a roof here...
+ // Check OK destination
+ if ( NewOKDestination( pSoldier, sNewGridNo, TRUE, 0 ) )
+ {
+ if ( FindStructure( sNewGridNo, STRUCTURE_FENCE ) == NULL )
+ {
+ {
+ fFound = TRUE;
+
+ // FInd how many turns we should go to get here
+ bNumTurns = FindNumTurnsBetweenDirs( (INT8)cnt, bStartingDir );
+
+ if ( bNumTurns < bMinNumTurns )
+ {
+ bMinNumTurns = bNumTurns;
+ bMinDirection = (INT8)cnt;
+ }
+
+ }
+ }
+ }
+ }
+
+ if ( fFound )
+ {
+ *pbDirection = bMinDirection;
+ return( TRUE );
+ }
+
+ return( FALSE );
+}
+//---------------------------------------------------------------------------------
+
+
GridNode::MapXY_t GridNode::MapXY;
static GridNode::MapXY_t *pMapXY = GridNode::initGridNodes(); // A hack to initialize the MapXY grid
@@ -632,7 +970,7 @@ INT32 GetRangeFromGridNoDiff( INT32 sGridNo1, INT32 sGridNo2 )
// Convert our grid-not into an XY
ConvertGridNoToXY( sGridNo2, &sXPos2, &sYPos2 );
- uiDist = sqrt((double) ( sXPos2 - sXPos )*( sXPos2 - sXPos ) + ( sYPos2 - sYPos ) * ( sYPos2 - sYPos ) );
+ uiDist = (INT32)(sqrt((double) ( sXPos2 - sXPos )*( sXPos2 - sXPos ) + ( sYPos2 - sYPos ) * ( sYPos2 - sYPos ) ));
return( uiDist );
}
diff --git a/TileEngine/Isometric Utils.h b/TileEngine/Isometric Utils.h
index db1f4791..22187869 100644
--- a/TileEngine/Isometric Utils.h
+++ b/TileEngine/Isometric Utils.h
@@ -140,4 +140,12 @@ public:
static MapXY_t *initGridNodes() { for (INT32 i=0; i
//SB: make size of gpRevealedMap dependable from variable tactical map dimensions
#define NUM_REVEALED_BYTES (WORLD_MAX/8)
diff --git a/TileEngine/Shade Table Util.cpp b/TileEngine/Shade Table Util.cpp
index 79081eaa..2956a5ef 100644
--- a/TileEngine/Shade Table Util.cpp
+++ b/TileEngine/Shade Table Util.cpp
@@ -12,7 +12,7 @@
#include "Fileman.h"
#endif
-#include "VFS/vfs.h"
+#include
#define SHADE_TABLE_DIR "ShadeTables"
diff --git a/TileEngine/Tactical Placement GUI.cpp b/TileEngine/Tactical Placement GUI.cpp
index 3dfa5aa4..59e73eb0 100644
--- a/TileEngine/Tactical Placement GUI.cpp
+++ b/TileEngine/Tactical Placement GUI.cpp
@@ -386,13 +386,10 @@ void InitTacticalPlacementGUI()
gMercPlacement[ giPlacements ].pSoldier = MercPtrs[ i ];
gMercPlacement[ giPlacements ].ubStrategicInsertionCode = MercPtrs[ i ]->ubStrategicInsertionCode;
gMercPlacement[ giPlacements ].fPlaced = FALSE;
- #ifdef JA2BETAVERSION
- CheckForValidMapEdge( &MercPtrs[ i ]->ubStrategicInsertionCode );
- #else
- // WANNE: We need to have valid map edges in multiplayer!
- if (is_networked)
- CheckForValidMapEdge( &MercPtrs[ i ]->ubStrategicInsertionCode );
- #endif
+
+ // WANNE: We always want to have edgepoints
+ CheckForValidMapEdge( &MercPtrs[ i ]->ubStrategicInsertionCode );
+
switch( MercPtrs[ i ]->ubStrategicInsertionCode )
{
case INSERTION_CODE_NORTH:
@@ -743,7 +740,6 @@ void RenderTacticalPlacementGUI()
}
else
{
- // TODO.RW: Check for insertion
if (is_networked)
{
gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode = GetValidInsertionDirectionForMP(gMercPlacement[ gbCursorMercID ].ubStrategicInsertionCode);
@@ -991,8 +987,8 @@ void TacticalPlacementHandle()
case ENTER:
if( ButtonList[ iTPButtons[ DONE_BUTTON ] ]->uiFlags & BUTTON_ENABLED )
{
- /*if(!is_client)KillTacticalPlacementGUI();*/
- //if(is_client)send_donegui(0); only by mouse //hayden
+ if(!is_client)KillTacticalPlacementGUI();
+ if(is_client)send_donegui(0);
}
break;
case 'c':
@@ -1010,25 +1006,6 @@ void TacticalPlacementHandle()
HandleShortCutExitState();
}
break;
- case 'l'://hayden
- if( InputEvent.usKeyState & ALT_DOWN )
- {
- /*
- if (is_networked)
- {
- KillTacticalPlacementGUI();
- DoQuickLoad();
- }
- */
- }
- break;
- case '7':
- if (is_networked)
- {
- if(is_server)
- manual_overide();
- }
- break;
}
}
}
diff --git a/TileEngine/TileEngine_VS2005.vcproj b/TileEngine/TileEngine_VS2005.vcproj
new file mode 100644
index 00000000..14329658
--- /dev/null
+++ b/TileEngine/TileEngine_VS2005.vcproj
@@ -0,0 +1,667 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TileEngine/TileEngine_VS2008.vcproj b/TileEngine/TileEngine_VS2008.vcproj
index 1aeb6162..2056ef22 100644
--- a/TileEngine/TileEngine_VS2008.vcproj
+++ b/TileEngine/TileEngine_VS2008.vcproj
@@ -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"
>
@@ -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"
>
@@ -499,6 +499,14 @@
RelativePath="worldman.h"
>
+
+
+
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}
+ Win32Proj
+ TileEngine
+ TileEngine
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TileEngine/TileEngine_VS2010.vcxproj.filters b/TileEngine/TileEngine_VS2010.vcxproj.filters
new file mode 100644
index 00000000..838f0b83
--- /dev/null
+++ b/TileEngine/TileEngine_VS2010.vcxproj.filters
@@ -0,0 +1,252 @@
+
+
+
+
+ {74f02e9a-2a7e-4654-8228-90ca0ba88a66}
+
+
+ {878cd328-bcac-4171-a25a-60953e8550e3}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/TileEngine/WorldDat.cpp b/TileEngine/WorldDat.cpp
index a352e116..307ab1f6 100644
--- a/TileEngine/WorldDat.cpp
+++ b/TileEngine/WorldDat.cpp
@@ -12,10 +12,16 @@
#include "sys globals.h"
#include "tile surface.h"
#include "fileMan.h"
+ #include "Debug.h"
#endif
-#include "VFS/vfs.h"
+#include
+#include
+#include "XML_TileSet.hpp"
#include "XMLWriter.h"
+
+void ExportTilesets(vfs::Path const& filename);
+
// THIS FILE CONTAINS DEFINITIONS FOR TILESET FILES
void SetTilesetThreeTerrainValues();
@@ -28,76 +34,156 @@ UINT8 gubNumSets = MAX_TILESETS;
TILESET gTilesets[ MAX_TILESETS ];
-
+extern bool g_bUseXML_Tilesets;
void InitEngineTilesets( )
{
- UINT32 cnt, cnt2, uiNumFiles;
-// FILE *hfile;
- HWFILE hfile;
- CHAR8 zName[32];
- UINT32 uiNumBytesRead;
- XMLWriter xmlw;
-
- //OPEN FILE
-// hfile = fopen( "BINARYDATA\\JA2SET.DAT", "rb" );
- hfile = FileOpen( "BINARYDATA\\JA2SET.DAT", FILE_ACCESS_READ, FALSE );
- if ( !hfile )
+ if(g_bUseXML_Tilesets)
{
- SET_ERROR( "Cannot open tileset data file" );
- return;
+ const vfs::Path tileset_filename(L"Ja2Set.dat.xml");
+ if(!getVFS()->fileExists(tileset_filename))
+ {
+ SGP_TRYCATCH_RETHROW( ExportTilesets(tileset_filename), L"Could not export tileset XML file");
+ }
+ vfs::tReadableFile* file = getVFS()->getReadFile(tileset_filename);
+ SGP_THROW_IFFALSE(file,
+ _BS(L"File '") << tileset_filename << L"' does not exist and could not be created" << _BS::wget);
+
+ CTilesetReader tileset_reader(gTilesets);
+ xml_auto::TGenericXMLParser pars(&tileset_reader,NULL);
+
+ SGP_TRYCATCH_RETHROW( pars.parseFile(file),
+ _BS(L"Parser Error in file : ") << file->getPath() << _BS::wget );
+ }
+ else
+ {
+ UINT32 cnt, cnt2, uiNumFiles;
+ //FILE *hfile;
+ HWFILE hfile;
+ CHAR8 zName[32];
+ UINT32 uiNumBytesRead;
+
+ //OPEN FILE
+ hfile = FileOpen( "BINARYDATA\\JA2SET.DAT", FILE_ACCESS_READ, FALSE );
+ if ( !hfile )
+ {
+ SET_ERROR( "Cannot open tileset data file" );
+ return;
+ }
+
+ // READ # TILESETS and compare
+ FileRead( hfile, &gubNumSets, sizeof( gubNumSets ), &uiNumBytesRead );
+ // CHECK
+ if ( gubNumSets > MAX_TILESETS )
+ {
+ // Report error
+ SET_ERROR( "Too many tilesets in the data file" );
+ return;
+ }
+
+ // READ #files
+ FileRead( hfile, &uiNumFiles, sizeof( uiNumFiles ), &uiNumBytesRead );
+
+ // COMPARE
+ if ( uiNumFiles != NUMBEROFTILETYPES )
+ {
+ // Report error
+ SET_ERROR( "Number of tilesets slots in code does not match data file" );
+ return;
+ }
+
+ // Loop through each tileset, load name then files
+ for ( cnt = 0; cnt < gubNumSets; cnt++ )
+ {
+ //Read name
+ FileRead( hfile, &zName, sizeof( zName ), &uiNumBytesRead );
+
+ // Read ambience value
+ FileRead( hfile, &(gTilesets[ cnt ].ubAmbientID), sizeof( UINT8 ), &uiNumBytesRead );
+
+ // Set into tileset
+ swprintf( gTilesets[ cnt ].zName, L"%S", zName );
+
+ // Loop for files
+ for ( cnt2 = 0; cnt2 < uiNumFiles; cnt2++ )
+ {
+ // Read file name
+ FileRead( hfile, &zName, sizeof( zName ), &uiNumBytesRead );
+
+ // Set into database
+ strcpy( gTilesets[ cnt ].TileSurfaceFilenames[ cnt2 ], zName );
+ }
+ }
+
+ FileClose( hfile );
}
+ // SET CALLBACK FUNTIONS!!!!!!!!!!!!!
+ gTilesets[ TLS_CAVES_1 ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetTwoTerrainValues;
+ gTilesets[ TLS_AIRSTRIP ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_DEAD_AIRSTRIP ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_PALACE ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_BALIME ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_BALIME_MUSEUM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_QUEENS_TROPICAL ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_MEDUNA_INNER_TOWN ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_QUEENS_SAM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+ gTilesets[ TLS_QUEENS_AIRPORT ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
+
+ gTilesets[ TLS_TROPICAL_1 ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetFourTerrainValues;
+ gTilesets[ TLS_DESERT_SAM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetFourTerrainValues;
+}
+
+#ifdef USE_VFS
+void ExportTilesets(vfs::Path const& filename)
+{
+ UINT32 uiNumBytesRead = 0;
+ CHAR8 zName[32];
+
+ //OPEN FILE
+ HWFILE hfile = FileOpen( "BINARYDATA\\JA2SET.DAT", FILE_ACCESS_READ, FALSE );
+ SGP_THROW_IFFALSE(hfile, L"Cannot open tileset data file" );
+
+ XMLWriter xmlw;
xmlw.openNode("JA2SET");
// READ # TILESETS and compare
-// fread( &gubNumSets, sizeof( gubNumSets ), 1, hfile );
- FileRead( hfile, &gubNumSets, sizeof( gubNumSets ), &uiNumBytesRead );
+ UINT8 numSets = 0;
+ FileRead( hfile, &numSets, sizeof( numSets ), &uiNumBytesRead );
+
// CHECK
- if ( gubNumSets > MAX_TILESETS )
- {
- // Report error
- SET_ERROR( "Too many tilesets in the data file" );
- return;
- }
- xmlw.addAttributeToNextValue("numTilesets",(int)gubNumSets);
+ SGP_THROW_IFFALSE( numSets <= MAX_TILESETS, L"Too many tilesets in the data file" );
+ xmlw.addAttributeToNextValue("numTilesets",(int)numSets);
// READ #files
-// fread( &uiNumFiles, sizeof( uiNumFiles ), 1, hfile );
- FileRead( hfile, &uiNumFiles, sizeof( uiNumFiles ), &uiNumBytesRead );
+ UINT32 numFiles;
+ FileRead( hfile, &numFiles, sizeof( numFiles ), &uiNumBytesRead );
// COMPARE
- if ( uiNumFiles != NUMBEROFTILETYPES )
- {
- // Report error
- SET_ERROR( "Number of tilesets slots in code does not match data file" );
- return;
- }
- xmlw.addAttributeToNextValue("numFiles",(int)uiNumFiles);
+ SGP_THROW_IFFALSE( numFiles == NUMBEROFTILETYPES,
+ L"Number of tilesets slots in code does not match data file" );
+
+ xmlw.addAttributeToNextValue("numFiles",(int)numFiles);
xmlw.openNode("tilesets");
// Loop through each tileset, load name then files
- for ( cnt = 0; cnt < gubNumSets; cnt++ )
+ for ( UINT8 cnt = 0; cnt < numSets; cnt++ )
{
xmlw.addAttributeToNextValue("index",(int)cnt);
xmlw.openNode("Tileset");
+
//Read name
-// fread( &zName, sizeof( zName ), 1, hfile );
FileRead( hfile, &zName, sizeof( zName ), &uiNumBytesRead );
xmlw.addValue("Name",std::string(zName));
// Read ambience value
-// fread( &(gTilesets[ cnt ].ubAmbientID), sizeof( UINT8), 1, hfile );
- FileRead( hfile, &(gTilesets[ cnt ].ubAmbientID), sizeof( UINT8 ), &uiNumBytesRead );
- xmlw.addValue("AmbientID",(int)gTilesets[ cnt ].ubAmbientID);
-
- // Set into tileset
- swprintf( gTilesets[ cnt ].zName, L"%S", zName );
+ UINT8 ambientID = 0;
+ FileRead( hfile, &ambientID, sizeof( UINT8 ), &uiNumBytesRead );
+ xmlw.addValue("AmbientID",(int)ambientID);
xmlw.openNode("Files");
// Loop for files
- for ( cnt2 = 0; cnt2 < uiNumFiles; cnt2++ )
+ for ( UINT32 cnt2 = 0; cnt2 < numFiles; cnt2++ )
{
// Read file name
-// fread( &zName, sizeof( zName ), 1, hfile );
FileRead( hfile, &zName, sizeof( zName ), &uiNumBytesRead );
if(!std::string(zName).empty())
{
@@ -107,38 +193,26 @@ void InitEngineTilesets( )
// Set into database
strcpy( gTilesets[ cnt ].TileSurfaceFilenames[ cnt2 ], zName );
-
+//ddd{ 250 .
+// if((cnt==0)&&(cnt2+1 == uiNumFiles))
+// { strcpy( gTilesets[ cnt ].TileSurfaceFilenames[ 151 ], "okop.sti" );
+// xmlw.AddAttributeToNextValue("index",(int)151); //for exp in xml
+// xmlw.AddValue("file",std::string("okop.sti"));
+// }
+//ddd}
+
}
xmlw.closeNode(); // Files
xmlw.closeNode(); // tileset
}
xmlw.closeNode();
-// fclose( hfile );
FileClose( hfile );
xmlw.closeNode();
-#ifdef USE_VFS
- xmlw.writeToFile("Ja2Set.dat.xml");
-#endif
- // SET CALLBACK FUNTIONS!!!!!!!!!!!!!
- gTilesets[ TLS_CAVES_1 ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetTwoTerrainValues;
- gTilesets[ TLS_AIRSTRIP ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_DEAD_AIRSTRIP ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_PALACE ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_BALIME ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_BALIME_MUSEUM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_QUEENS_TROPICAL ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_MEDUNA_INNER_TOWN ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_QUEENS_SAM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
- gTilesets[ TLS_QUEENS_AIRPORT ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetThreeTerrainValues;
-
- gTilesets[ TLS_TROPICAL_1 ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetFourTerrainValues;
- gTilesets[ TLS_DESERT_SAM ].MovementCostFnc = (TILESET_CALLBACK)SetTilesetFourTerrainValues;
+ xmlw.writeToFile(filename);
}
-
-
-
+#endif
void SetTilesetOneTerrainValues( )
{
diff --git a/TileEngine/XML_StructureData.hpp b/TileEngine/XML_StructureData.hpp
new file mode 100644
index 00000000..fcca146e
--- /dev/null
+++ b/TileEngine/XML_StructureData.hpp
@@ -0,0 +1,640 @@
+#ifndef _XML_STRUCTUREDATA_HPP_
+#define _XML_STRUCTUREDATA_HPP_
+
+#include "XML_auto_parse.h"
+
+#include
+#include
+
+class CStructureDataStates
+{
+public:
+ enum States
+ {
+ STATE_NONE,
+ STATE_STRUCTURE_FILE,
+ // ***********
+ STATE_HEADER,
+ STATE_HEADER_id,
+ STATE_HEADER_num_structures,
+ STATE_HEADER_num_images,
+ STATE_HEADER_struct_stored,
+ STATE_HEADER_tile_locs_stores,
+ STATE_HEADER_data_size,
+ STATE_HEADER_flags,
+ STATE_HEADER_flags_any,
+ // ***********
+ STATE_AUXIMAGE_DATA,
+ STATE_AUX_image,
+ STATE_AUX_image_tile_index,
+ STATE_AUX_image_wall_orient,
+ STATE_AUX_image_num_tiles,
+ STATE_AUX_image_num_frames,
+ STATE_AUX_image_cur_frame,
+ STATE_AUX_image_FLAGS,
+ STATE_AUX_image_FLAGS_any,
+ // ***********
+ STATE_TILE_OFFSETS,
+ STATE_TOFF_offset,
+ // ***********
+ STATE_STRUCTURE_DATA,
+ // --
+ STATE_SD_structure,
+ STATE_SD_structure_number,
+ STATE_SD_structure_armour,
+ STATE_SD_structure_hitpoits,
+ STATE_SD_structure_density,
+ STATE_SD_structure_wallrientation,
+ STATE_SD_structure_destr_partner,
+ STATE_SD_structure_desct_delta,
+ STATE_SD_structure_ZoffsetX,
+ STATE_SD_structure_ZoffsetY,
+ STATE_SD_structure_flags,
+ STATE_SD_structure_flags_any,
+ STATE_SD_structure_numtiles,
+ // --
+ STATE_SD_TILES,
+ STATE_SD_TILES_tile,
+ STATE_SD_TILES_tile_OffsetX,
+ STATE_SD_TILES_tile_OffsetY,
+ STATE_SD_TILES_tile_OffsetBase,
+ STATE_SD_TILES_tile_vehitLoc,
+ STATE_SD_TILES_tile_flags,
+ STATE_SD_TILES_tile_flags_any,
+ STATE_SD_TILES_tile_profile,
+ STATE_SD_TILES_tile_profile_any,
+ };
+};
+
+PARSER_CLASS_MACRO(CStructureDataReader, CStructureDataStates)
+{
+ typedef CStructureDataReader _myt;
+
+ struct StructureData
+ {
+ DB_STRUCTURE structure;
+ std::vector tiles;
+ };
+ std::vector _structures;
+public:
+ PURE_TRANSITION(NOOP, _myt);
+
+ /**********************************************************************/
+ /* HEADER */
+ /**********************************************************************/
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Header,_myt,false);
+ TRANSITION_ENTER{
+ memset(&(P_DATA->oHeader), 0, sizeof(STRUCTURE_FILE_HEADER));
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Header_NumStructures,_myt,true);
+ TRANSITION_LEAVE{
+ P_DATA->oHeader.usNumberOfStructures = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Header_NumImages,_myt,true);
+ TRANSITION_LEAVE{
+ P_DATA->oHeader.usNumberOfImages = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Header_StructStored,_myt,true);
+ TRANSITION_LEAVE{
+ P_DATA->oHeader.usNumberOfStructuresStored = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Header_TileLocsStored,_myt,true);
+ TRANSITION_LEAVE{
+ P_DATA->oHeader.usNumberOfImageTileLocsStored = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Header_DataSize,_myt,true);
+ TRANSITION_LEAVE{
+ P_DATA->oHeader.usStructureDataSize = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ DEFINE_TRANSITION(TR_Header_Flags,_myt,true);
+ TRANSITION_LEAVE{
+ if(std::string(tag_name) == "STRUCTURE_FILE_CONTAINS_STRUCTUREDATA") P_DATA->oHeader.fFlags |= STRUCTURE_FILE_CONTAINS_STRUCTUREDATA;
+ if(std::string(tag_name) == "STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA") P_DATA->oHeader.fFlags |= STRUCTURE_FILE_CONTAINS_AUXIMAGEDATA;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ /* AUXIMAGE_DATA */
+ /**********************************************************************/
+ int count_aux_tiles;
+ DEFINE_TRANSITION(TR_AUXIMAGE_DATA, _myt, false);
+ TRANSITION_ENTER{
+ long num = 0;
+ SGP_THROW_IFFALSE(atts.getLong("number_of",num), L"no attribute 'number_of'");
+ if(num > 0)
+ {
+ SGP_THROW_IFFALSE(num == P_DATA->oHeader.usNumberOfImages , L"inconsistent data");
+ P_DATA->pStructureFileRef->usNumberOfStructures = (UINT16)num;
+ int size = sizeof(AuxObjectData) * num;
+ P_DATA->pStructureFileRef->pAuxData = (AuxObjectData*)MemAlloc(size);
+ memset(P_DATA->pStructureFileRef->pAuxData, 0, size);
+ P_DATA->count_aux_tiles = 0;
+ }
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ AuxObjectData* current_aux;
+ DEFINE_TRANSITION(TR_AUX_image, _myt, false);
+ TRANSITION_ENTER{
+ long index = -1;
+ SGP_THROW_IFFALSE(atts.getLong("index", index), L"no attribute 'index'");
+ SGP_THROW_IFFALSE(index >= 0 && index < P_DATA->oHeader.usNumberOfImages, L"index out of range");
+ P_DATA->current_aux = &P_DATA->pStructureFileRef->pAuxData[index];
+ }
+ TRANSITION_LEAVE{
+ P_DATA->current_aux = NULL;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_image_tile_index, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_aux, L"aux is null");
+ P_DATA->current_aux->usTileLocIndex = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_image_wall_orient, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_aux, L"aux is null");
+ P_DATA->current_aux->ubWallOrientation = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_image_num_tiles, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_aux, L"aux is null");
+ int num_tiles = atoi(char_data.c_str());
+ P_DATA->current_aux->ubNumberOfTiles = num_tiles;
+ P_DATA->count_aux_tiles += num_tiles;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_image_num_frames, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_aux, L"aux is null");
+ P_DATA->current_aux->ubNumberOfFrames = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_image_cur_frame, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_aux, L"aux is null");
+ P_DATA->current_aux->ubCurrentFrame = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_image_FLAGS, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_aux, L"aux is null");
+ if(std::string(tag_name) == "AUX_FULL_TILE") P_DATA->current_aux->fFlags |= AUX_FULL_TILE;
+ if(std::string(tag_name) == "AUX_ANIMATED_TILE") P_DATA->current_aux->fFlags |= AUX_ANIMATED_TILE;
+ if(std::string(tag_name) == "AUX_DYNAMIC_TILE") P_DATA->current_aux->fFlags |= AUX_DYNAMIC_TILE;
+ if(std::string(tag_name) == "AUX_INTERACTIVE_TILE") P_DATA->current_aux->fFlags |= AUX_INTERACTIVE_TILE;
+ if(std::string(tag_name) == "AUX_IGNORES_HEIGHT") P_DATA->current_aux->fFlags |= AUX_IGNORES_HEIGHT;
+ if(std::string(tag_name) == "AUX_USES_LAND_Z") P_DATA->current_aux->fFlags |= AUX_USES_LAND_Z;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ /* AUXTILE_DATA */
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_AUX_TILES, _myt, false);
+ TRANSITION_ENTER{
+ long num = 0;
+ SGP_THROW_IFFALSE(atts.getLong("number_of",num), L"no attribute 'number_of'");
+ if(num > 0)
+ {
+ SGP_THROW_IFFALSE(num == P_DATA->count_aux_tiles && num == P_DATA->oHeader.usNumberOfImageTileLocsStored,
+ L"counted number and given number of tiles aux images are not equal");
+
+ int size = num * sizeof(RelTileLoc);
+ P_DATA->pStructureFileRef->pTileLocData = (RelTileLoc*)MemAlloc(size);
+ memset(P_DATA->pStructureFileRef->pTileLocData, 0, size);
+ }
+ }
+ FINISH_TRANSITION;
+
+ DEFINE_TRANSITION(TR_AUX_Tile_offset, _myt, false);
+ TRANSITION_ENTER{
+ long index = 0, x = 0 , y = 0;
+ SGP_THROW_IFFALSE(atts.getLong("index", index), L"nu attribute 'index'");
+ SGP_THROW_IFFALSE(index >= 0 && index < P_DATA->oHeader.usNumberOfImageTileLocsStored, L"index out of range");
+ SGP_THROW_IFFALSE(atts.getLong("x", x), L"no attribute 'x'");
+ SGP_THROW_IFFALSE(atts.getLong("y", y), L"no attribute 'y'");
+ P_DATA->pStructureFileRef->pTileLocData[index].bTileOffsetX = (INT8)x;
+ P_DATA->pStructureFileRef->pTileLocData[index].bTileOffsetY = (INT8)y;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ /* STRUCTURE_DATA */
+ /**********************************************************************/
+ StructureData* current_structure;
+ int structure_index, structure_count;
+ DEFINE_TRANSITION(TR_Structure_data,_myt, false);
+ TRANSITION_ENTER{
+ long num = 0, stored = 0;
+ SGP_THROW_IFFALSE(atts.getLong("number_of",num), L"structure data : no attribute 'number_of'");
+ if(!atts.getLong("stored",stored))
+ {
+ stored = num;
+ }
+ if(num > 0)
+ {
+ // header consistency check (to be removed later ?)
+ SGP_THROW_IFFALSE(num == P_DATA->oHeader.usNumberOfStructures, L"inconsistent data : number of structures");
+ SGP_THROW_IFFALSE(stored == P_DATA->oHeader.usNumberOfStructuresStored, L"inconsistent data : number of stored structures");
+ P_DATA->_structures.resize(stored);
+ for(int i=0; i < stored; ++i)
+ {
+ memset(&P_DATA->_structures[i].structure, 0, sizeof(DB_STRUCTURE));
+ }
+ // save data
+ P_DATA->pStructureFileRef->usNumberOfStructures = (UINT16)num;
+ P_DATA->pStructureFileRef->usNumberOfStructuresStored = (UINT16)stored;
+ }
+ P_DATA->structure_count = 0;
+ P_DATA->structure_index = -1;
+ }
+ TRANSITION_LEAVE{
+ // copy gathered data into game object
+ if(!P_DATA->_structures.empty())
+ {
+ SGP_THROW_IFFALSE(P_DATA->pStructureFileRef->usNumberOfStructuresStored == P_DATA->structure_count, L"wrong number of structures");
+
+ int size = 0;
+ for(::size_t i = 0; i < P_DATA->_structures.size(); ++i)
+ {
+ size += sizeof(DB_STRUCTURE);
+ for(::size_t j = 0; j < P_DATA->_structures[i].tiles.size(); ++j)
+ {
+ size += sizeof(DB_STRUCTURE_TILE);
+ }
+ }
+
+ SGP_THROW_IFFALSE(size == P_DATA->oHeader.usStructureDataSize,
+ _BS(L"data size is supposed to be '") << P_DATA->oHeader.usStructureDataSize << L"' but is '" << size << L"'" << _BS::wget);
+
+ P_DATA->structure_data_size = size;
+
+ P_DATA->pStructureFileRef->pubStructureData = (UINT8*)MemAlloc(size);
+ UINT8 *tmp = P_DATA->pStructureFileRef->pubStructureData;
+ for(::size_t i = 0; i < P_DATA->_structures.size(); ++i)
+ {
+ memcpy(tmp, &P_DATA->_structures[i].structure, sizeof(DB_STRUCTURE));
+ tmp += sizeof(DB_STRUCTURE);
+ for(::size_t j = 0; j < P_DATA->_structures[i].tiles.size(); ++j)
+ {
+ memcpy(tmp, &P_DATA->_structures[i].tiles[j], sizeof(DB_STRUCTURE_TILE));
+ tmp += sizeof(DB_STRUCTURE_TILE);
+ }
+ }
+ }
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure, _myt, false);
+ TRANSITION_ENTER{
+ long index;
+ SGP_THROW_IFFALSE( atts.getLong("index", index), L"no attribute 'index'" );
+ SGP_THROW_IFFALSE( (index >= 0) && (index < P_DATA->pStructureFileRef->usNumberOfStructures), L"structure index out of range");
+ SGP_THROW_IFFALSE( (P_DATA->structure_count >= 0) && (P_DATA->structure_count < P_DATA->pStructureFileRef->usNumberOfStructuresStored), L"structure count larger than announced");
+ P_DATA->current_structure = &P_DATA->_structures[P_DATA->structure_count];
+ P_DATA->current_structure->structure.usStructureNumber = (UINT16)index;
+ P_DATA->structure_index = index;
+ }
+ TRANSITION_LEAVE{
+ // finished this structure, increase index for next run
+ P_DATA->structure_index = -1;
+ P_DATA->structure_count += 1;
+ P_DATA->current_structure = NULL;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ //DEFINE_TRANSITION(TR_Structure_number, _myt, true);
+ //TRANSITION_LEAVE{
+ // SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ // P_DATA->current_structure->structure.usStructureNumber = atoi(char_data.c_str());
+ // SGP_THROW_IFFALSE( P_DATA->current_structure->structure.usStructureNumber == P_DATA->structure_index, L"inconsistent data");
+ //}
+ //FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_armour, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.ubArmour = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_hitpoints, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.ubHitPoints = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_density, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.ubDensity = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_wall_orient, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.ubWallOrientation = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_destr_partner, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.bDestructionPartner = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_partner_delta, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.bPartnerDelta = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_offX, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.bZTileOffsetX = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_offY, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ P_DATA->current_structure->structure.bZTileOffsetY = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_num_tiles, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ int num_tiles = atoi(char_data.c_str());
+ SGP_THROW_IFFALSE(num_tiles >= 0, L"invalid number");
+ P_DATA->current_structure->structure.ubNumberOfTiles = num_tiles;
+ P_DATA->current_structure->tiles.resize(num_tiles);
+ for(int i = 0 ;i < num_tiles; ++i)
+ {
+ memset(&P_DATA->current_structure->tiles[i], 0, sizeof(DB_STRUCTURE_TILE));
+ }
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_Structure_FLAGS, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->current_structure, L"null structure" );
+ if(std::string(tag_name) == "STRUCTURE_BASE_TILE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_BASE_TILE;
+ if(std::string(tag_name) == "STRUCTURE_OPEN") P_DATA->current_structure->structure.fFlags |= STRUCTURE_OPEN;
+ if(std::string(tag_name) == "STRUCTURE_OPENABLE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_OPENABLE;
+ if(std::string(tag_name) == "STRUCTURE_CLOSEABLE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_CLOSEABLE;
+ if(std::string(tag_name) == "STRUCTURE_SEARCHABLE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_SEARCHABLE;
+ if(std::string(tag_name) == "STRUCTURE_HIDDEN") P_DATA->current_structure->structure.fFlags |= STRUCTURE_HIDDEN;
+ if(std::string(tag_name) == "STRUCTURE_MOBILE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_MOBILE;
+ if(std::string(tag_name) == "STRUCTURE_PASSABLE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_PASSABLE;
+ if(std::string(tag_name) == "STRUCTURE_EXPLOSIVE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_EXPLOSIVE;
+ if(std::string(tag_name) == "STRUCTURE_TRANSPARENT") P_DATA->current_structure->structure.fFlags |= STRUCTURE_TRANSPARENT;
+ if(std::string(tag_name) == "STRUCTURE_GENERIC") P_DATA->current_structure->structure.fFlags |= STRUCTURE_GENERIC;
+ if(std::string(tag_name) == "STRUCTURE_TREE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_TREE;
+ if(std::string(tag_name) == "STRUCTURE_FENCE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_FENCE;
+ if(std::string(tag_name) == "STRUCTURE_WIREFENCE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_WIREFENCE;
+ if(std::string(tag_name) == "STRUCTURE_HASITEMONTOP") P_DATA->current_structure->structure.fFlags |= STRUCTURE_HASITEMONTOP;
+ if(std::string(tag_name) == "STRUCTURE_SPECIAL") P_DATA->current_structure->structure.fFlags |= STRUCTURE_SPECIAL;
+ if(std::string(tag_name) == "STRUCTURE_LIGHTSOURCE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_LIGHTSOURCE;
+ if(std::string(tag_name) == "STRUCTURE_VEHICLE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_VEHICLE;
+ if(std::string(tag_name) == "STRUCTURE_WALL") P_DATA->current_structure->structure.fFlags |= STRUCTURE_WALL;
+ if(std::string(tag_name) == "STRUCTURE_WALLNWINDOW") P_DATA->current_structure->structure.fFlags |= STRUCTURE_WALLNWINDOW;
+ if(std::string(tag_name) == "STRUCTURE_SLIDINGDOOR") P_DATA->current_structure->structure.fFlags |= STRUCTURE_SLIDINGDOOR;
+ if(std::string(tag_name) == "STRUCTURE_DOOR") P_DATA->current_structure->structure.fFlags |= STRUCTURE_DOOR;
+ if(std::string(tag_name) == "STRUCTURE_MULTI") P_DATA->current_structure->structure.fFlags |= STRUCTURE_MULTI;
+ if(std::string(tag_name) == "STRUCTURE_CAVEWALL") P_DATA->current_structure->structure.fFlags |= STRUCTURE_CAVEWALL;
+ if(std::string(tag_name) == "STRUCTURE_DDOOR_LEFT") P_DATA->current_structure->structure.fFlags |= STRUCTURE_DDOOR_LEFT;
+ if(std::string(tag_name) == "STRUCTURE_DDOOR_RIGHT") P_DATA->current_structure->structure.fFlags |= STRUCTURE_DDOOR_RIGHT;
+ if(std::string(tag_name) == "STRUCTURE_NORMAL_ROOF") P_DATA->current_structure->structure.fFlags |= STRUCTURE_NORMAL_ROOF;
+ if(std::string(tag_name) == "STRUCTURE_SLANTED_ROOF") P_DATA->current_structure->structure.fFlags |= STRUCTURE_SLANTED_ROOF;
+ if(std::string(tag_name) == "STRUCTURE_TALL_ROOF") P_DATA->current_structure->structure.fFlags |= STRUCTURE_TALL_ROOF;
+ if(std::string(tag_name) == "STRUCTURE_SWITCH") P_DATA->current_structure->structure.fFlags |= STRUCTURE_SWITCH;
+ if(std::string(tag_name) == "STRUCTURE_ON_LEFT_WALL") P_DATA->current_structure->structure.fFlags |= STRUCTURE_ON_LEFT_WALL;
+ if(std::string(tag_name) == "STRUCTURE_ON_RIGHT_WALL") P_DATA->current_structure->structure.fFlags |= STRUCTURE_ON_RIGHT_WALL;
+ if(std::string(tag_name) == "STRUCTURE_CORPSE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_CORPSE;
+ if(std::string(tag_name) == "STRUCTURE_PERSON") P_DATA->current_structure->structure.fFlags |= STRUCTURE_PERSON;
+ if(std::string(tag_name) == "STRUCTURE_ANYFENCE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_ANYFENCE;
+ if(std::string(tag_name) == "STRUCTURE_ANYDOOR") P_DATA->current_structure->structure.fFlags |= STRUCTURE_ANYDOOR;
+ if(std::string(tag_name) == "STRUCTURE_OBSTACLE") P_DATA->current_structure->structure.fFlags |= STRUCTURE_OBSTACLE;
+ if(std::string(tag_name) == "STRUCTURE_WALLSTUFF") P_DATA->current_structure->structure.fFlags |= STRUCTURE_WALLSTUFF;
+ if(std::string(tag_name) == "STRUCTURE_BLOCKSMOVES") P_DATA->current_structure->structure.fFlags |= STRUCTURE_BLOCKSMOVES;
+ if(std::string(tag_name) == "STRUCTURE_TYPE_DEFINED") P_DATA->current_structure->structure.fFlags |= STRUCTURE_TYPE_DEFINED;
+ if(std::string(tag_name) == "STRUCTURE_ROOF") P_DATA->current_structure->structure.fFlags |= STRUCTURE_ROOF;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ /* STRUCTURE_TILES */
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_TILES, _myt, false);
+ TRANSITION_ENTER{
+ long num = 0;
+ if(atts.getLong("number_of",num))
+ {
+ SGP_THROW_IFFALSE(num == P_DATA->current_structure->structure.ubNumberOfTiles, L"inconsistent data");
+ }
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DB_STRUCTURE_TILE* current_str_tile;
+ DEFINE_TRANSITION(TR_SD_Tile, _myt, false);
+ TRANSITION_ENTER{
+ long index = 0;
+ SGP_THROW_IFFALSE( atts.getLong("index",index), L"no attribute 'index'" );
+ SGP_THROW_IFFALSE( index >= 0 && index < (long)P_DATA->current_structure->tiles.size(), L"structure index out of range");
+ P_DATA->current_str_tile = &P_DATA->current_structure->tiles[index];
+ }
+ TRANSITION_LEAVE{
+ P_DATA->current_str_tile = NULL;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_Tile_offX, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_str_tile, L"null structure tile");
+ P_DATA->current_str_tile->bXPosRelToBase = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_Tile_offY, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_str_tile, L"null structure tile");
+ P_DATA->current_str_tile->bYPosRelToBase = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_Tile_offBase, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_str_tile, L"null structure tile");
+ P_DATA->current_str_tile->sPosRelToBase = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_Tile_VehHitLoc, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_str_tile, L"null structure tile");
+ P_DATA->current_str_tile->ubVehicleHitLocation = atoi(char_data.c_str());
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_Tile_FLAGS, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_str_tile, L"null structure tile");
+ if(std::string(tag_name) == "TILE_ON_ROOF") P_DATA->current_str_tile->fFlags |= TILE_ON_ROOF;
+ if(std::string(tag_name) == "TILE_PASSABLE") P_DATA->current_str_tile->fFlags |= TILE_PASSABLE;
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ DEFINE_TRANSITION(TR_SD_Tile_profile, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE(P_DATA->current_str_tile, L"null structure tile");
+ int y = -1;
+ if (std::string(tag_name) == "y0") y = 0;
+ else if(std::string(tag_name) == "y1") y = 1;
+ else if(std::string(tag_name) == "y2") y = 2;
+ else if(std::string(tag_name) == "y3") y = 3;
+ else if(std::string(tag_name) == "y4") y = 4;
+
+ if(y != -1)
+ {
+ int x = 0;
+ vfs::String token;
+ vfs::CTokenizer tok(char_data);
+ while(tok.next(token, L','))
+ {
+ if(x >= 0 && x < 5)
+ {
+ int z;
+ SGP_THROW_IFFALSE( vfs::convertTo(token,z), L"" );
+ if(z >= 0 && z < 16)
+ {
+ P_DATA->current_str_tile->Shape[y][x] = z;
+ }
+ }
+ x++;
+ }
+ }
+ }
+ FINISH_TRANSITION;
+
+ /**********************************************************************/
+ UINT32 structure_data_size;
+
+ STRUCTURE_FILE_REF* pStructureFileRef;
+ STRUCTURE_FILE_HEADER oHeader;
+ CStructureDataReader(STRUCTURE_FILE_REF* sfr)
+ : pStructureFileRef(sfr), current_structure(NULL), current_str_tile(NULL), current_aux(NULL)
+ {
+ SGP_THROW_IFFALSE(sfr, L"");
+
+ TR_PASS (STATE_NONE, "STRUCTURE_FILE", STATE_STRUCTURE_FILE);
+ // HEADER
+ TR_HANDLE( STATE_STRUCTURE_FILE, "HEADER", STATE_HEADER, TR_Header );
+ TR_HANDLE( STATE_HEADER, "usNumberOfStructures", STATE_HEADER_num_structures, TR_Header_NumStructures );
+ TR_HANDLE( STATE_HEADER, "usNumberOfImages", STATE_HEADER_num_images, TR_Header_NumImages );
+ TR_HANDLE( STATE_HEADER, "usNumberOfStructuresStored", STATE_HEADER_struct_stored, TR_Header_StructStored );
+ TR_HANDLE( STATE_HEADER, "usNumberOfImageTileLocsStored", STATE_HEADER_tile_locs_stores, TR_Header_TileLocsStored );
+ TR_HANDLE( STATE_HEADER, "usStructureDataSize", STATE_HEADER_data_size, TR_Header_DataSize );
+ TR_PASS ( STATE_HEADER, "flags", STATE_HEADER_flags );
+ TR_HANDLE( STATE_HEADER_flags, "", STATE_HEADER_flags_any, TR_Header_Flags );
+ // AUX IMAGE
+ TR_HANDLE( STATE_STRUCTURE_FILE, "AUXIMAGE_DATA", STATE_AUXIMAGE_DATA, TR_AUXIMAGE_DATA);
+ TR_HANDLE( STATE_AUXIMAGE_DATA, "auximage", STATE_AUX_image, TR_AUX_image);
+ TR_HANDLE( STATE_AUX_image, "tile_loc_index", STATE_AUX_image_tile_index, TR_AUX_image_tile_index);
+ TR_HANDLE( STATE_AUX_image, "wall_orientation", STATE_AUX_image_wall_orient, TR_AUX_image_wall_orient);
+ TR_HANDLE( STATE_AUX_image, "number_of_tiles", STATE_AUX_image_num_tiles, TR_AUX_image_num_tiles);
+ TR_HANDLE( STATE_AUX_image, "number_of_frames", STATE_AUX_image_num_frames, TR_AUX_image_num_frames);
+ TR_HANDLE( STATE_AUX_image, "current_frame", STATE_AUX_image_cur_frame, TR_AUX_image_cur_frame);
+ TR_PASS ( STATE_AUX_image, "flags", STATE_AUX_image_FLAGS);
+ TR_HANDLE( STATE_AUX_image_FLAGS, "", STATE_AUX_image_FLAGS_any, TR_AUX_image_FLAGS);
+ // AUX TILES
+ TR_HANDLE( STATE_STRUCTURE_FILE, "TILE_OFFSETS", STATE_TILE_OFFSETS, TR_AUX_TILES);
+ TR_HANDLE( STATE_TILE_OFFSETS, "offset", STATE_TOFF_offset, TR_AUX_Tile_offset);
+ // STRUCTURE
+ TR_HANDLE( STATE_STRUCTURE_FILE, "STRUCTURE_DATA", STATE_STRUCTURE_DATA, TR_Structure_data );
+ TR_HANDLE( STATE_STRUCTURE_DATA, "STRUCTURE", STATE_SD_structure, TR_Structure );
+// TR_HANDLE( STATE_SD_structure, "usStructureNumber", STATE_SD_structure_number, TR_Structure_number );
+ TR_HANDLE( STATE_SD_structure, "ubArmour", STATE_SD_structure_armour, TR_Structure_armour );
+ TR_HANDLE( STATE_SD_structure, "ubHitPoints", STATE_SD_structure_hitpoits, TR_Structure_hitpoints );
+ TR_HANDLE( STATE_SD_structure, "ubDensity", STATE_SD_structure_density, TR_Structure_density );
+ TR_HANDLE( STATE_SD_structure, "ubWallOrientation", STATE_SD_structure_wallrientation, TR_Structure_wall_orient );
+ TR_HANDLE( STATE_SD_structure, "bDestructionPartner", STATE_SD_structure_destr_partner, TR_Structure_destr_partner );
+ TR_HANDLE( STATE_SD_structure, "bPartnerDelta", STATE_SD_structure_desct_delta, TR_Structure_partner_delta );
+ TR_HANDLE( STATE_SD_structure, "bZTileOffsetX", STATE_SD_structure_ZoffsetX, TR_Structure_offX );
+ TR_HANDLE( STATE_SD_structure, "bZTileOffsetY", STATE_SD_structure_ZoffsetY, TR_Structure_offY );
+ TR_PASS ( STATE_SD_structure, "flags", STATE_SD_structure_flags );
+ TR_HANDLE( STATE_SD_structure_flags, "", STATE_SD_structure_flags_any, TR_Structure_FLAGS );
+ TR_HANDLE( STATE_SD_structure, "ubNumberOfTiles", STATE_SD_structure_numtiles, TR_Structure_num_tiles );
+ // STRUCTURE TILES
+ TR_HANDLE( STATE_SD_structure, "TILES", STATE_SD_TILES, TR_SD_TILES);
+ TR_HANDLE( STATE_SD_TILES, "STRUCTURE_TILE", STATE_SD_TILES_tile, TR_SD_Tile);
+ TR_HANDLE( STATE_SD_TILES_tile, "bXPosRelToBase", STATE_SD_TILES_tile_OffsetX, TR_SD_Tile_offX);
+ TR_HANDLE( STATE_SD_TILES_tile, "bYPosRelToBase", STATE_SD_TILES_tile_OffsetY, TR_SD_Tile_offY);
+ TR_HANDLE( STATE_SD_TILES_tile, "sPosRelToBase", STATE_SD_TILES_tile_OffsetBase, TR_SD_Tile_offBase);
+ TR_HANDLE( STATE_SD_TILES_tile, "ubVehicleHitLocation", STATE_SD_TILES_tile_vehitLoc, TR_SD_Tile_VehHitLoc);
+ TR_PASS ( STATE_SD_TILES_tile, "flags", STATE_SD_TILES_tile_flags );
+ TR_HANDLE( STATE_SD_TILES_tile_flags, "", STATE_SD_TILES_tile_flags_any, TR_SD_Tile_FLAGS );
+ TR_PASS ( STATE_SD_TILES_tile, "profile", STATE_SD_TILES_tile_profile );
+ TR_HANDLE( STATE_SD_TILES_tile_profile, "", STATE_SD_TILES_tile_profile_any, TR_SD_Tile_profile );
+ }
+};
+
+#endif // _XML_STRUCTUREDATA_HPP_
diff --git a/TileEngine/XML_TileSet.hpp b/TileEngine/XML_TileSet.hpp
new file mode 100644
index 00000000..0858b629
--- /dev/null
+++ b/TileEngine/XML_TileSet.hpp
@@ -0,0 +1,125 @@
+#ifndef _XML_TILESET_HPP_
+#define _XML_TILESET_HPP_
+
+#include "XML_auto_parse.h"
+#include "WorldDat.h"
+#include
+
+class CTilesetStates
+{
+public:
+ enum States
+ {
+ STATE_NONE,
+ STATE_JA2SET,
+ STATE_tilesets,
+ STATE_ts_tileset,
+ STATE_ts_tileset_name,
+ STATE_ts_tileset_ambientid,
+ STATE_ts_tileset_files,
+ STATE_ts_tileset_files_file,
+ };
+};
+
+PARSER_CLASS_MACRO(CTilesetReader, CTilesetStates)
+{
+ typedef CTilesetReader _myt;
+public:
+ /**
+ * NOOP
+ */
+ PURE_TRANSITION(NOOP, _myt);
+
+
+ /**
+ * Tilesets
+ */
+ DEFINE_TRANSITION_WDATA(TilesetsAttrib, _myt, false, struct TilesetInfo{int numTilesets; int numFiles;});
+ TRANSITION_ENTER{
+ long T_num, F_num;
+ if(atts.getLong("numTilesets", T_num)) T_DATA.numTilesets = (int)T_num;
+ else SGP_THROW(L"Attribute 'numTileset' not found");
+
+ if(atts.getLong("numFiles",F_num)) T_DATA.numFiles = (int)F_num ;
+ else SGP_THROW(L"Attribute 'numFiles' not found");
+ }
+ FINISH_TRANSITION;
+
+ /**
+ * Tileset
+ */
+ TILESET* _current_tileset;
+ DEFINE_TRANSITION(Tileset, _myt, false);
+ TRANSITION_ENTER{
+ long lindex;
+ if(atts.getLong("index", lindex)){
+ SGP_THROW_IFFALSE(lindex < MAX_TILESETS, _BS(L"tileset index is too large : ") << lindex << _BS::wget );
+ P_DATA->_current_tileset = &(P_DATA->_tilesets[ lindex ]);
+ }
+ else SGP_THROW(L"Attribute 'index' not found");
+ }
+ TRANSITION_LEAVE{
+ P_DATA->_current_tileset = NULL;
+ }
+ FINISH_TRANSITION;
+
+ /**
+ * Tileset Name
+ */
+ DEFINE_TRANSITION(TilesetName, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->_current_tileset != NULL, L"No tileset selected" );
+ std::string tmpString = vfs::trimString(char_data, 0, char_data.length());
+ wcsncpy( P_DATA->_current_tileset->zName, vfs::String( tmpString ).c_str(), 32 );
+ }
+ FINISH_TRANSITION;
+
+ /**
+ * Tileset ID
+ */
+ DEFINE_TRANSITION(TilesetAmbientID, _myt, true);
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->_current_tileset != NULL, L"No tileset selected" );
+ int tmp;
+ SGP_THROW_IFFALSE( vfs::convertTo(char_data, tmp),
+ _BS(L"Could not convert to int : ") << char_data << _BS::wget );
+ P_DATA->_current_tileset->ubAmbientID = tmp;
+
+ }
+ FINISH_TRANSITION;
+
+ /**
+ * Tileset File
+ */
+ DEFINE_TRANSITION_WDATA(TilesetFile, _myt, true, struct Index{int index;});
+ TRANSITION_ENTER{
+ long lindex;
+ if(atts.getLong("index", lindex)){
+ SGP_THROW_IFFALSE(lindex < NUMBEROFTILETYPES,
+ _BS(L"tileset file index is too large : ") << lindex << _BS::wget );
+ T_DATA.index = lindex;
+ }
+ else SGP_THROW(L"Attribute 'index' not found");
+ }
+ TRANSITION_LEAVE{
+ SGP_THROW_IFFALSE( P_DATA->_current_tileset != NULL, L"No tileset selected" );
+ std::string tmpString = vfs::trimString(char_data, 0, char_data.length());
+ strncpy( P_DATA->_current_tileset->TileSurfaceFilenames[T_DATA.index], tmpString.c_str(), 32);
+ }
+ FINISH_TRANSITION;
+
+
+ TILESET* _tilesets;
+ CTilesetReader(TILESET tilesets[ MAX_TILESETS ]) : _tilesets(tilesets), _current_tileset(NULL)
+ {
+ TR_PASS ( STATE_NONE, "JA2SET", STATE_JA2SET);
+ TR_HANDLE( STATE_JA2SET, "tilesets", STATE_tilesets, TilesetsAttrib );
+ TR_HANDLE( STATE_tilesets, "Tileset", STATE_ts_tileset, Tileset );
+ TR_HANDLE( STATE_ts_tileset, "Name", STATE_ts_tileset_name, TilesetName );
+ TR_HANDLE( STATE_ts_tileset, "AmbientID", STATE_ts_tileset_ambientid, TilesetAmbientID );
+ TR_PASS ( STATE_ts_tileset, "Files", STATE_ts_tileset_files );
+ TR_HANDLE( STATE_ts_tileset_files, "file", STATE_ts_tileset_files_file, TilesetFile );
+ }
+};
+
+#endif // _XML_TILESET_HPP_
diff --git a/TileEngine/environment.cpp b/TileEngine/environment.cpp
index d2041f34..f32f0706 100644
--- a/TileEngine/environment.cpp
+++ b/TileEngine/environment.cpp
@@ -960,12 +960,13 @@ void UpdateTemperature( UINT8 ubTemperatureCode )
INT8 SectorTemperature( UINT32 uiTime, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
+ // SANDRO - updated this code
if (bSectorZ > 0)
{
// cool underground
return( 0 );
}
- else if ( IsSectorDesert( sSectorX, sSectorY ) ) // is desert
+ else if ( IsSectorDesert( sSectorX, sSectorY ) && !( guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS ) ) ) // is desert
{
return( gubDesertTemperature );
}
diff --git a/TileEngine/overhead map.cpp b/TileEngine/overhead map.cpp
index 39cd8bdc..98f1ca65 100644
--- a/TileEngine/overhead map.cpp
+++ b/TileEngine/overhead map.cpp
@@ -1359,8 +1359,6 @@ void RenderOverheadOverlays()
if(pSoldier->bSide==0)
{
int personIndex = pSoldier->bTeam + 4;
- // TODO.RW: Get the correct person index (depending on the pSoldier->bTeam)
- //Blt8BPPDataTo16BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sX, sY, 3 );
Blt8BPPDataTo16BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sX, sY, personIndex );
}
}
@@ -1405,9 +1403,6 @@ void RenderOverheadOverlays()
if(pSoldier->bSide==0)
{
int personIndex = pSoldier->bTeam + 4;
- // TODO.RW: Get the correct person index (depending on the pSoldier->bTeam)
-
- //Blt8BPPDataTo16BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sX, sY, 3 );
Blt8BPPDataTo16BPPBufferTransparent((UINT16*)pDestBuf, uiDestPitchBYTES, hVObject, sX, sY, personIndex );
}
}
diff --git a/TileEngine/physics.cpp b/TileEngine/physics.cpp
index e3357152..a032d36f 100644
--- a/TileEngine/physics.cpp
+++ b/TileEngine/physics.cpp
@@ -369,9 +369,9 @@ void RemoveAllPhysicsObjects( )
void SimulateObject( REAL_OBJECT *pObject, real deltaT )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject");
+
if ( !PhysicsUpdateLife( pObject, (float)deltaT ) )
{
- // DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"SimulateObject: don't update life, returning");
return;
}
@@ -486,10 +486,15 @@ BOOLEAN PhysicsUpdateLife( REAL_OBJECT *pObject, real DeltaTime )
}
- // End life if we are out of bounds....
- if ( !GridNoOnVisibleWorldTile( pObject->sGridNo ) )
+ // WANNE.BMP: Only do this check on normal maps.
+ // When we do this check on Big Maps it always returns false and we got wrong physics when trowing items!
+ if (WORLD_COLS <= 160 && WORLD_ROWS <= 160)
{
- pObject->fAlive = FALSE;
+ // End life if we are out of bounds....
+ if ( !GridNoOnVisibleWorldTile( pObject->sGridNo ) )
+ {
+ pObject->fAlive = FALSE;
+ }
}
if ( !pObject->fAlive )
@@ -1496,9 +1501,7 @@ vector_3 FindBestForceForTrajectory( INT32 sSrcGridNo, INT32 sGridNo,INT16 sStar
dRange = (float)GetRangeInCellCoordsFromGridNoDiff( sGridNo, sSrcGridNo );
//calculate force needed
- {
- dForce = (float)( 12.0 * ( sqrt( ( GRAVITY * dRange ) / sin( 2.0 * dzDegrees ) ) ) );
- }
+ dForce = (float)( 12.0 * ( sqrt( ( GRAVITY * dRange ) / sin( 2.0 * dzDegrees ) ) ) );
do
{
@@ -1537,12 +1540,6 @@ vector_3 FindBestForceForTrajectory( INT32 sSrcGridNo, INT32 sGridNo,INT16 sStar
} while( TRUE );
- // OK, we have our force, calculate change to get through without collide
- //if ( ChanceToGetThroughObjectTrajectory( sEndZ, pItem, &vPosition, &vForce, NULL ) == 0 )
- {
- //ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Chance to get through throw is 0." );
- }
-
if ( pdMagForce )
{
(*pdMagForce) = dForce;
@@ -2152,6 +2149,9 @@ FLOAT CalculateForceFromRange( INT16 sRange, FLOAT dDegrees )
FindBestForceForTrajectory( sSrcGridNo, sDestGridNo, GET_SOLDIER_THROW_HEIGHT( 0 ), 0, dDegrees, &gTempObject, &sFinalGridNo, &dMagForce );
+ // WANNE: Problem is the FORCE!!
+ // dMagForce = 460.00;
+
return( dMagForce );
}
@@ -2204,6 +2204,12 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT32 sGridNo, UI
{
// then we hit!
bMissBy = 0;
+
+ // SANDRO - new merc records
+ if( pSoldier->bTeam == 0 && pSoldier->ubProfile != NO_PROFILE )
+ {
+ gMercProfiles[ pSoldier->ubProfile ].records.usShotsHit++;
+ }
}
//if ( 0 )
diff --git a/TileEngine/structure.cpp b/TileEngine/structure.cpp
index 319e0ae0..809bcc5d 100644
--- a/TileEngine/structure.cpp
+++ b/TileEngine/structure.cpp
@@ -23,7 +23,7 @@
#include "Smell.h"
#include "SaveLoadMap.h"
#include "strategicmap.h"
-
+ #include "sgp_logger.h"
#include "Sys Globals.h" //for access to gfEditMode flag
@@ -432,25 +432,122 @@ BOOLEAN CreateFileStructureArrays( STRUCTURE_FILE_REF * pFileRef, UINT32 uiDataS
return( TRUE );
}
+#include
+#include
+#include "XML_StructureData.hpp"
+
+void checkStructureValidity(STRUCTURE_FILE_REF *str1, STRUCTURE_FILE_REF* str2, UINT32 size1, UINT32 size2)
+{
+ if(str1 == str2 && str1 == NULL)
+ {
+ return;
+ }
+
+ if(str1->pubStructureData && str2->pubStructureData)
+ {
+ SGP_THROW_IFFALSE( size1 == size2, L"");
+ //SGP_THROW_IFFALSE( 0 == memcmp(str1->pubStructureData, str2->pubStructureData, size1), L"" );
+ UINT8* ptr1 = str1->pubStructureData;
+ UINT8* ptr2 = str2->pubStructureData;
+ unsigned int count = 0;
+ for(; count < size1 && (*ptr1++ == *ptr2++); count++) {}
+ SGP_THROW_IFFALSE(count == size1, L"bad structure data");
+ }
+ else if(str1->pubStructureData || str2->pubStructureData)
+ {
+ SGP_THROW(L"bad structure data");
+ }
+
+ int count_tiles_1 = 0, count_tiles_2 = 0;
+ if(str1->pAuxData && str2->pAuxData)
+ {
+ SGP_THROW_IFFALSE(str1->usNumberOfStructures == str2->usNumberOfStructures, L"");
+ SGP_THROW_IFFALSE(str1->usNumberOfStructuresStored == str2->usNumberOfStructuresStored, L"");
+ //SGP_THROW_IFFALSE( 0 == memcmp(str1->pAuxData, str2->pAuxData, sizeof(AuxObjectData)*str2->usNumberOfStructures), L"" );
+ for(int i = 0; i < str2->usNumberOfStructures; ++i)
+ {
+ SGP_THROW_IFFALSE( 0 == memcmp(&str1->pAuxData[i], &str2->pAuxData[i], sizeof(AuxObjectData)), _BS(L"bad aux_image : ") << i << _BS::wget );
+ }
+
+ for(int i = 0; i < str1->usNumberOfStructures; ++i){
+ count_tiles_1 += str1->pAuxData[i].ubNumberOfTiles;
+ }
+ for(int j = 0; j < str2->usNumberOfStructures; ++j){
+ count_tiles_2 += str2->pAuxData[j].ubNumberOfTiles;
+ }
+ SGP_THROW_IFFALSE(count_tiles_1 == count_tiles_2, L"");
+ }
+ else if(str1->pAuxData || str2->pAuxData)
+ {
+ SGP_THROW(L"bad aux image data");
+ }
+
+ if(str1->pTileLocData && str2->pTileLocData)
+ {
+ SGP_THROW_IFFALSE( 0 == memcmp(str1->pTileLocData, str2->pTileLocData, count_tiles_1*sizeof(RelTileLoc)), L"" );
+ }
+ else if(str1->pTileLocData || str2->pTileLocData)
+ {
+ SGP_THROW(L"bad aux tile data");
+ }
+}
+
STRUCTURE_FILE_REF * LoadStructureFile( STR szFileName )
{
// NB should be passed in expected number of structures so we can check equality
- UINT32 uiDataSize = 0;
- BOOLEAN fOk;
- STRUCTURE_FILE_REF * pFileRef;
+ UINT32 uiDataSize = 0;
+ BOOLEAN fOk;
+ STRUCTURE_FILE_REF* pFileRef;
- pFileRef = (STRUCTURE_FILE_REF *) MemAlloc( sizeof( STRUCTURE_FILE_REF ) );
- if (pFileRef == NULL)
+ bool found_jsd_xml_file = false;
+ extern bool g_bUseXML_Structures;
+
+ if(g_bUseXML_Structures)
{
- return( NULL );
+ vfs::Path filename = std::string(szFileName) + ".xml";
+
+ if(getVFS()->fileExists(filename))
+ {
+ pFileRef = (STRUCTURE_FILE_REF *) MemAlloc( sizeof( STRUCTURE_FILE_REF ) );
+ memset( pFileRef, 0, sizeof( STRUCTURE_FILE_REF ) );
+
+ CStructureDataReader str_reader(pFileRef);
+ xml_auto::TGenericXMLParser str_parser(&str_reader);
+
+ SGP_TRYCATCH_RETHROW( str_parser.parseFile(filename), _BS(L"Could not parse file : ") << filename << _BS::wget);
+
+ uiDataSize = str_reader.structure_data_size;
+ fOk = TRUE;
+
+ found_jsd_xml_file = true;
+ }
+ else
+ {
+ }
}
- memset( pFileRef, 0, sizeof( STRUCTURE_FILE_REF ) );
- fOk = LoadStructureData( szFileName, pFileRef, &uiDataSize );
+ if(!found_jsd_xml_file)
+ {
+ pFileRef = (STRUCTURE_FILE_REF *) MemAlloc( sizeof( STRUCTURE_FILE_REF ) );
+ if (pFileRef == NULL)
+ {
+ return( NULL );
+ }
+ memset( pFileRef, 0, sizeof( STRUCTURE_FILE_REF ) );
+
+ if(g_bUseXML_Structures)
+ {
+ }
+
+ fOk = LoadStructureData( szFileName, pFileRef, &uiDataSize );
+ }
+
if (!fOk)
{
+ SGP_WARNING("Could not load structure file : ") << szFileName << "[.jsd|.xml]" << sgp::endl << sgp::flush;
MemFree( pFileRef );
return( NULL );
}
+
if (pFileRef->pubStructureData != NULL)
{
fOk = CreateFileStructureArrays( pFileRef, uiDataSize );
diff --git a/TileEngine/worlddef.cpp b/TileEngine/worlddef.cpp
index d41b46ff..74a4e453 100644
--- a/TileEngine/worlddef.cpp
+++ b/TileEngine/worlddef.cpp
@@ -68,6 +68,8 @@
#include "LoadScreen.h"//dnl ch30 150909
#include "Interface Cursors.h"
#include "Simple Render Utils.h"//dnl ch54 111009
+///ddd
+ #include "gamesettings.h"
#endif
#define SET_MOVEMENTCOST( a, b, c, d ) ( ( gubWorldMovementCosts[ a ][ b ][ c ] < d ) ? ( gubWorldMovementCosts[ a ][ b ][ c ] = d ) : 0 );
@@ -159,7 +161,11 @@ INT32 *gpDirtyData;
UINT32 gSurfaceMemUsage;
//UINT8 gubWorldMovementCosts[ WORLD_MAX ][MAXDIR][2];
UINT8 (*gubWorldMovementCosts)[MAXDIR][2] = NULL;//dnl ch43 260909
-
+//ddd .
+BOOLEAN gubWorldTileInLight[ MAX_ALLOWED_WORLD_MAX ];
+BOOLEAN gubIsCorpseThere[ MAX_ALLOWED_WORLD_MAX ];
+INT32 gubMerkCanSeeThisTile[ MAX_ALLOWED_WORLD_MAX ];
+//ddd
// set to nonzero (locs of base gridno of structure are good) to have it defined by structure code
INT16 gsRecompileAreaTop = 0;
INT16 gsRecompileAreaLeft = 0;
@@ -735,6 +741,48 @@ void CompileWorldTerrainIDs( void )
}
}
+///dddokno {
+#pragma optimize("gpt",on)
+__forceinline
+BOOLEAN IsNotRestrictedWindow(STRUCTURE * pStructure)
+{
+
+ if ( (pStructure->fFlags & STRUCTURE_WALLNWINDOW) && gGameExternalOptions.fCanJumpThroughWindows
+ && !(pStructure->fFlags & STRUCTURE_SPECIAL)
+ && (pStructure->fFlags & STRUCTURE_OPEN)
+ && (pStructure->pDBStructureRef->pDBStructure->bPartnerDelta == NO_PARTNER_STRUCTURE) )
+ {
+ // ;( {
+ //build_13.sti - :
+
+ LEVELNODE *pNode = NULL;// STRUCTURE *pBase=NULL;
+ UINT32 uiTileType=0;
+ //pBase = FindStructure( pStructure->sGridNo, STRUCTURE_WALLNWINDOW );
+ //if(pBase!= NULL)
+ pNode = FindLevelNodeBasedOnStructure( pStructure->sGridNo, pStructure );
+ //pNode = gpWorldLevelData[ pStructure->sGridNo ].pStructHead;
+ if(pNode != NULL)
+ GetTileType( pNode->usIndex, &uiTileType );
+
+ UINT16 RestrSubIndex;
+ GetSubIndexFromTileIndex( pNode->usIndex, (UINT16 *)&RestrSubIndex );
+
+ // 0 ,
+ if ( _stricmp( gTilesets[ giCurrentTilesetID ].TileSurfaceFilenames[ uiTileType ], "build_13.sti" ) == 0
+ //&& ( pNode->usIndex == 814 || pNode->usIndex == 816 || pNode->usIndex == 817 || pNode->usIndex == 823) - ;(
+ && (RestrSubIndex == 40 || RestrSubIndex == 41 || RestrSubIndex == 37 || RestrSubIndex == 38
+ || RestrSubIndex == 43 || RestrSubIndex == 44 || RestrSubIndex == 46 || RestrSubIndex == 47) //
+
+ )
+ return FALSE;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+///dddokno }
+
void CompileTileMovementCosts( INT32 usGridNo )
{
UINT8 ubTerrainID;
@@ -845,6 +893,229 @@ void CompileTileMovementCosts( INT32 usGridNo )
}
// all other passable structures do not block movement in any way
}
+
+ /*
+ //dddokno{ =============================================================
+ else if ( IsNotRestrictedWindow(pStructure) )
+ {
+ // standard door
+ switch( pStructure->ubWallOrientation )
+ {
+ case OUTSIDE_TOP_LEFT:
+ SET_CURRMOVEMENTCOST( NORTHEAST, TRAVELCOST_WALL );
+ SET_CURRMOVEMENTCOST( NORTH, TRAVELCOST_JUMPABLEWINDOW );
+ SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_WALL );
+
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTHEAST, 0, TRAVELCOST_WALL );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTH, 0, TRAVELCOST_JUMPABLEWINDOW_N );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTHWEST, 0, TRAVELCOST_WALL );
+
+ // DO CORNERS
+ SET_MOVEMENTCOST( usGridNo - 1, NORTHWEST, 0, TRAVELCOST_WALL );
+ SET_MOVEMENTCOST( usGridNo + 1, NORTHEAST, 0, TRAVELCOST_WALL );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS - 1, SOUTHWEST, 0, TRAVELCOST_WALL );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_WALL );
+
+ break;
+
+ case INSIDE_TOP_LEFT:
+ SET_CURRMOVEMENTCOST( NORTHEAST, TRAVELCOST_WALL );
+ SET_CURRMOVEMENTCOST( NORTH, TRAVELCOST_JUMPABLEWINDOW );
+ SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_WALL );
+
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTH, 0, TRAVELCOST_JUMPABLEWINDOW_N );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+
+ // DO CORNERS
+ SET_MOVEMENTCOST( usGridNo - 1, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS - 1, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+
+ break;
+
+ case OUTSIDE_TOP_RIGHT:
+ SET_CURRMOVEMENTCOST( SOUTHWEST, TRAVELCOST_OBSTACLE );
+ SET_CURRMOVEMENTCOST( WEST, TRAVELCOST_JUMPABLEWINDOW );
+ SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_OBSTACLE );
+
+ SET_MOVEMENTCOST( usGridNo + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + 1, EAST, 0, TRAVELCOST_JUMPABLEWINDOW_W );
+ SET_MOVEMENTCOST( usGridNo + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+
+ // DO CORNERS
+ SET_MOVEMENTCOST( usGridNo - WORLD_COLS + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo - WORLD_COLS, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+
+
+ break;
+
+ case INSIDE_TOP_RIGHT:
+ SET_CURRMOVEMENTCOST( SOUTHWEST, TRAVELCOST_OBSTACLE );
+ SET_CURRMOVEMENTCOST( WEST, TRAVELCOST_JUMPABLEWINDOW );
+ SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_OBSTACLE );
+
+ SET_MOVEMENTCOST( usGridNo + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + 1, EAST, 0, TRAVELCOST_JUMPABLEWINDOW_W );
+ SET_MOVEMENTCOST( usGridNo + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+
+ // DO CORNERS
+ SET_MOVEMENTCOST( usGridNo - WORLD_COLS + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo - WORLD_COLS, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ SET_MOVEMENTCOST( usGridNo + WORLD_COLS, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+
+ break;
+
+
+ //switch( pStructure->ubWallOrientation )
+ //{
+ // case OUTSIDE_TOP_LEFT: //3 \# - ,
+ // case INSIDE_TOP_LEFT: //1 - \
+ // SET_CURRMOVEMENTCOST( NORTH, TRAVELCOST_JUMPABLEWINDOW );
+ // SET_CURRMOVEMENTCOST( NORTHEAST, TRAVELCOST_OBSTACLE);
+ // SET_CURRMOVEMENTCOST( EAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( EAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTHEAST, TRAVELCOST_OBSTACLE);
+ // SET_CURRMOVEMENTCOST( SOUTH, TRAVELCOST_JUMPABLEWINDOW);
+ // SET_CURRMOVEMENTCOST( SOUTHWEST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( WEST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_OBSTACLE );
+ // //?
+ // FORCE_SET_MOVEMENTCOST( sGridNo - WORLD_COLS, NORTH, 0, TRAVELCOST_NONE );
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + 1, EAST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // FORCE_SET_MOVEMENTCOST( sGridNo + WORLD_COLS, SOUTH, 0, TRAVELCOST_NONE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS - 1, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo - 1, WEST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS - 1, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+ //
+
+
+ // break;
+
+ // case OUTSIDE_TOP_RIGHT: //4 #/ // ,
+
+ // case INSIDE_TOP_RIGHT:
+
+ // //2 #/
+ // //. .
+ // // ,
+
+
+ // SET_CURRMOVEMENTCOST( NORTH, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( NORTHEAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( EAST, TRAVELCOST_JUMPABLEWINDOW );
+ // SET_CURRMOVEMENTCOST( SOUTHEAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTH, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTHWEST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( WEST, TRAVELCOST_JUMPABLEWINDOW );
+ // SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_OBSTACLE );
+ // //?
+ // // set values for the tiles EXITED from this location
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS, NORTH, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // // make sure no obstacle costs exists before changing path cost to 0
+ // if ( gubWorldMovementCosts[ sGridNo + 1 ][ EAST ][ 0 ] < TRAVELCOST_BLOCKED )
+ // {
+ // FORCE_SET_MOVEMENTCOST( sGridNo + 1, EAST, 0, TRAVELCOST_NONE );
+ // }
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS, SOUTH, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS - 1, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+ // if ( gubWorldMovementCosts[ sGridNo - 1 ][ WEST ][ 0 ] < TRAVELCOST_BLOCKED )
+ // {
+ // FORCE_SET_MOVEMENTCOST( sGridNo - 1, WEST, 0, TRAVELCOST_NONE );
+ // }
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS - 1, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+
+
+ // break;
+ // default:
+ // // corners aren't jumpable
+ // for (ubDirLoop=0; ubDirLoop < NUM_WORLD_DIRECTIONS; ubDirLoop++)
+ // {
+ // SET_CURRMOVEMENTCOST( ubDirLoop, TRAVELCOST_OBSTACLE );
+ // }
+ // break;
+ //}
+
+
+
+ //************************************ . ))
+ //if ( (pStructure->fFlags & STRUCTURE_WALLNWINDOW) //&& !(pStructure->fFlags & STRUCTURE_SPECIAL)
+ // && (pStructure->fFlags & STRUCTURE_WALLSTUFF)==0 )
+ //if(pStructure->pDBStructureRef->pDBStructure->bPartnerDelta == NO_PARTNER_STRUCTURE)
+
+ // jumpable!
+ // switch( pStructure->ubWallOrientation )
+ // {
+ // case OUTSIDE_TOP_LEFT:
+ // case INSIDE_TOP_LEFT:
+ // // can be jumped north and south
+ // SET_CURRMOVEMENTCOST( NORTH, TRAVELCOST_FENCE );
+ // SET_CURRMOVEMENTCOST( NORTHEAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( EAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTHEAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTH, TRAVELCOST_FENCE );
+ // SET_CURRMOVEMENTCOST( SOUTHWEST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( WEST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_OBSTACLE );
+ // // set values for the tiles EXITED from this location
+ // FORCE_SET_MOVEMENTCOST( sGridNo - WORLD_COLS, NORTH, 0, TRAVELCOST_NONE );
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + 1, EAST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // FORCE_SET_MOVEMENTCOST( sGridNo + WORLD_COLS, SOUTH, 0, TRAVELCOST_NONE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS - 1, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo - 1, WEST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS - 1, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+ // break;
+
+ // case OUTSIDE_TOP_RIGHT:
+ // case INSIDE_TOP_RIGHT:
+ // // can be jumped east and west
+ // SET_CURRMOVEMENTCOST( NORTH, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( NORTHEAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( EAST, TRAVELCOST_FENCE );
+ // SET_CURRMOVEMENTCOST( SOUTHEAST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTH, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( SOUTHWEST, TRAVELCOST_OBSTACLE );
+ // SET_CURRMOVEMENTCOST( WEST, TRAVELCOST_FENCE );
+ // SET_CURRMOVEMENTCOST( NORTHWEST, TRAVELCOST_OBSTACLE );
+ // // set values for the tiles EXITED from this location
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS, NORTH, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS + 1, NORTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // // make sure no obstacle costs exists before changing path cost to 0
+ // if ( gubWorldMovementCosts[ sGridNo + 1 ][ EAST ][ 0 ] < TRAVELCOST_BLOCKED )
+ // {
+ // FORCE_SET_MOVEMENTCOST( sGridNo + 1, EAST, 0, TRAVELCOST_NONE );
+ // }
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS + 1, SOUTHEAST, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS, SOUTH, 0, TRAVELCOST_OBSTACLE );
+ // SET_MOVEMENTCOST( sGridNo + WORLD_COLS - 1, SOUTHWEST, 0, TRAVELCOST_OBSTACLE );
+ // if ( gubWorldMovementCosts[ sGridNo - 1 ][ WEST ][ 0 ] < TRAVELCOST_BLOCKED )
+ // {
+ // FORCE_SET_MOVEMENTCOST( sGridNo - 1, WEST, 0, TRAVELCOST_NONE );
+ // }
+ // SET_MOVEMENTCOST( sGridNo - WORLD_COLS - 1, NORTHWEST, 0, TRAVELCOST_OBSTACLE );
+ // break;
+
+ // //default:
+ // // corners aren't jumpable
+ // for (ubDirLoop=0; ubDirLoop < NUM_WORLD_DIRECTIONS; ubDirLoop++)
+ // {
+ // SET_CURRMOVEMENTCOST( ubDirLoop, TRAVELCOST_OBSTACLE );
+ // }
+ // break;
+ // }//switch
+ //}//}if dddokno==============================================================================
+ */
+
else if (pStructure->fFlags & STRUCTURE_BLOCKSMOVES)
{
if ( (pStructure->fFlags & STRUCTURE_FENCE) && !(pStructure->fFlags & STRUCTURE_SPECIAL) )
diff --git a/TileEngine/worlddef.h b/TileEngine/worlddef.h
index 167174bd..0ccb7910 100644
--- a/TileEngine/worlddef.h
+++ b/TileEngine/worlddef.h
@@ -33,8 +33,10 @@ extern INT32 guiWorldRows;
#define WORLD_MAX (WORLD_COLS*WORLD_ROWS)
// WANNE - BMP: The maximum value WORLD_MAX can have. DONE!
-#define MAX_ALLOWED_WORLD_MAX 4000000 // (1000 cols x 1000 rows)
-
+// CptMoore - DC: added MAX values here so it is known that display cover depends on them
+#define WORLD_COLS_MAX 2000
+#define WORLD_ROWS_MAX 2000
+#define MAX_ALLOWED_WORLD_MAX WORLD_COLS_MAX*WORLD_ROWS_MAX // (2000 cols x 2000 rows)
//
@@ -284,6 +286,12 @@ extern MAP_ELEMENT *gpWorldLevelData;
// World Movement Costs
//UINT8 gubWorldMovementCosts[ WORLD_MAX ][MAXDIR][2];
+//ddd .
+extern BOOLEAN gubWorldTileInLight[ MAX_ALLOWED_WORLD_MAX ];
+extern BOOLEAN gubIsCorpseThere[ MAX_ALLOWED_WORLD_MAX ]; // \ ;)
+extern INT32 gubMerkCanSeeThisTile[ MAX_ALLOWED_WORLD_MAX ]; // , \ ?
+//ddd
+
extern UINT8 (*gubWorldMovementCosts)[MAXDIR][2];//dnl ch43 260909
//dnl ch44 290909 Translation routine
diff --git a/TileEngine/worldman.cpp b/TileEngine/worldman.cpp
index 8d577480..65e5388f 100644
--- a/TileEngine/worldman.cpp
+++ b/TileEngine/worldman.cpp
@@ -3768,3 +3768,37 @@ void SetTreeTopStateForMap()
// FOR THE NEXT RENDER LOOP, RE-EVALUATE REDUNDENT TILES
InvalidateWorldRedundency( );
}
+
+
+
+//--------------------legion 2 Jazz---------------------------------------------------------------
+BOOLEAN IsOknoLevel( INT32 sGridNo )
+{
+ STRUCTURE * pStructure;
+
+ pStructure = FindStructure( sGridNo, STRUCTURE_WALLNWINDOW );
+
+ if ( pStructure != NULL && !( pStructure->fFlags & STRUCTURE_OPEN ))
+ {
+ return( TRUE );
+ }
+
+ return( FALSE );
+
+}
+
+BOOLEAN IsLegionLevel( INT32 sGridNo )
+{
+ STRUCTURE * pStructure;
+
+ pStructure = FindStructure( sGridNo, STRUCTURE_FENCE );
+
+ if ( pStructure != NULL )//&& !( pStructure->fFlags & STRUCTURE_OPEN ))
+ {
+ return( TRUE );
+ }
+
+ return( FALSE );
+
+}
+//-------------------------------------------------------------------
diff --git a/TileEngine/worldman.h b/TileEngine/worldman.h
index 7de7acff..db7dbb33 100644
--- a/TileEngine/worldman.h
+++ b/TileEngine/worldman.h
@@ -153,4 +153,8 @@ extern UINT32 gCurrentBackground;
void SetTreeTopStateForMap();
+//legion by Jazz
+BOOLEAN IsOknoLevel( INT32 sGridNo );
+BOOLEAN IsLegionLevel( INT32 sGridNo );
+
#endif
\ No newline at end of file
diff --git a/Utils/Cinematics Bink.cpp b/Utils/Cinematics Bink.cpp
new file mode 100644
index 00000000..05f6d3f3
--- /dev/null
+++ b/Utils/Cinematics Bink.cpp
@@ -0,0 +1,433 @@
+#include "Types.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Debug.h"
+#include "FileMan.h"
+#include "smack.h"
+#include "DDraw.h"
+#include "mss.h"
+#include "DirectX Common.h"
+#include "DirectDraw Calls.h"
+#include "SoundMan.h"
+#include "Video.h"
+
+#include "Cinematics Bink.h"
+
+#include "vsurface_private.h"
+
+//#include "Intro.h"
+#include
+#include
+
+
+#include "radmalw.i"
+
+
+#include
+
+
+
+//*******************************************************************
+//
+// Local Defines
+//
+//*******************************************************************
+
+
+#define BINK_NUM_FLICS 4 // Maximum number of flics open
+
+
+
+//*******************************************************************
+//
+// Global Variables
+//
+//*******************************************************************
+
+BINKFLIC BinkList[BINK_NUM_FLICS];
+UINT32 guiBinkPixelFormat=0;
+
+//LPDIRECTDRAWSURFACE lpBinkVideoPlayback=NULL;
+LPDIRECTDRAWSURFACE2 lpBinkVideoPlayback2=NULL;
+HWND hBinkDisplayWindow=0;
+UINT32 guiHeight;
+
+
+
+//*******************************************************************
+//
+// Function Prototypes
+//
+//*******************************************************************
+
+void BinkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight);
+void BinkShutdown(void);
+BINKFLIC *BinkPlayFlic(CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, UINT32 uiFlags );
+BOOLEAN BinkPollFlics(void);
+BINKFLIC *BinkOpenFlic(const CHAR8 *cFilename);
+void BinkSetBlitPosition(BINKFLIC *pBink, UINT32 uiLeft, UINT32 uiTop);
+void BinkCloseFlic(BINKFLIC *pBink);
+BINKFLIC *BinkGetFreeFlic(void);
+void BinkSetupVideo(void);
+void BinkShutdownVideo(void);
+UINT16 GetNumberOfBits( UINT32 uiMask );
+
+
+
+
+
+//*******************************************************************
+//
+// Functions
+//
+//*******************************************************************
+
+
+
+void BinkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight)
+{
+ //HDIGDRIVER pSoundDriver = NULL;
+ void* pSoundDriver = NULL;
+
+
+ //Get the sound Driver handle
+ pSoundDriver = SoundGetDriverHandle();
+
+ //if we got the sound handle, use sound during the intro
+ if( pSoundDriver )
+ {
+ BinkSoundUseDirectSound( pSoundDriver );
+ }
+
+ guiHeight = uiHeight;
+}
+
+
+void BinkShutdown(void)
+{
+ UINT32 uiCount;
+
+ // Close and deallocate any open flics
+ for(uiCount=0; uiCount < BINK_NUM_FLICS; uiCount++)
+ {
+ //if the flic is currently open
+ if(BinkList[uiCount].uiFlags & BINK_FLIC_OPEN )
+ {
+ //close it
+ BinkCloseFlic( &BinkList[uiCount] );
+ }
+ }
+}
+
+
+
+BINKFLIC *BinkPlayFlic(const CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, UINT32 uiFlags )
+{
+ BINKFLIC *pBink;
+
+ // Open the flic
+ if( ( pBink = BinkOpenFlic( cFilename ) ) == NULL )
+ {
+ return(NULL);
+ }
+
+ if( uiFlags & BINK_FLIC_CENTER_VERTICAL)
+ {
+ uiTop = ( guiHeight - pBink->BinkHandle->Height ) / 2;
+ }
+
+ // Set the blitting position on the screen
+ BinkSetBlitPosition( pBink, uiLeft, uiTop);
+
+ // We're now playing, flag the flic for the poller to update
+ pBink->uiFlags |= BINK_FLIC_PLAYING;
+
+ if( uiFlags & BINK_FLIC_AUTOCLOSE )
+ {
+ pBink->uiFlags |= BINK_FLIC_AUTOCLOSE;
+ }
+ else
+ {
+ pBink->uiFlags |= BINK_FLIC_LOOP;
+ }
+
+
+ return(pBink);
+}
+
+BINKFLIC *BinkOpenFlic( const CHAR8 *cFilename )
+{
+ BINKFLIC *pBink;
+
+ // Get an available flic slot from the list
+ if( !( pBink = BinkGetFreeFlic() ) )
+ {
+ ErrorMsg("BINK ERROR: Out of flic slots, cannot open another");
+ return(NULL);
+ }
+#ifndef USE_VFS
+ // Attempt opening the filename
+ if(!(pBink->hFileHandle = FileOpen( const_cast(cFilename), FILE_OPEN_EXISTING | FILE_ACCESS_READ, FALSE ) ) )
+ {
+ ErrorMsg("BINK ERROR: Can't open the BINK file");
+ return(NULL);
+ }
+
+ //Get the real file handle for the file man handle for the smacker file
+ HANDLE hFile = GetRealFileHandleFromFileManFileHandle( pBink->hFileHandle );
+#else
+ vfs::Path introname(cFilename);
+ vfs::Path dir,filename;
+ introname.splitLast(dir,filename);
+ vfs::Path tempfile = vfs::Path(L"Temp") + filename;
+ if(!getVFS()->fileExists(tempfile))
+ {
+ try
+ {
+ if(!getVFS()->fileExists(introname))
+ {
+ return NULL;
+ }
+ vfs::COpenReadFile rfile(introname);
+ vfs::size_t size = rfile->getSize();
+ std::vector data(size);
+ rfile->read(&data[0],size);
+
+ vfs::COpenWriteFile wfile(tempfile,true);
+ wfile->write(&data[0],size);
+ }
+ catch(std::exception& ex)
+ {
+ SGP_RETHROW(_BS(L"Intro file \"") << filename << L"\" could not be extracted" << _BS::wget, ex);
+ }
+ }
+#endif
+
+#ifndef USE_VFS
+ if( !( pBink->BinkHandle = BinkOpen((CHAR8 *)hFile, BINKFILEHANDLE ) ) ) //| SMACKTRACKS
+#else
+ vfs::Path tempfilename;
+ try
+ {
+ vfs::COpenWriteFile wfile(tempfile);
+ if(!wfile->_getRealPath(tempfilename))
+ {
+ return NULL;
+ }
+ }
+ catch(std::exception& ex)
+ {
+ SGP_RETHROW(L"Temporary intro file could not be read", ex);
+ }
+ if( !( pBink->BinkHandle = BinkOpen(tempfilename.to_string().c_str(), BINKNOTHREADEDIO /*BINKFILEHANDLE*/ ) ) ) //| SMACKTRACKS
+#endif
+ {
+ ErrorMsg("BINK ERROR: Bink won't open the BINK file");
+ return(NULL);
+ }
+
+ // Make sure we have a video surface
+ BinkSetupVideo();
+
+ pBink->cFilename = cFilename;
+
+ pBink->lpDDS = lpBinkVideoPlayback2;
+
+ pBink->hWindow = hBinkDisplayWindow;
+
+ // Bink flic is now open and ready to go
+ pBink->uiFlags |= BINK_FLIC_OPEN;
+
+ return( pBink );
+}
+
+
+
+BINKFLIC *BinkGetFreeFlic()
+{
+ UINT32 uiCount;
+
+ //loop through to get a free slot
+ for( uiCount=0; uiCount < BINK_NUM_FLICS; uiCount++ )
+ {
+ //if this slot is currently not in use
+ if( !( BinkList[uiCount].uiFlags & BINK_FLIC_OPEN ) )
+ {
+ return( &BinkList[ uiCount ] );
+ }
+ }
+
+ return( NULL );
+}
+
+
+void BinkSetBlitPosition( BINKFLIC *pBink, UINT32 uiLeft, UINT32 uiTop )
+{
+ pBink->uiLeft = uiLeft;
+ pBink->uiTop = uiTop;
+}
+
+void BinkCloseFlic( BINKFLIC *pBink )
+{
+ // Deallocate the smack buffers
+// SmackBufferClose(pSmack->SmackBuffer);
+
+ // Close the smack flic
+ BinkClose(pBink->BinkHandle);
+
+ // Attempt opening the filename
+ FileClose(pBink->hFileHandle);
+
+ // Zero the memory, flags, etc.
+ memset( pBink, 0, sizeof(BINKFLIC) );
+}
+
+
+BOOLEAN BinkPollFlics(void)
+{
+ UINT32 uiCount;
+ BOOLEAN fFlicStatus=FALSE;
+ DDSURFACEDESC SurfaceDescription;
+ BINKFLIC *pBink=NULL;
+ UINT32 uiCopyToBufferFlags = guiBinkPixelFormat;
+
+ //loop through all the open flics
+ for(uiCount=0; uiCount < BINK_NUM_FLICS; uiCount++)
+ {
+ pBink = &BinkList[uiCount];
+
+ if( pBink->uiFlags & BINK_FLIC_PLAYING )
+ {
+ fFlicStatus = TRUE;
+
+ //do we still have to wait for the frame to be finished being displayed
+ if( !( BinkWait( pBink->BinkHandle ) ) )
+ {
+ DDLockSurface( pBink->lpDDS, NULL, &SurfaceDescription, 0, NULL);
+
+ BinkDoFrame( pBink->BinkHandle );
+
+ BinkCopyToBuffer( pBink->BinkHandle,
+ SurfaceDescription.lpSurface,
+ SurfaceDescription.lPitch,
+ pBink->BinkHandle->Height,
+ pBink->uiLeft,
+ pBink->uiTop,
+ uiCopyToBufferFlags );
+
+
+ DDUnlockSurface( pBink->lpDDS, SurfaceDescription.lpSurface);
+
+ // Check to see if the flic is done the last frame
+ if( pBink->BinkHandle->FrameNum == ( pBink->BinkHandle->Frames-1 ) )
+ {
+ // If flic is looping, reset frame to 0
+ if( pBink->uiFlags & BINK_FLIC_LOOP)
+ {
+ BinkGoto( pBink->BinkHandle, 0, 0 );
+ }
+ else if( pBink->uiFlags & BINK_FLIC_AUTOCLOSE)
+ {
+ BinkCloseFlic( pBink );
+ }
+ }
+ else
+ {
+ BinkNextFrame( BinkList[uiCount].BinkHandle );
+ }
+
+ }
+ }
+ }
+
+ return( fFlicStatus );
+}
+
+
+
+void BinkSetupVideo(void)
+{
+ DDSURFACEDESC SurfaceDescription;
+ HRESULT ReturnCode;
+ UINT16 usRed, usGreen, usBlue;
+ HVSURFACE hVSurface;
+
+ GetVideoSurface( &hVSurface, FRAME_BUFFER );
+
+ lpBinkVideoPlayback2 = GetVideoSurfaceDDSurface( hVSurface );
+
+ ZEROMEM(SurfaceDescription);
+ SurfaceDescription.dwSize = sizeof (DDSURFACEDESC);
+
+ ReturnCode = IDirectDrawSurface2_GetSurfaceDesc ( lpBinkVideoPlayback2, &SurfaceDescription );
+ if (ReturnCode != DD_OK)
+ {
+ DirectXAttempt ( ReturnCode, __LINE__, __FILE__ );
+ return;
+ }
+ /*
+ usRed = (UINT16) SurfaceDescription.ddpfPixelFormat.dwRBitMask;
+ usGreen = (UINT16) SurfaceDescription.ddpfPixelFormat.dwGBitMask;
+ usBlue = (UINT16) SurfaceDescription.ddpfPixelFormat.dwBBitMask;
+
+// SurfaceDescription.ddpfPixelFormat
+
+ if((usRed==0xf800) && (usGreen==0x07e0) && (usBlue==0x001f))
+ guiBinkPixelFormat = BINKSURFACE565;
+ else
+ guiBinkPixelFormat = BINKSURFACE555;
+*/
+ //
+ // Get bit count for the RGB
+ //
+ usRed = GetNumberOfBits( SurfaceDescription.ddpfPixelFormat.dwRBitMask );
+ usGreen = GetNumberOfBits( SurfaceDescription.ddpfPixelFormat.dwGBitMask );
+ usBlue = GetNumberOfBits( SurfaceDescription.ddpfPixelFormat.dwBBitMask );
+
+ // 555
+ if( usRed == 5 && usGreen == 5 && usBlue == 5 )
+ {
+ guiBinkPixelFormat = BINKSURFACE555;
+ }
+ //565
+ else if( usRed == 5 && usGreen == 6 && usBlue == 5 )
+ {
+ guiBinkPixelFormat = BINKSURFACE565;
+ }
+ //655
+ else if( usRed == 6 && usGreen == 5 && usBlue == 5 )
+ {
+ guiBinkPixelFormat = BINKSURFACE655;
+ }
+
+ //dont know the format, wont get video
+ else
+ {
+ guiBinkPixelFormat = 0;
+ }
+}
+
+UINT16 GetNumberOfBits( UINT32 uiMask )
+{
+ UINT16 usBits = 0;
+
+ while( uiMask )
+ {
+ uiMask = uiMask & ( uiMask - 1 );
+ usBits++;
+ }
+ return usBits;
+}
+
+
+void BinkShutdownVideo(void)
+{
+}
diff --git a/Utils/Cinematics Bink.h b/Utils/Cinematics Bink.h
new file mode 100644
index 00000000..f45ec3d4
--- /dev/null
+++ b/Utils/Cinematics Bink.h
@@ -0,0 +1,49 @@
+#ifndef _CINEMATICS_BINK__H_
+#define _CINEMATICS_BINK__H_
+
+
+#include "bink.h"
+
+
+
+
+// BINKFLIC uiFlags
+#define BINK_FLIC_OPEN 0x00000001 // Flic is open
+#define BINK_FLIC_PLAYING 0x00000002 // Flic is playing
+#define BINK_FLIC_LOOP 0x00000004 // Play flic in a loop
+#define BINK_FLIC_AUTOCLOSE 0x00000008 // Close when done
+#define BINK_FLIC_CENTER_VERTICAL 0x00000010 // Center the video on screen vertically
+
+
+
+
+// Paused???
+
+struct BINKFLIC
+{
+ const CHAR8 *cFilename;
+ HWFILE hFileHandle;
+ HBINK BinkHandle;
+/// SmackBuf *SmackBuffer;
+ UINT32 uiFlags;
+ LPDIRECTDRAWSURFACE2 lpDDS;
+ HWND hWindow;
+ UINT32 uiFrame;
+ UINT32 uiLeft, uiTop;
+// LPDIRECTDRAW2 lpDD;
+// UINT32 uiNumFrames;
+// UINT8 *pAudioData;
+// UINT8 *pCueData;
+
+};
+
+
+
+void BinkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight);
+BOOLEAN BinkPollFlics(void);
+void BinkCloseFlic(BINKFLIC *pBink);
+void BinkShutdownVideo(void);
+BINKFLIC *BinkPlayFlic(const CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, UINT32 uiFlags );
+
+
+#endif
\ No newline at end of file
diff --git a/Utils/Cinematics.cpp b/Utils/Cinematics.cpp
index f8b20bd8..cd98d22a 100644
--- a/Utils/Cinematics.cpp
+++ b/Utils/Cinematics.cpp
@@ -30,8 +30,8 @@
#include "DirectDraw Calls.h"
#include "Cinematics.h"
#include "soundman.h"
-#include "VFS/vfs.h"
-#include "VFS/vfs_file_raii.h"
+#include
+#include
#ifdef JA2
#include "video.h"
@@ -53,45 +53,45 @@
//-Flags-and-Symbols---------------------------------------------------------------
-#define SMK_NUM_FLICS 4 // Maximum number of flics open
+#define SMK_NUM_FLICS 4 // Maximum number of flics open
// SMKFLIC uiFlags
#define SMK_FLIC_OPEN 0x00000001 // Flic is open
-#define SMK_FLIC_PLAYING 0x00000002 // Flic is playing
+#define SMK_FLIC_PLAYING 0x00000002 // Flic is playing
#define SMK_FLIC_LOOP 0x00000004 // Play flic in a loop
-#define SMK_FLIC_AUTOCLOSE 0x00000008 // Close when done
+#define SMK_FLIC_AUTOCLOSE 0x00000008 // Close when done
//-Globals-------------------------------------------------------------------------
SMKFLIC SmkList[SMK_NUM_FLICS];
-HWND hDisplayWindow=0;
-UINT32 uiDisplayHeight, uiDisplayWidth;
-BOOLEAN fSuspendFlics=FALSE;
-UINT32 uiFlicsPlaying=0;
-UINT32 guiSmackPixelFormat=SMACKBUFFER565;
+HWND hDisplayWindow = 0;
+UINT32 uiDisplayHeight, uiDisplayWidth;
+BOOLEAN fSuspendFlics = FALSE;
+UINT32 uiFlicsPlaying = 0;
+UINT32 guiSmackPixelFormat = SMACKBUFFER565;
LPDIRECTDRAWSURFACE lpVideoPlayback=NULL;
LPDIRECTDRAWSURFACE2 lpVideoPlayback2=NULL;
//-Function-Prototypes-------------------------------------------------------------
-void SmkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight);
-void SmkShutdown(void);
+void SmkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight);
+void SmkShutdown(void);
SMKFLIC *SmkPlayFlic(CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, BOOLEAN fAutoClose);
BOOLEAN SmkPollFlics(void);
SMKFLIC *SmkOpenFlic(CHAR8 *cFilename);
-void SmkSetBlitPosition(SMKFLIC *pSmack, UINT32 uiLeft, UINT32 uiTop);
-void SmkCloseFlic(SMKFLIC *pSmack);
+void SmkSetBlitPosition(SMKFLIC *pSmack, UINT32 uiLeft, UINT32 uiTop);
+void SmkCloseFlic(SMKFLIC *pSmack);
SMKFLIC *SmkGetFreeFlic(void);
-void SmkSetupVideo(void);
-void SmkShutdownVideo(void);
+void SmkSetupVideo(void);
+void SmkShutdownVideo(void);
BOOLEAN SmkPollFlics(void)
{
-UINT32 uiCount;
-BOOLEAN fFlicStatus=FALSE;
-DDSURFACEDESC SurfaceDescription;
+ UINT32 uiCount;
+ BOOLEAN fFlicStatus = FALSE;
+ DDSURFACEDESC SurfaceDescription;
for(uiCount=0; uiCount < SMK_NUM_FLICS; uiCount++)
{
@@ -103,7 +103,7 @@ DDSURFACEDESC SurfaceDescription;
if(!SmackWait(SmkList[uiCount].SmackHandle))
{
DDLockSurface(SmkList[uiCount].lpDDS, NULL, &SurfaceDescription, 0, NULL);
- SmackToBuffer(SmkList[uiCount].SmackHandle,SmkList[uiCount].uiLeft,
+ SmackToBuffer(SmkList[uiCount].SmackHandle,SmkList[uiCount].uiLeft,
SmkList[uiCount].uiTop,
SurfaceDescription.lPitch,
SmkList[uiCount].SmackHandle->Height,
@@ -124,7 +124,9 @@ DDSURFACEDESC SurfaceDescription;
SmkCloseFlic(&SmkList[uiCount]);
}
else
+ {
SmackNextFrame(SmkList[uiCount].SmackHandle);
+ }
}
}
}
@@ -138,21 +140,19 @@ DDSURFACEDESC SurfaceDescription;
// Lesh changed this function only -----------------------------
void SmkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight)
{
- void *pSoundDriver = NULL;
-
// Wipe the flic list clean
memset(SmkList, 0, sizeof(SMKFLIC)*SMK_NUM_FLICS);
// Set playback window properties
- hDisplayWindow=hWindow;
- uiDisplayWidth=uiWidth;
- uiDisplayHeight=uiHeight;
+ hDisplayWindow = hWindow;
+ uiDisplayWidth = uiWidth;
+ uiDisplayHeight= uiHeight;
// Use MMX acceleration, if available
SmackUseMMX(1);
//Get the sound Driver handle
- pSoundDriver = SoundGetDriverHandle();
+ void* pSoundDriver = SoundGetDriverHandle();
//if we got the sound handle, use sound during the intro
if( pSoundDriver )
@@ -161,7 +161,7 @@ void SmkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight)
void SmkShutdown(void)
{
-UINT32 uiCount;
+ UINT32 uiCount;
// Close and deallocate any open flics
for(uiCount=0; uiCount < SMK_NUM_FLICS; uiCount++)
@@ -171,9 +171,9 @@ UINT32 uiCount;
}
}
-SMKFLIC *SmkPlayFlic(CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, BOOLEAN fClose)
+SMKFLIC *SmkPlayFlic(const CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, BOOLEAN fClose)
{
-SMKFLIC *pSmack;
+ SMKFLIC *pSmack;
// Open the flic
if((pSmack=SmkOpenFlic(cFilename))==NULL)
@@ -190,11 +190,10 @@ SMKFLIC *pSmack;
return(pSmack);
}
-SMKFLIC *SmkOpenFlic(CHAR8 *cFilename)
+SMKFLIC *SmkOpenFlic(const CHAR8 *cFilename)
{
SMKFLIC *pSmack;
-
// Get an available flic slot from the list
if(!(pSmack=SmkGetFreeFlic()))
{
@@ -228,18 +227,16 @@ SMKFLIC *SmkOpenFlic(CHAR8 *cFilename)
return NULL;
}
vfs::COpenReadFile rfile(introname);
- vfs::size_t size = rfile.file().getSize();
+ vfs::size_t size = rfile->getSize();
std::vector data(size);
- rfile.file().read(&data[0],size);
+ rfile->read(&data[0],size);
vfs::COpenWriteFile wfile(tempfile,true);
- wfile.file().write(&data[0],size);
+ wfile->write(&data[0],size);
}
- catch(CBasicException& ex)
+ catch(std::exception& ex)
{
- BuildString bs;
- bs.add(L"Intro file \"").add(filename()).add(L"\" could not be extracted");
- RETHROWEXCEPTION(bs.get(), &ex);
+ SGP_RETHROW(_BS(L"Intro file \"") << filename << L"\" could not be extracted" << _BS::wget, ex);
}
}
#endif
@@ -258,14 +255,14 @@ SMKFLIC *SmkOpenFlic(CHAR8 *cFilename)
try
{
vfs::COpenWriteFile wfile(tempfile);
- if(!wfile.file()._getRealPath(tempfilename))
+ if(!wfile->_getRealPath(tempfilename))
{
return NULL;
}
}
- catch(CBasicException& ex)
+ catch(std::exception& ex)
{
- RETHROWEXCEPTION(L"Temporary intro file could not be read", &ex);
+ SGP_RETHROW(L"Temporary intro file could not be read", ex);
}
if(!(pSmack->SmackHandle=SmackOpen(tempfilename.to_string().c_str(), SMACKTRACKS, SMACKAUTOEXTRA)))
#endif
@@ -310,7 +307,7 @@ void SmkCloseFlic(SMKFLIC *pSmack)
SMKFLIC *SmkGetFreeFlic(void)
{
-UINT32 uiCount;
+ UINT32 uiCount;
for(uiCount=0; uiCount < SMK_NUM_FLICS; uiCount++)
if(!(SmkList[uiCount].uiFlags & SMK_FLIC_OPEN))
@@ -321,26 +318,24 @@ UINT32 uiCount;
void SmkSetupVideo(void)
{
- DDSURFACEDESC SurfaceDescription;
- HRESULT ReturnCode;
- UINT16 usRed, usGreen, usBlue;
- HVSURFACE hVSurface;
-
// DEF:
-// lpVideoPlayback2=CinematicModeOn();
+// lpVideoPlayback2 = CinematicModeOn();
+ HVSURFACE hVSurface;
GetVideoSurface( &hVSurface, FRAME_BUFFER );
lpVideoPlayback2 = GetVideoSurfaceDDSurface( hVSurface );
+ DDSURFACEDESC SurfaceDescription;
ZEROMEM(SurfaceDescription);
SurfaceDescription.dwSize = sizeof (DDSURFACEDESC);
- ReturnCode = IDirectDrawSurface2_GetSurfaceDesc ( lpVideoPlayback2, &SurfaceDescription );
+ HRESULT ReturnCode = IDirectDrawSurface2_GetSurfaceDesc ( lpVideoPlayback2, &SurfaceDescription );
if (ReturnCode != DD_OK)
{
- DirectXAttempt ( ReturnCode, __LINE__, __FILE__ );
- return;
+ DirectXAttempt ( ReturnCode, __LINE__, __FILE__ );
+ return;
}
+ UINT16 usRed, usGreen, usBlue;
usRed = (UINT16) SurfaceDescription.ddpfPixelFormat.dwRBitMask;
usGreen = (UINT16) SurfaceDescription.ddpfPixelFormat.dwGBitMask;
usBlue = (UINT16) SurfaceDescription.ddpfPixelFormat.dwBBitMask;
diff --git a/Utils/Cinematics.h b/Utils/Cinematics.h
index e2f969c2..52be5601 100644
--- a/Utils/Cinematics.h
+++ b/Utils/Cinematics.h
@@ -3,31 +3,31 @@
#include "smack.h"
-typedef struct {
-
- CHAR8 *cFilename;
-// HFILE hFileHandle;
- HWFILE hFileHandle;
- Smack *SmackHandle;
- SmackBuf *SmackBuffer;
- UINT32 uiFlags;
+struct SMKFLIC
+{
+ const CHAR8 *cFilename;
+// HFILE hFileHandle;
+ HWFILE hFileHandle;
+ Smack *SmackHandle;
+ SmackBuf *SmackBuffer;
+ UINT32 uiFlags;
LPDIRECTDRAWSURFACE2 lpDDS;
- HWND hWindow;
- UINT32 uiFrame;
- UINT32 uiLeft, uiTop;
-// LPDIRECTDRAW2 lpDD;
-// UINT32 uiNumFrames;
-// UINT8 *pAudioData;
-// UINT8 *pCueData;
- } SMKFLIC;
+ HWND hWindow;
+ UINT32 uiFrame;
+ UINT32 uiLeft, uiTop;
+// LPDIRECTDRAW2 lpDD;
+// UINT32 uiNumFrames;
+// UINT8 *pAudioData;
+// UINT8 *pCueData;
+};
-void SmkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight);
-void SmkShutdown(void);
-SMKFLIC *SmkPlayFlic(CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, BOOLEAN fAutoClose);
+void SmkInitialize(HWND hWindow, UINT32 uiWidth, UINT32 uiHeight);
+void SmkShutdown(void);
+SMKFLIC *SmkPlayFlic(const CHAR8 *cFilename, UINT32 uiLeft, UINT32 uiTop, BOOLEAN fAutoClose);
BOOLEAN SmkPollFlics(void);
-SMKFLIC *SmkOpenFlic(CHAR8 *cFilename);
-void SmkSetBlitPosition(SMKFLIC *pSmack, UINT32 uiLeft, UINT32 uiTop);
-void SmkCloseFlic(SMKFLIC *pSmack);
+SMKFLIC *SmkOpenFlic(const CHAR8 *cFilename);
+void SmkSetBlitPosition(SMKFLIC *pSmack, UINT32 uiLeft, UINT32 uiTop);
+void SmkCloseFlic(SMKFLIC *pSmack);
SMKFLIC *SmkGetFreeFlic(void);
/*
diff --git a/Utils/Cursors.cpp b/Utils/Cursors.cpp
index c1c574de..2da6039f 100644
--- a/Utils/Cursors.cpp
+++ b/Utils/Cursors.cpp
@@ -1189,6 +1189,16 @@ CursorData CursorDatabase[] =
void InitCursors( )
{
+ //CHRISL: NCTH uses a completely different cursor so if we're in NCTH mode, we want to use different graphics
+ if(UsingNewCTHSystem() == true){
+ strncpy((char *)CursorFileDatabase[2].ubFilename,"CURSORS\\cur_tagr_ncth.sti",MAX_FILENAME_LEN);
+ strncpy((char *)CursorFileDatabase[3].ubFilename,"CURSORS\\targblak_ncth.sti",MAX_FILENAME_LEN);
+ strncpy((char *)CursorFileDatabase[5].ubFilename,"CURSORS\\cur_rbst_ncth.sti",MAX_FILENAME_LEN);
+ strncpy((char *)CursorFileDatabase[6].ubFilename,"CURSORS\\burstblk_ncth.sti",MAX_FILENAME_LEN);
+ strncpy((char *)CursorFileDatabase[7].ubFilename,"CURSORS\\cur_tr_ncth.sti",MAX_FILENAME_LEN);
+ strncpy((char *)CursorFileDatabase[8].ubFilename,"CURSORS\\cur_trw_ncth.sti",MAX_FILENAME_LEN);
+ strncpy((char *)CursorFileDatabase[35].ubFilename,"CURSORS\\cur_try_ncth.sti",MAX_FILENAME_LEN);
+ }
InitCursorDatabase( CursorFileDatabase, CursorDatabase, NUM_CURSOR_FILES );
SetMouseBltHook( (MOUSEBLT_HOOK)BltJA2CursorData );
@@ -1244,8 +1254,99 @@ extern INT16 gsCurMouseOffsetY;
extern UINT16 gsCurMouseHeight;
extern UINT16 gsCurMouseWidth;*/
+void DrawMouseGraphicsNCTH( )
+{
+ //////////////////////////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: This entire cursor drawing function is now OBSOLETE in NCTH.
+ // Instead of drawing the targeting cursor on limited cursor space (in the MOUSEBUFFER),
+ // I draw the new indicator directly on the FRAMEBUFFER through a function in
+ // Tactical\Interface.CPP. It bypasses the cursor system entirely in order to create
+ // a pseudo-cursor that can potentially be as large as the viewport (or larger). That
+ // is unfortunately not doable with the cursor system, so this code is now commented out.
+
+ // HEADROCK (HAM): Made several changes here to allow multi-shot CtH display for bursts.
+ UINT16 * ptrBuf;
+ UINT32 uiPitch;
+ UINT32 cnt, i;
+ UINT32 actualPct = __min(gbCtH[0],99);
+ UINT16 usCBorderTop = Get16BPPColor( FROMRGB( 155, 155, 155 ) );
+ UINT16 usCBorderBottom = Get16BPPColor( FROMRGB( 120, 120, 120 ) );
+ UINT16 usCBar = Get16BPPColor( FROMRGB( 255, 255-255*actualPct/99, 0 ) );
+ UINT16 usCBack = Get16BPPColor( FROMRGB( 155, 155-155*actualPct/99, 0 ) );
+ UINT16 usCBar2 = Get16BPPColor( FROMRGB( 180, 140-140*actualPct/99, 0 ) );
+ UINT16 usCBack2 = Get16BPPColor( FROMRGB( 110, 100-100*actualPct/99, 0 ) );
+ UINT32 barLength = __min(35,gsCurMouseWidth);
+ //UINT32 barY = gsCurMouseOffsetY-__min(35,gsCurMouseHeight)/2;
+ UINT32 barY;
+
+ if(gfUICtHBar)
+ {
+ // HEADROCK HAM B1/2/2.6:
+ // This causes the function to display two CTH bars for autofire - the CTH of the first bullet,
+ // and the CTH of the last bullet in the volley, stored in gbCtH[0] and [1] respectively.
+ if ( gbCtHAutoFire && (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 3) )
+ gbCtHBurstCount = 2;
+ else if ( gbCtHAutoFire )
+ gbCtHBurstCount = 0;
+
+
+ // Sets the initial offsets of the bars. Burst and Autofire will display them higher above the
+ // cursor, to avoid obscuring the target or other data.
+ if (gbCtHBurstCount > 1 && !gbCtHAutoFire && (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 2) )
+ barY = gsCurMouseOffsetY-__min(55,gsCurMouseHeight)/2;
+ else if (gbCtHBurstCount && gbCtHAutoFire && (gGameExternalOptions.ubNewCTHBars == 1 || gGameExternalOptions.ubNewCTHBars == 3) )
+ barY = gsCurMouseOffsetY-__min(55,gsCurMouseHeight)/2;
+ else
+ barY = gsCurMouseOffsetY-__min(35,gsCurMouseHeight)/2;
+
+ for (i=0; i>= 1;
+
+ for(cnt = gsCurMouseOffsetX+barLength/2;cnt > gsCurMouseOffsetX-barLength/2+1;cnt--)
+ {
+ ptrBuf[cnt-1 + uiPitch*(3+barY)] = usCBorderBottom;
+ ptrBuf[cnt-1 + uiPitch*barY] = usCBorderTop;
+ }
+
+ ptrBuf[gsCurMouseOffsetX+barLength/2 + uiPitch*(1+barY)] = usCBorderBottom;
+ ptrBuf[gsCurMouseOffsetX-barLength/2 + uiPitch*(1+barY)] = usCBorderTop;
+
+ ptrBuf[gsCurMouseOffsetX+barLength/2 + uiPitch*(2+barY)] = usCBorderBottom;
+ ptrBuf[gsCurMouseOffsetX-barLength/2 + uiPitch*(2+barY)] = usCBorderTop;
+
+
+ for(cnt = 0;cnt < (barLength-2)*actualPct/99;cnt++)
+ {
+ ptrBuf[cnt + gsCurMouseOffsetX-barLength/2+1 + uiPitch*(barY+2)] = usCBar2;
+ ptrBuf[cnt + gsCurMouseOffsetX-barLength/2+1 + uiPitch*(barY+1)] = usCBar;
+ }
+
+ for(cnt = (barLength-2)*actualPct/99;cnt < (barLength-2);cnt++)
+ {
+ ptrBuf[cnt + gsCurMouseOffsetX-barLength/2+1 + uiPitch*(barY+2)] = usCBack2;
+ ptrBuf[cnt + gsCurMouseOffsetX-barLength/2+1 + uiPitch*(barY+1)] = usCBack;
+ }
+
+
+ UnlockMouseBuffer();
+ if (gbCtHBurstCount>1)
+ barY = barY+5;
+ }
+ barY = gsCurMouseOffsetY-__min(35,gsCurMouseHeight)/2;
+ }
+
+}
+
void DrawMouseGraphics( )
{
+ if(UsingNewCTHSystem() == true){
+ DrawMouseGraphicsNCTH();
+ return;
+ }
// HEADROCK (HAM): Made several changes here to allow multi-shot CtH display for bursts.
UINT16 * ptrBuf;
UINT32 uiPitch;
@@ -1359,7 +1460,7 @@ void DrawMouseText( )
}
- if ( gfUIAutofireBulletCount )
+ if ( UsingNewCTHSystem() == false && gfUIAutofireBulletCount )
{
// Set dest for gprintf to be different
SetFontDestBuffer( MOUSE_BUFFER , 0, 0, 64, 64, FALSE );
@@ -1436,7 +1537,10 @@ void DrawMouseText( )
//if ( ( ( gTacticalStatus.uiFlags & TURNBASED ) && ( gTacticalStatus.uiFlags & INCOMBAT ) ) )
{
- if ( gfUIDisplayActionPoints )
+ // HEADROCK HAM 4: Added condition - the AP cost will no longer be displayed in the center when
+ // aiming a weapon. It will instead by displayed on the new NCTH Indicator.
+ if ( (UsingNewCTHSystem() == false && gfUIDisplayActionPoints) ||
+ (UsingNewCTHSystem() == true && gfUIDisplayActionPoints && !gfUICtHBar) )
{
if ( gfUIDisplayActionPointsInvalid )
{
diff --git a/Utils/Debug Control.cpp b/Utils/Debug Control.cpp
index 36458839..3b0e8771 100644
--- a/Utils/Debug Control.cpp
+++ b/Utils/Debug Control.cpp
@@ -6,8 +6,7 @@
#include "stdio.h"
#endif
-#include "VFS/vfs.h"
-#include "VFS/Tools/Log.h"
+#include "sgp_logger.h"
#ifdef _ANIMSUBSYSTEM_DEBUG
@@ -57,6 +56,13 @@ void AiDbgMessage( CHAR8 *strMessage)
#endif
+static struct LiveLog {
+ sgp::Logger_ID id;
+ LiveLog() {
+ id = sgp::Logger::instance().createLogger();
+ sgp::Logger::instance().connectFile(id, L"LiveLog.txt", false, sgp::Logger::FLUSH_ON_ENDL);
+ };
+} s_LiveLog;
void LiveMessage( CHAR8 *strMessage)
{
@@ -69,8 +75,7 @@ void LiveMessage( CHAR8 *strMessage)
fclose(OutFile);
}
#else
- static CLog& liveMsg = *CLog::create(L"LiveLog.txt",true);
- liveMsg << strMessage << CLog::ENDL;
+ SGP_LOG(s_LiveLog.id, strMessage);
#endif
}
void MPDebugMsg( CHAR8 *strMessage)
@@ -84,7 +89,7 @@ void MPDebugMsg( CHAR8 *strMessage)
fclose(OutFile);
}
#else
- static CLog& mpMsg = *CLog::create(L"MPDebug.txt", true);
- mpMsg << strMessage << CLog::ENDL;
+ static vfs::Log& mpMsg = *vfs::Log::create(L"MPDebug.txt", true);
+ mpMsg << strMessage << vfs::Log::endl;
#endif
}
diff --git a/Utils/ExportStrings.cpp b/Utils/ExportStrings.cpp
new file mode 100644
index 00000000..666f5a6c
--- /dev/null
+++ b/Utils/ExportStrings.cpp
@@ -0,0 +1,701 @@
+#include "ExportStrings.h"
+#include "LocalizedStrings.h"
+#include "Map Screen Interface.h"
+#include "personnel.h"
+#include "soldier profile type.h"
+#include "interface.h"
+#include "Keys.h"
+#include "Merc Contract.h"
+#include "Campaign Types.h"
+#include "Finances.h"
+#include "Laptop.h"
+
+#include
+#include
+#include
+#include
+
+namespace Loc
+{
+ bool Translate(vfs::String::char_t* str, int len, Language lang);
+
+ void ExportMercBio();
+ void ExportAIMHistory();
+ void ExportAIMPolicy();
+ void ExportAlumniName();
+ void ExportDialogues();
+ void ExportNPCDialogues();
+};
+
+//////////////////////////////////////////////////////////
+
+//#define GERMAN
+#include "Text.h"
+namespace Loc
+{
+#ifdef CHINESE
+# include "_ChineseText.cpp"
+ static Loc::Language gs_Lang = Loc::Chinese;
+#endif
+#ifdef DUTCH
+# include "_DutchText.cpp"
+ static Loc::Language gs_Lang = Loc::Dutch;
+#endif
+#ifdef ENGLISH
+# include "_EnglishText.cpp"
+ static Loc::Language gs_Lang = Loc::English;
+#endif
+#ifdef FRENCH
+# include "_FrenchText.cpp"
+ static Loc::Language gs_Lang = Loc::French;
+#endif
+#ifdef GERMAN
+# include "_GermanText.cpp"
+ static Loc::Language gs_Lang = Loc::German;
+#endif
+#ifdef ITALIAN
+# include "_ItalianText.cpp"
+ static Loc::Language gs_Lang = Loc::Italian;
+#endif
+#ifdef POLISH
+# include "_PolishText.cpp"
+ static Loc::Language gs_Lang = Loc::Polish;
+#endif
+#ifdef RUSSIAN
+# include "_RussianText.cpp"
+ static Loc::Language gs_Lang = Loc::Russian;
+#endif
+#ifdef TAIWANESE
+# include "_TaiwaneseText.cpp"
+ static Loc::Language gs_Lang = Loc::Taiwanese;
+#endif
+}
+
+#include "Assignments.h"
+#include "History.h"
+
+template
+void ExportSection(vfs::PropertyContainer& props, const vfs::String::char_t* section_name, T* strings, int min, int max)
+{
+ for(int i = min; i < max; ++i)
+ {
+ vfs::String str(strings[i]);
+ //Loc::Translate(&str.r_wcs()[0],str.length(), gs_Lang);
+ if(!str.empty())
+ {
+ props.setStringProperty(section_name, vfs::toString(i), str);
+ }
+ }
+}
+
+template<>
+void ExportSection(vfs::PropertyContainer& props, const vfs::String::char_t* section_name, wchar_t* strings, int min, int max)
+{
+ ExportSection(props,section_name, &strings, min, max);
+}
+
+
+bool Loc::ExportStrings()
+{
+ vfs::PropertyContainer::TagMap tmap;
+ //tmap.Container(L"LocalizedStrings");
+ //tmap.Section(L"Topic");
+ //tmap.SectionID(L"name");
+ //tmap.Key(L"msg");
+ //tmap.KeyID(L"index");
+
+ vfs::PropertyContainer props;
+
+ //not_required ExportSection(props, L"Ja2Credits", Loc::pCreditsJA2113, 0, 7);
+ ExportSection(props, L"WeaponType", Loc::WeaponType, 0, MAXITEMS);
+ ExportSection(props, L"TeamTurn", Loc::TeamTurnString, 0, 10);
+ ExportSection(props, L"Message", Loc::Message, 0, TEXT_NUM_STR_MESSAGE);
+ ExportSection(props, L"TownNames", Loc::pTownNames, 0, MAX_TOWNS);
+ ExportSection(props, L"Time", Loc::sTimeStrings, 0, 6);
+ ExportSection(props, L"Assignment", Loc::pAssignmentStrings, 0, NUM_ASSIGNMENTS);
+ ExportSection(props, L"PersonnelAssignment", Loc::pPersonnelAssignmentStrings, 0, NUM_ASSIGNMENTS);
+ ExportSection(props, L"LongAssignment", Loc::pLongAssignmentStrings, 0, NUM_ASSIGNMENTS);
+ ExportSection(props, L"Militia", Loc::pMilitiaString, 0, 3);
+
+ ExportSection(props, L"MilitiaButton", Loc::pMilitiaButtonString, 0, 2);
+ ExportSection(props, L"Condition", Loc::pConditionStrings, 0, 9);
+ ExportSection(props, L"EpcMenu", Loc::pEpcMenuStrings, 0, MAX_EPC_MENU_STRING_COUNT);
+ ExportSection(props, L"Contract", Loc::pContractStrings, 0, MAX_CONTRACT_MENU_STRING_COUNT);
+ ExportSection(props, L"POW", Loc::pPOWStrings, 0, 2);
+ ExportSection(props, L"InvPanelTitle", Loc::pInvPanelTitleStrings, 0, 5);
+ ExportSection(props, L"LongAttribute", Loc::pLongAttributeStrings, 0, 10);
+ ExportSection(props, L"ShortAttribute", Loc::pShortAttributeStrings, 0, 10);
+ ExportSection(props, L"UpperLeftMapScreen", Loc::pUpperLeftMapScreenStrings, 0, 6);
+ ExportSection(props, L"Training", Loc::pTrainingStrings, 0, 4);
+
+ ExportSection(props, L"GuardMenu", Loc::pGuardMenuStrings, 0, 10);
+ ExportSection(props, L"OtherGuardMenu", Loc::pOtherGuardMenuStrings, 0, 10);
+ ExportSection(props, L"AssignMenu", Loc::pAssignMenuStrings, 0, MAX_ASSIGN_STRING_COUNT);
+ ExportSection(props, L"MilitiaControlMenu", Loc::pMilitiaControlMenuStrings, 0, MAX_MILCON_STRING_COUNT);
+ ExportSection(props, L"RemoveMerc", Loc::pRemoveMercStrings, 0, MAX_REMOVE_MERC_COUNT);
+ ExportSection(props, L"AttributeMenu", Loc::pAttributeMenuStrings, 0, MAX_ATTRIBUTE_STRING_COUNT);
+ ExportSection(props, L"TrainingMenu", Loc::pTrainingMenuStrings, 0, MAX_TRAIN_STRING_COUNT);
+ ExportSection(props, L"SquadMenu", Loc::pSquadMenuStrings, 0, MAX_SQUAD_MENU_STRING_COUNT);
+ ExportSection(props, L"PersonnelTitle", Loc::pPersonnelTitle, 0, 1);
+ ExportSection(props, L"PersonnelScreen", Loc::pPersonnelScreenStrings, 0, TEXT_NUM_PRSNL);
+
+ ExportSection(props, L"MercSkill", Loc::gzMercSkillText, 0, NUM_SKILLTRAITS_OT);
+ ExportSection(props, L"TacticalPopupButton", Loc::pTacticalPopupButtonStrings, 0, NUM_ICONS);
+ ExportSection(props, L"DoorTrap", Loc::pDoorTrapStrings, 0, NUM_DOOR_TRAPS);
+ ExportSection(props, L"ContractExtend", Loc::pContractExtendStrings, 0, NUM_CONTRACT_EXTEND);
+ ExportSection(props, L"MapScreenMouseRegionHelp", Loc::pMapScreenMouseRegionHelpText, 0, 6);
+ ExportSection(props, L"NoiseVol", Loc::pNoiseVolStr, 0, 4);
+ ExportSection(props, L"NoiseType", Loc::pNoiseTypeStr, 0, 12);
+ ExportSection(props, L"Direction", Loc::pDirectionStr, 0, 8);
+ ExportSection(props, L"LandType", Loc::pLandTypeStrings, 0, NUM_TRAVTERRAIN_TYPES);
+ ExportSection(props, L"Strategic", Loc::gpStrategicString, 0, TEXT_NUM_STRATEGIC_TEXT);
+
+ ExportSection(props, L"GameClock", Loc::gpGameClockString, 0, TEXT_NUM_GAMECLOCK);
+ ExportSection(props, L"KeyDescription", Loc::sKeyDescriptionStrings, 0, 2);
+ ExportSection(props, L"WeaponStatsDesc", Loc::gWeaponStatsDesc, 0, 17);
+ ExportSection(props, L"WeaponStatsFasthelp", Loc::gzWeaponStatsFasthelp, 0, 29);
+ ExportSection(props, L"WeaponStatsFasthelpTactical",Loc::gzWeaponStatsFasthelpTactical, 0, 29);
+ ExportSection(props, L"AmmoStatsFasthelp", Loc::gzAmmoStatsFasthelp, 0, 20);
+ ExportSection(props, L"ArmorStatsFasthelp", Loc::gzArmorStatsFasthelp, 0, 20);
+ ExportSection(props, L"ExplosiveStatsFasthelp", Loc::gzExplosiveStatsFasthelp, 0, 20);
+ ExportSection(props, L"MiscItemStatsFasthelp", Loc::gzMiscItemStatsFasthelp, 0, 34);
+ ExportSection(props, L"MoneyStatsDesc", Loc::gMoneyStatsDesc, 0, TEXT_NUM_MONEY_DESC);
+
+ ExportSection(props, L"Health", Loc::zHealthStr, 0, 7);
+ ExportSection(props, L"MoneyAmounts", Loc::gzMoneyAmounts, 0, 6);
+ ExportSection(props, L"ProsLabel", Loc::gzProsLabel, 0, 1);
+ ExportSection(props, L"ConsLabel", Loc::gzConsLabel, 0, 1);
+ ExportSection(props, L"TalkMenu", Loc::zTalkMenuStrings, 0, 6);
+ ExportSection(props, L"Dealer", Loc::zDealerStrings, 0, 4);
+ ExportSection(props, L"DialogActions", Loc::zDialogActions, 0, 1);
+ ExportSection(props, L"Vehicle", Loc::pVehicleStrings, 0, 6);
+ ExportSection(props, L"ShortVehicle", Loc::pShortVehicleStrings, 0, 6);
+ ExportSection(props, L"VehicleName", Loc::zVehicleName, 0, 6);
+
+ ExportSection(props, L"Tactical", Loc::TacticalStr, 0, TEXT_NUM_TACTICAL_STR);
+ ExportSection(props, L"ExitingSectorHelp", Loc::pExitingSectorHelpText, 0, TEXT_NUM_EXIT_GUI);
+ ExportSection(props, L"Repair", Loc::pRepairStrings, 0, 4);
+ ExportSection(props, L"PreStatBuild", Loc::sPreStatBuildString, 0, 6);
+ ExportSection(props, L"StatGain", Loc::sStatGainStrings, 0, 11);
+ ExportSection(props, L"HelicopterEta", Loc::pHelicopterEtaStrings, 0, 10);
+ ExportSection(props, L"MapLevel", Loc::sMapLevelString, 0, 1);
+ ExportSection(props, L"Loyal", Loc::gsLoyalString, 0, 1);
+ ExportSection(props, L"Underground", Loc::gsUndergroundString, 0, 1);
+ ExportSection(props, L"TimeStings", Loc::gsTimeStrings, 0, 1);
+
+ ExportSection(props, L"Facilities", Loc::sFacilitiesStrings, 0, 7);
+ ExportSection(props, L"MapPopUpInventory", Loc::pMapPopUpInventoryText, 0, 2);
+ ExportSection(props, L"TownInfo", Loc::pwTownInfoStrings, 0, 12);
+ ExportSection(props, L"Mine", Loc::pwMineStrings, 0, 14);
+ ExportSection(props, L"MiscSector", Loc::pwMiscSectorStrings, 0, 7);
+ ExportSection(props, L"MapInventoryError", Loc::pMapInventoryErrorString, 0, 7);
+ ExportSection(props, L"MapInventory", Loc::pMapInventoryStrings, 0, 2);
+ ExportSection(props, L"MapScreenFastHelp", Loc::pMapScreenFastHelpTextList, 0, 10);
+ ExportSection(props, L"MovementMenu", Loc::pMovementMenuStrings, 0, 4);
+ ExportSection(props, L"UpdateMerc", Loc::pUpdateMercStrings, 0, 6);
+
+ ExportSection(props, L"MapScreenBorderButtonHelp", Loc::pMapScreenBorderButtonHelpText,0, 6);
+ ExportSection(props, L"MapScreenBottomFastHelp", Loc::pMapScreenBottomFastHelp, 0, 8);
+ ExportSection(props, L"MapScreenBottom", Loc::pMapScreenBottomText, 0, 1);
+ ExportSection(props, L"MercDead", Loc::pMercDeadString, 0, 1);
+ ExportSection(props, L"Day", Loc::pDayStrings, 0, 1);
+ ExportSection(props, L"SenderName", Loc::pSenderNameList, 0, 51);
+ ExportSection(props, L"Traverse", Loc::pTraverseStrings, 0, 2);
+ ExportSection(props, L"NewMail", Loc::pNewMailStrings, 0, 1);
+ ExportSection(props, L"DeleteMail", Loc::pDeleteMailStrings, 0, 2);
+ ExportSection(props, L"EmailHeader", Loc::pEmailHeaders, 0, 3);
+
+ ExportSection(props, L"EmailTitle", Loc::pEmailTitleText, 0, 1);
+ ExportSection(props, L"FinanceTitle", Loc::pFinanceTitle, 0, 1);
+ ExportSection(props, L"FinanceSummary", Loc::pFinanceSummary, 0, 12);
+ ExportSection(props, L"FinanceHeader", Loc::pFinanceHeaders, 0, 7);
+ ExportSection(props, L"Transaction", Loc::pTransactionText, 0, TEXT_NUM_FINCANCES);
+ ExportSection(props, L"TransactionAlternate", Loc::pTransactionAlternateText, 0, 4);
+ ExportSection(props, L"Skyrider", Loc::pSkyriderText, 0, 7);
+ ExportSection(props, L"Moral", Loc::pMoralStrings, 0, 6);
+ ExportSection(props, L"LeftEquipment", Loc::pLeftEquipmentString, 0, 2);
+ ExportSection(props, L"MapScreenStatus", Loc::pMapScreenStatusStrings, 0, 5);
+
+ ExportSection(props, L"MapScreenPrevNextCharButtonHelp", Loc::pMapScreenPrevNextCharButtonHelpText, 0, 2);
+ ExportSection(props, L"Eta", Loc::pEtaString, 0, 1);
+ ExportSection(props, L"TrashItem", Loc::pTrashItemText, 0, 2);
+ ExportSection(props, L"MapError", Loc::pMapErrorString, 0, 50);
+ ExportSection(props, L"MapPlot", Loc::pMapPlotStrings, 0, 5);
+ ExportSection(props, L"Bullseye", Loc::pBullseyeStrings, 0, 5);
+ ExportSection(props, L"MiscMapScreenMouseRegionHelp", Loc::pMiscMapScreenMouseRegionHelpText, 0, 3);
+ ExportSection(props, L"MercHeLeave", Loc::pMercHeLeaveString, 0, 5);
+ ExportSection(props, L"MercSheLeave", Loc::pMercSheLeaveString, 0, 5);
+ ExportSection(props, L"MercContractOver", Loc::pMercContractOverStrings, 0, 5);
+
+ ExportSection(props, L"ImpPopUp", Loc::pImpPopUpStrings, 0, 12);
+ ExportSection(props, L"ImpButton", Loc::pImpButtonText, 0, 26);
+ ExportSection(props, L"ExtraIMP", Loc::pExtraIMPStrings, 0, 4);
+ ExportSection(props, L"FilesTitle", Loc::pFilesTitle, 0, 1);
+ ExportSection(props, L"FilesSender", Loc::pFilesSenderList, 0, 7);
+ ExportSection(props, L"HistoryTitle", Loc::pHistoryTitle, 0, 1);
+ ExportSection(props, L"HistoryHeader", Loc::pHistoryHeaders, 0, 5);
+ ExportSection(props, L"History", Loc::pHistoryStrings, 0, TEXT_NUM_HISTORY);
+ ExportSection(props, L"HistoryLocation", Loc::pHistoryLocations, 0, 1);
+ ExportSection(props, L"LaptopIcon", Loc::pLaptopIcons, 0, 8);
+
+ ExportSection(props, L"BookMark", Loc::pBookMarkStrings, 0, TEXT_NUM_LAPTOP_BOOKMARKS);
+ ExportSection(props, L"BookmarkTitle", Loc::pBookmarkTitle, 0, 2);
+ ExportSection(props, L"Download", Loc::pDownloadString, 0, 2);
+ ExportSection(props, L"AtmSideButton", Loc::gsAtmSideButtonText, 0, 5);
+ ExportSection(props, L"AtmStartButton", Loc::gsAtmStartButtonText, 0, 4);
+ ExportSection(props, L"ATM", Loc::sATMText, 0, 6);
+ ExportSection(props, L"Error", Loc::pErrorStrings, 0, 5);
+ ExportSection(props, L"Personnel", Loc::pPersonnelString, 0, 1);
+ ExportSection(props, L"WebTitle", Loc::pWebTitle, 0, 1);
+ ExportSection(props, L"WebPagesTitle", Loc::pWebPagesTitles, 0, 36);
+
+ ExportSection(props, L"ShowBookmark", Loc::pShowBookmarkString, 0, 2);
+ ExportSection(props, L"LaptopTitle", Loc::pLaptopTitles, 0, 5);
+ ExportSection(props, L"PersonnelDepartedState", Loc::pPersonnelDepartedStateStrings, 0, TEXT_NUM_DEPARTED);
+ ExportSection(props, L"PersonelTeam", Loc::pPersonelTeamStrings, 0, 8);
+ ExportSection(props, L"PersonnelCurrentTeamStats", Loc::pPersonnelCurrentTeamStatsStrings, 0, 3);
+ ExportSection(props, L"PersonnelTeamStats", Loc::pPersonnelTeamStatsStrings, 0, 11);
+ ExportSection(props, L"MapVertIndex", Loc::pMapVertIndex, 0, 17);
+ ExportSection(props, L"MapHortIndex", Loc::pMapHortIndex, 0, 17);
+ ExportSection(props, L"MapDepthIndex", Loc::pMapDepthIndex, 0, 4);
+ ExportSection(props, L"ContractButton", Loc::pContractButtonString, 0, 1);
+
+ ExportSection(props, L"UpdatePanelButton", Loc::pUpdatePanelButtons, 0, 2);
+ ExportSection(props, L"LargeTactical", Loc::LargeTacticalStr, 0, TEXT_NUM_LARGESTR);
+ ExportSection(props, L"InsContract", Loc::InsContractText, 0, TEXT_NUM_INS_CONTRACT);
+ ExportSection(props, L"InsInfo", Loc::InsInfoText, 0, TEXT_NUM_INS_INFO);
+ ExportSection(props, L"MercAccount", Loc::MercAccountText, 0, TEXT_NUM_MERC_ACCOUNT);
+ ExportSection(props, L"MercAccountPage", Loc::MercAccountPageText, 0, 2);
+ ExportSection(props, L"MercInfo", Loc::MercInfo, 0, TEXT_NUM_MERC_FILES);
+ ExportSection(props, L"MercNoAccount", Loc::MercNoAccountText, 0, TEXT_NUM_MERC_NO_ACC);
+ ExportSection(props, L"MercHomePage", Loc::MercHomePageText, 0, TEXT_NUM_MERC);
+ ExportSection(props, L"Funeral", Loc::sFuneralString, 0, TEXT_NUM_FUNERAL);
+
+ ExportSection(props, L"Florist", Loc::sFloristText, 0, TEXT_NUM_FLORIST);
+ ExportSection(props, L"OrderForm", Loc::sOrderFormText, 0, TEXT_NUM_FLORIST_ORDER);
+ ExportSection(props, L"FloristGallery", Loc::sFloristGalleryText, 0, TEXT_NUM_FLORIST_GALLERY);
+ ExportSection(props, L"FloristCards", Loc::sFloristCards, 0, TEXT_NUM_FLORIST_CARDS);
+ ExportSection(props, L"BobbyROrderForm", Loc::BobbyROrderFormText, 0, TEXT_NUM_BOBBYR_MAILORDER);
+ ExportSection(props, L"BobbyRFilter", Loc::BobbyRFilter, 0, TEXT_NUM_BOBBYR_FILTER);
+ ExportSection(props, L"BobbyR", Loc::BobbyRText, 0, TEXT_NUM_BOBBYR_GUNS);
+ ExportSection(props, L"BobbyRaysFront", Loc::BobbyRaysFrontText, 0, TEXT_NUM_BOBBYR);
+ ExportSection(props, L"AimSort", Loc::AimSortText, 0, TEXT_NUM_AIM_SORT);
+ ExportSection(props, L"AimPolicy", Loc::AimPolicyText, 0, TEXT_NUM_AIM_POLICIES);
+
+ ExportSection(props, L"AimMember", Loc::AimMemberText, 0, 4);
+ ExportSection(props, L"CharacterInfo", Loc::CharacterInfo, 0, TEXT_NUM_AIM_MEMBER_CHARINFO);
+ ExportSection(props, L"VideoConfercing", Loc::VideoConfercingText, 0, TEXT_NUM_AIM_MEMBER_VCONF);
+ ExportSection(props, L"AimPopUp", Loc::AimPopUpText, 0, TEXT_NUM_AIM_MEMBER_POPUP);
+ ExportSection(props, L"AimLink", Loc::AimLinkText, 0, TEXM_NUM_AIM_LINK);
+ ExportSection(props, L"AimHistory", Loc::AimHistoryText, 0, TEXT_NUM_AIM_HISTORY);
+ ExportSection(props, L"AimFi", Loc::AimFiText, 0, TEXT_NUM_AIM_FI);
+ ExportSection(props, L"AimAlumni", Loc::AimAlumniText, 0, TEXT_NUM_AIM_ALUMNI);
+ ExportSection(props, L"AimScreen", Loc::AimScreenText, 0, TEXT_NUM_AIM_SCREEN);
+ ExportSection(props, L"AimBottomMenu", Loc::AimBottomMenuText, 0, TEXT_NUM_AIM_MENU);
+
+ ExportSection(props, L"SKI", Loc::SKI_Text, 0, TEXT_NUM_SKI_TEXT);
+ ExportSection(props, L"SkiAtm", Loc::SkiAtmText, 0, NUM_SKI_ATM_BUTTONS);
+ ExportSection(props, L"SkiAtmText", Loc::gzSkiAtmText, 0, TEXT_NUM_SKI_ATM_MODE_TEXT);
+ ExportSection(props, L"SkiMessageBox", Loc::SkiMessageBoxText, 0, TEXT_NUM_SKI_MBOX_TEXT);
+ ExportSection(props, L"Options", Loc::zOptionsText, 0, TEXT_NUM_OPT_TEXT);
+ ExportSection(props, L"SaveLoad", Loc::zSaveLoadText, 0, TEXT_NUM_SLG_TEXT);
+ ExportSection(props, L"MarksMapScreen", Loc::zMarksMapScreenText, 0, 25);
+ ExportSection(props, L"LandMarkInSector", Loc::pLandMarkInSectorString, 0, 1);
+ ExportSection(props, L"MilitiaConfirm", Loc::pMilitiaConfirmStrings, 0, 11);
+ ExportSection(props, L"MoneyWithdrawMessage", Loc::gzMoneyWithdrawMessageText, 0, TEXT_NUM_MONEY_WITHDRAW);
+
+ ExportSection(props, L"Copyright", Loc::gzCopyrightText, 0, 1);
+ ExportSection(props, L"OptionsToggle", Loc::zOptionsToggleText, 0, 48);
+ ExportSection(props, L"OptionsScreenHelp", Loc::zOptionsScreenHelpText, 0, 48);
+ ExportSection(props, L"GIOScreen", Loc::gzGIOScreenText, 0, TEXT_NUM_GIO_TEXT);
+ ExportSection(props, L"MPJScreen", Loc::gzMPJScreenText, 0, TEXT_NUM_MPJ_TEXT);
+ ExportSection(props, L"MPJHelpText", Loc::gzMPJHelpText, 0, 10);
+ ExportSection(props, L"MPHScreen", Loc::gzMPHScreenText, 0, TEXT_NUM_MPH_TEXT);
+ ExportSection(props, L"DeliveryLocation", Loc::pDeliveryLocationStrings, 0, 17);
+ ExportSection(props, L"SkillAtZeroWarning", Loc::pSkillAtZeroWarning, 0, 1);
+ ExportSection(props, L"IMPBeginScreen", Loc::pIMPBeginScreenStrings, 0, 1);
+ ExportSection(props, L"IMPFinishButton", Loc::pIMPFinishButtonText, 0, 1);
+
+ ExportSection(props, L"IMPFinish", Loc::pIMPFinishStrings, 0, 1);
+ ExportSection(props, L"IMPVoices", Loc::pIMPVoicesStrings, 0, 1);
+ ExportSection(props, L"DepartedMercPortrait", Loc::pDepartedMercPortraitStrings, 0, 3);
+ ExportSection(props, L"PersTitle", Loc::pPersTitleText, 0, 1);
+ ExportSection(props, L"PausedGame", Loc::pPausedGameText, 0, 3);
+ ExportSection(props, L"MessageStrings", Loc::pMessageStrings, 0, TEXT_NUM_MSG);
+ ExportSection(props, L"ItemPickupHelpPopup", Loc::ItemPickupHelpPopup, 0, 5);
+ ExportSection(props, L"DoctorWarning", Loc::pDoctorWarningString, 0, 2);
+ ExportSection(props, L"MilitiaButtonsHelp", Loc::pMilitiaButtonsHelpText, 0, 4);
+ ExportSection(props, L"MapScreenJustStartedHelp", Loc::pMapScreenJustStartedHelpText, 0, 2);
+
+ ExportSection(props, L"AntiHacker", Loc::pAntiHackerString, 0, TEXT_NUM_ANTIHACKERSTR);
+ ExportSection(props, L"LaptopHelp", Loc::gzLaptopHelpText, 0, TEXT_NUM_LAPTOP_BN_BOOKMARK_TEXT);
+ ExportSection(props, L"HelpScreen", Loc::gzHelpScreenText, 0, TEXT_NUM_HLP);
+ ExportSection(props, L"NonPersistantPBI", Loc::gzNonPersistantPBIText, 0, 10);
+ ExportSection(props, L"MiscString", Loc::gzMiscString, 0, 5);
+ ExportSection(props, L"IntroScreen", Loc::gzIntroScreen, 0, 1);
+ ExportSection(props, L"NewNoise", Loc::pNewNoiseStr, 0, 11/*MAX_NOISES*/);
+ ExportSection(props, L"MapScreenSortButtonHelp", Loc::wMapScreenSortButtonHelpText, 0, 6);
+ ExportSection(props, L"BrokenLink", Loc::BrokenLinkText, 0, TEXT_NUM_BROKEN_LINK);
+ ExportSection(props, L"BobbyRShipment", Loc::gzBobbyRShipmentText, 0, TEXT_NUM_BOBBYR_SHIPMENT);
+
+ ExportSection(props, L"CreditNames", Loc::gzCreditNames, 0, 15);
+ ExportSection(props, L"CreditNameTitle", Loc::gzCreditNameTitle, 0, 15);
+ ExportSection(props, L"CreditNameFunny", Loc::gzCreditNameFunny, 0, 15);
+ ExportSection(props, L"RepairsDone", Loc::sRepairsDoneString, 0, 7);
+ ExportSection(props, L"GioDifConfirm", Loc::zGioDifConfirmText, 0, TEXT_NUM_GIO_CFS);
+ ExportSection(props, L"LateLocalized", Loc::gzLateLocalizedString, 0, 64);
+ ExportSection(props, L"CWStrings", Loc::gzCWStrings, 0, 1);
+ ExportSection(props, L"TooltipStrings", Loc::gzTooltipStrings, 0, TEXT_NUM_STR_TT);
+ ExportSection(props, L"New113Message", Loc::New113Message, 0, TEXT_NUM_MSG113);
+
+ ExportSection(props, L"New113HAMMessage", Loc::New113HAMMessage, 0, 22);
+ ExportSection(props, L"New113MERCMercMail", Loc::New113MERCMercMailTexts, 0, 4);
+ ExportSection(props, L"New113AIMMercMail", Loc::New113AIMMercMailTexts, 0, 16);
+ ExportSection(props, L"MissingIMPSkills", Loc::MissingIMPSkillsDescriptions, 0, 2);
+ ExportSection(props, L"NewInvMessage", Loc::NewInvMessage, 0, TEXT_NUM_NIV);
+ ExportSection(props, L"MPServerMessage", Loc::MPServerMessage, 0, 13);
+ ExportSection(props, L"MPClientMessage", Loc::MPClientMessage, 0, 69);
+ ExportSection(props, L"MPEdges", Loc::gszMPEdgesText, 0, 5);
+ ExportSection(props, L"MPTeamName", Loc::gszMPTeamNames, 0, 5);
+ ExportSection(props, L"MPMapscreen", Loc::gszMPMapscreenText, 0, 9);
+
+ ExportSection(props, L"MPSScreen", Loc::gzMPSScreenText, 0, TEXT_NUM_MPS_TEXT);
+ ExportSection(props, L"MPCScreen", Loc::gzMPCScreenText, 0, TEXT_NUM_MPC_TEXT);
+ ExportSection(props, L"MPChatToggle", Loc::gzMPChatToggleText, 0, 2);
+ ExportSection(props, L"MPChatbox", Loc::gzMPChatboxText, 0, 2);
+
+ props.writeToXMLFile(L"Localization/GameStrings.xml",tmap);
+ props.writeToIniFile(L"Localization/GameStrings.ini",true);
+
+ Loc::ExportMercBio();
+ Loc::ExportAIMHistory();
+ Loc::ExportAIMPolicy();
+ Loc::ExportAlumniName();
+ Loc::ExportDialogues();
+ Loc::ExportNPCDialogues();
+
+ return true;
+}
+
+#include
+#include "Encrypted File.h"
+
+namespace Loc
+{
+ wchar_t ToPolish(wchar_t siChar)
+ {
+ switch( siChar )
+ {
+ case 165: siChar = 260; break;
+ case 198: siChar = 262; break;
+ case 202: siChar = 280; break;
+ case 163: siChar = 321; break;
+ case 209: siChar = 323; break;
+ case 211: siChar = 211; break;
+
+ case 140: siChar = 346; break;
+ case 175: siChar = 379; break;
+ case 143: siChar = 377; break;
+ case 185: siChar = 261; break;
+ case 230: siChar = 263; break;
+ case 234: siChar = 281; break;
+
+ case 179: siChar = 322; break;
+ case 241: siChar = 324; break;
+ case 243: siChar = 243; break;
+ case 156: siChar = 347; break;
+ case 191: siChar = 380; break;
+ case 159: siChar = 378; break;
+ }
+ return siChar;
+ }
+
+ wchar_t ToRussian(wchar_t siChar)
+ {
+ switch( siChar )
+ {
+ //capital letters
+ case 168: siChar = 1025; break; //U+0401 d0 81 CYRILLIC CAPITAL LETTER IO
+ case 192: siChar = 1040; break; //U+0410 A d0 90 CYRILLIC CAPITAL LETTER A
+ case 193: siChar = 1041; break;
+ case 194: siChar = 1042; break;
+ case 195: siChar = 1043; break;
+ case 196: siChar = 1044; break;
+ case 197: siChar = 1045; break;
+ case 198: siChar = 1046; break;
+ case 199: siChar = 1047; break;
+ case 200: siChar = 1048; break;
+ case 201: siChar = 1049; break;
+ case 202: siChar = 1050; break;
+ case 203: siChar = 1051; break;
+ case 204: siChar = 1052; break;
+ case 205: siChar = 1053; break;
+ case 206: siChar = 1054; break;
+ case 207: siChar = 1055; break;
+ case 208: siChar = 1056; break;
+ case 209: siChar = 1057; break;
+ case 210: siChar = 1058; break;
+ case 211: siChar = 1059; break;
+ case 212: siChar = 1060; break;
+ case 213: siChar = 1061; break;
+ case 214: siChar = 1062; break;
+ case 215: siChar = 1063; break;
+ case 216: siChar = 1064; break;
+ case 217: siChar = 1065; break;
+ case 218: siChar = 1066; break;
+ case 219: siChar = 1067; break;
+ case 220: siChar = 1068; break;
+ case 221: siChar = 1069; break;
+ case 222: siChar = 1070; break;
+ case 223: siChar = 1071; break; //U+042F d0 af CYRILLIC CAPITAL LETTER YA
+
+ //small letters
+ case 185: siChar = 8470; break; // ¹
+ case 178: siChar = 1030; break; // ²
+ case 161: siChar = 1038; break; // ¡
+ case 179: siChar = 1110; break; // ³
+ case 162: siChar = 1118; break; // ¢
+ case 165: siChar = 1168; break; // ¥
+ case 170: siChar = 1028; break; // ª
+ case 175: siChar = 1031; break; // ¯
+ case 180: siChar = 1169; break; // ´
+ case 186: siChar = 1108; break; // º
+ case 191: siChar = 1111; break; // ¿
+
+ case 184: siChar = 1105; break; //U+0451 d1 91 CYRILLIC SMALL LETTER IO
+ case 224: siChar = 1072; break; //U+0430 a d0 b0 CYRILLIC SMALL LETTER A
+ case 225: siChar = 1073; break;
+ case 226: siChar = 1074; break;
+ case 227: siChar = 1075; break;
+ case 228: siChar = 1076; break;
+ case 229: siChar = 1077; break;
+ case 230: siChar = 1078; break;
+ case 231: siChar = 1079; break;
+ case 232: siChar = 1080; break;
+ case 233: siChar = 1081; break;
+ case 234: siChar = 1082; break;
+ case 235: siChar = 1083; break;
+ case 236: siChar = 1084; break;
+ case 237: siChar = 1085; break;
+ case 238: siChar = 1086; break;
+ case 239: siChar = 1087; break; //U+043F d0 bf CYRILLIC SMALL LETTER PE
+ case 240: siChar = 1088; break; //U+0440 p d1 80 CYRILLIC SMALL LETTER ER
+ case 241: siChar = 1089; break;
+ case 242: siChar = 1090; break;
+ case 243: siChar = 1091; break;
+ case 244: siChar = 1092; break;
+ case 245: siChar = 1093; break;
+ case 246: siChar = 1094; break;
+ case 247: siChar = 1095; break;
+ case 248: siChar = 1096; break;
+ case 249: siChar = 1097; break;
+ case 250: siChar = 1098; break;
+ case 251: siChar = 1099; break;
+ case 252: siChar = 1100; break;
+ case 253: siChar = 1101; break;
+ case 254: siChar = 1102; break;
+ case 255: siChar = 1103; break; //U+044F d1 8f CYRILLIC SMALL LETTER YA
+ }
+ return siChar;
+ }
+ bool Translate(vfs::String::char_t* str, int len, Language lang)
+ {
+ if(lang == English || lang == German)
+ {
+ return true;
+ }
+ else if(lang == Russian)
+ {
+ for(int i=0; i(i), pInfoString);
+
+ file.read((vfs::Byte*)pAddInfo, SIZE_MERC_ADDITIONAL_INFO);
+ DecodeString(pAddInfo, SIZE_MERC_ADDITIONAL_INFO);
+ Loc::Translate(pAddInfo, SIZE_MERC_ADDITIONAL_INFO, lang);
+ props.setStringProperty(L"Add", vfs::toString(i), pAddInfo);
+ }
+ props.writeToXMLFile(L"Localization/AimBiographies.xml", vfs::PropertyContainer::TagMap());
+}
+
+void Loc::ExportAIMHistory()
+{
+ Loc::Language lang = gs_Lang;
+ #define AIM_HISTORY_LINE_SIZE 400 * 2
+ vfs::String::char_t pHistLine[AIM_HISTORY_LINE_SIZE];
+ vfs::COpenReadFile rfile("BINARYDATA\\AimHist.edt");
+ vfs::tReadableFile& file = rfile.file();
+
+ vfs::PropertyContainer props;
+ for(int i=0; i<23; ++i)
+ {
+ memset(pHistLine,0,AIM_HISTORY_LINE_SIZE*sizeof(wchar_t));
+ //
+ file.read((vfs::Byte*)pHistLine, AIM_HISTORY_LINE_SIZE);
+ DecodeString(pHistLine,AIM_HISTORY_LINE_SIZE);
+ Loc::Translate(pHistLine, AIM_HISTORY_LINE_SIZE, lang);
+ props.setStringProperty(L"Line", vfs::toString(i), pHistLine);
+ }
+ props.writeToXMLFile(L"Localization/AimHistory.xml", vfs::PropertyContainer::TagMap());
+}
+
+
+void Loc::ExportAIMPolicy()
+{
+ Loc::Language lang = gs_Lang;
+ #define AIM_HISTORY_LINE_SIZE 400 * 2
+ vfs::String::char_t pPolLine[AIM_HISTORY_LINE_SIZE];
+ vfs::COpenReadFile rfile("BINARYDATA\\AimPol.edt");
+ vfs::tReadableFile& file = rfile.file();
+
+ vfs::PropertyContainer props;
+ for(int i=0; i<46; ++i)
+ {
+ memset(pPolLine,0,400*sizeof(wchar_t));
+ //
+ file.read((vfs::Byte*)pPolLine, AIM_HISTORY_LINE_SIZE);
+ DecodeString(pPolLine,AIM_HISTORY_LINE_SIZE);
+ Loc::Translate(pPolLine, AIM_HISTORY_LINE_SIZE, lang);
+ props.setStringProperty(L"Line", vfs::toString(i), pPolLine);
+ }
+ props.writeToXMLFile(L"Localization/AimPolicy.xml", vfs::PropertyContainer::TagMap());
+}
+
+void Loc::ExportAlumniName()
+{
+ Loc::Language lang = gs_Lang;
+ #define AIM_ALUMNI_NAME_SIZE 80 * 2
+ vfs::String::char_t pAlumniName[AIM_ALUMNI_NAME_SIZE];
+ vfs::COpenReadFile rfile("BINARYDATA\\AlumName.edt");
+ vfs::tReadableFile& file = rfile.file();
+
+ vfs::PropertyContainer props;
+ for(int i=0; i<51; ++i)
+ {
+ memset(pAlumniName,0,AIM_ALUMNI_NAME_SIZE*sizeof(wchar_t));
+ //
+ file.read((vfs::Byte*)pAlumniName, AIM_ALUMNI_NAME_SIZE);
+ DecodeString(pAlumniName,AIM_ALUMNI_NAME_SIZE);
+ Loc::Translate(pAlumniName, AIM_ALUMNI_NAME_SIZE, lang);
+ props.setStringProperty(L"Line", vfs::toString(i), pAlumniName);
+ }
+ props.writeToXMLFile(L"Localization/AlumniName.xml", vfs::PropertyContainer::TagMap());
+}
+
+#include
+
+void Loc::ExportDialogues()
+{
+ Loc::Language lang = gs_Lang;
+ #define DIALOGUESIZE 480
+ vfs::String::char_t pDiagLine[DIALOGUESIZE];
+
+ vfs::CVirtualFileSystem::Iterator it = getVFS()->begin(L"MercEdt/*.edt");
+ for(; !it.end(); it.next())
+ {
+ vfs::PropertyContainer props;
+ vfs::COpenReadFile rfile(it.value());
+ vfs::tReadableFile& file = rfile.file();
+
+ std::wstringstream wss;
+ wss.str(file.getName().c_str());
+ int id=0;
+ wss >> id;
+
+ for(int i=0; i<200; ++i)
+ {
+ memset(pDiagLine,0,DIALOGUESIZE*sizeof(wchar_t));
+ //
+ if(file.read((vfs::Byte*)pDiagLine, DIALOGUESIZE) > 0)
+ {
+ DecodeString(pDiagLine,DIALOGUESIZE);
+ Loc::Translate(pDiagLine, DIALOGUESIZE, lang);
+ if(wcslen(pDiagLine))
+ {
+ props.setStringProperty(vfs::toString(id),vfs::toString(i), pDiagLine);
+ }
+ }
+ }
+ vfs::Path x(L"Localization/Dialogue");
+ x += vfs::Path(file.getName().c_wcs() + L".xml");
+ props.writeToXMLFile(x, vfs::PropertyContainer::TagMap());
+ }
+}
+
+void Loc::ExportNPCDialogues()
+{
+ Loc::Language lang = gs_Lang;
+ #define DIALOGUESIZE 480
+ #define CIVQUOTESIZE 320
+ vfs::String::char_t pDiagLine[DIALOGUESIZE];
+
+ vfs::CVirtualFileSystem::Iterator it = getVFS()->begin(L"npcdata/*.edt");
+ for(; !it.end(); it.next())
+ {
+ vfs::PropertyContainer props;
+ vfs::COpenReadFile rfile(it.value());
+ vfs::tReadableFile& file = rfile.file();
+
+ vfs::String::str_t const& ws = file.getName().c_wcs();
+ vfs::String::str_t::size_type pos = ws.find_first_of(L".");
+ vfs::String id = ws.substr(0,pos);
+
+ int SIZE;
+ if(vfs::matchPattern(L"civ*", id))
+ {
+ SIZE = CIVQUOTESIZE;
+ }
+ else
+ {
+ SIZE = DIALOGUESIZE;
+ }
+
+ for(int i=0; i<200; ++i)
+ {
+ memset(pDiagLine,0,DIALOGUESIZE*sizeof(wchar_t));
+ //
+ if(file.read((vfs::Byte*)pDiagLine, SIZE) > 0)
+ {
+ DecodeString(pDiagLine,SIZE);
+ Loc::Translate(pDiagLine, SIZE, lang);
+ if(wcslen(pDiagLine))
+ {
+ props.setStringProperty(id,vfs::toString(i), pDiagLine);
+ }
+ }
+ }
+ vfs::Path x(L"Localization/NpcDialogue");
+ x += vfs::Path(file.getName().c_wcs() + L".xml");
+ props.writeToXMLFile(x, vfs::PropertyContainer::TagMap());
+ }
+}
diff --git a/Utils/ExportStrings.h b/Utils/ExportStrings.h
new file mode 100644
index 00000000..f2156ed5
--- /dev/null
+++ b/Utils/ExportStrings.h
@@ -0,0 +1,9 @@
+#ifndef _EXPORTSTRINGS_H_
+#define _EXPORTSTRINGS_H_
+
+namespace Loc
+{
+ bool ExportStrings();
+}
+
+#endif // _EXPORTSTRINGS_H_
\ No newline at end of file
diff --git a/Utils/INIReader.cpp b/Utils/INIReader.cpp
index 5ea92fb0..36656609 100644
--- a/Utils/INIReader.cpp
+++ b/Utils/INIReader.cpp
@@ -10,8 +10,11 @@
// Kaiden: INI reading function definitions:
-#include "VFS/vfs.h"
+#include
+#ifdef USE_VFS
+std::set CIniReader::m_merge_files;
+#endif
std::stack iniErrorMessages;
template
@@ -29,6 +32,13 @@ void PushErrorMessage(std::string const& filename,
iniErrorMessages.push(errMessage.str());
}
+#ifdef USE_VFS
+void CIniReader::RegisterFileForMerging(vfs::Path const& filename)
+{
+ m_merge_files.insert(filename);
+}
+#endif
+
CIniReader::CIniReader(const STR8 szFileName)
{
memset(m_szFileName,0,sizeof(m_szFileName));
@@ -43,7 +53,26 @@ CIniReader::CIniReader(const STR8 szFileName)
}
#else
strncpy(m_szFileName,szFileName, std::min(strlen(szFileName), sizeof(m_szFileName)-1));
- m_oProps.initFromIniFile(vfs::Path(szFileName));
+ if(m_merge_files.find(szFileName) == m_merge_files.end())
+ {
+ m_oProps.initFromIniFile(vfs::Path(szFileName));
+ }
+ else
+ {
+ vfs::CProfileStack* profs = getVFS()->getProfileStack();
+ vfs::CProfileStack::Iterator it = profs->begin();
+ std::stack rev_order;
+ for(; !it.end(); it.next()) { rev_order.push(it.value()); }
+ while(!rev_order.empty())
+ {
+ vfs::IBaseFile* file = rev_order.top()->getFile(szFileName);
+ if(file)
+ {
+ m_oProps.initFromIniFile(vfs::tReadableFile::cast(file));
+ }
+ rev_order.pop();
+ }
+ }
#endif
}
@@ -79,7 +108,28 @@ CIniReader::CIniReader(const STR8 szFileName, BOOLEAN Force_Custom_Data_Path)
}
#else
strncpy(m_szFileName,szFileName, std::min(strlen(szFileName), sizeof(m_szFileName)-1));
- CIniReader_File_Found = m_oProps.initFromIniFile(vfs::Path(szFileName));
+ if(m_merge_files.find(szFileName) == m_merge_files.end())
+ {
+ CIniReader_File_Found = m_oProps.initFromIniFile(vfs::Path(szFileName));
+ }
+ else
+ {
+ CIniReader_File_Found = TRUE;
+ vfs::CProfileStack* profs = getVFS()->getProfileStack();
+ vfs::CProfileStack::Iterator it = profs->begin();
+ std::stack rev_order;
+ for(; !it.end(); it.next()) { rev_order.push(it.value()); }
+ while(!rev_order.empty())
+ {
+ vfs::IBaseFile* file = rev_order.top()->getFile(szFileName);
+ if(file)
+ {
+ CIniReader_File_Found = ((CIniReader_File_Found != FALSE) && m_oProps.initFromIniFile(vfs::tReadableFile::cast(file))) ? TRUE : FALSE;
+ }
+ rev_order.pop();
+ }
+ }
+
#endif
}
@@ -99,7 +149,7 @@ int CIniReader::ReadInteger(const STR8 szSection, const STR8 szKey, int iDefault
#ifndef USE_VFS
return GetPrivateProfileInt(szSection, szKey, iDefaultValue, m_szFileName);
#else
- return m_oProps.getIntProperty(szSection, szKey, iDefaultValue);
+ return (int)(m_oProps.getIntProperty(szSection, szKey, iDefaultValue));
#endif
}
@@ -107,9 +157,9 @@ int CIniReader::ReadInteger(const STR8 szSection, const STR8 szKey, int iDefault
int CIniReader::ReadInteger(const STR8 szSection, const STR8 szKey, int defaultValue, int minValue, int maxValue)
{
#ifndef USE_VFS
- int iniValueReadFromFile = GetPrivateProfileInt(szSection, szKey, defaultValue, m_szFileName);
+ int iniValueReadFromFile = (int)(GetPrivateProfileInt(szSection, szKey, defaultValue, m_szFileName));
#else
- int iniValueReadFromFile = m_oProps.getIntProperty(szSection, szKey, defaultValue);
+ int iniValueReadFromFile = (int)(m_oProps.getIntProperty(szSection, szKey, defaultValue));
#endif
//AssertGE(iniValueReadFromFile, minValue);
//AssertLE(iniValueReadFromFile, maxValue);
@@ -195,7 +245,7 @@ FLOAT CIniReader::ReadFloat(const STR8 szSection, const STR8 szKey, FLOAT defaul
return iniValueReadFromFile;
}
-BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, bool defaultValue)
+BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, bool defaultValue, bool bolDisplayError)
{
#ifndef USE_VFS
char szResult[255];
@@ -209,12 +259,12 @@ BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, bool def
else if (strcmp(szResult, "FALSE") == 0)
return FALSE;
#else
- utf8string str = m_oProps.getStringProperty(szSection, szKey, L"");
- if( StrCmp::Equal(str, L"true") )
+ vfs::String str = m_oProps.getStringProperty(szSection, szKey, L"");
+ if( vfs::StrCmp::Equal(str, L"true") )
{
return TRUE;
}
- else if( StrCmp::Equal(str, L"false") )
+ else if( vfs::StrCmp::Equal(str, L"false") )
{
return FALSE;
}
@@ -222,10 +272,12 @@ BOOLEAN CIniReader::ReadBoolean(const STR8 szSection, const STR8 szKey, bool def
char szDefault[255];
sprintf(szDefault, "%s", defaultValue? "TRUE" : "FALSE");
#endif
- std::stringstream errMessage;
- errMessage << "The value [" << szSection << "][" << szKey << "] = \"" << szResult << "\" "
- << "in file [" << this->m_szFileName << "] is neither TRUE nor FALSE. The value " << szDefault << " will be used.";
- iniErrorMessages.push(errMessage.str());
+ if(bolDisplayError){
+ std::stringstream errMessage;
+ errMessage << "The value [" << szSection << "][" << szKey << "] = \"" << szResult << "\" "
+ << "in file [" << this->m_szFileName << "] is neither TRUE nor FALSE. The value " << szDefault << " will be used.";
+ iniErrorMessages.push(errMessage.str());
+ }
return defaultValue;
}
diff --git a/Utils/INIReader.h b/Utils/INIReader.h
index c53e9bba..0b586b08 100644
--- a/Utils/INIReader.h
+++ b/Utils/INIReader.h
@@ -6,7 +6,7 @@
#include
#include
-#include "VFS/PropertyContainer.h"
+#include
// Kaiden: This will read any value out of
// an INI file as long as the correct type is specified.
@@ -42,7 +42,7 @@ public:
DOUBLE ReadDouble(const STR8 szSection, const STR8 szKey, DOUBLE defaultValue, DOUBLE minValue, DOUBLE maxValue);
FLOAT ReadFloat (const STR8 szSection, const STR8 szKey, FLOAT defaultValue, FLOAT minValue, FLOAT maxValue);
- BOOLEAN ReadBoolean(const STR8 szSection, const STR8 szKey, bool bolDefaultValue);
+ BOOLEAN ReadBoolean(const STR8 szSection, const STR8 szKey, bool bolDefaultValue, bool bolDisplayError = true);
void ReadString(const STR8 szSection, const STR8 szKey, const STR8 szDefaultValue, STR8 input_buffer, size_t buffer_size);
@@ -51,13 +51,19 @@ public:
BOOLEAN Is_CIniReader_File_Found(void) {return (CIniReader_File_Found);}
void Clear();
+
+#ifdef USE_VFS
+ static void RegisterFileForMerging(vfs::Path const& filename);
+#endif
private:
- CPropertyContainer m_oProps;
+ vfs::PropertyContainer m_oProps;
char m_szFileName[MAX_PATH];
BOOLEAN CIniReader_File_Found;
UINT32 ReadUINT(const STR8 szSection, const STR8 szKey, UINT32 defaultValue, UINT32 minValue, UINT32 maxValue);
-
+#ifdef USE_VFS
+ static std::set m_merge_files;
+#endif
};
#endif//INIREADER_H
\ No newline at end of file
diff --git a/Utils/ImportStrings.cpp b/Utils/ImportStrings.cpp
new file mode 100644
index 00000000..1d4131c4
--- /dev/null
+++ b/Utils/ImportStrings.cpp
@@ -0,0 +1,38 @@
+#include "ImportStrings.h"
+#include "LocalizedStrings.h"
+#include "Language Defines.h"
+
+#include
+#include
+
+#include
+
+void Loc::ImportStrings()
+{
+ Loc::AssociateWithFile(Loc::AIM_BIOGRAPHY, L"Localization/AimBiographies.xml");
+ Loc::AssociateWithFile(Loc::AIM_HISTORY, L"Localization/AimHistory.xml");
+ Loc::AssociateWithFile(Loc::AIM_POLICY, L"Localization/AimPolicy.xml");
+ Loc::AssociateWithFile(Loc::GAME_STRINGS, L"Localization/GameStrings.xml");
+
+ vfs::String bio, add, bio2;
+ Loc::GetString(Loc::AIM_BIOGRAPHY,L"Bio",L"0",add);
+ Loc::GetString(Loc::AIM_BIOGRAPHY,L"Add",L"10",bio);
+ Loc::GetString(Loc::AIM_BIOGRAPHY,L"Bio",23,bio2);
+
+ for(int i=0; i<200; ++i)
+ {
+ std::wstringstream wss;
+ for(int exp=2; exp>=0; --exp)
+ {
+ int t = (int)std::pow((double)10,(double)exp);
+ wss << (i % (t*10)) / t;
+ }
+ vfs::String s = wss.str() + L".EDT.xml";
+ vfs::Path filename(L"Localization/Dialogue");
+ filename += vfs::Path(s);
+ if(getVFS()->fileExists(filename))
+ {
+ Loc::AssociateWithFile(Loc::DIALOGUE,filename,vfs::toString(i));
+ }
+ }
+}
diff --git a/Utils/ImportStrings.h b/Utils/ImportStrings.h
new file mode 100644
index 00000000..30bd0b78
--- /dev/null
+++ b/Utils/ImportStrings.h
@@ -0,0 +1,9 @@
+#ifndef _IMPORTSTRINGS_H_
+#define _IMPORTSTRINGS_H_
+
+namespace Loc
+{
+ void ImportStrings();
+}
+
+#endif // _IMPORTSTRINGS_H_
diff --git a/Utils/LocalizedStrings.cpp b/Utils/LocalizedStrings.cpp
new file mode 100644
index 00000000..62153401
--- /dev/null
+++ b/Utils/LocalizedStrings.cpp
@@ -0,0 +1,127 @@
+#include "LocalizedStrings.h"
+
+#include
+#include
+
+bool g_bUseXML_Strings = false;
+
+namespace Loc
+{
+ void Init(Topic t, vfs::String const& section);
+ void Clear(Topic t);
+ void ClearAll();
+
+ class _Strings
+ {
+ public:
+ _Strings() : initialized(false) {};
+ bool initialized;
+ vfs::PropertyContainer stringMap;
+ };
+ class _PropState
+ {
+ public:
+ _PropState() : loaded(false) {};
+ bool loaded;
+ vfs::Path filename;
+ };
+
+ typedef std::map tSectionState;
+
+ static std::map _localizedStrings;
+ static std::map _topicFiles;
+};
+
+
+
+bool Loc::AssociateWithFile(Loc::Topic t, vfs::Path const& sFilename)
+{
+ _topicFiles[t][L"_ALL"].filename = sFilename;
+ _topicFiles[t][L"_ALL"].loaded = false;
+ return true;
+}
+
+bool Loc::AssociateWithFile(Topic t, vfs::Path const& sFilename, vfs::String const& section)
+{
+ _topicFiles[t][section].filename = sFilename;
+ _topicFiles[t][section].loaded = false;
+ return false;
+}
+
+
+bool Loc::GetString(Loc::Topic t, vfs::String const& section, vfs::String const& key, vfs::String& value)
+{
+ Init(t,section);
+ return _localizedStrings[t].getStringProperty(section, key, value);
+}
+bool Loc::GetString(Loc::Topic t, vfs::String const& section, int key, vfs::String& value)
+{
+ return GetString(t, section, vfs::toString(key), value);
+}
+
+bool Loc::GetString(Topic t, vfs::String const& section, vfs::String const& key, vfs::String::char_t* value, vfs::UInt32 len)
+{
+ Init(t,section);
+ return _localizedStrings[t].getStringProperty(section, key, value, len);
+}
+bool Loc::GetString(Topic t, vfs::String const& section, int key, vfs::String::char_t* value, vfs::UInt32 len)
+{
+ return GetString(t, section, vfs::toString(key), value, len);
+}
+
+vfs::String const& Loc::GetString(Topic t, vfs::String const& section, vfs::String const& key)
+{
+ Init(t,section);
+ return _localizedStrings[t].getStringProperty(section, key);
+}
+vfs::String const& Loc::GetString(Topic t, vfs::String const& section, int key)
+{
+ return GetString(t,section,vfs::toString(key));
+}
+
+
+
+void Loc::Init(Topic t, vfs::String const& section)
+{
+ _PropState& state = _topicFiles[t][L"_ALL"];
+ if(!state.filename.empty() && !state.loaded)
+ {
+ _localizedStrings[t].initFromXMLFile(state.filename, vfs::PropertyContainer::TagMap());
+ state.loaded = true;
+ }
+ state = _topicFiles[t][section];
+ if(!state.filename.empty() && !state.loaded)
+ {
+ _localizedStrings[t].initFromXMLFile(state.filename, vfs::PropertyContainer::TagMap());
+ state.loaded = true;
+ }
+}
+
+void Loc::Clear(Topic t)
+{
+ _localizedStrings[t].clearContainer();
+ tSectionState::iterator it = _topicFiles[t].begin();
+ for(; it != _topicFiles[t].end(); ++it)
+ {
+ it->second.loaded = false;
+ }
+
+}
+
+void Loc::ClearAll()
+{
+ std::map::iterator sit = _topicFiles.begin();
+ for(; sit != _topicFiles.end(); ++sit)
+ {
+ tSectionState::iterator it = sit->second.begin();
+ for(; it != sit->second.end(); ++it)
+ {
+ it->second.loaded = false;
+ }
+ }
+ _localizedStrings.clear();
+}
+
+
+
+
diff --git a/Utils/LocalizedStrings.h b/Utils/LocalizedStrings.h
new file mode 100644
index 00000000..5e10f80e
--- /dev/null
+++ b/Utils/LocalizedStrings.h
@@ -0,0 +1,59 @@
+#ifndef _LOCALIZEDSTRINGS_H_
+#define _LOCALIZEDSTRINGS_H_
+
+#include
+
+//#define USE_LOCALIZATION
+
+namespace Loc
+{
+ enum Language
+ {
+ Chinese,
+ Dutch,
+ English,
+ French,
+ German,
+ Italian,
+ Polish,
+ Russian,
+ Taiwanese,
+ };
+
+ static const wchar_t* LangSuffix [] = {
+ L"_cn",
+ L"_nl",
+ L"_en",
+ L"_fr",
+ L"_de",
+ L"_it",
+ L"_pl",
+ L"_ru",
+ L"_tw",
+ };
+
+ enum Topic
+ {
+ AIM_BIOGRAPHY,
+ AIM_HISTORY,
+ AIM_POLICY,
+ GAME_STRINGS,
+ DIALOGUE,
+ };
+
+ bool AssociateWithFile(Topic t, vfs::Path const& sFilename);
+ bool AssociateWithFile(Topic t, vfs::Path const& sFilename, vfs::String const& section);
+
+ bool GetString(Topic t, vfs::String const& section, vfs::String const& key, vfs::String& value);
+ bool GetString(Topic t, vfs::String const& section, int key, vfs::String& value);
+
+ bool GetString(Topic t, vfs::String const& section, vfs::String const& key, vfs::String::char_t* value, vfs::UInt32 len);
+ bool GetString(Topic t, vfs::String const& section, int key, vfs::String::char_t* value, vfs::UInt32 len);
+
+ vfs::String const& GetString(Topic t, vfs::String const& section, vfs::String const& key);
+ vfs::String const& GetString(Topic t, vfs::String const& section, int key);
+};
+
+extern bool g_bUseXML_Strings;
+
+#endif // _LOCALIZEDSTRINGS_H_
diff --git a/Utils/Multi Language Graphic Utils.cpp b/Utils/Multi Language Graphic Utils.cpp
index e2847f8c..d38408a6 100644
--- a/Utils/Multi Language Graphic Utils.cpp
+++ b/Utils/Multi Language Graphic Utils.cpp
@@ -20,6 +20,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_AIMSYMBOL:
sprintf( filename, "LAPTOP\\AimSymbol.sti" );
return TRUE;
+ case MLG_AIMSYMBOL_SMALL:
+ sprintf( filename, "LAPTOP\\AimSymbol_Small.sti" );
+ return TRUE;
case MLG_BOBBYNAME:
sprintf( filename, "LAPTOP\\BobbyName.sti" );
return TRUE;
@@ -138,6 +141,10 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
//Same graphic (no translation needed)
sprintf( filename, "LAPTOP\\AimSymbol.sti" );
return TRUE;
+ case MLG_AIMSYMBOL_SMALL:
+ //Same graphic (no translation needed)
+ sprintf( filename, "LAPTOP\\AimSymbol_Small.sti" );
+ return TRUE;
case MLG_BOBBYNAME:
//Same graphic (no translation needed)
sprintf( filename, "LAPTOP\\BobbyName.sti" );
@@ -298,6 +305,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_AIMSYMBOL:
sprintf( filename, "%s\\AimSymbol_%s.sti", zLanguage, zLanguage );
break;
+ case MLG_AIMSYMBOL_SMALL:
+ sprintf( filename, "%s\\AimSymbol_Small_%s.sti", zLanguage, zLanguage );
+ break;
case MLG_BOBBYNAME:
sprintf( filename, "%s\\BobbyName_%s.sti", zLanguage, zLanguage );
break;
@@ -419,6 +429,9 @@ BOOLEAN GetMLGFilename( SGPFILENAME filename, UINT16 usMLGGraphicID )
case MLG_AIMSYMBOL:
sprintf( filename, "LAPTOP\\AimSymbol.sti" );
return TRUE;
+ case MLG_AIMSYMBOL_SMALL:
+ sprintf( filename, "LAPTOP\\AimSymbol_Small.sti" );
+ return TRUE;
case MLG_BOBBYNAME:
sprintf( filename, "LAPTOP\\BobbyName.sti" );
return TRUE;
diff --git a/Utils/Multi Language Graphic Utils.h b/Utils/Multi Language Graphic Utils.h
index 4270d466..13ffb918 100644
--- a/Utils/Multi Language Graphic Utils.h
+++ b/Utils/Multi Language Graphic Utils.h
@@ -4,6 +4,7 @@
enum
{
MLG_AIMSYMBOL,
+ MLG_AIMSYMBOL_SMALL,
MLG_BOBBYNAME,
MLG_BOBBYRAYAD21,
MLG_BOBBYRAYLINK,
diff --git a/Utils/Music Control.cpp b/Utils/Music Control.cpp
index 5727f929..2e47dd3b 100644
--- a/Utils/Music Control.cpp
+++ b/Utils/Music Control.cpp
@@ -14,27 +14,36 @@
#include "fade screen.h"
#endif
-extern int iScreenMode;
+//extern int iScreenMode;
-UINT32 uiMusicHandle=NO_SAMPLE;
-UINT32 uiMusicVolume=50;
-BOOLEAN fMusicPlaying=FALSE;
-BOOLEAN fMusicFadingOut=FALSE;
-BOOLEAN fMusicFadingIn=FALSE;
+static UINT32 uiMusicHandle = NO_SAMPLE;
+static BOOLEAN fMusicPlaying = FALSE;
-BOOLEAN gfMusicEnded = FALSE;
+static BOOLEAN fMusicFadingOut = FALSE;
+static BOOLEAN fMusicFadingIn = FALSE;
+static UINT32 uiMusicVolume = 50;
-UINT8 gubMusicMode = 0;
-UINT8 gubOldMusicMode = 0;
+static BOOLEAN gfMusicEnded = FALSE;
-INT8 gbVictorySongCount = 0;
-INT8 gbDeathSongCount = 0;
+static UINT8 gubMusicMode = 0;
-INT8 bNothingModeSong;
-INT8 bEnemyModeSong;
-INT8 bBattleModeSong;
+static UINT8 gubOldMusicMode = 0;
+
+static INT8 gbVictorySongCount = 0;
+static INT8 gbDeathSongCount = 0;
+
+static INT8 bNothingModeSong;
+static INT8 bEnemyModeSong;
+static INT8 bBattleModeSong;
+
+static BOOLEAN gfUseCreatureMusic = FALSE;
+
+static INT8 gbFadeSpeed = 1;
+
+static BOOLEAN gfDontRestartSong = FALSE;
+// unused
+//BOOLEAN gfForceMusicToTense = FALSE;
-INT8 gbFadeSpeed = 1;
CHAR8 *szMusicList[NUM_MUSIC]=
{
@@ -55,39 +64,40 @@ CHAR8 *szMusicList[NUM_MUSIC]=
"MUSIC\\creature battle.wav",
};
-BOOLEAN gfForceMusicToTense = FALSE;
-BOOLEAN gfDontRestartSong = FALSE;
+BOOLEAN StartMusicBasedOnMode(void);
+void DoneFadeOutDueToEndMusic(void);
+void MusicStopCallback(void *pData);
+BOOLEAN MusicStop(void);
+BOOLEAN MusicFadeOut(void);
+BOOLEAN MusicFadeIn(void);
-BOOLEAN StartMusicBasedOnMode( );
-void DoneFadeOutDueToEndMusic( void );
-extern void HandleEndDemoInCreatureLevel( );
+//extern void HandleEndDemoInCreatureLevel( );
+
+//BOOLEAN NoEnemiesInSight( )
+//{
+// SOLDIERTYPE *pSoldier;
+// INT32 cnt;
+//
+// // Loop through our guys
+// // End the turn of player charactors
+// cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
+//
+// // look for all mercs on the same team,
+// for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ )
+// {
+// if ( pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE )
+// {
+// if ( pSoldier->aiData.bOppCnt != 0 )
+// {
+// return( FALSE );
+// }
+// }
+// }
+//
+// return( TRUE );
+//}
-BOOLEAN NoEnemiesInSight( )
-{
- SOLDIERTYPE *pSoldier;
- INT32 cnt;
-
- // Loop through our guys
- // End the turn of player charactors
- cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
-
- // look for all mercs on the same team,
- for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++ )
- {
- if ( pSoldier->bActive && pSoldier->stats.bLife >= OKLIFE )
- {
- if ( pSoldier->aiData.bOppCnt != 0 )
- {
- return( FALSE );
- }
- }
- }
-
- return( TRUE );
-}
-
-void MusicStopCallback( void *pData );
//********************************************************************************
// MusicPlay
@@ -109,28 +119,28 @@ BOOLEAN MusicPlay(UINT32 uiNum)
MusicStop();
memset(&spParms, 0xff, sizeof(SOUNDPARMS));
- spParms.uiPriority=PRIORITY_MAX;
- spParms.uiVolume=0;
- spParms.uiLoop=1; // Lesh: only 1 line added
+ spParms.uiPriority = PRIORITY_MAX;
+ spParms.uiVolume = 0;
+ spParms.uiLoop = 1; // Lesh: only 1 line added
spParms.EOSCallback = MusicStopCallback;
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "About to call SoundPlayStreamedFile" );
- uiMusicHandle=SoundPlayStreamedFile(szMusicList[uiNum], &spParms);
+ uiMusicHandle = SoundPlayStreamedFile(szMusicList[uiNum], &spParms);
- if(uiMusicHandle!=SOUND_ERROR)
+ if(uiMusicHandle != SOUND_ERROR)
{
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Music PLay %d %d", uiMusicHandle, gubMusicMode ) );
- gfMusicEnded = FALSE;
- fMusicPlaying=TRUE;
+ gfMusicEnded = FALSE;
+ fMusicPlaying = TRUE;
MusicFadeIn();
- return(TRUE);
+ return TRUE;
}
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Music PLay %d %d", uiMusicHandle, gubMusicMode ) );
- return(FALSE);
+ return FALSE;
}
//********************************************************************************
@@ -149,32 +159,31 @@ BOOLEAN MusicSetVolume(UINT32 uiVolume)
//if( 1==iScreenMode ) /* on Windowed mode, skip the music? was coded for WINDOWED_MODE that way...*/
//return FALSE;
+ uiMusicVolume = __min(uiVolume, 127);
- uiMusicVolume=__min(uiVolume, 127);
-
- if(uiMusicHandle!=NO_SAMPLE)
+ if(uiMusicHandle != NO_SAMPLE)
{
- // get volume and if 0 stop music!
- if ( uiMusicVolume == 0 )
- {
- gfDontRestartSong = TRUE;
- MusicStop( );
- return( TRUE );
- }
+ // get volume and if 0 stop music!
+ if (uiMusicVolume == 0)
+ {
+ gfDontRestartSong = TRUE;
+ MusicStop();
+ return TRUE;
+ }
SoundSetVolume(uiMusicHandle, uiMusicVolume);
- return(TRUE);
+ return TRUE;
}
// If here, check if we need to re-start music
// Have we re-started?
- if ( uiMusicVolume > 0 && uiOldMusicVolume == 0 )
+ if (uiMusicVolume > 0 && uiOldMusicVolume == 0)
{
- StartMusicBasedOnMode( );
+ StartMusicBasedOnMode();
}
- return(FALSE);
+ return FALSE;
}
//********************************************************************************
@@ -187,7 +196,7 @@ BOOLEAN MusicSetVolume(UINT32 uiVolume)
//********************************************************************************
UINT32 MusicGetVolume(void)
{
- return(uiMusicVolume);
+ return uiMusicVolume;
}
//********************************************************************************
@@ -198,25 +207,24 @@ UINT32 MusicGetVolume(void)
// Returns: TRUE if the music was stopped, FALSE if an error occurred
//
//********************************************************************************
-BOOLEAN MusicStop(void)
+static BOOLEAN MusicStop(void)
{
// WANNE: We want music in windowed mode
//if( 1==iScreenMode ) /* on Windowed mode, skip the music? was coded for WINDOWED_MODE that way...*/
// return(FALSE);
-
- if(uiMusicHandle!=NO_SAMPLE)
+ if(uiMusicHandle != NO_SAMPLE)
{
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Music Stop %d %d", uiMusicHandle, gubMusicMode ) );
SoundStop(uiMusicHandle);
- fMusicPlaying=FALSE;
+ fMusicPlaying = FALSE;
uiMusicHandle = NO_SAMPLE;
- return(TRUE);
+ return TRUE;
}
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Music Stop %d %d", uiMusicHandle, gubMusicMode ) );
- return(FALSE);
+ return FALSE;
}
//********************************************************************************
@@ -227,14 +235,14 @@ BOOLEAN MusicStop(void)
// Returns: TRUE if the music has begun fading, FALSE if an error occurred
//
//********************************************************************************
-BOOLEAN MusicFadeOut(void)
+static BOOLEAN MusicFadeOut(void)
{
- if(uiMusicHandle!=NO_SAMPLE)
+ if(uiMusicHandle != NO_SAMPLE)
{
- fMusicFadingOut=TRUE;
- return(TRUE);
+ fMusicFadingOut = TRUE;
+ return TRUE;
}
- return(FALSE);
+ return FALSE;
}
//********************************************************************************
@@ -245,14 +253,14 @@ BOOLEAN MusicFadeOut(void)
// Returns: TRUE if the music has begun fading in, FALSE if an error occurred
//
//********************************************************************************
-BOOLEAN MusicFadeIn(void)
+static BOOLEAN MusicFadeIn(void)
{
- if(uiMusicHandle!=NO_SAMPLE)
+ if(uiMusicHandle != NO_SAMPLE)
{
- fMusicFadingIn=TRUE;
- return(TRUE);
+ fMusicFadingIn = TRUE;
+ return TRUE;
}
- return(FALSE);
+ return FALSE;
}
//********************************************************************************
@@ -264,7 +272,7 @@ BOOLEAN MusicFadeIn(void)
// Returns: TRUE always
//
//********************************************************************************
-BOOLEAN MusicPoll( BOOLEAN fForce )
+BOOLEAN MusicPoll(BOOLEAN /*fForce*/)
{
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll");
@@ -281,99 +289,96 @@ BOOLEAN MusicPoll( BOOLEAN fForce )
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: Handle Sound every sound overhead time");
// Handle Sound every sound overhead time....
- if ( COUNTERDONE( MUSICOVERHEAD ) )
+ if (COUNTERDONE(MUSICOVERHEAD))
{
- //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: Reset counter");
+ //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: Reset counter");
// Reset counter
- RESETCOUNTER( MUSICOVERHEAD );
+ RESETCOUNTER(MUSICOVERHEAD);
- if(fMusicFadingIn)
+ if (fMusicFadingIn)
{
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: music fading in");
- if(uiMusicHandle!=NO_SAMPLE)
+ if(uiMusicHandle != NO_SAMPLE)
{
- iVol=SoundGetVolume(uiMusicHandle);
- iVol=__min( (INT32)uiMusicVolume, iVol+gbFadeSpeed );
+ iVol = SoundGetVolume(uiMusicHandle);
+ iVol = __min( (INT32)uiMusicVolume, iVol+gbFadeSpeed );
SoundSetVolume(uiMusicHandle, iVol);
- if(iVol==(INT32)uiMusicVolume)
+ if(iVol == (INT32)uiMusicVolume)
{
- fMusicFadingIn=FALSE;
+ fMusicFadingIn = FALSE;
gbFadeSpeed = 1;
}
}
}
- else if(fMusicFadingOut)
+ else if (fMusicFadingOut)
{
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: music fading out");
- if(uiMusicHandle!=NO_SAMPLE)
+ if(uiMusicHandle != NO_SAMPLE)
{
- iVol=SoundGetVolume(uiMusicHandle);
- iVol=(iVol >=1)? iVol-gbFadeSpeed : 0;
+ iVol = SoundGetVolume(uiMusicHandle);
+ iVol = (iVol >=1)? iVol-gbFadeSpeed : 0;
- iVol=__max( (INT32)iVol, 0 );
+ iVol = __max( (INT32)iVol, 0 );
SoundSetVolume(uiMusicHandle, iVol);
- if(iVol==0)
+ if(iVol == 0)
{
MusicStop();
- fMusicFadingOut=FALSE;
+ fMusicFadingOut = FALSE;
gbFadeSpeed = 1;
}
}
}
- //#endif
-
- if ( gfMusicEnded )
+ if (gfMusicEnded)
{
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: music ended");
// OK, based on our music mode, play another!
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Music End Loop %d %d", uiMusicHandle, gubMusicMode ) );
// If we were in victory mode, change!
- if ( gbVictorySongCount == 1 || gbDeathSongCount == 1 )
+ if (gbVictorySongCount == 1 || gbDeathSongCount == 1)
{
- if ( gbDeathSongCount == 1 && guiCurrentScreen == GAME_SCREEN )
+ if (gbDeathSongCount == 1 && guiCurrentScreen == GAME_SCREEN)
{
CheckAndHandleUnloadingOfCurrentWorld();
}
- if ( gbVictorySongCount == 1 )
+ if (gbVictorySongCount == 1)
{
- SetMusicMode( MUSIC_TACTICAL_NOTHING );
+ SetMusicMode(MUSIC_TACTICAL_NOTHING);
}
}
else
{
- if ( !gfDontRestartSong )
+ if (!gfDontRestartSong)
{
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll: don't restart song, StartMusicBasedOnMode");
- StartMusicBasedOnMode( );
+ StartMusicBasedOnMode();
}
}
gfMusicEnded = FALSE;
- gfDontRestartSong = FALSE;
+ gfDontRestartSong = FALSE;
}
}
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"MusicPoll done");
- return(TRUE);
+ return TRUE;
}
-BOOLEAN SetMusicMode( UINT8 ubMusicMode )
+static BOOLEAN SetMusicMode(UINT8 ubMusicMode, BOOLEAN fForce)
{
static INT8 bPreviousMode = 0;
-
// OK, check if we want to restore
- if ( ubMusicMode == MUSIC_RESTORE )
+ if (ubMusicMode == MUSIC_RESTORE)
{
- if ( bPreviousMode == MUSIC_TACTICAL_VICTORY || bPreviousMode == MUSIC_TACTICAL_DEATH )
- {
- bPreviousMode = MUSIC_TACTICAL_NOTHING;
- }
+ if (bPreviousMode == MUSIC_TACTICAL_VICTORY || bPreviousMode == MUSIC_TACTICAL_DEATH)
+ {
+ bPreviousMode = MUSIC_TACTICAL_NOTHING;
+ }
ubMusicMode = bPreviousMode;
}
@@ -384,7 +389,7 @@ BOOLEAN SetMusicMode( UINT8 ubMusicMode )
}
// if different, start a new music song
- if ( gubOldMusicMode != ubMusicMode )
+ if (fForce || gubOldMusicMode != ubMusicMode)
{
// Set mode....
gubMusicMode = ubMusicMode;
@@ -394,108 +399,106 @@ BOOLEAN SetMusicMode( UINT8 ubMusicMode )
gbVictorySongCount = 0;
gbDeathSongCount = 0;
- if(uiMusicHandle!=NO_SAMPLE )
+ if(uiMusicHandle != NO_SAMPLE)
{
// Fade out old music
- MusicFadeOut( );
+ MusicFadeOut();
}
else
{
// Change music!
- StartMusicBasedOnMode( );
+ StartMusicBasedOnMode();
}
-
}
+
gubOldMusicMode = gubMusicMode;
- return( TRUE );
+ return TRUE;
}
-BOOLEAN StartMusicBasedOnMode( )
+static BOOLEAN StartMusicBasedOnMode(void)
{
static BOOLEAN fFirstTime = TRUE;
- if ( fFirstTime )
+ if (fFirstTime)
{
fFirstTime = FALSE;
- bNothingModeSong = (INT8) (NOTHING_A_MUSIC + Random( 4 ));
-
- bEnemyModeSong = (INT8) (TENSOR_A_MUSIC + Random( 3 ));
-
- bBattleModeSong = (INT8) (BATTLE_A_MUSIC + Random( 2 ));
-
+ bNothingModeSong = (INT8) (NOTHING_A_MUSIC + Random(4));
+ bEnemyModeSong = (INT8) (TENSOR_A_MUSIC + Random(3));
+ bBattleModeSong = (INT8) (BATTLE_A_MUSIC + Random(2));
}
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "StartMusicBasedOnMode() %d %d", uiMusicHandle, gubMusicMode ) );
// Setup a song based on mode we're in!
- switch( gubMusicMode )
+ switch(gubMusicMode)
{
case MUSIC_MAIN_MENU:
// ATE: Don't fade in
gbFadeSpeed = (INT8)uiMusicVolume;
- MusicPlay( MENUMIX_MUSIC );
+ MusicPlay(MENUMIX_MUSIC);
break;
case MUSIC_LAPTOP:
gbFadeSpeed = (INT8)uiMusicVolume;
- MusicPlay( MARIMBAD2_MUSIC );
+ MusicPlay(MARIMBAD2_MUSIC);
break;
case MUSIC_TACTICAL_NOTHING:
// ATE: Don't fade in
gbFadeSpeed = (INT8)uiMusicVolume;
- if( gfUseCreatureMusic )
+ if(gfUseCreatureMusic)
{
- MusicPlay( CREEPY_MUSIC );
+ MusicPlay(CREEPY_MUSIC);
}
else
{
- MusicPlay( bNothingModeSong );
- bNothingModeSong = (INT8) (NOTHING_A_MUSIC + Random( 4 ) );
+ MusicPlay(bNothingModeSong);
+ bNothingModeSong = (INT8) (NOTHING_A_MUSIC + Random(4));
}
break;
case MUSIC_TACTICAL_ENEMYPRESENT:
// ATE: Don't fade in EnemyPresent...
gbFadeSpeed = (INT8)uiMusicVolume;
- if( gfUseCreatureMusic )
+ if(gfUseCreatureMusic)
{
- MusicPlay( CREEPY_MUSIC );
+ MusicPlay(CREEPY_MUSIC);
}
else
{
- MusicPlay( bEnemyModeSong );
- bEnemyModeSong = (INT8) (TENSOR_A_MUSIC + Random( 3 ));
+ MusicPlay(bEnemyModeSong);
+ bEnemyModeSong = (INT8) (TENSOR_A_MUSIC + Random(3));
}
break;
case MUSIC_TACTICAL_BATTLE:
// ATE: Don't fade in
gbFadeSpeed = (INT8)uiMusicVolume;
- if( gfUseCreatureMusic )
+ if(gfUseCreatureMusic)
{
- MusicPlay( CREATURE_BATTLE_MUSIC );
+ MusicPlay(CREATURE_BATTLE_MUSIC);
}
else
{
- MusicPlay( bBattleModeSong );
+ MusicPlay(bBattleModeSong);
}
- bBattleModeSong = (INT8) (BATTLE_A_MUSIC + Random( 2 ));
+ bBattleModeSong = (INT8) (BATTLE_A_MUSIC + Random(2));
break;
case MUSIC_TACTICAL_VICTORY:
// ATE: Don't fade in EnemyPresent...
gbFadeSpeed = (INT8)uiMusicVolume;
- MusicPlay( TRIUMPH_MUSIC );
+ MusicPlay(TRIUMPH_MUSIC);
gbVictorySongCount++;
- if( gfUseCreatureMusic && !gbWorldSectorZ )
- { //We just killed all the creatures that just attacked the town.
+ if(gfUseCreatureMusic && !gbWorldSectorZ)
+ {
+ //We just killed all the creatures that just attacked the town.
gfUseCreatureMusic = FALSE;
}
break;
@@ -504,55 +507,90 @@ BOOLEAN StartMusicBasedOnMode( )
// ATE: Don't fade in EnemyPresent...
gbFadeSpeed = (INT8)uiMusicVolume;
- MusicPlay( DEATH_MUSIC );
+ MusicPlay(DEATH_MUSIC);
gbDeathSongCount++;
break;
default:
- MusicFadeOut( );
+ MusicFadeOut();
break;
}
- return( TRUE );
+ return TRUE;
}
+BOOLEAN SetMusicMode(UINT8 ubMusicMode)
+{
+ return SetMusicMode(ubMusicMode, FALSE);
+}
-void MusicStopCallback( void *pData )
+static void MusicStopCallback(void *pData)
{
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "Music EndCallback %d %d", uiMusicHandle, gubMusicMode ) );
- gfMusicEnded = TRUE;
+ gfMusicEnded = TRUE;
uiMusicHandle = NO_SAMPLE;
//DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Music EndCallback completed" );
}
-void SetMusicFadeSpeed( INT8 bFadeSpeed )
+void SetMusicFadeSpeed(INT8 bFadeSpeed)
{
gbFadeSpeed = bFadeSpeed;
}
-void FadeMusicForXSeconds( UINT32 uiDelay )
+UINT8 GetMusicMode(void)
{
- INT16 sNumTimeSteps, sNumVolumeSteps;
-
- // get # time steps in delay....
- sNumTimeSteps = (INT16)( uiDelay / 10 );
-
- // Devide this by music volume...
- sNumVolumeSteps = (INT16)( uiMusicVolume / sNumTimeSteps );
-
- // Set fade delay...
- SetMusicFadeSpeed( (INT8)sNumVolumeSteps );
+ return gubMusicMode;
}
-
-void DoneFadeOutDueToEndMusic( void )
+BOOLEAN UsingCreatureMusic(void)
{
- // Quit game....
- InternalLeaveTacticalScreen( MAINMENU_SCREEN );
- //SetPendingNewScreen( MAINMENU_SCREEN );
+ return gfUseCreatureMusic;
}
+void UseCreatureMusic(BOOLEAN fUseCreatureMusic)
+{
+ if (gfUseCreatureMusic != fUseCreatureMusic)
+ {
+ // this means a change
+ gfUseCreatureMusic = fUseCreatureMusic;
+ SetMusicMode(gubMusicMode, TRUE); // same as before
+ }
+}
+
+BOOLEAN IsMusicPlaying(void)
+{
+ return fMusicPlaying;
+}
+
+UINT32 GetMusicHandle(void)
+{
+ return uiMusicHandle;
+}
+
+// unused
+//void FadeMusicForXSeconds( UINT32 uiDelay )
+//{
+// INT16 sNumTimeSteps, sNumVolumeSteps;
+//
+// // get # time steps in delay....
+// sNumTimeSteps = (INT16)( uiDelay / 10 );
+//
+// // Devide this by music volume...
+// sNumVolumeSteps = (INT16)( uiMusicVolume / sNumTimeSteps );
+//
+// // Set fade delay...
+// SetMusicFadeSpeed( (INT8)sNumVolumeSteps );
+//}
+
+// unused
+//void DoneFadeOutDueToEndMusic( void )
+//{
+// // Quit game....
+// InternalLeaveTacticalScreen( MAINMENU_SCREEN );
+// //SetPendingNewScreen( MAINMENU_SCREEN );
+//}
+
diff --git a/Utils/Music Control.h b/Utils/Music Control.h
index 676a1f42..f6b9c16b 100644
--- a/Utils/Music Control.h
+++ b/Utils/Music Control.h
@@ -1,7 +1,8 @@
#ifndef _MUSIC_CONTROL_H_
#define _MUSIC_CONTROL_H_
-enum MusicList {
+enum MusicList
+{
MARIMBAD2_MUSIC,
MENUMIX_MUSIC,
NOTHING_A_MUSIC,
@@ -20,8 +21,8 @@ enum MusicList {
NUM_MUSIC
};
-enum MusicMode {
-
+enum MusicMode
+{
MUSIC_NONE,
MUSIC_RESTORE,
MUSIC_MAIN_MENU,
@@ -33,23 +34,34 @@ enum MusicMode {
MUSIC_LAPTOP,
};
-extern UINT32 uiMusicHandle;
-extern BOOLEAN fMusicPlaying;
-extern UINT8 gubMusicMode;
-extern BOOLEAN gfForceMusicToTense;
+//extern UINT32 uiMusicHandle;
+//extern BOOLEAN fMusicPlaying;
+//extern UINT8 gubMusicMode;
+//extern BOOLEAN gfForceMusicToTense;
+UINT8 GetMusicMode(void);
+BOOLEAN SetMusicMode(UINT8 ubMusicMode);
-BOOLEAN SetMusicMode( UINT8 ubMusicMode );
+// only for editor (editscreen.cpp)
BOOLEAN MusicPlay(UINT32 uiNum);
-BOOLEAN MusicSetVolume(UINT32 uiVolume);
+
UINT32 MusicGetVolume(void);
-BOOLEAN MusicStop(void);
-BOOLEAN MusicFadeOut(void);
-BOOLEAN MusicFadeIn(void);
-BOOLEAN MusicPoll( BOOLEAN fForce );
+BOOLEAN MusicSetVolume(UINT32 uiVolume);
-void SetMusicFadeSpeed( INT8 bFadeSpeed );
+BOOLEAN MusicPoll(BOOLEAN fForce);
-void FadeMusicForXSeconds( UINT32 uiDelay );
+void SetMusicFadeSpeed(INT8 bFadeSpeed);
+
+BOOLEAN UsingCreatureMusic(void);
+void UseCreatureMusic(BOOLEAN fUseCreatureMusic);
+
+// only for luaglobal.cpp
+BOOLEAN IsMusicPlaying(void);
+UINT32 GetMusicHandle(void);
+
+//BOOLEAN MusicStop(void);
+//BOOLEAN MusicFadeOut(void);
+//BOOLEAN MusicFadeIn(void);
+//void FadeMusicForXSeconds( UINT32 uiDelay );
#endif
diff --git a/Utils/Slider.cpp b/Utils/Slider.cpp
index ba3cd4ca..10ff5fbd 100644
--- a/Utils/Slider.cpp
+++ b/Utils/Slider.cpp
@@ -624,10 +624,10 @@ void CalculateNewSliderIncrement( UINT32 uiSliderID, UINT16 usPos )
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
- if( usPos >= (UINT16)(pSlider->usHeight * (FLOAT).99 ) )
+ if( usPos >= (UINT16)(pSlider->usHeight * 0.99f ) )
fLastSpot = TRUE;
- if( usPos <= (UINT16)(pSlider->usHeight * (FLOAT).01 ) )
+ if( usPos <= (UINT16)(pSlider->usHeight * 0.01f ) )
fFirstSpot = TRUE;
diff --git a/Utils/Text Input.cpp b/Utils/Text Input.cpp
index 768e4a61..c94d62f4 100644
--- a/Utils/Text Input.cpp
+++ b/Utils/Text Input.cpp
@@ -21,7 +21,7 @@
#include "Sound Control.h"
#endif
-#include "VFS/Tools/ParserTools.h"
+#include
STR16 szClipboard;
BOOLEAN gfNoScroll = FALSE;
diff --git a/Utils/Text.h b/Utils/Text.h
index f7e05d6f..fb192c64 100644
--- a/Utils/Text.h
+++ b/Utils/Text.h
@@ -7,6 +7,8 @@
#define STRING_LENGTH 255
+extern CHAR16 gszAimPages[ 6 ][ 20 ];
+extern CHAR16 zGrod[][500];
extern STR16 pCreditsJA2113[];
extern CHAR16 ShortItemNames[MAXITEMS][80];
extern CHAR16 ItemNames[MAXITEMS][80];
@@ -30,6 +32,7 @@ extern STR16 pAssignmentStrings[];
extern STR16 pConditionStrings[];
extern CHAR16 pTownNames[MAX_TOWNS][MAX_TOWN_NAME_LENGHT]; // Lesh: look mapscreen.h for definitions
extern STR16 pPersonnelScreenStrings[];
+extern STR16 pPersonnelRecordsHelpTexts[]; // added by SANDRO
extern STR16 pPersonnelTitle[];
extern STR16 pUpperLeftMapScreenStrings[];
extern STR16 pTacticalPopupButtonStrings[];
@@ -76,7 +79,7 @@ extern STR16 pMapScreenBorderButtonHelpText[];
extern STR16 pMapScreenBottomFastHelp[];
extern STR16 pMapScreenBottomText[];
extern STR16 pMercDeadString[];
-extern STR16 pSenderNameList[];
+extern CHAR16 pSenderNameList[500][128];
extern STR16 pTraverseStrings[];
extern STR16 pNewMailStrings[];
extern STR16 pDeleteMailStrings[];
@@ -153,6 +156,7 @@ extern STR16 pMilitiaButtonsHelpText[];
extern STR16 pMapScreenJustStartedHelpText[];
extern STR16 pLandMarkInSectorString[];
extern STR16 gzMercSkillText[];
+extern STR16 gzMercSkillTextNew[]; // added by SANDRO
extern STR16 gzNonPersistantPBIText[];
extern STR16 gzMiscString[];
@@ -172,6 +176,14 @@ extern STR16 gzIMPCharacterTraitText[];
extern STR16 gzIMPColorChoosingText[];
extern STR16 sColorChoiceExplanationTexts[];
extern STR16 gzIMPDisabilityTraitText[];
+extern STR16 sEnemyTauntsFireGun[];
+extern STR16 sEnemyTauntsFireLauncher[];
+extern STR16 sEnemyTauntsThrow[];
+extern STR16 sEnemyTauntsChargeKnife[];
+extern STR16 sEnemyTauntsRunAway[];
+extern STR16 sEnemyTauntsSeekNoise[];
+extern STR16 sEnemyTauntsAlert[];
+extern STR16 sEnemyTauntsGotHit[];
//****
// HEADROCK HAM 3.6: New arrays for facility operation messages
@@ -179,9 +191,13 @@ extern STR16 gzFacilityErrorMessage[];
extern STR16 gzFacilityAssignmentStrings[];
extern STR16 gzFacilityRiskResultStrings[];
+// HEADROCK HAM 4: Text for the new CTH indicator.
+extern STR16 gzNCTHlabels[];
+
enum
{
ANTIHACKERSTR_EXITGAME,
+ TEXT_NUM_ANTIHACKERSTR,
};
extern STR16 pAntiHackerString[];
@@ -266,8 +282,8 @@ enum
MSG_HISTORY_UPDATED,
MSG_GL_BURST_CURSOR_ON,
MSG_GL_BURST_CURSOR_OFF,
- MSG_DROP_ALL_ON,
- MSG_DROP_ALL_OFF,
+ MSG_SOLDIER_TOOLTIPS_ON, // changed by SANDRO
+ MSG_SOLDIER_TOOLTIPS_OFF, // changed by SANDRO
MSG_GL_LOW_ANGLE,
MSG_GL_HIGH_ANGLE,
MSG_FORCED_TURN_MODE,
@@ -278,8 +294,9 @@ enum
MSG_END_TURN_AUTO_SAVE,
#endif
MSG_MPSAVEDIRECTORY,//84
- MSG_CLIENT
-
+ MSG_CLIENT,
+ MSG_NAS_AND_OIV_INCOMPATIBLE,
+ TEXT_NUM_MSG,
};
extern STR16 pMessageStrings[];
@@ -357,6 +374,23 @@ enum
STR_NO_SEMI_AUTO,
STR_NO_MORE_ITEMS_TO_STEAL,
STR_NO_MORE_ITEM_IN_HAND,
+
+ //add new camo text
+ STR_DESERT_WORN_OFF,
+ STR_DESERT_WASHED_OFF,
+
+ STR_JUNGLE_WORN_OFF,
+ STR_JUNGLE_WASHED_OFF,
+
+ STR_URBAN_WORN_OFF,
+ STR_URBAN_WASHED_OFF,
+
+ STR_SNOW_WORN_OFF,
+ STR_SNOW_WASHED_OFF,
+
+ STR_CANNOT_ATTACH_SLOT,
+
+ TEXT_NUM_STR_MESSAGE,
};
// WANNE: Tooltips
@@ -399,6 +433,12 @@ enum
STR_TT_NO_VEST,
STR_TT_NO_LEGGING,
STR_TT_CAT_ARMOR_2,
+ // Following added - SANDRO
+ STR_TT_SKILL_TRAIT_1,
+ STR_TT_SKILL_TRAIT_2,
+ STR_TT_SKILL_TRAIT_3,
+
+ TEXT_NUM_STR_TT
};
#define LARGE_STRING_LENGTH 200
@@ -415,17 +455,44 @@ extern CHAR16 zTalkMenuStrings[][ SMALL_STRING_LENGTH ];
extern STR16 gzMoneyAmounts[6];
extern CHAR16 gzProsLabel[10];
extern CHAR16 gzConsLabel[10];
+// HEADROCK HAM 4: Text for the UDB tabs
+extern STR16 gzItemDescTabButtonText[ 3 ];
+extern STR16 gzItemDescTabButtonShortText[ 3 ];
+extern STR16 gzItemDescGenHeaders[ 4 ];
+extern STR16 gzItemDescGenIndexes[ 4 ];
+// HEADROCK HAM 4: Added list of condition strings
+extern STR16 gConditionDesc[ 9 ];
+
extern CHAR16 gMoneyStatsDesc[][ 13 ];
-// HEADROCK: Altered value to 16
-extern CHAR16 gWeaponStatsDesc[][ 16 ];
+// HEADROCK: Altered value to 16 //WarmSteel - And I need 17.
+extern CHAR16 gWeaponStatsDesc[][ 17 ];
// HEADROCK: Added externs for Item Description Box icon and stat tooltips
// Note that I've inflated some of these to 20 to avoid issues.
-extern STR16 gzWeaponStatsFasthelp[ 29 ];
-extern STR16 gzWeaponStatsFasthelpTactical[ 29 ];
+extern STR16 gzWeaponStatsFasthelp[ 32 ];
+extern STR16 gzWeaponStatsFasthelpTactical[ 32 ];
extern STR16 gzAmmoStatsFasthelp[ 20 ];
extern STR16 gzArmorStatsFasthelp[ 20 ];
extern STR16 gzExplosiveStatsFasthelp[ 20 ];
extern STR16 gzMiscItemStatsFasthelp[ 34 ];
+// HEADROCK HAM 4: New tooltip texts
+extern STR16 gzUDBButtonTooltipText[ 3 ];
+extern STR16 gzUDBHeaderTooltipText[ 4 ];
+extern STR16 gzUDBGenIndexTooltipText[ 4 ];
+extern STR16 gzUDBAdvIndexTooltipText[ 5 ];
+extern STR16 szUDBGenWeaponsStatsTooltipText[ 22 ];
+extern STR16 szUDBGenWeaponsStatsExplanationsTooltipText[ 22 ];
+extern STR16 szUDBGenArmorStatsTooltipText[ 3 ];
+extern STR16 szUDBGenArmorStatsExplanationsTooltipText[ 3 ];
+extern STR16 szUDBGenAmmoStatsTooltipText[ 3 ];
+extern STR16 szUDBGenAmmoStatsExplanationsTooltipText[ 3 ];
+extern STR16 szUDBGenExplosiveStatsTooltipText[ 18 ];
+extern STR16 szUDBGenExplosiveStatsExplanationsTooltipText[ 18 ];
+extern STR16 szUDBGenSecondaryStatsTooltipText[ 26 ];
+extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 26 ];
+extern STR16 szUDBAdvStatsTooltipText[ 44 ];
+extern STR16 szUDBAdvStatsExplanationsTooltipText[ 44 ];
+extern STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[ 44 ];
+
// Headrock: End Externs
extern STR16 sKeyDescriptionStrings[2];
extern CHAR16 zHealthStr[][13];
@@ -583,6 +650,7 @@ enum
NO_LOS_TO_TALK_TARGET,
ATTACHMENT_REMOVED,
VEHICLE_CAN_NOT_BE_ADDED,
+ TEXT_NUM_TACTICAL_STR
};
enum{
@@ -601,6 +669,7 @@ enum{
EXIT_GUI_SINGLE_TRAVERSAL_WILL_SEPARATE_SQUADS_HELPTEXT,
EXIT_GUI_ALL_TRAVERSAL_WILL_MOVE_CURRENT_SQUAD_HELPTEXT,
EXIT_GUI_ESCORTED_CHARACTERS_CANT_LEAVE_SECTOR_ALONE_STR,
+ TEXT_NUM_EXIT_GUI
};
extern STR16 pExitingSectorHelpText[];
@@ -610,6 +679,7 @@ enum
LARGESTR_NOONE_LEFT_CAPABLE_OF_BATTLE_STR,
LARGESTR_NOONE_LEFT_CAPABLE_OF_BATTLE_AGAINST_CREATURES_STR,
LARGESTR_HAVE_BEEN_CAPTURED,
+ TEXT_NUM_LARGESTR
};
@@ -620,6 +690,7 @@ enum
INS_CONTRACT_NEXT,
INS_CONTRACT_ACCEPT,
INS_CONTRACT_CLEAR,
+ TEXT_NUM_INS_CONTRACT
};
extern STR16 InsContractText[];
@@ -629,6 +700,7 @@ enum
{
INS_INFO_PREVIOUS,
INS_INFO_NEXT,
+ TEXT_NUM_INS_INFO,
};
extern STR16 InsInfoText[];
@@ -645,6 +717,7 @@ enum
MERC_ACCOUNT_TOTAL,
MERC_ACCOUNT_AUTHORIZE_CONFIRMATION,
MERC_ACCOUNT_NOT_ENOUGH_MONEY,
+ TEXT_NUM_MERC_ACCOUNT,
};
extern STR16 MercAccountText[];
@@ -680,6 +753,7 @@ enum
MERC_FILES_HIRE_TO_MANY_PEOPLE_WARNING,
MERC_FILES_MERC_UNAVAILABLE,
+ TEXT_NUM_MERC_FILES,
};
extern STR16 MercInfo[];
@@ -690,6 +764,7 @@ enum
MERC_NO_ACC_OPEN_ACCOUNT,
MERC_NO_ACC_CANCEL,
MERC_NO_ACC_NO_ACCOUNT_OPEN_ONE,
+ TEXT_NUM_MERC_NO_ACC,
};
extern STR16 MercNoAccountText[];
@@ -703,6 +778,7 @@ enum
MERC_VIEW_ACCOUNT,
MERC_VIEW_FILES,
MERC_SPECK_COM,
+ TEXT_NUM_MERC,
};
extern STR16 MercHomePageText[];
@@ -722,6 +798,7 @@ enum
FUNERAL_FUNERAL_ETTIQUETTE,
FUNERAL_OUR_CONDOLENCES, //10
FUNERAL_OUR_SYMPATHIES,
+ TEXT_NUM_FUNERAL,
};
extern STR16 sFuneralString[];
@@ -742,6 +819,8 @@ enum
FLORIST_ADVERTISEMENT_6,
FLORIST_ADVERTISEMENT_7,
FLORIST_ADVERTISEMENT_8,
+ FLORIST_ADVERTISEMENT_9,
+ TEXT_NUM_FLORIST,
};
extern STR16 sFloristText[];
@@ -771,6 +850,7 @@ enum
FLORIST_ORDER_STANDARDIZED_CARDS,
FLORIST_ORDER_BILLING_INFO, //20
FLORIST_ORDER_NAME,
+ TEXT_NUM_FLORIST_ORDER,
};
extern STR16 sOrderFormText[];
@@ -784,6 +864,7 @@ enum
FLORIST_GALLERY_CLICK_TO_ORDER,
FLORIST_GALLERY_ADDIFTIONAL_FEE,
FLORIST_GALLERY_HOME,
+ TEXT_NUM_FLORIST_GALLERY,
};
extern STR16 sFloristGalleryText[];
@@ -793,6 +874,7 @@ enum
{
FLORIST_CARDS_CLICK_SELECTION,
FLORIST_CARDS_BACK,
+ TEXT_NUM_FLORIST_CARDS,
};
extern STR16 sFloristCards[];
@@ -825,6 +907,7 @@ enum
BOBBYR_PACKAGE_WEIGHT,
BOBBYR_MINIMUM_WEIGHT,
BOBBYR_GOTOSHIPMENT_PAGE,
+ TEXT_NUM_BOBBYR_MAILORDER,
};
extern STR16 BobbyROrderFormText[];
@@ -871,6 +954,7 @@ enum
BOBBYR_FILTER_MISC_FACE,
BOBBYR_FILTER_MISC_LBEGEAR,
BOBBYR_FILTER_MISC_MISC,
+ TEXT_NUM_BOBBYR_FILTER
};
@@ -908,7 +992,7 @@ enum
BOBBYR_MORE_THEN_10_PURCHASES,
BOBBYR_MORE_NO_MORE_IN_STOCK,
BOBBYR_NO_MORE_STOCK,
-
+ TEXT_NUM_BOBBYR_GUNS,
};
extern STR16 BobbyRText[];
@@ -927,6 +1011,7 @@ enum
BOBBYR_ARMOR,
BOBBYR_ADVERTISMENT_3,
BOBBYR_UNDER_CONSTRUCTION,
+ TEXT_NUM_BOBBYR
};
extern STR16 BobbyRaysFrontText[];
@@ -945,7 +1030,8 @@ enum
MERCENARY_FILES,
ALUMNI_GALLERY,
ASCENDING,
- DESCENDING
+ DESCENDING,
+ TEXT_NUM_AIM_SORT
};
extern STR16 AimSortText[];
@@ -958,6 +1044,7 @@ enum
AIM_POLICIES_NEXT_PAGE,
AIM_POLICIES_DISAGREE,
AIM_POLICIES_AGREE,
+ TEXT_NUM_AIM_POLICIES
};
extern STR16 AimPolicyText[];
@@ -968,6 +1055,7 @@ extern STR16 AimPolicyText[];
enum
{
AIM_MEMBER_CLICK_INSTRUCTIONS,
+ TEXT_NUM_AIM_MEMBER_TEXT
};
extern STR16 AimMemberText[];
@@ -998,7 +1086,14 @@ enum
AIM_MEMBER_ADDTNL_INFO,
AIM_MEMBER_ACTIVE_MEMBERS, //20
AIM_MEMBER_OPTIONAL_GEAR,
+ AIM_MEMBER_OPTIONAL_GEAR_NSGI,
AIM_MEMBER_MEDICAL_DEPOSIT_REQ,
+ AIM_MEMBER_GEAR_KIT_ONE,
+ AIM_MEMBER_GEAR_KIT_TWO, //25
+ AIM_MEMBER_GEAR_KIT_THREE,
+ AIM_MEMBER_GEAR_KIT_FOUR,
+ AIM_MEMBER_GEAR_KIT_FIVE,
+ TEXT_NUM_AIM_MEMBER_CHARINFO,
};
extern STR16 CharacterInfo[];
@@ -1022,6 +1117,7 @@ enum
AIM_MEMBER_VIDEO_CONF_WITH,
AIM_MEMBER_CONNECTING,
AIM_MEMBER_WITH_MEDICAL, //14
+ TEXT_NUM_AIM_MEMBER_VCONF
};
extern STR16 VideoConfercingText[];
@@ -1040,7 +1136,7 @@ enum
AIM_MEMBER_PRERECORDED_MESSAGE,
AIM_MEMBER_MESSAGE_RECORDED,
-
+ TEXT_NUM_AIM_MEMBER_POPUP
};
extern STR16 AimPopUpText[];
@@ -1048,6 +1144,7 @@ extern STR16 AimPopUpText[];
enum
{
AIM_LINK_TITLE,
+ TEXM_NUM_AIM_LINK,
};
extern STR16 AimLinkText[];
@@ -1060,6 +1157,7 @@ enum
AIM_HISTORY_HOME,
AIM_HISTORY_AIM_ALUMNI,
AIM_HISTORY_NEXT,
+ TEXT_NUM_AIM_HISTORY,
};
extern STR16 AimHistoryText[];
@@ -1081,7 +1179,9 @@ enum
AIM_FI_RIGHT_CLICK,
AIM_FI_TO_ENTER_SORT_PAGE,
AIM_FI_AWAY,
- AIM_FI_DEAD,
+ AIM_FI_DEAD,
+ AIM_FI_ON_ASSIGN,
+ TEXT_NUM_AIM_FI,
};
extern STR16 AimFiText[];
@@ -1094,6 +1194,7 @@ enum
AIM_ALUMNI_PAGE_3,
AIM_ALUMNI_ALUMNI,
AIM_ALUMNI_DONE,
+ TEXT_NUM_AIM_ALUMNI,
};
extern STR16 AimAlumniText[];
@@ -1115,7 +1216,7 @@ enum
AIM_BOBBYR_ADD1,
AIM_BOBBYR_ADD2,
AIM_BOBBYR_ADD3,
-
+ TEXT_NUM_AIM_SCREEN
};
extern STR16 AimScreenText[];
@@ -1129,6 +1230,7 @@ enum
AIM_POLICIES,
AIM_HISTORY,
AIM_LINKS,
+ TEXT_NUM_AIM_MENU
};
extern STR16 AimBottomMenuText[];
@@ -1140,6 +1242,7 @@ enum
{
MAP_SCREEN_MAP_LEVEL,
MAP_SCREEN_NO_MILITIA_TEXT,
+ TEXT_NUM_MAP_SCREEN,
};
extern STR16 zMarksMapScreenText[];
@@ -1244,6 +1347,7 @@ enum
STR_DIALOG_CREATURES_KILL_CIVILIANS,
STR_DIALOG_ENEMIES_ATTACK_UNCONCIOUSMERCS,
STR_DIALOG_CREATURES_ATTACK_UNCONCIOUSMERCS,
+ TEXT_NUM_STRATEGIC_TEXT
};
//Strings used in conjunction with above enumerations
@@ -1252,6 +1356,7 @@ extern STR16 gpStrategicString[];
enum
{
STR_GAMECLOCK_DAY_NAME,
+ TEXT_NUM_GAMECLOCK,
};
extern STR16 gpGameClockString[];
@@ -1272,6 +1377,7 @@ enum
SKI_TEXT_NO_MORE_ROOM_IN_PLAYER_OFFER_AREA,
SKI_TEXT_MINUTES,
SKI_TEXT_DROP_ITEM_TO_GROUND,
+ TEXT_NUM_SKI_TEXT
};
extern STR16 SKI_Text[];
@@ -1307,6 +1413,7 @@ enum
SKI_ATM_MODE_TEXT_SELECT_FROM_MERC,
SKI_ATM_MODE_TEXT_SELECT_INUSUFFICIENT_FUNDS,
SKI_ATM_MODE_TEXT_BALANCE,
+ TEXT_NUM_SKI_ATM_MODE_TEXT,
};
extern STR16 gzSkiAtmText[];
@@ -1322,6 +1429,7 @@ enum
SKI_DONE_BUTTON_HELP_TEXT,
SKI_PLAYERS_CURRENT_BALANCE,
+ TEXT_NUM_SKI_MBOX_TEXT
};
extern STR16 SkiMessageBoxText[];
@@ -1362,7 +1470,9 @@ enum
SLG_BR_AWESOME_TEXT,
SLG_INV_RES_ERROR,
- SLG_INV_CUSTUM_ERROR,
+ SLG_INV_CUSTUM_ERROR,
+
+ TEXT_NUM_SLG_TEXT,
};
extern STR16 zSaveLoadText[];
@@ -1383,6 +1493,7 @@ enum
OPT_MUSIC,
OPT_RETURN_TO_MAIN,
OPT_NEED_AT_LEAST_SPEECH_OR_SUBTITLE_OPTION_ON,
+ TEXT_NUM_OPT_TEXT,
};
extern STR16 zOptionsText[];
@@ -1400,7 +1511,7 @@ enum
MONEY_DESC_BALANCE,
MONEY_DESC_AMOUNT_2_WITHDRAW,
MONEY_DESC_TO_WITHDRAW,
-
+ TEXT_NUM_MONEY_DESC,
};
@@ -1409,6 +1520,7 @@ enum
{
MONEY_TEXT_WITHDRAW_MORE_THEN_MAXIMUM,
CONFIRMATION_TO_DEPOSIT_MONEY_TO_ACCOUNT,
+ TEXT_NUM_MONEY_WITHDRAW
};
@@ -1433,7 +1545,7 @@ enum
GIO_HARD_TEXT,
GIO_INSANE_TEXT,
- GIO_OK_TEXT,
+ GIO_START_TEXT,
GIO_CANCEL_TEXT,
GIO_GAME_SAVE_STYLE_TEXT,
@@ -1452,6 +1564,41 @@ enum
GIO_INV_NEW_TEXT,
GIO_LOAD_MP_GAME,
GIO_INITIAL_GAME_SETTINGS_MP,
+ ////////////////////////////////////
+ // SANDRO - added following
+ GIO_TRAITS_TEXT,
+ GIO_TRAITS_OLD_TEXT,
+ GIO_TRAITS_NEW_TEXT,
+ GIO_IMP_NUMBER_TITLE_TEXT,
+ GIO_IMP_NUMBER_1,
+ GIO_IMP_NUMBER_2,
+ GIO_IMP_NUMBER_3,
+ GIO_IMP_NUMBER_4,
+ GIO_IMP_NUMBER_5,
+ GIO_IMP_NUMBER_6,
+ GIO_DROPALL_TITLE_TEXT,
+ GIO_DROPALL_OFF_TEXT,
+ GIO_DROPALL_ON_TEXT,
+ GIO_TERRORISTS_TITLE_TEXT,
+ GIO_TERRORISTS_RANDOM_TEXT,
+ GIO_TERRORISTS_ALL_TEXT,
+ GIO_CACHES_TITLE_TEXT,
+ GIO_CACHES_RANDOM_TEXT,
+ GIO_CACHES_ALL_TEXT,
+ GIO_PROGRESS_TITLE_TEXT,
+ GIO_PROGRESS_VERY_SLOW_TEXT,
+ GIO_PROGRESS_SLOW_TEXT,
+ GIO_PROGRESS_NORMAL_TEXT,
+ GIO_PROGRESS_FAST_TEXT,
+ GIO_PROGRESS_VERY_FAST_TEXT,
+
+ // WANNE: New strings for start new game screen (for NAS)
+ GIO_INV_SETTING_OLD_TEXT,
+ GIO_INV_SETTING_NEW_TEXT,
+ GIO_INV_SETTING_NEW_NAS_TEXT,
+
+ ////////////////////////////////////
+ TEXT_NUM_GIO_TEXT
};
extern STR16 gzGIOScreenText[];
@@ -1474,9 +1621,12 @@ enum
MPJ_PING_TEXT,
MPJ_HANDLE_INVALID,
MPJ_SERVERIP_INVALID,
- MPJ_SERVERPORT_INVALID
+ MPJ_SERVERPORT_INVALID,
+ TEXT_NUM_MPJ_TEXT
};
+extern STR16 gzMPJHelpText[];
+
extern STR16 gzMPJScreenText[];
//Multiplayer Host Screen
enum
@@ -1512,11 +1662,40 @@ enum
MPH_ENABLECIV_TEXT,
MPH_USENIV_TEXT,
MPH_OVERRIDEMAXAI_TEXT,
- MPH_SYNC_CLIENT_MP_DIR,
+ MPH_SYNC_GAME_DIRECTORY,
MPH_FILE_TRANSFER_DIR_TEXT,
MPH_FILE_TRANSFER_DIR_INVALID,
MPH_FILE_TRANSFER_DIR_TEXT_ADDITIONAL,
MPH_FILE_TRANSFER_DIR_NOT_EXIST,
+ MPH_1,
+ MPH_2,
+ MPH_3,
+ MPH_4,
+ MPH_5,
+ MPH_6,
+ MPH_YES,
+ MPH_NO,
+ MPH_MORNING,
+ MPH_AFTERNOON,
+ MPH_NIGHT,
+ MPH_CASH_LOW,
+ MPH_CASH_MEDIUM,
+ MPH_CASH_HIGH,
+ MPH_CASH_UNLIMITED,
+ MPH_TIME_NEVER,
+ MPH_TIME_SLOW,
+ MPH_TIME_MEDIUM,
+ MPH_TIME_FAST,
+ MPH_DAMAGE_VERYLOW,
+ MPH_DAMAGE_LOW,
+ MPH_DAMAGE_NORMAL,
+ MPH_HIRE_RANDOM,
+ MPH_HIRE_NORMAL,
+ MPH_EDGE_RANDOM,
+ MPH_EDGE_SELECTABLE,
+ MPH_DISABLE,
+ MPH_ALLOW,
+ TEXT_NUM_MPH_TEXT,
};
extern STR16 gzMPHScreenText[];
enum
@@ -1533,7 +1712,8 @@ enum
MPS_ACCURACY_TEXT,
MPS_DMGDONE_TEXT,
MPS_DMGTAKEN_TEXT,
- MPS_WAITSERVER_TEXT
+ MPS_WAITSERVER_TEXT,
+ TEXT_NUM_MPS_TEXT,
};
extern STR16 gzMPSScreenText[];
enum
@@ -1545,6 +1725,7 @@ enum
MPC_HELP1_TEXT,
MPC_HELP2_TEXT,
MPC_READY_TEXT,
+ TEXT_NUM_MPC_TEXT,
};
extern STR16 gzMPCScreenText[];
// Multiplayer Starting Edges
@@ -1594,7 +1775,7 @@ enum
BOOKMARK_TEXT_MCGILLICUTTY_MORTUARY,
BOOKMARK_TEXT_UNITED_FLORAL_SERVICE,
BOOKMARK_TEXT_INSURANCE_BROKERS_FOR_AIM_CONTRACTS,
-
+ TEXT_NUM_LAPTOP_BN_BOOKMARK_TEXT
};
@@ -1602,6 +1783,7 @@ enum
enum
{
HLP_SCRN_TXT__EXIT_SCREEN,
+ TEXT_NUM_HLP
};
extern STR16 gzHelpScreenText[];
@@ -1623,6 +1805,7 @@ enum
MAPINV_CANT_PICKUP_IN_COMBAT,
MAPINV_CANT_DROP_IN_COMBAT,
MAPINV_NOT_IN_SECTOR_TO_DROP,
+ TEXT_NUM_MAPINV
};
@@ -1631,6 +1814,7 @@ enum
{
BROKEN_LINK_TXT_ERROR_404,
BROKEN_LINK_TXT_SITE_NOT_FOUND,
+ TEXT_NUM_BROKEN_LINK,
};
extern STR16 BrokenLinkText[];
@@ -1641,6 +1825,7 @@ enum
BOBBYR_SHIPMENT__ORDER_NUM,
BOBBYR_SHIPMENT__NUM_ITEMS,
BOBBYR_SHIPMENT__ORDERED_ON,
+ TEXT_NUM_BOBBYR_SHIPMENT,
};
extern STR16 gzBobbyRShipmentText[];
@@ -1652,6 +1837,7 @@ enum
GIO_CFS_EXPERIENCED,
GIO_CFS_EXPERT,
GIO_CFS_INSANE,
+ TEXT_NUM_GIO_CFS,
};
extern STR16 zGioDifConfirmText[];
@@ -1691,6 +1877,8 @@ extern STR16 New113Message[];
extern STR16 New113MERCMercMailTexts[];
extern STR16 MissingIMPSkillsDescriptions[];
+extern STR16 New113AIMMercMailTexts[]; // WANNE: new WF Merc text, that does not exist in Email.edt
+
// HEADROCK: HAM Messages
extern STR16 New113HAMMessage[];
enum
@@ -1719,6 +1907,24 @@ enum
MSG113_RTM_SNEAKING_OFF,
MSG113_RTM_SNEAKING_ON,
MSG113_RTM_ENEMIES_SPOOTED,
+ // added by SANDRO
+ MSG113_THIEF_SUCCESSFUL,
+ MSG113_NOT_ENOUGH_APS_TO_STEAL_ALL,
+ MSG113_DO_WE_WANT_SURGERY_FIRST,
+ MSG113_DO_WE_WANT_SURGERY,
+ MSG113_SURGERY_BEFORE_DOCTOR_ASSIGNMENT,
+ MSG113_SURGERY_BEFORE_PATIENT_ASSIGNMENT,
+ MSG113_SURGERY_ON_TACTICAL_AUTOBANDAGE,
+ MSG113_SURGERY_FINISHED,
+ MSG113_LOSES_ONE_POINT_MAX_HEALTH,
+ MSG113_LOSES_X_POINTS_MAX_HEALTH,
+ MSG113_REGAINED_ONE_POINTS_OF_STAT,
+ MSG113_REGAINED_X_POINTS_OF_STATS,
+ MSG113_ENEMY_AMBUSH_PREVENTED,
+ MSG113_BLOODCATS_AMBUSH_PREVENTED,
+ MSG113_SOLDIER_HIT_TO_GROIN,
+
+ TEXT_NUM_MSG113,
};
//CHRISL: NewInv messages
@@ -1727,7 +1933,6 @@ extern STR16 NewInvMessage[];
// WANNE - MP: New multiplayer messages
extern STR16 MPServerMessage[];
extern STR16 MPClientMessage[];
-extern STR16 MPHelp[];
// WANNE: Some Chinese specific strings that needs to be in unicode!
extern STR16 ChineseSpecString1;
@@ -1748,6 +1953,7 @@ enum
NIV_SELL_ALL,
NIV_DELETE_ALL,
NIV_NO_CLIMB,
+ TEXT_NUM_NIV,
};
// OJW - MP
diff --git a/Utils/Utils_VS2005.vcproj b/Utils/Utils_VS2005.vcproj
new file mode 100644
index 00000000..bdabfabc
--- /dev/null
+++ b/Utils/Utils_VS2005.vcproj
@@ -0,0 +1,755 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Utils/Utils_VS2008.vcproj b/Utils/Utils_VS2008.vcproj
index f2a3fd2b..fafecee4 100644
--- a/Utils/Utils_VS2008.vcproj
+++ b/Utils/Utils_VS2008.vcproj
@@ -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"
>
@@ -148,7 +148,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"
>
@@ -213,7 +213,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"
>
@@ -378,6 +378,14 @@
RelativePath="Animated ProgressBar.h"
>
+
+
+
+
@@ -406,14 +414,26 @@
RelativePath="Event Pump.h"
>
+
+
+
+
+
+
@@ -490,10 +510,18 @@
RelativePath="WordWrap.h"
>
+
+
+
+
@@ -578,6 +606,10 @@
RelativePath="Animated ProgressBar.cpp"
>
+
+
@@ -606,14 +638,26 @@
RelativePath="Event Pump.cpp"
>
+
+
+
+
+
+
@@ -690,6 +734,10 @@
RelativePath="XML_Items.cpp"
>
+
+
diff --git a/Utils/Utils_VS2010.vcxproj b/Utils/Utils_VS2010.vcxproj
new file mode 100644
index 00000000..b578f2b2
--- /dev/null
+++ b/Utils/Utils_VS2010.vcxproj
@@ -0,0 +1,315 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {082F6E91-D049-4314-BE9D-D9509E853B01}
+ Win32Proj
+ Utils
+ Utils
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Utils/Utils_VS2010.vcxproj.filters b/Utils/Utils_VS2010.vcxproj.filters
new file mode 100644
index 00000000..0acf8db6
--- /dev/null
+++ b/Utils/Utils_VS2010.vcxproj.filters
@@ -0,0 +1,321 @@
+
+
+
+
+ {85134125-f317-490e-9a9d-d210267ff98b}
+
+
+ {2c5f371b-8372-46d7-8b88-8c1885ddf7ef}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Utils/XMLProperties.cpp b/Utils/XMLProperties.cpp
index ddbeacbd..b75f3b92 100644
--- a/Utils/XMLProperties.cpp
+++ b/Utils/XMLProperties.cpp
@@ -1,12 +1,16 @@
+#include
+#include
+#include
+#include
+
+#include
+#include
+
#include "XML_Parser.h"
-#include "vfs_types.h"
-#include "PropertyContainer.h"
#include "XMLWriter.h"
+#include "Debug.h"
-#include "VFS/vfs_file_raii.h"
-#include "VFS/File/vfs_file.h"
-
-CPropertyContainer::TagMap::TagMap()
+vfs::PropertyContainer::TagMap::TagMap()
{
// setup default map
_map[L"Container"] = L"Container";
@@ -15,7 +19,7 @@ CPropertyContainer::TagMap::TagMap()
_map[L"Key"] = L"Key";
_map[L"KeyID"] = L"name";
}
-utf8string const& CPropertyContainer::TagMap::container(utf8string::char_t* container)
+vfs::String const& vfs::PropertyContainer::TagMap::container(vfs::String::char_t* container)
{
if(container)
{
@@ -23,7 +27,7 @@ utf8string const& CPropertyContainer::TagMap::container(utf8string::char_t* cont
}
return _map[L"Container"];
}
-utf8string const& CPropertyContainer::TagMap::section(utf8string::char_t* section)
+vfs::String const& vfs::PropertyContainer::TagMap::section(vfs::String::char_t* section)
{
if(section)
{
@@ -31,7 +35,7 @@ utf8string const& CPropertyContainer::TagMap::section(utf8string::char_t* sectio
}
return _map[L"Section"];
}
-utf8string const& CPropertyContainer::TagMap::sectionID(utf8string::char_t* section_id)
+vfs::String const& vfs::PropertyContainer::TagMap::sectionID(vfs::String::char_t* section_id)
{
if(section_id)
{
@@ -39,7 +43,7 @@ utf8string const& CPropertyContainer::TagMap::sectionID(utf8string::char_t* sect
}
return _map[L"SectionID"];
}
-utf8string const& CPropertyContainer::TagMap::key(utf8string::char_t* key)
+vfs::String const& vfs::PropertyContainer::TagMap::key(vfs::String::char_t* key)
{
if(key)
{
@@ -47,7 +51,7 @@ utf8string const& CPropertyContainer::TagMap::key(utf8string::char_t* key)
}
return _map[L"Key"];
}
-utf8string const& CPropertyContainer::TagMap::keyID(utf8string::char_t* key_id)
+vfs::String const& vfs::PropertyContainer::TagMap::keyID(vfs::String::char_t* key_id)
{
if(key_id)
{
@@ -56,7 +60,7 @@ utf8string const& CPropertyContainer::TagMap::keyID(utf8string::char_t* key_id)
return _map[L"KeyID"];
}
-bool CPropertyContainer::writeToXMLFile(vfs::Path const& sFileName, CPropertyContainer::TagMap& tagmap)
+bool vfs::PropertyContainer::writeToXMLFile(vfs::Path const& sFileName, vfs::PropertyContainer::TagMap& tagmap)
{
XMLWriter xmlw;
@@ -68,8 +72,8 @@ bool CPropertyContainer::writeToXMLFile(vfs::Path const& sFileName, CPropertyCon
xmlw.addAttributeToNextValue(tagmap.sectionID(),sit->first.utf8());
xmlw.openNode(tagmap.section());
- CPropertyContainer::CSection& section = sit->second;
- CPropertyContainer::CSection::tProps::iterator kit = section.mapProps.begin();
+ vfs::PropertyContainer::Section& section = sit->second;
+ vfs::PropertyContainer::Section::tProps::iterator kit = section.mapProps.begin();
for(; kit != section.mapProps.end(); ++kit)
{
xmlw.addAttributeToNextValue(tagmap.keyID(), kit->first.utf8());
@@ -99,11 +103,11 @@ class CPropertyXMLParser : public IXMLParser
};
public:
CPropertyXMLParser(
- CPropertyContainer& container,
- CPropertyContainer::TagMap& tagmap,
+ vfs::PropertyContainer& container,
+ vfs::PropertyContainer::TagMap& tagmap,
XML_Parser &parser,
IXMLParser* caller = NULL)
- : IXMLParser("",parser,caller),
+ : IXMLParser("",&parser,caller),
_container(container),
_tagmap(tagmap),
current_state(DO_ELEMENT_NONE) // doesn't matter where we come from, we start fresh
@@ -112,27 +116,27 @@ public:
virtual void onEndElement(const XML_Char* name);
virtual void onTextElement(const XML_Char *str, int len);
private:
- CPropertyContainer& _container;
- CPropertyContainer::TagMap& _tagmap;
+ vfs::PropertyContainer& _container;
+ vfs::PropertyContainer::TagMap& _tagmap;
DOM_OBJECT current_state;
- utf8string current_section;
- utf8string current_key;
+ vfs::String current_section;
+ vfs::String current_key;
};
void CPropertyXMLParser::onStartElement(const XML_Char *name, const XML_Char **atts)
{
- utf8string utf8_name(name);
- if(current_state == DO_ELEMENT_NONE && StrCmp::Equal(utf8_name,_tagmap.container()))
+ vfs::String utf8_name(name);
+ if(current_state == DO_ELEMENT_NONE && vfs::StrCmp::Equal(utf8_name,_tagmap.container()))
{
current_state = DO_ELEMENT_Container;
}
- else if(current_state == DO_ELEMENT_Container && StrCmp::Equal(utf8_name, _tagmap.section()))
+ else if(current_state == DO_ELEMENT_Container && vfs::StrCmp::Equal(utf8_name, _tagmap.section()))
{
current_state = DO_ELEMENT_Section;
current_section = this->getAttribute(_tagmap.sectionID().utf8().c_str(),atts);
}
- else if(current_state == DO_ELEMENT_Section && StrCmp::Equal(utf8_name, _tagmap.key()))
+ else if(current_state == DO_ELEMENT_Section && vfs::StrCmp::Equal(utf8_name, _tagmap.key()))
{
current_state = DO_ELEMENT_Key;
current_key = this->getAttribute(_tagmap.keyID().utf8().c_str(),atts);
@@ -142,17 +146,17 @@ void CPropertyXMLParser::onStartElement(const XML_Char *name, const XML_Char **a
void CPropertyXMLParser::onEndElement(const XML_Char* name)
{
- utf8string utf8_name(name);
- if(current_state == DO_ELEMENT_Key && StrCmp::Equal(utf8_name, _tagmap.key()))
+ vfs::String utf8_name(name);
+ if(current_state == DO_ELEMENT_Key && vfs::StrCmp::Equal(utf8_name, _tagmap.key()))
{
_container.setStringProperty(current_section, current_key, vfs::trimString(sCharData,0,sCharData.length()));
current_state = DO_ELEMENT_Section;
}
- else if(current_state == DO_ELEMENT_Section && StrCmp::Equal(utf8_name, _tagmap.section()))
+ else if(current_state == DO_ELEMENT_Section && vfs::StrCmp::Equal(utf8_name, _tagmap.section()))
{
current_state = DO_ELEMENT_Container;
}
- else if(current_state == DO_ELEMENT_Container && StrCmp::Equal(utf8_name, _tagmap.container()))
+ else if(current_state == DO_ELEMENT_Container && vfs::StrCmp::Equal(utf8_name, _tagmap.container()))
{
current_state = DO_ELEMENT_NONE;
}
@@ -166,25 +170,23 @@ void CPropertyXMLParser::onTextElement(const XML_Char *str, int len)
}
}
-bool CPropertyContainer::initFromXMLFile(vfs::Path const& sFileName, CPropertyContainer::TagMap& tagmap)
+bool vfs::PropertyContainer::initFromXMLFile(vfs::Path const& sFileName, vfs::PropertyContainer::TagMap& tagmap)
{
vfs::tReadableFile *file = NULL;
bool delete_file = false;
- try
+ if(getVFS()->fileExists(sFileName))
{
vfs::COpenReadFile rfile(sFileName);
file = &rfile.file();
rfile.release();
}
- catch(CBasicException& ex)
+ else
{
- logException(ex);
vfs::CFile* rfile = new vfs::CFile(sFileName);
delete_file = true;
file = vfs::tReadableFile::cast(rfile);
if(!file->openRead())
{
- file->close();
delete file;
return false;
}
@@ -198,7 +200,7 @@ bool CPropertyContainer::initFromXMLFile(vfs::Path const& sFileName, CPropertyCo
std::vector buffer(size+1);
- TRYCATCH_RETHROW( file->read(&buffer[0],size), L"" );
+ SGP_TRYCATCH_RETHROW( file->read(&buffer[0],size), L"" );
buffer[size] = 0;
file->close();
@@ -213,10 +215,10 @@ bool CPropertyContainer::initFromXMLFile(vfs::Path const& sFileName, CPropertyCo
{
std::wstringstream wss;
wss << L"XML Parser Error in Groups.xml: "
- << utf8string::as_utf16(XML_ErrorString(XML_GetErrorCode(parser)))
+ << vfs::String::as_utf16(XML_ErrorString(XML_GetErrorCode(parser)))
<< L" at line "
<< XML_GetCurrentLineNumber(parser);
- THROWEXCEPTION(wss.str().c_str());
+ SGP_THROW(wss.str().c_str());
//return false;
}
diff --git a/Utils/XMLWriter.cpp b/Utils/XMLWriter.cpp
index 0a860f51..8b1c407a 100644
--- a/Utils/XMLWriter.cpp
+++ b/Utils/XMLWriter.cpp
@@ -1,21 +1,30 @@
#include "XMLWriter.h"
+#include "sgp_logger.h"
-#include "VFS/vfs_file_raii.h"
-#include "VFS/File/vfs_file.h"
+#include
+#include
-void XMLWriter::addValue(utf8string const& key)
+void XMLWriter::addValue(vfs::String const& key)
{
m_ssBuffer << indent() << "<" << key.utf8();
insertAttributesIntoBuffer();
m_ssBuffer << " />\n";
}
-void XMLWriter::addComment(utf8string const& comment)
+void XMLWriter::addComment(vfs::String const& comment)
{
m_ssBuffer << indent() << "\n";
}
-void XMLWriter::openNode(utf8string const& key)
+void XMLWriter::addFlag(UINT32 const& flags, UINT32 const& flag, vfs::String strFlag)
+{
+ if( ( flags & flag) == flag )
+ {
+ this->addValue(strFlag);
+ }
+}
+
+void XMLWriter::openNode(vfs::String const& key)
{
std::string utf8key = key.utf8();
m_ssBuffer << indent() << "<" << utf8key;
@@ -49,9 +58,9 @@ bool XMLWriter::writeToFile(vfs::Path const& sFileName)
vfs::COpenWriteFile file(sFileName,true,true);
return writeToFile( &file.file() );
}
- catch(CBasicException& ex)
+ catch(vfs::Exception& ex)
{
- logException(ex);
+ SGP_ERROR(ex.what());
vfs::CFile file(sFileName);
if(file.openWrite(true,true))
{
@@ -70,9 +79,9 @@ bool XMLWriter::writeToFile(vfs::tWritableFile* pFile)
pFile->write(str.c_str(), str.length() * sizeof(std::string::value_type));
return true;
}
- catch(CBasicException& ex)
+ catch(vfs::Exception& ex)
{
- logException(ex);
+ SGP_ERROR(ex.what());
return false;
}
}
diff --git a/Utils/XMLWriter.h b/Utils/XMLWriter.h
index 7ca99930..0825b03e 100644
--- a/Utils/XMLWriter.h
+++ b/Utils/XMLWriter.h
@@ -2,8 +2,8 @@
#define _XMLWRITER_H_
#include "FileMan.h"
-#include "VFS/Interface/vfs_file_interface.h"
-#include "utf8string.h"
+#include
+#include
#include
#include
@@ -23,7 +23,7 @@ public:
{};
template
- void addAttributeToNextValue(utf8string const& attribute, ValueType const& value)
+ void addAttributeToNextValue(vfs::String const& attribute, ValueType const& value)
{
std::stringstream temp_buffer;
temp_buffer << value;
@@ -31,27 +31,28 @@ public:
}
template
- void addValue(utf8string const& key, ValueType const& value)
+ void addValue(vfs::String const& key, ValueType const& value)
{
std::string utf8key = key.utf8();
m_ssBuffer << indent() << "<" << utf8key;
insertAttributesIntoBuffer();
- m_ssBuffer << "> " << value << " " << utf8key << ">\n";
+ m_ssBuffer << ">" << value << "" << utf8key << ">\n";
}
template<>
- void addValue(utf8string const& key, std::string const& value)
+ void addValue(vfs::String const& key, std::string const& value)
{
std::string utf8key = key.utf8();
m_ssBuffer << indent() << "<" << utf8key;
insertAttributesIntoBuffer();
- m_ssBuffer << "> " << handleSpecialCharacters(value) << " " << utf8key << ">\n";
+ m_ssBuffer << ">" << handleSpecialCharacters(value) << "" << utf8key << ">\n";
}
- void addValue(utf8string const& key);
- void addComment(utf8string const& comment);
+ void addValue(vfs::String const& key);
+ void addComment(vfs::String const& comment);
+ void addFlag(UINT32 const& flags, UINT32 const& flag, vfs::String strFlag);
- void openNode(utf8string const& key);
+ void openNode(vfs::String const& key);
bool closeNode();
bool writeToFile(vfs::Path const& sFileName);
diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp
index 684b9ccf..b818f2ce 100644
--- a/Utils/XML_Items.cpp
+++ b/Utils/XML_Items.cpp
@@ -54,6 +54,7 @@ struct
INVTYPE curItem;
INVTYPE * curArray;
UINT32 maxArraySize;
+ INT8 curStance;
UINT32 currentDepth;
UINT32 maxReadDepth;
@@ -62,6 +63,9 @@ typedef itemParseData;
BOOLEAN localizedTextOnly;
+// HEADROCK HAM 4: Inherits data between stance-based modifiers
+void InheritStanceModifiers( itemParseData *pData );
+
static void XMLCALL
itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
@@ -86,6 +90,28 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
if ( !localizedTextOnly )
memset(&pData->curItem,0,sizeof(INVTYPE));
+ // HEADROCK HAM 4: With the new stance-based variables, it is necessary to set vars to have an impossible
+ // value. That way when they are later recorded in the item structs, a parent->child inheritence can occur
+ // for children that do not have data put into them from XML.
+ // -10000 has been selected to pose as "no value". Modders should never even reduce the value of any of
+ // these tags below -100 anyway, and although it's not the best solution that's the only one I came up with.
+
+ for (INT8 X = 0; X < 3; X++)
+ {
+ pData->curItem.flatbasemodifier[X] = -10000;
+ pData->curItem.percentbasemodifier[X] = -10000;
+ pData->curItem.flataimmodifier[X] = -10000;
+ pData->curItem.percentaimmodifier[X] = -10000;
+ pData->curItem.percentcapmodifier[X] = -10000;
+ pData->curItem.percenthandlingmodifier[X] = -10000;
+ pData->curItem.targettrackingmodifier[X] = -10000;
+ pData->curItem.percentdropcompensationmodifier[X] = -10000;
+ pData->curItem.maxcounterforcemodifier[X] = -10000;
+ pData->curItem.counterforceaccuracymodifier[X] = -10000;
+ pData->curItem.counterforcefrequencymodifier[X] = -10000;
+ pData->curItem.aimlevelsmodifier[X] = -10000;
+ }
+
pData->maxReadDepth++; //we are not skipping this element
}
else if(pData->curElement == ELEMENT &&
@@ -96,6 +122,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "szBRName") == 0 ||
strcmp(name, "szBRDesc") == 0 ||
strcmp(name, "usItemClass") == 0 ||
+ strcmp(name, "nasAttachmentClass") == 0 ||
+ strcmp(name, "nasLayoutClass") == 0 ||
strcmp(name, "ubClassIndex") == 0 ||
strcmp(name, "ubCursor") == 0 ||
strcmp(name, "bSoundType") == 0 ||
@@ -213,15 +241,68 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "StealthBonus") == 0 ||
strcmp(name, "SciFi") == 0 ||
strcmp(name, "NewInv") == 0 ||
+ strcmp(name, "AttachmentSystem") == 0 ||
//zilpin: pellet spread patterns externalized in XML
strcmp(name, "spreadPattern") == 0 ||
- strcmp(name, "fFlags") == 0 ))
+ // HEADROCK HAM 4: new NCTH variables.
+ strcmp(name, "ScopeMagFactor") == 0 ||
+ strcmp(name, "ProjectionFactor") == 0 ||
+ strcmp(name, "PercentAccuracyModifier") == 0 ||
+ strcmp(name, "RecoilModifierX") == 0 ||
+ strcmp(name, "RecoilModifierY") == 0 ||
+ strcmp(name, "PercentRecoilModifier") == 0 ||
+
+ strcmp(name, "fFlags") == 0 ))
{
pData->curElement = ELEMENT_PROPERTY;
//DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) );
pData->maxReadDepth++; //we are not skipping this element
}
+ // HEADROCK HAM 4: New depth: Stance-based variables
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "STAND_MODIFIERS") == 0 ||
+ strcmp(name, "CROUCH_MODIFIERS") == 0 ||
+ strcmp(name, "PRONE_MODIFIERS") == 0))
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+
+ // Set current stance.
+ if (strcmp(name, "STAND_MODIFIERS") == 0)
+ {
+ pData->curStance = 0;
+ }
+ else if (strcmp(name, "CROUCH_MODIFIERS") == 0)
+ {
+ pData->curStance = 1;
+ }
+ else // prone
+ {
+ pData->curStance = 2;
+ }
+
+ pData->maxReadDepth++;
+ }
+
+ // HEADROCK HAM 4: Read stance-based variables
+ else if(pData->curElement == ELEMENT_SUBLIST &&
+ (strcmp(name, "FlatBase") == 0 ||
+ strcmp(name, "PercentBase") == 0 ||
+ strcmp(name, "FlatAim") == 0 ||
+ strcmp(name, "PercentAim") == 0 ||
+ strcmp(name, "PercentCap") == 0 ||
+ strcmp(name, "PercentHandling") == 0 ||
+ strcmp(name, "PercentTargetTrackingSpeed") == 0 ||
+ strcmp(name, "PercentDropCompensation") == 0 ||
+ strcmp(name, "PercentMaxCounterForce") == 0 ||
+ strcmp(name, "PercentCounterForceAccuracy") == 0 ||
+ strcmp(name, "PercentCounterForceFrequency") == 0 ||
+ strcmp(name, "AimLevels") == 0))
+ {
+ pData->curElement = ELEMENT_SUBLIST_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
pData->szCharData[0] = '\0';
}
@@ -264,7 +345,12 @@ itemEndElementHandle(void *userData, const XML_Char *name)
if(pData->curItem.uiIndex < pData->maxArraySize)
{
if ( pData->curItem.usItemClass != 0 )
+ {
+ // HEADROCK HAM 4: Inherit stance-base modifiers upwards.
+ InheritStanceModifiers( pData );
+
pData->curArray[pData->curItem.uiIndex] = pData->curItem; //write the item into the table
+ }
else if ( sizeof(pData->curItem.szItemName)>0 && localizedTextOnly )
{
wcscpy(pData->curArray[pData->curItem.uiIndex].szItemName,pData->curItem.szItemName);
@@ -429,6 +515,16 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.usItemClass = (UINT32) atol(pData->szCharData);
}
+ else if(strcmp(name, "nasAttachmentClass") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.nasAttachmentClass = (UINT32) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "nasLayoutClass") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.nasLayoutClass = (UINT32) atol(pData->szCharData);
+ }
else if(strcmp(name, "ubClassIndex") == 0)
{
pData->curElement = ELEMENT;
@@ -767,6 +863,11 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.newinv = (BOOLEAN) atol(pData->szCharData);
}
+ else if(strcmp(name, "AttachmentSystem") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.ubAttachmentSystem = (UINT8) atol(pData->szCharData);
+ }
else if(strcmp(name, "HideMuzzleFlash") == 0)
{
pData->curElement = ELEMENT;
@@ -840,7 +941,12 @@ itemEndElementHandle(void *userData, const XML_Char *name)
else if(strcmp(name, "DefaultAttachment") == 0)
{
pData->curElement = ELEMENT;
- pData->curItem.defaultattachment = (UINT16) atol(pData->szCharData);
+ for(UINT8 cnt = 0; cnt < MAX_DEFAULT_ATTACHMENTS; cnt++){
+ if(pData->curItem.defaultattachments[cnt] == 0){
+ pData->curItem.defaultattachments[cnt] = (UINT16) atol(pData->szCharData);
+ break;
+ }
+ }
}
else if(strcmp(name, "BrassKnuckles") == 0)
{
@@ -1028,12 +1134,118 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curItem.bestlaserrange = (INT16) atol(pData->szCharData);
}
//zilpin: pellet spread patterns externalized in XML
- else if(strcmp(name, "spreadPattern") == 0)
+ if(strcmp(name, "spreadPattern") == 0)
{
pData->curElement = ELEMENT;
pData->curItem.spreadPattern = FindSpreadPatternIndex( pData->szCharData );
}
+ //////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Read new variables from XML
+ else if(strcmp(name, "ScopeMagFactor") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.scopemagfactor = (FLOAT) atof(pData->szCharData);
+ }
+ else if(strcmp(name, "ProjectionFactor") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.projectionfactor = (FLOAT) atof(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentAccuracyModifier") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.percentaccuracymodifier = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RecoilModifierX") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.RecoilModifierX = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "RecoilModifierY") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.RecoilModifierY = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentRecoilModifier") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curItem.PercentRecoilModifier = (INT16) atol(pData->szCharData);
+ }
+
+
+ //////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Read stance-based variables and put them into the right place.
+ else if(strcmp(name, "FlatBase") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.flatbasemodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentBase") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.percentbasemodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "FlatAim") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.flataimmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentAim") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.percentaimmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentCap") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.percentcapmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentHandling") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.percenthandlingmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentTargetTrackingSpeed") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.targettrackingmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentDropCompensation") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.percentdropcompensationmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentMaxCounterForce") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.maxcounterforcemodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentCounterForceAccuracy") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.counterforceaccuracymodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "PercentCounterForceFrequency") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.counterforcefrequencymodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "AimLevels") == 0)
+ {
+ pData->curElement = ELEMENT_SUBLIST;
+ pData->curItem.aimlevelsmodifier[pData->curStance] = (INT16) atol(pData->szCharData);
+ }
+
+ //////////////////////////////////////////////////////////////////
+ // HEADROCK HAM 4: Close opened Stance Tags.
+ else if(strcmp(name, "STAND_MODIFIERS") == 0 ||
+ strcmp(name, "CROUCH_MODIFIERS") == 0 ||
+ strcmp(name, "PRONE_MODIFIERS") == 0)
+ {
+ pData->curElement = ELEMENT;
+ }
+
pData->maxReadDepth--;
}
@@ -1425,6 +1637,8 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usItemClass);
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].nasAttachmentClass);
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].nasLayoutClass);
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].ubClassIndex);
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].ubCursor);
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].bSoundType);
@@ -1468,6 +1682,7 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].biggunlist );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].scifi );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].newinv );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].ubAttachmentSystem );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].notineditor );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].defaultundroppable );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].unaerodynamic );
@@ -1514,7 +1729,12 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].discardedlauncheritem );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].rocketrifle);
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].cannon);
- FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].defaultattachment );
+
+ for(UINT8 cnt2 = 0; cnt2 < MAX_DEFAULT_ATTACHMENTS; cnt2++){
+ if(Item[cnt].defaultattachments[cnt2] != 0){
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].defaultattachments[cnt2] );
+ }
+ }
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].brassknuckles );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].crowbar );
@@ -1572,6 +1792,57 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].fingerprintid );
FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].ammocrate );
+ // HEADROCK HAM 4: Print out new values
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].scopemagfactor );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].projectionfactor );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].percentaccuracymodifier );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].RecoilModifierX );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].RecoilModifierY );
+ FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].PercentRecoilModifier );
+
+ // HEADROCK HAM 4: Print out stance-based values
+ FilePrintf(hFile,"\t\t\r\n");
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].flatbasemodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentbasemodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].flataimmodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentcapmodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percenthandlingmodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].targettrackingmodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentdropcompensationmodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].maxcounterforcemodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].counterforceaccuracymodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].counterforcefrequencymodifier[0] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].aimlevelsmodifier[0] );
+ FilePrintf(hFile,"\t\t\r\n");
+
+ FilePrintf(hFile,"\t\t\r\n");
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].flatbasemodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentbasemodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].flataimmodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentcapmodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percenthandlingmodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].targettrackingmodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentdropcompensationmodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].maxcounterforcemodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].counterforceaccuracymodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].counterforcefrequencymodifier[1] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].aimlevelsmodifier[1] );
+ FilePrintf(hFile,"\t\t\r\n");
+
+ FilePrintf(hFile,"\t\t\r\n");
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].flatbasemodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentbasemodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].flataimmodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentcapmodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percenthandlingmodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].targettrackingmodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].percentdropcompensationmodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].maxcounterforcemodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].counterforceaccuracymodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].counterforcefrequencymodifier[2] );
+ FilePrintf(hFile,"\t\t\t%d\r\n", Item[cnt].aimlevelsmodifier[2] );
+ FilePrintf(hFile,"\t\t\r\n");
+
FilePrintf(hFile,"\t\r\n");
}
FilePrintf(hFile,"\r\n");
@@ -1580,3 +1851,76 @@ BOOLEAN WriteItemStats()
return( TRUE );
}
+
+// HEADROCK HAM 4: This function runs just before the items are written into the item array. It causes all stance bonuses
+// to inherit their properties from the bonus "above" them, as long as they don't already have their own value defined.
+void InheritStanceModifiers( itemParseData *pData )
+{
+
+ // Create a two-dimensional temp array to hold all the data about stance modifiers.
+ INT16 TempArray[12][3];
+ INT8 count = 0;
+ INT8 arrcount = 0;
+
+ // Copy stance modifier data into this array
+ for (count = 0; count < 3; count++)
+ {
+ TempArray[0][count] = pData->curItem.flatbasemodifier[count];
+ TempArray[1][count] = pData->curItem.percentbasemodifier[count];
+ TempArray[2][count] = pData->curItem.flataimmodifier[count];
+ TempArray[3][count] = pData->curItem.percentaimmodifier[count];
+ TempArray[4][count] = pData->curItem.percentcapmodifier[count];
+ TempArray[5][count] = pData->curItem.percenthandlingmodifier[count];
+ TempArray[6][count] = pData->curItem.targettrackingmodifier[count];
+ TempArray[7][count] = pData->curItem.percentdropcompensationmodifier[count];
+ TempArray[8][count] = pData->curItem.maxcounterforcemodifier[count];
+ TempArray[9][count] = pData->curItem.counterforceaccuracymodifier[count];
+ TempArray[10][count] = pData->curItem.counterforcefrequencymodifier[count];
+ TempArray[11][count] = pData->curItem.aimlevelsmodifier[count];
+ }
+
+ for (arrcount = 0; arrcount < 12; arrcount++)
+ {
+ if (TempArray[arrcount][2] == -10000)
+ {
+ if (TempArray[arrcount][1] == -10000)
+ {
+ TempArray[arrcount][1] = TempArray[arrcount][0];
+ TempArray[arrcount][2] = TempArray[arrcount][0];
+ }
+ else
+ {
+ TempArray[arrcount][2] = TempArray[arrcount][1];
+ }
+ }
+ else if (TempArray[arrcount][1] == -10000)
+ {
+ TempArray[arrcount][1] = TempArray[arrcount][0];
+ }
+ for (INT8 X = 0; X < 3; X++)
+ {
+ if (TempArray[arrcount][X] == -10000)
+ {
+ TempArray[arrcount][X] = 0;
+ }
+ }
+ }
+
+ // Copy stance modifier data back out of the temp array
+ for (count = 0; count < 3; count++)
+ {
+ pData->curItem.flatbasemodifier[count] = TempArray[0][count];
+ pData->curItem.percentbasemodifier[count] = TempArray[1][count];
+ pData->curItem.flataimmodifier[count] = TempArray[2][count];
+ pData->curItem.percentaimmodifier[count] = TempArray[3][count];
+ pData->curItem.percentcapmodifier[count] = TempArray[4][count];
+ pData->curItem.percenthandlingmodifier[count] = TempArray[5][count];
+ pData->curItem.targettrackingmodifier[count] = TempArray[6][count];
+ pData->curItem.percentdropcompensationmodifier[count] = TempArray[7][count];
+ pData->curItem.maxcounterforcemodifier[count] = TempArray[8][count];
+ pData->curItem.counterforceaccuracymodifier[count] = TempArray[9][count];
+ pData->curItem.counterforcefrequencymodifier[count] = TempArray[10][count];
+ pData->curItem.aimlevelsmodifier[count] = TempArray[11][count];
+ }
+
+}
diff --git a/Utils/XML_Parser.h b/Utils/XML_Parser.h
index def484fa..4c2a9dbe 100644
--- a/Utils/XML_Parser.h
+++ b/Utils/XML_Parser.h
@@ -2,15 +2,61 @@
#define _XML_PARSER_H_
#include "expat.h"
-#include "XML.h"
+//#include "XML.h"
+#include
+
+template
+class LazyCondition
+{
+public:
+ typedef bool (*cond_fct)(OperandType op1, OperandType op2);
+ LazyCondition(OperandType op1, OperandType op2, cond_fct fct)
+ : _op1(op1), _op2(op2), _fct(fct)
+ {};
+ bool check()
+ {
+ return _fct(_op1,_op2);
+ }
+private:
+ OperandType _op1;
+ OperandType _op2;
+ cond_fct _fct;
+};
+
+inline bool lazyStrEqual(const char* str1, const char* str2)
+{
+ return strcmp(str1,str2) == 0;
+}
+
+class LazyStrEqual : public LazyCondition
+{
+public:
+ LazyStrEqual(const char* str1, const char* str2)
+ : LazyCondition(str1, str2, lazyStrEqual)
+ {};
+};
+
+class LazyTrue : public LazyCondition
+{
+ static bool True(bool a, bool b){return true;};
+public:
+ LazyTrue() : LazyCondition(true,true,LazyTrue::True) {};
+};
+
class IXMLParser
{
public:
const XML_Char* ElementName;
public:
- IXMLParser(const XML_Char *element_name, XML_Parser &parser, IXMLParser* caller=NULL)
- : _parser(parser), _caller(caller), ElementName(element_name) {};
+ IXMLParser(const XML_Char *element_name, XML_Parser* parser, IXMLParser* caller=NULL)
+ : _caller(caller), ElementName(element_name)
+ {
+ if(parser)
+ {
+ this->setParser(parser);
+ }
+ };
~IXMLParser() {};
/**
@@ -35,9 +81,9 @@ public:
}
void grabParser()
{
- XML_SetUserData(_parser,this);
- XML_SetElementHandler(_parser, IXMLParser::onStartCallback, IXMLParser::onEndCallback);
- XML_SetCharacterDataHandler(_parser, IXMLParser::onTextCallback);
+ XML_SetUserData(*_parser,this);
+ XML_SetElementHandler(*_parser, IXMLParser::onStartCallback, IXMLParser::onEndCallback);
+ XML_SetCharacterDataHandler(*_parser, IXMLParser::onTextCallback);
}
/**
@@ -48,8 +94,88 @@ public:
virtual void onEndElement(const XML_Char* name)
{};
virtual void onTextElement(const XML_Char *str, int len)
- {};
+ {
+ };
+
+ class Attributes
+ {
+ public:
+ Attributes(const XML_Char** atts) : _atts(atts) {};
+ XML_Char const* get(const XML_Char* attr_name) const
+ {
+ const XML_Char** atts = _atts;
+ while(*atts)
+ {
+ if(strcmp(*atts++,attr_name) == 0)
+ {
+ return *atts;
+ }
+ atts++;
+ }
+ return "";
+ }
+ bool getLong(const XML_Char* attr_name, long& attr) const
+ {
+ XML_Char const* result = this->get(attr_name);
+ if( strcmp(result,"") != 0)
+ {
+ attr = (int)atol(result);
+ return true;
+ }
+ return false;
+ }
+ bool getDouble(const XML_Char* attr_name, double &attr) const
+ {
+ XML_Char const* result = this->get(attr_name);
+ if( strcmp(result,"") != 0)
+ {
+ attr = atof(result);
+ return true;
+ }
+ return false;
+ }
+ private:
+ const XML_Char** _atts;
+ };
+
+ template
+ class ParserState
+ {
+ public:
+ ParserState(const StateType start_state)
+ : _my_state(start_state)
+ {};
+
+ StateType const& state()
+ {
+ return _my_state;
+ }
+
+ template
+ bool stateTransition(const StateType current_state, LazyCondition condition, const StateType next_state)
+ {
+ if(_my_state == current_state && condition.check() )
+ {
+ _my_state = next_state;
+ return true;
+ }
+ return false;
+ }
+ private:
+ StateType _my_state;
+ };
+
+ XML_Parser& getParser()
+ {
+ return *_parser;
+ }
protected:
+ void setParser(XML_Parser* parser)
+ {
+ _parser = parser;
+ // grabParser(); ???
+ }
+
XML_Char const* getAttribute(const XML_Char* attr_name, const XML_Char** atts)
{
while(*atts)
@@ -85,12 +211,12 @@ protected:
int getCurrentLineNumber()
{
- return XML_GetCurrentLineNumber(this->_parser);
+ return XML_GetCurrentLineNumber(*this->_parser);
}
protected:
std::string sCharData;
- XML_Parser& _parser;
+ XML_Parser* _parser;
IXMLParser* _caller;
};
diff --git a/Utils/XML_SenderNameList.cpp b/Utils/XML_SenderNameList.cpp
new file mode 100644
index 00000000..f181ca7d
--- /dev/null
+++ b/Utils/XML_SenderNameList.cpp
@@ -0,0 +1,174 @@
+#ifdef PRECOMPILEDHEADERS
+ #include "Tactical All.h"
+#else
+ #include "sgp.h"
+ #include "Debug Control.h"
+ #include "expat.h"
+ #include "XML.h"
+ #include "Interface.h"
+ #include "Text.h"
+#endif
+
+struct
+{
+ PARSE_STAGE curElement;
+
+ CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
+ SENDER_NAMES_VALUES curSenderNameList;
+ SENDER_NAMES_VALUES * curArray;
+
+ UINT32 maxArraySize;
+ UINT32 curIndex;
+ UINT32 currentDepth;
+ UINT32 maxReadDepth;
+}
+typedef senderNameListParseData;
+
+BOOLEAN SenderNameList_TextOnly;
+
+static void XMLCALL
+senderNameListStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ senderNameListParseData * pData = (senderNameListParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
+ {
+ if(strcmp(name, "SENDER_LIST") == 0 && pData->curElement == ELEMENT_NONE)
+ {
+ pData->curElement = ELEMENT_LIST;
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(strcmp(name, "NAME") == 0 && pData->curElement == ELEMENT_LIST)
+ {
+ pData->curElement = ELEMENT;
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+ else if(pData->curElement == ELEMENT &&
+ (strcmp(name, "uiIndex") == 0 ||
+ strcmp(name, "Name") == 0 ))
+ {
+ pData->curElement = ELEMENT_PROPERTY;
+
+ pData->maxReadDepth++; //we are not skipping this element
+ }
+
+ pData->szCharData[0] = '\0';
+ }
+
+ pData->currentDepth++;
+
+}
+
+static void XMLCALL
+senderNameListCharacterDataHandle(void *userData, const XML_Char *str, int len)
+{
+ senderNameListParseData * pData = (senderNameListParseData *)userData;
+
+ if( (pData->currentDepth <= pData->maxReadDepth) &&
+ (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
+ ){
+ strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
+ }
+}
+
+
+static void XMLCALL
+senderNameListEndElementHandle(void *userData, const XML_Char *name)
+{
+ senderNameListParseData * pData = (senderNameListParseData *)userData;
+
+ if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
+ {
+ if(strcmp(name, "SENDER_LIST") == 0)
+ {
+ pData->curElement = ELEMENT_NONE;
+ }
+ else if(strcmp(name, "NAME") == 0)
+ {
+ pData->curElement = ELEMENT_LIST;
+
+ wcscpy(pSenderNameList[pData->curSenderNameList.uiIndex], pData->curSenderNameList.Name);
+
+ }
+ else if(strcmp(name, "uiIndex") == 0)
+ {
+ pData->curElement = ELEMENT;
+ pData->curSenderNameList.uiIndex = (UINT16) atol(pData->szCharData);
+ }
+ else if(strcmp(name, "Name") == 0 )
+ {
+ pData->curElement = ELEMENT;
+
+ MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curSenderNameList.Name, sizeof(pData->curSenderNameList.Name)/sizeof(pData->curSenderNameList.Name[0]) );
+ pData->curSenderNameList.Name[sizeof(pData->curSenderNameList.Name)/sizeof(pData->curSenderNameList.Name[0]) - 1] = '\0';
+ }
+ pData->maxReadDepth--;
+ }
+
+ pData->currentDepth--;
+}
+
+
+
+
+BOOLEAN ReadInSenderNameList(STR fileName, BOOLEAN localizedVersion)
+{
+ HWFILE hFile;
+ UINT32 uiBytesRead;
+ UINT32 uiFSize;
+ CHAR8 * lpcBuffer;
+ XML_Parser parser = XML_ParserCreate(NULL);
+
+ senderNameListParseData pData;
+
+ DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading SenderNameList.xml" );
+
+ SenderNameList_TextOnly = localizedVersion;
+
+ // Open file
+ hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
+ if ( !hFile )
+ return( localizedVersion );
+
+ uiFSize = FileGetSize(hFile);
+ lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+
+ //Read in block
+ if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
+ {
+ MemFree(lpcBuffer);
+ return( FALSE );
+ }
+
+ lpcBuffer[uiFSize] = 0; //add a null terminator
+
+ FileClose( hFile );
+
+
+ XML_SetElementHandler(parser, senderNameListStartElementHandle, senderNameListEndElementHandle);
+ XML_SetCharacterDataHandler(parser, senderNameListCharacterDataHandle);
+
+
+ memset(&pData,0,sizeof(pData));
+ XML_SetUserData(parser, &pData);
+
+
+ if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
+ {
+ CHAR8 errorBuf[511];
+
+ sprintf(errorBuf, "XML Parser Error in SenderNameList.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
+ LiveMessage(errorBuf);
+
+ MemFree(lpcBuffer);
+ return FALSE;
+ }
+
+ MemFree(lpcBuffer);
+
+
+ XML_ParserFree(parser);
+
+
+ return( TRUE );
+}
\ No newline at end of file
diff --git a/Utils/XML_SenderNameList.h b/Utils/XML_SenderNameList.h
new file mode 100644
index 00000000..3cca54e1
--- /dev/null
+++ b/Utils/XML_SenderNameList.h
@@ -0,0 +1,18 @@
+#ifndef _XML_SENDERNAMELIST_H
+#define _XML_SENDERNAMELIST_H
+
+#include "Types.h"
+
+#define MAX_SENDER_NAMES_CHARS 128
+
+typedef struct
+{
+ UINT16 uiIndex;
+ CHAR16 Name[MAX_SENDER_NAMES_CHARS];
+
+} SENDER_NAMES_VALUES;
+
+extern SENDER_NAMES_VALUES zSenderNameList[500];
+
+
+#endif
diff --git a/Utils/XML_auto_parse.h b/Utils/XML_auto_parse.h
new file mode 100644
index 00000000..78e4f57c
--- /dev/null
+++ b/Utils/XML_auto_parse.h
@@ -0,0 +1,258 @@
+#ifndef XML_AUTO_PARSE_H
+#define XML_AUTO_PARSE_H
+
+#include
+#include
+#include "XML_Parser.h"
+#include
+#include
+#include
@@ -608,7 +608,7 @@
>
diff --git a/ja2_VS2010.sln b/ja2_VS2010.sln
new file mode 100644
index 00000000..ab75f9be
--- /dev/null
+++ b/ja2_VS2010.sln
@@ -0,0 +1,233 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VFS", "ext\VFS\build\VFS_VS2010.vcxproj", "{463CB476-2798-493F-9CE8-CEAC5ECE5664}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6} = {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TileEngine", "TileEngine\TileEngine_VS2010.vcxproj", "{D027A0E1-C661-4B8C-8159-4E0BF3D163AA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TacticalAI", "TacticalAI\TacticalAI_VS2010.vcxproj", "{B369A125-E62E-46AE-9285-58003D688301}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Utils", "Utils\Utils_VS2010.vcxproj", "{082F6E91-D049-4314-BE9D-D9509E853B01}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Strategic", "Strategic\Strategic_VS2010.vcxproj", "{DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SGP", "Standard Gaming Platform\SGP_VS2010.vcxproj", "{1237FA1E-6E76-4AB5-B569-45B01C691FAB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lua", "lua\lua_VS2010.vcxproj", "{9DA9FE0C-B1F2-4E15-9097-A929E203AC28}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "ext\libpng\projects\visualc71\libpng_VS2010.vcxproj", "{735F8DBF-6646-4713-BE36-394F33E69B57}"
+ ProjectSection(ProjectDependencies) = postProject
+ {EC27EB68-C428-4B80-8170-D93F988EA34C} = {EC27EB68-C428-4B80-8170-D93F988EA34C}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Laptop", "Laptop\Laptop_VS2010.vcxproj", "{6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Editor", "Editor\Editor_VS2010.vcxproj", "{23EA0500-038A-4EB8-B753-0C709B25470D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Console", "Console\Console_VS2010.vcxproj", "{A32479BF-C284-4C40-99A5-4F6B5933D1C0}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Tactical", "Tactical\Tactical_VS2010.vcxproj", "{433FBCC4-F612-489C-AA28-CCD6CF27D80C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "ext\libpng\projects\visualc71\zlib_VS2010.vcxproj", "{EC27EB68-C428-4B80-8170-D93F988EA34C}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ja2", "ja2_VS2010.vcxproj", "{C0E14A90-2BD1-4866-A684-98C6F6B96C2D}"
+ ProjectSection(ProjectDependencies) = postProject
+ {23EA0500-038A-4EB8-B753-0C709B25470D} = {23EA0500-038A-4EB8-B753-0C709B25470D}
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28} = {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6} = {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB} = {1237FA1E-6E76-4AB5-B569-45B01C691FAB}
+ {B369A125-E62E-46AE-9285-58003D688301} = {B369A125-E62E-46AE-9285-58003D688301}
+ {EC27EB68-C428-4B80-8170-D93F988EA34C} = {EC27EB68-C428-4B80-8170-D93F988EA34C}
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664} = {463CB476-2798-493F-9CE8-CEAC5ECE5664}
+ {082F6E91-D049-4314-BE9D-D9509E853B01} = {082F6E91-D049-4314-BE9D-D9509E853B01}
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0} = {A32479BF-C284-4C40-99A5-4F6B5933D1C0}
+ {735F8DBF-6646-4713-BE36-394F33E69B57} = {735F8DBF-6646-4713-BE36-394F33E69B57}
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C} = {433FBCC4-F612-489C-AA28-CCD6CF27D80C}
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C} = {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA} = {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D} = {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ja2export", "ext\export\ja2export_VS2010.vcxproj", "{802552D2-B514-42E5-A169-F1E108527678}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6} = {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664} = {463CB476-2798-493F-9CE8-CEAC5ECE5664}
+ {735F8DBF-6646-4713-BE36-394F33E69B57} = {735F8DBF-6646-4713-BE36-394F33E69B57}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "7z", "ext\VFS\build\7z_VS2010.vcxproj", "{3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ MapEditor|Win32 = MapEditor|Win32
+ MapEditorD|Win32 = MapEditorD|Win32
+ Release|Win32 = Release|Win32
+ Relese_WithDebugInfo|Win32 = Relese_WithDebugInfo|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.Debug|Win32.ActiveCfg = Debug|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.Debug|Win32.Build.0 = Debug|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.Release|Win32.ActiveCfg = Release|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.Release|Win32.Build.0 = Release|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {463CB476-2798-493F-9CE8-CEAC5ECE5664}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.Debug|Win32.Build.0 = Debug|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.Release|Win32.ActiveCfg = Release|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.Release|Win32.Build.0 = Release|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {D027A0E1-C661-4B8C-8159-4E0BF3D163AA}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.Debug|Win32.Build.0 = Debug|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.Release|Win32.ActiveCfg = Release|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.Release|Win32.Build.0 = Release|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {B369A125-E62E-46AE-9285-58003D688301}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.Debug|Win32.ActiveCfg = Debug|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.Debug|Win32.Build.0 = Debug|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.Release|Win32.ActiveCfg = Release|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.Release|Win32.Build.0 = Release|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {082F6E91-D049-4314-BE9D-D9509E853B01}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.Debug|Win32.Build.0 = Debug|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.Release|Win32.ActiveCfg = Release|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.Release|Win32.Build.0 = Release|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.Debug|Win32.Build.0 = Debug|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.Release|Win32.ActiveCfg = Release|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.Release|Win32.Build.0 = Release|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {1237FA1E-6E76-4AB5-B569-45B01C691FAB}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.Debug|Win32.Build.0 = Debug|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.Release|Win32.ActiveCfg = Release|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.Release|Win32.Build.0 = Release|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.Debug|Win32.ActiveCfg = Debug|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.Debug|Win32.Build.0 = Debug|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.Release|Win32.ActiveCfg = Release|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.Release|Win32.Build.0 = Release|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {735F8DBF-6646-4713-BE36-394F33E69B57}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.Debug|Win32.Build.0 = Debug|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.Release|Win32.ActiveCfg = Release|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.Release|Win32.Build.0 = Release|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {6CFD0AF4-6BB4-4A19-B72E-71768A8D029D}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.Debug|Win32.Build.0 = Debug|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.Release|Win32.ActiveCfg = Release|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.Release|Win32.Build.0 = Release|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {23EA0500-038A-4EB8-B753-0C709B25470D}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.Debug|Win32.Build.0 = Debug|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.Release|Win32.ActiveCfg = Release|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.Release|Win32.Build.0 = Release|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {A32479BF-C284-4C40-99A5-4F6B5933D1C0}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.Debug|Win32.Build.0 = Debug|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.Release|Win32.ActiveCfg = Release|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.Release|Win32.Build.0 = Release|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {433FBCC4-F612-489C-AA28-CCD6CF27D80C}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.Debug|Win32.Build.0 = Debug|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.Release|Win32.ActiveCfg = Release|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.Release|Win32.Build.0 = Release|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {EC27EB68-C428-4B80-8170-D93F988EA34C}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.Debug|Win32.Build.0 = Debug|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.Release|Win32.ActiveCfg = Release|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.Release|Win32.Build.0 = Release|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.Debug|Win32.ActiveCfg = Debug|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.MapEditor|Win32.ActiveCfg = Release|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.MapEditorD|Win32.ActiveCfg = Release|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.MapEditorD|Win32.Build.0 = Release|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.Release|Win32.ActiveCfg = Release|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.Release|Win32.Build.0 = Release|Win32
+ {802552D2-B514-42E5-A169-F1E108527678}.Relese_WithDebugInfo|Win32.ActiveCfg = Debug|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.Debug|Win32.Build.0 = Debug|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.MapEditor|Win32.ActiveCfg = MapEditor|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.MapEditor|Win32.Build.0 = MapEditor|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.MapEditorD|Win32.ActiveCfg = MapEditorD|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.MapEditorD|Win32.Build.0 = MapEditorD|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.Release|Win32.ActiveCfg = Release|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.Release|Win32.Build.0 = Release|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.Relese_WithDebugInfo|Win32.ActiveCfg = Relese_WithDebugInfo|Win32
+ {3B7B950D-0DC8-4ADD-9FE2-7DE4297C62F6}.Relese_WithDebugInfo|Win32.Build.0 = Relese_WithDebugInfo|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ja2_VS2010.vcxproj b/ja2_VS2010.vcxproj
new file mode 100644
index 00000000..30b093aa
--- /dev/null
+++ b/ja2_VS2010.vcxproj
@@ -0,0 +1,321 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+ {C0E14A90-2BD1-4866-A684-98C6F6B96C2D}
+ Win32Proj
+ ja2
+ ja2
+
+
+
+ Application
+ true
+ NotSet
+
+
+ Application
+ true
+ NotSet
+
+
+ Application
+ false
+ false
+ NotSet
+
+
+ Application
+ false
+ false
+ NotSet
+
+
+ Application
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ bin\VS2010\$(Configuration)\
+ build\VS2010\$(ProjectName)_$(Configuration)\
+ JA2_EN_Debug.exe
+
+
+
+ true
+ bin\VS2010\$(Configuration)\
+ build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ MapEditor_EN_Debug.exe
+
+
+ false
+ bin\VS2010\$(Configuration)\
+ build\VS2010\$(ProjectName)_$(Configuration)\
+ JA2_EN_Release.exe
+
+
+
+ false
+ bin\VS2010\$(Configuration)\
+ build\VS2010\$(ProjectName)_$(Configuration)\
+ MapEditor_EN_Release.exe
+
+
+
+ false
+ bin\VS2010\$(Configuration)\
+ build\VS2010\$(ProjectName)_$(Configuration)\
+ JA2_EN_ReleaseDebugInfo.exe
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ Multiplayer\raknet;%(AdditionalLibraryDirectories)
+ Winmm.lib;RakNetLibStatic.lib;ws2_32.lib;DbgHelp.lib;%(AdditionalDependencies)
+ $(OutDir)\JA2_EN_Debug.exe
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+ Windows
+ true
+ Multiplayer\raknet;%(AdditionalLibraryDirectories)
+ Winmm.lib;RakNetLibStatic.lib;ws2_32.lib;DbgHelp.lib;%(AdditionalDependencies)
+ $(OutDir)\MapEditor_EN_Debug.exe
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+ Windows
+ false
+ true
+ true
+ Multiplayer\raknet;%(AdditionalLibraryDirectories)
+ Winmm.lib;RakNetLibStatic.lib;ws2_32.lib;DbgHelp.lib;%(AdditionalDependencies)
+ $(OutDir)\JA2_EN_Release.exe
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+ Windows
+ false
+ true
+ true
+ Multiplayer\raknet;%(AdditionalLibraryDirectories)
+ Winmm.lib;RakNetLibStatic.lib;ws2_32.lib;DbgHelp.lib;%(AdditionalDependencies)
+ $(OutDir)\MapEditor_EN_Release.exe
+
+
+
+
+ Level3
+
+
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreaded
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+ Multiplayer\raknet;%(AdditionalLibraryDirectories)
+ Winmm.lib;RakNetLibStatic.lib;ws2_32.lib;DbgHelp.lib;%(AdditionalDependencies)
+ $(OutDir)\JA2_EN_ReleaseDebugInfo.exe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ja2_VS2010.vcxproj.filters b/ja2_VS2010.vcxproj.filters
new file mode 100644
index 00000000..b0742e29
--- /dev/null
+++ b/ja2_VS2010.vcxproj.filters
@@ -0,0 +1,265 @@
+
+
+
+
+ {359f3c3e-57b2-40d7-b083-85c85db31e63}
+
+
+ {05dccef7-dd96-43de-9b63-9d7c8919e41a}
+
+
+ {f3b2a941-8bd5-415f-bf6f-e5f8a0cf1397}
+
+
+ {b90d96e4-cddd-48f9-aa85-407f16af8948}
+
+
+ {fee7e775-f3f7-4522-83ca-c6a46499a675}
+
+
+ {4174d974-f404-4614-9bc3-d6503ec290da}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Multiplayer\Source Files
+
+
+ Multiplayer\Source Files
+
+
+ Multiplayer\Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Resource Files
+
+
+ Multiplayer\Header Files
+
+
+ Multiplayer\Header Files
+
+
+ Multiplayer\Header Files
+
+
+ Multiplayer\Header Files
+
+
+
+
+ Resource Files
+
+
+ Resource Files
+
+
+
+
+ Resource Files
+
+
+
\ No newline at end of file
diff --git a/jascreens.cpp b/jascreens.cpp
index 0a39da67..75b4646a 100644
--- a/jascreens.cpp
+++ b/jascreens.cpp
@@ -61,8 +61,8 @@
#include "IniReader.h"
#endif
-#include "VFS/vfs.h"
-#include "VFS/Tools/Log.h"
+#include "sgp_logger.h"
+
#define _UNICODE
// Networking Stuff
#ifdef NETWORKED
@@ -425,8 +425,9 @@ UINT32 InitScreenHandle(void)
// Handle queued .ini file error messages
int y = 40;
#ifdef USE_VFS
- CLog logger(L"ERROR_REPORT.iniErrorMessages.txt");
- //logger.SetAppend();
+ sgp::Logger_ID ini_id = sgp::Logger::instance().createLogger();
+ sgp::Logger::instance().connectFile(ini_id, L"ERROR_REPORT.iniErrorMessages.txt", false, sgp::Logger::FLUSH_ON_DELETE);
+ sgp::Logger::LogInstance logger = sgp::Logger::instance().logger(ini_id);
#endif
while (! iniErrorMessages.empty()) {
#ifndef USE_VFS
@@ -459,7 +460,7 @@ UINT32 InitScreenHandle(void)
fprintf_s (file_pointer , "%S\n" , str );
fclose( file_pointer );
#else
- logger << iniErrorMessage << CLog::ENDL;
+ logger << iniErrorMessage << sgp::endl;
#endif
DisplayWrappedString( 10, y, 560, 2, FONT12ARIAL, FONT_RED, str, FONT_BLACK, TRUE, LEFT_JUSTIFIED );
iniErrorMessages.pop();
@@ -919,10 +920,15 @@ UINT32 SexScreenHandle(void)
// Update frame
uiTime = GetJA2Clock( );
+ static bool started_sound = false;
// if we are animation smile...
if ( ubCurrentScreen == 1 )
{
- PlayJA2StreamingSampleFromFile( "Sounds\\Sex.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, NULL );
+ if(!started_sound)
+ {
+ PlayJA2StreamingSampleFromFile( "Sounds\\Sex.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN, NULL );
+ started_sound = true;
+ }
if ( ( uiTime - uiTimeOfLastUpdate ) > SMILY_DELAY )
{
uiTimeOfLastUpdate = uiTime;
@@ -944,6 +950,7 @@ UINT32 SexScreenHandle(void)
uiTimeOfLastUpdate = uiTime;
ubCurrentScreen = 0;
+ started_sound = false;
// Remove video object...
DeleteVideoObjectFromIndex( guiSMILY );
@@ -997,7 +1004,8 @@ void DoneFadeOutForDemoExitScreen( void )
gfProgramIsRunning = FALSE;
}
-extern INT8 gbFadeSpeed;
+// unused
+//extern INT8 gbFadeSpeed;
#ifdef GERMAN
void DisplayTopwareGermanyAddress()
diff --git a/jascreens.h b/jascreens.h
index 38e36857..8d5dc579 100644
--- a/jascreens.h
+++ b/jascreens.h
@@ -6,7 +6,7 @@
#include "mousesystem.h"
#include "Button System.h"
#include
-#include "VFS/utf8string.h"
+#include
extern UINT32 EditScreenInit(void);
extern UINT32 EditScreenHandle(void);
@@ -169,7 +169,7 @@ void LeaveTacticalScreen( UINT32 uiNewScreen );
struct SExceptionData
{
- utf8string message,function,file;
+ vfs::String message,function,file;
int line;
};
diff --git a/lua/Lua Interpreter.h b/lua/Lua Interpreter.h
index 59f13187..8be61dfe 100644
--- a/lua/Lua Interpreter.h
+++ b/lua/Lua Interpreter.h
@@ -1,3 +1,6 @@
+#ifndef _LUA_INTERPRETER_H_
+#define _LUA_INTERPRETER_H_
+
extern "C" {
#include "lua.h"
#include "lauxlib.h"
@@ -29,3 +32,5 @@ void NewLuaObject( lua_State *L, STR8 ClsName, void *Ptr );
void LuaStrategicSetup(lua_State *L);
void LuaTacticalSetup(lua_State *L);
void LuaEnvironmentSetup(lua_State *L);
+
+#endif // _LUA_INTERPRETER_H_
diff --git a/lua/lua_VS2005.vcproj b/lua/lua_VS2005.vcproj
new file mode 100644
index 00000000..eb1212ed
--- /dev/null
+++ b/lua/lua_VS2005.vcproj
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lua/lua_VS2008.vcproj b/lua/lua_VS2008.vcproj
index 9a36672d..ef1588ab 100644
--- a/lua/lua_VS2008.vcproj
+++ b/lua/lua_VS2008.vcproj
@@ -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"
>
@@ -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"
>
@@ -355,6 +355,22 @@
RelativePath="lua.hpp"
>
+
+
+
+
+
+
+
+
@@ -375,14 +391,30 @@
RelativePath="lua.cpp"
>
+
+
+
+
+
+
+
+
diff --git a/lua/lua_VS2010.vcxproj b/lua/lua_VS2010.vcxproj
new file mode 100644
index 00000000..47fd14e8
--- /dev/null
+++ b/lua/lua_VS2010.vcxproj
@@ -0,0 +1,233 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ MapEditorD
+ Win32
+
+
+ MapEditor
+ Win32
+
+
+ Release
+ Win32
+
+
+ Relese_WithDebugInfo
+ Win32
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {9DA9FE0C-B1F2-4E15-9097-A929E203AC28}
+ Win32Proj
+ lua
+ lua
+
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ true
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+ StaticLibrary
+ false
+ false
+ NotSet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\lib\VS2010\$(Configuration)\
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+ ..\build\VS2010\$(ProjectName)_$(Configuration)\
+ ..\lib\VS2010\$(Configuration)\
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+
+
+
+
+
+
+ Windows
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ Disabled
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ MultiThreaded
+
+
+
+
+ EditAndContinue
+
+
+ Windows
+ true
+ true
+ true
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lua/lua_VS2010.vcxproj.filters b/lua/lua_VS2010.vcxproj.filters
new file mode 100644
index 00000000..72198bfa
--- /dev/null
+++ b/lua/lua_VS2010.vcxproj.filters
@@ -0,0 +1,59 @@
+
+
+
+
+ {363547e5-d794-4293-8484-b7cc64b304dd}
+
+
+ {ffb119e4-d4fc-4b6b-93ae-2958a9ec49dc}
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lua/lua_class_interface.cpp b/lua/lua_class_interface.cpp
new file mode 100644
index 00000000..b9f950b9
--- /dev/null
+++ b/lua/lua_class_interface.cpp
@@ -0,0 +1,247 @@
+#include "lua_class_interface.h"
+
+#include
+
+#define ARRAY_INDEX " idx" // The space is intentional to make this an out-of-band field
+
+luaL_Reg LuaInterface::s_ClassList[] = {
+ { "__index", LuaInterface::luaGetObject, },
+ { "__newindex", LuaInterface::luaSetObject, },
+ { NULL, },
+};
+
+const char* LuaInterface::luaClassName = "ja2_LuaInterface";
+
+LuaInterface::LuaInterface()
+: luaObject(NULL)
+{
+}
+
+LuaInterface::~LuaInterface()
+{
+}
+
+LuaInterface::SInterfaceData* LuaInterface::luaGetInterface()
+{
+ return NULL;
+}
+
+
+void* LuaInterface::luaIsOfType(LuaState state, int index, const char* sClassName)
+{
+ lua_State* L = state();
+ void *p = lua_touserdata(L, index);
+ LuaInterface::SInterfaceData* iface = NULL;
+ if( lua_getmetatable(L, index) ) /* does it have a metatable? */
+ {
+ lua_getfield(L, -1, "__ClassInterface");
+ iface = (LuaInterface::SInterfaceData*) lua_touserdata(L, -1);
+ if( !iface )
+ {
+ return NULL;
+ }
+ lua_pop(L,2);
+ }
+ else
+ {
+ return NULL;
+ }
+ LuaInterface::SInterfaceData::tClassInterface::iterator it = iface->ClassHierarchy.begin();
+ for(; it != iface->ClassHierarchy.end(); ++it)
+ {
+ if( *it == sClassName )
+ {
+ return p;
+ }
+ }
+ return NULL;
+}
+
+LuaInterface::SInterfaceData* LuaInterface::luaGetExportedInterface( SInterfaceData* iface )
+{
+ //iface.Attribs.push_back(s_attrClassList);
+ //iface.ClassHierarchy.push_back(LuaInterface::luaClassName);
+ return iface;
+}
+
+void LuaInterface::luaExportInterface(LuaState state, LuaInterface::SInterfaceData& iface )
+{
+ luaL_Reg *i;
+ LuaAttrib *idx;
+ lua_State* L = state();
+
+ LuaInterface::SInterfaceData::tClassInterface::iterator it_class = iface.ClassHierarchy.begin();
+
+ luaL_newmetatable( L, (*it_class).c_str() );
+ for (i = s_ClassList; i->name; i++)
+ {
+ lua_pushstring(L, i->name);
+ lua_pushlightuserdata(L, &iface);
+ lua_pushcclosure(L, i->func, 1);
+ lua_rawset(L, -3);
+ }
+ lua_pushlightuserdata(L, &iface);
+ lua_setfield(L, -2, "__ClassInterface");
+
+ LuaInterface::SInterfaceData::tAttribs::iterator it_attrib = iface.Attribs.begin();
+ for(;it_attrib != iface.Attribs.end(); ++it_attrib)
+ {
+ for (idx=*it_attrib; idx->name; idx++)
+ {
+ if (idx->staticcall)
+ {
+ lua_pushstring(L, idx->name);
+ lua_pushcfunction(L, idx->staticcall);
+ lua_rawset(L, -3 );
+ }
+ }
+ }
+}
+
+LuaAttrib* LuaInterface::luaCommonGetSet(LuaState state)
+{
+ const char *AttrToFind;
+ typedef std::list tAttributes;
+ lua_State* L = state();
+
+ LuaInterface::SInterfaceData* iface = (LuaInterface::SInterfaceData*) lua_touserdata(L, lua_upvalueindex( 1));
+ if(!iface)
+ {
+ return NULL;
+ }
+ tAttributes* Attributes = &iface->Attribs;
+
+ if (lua_isnumber(L, 2) )
+ {
+ AttrToFind = ARRAY_INDEX;
+ }
+ else if (lua_isstring(L, 2) )
+ {
+ AttrToFind = lua_tostring(L, 2);
+ }
+ else
+ {
+ luaL_argcheck(L, 0, 2, "Invalid index to the table" );
+ // The last function doesn't return, but gotta keep the compiler happy
+ return NULL;
+ }
+
+ tAttributes::iterator it = Attributes->begin();
+ for(;it != Attributes->end(); ++it)
+ {
+ LuaAttrib* attrib = (*it);
+ for ( ; attrib->name; attrib++ )
+ {
+ if ( strcmp( attrib->name, AttrToFind) == 0 )
+ {
+ return attrib;
+ }
+ }
+ }
+ std::string err = "No such field : " + std::string(AttrToFind);
+ luaL_error(L, err.c_str());
+ return NULL;
+}
+
+//int LuaInterface::luaGetObject(lua_State* L)
+DEFINE_LUA_CFUNCTION(LuaInterface, luaGetObject)
+{
+ LuaAttrib *Attributes;
+
+ Attributes = LuaInterface::luaCommonGetSet(L);
+ if (!Attributes)
+ {
+ lua_pushnil( L );
+ return 1;
+ }
+
+ if (!Attributes->get)
+ {
+ if (!Attributes->call)
+ {
+ lua_pushnil( L );
+ }
+ else
+ {
+ lua_pushcfunction(L, Attributes->call);
+ }
+ return 1;
+ }
+
+ return Attributes->get( L );
+}
+
+//int LuaInterface::luaSetObject(lua_State* L)
+DEFINE_LUA_CFUNCTION(LuaInterface, luaSetObject)
+{
+ LuaAttrib *Attributes;
+
+ Attributes = LuaInterface::luaCommonGetSet(L);
+
+ if (!Attributes)
+ {
+ lua_rawset( L, 1 );
+ return 0;
+ }
+
+ if (!Attributes->set)
+ {
+ luaL_error( L, "The attribute is not writable" );
+ }
+
+ return Attributes->set(L);
+}
+
+
+void LuaInterface::luaCreateObject( LuaState state, void *Ptr )
+{
+ lua_State* L = state();
+ // Create the object and initialize its pointer
+ void **ud;
+ ud = (void**)lua_newuserdata( L, sizeof( void*) );
+ *ud = Ptr;
+ // save user data
+ state.registry().GetUserDataTable();
+ lua_pushlightuserdata(L, this);
+ lua_pushvalue(L, -3);
+ lua_rawset(L, -3);
+ lua_pop(L, 1);
+ // Swap the table and metatable for stack arg purposes
+ lua_insert( L, -2 );
+ lua_setmetatable( L, -2 );
+}
+
+void LuaInterface::luaPushObject( LuaState state, const char* sClassName, void *Ptr )
+{
+ lua_State* L = state();
+ state.registry().GetUserDataTable();
+ lua_pushlightuserdata(L, Ptr);
+ lua_rawget(L,-2);
+ if(lua_isnil(L,-1))
+ {
+ lua_pop(L, 1);
+ luaL_getmetatable( L, sClassName );
+ if (lua_istable( L, -1 ) )
+ {
+ this->luaCreateObject( state, Ptr );
+ }
+ }
+ if(!lua_isuserdata(L,-1))
+ {
+ SGP_THROW(L"Could not create User Data");
+ }
+ lua_insert(L, -2);
+ lua_pop(L, 1);
+}
+
+void LuaInterface::luaPushObject( LuaState state, const char* luaName )
+{
+ LuaInterface::SInterfaceData* iface = this->luaGetInterface();
+ this->luaPushObject(state, iface->ClassHierarchy.front().c_str(), this);
+ if(luaName != NULL)
+ {
+ lua_setglobal( state(), luaName );
+ }
+}
+
+
diff --git a/lua/lua_class_interface.h b/lua/lua_class_interface.h
new file mode 100644
index 00000000..09571e43
--- /dev/null
+++ b/lua/lua_class_interface.h
@@ -0,0 +1,122 @@
+#ifndef _LUA_CLASS_INTERFACE_H_
+#define _LUA_CLASS_INTERFACE_H_
+
+//#include "Lua Interpreter.h"
+#include "lua_state.h"
+
+#include
+#include
+
+#define DECLARE_LUA_CFUNCTION(name) static int name(lua_State* L)
+#define DEFINE_LUA_CFUNCTION(class_name,name) int class_name::name(lua_State* L)
+
+class LuaInterface
+{
+public:
+ struct SInterfaceData
+ {
+ typedef std::list tAttribs;
+ typedef std::list tClassInterface;
+ tAttribs Attribs;
+ tClassInterface ClassHierarchy;
+ };
+
+ static const char* luaClassName;
+public:
+ LuaInterface();
+ virtual ~LuaInterface();
+
+ virtual void luaPushObject( LuaState L, const char* luaName = NULL );
+
+protected:
+ static void luaExportInterface(LuaState L, LuaInterface::SInterfaceData& iface);
+ static SInterfaceData* luaGetExportedInterface( SInterfaceData* iface=NULL);
+
+ virtual SInterfaceData* luaGetInterface();
+
+ void luaPushObject( LuaState L, const char* sClassName, void *Ptr );
+private:
+ void luaCreateObject( LuaState L, void *Ptr );
+ void* luaObject;
+
+ static LuaAttrib* luaCommonGetSet( LuaState L );
+ static void* luaIsOfType(LuaState L, int index, const char* sClassName);
+
+ // "meta"-interface
+ //static int luaGetObject( lua_State *L);
+ //static int luaSetObject( lua_State *L);
+ DECLARE_LUA_CFUNCTION( luaGetObject );
+ DECLARE_LUA_CFUNCTION( luaSetObject );
+
+ static luaL_Reg s_ClassList[];
+public:
+ /////////////////////////////////////////////////////////////////////////
+ template
+ static void luaExportClass( LuaState L )
+ {
+ LuaInterface::SInterfaceData* iface = T::luaGetExportedInterface();
+ LuaInterface::luaExportInterface(L, *iface);
+ }
+
+ template
+ static T* luaGetTypedUserData(LuaState L, int index)
+ {
+ void *ptr = LuaInterface::luaIsOfType(L, index, T::luaClassName);
+ if( !ptr )
+ {
+ luaL_typerror(L(), index, T::luaClassName);
+ }
+
+ T** ppNode = (T**)(ptr);
+ if(ppNode)
+ {
+ return *ppNode;
+ }
+ return NULL;
+ }
+};
+
+class LuaUserObject
+{
+public:
+ LuaUserObject(LuaInterface* luaObject=NULL) : _luaObject(luaObject) {};
+ void PushObject(LuaState state, const char* luaName = NULL)
+ {
+ if(_luaObject) _luaObject->luaPushObject(state, luaName);
+ }
+private:
+ LuaInterface* _luaObject;
+};
+
+#ifndef DECLARE_LUA_INTERFACE
+#define DECLARE_LUA_INTERFACE(BaseClass) \
+ private: \
+ typedef BaseClass tSuperClass; \
+ public: \
+ static const char* luaClassName; \
+ static SInterfaceData* luaGetExportedInterface(SInterfaceData* iface=NULL); \
+ protected: \
+ virtual SInterfaceData* luaGetInterface(); \
+ private: \
+ static SInterfaceData luaInterface;
+#endif // DECLARE_LUA_INTERFACE
+
+#ifndef IMPLEMENT_LUA_INTERFACE
+#define IMPLEMENT_LUA_INTERFACE(className, classLuaName, AttribArray) \
+ const char* className::luaClassName = classLuaName; \
+ LuaInterface::SInterfaceData className::luaInterface; \
+ LuaInterface::SInterfaceData* className::luaGetInterface() \
+ { \
+ return &(className::luaInterface); \
+ } \
+ LuaInterface::SInterfaceData* className::luaGetExportedInterface(LuaInterface::SInterfaceData* iface) \
+ { \
+ if(!iface) iface = &(className::luaInterface); \
+ iface->ClassHierarchy.push_back(className::luaClassName); \
+ iface->Attribs.push_back(AttribArray); \
+ return tSuperClass::luaGetExportedInterface( iface ); \
+ }
+#endif // IMPLEMENT_LUA_INTERFACE
+
+#endif // _LUA_CLASS_INTERFACE_H_
+
diff --git a/lua/lua_function.cpp b/lua/lua_function.cpp
new file mode 100644
index 00000000..935675fc
--- /dev/null
+++ b/lua/lua_function.cpp
@@ -0,0 +1,57 @@
+#include "DEBUG.H"
+#include "lua/lua_function.h"
+
+template<>
+LuaFunction& LuaFunction::Param(std::string const& par)
+{
+ if(m_is_function || is_function())
+ {
+ lua_pushstring(_L, par.c_str());
+ _counter++;
+ }
+ return *this;
+}
+
+template<>
+LuaFunction& LuaFunction::Param(double const& par)
+{
+ if(m_is_function || is_function())
+ {
+ lua_pushnumber(_L, par);
+ _counter++;
+ }
+ return *this;
+}
+
+template<>
+LuaFunction& LuaFunction::Param(int const& par)
+{
+ if(m_is_function || is_function())
+ {
+ lua_pushinteger(_L, par);
+ _counter++;
+ }
+ return *this;
+}
+
+template<>
+LuaFunction& LuaFunction::Param(unsigned int const& par)
+{
+ if(m_is_function || is_function())
+ {
+ lua_pushnumber(_L, (double)par);
+ _counter++;
+ }
+ return *this;
+}
+
+template<>
+LuaFunction& LuaFunction::Param(bool const& par)
+{
+ if(m_is_function || is_function())
+ {
+ lua_pushboolean(_L, par);
+ _counter++;
+ }
+ return *this;
+}
diff --git a/lua/lua_function.h b/lua/lua_function.h
new file mode 100644
index 00000000..61534edc
--- /dev/null
+++ b/lua/lua_function.h
@@ -0,0 +1,93 @@
+#ifndef _LUA_FUNCTION_H_
+#define _LUA_FUNCTION_H_
+
+#include
+#include
+
+#include
+
+class LuaFunction
+{
+public:
+ LuaFunction(LuaState L, const char* function_name)
+ : _function_name(function_name), _L(L()), _counter(0), m_is_function(false)
+ {
+ lua_getglobal(_L, function_name);
+ }
+
+ template
+ LuaFunction& Param(T const& par);
+
+ template
+ LuaFunction& TParam(TI const index, TV const& par)
+ {
+ if(m_is_function || is_function(-2))
+ {
+ if(!_tables.empty())
+ {
+ LuaTable& tab = *_tables.top();
+ tab.setValue(index, par);
+ }
+ }
+ return *this;
+ }
+
+ LuaFunction& TableOpen()
+ {
+ _tables.push(new LuaTable(_L));
+ return *this;
+ }
+ LuaFunction& TableClose()
+ {
+ if(!_tables.empty())
+ {
+ LuaTable* tab = _tables.top();
+ _tables.pop();
+ if(tab) delete tab;
+ _counter++;
+ }
+ return *this;
+ }
+
+ bool Call(int num_ret)
+ {
+ if(m_is_function || is_function())
+ {
+ if(_tables.empty() && num_ret >= 0)
+ {
+ if( lua_pcall(_L, _counter, num_ret, 0) != 0)
+ {
+ std::string err = lua_tostring(_L, -1);
+
+ std::wstring wstr;
+ convert_string(_function_name, wstr);
+
+ std::wstringstream wss;
+ wss << L"Execution of lua function '" << wstr << L"' failed : ";
+
+ convert_string(err, wstr);
+ wss << wstr;
+
+ SGP_THROW(wss.str().c_str());
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+private:
+ bool is_function(int pos=-1)
+ {
+ return m_is_function = lua_isfunction(_L, pos);
+ }
+private:
+ std::string _function_name;
+ lua_State* _L;
+ std::stack _tables;
+ int _counter;
+ bool m_is_function;
+};
+
+
+#endif // _LUA_FUNCTION_H_
diff --git a/lua/lua_state.cpp b/lua/lua_state.cpp
new file mode 100644
index 00000000..5b11019c
--- /dev/null
+++ b/lua/lua_state.cpp
@@ -0,0 +1,293 @@
+#include "lua/lua_state.h"
+#include
+#include "sgp_logger.h"
+
+#include
+
+LuaState::LuaState(lua_State* state, bool own) : _L(state), _own(own), _registry(state)
+{
+}
+
+LuaState::LuaState() : _L(NULL), _own(true), _registry(NULL)
+{
+ //_L = lua_open();
+ //_registry._L = _L;
+}
+
+LuaState::~LuaState()
+{
+}
+
+void LuaState::init(bool init_libs)
+{
+ if(!_L)
+ {
+ _L = lua_open();
+ if(init_libs)
+ {
+ luaL_openlibs(_L);
+ }
+ _registry._L = _L;
+ }
+}
+
+void LuaState::close()
+{
+ if(_L && _own)
+ {
+ lua_close(_L);
+ }
+}
+
+#include
+bool LuaState::EvalFile(const char* filename)
+{
+ try
+ {
+ vfs::COpenReadFile rfile(filename);
+ vfs::UInt32 size = rfile.file().getSize();
+ std::vector buffer(size+1);
+ rfile.file().read(&buffer[0], size);
+ buffer[size] = 0;
+ return this->EvalString((char*)&buffer[0], size, filename);
+ }
+ catch(std::exception &ex)
+ {
+ SGP_ERROR(ex.what());
+ }
+ return false;
+}
+
+bool LuaState::CallFunction(const char* function_name)
+{
+ if(function_name)
+ {
+ // call function
+ lua_getglobal(_L, function_name);
+ if(lua_isfunction(_L, -1))
+ {
+ if( lua_pcall(_L, 0, 1, 0) != 0 )
+ {
+ std::string err = lua_tostring(_L, -1);
+ std::wstringstream wss;
+ wss << L"Execution of lua function '" << vfs::String::as_utf16(function_name) << L"' failed : ";
+ wss << vfs::String::as_utf16(err);
+ SGP_THROW(wss.str().c_str());
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool LuaState::EvalString(const wchar_t *lua_str, size_t length, const char* id_str)
+{
+ std::string s = vfs::String::as_utf8(lua_str, length);
+
+ return this->EvalString(s.c_str(), s.length(), id_str);
+}
+
+bool LuaState::EvalString(const char *lua_str, size_t length, const char* id_str)
+{
+ int error;
+
+ if(length == 0)
+ {
+ length = strlen(lua_str);
+ }
+ error = luaL_loadbuffer(_L, lua_str, length, id_str) ||
+ lua_pcall(_L, 0, 0, 0);
+
+ if (error)
+ {
+ const char *error = lua_tostring(_L, -1);
+ int len = strlen( error);
+ if (len >= 7 && !strcmp( error + len - 7, "''"))
+ {
+ lua_pop(_L, 1); /* pop error message from the stack */
+ return false;
+ }
+ std::string s = lua_tostring(_L, -1);
+ SGP_THROW(s);
+ //printf( "%s\n", lua_tostring(L, -1));
+ //lua_pop(L, 1); /* pop error message from the stack */
+ //return true;
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+LuaState::Registry::Registry(lua_State* L) : _L(L)
+{
+}
+
+void LuaState::Registry::CreateCallbackTable()
+{
+ lua_getfield(_L, LUA_REGISTRYINDEX, "__CallBackRegistry");
+ if(lua_isnil(_L,-1))
+ {
+ lua_pop(_L,1); // pop 'nil' from stack
+ lua_newtable(_L);
+ lua_setfield(_L,LUA_REGISTRYINDEX,"__CallBackRegistry"); // 'setfield' removes value from stack
+ return;
+ }
+ else if(lua_istable(_L,-1))
+ {
+ lua_pop(_L,1);
+ return;
+ }
+ SGP_THROW(L"Could not create callback registy table");
+}
+void LuaState::Registry::GetCallbackTable()
+{
+ lua_getfield(_L, LUA_REGISTRYINDEX, "__CallBackRegistry");
+ if(!lua_istable(_L,-1))
+ {
+ SGP_THROW("CallBack registry table does not exist");
+ }
+}
+
+void LuaState::Registry::SetCallback(const char* callback_name)
+{
+ // function is at (L, -2)
+ // user data value is at (L, -1)
+ this->GetCallbackTable();
+ lua_pushvalue(_L, -2);
+ lua_rawget(_L, -2);
+ if(!lua_istable(_L, -1))
+ {
+ lua_pop(_L, 1); // remove 'nil'
+ // set new table
+ lua_pushvalue(_L, -2);
+ lua_newtable(_L);
+ lua_rawset(_L, -3);
+ // get table
+ lua_pushvalue(_L, -2);
+ lua_rawget(_L, -2);
+ }
+ if(!lua_istable(_L,-1))
+ {
+ SGP_THROW("Could not create callback");
+ }
+ lua_pushvalue(_L, -4);
+ lua_setfield(_L, -2, callback_name);
+ lua_pop(_L, 4);
+}
+void LuaState::Registry::GetCallback(const char* callback_name)
+{
+ // user data is at (L, -1)
+ this->GetCallbackTable();
+ lua_pushvalue(_L, -2);
+ lua_rawget(_L, -2);
+ if(lua_istable(_L, -1))
+ {
+ lua_getfield(_L, -1, callback_name);
+ if(lua_isfunction(_L, -1))
+ {
+ lua_insert(_L, -4);
+ lua_pop(_L, 3);
+ if(!lua_isfunction(_L,-1))
+ {
+ SGP_THROW("messed up stack");
+ }
+ return;
+ }
+ // no callback defined
+ lua_pop(_L, 4);
+ }
+ // no table created
+ lua_pop(_L, 3); // also pops user data
+ return;
+}
+
+
+void LuaState::Registry::CreateUserDataTable()
+{
+ lua_getfield(_L, LUA_REGISTRYINDEX, "__UserData");
+ if(lua_isnil(_L,-1))
+ {
+ lua_pop(_L,1); // pop 'nil' from stack
+ lua_newtable(_L);
+ lua_setfield(_L,LUA_REGISTRYINDEX,"__UserData"); // 'setfield' removes value from stack
+ return;
+ }
+ else if(lua_istable(_L,-1))
+ {
+ lua_pop(_L,1);
+ return;
+ }
+ SGP_THROW(L"Could not create User Data registy table");
+}
+
+void LuaState::Registry::GetUserDataTable()
+{
+ lua_getfield(_L, LUA_REGISTRYINDEX, "__UserData");
+ if(!lua_istable(_L,-1))
+ {
+ SGP_THROW("User Data registry table does not exist");
+ }
+}
+
+
+/************************************************************************************/
+
+#include