Index: binaries/data/mods/public/gui/session/menu.js =================================================================== --- binaries/data/mods/public/gui/session/menu.js +++ binaries/data/mods/public/gui/session/menu.js @@ -556,6 +556,15 @@ "cost": modifiedTemplate.cost, "player": g_ViewedPlayer }); + let costRatio = Engine.GetTemplate("special/spy").VisionSharing.FailureCostRatio; + if (costRatio > 0) + { + tooltips.push(translate("A failed bribe will cost you:")); + for (let res in modifiedTemplate.cost) + modifiedTemplate.cost[res] = Math.floor(costRatio * modifiedTemplate.cost[res]); + tooltips.push(getEntityCostTooltip(modifiedTemplate)); + } + if (neededResources) { if (button.enabled) Index: binaries/data/mods/public/simulation/components/VisionSharing.js =================================================================== --- binaries/data/mods/public/simulation/components/VisionSharing.js +++ binaries/data/mods/public/simulation/components/VisionSharing.js @@ -8,6 +8,11 @@ "" + "" + "" + + "" + + "" + + "" + + "" + + "" + ""; VisionSharing.prototype.Init = function() @@ -118,14 +123,7 @@ return 0; let template = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager).GetTemplate("special/spy"); - let costs = {}; - // Additional cost for this owner - let cmpPlayerBribed = QueryPlayerIDInterface(cmpOwnership.GetOwner()); - let multiplier = cmpPlayerBribed.GetSpyCostMultiplier(); - for (let res in template.Cost.Resources) - costs[res] = Math.floor(multiplier * ApplyValueModificationsToTemplate("Cost/Resources/" + res, +template.Cost.Resources[res], player, template)); - let cmpPlayerSpy = QueryPlayerIDInterface(player); - if (!cmpPlayerSpy || !cmpPlayerSpy.TrySubtractResources(costs)) + if (!IncurBribeCost(template, player, cmpOwnership.GetOwner(), false)) return 0; // If no duration given, take it from the spy template and scale it with the ent vision Index: binaries/data/mods/public/simulation/components/tests/test_VisionSharing.js =================================================================== --- binaries/data/mods/public/simulation/components/tests/test_VisionSharing.js +++ binaries/data/mods/public/simulation/components/tests/test_VisionSharing.js @@ -1,5 +1,6 @@ Engine.LoadHelperScript("Player.js"); Engine.LoadHelperScript("ValueModification.js"); +Engine.LoadHelperScript("Commands.js"); Engine.LoadComponentScript("interfaces/GarrisonHolder.js"); Engine.LoadComponentScript("interfaces/TechnologyManager.js"); Engine.LoadComponentScript("interfaces/AuraManager.js"); Index: binaries/data/mods/public/simulation/helpers/Commands.js =================================================================== --- binaries/data/mods/public/simulation/helpers/Commands.js +++ binaries/data/mods/public/simulation/helpers/Commands.js @@ -783,12 +783,16 @@ }); } else + { + let template = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager).GetTemplate("special/spy"); + IncurBribeCost(template, player, cmd.player, true); cmpGUIInterface.PushNotification({ "type": "text", "players": [player], "message": markForTranslation("There are no bribable units"), "translateMessage": true }); + } }, "diplomacy-request": function(player, cmd, data) @@ -1685,8 +1689,32 @@ return entities.filter(ent => CanControlUnitOrIsAlly(ent, player, controlAll)); } +/** + * Incur the player with the cost of a bribe, optionally multiply the cost with + * the additionalMultiplier + */ +function IncurBribeCost(template, player, playerBribed, failedBribe) +{ + let cmpPlayerBribed = QueryPlayerIDInterface(playerBribed); + if (!cmpPlayerBribed) + return false; + + let costs = {}; + // Additional cost for this owner + let multiplier = cmpPlayerBribed.GetSpyCostMultiplier(); + if (failedBribe) + multiplier *= template.VisionSharing.FailureCostRatio; + + for (let res in template.Cost.Resources) + costs[res] = Math.floor(multiplier * ApplyValueModificationsToTemplate("Cost/Resources/" + res, +template.Cost.Resources[res], player, template)); + + let cmpPlayer = QueryPlayerIDInterface(player); + return cmpPlayer && cmpPlayer.TrySubtractResources(costs); +} + Engine.RegisterGlobal("GetFormationRequirements", GetFormationRequirements); Engine.RegisterGlobal("CanMoveEntsIntoFormation", CanMoveEntsIntoFormation); Engine.RegisterGlobal("GetDockAngle", GetDockAngle); Engine.RegisterGlobal("ProcessCommand", ProcessCommand); Engine.RegisterGlobal("g_Commands", g_Commands); +Engine.RegisterGlobal("IncurBribeCost", IncurBribeCost); Index: binaries/data/mods/public/simulation/templates/special/spy.xml =================================================================== --- binaries/data/mods/public/simulation/templates/special/spy.xml +++ binaries/data/mods/public/simulation/templates/special/spy.xml @@ -20,5 +20,6 @@ false 15 + 0.25