Source: Population.js

/**
 * @class
 */
function Population() {}

Population.prototype.Schema =
	"<a:help>Specifies the Population cap increase generated by this entity.</a:help>" +
	"<a:example>" +
		"<Bonus>15</Bonus>" +
	"</a:example>" +
	"<element name='Bonus' a:help='Population cap increase while this entity exists.'>" +
		"<data type='nonNegativeInteger'/>" +
	"</element>";

Population.prototype.Init = function()
{
	this.bonus = +this.template.Bonus;
};

/**
 * @return {number} - The population space provided by this entity.
 */
Population.prototype.GetPopBonus = function()
{
	return this.bonus;
};

Population.prototype.RecalculateValues = function()
{
	this.bonus = Math.round(ApplyValueModificationsToEntity("Population/Bonus", +this.template.Bonus, this.entity));
};

Population.prototype.OnOwnershipChanged = function(msg)
{
	if (msg.from != INVALID_PLAYER)
	{
		let cmpPlayer = QueryPlayerIDInterface(msg.from);
		if (cmpPlayer)
			cmpPlayer.AddPopulationBonuses(-this.bonus);
	}
	if (msg.to != INVALID_PLAYER)
	{
		this.RecalculateValues();
		let cmpPlayer = QueryPlayerIDInterface(msg.to);
		if (cmpPlayer)
			cmpPlayer.AddPopulationBonuses(this.bonus);
	}
};

Population.prototype.OnValueModification = function(msg)
{
	if (msg.component != "Population")
		return;

	// Foundations shouldn't give a pop bonus.
	if (Engine.QueryInterface(this.entity, IID_Foundation))
		return;

	let oldPopBonus = this.bonus;
	this.RecalculateValues();
	let popDifference = this.bonus - oldPopBonus;

	if (!popDifference)
		return;
	let cmpPlayer = QueryOwnerInterface(this.entity);
	if (cmpPlayer)
		cmpPlayer.AddPopulationBonuses(popDifference);
};

Engine.RegisterComponentType(IID_Population, "Population", Population);