AGIDMGen 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. AGIDMGen/IDModGenService.py +300 -0
  2. AGIDMGen/__init__.py +78 -0
  3. AGIDMGen/__main__.py +24 -0
  4. AGIDMGen/constants/DXGIFormats.py +35 -0
  5. AGIDMGen/constants/DumpDataKinds.py +41 -0
  6. AGIDMGen/constants/FileEncodings.py +39 -0
  7. AGIDMGen/constants/GIMIBuffers.py +53 -0
  8. AGIDMGen/constants/GIMITextureLayouts.py +58 -0
  9. AGIDMGen/constants/ModDownloadRepos.py +45 -0
  10. AGIDMGen/constants/ModLoaders.py +33 -0
  11. AGIDMGen/constants/WWMIBuffers.py +95 -0
  12. AGIDMGen/constants/__init__.py +13 -0
  13. AGIDMGen/data/ModDownloadData.py +4519 -0
  14. AGIDMGen/data/__init__.py +13 -0
  15. AGIDMGen/exceptions/BadAssetData.py +31 -0
  16. AGIDMGen/exceptions/DownloadFailed.py +39 -0
  17. AGIDMGen/exceptions/Error.py +25 -0
  18. AGIDMGen/exceptions/UnknownDXGIFormat.py +37 -0
  19. AGIDMGen/exceptions/__init__.py +13 -0
  20. AGIDMGen/main.py +272 -0
  21. AGIDMGen/model/IDModGenStats.py +84 -0
  22. AGIDMGen/model/ModDownload.py +74 -0
  23. AGIDMGen/model/__init__.py +13 -0
  24. AGIDMGen/model/files/DumpDataType.py +144 -0
  25. AGIDMGen/model/files/DumpElement.py +109 -0
  26. AGIDMGen/model/files/FmtFile.py +161 -0
  27. AGIDMGen/model/files/IbDumpFile.py +119 -0
  28. AGIDMGen/model/files/VbDumpFile.py +217 -0
  29. AGIDMGen/model/files/__init__.py +13 -0
  30. AGIDMGen/model/gimi/GIMIComponent.py +112 -0
  31. AGIDMGen/model/gimi/GIMIIdentityMod.py +122 -0
  32. AGIDMGen/model/gimi/GIMITextureSource.py +145 -0
  33. AGIDMGen/model/gimi/__init__.py +13 -0
  34. AGIDMGen/model/wwmi/WWMIBlendRemap.py +54 -0
  35. AGIDMGen/model/wwmi/WWMIComponent.py +235 -0
  36. AGIDMGen/model/wwmi/WWMIDrawRange.py +93 -0
  37. AGIDMGen/model/wwmi/WWMIIdentityMod.py +201 -0
  38. AGIDMGen/model/wwmi/WWMIMesh.py +94 -0
  39. AGIDMGen/model/wwmi/WWMIShapeKeys.py +101 -0
  40. AGIDMGen/model/wwmi/__init__.py +13 -0
  41. AGIDMGen/py.typed +0 -0
  42. AGIDMGen/tools/DumpValueTools.py +120 -0
  43. AGIDMGen/tools/FormatTools.py +58 -0
  44. AGIDMGen/tools/ModDownloader.py +300 -0
  45. AGIDMGen/tools/VersionTools.py +108 -0
  46. AGIDMGen/tools/__init__.py +13 -0
  47. AGIDMGen/tools/gimi/GIMIDownloadFolderBuilder.py +187 -0
  48. AGIDMGen/tools/gimi/GIMIIdentityModGenerator.py +553 -0
  49. AGIDMGen/tools/gimi/GIMIIniBuilder.py +153 -0
  50. AGIDMGen/tools/gimi/__init__.py +13 -0
  51. AGIDMGen/tools/wwmi/WWMIDownloadFolderBuilder.py +113 -0
  52. AGIDMGen/tools/wwmi/WWMIIdentityModGenerator.py +853 -0
  53. AGIDMGen/tools/wwmi/WWMIIniBuilder.py +284 -0
  54. AGIDMGen/tools/wwmi/__init__.py +13 -0
  55. agidmgen-0.1.0.dist-info/METADATA +259 -0
  56. agidmgen-0.1.0.dist-info/RECORD +59 -0
  57. agidmgen-0.1.0.dist-info/WHEEL +5 -0
  58. agidmgen-0.1.0.dist-info/licenses/LICENSE +21 -0
  59. agidmgen-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,300 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ import os
