Ticket #3731: t3731_observer_selection_panels_v1.patch
File t3731_observer_selection_panels_v1.patch, 17.5 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/session/input.js
function handleInputBeforeGui(ev, hovere 683 683 var result = updateBuildingPlacementPreview(); // includes an update of the snap entity candidates 684 684 685 685 if (result && result.cost) 686 686 { 687 687 placementSupport.tooltipMessage = getEntityCostTooltip(result); 688 var neededResources = Engine.GuiInterfaceCall("GetNeededResources", result.cost);688 var neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": result.cost }); 689 689 if (neededResources) 690 690 placementSupport.tooltipMessage += getNeededResourcesTooltip(neededResources); 691 691 } 692 692 693 693 break; … … function handleInputAfterGui(ev) 1079 1079 placementSupport.wallSnapEntitiesIncludeOffscreen = false; 1080 1080 } 1081 1081 else 1082 1082 { 1083 1083 // cancel if not enough resources 1084 if (placementSupport.template && Engine.GuiInterfaceCall("GetNeededResources", GetTemplateData(placementSupport.template).cost))1084 if (placementSupport.template && Engine.GuiInterfaceCall("GetNeededResources", { "cost": GetTemplateData(placementSupport.template).cost })) 1085 1085 { 1086 1086 placementSupport.Reset(); 1087 1087 inputState = INPUT_NORMAL; 1088 1088 return true; 1089 1089 } … … function addTrainingToQueue(selection, t 1412 1412 inputState = INPUT_NORMAL; 1413 1413 } 1414 1414 else if (limits.canBeAddedCount == undefined || 1415 1415 limits.canBeAddedCount > batchTrainingCount * appropriateBuildings.length) 1416 1416 { 1417 if (Engine.GuiInterfaceCall("GetNeededResources", multiplyEntityCosts(1418 template, batchTrainingCount + batchIncrementSize)))1417 if (Engine.GuiInterfaceCall("GetNeededResources", { "cost": 1418 multiplyEntityCosts(template, batchTrainingCount + batchIncrementSize) })) 1419 1419 return; 1420 1420 1421 1421 batchTrainingCount += batchIncrementSize; 1422 1422 } 1423 1423 batchTrainingEntityAllowedCount = limits.canBeAddedCount; … … function addTrainingToQueue(selection, t 1430 1430 // fall through to create the new batch 1431 1431 } 1432 1432 } 1433 1433 1434 1434 // Don't start a new batch if decrementing or unable to afford it. 1435 if (decrement || Engine.GuiInterfaceCall("GetNeededResources", 1436 multiplyEntityCosts(template, batchIncrementSize) ))1435 if (decrement || Engine.GuiInterfaceCall("GetNeededResources", { "cost": 1436 multiplyEntityCosts(template, batchIncrementSize) })) 1437 1437 return; 1438 1438 1439 1439 inputState = INPUT_BATCHTRAINING; 1440 1440 batchTrainingEntities = selection; 1441 1441 batchTrainingType = trainEntType; -
binaries/data/mods/public/gui/session/selection_details.js
function updateSelectionDetails() 412 412 displayMultiple(selection); 413 413 414 414 // Show basic details. 415 415 detailsPanel.hidden = false; 416 416 417 if (g_IsObserver) 418 { 419 // Observers don't need these displayed. 420 supplementalDetailsPanel.hidden = true; 421 commandsPanel.hidden = true; 422 } 423 else 424 { 425 // Fill out commands panel for specific unit selected (or first unit of primary group) 426 updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection); 427 } 417 // Fill out commands panel for specific unit selected (or first unit of primary group) 418 updateUnitCommands(entState, supplementalDetailsPanel, commandsPanel, selection); 428 419 } -
binaries/data/mods/public/gui/session/selection_panels.js
g_SelectionPanels.Alert = { 88 88 else if (data.item == "end") 89 89 { 90 90 data.button.hidden = !data.unitEntState.alertRaiser.hasRaisedAlert; 91 91 data.icon.sprite = "stretched:session/icons/bell_level0.png"; 92 92 } 93 data.button.enabled = !data.button.hidden ;93 data.button.enabled = !data.button.hidden && IsPlaying(); 94 94 }, 95 95 }; 96 96 97 97 // BARTER 98 98 g_SelectionPanels.Barter = { … … g_SelectionPanels.Barter = { 156 156 var grayscale = data.isSelected ? "color: 0 0 0 100:grayscale:" : ""; 157 157 158 158 // do we have enough of this resource to sell? 159 159 var neededRes = {}; 160 160 neededRes[data.item] = data.amountToSell; 161 var canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", neededRes) != undefined ? "color:255 0 0 80:" : ""; 161 var canSellCurrent = Engine.GuiInterfaceCall("GetNeededResources", { 162 "cost": neededRes, 163 "player": data.unitEntState.player 164 }) ? "color:255 0 0 80:" : ""; 165 162 166 // Let's see if we have enough resources to barter. 163 167 neededRes = {}; 164 168 neededRes[g_barterSell] = data.amountToSell; 165 var canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", neededRes) != undefined ? "color:255 0 0 80:" : ""; 169 var canBuyAny = Engine.GuiInterfaceCall("GetNeededResources", { 170 "cost": neededRes, 171 "player": data.unitEntState.player 172 }) ? "color:255 0 0 80:" : ""; 166 173 167 174 data.icon.Sell.sprite = canSellCurrent + "stretched:"+grayscale+"session/icons/resources/" + data.item + ".png"; 168 175 data.icon.Buy.sprite = canBuyAny + "stretched:"+grayscale+"session/icons/resources/" + data.item + ".png"; 169 176 170 177 data.button.Buy.hidden = data.isSelected; 178 data.button.Buy.enabled = IsPlaying(); 171 179 data.button.Sell.hidden = false; 172 180 data.selectionIcon.hidden = !data.isSelected; 173 181 }, 174 182 "setPosition": function(data) 175 183 { … … g_SelectionPanels.Command = { 210 218 data.countDisplay.caption = data.item.count || ""; 211 219 }, 212 220 "setGraphics": function(data) 213 221 { 214 222 data.icon.sprite = "stretched:session/icons/" + data.item.icon; 223 data.button.enabled = IsPlaying(); 215 224 }, 216 225 "setPosition": function(data) 217 226 { 218 227 var size = data.button.size; 219 228 // count on square buttons, so size.bottom is the width too … … g_SelectionPanels.AllyCommand = { 260 269 data.countDisplay.caption = data.item.count || ""; 261 270 }, 262 271 "setGraphics": function(data) 263 272 { 264 273 data.icon.sprite = "stretched:session/icons/" + data.item.icon; 274 data.button.enabled = IsPlaying(); 265 275 }, 266 276 "setPosition": function(data) 267 277 { 268 278 var size = data.button.size; 269 279 // count on square buttons, so size.bottom is the width too … … g_SelectionPanels.Construction = { 291 301 { 292 302 data.entType = data.item; 293 303 data.template = GetTemplateData(data.entType); 294 304 if (!data.template) // abort if no template 295 305 return false; 296 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", data.template.requiredTechnology); 306 307 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", { 308 "tech": data.template.requiredTechnology, 309 "player": data.unitEntState.player 310 }); 311 297 312 if (data.template.cost) 298 { 299 var totalCost = multiplyEntityCosts(data.template, 1); 300 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", totalCost); 301 } 313 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 314 "cost": multiplyEntityCosts(data.template, 1), 315 "player": data.unitEntState.player 316 }); 317 302 318 data.limits = getEntityLimitAndCount(data.playerState, data.entType); 303 319 return true; 304 320 }, 305 321 "setAction": function(data) 306 322 { … … g_SelectionPanels.Construction = { 340 356 else if (data.neededResources) 341 357 { 342 358 data.button.enabled = false; 343 359 modifier += resourcesToAlphaMask(data.neededResources) +":"; 344 360 } 361 else 362 data.button.enabled = IsPlaying(); 345 363 346 364 if (data.template.icon) 347 365 data.icon.sprite = modifier + "stretched:session/portraits/" + data.template.icon; 348 366 }, 349 367 "setPosition": function(data) … … g_SelectionPanels.Formation = { 392 410 tooltip += "\n" + "[color=\"red\"]" + translate(data.formationInfo.tooltip) + "[/color]"; 393 411 data.button.tooltip = tooltip; 394 412 }, 395 413 "setGraphics": function(data) 396 414 { 397 data.button.enabled = data.formationOk ;415 data.button.enabled = data.formationOk && IsPlaying(); 398 416 var grayscale = data.formationOk ? "" : "grayscale:"; 399 417 data.guiSelection.hidden = !data.formationSelected; 400 418 data.icon.sprite = "stretched:"+grayscale+"session/icons/"+data.formationInfo.icon; 401 419 }, 402 420 }; … … g_SelectionPanels.Gate = { 543 561 return count; 544 562 }, 0); 545 563 546 564 tooltip += "\n" + getEntityCostTooltip(data.template, data.wallCount); 547 565 566 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { "cost": 567 multiplyEntityCosts(data.template, data.wallCount) }); 548 568 549 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", multiplyEntityCosts(data.template, data.wallCount));550 569 if (data.neededResources) 551 570 tooltip += getNeededResourcesTooltip(data.neededResources); 552 571 } 553 572 data.button.tooltip = tooltip; 554 573 }, 555 574 "setGraphics": function(data) 556 575 { 576 data.button.enabled = IsPlaying(); 557 577 var gateIcon; 558 578 if (data.item.gate) 559 579 { 560 580 // If already a gate, show locking actions 561 581 gateIcon = "icons/lock_" + GATE_ACTIONS[data.item.locked ? 0 : 1] + "ed.png"; … … g_SelectionPanels.Pack = { 638 658 data.icon.sprite = "stretched:session/icons/cancel.png"; 639 659 else if (data.item.packed) 640 660 data.icon.sprite = "stretched:session/icons/unpack.png"; 641 661 else 642 662 data.icon.sprite = "stretched:session/icons/pack.png"; 663 664 data.button.enabled = IsPlaying(); 643 665 }, 644 666 "setPosition": function(data) 645 667 { 646 668 var index = data.i + getNumberOfRightPanelButtons(); 647 669 setPanelObjectPosition(data.button, index, data.rowLength); … … g_SelectionPanels.Queue = { 718 740 }, 719 741 "setGraphics": function(data) 720 742 { 721 743 if (data.template.icon) 722 744 data.icon.sprite = "stretched:session/portraits/" + data.template.icon; 745 746 data.button.enabled = IsPlaying(); 723 747 }, 724 748 }; 725 749 726 750 // RESEARCH 727 751 g_SelectionPanels.Research = { … … g_SelectionPanels.Research = { 777 801 data.unchosenIcon = data.positions.map(function(p) { 778 802 return Engine.GetGUIObjectByName("unitResearchUnchosenIcon["+p+"]"); 779 803 }); 780 804 781 805 data.neededResources = data.template.map(function(t) { 782 return Engine.GuiInterfaceCall("GetNeededResources", t.cost); 806 return Engine.GuiInterfaceCall("GetNeededResources", { 807 "cost": t.cost, 808 "player": data.unitEntState.player 809 }); 783 810 }); 784 811 785 812 data.requirementsPassed = data.entType.map(function(e) { 786 return Engine.GuiInterfaceCall("CheckTechnologyRequirements",e); 813 return Engine.GuiInterfaceCall("CheckTechnologyRequirements", { 814 "tech": e, 815 "player": data.unitEntState.player 816 }); 787 817 }); 788 818 789 819 data.pair = Engine.GetGUIObjectByName("unitResearchPair["+data.i+"]"); 790 820 791 821 return true; … … g_SelectionPanels.Research = { 804 834 if (!data.requirementsPassed[i]) 805 835 { 806 836 tooltip += "\n" + template.requirementsTooltip; 807 837 if (template.classRequirements) 808 838 { 809 var player = Engine.GetPlayerID();839 var player = data.unitEntState.player; 810 840 var current = GetSimState().players[player].classCounts[template.classRequirements.class] || 0; 811 841 var remaining = template.classRequirements.number - current; 812 842 tooltip += " " + sprintf(translatePlural("Remaining: %(number)s to build.", "Remaining: %(number)s to build.", remaining), { number: remaining}); 813 843 } 814 844 } … … g_SelectionPanels.Research = { 860 890 { 861 891 button.enabled = false; 862 892 modifier += resourcesToAlphaMask(data.neededResources[i]) + ":"; 863 893 } 864 894 else 865 button.enabled = true;895 button.enabled = IsPlaying(); 866 896 867 897 if (data.template[i].icon) 868 898 data.icon[i].sprite = modifier + "stretched:session/portraits/" + data.template[i].icon; 869 899 } 870 900 for (var button of data.buttonsToHide) … … g_SelectionPanels.Selection = { 968 998 }, 969 999 "setGraphics": function(data) 970 1000 { 971 1001 if (data.template.icon) 972 1002 data.icon.sprite = "stretched:session/portraits/" + data.template.icon; 1003 1004 data.button.enabled = IsPlaying(); 973 1005 }, 974 1006 }; 975 1007 976 1008 // STANCE 977 1009 g_SelectionPanels.Stance = { … … g_SelectionPanels.Stance = { 1003 1035 }, 1004 1036 "setGraphics": function(data) 1005 1037 { 1006 1038 data.guiSelection.hidden = !data.stanceSelected; 1007 1039 data.icon.sprite = "stretched:session/icons/stances/"+data.item+".png"; 1040 data.button.enabled = IsPlaying(); 1008 1041 }, 1009 1042 }; 1010 1043 1011 1044 // TRAINING 1012 1045 g_SelectionPanels.Training = { … … g_SelectionPanels.Training = { 1022 1055 { 1023 1056 data.entType = data.item; 1024 1057 data.template = GetTemplateData(data.entType); 1025 1058 if (!data.template) 1026 1059 return false; 1027 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", data.template.requiredTechnology); 1060 1061 data.technologyEnabled = Engine.GuiInterfaceCall("IsTechnologyResearched", { 1062 "tech": data.template.requiredTechnology, 1063 "player": data.unitEntState.player 1064 }); 1028 1065 1029 1066 var [buildingsCountToTrainFullBatch, fullBatchSize, remainderBatch] = 1030 1067 getTrainingBatchStatus(data.playerState, data.unitEntState.id, data.entType, data.selection); 1031 1068 data.buildingsCountToTrainFullBatch = buildingsCountToTrainFullBatch; 1032 1069 data.fullBatchSize = fullBatchSize; … … g_SelectionPanels.Training = { 1036 1073 data.trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch; 1037 1074 1038 1075 if (data.template.cost) 1039 1076 { 1040 1077 var totalCosts = multiplyEntityCosts(data.template, data.trainNum); 1041 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", totalCosts); 1078 data.neededResources = Engine.GuiInterfaceCall("GetNeededResources", { 1079 "cost": totalCosts, 1080 "player": data.unitEntState.player 1081 }); 1042 1082 } 1043 1083 1044 1084 return true; 1045 1085 }, 1046 1086 "setAction": function(data) … … var g_PanelsOrder = [ 1138 1178 "Command", 1139 1179 "AllyCommand", 1140 1180 "Queue", 1141 1181 "Selection", 1142 1182 ]; 1183 1184 /** 1185 * Returns true if the user is an assigned player or if an observer uses the change-perspective tool. 1186 */ 1187 function IsPlaying() 1188 { 1189 return Engine.GetPlayerID() != -1; 1190 } -
binaries/data/mods/public/gui/session/unit_commands.js
function updateUnitCommands(entState, su 166 166 // Get player state to check some constraints 167 167 // e.g. presence of a hero or build limits 168 168 var simState = GetSimState(); 169 169 var playerState = simState.players[player]; 170 170 171 if (entState.player == player || g_DevSettings.controlAll )171 if (entState.player == player || g_DevSettings.controlAll || g_IsObserver) 172 172 { 173 173 for (var guiName of g_PanelsOrder) 174 174 { 175 175 if ( 176 176 g_SelectionPanels[guiName].conflictsWith && 177 177 g_SelectionPanels[guiName].conflictsWith.some(function (p) { return g_SelectionPanels[p].used; }) 178 178 ) 179 179 continue; 180 180 181 setupUnitPanel(guiName, entState, playerState);181 setupUnitPanel(guiName, entState, simState.players[entState.player]); 182 182 } 183 183 184 184 supplementalDetailsPanel.hidden = false; 185 185 commandsPanel.hidden = false; 186 186 } -
binaries/data/mods/public/simulation/components/GuiInterface.js
GuiInterface.prototype.GetTechnologyData 582 582 583 583 let cmpPlayer = QueryPlayerIDInterface(player, IID_Player); 584 584 return GetTechnologyDataHelper(template, cmpPlayer.GetCiv()); 585 585 }; 586 586 587 GuiInterface.prototype.IsTechnologyResearched = function(player, tech)587 GuiInterface.prototype.IsTechnologyResearched = function(player, data) 588 588 { 589 if (! tech)589 if (!data.tech) 590 590 return true; 591 591 592 let cmpTechnologyManager = QueryPlayerIDInterface( player, IID_TechnologyManager);592 let cmpTechnologyManager = QueryPlayerIDInterface(data.player || player, IID_TechnologyManager); 593 593 594 594 if (!cmpTechnologyManager) 595 595 return false; 596 596 597 return cmpTechnologyManager.IsTechnologyResearched( tech);597 return cmpTechnologyManager.IsTechnologyResearched(data.tech); 598 598 }; 599 599 600 600 // Checks whether the requirements for this technology have been met 601 GuiInterface.prototype.CheckTechnologyRequirements = function(player, tech)601 GuiInterface.prototype.CheckTechnologyRequirements = function(player, data) 602 602 { 603 let cmpTechnologyManager = QueryPlayerIDInterface( player, IID_TechnologyManager);603 let cmpTechnologyManager = QueryPlayerIDInterface(data.player || player, IID_TechnologyManager); 604 604 605 605 if (!cmpTechnologyManager) 606 606 return false; 607 607 608 return cmpTechnologyManager.CanResearch( tech);608 return cmpTechnologyManager.CanResearch(data.tech); 609 609 }; 610 610 611 611 // Returns technologies that are being actively researched, along with 612 612 // which entity is researching them and how far along the research is. 613 613 GuiInterface.prototype.GetStartedResearch = function(player) … … GuiInterface.prototype.GetIncomingAttack 645 645 { 646 646 return QueryPlayerIDInterface(player, IID_AttackDetection).GetIncomingAttacks(); 647 647 }; 648 648 649 649 // Used to show a red square over GUI elements you can't yet afford. 650 GuiInterface.prototype.GetNeededResources = function(player, amounts)650 GuiInterface.prototype.GetNeededResources = function(player, data) 651 651 { 652 return QueryPlayerIDInterface( player).GetNeededResources(amounts);652 return QueryPlayerIDInterface(data.player || player).GetNeededResources(data.cost); 653 653 }; 654 654 655 655 /** 656 656 * Add a timed notification. 657 657 * Warning: timed notifacations are serialised … … GuiInterface.prototype.SetWallPlacementP 1486 1486 result.cost.time += tplData.cost.time; 1487 1487 } 1488 1488 1489 1489 let canAfford = true; 1490 1490 let cmpPlayer = QueryPlayerIDInterface(player, IID_Player); 1491 if (cmpPlayer && cmpPlayer.GetNeededResources( result.cost))1491 if (cmpPlayer && cmpPlayer.GetNeededResources({ "cost": result.cost })) 1492 1492 canAfford = false; 1493 1493 1494 1494 let cmpVisual = Engine.QueryInterface(ent, IID_Visual); 1495 1495 if (cmpVisual) 1496 1496 {