V-Gears 0
Free Final Fantasy VII engine.
FF7NameLookup.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 The V-Gears Team
3 *
4 * This file is part of V-Gears
5 *
6 * V-Gears is free software: you can redistribute it and/or modify it under
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, version 3.0 (GPLv3) of the License.
9 *
10 * V-Gears is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#pragma once
17
18#include "common/TypeDefine.h"
20#include "core/XmlFile.h"
21
22// TODO: Move implementations to cpp file.
23
24namespace VGears{
25
26
30 class FF7Metadata : public XmlFile{
31
32 public:
33
40 TiXmlNode* node = file_.RootElement();
41 if (node == nullptr || node->ValueStr() != "metadata"){
42 throw std::runtime_error(
43 "FF7Metadata: " + file_.ValueStr()
44 + " is not a valid metadata file! No <metadata> in root."
45 );
46 }
47
48 node = node->FirstChild();
49 while (node){
50 if (node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "models")
51 ReadModels(node->FirstChild());
52 else if (
53 node->Type() == TiXmlNode::TINYXML_ELEMENT&& node->ValueStr() == "animations"
54 ){
55 ReadAnimations(node->FirstChild());
56 }
57 else if (
58 node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "scripts"
59 ){
60 ReadScripts(node->FirstChild());
61 }
62 node = node->NextSibling();
63 }
64 }
65
77 const String& Animation(const String &key) const{
78 auto it = animations_.find(key);
79 if (it != std::end(animations_)) return it->second;
80 String base_name;
81 StringUtil::splitBase(key, base_name);
82 it = animations_.find(base_name);
83 if (it != std::end(animations_)) return it->second;
84 return key;
85 }
86
98 const String& Model(const String &key) const{
99 auto it = models_.find(key);
100 if (it != std::end(models_)) return it->second;
101 String base_name;
102 StringUtil::splitBase(key, base_name);
103 it = models_.find(base_name);
104 if (it != std::end(models_)) return it->second;
105 return key;
106 }
107
108 private:
109
115 void ReadModels(TiXmlNode* node){
116 while (node){
117 const auto src = GetString(node, "name");
118 const auto dst = GetString(node, "target");
119 models_[src] = dst;
120 node = node->NextSibling();
121 }
122 }
123
129 void ReadAnimations(TiXmlNode* node){
130 while (node){
131 const auto src = GetString(node, "name");
132 const auto dst = GetString(node, "target");
133 animations_[src] = dst;
134 node = node->NextSibling();
135 }
136 }
137
138
144 void ReadScripts(TiXmlNode* node){
145 while (node){
146 if (
147 node->Type() == TiXmlNode::TINYXML_ELEMENT
148 && node->ValueStr() == "CharacterIds"
149 ){ReadCharacterIds(node->FirstChild());}
150 else if (
151 node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "var_names"
152 ){ReadVarNames(node->FirstChild());}
153 else if (
154 node->Type() == TiXmlNode::TINYXML_ELEMENT
155 && node->ValueStr() == "entity_names"
156 ){ReadEntityNames(node->FirstChild());}
157 else if (
158 node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "field"
159 ){
160 const auto name = GetString(node, "name");
161 ReadField(node->FirstChild(), name);
162 }
163 node = node->NextSibling();
164 }
165 }
166
173 void ReadField(TiXmlNode* node, const std::string& name){
174 while (node){
175 if (
176 node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "function"
177 ){ReadFunction(node, name);}
178 else if (
179 node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "entity"
180 ){
181 const auto old_name = GetString(node, "name");
182 const auto new_name = GetString(node, "new");
183 field_data_[name].entity_name_map[old_name] = new_name;
184 }
185 node = node->NextSibling();
186 }
187 }
188
195 void ReadFunction(TiXmlNode* node, const std::string& field_name){
196 const auto entity_name = GetString(node, "entity_name");
197 const auto old_name = GetString(node, "name");
198 const auto new_name = GetString(node, "new");
199 const auto comment = GetString(node, "Comment");
200 field_data_[field_name].function_map[entity_name][old_name]
201 = std::make_pair(new_name, comment);
202 }
203
209 void ReadEntityNames(TiXmlNode* node){
210 while (node){
211 if (node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "entity"){
212 const auto old_name = GetString(node, "name");
213 const auto new_name = GetString(node, "new");
214 entity_name_map_[old_name] = new_name;
215 }
216 node = node->NextSibling();
217 }
218 }
219
225 void ReadVarNames(TiXmlNode* node){
226 while (node){
227 if (node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "var"){
228 const auto bank = GetInt(node, "Bank");
229 const auto address = GetInt(node, "Address");
230 const auto name = GetString(node, "Name");
231 var_map_[bank][address] = name;
232 }
233 node = node->NextSibling();
234 }
235 }
236
242 void ReadCharacterIds(TiXmlNode* node){
243 while (node){
244 if (node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "char"){
245 const auto id = GetInt(node, "Id");
246 const auto name = GetString(node, "Name");
247 character_ids_[id] = name;
248 }
249 node = node->NextSibling();
250 }
251 }
252
266 std::pair<String,String> FieldScriptFunctionData(
267 const String& field_name, const String& entity_name, const String& old_function_name
268 ){
269 // Find a collection of field data for this field.
270 auto field_iterator = field_data_.find(field_name);
271 if (field_iterator != std::end(field_data_)){
272 // See if there is any info for this entity.
273 auto entity_iterator = field_iterator->second.function_map.find(entity_name);
274 if (entity_iterator != std::end(field_iterator->second.function_map)){
275 // See if there is any info for this function in
276 // this entity.
277 auto function_iterator = entity_iterator->second.find(old_function_name);
278 if (function_iterator != std::end(entity_iterator->second))
279 return function_iterator->second;
280 }
281 }
282 return std::make_pair("", "");
283 }
284
285
286 typedef std::map<String, String> LookupMap;
287
292
297
301 std::map<int, String> character_ids_;
302
306 std::map<int, std::map<int, String>> var_map_;
307
312
317
324 std::map<String, std::map<String, std::pair<String,String>>> function_map;
325
332 };
333 std::map<String, FieldMetaData> field_data_;
334
335 friend class NameLookup;
336
337 };
338
343
344 public:
345
349 NameLookup() = delete;
350
354 static String CharName(int char_id){
355 auto it = Data().character_ids_.find(char_id);
356 if (it != std::end(Data().character_ids_)) return it->second;
357 // Empty becomes lua "nil" value for this special case:
358 if (char_id == 254) return "";
359 return std::to_string(char_id);
360 }
361
373 static const String& Animation(const String &key){return Data().Animation(key);}
374
386 static const String& model(const String &key){return Data().Model(key);}
387
399 static String FieldScriptVarName(int bank, int addr){
400 auto bank_iterator = Data().var_map_.find(bank);
401 if (bank_iterator != std::end(Data().var_map_)){
402 auto address_iterator = bank_iterator->second.find(addr);
403 if (address_iterator != std::end(bank_iterator->second)){
404 if (address_iterator->second.empty() == false)
405 return address_iterator->second;
406 }
407 }
408 return "";
409 }
410
422 static String FieldScriptEntityName(const String& old_entity_name){
423 auto it = Data().entity_name_map_.find(old_entity_name);
424 if (it != std::end(Data().entity_name_map_)) return it->second;
425 return old_entity_name;
426 }
427
441 const String& field_name, const String& entity_name, const String& old_function_name
442 ){
444 field_name, entity_name, old_function_name
445 ).second;
446 }
447
464 const String& field_name, const String& entity_name, const String& old_function_name
465 ){
466 auto name = Data().FieldScriptFunctionData(
467 field_name, entity_name, old_function_name
468 ).first;
469 if (name.empty()) return old_function_name;
470 return name;
471 }
472
478 static FF7Metadata& Data(){
479 static FF7Metadata data("field_models_and_animation_metadata.xml");
480 return data;
481 }
482 };
483}
Handles Final Fantasy VII Metadata.
Definition: FF7NameLookup.h:30
std::pair< String, String > FieldScriptFunctionData(const String &field_name, const String &entity_name, const String &old_function_name)
Retrieves a field script function data.
Definition: FF7NameLookup.h:266
FF7Metadata(Ogre::String file)
Constructor.
Definition: FF7NameLookup.h:39
void ReadField(TiXmlNode *node, const std::string &name)
Reads field information from an XML node.
Definition: FF7NameLookup.h:173
void ReadVarNames(TiXmlNode *node)
Reads all variable names from an XML node.
Definition: FF7NameLookup.h:225
LookupMap entity_name_map_
Entity name map.
Definition: FF7NameLookup.h:311
void ReadModels(TiXmlNode *node)
Reads all models from an XML node.
Definition: FF7NameLookup.h:115
LookupMap models_
The list of models.
Definition: FF7NameLookup.h:291
std::map< int, std::map< int, String > > var_map_
Variable map.
Definition: FF7NameLookup.h:306
LookupMap animations_
The list of animations.
Definition: FF7NameLookup.h:296
std::map< String, FieldMetaData > field_data_
Definition: FF7NameLookup.h:333
void ReadCharacterIds(TiXmlNode *node)
Reads all character identifiers from an XML node.
Definition: FF7NameLookup.h:242
void ReadScripts(TiXmlNode *node)
Reads all scripts from an XML node.
Definition: FF7NameLookup.h:144
std::map< int, String > character_ids_
Character identifier map.
Definition: FF7NameLookup.h:301
const String & Animation(const String &key) const
Matches animation names.
Definition: FF7NameLookup.h:77
void ReadFunction(TiXmlNode *node, const std::string &field_name)
Reads a function of a field from an XML node.
Definition: FF7NameLookup.h:195
const String & Model(const String &key) const
Matches model names.
Definition: FF7NameLookup.h:98
void ReadAnimations(TiXmlNode *node)
Reads all models from an XML node.
Definition: FF7NameLookup.h:129
void ReadEntityNames(TiXmlNode *node)
Reads all entity from an XML node.
Definition: FF7NameLookup.h:209
std::map< String, String > LookupMap
Definition: FF7NameLookup.h:286
Name lookup convenience class.
Definition: FF7NameLookup.h:342
static String FieldScriptEntityName(const String &old_entity_name)
Matches entity names.
Definition: FF7NameLookup.h:422
static String FieldScriptVarName(int bank, int addr)
Retrieves a variable name.
Definition: FF7NameLookup.h:399
static String FieldScriptFunctionName(const String &field_name, const String &entity_name, const String &old_function_name)
Matches function names.
Definition: FF7NameLookup.h:463
static const String & Animation(const String &key)
Matches animation names.
Definition: FF7NameLookup.h:373
NameLookup()=delete
Constructor, not to use.
static FF7Metadata & Data()
Retrieves game metadata.
Definition: FF7NameLookup.h:478
static String CharName(int char_id)
Retrieves a character name from an ID.
Definition: FF7NameLookup.h:354
static const String & model(const String &key)
Matches model names.
Definition: FF7NameLookup.h:386
static String FieldScriptFunctionComment(const String &field_name, const String &entity_name, const String &old_function_name)
Matches function comments.
Definition: FF7NameLookup.h:440
static void splitBase(const String &name, String &basename)
Extract a file name without extension.
Definition: VGearsStringUtil.cpp:25
Handles XML files.
Definition: XmlFile.h:28
const Ogre::String GetString(TiXmlNode *node, const Ogre::String &tag, const Ogre::String &def="") const
Retrieves a string from an XMl tag.
Definition: XmlFile.cpp:56
int GetInt(TiXmlNode *node, const Ogre::String &tag, int def=0) const
Retrieves an integer from an XMl tag.
Definition: XmlFile.cpp:38
TiXmlDocument file_
The XML file.
Definition: XmlFile.h:189
Definition: FF7NameLookup.h:24
Ogre::String String
Definition: TypeDefine.h:37
A field metadata representation.
Definition: FF7NameLookup.h:316
std::map< String, std::map< String, std::pair< String, String > > > function_map
Function map.
Definition: FF7NameLookup.h:324
LookupMap entity_name_map
Entity name map.
Definition: FF7NameLookup.h:331