Ticket #531: PopLimit.diff

File PopLimit.diff, 6.5 KB (added by evans, 22 months ago)
  • binaries/data/mods/public/simulation/components/TrainingQueue.js

     
    1919TrainingQueue.prototype.Init = function() 
    2020{ 
    2121    this.nextID = 1; 
    22  
     22    this.popReserve = 0; 
    2323    this.queue = []; 
    2424    // Queue items are: 
    2525    //   { 
     
    4646    return string.split(/\s+/); 
    4747}; 
    4848 
     49TrainingQueue.prototype.GetPlayer = function() 
     50{ 
     51    var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 
     52    var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership); 
     53    var playerEnt = cmpPlayerMan.GetPlayerByID(cmpOwnership.GetOwner()); 
     54    return Engine.QueryInterface(playerEnt, IID_Player); 
     55}; 
     56 
     57TrainingQueue.prototype.ReservePopulationSlots = function(num) 
     58{ 
     59    this.popReserve += num; 
     60}; 
     61 
     62TrainingQueue.prototype.UnReservePopulationSlots = function(num) 
     63{ 
     64    this.popReserve -= Math.min(num, this.popReserve); 
     65}; 
     66 
    4967TrainingQueue.prototype.AddBatch = function(player, templateName, count) 
    5068{ 
    5169    // TODO: there should probably be a limit on the number of queued batches 
     
    7088        else 
    7189            costs[r] = 0; 
    7290    } 
     91    var population; 
     92    if(template.Cost.Population) 
     93    { 
     94        population = template.Cost.Population * count; 
     95    } 
     96    else 
     97    { 
     98        population = 0; 
     99    } 
    73100 
    74     // Find the player 
    75     var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 
    76     var playerEnt = cmpPlayerMan.GetPlayerByID(player); 
    77     var cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player); 
     101    var cmpPlayer = this.GetPlayer(); 
    78102 
    79103    if (!cmpPlayer.TrySubtractResources(costs)) 
    80104    { 
     
    82106        return; 
    83107    } 
    84108 
     109     
    85110    this.queue.push({ 
    86111        "id": this.nextID++, 
    87112        "template": templateName, 
    88113        "count": count, 
    89114        "resources": costs, 
     115        "population": population, 
     116        "trainingStarted": false, 
    90117        "timeTotal": time*1000, 
    91118        "timeRemaining": time*1000, 
    92119    }); 
     
    109136 
    110137        // Now we've found the item to remove 
    111138 
    112         // Find the player 
    113         var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 
    114         var playerEnt = cmpPlayerMan.GetPlayerByID(player); 
    115         var cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player); 
     139        var cmpPlayer = this.GetPlayer(); 
    116140 
    117141        // Refund the resource cost for this batch 
    118142        cmpPlayer.AddResources(item.resources); 
    119  
     143         
     144        //Remove reserved population slots 
     145        if (item.trainingStarted) 
     146        { 
     147            //The batch's training has started. It will have  
     148            //population slots reserved for it 
     149            cmpPlayer.UnReservePopulationSlots(item.population); 
     150            this.UnReservePopulationSlots(item.population); 
     151        } 
     152         
    120153        // Remove from the queue 
    121154        // (We don't need to remove the timer - it'll expire if it discovers the queue is empty) 
    122155        this.queue.splice(i, 1); 
    123156        return; 
    124157    } 
    125 } 
     158}; 
    126159 
    127160TrainingQueue.prototype.GetQueue = function() 
    128161{ 
     
    139172    return out; 
    140173}; 
    141174 
     175TrainingQueue.prototype.OnOwnershipChanged = function(msg) 
     176{ 
     177    var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 
     178    if (msg.from != -1) 
     179    { 
     180        //if msg.from==-1, Building has just been created, 
     181        //so there will be no need to remove reserved slots 
     182        var fromPlayerEnt = cmpPlayerMan.GetPlayerByID(msg.from); 
     183        var cmpFromPlayer = Engine.QueryInterface(fromPlayerEnt, IID_Player); 
     184        //Remove reserved slots from the original owner 
     185        cmpFromPlayer.UnReservePopulationSlots(this.popReserve); 
     186    } 
     187    if (msg.to != -1) 
     188    { 
     189        //if msg.to==-1, Building has been destroyed, 
     190        //so there will be no need to reserve slots 
     191        var toPlayerEnt = cmpPlayerMan.GetPlayerByID(msg.to); 
     192        var cmpToPlayer = Engine.QueryInterface(toPlayerEnt, IID_Player); 
     193        //Reserve slots in new owner 
     194        cmpToPlayer.ReservePopulationSlots(this.popReserve); 
     195    } 
     196     
     197}; 
     198 
    142199TrainingQueue.prototype.OnDestroy = function() 
    143200{ 
    144201    // If the building is destroyed while it's got a large training queue, 
    145202    // you lose all the resources invested in that queue. That'll teach you 
    146203    // to be so reckless with your buildings. 
    147  
    148204    if (this.timer) 
    149205    { 
    150206        var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 
     
    163219    for (var i = 0; i < count; ++i) 
    164220    { 
    165221        var ent = Engine.AddEntity(templateName); 
    166  
    167222        var pos = cmpFootprint.PickSpawnPoint(ent); 
    168223        if (pos.y < 0) 
    169224        { 
     
    198253    // until we've used up all the time (so that we work accurately 
    199254    // with items that take fractions of a second) 
    200255    var time = g_ProgressInterval; 
    201  
     256    var cmpPlayer = this.GetPlayer(); 
     257     
    202258    time *= 10; // XXX: this is a hack to make testing easier 
    203  
    204259    while (time > 0 && this.queue.length) 
    205260    { 
    206261        var item = this.queue[0]; 
    207         if (item.timeRemaining > time) 
     262        if (!item.trainingStarted) 
    208263        { 
     264            //Batch's training hasn't started yet 
     265            var popSlotsAvail = cmpPlayer.GetPopulationLimit() - cmpPlayer.GetPopulationCount(); 
     266            if (popSlotsAvail >= item.population) 
     267            { 
     268                //Slots available; 
     269                //Reserve those slots 
     270                this.ReservePopulationSlots(item.population); 
     271                cmpPlayer.ReservePopulationSlots(item.population); 
     272                //Start Training 
     273                item.timeRemaining -= time; 
     274                item.trainingStarted = true; 
     275            } 
     276            break; 
     277        } 
     278        else if (item.timeRemaining > time) 
     279        { 
    209280            item.timeRemaining -= time; 
    210281            break; 
    211282        } 
     
    213284        // This item is finished now 
    214285        time -= item.timeRemaining; 
    215286        this.SpawnUnits(item.template, item.count); 
     287        //Unit has been created. Remove reserved spots 
     288        cmpPlayer.UnReservePopulationSlots(item.population); 
     289        this.UnReservePopulationSlots(item.population); 
    216290        this.queue.shift(); 
    217291    } 
    218292 
  • binaries/data/mods/public/simulation/components/Player.js

     
    1010    this.civ = "gaia"; 
    1111    this.colour = { "r": 0.0, "g": 0.0, "b": 0.0, "a": 1.0 }; 
    1212    this.popCount = 0; 
    13     this.popLimit = 50; 
     13    this.popLimit = 0; 
     14    this.popReserve = 0; 
    1415    this.resourceCount = { 
    1516        "food": 2000,    
    1617        "wood": 1500,    
     
    5455    return this.colour; 
    5556}; 
    5657 
     58Player.prototype.ReservePopulationSlots = function(num) 
     59{ 
     60    this.popReserve += num; 
     61}; 
     62 
     63Player.prototype.UnReservePopulationSlots = function(num) 
     64{ 
     65    this.popReserve -= Math.min(num, this.popReserve); 
     66} 
     67 
    5768Player.prototype.GetPopulationCount = function() 
    5869{ 
    59     return this.popCount; 
     70    return this.popCount + this.popReserve; 
    6071}; 
    6172 
    6273Player.prototype.GetPopulationLimit = function()