mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
New feature: radio operator trait allows calling in artillery, requesting reinforcements, scanning for enemies and a few other skills.
Also includes mechansim for easy implementation of new skills. For more info see http://www.bears-pit.com/board/ubbthreads.php/topics/327348.html#Post327348 Requires GameDir >= r1848. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6547 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
+288
-20
@@ -67,6 +67,15 @@ enum MINES_VALUES
|
||||
MAX_MINES
|
||||
};
|
||||
|
||||
// Flugente: trait display
|
||||
enum TRAIT_VALUES
|
||||
{
|
||||
TRAIT_ALL = MAX_MINES + 1,
|
||||
TRAIT_1,
|
||||
TRAIT_2,
|
||||
MAX_TRAIT
|
||||
};
|
||||
|
||||
|
||||
struct CoverCell
|
||||
{
|
||||
@@ -75,8 +84,9 @@ struct CoverCell
|
||||
BOOLEAN fInverseColor;
|
||||
|
||||
INT8 bMines;
|
||||
INT8 bTrait;
|
||||
|
||||
CoverCell() : sGridNo(NOWHERE), bCover(INVALID_COVER), fInverseColor(FALSE), bMines(MINES_ALL) {}
|
||||
CoverCell() : sGridNo(NOWHERE), bCover(INVALID_COVER), fInverseColor(FALSE), bMines(MINES_ALL), bTrait(TRAIT_ALL) {}
|
||||
|
||||
};
|
||||
|
||||
@@ -111,6 +121,13 @@ enum MINES_DRAW_MODE {
|
||||
MINES_DRAW_MAX
|
||||
};
|
||||
|
||||
// Flugente: trait draw mode
|
||||
enum TRAIT_DRAW_MODE {
|
||||
TRAIT_DRAW_OFF,
|
||||
TRAIT_DRAW_RANGE,
|
||||
TRAIT_DRAW_MAX
|
||||
};
|
||||
|
||||
|
||||
//****** Local Variables *********************************************
|
||||
|
||||
@@ -124,6 +141,8 @@ COVER_DRAW_MODE gubDrawMode = COVER_DRAW_OFF;
|
||||
|
||||
MINES_DRAW_MODE gubDrawModeMine = MINES_DRAW_OFF; // Flugente: mines display
|
||||
|
||||
TRAIT_DRAW_MODE gubDrawModeTrait = TRAIT_DRAW_OFF; // Flugente: mines display
|
||||
|
||||
|
||||
//******* Local Function Prototypes ***********************************
|
||||
|
||||
@@ -138,7 +157,7 @@ void AddCoverObjectsToViewArea();
|
||||
void RemoveCoverObjectsFromViewArea();
|
||||
|
||||
void RemoveMinesObjectsFromViewArea(); // added by Flugente, has to be declared here
|
||||
|
||||
void RemoveTraitObjectsFromViewArea();
|
||||
|
||||
void CalculateCover();
|
||||
void CalculateCoverForSoldier( SOLDIERTYPE* pForSoldier, const INT32& sTargetGridNo, const BOOLEAN& fRoof, INT8& bCover );
|
||||
@@ -746,11 +765,6 @@ void ToggleHostileTrapsView()
|
||||
void ToggleTrapNetworkView()
|
||||
{
|
||||
SwitchMinesDrawModeForNetworks();
|
||||
/*if (gubDrawModeMine == MINES_DRAW_PLAYERTEAM_NETWORKS) {
|
||||
SwitchMineViewOff();
|
||||
} else {
|
||||
SwitchToTrapNetworkView();
|
||||
}*/
|
||||
}
|
||||
|
||||
void SwitchMinesDrawModeForNetworks()
|
||||
@@ -797,19 +811,6 @@ void SwitchMinesDrawModeForNetworks()
|
||||
DisplayMines(TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
/*switch(gubDrawModeMine)
|
||||
{
|
||||
case MINES_DRAW_OFF:
|
||||
SwitchToTrapNetworkView();
|
||||
break;
|
||||
case MINES_DRAW_PLAYERTEAM_NETWORKS:
|
||||
SwitchToHostileTrapsView();
|
||||
break;
|
||||
default:
|
||||
SwitchMineViewOff();
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
///END key binding functions
|
||||
|
||||
@@ -1254,3 +1255,270 @@ void DetermineMineDisplayInTile( INT32 sGridNo, INT8 bLevel, INT8& bMines, BOOLE
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------- trait range display after this ----------------------------------------
|
||||
// added by Flugente
|
||||
|
||||
//******* Local Function Prototypes ***********************************
|
||||
|
||||
TileDefines GetTileTraitIndex( const INT8& bTrait );
|
||||
|
||||
void AddTraitObjectsToViewArea();
|
||||
|
||||
void CalculateTraitRange();
|
||||
|
||||
BOOLEAN TraitTileHasAdjTile( const INT32& ubX, const INT32& ubY, const INT32& ubZ );
|
||||
|
||||
UINT32 usDisplayTrait = NO_SKILLTRAIT_NT;
|
||||
INT32 sTraitgridNo = NOWHERE;
|
||||
|
||||
///BEGIN key binding functions
|
||||
void ToggleTraitRangeView(BOOLEAN fOn)
|
||||
{
|
||||
if ( fOn )
|
||||
{
|
||||
gubDrawModeTrait = TRAIT_DRAW_RANGE;
|
||||
gubDrawMode = COVER_DRAW_OFF;
|
||||
gubDrawModeMine = MINES_DRAW_OFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
gubDrawModeTrait = TRAIT_DRAW_OFF;
|
||||
SetTraitToDisplay( NO_SKILLTRAIT_NT );
|
||||
SetGridNoForTraitDisplay( NOWHERE );
|
||||
}
|
||||
|
||||
//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trait ranges");
|
||||
DisplayTraitRange(TRUE);
|
||||
}
|
||||
|
||||
void SetTraitToDisplay( UINT32 aTrait )
|
||||
{
|
||||
usDisplayTrait = aTrait;
|
||||
}
|
||||
|
||||
void SetGridNoForTraitDisplay( INT32 sGridNo )
|
||||
{
|
||||
sTraitgridNo = sGridNo;
|
||||
}
|
||||
|
||||
void DisplayTraitRange( const BOOLEAN& forceUpdate )
|
||||
{
|
||||
if ( gGameExternalOptions.ubCoverDisplayUpdateWait == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( forceUpdate || ( !gfScrollPending && !gfScrollInertia && GetTickCount() > guiMinesNextUpdateTime ) )
|
||||
{
|
||||
CalculateTraitRange();
|
||||
guiMinesNextUpdateTime = GetTickCount() + gGameExternalOptions.ubCoverDisplayUpdateWait;
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateTraitRange()
|
||||
{
|
||||
INT32 ubX, ubY, ubZ;
|
||||
SOLDIERTYPE* pSoldier;
|
||||
|
||||
RemoveTraitObjectsFromViewArea();
|
||||
|
||||
if ( gubDrawModeTrait == TRAIT_DRAW_OFF )
|
||||
return;
|
||||
|
||||
if( gusSelectedSoldier == NOBODY || !GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||
return;
|
||||
|
||||
UINT16 range1 = 0;
|
||||
UINT16 range2 = 0;
|
||||
switch ( usDisplayTrait )
|
||||
{
|
||||
case RADIO_OPERATOR_NT:
|
||||
{
|
||||
// we 'mark' the map position with which we called the menu, so that the player sees where he is targetting
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
//remove other displays
|
||||
if( gubDrawModeMine != MINES_DRAW_OFF )
|
||||
RemoveMinesObjectsFromViewArea();
|
||||
|
||||
if ( gubDrawMode != COVER_DRAW_OFF )
|
||||
RemoveCoverObjectsFromViewArea();
|
||||
|
||||
const INT32& sSelectedSoldierGridNo = MercPtrs[ gusSelectedSoldier ]->sGridNo;
|
||||
|
||||
INT16 usTmp;
|
||||
GetScreenXYWorldCell( gsVIEWPORT_START_X, gsVIEWPORT_START_Y, &gsMineMinCellX, &usTmp );
|
||||
GetScreenXYWorldCell( gsVIEWPORT_END_X, gsVIEWPORT_END_Y, &gsMineMaxCellX, &usTmp );
|
||||
|
||||
GetScreenXYWorldCell( gsVIEWPORT_END_X, gsVIEWPORT_START_Y, &usTmp, &gsMineMinCellY );
|
||||
GetScreenXYWorldCell( gsVIEWPORT_START_X, gsVIEWPORT_END_Y, &usTmp, &gsMineMaxCellY );
|
||||
for ( ubX=gsMineMinCellX; ubX<=gsMineMaxCellX; ++ubX )
|
||||
{
|
||||
for ( ubY=gsMineMinCellY; ubY<=gsMineMaxCellY; ++ubY )
|
||||
{
|
||||
for ( ubZ=0; ubZ<COVER_Z_CELLS; ++ubZ )
|
||||
{
|
||||
INT32& sGridNo = gCoverViewArea[ ubX ][ ubY ][ ubZ ].sGridNo;
|
||||
|
||||
GetGridNoForViewPort( ubX, ubY, sGridNo );
|
||||
|
||||
if( !GridNoOnScreenAndAround( sGridNo, 2 ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !NewOKDestination( pSoldier, sGridNo, false, (INT8) ubZ ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// do not show stuff on roofs if ground is shown
|
||||
if ( ubZ == I_ROOF_LEVEL && !IsTheRoofVisible( sGridNo ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// do not show stuff on ground if roof is shown
|
||||
if ( ubZ == I_GROUND_LEVEL && IsTheRoofVisible( sGridNo ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( range1 && PythSpacesAway(sSelectedSoldierGridNo, sGridNo) == range1 )
|
||||
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = TRAIT_1;
|
||||
else if ( range2 && PythSpacesAway(sSelectedSoldierGridNo, sGridNo) == range2 )
|
||||
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = TRAIT_2;
|
||||
// mark the gridno we are targetting
|
||||
else if ( PythSpacesAway(sTraitgridNo, sGridNo) == 1 )
|
||||
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = TRAIT_1;
|
||||
else
|
||||
gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait = MAX_TRAIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddTraitObjectsToViewArea();
|
||||
}
|
||||
|
||||
void AddTraitObjectsToViewArea()
|
||||
{
|
||||
if (gsMineMaxCellY == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
INT32 ubX, ubY, ubZ;
|
||||
BOOLEAN fChanged = FALSE;
|
||||
|
||||
for ( ubX=gsMineMinCellX; ubX<=gsMineMaxCellX; ++ubX )
|
||||
{
|
||||
for ( ubY=gsMineMinCellY; ubY<=gsMineMaxCellY; ++ubY )
|
||||
{
|
||||
for ( ubZ=0; ubZ<COVER_Z_CELLS; ++ubZ )
|
||||
{
|
||||
INT32& sGridNo = gCoverViewArea[ ubX ][ ubY ][ ubZ ].sGridNo;
|
||||
INT8& bTrait = gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait;
|
||||
|
||||
if ( bTrait != -1 && ( bTrait == TRAIT_1 || bTrait == TRAIT_2 ) )
|
||||
{
|
||||
TileDefines tile = GetTileTraitIndex( bTrait );
|
||||
AddCoverObjectToWorld( sGridNo, tile, (BOOLEAN) ubZ );
|
||||
fChanged = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-render the scene!
|
||||
if ( fChanged )
|
||||
{
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
}
|
||||
|
||||
TileDefines GetTileTraitIndex( const INT8& bTrait )
|
||||
{
|
||||
switch(bTrait)
|
||||
{
|
||||
case TRAIT_1:
|
||||
return SPECIALTILE_COVER_5; // green
|
||||
case TRAIT_2:
|
||||
return SPECIALTILE_COVER_2; // orange
|
||||
case TRAIT_ALL:
|
||||
return SPECIALTILE_COVER_3; // yellow
|
||||
case MAX_TRAIT:
|
||||
default:
|
||||
return SPECIALTILE_COVER_1; // red
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN TraitTileHasAdjTile( const INT32& ubX, const INT32& ubY, const INT32& ubZ )
|
||||
{
|
||||
INT32 ubTX, ubTY;
|
||||
|
||||
for ( ubTX = ubX-1; ubTX <= ubX+1; ++ubTX )
|
||||
{
|
||||
if ( ubTX < 0 || ubTX > WORLD_COLS )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for ( ubTY = ubY-1; ubTY <= ubY+1; ++ubTY )
|
||||
{
|
||||
if ( ubTY < 0 || ubTY > WORLD_ROWS )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
INT8& bTrait = gCoverViewArea[ ubTX ][ ubTY ][ ubZ ].bTrait;
|
||||
|
||||
if ( bTrait == TRAIT_1 || bTrait == TRAIT_2 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void RemoveTraitObjectsFromViewArea()
|
||||
{
|
||||
if (gsMineMaxCellY == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
INT32 ubX, ubY, ubZ;
|
||||
BOOLEAN fChanged = FALSE;
|
||||
|
||||
for ( ubX=gsMineMinCellX; ubX<=gsMineMaxCellX; ++ubX )
|
||||
{
|
||||
for ( ubY=gsMineMinCellY; ubY<=gsMineMaxCellY; ++ubY )
|
||||
{
|
||||
for ( ubZ=0; ubZ<COVER_Z_CELLS; ++ubZ )
|
||||
{
|
||||
INT32& sGridNo = gCoverViewArea[ ubX ][ ubY ][ ubZ ].sGridNo;
|
||||
INT8& bTrait = gCoverViewArea[ ubX ][ ubY ][ ubZ ].bTrait;
|
||||
|
||||
if ( bTrait != -1 || TraitTileHasAdjTile( ubX, ubY, ubZ ))
|
||||
{
|
||||
TileDefines tile = GetTileTraitIndex( bTrait );
|
||||
RemoveCoverObjectFromWorld( sGridNo, tile, (BOOLEAN) ubZ );
|
||||
bTrait = -1;
|
||||
fChanged = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Re-render the scene!
|
||||
if ( fChanged )
|
||||
{
|
||||
SetRenderFlags( RENDER_FLAG_FULL );
|
||||
}
|
||||
}
|
||||
@@ -50,5 +50,12 @@ void ToggleHostileTrapsView();
|
||||
|
||||
void SwitchMinesDrawModeForNetworks();
|
||||
|
||||
// ----------------------------- trait range display after this ----------------------------------------
|
||||
// added by Flugente: display of ranges and areas of effects for traits
|
||||
void DisplayTraitRange(const BOOLEAN& forceUpdate = FALSE);
|
||||
|
||||
void ToggleTraitRangeView(BOOLEAN fOn = TRUE);
|
||||
void SetTraitToDisplay( UINT32 aTrait );
|
||||
void SetGridNoForTraitDisplay( INT32 sGridNo );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2196,6 +2196,21 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
|
||||
bNumRightIcons++;
|
||||
}
|
||||
|
||||
// Flugente: icons for radio operator actions (not the assignment)
|
||||
if ( MercPtrs[ pFace->ubSoldierID ]->bAssignment != RADIO_SCAN )
|
||||
{
|
||||
if ( MercPtrs[ pFace->ubSoldierID ]->bSoldierFlagMask & (SOLDIER_RADIO_OPERATOR_SCANNING|SOLDIER_RADIO_OPERATOR_LISTENING) )
|
||||
{
|
||||
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 19 );
|
||||
bNumRightIcons++;
|
||||
}
|
||||
else if ( MercPtrs[ pFace->ubSoldierID ]->bSoldierFlagMask & SOLDIER_RADIO_OPERATOR_JAMMING )
|
||||
{
|
||||
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 20 );
|
||||
bNumRightIcons++;
|
||||
}
|
||||
}
|
||||
|
||||
switch( pSoldier->bAssignment )
|
||||
{
|
||||
case DOCTOR:
|
||||
@@ -2270,6 +2285,11 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
|
||||
|
||||
break;
|
||||
|
||||
case RADIO_SCAN:
|
||||
sIconIndex_Assignment = 19;
|
||||
fDoIcon_Assignment = TRUE;
|
||||
break;
|
||||
|
||||
case MOVE_EQUIPMENT:
|
||||
{
|
||||
sIconIndex_Assignment = 15;
|
||||
|
||||
@@ -3946,6 +3946,23 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: display energy level of power packs
|
||||
if ( HasItemFlag(pObject->usItem, POWER_PACK) )
|
||||
{
|
||||
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
|
||||
{
|
||||
FLOAT energylevel = (*pObject)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE;
|
||||
|
||||
UINT32 red = (UINT32) ( 255 * ( 1.0 - max(0, 2*energylevel - 1.0) ) );
|
||||
UINT32 green = (UINT32) ( 255 * ( min(1.0, 2*energylevel) ) );
|
||||
UINT32 blue = 0;
|
||||
|
||||
UINT16 colour = Get16BPPColor( FROMRGB( red, green, blue ) );
|
||||
|
||||
DrawItemUIBarEx( pObject, DRAW_ITEM_TEMPERATURE, sX, sY + sHeight-1, ITEMDESC_ITEM_STATUS_WIDTH, sHeight-1, colour, colour, TRUE, guiSAVEBUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
// display symbol if we are leaning our weapon on something
|
||||
// display only if eapon resting is allowed, display is allowed, item is a gun/launcher, we are a person, we hold the gun in our hand, and we are resting the gun
|
||||
if ( gGameExternalOptions.fWeaponResting && gGameExternalOptions.fDisplayWeaponRestingIndicator && pItem->usItemClass & (IC_GUN | IC_LAUNCHER) && pSoldier && &(pSoldier->inv[pSoldier->ubAttackingHand]) == pObject && pSoldier->IsWeaponMounted() )
|
||||
@@ -6771,6 +6788,22 @@ void RenderItemDescriptionBox( )
|
||||
|
||||
DrawItemUIBarEx( &(*iter), DRAW_ITEM_TEMPERATURE, sCenX+4, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, colour, colour, TRUE, guiSAVEBUFFER );
|
||||
}
|
||||
// Flugente: display energy level of power packs
|
||||
else if ( HasItemFlag(iter->usItem, POWER_PACK) )
|
||||
{
|
||||
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
|
||||
{
|
||||
FLOAT energylevel = (*iter)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE;
|
||||
|
||||
UINT32 red = (UINT32) ( 255 * ( 1.0 - max(0, 2*energylevel - 1.0) ) );
|
||||
UINT32 green = (UINT32) ( 255 * ( min(1.0, 2*energylevel) ) );
|
||||
UINT32 blue = 0;
|
||||
|
||||
UINT16 colour = Get16BPPColor( FROMRGB( red, green, blue ) );
|
||||
|
||||
DrawItemUIBarEx( &(*iter), DRAW_ITEM_TEMPERATURE, sCenX+4, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, colour, colour, TRUE, guiSAVEBUFFER );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7017,6 +7050,54 @@ void RenderItemDescriptionBox( )
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
else if ( HasItemFlag(gpItemDescObject->usItem, POWER_PACK) )
|
||||
{
|
||||
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
|
||||
{
|
||||
FLOAT energylevel = (*gpItemDescObject)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE;
|
||||
|
||||
UINT32 red = (UINT32) ( 255 * ( 1.0 - max(0, 2*energylevel - 1.0) ) );
|
||||
UINT32 green = (UINT32) ( 255 * ( min(1.0, 2*energylevel) ) );
|
||||
UINT32 blue = 0;
|
||||
|
||||
UINT8 stringNum = 5;
|
||||
if ( energylevel > 0.8f )
|
||||
stringNum = 1;
|
||||
else if ( energylevel > 0.6f )
|
||||
stringNum = 2;
|
||||
else if ( energylevel > 0.4f )
|
||||
stringNum = 3;
|
||||
else if ( energylevel > 0.2f )
|
||||
stringNum = 4;
|
||||
|
||||
// UDB system displays a string with colored condition text.
|
||||
int regionindex = 7;
|
||||
SetFontForeground( ForegroundColor );
|
||||
swprintf( pStr, L"%s", gPowerPackDesc[STR_POWERPACK_BEGIN] ); // "Temperature is "
|
||||
mprintf( gItemDescTextRegions[regionindex].sLeft, gItemDescTextRegions[regionindex].sTop, pStr );
|
||||
// Record length
|
||||
INT16 indent = StringPixLength( gPowerPackDesc[STR_POWERPACK_BEGIN], ITEMDESC_FONT );
|
||||
|
||||
swprintf( pStr, L"%s", gPowerPackDesc[stringNum] );
|
||||
|
||||
SetRGBFontForeground( red, green, blue );
|
||||
|
||||
mprintf( gItemDescTextRegions[regionindex].sLeft+indent+2, gItemDescTextRegions[regionindex].sTop, pStr );
|
||||
// Record length
|
||||
indent += StringPixLength( gPowerPackDesc[stringNum], ITEMDESC_FONT );
|
||||
|
||||
SetFontForeground( ForegroundColor );
|
||||
swprintf( pStr, L"%s", gPowerPackDesc[STR_POWERPACK_END] ); // "."
|
||||
mprintf( gItemDescTextRegions[regionindex].sLeft + indent + 2, gItemDescTextRegions[regionindex].sTop, pStr );
|
||||
|
||||
// to get the text to the left side...
|
||||
swprintf( pStr, L"");
|
||||
|
||||
FindFontRightCoordinates( gItemDescTextRegions[regionindex].sLeft, gItemDescTextRegions[regionindex].sTop, gItemDescTextRegions[regionindex].sRight - gItemDescTextRegions[regionindex].sLeft ,gItemDescTextRegions[regionindex].sBottom - gItemDescTextRegions[regionindex].sTop ,pStr, BLOCKFONT2, &usX, &usY);
|
||||
|
||||
mprintf( usX, usY, pStr );
|
||||
}
|
||||
}
|
||||
|
||||
// UDB system displays a string with colored condition text.
|
||||
SetFontForeground( ForegroundColor );
|
||||
|
||||
@@ -508,6 +508,13 @@ void DrawItemUIBarEx( OBJECTTYPE *pObject, UINT8 ubStatus, INT16 sXPos, INT16 sY
|
||||
{
|
||||
sValue = 100;
|
||||
}
|
||||
else if ( HasItemFlag(pObject->usItem, POWER_PACK) )
|
||||
{
|
||||
if ( OVERHEATING_MAX_TEMPERATURE > 0 )
|
||||
{
|
||||
sValue = (INT16) ( 100 * (*pObject)[0]->data.bTemperature / (FLOAT)OVERHEATING_MAX_TEMPERATURE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sValue = (INT16) (100 * GetGunOverheatJamPercentage( pObject) );
|
||||
|
||||
+12
-7
@@ -714,10 +714,10 @@ extern OBJECTTYPE gTempObject;
|
||||
#define TRIPWIRE_NETWORK_LVL_3 0x00400000 //4194304
|
||||
#define TRIPWIRE_NETWORK_LVL_4 0x00800000 //8388608
|
||||
|
||||
/*#define TRIPWIRE_NETWORK_LVL_1 0x01000000 //16777216
|
||||
#define TRIPWIRE_NETWORK_LVL_2 0x02000000 //33554432
|
||||
#define TRIPWIRE_NETWORK_LVL_3 0x04000000 //67108864
|
||||
#define TRIPWIRE_NETWORK_LVL_4 0x08000000 //134217728
|
||||
#define ARTILLERY_STRIKE_COUNT_1 0x01000000 //16777216
|
||||
#define ARTILLERY_STRIKE_COUNT_2 0x02000000 //33554432
|
||||
#define ARTILLERY_STRIKE_COUNT_4 0x04000000 //67108864
|
||||
/*#define TRIPWIRE_NETWORK_LVL_4 0x08000000 //134217728
|
||||
|
||||
#define PLAYER_NET_1_LVL_4 0x10000000 //268435456
|
||||
#define PLAYER_NET_2_LVL_4 0x20000000 //536870912
|
||||
@@ -725,6 +725,8 @@ extern OBJECTTYPE gTempObject;
|
||||
#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
#define ANY_ARTILLERY_FLAG (ARTILLERY_STRIKE_COUNT_1|ARTILLERY_STRIKE_COUNT_2|ARTILLERY_STRIKE_COUNT_4)
|
||||
|
||||
// -------- added by Flugente: various item flags --------
|
||||
// flags used for various item properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
// note that these should not be used to determine what kind of an attachment an item is, that is determined by attachmentclass and the AC_xxx flags above
|
||||
@@ -759,9 +761,9 @@ extern OBJECTTYPE gTempObject;
|
||||
#define SCUBA_FINS 0x00800000 //8388608 // this item speed up swimming, but slows walking and running
|
||||
|
||||
#define TRIPWIREROLL 0x01000000 //16777216 // this item is a tripwire roll
|
||||
/*#define PLAYER_NET_2_LVL_3 0x02000000 //33554432
|
||||
#define PLAYER_NET_3_LVL_3 0x04000000 //67108864
|
||||
#define PLAYER_NET_4_LVL_3 0x08000000 //134217728
|
||||
#define RADIO_SET 0x02000000 //33554432 // item can be used to radio militia/squads in other sectors
|
||||
#define SIGNAL_SHELL 0x04000000 //67108864 // this is a signal shell that precedes artillery barrages
|
||||
#define POWER_PACK 0x08000000 //134217728 // item continously powers an item it is attached to
|
||||
|
||||
#define PLAYER_NET_1_LVL_4 0x10000000 //268435456
|
||||
#define PLAYER_NET_2_LVL_4 0x20000000 //536870912
|
||||
@@ -1856,6 +1858,9 @@ enum
|
||||
IMP_COVERT,
|
||||
IMP_COVERT_EXP,
|
||||
|
||||
// Flugente: added radio operator
|
||||
IMP_RADIO_OPERATOR,
|
||||
|
||||
MAX_IMP_ITEM_TYPES
|
||||
};
|
||||
|
||||
|
||||
@@ -7822,6 +7822,12 @@ BOOLEAN CreateItem( UINT16 usItem, INT16 bStatus, OBJECTTYPE * pObj )
|
||||
(*pObj)[0]->data.bTemperature = OVERHEATING_MAX_TEMPERATURE;
|
||||
}
|
||||
|
||||
// Flugente: certain items get the maximum temperature when they are created
|
||||
if ( HasItemFlag(usItem, POWER_PACK) )
|
||||
{
|
||||
(*pObj)[0]->data.bTemperature = (FLOAT)(OVERHEATING_MAX_TEMPERATURE);
|
||||
}
|
||||
|
||||
//ADB ubWeight has been removed, see comments in OBJECTTYPE
|
||||
//pObj->ubWeight = CalculateObjectWeight( pObj );
|
||||
fRet = TRUE;
|
||||
|
||||
@@ -494,6 +494,7 @@ typedef struct
|
||||
UINT8 usWaterType; // type of water source in this sector
|
||||
UINT16 usNaturalDirt; // extra dirt percentage when firing in this sector
|
||||
UINT8 usCurfewValue; // determines wether mercs disguising as civilian are automatically discovered (certain sectors are 'restricted' to civilians)
|
||||
INT8 sRadioScanModifier; // modifies the scan range of the radio scan assignment in this sector
|
||||
UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // room numbers of prisons
|
||||
|
||||
} SECTOR_EXT_DATA;
|
||||
|
||||
@@ -1009,7 +1009,8 @@ void HandleShadingOfLinesForMilitiaControlMenu( void )
|
||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||
{
|
||||
// Check LOS!
|
||||
if ( SoldierTo3DLocationLineOfSightTest( pSoldier, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
|
||||
// Flugente: active radio sets allows us to give individual orders even without a line of sight
|
||||
if ( pSoldier->CanUseRadio() || SoldierTo3DLocationLineOfSightTest( pSoldier, pTMilitiaSoldier->sGridNo, pTMilitiaSoldier->pathing.bLevel, 3, TRUE, CALC_FROM_ALL_DIRS ) )
|
||||
{
|
||||
UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_ATTACK );
|
||||
UnShadeStringInBox( ghMilitiaControlBox, MILCON_MENU_HOLD );
|
||||
@@ -1069,7 +1070,11 @@ BOOLEAN CheckIfRadioIsEquipped( void )
|
||||
//pSoldier = GetSelectedAssignSoldier( FALSE ); //do not use
|
||||
|
||||
if ( GetSoldier( &pSoldier, gusSelectedSoldier ) )
|
||||
{
|
||||
{
|
||||
// Flugente: active radio sets also count as radio
|
||||
if ( pSoldier->CanUseRadio() )
|
||||
return TRUE;
|
||||
|
||||
//bSlot = FindObj( pSoldier, EXTENDEDEAR );
|
||||
bSlot = FindHearingAid(pSoldier);
|
||||
//ScreenMsg( FONT_WHITE, MSG_INTERFACE, L"Position: %d", bSlot );
|
||||
|
||||
@@ -0,0 +1,677 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Flugente (bears-pit.com)
|
||||
*/
|
||||
|
||||
#include "SkillMenu.h"
|
||||
#include "Soldier Profile Type.h"
|
||||
#include "Overhead.h"
|
||||
#include "Text.h"
|
||||
#include "Isometric Utils.h"
|
||||
#include "DisplayCover.h"
|
||||
#include "worldman.h"
|
||||
|
||||
UINT16 usTraitMenuPosX = 0;
|
||||
UINT16 usTraitMenuPosY = 0;
|
||||
|
||||
INT32 sTraitsMenuTargetGridNo = NOWHERE;
|
||||
|
||||
void Hide( void )
|
||||
{
|
||||
// set off display of trait range/target gridno
|
||||
ToggleTraitRangeView(FALSE);
|
||||
|
||||
// Dirty!
|
||||
fMapPanelDirty = TRUE;
|
||||
}
|
||||
|
||||
// Turns an option off by always returning FALSE
|
||||
BOOLEAN Popup_OptionOff( void ) { return FALSE; }
|
||||
|
||||
void
|
||||
SkillMenuItem::SetupPopup(CHAR* name)
|
||||
{
|
||||
// create a popup
|
||||
gPopup = new POPUP(name);
|
||||
|
||||
// add a callback that lets the keyboard handler know we're done (and ready to pop up again)
|
||||
gPopup->setCallback(POPUP_CALLBACK_HIDE, new popupCallbackFunction<void, void>( &Hide ) );
|
||||
}
|
||||
|
||||
// Different SkillItem classes. We need wrappers for each one, as we cannot pass a pointer to a member function (we need a concrete object)
|
||||
|
||||
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
||||
TraitSelection gTraitSelection;
|
||||
|
||||
//void Wrapper_Function_TraitSelection( UINT32 aVal) { gTraitSelection.Functions(aVal); }
|
||||
void Wrapper_Setup_TraitSelection( UINT32 aVal) { gTraitSelection.Setup(aVal); }
|
||||
void Wrapper_Cancel_TraitSelection( UINT32 aVal ) { gTraitSelection.Cancel(); }
|
||||
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Skill Selection ////////////////////////////////////////////
|
||||
SkillSelection gSkillSelection;
|
||||
|
||||
void Wrapper_Function_SkillSelection( UINT32 aVal) { gSkillSelection.Functions(aVal); }
|
||||
void Wrapper_Setup_SkillSelection( UINT32 aVal) { gSkillSelection.Setup(aVal); }
|
||||
void Wrapper_Cancel_SkillSelection( UINT32 aVal ) { gSkillSelection.Cancel(); }
|
||||
/////////////////////////////// Skill Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
|
||||
ArtillerySector gArtillerySector;
|
||||
|
||||
//void Wrapper_Function_ArtillerySector( UINT32 aVal) { gArtillerySector.Functions(aVal); }
|
||||
void Wrapper_Setup_ArtillerySector( UINT32 aVal) { gArtillerySector.Setup(aVal); }
|
||||
void Wrapper_Cancel_ArtillerySector( UINT32 aVal ) { gArtillerySector.Cancel(); }
|
||||
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
|
||||
ArtilleryTeam gArtilleryTeam;
|
||||
|
||||
void Wrapper_Function_ArtilleryTeam( UINT32 aVal) { gArtilleryTeam.Functions(aVal); }
|
||||
void Wrapper_Setup_ArtilleryTeam( UINT32 aVal) { gArtilleryTeam.Setup(aVal); }
|
||||
void Wrapper_Cancel_ArtilleryTeam( UINT32 aVal ) { gArtilleryTeam.Cancel(); }
|
||||
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
|
||||
ReinforcementSector gReinforcementSector;
|
||||
|
||||
//void Wrapper_Function_ReinforcementSector( UINT32 aVal) { gReinforcementSector.Functions(aVal); }
|
||||
void Wrapper_Setup_ReinforcementSector( UINT32 aVal) { gReinforcementSector.Setup(aVal); }
|
||||
void Wrapper_Cancel_ReinforcementSector( UINT32 aVal ) { gReinforcementSector.Cancel(); }
|
||||
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
|
||||
ReinforcementNumber gReinforcementNumber;
|
||||
|
||||
void Wrapper_Function_ReinforcementNumber( UINT32 aVal) { gReinforcementNumber.Functions(aVal); }
|
||||
void Wrapper_Setup_ReinforcementNumber( UINT32 aVal) { gReinforcementNumber.Setup(aVal); }
|
||||
void Wrapper_Cancel_ReinforcementNumber( UINT32 aVal ) { gReinforcementNumber.Cancel(); }
|
||||
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
|
||||
SoldierSelection gSoldierSelection;
|
||||
|
||||
void Wrapper_Function_SoldierSelection( UINT32 aVal) { gSoldierSelection.Functions(aVal); }
|
||||
void Wrapper_Setup_SoldierSelection( UINT32 aVal) { gSoldierSelection.Setup(aVal); }
|
||||
void Wrapper_Cancel_SoldierSelection( UINT32 aVal ) { gSoldierSelection.Cancel(); }
|
||||
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
||||
void
|
||||
TraitSelection::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
SetupPopup("TraitSelection");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
// create entries for the sub-menus for each trait
|
||||
const UINT8 num = 1;
|
||||
UINT8 traitarray[num];
|
||||
traitarray[0] = RADIO_OPERATOR_NT;
|
||||
for ( int i = 0; i < num; ++i)
|
||||
{
|
||||
swprintf( pStr, gzMercSkillTextNew[traitarray[i]] );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Setup_SkillSelection, traitarray[i] ) );
|
||||
|
||||
// if we cannot perform this skill, grey it out
|
||||
if ( !HAS_SKILL_TRAIT(pSoldier, traitarray[i]) )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_TraitSelection, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// grab soldier's x,y screen position
|
||||
INT16 sX, sY;
|
||||
GetSoldierScreenPos( pSoldier, &sX, &sY );
|
||||
|
||||
if( sX < 0 ) sX = 0;
|
||||
if( sY < 0 ) sY = 0;
|
||||
|
||||
usTraitMenuPosX = sX + 30;
|
||||
usTraitMenuPosY = sY;
|
||||
|
||||
if ( ( usTraitMenuPosX + 400 ) > SCREEN_WIDTH )
|
||||
usTraitMenuPosX = SCREEN_WIDTH - 400;
|
||||
|
||||
if ( ( usTraitMenuPosY + 130 ) > SCREEN_HEIGHT )
|
||||
usTraitMenuPosY = SCREEN_HEIGHT - 190;
|
||||
|
||||
SetPos(usTraitMenuPosX, usTraitMenuPosY);
|
||||
}
|
||||
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////// Skill Selection ////////////////////////////////////////////
|
||||
void
|
||||
SkillSelection::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( HAS_SKILL_TRAIT(pSoldier, aVal) )
|
||||
{
|
||||
SetupPopup("SkillSelection");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
SetTraitToDisplay(aVal);
|
||||
SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo);
|
||||
|
||||
// this switch isn't really necessary. But dividing the skills into menus for each trait gives a better overview, and looks way better than a huge list
|
||||
switch ( aVal )
|
||||
{
|
||||
case RADIO_OPERATOR_NT:
|
||||
{
|
||||
for(UINT32 uiCounter = SKILLS_RADIO_FIRST; uiCounter <= SKILLS_RADIO_LAST; ++uiCounter)
|
||||
{
|
||||
swprintf( pStr, pTraitSkillsMenuStrings[uiCounter] );
|
||||
|
||||
if ( uiCounter == SKILLS_RADIO_ARTILLERY)
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Setup_ArtillerySector, uiCounter ) );
|
||||
else if ( uiCounter == SKILLS_RADIO_CALLREINFORCEMENTS)
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Setup_ReinforcementSector, uiCounter ) );
|
||||
else
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Function_SkillSelection, uiCounter ) );
|
||||
|
||||
// if we cannot perform this skill, grey it out
|
||||
if ( !(pSoldier->CanUseSkill(uiCounter, TRUE)) )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// certain traits have skills whose effects depend on wether eomeone is near to us (squadleader, commissar). We therefore display our radius of effect while this display is open
|
||||
ToggleTraitRangeView(TRUE);
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_SkillSelection, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// same y, different x
|
||||
SetPos(gTraitSelection.GetMaxPosX(), usTraitMenuPosY);
|
||||
|
||||
if ( HAS_SKILL_TRAIT(pSoldier, aVal) )
|
||||
{
|
||||
UINT8 cnt = 0;
|
||||
switch ( aVal )
|
||||
{
|
||||
case RADIO_OPERATOR_NT:
|
||||
{
|
||||
for(UINT32 uiCounter = SKILLS_RADIO_FIRST; uiCounter <= SKILLS_RADIO_LAST; ++uiCounter)
|
||||
{
|
||||
SetRegionFastHelpText( &(GetPopup()->MenuRegion[cnt++]), pSoldier->PrintSkillDesc(uiCounter) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SkillSelection::Functions( UINT32 aVal )
|
||||
{
|
||||
Cancel();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
UINT8 ubID = WhoIsThere2(sTraitsMenuTargetGridNo, 0 );
|
||||
|
||||
pSoldier->UseSkill(aVal, sTraitsMenuTargetGridNo, ubID);
|
||||
|
||||
Cancel();
|
||||
gTraitSelection.Cancel();
|
||||
}
|
||||
/////////////////////////////// Skill Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
|
||||
void
|
||||
ArtillerySector::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) )
|
||||
{
|
||||
SetupPopup("ArtillerySector");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
// check wether we can call artillery from the 4 adjacent sectors
|
||||
for (UINT8 i = 0; i < 4; ++i)
|
||||
{
|
||||
INT16 loopX = pSoldier->sSectorX;
|
||||
INT16 loopY = pSoldier->sSectorY;
|
||||
|
||||
if ( i == 0 ) ++loopY;
|
||||
else if ( i == 1 ) ++loopX;
|
||||
else if ( i == 2 ) --loopY;
|
||||
else if ( i == 3 ) --loopX;
|
||||
|
||||
if ( loopX < 1 || loopX >= MAP_WORLD_X - 1 || loopY < 1 || loopY >= MAP_WORLD_Y - 1 )
|
||||
continue;
|
||||
|
||||
UINT32 sectornr = (UINT32)SECTOR( loopX, loopY );
|
||||
|
||||
swprintf( pStr, L"%c%d", loopY + 'A' - 1, loopX );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ArtilleryTeam, sectornr ) );
|
||||
|
||||
// grey out if no artillery can be called from this sector
|
||||
if ( !IsValidArtilleryOrderSector( loopX, loopY, pSoldier->bSectorZ, pSoldier->bTeam ) && !IsValidArtilleryOrderSector( loopX, loopY, pSoldier->bSectorZ, MILITIA_TEAM ) )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtillerySector, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// same y, different x
|
||||
SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY);
|
||||
}
|
||||
/////////////////////////////// Artillery Sector Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
|
||||
void
|
||||
ArtilleryTeam::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) && pSoldier->bSectorZ == 0)
|
||||
{
|
||||
usSector = aVal;
|
||||
|
||||
SetupPopup("ArtilleryTeam");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
// determine sector coordinates
|
||||
INT16 sSectorX = SECTORX(usSector);
|
||||
INT16 sSectorY = SECTORY(usSector);
|
||||
|
||||
// order artillery from militia
|
||||
swprintf( pStr, L"Militia" );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ArtilleryTeam, MILITIA_TEAM ) );
|
||||
|
||||
// grey out if no ArtilleryTeam can be called from this sector
|
||||
if ( !IsValidArtilleryOrderSector( sSectorX, sSectorY, pSoldier->bSectorZ, MILITIA_TEAM ) )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// order artillery from our mercs
|
||||
swprintf( pStr, L"Other Squads" );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, INT8>( &Wrapper_Function_ArtilleryTeam, pSoldier->bTeam ) );
|
||||
|
||||
// grey out if no ArtilleryTeam can be called from this sector
|
||||
if ( !IsValidArtilleryOrderSector( sSectorX, sSectorY, pSoldier->bSectorZ, pSoldier->bTeam ) )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtilleryTeam, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// same y, different x
|
||||
SetPos(gArtillerySector.GetMaxPosX(), usTraitMenuPosY);
|
||||
}
|
||||
|
||||
void
|
||||
ArtilleryTeam::Functions( UINT32 aVal )
|
||||
{
|
||||
Cancel();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL || !pSoldier->CanUseSkill(SKILLS_RADIO_ARTILLERY) )
|
||||
return;
|
||||
|
||||
pSoldier->OrderArtilleryStrike(usSector, sTraitsMenuTargetGridNo, (UINT8)(aVal));
|
||||
|
||||
Cancel();
|
||||
gArtillerySector.Cancel();
|
||||
gSkillSelection.Cancel();
|
||||
gTraitSelection.Cancel();
|
||||
}
|
||||
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
|
||||
extern UINT8 CountAllMilitiaInSector(INT16 sMapX, INT16 sMapY);
|
||||
|
||||
void
|
||||
ReinforcementSector::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( pSoldier->CanUseSkill(aVal) )
|
||||
{
|
||||
SetupPopup("Reinforcements sector");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
// check wether we can call artillery from the 4 adjacent sectors
|
||||
for (UINT8 i = 0; i < 4; ++i)
|
||||
{
|
||||
INT16 loopX = pSoldier->sSectorX;
|
||||
INT16 loopY = pSoldier->sSectorY;
|
||||
|
||||
if ( i == 0 ) ++loopY;
|
||||
else if ( i == 1 ) ++loopX;
|
||||
else if ( i == 2 ) --loopY;
|
||||
else if ( i == 3 ) --loopX;
|
||||
|
||||
if ( loopX < 1 || loopX >= MAP_WORLD_X - 1 || loopY < 1 || loopY >= MAP_WORLD_Y - 1 )
|
||||
continue;
|
||||
|
||||
UINT32 sectornr = (UINT32)SECTOR( loopX, loopY );
|
||||
|
||||
swprintf( pStr, L"%c%d", loopY + 'A' - 1, loopX );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_ReinforcementNumber, sectornr ) );
|
||||
|
||||
// grey out if no reinforcements can be called from this sector
|
||||
if( !CountAllMilitiaInSector( loopX, loopY ) )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Cancel_ReinforcementSector, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// same y, different x
|
||||
SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY);
|
||||
}
|
||||
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
|
||||
void
|
||||
ReinforcementNumber::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( pSoldier->CanUseSkill(SKILLS_RADIO_CALLREINFORCEMENTS) )
|
||||
{
|
||||
usSector = aVal;
|
||||
|
||||
SetupPopup("Reinforcements number submenu");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
UINT8 numberofmilitia = CountAllMilitiaInSector( SECTORX(usSector), SECTORY(usSector) );
|
||||
|
||||
// 5 militia option
|
||||
swprintf( pStr, L"5 Militia" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 5 ) );
|
||||
|
||||
if ( numberofmilitia < 5 )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// 10 militia option
|
||||
swprintf( pStr, L"10 Militia" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 10 ) );
|
||||
|
||||
if ( numberofmilitia < 10 )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// 15 militia option
|
||||
swprintf( pStr, L"15 Militia" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 15 ) );
|
||||
|
||||
if ( numberofmilitia < 15 )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// 20 militia option
|
||||
swprintf( pStr, L"20 Militia" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 20 ) );
|
||||
|
||||
if ( numberofmilitia < 20 )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// all militia option
|
||||
swprintf( pStr, L"All Militia" );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, numberofmilitia ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Cancel_ReinforcementNumber, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// same y, different x
|
||||
SetPos(gReinforcementSector.GetMaxPosX(), usTraitMenuPosY);
|
||||
}
|
||||
|
||||
void
|
||||
ReinforcementNumber::Functions( UINT32 aVal )
|
||||
{
|
||||
Cancel();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL || !pSoldier->CanUseSkill(SKILLS_RADIO_CALLREINFORCEMENTS) )
|
||||
return;
|
||||
|
||||
pSoldier->RadioCallReinforcements(usSector, aVal);
|
||||
|
||||
Cancel();
|
||||
gReinforcementSector.Cancel();
|
||||
gSkillSelection.Cancel();
|
||||
gTraitSelection.Cancel();
|
||||
}
|
||||
/////////////////////////////// Reinforcement Number Selection ////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
|
||||
void
|
||||
SoldierSelection::Setup( UINT32 aVal )
|
||||
{
|
||||
Destroy();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
if ( pSoldier->CanUseSkill(aVal) )
|
||||
{
|
||||
usSkill = aVal;
|
||||
|
||||
SetupPopup("SoldierSelection");
|
||||
|
||||
POPUP_OPTION *pOption;
|
||||
|
||||
CHAR16 pStr[300];
|
||||
|
||||
// pretty simple: we find every soldier in a radius around the target position and add him to the list
|
||||
// loop through all soldiers around
|
||||
for ( UINT32 cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID ; cnt <= gTacticalStatus.Team[ CIV_TEAM ].bLastID ; ++cnt )
|
||||
{
|
||||
INT32 iRange = GetRangeInCellCoordsFromGridNoDiff( sTraitsMenuTargetGridNo, MercPtrs[ cnt ]->sGridNo );
|
||||
|
||||
if ( iRange < 100 )
|
||||
{
|
||||
if ( cnt != pSoldier->ubID )
|
||||
{
|
||||
swprintf( pStr, L"%s", MercPtrs[ cnt ]->GetName() );
|
||||
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT8>( &Wrapper_Function_SoldierSelection, cnt ) );
|
||||
|
||||
// grey out if no artillery can be called from this sector
|
||||
if ( 0 )
|
||||
{
|
||||
// Set this option off.
|
||||
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
||||
}
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cancel option
|
||||
swprintf( pStr, L"Cancel" );
|
||||
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_SoldierSelection, 0 ) );
|
||||
GetPopup()->addOption( *pOption );
|
||||
}
|
||||
|
||||
// same y, different x
|
||||
SetPos(gSkillSelection.GetMaxPosX(), usTraitMenuPosY);
|
||||
}
|
||||
|
||||
void
|
||||
SoldierSelection::Functions( UINT32 aVal )
|
||||
{
|
||||
Cancel();
|
||||
|
||||
SOLDIERTYPE * pSoldier = NULL;
|
||||
|
||||
GetSoldier( &pSoldier, gusSelectedSoldier );
|
||||
|
||||
if ( pSoldier == NULL )
|
||||
return;
|
||||
|
||||
pSoldier->UseSkill(usSkill, sTraitsMenuTargetGridNo, aVal);
|
||||
|
||||
Cancel();
|
||||
gSkillSelection.Cancel();
|
||||
gTraitSelection.Cancel();
|
||||
}
|
||||
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Flugente: traits menu popup box
|
||||
* This will create other boxes when needed
|
||||
*/
|
||||
void TraitsMenu( INT32 usMapPos )
|
||||
{
|
||||
sTraitsMenuTargetGridNo = usMapPos;
|
||||
|
||||
gTraitSelection.Setup(0);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
#ifndef _SKILL_MENU_
|
||||
#define _SKILL_MENU_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @author Flugente (bears-pit.com)
|
||||
*/
|
||||
|
||||
#include "popup_class.h"
|
||||
|
||||
/**
|
||||
* @brief A basic class for popup menus
|
||||
* Use this to create mensu calling other menus, each having various sub-options
|
||||
* I tried to make this as orderly as possible. It's ugly, but much more clean than the first solution, which was a hardcoded mess.
|
||||
* You will, however, still need wrapper functions (we use callbacks on member functions), see Implementation.
|
||||
*/
|
||||
class SkillMenuItem
|
||||
{
|
||||
public:
|
||||
SkillMenuItem() :
|
||||
fInitialized(FALSE), usPosX(0), gPopup(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Cancel()
|
||||
{
|
||||
// Hide the Filter Menu pop-up.
|
||||
if (gPopup != NULL && fInitialized )
|
||||
{
|
||||
gPopup->hide();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Destroy()
|
||||
{
|
||||
// If we already have a popup, destroy it first. This ensures we get a fresh menu each time.
|
||||
if ( fInitialized )
|
||||
{
|
||||
delete(gPopup);
|
||||
gPopup = NULL;
|
||||
fInitialized = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
UINT16 GetMaxPosX()
|
||||
{
|
||||
if ( gPopup )
|
||||
return (usPosX + gPopup->getBoxDimensions().iRight);
|
||||
|
||||
return usPosX;
|
||||
}
|
||||
|
||||
virtual void SetPos(UINT16 usX, UINT16 usY)
|
||||
{
|
||||
// same y, different x
|
||||
usPosX = usX;
|
||||
gPopup->setPosition( usPosX, usY );
|
||||
|
||||
fInitialized = TRUE;
|
||||
gPopup->show();
|
||||
}
|
||||
|
||||
void SetupPopup(CHAR* name);
|
||||
|
||||
POPUP* GetPopup()
|
||||
{
|
||||
return gPopup;
|
||||
}
|
||||
|
||||
virtual void Setup( UINT32 aVal ) {}
|
||||
virtual void Functions( UINT32 aVal ) {}
|
||||
|
||||
private:
|
||||
BOOLEAN fInitialized;
|
||||
UINT16 usPosX;
|
||||
POPUP* gPopup;
|
||||
};
|
||||
|
||||
// select a trait
|
||||
class TraitSelection : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
TraitSelection() {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
};
|
||||
|
||||
// select a skill
|
||||
class SkillSelection : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
SkillSelection() : usSector(0) {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
void Functions( UINT32 aVal );
|
||||
|
||||
private:
|
||||
UINT32 usSector;
|
||||
};
|
||||
|
||||
// select sector to call artillery from
|
||||
class ArtillerySector : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
ArtillerySector() {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
};
|
||||
|
||||
// select team we request artillery from
|
||||
class ArtilleryTeam : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
ArtilleryTeam() : usSector(0) {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
void Functions( UINT32 aVal );
|
||||
|
||||
private:
|
||||
UINT32 usSector;
|
||||
};
|
||||
|
||||
// select the sector we call reinforcements from
|
||||
class ReinforcementSector : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
ReinforcementSector() {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
};
|
||||
|
||||
// select the number of milita that should reinforce
|
||||
class ReinforcementNumber : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
ReinforcementNumber() : usSector(0) {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
void Functions( UINT32 aVal );
|
||||
|
||||
private:
|
||||
UINT32 usSector;
|
||||
};
|
||||
|
||||
// select an individual soldier as target of a skill
|
||||
class SoldierSelection : public SkillMenuItem
|
||||
{
|
||||
public:
|
||||
SoldierSelection() : usSkill(0) {}
|
||||
|
||||
void Setup( UINT32 aVal );
|
||||
void Functions( UINT32 aVal );
|
||||
|
||||
private:
|
||||
UINT32 usSkill;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Flugente: traits menu popup box
|
||||
* This will create other boxes when needed
|
||||
*/
|
||||
void TraitsMenu( INT32 usMapPos );
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
+98
-26
@@ -353,34 +353,34 @@ enum
|
||||
|
||||
// -------- added by Flugente: various flags for soldiers --------
|
||||
// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
#define SOLDIER_DRUGGED 0x00000001 //1 // Soldier is on drugs
|
||||
#define SOLDIER_NO_AP 0x00000002 //2 // Soldier has no APs this turn (fix for reinforcement bug)
|
||||
#define SOLDIER_COVERT_CIV 0x00000004 //4 // Soldier is currently disguised as a civilian
|
||||
#define SOLDIER_COVERT_SOLDIER 0x00000008 //8 // Soldier is currently disguised as an enemy soldier
|
||||
#define SOLDIER_DRUGGED 0x00000001 //1 // Soldier is on drugs
|
||||
#define SOLDIER_NO_AP 0x00000002 //2 // Soldier has no APs this turn (fix for reinforcement bug)
|
||||
#define SOLDIER_COVERT_CIV 0x00000004 //4 // Soldier is currently disguised as a civilian
|
||||
#define SOLDIER_COVERT_SOLDIER 0x00000008 //8 // Soldier is currently disguised as an enemy soldier
|
||||
|
||||
#define SOLDIER_DAMAGED_VEST 0x00000010 //16 // Soldier's vest is damaged (and thus can't be taken off)
|
||||
#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs when recruited (used for covert stuff)
|
||||
#define SOLDIER_NEW_VEST 0x00000040 //64 // Soldier is wearing new vest. if having both vest and pants, he can disguise
|
||||
#define SOLDIER_NEW_PANTS 0x00000080 //128 // Soldier is wearing new pants
|
||||
#define SOLDIER_DAMAGED_VEST 0x00000010 //16 // Soldier's vest is damaged (and thus can't be taken off)
|
||||
#define SOLDIER_COVERT_NPC_SPECIAL 0x00000020 //32 // Special flag for NPCs when recruited (used for covert stuff)
|
||||
#define SOLDIER_NEW_VEST 0x00000040 //64 // Soldier is wearing new vest. if having both vest and pants, he can disguise
|
||||
#define SOLDIER_NEW_PANTS 0x00000080 //128 // Soldier is wearing new pants
|
||||
|
||||
#define SOLDIER_DAMAGED_PANTS 0x00000100 //256 // Soldier's vest is damaged (and thus can't be taken off)
|
||||
#define SOLDIER_HEADSHOT 0x00000200 //512 // last hit received was a headshot (attack to the head, so knifes/punches also work)
|
||||
#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war
|
||||
#define SOLDIER_ASSASSIN 0x00000800 //2048 // we are an enemy assassin, and thus we will behave very different from normal enemies
|
||||
#define SOLDIER_DAMAGED_PANTS 0x00000100 //256 // Soldier's vest is damaged (and thus can't be taken off)
|
||||
#define SOLDIER_HEADSHOT 0x00000200 //512 // last hit received was a headshot (attack to the head, so knifes/punches also work)
|
||||
#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war
|
||||
#define SOLDIER_ASSASSIN 0x00000800 //2048 // we are an enemy assassin, and thus we will behave very different from normal enemies
|
||||
|
||||
#define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive
|
||||
#define SOLDIER_EQUIPMENT_DROPPED 0x00002000 //8192 // under certain circumstances, militia can be ordered to drop their gear twice. Thus we set a marker to avoid that.
|
||||
#define SOLDIER_ACCESSTEAMMEMBER 0x00004000 //16384 // this merc is accessing another team member'S inventory (via abusing the stealing mechanic)
|
||||
#define SOLDIER_REDOFLASHLIGHT 0x00008000 //32768 // this flag signifies that we somehow interacted with the items in our hands. Thus we have to possible redo lighting from flashlights
|
||||
#define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive
|
||||
#define SOLDIER_EQUIPMENT_DROPPED 0x00002000 //8192 // under certain circumstances, militia can be ordered to drop their gear twice. Thus we set a marker to avoid that.
|
||||
#define SOLDIER_ACCESSTEAMMEMBER 0x00004000 //16384 // this merc is accessing another team member'S inventory (via abusing the stealing mechanic)
|
||||
#define SOLDIER_REDOFLASHLIGHT 0x00008000 //32768 // this flag signifies that we somehow interacted with the items in our hands. Thus we have to possible redo lighting from flashlights
|
||||
|
||||
#define SOLDIER_LIGHT_OWNER 0x00010000 //65536 // we 'own' at least one light source (via flashlights)
|
||||
#define SOLDIER_AIRDROP_BONUS 0x00020000 //131072 // backgrounds: special AP bonus during the first turn of an airdrop
|
||||
#define SOLDIER_ASSAULT_BONUS 0x00040000 //262144 // backgrounds: our first turn in an assault
|
||||
/*#define PLAYER_NET_4_LVL_1 0x00080000 //524288
|
||||
#define SOLDIER_LIGHT_OWNER 0x00010000 //65536 // we 'own' at least one light source (via flashlights)
|
||||
#define SOLDIER_AIRDROP_BONUS 0x00020000 //131072 // backgrounds: special AP bonus during the first turn of an airdrop
|
||||
#define SOLDIER_ASSAULT_BONUS 0x00040000 //262144 // backgrounds: our first turn in an assault
|
||||
#define SOLDIER_RADIO_OPERATOR_LISTENING 0x00080000 //524288 // radio operator is listening with his set
|
||||
|
||||
#define PLAYER_NET_1_LVL_2 0x00100000 //1048576
|
||||
#define PLAYER_NET_2_LVL_2 0x00200000 //2097152
|
||||
#define PLAYER_NET_3_LVL_2 0x00400000 //4194304
|
||||
#define SOLDIER_RADIO_OPERATOR_JAMMING 0x00100000 //1048576 // radio operator is jamming frequencies
|
||||
#define SOLDIER_RADIO_OPERATOR_SCANNING 0x00200000 //2097152 // radio operator is scanning for jammers
|
||||
/*#define PLAYER_NET_3_LVL_2 0x00400000 //4194304
|
||||
#define PLAYER_NET_4_LVL_2 0x00800000 //8388608
|
||||
|
||||
#define PLAYER_NET_1_LVL_3 0x01000000 //16777216
|
||||
@@ -423,6 +423,36 @@ enum
|
||||
NUM_MTA,
|
||||
};
|
||||
|
||||
//Flugente skills from traits and other sources
|
||||
enum{
|
||||
// psyker skills
|
||||
SKILLS_FIRST = 0,
|
||||
|
||||
// radio operator
|
||||
SKILLS_RADIO_FIRST = SKILLS_FIRST,
|
||||
SKILLS_RADIO_ARTILLERY = SKILLS_RADIO_FIRST,
|
||||
SKILLS_RADIO_JAM,
|
||||
SKILLS_RADIO_SCAN_FOR_JAM,
|
||||
SKILLS_RADIO_LISTEN,
|
||||
SKILLS_RADIO_CALLREINFORCEMENTS,
|
||||
SKILLS_RADIO_TURNOFF,
|
||||
SKILLS_RADIO_LAST = SKILLS_RADIO_TURNOFF,
|
||||
|
||||
SKILLS_MAX,
|
||||
};
|
||||
|
||||
// Flugente: certain skills/traits/taints add effects that require a counter, here are enums for these
|
||||
enum {
|
||||
SOLDIER_COUNTER_RADIO_ARTILLERY, // there is actually no need for an artillery timer, but we use one to forbid the same AI guy ordering multiple strikes at once
|
||||
|
||||
SOLDIER_COUNTER_MAX = 20, // enough space for fillers
|
||||
};
|
||||
|
||||
// Flugente: certain skills/traits/taints require a cooldown timer
|
||||
enum {
|
||||
SOLDIER_COOLDOWN_MAX = 20, // enough space for fillers
|
||||
};
|
||||
|
||||
// enum of uniform pieces
|
||||
typedef struct
|
||||
{
|
||||
@@ -1297,12 +1327,17 @@ public:
|
||||
|
||||
UINT16 usSoldierProfile; // Flugente: allow linking to a xml-based profile specifiying name, visuals, traits etc.
|
||||
|
||||
// Flugente: sector ID for move items assignemnt
|
||||
// Flugente: sector ID for move items assignment
|
||||
UINT8 usItemMoveSectorID;
|
||||
|
||||
// Flugente: skill stuff
|
||||
UINT8 usAISkillUse; // this variable allows the AI to remember which skill it wants to use
|
||||
UINT16 usSkillCounter[SOLDIER_COUNTER_MAX]; // counters used for various skill/trait/taint effects
|
||||
UINT32 usSkillCooldown[SOLDIER_COOLDOWN_MAX]; // cooldown used for various skill/trait/taint effects
|
||||
|
||||
// Flugente: Decrease this filler by 1 for each new UINT8 / BOOLEAN variable, so we can maintain savegame compatibility!!
|
||||
// Note that we also have to account for padding, so you might need to substract more than just the size of the new variables
|
||||
UINT8 ubFiller[7];
|
||||
UINT8 ubFiller[20];
|
||||
|
||||
#ifdef JA2UB
|
||||
//ja25
|
||||
@@ -1610,6 +1645,38 @@ public:
|
||||
|
||||
void SoldierPropertyUpkeep(); // update functions for various properties (updating counters, resetting flags etc.)
|
||||
|
||||
// Flugente: functions for skill usage
|
||||
// traits can allow use of certain skills
|
||||
// check if Soldier can use the spell skillwise, with fAPCheck = TRUE also check current APs
|
||||
BOOLEAN CanUseSkill( INT8 iSkill, BOOLEAN fAPCheck = TRUE );
|
||||
|
||||
// use a skill. For safety reasons, this calls CanUseSkill again (it is possible to switch the soldier while the menu is open)
|
||||
BOOLEAN UseSkill( UINT8 iSkill, INT32 usMapPos, UINT8 ID );
|
||||
|
||||
// is the AI allowed to use a skill? we have to check how much breath and life using this skill would cost, as otherwise the AI might commit suicide by casting
|
||||
BOOLEAN IsAIAllowedtoUseSkill( INT8 iSkill );
|
||||
|
||||
// print a small description of the skill if we can use it, or its requirements if we cannot
|
||||
STR16 PrintSkillDesc( INT8 iSkill);
|
||||
|
||||
// Flugente: functions for the radio operator trait
|
||||
BOOLEAN CanUseRadio(); // can we use radio, if we even have one?
|
||||
BOOLEAN UseRadio(); // simply drain the batteries
|
||||
BOOLEAN HasMortar();
|
||||
BOOLEAN GetSlotOfSignalShellIfMortar(UINT8* pbLoop); // if we have a mortar and a fitting signal shell, return the inventory slot it is in
|
||||
BOOLEAN CanAnyArtilleryStrikeBeOrdered(UINT32* pSectorID); // can any artillery strikes be ordered by this guy's team from the neighbouring sectors?
|
||||
BOOLEAN OrderArtilleryStrike( UINT32 usSectorNr, INT32 sTargetGridNo, UINT8 bTeam );
|
||||
BOOLEAN IsJamming(); // are we currently jamming communication frequencies?
|
||||
BOOLEAN JamCommunications();
|
||||
BOOLEAN IsScanning();
|
||||
BOOLEAN ScanForJam();
|
||||
BOOLEAN IsRadioListening();
|
||||
BOOLEAN RadioListen();
|
||||
BOOLEAN RadioCallReinforcements( UINT32 usSector, UINT16 sNumber );
|
||||
BOOLEAN SwitchOffRadio();
|
||||
void RadioFail(); // display and error sound used either when the radio set fails or the sector is jammed - the player knows of the error, but cannot be sure of the cause
|
||||
void DepleteActiveRadioSetEnergy(BOOLEAN fActivation = FALSE, BOOLEAN fAssignment = FALSE);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
@@ -1737,7 +1804,12 @@ BOOLEAN ResolvePendingInterrupt( SOLDIERTYPE * pSoldier, UINT8 ubInterruptType )
|
||||
BOOLEAN AIDecideHipOrShoulderStance( SOLDIERTYPE * pSoldier, INT32 iGridNo );
|
||||
BOOLEAN DecideAltAnimForBigMerc( SOLDIERTYPE * pSoldier );
|
||||
|
||||
BOOLEAN TwoStagedTrait( UINT8 uiSkillTraitNumber ); // Flugente: determine if this (new) trait has two stages
|
||||
// added by Flugente
|
||||
BOOLEAN TwoStagedTrait( UINT8 uiSkillTraitNumber ); // determine if this (new) trait has two stages
|
||||
BOOLEAN GetRadioOperatorSignal(UINT8 usOwner, INT32* psTargetGridNo); // retrieve the gridno of a radio operator who (or whose team) ordered an artillery strike
|
||||
BOOLEAN IsValidArtilleryOrderSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 bTeam ); // can an artillery strike be ordered FROM this sector
|
||||
BOOLEAN SectorJammed();
|
||||
BOOLEAN PlayerTeamIsScanning();
|
||||
|
||||
//typedef struct
|
||||
class OLDSOLDIERTYPE_101
|
||||
|
||||
@@ -4630,6 +4630,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
BOOLEAN foundThrowing = FALSE;
|
||||
BOOLEAN foundHtH = FALSE;
|
||||
BOOLEAN foundMelee = FALSE;
|
||||
BOOLEAN fRadioSetFound = FALSE;
|
||||
|
||||
// FIRST FIND OUT THE COMPOSITION OF OUR GEAR
|
||||
for (bLoop = 0; bLoop < (INT8) pSoldier->inv.size(); bLoop++)
|
||||
@@ -4653,6 +4654,8 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
else if (Item[pCreateStruct->Inv[bLoop].usItem].usItemClass == 128 && // 128 is an identifier of blunt melee weapons
|
||||
Item[pCreateStruct->Inv[bLoop].usItem].uiIndex != 0 )
|
||||
foundMelee = TRUE;
|
||||
else if ( HasItemFlag(pCreateStruct->Inv[bLoop].usItem, RADIO_SET) )
|
||||
fRadioSetFound = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5191,6 +5194,31 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: new traits
|
||||
if ( gGameOptions.fNewTraitSystem && (!ATraitAssigned || !BTraitAssigned || !CTraitAssigned ) )
|
||||
{
|
||||
// if we have a radio set, give us the corresponding trait so we can use it...
|
||||
if ( fRadioSetFound )
|
||||
{
|
||||
if ( !ATraitAssigned )
|
||||
{
|
||||
pSoldier->stats.ubSkillTraits[0] = RADIO_OPERATOR_NT;
|
||||
ATraitAssigned = TRUE;
|
||||
}
|
||||
else if ( !BTraitAssigned )
|
||||
{
|
||||
pSoldier->stats.ubSkillTraits[1] = RADIO_OPERATOR_NT;
|
||||
BTraitAssigned = TRUE;
|
||||
}
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ELITE || ubSolClass == SOLDIER_CLASS_ELITE_MILITIA )
|
||||
{
|
||||
pSoldier->stats.ubSkillTraits[2] = RADIO_OPERATOR_NT;
|
||||
CTraitAssigned = TRUE;
|
||||
return( TRUE ); // We no longer need to continue from here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// RETURN TRUE IF ALL TRAITS ASSIGNED OTHERWISE FALSE
|
||||
if (( !gGameOptions.fNewTraitSystem && ATraitAssigned && BTraitAssigned ) || ( gGameOptions.fNewTraitSystem && ATraitAssigned && BTraitAssigned && CTraitAssigned ) )
|
||||
|
||||
@@ -578,6 +578,10 @@
|
||||
RelativePath=".\SkillCheck.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SkillMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Soldier Add.h"
|
||||
>
|
||||
@@ -904,6 +908,10 @@
|
||||
RelativePath=".\SkillCheck.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SkillMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Soldier Add.cpp"
|
||||
>
|
||||
|
||||
@@ -582,6 +582,10 @@
|
||||
RelativePath="SkillCheck.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="SkillMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Soldier Add.h"
|
||||
>
|
||||
@@ -906,6 +910,10 @@
|
||||
RelativePath="SkillCheck.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="SkillMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Soldier Add.cpp"
|
||||
>
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
<ClInclude Include="ShopKeeper Interface.h" />
|
||||
<ClInclude Include="ShopKeeper Quotes.h" />
|
||||
<ClInclude Include="SkillCheck.h" />
|
||||
<ClInclude Include="SkillMenu.h" />
|
||||
<ClInclude Include="Soldier Add.h" />
|
||||
<ClInclude Include="Soldier Ani.h" />
|
||||
<ClInclude Include="Soldier Control.h" />
|
||||
@@ -165,6 +166,7 @@
|
||||
<ClCompile Include="Rotting Corpses.cpp" />
|
||||
<ClCompile Include="ShopKeeper Interface.cpp" />
|
||||
<ClCompile Include="SkillCheck.cpp" />
|
||||
<ClCompile Include="SkillMenu.cpp" />
|
||||
<ClCompile Include="Soldier Add.cpp" />
|
||||
<ClCompile Include="Soldier Ani.cpp" />
|
||||
<ClCompile Include="Soldier Control.cpp" />
|
||||
|
||||
@@ -264,6 +264,9 @@
|
||||
<ClInclude Include="Food.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SkillMenu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Air Raid.cpp">
|
||||
@@ -647,5 +650,8 @@
|
||||
<ClCompile Include="XML_Background.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SkillMenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -114,7 +114,8 @@
|
||||
#include "fresh_header.h"
|
||||
|
||||
|
||||
#include "IMP Skill Trait.h" // added by Flugente
|
||||
#include "IMP Skill Trait.h" // added by Flugente
|
||||
#include "SkillMenu.h" // added by Flugente
|
||||
|
||||
//forward declarations of common classes to eliminate includes
|
||||
class OBJECTTYPE;
|
||||
@@ -2495,7 +2496,15 @@ void GetKeyboardInput( UINT32 *puiNewEvent )
|
||||
break;
|
||||
|
||||
case '$':
|
||||
ChangeCurrentSquad( 13 );
|
||||
{
|
||||
// Flugente: trait skill selection menu. Yes, screw squad 13
|
||||
INT32 usMapPos;
|
||||
if ( GetMouseMapPos( &usMapPos ) )
|
||||
{
|
||||
TraitsMenu(usMapPos);
|
||||
}
|
||||
}
|
||||
//ChangeCurrentSquad( 13 );
|
||||
break;
|
||||
|
||||
case '%':
|
||||
|
||||
@@ -13019,4 +13019,85 @@ FLOAT CalcNewChanceToHitAimTraitBonus(SOLDIERTYPE *pSoldier, FLOAT fAimCap, FLOA
|
||||
}
|
||||
|
||||
return fAimChance;
|
||||
}
|
||||
|
||||
extern BOOLEAN IsRoofPresentAtGridNo( INT32 sGridNo );
|
||||
|
||||
// Flugente: fire item from A to B (intended for mortarshells and launchable grenades)
|
||||
BOOLEAN ArtilleryStrike( UINT16 usItem, UINT32 usStartingGridNo, UINT32 usTargetMapPos )
|
||||
{
|
||||
FLOAT dForce, dDegrees;
|
||||
INT16 sDestX, sDestY, sSrcX, sSrcY;
|
||||
vector_3 vForce, vDirNormal;
|
||||
INT16 sStartZ = ( 1 * 256 ) + 50;
|
||||
INT16 sEndZ = 0;
|
||||
|
||||
// radius is way smaller for signal shells, otherwise the inaccuraccy would increase too much
|
||||
INT8 bRadius = gSkillTraitValues.usVOMortarRadius;
|
||||
if ( HasItemFlag(usItem, SIGNAL_SHELL) )
|
||||
bRadius = gSkillTraitValues.usVOMortarSignalShellRadius;
|
||||
|
||||
INT32 sTargetGridNo = GetArtilleryTargetGridNo( usTargetMapPos, bRadius );
|
||||
|
||||
if ( TileIsOutOfBounds(sTargetGridNo) )
|
||||
return FALSE;
|
||||
|
||||
UINT8 ubLevel = 0;
|
||||
if ( IsRoofPresentAtGridNo( sTargetGridNo ) )
|
||||
ubLevel = 1;
|
||||
|
||||
// create shell
|
||||
OBJECTTYPE shellobj;
|
||||
CreateItem( usItem, 100, &shellobj );
|
||||
|
||||
// Get basic launch params...
|
||||
if ( !GetArtilleryLaunchParams(usStartingGridNo, sTargetGridNo, sStartZ, sEndZ, usItem, &shellobj, &dForce, &dDegrees) )
|
||||
return FALSE;
|
||||
|
||||
// Get XY from gridno
|
||||
ConvertGridNoToCenterCellXY( sTargetGridNo, &sDestX, &sDestY );
|
||||
ConvertGridNoToCenterCellXY( usStartingGridNo, &sSrcX, &sSrcY );
|
||||
|
||||
// OK, get direction normal
|
||||
vDirNormal.x = (float)(sDestX - sSrcX);
|
||||
vDirNormal.y = (float)(sDestY - sSrcY);
|
||||
vDirNormal.z = 0;
|
||||
|
||||
// NOmralize
|
||||
vDirNormal = VGetNormal( &vDirNormal );
|
||||
|
||||
// From degrees, calculate Z portion of normal
|
||||
vDirNormal.z = (float)sin( dDegrees );
|
||||
|
||||
// Do force....
|
||||
vForce.x = dForce * vDirNormal.x;
|
||||
vForce.y = dForce * vDirNormal.y;
|
||||
vForce.z = dForce * vDirNormal.z;
|
||||
|
||||
float dX = (float)sSrcX;
|
||||
float dY = (float)sSrcY;
|
||||
float dZ = (float)sStartZ;
|
||||
float dForceX = vForce.x;
|
||||
float dForceY = vForce.y;
|
||||
float dForceZ = vForce.z;
|
||||
|
||||
if ( Weapon[ usItem ].sSound != NO_WEAPON_SOUND )
|
||||
{
|
||||
PlayJA2Sample( Weapon[ usItem ].sSound, RATE_11025, SoundVolume( HIGHVOLUME, usStartingGridNo ), 1, SoundDir( usStartingGridNo ) );
|
||||
}
|
||||
|
||||
INT32 iID = CreatePhysicalObject( &shellobj, -1, dX, dY, dZ, dForceX, dForceY, dForceZ, 0, THROW_ARM_ITEM, 0, FALSE );
|
||||
|
||||
// OJW - 20091002 - Explosives
|
||||
/*if (is_networked && is_client)
|
||||
{
|
||||
if (pSoldier->bTeam == 0 || (pSoldier->bTeam == 1 && is_server))
|
||||
{
|
||||
send_grenade( &shellobj , dLifeSpan,dX, dY, dZ, dForceX, dForceY, dForceZ, sTargetGridNo, pSoldier->ubID, ubActionCode, uiActionData, iID , false);
|
||||
}
|
||||
}*/
|
||||
|
||||
//REAL_OBJECT* pObject = &( ObjectSlots[ iID ] );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -283,6 +283,7 @@ enum
|
||||
EXPLOSV_CREATUREGAS,
|
||||
EXPLOSV_BURNABLEGAS,
|
||||
EXPLOSV_FLASHBANG,
|
||||
EXPLOSV_SIGNAL_SMOKE,
|
||||
};
|
||||
|
||||
#define AMMO_DAMAGE_ADJUSTMENT_BUCKSHOT( x ) (x / 4)
|
||||
@@ -539,4 +540,6 @@ FLOAT GetOverheatJamThreshold( OBJECTTYPE *pObj );
|
||||
FLOAT GetOverheatDamageThresholdModifier( OBJECTTYPE *pObj );
|
||||
FLOAT GetOverheatDamageThreshold( OBJECTTYPE *pObj );
|
||||
|
||||
BOOLEAN ArtilleryStrike( UINT16 usItem, UINT32 usStartingGridNo, UINT32 usTargetMapPos );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -136,6 +136,9 @@ explosiveEndElementHandle(void *userData, const XML_Char *name)
|
||||
{
|
||||
pData->curElement = ELEMENT;
|
||||
pData->curExplosive.ubRadius = (UINT8) atol(pData->szCharData);
|
||||
|
||||
// Flugente: variable is UINT16, but is always used as UINT8, so better keep it in line
|
||||
pData->curExplosive.ubRadius = max( 0, min(255, pData->curExplosive.ubRadius));
|
||||
}
|
||||
else if(strcmp(name, "ubVolume") == 0)
|
||||
{
|
||||
|
||||
@@ -161,19 +161,20 @@ typedef enum
|
||||
|
||||
// Flugente: new traits have to go here, even if they are major traits, as otherwise the existing traits in profiles get mixed up
|
||||
COVERT_NT, // 20
|
||||
RADIO_OPERATOR_NT, //21 // a minor trait
|
||||
|
||||
NUM_SKILLTRAITS_NT
|
||||
} SkillTraitNew;
|
||||
|
||||
#define NUM_MAJOR_TRAITS 10
|
||||
#define NUM_MINOR_TRAITS 10
|
||||
#define NUM_MINOR_TRAITS 11
|
||||
|
||||
#define NUM_ORIGINAL_MAJOR_TRAITS 9
|
||||
|
||||
// Flugente: I've had it with this hardcoding madness. Without this, adding or removing a new trait would crash anything related to a bubblehelp display of traits
|
||||
// always check every use of these enums and every use of the skill-strings if you add a new trait
|
||||
#define NEWTRAIT_MERCSKILL_EXPERTOFFSET NUM_MAJOR_TRAITS + NUM_MINOR_TRAITS
|
||||
#define NEWTRAIT_MERCSKILL_OFFSET_ALL NEWTRAIT_MERCSKILL_EXPERTOFFSET + NUM_MAJOR_TRAITS
|
||||
#define NEWTRAIT_MERCSKILL_EXPERTOFFSET (NUM_MAJOR_TRAITS + NUM_MINOR_TRAITS)
|
||||
#define NEWTRAIT_MERCSKILL_OFFSET_ALL (NEWTRAIT_MERCSKILL_EXPERTOFFSET + NUM_MAJOR_TRAITS)
|
||||
|
||||
// SANDRO - new set of character traits
|
||||
typedef enum
|
||||
|
||||
Reference in New Issue
Block a user