Changeset View
Standalone View
binaries/data/mods/public/simulation/components/VisionSharing.js
function VisionSharing() {} | function VisionSharing() {} | ||||
VisionSharing.prototype.Schema = | VisionSharing.prototype.Schema = | ||||
"<empty/>"; | "<element name='Bribable'>" + | ||||
"<data type='boolean'/>" + | |||||
"</element>"; | |||||
VisionSharing.prototype.Init = function() | VisionSharing.prototype.Init = function() | ||||
elexis: Should state something when it's a permanent spy | |||||
Not Done Inline Actionsok mimo: ok | |||||
{ | { | ||||
Not Done Inline Actions(Usually milliseconds in the templates, but I'm fine with seconds as likely noone (not even modders on a mars mission) will use something with higher precision) elexis: (Usually milliseconds in the templates, but I'm fine with seconds as likely noone (not even… | |||||
Not Done Inline ActionsUsually? all BuildTime or tech ResearchTime are in second. But i agree that we always have this ambiguity when reading templates which is not nice. Maybe we should decide on one time convention at least for future additions. I've no strong opinion about second or millisecond. mimo: Usually? all BuildTime or tech ResearchTime are in second. But i agree that we always have this… | |||||
this.activated = false; | this.activated = false; | ||||
this.shared = new Set(); | this.shared = new Set(); | ||||
this.spyId = 0; | |||||
this.spies = new Map(); | |||||
}; | }; | ||||
/** | /** | ||||
* As entities have not necessarily the VisionSharing component, it has to be activated | * As entities have not necessarily the VisionSharing component, it has to be activated | ||||
* before use so that the rangeManager can register it | * before use so that the rangeManager can register it | ||||
*/ | */ | ||||
VisionSharing.prototype.Activate = function() | VisionSharing.prototype.Activate = function() | ||||
{ | { | ||||
Show All 33 Lines | if (cmpGarrisonHolder) | ||||
if (entOwner > 0 && entOwner != owner) | if (entOwner > 0 && entOwner != owner) | ||||
{ | { | ||||
shared.add(entOwner); | shared.add(entOwner); | ||||
// if shared by another player than the owner and not yet activated, do it | // if shared by another player than the owner and not yet activated, do it | ||||
this.Activate(); | this.Activate(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// vision sharing due to spies | |||||
for (let spy of this.spies.values()) | |||||
if (spy > 0 && spy != owner) | |||||
shared.add(spy); | |||||
} | } | ||||
if (!this.activated) | if (!this.activated) | ||||
return; | return; | ||||
// compare with previous vision sharing, and update if needed | // compare with previous vision sharing, and update if needed | ||||
for (let player of shared) | for (let player of shared) | ||||
if (!this.shared.has(player)) | if (!this.shared.has(player)) | ||||
Engine.PostMessage(this.entity, MT_VisionSharingChanged, | Engine.PostMessage(this.entity, MT_VisionSharingChanged, | ||||
{ "entity": this.entity, "player": player, "add": true }); | { "entity": this.entity, "player": player, "add": true }); | ||||
for (let player of this.shared) | for (let player of this.shared) | ||||
if (!shared.has(player)) | if (!shared.has(player)) | ||||
Engine.PostMessage(this.entity, MT_VisionSharingChanged, | Engine.PostMessage(this.entity, MT_VisionSharingChanged, | ||||
{ "entity": this.entity, "player": player, "add": false }); | { "entity": this.entity, "player": player, "add": false }); | ||||
this.shared = shared; | this.shared = shared; | ||||
}; | }; | ||||
VisionSharing.prototype.IsBribable = function() | |||||
{ | |||||
return this.template.Bribable == "true"; | |||||
}; | |||||
VisionSharing.prototype.OnDiplomacyChanged = function(msg) | VisionSharing.prototype.OnDiplomacyChanged = function(msg) | ||||
{ | { | ||||
this.CheckVisionSharings(); | this.CheckVisionSharings(); | ||||
}; | }; | ||||
VisionSharing.prototype.OnGarrisonedUnitsChanged = function(msg) | VisionSharing.prototype.OnGarrisonedUnitsChanged = function(msg) | ||||
{ | { | ||||
this.CheckVisionSharings(); | this.CheckVisionSharings(); | ||||
}; | }; | ||||
VisionSharing.prototype.OnOwnershipChanged = function(msg) | VisionSharing.prototype.OnOwnershipChanged = function(msg) | ||||
{ | { | ||||
if (this.activated) | if (this.activated) | ||||
this.CheckVisionSharings(); | this.CheckVisionSharings(); | ||||
}; | }; | ||||
Not Done Inline ActionsJust note for myself: fatherbushido: Just note for myself:
(When msg.to == -1,
The CheckVisionSharings() calls will just set this. | |||||
VisionSharing.prototype.AddSpy = function(player, duration) | |||||
{ | |||||
if (!this.IsBribable()) | |||||
return; | |||||
let cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); | |||||
if (!cmpOwnership || cmpOwnership.GetOwner() == player || player <= 0) | |||||
return; | |||||
let cmpTechnologyManager = QueryPlayerIDInterface(player, IID_TechnologyManager); | |||||
if (!cmpTechnologyManager || !cmpTechnologyManager.CanProduce("special/spy")) | |||||
return; | |||||
let template = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager).GetTemplate("special/spy"); | |||||
let costs = {}; | |||||
for (let res in template.Cost.Resources) | |||||
costs[res] = Math.floor(ApplyValueModificationsToTemplate("Cost/Resources/"+res, +template.Cost.Resources[res], player, template)); | |||||
let cmpPlayer = QueryPlayerIDInterface(player); | |||||
if (!cmpPlayer || !cmpPlayer.TrySubtractResources(costs)) | |||||
return; | |||||
this.spies.set(++this.spyId, player); | |||||
if (duration) | |||||
{ | |||||
let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); | |||||
cmpTimer.SetTimeout(this.entity, IID_VisionSharing, "RemoveSpy", duration, { "id": this.spyId }); | |||||
} | |||||
this.Activate(); | |||||
this.CheckVisionSharings(); | |||||
Not Done Inline ActionsNot convinced by scaling with the vision range in comparison to just using the default. Permanent spies are impossible without changing special/spy.xml? Sounds bad for modders and future extension if so. (Would that actually work if attempted to be used or bug with undefined?) elexis: Not convinced by scaling with the vision range in comparison to just using the default. | |||||
Not Done Inline Actionswhile scaling is not really needed with bribable traders (land and naval traders have nearly the same vision), it would be unfair to pay the same price for a female (vision=32) and a cav (vision=90) if we add more bribable units. We could replace this scaling by a price depending on vision of the unit which will be selected, but i'm not sure it is worth the complication. mimo: while scaling is not really needed with bribable traders (land and naval traders have nearly… | |||||
Not Done Inline ActionsShouldn't the template specify the duration, thus the use/cost ratio? elexis: Shouldn't the template specify the duration, thus the use/cost ratio?
Permanent spies, well… | |||||
return this.spyId; | |||||
}; | |||||
VisionSharing.prototype.RemoveSpy = function(data) | |||||
{ | |||||
this.spies.delete(data.id); | |||||
this.CheckVisionSharings(); | |||||
}; | |||||
Not Done Inline Actions(Apparently the usual cases (defeat, ownership change, diplomacy change) that have often caused trouble with various components are covered, good) elexis: (Apparently the usual cases (defeat, ownership change, diplomacy change) that have often caused… | |||||
Engine.RegisterComponentType(IID_VisionSharing, "VisionSharing", VisionSharing); | Engine.RegisterComponentType(IID_VisionSharing, "VisionSharing", VisionSharing); | ||||
Not Done Inline Actions(perhaps add spaces) fatherbushido: (perhaps add spaces) | |||||
Not Done Inline Actionsyou mean for "duration*1000"? ok mimo: you mean for "duration*1000"? ok | |||||
Not Done Inline Actionsyes fatherbushido: yes | |||||
Not Done Inline Actions(indeed according to Coding_Conventions) elexis: (indeed according to Coding_Conventions) | |||||
Not Done Inline Actions/** * */ elexis: ```
/**
*
*/
``` | |||||
Not Done Inline Actionstrailing whitespace elexis: trailing whitespace |
Should state something when it's a permanent spy