Ticket #3000: heropanel4.patch
File heropanel4.patch, 9.8 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/session/session.js
From 6fa0e69334ec1a629c615012cc7310dd4f0f4e0c Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" <clockwork-muse@outlook.com> Date: Sat, 14 May 2016 11:03:03 +0900 Subject: [PATCH] heros --- binaries/data/mods/public/gui/session/session.js | 165 +++++++++++++++------ .../gui/session/session_objects/hero_icon.xml | 29 ++-- 2 files changed, 135 insertions(+), 59 deletions(-) diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index f944549..6b62cb3 100644
a b const g_DefaultPopulationColor = "white"; 8 8 const g_PopulationAlertColor = "orange"; 9 9 10 10 /** 11 * Maximum number of heroes to display (must stay in sync with hero_icon.xml). 12 */ 13 const g_HeroPanelCount = 10; 14 15 /** 11 16 * A random file will be played. TODO: more variety 12 17 */ 13 18 const g_Ambient = [ "audio/ambient/dayscape/day_temperate_gen_03.ogg" ]; … … var g_ShowGuarded = false; 143 148 var g_AdditionalHighlight = []; 144 149 145 150 /** 146 * Blink the hero selection if that entity has lost health since the last turn.151 * Previous set of heroes to display. 147 152 */ 148 var g_PreviousHero HitPoints;153 var g_PreviousHeroes = []; 149 154 150 155 /** 151 156 * Unit classes to be checked for the idle-worker-hotkey. … … function init(initData, hotloadData) 271 276 gameSpeed.onSelectionChange = function() { changeGameSpeed(+this.list_data[this.selected]); }; 272 277 initMenuPosition(); 273 278 279 // Initialize heroes and buttons. 280 for (let i = 0; i < g_HeroPanelCount; ++i) 281 { 282 // "Save" off the value to deal with the closure. 283 let slot = i; 284 let button = Engine.GetGUIObjectByName("unitHeroButton[" + slot + "]"); 285 button.onPress = function() 286 { 287 let hero = g_PreviousHeroes[slot]; 288 if (!hero) 289 return; 290 291 if (!Engine.HotkeyIsPressed("selection.add")) 292 g_Selection.reset(); 293 g_Selection.addList([hero.ent]); 294 }; 295 296 button.onDoublePress = function() { 297 let hero = g_PreviousHeroes[slot]; 298 if (hero) 299 selectAndMoveTo(getEntityOrHolder(hero.ent)); 300 }; 301 } 302 274 303 // Populate player selection dropdown 275 304 let playerNames = [translate("Observer")]; 276 305 let playerIDs = [-1]; … … function updateGUIObjects() 712 741 if (g_ShowGuarding || g_ShowGuarded) 713 742 updateAdditionalHighlight(); 714 743 715 updateHero ();744 updateHeroes(); 716 745 updateGroups(); 717 746 updateDebug(); 718 747 updatePlayerDisplay(); … … function updateGUIStatusBar(nameOfBar, points, maxPoints, direction) 788 817 } 789 818 790 819 791 function updateHero ()820 function updateHeroes() 792 821 { 793 let unitHeroPanel = Engine.GetGUIObjectByName("unitHeroPanel");794 let heroButton = Engine.GetGUIObjectByName("unitHeroButton");795 796 822 let playerState = GetSimState().players[g_ViewedPlayer]; 797 if (!playerState || playerState.heroes.length <= 0)823 if (!playerState || playerState.heroes.length == 0) 798 824 { 799 g_PreviousHeroHitPoints = undefined; 800 unitHeroPanel.hidden = true; 825 if (g_PreviousHeroes.length > 0) 826 { 827 g_PreviousHeroes.forEach((hero, slot) => { 828 if (hero) 829 Engine.GetGUIObjectByName("unitHeroButton[" + slot + "]").hidden = true; 830 }); 831 g_PreviousHeroes = []; 832 } 801 833 return; 802 834 } 803 835 804 let heroImage = Engine.GetGUIObjectByName("unitHeroImage"); 805 let heroState = GetExtendedEntityState(playerState.heroes[0]); 806 let template = GetTemplateData(heroState.template); 807 heroImage.sprite = "stretched:session/portraits/" + template.icon; 808 let hero = playerState.heroes[0]; 809 810 heroButton.onpress = function() 836 let mapped = playerState.heroes.map(ent => { 837 // Retain current ordering, if displayed previously. 838 // This does a linear search through the array, 839 // but the multiple-hero case is extremely rare. 840 let previous = g_PreviousHeroes.find(hero => hero && hero.ent == ent); 841 if (previous) 842 return { 843 "ent": ent, 844 "index": previous.index, 845 "previous": previous 846 }; 847 848 // Place new heroes at the end of the list. 849 return { 850 "ent": ent, 851 "index": g_HeroPanelCount 852 }; 853 }).sort((l, r) => l.index == r.index ? l.ent - r.ent : l.index - r.index); 854 855 let heroes = new Array(g_HeroPanelCount).fill(undefined); 856 857 for (let displayIndex = 0; displayIndex < Math.min(g_HeroPanelCount, mapped.length); ++displayIndex) 811 858 { 812 if (!Engine.HotkeyIsPressed("selection.add")) 813 g_Selection.reset(); 814 g_Selection.addList([hero]); 815 }; 816 heroButton.ondoublepress = function() { selectAndMoveTo(getEntityOrHolder(hero)); }; 817 unitHeroPanel.hidden = false; 859 let hero = mapped[displayIndex]; 860 861 // Find the first unused slot if new, otherwise reuse previous. 862 let slot = hero.previous ? 863 hero.previous.slot : 864 heroes.findIndex(slot => !slot); 865 866 let heroButton = Engine.GetGUIObjectByName("unitHeroButton[" + slot + "]"); 867 let heroState = GetExtendedEntityState(hero.ent); 868 let template = GetTemplateData(heroState.template); 869 870 if (!hero.previous) 871 { 872 // Ensure no pre-existing animations. 873 stopColorFade("heroHitOverlay[" + slot + "]"); 874 let heroImage = Engine.GetGUIObjectByName("unitHeroImage[" + slot + "]"); 875 heroImage.sprite = "stretched:session/portraits/" + template.icon; 818 876 877 heroButton.hidden = false; 878 } 879 880 heroButton.tooltip = createHeroTooltip(heroState, template); 881 updateGUIStatusBar("heroHealthBar[" + slot + "]", 882 heroState.hitpoints, heroState.maxHitpoints); 883 884 // The "slot" is which button, but it's the identity (name) of the button, not its position. 885 // Heroes stay in the same slot, but the position of the button may change. 886 // TODO: Instead of instant position changes, animate button movement. 887 setPanelObjectPosition(heroButton, displayIndex, g_HeroPanelCount); 888 889 // If the health of the hero changed since the last update, trigger the animation. 890 if (hero.previous && hero.previous.hitpoints > heroState.hitpoints) 891 startColorFade("heroHitOverlay[" + slot + "]", 100, 0, 892 colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 893 894 heroes[slot] = { 895 "ent": hero.ent, 896 "slot": slot, 897 "index": displayIndex, 898 "hitpoints": heroState.hitpoints 899 }; 900 } 901 902 // In case heroes were removed and their slot/button was freed, hide it. 903 g_PreviousHeroes.forEach((hero, slot) => { 904 if (!heroes[slot]) 905 Engine.GetGUIObjectByName("unitHeroButton[" + slot + "]").hidden = true; 906 }); 907 908 g_PreviousHeroes = heroes; 909 } 910 911 function createHeroTooltip(heroState, template) 912 { 819 913 // Setup tooltip 820 914 let tooltip = "[font=\"sans-bold-16\"]" + template.name.specific + "[/font]"; 821 let healthLabel = "[font=\"sans-bold-13\"]" + translate("Health:") + "[/font]"; 822 tooltip += "\n" + sprintf(translate("%(label)s %(current)s / %(max)s"), { 823 "label": healthLabel, 915 tooltip += "\n" + sprintf(translate("%(label)s %(current)s / %(max)s"), { 916 "label": "[font=\"sans-bold-13\"]" + translate("Health:") + "[/font]", 824 917 "current": Math.ceil(heroState.hitpoints), 825 918 "max": Math.ceil(heroState.maxHitpoints) 826 919 }); … … function updateHero() 830 923 tooltip += "\n" + getArmorTooltip(heroState.armour); 831 924 if (template.tooltip) 832 925 tooltip += "\n" + template.tooltip; 833 834 heroButton.tooltip = tooltip; 835 836 // update heros health bar 837 updateGUIStatusBar("heroHealthBar", heroState.hitpoints, heroState.maxHitpoints); 838 839 let heroHP = { 840 "hitpoints": heroState.hitpoints, 841 "player": g_ViewedPlayer 842 }; 843 844 if (!g_PreviousHeroHitPoints) 845 g_PreviousHeroHitPoints = heroHP; 846 847 // if the health of the hero changed since the last update, trigger the animation 848 if (g_PreviousHeroHitPoints.player == heroHP.player && g_PreviousHeroHitPoints.hitpoints > heroHP.hitpoints) 849 startColorFade("heroHitOverlay", 100, 0, colorFade_attackUnit, true, smoothColorFadeRestart_attackUnit); 850 851 g_PreviousHeroHitPoints = heroHP; 926 return tooltip; 852 927 } 853 928 854 929 function updateGroups() -
binaries/data/mods/public/gui/session/session_objects/hero_icon.xml
diff --git a/binaries/data/mods/public/gui/session/session_objects/hero_icon.xml b/binaries/data/mods/public/gui/session/session_objects/hero_icon.xml index 35d7053..6219006 100644
a b 2 2 <object 3 3 name="unitHeroPanel" 4 4 size="0 36 50 93" 5 hidden=" true"5 hidden="false" 6 6 > 7 <object name="unitHeroButton" size="0 0 50 50" type="button" style="iconButton" 8 tooltip_style="sessionToolTip"> 9 <object name="unitHeroImage" size="5 5 100%-5 100%-5" type="image" ghost="true"/> 10 <object name="heroHitOverlay" hidden="true" type="image" ghost="true" size="5 5 100%-5 100%-5"/> 11 </object> 12 <!-- Hero Health bar --> 13 <object size="3 100%-7 100%-3 100%-2" name="heroHealthSection" ghost="true"> 14 <object size="0 0 100% 5" name="heroHealth" type="image" ghost="true"> 15 <object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/> 16 <object type="image" sprite="healthBackground" ghost="true"/> 17 <object type="image" sprite="healthForeground" ghost="true" name="heroHealthBar"/> 18 <object type="image" sprite="statsBarShaderHorizontal" ghost="true"/> 7 <repeat count="10" var="n"> 8 <object name="unitHeroButton[n]" size="0 0 50 50" type="button" hidden="true" style="iconButton" tooltip_style="sessionToolTip"> 9 <object name="unitHeroImage[n]" size="5 5 100%-5 100%-5" type="image" ghost="true"/> 10 <object name="heroHitOverlay[n]" hidden="true" type="image" ghost="true" size="5 5 100%-5 100%-5"/> 11 <!-- Hero Health bar --> 12 <object size="3 100%-7 100%-3 100%-2" name="heroHealthSection[n]" ghost="true"> 13 <object size="0 0 100% 5" name="heroHealth[n]" type="image" ghost="true"> 14 <object type="image" sprite="barBorder" ghost="true" size="-1 -1 100%+1 100%+1"/> 15 <object type="image" sprite="healthBackground" ghost="true"/> 16 <object type="image" sprite="healthForeground" ghost="true" name="heroHealthBar[n]"/> 17 <object type="image" sprite="statsBarShaderHorizontal" ghost="true"/> 18 </object> 19 </object> 19 20 </object> 20 </ object>21 </repeat> 21 22 </object>