14
+ from typing import Any, List, Optional, Union
15
+ from FixRaidenBoss2 import BaseLogger, Model
16
+ ##### EndExtImports
17
+
18
+
19
+ ##### LocalImports
20
+ from .constants.ModLoaders import ModLoaders
21
+ from .exceptions.Error import Error
22
+ from .model.IDModGenStats import IDModGenStats
23
+ from .tools.ModDownloader import ModDownloader
24
+ from .tools.gimi.GIMIIdentityModGenerator import GIMIIdentityModGenerator
25
+ from .tools.wwmi.WWMIIdentityModGenerator import WWMIIdentityModGenerator
26
+ ##### EndLocalImports
27
+
28
+
29
+ ##### Script
30
+ class IDModGenService(Model):
31
+ """
32
+ The library's entry point: generates the identity mods of several characters at once, from their asset
33
+ folders or from their download folders, and reports what it did
34
+
35
+ It is the model half, with no user interface of its own: progress and the summary go to the
36
+ :attr:`logger` (nothing is reported without one), and the results are in :attr:`stats`. A character that
37
+ cannot be generated does not stop the others: its exception is recorded in :attr:`IDModGenStats.skipped`.
38
+
39
+ .. note::
40
+ Like Anime Game Remap's ``RemapService``, :meth:`generate` returns nothing; read :attr:`stats` after it.
41
+ For one character, a generator (:class:`GIMIIdentityModGenerator` or :class:`WWMIIdentityModGenerator`)
42
+ can be used directly instead, and raises when it fails.
43
+
44
+ Examples
45
+ --------
46
+ .. code-block:: python
47
+ :linenos:
48
+
49
+ import AGIDMGen as IDMG
50
+ import FixRaidenBoss2 as FRB # Anime Game Remap's API: its logger serves both libraries
51
+
52
+ # every character's newest download folder, printed as it goes
53
+ service = IDMG.IDModGenService(IDMG.ModLoaders.GIMI, names = ["Yelan", "Ayaka"], outputFolder = "Mods", logger = FRB.Logger())
54
+ service.generate()
55
+ print(sorted(service.stats.generated), service.stats.skipped)
56
+
57
+ # from asset folders, collecting the output instead of printing it (eg. in a server)
58
+ logger = FRB.Logger(logTxt = True, verbose = False)
59
+ service = IDMG.IDModGenService(IDMG.ModLoaders.WWMI, assetsFolders = ["WWMI-Assets/PlayerCharacterData/Sanhua"], logger = logger)
60
+ service.generate()
61
+ print(logger.loggedTxt)
62
+
63
+ Parameters
64
+ ----------
65
+ loader: :class:`ModLoaders`
66
+ The mod loader the mods are for
67
+
68
+ assetsFolders: Optional[List[:class:`str`]]
69
+ The characters' asset folders to generate from. If this value is ``None``, no asset folder is used :raw-html:`<br />` :raw-html:`<br />`
70
+
71
+ **Default**: ``None``
72
+
73
+ names: Optional[List[:class:`str`]]
74
+ The characters to generate from their download folders (see :meth:`ModDownloader.getName`). If this value is ``None``, no download folder is used :raw-html:`<br />` :raw-html:`<br />`
75
+
76
+ **Default**: ``None``
77
+
78
+ outputFolder: Optional[:class:`str`]
79
+ The folder each mod is written into, as ``<outputFolder>/<name>``. If this value is ``None``, the current folder is used :raw-html:`<br />` :raw-html:`<br />`
80
+
81
+ **Default**: ``None``
82
+
83
+ version: Optional[:class:`str`]
84
+ The game version wanted for the download folders (see :meth:`ModDownloader.find`). If this value is ``None``, the newest :raw-html:`<br />` :raw-html:`<br />`
85
+
86
+ **Default**: ``None``
87
+
88
+ downloader: Optional[:class:`ModDownloader`]
89
+ What downloads the download folders. If this value is ``None``, one that downloads every file :raw-html:`<br />` :raw-html:`<br />`
90
+
91
+ **Default**: ``None``
92
+
93
+ downloadFolder: Optional[:class:`str`]
94
+ The folder to keep the downloaded files in, as ``<downloadFolder>/<name>``. If this value is ``None``, temporary folders are used :raw-html:`<br />` :raw-html:`<br />`
95
+
96
+ **Default**: ``None``
97
+
98
+ generator: Optional[Union[:class:`GIMIIdentityModGenerator`, :class:`WWMIIdentityModGenerator`]]
99
+ The generator, with its options. If this value is ``None``, one for ``loader`` with its default options :raw-html:`<br />` :raw-html:`<br />`
100
+
101
+ **Default**: ``None``
102
+
103
+ modName: Optional[:class:`str`]
104
+ The name of the character in the mod, when there is only one character. If this value is ``None``, the generator's default :raw-html:`<br />` :raw-html:`<br />`
105
+
106
+ **Default**: ``None``
107
+
108
+ assetPrefix: Optional[:class:`str`]
109
+ What a GIMI asset folder's files start with, when there is only one asset folder (see :meth:`GIMIIdentityModGenerator.generate`) :raw-html:`<br />` :raw-html:`<br />`
110
+
111
+ **Default**: ``None``
112
+
113
+ handleExceptions: :class:`bool`
114
+ Whether a failure of the whole run (eg. options that contradict each other) is reported to the logger and :meth:`generate` returns, rather than raised :raw-html:`<br />` :raw-html:`<br />`
115
+
116
+ **Default**: ``False``
117
+
118
+ logger: Optional[:class:`BaseLogger`]
119
+ Where the run reports progress. If this value is ``None``, nothing is reported :raw-html:`<br />` :raw-html:`<br />`
120
+
121
+ **Default**: ``None``
122
+
123
+ Attributes
124
+ ----------
125
+ loader: :class:`ModLoaders`
126
+ The mod loader the mods are for
127
+
128
+ assetsFolders: List[:class:`str`]
129
+ The characters' asset folders to generate from
130
+
131
+ names: List[:class:`str`]
132
+ The characters to generate from their download folders
133
+
134
+ outputFolder: :class:`str`
135
+ The folder each mod is written into
136
+
137
+ version: Optional[:class:`str`]
138
+ The game version wanted for the download folders
139
+
140
+ downloader: :class:`ModDownloader`
141
+ What downloads the download folders
142
+
143
+ downloadFolder: Optional[:class:`str`]
144
+ The folder to keep the downloaded files in
145
+
146
+ generator: Union[:class:`GIMIIdentityModGenerator`, :class:`WWMIIdentityModGenerator`]
147
+ The generator
148
+
149
+ modName: Optional[:class:`str`]
150
+ The name of the character in the mod, when there is only one character
151
+
152
+ assetPrefix: Optional[:class:`str`]
153
+ What a GIMI asset folder's files start with, when there is only one asset folder
154
+
155
+ handleExceptions: :class:`bool`
156
+ Whether a failure of the whole run is reported rather than raised
157
+ """
158
+
159
+ def __init__(self, loader: ModLoaders, assetsFolders: Optional[List[str]] = None, names: Optional[List[str]] = None, outputFolder: Optional[str] = None,
160
+ version: Optional[str] = None, downloader: Optional[ModDownloader] = None, downloadFolder: Optional[str] = None,
161
+ generator: Optional[Union[GIMIIdentityModGenerator, WWMIIdentityModGenerator]] = None, modName: Optional[str] = None,
162
+ assetPrefix: Optional[str] = None, handleExceptions: bool = False, logger: Optional[BaseLogger] = None):
163
+ super().__init__(logger = logger)
164
+ self.loader = loader
165
+ self.assetsFolders = [] if (assetsFolders is None) else list(assetsFolders)
166
+ self.names = [] if (names is None) else list(names)
167
+ self.outputFolder = os.getcwd() if (outputFolder is None) else outputFolder
168
+ self.version = version
169
+ self.downloader = ModDownloader(logger = logger) if (downloader is None) else downloader
170
+ self.downloadFolder = downloadFolder
171
+ self.generator = generator
172
+ self.modName = modName
173
+ self.assetPrefix = assetPrefix
174
+ self.handleExceptions = handleExceptions
175
+ self._stats = IDModGenStats()
176
+
177
+ @property
178
+ def stats(self) -> IDModGenStats:
179
+ """
180
+ What the last :meth:`generate` did
181
+
182
+ :getter: Retrieves the stats
183
+ :type: :class:`IDModGenStats`
184
+ """
185
+
186
+ return self._stats
187
+
188
+ def _getGenerator(self) -> Union[GIMIIdentityModGenerator, WWMIIdentityModGenerator]:
189
+ expected = GIMIIdentityModGenerator if (self.loader == ModLoaders.GIMI) else WWMIIdentityModGenerator
190
+ if (self.generator is None):
191
+ return expected(logger = self.logger)
192
+ if (not isinstance(self.generator, expected)):
193
+ raise Error(f"a {type(self.generator).__name__} cannot generate {self.loader.value} mods")
194
+ if (self.generator.logger is None):
195
+ self.generator.logger = self.logger
196
+ return self.generator
197
+
198
+ def _checkOptions(self):
199
+ sourceCount = len(self.assetsFolders) + len(self.names)
200
+ if (sourceCount == 0):
201
+ raise Error("there is nothing to generate: give asset folders or character names")
202
+ if (self.modName is not None and sourceCount > 1):
203
+ raise Error("a mod name can only be given for one character")
204
+ if (self.assetPrefix is not None and (len(self.assetsFolders) != 1 or self.names)):
205
+ raise Error("an asset prefix can only be given for one asset folder")
206
+ if (self.assetPrefix is not None and self.loader != ModLoaders.GIMI):
207
+ raise Error("an asset prefix is only for GIMI asset folders")
208
+
209
+ def _reportException(self, error: BaseException):
210
+ # the library's own errors explain themselves; anything else is a bug, and gets its traceback
211
+ if (isinstance(error, Error)):
212
+ self.print("error", str(error))
213
+ else:
214
+ self.print("handleException", error)
215
+
216
+ def _generateOne(self, generator, label: str, generate) -> Optional[Any]:
217
+ self.print("openHeading", label, sideLen = 5)
218
+ try:
219
+ mod = generate()
220
+ except Exception as e:
221
+ self._stats.addSkipped(label, e)
222
+ self._reportException(e)
223
+ self.print("closeHeading")
224
+ return None
225
+
226
+ self._stats.addGenerated(label, mod)
227
+ for line in mod.getSummary():
228
+ self.print("log", line)
229
+ self.print("closeHeading")
230
+ self.print("space")
231
+ return mod
232
+
233
+ def generate(self):
234
+ """
235
+ Generates the identity mods, then reports what was done
236
+
237
+ Raises
238
+ ------
239
+ :class:`Error`
240
+ If the options contradict each other, and :attr:`handleExceptions` is ``False``
241
+ """
242
+
243
+ self._stats.clear()
244
+ try:
245
+ self._checkOptions()
246
+ generator = self._getGenerator()
247
+ except Exception as e:
248
+ if (not self.handleExceptions):
249
+ raise
250
+ self._reportException(e)
251
+ return
252
+
253
+ prevPrefix = None if (self.logger is None) else self.logger.prefix
254
+ for assetsFolder in self.assetsFolders:
255
+ label = os.path.basename(os.path.normpath(assetsFolder))
256
+ if (self.logger is not None):
257
+ self.logger.prefix = label
258
+
259
+ kwargs = {"name": self.modName}
260
+ if (self.loader == ModLoaders.GIMI):
261
+ kwargs["assetPrefix"] = self.assetPrefix
262
+ modFolder = os.path.join(self.outputFolder, self.modName if (self.modName is not None) else label)
263
+ self._generateOne(generator, label, lambda: generator.generate(assetsFolder, modFolder, **kwargs))
264
+
265
+ for name in self.names:
266
+ if (self.logger is not None):
267
+ self.logger.prefix = name
268
+
269
+ modFolder = os.path.join(self.outputFolder, self.modName if (self.modName is not None) else name)
270
+ downloadFolder = None if (self.downloadFolder is None) else os.path.join(self.downloadFolder, name)
271
+ self._generateOne(generator, name, lambda: generator.generateFromRepo(name, modFolder, version = self.version, downloader = self.downloader,
272
+ downloadFolder = downloadFolder, modName = self.modName))
273
+
274
+ if (self.logger is not None):
275
+ self.logger.prefix = prevPrefix
276
+ self.report()
277
+
278
+ def report(self):
279
+ """
280
+ Reports the summary of the last :meth:`generate` to the logger
281
+ """
282
+
283
+ if (self.logger is None):
284
+ return
285
+
286
+ includePrefix = self.logger.includePrefix
287
+ self.logger.includePrefix = False
288
+ self.print("openHeading", "Summary", sideLen = 10)
289
+ self.print("log", f"Generated {len(self._stats.generated)} identity mod(s) into {self.outputFolder}")
290
+ if (self._stats.skipped):
291
+ self.print("log", f"Could not generate {len(self._stats.skipped)}:")
292
+ for name, error in self._stats.skipped.items():
293
+ self.print("bulletPoint", f"{name}: {error}")
294
+ self.print("closeHeading")
295
+
296
+ if (self._stats.noErrors):
297
+ self.print("space")
298
+ self.print("log", "ENJOY")
299
+ self.logger.includePrefix = includePrefix
300
+ ##### EndScript
AGIDMGen/__init__.py ADDED
@@ -0,0 +1,78 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+ ##### LocalImports
12
+
13
+ # --- Constants --------
14
+ from .constants.DumpDataKinds import DumpDataKinds
15
+ from .constants.DXGIFormats import DXGIFormats, DXGIFormatPrefix
16
+ from .constants.FileEncodings import FileEncodings, IniFileEncoding, ReadEncodings
17
+ from .constants.GIMIBuffers import GIMIBuffers, GIMISemanticBuffers, GIMIFixedStrides, GIMIHashFileSuffix
18
+ from .constants.GIMITextureLayouts import GIMITextureLayouts
19
+ from .constants.ModDownloadRepos import ModDownloadRepos, ModDownloadGameFolders
20
+ from .constants.ModLoaders import ModLoaders
21
+
22
+ # --- Data --------
23
+ from .data.ModDownloadData import ModDownloadData, ModDownloadAliases
24
+ from .constants.WWMIBuffers import WWMIBuffers, WWMIBlendRemapBuffers, WWMIShapeKeySlots, WWMIBlendRemapSize, WWMIBlendIndexLimit, WWMIDownloadNames, WWMIDownloadTextureSuffix
25
+
26
+ # --- Exceptions --------
27
+ from .exceptions.Error import Error
28
+ from .exceptions.BadAssetData import BadAssetData
29
+ from .exceptions.DownloadFailed import DownloadFailed
30
+ from .exceptions.UnknownDXGIFormat import UnknownDXGIFormat
31
+
32
+ # --- Model --------
33
+ from .model.IDModGenStats import IDModGenStats
34
+ from .model.ModDownload import ModDownload
35
+ from .model.files.DumpDataType import DumpDataType
36
+ from .model.files.DumpElement import DumpElement
37
+ from .model.files.FmtFile import FmtFile
38
+ from .model.files.IbDumpFile import IbDumpFile
39
+ from .model.files.VbDumpFile import VbDumpFile
40
+ from .model.gimi.GIMIComponent import GIMIComponent
41
+ from .model.gimi.GIMIIdentityMod import GIMIIdentityMod
42
+ from .model.gimi.GIMITextureSource import GIMITextureSource
43
+ from .model.wwmi.WWMIBlendRemap import WWMIBlendRemap
44
+ from .model.wwmi.WWMIComponent import WWMIComponent
45
+ from .model.wwmi.WWMIDrawRange import WWMIDrawRange
46
+ from .model.wwmi.WWMIMesh import WWMIMesh
47
+ from .model.wwmi.WWMIIdentityMod import WWMIIdentityMod
48
+ from .model.wwmi.WWMIShapeKeys import WWMIShapeKeys
49
+
50
+ # --- Tools --------
51
+ from .tools.DumpValueTools import DumpValueTools
52
+ from .tools.FormatTools import FormatTools
53
+ from .tools.ModDownloader import ModDownloader
54
+ from .tools.VersionTools import VersionTools
55
+ from .tools.gimi.GIMIDownloadFolderBuilder import GIMIDownloadFolderBuilder
56
+ from .tools.gimi.GIMIIniBuilder import GIMIIniBuilder
57
+ from .tools.gimi.GIMIIdentityModGenerator import GIMIIdentityModGenerator
58
+ from .tools.wwmi.WWMIDownloadFolderBuilder import WWMIDownloadFolderBuilder
59
+ from .tools.wwmi.WWMIIniBuilder import WWMIIniBuilder
60
+ from .tools.wwmi.WWMIIdentityModGenerator import WWMIIdentityModGenerator, WWMITexturePattern
61
+
62
+ # --- Service --------
63
+ from .IDModGenService import IDModGenService
64
+
65
+ ##### EndLocalImports
66
+
67
+
68
+ __all__ = ["IDModGenService", "IDModGenStats",
69
+ "DumpDataKinds", "GIMIBuffers", "GIMISemanticBuffers", "GIMIFixedStrides", "GIMITextureLayouts",
70
+ "DumpDataType", "DumpElement", "IbDumpFile", "VbDumpFile", "GIMIComponent", "GIMIIdentityMod", "GIMITextureSource",
71
+ "DumpValueTools", "GIMIIniBuilder", "GIMIIdentityModGenerator", "GIMIDownloadFolderBuilder", "WWMIDownloadFolderBuilder",
72
+ "ModDownloadRepos", "ModDownloadGameFolders", "ModDownloadData", "ModDownloadAliases", "DownloadFailed", "ModDownload", "ModDownloader", "VersionTools",
73
+ "GIMIHashFileSuffix", "WWMIDownloadNames", "WWMIDownloadTextureSuffix", "WWMIDrawRange", "WWMIMesh",
74
+ "DXGIFormats", "DXGIFormatPrefix", "FileEncodings", "IniFileEncoding", "ReadEncodings", "ModLoaders",
75
+ "WWMIBuffers", "WWMIBlendRemapBuffers", "WWMIShapeKeySlots", "WWMIBlendRemapSize", "WWMIBlendIndexLimit",
76
+ "Error", "BadAssetData", "UnknownDXGIFormat",
77
+ "FmtFile", "WWMIBlendRemap", "WWMIComponent", "WWMIIdentityMod", "WWMIShapeKeys",
78
+ "FormatTools", "WWMIIniBuilder", "WWMIIdentityModGenerator", "WWMITexturePattern"]
AGIDMGen/__main__.py ADDED
@@ -0,0 +1,24 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ import sys
14
+ ##### EndExtImports
15
+
16
+
17
+ ##### LocalImports
18
+ from .main import main
19
+ ##### EndLocalImports
20
+
21
+
22
+ ##### Script
23
+ sys.exit(main())
24
+ ##### EndScript
@@ -0,0 +1,35 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ from typing import Dict, Tuple
14
+ ##### EndExtImports
15
+
16
+
17
+ ##### Script
18
+ #: The prefix of the full name of a DXGI format
19
+ DXGIFormatPrefix = "DXGI_FORMAT_"
20
+
21
+ # The DXGI formats a buffer element may be declared with, and how each one is decoded: the numpy dtype
22
+ # of one channel and the number of channels.
23
+ #
24
+ # note: this is a dict and not an Enum on purpose -- several formats decode the same way
25
+ # (R8G8B8A8_UINT and R8G8B8A8_UNORM), and an Enum would make those aliases of one member
26
+
27
+ #: The DXGI formats a buffer element can be decoded from (without the ``DXGI_FORMAT_`` prefix), each with the numpy dtype of one channel and the number of channels
28
+ DXGIFormats: Dict[str, Tuple[str, int]] = {
29
+ "R32G32B32A32_FLOAT": ("<f4", 4), "R32G32B32_FLOAT": ("<f4", 3), "R32G32_FLOAT": ("<f4", 2), "R32_FLOAT": ("<f4", 1),
30
+ "R16G16B16A16_FLOAT": ("<f2", 4), "R16G16B16_FLOAT": ("<f2", 3), "R16G16_FLOAT": ("<f2", 2), "R16_FLOAT": ("<f2", 1),
31
+ "R8G8B8A8_UINT": ("u1", 4), "R8G8B8A8_UNORM": ("u1", 4), "R8G8B8A8_SNORM": ("i1", 4), "R8G8B8_SNORM": ("i1", 3), "R8_SNORM": ("i1", 1), "R8_UINT": ("u1", 1), "R8_UNORM": ("u1", 1),
32
+ "R16G16B16A16_UINT": ("<u2", 4), "R16G16B16A16_UNORM": ("<u2", 4), "R16G16_UNORM": ("<u2", 2), "R16_UINT": ("<u2", 1),
33
+ "R32G32B32A32_UINT": ("<u4", 4), "R32_UINT": ("<u4", 1),
34
+ }
35
+ ##### EndScript
@@ -0,0 +1,41 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ from enum import Enum
14
+ ##### EndExtImports
15
+
16
+
17
+ ##### Script
18
+ class DumpDataKinds(Enum):
19
+ """
20
+ The kinds of value one channel of a buffer element can hold, as named by the suffix of its DXGI format
21
+
22
+ Attributes
23
+ ----------
24
+ Float: :class:`str`
25
+ A floating point number (``FLOAT``)
26
+
27
+ SignedInt: :class:`str`
28
+ A signed integer (``SINT``)
29
+
30
+ UnsignedInt: :class:`str`
31
+ An unsigned integer (``UINT``)
32
+
33
+ Unorm: :class:`str`
34
+ An unsigned number from 0 to 1, stored as an unsigned integer scaled to its largest value (``UNORM``)
35
+ """
36
+
37
+ Float = "FLOAT"
38
+ SignedInt = "SINT"
39
+ UnsignedInt = "UINT"
40
+ Unorm = "UNORM"
41
+ ##### EndScript
@@ -0,0 +1,39 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ from enum import Enum
14
+ ##### EndExtImports
15
+
16
+
17
+ ##### Script
18
+ class FileEncodings(Enum):
19
+ """
20
+ The text encodings used when reading and writing the files of a mod
21
+
22
+ Attributes
23
+ ----------
24
+ UTF8: :class:`str`
25
+ The `utf-8` encoding
26
+
27
+ Latin1: :class:`str`
28
+ The `latin1` encoding
29
+ """
30
+
31
+ UTF8 = "utf-8"
32
+ Latin1 = "latin1"
33
+
34
+
35
+ #: The encoding a ``.ini`` file is written in
36
+ IniFileEncoding = FileEncodings.UTF8.value
37
+ #: The encodings tried, in order, when reading a text file
38
+ ReadEncodings = [IniFileEncoding, FileEncodings.Latin1.value]
39
+ ##### EndScript
@@ -0,0 +1,53 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ from enum import Enum
14
+ from typing import Dict
15
+ ##### EndExtImports
16
+
17
+
18
+ ##### Script
19
+ class GIMIBuffers(Enum):
20
+ """
21
+ The vertex buffers of one component of a GIMI mod, in the order GIMI lays a vertex out. Each one is
22
+ written to ``<name><component><buffer>.buf``
23
+
24
+ Attributes
25
+ ----------
26
+ Position: :class:`str`
27
+ The ``POSITION``, ``NORMAL`` and ``TANGENT`` of the vertices
28
+
29
+ Blend: :class:`str`
30
+ The ``BLENDWEIGHT(S)`` and ``BLENDINDICES`` of the vertices
31
+
32
+ Texcoord: :class:`str`
33
+ The ``COLOR`` and ``TEXCOORD`` (``TEXCOORD1``, ...) of the vertices
34
+ """
35
+
36
+ Position = "Position"
37
+ Blend = "Blend"
38
+ Texcoord = "Texcoord"
39
+
40
+
41
+ #: The buffer each element of a dumped vertex belongs to, by its semantic name
42
+ GIMISemanticBuffers: Dict[str, GIMIBuffers] = {
43
+ "POSITION": GIMIBuffers.Position, "NORMAL": GIMIBuffers.Position, "TANGENT": GIMIBuffers.Position,
44
+ "BLENDWEIGHT": GIMIBuffers.Blend, "BLENDWEIGHTS": GIMIBuffers.Blend, "BLENDINDICES": GIMIBuffers.Blend,
45
+ "COLOR": GIMIBuffers.Texcoord, "TEXCOORD": GIMIBuffers.Texcoord
46
+ }
47
+
48
+ #: The number of bytes per vertex GIMI fixes for a buffer. The Texcoord buffer's is not fixed: it is 20 with a second UV set and 12 without, and can differ between the components of one character
49
+ GIMIFixedStrides: Dict[GIMIBuffers, int] = {GIMIBuffers.Position: 40, GIMIBuffers.Blend: 32}
50
+
51
+ #: What the name of a download folder's copy of the asset folder's ``hash.json`` ends with: ``<prefix>Hash.json``
52
+ GIMIHashFileSuffix = "Hash.json"
53
+ ##### EndScript
@@ -0,0 +1,58 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ from enum import Enum
14
+ from typing import Tuple
15
+ ##### EndExtImports
16
+
17
+
18
+ ##### Script
19
+ class GIMITextureLayouts(Enum):
20
+ """
21
+ The two layouts a GIMI mod binds an object's textures in, chosen by whether the object's shader reads a
22
+ normal map. Each value is the (register, texture kind) pairs of the layout, and the command list of
23
+ ``ORFix`` that moves the textures to the registers the shader actually reads
24
+
25
+ Attributes
26
+ ----------
27
+ NormalMap: Tuple[Tuple[Tuple[:class:`str`, :class:`str`], ...], :class:`str`]
28
+ ``ps-t0`` normal map, ``ps-t1`` diffuse and ``ps-t2`` light map, fixed by ``ORFix``
29
+
30
+ Plain: Tuple[Tuple[Tuple[:class:`str`, :class:`str`], ...], :class:`str`]
31
+ ``ps-t0`` diffuse and ``ps-t1`` light map, fixed by ``NNFix``
32
+ """
33
+
34
+ NormalMap = ((("ps-t0", "NormalMap"), ("ps-t1", "Diffuse"), ("ps-t2", "LightMap")), "CommandList\\global\\ORFix\\ORFix")
35
+ Plain = ((("ps-t0", "Diffuse"), ("ps-t1", "LightMap")), "CommandList\\global\\ORFix\\NNFix")
36
+
37
+ @property
38
+ def registers(self) -> Tuple[Tuple[str, str], ...]:
39
+ """
40
+ The (register, texture kind) pairs of the layout
41
+
42
+ :getter: Retrieves the registers
43
+ :type: Tuple[Tuple[:class:`str`, :class:`str`], ...]
44
+ """
45
+
46
+ return self.value[0]
47
+
48
+ @property
49
+ def fixCommand(self) -> str:
50
+ """
51
+ The command list that moves the layout's textures to the registers the shader reads
52
+
53
+ :getter: Retrieves the command list
54
+ :type: :class:`str`
55
+ """
56
+
57
+ return self.value[1]
58
+ ##### EndScript
@@ -0,0 +1,45 @@
1
+ ##### Credits
2
+
3
+ # ===== Anime Game Identity Mod Generator (AGIDMGen) =====
4
+ # Authors: Albert Gold#2696
5
+ #
6
+ # A sub-project of Anime Game Remap (AG Remap)
7
+ # if you used it to make your mods pls give credit for "Albert Gold#2696"
8
+
9
+ ##### EndCredits
10
+
11
+
12
+ ##### ExtImports
13
+ from enum import Enum
14
+ from typing import Dict
15
+ ##### EndExtImports
16
+
17
+
18
+ ##### LocalImports
19
+ from .ModLoaders import ModLoaders
20
+ ##### EndLocalImports
21
+
22
+
23
+ ##### Script
24
+ class ModDownloadRepos(Enum):
25
+ """
26
+ The repositories that hold characters' download folders, in the order they are searched: a file Anime
27
+ Game Remap has is taken from Anime Game Remap, so it is never kept twice. Each value is the address of
28
+ the repository's ``Data/Mod Downloads`` folder
29
+
30
+ Attributes
31
+ ----------
32
+ AGRemap: :class:`str`
33
+ `Anime Game Remap <https://github.com/nhok0169/Anime-Game-Remap>`_'s download folders
34
+
35
+ AGIDMGen: :class:`str`
36
+ This library's own download folders, for what Anime Game Remap does not have
37
+ """
38
+
39
+ AGRemap = "https://github.com/nhok0169/Anime-Game-Remap/raw/master/Data/Mod%20Downloads"
40
+ AGIDMGen = "https://github.com/Alex-Au1/Anime-Game-Identity-Mod-Generator/raw/main/Data/Mod%20Downloads"
41
+
42
+
43
+ #: The folder of each mod loader's game in ``Data/Mod Downloads``
44
+ ModDownloadGameFolders: Dict[ModLoaders, str] = {ModLoaders.GIMI: "GI", ModLoaders.WWMI: "WuWa"}
45
+ ##### EndScript