Index: binaries/data/mods/public/simulation/components/Health.js =================================================================== --- binaries/data/mods/public/simulation/components/Health.js +++ binaries/data/mods/public/simulation/components/Health.js @@ -144,12 +144,30 @@ Health.prototype.ExecuteRegeneration = function() { - let regen = this.GetRegenRate(); - if (this.GetIdleRegenRate() != 0) + let regen; + let cmpIdentity = Engine.QueryInterface(this.entity, IID_Identity); + if (!cmpIdentity || !cmpIdentity.HasClass("Field")) + { + let regen = this.GetRegenRate(); + if (this.GetIdleRegenRate() != 0) + { + let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); + if (cmpUnitAI && (cmpUnitAI.IsIdle() || cmpUnitAI.IsGarrisoned() && !cmpUnitAI.IsTurret())) + regen += this.GetIdleRegenRate(); + } + } + else { - let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); - if (cmpUnitAI && (cmpUnitAI.IsIdle() || cmpUnitAI.IsGarrisoned() && !cmpUnitAI.IsTurret())) - regen += this.GetIdleRegenRate(); + // The regen rate for fields is by gatherers, while the idle one applies when no gatherers + let cmpResourceSupply = Engine.QueryInterface(this.entity, IID_ResourceSupply) + if (cmpResourceSupply) + { + let num = cmpResourceSupply.GetNumGatherers(); + if (num) + regen = num * this.GetRegenRate(); + else + regen = this.GetIdleRegenRate(); + } } if (regen > 0) @@ -166,7 +184,8 @@ // check if we need a timer if (this.GetRegenRate() == 0 && this.GetIdleRegenRate() == 0 || this.GetHitpoints() == this.GetMaxHitpoints() && this.GetRegenRate() >= 0 && this.GetIdleRegenRate() >= 0 || - this.GetHitpoints() == 0) + this.GetHitpoints() == 0 || + Engine.QueryInterface(this.entity, IID_Foundation)) { // we don't need a timer, disable if one exists if (this.regenTimer) Index: binaries/data/mods/public/simulation/components/ResourceGatherer.js =================================================================== --- binaries/data/mods/public/simulation/components/ResourceGatherer.js +++ binaries/data/mods/public/simulation/components/ResourceGatherer.js @@ -248,6 +248,9 @@ if (rate == 0 && type.generic) rate = this.GetGatherRate(type.generic); + // Health dependent rate of the supply if any + rate *= cmpResourceSupply.GetHealthRate(); + let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); let cheatMultiplier = cmpPlayer ? cmpPlayer.GetCheatTimeMultiplier() : 1; rate = rate / cheatMultiplier; Index: binaries/data/mods/public/simulation/components/ResourceSupply.js =================================================================== --- binaries/data/mods/public/simulation/components/ResourceSupply.js +++ binaries/data/mods/public/simulation/components/ResourceSupply.js @@ -22,6 +22,9 @@ "" + "" + "" + + "" + + "" + + "" + ""; ResourceSupply.prototype.Init = function() @@ -97,6 +100,19 @@ return null; }; +/* Health dependent factor to be applied on the gatherer rate */ +ResourceSupply.prototype.GetHealthRate = function() +{ + if (!("HealthRate" in this.template) || +this.template.HealthRate >= 1) + return 1; + + let cmpHealth = Engine.QueryInterface(this.entity, IID_Health); + if (!cmpHealth) + return 1; + + return Math.max(+this.template.HealthRate, cmpHealth.GetHitpoints() / cmpHealth.GetMaxHitpoints()); +}; + ResourceSupply.prototype.TakeResources = function(rate) { // Before changing the amount, activate Fogging if necessary to hide changes Index: binaries/data/mods/public/simulation/data/technologies/field_irrigation.json =================================================================== --- /dev/null +++ binaries/data/mods/public/simulation/data/technologies/field_irrigation.json @@ -0,0 +1,16 @@ +{ + "genericName": "Irrigation", + "description": "With irrigation, fields need less daily maintenance.", + "cost": { "food": 150, "wood": 150, "stone": 0, "metal": 0 }, + "requirements": { "tech": "phase_town" }, + "requirementsTooltip": "Unlocked in Town Phase.", + "icon": "irrigation.png", + "researchTime": 40, + "tooltip": "Field decay to fallow land when not worked on will be twice slower, while recultivation is twice faster.", + "modifications": [ + { "value": "Health/regenRate", "multiply": 2.0 }, + { "value": "Health/IdleRegenRate", "multiply": 0.5 } + ], + "affects": ["Field"], + "soundComplete": "interface/alarm/alarm_upgradearmory.xml" +} Index: binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml +++ binaries/data/mods/public/simulation/templates/template_structure_economic_farmstead.xml @@ -40,6 +40,7 @@ gather_farming_plows gather_farming_training gather_farming_fertilizer + field_irrigation Index: binaries/data/mods/public/simulation/templates/template_structure_resource_field.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_structure_resource_field.xml +++ binaries/data/mods/public/simulation/templates/template_structure_resource_field.xml @@ -2,7 +2,7 @@ 15 - 40 + 30 5 @@ -10,7 +10,7 @@ - 50 + 15 100 @@ -21,12 +21,15 @@ 250 + 75 rubble/rubble_field + 0.5 + -4 Field Field - Harvest vegetables for food. Max gatherers: 5. + Harvest vegetables for food. Max gatherers: 5. Fields slowly revert to fallow land when not worked on, while their fertility (health) improves when farmed. The gather rate increases with fertility. Farming originated around 9500 BC in India and the Middle East. The history of agriculture is a central element of human history, as agricultural progress has been a crucial factor in worldwide socio-economic change. Wealth-building and militaristic specializations rarely seen in hunter-gatherer cultures are commonplace in agricultural and agro-industrial societies - when farmers became capable of producing food beyond the needs of their own families, others in the tribe/nation/empire were freed to devote themselves to projects other than food acquisition. structures/field.png @@ -44,12 +47,14 @@ + false Infinity food.grain 5 0.90 + 0.3 Index: source/ps/TemplateLoader.cpp =================================================================== --- source/ps/TemplateLoader.cpp +++ source/ps/TemplateLoader.cpp @@ -484,8 +484,10 @@ // Add the Foundation component, to deal with the construction process CParamNode::LoadXMLString(out, ""); - // Initialise health to 1 + // Initialise health to 1 and Max health to the initial health of base entity CParamNode::LoadXMLString(out, "1"); + if (in.GetChild("Entity").GetChild("Health").GetChild("Initial").IsOk()) + CParamNode::LoadXMLString(out, (""+utf8_from_wstring(in.GetChild("Entity").GetChild("Health").GetChild("Initial").ToString())+"").c_str()); // Foundations shouldn't initially block unit movement if (out.GetChild("Entity").GetChild("Obstruction").IsOk())