diff --git a/X2WOTCCommunityPromotionScreen/Content/3DUIBP_Armory_Promotion_Hero.umap b/X2WOTCCommunityPromotionScreen/Content/3DUIBP_Armory_Promotion_Hero.umap new file mode 100644 index 0000000..0f2f7ea Binary files /dev/null and b/X2WOTCCommunityPromotionScreen/Content/3DUIBP_Armory_Promotion_Hero.umap differ diff --git a/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHero.uc b/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHero.uc index ce4c1c4..b9a51cb 100644 --- a/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHero.uc +++ b/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHero.uc @@ -98,13 +98,17 @@ simulated function InitPromotion(StateObjectReference UnitRef, optional bool bIn //Only set position and animate in the scrollbar once after data population. Prevents scrollbar flicker on scrolling. if (Scrollbar != none) { + // KDM : When the scrollbar was anchored, it would move around when + // switching from 'fullscreen' mode to 'windowed' mode. Consequently, + // anchoring has been removed, and its X location has been updated + // so that it remains on the right side of the promotion screen. if (bHasBrigadierRank) { - Scrollbar.SetPosition(-465, 310); + Scrollbar.SetPosition(1505, 310); } else { - Scrollbar.SetPosition(-550, 310); + Scrollbar.SetPosition(1275, 310); } Scrollbar.MC.SetNum("_alpha", 0); @@ -155,7 +159,7 @@ function CacheSoldierInfo() simulated function PopulateData() { local XComGameState_Unit Unit; - local NPSBDP_UIArmory_PromotionHeroColumn Column; + local CPS_UIArmory_PromotionHeroColumn Column; local string HeaderString, rankIcon, classIcon; local int iRank, maxRank; local bool bHighlightColumn; @@ -248,7 +252,7 @@ simulated function PopulateData() maxRank = Columns.Length; //class'X2ExperienceConfig'.static.GetMaxRank(); for (iRank = 0; iRank < maxRank; iRank++) { - Column = NPSBDP_UIArmory_PromotionHeroColumn(Columns[iRank]); + Column = CPS_UIArmory_PromotionHeroColumn(Columns[iRank]); Column.Offset = Position; // Start Issue #18 - show "new rank" banner only if the player has an ability to choose and can afford it. @@ -326,7 +330,7 @@ function HidePreview() AS_SetDescriptionData("", ClassName, ClassDesc, "", "", "", ""); } -function bool UpdateAbilityIcons_Override(out NPSBDP_UIArmory_PromotionHeroColumn Column) +function bool UpdateAbilityIcons_Override(out CPS_UIArmory_PromotionHeroColumn Column) { local X2AbilityTemplateManager AbilityTemplateManager; local X2AbilityTemplate AbilityTemplate, NextAbilityTemplate; @@ -470,7 +474,6 @@ simulated function RealizeScrollbar() if(Scrollbar == none) { Scrollbar = Spawn(class'UIScrollbar', self).InitScrollbar(); - Scrollbar.SetAnchor(class'UIUtilities'.const.ANCHOR_TOP_RIGHT); Scrollbar.SetHeight(450); } Scrollbar.NotifyValueChange(OnScrollBarChange, 0.0, MaxPosition); @@ -589,7 +592,7 @@ simulated function bool AttemptScroll(bool Up) function InitColumns() { - local NPSBDP_UIArmory_PromotionHeroColumn Column; + local CPS_UIArmory_PromotionHeroColumn Column; local int i, numCols; numCols = bHasBrigadierRank ? 8 : 7; @@ -598,7 +601,7 @@ function InitColumns() for (i = 0; i < numCols; i++) { - Column = Spawn(class'NPSBDP_UIArmory_PromotionHeroColumn', self); + Column = Spawn(class'CPS_UIArmory_PromotionHeroColumn', self); Column.MCName = name("rankColumn"$i); Column.InitPromotionHeroColumn(i); Columns.AddItem(Column); @@ -1091,60 +1094,51 @@ function bool GetCustomAbilitiesPerRank() function ResizeScreenForBrigadierRank() { - - // Fix width and position of elements to make space for the 8th column - // - Width = int(MC.GetNum("_width")); - AdjustXOffset = MC.GetNum("rankColumn6._x") - MC.GetNum("rankColumn5._x"); - SetWidth(Width + AdjustXOffset); - - // Widths - MC.ChildSetNum("bg", "_width", MC.GetNum("bg._width") + AdjustXOffset); - MC.ChildSetNum("topDivider", "_width", MC.GetNum("topDivider._width") + AdjustXOffset); - MC.ChildSetNum("bottomDivider", "_width", MC.GetNum("bottomDivider._width") + AdjustXOffset); - MC.ChildSetNum("headerLines", "_width", MC.GetNum("headerLines._width") + AdjustXOffset); - MC.ChildSetNum("columnGradients", "_width", MC.GetNum("columnGradients._width") + AdjustXOffset); - - // X Positions - MC.SetNum("_x", MC.GetNum("_x") + 50); - MC.ChildSetNum("topDivider", "_x", MC.GetNum("topDivider._x") - AdjustXOffset); - MC.ChildSetNum("bottomDivider", "_x", MC.GetNum("bottomDivider._x") - AdjustXOffset); - MC.ChildSetNum("headerLines", "_x", MC.GetNum("headerLines._x") - AdjustXOffset); - MC.ChildSetNum("columnGradients", "_x", MC.GetNum("columnGradients._x") - AdjustXOffset); - MC.ChildSetNum("factionLogoLarge", "_x", MC.GetNum("factionLogoLarge._x") - AdjustXOffset); - MC.ChildSetNum("factionLogo", "_x", MC.GetNum("factionLogo._x") - AdjustXOffset); - MC.ChildSetNum("classIcon", "_x", MC.GetNum("classIcon._x") - AdjustXOffset); - MC.ChildSetNum("rankIcon", "_x", MC.GetNum("rankIcon._x") - AdjustXOffset); - MC.ChildSetNum("factionName", "_x", MC.GetNum("factionName._x") - AdjustXOffset); - MC.ChildSetNum("abilityLabel", "_x", MC.GetNum("abilityLabel._x") - AdjustXOffset); - //MC.ChildSetNum("soldierAPLabel", "_x", MC.GetNum("soldierAPLabel._x") - AdjustXOffset); - //MC.ChildSetNum("soldierAPValue", "_x", MC.GetNum("soldierAPValue._x") - AdjustXOffset); - //MC.ChildSetNum("teamAPLabel", "_x", MC.GetNum("teamAPLabel._x") - AdjustXOffset); - //MC.ChildSetNum("teamAPValue", "_x", MC.GetNum("teamAPValue._x") - AdjustXOffset); - //MC.ChildSetNum("combatIntelLabel", "_x", MC.GetNum("combatIntelLabel._x") - AdjustXOffset); - //MC.ChildSetNum("combatIntelValue", "_x", MC.GetNum("combatIntelValue._x") - AdjustXOffset); - MC.ChildSetNum("unitName", "_x", MC.GetNum("unitName._x") - AdjustXOffset); - MC.ChildSetNum("descriptionTitle", "_x", MC.GetNum("descriptionTitle._x") - AdjustXOffset); - MC.ChildSetNum("descriptionBody", "_x", MC.GetNum("descriptionBody._x") - AdjustXOffset); - MC.ChildSetNum("descriptionDetail", "_x", MC.GetNum("descriptionDetail._x") - AdjustXOffset); - MC.ChildSetNum("descriptionIcon", "_x", MC.GetNum("descriptionIcon._x") - AdjustXOffset); - MC.ChildSetNum("costLabel", "_x", MC.GetNum("costLabel._x") - AdjustXOffset); - MC.ChildSetNum("costValue", "_x", MC.GetNum("costValue._x") - AdjustXOffset); - MC.ChildSetNum("apLabel", "_x", MC.GetNum("apLabel._x") - AdjustXOffset); - MC.ChildSetNum("abilityPathHeader", "_x", MC.GetNum("abilityPathHeader._x") - AdjustXOffset); - MC.ChildSetNum("pathLabel0", "_x", MC.GetNum("pathLabel0._x") - AdjustXOffset); - MC.ChildSetNum("pathLabel1", "_x", MC.GetNum("pathLabel1._x") - AdjustXOffset); - MC.ChildSetNum("pathLabel2", "_x", MC.GetNum("pathLabel2._x") - AdjustXOffset); - MC.ChildSetNum("pathLabel3", "_x", MC.GetNum("pathLabel3._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn0", "_x", MC.GetNum("rankColumn0._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn1", "_x", MC.GetNum("rankColumn1._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn2", "_x", MC.GetNum("rankColumn2._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn3", "_x", MC.GetNum("rankColumn3._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn4", "_x", MC.GetNum("rankColumn4._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn5", "_x", MC.GetNum("rankColumn5._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn6", "_x", MC.GetNum("rankColumn6._x") - AdjustXOffset); - MC.ChildSetNum("rankColumn7", "_x", MC.GetNum("rankColumn6._x")); - MC.ChildSetNum("rankColumn7", "_y", MC.GetNum("rankColumn6._y")); + local int ScreenX, ScreenXOffset, RankColumnWidth; + + // KDM : Get the screen's location and width via Flash since they aren't updated in UnrealScript yet. + ScreenX = MC.GetNum("_x"); + ScreenXOffset = -10; + + // KDM : Determine the width of our 8th rank column based on the distance between 2 rank columns + // which already exist. + RankColumnWidth = MC.GetNum("rankColumn6._x") - MC.GetNum("rankColumn5._x"); + + SetX(ScreenX + ScreenXOffset); + + // KDM : Increase the width of a number of background UI elements since we are adding an extra rank column. + MC.ChildSetNum("bg", "_width", MC.GetNum("bg._width") + RankColumnWidth); + MC.ChildSetNum("topDivider", "_width", MC.GetNum("topDivider._width") + RankColumnWidth); + MC.ChildSetNum("bottomDivider", "_width", MC.GetNum("bottomDivider._width") + RankColumnWidth); + MC.ChildSetNum("headerLines", "_width", MC.GetNum("headerLines._width") + RankColumnWidth); + MC.ChildSetNum("columnGradients", "_width", MC.GetNum("columnGradients._width") + RankColumnWidth); + + // KDM : The background, 'bg', is a bit of an odd-ball since it doesn't seem to move with the rest of the + // panels when the screen X value is changed. Therefore, shift it over a bit so it fits nicely behind all of the + // other panels. + MC.ChildSetNum("bg", "_x", MC.GetNum("bg._x") + RankColumnWidth); + // KDM : Shift the soldier AP label and value to the top right corner of the background panel. + MC.ChildSetNum("soldierAPLabel", "_x", MC.GetNum("soldierAPLabel._x") + RankColumnWidth); + MC.ChildSetNum("soldierAPValue", "_x", MC.GetNum("soldierAPValue._x") + RankColumnWidth); + // KDM : Shift the XCom AP label and value so they are next to the soldier AP label and value. + MC.ChildSetNum("teamAPLabel", "_x", MC.GetNum("teamAPLabel._x") + RankColumnWidth); + MC.ChildSetNum("teamAPValue", "_x", MC.GetNum("teamAPValue._x") + RankColumnWidth); + // KDM : Shift the Combat Intelligence label and value so they are next to the XCom AP label and value. + MC.ChildSetNum("combatIntelLabel", "_x", MC.GetNum("combatIntelLabel._x") + RankColumnWidth); + MC.ChildSetNum("combatIntelValue", "_x", MC.GetNum("combatIntelValue._x") + RankColumnWidth); + // KDM : Shift the ability point label, cost label, and cost value to the bottom right corner of the background panel. + MC.ChildSetNum("apLabel", "_x", MC.GetNum("apLabel._x") + RankColumnWidth); + MC.ChildSetNum("costLabel", "_x", MC.GetNum("costLabel._x") + RankColumnWidth); + MC.ChildSetNum("costValue", "_x", MC.GetNum("costValue._x") + RankColumnWidth); + // KDM : Place the 8th rank column to the right of the 7th rank column. + MC.ChildSetNum("rankColumn7", "_x", MC.GetNum("rankColumn6._x") + RankColumnWidth); + // KDM : Increase the width of the soldier's name container; unitName is an XComScrollingTextField, + // within Flash, so get and set its width appropriately. + MC.ChildFunctionNum("unitName", "setWidth", MC.GetNum("unitName.maskWidth") + RankColumnWidth); + // KDM : Increase the width of the ability description container; descriptionBody is a textField, + // within Flash, so set its width appropriately. + MC.ChildSetNum("descriptionBody", "_width", MC.GetNum("descriptionBody._width") + RankColumnWidth); + MC.ChildSetNum("rankColumn7", "_y", MC.GetNum("rankColumn6._y")); } diff --git a/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHeroColumn.uc b/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHeroColumn.uc new file mode 100644 index 0000000..787b659 --- /dev/null +++ b/X2WOTCCommunityPromotionScreen/Src/X2WOTCCommunityPromotionScreen/Classes/CPS_UIArmory_PromotionHeroColumn.uc @@ -0,0 +1,203 @@ +//--------------------------------------------------------------------------------------- +// FILE: CPS_UIArmory_PromotionHeroColumn.uc +// AUTHORS: Tzarnal - MoonWolf, Peter Ledbrook +// PURPOSE: Replaces promotion screen columns for improved layout. +//--------------------------------------------------------------------------------------- +class CPS_UIArmory_PromotionHeroColumn extends UIArmory_PromotionHeroColumn; + +var int Offset; + +// Start Issue #13 - modify columns to be slightly narrower to fit +// a shorter promotion screen overall. +var UIText RankLabelLine1, RankLabelLine2; + +function UIArmory_PromotionHeroColumn InitPromotionHeroColumn(int InitRank) +{ + super.InitPromotionHeroColumn(InitRank); + + // KDM : Create the UIText's which will display the rank labels. + RankLabelLine1 = Spawn(class'UIText', self); + RankLabelLine1.InitText('RankLabelLine1', ""); + RankLabelLine2 = Spawn(class'UIText', self); + RankLabelLine2.InitText('RankLabelLine2', ""); + + UpdateSizeAndPosition(); + + return self; +} + +function UpdateSizeAndPosition() +{ + // KDM : The rank icon. + MC.ChildSetNum("rankMC", "_x", 41); + MC.ChildSetNum("rankMC", "_y", -8); + + // KDM : The 'rank up' highlight. + MC.ChildSetNum("rankHighlight", "_x", 0); + MC.ChildSetNum("rankHighlight", "_y", -31); + + // KDM : Rank label line 1. + RankLabelLine1.SetPosition(2, 52); + RankLabelLine1.SetWidth(145); + + // KDM : Rank label line 2. + RankLabelLine2.SetPosition(2, 78); + RankLabelLine2.SetWidth(145); +} + +function AS_SetData(bool ShowHighlight, string HighlightText, string RankIcon, string RankLabel) +{ + MC.BeginFunctionOp("SetData"); + MC.QueueBoolean(ShowHighlight); + MC.QueueString(HighlightText); + MC.QueueString(RankIcon); + // KDM : We no longer want to set rankLabel, within Flash, since we will be dealing with + // multi-line rank labels by ourself. + MC.QueueString(""); + MC.EndOp(); + + SetRankLabel(RankLabel); +} + +function SetRankLabel(string RankLabel) +{ + local int i; + local string ConcatenatedString; + local array RankLabelComponents; + + RankLabelComponents = SplitString(RankLabel, " ", true); + if (RankLabelComponents.Length >= 1) + { + RankLabelLine1.SetHtmlText(class'UIUtilities_Text'.static.GetColoredText( + RankLabelComponents[0], eUIState_Normal, 24, "CENTER")); + + i = 1; + ConcatenatedString = ""; + // KDM : Normally, a rank label will consist of 1 or 2 words; if it consists of more, any word after + // the 1st will be concatenated with spaces and placed in RankLabelLine2. + while (i < RankLabelComponents.Length) + { + ConcatenatedString $= RankLabelComponents[i]; + if (i + 1 < RankLabelComponents.Length) + { + ConcatenatedString $= " "; + } + i++; + } + RankLabelLine2.SetHtmlText(class'UIUtilities_Text'.static.GetColoredText( + ConcatenatedString, eUIState_Normal, 24, "CENTER")); + } +} +// End Issue #13 + +function OnAbilityInfoClicked(UIButton Button) +{ + local X2AbilityTemplate AbilityTemplate; + local X2AbilityTemplateManager AbilityTemplateManager; + local UIButton InfoButton; + local NPSBDP_UIArmory_PromotionHero PromotionScreen; + local int idx; + + PromotionScreen = NPSBDP_UIArmory_PromotionHero(Screen); + + AbilityTemplateManager = class'X2AbilityTemplateManager'.static.GetAbilityTemplateManager(); + + foreach InfoButtons(InfoButton, idx) + { + if (InfoButton == Button) + { + AbilityTemplate = AbilityTemplateManager.FindAbilityTemplate(AbilityNames[idx]); + break; + } + } + + if (AbilityTemplate != none) + `HQPRES.UIAbilityPopup(AbilityTemplate, PromotionScreen.UnitReference); + + if( InfoButton != none ) + InfoButton.Hide(); +} + +function SelectAbility(int idx) +{ + local UIArmory_PromotionHero PromotionScreen; + + PromotionScreen = UIArmory_PromotionHero(Screen); + + if( PromotionScreen.OwnsAbility(AbilityNames[idx]) ) + OnInfoButtonMouseEvent(InfoButtons[idx], class'UIUtilities_Input'.const.FXS_L_MOUSE_UP); + else if (bEligibleForPurchase && PromotionScreen.CanPurchaseAbility(Rank, idx + Offset, AbilityNames[idx])) + PromotionScreen.ConfirmAbilitySelection(Rank, idx); + else if (!PromotionScreen.IsAbilityLocked(Rank)) + OnInfoButtonMouseEvent(InfoButtons[idx], class'UIUtilities_Input'.const.FXS_L_MOUSE_UP); + else + Movie.Pres.PlayUISound(eSUISound_MenuClickNegative); +} + +// Override to handle Scrolling +simulated function SelectNextIcon() +{ + local int newIndex; + newIndex = m_iPanelIndex; //Establish a baseline so we can loop correctly + + do + { + newIndex += 1; + if( newIndex >= AbilityIcons.Length ) + { + if (AttemptScroll(false)) + { + // The screen has scrolled for us, we don't need to wrap around for now + newIndex--; + } + else + { + // Wrap around + newIndex = 0; + } + } + } until( AbilityIcons[newIndex].bIsVisible); + + UnfocusIcon(m_iPanelIndex); + m_iPanelIndex = newIndex; + FocusIcon(m_iPanelIndex); + Movie.Pres.PlayUISound(eSUISound_MenuSelect); //bsg-crobinson (5.11.17): Add sound +} + +simulated function SelectPrevIcon() +{ + local int newIndex; + newIndex = m_iPanelIndex; //Establish a baseline so we can loop correctly + + do + { + newIndex -= 1; + if( newIndex < 0 ) + { + if (AttemptScroll(true)) + { + // The screen has scrolled for us, we don't need to wrap around for now + newIndex++; + } + else + { + // Wrap around + newIndex = AbilityIcons.Length - 1; + } + } + } until( AbilityIcons[newIndex].bIsVisible); + + UnfocusIcon(m_iPanelIndex); + m_iPanelIndex = newIndex; + FocusIcon(m_iPanelIndex); + Movie.Pres.PlayUISound(eSUISound_MenuSelect); //bsg-crobinson (5.11.17): Add sound +} + + +// Instruct the Screen to Scroll the selection. +// Returns false if the column needs to wrap around, true else +// I.e. if we have <= 4 rows, this will always return false +simulated function bool AttemptScroll(bool Up) +{ + return NPSBDP_UIArmory_PromotionHero(Screen).AttemptScroll(Up); +} diff --git a/X2WOTCCommunityPromotionScreen/X2WOTCCommunityPromotionScreen.x2proj b/X2WOTCCommunityPromotionScreen/X2WOTCCommunityPromotionScreen.x2proj index 259a27f..0c68ef5 100644 --- a/X2WOTCCommunityPromotionScreen/X2WOTCCommunityPromotionScreen.x2proj +++ b/X2WOTCCommunityPromotionScreen/X2WOTCCommunityPromotionScreen.x2proj @@ -152,6 +152,9 @@ Content + + Content + Content