Index: binaries/data/mods/public/art/actors/actor.rng =================================================================== --- binaries/data/mods/public/art/actors/actor.rng +++ binaries/data/mods/public/art/actors/actor.rng @@ -27,6 +27,11 @@ + + + + + @@ -200,6 +205,9 @@ + + + Index: binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_a.xml @@ -139,44 +139,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_b.xml @@ -44,44 +44,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_e.xml @@ -170,44 +170,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/britons/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/britons/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/britons/infantry_spearman_a.xml @@ -64,37 +64,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/britons/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/britons/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/britons/infantry_spearman_b.xml @@ -62,39 +62,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/britons/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/britons/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/britons/infantry_spearman_e.xml @@ -66,37 +66,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_a.xml @@ -83,44 +83,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_b.xml @@ -40,44 +40,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/carthaginians/infantry_spearman_e.xml @@ -91,44 +91,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_a.xml @@ -78,37 +78,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_b.xml @@ -78,37 +78,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/gauls/infantry_spearman_e.xml @@ -96,37 +96,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_a.xml @@ -37,37 +37,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_b.xml @@ -61,37 +61,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/kushites/infantry_spearman_e.xml @@ -40,37 +40,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_a.xml @@ -15,37 +15,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_b.xml @@ -15,37 +15,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/mauryas/infantry_spearman_e.xml @@ -15,37 +15,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/persians/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/persians/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/persians/infantry_spearman_a.xml @@ -89,37 +89,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/persians/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/persians/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/persians/infantry_spearman_b.xml @@ -76,37 +76,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/persians/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/persians/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/persians/infantry_spearman_e.xml @@ -52,37 +52,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_a.xml @@ -41,49 +41,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_b.xml @@ -62,49 +62,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/ptolemies/infantry_spearman_e.xml @@ -26,49 +26,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/actors/units/romans/infantry_spearman_a.xml =================================================================== --- binaries/data/mods/public/art/actors/units/romans/infantry_spearman_a.xml +++ binaries/data/mods/public/art/actors/units/romans/infantry_spearman_a.xml @@ -136,45 +136,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/romans/infantry_spearman_b.xml =================================================================== --- binaries/data/mods/public/art/actors/units/romans/infantry_spearman_b.xml +++ binaries/data/mods/public/art/actors/units/romans/infantry_spearman_b.xml @@ -65,45 +65,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans_spec.xml Index: binaries/data/mods/public/art/actors/units/romans/infantry_spearman_e.xml =================================================================== --- binaries/data/mods/public/art/actors/units/romans/infantry_spearman_e.xml +++ binaries/data/mods/public/art/actors/units/romans/infantry_spearman_e.xml @@ -111,45 +111,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + player_trans.xml Index: binaries/data/mods/public/art/groups/base_hoplite.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_hoplite.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_hoplite_idle.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_hoplite_idle.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_infantry_worker_idle.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_infantry_worker_idle.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_spearman_relax.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_spearman_relax.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_spearman_roman.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_spearman_roman.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_spearman_shield_relax_celt.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_spearman_shield_relax_celt.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_spearman_shield_relax_ptol.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_spearman_shield_relax_ptol.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + Index: binaries/data/mods/public/art/groups/base_spearman_shield_relax_ptol_idle.xml =================================================================== --- /dev/null +++ binaries/data/mods/public/art/groups/base_spearman_shield_relax_ptol_idle.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Index: source/graphics/ObjectBase.h =================================================================== --- source/graphics/ObjectBase.h +++ source/graphics/ObjectBase.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -195,7 +195,7 @@ [[nodiscard]] bool Load(const CXeromyces& XeroFile, const XMBElement& base); [[nodiscard]] bool LoadVariant(const CXeromyces& XeroFile, const XMBElement& variant, Variant& currentVariant); - + [[nodiscard]] bool LoadGroup(const CXeromyces& XeroFile, const XMBElement& group, std::vector< std::vector >& variantGroups); private: // Backref to the owning actor. CActorDef& m_ActorDef; Index: source/graphics/ObjectBase.cpp =================================================================== --- source/graphics/ObjectBase.cpp +++ source/graphics/ObjectBase.cpp @@ -85,9 +85,11 @@ EL(castshadow); EL(float); EL(group); + EL(groupref); EL(material); AT(maxquality); AT(minquality); + AT(file); #undef AT #undef EL @@ -124,22 +126,36 @@ if (shouldSkip(child)) continue; - if (child_name == el_group) + if (child_name == el_groupref) { - std::vector& currentGroup = m_VariantGroups.emplace_back(); - currentGroup.reserve(child.GetChildNodes().size()); - XERO_ITER_EL(child, variant) + XERO_ITER_ATTR(child, attr) { - if (shouldSkip(variant)) - continue; - - if (!LoadVariant(XeroFile, variant, currentGroup.emplace_back())) - return false; + if (attr.Name == at_file) + { + m_ActorDef.m_UsedFiles.insert(attr.Value); + CXeromyces XeroGroup; + if (XeroGroup.Load(g_VFS, "art/groups/" + attr.Value) == PSRETURN_OK) + { + if (!LoadGroup(XeroGroup, XeroGroup.GetRoot(), m_VariantGroups)) + { + LOGERROR("Failed to load group ('%s')", m_Identifier); + return false; + } + } + else + { + LOGERROR("Could not open path %s", attr.Value); + return false; + } + } } + } - if (currentGroup.size() == 0) + if (child_name == el_group) + { + if (!LoadGroup(XeroFile, child, m_VariantGroups)) { - LOGERROR("Actor group has zero variants ('%s')", m_Identifier); + LOGERROR("Failed to load group ('%s')", m_Identifier); return false; } } @@ -157,6 +173,46 @@ return true; } +bool CObjectBase::LoadGroup(const CXeromyces& XeroFile, const XMBElement& group, std::vector< std::vector >& variantGroups) +{ + #define EL(x) int el_##x = XeroFile.GetElementID(#x) + #define AT(x) int at_##x = XeroFile.GetAttributeID(#x) + EL(group); + AT(maxquality); + AT(minquality); + #undef AT + #undef EL + + if (group.GetNodeName() != el_group) + { + LOGERROR("Invalid group format (unrecognised root element '%s')", XeroFile.GetElementString(group.GetNodeName())); + return false; + } + + std::vector& currentGroup = variantGroups.emplace_back(); + currentGroup.reserve(group.GetChildNodes().size()); + + auto shouldSkip = [&](XMBElement& node) { + XERO_ITER_ATTR(node, attr) + { + if (attr.Name == at_minquality && GetQuality(attr.Value) > m_QualityLevel) + return true; + else if (attr.Name == at_maxquality && GetQuality(attr.Value) <= m_QualityLevel) + return true; + } + return false; + }; + XERO_ITER_EL(group, variant) + { + if (shouldSkip(variant)) + continue; + + if (!LoadVariant(XeroFile, variant, currentGroup.emplace_back())) + return false; + } + return true; +} + bool CObjectBase::LoadVariant(const CXeromyces& XeroFile, const XMBElement& variant, Variant& currentVariant) { #define EL(x) int el_##x = XeroFile.GetElementID(#x)