1
0
forked from 0ad/0ad

Allow for unification in identity class matching + add the opportunity to combine with AND and OR. Fixes #2612

This was SVN commit r15294.
This commit is contained in:
sanderd17 2014-06-05 09:39:36 +00:00
parent cbfbc72d36
commit a4f2c2ac90
9 changed files with 57 additions and 51 deletions

View File

@ -57,17 +57,5 @@ function GetTechModifiedProperty(currentTechModifications, entityTemplateData, p
*/
function DoesModificationApply(modification, classes)
{
// See if any of the lists of classes matches this entity
for (var j in modification.affects)
{
var hasAllClasses = true;
// Check each class in affects is present for the entity
for (var k in modification.affects[j])
hasAllClasses = hasAllClasses && (classes.indexOf(modification.affects[j][k]) !== -1);
if (hasAllClasses)
return true;
}
return false;
return MatchesClassList(classes, modification.affects);
}

View File

@ -26,4 +26,40 @@ function GetVisibleIdentityClasses(template)
return [];
}
/**
* Check if the classes given in the identity template
* match a list of classes
* @param classes List of the classes to check against
* @param match Either a string in the form
* "Class1 Class2+Class3"
* where spaces are handled as OR and '+'-signs as AND,
* Or a list in the form
* [["Class1"], ["Class2", "Class3"]]
* where the outer list is combined as OR, and the inner lists are AND-ed
* Or a hybrid format containing a list of strings, where the list is
* combined as OR, and the strings are split by space and '+' and AND-ed
*
* @return undefined if there are no classes or no match object
* true if the the logical combination in the match object matches the classes
* false otherwise
*/
function MatchesClassList(classes, match)
{
if (!match || !classes)
return undefined;
// transform the string to an array
if (typeof match == "string")
match = match.split(/\s+/);
for (var sublist of match)
{
// if the elements are still strings, split them by space or by '+'
if (typeof sublist == "string")
sublist = sublist.split(/[+\s]+/);
if (sublist.every(function(c) { return classes.indexOf(c) != -1; }))
return true;
}
return false;
}

View File

@ -367,12 +367,8 @@ function getActionInfo(action, target)
extraCount += entState.garrisonHolder.garrisonedEntitiesCount;
if (targetState.garrisonHolder.garrisonedEntitiesCount + extraCount >= targetState.garrisonHolder.capacity)
tooltip = "[color=\"orange\"]" + tooltip + "[/color]";
var allowedClasses = targetState.garrisonHolder.allowedClasses;
for each (var unitClass in entState.identity.classes)
{
if (allowedClasses.indexOf(unitClass) != -1)
return {"possible": true, "tooltip": tooltip};
}
if (MatchesClassList(entState.identity.classes, targetState.garrisonHolder.allowedClasses))
return {"possible": true, "tooltip": tooltip};
}
break;
case "setup-trade-route":

View File

@ -380,9 +380,9 @@ m.Template = m.Class({
garrisonableClasses: function() {
if (!this.get("GarrisonHolder") || !this.get("GarrisonHolder/List/_string"))
if (!this.get("GarrisonHolder"))
return undefined;
return this.get("GarrisonHolder/List/_string").split(/\s+/);
return this.get(this.get("GarrisonHolder/List/_string"));
},
garrisonMax: function() {

View File

@ -191,20 +191,13 @@ Auras.prototype.Clean = function()
Auras.prototype.GiveMembersWithValidClass = function(auraName, entityList)
{
var validClasses = this.GetClasses(auraName);
var match = this.GetClasses(auraName);
var r = [];
for each (var ent in entityList)
for (var ent of entityList)
{
var cmpIdentity = Engine.QueryInterface(ent, IID_Identity);
var targetClasses = cmpIdentity.GetClassesList();
for each (var classCollection in validClasses)
{
if (classCollection.split(/\s+/).every(function(c) {return targetClasses.indexOf(c) > -1}))
{
r.push(ent);
break;
}
}
if (cmpIdentity && MatchesClassList(cmpIdentity.GetClassesList(), match))
r.push(ent);
}
return r;
}

View File

@ -110,10 +110,9 @@ GarrisonHolder.prototype.GetEntities = function()
* Returns an array of unit classes which can be garrisoned inside this
* particualar entity. Obtained from the entity's template
*/
GarrisonHolder.prototype.GetAllowedClassesList = function()
GarrisonHolder.prototype.GetAllowedClasses = function()
{
var classes = this.template.List._string;
return classes ? classes.split(/\s+/) : [];
return this.template.List._string;
};
/**
@ -211,17 +210,11 @@ GarrisonHolder.prototype.AllowedToGarrison = function(entity)
if (!this.IsGarrisoningAllowed())
return false;
var allowedClasses = this.GetAllowedClassesList();
var entityClasses = (Engine.QueryInterface(entity, IID_Identity)).GetClassesList();
// Check if the unit is allowed to be garrisoned inside the building
for each (var allowedClass in allowedClasses)
{
if (entityClasses.indexOf(allowedClass) != -1)
{
return true;
}
}
return false;
var cmpIdentity = Engine.QueryInterface(entity, IID_Identity);
if (!cmpIdentity)
return false;
var entityClasses = cmpIdentity.GetClassesList();
return MatchesClassList(entityClasses, this.template.List._string);
};
/**

View File

@ -273,7 +273,7 @@ GuiInterface.prototype.GetEntityState = function(player, ent)
{
ret.garrisonHolder = {
"entities": cmpGarrisonHolder.GetEntities(),
"allowedClasses": cmpGarrisonHolder.GetAllowedClassesList(),
"allowedClasses": cmpGarrisonHolder.GetAllowedClasses(),
"capacity": cmpGarrisonHolder.GetCapacity(),
"garrisonedEntitiesCount": cmpGarrisonHolder.GetGarrisonedEntitiesCount()
};

View File

@ -19,9 +19,9 @@
</Health>
<GarrisonHolder>
<Max>5</Max>
<List datatype="tokens">Infantry</List>
<List datatype="tokens">Ranged+Infantry</List>
<EjectHealth>0.1</EjectHealth>
<EjectClassesOnDestroy datatype="tokens">Infantry</EjectClassesOnDestroy>
<EjectClassesOnDestroy datatype="tokens">Unit</EjectClassesOnDestroy>
<BuffHeal>0</BuffHeal>
<LoadingRange>2</LoadingRange>
<VisibleGarrisonPoints>

View File

@ -16,9 +16,9 @@
</Cost>
<GarrisonHolder>
<Max>3</Max>
<List datatype="tokens">Infantry</List>
<List datatype="tokens">Ranged+Infantry</List>
<EjectHealth>0.1</EjectHealth>
<EjectClassesOnDestroy datatype="tokens">Infantry</EjectClassesOnDestroy>
<EjectClassesOnDestroy datatype="tokens">Unit</EjectClassesOnDestroy>
<BuffHeal>0</BuffHeal>
<LoadingRange>2</LoadingRange>
<VisibleGarrisonPoints>