Changeset View
Standalone View
binaries/data/mods/public/simulation/ai/petra/queueplanUpgrading.js
- This file was added.
PETRA.UpgradePlan = function(gameState, entityID, upgradeData) | ||||||||||||||
{ | ||||||||||||||
const ent = gameState.getEntityById(entityID); | ||||||||||||||
if (!ent || ent.upgradableEntities().every(upgrade => upgradeData.Entity !== upgrade.Entity)) | ||||||||||||||
FreagarachUnsubmitted Not Done Inline Actions
Freagarach: | ||||||||||||||
return false; | ||||||||||||||
ent.setMetadata(PlayerID, "upgrading", true); | ||||||||||||||
Done Inline ActionsThis is not OOS safe as the state needs to be serialized and conditionally set when deserializing. Otherwise it mismatches when one client deserializes and set this as true when the continuing client might have it as false. The fix is to surround this with a serialization check, but such things are everywhere, so I don't think that's grounds for blocking. lyv: This is not OOS safe as the state needs to be serialized and conditionally set when… | ||||||||||||||
Not Done Inline ActionsEntity metadata are serialised Silier: Entity metadata are serialised | ||||||||||||||
Not Done Inline ActionsI should have phrased that better. We need to wrap this in if (!gamestate.ai.isDeserializing) because when constructed in the process of deserialization, entity metadata would already be set. It's a consequence of having constructors with side effects. But we couldn't find a better place, so here it is. lyv: I should have phrased that better.
What will happen is that this constructor would override the… | ||||||||||||||
this.entityID = entityID; | ||||||||||||||
this.upgradeData = upgradeData; | ||||||||||||||
this.cost = new API3.Resources(upgradeData.Cost); | ||||||||||||||
// We do not call the base constructor, so set the ID here. | ||||||||||||||
this.ID = gameState.ai.uniqueIDs.plans++; | ||||||||||||||
this.category = "upgrading"; | ||||||||||||||
this.type = "upgrading"; | ||||||||||||||
Not Done Inline ActionsWhy do you need these? Freagarach: Why do you need these? | ||||||||||||||
Done Inline ActionsBase class properties used in various places. number: intended for counts. category and type: used for some specific logic such as not having multiple technology plans and whatnot in the same queue. lyv: Base class properties used in various places.
```
number: intended for counts.
category and… | ||||||||||||||
this.number = 1; | ||||||||||||||
return true; | ||||||||||||||
}; | ||||||||||||||
PETRA.UpgradePlan.prototype = Object.create(PETRA.QueuePlan.prototype); | ||||||||||||||
PETRA.UpgradePlan.prototype.canStart = function(gameState) | ||||||||||||||
{ | ||||||||||||||
const requiredTech = this.upgradeData.RequiredTechnology; | ||||||||||||||
return !requiredTech || gameState.isResearched(requiredTech); | ||||||||||||||
}; | ||||||||||||||
Not Done Inline ActionsSide effect Silier: Side effect | ||||||||||||||
Not Done Inline ActionsThe alternative is lifting the state up to the relevant manager and letting them sort it out I suppose. Which might be better as we might not want to research the techs *for* an upgrade, rather upgrade *if* it can be done. This is currently ignoring the strategy built into researchMan. lyv: The alternative is lifting the state up to the relevant manager and letting them sort it out I… | ||||||||||||||
Not Done Inline Actions
Freagarach: | ||||||||||||||
Done Inline ActionsArtifacts from when this had side effects on the research manager. Missed again. lyv: Artifacts from when this had side effects on the research manager. Missed again. | ||||||||||||||
PETRA.UpgradePlan.prototype.isInvalid = function(gameState) | ||||||||||||||
{ | ||||||||||||||
const ent = gameState.getEntityById(this.entityID); | ||||||||||||||
return !ent || !ent.getMetadata(PlayerID, "upgrading"); | ||||||||||||||
}; | ||||||||||||||
PETRA.UpgradePlan.prototype.start = function(gameState) | ||||||||||||||
{ | ||||||||||||||
Engine.PostCommand(PlayerID, { | ||||||||||||||
"type": "upgrade", | ||||||||||||||
"entities": [this.entityID], | ||||||||||||||
"template": gameState.applyCiv(this.upgradeData.Entity), | ||||||||||||||
"queued": false | ||||||||||||||
}); | ||||||||||||||
this.onStart(gameState); | ||||||||||||||
}; | ||||||||||||||
PETRA.UpgradePlan.prototype.onStart = function(gameState) | ||||||||||||||
{ | ||||||||||||||
if (this.queueToReset) | ||||||||||||||
gameState.ai.queueManager.changePriority(this.queueToReset, gameState.ai.Config.priorities[this.queueToReset]); | ||||||||||||||
}; | ||||||||||||||
PETRA.UpgradePlan.prototype.Serialize = function() | ||||||||||||||
{ | ||||||||||||||
return { | ||||||||||||||
Not Done Inline ActionsCould something like this be beneficial https://code.wildfiregames.com/source/0ad/browse/ps/trunk/binaries/data/mods/public/simulation/components/Researcher.js$117-142? (Not serialising not set values and one can (de)serialise the cost separately.) Freagarach: Could something like this be beneficial https://code.wildfiregames. | ||||||||||||||
Done Inline ActionsDefining the keys on the object literal vs defining them elsewhere is semantically equivalent I guess. In fact, I am not sure what advantages the other approach actually brings. lyv: Defining the keys on the object literal vs defining them elsewhere is semantically equivalent I… | ||||||||||||||
"entityID": this.entityID, | ||||||||||||||
"upgradeData": this.upgradeData, | ||||||||||||||
"category": this.category, | ||||||||||||||
"cost": this.cost.Serialize(), | ||||||||||||||
"queueToReset": this.queueToReset || undefined | ||||||||||||||
}; | ||||||||||||||
}; | ||||||||||||||
PETRA.UpgradePlan.prototype.Deserialize = function(gameState, data) | ||||||||||||||
{ | ||||||||||||||
for (const key in data) | ||||||||||||||
this[key] = data[key]; | ||||||||||||||
Not Done Inline ActionsWonder if object.assign works Stan: Wonder if object.assign works | ||||||||||||||
Done Inline ActionsObject.assign(this, data) is equivalent as long as data is not a Map or something. lyv: `Object.assign(this, data)` is equivalent as long as data is not a `Map` or something. | ||||||||||||||
this.cost = new API3.Resources(); | ||||||||||||||
this.cost.Deserialize(data.cost); | ||||||||||||||
}; |