function ResourceSupply() {} ResourceSupply.prototype.Schema = "Provides a supply of one particular type of resource." + "" + "1000" + "food.meat" + "" + "" + "" + "" + "" + "Infinity" + "" + "" + "" + "wood.tree" + "wood.ruins" + "stone.rock" + "stone.ruins" + "metal.ore" + "food.fish" + "food.fruit" + "food.grain" + "food.meat" + "food.milk" + "treasure.wood" + "treasure.stone" + "treasure.metal" + "treasure.food" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; ResourceSupply.prototype.Init = function() { // Current resource amount (non-negative) this.amount = this.GetMaxAmount(); this.gatherers = []; // list of IDs for each players var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); // system component so that's safe. var numPlayers = cmpPlayerManager.GetNumPlayers(); for (var i = 0; i <= numPlayers; ++i) // use "<=" because we want Gaia too. this.gatherers.push([]); this.infinite = !isFinite(+this.template.Amount); }; ResourceSupply.prototype.IsInfinite = function() { return this.infinite; }; ResourceSupply.prototype.GetKillBeforeGather = function() { return (this.template.KillBeforeGather == "true"); }; ResourceSupply.prototype.GetMaxAmount = function() { return +this.template.Amount; }; ResourceSupply.prototype.GetCurrentAmount = function() { return this.amount; }; ResourceSupply.prototype.GetMaxGatherers = function() { return +this.template.MaxGatherers; }; ResourceSupply.prototype.GetGatherers = function() { var numPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetNumPlayers(); var total = []; for (var playerid = 0; playerid <= numPlayers; playerid++) for (var gatherer = 0; gatherer < this.gatherers[playerid].length; gatherer++) total.push(this.gatherers[playerid][gatherer]); return total; }; ResourceSupply.prototype.GetDiminishingReturns = function() { if ("DiminishingReturns" in this.template) return ApplyValueModificationsToEntity("ResourceSupply/DiminishingReturns", +this.template.DiminishingReturns, this.entity); return null; }; ResourceSupply.prototype.TakeResources = function(rate) { if (this.infinite) return { "amount": rate, "exhausted": false }; // 'rate' should be a non-negative integer 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) }; }; ResourceSupply.prototype.GetType = function() { // All resources must have both type and subtype var [type, subtype] = this.template.Type.split('.'); return { "generic": type, "specific": subtype }; }; ResourceSupply.prototype.IsAvailable = function(player, gathererID) { if (this.GetGatherers().length < this.GetMaxGatherers() || this.gatherers[player].indexOf(gathererID) !== -1) return true; return false; }; ResourceSupply.prototype.AddGatherer = function(player, gathererID) { if (!this.IsAvailable(player, gathererID)) return false; if (this.gatherers[player].indexOf(gathererID) === -1) { this.gatherers[player].push(gathererID); // broadcast message, mainly useful for the AIs. Engine.PostMessage(this.entity, MT_ResourceSupplyGatherersChanged, { "to": this.GetGatherers() }); } return true; }; // should this return false if the gatherer didn't gather from said resource? ResourceSupply.prototype.RemoveGatherer = function(gathererID, player) { // this can happen if the unit is dead if (player === undefined || player === -1) { for (var i = 0; i < this.gatherers.length; ++i) this.RemoveGatherer(gathererID, i); } else { var index = this.gatherers[player].indexOf(gathererID); if (index !== -1) { this.gatherers[player].splice(index,1); // broadcast message, mainly useful for the AIs. Engine.PostMessage(this.entity, MT_ResourceSupplyGatherersChanged, { "to": this.GetGatherers() }); return; } } }; Engine.RegisterComponentType(IID_ResourceSupply, "ResourceSupply", ResourceSupply);