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 @@ -47,6 +47,11 @@ "" + "" + "" + + "" + + "" + + "" + + "" + + "" + "" + "" + "" + @@ -144,12 +149,29 @@ Health.prototype.ExecuteRegeneration = function() { - let regen = this.GetRegenRate(); - if (this.GetIdleRegenRate() != 0) + let regen = 0; + if (this.template.RegenWhenAttended) + { + // 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(); + } + } + else { - let cmpUnitAI = Engine.QueryInterface(this.entity, IID_UnitAI); - if (cmpUnitAI && (cmpUnitAI.IsIdle() || cmpUnitAI.IsGarrisoned() && !cmpUnitAI.IsTurret())) - regen += this.GetIdleRegenRate(); + 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(); + } } if (regen > 0) @@ -166,7 +188,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) @@ -222,7 +245,7 @@ PlaySound("death", this.entity); // If SpawnEntityOnDeath is set, spawn the entity - if(this.template.SpawnEntityOnDeath) + if (this.template.SpawnEntityOnDeath) this.CreateDeathSpawnedEntity(); if (this.template.DeathType == "corpse") 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 (!("MinHealthRate" in this.template) || +this.template.MinHealthRate >= 1) + return 1; + + let cmpHealth = Engine.QueryInterface(this.entity, IID_Health); + if (!cmpHealth) + return 1; + + return Math.max(+this.template.MinHealthRate, 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,16 @@ 250 + 75 rubble/rubble_field + true + 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 +48,14 @@ + false Infinity food.grain 5 0.90 + 0.4 Index: source/ps/TemplateLoader.cpp =================================================================== --- source/ps/TemplateLoader.cpp +++ source/ps/TemplateLoader.cpp @@ -76,6 +76,11 @@ m_TemplateFileData[templateName] = m_TemplateFileData[baseName]; CParamNode::LoadXML(m_TemplateFileData[templateName], xero, path.string().c_str()); + // TODO only temporary hack, for test purposes + // Initialise Max health to the initial health of base entity (useful for foundation) + if (prefix == "foundation" && + m_TemplateFileData[baseName].GetChild("Entity").GetChild("Health").GetChild("Initial").IsOk()) + CParamNode::LoadXMLString(m_TemplateFileData[templateName], (""+utf8_from_wstring(m_TemplateFileData[baseName].GetChild("Entity").GetChild("Health").GetChild("Initial").ToString())+"").c_str()); return true; }