mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
1123 lines
36 KiB
C++
1123 lines
36 KiB
C++
/**
|
|
* @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"
|
|
#include "Queen Command.h"
|
|
#include "strategicmap.h"
|
|
#include "Map Screen Interface.h"
|
|
#include "Rotting Corpses.h"
|
|
#include "Dialogue Control.h"
|
|
#include "Handle Items.h"
|
|
|
|
extern void GetEquipmentTemplates( );
|
|
|
|
std::vector<std::string> gTemplateVector;
|
|
|
|
extern void ReadEquipmentTable( SOLDIERTYPE* pSoldier, std::string name );
|
|
|
|
extern INT8 bSelectedInfoChar;
|
|
|
|
// sevenfm: need this for correct calculation of traits menu position
|
|
extern INT16 gsInterfaceLevel;
|
|
extern void BeginAutoBandage();
|
|
|
|
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_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(); }
|
|
|
|
void Wrapper_Setup_AutobandageSelection(UINT32 aVal)
|
|
{
|
|
gSkillSelection.Cancel();
|
|
gTraitSelection.Cancel();
|
|
|
|
BeginAutoBandage();
|
|
}
|
|
/////////////////////////////// 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 ////////////////////////////////////////////
|
|
|
|
/////////////////////////////// Drag Selection ////////////////////////////////////////////
|
|
DragSelection gDragSelection;
|
|
|
|
void Wrapper_Function_DragSelection( UINT32 aVal) { gDragSelection.Functions(aVal); }
|
|
void Wrapper_Function_DragSelection_GridNo( INT32 aVal ){ gDragSelection.FunctionsGridNo( aVal ); }
|
|
void Wrapper_Setup_DragSelection( UINT32 aVal ) { gDragSelection.Setup( aVal ); }
|
|
void Wrapper_Cancel_DragSelection( UINT32 aVal ) { gDragSelection.Cancel( ); }
|
|
/////////////////////////////// Drag 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 = 5;
|
|
UINT8 traitarray[num];
|
|
traitarray[0] = RADIO_OPERATOR_NT;
|
|
traitarray[1] = INTEL;
|
|
traitarray[2] = DISGUISE;
|
|
traitarray[3] = VARIOUSSKILLS;
|
|
traitarray[4] = AUTOBANDAGESKILLS;
|
|
|
|
for ( int i = 0; i < num; ++i)
|
|
{
|
|
swprintf( pStr, gzMercSkillTextNew[traitarray[i]] );
|
|
|
|
if (traitarray[i] == AUTOBANDAGESKILLS)
|
|
{
|
|
pOption = new POPUP_OPTION(&std::wstring(pStr), new popupCallbackFunction<void, UINT32>(&Wrapper_Setup_AutobandageSelection, traitarray[i]));
|
|
}
|
|
else
|
|
{
|
|
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, pSkillMenuStrings[SKILLMENU_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;
|
|
// sevenfm: changed TraitsMenu position from soldier to mouse
|
|
//GetSoldierScreenPos( pSoldier, &sX, &sY );
|
|
GetGridNoScreenPos( sTraitsMenuTargetGridNo, (UINT8)gsInterfaceLevel, &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;
|
|
|
|
case INTEL:
|
|
{
|
|
for ( UINT32 uiCounter = SKILLS_INTEL_FIRST; uiCounter <= SKILLS_INTEL_LAST; ++uiCounter )
|
|
{
|
|
swprintf( pStr, pTraitSkillsMenuStrings[uiCounter] );
|
|
|
|
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, sTraitsMenuTargetGridNo ) ) )
|
|
{
|
|
// Set this option off.
|
|
pOption->setAvail( new popupCallbackFunction<bool, void*>( &Popup_OptionOff, NULL ) );
|
|
}
|
|
|
|
GetPopup()->addOption( *pOption );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DISGUISE:
|
|
{
|
|
for ( UINT32 uiCounter = SKILLS_DISGUISE_FIRST; uiCounter <= SKILLS_DISGUISE_LAST; ++uiCounter )
|
|
{
|
|
swprintf( pStr, pTraitSkillsMenuStrings[uiCounter] );
|
|
|
|
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, sTraitsMenuTargetGridNo ) ) )
|
|
{
|
|
// Set this option off.
|
|
pOption->setAvail( new popupCallbackFunction<bool, void*>( &Popup_OptionOff, NULL ) );
|
|
}
|
|
|
|
GetPopup()->addOption( *pOption );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case VARIOUSSKILLS:
|
|
{
|
|
for(UINT32 uiCounter = SKILLS_VARIOUS_FIRST; uiCounter <= SKILLS_VARIOUS_LAST; ++uiCounter)
|
|
{
|
|
swprintf( pStr, pTraitSkillsMenuStrings[uiCounter] );
|
|
|
|
if ( uiCounter == SKILLS_DRAG )
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Setup_DragSelection, 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, sTraitsMenuTargetGridNo )) )
|
|
{
|
|
// Set this option off.
|
|
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
|
}
|
|
|
|
GetPopup()->addOption( *pOption );
|
|
}
|
|
|
|
SetTraitToDisplay(VARIOUSSKILLS);
|
|
SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo);
|
|
ToggleTraitRangeView(TRUE);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// cancel option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_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, sTraitsMenuTargetGridNo ) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case INTEL:
|
|
{
|
|
for ( UINT32 uiCounter = SKILLS_INTEL_FIRST; uiCounter <= SKILLS_INTEL_LAST; ++uiCounter )
|
|
{
|
|
SetRegionFastHelpText( &( GetPopup()->MenuRegion[cnt++] ), pSoldier->PrintSkillDesc( uiCounter, sTraitsMenuTargetGridNo ) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DISGUISE:
|
|
for ( UINT32 uiCounter = SKILLS_DISGUISE_FIRST; uiCounter <= SKILLS_DISGUISE_LAST; ++uiCounter )
|
|
{
|
|
SetRegionFastHelpText( &( GetPopup()->MenuRegion[cnt++] ), pSoldier->PrintSkillDesc( uiCounter, sTraitsMenuTargetGridNo ) );
|
|
}
|
|
break;
|
|
|
|
case VARIOUSSKILLS:
|
|
{
|
|
for(UINT32 uiCounter = SKILLS_VARIOUS_FIRST; uiCounter <= SKILLS_VARIOUS_LAST; ++uiCounter)
|
|
{
|
|
SetRegionFastHelpText( &(GetPopup()->MenuRegion[cnt++]), pSoldier->PrintSkillDesc(uiCounter, sTraitsMenuTargetGridNo ) );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
SkillSelection::Functions( UINT32 aVal )
|
|
{
|
|
Cancel();
|
|
|
|
SOLDIERTYPE * pSoldier = NULL;
|
|
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
if ( pSoldier == NULL )
|
|
return;
|
|
|
|
UINT8 ubID = WhoIsThere2(sTraitsMenuTargetGridNo, 0 );
|
|
|
|
BOOLEAN result = pSoldier->UseSkill(aVal, sTraitsMenuTargetGridNo, ubID);
|
|
|
|
// additional dialogue
|
|
AdditionalTacticalCharacterDialogue_CallsLua( pSoldier, ADE_SKILL_RESULT, aVal, result );
|
|
|
|
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, pSkillMenuStrings[SKILLMENU_CANCEL] );
|
|
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtillerySector, 0 ) );
|
|
GetPopup()->addOption( *pOption );
|
|
|
|
// certain traits have skills whose effects depend on wether someone is near to us (squadleader, commissar). We therefore display our radius of effect while this display is open
|
|
SetTraitToDisplay(RADIO_OPERATOR_NT);
|
|
SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo);
|
|
ToggleTraitRangeView(TRUE);
|
|
}
|
|
|
|
// 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, pSkillMenuStrings[SKILLMENU_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, pSkillMenuStrings[SKILLMENU_OTHERSQUADS] );
|
|
|
|
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, pSkillMenuStrings[SKILLMENU_CANCEL] );
|
|
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void,UINT32>( &Wrapper_Cancel_ArtilleryTeam, 0 ) );
|
|
GetPopup()->addOption( *pOption );
|
|
|
|
// certain traits have skills whose effects depend on wether someone is near to us (squadleader, commissar). We therefore display our radius of effect while this display is open
|
|
SetTraitToDisplay(RADIO_OPERATOR_NT);
|
|
SetGridNoForTraitDisplay(sTraitsMenuTargetGridNo);
|
|
ToggleTraitRangeView(TRUE);
|
|
}
|
|
|
|
// 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;
|
|
|
|
BOOLEAN result = pSoldier->OrderArtilleryStrike(usSector, sTraitsMenuTargetGridNo, (UINT8)(aVal));
|
|
|
|
// additional dialogue
|
|
AdditionalTacticalCharacterDialogue_CallsLua( pSoldier, ADE_SKILL_RESULT, SKILLS_RADIO_ARTILLERY, result );
|
|
|
|
Cancel();
|
|
gArtillerySector.Cancel();
|
|
gSkillSelection.Cancel();
|
|
gTraitSelection.Cancel();
|
|
}
|
|
/////////////////////////////// Artillery Team Selection ////////////////////////////////////////////
|
|
|
|
/////////////////////////////// Reinforcement Sector Selection ////////////////////////////////////////////
|
|
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 ( !CanRequestMilitiaReinforcements( pSoldier->sSectorX, pSoldier->sSectorY, loopX, loopY ) )
|
|
{
|
|
// Set this option off.
|
|
pOption->setAvail(new popupCallbackFunction<bool,void*>( &Popup_OptionOff, NULL ));
|
|
}
|
|
GetPopup()->addOption( *pOption );
|
|
}
|
|
|
|
// cancel option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_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 = NumNonPlayerTeamMembersInSector( SECTORX( usSector ), SECTORY( usSector ), MILITIA_TEAM );
|
|
|
|
// 5 militia option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_X_MILITIA], 5 );
|
|
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, pSkillMenuStrings[SKILLMENU_X_MILITIA], 10 );
|
|
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, pSkillMenuStrings[SKILLMENU_X_MILITIA], 15 );
|
|
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, pSkillMenuStrings[SKILLMENU_X_MILITIA], 20 );
|
|
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 ));
|
|
}
|
|
|
|
// 30 militia option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_X_MILITIA], 30 );
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 30 ) );
|
|
|
|
if ( numberofmilitia < 30 )
|
|
{
|
|
// Set this option off.
|
|
pOption->setAvail( new popupCallbackFunction<bool, void*>( &Popup_OptionOff, NULL ) );
|
|
}
|
|
|
|
// 40 militia option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_X_MILITIA], 40 );
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, 40 ) );
|
|
|
|
if ( numberofmilitia < 40 )
|
|
{
|
|
// Set this option off.
|
|
pOption->setAvail( new popupCallbackFunction<bool, void*>( &Popup_OptionOff, NULL ) );
|
|
}
|
|
|
|
GetPopup()->addOption( *pOption );
|
|
|
|
// all militia option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_ALL_MILITIA] );
|
|
|
|
pOption = new POPUP_OPTION(&std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_ReinforcementNumber, numberofmilitia ) );
|
|
GetPopup()->addOption( *pOption );
|
|
|
|
// cancel option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_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;
|
|
|
|
BOOLEAN result = pSoldier->RadioCallReinforcements(usSector, aVal);
|
|
|
|
// additional dialogue
|
|
AdditionalTacticalCharacterDialogue_CallsLua( pSoldier, ADE_SKILL_RESULT, SKILLS_RADIO_CALLREINFORCEMENTS, result );
|
|
|
|
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, pSkillMenuStrings[SKILLMENU_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;
|
|
|
|
BOOLEAN result = pSoldier->UseSkill(usSkill, sTraitsMenuTargetGridNo, aVal);
|
|
|
|
// additional dialogue
|
|
AdditionalTacticalCharacterDialogue_CallsLua( pSoldier, ADE_SKILL_RESULT, usSkill, result );
|
|
|
|
Cancel();
|
|
gSkillSelection.Cancel();
|
|
gTraitSelection.Cancel();
|
|
}
|
|
/////////////////////////////// Soldier Target Selection ////////////////////////////////////////////
|
|
|
|
/////////////////////////////// Drag Selection ////////////////////////////////////////////
|
|
void
|
|
DragSelection::Setup( UINT32 aVal )
|
|
{
|
|
Destroy( );
|
|
|
|
SOLDIERTYPE * pSoldier = NULL;
|
|
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
if ( pSoldier == NULL )
|
|
return;
|
|
|
|
if ( pSoldier->CanUseSkill( aVal ) )
|
|
{
|
|
usSkill = aVal;
|
|
|
|
SetupPopup( "DragSelection" );
|
|
|
|
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 )
|
|
{
|
|
if ( cnt != pSoldier->ubID && pSoldier->CanDragPerson(cnt) )
|
|
{
|
|
swprintf( pStr, L"%s", MercPtrs[cnt]->GetName( ) );
|
|
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_DragSelection, cnt ) );
|
|
|
|
GetPopup( )->addOption( *pOption );
|
|
}
|
|
}
|
|
|
|
// corpses
|
|
std::vector<INT16> corpseids = GetCorpseIDsNearGridNo( pSoldier->sGridNo, pSoldier->pathing.bLevel, 1 );
|
|
|
|
for ( std::vector<INT16>::iterator it = corpseids.begin(); it != corpseids.end(); ++it )
|
|
{
|
|
ROTTING_CORPSE* pCorpse = GetRottingCorpse( (*it) );
|
|
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_CORPSES], pCorpse->name );
|
|
|
|
// we have to use an offset of NOBODY in order to differentiate between person and corpse
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_DragSelection, (*it) + NOBODY ) );
|
|
|
|
GetPopup( )->addOption( *pOption );
|
|
}
|
|
|
|
// gridno
|
|
for ( int ubDirection = 0; ubDirection < NUM_WORLD_DIRECTIONS; ++ubDirection )
|
|
{
|
|
INT32 sTempGridNo = NewGridNo( pSoldier->sGridNo, DirectionInc( ubDirection ) );
|
|
|
|
UINT32 tiletype;
|
|
UINT16 structurenumber;
|
|
UINT8 hitpoints;
|
|
UINT8 decalflag;
|
|
if ( pSoldier->CanDragStructure( sTempGridNo )
|
|
&& IsDragStructurePresent( sTempGridNo, pSoldier->pathing.bLevel, tiletype, structurenumber, hitpoints, decalflag ) )
|
|
{
|
|
int xmlentry;
|
|
GetDragStructureXmlEntry( tiletype, structurenumber, xmlentry );
|
|
|
|
if ( xmlentry >= 0 )
|
|
{
|
|
WCHAR buf[256];
|
|
MultiByteToWideChar(CP_UTF8, 0, gStructureMovePossible[xmlentry].szTileSetDisplayName, -1, buf, 256);
|
|
swprintf(pStr, L"%s (%s)", buf, FaceDirs[gOneCDirection[ubDirection]]);
|
|
|
|
// we have to use an offset of NOBODY in order to differentiate between person and corpse
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_DragSelection_GridNo, sTempGridNo ) );
|
|
|
|
GetPopup()->addOption( *pOption );
|
|
}
|
|
}
|
|
}
|
|
|
|
// cancel option
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_CANCEL] );
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Cancel_DragSelection, 0 ) );
|
|
GetPopup( )->addOption( *pOption );
|
|
}
|
|
|
|
// same y, different x
|
|
SetPos( gSkillSelection.GetMaxPosX( ), usTraitMenuPosY );
|
|
}
|
|
|
|
void
|
|
DragSelection::Functions( UINT32 aVal )
|
|
{
|
|
SOLDIERTYPE * pSoldier = NULL;
|
|
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
if ( pSoldier )
|
|
{
|
|
BOOLEAN result = pSoldier->UseSkill( usSkill, NOWHERE, aVal );
|
|
|
|
// additional dialogue
|
|
AdditionalTacticalCharacterDialogue_CallsLua( pSoldier, ADE_SKILL_RESULT, usSkill, result );
|
|
}
|
|
|
|
Cancel( );
|
|
gSkillSelection.Cancel();
|
|
gTraitSelection.Cancel( );
|
|
}
|
|
|
|
void
|
|
DragSelection::FunctionsGridNo( INT32 aVal )
|
|
{
|
|
SOLDIERTYPE * pSoldier = NULL;
|
|
|
|
GetSoldier( &pSoldier, gusSelectedSoldier );
|
|
|
|
if ( pSoldier )
|
|
{
|
|
BOOLEAN result = pSoldier->UseSkill( usSkill, aVal, 0 );
|
|
|
|
// additional dialogue
|
|
AdditionalTacticalCharacterDialogue_CallsLua( pSoldier, ADE_SKILL_RESULT, usSkill, result );
|
|
}
|
|
|
|
Cancel();
|
|
gSkillSelection.Cancel();
|
|
gTraitSelection.Cancel();
|
|
}
|
|
/////////////////////////////// Drag Selection ////////////////////////////////////////////
|
|
|
|
/**
|
|
* Flugente: traits menu popup box
|
|
* This will create other boxes when needed
|
|
*/
|
|
void TraitsMenu( INT32 usMapPos )
|
|
{
|
|
sTraitsMenuTargetGridNo = usMapPos;
|
|
|
|
gTraitSelection.Setup(0);
|
|
}
|
|
|
|
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
|
EquipmentSelection gEquipmentSelection;
|
|
|
|
void Wrapper_Function_EquipmentSelection(UINT32 aVal) { gEquipmentSelection.Functions(aVal); }
|
|
void Wrapper_Setup_EquipmentSelection(UINT32 aVal) { gEquipmentSelection.Setup(aVal); }
|
|
void Wrapper_Cancel_EquipmentSelection(UINT32 aVal) { gEquipmentSelection.Cancel(); }
|
|
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
|
|
|
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
|
UINT32 gEquipmentSelectionFirstEntryShown = 0;
|
|
UINT32 gEquipmentSelectionLastEntryShown = 0;
|
|
UINT32 gEquipmentSelectionMaxEntriesShown = 0;
|
|
|
|
void
|
|
EquipmentSelection::Setup(UINT32 aVal)
|
|
{
|
|
Destroy();
|
|
|
|
SetupPopup("EquipmentSelection");
|
|
|
|
INT16 sX = 261 + 406 + xResOffset + 30;
|
|
INT16 sY = 0 + 10 + yResOffset + 30;
|
|
|
|
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;
|
|
|
|
POPUP_OPTION *pOption;
|
|
|
|
CHAR16 pStr[300];
|
|
|
|
// create entries for the sub-menus for each trait
|
|
GetEquipmentTemplates();
|
|
|
|
// we limit the maximum number of entries shown at once - too many entries could theoretically cause the button system to freak out
|
|
gEquipmentSelectionMaxEntriesShown = min(40, max( 0, (SCREEN_HEIGHT - 150 - usTraitMenuPosY) / 12 ) );
|
|
|
|
gEquipmentSelectionLastEntryShown = min( gEquipmentSelectionFirstEntryShown + gEquipmentSelectionMaxEntriesShown, gTemplateVector.size( ) );
|
|
|
|
if ( gEquipmentSelectionLastEntryShown < gEquipmentSelectionMaxEntriesShown )
|
|
gEquipmentSelectionFirstEntryShown = 0;
|
|
else
|
|
gEquipmentSelectionFirstEntryShown = gEquipmentSelectionLastEntryShown - gEquipmentSelectionMaxEntriesShown;
|
|
|
|
UINT32 cnt = gEquipmentSelectionFirstEntryShown;
|
|
for ( UINT32 i = gEquipmentSelectionFirstEntryShown; i < gEquipmentSelectionLastEntryShown; ++i )
|
|
{
|
|
//std::string str8 = (*it);
|
|
std::string str8 = gTemplateVector[i];
|
|
|
|
std::size_t found = str8.find_last_of( "." );
|
|
|
|
std::string str82 = str8.substr( 0, found );
|
|
|
|
const char* coca = str82.c_str( );
|
|
|
|
CHAR16 tmpchar[256];
|
|
|
|
int nChars = MultiByteToWideChar( CP_ACP, 0, coca, -1, NULL, 0 );
|
|
MultiByteToWideChar( CP_UTF8, 0, coca, -1, tmpchar, nChars );
|
|
|
|
pOption = new POPUP_OPTION( &std::wstring( tmpchar ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_EquipmentSelection, i ) );
|
|
|
|
pOption->color_foreground = FONT_GREEN;
|
|
|
|
GetPopup()->addOption(*pOption);
|
|
}
|
|
|
|
// 'more' option (moves down list)
|
|
if ( gEquipmentSelectionMaxEntriesShown < gTemplateVector.size( ) )
|
|
{
|
|
swprintf( pStr, pSkillMenuStrings[SKILLMENU_MORE] );
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_EquipmentSelection, 99999 ) );
|
|
GetPopup( )->addOption( *pOption );
|
|
}
|
|
|
|
// cancel option
|
|
swprintf(pStr, pSkillMenuStrings[SKILLMENU_CANCEL]);
|
|
pOption = new POPUP_OPTION( &std::wstring( pStr ), new popupCallbackFunction<void, UINT32>( &Wrapper_Function_EquipmentSelection, 99998 ) );
|
|
GetPopup()->addOption(*pOption);
|
|
|
|
SetPos(usTraitMenuPosX, usTraitMenuPosY);
|
|
}
|
|
|
|
void
|
|
EquipmentSelection::Functions(UINT32 aVal)
|
|
{
|
|
// this special value allows to 'scroll down'
|
|
if ( aVal == 99999 )
|
|
{
|
|
gEquipmentSelectionFirstEntryShown += gEquipmentSelectionMaxEntriesShown;
|
|
|
|
if ( gEquipmentSelectionFirstEntryShown >= gTemplateVector.size( ) )
|
|
gEquipmentSelectionFirstEntryShown = 0;
|
|
|
|
Cancel( );
|
|
|
|
EquipmentListMenu();
|
|
}
|
|
else if ( aVal == 99998 )
|
|
{
|
|
gEquipmentSelectionFirstEntryShown = 0;
|
|
|
|
Cancel( );
|
|
}
|
|
else if ( aVal < gTemplateVector.size( ) )
|
|
{
|
|
SOLDIERTYPE* pSoldier = &Menptr[gCharactersList[bSelectedInfoChar].usSolID];
|
|
if ( pSoldier )
|
|
{
|
|
std::string name = gTemplateVector[aVal];
|
|
|
|
ReadEquipmentTable( pSoldier, name );
|
|
}
|
|
|
|
// Note that we don't close menu - this way we don't have to open it every time we want to apply a template
|
|
}
|
|
}
|
|
/////////////////////////////// Trait Selection ////////////////////////////////////////////
|
|
|
|
void EquipmentListMenu()
|
|
{
|
|
gEquipmentSelection.Setup(0);
|
|
}
|
|
|
|
void EquipmentListMenuCancel()
|
|
{
|
|
gEquipmentSelection.Cancel();
|
|
}
|