Index: ps/trunk/binaries/data/mods/public/simulation/templates/mixins/builder.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/mixins/builder.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/mixins/builder.xml
@@ -0,0 +1,37 @@
+
+
+
+ 1.0
+
+ structures/{civ}/civil_centre
+ structures/{civ}/crannog
+ structures/{civ}/military_colony
+ structures/{civ}/house
+ structures/{civ}/apartment
+ structures/{civ}/storehouse
+ structures/{civ}/farmstead
+ structures/{civ}/field
+ structures/{civ}/corral
+ structures/{civ}/dock
+ structures/{civ}/barracks
+ structures/{civ}/stable
+ structures/{civ}/elephant_stable
+ structures/{civ}/arsenal
+ structures/{civ}/forge
+ structures/{civ}/temple
+ structures/{civ}/market
+ structures/{civ}/outpost
+ structures/{civ}/sentry_tower
+ structures/{civ}/defense_tower
+ structures/{civ}/fortress
+ structures/wallset_palisade
+ structures/{civ}/wallset_siege
+ structures/{civ}/wallset_stone
+ structures/{civ}/theater
+ structures/{civ}/wonder
+
+
+
+ Builder
+
+
Index: ps/trunk/binaries/data/mods/public/simulation/templates/mixins/hoplite.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/mixins/hoplite.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/mixins/hoplite.xml
@@ -0,0 +1,8 @@
+
+
+
+
+ special/formations/phalanx
+
+
+
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_spearman_hoplite.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_spearman_hoplite.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_champion_infantry_spearman_hoplite.xml
@@ -1,8 +0,0 @@
-
-
-
-
- special/formations/phalanx
-
-
-
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_spearman_hoplite.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_spearman_hoplite.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_hero_infantry_spearman_hoplite.xml
@@ -1,8 +0,0 @@
-
-
-
-
- special/formations/phalanx
-
-
-
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry.xml
@@ -1,5 +1,5 @@
-
+
Capture
@@ -16,37 +16,6 @@
2
-
- 1.0
-
- structures/{civ}/civil_centre
- structures/{civ}/crannog
- structures/{civ}/military_colony
- structures/{civ}/house
- structures/{civ}/apartment
- structures/{civ}/storehouse
- structures/{civ}/farmstead
- structures/{civ}/field
- structures/{civ}/corral
- structures/{civ}/dock
- structures/{civ}/barracks
- structures/{civ}/stable
- structures/{civ}/elephant_stable
- structures/{civ}/arsenal
- structures/{civ}/forge
- structures/{civ}/temple
- structures/{civ}/market
- structures/{civ}/outpost
- structures/{civ}/sentry_tower
- structures/{civ}/defense_tower
- structures/{civ}/fortress
- structures/wallset_palisade
- structures/{civ}/wallset_siege
- structures/{civ}/wallset_stone
- structures/{civ}/theater
- structures/{civ}/wonder
-
-
12
@@ -62,7 +31,7 @@
Infantry
Human CitizenSoldier
- Citizen Builder Worker Soldier Infantry
+ Citizen Worker Soldier Infantry
Basic
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_spearman_hoplite.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_spearman_hoplite.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_infantry_melee_spearman_hoplite.xml
@@ -1,8 +0,0 @@
-
-
-
-
- special/formations/phalanx
-
-
-
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_female_citizen.xml
@@ -1,5 +1,5 @@
-
+
Dagger
@@ -18,37 +18,6 @@
2
-
- 1.0
-
- structures/{civ}/civil_centre
- structures/{civ}/crannog
- structures/{civ}/military_colony
- structures/{civ}/house
- structures/{civ}/apartment
- structures/{civ}/storehouse
- structures/{civ}/farmstead
- structures/{civ}/field
- structures/{civ}/corral
- structures/{civ}/dock
- structures/{civ}/barracks
- structures/{civ}/stable
- structures/{civ}/elephant_stable
- structures/{civ}/arsenal
- structures/{civ}/forge
- structures/{civ}/temple
- structures/{civ}/market
- structures/{civ}/outpost
- structures/{civ}/sentry_tower
- structures/{civ}/defense_tower
- structures/{civ}/fortress
- structures/wallset_palisade
- structures/{civ}/wallset_siege
- structures/{civ}/wallset_stone
- structures/{civ}/theater
- structures/{civ}/wonder
-
-
9
@@ -63,7 +32,7 @@
Female Citizen
template_unit_support_female_citizen
FemaleCitizen
- Citizen Builder Worker
+ Citizen Worker
Index: ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_slave.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_slave.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/template_unit_support_slave.xml
@@ -1,35 +1,7 @@
-
+
0.5
-
- structures/{civ}/civil_centre
- structures/{civ}/crannog
- structures/{civ}/military_colony
- structures/{civ}/house
- structures/{civ}/apartment
- structures/{civ}/storehouse
- structures/{civ}/farmstead
- structures/{civ}/field
- structures/{civ}/corral
- structures/{civ}/dock
- structures/{civ}/barracks
- structures/{civ}/stable
- structures/{civ}/elephant_stable
- structures/{civ}/arsenal
- structures/{civ}/forge
- structures/{civ}/temple
- structures/{civ}/market
- structures/{civ}/outpost
- structures/{civ}/sentry_tower
- structures/{civ}/defense_tower
- structures/{civ}/fortress
- structures/wallset_palisade
- structures/{civ}/wallset_siege
- structures/{civ}/wallset_stone
- structures/{civ}/theater
- structures/{civ}/wonder
-
0
@@ -46,7 +18,7 @@
Slave
template_unit_support_slave
Gatherer with a finite life span. Bonused at mining and lumbering.
- Builder Worker Slave
+ Worker Slave
10
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/champion_infantry.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/champion_infantry.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/champion_infantry.xml
@@ -1,5 +1,5 @@
-
+
athen
greek
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/hero_pericles.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/hero_pericles.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/hero_pericles.xml
@@ -1,5 +1,5 @@
-
+
units/heroes/athen_hero_pericles_1
units/heroes/athen_hero_pericles_2
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/infantry_spearman_b.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/infantry_spearman_b.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/athen/infantry_spearman_b.xml
@@ -1,5 +1,5 @@
-
+
structures/athen/gymnasium
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/cart/champion_infantry.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/cart/champion_infantry.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/cart/champion_infantry.xml
@@ -1,5 +1,5 @@
-
+
cart
Sacred Band Infantry
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/cart/infantry_spearman_b.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/cart/infantry_spearman_b.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/cart/infantry_spearman_b.xml
@@ -1,5 +1,5 @@
-
+
structures/cart/super_dock
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/mace/champion_infantry_spearman.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/mace/champion_infantry_spearman.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/mace/champion_infantry_spearman.xml
@@ -1,5 +1,5 @@
-
+
mace
greek
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/pers/kardakes_hoplite.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/pers/kardakes_hoplite.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/pers/kardakes_hoplite.xml
@@ -1,5 +1,5 @@
-
+
pers
Mercenary
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/ptol/infantry_spearman_merc_b.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/ptol/infantry_spearman_merc_b.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/ptol/infantry_spearman_merc_b.xml
@@ -1,5 +1,5 @@
-
+
structures/ptol/lighthouse
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/samnite_spearman.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/samnite_spearman.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/samnite_spearman.xml
@@ -1,5 +1,5 @@
-
+
Mercenary
Samnite Spearman
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/sele/infantry_spearman_b.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/sele/infantry_spearman_b.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/sele/infantry_spearman_b.xml
@@ -1,5 +1,5 @@
-
+
sele
greek
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/champion_infantry_spear.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/champion_infantry_spear.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/champion_infantry_spear.xml
@@ -1,5 +1,5 @@
-
+
spart
greek
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/hero_agis.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/hero_agis.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/hero_agis.xml
@@ -1,5 +1,5 @@
-
+
spart
greek
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/hero_leonidas.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/hero_leonidas.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/hero_leonidas.xml
@@ -1,5 +1,5 @@
-
+
units/heroes/spart_hero_leonidas
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/infantry_spearman_b.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/infantry_spearman_b.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/spart/infantry_spearman_b.xml
@@ -1,5 +1,5 @@
-
+
structures/spart/syssiton
Index: ps/trunk/binaries/data/mods/public/simulation/templates/units/thebes_sacred_band_hoplitai.xml
===================================================================
--- ps/trunk/binaries/data/mods/public/simulation/templates/units/thebes_sacred_band_hoplitai.xml
+++ ps/trunk/binaries/data/mods/public/simulation/templates/units/thebes_sacred_band_hoplitai.xml
@@ -1,5 +1,5 @@
-
+
greek
Theban Sacred Band Hoplite
Index: ps/trunk/source/ps/TemplateLoader.h
===================================================================
--- ps/trunk/source/ps/TemplateLoader.h
+++ ps/trunk/source/ps/TemplateLoader.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017 Wildfire Games.
+/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -20,6 +20,9 @@
#include "simulation2/system/ParamNode.h"
+#include
+#include
+
enum ETemplatesType
{
ALL_TEMPLATES,
@@ -69,14 +72,16 @@
* (Re)loads the given template, regardless of whether it exists already,
* and saves into m_TemplateFileData. Also loads any parents that are not yet
* loaded. Returns false on error.
- * @param templateName XML filename to load (not a |-separated string)
+ * @param templateName - XML filename to load (may be a |-separated string)
+ * @param compositing - whether this template is an intermediary layer in a |-separated string.
+ * @param depth - the current recursion depth.
*/
- bool LoadTemplateFile(const std::string& templateName, int depth);
+ bool LoadTemplateFile(CParamNode& node, std::string_view templateName, bool compositing, int depth);
/**
* Constructs a standard static-decorative-object template for the given actor
*/
- void ConstructTemplateActor(const std::string& actorName, CParamNode& out);
+ void ConstructTemplateActor(std::string_view actorName, CParamNode& out);
/**
* Map from template name (XML filename or special |-separated string) to the most recently
@@ -84,7 +89,7 @@
* (Failed loads won't remove existing entries under the same name, so we behave more nicely
* when hotloading broken files)
*/
- std::map m_TemplateFileData;
+ std::unordered_map m_TemplateFileData;
};
#endif // INCLUDED_TEMPLATELOADER
Index: ps/trunk/source/ps/TemplateLoader.cpp
===================================================================
--- ps/trunk/source/ps/TemplateLoader.cpp
+++ ps/trunk/source/ps/TemplateLoader.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2020 Wildfire Games.
+/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -29,91 +29,58 @@
static CParamNode NULL_NODE(false);
-bool CTemplateLoader::LoadTemplateFile(const std::string& templateName, int depth)
+bool CTemplateLoader::LoadTemplateFile(CParamNode& node, std::string_view templateName, bool compositing, int depth)
{
- // If this file was already loaded, we don't need to do anything
- if (m_TemplateFileData.find(templateName) != m_TemplateFileData.end())
+ // Handle special case "actor|foo", which does not load 'foo' at all, just uses the name.
+ if (templateName.compare(0, 6, "actor|") == 0)
+ {
+ ConstructTemplateActor(templateName.substr(6), node);
return true;
-
+ }
// Handle infinite loops more gracefully than running out of stack space and crashing
if (depth > 100)
{
- LOGERROR("Probable infinite inheritance loop in entity template '%s'", templateName.c_str());
+ LOGERROR("Probable infinite inheritance loop in entity template '%s'", std::string(templateName));
return false;
}
- // Handle special case "actor|foo"
- if (templateName.find("actor|") == 0)
- {
- ConstructTemplateActor(templateName.substr(6), m_TemplateFileData[templateName]);
- return true;
- }
-
- // Handle special case "bar|foo"
size_t pos = templateName.find_first_of('|');
if (pos != std::string::npos)
{
- std::string prefix = templateName.substr(0, pos);
- std::string baseName = templateName.substr(pos+1);
-
- if (!LoadTemplateFile(baseName, depth+1))
- {
- LOGERROR("Failed to load entity template '%s'", baseName.c_str());
+ // 'foo|bar' pattern: 'bar' is treated as the parent of 'foo'.
+ if (!LoadTemplateFile(node, templateName.substr(pos + 1), false, depth + 1))
return false;
- }
-
- VfsPath path = VfsPath(TEMPLATE_ROOT) / L"special" / L"filter" / wstring_from_utf8(prefix + ".xml");
- if (!VfsFileExists(path))
- {
- LOGERROR("Invalid subset '%s'", prefix.c_str());
+ if (!LoadTemplateFile(node, templateName.substr(0, pos), true, depth + 1))
return false;
- }
-
- CXeromyces xero;
- PSRETURN ok = xero.Load(g_VFS, path);
- if (ok != PSRETURN_OK)
- return false; // (Xeromyces already logged an error with the full filename)
-
- m_TemplateFileData[templateName] = m_TemplateFileData[baseName];
- CParamNode::LoadXML(m_TemplateFileData[templateName], xero, path.string().c_str());
return true;
}
- // Normal case: templateName is an XML file:
+ // Load the data we need to apply on the node. This data may contain special modifiers,
+ // such as filters, merges, multiplying the parent values, etc. Applying it to paramnode is destructive.
+ // Find the XML file to load - by default, this assumes the files reside in 'special/filter'.
+ // If not found there, it will be searched for in 'mixins/', then from the root.
+ // The reason for this order is that filters are used at runtime, mixins at load time.
+ std::wstring wtempName = wstring_from_utf8(std::string(templateName) + ".xml");
+ VfsPath path = VfsPath(TEMPLATE_ROOT) / L"special" / L"filter" / wtempName;
+ if (!VfsFileExists(path))
+ path = VfsPath(TEMPLATE_ROOT) / L"mixins" / wtempName;
+ if (!VfsFileExists(path))
+ path = VfsPath(TEMPLATE_ROOT) / wtempName;
- VfsPath path = VfsPath(TEMPLATE_ROOT) / wstring_from_utf8(templateName + ".xml");
CXeromyces xero;
PSRETURN ok = xero.Load(g_VFS, path);
if (ok != PSRETURN_OK)
return false; // (Xeromyces already logged an error with the full filename)
+ // If the layer defines an explicit parent, we must load that and apply it before ourselves.
int attr_parent = xero.GetAttributeID("parent");
CStr parentName = xero.GetRoot().GetAttributes().GetNamedItem(attr_parent);
- if (!parentName.empty())
- {
- // To prevent needless complexity in template design, we don't allow |-separated strings as parents
- if (parentName.find('|') != parentName.npos)
- {
- LOGERROR("Invalid parent '%s' in entity template '%s'", parentName.c_str(), templateName.c_str());
- return false;
- }
-
- // Ensure the parent is loaded
- if (!LoadTemplateFile(parentName, depth+1))
- {
- LOGERROR("Failed to load parent '%s' of entity template '%s'", parentName.c_str(), templateName.c_str());
- return false;
- }
-
- CParamNode& parentData = m_TemplateFileData[parentName];
-
- // Initialise this template with its parent
- m_TemplateFileData[templateName] = parentData;
- }
-
- // Load the new file into the template data (overriding parent values)
- CParamNode::LoadXML(m_TemplateFileData[templateName], xero, wstring_from_utf8(templateName).c_str());
+ if (!parentName.empty() && !LoadTemplateFile(node, parentName, compositing, depth + 1))
+ return false;
+ // Load the new file into the template data (overriding parent values).
+ // TODO: error handling.
+ CParamNode::LoadXML(node, xero);
return true;
}
@@ -124,13 +91,14 @@
// Strip the .xml extension
VfsPath pathstem = pathname.ChangeExtension(L"");
// Strip the root from the path
- std::wstring name = pathstem.string().substr(ARRAY_SIZE(TEMPLATE_ROOT)-1);
+ std::wstring_view name = pathstem.string().substr(ARRAY_SIZE(TEMPLATE_ROOT)-1);
// We want to ignore template_*.xml templates, since they should never be built in the editor
if (name.substr(0, 9) == L"template_")
return INFO::OK;
- if (name.substr(0, 8) == L"special/")
+ // Also ignore some subfolders.
+ if (name.substr(0, 8) == L"special/" || name.substr(0, 7) == L"mixins/")
return INFO::OK;
templates.push_back(std::string(name.begin(), name.end()));
@@ -178,33 +146,35 @@
const CParamNode& CTemplateLoader::GetTemplateFileData(const std::string& templateName)
{
- // Load the template if necessary
- if (!LoadTemplateFile(templateName, 0))
+ if (std::unordered_map::const_iterator it = m_TemplateFileData.find(templateName); it != m_TemplateFileData.end())
+ return it->second;
+
+ CParamNode ret;
+ if (!LoadTemplateFile(ret, templateName, false, 0))
{
LOGERROR("Failed to load entity template '%s'", templateName.c_str());
return NULL_NODE;
}
-
- return m_TemplateFileData[templateName];
+ return m_TemplateFileData.insert_or_assign(templateName, ret).first->second;
}
-void CTemplateLoader::ConstructTemplateActor(const std::string& actorName, CParamNode& out)
+void CTemplateLoader::ConstructTemplateActor(std::string_view actorName, CParamNode& out)
{
// Copy the actor template
out = GetTemplateFileData("special/actor");
// Initialize the actor's name and make it an Atlas selectable entity.
- std::wstring actorNameW = wstring_from_utf8(actorName);
- std::string name = utf8_from_wstring(CParamNode::EscapeXMLString(actorNameW));
- std::string xml = ""
- "" + name + ""
- // Arbitrary-sized Footprint definition to make actors' selection outlines show up in Atlas.
- "1.0"
- ""
- ""
- "128x128/ellipse.png128x128/ellipse_mask.png"
- ""
- "";
-
- CParamNode::LoadXMLString(out, xml.c_str(), actorNameW.c_str());
+ std::string source(actorName);
+ std::wstring actorNameW = wstring_from_utf8(source);
+ source = ""
+ "" + source + ""
+ // Arbitrary-sized Footprint definition to make actors' selection outlines show up in Atlas.
+ "1.0"
+ ""
+ ""
+ "128x128/ellipse.png128x128/ellipse_mask.png"
+ ""
+ "";
+ // We'll assume that actorName is valid XML, otherwise this will fail and report the error anyways.
+ CParamNode::LoadXMLString(out, source.c_str(), actorNameW.c_str());
}
Index: ps/trunk/source/tools/entity/Entity.pm
===================================================================
--- ps/trunk/source/tools/entity/Entity.pm
+++ ps/trunk/source/tools/entity/Entity.pm
@@ -12,7 +12,13 @@
sub get_filename
{
my ($vfspath, $mod) = @_;
- my $fn = "$vfsroot/$mod/simulation/templates/$vfspath.xml";
+ my $fn = "$vfsroot/$mod/simulation/templates/special/filter/$vfspath.xml";
+ if (not -e $fn) {
+ $fn = "$vfsroot/$mod/simulation/templates/mixins/$vfspath.xml";
+ }
+ if (not -e $fn) {
+ $fn = "$vfsroot/$mod/simulation/templates/$vfspath.xml";
+ }
return $fn;
}
@@ -136,16 +142,28 @@
sub load_inherited
{
- my ($vfspath, $mods) = @_;
+ my ($vfspath, $mods, $base) = @_;
+ if ($vfspath =~ /\|/) {
+ my @paths = split(/\|/, $vfspath, 2);
+ $base = load_inherited($paths[1], $mods, $base);
+ $base = load_inherited($paths[0], $mods, $base);
+ return $base
+ }
my $main_mod = get_main_mod($vfspath, $mods);
my $layer = load_xml($vfspath, get_file($vfspath, $main_mod));
if ($layer->{Entity}{'@parent'}) {
- my $parent = load_inherited($layer->{Entity}{'@parent'}{' content'}, $mods);
+ my $parent = load_inherited($layer->{Entity}{'@parent'}{' content'}, $mods, $base);
apply_layer($parent->{Entity}, $layer->{Entity});
return $parent;
} else {
- return $layer;
+ if (not $base) {
+ return $layer;
+ }
+ else {
+ apply_layer($base->{Entity}, $layer->{Entity});
+ return $base
+ }
}
}
Index: ps/trunk/source/tools/entity/checkrefs.pl
===================================================================
--- ps/trunk/source/tools/entity/checkrefs.pl
+++ ps/trunk/source/tools/entity/checkrefs.pl
@@ -130,7 +130,14 @@
push @files, $path;
my $ent = Entity::load_inherited($f, "$mod_list_string");
- push @deps, [ $path, "simulation/templates/" . $ent->{Entity}{'@parent'}{' content'} . ".xml" ] if $ent->{Entity}{'@parent'};
+ if ($ent->{Entity}{'@parent'})
+ {
+ my @parents = split(/\|/, $ent->{Entity}{'@parent'}{' content'});
+ for my $parentPath (@parents)
+ {
+ push @deps, [ $path, "simulation/templates/" . $parentPath . ".xml" ];
+ }
+ }
if ($f !~ /^template_/)
{
@@ -638,6 +645,11 @@
for my $f (sort keys %revdeps)
{
+ if ($f =~ /simulation\/templates\//)
+ {
+ next if exists $files{$f =~ s/templates\//templates\/special\/filter\//r};
+ next if exists $files{$f =~ s/templates\//templates\/mixins\//r};
+ }
next if exists $files{$f};
warn "Missing file '$f' referenced by: " . (join ', ', map "'$_'", map vfs_to_relative_to_mods($_), sort @{$revdeps{$f}}) . "\n";