#include "pch.h"
#include "trekctrls.h"
#include "loadout.h"
#include "limits.h"
#include "trekmdl.h"
#define shipIDLoadout SHRT_MAX class PartListItem : public ListItem
{
private:
long m_lData;
TRef<IbucketIGC> m_pBucket;
TRef<IbuyableIGC> m_pBuyable;
Money m_moneyCost;
const char* m_szModel;
TRef<Image> m_pImagePart;
TRef<Image> m_pImageBkgnd;
TRef<Image> m_pImageSelect;
TRef<Image> m_pImageBrackets;
public:
IbuyableIGC* GetBuyable()
{ return m_pBuyable;}
PartListItem(IbucketIGC* pBucket)
{
m_lData = (long)pBucket;
m_pBucket = pBucket;
m_pBuyable = pBucket;
m_moneyCost = m_pBuyable->GetPrice();
Construct();
}
void Construct()
{
assert(m_pBuyable);
m_szModel = m_pBuyable->GetModelName();
m_pImageBrackets = GetModeler()->LoadImage("conshadebracketsbmp", true);
m_pImageBkgnd = GetModeler()->LoadImage(AWF_LOADOUT_ITEM, true);
m_pImageSelect = GetModeler()->LoadImage("investhighlightbmp", true);
m_pImagePart = GetModeler()->LoadImage(
(ZString("i") + ZString(m_szModel) + "bmp").ToLower(),
false
);
}
static int CountDronesOfType(IdroneTypeIGC* pDroneType)
{
DroneTypeID dtid = pDroneType->GetObjectID();
SideID sid = trekClient.GetSideID();
int nCount = 0;
for (PlayerLink* ppl = trekClient.GetPlayerList()->first();
(ppl != NULL);
ppl = ppl->next())
{
const PlayerInfo& pi = ppl->data();
if ((pi.GetDroneTypeID() == dtid) && (pi.SideID() == sid))
{
nCount++;
}
}
return nCount;
}
static int CountStationsOfType(IstationTypeIGC* pStationtypeTest)
{
IsideIGC* pSide = trekClient.GetSide();
const StationListIGC* stationList = pSide->GetStations();
StationClassID classID = pStationtypeTest->GetClassID();
int nCount = 0;
for (StationLinkIGC* stationLink = (stationList ? stationList->first() : NULL);
stationLink; stationLink=stationLink->next())
{
IstationTypeIGC* pstationtype = stationLink->data()->GetBaseStationType();
if (pstationtype->GetClassID() == classID)
nCount++;
}
return nCount;
}
static bool BuildSpotFoundForStationType(IstationTypeIGC* pStationtype)
{
AsteroidAbilityBitMask aabm = pStationtype->GetBuildAABM();
for (AsteroidLinkIGC* asteriodLink = trekClient.GetCore()->GetAsteroids()->first();
asteriodLink != NULL; asteriodLink = asteriodLink->next())
{
if (asteriodLink->data()->HasCapability(aabm))
return true;
}
return false;
}
static IshipIGC* FindBuilderForStationType(IstationTypeIGC* pStationtype)
{
if (trekClient.GetSide())
{
for (ShipLinkIGC* shipLink = trekClient.GetSide()->GetShips()->first();
shipLink != NULL; shipLink = shipLink->next())
{
if (shipLink->data()->GetBaseData() == pStationtype)
return shipLink->data();
}
}
return NULL;
}
ZString GetBuildingStatusText()
{
IstationTypeIGC* pStationtype;
CastTo(pStationtype, m_pBucket->GetBuyable());
IshipIGC* pshipBuilder = FindBuilderForStationType(pStationtype);
if (m_pBucket->GetPercentBought() >= 100)
{
return "Preparing builder ...";
}
if (pshipBuilder)
{
if (pshipBuilder->GetCommandTarget(c_cmdAccepted) &&
(pshipBuilder->GetCommandID(c_cmdAccepted) == c_cidBuild))
{
return "Constructor en route ...";
}
else
{
return "Constructor waiting ...";
}
}
else if (BuildSpotFoundForStationType(pStationtype))
{
return "";
}
else
{
return ZString("no ")
+ IasteroidIGC::GetTypeName(pStationtype->GetBuildAABM())
+ " asteroid available";
}
}
void DrawText(Surface* pSurface, const WinRect& rect)
{
Color colorShadow(0, 0, 33.0f / 256.0f);
char szPrice[20];
sprintf(szPrice, "$ %d", m_moneyCost);
pSurface->DrawStringWithShadow(
TrekResources::SmallFont(),
Color::White(),
colorShadow,
rect.Min() + WinPoint(147,1),
szPrice
);
ZString strName = m_pBuyable->GetName();
if (m_pBucket)
{
ObjectType otBucket = m_pBucket->GetBucketType();
if (otBucket != OT_development)
{
int nTotalNumber;
switch (otBucket)
{
case OT_stationType:
{
pSurface->DrawStringWithShadow(
TrekResources::SmallFont(),
Color::White(),
colorShadow,
rect.Min() + WinPoint(11,42),
GetBuildingStatusText()
);
IstationTypeIGC* pStationtype;
CastTo(pStationtype, m_pBucket->GetBuyable());
nTotalNumber = CountStationsOfType(pStationtype);
strName = "Build " + strName + " (" + ZString(nTotalNumber) + ")";
}
break;
case OT_droneType:
{
IdroneTypeIGC* pDronetype;
int nMaxMiners = trekClient.MyMission()->GetMissionDef().misparms.nMaxMinersPerTeam;
CastTo(pDronetype, m_pBucket->GetBuyable());
nTotalNumber = CountDronesOfType(pDronetype);
if (nTotalNumber >= nMaxMiners){
pSurface->DrawStringWithShadow(
TrekResources::SmallFont(),
Color::White(),
colorShadow,
rect.Min() + WinPoint(11,42),
"At maximum " + strName + "s"
);
}
strName = "Build " + strName + " (" + ZString(nTotalNumber)
+ "/" + ZString(nMaxMiners) + ")";
}
break;
case OT_partType:
case OT_hullType:
{
nTotalNumber = m_pBucket->GetSide()->GetStockpile(m_pBucket->GetBuyable());
strName = "Build " + strName + " (" + ZString(nTotalNumber) + ")";
}
}
}
}
pSurface->DrawStringWithShadow(
TrekResources::SmallFont(),
Color::White(),
colorShadow,
rect.Min() + WinPoint(11,1),
strName
);
}
void FillClippedRect(Context* pcontext, const WinRect& rect, const WinRect& rectClip, const Color& color)
{
WinRect rectClipped = rect;
rectClipped.Intersect(rectClip);
if (!rectClipped.IsEmpty()) {
pcontext->FillRect(Rect::Cast(rect), color);
}
}
void DrawShade(Surface* pSurface, const WinRect& rect)
{
int nWidth = (int)(rect.XSize() - 23);
int nPaidShadeWidth = (int)(nWidth * m_pBucket->GetPercentBought()/100);
int nCompletedShadeWidth = (int)(nWidth * m_pBucket->GetPercentComplete()/100);
if (nPaidShadeWidth > nWidth)
nPaidShadeWidth = nWidth;
if (nCompletedShadeWidth > nWidth)
nCompletedShadeWidth = nWidth;
pSurface->BitBlt(rect.Min(), m_pImageBrackets->GetSurface());
Point offset = Point::Cast(pSurface->GetOffset() + rect.Min() + WinPoint(8, 2));
const WinPoint& size = pSurface->GetSize();
WinRect rectClip = pSurface->GetClipRect();
rectClip.Offset(pSurface->GetOffset());
rectClip =
WinRect(
rectClip.XMin(),
size.Y() - rectClip.YMax(),
rectClip.XMax(),
size.Y() - rectClip.YMin()
);
TRef<Context> pcontext = pSurface->GetContext();
if (pcontext) {
pcontext->SetBlendMode(BlendModeSourceAlpha);
float bright = 0.5f;
FillClippedRect(
pcontext,
WinRect(
offset.X(),
size.Y() - (offset.Y() + rect.YSize()-13),
offset.X() + nCompletedShadeWidth,
size.Y() - offset.Y()
),
rectClip,
Color(0.0, bright, 0.0, bright)
);
Point offsetPaid = offset + Point(nCompletedShadeWidth, 0);
FillClippedRect(
pcontext,
WinRect(
offsetPaid.X(),
size.Y() - (offsetPaid.Y() + rect.YSize()-13),
offsetPaid.X() + nPaidShadeWidth - nCompletedShadeWidth,
size.Y() - offsetPaid.Y()
),
rectClip,
Color(bright, bright, 0.0, bright)
);
pSurface->ReleaseContext(pcontext);
}
}
short GetItemHeight()
{
return 1;
}
long GetItemData()
{
return m_lData;
};
bool Update()
{
return true;
}
void SetSortOrder(long lSortOrder)
{
}
bool SetFilter(long lFilter)
{
return true;
}
void DrawItem(Surface* pSurface, const WinRect& rect, bool fSelected, int iFirstSlot)
{ if (m_pImagePart) {
pSurface->BitBlt(rect.Min() + WinPoint(10, 2), m_pImagePart->GetSurface());
} else {
pSurface->BitBlt(rect.Min(), m_pImageBkgnd->GetSurface());
}
if (fSelected)
{
pSurface->BitBlt(rect.Min() + WinPoint(10, 2), m_pImageSelect->GetSurface());
}
if (m_pBucket)
DrawShade(pSurface, rect);
DrawText(pSurface, rect);
}
};
class PurchasesPaneImpl : public PurchasesPane,
public EventTargetContainer<PurchasesPaneImpl>,
public TrekClientEventSink
{
private:
TRef<ListPaneOld> m_pListPane;
int m_nTabSel;
TRef<PartInfoPane> m_pPartInfoPane;
int m_nLastHoverIndex;
TRef<IstationIGC> m_pStation;
TRef<ButtonPane> m_pButtonInvest;
TRef<ButtonPane> m_pButtonTab0;
TRef<ButtonPane> m_pButtonTab1;
TRef<ButtonPane> m_pButtonTab2;
TRef<ButtonPane> m_pButtonTab3;
TRef<ButtonPane> m_pButtonTab4;
TRef<ButtonPane> m_pButtonTab5;
TRef<ButtonPane> m_pButtonClose;
Window* m_pPaneWindow;
TRef<Pane> m_pBlankPane;
TRef<Pane> m_pBlankPane0;
TRef<Pane> m_pBlankPane1;
TRef<Pane> m_pBlankPane2;
TRef<Pane> m_pBlankPane3;
TRef<Pane> m_pBlankPane4;
TRef<Pane> m_pBlankPane5;
public:
PurchasesPaneImpl(PartInfoPane* pPartInfoPane) :
m_nTabSel(-1),
m_nLastHoverIndex(-1),
m_pPartInfoPane(pPartInfoPane),
m_pStation(NULL),
m_pPaneWindow(NULL)
{
TRef<ImagePane> pImagePane = new ImagePane(GetModeler()->LoadImage(
AWF_LOADOUT_FLIGHT_PURCHASE_PANEL, false));
InsertAtBottom(pImagePane);
TRef<ColumnPane> pColumnPane = new ColumnPane();
TRef<RowPane> pRowPane = new RowPane();
const int nTabWidth = 180;
m_pBlankPane5 = new Pane();
InternalSetSize(m_pBlankPane5, WinPoint(nTabWidth, 3));
pColumnPane->InsertAtBottom(m_pBlankPane5);
m_pButtonTab0 =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btndronesbmp", true),
ButtonNormal
),
false, mouseclickSound
);
pColumnPane->InsertAtBottom(m_pButtonTab0);
m_pButtonTab1 =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btnstarbasebmp", true),
ButtonNormal
),
false, mouseclickSound
);
pColumnPane->InsertAtBottom(m_pButtonTab1);
m_pBlankPane1 = new Pane();
InternalSetSize(m_pBlankPane1, WinPoint(nTabWidth, 1));
pColumnPane->InsertAtBottom(m_pBlankPane1);
m_pButtonTab2 =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btnordnancebmp", true),
ButtonNormal
),
false, mouseclickSound
);
pColumnPane->InsertAtBottom(m_pButtonTab2);
m_pBlankPane2 = new Pane();
InternalSetSize(m_pBlankPane2, WinPoint(nTabWidth, 1));
pColumnPane->InsertAtBottom(m_pBlankPane2);
m_pButtonTab3 =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btnelectronicsbmp", true),
ButtonNormal
),
false, mouseclickSound
);
pColumnPane->InsertAtBottom(m_pButtonTab3);
m_pBlankPane3 = new Pane();
InternalSetSize(m_pBlankPane3, WinPoint(nTabWidth, 1));
pColumnPane->InsertAtBottom(m_pBlankPane3);
m_pButtonTab4 =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btnresearchbmp", true),
ButtonNormal
),
false, mouseclickSound
);
pColumnPane->InsertAtBottom(m_pButtonTab4);
m_pBlankPane4 = new Pane();
InternalSetSize(m_pBlankPane4, WinPoint(nTabWidth, 1));
pColumnPane->InsertAtBottom(m_pBlankPane4);
m_pButtonTab5 =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btnshipyardbmp", true),
ButtonNormal
),
false, mouseclickSound
);
pColumnPane->InsertAtBottom(m_pButtonTab5);
pRowPane->InsertAtBottom(pColumnPane);
m_pBlankPane = new Pane();
InternalSetSize(m_pBlankPane, WinPoint(30, 10));
pRowPane->InsertAtBottom(m_pBlankPane);
m_pButtonClose =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface("btnclosepanebmp", true),
ButtonNormal
),
false
);
m_pListPane = ListPaneOld::Create(WinPoint(203, 432), 72, true, m_pButtonClose),
pRowPane->InsertAtBottom(m_pListPane);
m_pButtonInvest =
CreateTrekButton(
CreateButtonFacePane(
GetModeler()->LoadSurface(AWF_LOADOUT_INVEST_BUTTON, true),
ButtonNormal
),
false
);
pImagePane->InsertAtBottom(m_pButtonInvest);
m_pButtonInvest->SetOffset(WinPoint(63,315));
pImagePane->InsertAtBottom(pRowPane);
pRowPane->SetOffset(WinPoint(17,9));
m_pButtonTab0->SetChecked(true);
OnTabSelect0();
AddEventTarget(&PurchasesPaneImpl::OnTabSelect0, m_pButtonTab0->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnTabSelect1, m_pButtonTab1->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnTabSelect2, m_pButtonTab2->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnTabSelect3, m_pButtonTab3->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnTabSelect4, m_pButtonTab4->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnTabSelect5, m_pButtonTab5->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnListSelect, m_pListPane->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnInvest, m_pListPane->GetDoubleClickEventSource());
AddEventTarget(&PurchasesPaneImpl::OnPartial, m_pListPane->GetRightClickEventSource()); AddEventTarget(&PurchasesPaneImpl::OnListHover, m_pListPane->GetMouseOverEvent());
AddEventTarget(&PurchasesPaneImpl::OnInvest, m_pButtonInvest->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnButtonBack, m_pButtonClose->GetEventSource());
AddEventTarget(&PurchasesPaneImpl::OnMouseEnterInvestButton, m_pButtonInvest->GetMouseEnterEventSource());
AddEventTarget(&PurchasesPaneImpl::OnMouseLeaveInvestButton, m_pButtonInvest->GetMouseLeaveEventSource());
}
~PurchasesPaneImpl()
{
GetWindow()->SetInvestAsteroid(0);
}
bool OnInvest()
{
if (trekClient.MyMissionInProgress())
{
TRef<ListItem> pItem = m_pListPane->GetSelItem();
if (pItem)
{
IbucketIGC* pBucket = (IbucketIGC*)m_pListPane->GetSelItem()->GetItemData();
if (CanInvest(pBucket))
{
Money bucketCost = pBucket->GetPrice() - pBucket->GetMoney();
Money investmentAmount = min(bucketCost, trekClient.GetMoney());
trekClient.AddMoneyToBucket(pBucket, investmentAmount);
}
}
}
return true;
}
bool OnPartial()
{
if (trekClient.MyMissionInProgress())
{
TRef<ListItem> pItem = m_pListPane->GetSelItem();
if (pItem)
{
IbucketIGC* pBucket = (IbucketIGC*)m_pListPane->GetSelItem()->GetItemData();
if (CanInvest(pBucket))
{
Money bucketCost = pBucket->GetPrice() - pBucket->GetMoney();
if (bucketCost == 1)
return true;
Money TenPercent = pBucket->GetPrice() * 0.1; Money investmentAmount = min(TenPercent, trekClient.GetMoney()); while (pBucket->GetMoney() + investmentAmount >= pBucket->GetPrice())
investmentAmount -= 1;
trekClient.AddMoneyToBucket(pBucket, investmentAmount);
}
}
}
return true;
}
bool OnButtonBack()
{
GetWindow()->TurnOffOverlayFlags(ofInvestment);
return true;
}
void OnBucketChange(BucketChange bc, IbucketIGC* b)
{
if (bc == c_bcTerminated)
m_pListPane->RemoveItemByData((long)b);
else
m_pListPane->UpdateItemByData((long)b);
UpdateSpendButtons();
}
void OnModelTerminated(ImodelIGC* pmodel)
{
if ((pmodel->GetObjectType() == OT_station) && (pmodel->GetSide() != NULL)
&& (pmodel->GetSide()->GetObjectID() == trekClient.GetSideID()))
{
m_pListPane->UpdateAll();
UpdateSpendButtons();
}
}
void OnStationCaptured(StationID stationID, SideID sideID)
{
m_pListPane->UpdateAll();
UpdateSpendButtons();
}
void OnDiscoveredStation(IstationIGC* pstation)
{
m_pListPane->UpdateAll();
UpdateSpendButtons();
}
void OnDiscoveredAsteroid(IasteroidIGC* pasteroid)
{
m_pListPane->UpdateAll();
UpdateSpendButtons();
}
void UpdateTechList()
{
int nInsertionIndex = 0;
BuyableGroupID group = (BuyableGroupID)m_nTabSel;
IsideIGC* pSide = trekClient.GetSide();
if (pSide)
{
const BucketListIGC* pList = pSide->GetBuckets();
for (BucketLinkIGC* pBucketNode = pList->first();
pBucketNode != NULL; pBucketNode = pBucketNode->next())
{
IbucketIGC* pBucket = pBucketNode->data();
if (pBucket->GetGroupID() == group)
{
if (pSide->CanBuy(pBucket))
{
IbucketIGC* pbucketPredecessor = pBucket->GetPredecessor();
if ((pbucketPredecessor == NULL) || pbucketPredecessor->GetCompleteF())
{
int nExistingIndex = m_pListPane->GetItemIdxByData((long)pBucket);
if (nExistingIndex == NA)
m_pListPane->InsertItem(nInsertionIndex++, new PartListItem(pBucket));
else
nInsertionIndex = nExistingIndex + 1;
}
}
else
{
m_pListPane->RemoveItemByData((long)pBucket);
}
}
}
}
m_pButtonTab0->SetEnabled(BuyableTechExistsInGroup(0));
m_pButtonTab1->SetEnabled(BuyableTechExistsInGroup(1));
m_pButtonTab2->SetEnabled(BuyableTechExistsInGroup(2));
m_pButtonTab3->SetEnabled(BuyableTechExistsInGroup(3));
m_pButtonTab4->SetEnabled(BuyableTechExistsInGroup(4));
m_pButtonTab5->SetEnabled(BuyableTechExistsInGroup(5));
UpdateSpendButtons();
}
bool BuyableTechExistsInGroup(BuyableGroupID group)
{
IsideIGC* pSide = trekClient.GetSide();
if (pSide)
{
const BucketListIGC* pList = pSide->GetBuckets();
for (BucketLinkIGC* pBucketNode = pList->first();
pBucketNode != NULL; pBucketNode = pBucketNode->next())
{
IbucketIGC* pBucket = pBucketNode->data();
if (pBucket->GetGroupID() == group)
{
if (pSide->CanBuy(pBucket))
{
IbucketIGC* pbucketPredecessor = pBucket->GetPredecessor();
if ((pbucketPredecessor == NULL) || pbucketPredecessor->GetCompleteF())
{
return true;
}
}
}
}
}
return false;
}
void OnTechTreeChanged(SideID sid)
{
if (trekClient.GetSideID() == sid)
{
UpdateTechList();
}
}
bool CanInvest(IbucketIGC* pBucket)
{
if (!trekClient.MyMissionInProgress())
return false;
if (!trekClient.GetSide())
return false;
if (pBucket->GetBucketType() == OT_droneType)
{
IdroneTypeIGC* pDronetype;
CastTo(pDronetype, pBucket->GetBuyable());
if (PartListItem::CountDronesOfType(pDronetype)
>= trekClient.MyMission()->GetMissionDef().misparms.nMaxMinersPerTeam)
{
return false;
}
}
if (pBucket->GetBucketType() == OT_stationType)
{
IstationTypeIGC* pStationtype;
CastTo(pStationtype, pBucket->GetBuyable());
if (!PartListItem::BuildSpotFoundForStationType(pStationtype)
|| PartListItem::FindBuilderForStationType(pStationtype) != NULL)
return false;
}
if (trekClient.GetMoney() <= 0)
return false;
if (pBucket->GetPercentBought() >= 100)
return false;
return true;
}
void UpdateSpendButtons()
{
TRef<ListItem> pItem = m_pListPane->GetSelItem();
if (pItem)
{
IbucketIGC* pBucket = (IbucketIGC*)(pItem->GetItemData());
m_pButtonInvest->SetEnabled(CanInvest(pBucket));
}
else
{
m_pButtonInvest->SetEnabled(false);
}
}
void OnMoneyChange(PlayerInfo* pPlayerInfo)
{
UpdateSpendButtons();
}
bool OnListHover(int nSel)
{
if (nSel == -1)
{
m_pPartInfoPane->DisplayNothing();
}
else
{
IbucketIGC* pBucket = (IbucketIGC*)m_pListPane->GetItemByIdx(nSel)->GetItemData();
if (m_nLastHoverIndex != nSel)
trekClient.PlaySoundEffect(mouseoverSound);
m_pPartInfoPane->DisplayTeamPurchase(pBucket, false);
}
m_nLastHoverIndex = nSel;
return true;
}
bool OnMouseEnterInvestButton()
{
OnListHover(m_pListPane->GetSelItemIdx());
return true;
}
bool OnMouseLeaveInvestButton()
{
OnListHover(-1);
return true;
}
bool OnListSelect(int nSel)
{
UpdateSpendButtons();
return true;
}
void OnAddPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo)
{
m_pListPane->UpdateAll();
UpdateSpendButtons();
}
void OnDelPlayer(MissionInfo* pMissionInfo, SideID sideID, PlayerInfo* pPlayerInfo, QuitSideReason reason, const char* szMessageParam)
{
m_pListPane->UpdateAll();
UpdateSpendButtons();
}
bool OnTabSelect0()
{
m_pListPane->RemoveAll();
m_nTabSel = 0;
m_pButtonTab0->SetChecked(true);
m_pButtonTab1->SetChecked(false);
m_pButtonTab2->SetChecked(false);
m_pButtonTab3->SetChecked(false);
m_pButtonTab4->SetChecked(false);
m_pButtonTab5->SetChecked(false);
UpdateTechList();
m_pListPane->SetSelItemByIdx(0);
return true;
}
bool OnTabSelect1()
{
m_pListPane->RemoveAll();
m_nTabSel = 1;
m_pButtonTab0->SetChecked(false);
m_pButtonTab1->SetChecked(true);
m_pButtonTab2->SetChecked(false);
m_pButtonTab3->SetChecked(false);
m_pButtonTab4->SetChecked(false);
m_pButtonTab5->SetChecked(false);
UpdateTechList();
m_pListPane->SetSelItemByIdx(0);
return true;
}
bool OnTabSelect2()
{
m_pListPane->RemoveAll();
m_nTabSel = 2;
m_pButtonTab0->SetChecked(false);
m_pButtonTab1->SetChecked(false);
m_pButtonTab2->SetChecked(true);
m_pButtonTab3->SetChecked(false);
m_pButtonTab4->SetChecked(false);
m_pButtonTab5->SetChecked(false);
UpdateTechList();
m_pListPane->SetSelItemByIdx(0);
return true;
}
bool OnTabSelect3()
{
m_pListPane->RemoveAll();
m_nTabSel = 3;
m_pButtonTab0->SetChecked(false);
m_pButtonTab1->SetChecked(false);
m_pButtonTab2->SetChecked(false);
m_pButtonTab3->SetChecked(true);
m_pButtonTab4->SetChecked(false);
m_pButtonTab5->SetChecked(false);
UpdateTechList();
m_pListPane->SetSelItemByIdx(0);
return true;
}
bool OnTabSelect4()
{
m_pListPane->RemoveAll();
m_nTabSel = 4;
m_pButtonTab0->SetChecked(false);
m_pButtonTab1->SetChecked(false);
m_pButtonTab2->SetChecked(false);
m_pButtonTab3->SetChecked(false);
m_pButtonTab4->SetChecked(true);
m_pButtonTab5->SetChecked(false);
UpdateTechList();
m_pListPane->SetSelItemByIdx(0);
return true;
}
bool OnTabSelect5()
{
m_pListPane->RemoveAll();
m_nTabSel = 5;
m_pButtonTab0->SetChecked(false);
m_pButtonTab1->SetChecked(false);
m_pButtonTab2->SetChecked(false);
m_pButtonTab3->SetChecked(false);
m_pButtonTab4->SetChecked(false);
m_pButtonTab5->SetChecked(true);
UpdateTechList();
m_pListPane->SetSelItemByIdx(0);
return true;
}
void UpdateLayout()
{
DefaultUpdateLayout();
}
void SetPaneWindow(Window* pWindow)
{
m_pPaneWindow = pWindow;
}
};
TRef<PurchasesPane> PurchasesPane::Create(PartInfoPane* pPartInfoPane)
{
return new PurchasesPaneImpl(pPartInfoPane);
}
TRef<IObject> PurchasesPaneFactory::Apply(ObjectStack& stack)
{
TRef<PartInfoPane> pinfoPane; CastTo(pinfoPane, (Pane*)(IObject*)stack.Pop());
return (Pane*)PurchasesPane::Create(pinfoPane);
}
static WinPoint s_rgPtLabels[] =
{
WinPoint(9,25), WinPoint(9,42), WinPoint(9,59),
WinPoint(9,76), WinPoint(9,92),
WinPoint(120,25), WinPoint(120,42), WinPoint(120,59),
WinPoint(120,76), WinPoint(120,92),
};
static WinPoint s_rgPtStats[] =
{
WinPoint(67,25), WinPoint(67,42), WinPoint(67,59),
WinPoint(67,76), WinPoint(67,92),
WinPoint(178,25), WinPoint(178,42), WinPoint(178,59),
WinPoint(178,76), WinPoint(178,92),
};
class PartInfoPaneImpl : public PartInfoPane
{
private:
TRef<IbuyableIGC> m_pBuyable;
TRef<IhullTypeIGC> m_pHullType;
TRef<IpartTypeIGC> m_pPartType;
Money m_moneyCost;
const char* m_szModel;
TRef<Image> m_pImagePart;
TRef<Image> m_pImageBkgnd;
TRef<ConnectorPane> m_pConnectorPaneInventory;
TRef<ConnectorPane> m_pConnectorPanePurchases;
public:
PartInfoPaneImpl(ConnectorPane* pConnectorPanePurchases, ConnectorPane* pConnectorPaneInventory) :
m_pConnectorPaneInventory(pConnectorPaneInventory),
m_pConnectorPanePurchases(pConnectorPanePurchases)
{
m_pImageBkgnd = GetModeler()->LoadImage(AWF_LOADOUT_INFO_PANEL, false);
DisplayNothing();
}
void DisplayTeamPurchase(IbucketIGC* pBucket, bool bPartInInventory)
{
if (m_pConnectorPaneInventory)
m_pConnectorPaneInventory->SetVisible(bPartInInventory);
if (m_pConnectorPanePurchases)
m_pConnectorPanePurchases->SetVisible(!bPartInInventory);
m_pPartType = NULL;
m_pHullType = NULL;
m_pBuyable = pBucket;
InternalSetSize(m_pImageBkgnd->GetSurface()->GetSize());
NeedPaint();
GetWindow()->SetInvestAsteroid(0);
IbuyableIGC* pbuyable = pBucket->GetBuyable();
if (pbuyable->GetObjectType() == OT_stationType)
{
IstationTypeIGC* pst = (IstationTypeIGC*)pbuyable;
AsteroidAbilityBitMask aabm = pst->GetBuildAABM();
GetWindow()->SetInvestAsteroid(aabm);
}
}
void DisplayNothing()
{
GetWindow()->SetInvestAsteroid(0);
if (m_pConnectorPaneInventory)
m_pConnectorPaneInventory->SetVisible(false);
if (m_pConnectorPanePurchases)
m_pConnectorPanePurchases->SetVisible(false);
m_pImagePart = NULL;
m_pPartType = NULL;
m_pHullType = NULL;
m_pBuyable = NULL;
m_szModel = NULL;
NeedPaint();
}
private:
void UpdateLayout()
{
InternalSetSize(m_pImageBkgnd->GetSurface()->GetSize());
Pane::UpdateLayout();
}
void DrawName(Surface* pSurface, IbuyableIGC* pBuyable) const
{
pSurface->DrawString(
TrekResources::SmallBoldFont(),
Color(64.0f / 255.0f, 70.0f / 255.0f, 1.0f),
WinPoint(15,10),
pBuyable->GetName()
);
}
void DrawDescription(Surface* pSurface, IbuyableIGC* pBuyable) const
{
const int nBorderWidth = 13;
const int nLineHeight = 12;
const int nFirstLineY = 4*nLineHeight;
const int nWidth = (int)m_pImageBkgnd->GetBounds().GetRect().XSize() - nBorderWidth*2;
int nCurrentYPos = nFirstLineY + nBorderWidth;
TRef<IEngineFont> pfont = TrekResources::SmallFont();
Color color = MakeColorFromCOLORREF(RGB(180,180,180));
pSurface->DrawString(pfont, color, WinPoint(nBorderWidth, 15 + nLineHeight), ZString("Cost: $") + ZString(pBuyable->GetPrice()));
pSurface->DrawString(pfont, color, WinPoint(nBorderWidth, 15 + 2*nLineHeight), ZString("Time: ") + ZString((long)pBuyable->GetTimeToBuild()) + ZString(" Sec."));
ZString strDescription(pBuyable->GetDescription() + ZString(" "));
while (strDescription.GetLength() != 0)
{
int nLineLength = TrekResources::SmallFont()->GetMaxTextLength(strDescription, nWidth, true);
int nWordBreakLength = nLineLength;
while (nWordBreakLength > 0 && strDescription[nWordBreakLength] != ' '
&& strDescription[nWordBreakLength-1] != ' ')
nWordBreakLength--;
if (nWordBreakLength != 0)
nLineLength = nWordBreakLength;
if (nLineLength <= 0)
{
nLineLength = 1;
}
else
{
pSurface->DrawString(pfont, color, WinPoint(nBorderWidth,nCurrentYPos),
strDescription.Left(nLineLength));
nCurrentYPos += nLineHeight;
}
strDescription = strDescription.RightOf(nLineLength);
}
}
void Paint(Surface* pSurface)
{
pSurface->BitBlt(WinPoint(0, 0),
m_pImageBkgnd->GetSurface(),
WinRect(0, 0, XSize(), YSize()));
if (m_pBuyable)
{
DrawName(pSurface, m_pBuyable);
DrawDescription(pSurface, m_pBuyable);
}
}
};
TRef<PartInfoPane> PartInfoPane::Create(ConnectorPane* pConnectorPanePurchases, ConnectorPane* pConnectorPaneInventory)
{
return new PartInfoPaneImpl(pConnectorPanePurchases, pConnectorPaneInventory);
}
TRef<IObject> PartInfoPaneFactory::Apply(ObjectStack& stack)
{
return (Pane*)PartInfoPane::Create(NULL, NULL);
}