Ticket #1089: qbot_full_serialize.patch

File qbot_full_serialize.patch, 50.5 KB (added by historic_bruno, 6 years ago)
  • binaries/data/mods/public/simulation/ai/common-api-v2/base.js

     
    44        return;
    55
    66    // Make some properties non-enumerable, so they won't be serialised
    7     Object.defineProperty(this, "_player", {value: settings.player, enumerable: false});
    8     Object.defineProperty(this, "_templates", {value: settings.templates, enumerable: false});
    9     Object.defineProperty(this, "_derivedTemplates", {value: {}, enumerable: false});
     7    // Object.defineProperty(this, "_player", {value: settings.player, enumerable: false});
     8    // Object.defineProperty(this, "_templates", {value: settings.templates, enumerable: false});
     9    // Object.defineProperty(this, "_derivedTemplates", {value: {}, enumerable: false});
     10    this._player = settings.player;
     11    this._templates = settings.templates;
     12    this._derivedTemplates = {};
    1013
    1114    this._entityMetadata = {};
    1215
     
    1720    this.turn = 0;
    1821}
    1922
    20 //Return a simple object (using no classes etc) that will be serialized
    21 //into saved games
    22 BaseAI.prototype.Serialize = function()
    23 {
    24     var rawEntities = {};
    25    
    26     for (var id in this._entities)
    27     {
    28         rawEntities[id] = this._entities[id]._entity;
    29     }
    30    
    31     return {
    32         _rawEntities: rawEntities,
    33         _entityMetadata: this._entityMetadata,
    34     };
    35 
    36     // TODO: ought to get the AI script subclass to serialize its own state
    37 };
    38 
    39 //Called after the constructor when loading a saved game, with 'data' being
    40 //whatever Serialize() returned
    41 BaseAI.prototype.Deserialize = function(data)
    42 {
    43     var rawEntities = data._rawEntities;
    44     this._entityMetadata = data._entityMetadata;
    45     this._entities = {}
    46    
    47     for (var id in rawEntities)
    48     {
    49         this._entities[id] = new Entity(this, rawEntities[id]);
    50     }
    51 
    52     // TODO: ought to get the AI script subclass to deserialize its own state
    53 };
    54 
    5523// Components that will be disabled in foundation entity templates.
    5624// (This is a bit yucky and fragile since it's the inverse of
    5725// CCmpTemplateManager::CopyFoundationSubset and only includes components
     
    306274        return undefined;
    307275    return metadata[key];
    308276}
     277
     278Engine.RegisterSerializablePrototype("BaseAI", BaseAI.prototype);
  • binaries/data/mods/public/simulation/ai/common-api-v2/entity.js

     
    452452    },
    453453});
    454454
     455Engine.RegisterSerializablePrototype("Entity", Entity.prototype);
     456Engine.RegisterSerializablePrototype("EntityTemplate", EntityTemplate.prototype);
     457
  • binaries/data/mods/public/simulation/ai/common-api-v2/entitycollection.js

     
    88    // Compute length lazily on demand, since it can be
    99    // expensive for large collections
    1010    this._length = undefined;
    11     Object.defineProperty(this, "length", {
    12         get: function () {
    13             if (this._length === undefined)
    14             {
    15                 this._length = 0;
    16                 for (var id in entities)
    17                     ++this._length;
    18             }
    19             return this._length;
    20         }
    21     });
    2211}
    2312
     13// Add custom getter on the prototype so the serializer doesn't lose it
     14// TODO: why don't we just use .getLength() instead of hiding this?
     15Object.defineProperty(EntityCollection.prototype, "length", {
     16    get: function () {
     17        if (this._length === undefined)
     18        {
     19            this._length = 0;
     20            for (var id in this._entities)
     21                ++this._length;
     22        }
     23        return this._length;
     24    }
     25});
     26
    2427EntityCollection.prototype.toIdArray = function()
    2528{
    2629    var ret = [];
     
    6770    return new EntityCollection(this._ai, ret);
    6871};
    6972
    70 EntityCollection.prototype.filter = function(filter, thisp)
     73EntityCollection.prototype.filter = function(filter)
    7174{
    72     if (typeof(filter) == "function")
    73         filter = {"func": filter, "dynamicProperties": []};
    74    
    7575    var ret = {};
    7676    for (var id in this._entities)
    7777    {
    7878        var ent = this._entities[id];
    79         if (filter.func.call(thisp, ent, id, this))
     79        if (filter.test(ent))
    8080            ret[id] = ent;
    8181    }
    8282   
     
    160160    var passesFilters = true;
    161161    for each (var filter in this._filters)
    162162    {
    163         passesFilters = passesFilters && filter.func(ent);
     163        passesFilters = passesFilters && filter.test(ent);
    164164    }
    165165
    166166    if (passesFilters)
     
    198198{
    199199    return this._UID;
    200200};
     201
     202Engine.RegisterSerializablePrototype("EntityCollection", EntityCollection.prototype);
  • binaries/data/mods/public/simulation/ai/common-api-v2/filters.js

     
    1 var Filters = {
    2     byType: function(type){
    3         return {"func" : function(ent){
    4             return ent.templateName() === type;
    5         },
    6         "dynamicProperties": []};
    7     },
     1// TODO: Some of these can use inheritance
     2
     3function FilterByType(type)
     4{
     5    this.type = type;
     6    this.dynamicProperties = [];
     7}
     8FilterByType.prototype.test = function(ent)
     9{
     10    return ent.templateName() === this.type;
     11};
     12Engine.RegisterSerializablePrototype("FilterByType", FilterByType.prototype);
     13
     14function FilterByClass(cls)
     15{
     16    this.cls = cls;
     17    this.dynamicProperties = [];
     18}
     19FilterByClass.prototype.test = function(ent)
     20{
     21    return ent.hasClass(this.cls);
     22};
     23Engine.RegisterSerializablePrototype("FilterByClass", FilterByClass.prototype);
     24
     25function FilterByClassesAnd(clsList)
     26{
     27    this.clsList = clsList;
     28    this.dynamicProperties = [];
     29}
     30FilterByClassesAnd.prototype.test = function(ent)
     31{
     32    var ret = true;
     33    for (var i in this.clsList){
     34        ret = ret && ent.hasClass(this.clsList[i]);
     35    }
     36    return ret;
     37};
     38Engine.RegisterSerializablePrototype("FilterByClassesAnd", FilterByClassesAnd.prototype);
     39
     40function FilterByClassesOr(clsList)
     41{
     42    this.clsList = clsList;
     43    this.dynamicProperties = [];
     44}
     45FilterByClassesOr.prototype.test = function(ent)
     46{
     47    var ret = false;
     48    for (var i in this.clsList){
     49        ret = ret || ent.hasClass(this.clsList[i]);
     50    }
     51    return ret;
     52};
     53Engine.RegisterSerializablePrototype("FilterByClassesOr", FilterByClassesOr.prototype);
     54
     55function FilterByMetadata(key, value)
     56{
     57    this.key = key;
     58    this.value = value;
     59    this.dynamicProperties = "metadata." + key;
     60}
     61FilterByMetadata.prototype.test = function(ent)
     62{
     63    return (ent.getMetadata(this.key) == this.value);
     64};
     65Engine.RegisterSerializablePrototype("FilterByMetadata", FilterByMetadata.prototype);
     66
     67function FilterAnd(filter1, filter2)
     68{
     69    this.filter1 = filter1;
     70    this.filter2 = filter2;
     71    this.dynamicProperties = filter1.dynamicProperties.concat(filter2.dynamicProperties);
     72}
     73FilterAnd.prototype.test = function(ent)
     74{
     75    return this.filter1.test(ent) && this.filter2.test(ent);
     76};
     77Engine.RegisterSerializablePrototype("FilterAnd", FilterAnd.prototype);
     78
     79function FilterOr(filter1, filter2)
     80{
     81    this.filter1 = filter1;
     82    this.filter2 = filter2;
     83    this.dynamicProperties = filter1.dynamicProperties.concat(filter2.dynamicProperties);
     84}
     85FilterOr.prototype.test = function(ent)
     86{
     87    return this.filter1.test(ent) || this.filter2.test(ent);
     88};
     89Engine.RegisterSerializablePrototype("FilterOr", FilterOr.prototype);
     90
     91function FilterNot(filter)
     92{
     93    this.filter = filter;
     94    this.dynamicProperties = filter.dynamicProperties;
     95}
     96FilterNot.prototype.test = function(ent)
     97{
     98    return !this.filter.test(ent);
     99};
     100Engine.RegisterSerializablePrototype("FilterNot", FilterNot.prototype);
     101
     102function FilterByOwner(owner)
     103{
     104    this.owner = owner;
     105    this.dynamicProperties = ["owner"];
     106}
     107FilterByOwner.prototype.test = function(ent)
     108{
     109    return (ent.owner() === this.owner);
     110};
     111Engine.RegisterSerializablePrototype("FilterByOwner", FilterByOwner.prototype);
    8112   
    9     byClass: function(cls){
    10         return {"func" : function(ent){
    11             return ent.hasClass(cls);
    12         },
    13         "dynamicProperties": []};
    14     },
     113function FilterByNotOwner(owner)
     114{
     115    this.owner = owner;
     116    this.dynamicProperties = ["owner"];
     117}
     118FilterByNotOwner.prototype.test = function(ent)
     119{
     120    return (ent.owner() !== this.owner);
     121};
     122Engine.RegisterSerializablePrototype("FilterByNotOwner", FilterByNotOwner.prototype);
    15123   
    16     byClassesAnd: function(clsList){
    17         return {"func" : function(ent){
    18             var ret = true;
    19             for (var i in clsList){
    20                 ret = ret && ent.hasClass(clsList[i]);
    21             }
    22             return ret;
    23         },
    24         "dynamicProperties": []};
    25     },
    26    
    27     byClassesOr: function(clsList){
    28         return {"func" : function(ent){
    29             var ret = false;
    30             for (var i in clsList){
    31                 ret = ret || ent.hasClass(clsList[i]);
    32             }
    33             return ret;
    34         },
    35         "dynamicProperties": []};
    36     },
     124function FilterByOwners(owners)
     125{
     126    this.owners = owners;
     127    this.dynamicProperties = ["owner"];
     128}
     129FilterByOwners.prototype.test = function(ent)
     130{
     131    for (var i in this.owners){
     132        if (ent.owner() == +this.owners[i]){
     133            return true;
     134        }
     135    }
     136    return false;
     137};
     138Engine.RegisterSerializablePrototype("FilterByOwners", FilterByOwners.prototype);
    37139
    38     byMetadata: function(key, value){
    39         return {"func" : function(ent){
    40             return (ent.getMetadata(key) == value);
    41         },
    42         "dynamicProperties": ['metadata.' + key]};
    43     },
     140function FilterByTrainingQueue()
     141{
     142    this.dynamicProperties = ["trainingQueue"];
     143}
     144FilterByTrainingQueue.prototype.test = function(ent)
     145{
     146    return ent.trainingQueue();
     147};
     148Engine.RegisterSerializablePrototype("FilterByTrainingQueue", FilterByTrainingQueue.prototype);
     149
     150function FilterIsSoldier()
     151{
     152    this.dynamicProperties = [];
     153}
     154FilterIsSoldier.prototype.test = function(ent)
     155{
     156    var filter = new FilterByClassesOr(["CitizenSoldier", "Super"]);
     157    return filter.test(ent);
     158};
     159Engine.RegisterSerializablePrototype("FilterIsSoldier", FilterIsSoldier.prototype);
     160
     161function FilterIsIdle()
     162{
     163    this.dynamicProperties = ["idle"];
     164}
     165FilterIsIdle.prototype.test = function(ent)
     166{
     167    return ent.isIdle();
     168};
     169Engine.RegisterSerializablePrototype("FilterIsIdle", FilterIsIdle.prototype);
     170
     171function FilterIsFoundation()
     172{
     173    this.dynamicProperties = [];
     174}
     175FilterIsFoundation.prototype.test = function(ent)
     176{
     177    return ent.foundationProgress() !== undefined;
     178};
     179Engine.RegisterSerializablePrototype("FilterIsFoundation", FilterIsFoundation.prototype);
     180
     181function FilterByDistance(startPoint, dist)
     182{
     183    this.startPoint = startPoint;
     184    this.dist = dist;
     185    this.dynamicProperties = ["position"];
     186}
     187FilterByDistance.prototype.test = function(ent)
     188{
     189    if (ent.position() === undefined)
     190        return false;
     191    else
     192        return (SquareVectorDistance(this.startPoint, ent.position()) < this.dist*this.dist);
     193};
     194Engine.RegisterSerializablePrototype("FilterByDistance", FilterByDistance.prototype);
     195
     196// Distance filter with no auto updating, use with care
     197function FilterByStaticDistance(startPoint, dist)
     198{
     199    this.startPoint = startPoint;
     200    this.dist = dist;
     201    this.dynamicProperties = [];
     202}
     203FilterByStaticDistance.prototype.test = function(ent)
     204{
     205    if (!ent.position())
     206        return false;
     207    else
     208        return (SquareVectorDistance(this.startPoint, ent.position()) < this.dist*this.dist);
     209};
     210Engine.RegisterSerializablePrototype("FilterByStaticDistance", FilterByStaticDistance.prototype);
     211
     212function FilterIsDropsite(resourceType)
     213{
     214    this.resourceType = resourceType;
     215    this.dynamicProperties = [];
     216}
     217FilterIsDropsite.prototype.test = function(ent)
     218{
     219    return (ent.resourceDropsiteTypes() && ent.resourceDropsiteTypes().indexOf(this.resourceType) !== -1);
     220}
     221Engine.RegisterSerializablePrototype("FilterIsDropsite", FilterIsDropsite.prototype);
     222
     223function FilterByResource(resourceType)
     224{
     225    this.resourceType = resourceType;
     226    this.dynamicProperties = [/*"resourceSupplyAmount", */"owner", "metadata.inaccessible", "metadata.full"];
     227}
     228FilterByResource.prototype.test = function(ent)
     229{
     230    var type = ent.resourceSupplyType();
     231    if (!type)
     232        return false;
     233    var amount = ent.resourceSupplyMax();
     234    if (!amount)
     235        return false;
    44236   
    45     and: function(filter1, filter2){
    46         return {"func": function(ent){
    47             return filter1.func(ent) && filter2.func(ent);
    48         },
    49         "dynamicProperties": filter1.dynamicProperties.concat(filter2.dynamicProperties)};
    50     },
     237    // Skip targets that are too hard to hunt
     238    if (ent.isUnhuntable())
     239        return false;
    51240   
    52     or: function(filter1, filter2){
    53         return {"func" : function(ent){
    54             return filter1.func(ent) || filter2.func(ent);
    55         },
    56         "dynamicProperties": filter1.dynamicProperties.concat(filter2.dynamicProperties)};
    57     },
     241    // And don't go for the bloody fish! TODO: better accessibility checks
     242    if (ent.hasClass("SeaCreature"))
     243        return false;
    58244   
    59     not: function(filter){
    60         return {"func": function(ent){
    61             return !filter.func(ent);
    62         },
    63         "dynamicProperties": filter.dynamicProperties};
    64     },
     245    // Don't go for floating treasures since we won't be able to reach them and it kills the pathfinder.
     246    if (ent.templateName() == "other/special_treasure_shipwreck_debris" ||
     247            ent.templateName() == "other/special_treasure_shipwreck" )
     248        return false;
    65249   
    66     byOwner: function(owner){
    67         return {"func" : function(ent){
    68             return (ent.owner() === owner);
    69         },
    70         "dynamicProperties": ['owner']};
    71     },
     250    // Don't gather enemy farms
     251    if (!ent.isOwn() && ent.owner() !== 0)
     252        return false;
    72253   
    73     byNotOwner: function(owner){
    74         return {"func" : function(ent){
    75             return (ent.owner() !== owner);
    76         },
    77         "dynamicProperties": ['owner']};
    78     },
     254    if (ent.getMetadata("inaccessible") === true)
     255        return false;
    79256   
    80     byOwners: function(owners){
    81         return {"func" : function(ent){
    82             for (var i in owners){
    83                 if (ent.owner() == +owners[i]){
    84                     return true;
    85                 }
    86             }
    87             return false;
    88         },
    89         "dynamicProperties": ['owner']};
    90     },
     257    // too many workers trying to gather from this resource
     258    if (ent.getMetadata("full") === true)
     259        return false;
    91260   
    92     byTrainingQueue: function(){
    93         return {"func" : function(ent){
    94             return ent.trainingQueue();
    95         },
    96         "dynamicProperties": ['trainingQueue']};
    97     },
    98    
    99     isSoldier: function(){
    100         return {"func" : function(ent){
    101             return Filters.byClassesOr(["CitizenSoldier", "Super"])(ent);
    102         },
    103         "dynamicProperties": []};
    104     },
    105    
    106     isIdle: function(){
    107         return {"func" : function(ent){
    108             return ent.isIdle();
    109         },
    110         "dynamicProperties": ['idle']};
    111     },
    112    
    113     isFoundation: function(){
    114         return {"func": function(ent){
    115             return ent.foundationProgress() !== undefined;
    116         },
    117         "dynamicProperties": []};
    118     },
    119    
    120     byDistance: function(startPoint, dist){
    121         return {"func": function(ent){
    122             if (ent.position() === undefined){
    123                 return false;
    124             }else{
    125                 return (SquareVectorDistance(startPoint, ent.position()) < dist*dist);
    126             }
    127         },
    128         "dynamicProperties": ['position']};
    129     },
    130    
    131     // Distance filter with no auto updating, use with care
    132     byStaticDistance: function(startPoint, dist){
    133         return {"func": function(ent){
    134             if (!ent.position()){
    135                 return false;
    136             }else{
    137                 return (SquareVectorDistance(startPoint, ent.position()) < dist*dist);
    138             }
    139         },
    140         "dynamicProperties": []};
    141     },
    142    
    143     isDropsite: function(resourceType){
    144         return {"func": function(ent){
    145             return (ent.resourceDropsiteTypes() && ent.resourceDropsiteTypes().indexOf(resourceType) !== -1);
    146         },
    147         "dynamicProperties": []};
    148     },
    149    
    150     byResource: function(resourceType){
    151         return {"func" : function(ent){
    152             var type = ent.resourceSupplyType();
    153             if (!type)
    154                 return false;
    155             var amount = ent.resourceSupplyMax();
    156             if (!amount)
    157                 return false;
    158            
    159             // Skip targets that are too hard to hunt
    160             if (ent.isUnhuntable())
    161                 return false;
    162            
    163             // And don't go for the bloody fish! TODO: better accessibility checks
    164             if (ent.hasClass("SeaCreature")){
    165                 return false;
    166             }
    167            
    168             // Don't go for floating treasures since we won't be able to reach them and it kills the pathfinder.
    169             if (ent.templateName() == "other/special_treasure_shipwreck_debris" ||
    170                     ent.templateName() == "other/special_treasure_shipwreck" ){
    171                 return false;
    172             }
    173            
    174             // Don't gather enemy farms
    175             if (!ent.isOwn() && ent.owner() !== 0){
    176                 return false;
    177             }
    178            
    179             if (ent.getMetadata("inaccessible") === true){
    180                 return false;
    181             }
    182            
    183             // too many workers trying to gather from this resource
    184             if (ent.getMetadata("full") === true){
    185                 return false;
    186             }
    187            
    188             if (type.generic == "treasure"){
    189                 return (resourceType == type.specific);
    190             } else {
    191                 return (resourceType == type.generic);
    192             }
    193         },
    194         "dynamicProperties": [/*"resourceSupplyAmount", */"owner", "metadata.inaccessible", "metadata.full"]};
    195     }
     261    if (type.generic == "treasure")
     262        return (this.resourceType == type.specific);
     263    else
     264        return (this.resourceType == type.generic);
    196265};
     266Engine.RegisterSerializablePrototype("FilterByResource", FilterByResource.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/attackMoveToCC.js

     
    3838    var targets = militaryManager.getEnemyBuildings(gameState,"ConquestCritical");
    3939    // If there are no critical structures, attack anything else that's critical
    4040    if (targets.length == 0) {
    41         targets = gameState.entities.filter(function(ent) {
    42             return (gameState.isEntityEnemy(ent) && ent.hasClass("ConquestCritical") && ent.owner() !== 0 && ent.position());
    43         });
     41        targets = gameState.entities.filter(new FilterEnemyConquestCritical(gameState));
    4442    }
    4543    // If there's nothing, attack anything else that's less critical
    4644    if (targets.length == 0) {
     
    203201    this.previousHealth = totalHealth;
    204202};
    205203
     204Engine.RegisterSerializablePrototype("AttackMoveToCC", AttackMoveToCC.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/attackMoveToLocation.js

     
     1// Default target finder aims for conquest critical targets
     2function DefaultTargetFinder()
     3{
     4}
     5DefaultTargetFinder.prototype.findTargets = function(gameState, militaryManager)
     6{
     7    // Find the critical enemy buildings we could attack
     8    var targets = militaryManager.getEnemyBuildings(gameState,"ConquestCritical");
     9    // If there are no critical structures, attack anything else that's critical
     10    if (targets.length == 0) {
     11        targets = gameState.entities.filter(new FilterEnemyConquestCritical(gameState));
     12    }
     13    // If there's nothing, attack anything else that's less critical
     14    if (targets.length == 0) {
     15        targets = militaryManager.getEnemyBuildings(gameState,"Town");
     16    }
     17    if (targets.length == 0) {
     18        targets = militaryManager.getEnemyBuildings(gameState,"Village");
     19    }
     20    return targets;
     21};
     22
    123function AttackMoveToLocation(gameState, militaryManager, minAttackSize, maxAttackSize, targetFinder){
    224    this.minAttackSize = minAttackSize || Config.attack.minAttackSize;
    325    this.maxAttackSize = maxAttackSize || Config.attack.maxAttackSize;
     
    628    this.previousTime = 0;
    729    this.state = "unexecuted";
    830   
    9     this.targetFinder = targetFinder || this.defaultTargetFinder;
     31    this.targetFinder = targetFinder || new DefaultTargetFinder();
    1032   
    1133    this.healthRecord = [];
    1234};
     
    2951            || availableCount >= this.maxAttackSize);
    3052};
    3153
    32 // Default target finder aims for conquest critical targets
    33 AttackMoveToLocation.prototype.defaultTargetFinder = function(gameState, militaryManager){
    34     // Find the critical enemy buildings we could attack
    35     var targets = militaryManager.getEnemyBuildings(gameState,"ConquestCritical");
    36     // If there are no critical structures, attack anything else that's critical
    37     if (targets.length == 0) {
    38         targets = gameState.entities.filter(function(ent) {
    39             return (gameState.isEntityEnemy(ent) && ent.hasClass("ConquestCritical") && ent.owner() !== 0 && ent.position());
    40         });
    41     }
    42     // If there's nothing, attack anything else that's less critical
    43     if (targets.length == 0) {
    44         targets = militaryManager.getEnemyBuildings(gameState,"Town");
    45     }
    46     if (targets.length == 0) {
    47         targets = militaryManager.getEnemyBuildings(gameState,"Village");
    48     }
    49     return targets;
    50 };
    51 
    5254// Executes the attack plan, after this is executed the update function will be run every turn
    5355AttackMoveToLocation.prototype.execute = function(gameState, militaryManager){
    5456    var availableCount = militaryManager.countAvailableUnits();
     
    5759   
    5860    var pending = EntityCollectionFromIds(gameState, this.idList);
    5961   
    60     var targets = this.targetFinder(gameState, militaryManager);
     62    var targets = this.targetFinder.findTargets(gameState, militaryManager);
    6163   
    6264    if (targets.length === 0){
    63         targets = this.defaultTargetFinder(gameState, militaryManager);
     65        targets = new DefaultTargetFinder().findTargets(gameState, militaryManager);
    6466    }
    6567   
    6668    // If we have a target, move to it
     
    236238    this.previousHealth = totalHealth;
    237239};
    238240
     241Engine.RegisterSerializablePrototype("AttackMoveToLocation", AttackMoveToLocation.prototype);
     242Engine.RegisterSerializablePrototype("DefaultTargetFinder", DefaultTargetFinder.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/config.js

     
    1 var baseConfig = {
     1var Config = {
    22    "attack" : {
    33        "minAttackSize" : 20, // attackMoveToLocation
    44        "maxAttackSize" : 60, // attackMoveToLocation
     
    5555   
    5656    "debug" : false
    5757};
    58 
    59 var Config = {
    60         "debug": false
    61 };
    62 
    63 Config.__proto__ = baseConfig;
    64  No newline at end of file
  • binaries/data/mods/public/simulation/ai/qbot/defence.js

     
    4141    if (numAttackers * this.DEFENCE_RATIO <= numAssignedDefenders){
    4242        militaryManager.unassignUnits(unassignedDefenders);
    4343       
    44         var CCs = gameState.getOwnEntities().filter(Filters.byClass("CivCentre"));
     44        var CCs = gameState.getOwnEntities().filter(new FilterByClass("CivCentre"));
    4545       
    4646        for (var i in unassignedDefenders){
    4747            var pos = this.defenders[unassignedDefenders[i]].position();
     
    6262    // Check to see if we need to recruit more defenders
    6363    if (numAttackers * this.DEFENCE_RATIO > numDefenders){
    6464        var numNeeded = Math.ceil(numAttackers * this.DEFENCE_RATIO - numDefenders);
    65         var numIdleAvailable = militaryManager.countAvailableUnits(Filters.isIdle());
     65        var numIdleAvailable = militaryManager.countAvailableUnits(new FilterIsIdle());
    6666       
    6767        if (numIdleAvailable > numNeeded){
    68             var newUnits = militaryManager.getAvailableUnits(numNeeded, Filters.isIdle());
     68            var newUnits = militaryManager.getAvailableUnits(numNeeded, new FilterIsIdle());
    6969            for (var i in newUnits){
    7070                var ent = gameState.getEntityById(newUnits[i]);
    7171            }
     
    142142// Returns an entity collection of key buildings which should be defended.
    143143// Currently just returns civ centres
    144144Defence.prototype.getKeyBuildings = function(gameState){
    145     return gameState.getOwnEntities().filter(Filters.byClass("CivCentre"));
     145    return gameState.getOwnEntities().filter(new FilterByClass("CivCentre"));
    146146};
    147147
    148148/*
     
    276276        }
    277277    }
    278278};
     279
     280Engine.RegisterSerializablePrototype("Defence", Defence.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/economy.js

     
    4343    var numGatherers = {};
    4444    for ( var type in this.gatherWeights){
    4545        numGatherers[type] = gameState.updatingCollection("workers-gathering-" + type,
    46                 Filters.byMetadata("gather-type", type), gameState.getOwnEntitiesByRole("worker")).length;
     46                new FilterByMetadata("gather-type", type), gameState.getOwnEntitiesByRole("worker")).length;
    4747    }
    4848
    4949    var types = Object.keys(this.gatherWeights);
     
    111111    var self = this;
    112112
    113113    // Search for idle workers, and tell them to gather resources based on demand
    114     var filter = Filters.or(Filters.isIdle(), Filters.byMetadata("subrole", "idle"));
     114    var filter = new FilterOr(new FilterIsIdle(), new FilterByMetadata("subrole", "idle"));
    115115    var idleWorkers = gameState.updatingCollection("idle-workers", filter, gameState.getOwnEntitiesByRole("worker"));
    116116   
    117117    if (idleWorkers.length) {
     
    133133
    134134EconomyManager.prototype.workersBySubrole = function(gameState, subrole) {
    135135    var workers = gameState.getOwnEntitiesByRole("worker");
    136     return gameState.updatingCollection("subrole-" + subrole, Filters.byMetadata("subrole", subrole), workers);
     136    return gameState.updatingCollection("subrole-" + subrole, new FilterByMetadata("subrole", subrole), workers);
    137137};
    138138
    139139EconomyManager.prototype.assignToFoundations = function(gameState) {
     
    163163
    164164    var target = foundations.toEntityArray()[0];
    165165
    166     var nonBuilderWorkers = workers.filter(function(ent) {
    167         // check position so garrisoned units aren't tasked
    168         return (ent.getMetadata("subrole") !== "builder" && ent.position() !== undefined);
    169     });
     166    var nonBuilderWorkers = workers.filter(new FilterNonBuilders());
    170167
    171168    var nearestNonBuilders = nonBuilderWorkers.filterNearest(target.position(), extraNeeded);
    172169
     
    184181   
    185182    var numFood = 0;
    186183   
    187     gameState.updatingCollection("active-dropsite-food", Filters.byMetadata("active-dropsite-food", true),
     184    gameState.updatingCollection("active-dropsite-food", new FilterByMetadata("active-dropsite-food", true),
    188185            gameState.getOwnDropsites("food")).forEach(function (dropsite){
    189186        numFood += dropsite.getMetadata("nearby-resources-food").length;
    190187    });
     
    339336       
    340337        gameState.getOwnDropsites(resource).forEach(function(ent) {
    341338            if (ent.getMetadata("nearby-resources-" + resource) === undefined){
    342                 var filterPos = Filters.byStaticDistance(ent.position(), radius);
     339                var filterPos = new FilterByStaticDistance(ent.position(), radius);
    343340               
    344341                var collection = gameState.getResourceSupplies(resource).filter(filterPos);
    345342                collection.registerUpdates();
     
    411408                if (this.checkResourceConcentrations(gameState, resource) < this.dropsiteNumbers[resource]){
    412409                    var spot = this.getBestResourceBuildSpot(gameState, resource);
    413410                   
    414                     var myCivCentres = gameState.getOwnEntities().filter(function(ent) {
    415                         if (!ent.hasClass("CivCentre") || ent.position() === undefined){
    416                             return false;
    417                         }
    418                         var dx = (spot[0]-ent.position()[0]);
    419                         var dy = (spot[1]-ent.position()[1]);
    420                         var dist2 = dx*dx + dy*dy;
    421                         return (ent.hasClass("CivCentre") && dist2 < 180*180);
    422                     });
     411                    var myCivCentres = gameState.getOwnEntities().filter(new FilterNearbyCivCenters(spot));
    423412                   
    424413                    if (myCivCentres.length === 0){
    425414                        queues.economicBuilding.addItem(new BuildingConstructionPlan(gameState, "structures/{civ}_civil_centre", spot));
     
    521510    });
    522511   
    523512    // Gatherer count updates for non-workers
    524     var filter = Filters.and(Filters.not(Filters.byMetadata("worker-object", undefined)),
    525                              Filters.not(Filters.byMetadata("role", "worker")));
     513    var filter = new FilterAnd(new FilterNot(new FilterByMetadata("worker-object", undefined)),
     514                             new FilterNot(new FilterByMetadata("role", "worker")));
    526515    gameState.updatingCollection("reassigned-workers", filter, gameState.getOwnEntities()).forEach(function(ent){
    527516        ent.getMetadata("worker-object").updateGathererCounts(gameState);
    528517    });
     
    541530
    542531    Engine.ProfileStop();
    543532};
     533
     534Engine.RegisterSerializablePrototype("EconomyManager", EconomyManager.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/filters.js

     
     1function FilterEnemyConquestCritical(gameState)
     2{
     3    this.gameState = gameState;
     4    this.dynamicProperties = [];
     5}
     6FilterEnemyConquestCritical.prototype.test = function(ent)
     7{
     8    return (this.gameState.isEntityEnemy(ent) && ent.hasClass("ConquestCritical") && ent.owner() !== 0 && ent.position());
     9};
     10Engine.RegisterSerializablePrototype("FilterEnemyConquestCritical", FilterEnemyConquestCritical.prototype);
     11
     12function FilterNonBuilders()
     13{
     14    this.dynamicProperties = [];
     15}
     16FilterNonBuilders.prototype.test = function(ent)
     17{
     18    // check position so garrisoned units aren't tasked
     19    return (ent.getMetadata("subrole") !== "builder" && ent.position() !== undefined);
     20};
     21Engine.RegisterSerializablePrototype("FilterNonBuilders", FilterNonBuilders.prototype);
     22
     23function FilterNearbyCivCenters(spot)
     24{
     25    this.spot = spot;
     26    this.dynamicProperties = [];
     27}
     28FilterNearbyCivCenters.prototype.test = function(ent)
     29{
     30    if (!ent.hasClass("CivCentre") || ent.position() === undefined)
     31        return false;
     32
     33    var dx = (this.spot[0]-ent.position()[0]);
     34    var dy = (this.spot[1]-ent.position()[1]);
     35    var dist2 = dx*dx + dy*dy;
     36    return (ent.hasClass("CivCentre") && dist2 < 180*180);
     37};
     38Engine.RegisterSerializablePrototype("FilterNearbyCivCenters", FilterNearbyCivCenters.prototype);
     39
     40function FilterAvailableTrainers(template)
     41{
     42    this.template = template;
     43    this.dynamicProperties = [];
     44}
     45FilterAvailableTrainers.prototype.test = function(ent)
     46{
     47    var maxQueueLength = 2; // avoid tying up resources in giant training queues
     48    var trainable = ent.trainableEntities();
     49    if (!trainable || trainable.indexOf(this.template) == -1)
     50        return false;
     51
     52    var queue = ent.trainingQueue();
     53    if (queue)
     54        if (queue.length >= maxQueueLength)
     55            return false;
     56
     57    return true;
     58};
     59Engine.RegisterSerializablePrototype("FilterAvailableTrainers", FilterAvailableTrainers.prototype);
     60
     61function FilterAvailableBuilders(template)
     62{
     63    this.template = template;
     64    this.dynamicProperties = [];
     65}
     66FilterAvailableBuilders.prototype.test = function(ent)
     67{
     68    var buildable = ent.buildableEntities();
     69    if (!buildable || buildable.indexOf(this.template) == -1)
     70        return false;
     71
     72    return true;
     73};
     74Engine.RegisterSerializablePrototype("FilterAvailableBuilders", FilterAvailableBuilders.prototype);
     75
     76function FilterEnemyStructuresByClass(gameState, cls)
     77{
     78    this.gameState = gameState;
     79    this.cls = cls;
     80    this.dynamicProperties = [];
     81}
     82FilterEnemyStructuresByClass.prototype.test = function(ent)
     83{
     84    return (this.gameState.isEntityEnemy(ent) && ent.hasClass("Structure") && ent.hasClass(this.cls) && ent.owner() !== 0  && ent.position());
     85};
     86Engine.RegisterSerializablePrototype("FilterEnemyStructuresByClass", FilterEnemyStructuresByClass.prototype);
     87
  • binaries/data/mods/public/simulation/ai/qbot/gamestate.js

     
    133133
    134134GameState.prototype.getOwnEntities = function() {
    135135    if (!this.store.ownEntities){
    136         this.store.ownEntities = this.getEntities().filter(Filters.byOwner(this.player));
     136        this.store.ownEntities = this.getEntities().filter(new FilterByOwner(this.player));
    137137        this.store.ownEntities.registerUpdates();
    138138    }
    139139   
     
    155155        }
    156156    }
    157157    if (diplomacyChange || !this.store.enemyEntities){
    158         var filter = Filters.byOwners(enemies);
     158        var filter = new FilterByOwners(enemies);
    159159        this.store.enemyEntities = this.getEntities().filter(filter);
    160160        this.store.enemyEntities.registerUpdates();
    161161        this.store.enemies = enemies;
     
    179179
    180180GameState.prototype.getOwnEntitiesByMetadata = function(key, value){
    181181    if (!this.store[key + "-" + value]){
    182         var filter = Filters.byMetadata(key, value);
     182        var filter = new FilterByMetadata(key, value);
    183183        this.store[key + "-" + value] = this.getOwnEntities().filter(filter);
    184184        this.store[key + "-" + value].registerUpdates();
    185185    }
     
    193193
    194194// TODO: fix this so it picks up not in use training stuff
    195195GameState.prototype.getOwnTrainingFacilities = function(){
    196     return this.updatingCollection("own-training-facilities", Filters.byTrainingQueue(), this.getOwnEntities());
     196    return this.updatingCollection("own-training-facilities", new FilterByTrainingQueue(), this.getOwnEntities());
    197197};
    198198
    199199GameState.prototype.getOwnEntitiesByType = function(type){
    200     var filter = Filters.byType(type);
    201     return this.updatingCollection("own-by-type-" + type, filter, this.getOwnEntities());
     200    return this.updatingCollection("own-by-type-" + type, new FilterByType(type), this.getOwnEntities());
    202201};
    203202
    204203GameState.prototype.countEntitiesByType = function(type) {
     
    259258 * already too busy.
    260259 */
    261260GameState.prototype.findTrainers = function(template) {
    262     var maxQueueLength = 2; // avoid tying up resources in giant training queues
    263    
    264     return this.getOwnTrainingFacilities().filter(function(ent) {
    265 
    266         var trainable = ent.trainableEntities();
    267         if (!trainable || trainable.indexOf(template) == -1)
    268             return false;
    269 
    270         var queue = ent.trainingQueue();
    271         if (queue) {
    272             if (queue.length >= maxQueueLength)
    273                 return false;
    274         }
    275 
    276         return true;
    277     });
     261    return this.getOwnTrainingFacilities().filter(new FilterAvailableTrainers(template));
    278262};
    279263
    280264/**
    281265 * Find units that are capable of constructing the given building type.
    282266 */
    283267GameState.prototype.findBuilders = function(template) {
    284     return this.getOwnEntities().filter(function(ent) {
    285 
    286         var buildable = ent.buildableEntities();
    287         if (!buildable || buildable.indexOf(template) == -1)
    288             return false;
    289 
    290         return true;
    291     });
     268    return this.getOwnEntities().filter(new FilterAvailableBuilders(template));
    292269};
    293270
    294271GameState.prototype.getOwnFoundations = function() {
    295     return this.updatingCollection("ownFoundations", Filters.isFoundation(), this.getOwnEntities());
     272    return this.updatingCollection("ownFoundations", new FilterIsFoundation(), this.getOwnEntities());
    296273};
    297274
    298275GameState.prototype.getOwnDropsites = function(resource){
    299     return this.updatingCollection("dropsite-own-" + resource, Filters.isDropsite(resource), this.getOwnEntities());
     276    return this.updatingCollection("dropsite-own-" + resource, new FilterIsDropsite(resource), this.getOwnEntities());
    300277};
    301278
    302279GameState.prototype.getResourceSupplies = function(resource){
    303     return this.updatingCollection("resource-" + resource, Filters.byResource(resource), this.getEntities());
     280    return this.updatingCollection("resource-" + resource, new FilterByResource(resource), this.getEntities());
    304281};
    305282
    306283GameState.prototype.getEntityLimits = function() {
     
    321298    else
    322299        return (this.playerData.entityCounts[category] >= this.playerData.entityLimits[category]);
    323300};
     301
     302Engine.RegisterSerializablePrototype("GameState", GameState.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/housing.js

     
    2727
    2828    Engine.ProfileStop();
    2929};
     30
     31Engine.RegisterSerializablePrototype("HousingManager", HousingManager.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/map-module.js

     
    261261    threshold = threshold ? threshold : 256;
    262262    Engine.DumpImage(name, this.map, this.width, this.height, threshold);
    263263};
     264
     265Engine.RegisterSerializablePrototype("Map", Map.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/military.js

     
    88
    99var MilitaryAttackManager = function() {
    1010    // these use the structure soldiers[unitId] = true|false to register the units
    11     this.attackManagers = [AttackMoveToLocation];
     11    this.attackManagers = ["AttackMoveToLocation"];
    1212    this.availableAttacks = [];
    1313    this.currentAttacks = [];
    1414   
     
    4949        this.bFort[i] = gameState.applyCiv(this.bFort[i]);
    5050    }
    5151   
    52     this.getEconomicTargets = function(gameState, militaryManager){
    53         return militaryManager.getEnemyBuildings(gameState, "Economic");
    54     };
     52    // this.getEconomicTargets = function(gameState, militaryManager){
     53        // return militaryManager.getEnemyBuildings(gameState, "Economic");
     54    // };
    5555    // TODO: figure out how to make this generic
    5656    for (var i in this.attackManagers){
    57         this.availableAttacks[i] = new this.attackManagers[i](gameState, this);
     57        this.availableAttacks[i] = new global[this.attackManagers[i]](gameState, this);
    5858    }
    5959   
    6060    var enemies = gameState.getEnemyEntities();
    61     var filter = Filters.byClassesOr(["CitizenSoldier", "Champion", "Hero", "Siege"]);
     61    var filter = new FilterByClassesOr(["CitizenSoldier", "Champion", "Hero", "Siege"]);
    6262    this.enemySoldiers = enemies.filter(filter); // TODO: cope with diplomacy changes
    6363    this.enemySoldiers.registerUpdates();
    6464};
     
    141141};
    142142
    143143// return count of enemy buildings for a given building class
    144 MilitaryAttackManager.prototype.getEnemyBuildings = function(gameState,cls) {
    145     var targets = gameState.entities.filter(function(ent) {
    146             return (gameState.isEntityEnemy(ent) && ent.hasClass("Structure") && ent.hasClass(cls) && ent.owner() !== 0  && ent.position());
    147         });
     144MilitaryAttackManager.prototype.getEnemyBuildings = function(gameState, cls) {
     145    var targets = gameState.entities.filter(new FilterEnemyStructuresByClass(gameState, cls));
    148146    return targets;
    149147};
    150148
     
    435433            this.currentAttacks.push(this.availableAttacks[i]);
    436434            //debug("Attacking!");
    437435        }
    438         this.availableAttacks.splice(i, 1, new this.attackManagers[i](gameState, this));
     436        this.availableAttacks.splice(i, 1, new global[this.attackManagers[i]](gameState, this));
    439437    }
    440438    Engine.ProfileStop();
    441439   
     
    457455   
    458456    Engine.ProfileStop();
    459457};
     458
     459Engine.RegisterSerializablePrototype("MilitaryAttackManager", MilitaryAttackManager.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/plan-building.js

     
    122122        "angle" : angle
    123123    };
    124124};
     125
     126Engine.RegisterSerializablePrototype("BuildingConstructionPlan", BuildingConstructionPlan.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/plan-training.js

     
    5353
    5454UnitTrainingPlan.prototype.addItem = function(){
    5555    this.number += 1;
    56 };
    57  No newline at end of file
     56};
     57
     58Engine.RegisterSerializablePrototype("UnitTrainingPlan", UnitTrainingPlan.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/qbot.js

     
    5050       
    5151        this.firstTime = false;
    5252       
    53         var myKeyEntities = gameState.getOwnEntities().filter(function(ent) {
    54             return ent.hasClass("CivCentre");
    55         });
     53        var myKeyEntities = gameState.getOwnEntities().filter(new FilterByClass("CivCentre"));
    5654       
    5755        if (myKeyEntities.length == 0){
    5856            myKeyEntities = gameState.getOwnEntities();
    5957        }
    6058       
    6159       
    62         var filter = Filters.byClass("CivCentre");
     60        var filter = new FilterByClass("CivCentre");
    6361        var enemyKeyEntities = gameState.getEnemyEntities().filter(filter);
    6462       
    6563        if (enemyKeyEntities.length == 0){
     
    146144    Engine.ProfileStop();
    147145};
    148146
    149 // TODO: Remove override when the whole AI state is serialised
    150 QBotAI.prototype.Deserialize = function(data)
    151 {
    152     BaseAI.prototype.Deserialize.call(this, data);
    153 };
    154 
    155 // Override the default serializer
    156 QBotAI.prototype.Serialize = function()
    157 {
    158     var ret = BaseAI.prototype.Serialize.call(this);
    159     ret._entityMetadata = {};
    160     return ret;
    161 };
    162 
    163147function debug(output){
    164148    if (Config.debug){
    165149        if (typeof output === "string"){
     
    178162        descendant.prototype[m] = parent.prototype[m];
    179163    }
    180164}
     165
     166Engine.RegisterSerializablePrototype("QBotAI", QBotAI.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/queue-manager.js

     
    199199   
    200200    for (var i in this.priorities){
    201201        if (!(this.priorities[i] > 0)){
     202            warn("QueueManager received bad priorities, please report this error: " + uneval(this.priorities));
    202203            this.priorities[i] = 1;  // TODO: make the Queue Manager not die when priorities are zero.
    203             warn("QueueManager received bad priorities, please report this error: " + uneval(this.priorities));
    204204        }
    205205    }
    206206   
     
    300300    Engine.ProfileStop();
    301301    Engine.ProfileStop();
    302302};
     303
     304Engine.RegisterSerializablePrototype("QueueManager", QueueManager.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/queue.js

     
    111111        }
    112112    }
    113113    return count;
    114 };
    115  No newline at end of file
     114};
     115
     116Engine.RegisterSerializablePrototype("Queue", Queue.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/resources.js

     
    6464    sum += this.population * 50; // based on typical unit costs
    6565    return sum;
    6666};
     67
     68Engine.RegisterSerializablePrototype("Resources", Resources.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/terrain-analysis.js

     
    347347        newStack = [];
    348348    }
    349349    return count;
    350 };
    351  No newline at end of file
     350};
     351
     352Engine.RegisterSerializablePrototype("TerrainAnalysis", TerrainAnalysis.prototype);
     353Engine.RegisterSerializablePrototype("PathFinder", PathFinder.prototype);
     354Engine.RegisterSerializablePrototype("Accessibility", Accessibility.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/timer.js

     
    99
    1010
    1111//-EmjeR-// Timer class //
    12 var Timer = function() {
    13     ///Private array.
    14     var alarmList = [];
     12var Timer = function()
     13{
     14    this.alarmList = [];
     15}
     16
     17///Private methods
     18Timer.prototype.num_alarms = function()
     19{
     20    return this.alarmList.length;
     21};
     22
     23Timer.prototype.get_alarm = function(id)
     24{
     25    return this.alarmList[id];
     26};
    1527   
    16     ///Private methods
    17     function num_alarms() {
    18         return alarmList.length;
    19     };
     28Timer.prototype.add_alarm = function(index, alarm)
     29{
     30    this.alarmList[index] = alarm;
     31};
    2032   
    21     function get_alarm(id) {
    22         return alarmList[id];
    23     };
     33Timer.prototype.delete_alarm = function(id)
     34{
     35    // Set the array element to undefined
     36    delete this.alarmList[id];
     37};
    2438   
    25     function add_alarm(index, alarm) {
    26         alarmList[index] = alarm;
    27     };
     39///Privileged methods
     40// Add an new alarm to the list
     41Timer.prototype.setTimer = function(gameState, interval, delay, repeat)
     42{
     43    delay = delay || 0;
     44    repeat = repeat || -1;
    2845   
    29     function delete_alarm(id) {
    30         // Set the array element to undefined
    31         delete alarmList[id];
    32     };
     46    var index = this.num_alarms();
    3347   
    34     ///Privileged methods
    35     // Add an new alarm to the list
    36     this.setTimer = function(gameState, interval, delay, repeat) {
    37         delay = delay || 0;
    38         repeat = repeat || -1;
    39        
    40         var index = num_alarms();
    41        
    42         //Add a new alarm to the list
    43         add_alarm(index, new alarm(gameState, index, interval, delay, repeat));
    44         return index;
    45     };
     48    //Add a new alarm to the list
     49    this.add_alarm(index, new Alarm(gameState, index, interval, delay, repeat));
     50    return index;
     51};
    4652   
     53// Check if a alarm has reached its interval.
     54Timer.prototype.checkTimer = function(gameState,id)
     55{
     56    var alarm = this.get_alarm(id);
     57    if (alarm === undefined)
     58        return false;
     59    if (!alarm.active)
     60        return false;
     61    var time = gameState.getTimeElapsed();
     62    var alarmState = false;
    4763   
    48     // Check if a alarm has reached its interval.
    49     this.checkTimer = function(gameState,id) {
    50         var alarm = get_alarm(id);
    51         if (alarm === undefined)
    52             return false;
    53         if (!alarm.active)
    54             return false;
    55         var time = gameState.getTimeElapsed();
    56         var alarmState = false;
    57        
    58         // If repeat forever (repeat is -1). Or if the alarm has rung less times than repeat.
    59         if (alarm.repeat < 0 || alarm.counter < alarm.repeat) {
    60             var time_diffrence = time - alarm.start_time - alarm.delay - alarm.interval * alarm.counter;
    61             if (time_diffrence > alarm.interval) {
    62                 alarmState = true;
    63                 alarm.counter++;
    64             }
     64    // If repeat forever (repeat is -1). Or if the alarm has rung less times than repeat.
     65    if (alarm.repeat < 0 || alarm.counter < alarm.repeat) {
     66        var time_diffrence = time - alarm.start_time - alarm.delay - alarm.interval * alarm.counter;
     67        if (time_diffrence > alarm.interval) {
     68            alarmState = true;
     69            alarm.counter++;
    6570        }
    66        
    67         // Check if the alarm has rung 'alarm.repeat' times if so, delete the alarm.
    68         if (alarm.counter >= alarm.repeat && alarm.repeat != -1) {
    69             this.clearTimer(id);
    70         }
    71        
    72         return alarmState;
    73     };
     71    }
    7472   
    75     // Remove an alarm from the list.
    76     this.clearTimer = function(id) {
    77         delete_alarm(id);
    78     };
     73    // Check if the alarm has rung 'alarm.repeat' times if so, delete the alarm.
     74    if (alarm.counter >= alarm.repeat && alarm.repeat != -1) {
     75        this.clearTimer(id);
     76    }
    7977   
    80     // Activate a deactivated alarm.
    81     this.activateTimer = function(id) {
    82         var alarm = get_alarm(id);
    83         alarm.active = true;
    84     };
     78    return alarmState;
     79};
    8580   
    86     // Deactivate an active alarm but don't delete it.
    87     this.deactivateTimer = function(id) {
    88         var alarm = get_alarm(id);
    89         alarm.active = false;
    90     };
     81// Remove an alarm from the list.
     82Timer.prototype.clearTimer = function(id)
     83{
     84    this.delete_alarm(id);
    9185};
     86   
     87// Activate a deactivated alarm.
     88Timer.prototype.activateTimer = function(id)
     89{
     90    var alarm = this.get_alarm(id);
     91    alarm.active = true;
     92};
     93   
     94// Deactivate an active alarm but don't delete it.
     95Timer.prototype.deactivateTimer = function(id) {
     96    var alarm = this.get_alarm(id);
     97    alarm.active = false;
     98};
    9299
    93 
    94100//-EmjeR-// Alarm class //
    95 function alarm(gameState, id, interval, delay, repeat) {
     101function Alarm(gameState, id, interval, delay, repeat)
     102{
    96103    this.id = id;
    97104    this.interval = interval;
    98105    this.delay = delay;
     
    102109    this.active = true;
    103110    this.counter = 0;
    104111};
     112
     113Engine.RegisterSerializablePrototype("Timer", Timer.prototype);
     114Engine.RegisterSerializablePrototype("Alarm", Alarm.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/walkToCC.js

     
    3333    var targets = militaryManager.getEnemyBuildings(gameState,"ConquestCritical");
    3434    // If there are no critical structures, attack anything else that's critical
    3535    if (targets.length == 0) {
    36         targets = gameState.entities.filter(function(ent) {
    37             return (gameState.isEntityEnemy(ent) && ent.hasClass("ConquestCritical") && ent.owner() !== 0);
    38         });
     36        targets = gameState.entities.filter(new FilterEnemyConquestCritical(gameState));
    3937    }
    4038    // If there's nothing, attack anything else that's less critical
    4139    if (targets.length == 0) {
     
    8280    for (var i in removeList){
    8381        this.idList.splice(this.idList.indexOf(removeList[i]),1);
    8482    }
    85 };
    86  No newline at end of file
     83};
     84
     85Engine.RegisterSerializablePrototype("WalkToCC", WalkToCC.prototype);
  • binaries/data/mods/public/simulation/ai/qbot/worker.js

     
    128128    var nearestResources = undefined;
    129129    var nearestDropsite = undefined;
    130130   
    131     gameState.updatingCollection("active-dropsite-" + resource, Filters.byMetadata("active-dropsite-" + resource, true),
     131    gameState.updatingCollection("active-dropsite-" + resource, new FilterByMetadata("active-dropsite-" + resource, true),
    132132            gameState.getOwnDropsites(resource)).forEach(function (dropsite){
    133133        if (dropsite.position()){
    134134            var dist = VectorDistance(ent.position(), dropsite.position());
     
    248248    }else{
    249249        return type.generic;
    250250    }
    251 };
    252  No newline at end of file
     251};
     252
     253Engine.RegisterSerializablePrototype("Worker", Worker.prototype);