Ticket #3286: easy_switch_animations.diff
File easy_switch_animations.diff, 18.3 KB (added by , 9 years ago) |
---|
-
binaries/data/mods/public/art/actors/units/athenians/infantry_archer_b.xml
6 6 <animations> 7 7 <animation file="biped/inf_sword_ready_a.dae" name="Idle" speed="100"/> 8 8 <animation file="biped/inf_sword_ready_a.dae" name="Idle" speed="97"/> 9 <animation event="0.4" file="infantry/sword/attack/isw_s_def_01.psa" name="attack_capture" speed="100"/>10 <animation event="0.4" file="infantry/sword/attack/isw_s_def_06.psa" name="attack_capture" speed="100"/>11 <animation event="0.2" file="infantry/sword/attack/isw_s_em_04.psa" name="attack_capture" speed="100"/>12 9 <animation event="0.5" file="infantry/sword/attack/isw_s_off_05.psa" name="attack_slaughter" speed="100"/> 13 10 <animation event="0.84" file="biped/inf_arch_atk_a.psa" load="0.16" name="attack_ranged" speed="90"/> 14 11 <animation file="infantry/general/dude/dudewalk.psa" name="Walk" speed="100"/> … … 44 41 </group> 45 42 <group> 46 43 <variant frequency="100" name="Idle"/> 47 <variant name="attack_capture"> 48 <props> 49 <prop actor="props/units/tools/pitchfork.xml" attachpoint="r_hand"/> 50 </props> 51 </variant> 44 <variant file="units/variants/biped_attack_capture.xml"/> 52 45 <variant name="attack_ranged"> 53 46 <props> 54 47 <prop actor="props/units/weapons/bow_short.xml" attachpoint="l_hand"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_javelinist_b.xml
5 5 <variant frequency="100" name="Base"> 6 6 <animations> 7 7 <animation file="infantry/general/dude/dudeidle.psa" name="Idle" speed="100"/> 8 <animation event="0.4" file="infantry/sword/attack/isw_s_def_01.psa" name="attack_capture" speed="100"/>9 <animation event="0.4" file="infantry/sword/attack/isw_s_def_06.psa" name="attack_capture" speed="100"/>10 <animation event="0.2" file="infantry/sword/attack/isw_s_em_04.psa" name="attack_capture" speed="100"/>11 8 <animation event="0.5" file="infantry/javelin/attack/ijv_off_01.psa" load="0" name="attack_ranged" speed="75"/> 12 9 <animation event="0.5" file="infantry/sword/attack/isw_s_off_05.psa" name="attack_slaughter" speed="100"/> 13 10 <animation file="biped/walk_spearshield.psa" name="Walk" speed="120"/> … … 48 45 </group> 49 46 <group> 50 47 <variant frequency="100" name="Idle"/> 51 <variant name="attack_capture"> 52 <props> 53 <prop actor="props/units/tools/pitchfork.xml" attachpoint="r_hand"/> 54 </props> 55 </variant> 48 <variant file="units/variants/biped_attack_capture.xml"/> 56 49 <variant name="attack_ranged"> 57 50 <props> 58 51 <prop attachpoint="r_hand"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_slinger_b.xml
11 11 <animation file="biped/walk_spearshield.psa" name="carry_wood" speed="120"/> 12 12 <animation file="biped/walk_spearshield.psa" name="carry_stone" speed="120"/> 13 13 <animation file="biped/walk_spearshield.psa" name="carry_metal" speed="120"/> 14 <animation event="0.4" file="infantry/sword/attack/isw_s_def_01.psa" name="attack_capture" speed="100"/>15 <animation event="0.4" file="infantry/sword/attack/isw_s_def_06.psa" name="attack_capture" speed="100"/>16 <animation event="0.2" file="infantry/sword/attack/isw_s_em_04.psa" name="attack_capture" speed="100"/>17 14 18 15 <animation event="0.5" file="biped/inf_sling_atk_a.psa" name="attack_ranged" speed="30"/> 19 16 <animation event="0.5" file="infantry/sword/attack/isw_s_off_05.psa" name="attack_slaughter" speed="100"/> … … 46 43 </group> 47 44 <group> 48 45 <variant frequency="1" name="Idle"/> 49 <variant name="attack_capture"> 50 <props> 51 <prop actor="props/units/tools/pitchfork.xml" attachpoint="r_hand"/> 52 </props> 53 </variant> 46 <variant file="units/variants/biped_attack_capture.xml"/> 54 47 <variant name="attack_slaughter"> 55 48 <props> 56 49 <prop actor="props/units/weapons/knife.xml" attachpoint="r_hand"/> -
binaries/data/mods/public/art/actors/units/athenians/infantry_spearman_b.xml
12 12 <animation file="biped/walk_spearshield.psa" name="carry_wood" speed="120"/> 13 13 <animation file="biped/walk_spearshield.psa" name="carry_stone" speed="120"/> 14 14 <animation file="biped/walk_spearshield.psa" name="carry_metal" speed="120"/> 15 <animation event="0.4" file="infantry/sword/attack/isw_s_def_01.psa" name="attack_capture" speed="100"/>16 <animation event="0.4" file="infantry/sword/attack/isw_s_def_06.psa" name="attack_capture" speed="100"/>17 <animation event="0.2" file="infantry/sword/attack/isw_s_em_04.psa" name="attack_capture" speed="100"/>18 15 <animation event="0.5" file="biped/inf_hoplite_atk_a.psa" name="attack_melee" speed="200"/> 19 16 <animation event="0.5" file="biped/inf_hoplite_atk_a.psa" name="attack_slaughter" speed="200"/> 20 17 <animation event="0.23" file="infantry/general/chop.psa" name="gather_tree" speed="250"/> … … 55 52 </group> 56 53 <group> 57 54 <variant frequency="1" name="Idle"/> 58 <variant name="attack_capture"> 59 <props> 60 <prop actor="props/units/tools/pitchfork.xml" attachpoint="r_hand"/> 61 </props> 62 </variant> 55 <variant file="units/variants/biped_attack_capture.xml"/> 63 56 <variant name="attack_melee"> 64 57 <props> 65 58 <prop actor="props/units/weapons/spear_hoplite.xml" attachpoint="r_hand"/> -
binaries/data/mods/public/art/actors/units/variants/biped_attack_capture.xml
1 <variant name="attack_capture"> 2 <animations> 3 <animation event="0.4" file="infantry/sword/attack/isw_s_def_01.psa" name="attack_capture" speed="100"/> 4 <animation event="0.4" file="infantry/sword/attack/isw_s_def_06.psa" name="attack_capture" speed="100"/> 5 <animation event="0.2" file="infantry/sword/attack/isw_s_em_04.psa" name="attack_capture" speed="100"/> 6 </animations> 7 <props> 8 <prop actor="props/units/tools/pitchfork.xml" attachpoint="r_hand"/> 9 </props> 10 </variant> -
source/graphics/ObjectBase.cpp
38 38 m_Properties.m_FloatOnWater = false; 39 39 } 40 40 41 void CObjectBase::LoadVariant(const CXeromyces& XeroFile, const XMBElement& variant, Variant& currentVariant) 42 { 43 #define EL(x) int el_##x = XeroFile.GetElementID(#x) 44 #define AT(x) int at_##x = XeroFile.GetAttributeID(#x) 45 EL(animation); 46 EL(animations); 47 EL(color); 48 EL(decal); 49 EL(mesh); 50 EL(particles); 51 EL(prop); 52 EL(props); 53 EL(texture); 54 EL(textures); 55 EL(variant); 56 AT(actor); 57 AT(angle); 58 AT(attachpoint); 59 AT(depth); 60 AT(event); 61 AT(file); 62 AT(frequency); 63 AT(load); 64 AT(maxheight); 65 AT(minheight); 66 AT(name); 67 AT(offsetx); 68 AT(offsetz); 69 AT(selectable); 70 AT(sound); 71 AT(speed); 72 AT(width); 73 #undef AT 74 #undef EL 75 76 if (variant.GetNodeName() != el_variant) 77 { 78 LOGERROR("Invalid variant format in (unrecognised root element '%s')", XeroFile.GetElementString(variant.GetNodeName()).c_str()); 79 return; 80 } 81 82 XERO_ITER_ATTR(variant, attr) 83 { 84 if (attr.Name == at_name) 85 currentVariant.m_VariantName = attr.Value.LowerCase(); 86 else if (attr.Name == at_frequency) 87 currentVariant.m_Frequency = attr.Value.ToInt(); 88 } 89 90 XERO_ITER_EL(variant, option) 91 { 92 int option_name = option.GetNodeName(); 93 94 if (option_name == el_mesh) 95 { 96 currentVariant.m_ModelFilename = VfsPath("art/meshes") / option.GetText().FromUTF8(); 97 } 98 else if (option_name == el_textures) 99 { 100 XERO_ITER_EL(option, textures_element) 101 { 102 ENSURE(textures_element.GetNodeName() == el_texture); 103 104 Samp samp; 105 XERO_ITER_ATTR(textures_element, se) 106 { 107 if (se.Name == at_file) 108 samp.m_SamplerFile = VfsPath("art/textures/skins") / se.Value.FromUTF8(); 109 else if (se.Name == at_name) 110 samp.m_SamplerName = CStrIntern(se.Value); 111 } 112 currentVariant.m_Samplers.push_back(samp); 113 } 114 } 115 else if (option_name == el_decal) 116 { 117 XMBAttributeList attrs = option.GetAttributes(); 118 Decal decal; 119 decal.m_SizeX = attrs.GetNamedItem(at_width).ToFloat(); 120 decal.m_SizeZ = attrs.GetNamedItem(at_depth).ToFloat(); 121 decal.m_Angle = DEGTORAD(attrs.GetNamedItem(at_angle).ToFloat()); 122 decal.m_OffsetX = attrs.GetNamedItem(at_offsetx).ToFloat(); 123 decal.m_OffsetZ = attrs.GetNamedItem(at_offsetz).ToFloat(); 124 currentVariant.m_Decal = decal; 125 } 126 else if (option_name == el_particles) 127 { 128 XMBAttributeList attrs = option.GetAttributes(); 129 VfsPath file = VfsPath("art/particles") / attrs.GetNamedItem(at_file).FromUTF8(); 130 currentVariant.m_Particles = file; 131 132 // For particle hotloading, it's easiest to reload the entire actor, 133 // so remember the relevant particle file as a dependency for this actor 134 m_UsedFiles.insert(file); 135 } 136 else if (option_name == el_color) 137 { 138 currentVariant.m_Color = option.GetText(); 139 } 140 else if (option_name == el_animations) 141 { 142 XERO_ITER_EL(option, anim_element) 143 { 144 ENSURE(anim_element.GetNodeName() == el_animation); 145 146 Anim anim; 147 XERO_ITER_ATTR(anim_element, ae) 148 { 149 if (ae.Name == at_name) 150 { 151 anim.m_AnimName = ae.Value; 152 } 153 else if (ae.Name == at_file) 154 { 155 anim.m_FileName = VfsPath("art/animation") / ae.Value.FromUTF8(); 156 } 157 else if (ae.Name == at_speed) 158 { 159 anim.m_Speed = ae.Value.ToInt() / 100.f; 160 if (anim.m_Speed <= 0.0) anim.m_Speed = 1.0f; 161 } 162 else if (ae.Name == at_event) 163 { 164 float pos = ae.Value.ToFloat(); 165 anim.m_ActionPos = clamp(pos, 0.f, 1.f); 166 } 167 else if (ae.Name == at_load) 168 { 169 float pos = ae.Value.ToFloat(); 170 anim.m_ActionPos2 = clamp(pos, 0.f, 1.f); 171 } 172 else if (ae.Name == at_sound) 173 { 174 float pos = ae.Value.ToFloat(); 175 anim.m_SoundPos = clamp(pos, 0.f, 1.f); 176 } 177 } 178 currentVariant.m_Anims.push_back(anim); 179 } 180 181 } 182 else if (option_name == el_props) 183 { 184 XERO_ITER_EL(option, prop_element) 185 { 186 ENSURE(prop_element.GetNodeName() == el_prop); 187 188 Prop prop; 189 XERO_ITER_ATTR(prop_element, pe) 190 { 191 if (pe.Name == at_attachpoint) 192 prop.m_PropPointName = pe.Value; 193 else if (pe.Name == at_actor) 194 prop.m_ModelName = pe.Value.FromUTF8(); 195 else if (pe.Name == at_minheight) 196 prop.m_minHeight = pe.Value.ToFloat(); 197 else if (pe.Name == at_maxheight) 198 prop.m_maxHeight = pe.Value.ToFloat(); 199 else if (pe.Name == at_selectable) 200 prop.m_selectable = pe.Value != "false"; 201 } 202 currentVariant.m_Props.push_back(prop); 203 } 204 } 205 } 206 } 207 41 208 bool CObjectBase::Load(const VfsPath& pathname) 42 209 { 43 210 m_UsedFiles.clear(); … … 53 220 EL(actor); 54 221 EL(castshadow); 55 222 EL(float); 223 EL(group); 56 224 EL(material); 57 EL(group);58 225 EL(variant); 59 EL(animations);60 EL(animation);61 EL(props);62 EL(prop);63 EL(mesh);64 EL(texture);65 EL(textures);66 EL(color);67 EL(decal);68 EL(particles);69 226 AT(file); 70 AT(name);71 AT(speed);72 AT(event);73 AT(load);74 AT(sound);75 AT(attachpoint);76 AT(actor);77 AT(frequency);78 AT(width);79 AT(depth);80 AT(angle);81 AT(offsetx);82 AT(offsetz);83 AT(minheight);84 AT(maxheight);85 AT(selectable);86 227 #undef AT 87 228 #undef EL 88 229 … … 94 235 return false; 95 236 } 96 237 97 98 238 m_VariantGroups.clear(); 99 239 100 240 m_Pathname = pathname; … … 135 275 ENSURE(variant.GetNodeName() == el_variant); 136 276 XERO_ITER_ATTR(variant, attr) 137 277 { 138 if (attr.Name == at_name) 139 currentVariant->m_VariantName = attr.Value.LowerCase(); 140 141 else if (attr.Name == at_frequency) 142 currentVariant->m_Frequency = attr.Value.ToInt(); 143 } 144 145 XERO_ITER_EL(variant, option) 146 { 147 int option_name = option.GetNodeName(); 148 149 if (option_name == el_mesh) 278 if (attr.Name == at_file) 150 279 { 151 currentVariant->m_ModelFilename = VfsPath("art/meshes") / option.GetText().FromUTF8();152 }153 else if (option_name == el_textures)154 {155 XERO_ITER_EL(option, textures_element)280 // Open up an external file to load. 281 // Don't crash hard when failures happen, but log them and continue 282 m_UsedFiles.insert(attr.Value); 283 CXeromyces XeroVariant; 284 if (XeroVariant.Load(g_VFS, "art/actors/" + attr.Value) == PSRETURN_OK) 156 285 { 157 ENSURE(textures_element.GetNodeName() == el_texture); 158 159 Samp samp; 160 XERO_ITER_ATTR(textures_element, se) 161 { 162 if (se.Name == at_file) 163 samp.m_SamplerFile = VfsPath("art/textures/skins") / se.Value.FromUTF8(); 164 else if (se.Name == at_name) 165 samp.m_SamplerName = CStrIntern(se.Value); 166 } 167 currentVariant->m_Samplers.push_back(samp); 286 XMBElement variantRoot = XeroVariant.GetRoot(); 287 LoadVariant(XeroVariant, variantRoot, *currentVariant); 168 288 } 289 else 290 LOGERROR("Could not open path %s", attr.Value); 169 291 } 170 else if (option_name == el_decal)171 {172 XMBAttributeList attrs = option.GetAttributes();173 Decal decal;174 decal.m_SizeX = attrs.GetNamedItem(at_width).ToFloat();175 decal.m_SizeZ = attrs.GetNamedItem(at_depth).ToFloat();176 decal.m_Angle = DEGTORAD(attrs.GetNamedItem(at_angle).ToFloat());177 decal.m_OffsetX = attrs.GetNamedItem(at_offsetx).ToFloat();178 decal.m_OffsetZ = attrs.GetNamedItem(at_offsetz).ToFloat();179 currentVariant->m_Decal = decal;180 }181 else if (option_name == el_particles)182 {183 XMBAttributeList attrs = option.GetAttributes();184 VfsPath file = VfsPath("art/particles") / attrs.GetNamedItem(at_file).FromUTF8();185 currentVariant->m_Particles = file;186 187 // For particle hotloading, it's easiest to reload the entire actor,188 // so remember the relevant particle file as a dependency for this actor189 m_UsedFiles.insert(file);190 }191 else if (option_name == el_color)192 {193 currentVariant->m_Color = option.GetText();194 }195 else if (option_name == el_animations)196 {197 XERO_ITER_EL(option, anim_element)198 {199 ENSURE(anim_element.GetNodeName() == el_animation);200 201 Anim anim;202 XERO_ITER_ATTR(anim_element, ae)203 {204 if (ae.Name == at_name)205 {206 anim.m_AnimName = ae.Value;207 }208 else if (ae.Name == at_file)209 {210 anim.m_FileName = VfsPath("art/animation") / ae.Value.FromUTF8();211 }212 else if (ae.Name == at_speed)213 {214 anim.m_Speed = ae.Value.ToInt() / 100.f;215 if (anim.m_Speed <= 0.0) anim.m_Speed = 1.0f;216 }217 else if (ae.Name == at_event)218 {219 float pos = ae.Value.ToFloat();220 anim.m_ActionPos = clamp(pos, 0.f, 1.f);221 }222 else if (ae.Name == at_load)223 {224 float pos = ae.Value.ToFloat();225 anim.m_ActionPos2 = clamp(pos, 0.f, 1.f);226 }227 else if (ae.Name == at_sound)228 {229 float pos = ae.Value.ToFloat();230 anim.m_SoundPos = clamp(pos, 0.f, 1.f);231 }232 }233 currentVariant->m_Anims.push_back(anim);234 }235 236 }237 else if (option_name == el_props)238 {239 XERO_ITER_EL(option, prop_element)240 {241 ENSURE(prop_element.GetNodeName() == el_prop);242 243 Prop prop;244 XERO_ITER_ATTR(prop_element, pe)245 {246 if (pe.Name == at_attachpoint)247 prop.m_PropPointName = pe.Value;248 else if (pe.Name == at_actor)249 prop.m_ModelName = pe.Value.FromUTF8();250 else if (pe.Name == at_minheight)251 prop.m_minHeight = pe.Value.ToFloat();252 else if (pe.Name == at_maxheight)253 prop.m_maxHeight = pe.Value.ToFloat();254 else if (pe.Name == at_selectable)255 prop.m_selectable = pe.Value != "false";256 }257 currentVariant->m_Props.push_back(prop);258 }259 }260 292 } 261 293 294 // Always expand the contents of this node, even if a file has 295 // been loaded to allow for extra definitions 296 LoadVariant(XeroFile, variant, *currentVariant); 262 297 ++currentVariant; 263 298 } 264 299 265 300 if (currentGroup->size() == 0) 266 {267 301 LOGERROR("Actor group has zero variants ('%s')", pathname.string8()); 268 }269 302 270 303 ++currentGroup; 271 304 } 272 305 else if (child_name == el_castshadow) 273 {274 306 m_Properties.m_CastShadows = true; 275 }276 307 else if (child_name == el_float) 277 {278 308 m_Properties.m_FloatOnWater = true; 279 }280 309 else if (child_name == el_material) 281 {282 310 m_Material = VfsPath("art/materials") / child.GetText().FromUTF8(); 283 }284 311 } 285 312 286 313 if (m_Material.empty()) -
source/graphics/ObjectBase.h
29 29 #include "lib/file/vfs/vfs_path.h" 30 30 #include "ps/CStr.h" 31 31 #include "ps/CStrIntern.h" 32 #include "ps/XML/Xeromyces.h" 32 33 33 34 #include <boost/random/mersenne_twister.hpp> 34 35 … … 187 188 CObjectManager& m_ObjectManager; 188 189 189 190 boost::unordered_set<VfsPath> m_UsedFiles; 191 192 void LoadVariant(const CXeromyces& XeroFile, const XMBElement& variant, Variant& currentVariant); 190 193 }; 191 194 192 195 #endif