|
3 | 3 | #include <Ext/Anim/Body.h> |
4 | 4 | #include <Ext/SWType/Body.h> |
5 | 5 | #include <Ext/House/Body.h> |
| 6 | +#include <ObjectClass.h> |
6 | 7 |
|
7 | 8 | void TechnoExt::DrawSelfHealPips(TechnoClass* pThis, Point2D* pLocation, RectangleStruct* pBounds) |
8 | 9 | { |
@@ -873,3 +874,122 @@ void TechnoExt::ShowPromoteAnim(TechnoClass* pThis) |
873 | 874 | else if (!eliteAnims.empty()) |
874 | 875 | AnimExt::CreateRandomAnim(eliteAnims, pThis->GetCenterCoords(), pThis, pThis->Owner, true, true); |
875 | 876 | } |
| 877 | + |
| 878 | +void TechnoExt::DrawUnitPassengers(TechnoClass* pThis) |
| 879 | +{ |
| 880 | + if (ObjectClass::CurrentObjects.Count != 1) |
| 881 | + return; |
| 882 | + |
| 883 | + if (ObjectClass::CurrentObjects.GetItem(0) != pThis) |
| 884 | + return; |
| 885 | + |
| 886 | + const auto whatAmI = pThis->WhatAmI(); |
| 887 | + if (whatAmI != AbstractType::Unit && whatAmI != AbstractType::Aircraft) |
| 888 | + return; |
| 889 | + |
| 890 | + const auto pType = pThis->GetTechnoType(); |
| 891 | + const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pType); |
| 892 | + const auto pRulesExt = RulesExt::Global(); |
| 893 | + |
| 894 | + bool shouldShow = false; |
| 895 | + |
| 896 | + if (pTypeExt->ShowPassengers.isset()) |
| 897 | + { |
| 898 | + shouldShow = pTypeExt->ShowPassengers.Get(); |
| 899 | + } |
| 900 | + else if (pRulesExt->ShowUnitPassengers) |
| 901 | + { |
| 902 | + shouldShow = true; |
| 903 | + } |
| 904 | + else |
| 905 | + { |
| 906 | + const bool toggleable = pTypeExt->ShowPassengers_Toggleable.Get(pRulesExt->ShowUnitPassengers_Toggleable); |
| 907 | + if (toggleable && Phobos::Config::UnitPassengers_Enable) |
| 908 | + shouldShow = true; |
| 909 | + } |
| 910 | + |
| 911 | + if (!shouldShow) |
| 912 | + return; |
| 913 | + |
| 914 | + if (pThis->Passengers.NumPassengers <= 0) |
| 915 | + return; |
| 916 | + |
| 917 | + std::map<TechnoTypeClass*, int> passengerCounts; |
| 918 | + for (auto pPassenger = pThis->Passengers.GetFirstPassenger(); pPassenger; pPassenger = abstract_cast<FootClass*>(pPassenger->NextObject)) |
| 919 | + { |
| 920 | + passengerCounts[pPassenger->GetTechnoType()]++; |
| 921 | + } |
| 922 | + |
| 923 | + if (passengerCounts.empty()) |
| 924 | + return; |
| 925 | + |
| 926 | + const auto bracketPos = GetFootSelectBracketPosition(pThis, Anchor(HorizontalPosition::Center, VerticalPosition::Top)); |
| 927 | + const auto& bottomOffset = pTypeExt->Passengers_BottomOffset; |
| 928 | + Point2D basePos = bracketPos; |
| 929 | + basePos.X += bottomOffset.Get().X; |
| 930 | + basePos.Y += bottomOffset.Get().Y + pType->PixelSelectionBracketDelta; |
| 931 | + |
| 932 | + const double scale = 1.0; |
| 933 | + |
| 934 | + const int perRow = pTypeExt->Passengers_PerRow; |
| 935 | + const int iconWidth = static_cast<int>(60 * scale); |
| 936 | + const int iconHeight = static_cast<int>(48 * scale); |
| 937 | + const int hGap = 2; |
| 938 | + const int vGap = 2; |
| 939 | + |
| 940 | + const int count = static_cast<int>(passengerCounts.size()); |
| 941 | + const int rows = (count + perRow - 1) / perRow; |
| 942 | + |
| 943 | + const auto pSurface = DSurface::Composite; |
| 944 | + RectangleStruct bounds = DSurface::Composite->GetRect(); |
| 945 | + |
| 946 | + int idx = 0; |
| 947 | + for (const auto& item : passengerCounts) |
| 948 | + { |
| 949 | + const auto pPassengerType = item.first; |
| 950 | + const int passengerCount = item.second; |
| 951 | + |
| 952 | + const int row = idx / perRow; |
| 953 | + const int col = idx % perRow; |
| 954 | + |
| 955 | + const int itemsInThisRow = (row == rows - 1 && count % perRow != 0) ? (count % perRow) : perRow; |
| 956 | + const int rowWidth = itemsInThisRow * (iconWidth + hGap) - hGap; |
| 957 | + const int startX = basePos.X - rowWidth / 2; |
| 958 | + |
| 959 | + const int y = basePos.Y - iconHeight - (rows - 1 - row) * (iconHeight + vGap); |
| 960 | + |
| 961 | + Point2D iconPos = { startX + col * (iconWidth + hGap), y }; |
| 962 | + |
| 963 | + SHPStruct* pCameo = pPassengerType->GetCameo(); |
| 964 | + if (pCameo) |
| 965 | + { |
| 966 | + pSurface->DrawSHP( |
| 967 | + FileSystem::CAMEO_PAL, |
| 968 | + pCameo, |
| 969 | + 0, |
| 970 | + &iconPos, |
| 971 | + &bounds, |
| 972 | + BlitterFlags::bf_400 | BlitterFlags::Alpha, |
| 973 | + 0, 0, |
| 974 | + ZGradient::Ground, |
| 975 | + 1000, 0, nullptr, 0, 0, 0 |
| 976 | + ); |
| 977 | + |
| 978 | + wchar_t countText[16]; |
| 979 | + _snwprintf_s(countText, _countof(countText), _TRUNCATE, L"%d", passengerCount); |
| 980 | + |
| 981 | + Point2D textPos = { iconPos.X + iconWidth - 4, iconPos.Y + 2 }; |
| 982 | + |
| 983 | + pSurface->DrawTextA( |
| 984 | + countText, |
| 985 | + &bounds, |
| 986 | + &textPos, |
| 987 | + Drawing::RGB_To_Int({ 0, 255, 0 }), |
| 988 | + 0, |
| 989 | + TextPrintType::Center | TextPrintType::FullShadow |
| 990 | + ); |
| 991 | + } |
| 992 | + |
| 993 | + idx++; |
| 994 | + } |
| 995 | +} |
0 commit comments