diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index 7d08d7eebf..4dc1717ac6 100644
--- a/binaries/data/config/default.cfg
+++ b/binaries/data/config/default.cfg
@@ -249,6 +249,7 @@ hotkey.session.attackmove = Ctrl ; Modifier to attackmove when clicki
hotkey.session.queue = Shift ; Modifier to queue unit orders instead of replacing
hotkey.session.batchtrain = Shift ; Modifier to train units in batches
hotkey.session.massbarter = Shift ; Modifier to barter bunch of resources
+hotkey.session.masstribute = Shift ; Modifier to tribute bunch of resources
hotkey.session.unloadtype = Shift ; Modifier to unload all units of type
hotkey.session.deselectgroup = Ctrl ; Modifier to deselect units when clicking group icon, instead of selecting
hotkey.session.rotate.cw = RightBracket ; Rotate building placement preview clockwise
diff --git a/binaries/data/mods/public/gui/session/input.js b/binaries/data/mods/public/gui/session/input.js
index 6cc2d26c5c..c7e544b217 100644
--- a/binaries/data/mods/public/gui/session/input.js
+++ b/binaries/data/mods/public/gui/session/input.js
@@ -27,6 +27,7 @@ const INPUT_BATCHTRAINING = 6;
const INPUT_PRESELECTEDACTION = 7;
const INPUT_BUILDING_WALL_CLICK = 8;
const INPUT_BUILDING_WALL_PATHING = 9;
+const INPUT_MASSTRIBUTING = 10;
var inputState = INPUT_NORMAL;
var placementSupport = new PlacementSupport();
@@ -987,17 +988,21 @@ function handleInputBeforeGui(ev, hoveredObject)
}
break;
- case INPUT_BATCHTRAINING:
- switch (ev.type)
+ case INPUT_MASSTRIBUTING:
+ if (ev.type == "hotkeyup" && ev.hotkey == "session.masstribute")
{
- case "hotkeyup":
- if (ev.hotkey == "session.batchtrain")
- {
- flushTrainingBatch();
- inputState = INPUT_NORMAL;
- }
- break;
+ flushTributing();
+ inputState = INPUT_NORMAL;
}
+ break;
+
+ case INPUT_BATCHTRAINING:
+ if (ev.type == "hotkeyup" && ev.hotkey == "session.batchtrain")
+ {
+ flushTrainingBatch();
+ inputState = INPUT_NORMAL;
+ }
+ break;
}
return false;
diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js
index 5bae2109a0..ea83bbf089 100644
--- a/binaries/data/mods/public/gui/session/menu.js
+++ b/binaries/data/mods/public/gui/session/menu.js
@@ -34,6 +34,9 @@ var menu;
var isDiplomacyOpen = false;
+// Redefined every time someone makes a tribute (so we can save some data in a closure). Called in input.js handleInputBeforeGui.
+var flushTributing = function() {};
+
// Ignore size defined in XML and set the actual menu size here
function initMenuPosition()
{
@@ -271,15 +274,37 @@ function openDiplomacy()
for each (var resource in ["food", "wood", "stone", "metal"])
{
var button = getGUIObjectByName("diplomacyPlayerTribute"+toTitleCase(resource)+"["+(i-1)+"]");
- // TODO: Make amounts changeable or change to 500 if shift is pressed
- var amounts = {
- "food": (resource=="food")?100:0,
- "wood": (resource=="wood")?100:0,
- "stone": (resource=="stone")?100:0,
- "metal": (resource=="metal")?100:0,
- };
- button.onpress = (function(e){ return function() { tributeResource(e) } })({"player": i, "amounts": amounts});
+ button.onpress = (function(player, resource, button){
+ // Implement something like how unit batch training works. Shift+click to send 500, shift+click+click to send 1000, etc.
+ // Also see input.js (searching for "INPUT_MASSTRIBUTING" should get all the relevant parts).
+ var multiplier = 1;
+ return function() {
+ var isBatchTrainPressed = Engine.HotkeyIsPressed("session.masstribute");
+ if (isBatchTrainPressed)
+ {
+ inputState = INPUT_MASSTRIBUTING;
+ multiplier += multiplier == 1 ? 4 : 5;
+ }
+ var amounts = {
+ "food": (resource == "food" ? 100 : 0) * multiplier,
+ "wood": (resource == "wood" ? 100 : 0) * multiplier,
+ "stone": (resource == "stone" ? 100 : 0) * multiplier,
+ "metal": (resource == "metal" ? 100 : 0) * multiplier,
+ };
+ button.tooltip = formatTributeTooltip(players[player], resource, amounts[resource]);
+ // This is in a closure so that we have access to `player`, `amounts`, and `multiplier` without some
+ // evil global variable hackery.
+ flushTributing = function() {
+ tributeResource({"player": player, "amounts": amounts});
+ multiplier = 1;
+ button.tooltip = formatTributeTooltip(players[player], resource, 100);
+ };
+ if (!isBatchTrainPressed)
+ flushTributing();
+ };
+ })(i, resource, button);
button.hidden = false;
+ button.tooltip = formatTributeTooltip(players[i], resource, 100);
}
// Skip our own teams on teams locked
@@ -396,3 +421,10 @@ function closeOpenDialogs()
closeDiplomacy();
closeSettings(false);
}
+
+function formatTributeTooltip(player, resource, amount)
+{
+ var playerColor = player.color.r + " " + player.color.g + " " + player.color.b;
+ return "Tribute " + amount + " " + resource + " to [color=\"" + playerColor + "\"]" + player.name +
+ "[/color]. Shift-click to tribute " + (amount < 500 ? 500 : amount + 500) + ".";
+}
diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml
index 92594b2c52..13ca0707db 100644
--- a/binaries/data/mods/public/gui/session/session.xml
+++ b/binaries/data/mods/public/gui/session/session.xml
@@ -313,16 +313,16 @@
-