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 @@ -293,9 +293,17 @@ // persistent corpse retaining the ResourceSupply element of the parent. var cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager); var templateName = cmpTemplateManager.GetCurrentTemplateName(this.entity); - var corpse; + let corpse; if (leaveResources) - corpse = Engine.AddEntity("resource|" + templateName); + { + let cmpResourceSupply = Engine.QueryInterface(this.entity, IID_ResourceSupply); + if (cmpResourceSupply) + { + corpse = Engine.AddEntity("resource|" + templateName); + let corpseResourceSupply = Engine.QueryInterface(corpse, IID_ResourceSupply); + corpseResourceSupply.SetAmount(cmpResourceSupply.GetCurrentAmount()); + } + } else corpse = Engine.AddLocalEntity("corpse|" + templateName); 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 @@ -4,10 +4,21 @@ "Provides a supply of one particular type of resource." + "" + "1000" + + "500" + "food.meat" + "false" + "25" + "0.8" + + "" + + "" + + "1" + + "500" + + "" + + "" + + "" + + "1" + + "1000" + + "" + "" + "" + "" + @@ -15,6 +26,11 @@ "" + "Infinity" + "" + + "" + + "" + + "" + + "" + + "" + "" + Resources.BuildChoicesSchema(true, true) + "" + @@ -25,21 +41,83 @@ "" + "" + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + ""; + ResourceSupply.prototype.Init = function() { // Current resource amount (non-negative) - this.amount = this.GetMaxAmount(); + this.amount = +this.template.Amount; + this.maxAmount = this.amount; + if (this.template.MaxAmount && +this.template.MaxAmount > this.amount) + this.maxAmount = +this.template.MaxAmount; + this.growsWhenAliveOnly = false; + this.growthRate = 0; + this.growthInterval = null; + this.growthTimer = null; + + this.decaysWhenDeadOnly = false; + this.decayRate = 0; + this.decayInterval = null; + this.decayTimer = null; + + this.infinite = !isFinite(+this.template.Amount); + + if (this.template.Growth) + { + this.growsWhenAliveOnly = !!this.template.Growth.GrowsWhenAliveOnly; + this.growthRate = +this.template.Growth.Rate; + this.growthInterval = +this.template.Growth.Interval; + this.AddGrowthTimer(); + } + + if (this.template.Decay && !this.infinite) + { + this.decaysWhenDeadOnly = !!this.template.Decay.DecaysWhenDeadOnly; + this.decayRate = +this.template.Decay.Rate; + this.decayInterval = +this.template.Decay.Interval; + this.AddDecayTimer(); + } + + + // List of IDs for each player this.gatherers = []; let numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers() for (let i = 0; i < numPlayers; ++i) this.gatherers.push([]); - this.infinite = !isFinite(+this.template.Amount); - let [type, subtype] = this.template.Type.split('.'); this.cachedType = { "generic": type, "specific": subtype }; }; @@ -56,7 +134,7 @@ ResourceSupply.prototype.GetMaxAmount = function() { - return +this.template.Amount; + return this.maxAmount; }; ResourceSupply.prototype.GetCurrentAmount = function() @@ -90,6 +168,11 @@ return null; }; +ResourceSupply.prototype.SetAmount = function(newAmount) +{ + this.amount = Math.min(Math.max(newAmount, 0), this.GetMaxAmount()); +} + ResourceSupply.prototype.TakeResources = function(rate) { // Before changing the amount, activate Fogging if necessary to hide changes @@ -100,19 +183,11 @@ if (this.infinite) return { "amount": rate, "exhausted": false }; - // 'rate' should be a non-negative integer + let old = this.amount; + this.SetAmount(old - rate); + this.UpdateSupplyStatus(old); - var old = this.amount; - this.amount = Math.max(0, old - rate); - var change = old - this.amount; - - // Remove entities that have been exhausted - if (this.amount === 0) - Engine.DestroyEntity(this.entity); - - Engine.PostMessage(this.entity, MT_ResourceSupplyChanged, { "from": old, "to": this.amount }); - - return { "amount": change, "exhausted": (this.amount === 0) }; + return { "amount": old - this.GetCurrentAmount(), "exhausted": this.GetCurrentAmount() === 0 }; }; ResourceSupply.prototype.GetType = function() @@ -138,6 +213,18 @@ Engine.PostMessage(this.entity, MT_ResourceSupplyNumGatherersChanged, { "to": this.GetNumGatherers() }); } + if (this.growthTimer) + { + Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).CancelTimer(this.growthTimer); + this.growthTimer = null; + } + + if (this.decayTimer) + { + Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).CancelTimer(this.decayTimer); + this.decayTimer = null; + } + return true; }; @@ -161,6 +248,63 @@ return; } } + + if (this.template.Growth && this.gatherers.some(player => !player.length) && !this.regenerateTimer) + this.AddGrowthTimer(); + + if (this.template.Decay && this.gatherers.some(player => !player.length) && !this.regenerateTimer) + this.AddDecayTimer(); }; +ResourceSupply.prototype.AddGrowthTimer = function() +{ + this.regenerateTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer) + .SetInterval(this.entity, IID_ResourceSupply, "GrowSupply", this.growthInterval, this.growthInterval, undefined); +} + +ResourceSupply.prototype.AddDecayTimer = function() +{ + this.regenerateTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer) + .SetInterval(this.entity, IID_ResourceSupply, "DecaySupply", this.decayInterval, this.decayInterval, undefined); +} + +ResourceSupply.prototype.GrowSupply = function() +{ + if(this.growsWhenAliveOnly) + { + // TODO: Check if alive, else return; + } + + let old = this.GetCurrentAmount(); + this.SetAmount(old + this.growthRate); + this.UpdateSupplyStatus(old); +}; + +ResourceSupply.prototype.DecaySupply = function() +{ + if(this.decaysWhenDeadOnly) + { + // TODO: Check if dead, else return; + } + + let old = this.GetCurrentAmount(); + this.SetAmount(old - this.decayRate); + this.UpdateSupplyStatus(old); +}; + +ResourceSupply.prototype.UpdateSupplyStatus = function(old) +{ + + // Remove entities that have been exhausted. + if (this.GetCurrentAmount() === 0) + Engine.DestroyEntity(this.entity); + + // Do not send messages if the resource count didn't change. + if (old == this.GetCurrentAmount()) + return; + + Engine.PostMessage(this.entity, MT_ResourceSupplyChanged, { "from": old, "to": this.GetCurrentAmount() }); +} + + Engine.RegisterComponentType(IID_ResourceSupply, "ResourceSupply", ResourceSupply); Index: binaries/data/mods/public/simulation/templates/gaia/fauna_sheep.xml =================================================================== --- binaries/data/mods/public/simulation/templates/gaia/fauna_sheep.xml +++ binaries/data/mods/public/simulation/templates/gaia/fauna_sheep.xml @@ -12,6 +12,19 @@ pitch + + 200 + + + 2 + 1000 + + + + 1 + 1000 + + Index: binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt.xml =================================================================== --- binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt.xml +++ binaries/data/mods/public/simulation/templates/template_unit_fauna_hunt.xml @@ -12,5 +12,10 @@ 100 food.meat 8 + + + 1 + 1000 +