diff --git a/README.md b/README.md
index 4393dd8..0ccc35f 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,65 @@
- ```
-• ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+```
+ • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+ ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+ ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+ ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+ ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+ Magicbane Emulator Project © 2013 - 2022
+ www.magicbane.com
+```
+
+# mbEditorPro v 2.0
+
+![Example Output](https://cdn.discordapp.com/attachments/399623779531096074/1029063849640468550/unknown.png)
+
+Team Magicbane presents to the community technology allowing MagicBox administrators
+to fully modify their game using nothing more than notepad.exe.
+
+- Tool directly converts Shadowbane .cache files to and from a high fidelity pure JSON representation.
+- Enumerations are used throughout hiding from the user ugly signed ulong values.
+- Written in Python and open-source allowing modification and extension with ease.
+- Want to raise all weapon damage by x%; Just modify item values as they are being parsed!
- Magicbane Emulator Project © 2013 - 2022
- www.magicbane.com
+The tool built with Edltirch Technologies parses all Shadowbane .cache files giving the user complete control over the game
+
+Team Magicbane aims to deliver you the best crackhead free MMO technology around; all for free!
+
+### Usage:
+```
+mbEditorPro.py unpack cobjects
+mbEditorPro.py unpack all
+```
+JSON output will be in a folder **ARCANE DUMP**
+
+```
+mbEditorPro.py pack textures
+mbEditorPro.py pack all
```
-This repository holds the source code for mbEditorPro along with other tooling and data required to give every MagicBox administrator the ability to fully modify the game as they see fit.
\ No newline at end of file
+New binary cache file will be built from the JSON and output in the current directory.
>
+
+> note: Unpacked data from a 2008 cache file is available in the Data repo. Build a new cache file right out of the box.
+
+### Limitations
+
+Hirelings, ZoneEvents and Mobile Inventory are not parsed or written as there were no
+examples in the .cache files to begin with. The game does seem to support them, however.
+
+### JSON
+
+The tool generating pure JSON has the following benefits:
+
+- It's ubiquitous and the tooling is mature. The standard interop exchange format.
+- Human and machine-readable.
+- Ease of importing into MySQL or other databases.
+- Use as an intermediate representation to build a GUI World Editor or FBX importer.
+
+### Future
+
+mbEditorPro will be the cornerstone of Magicbane's data project. The Team's goal is threefold:
+
+- Ship MagicBox 1.5 with both Aerynth and Vorringia mapsets available.
+- Integrate Magicbane's wpak extractor technology into the tool
+
+
+
diff --git a/mbEditorPro/arcane/__init__.py b/mbEditorPro/arcane/__init__.py
deleted file mode 100644
index 584dceb..0000000
--- a/mbEditorPro/arcane/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
diff --git a/mbEditorPro/arcane/enums/__init__.py b/mbEditorPro/arcane/enums/__init__.py
deleted file mode 100644
index 584dceb..0000000
--- a/mbEditorPro/arcane/enums/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
diff --git a/mbEditorPro/arcane/enums/common/__init__.py b/mbEditorPro/arcane/enums/common/__init__.py
deleted file mode 100644
index 584dceb..0000000
--- a/mbEditorPro/arcane/enums/common/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
diff --git a/mbEditorPro/arcane/enums/common/arc_inventory.py b/mbEditorPro/arcane/enums/common/arc_inventory.py
deleted file mode 100644
index 0ddd452..0000000
--- a/mbEditorPro/arcane/enums/common/arc_inventory.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-INVENTORY_TYPE_GOLD = 1
-INVENTORY_TYPE_ITEM = 2
-INVENTORY_TYPE_BOOTYTABLE = 3
-
-INVENTORY_TYPE_TO_STRING = {
- INVENTORY_TYPE_GOLD: 'GOLD',
- INVENTORY_TYPE_ITEM: 'ITEM',
- INVENTORY_TYPE_BOOTYTABLE: 'BOOTYTABLE',
-}
-
-STRING_TO_INVENTORY_TYPE = {
- 'GOLD': INVENTORY_TYPE_GOLD,
- 'ITEM': INVENTORY_TYPE_ITEM,
- 'BOOTYTABLE': INVENTORY_TYPE_BOOTYTABLE,
-}
diff --git a/mbEditorPro/arcane/enums/hashes/__init__.py b/mbEditorPro/arcane/enums/hashes/__init__.py
deleted file mode 100644
index afc97b5..0000000
--- a/mbEditorPro/arcane/enums/hashes/__init__.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-import glob
-import os
-
-from arcane.util.hasher import hash_string
-
-_STRING_TO_HASH = {}
-_HASH_TO_STRING = {}
-
-
-def load_files():
- directory = os.path.dirname(__file__)
-
- for filepath in glob.glob(os.path.join(directory, '*.txt')):
- lines = list(map(lambda s: s.strip(), open(filepath).readlines()))
-
- _STRING_TO_HASH.update({
- s: hash_string(s) for s in lines
- })
-
- _HASH_TO_STRING.update({
- hash_string(s): s for s in lines
- })
-
-
-def string_to_hash(s):
- return _STRING_TO_HASH.get(s, s)
-
-
-def hash_to_string(h):
- return _HASH_TO_STRING.get(h, h)
-
-
-load_files()
diff --git a/mbEditorPro/arcane/enums/zone/arc_mobile.py b/mbEditorPro/arcane/enums/zone/arc_mobile.py
deleted file mode 100644
index 46c86d5..0000000
--- a/mbEditorPro/arcane/enums/zone/arc_mobile.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-MOBILE = 1
-BANKER = 2
-SHOPKEEPER = 3
-TRAINER = 4
-MERCHANT = 8
-HIRELING = 9
-PET = 10
-MINION = 11
-
-MOBILE_TO_STRING = {
- MOBILE: 'MOBILE',
- BANKER: 'BANKER',
- SHOPKEEPER: 'SHOPKEEPER',
- TRAINER: 'TRAINER',
- MERCHANT: 'MERCHANT',
- HIRELING: 'HIRELING',
- PET: 'PET',
- MINION: 'MINION',
-}
-
-STRING_TO_MOBILE = {
- 'MOBILE': MOBILE,
- 'BANKER': BANKER,
- 'SHOPKEEPER': SHOPKEEPER,
- 'TRAINER': TRAINER,
- 'MERCHANT': MERCHANT,
- 'HIRELING': HIRELING,
- 'PET': PET,
- 'MINION': MINION,
-}
diff --git a/mbEditorPro/arcane/enums/zone/arc_prop.py b/mbEditorPro/arcane/enums/zone/arc_prop.py
deleted file mode 100644
index b352b28..0000000
--- a/mbEditorPro/arcane/enums/zone/arc_prop.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-PROP = 5
-CITY = 6
-CONTAINER = 7
-
-PROP_TO_STRING = {
- PROP: 'PROP',
- CITY: 'CITY',
- CONTAINER: 'CONTAINER',
-}
-
-STRING_TO_PROP = {
- 'PROP': PROP,
- 'CITY': CITY,
- 'CONTAINER': CONTAINER,
-}
diff --git a/mbEditorPro/arcane/enums/zone/arc_terraingen.py b/mbEditorPro/arcane/enums/zone/arc_terraingen.py
deleted file mode 100644
index 816be5d..0000000
--- a/mbEditorPro/arcane/enums/zone/arc_terraingen.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-PEAKED = 1
-RIDGED = 2
-ROLLING = 3
-MESA = 5
-PLANAR = 4
-MESH = 6
-TARGA = 7
-
-TERRAIN_TYPE_TO_STRING = {
- PEAKED: 'PEAKED',
- RIDGED: 'RIDGED',
- ROLLING: 'ROLLING',
- MESA: 'MESA',
- PLANAR: 'PLANAR',
- MESH: 'MESH',
- TARGA: 'TARGA',
-}
-
-STRING_TO_TERRAIN_TYPE = {
- 'PEAKED': PEAKED,
- 'RIDGED': RIDGED,
- 'ROLLING': ROLLING,
- 'MESA': MESA,
- 'PLANAR': PLANAR,
- 'MESH': MESH,
- 'TARGA': TARGA,
-}
diff --git a/mbEditorPro/arcane/enums/zone/arc_zone.py b/mbEditorPro/arcane/enums/zone/arc_zone.py
deleted file mode 100644
index 57991a7..0000000
--- a/mbEditorPro/arcane/enums/zone/arc_zone.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-ELLIPTICAL = 0
-RECTANGULAR = 1
-
-ZONE_TO_STRING = {
- ELLIPTICAL: 'ELLIPTICAL',
- RECTANGULAR: 'RECTANGULAR',
-}
-
-STRING_TO_ZONE = {
- 'ELLIPTICAL': ELLIPTICAL,
- 'RECTANGULAR': RECTANGULAR,
-}
-
-GLOBAL = 0
-LOCAL = 1
-
-TILECOORD_TO_STRING = {
- GLOBAL: 'GLOBAL',
- LOCAL: 'LOCAL',
-}
-
-STRING_TO_TILECOORD = {
- 'GLOBAL': GLOBAL,
- 'LOCAL': LOCAL,
-}
-
-ADJACENT = 0
-RANDOM = 1
-
-PATTERN_TO_STRING = {
- ADJACENT: 'ADJACENT',
- RANDOM: 'RANDOM',
-}
-
-STRING_TO_PATTERN = {
- 'ADJACENT': ADJACENT,
- 'RANDOM': RANDOM,
-}
-
-PARENT = 0
-WORLD = 1
-SELF = 2
-
-SEALEVEL_TO_STRING = {
- PARENT: 'PARENT',
- WORLD: 'WORLD',
- SELF: 'SELF',
-}
-
-STRING_TO_SEALEVEL = {
- 'PARENT': PARENT,
- 'WORLD': WORLD,
- 'SELF': SELF,
-}
diff --git a/mbEditorPro/arcane/objects/ArcAssetStructureObject.py b/mbEditorPro/arcane/objects/ArcAssetStructureObject.py
deleted file mode 100644
index 3eb74cc..0000000
--- a/mbEditorPro/arcane/objects/ArcAssetStructureObject.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-from arcane.util import ResStream
-from .ArcStructureObject import ArcStructureObject
-
-
-class ArcAssetStructureObject(ArcStructureObject):
- def load_binary(self, stream: ResStream):
- super().load_binary(stream)
- self.asset_structure_template_id = stream.read_qword()
-
- def save_binary(self, stream: ResStream):
- super().save_binary(stream)
- stream.write_qword(self.asset_structure_template_id)
-
- def load_json(self, data):
- super().load_json(data)
- self.asset_structure_template_id = data['asset_structure_template_id']
-
- def save_json(self):
- data = super().save_json()
- data['asset_structure_template_id'] = self.asset_structure_template_id
- return data
diff --git a/mbEditorPro/arcane/objects/__init__.py b/mbEditorPro/arcane/objects/__init__.py
deleted file mode 100644
index 9205487..0000000
--- a/mbEditorPro/arcane/objects/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-from .ArcAssetStructureObject import ArcAssetStructureObject
-from .ArcCityAssetTemplate import ArcCityAssetTemplate
-from .ArcCombatObj import ArcCombatObj, ArcCharacter
-from .ArcContainerObject import ArcContainerObject
-from .ArcDeed import ArcDeed
-from .ArcDoorObject import ArcDoorObject
-from .ArcDungeonUnitObject import ArcDungeonUnitObject, ArcDungeonExitObject, ArcDungeonStairObject
-from .ArcItem import ArcItem
-from .ArcKey import ArcKey
-from .ArcObj import ArcObj
-from .ArcRune import ArcRune
-from .ArcStaticObject import ArcStaticObject
-from .ArcStructureObject import ArcStructureObject
diff --git a/mbEditorPro/arcane/objects/common/Discipline.py b/mbEditorPro/arcane/objects/common/Discipline.py
deleted file mode 100644
index f9e2223..0000000
--- a/mbEditorPro/arcane/objects/common/Discipline.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-from collections import OrderedDict
-
-from arcane.enums.hashes import hash_to_string, string_to_hash
-from arcane.util import ResStream
-
-
-class DiscRequired:
- def load_binary(self, stream: ResStream):
- discs = stream.read_dword()
- self.disc_restrict = stream.read_bool()
- self.disc_values = [
- stream.read_dword() for _ in range(discs)
- ]
-
- def save_binary(self, stream: ResStream):
- stream.write_dword(len(self.disc_values))
- stream.write_bool(self.disc_restrict)
- for disc in self.disc_values:
- stream.write_dword(disc)
-
- def load_json(self, data):
- self.disc_restrict = data['restrict']
- self.disc_values = []
- for disc in data['disces']:
- self.disc_values.append(string_to_hash(disc))
-
- def save_json(self):
- data = OrderedDict()
- data['restrict'] = self.disc_restrict
- data['disces'] = []
- for disc in self.disc_values:
- data['disces'].append(hash_to_string(disc))
- return data
diff --git a/mbEditorPro/arcane/objects/common/Race.py b/mbEditorPro/arcane/objects/common/Race.py
deleted file mode 100644
index 7f3be75..0000000
--- a/mbEditorPro/arcane/objects/common/Race.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-from collections import OrderedDict
-
-from arcane.enums.hashes import hash_to_string, string_to_hash
-from arcane.util import ResStream
-
-
-class RaceRequired:
- def load_binary(self, stream: ResStream):
- races = stream.read_dword()
- self.race_restrict = stream.read_bool()
- self.race_values = [
- stream.read_dword() for _ in range(races)
- ]
-
- def save_binary(self, stream: ResStream):
- stream.write_dword(len(self.race_values))
- stream.write_bool(self.race_restrict)
- for race in self.race_values:
- stream.write_dword(race)
-
- def load_json(self, data):
- self.race_restrict = data['restrict']
- self.race_values = []
- for race in data['racees']:
- self.race_values.append(string_to_hash(race))
-
- def save_json(self):
- data = OrderedDict()
- data['restrict'] = self.race_restrict
- data['racees'] = []
- for race in self.race_values:
- data['racees'].append(hash_to_string(race))
- return data
diff --git a/mbEditorPro/arcane/objects/common/__init__.py b/mbEditorPro/arcane/objects/common/__init__.py
deleted file mode 100644
index 584dceb..0000000
--- a/mbEditorPro/arcane/objects/common/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
diff --git a/mbEditorPro/arcane/util/__init__.py b/mbEditorPro/arcane/util/__init__.py
deleted file mode 100644
index b10ad96..0000000
--- a/mbEditorPro/arcane/util/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-from .ArcFileCache import load_cache_file, save_cache_file
-from .ResStream import ResStream
diff --git a/mbEditorPro/arcane/zones/ArcDungeonInfo.py b/mbEditorPro/arcane/zones/ArcDungeonInfo.py
deleted file mode 100644
index b06a516..0000000
--- a/mbEditorPro/arcane/zones/ArcDungeonInfo.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-from collections import OrderedDict
-
-from arcane.util import ResStream
-
-
-class ArcDungeonInfo:
- def load_binary(self, stream: ResStream):
- self.dungeon_template_id = stream.read_qword()
- self.dungeon_unkown = stream.read_qword()
- self.dungeon_spawn_location = stream.read_tuple()
- self.dungeon_y_offset = stream.read_float()
-
- def save_binary(self, stream: ResStream):
- stream.write_qword(self.dungeon_template_id)
- stream.write_qword(self.dungeon_unkown)
- stream.write_tuple(self.dungeon_spawn_location)
- stream.write_float(self.dungeon_y_offset)
-
- def save_json(self):
- data = OrderedDict()
- data['dungeon_template_id'] = self.dungeon_template_id
- data['dungeon_unkown'] = self.dungeon_unkown
- data['dungeon_spawn_location'] = self.dungeon_spawn_location
- data['dungeon_y_offset'] = self.dungeon_y_offset
- return data
-
- def load_json(self, data):
- self.dungeon_template_id = data['dungeon_template_id']
- self.dungeon_unkown = data['dungeon_unkown']
- self.dungeon_spawn_location = data['dungeon_spawn_location']
- self.dungeon_y_offset = data['dungeon_y_offset']
diff --git a/mbEditorPro/arcane/zones/__init__.py b/mbEditorPro/arcane/zones/__init__.py
deleted file mode 100644
index 4ee99ac..0000000
--- a/mbEditorPro/arcane/zones/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-from .ArcZone import ArcZone
diff --git a/mbEditorPro/arcane/zones/mobile/MinionInfo.py b/mbEditorPro/arcane/zones/mobile/MinionInfo.py
deleted file mode 100644
index f54e80e..0000000
--- a/mbEditorPro/arcane/zones/mobile/MinionInfo.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-from arcane.util import ResStream
-from .HirelingInfo import HirelingInfo
-
-
-class MinionInfo(HirelingInfo):
- def __init__(self):
- super().__init__()
- self.minion_info_u = None
-
- def load_binary(self, stream: ResStream):
- super().load_binary(stream)
- self.minion_info_u = stream.read_string()
diff --git a/mbEditorPro/arcane/zones/mobile/__init__.py b/mbEditorPro/arcane/zones/mobile/__init__.py
deleted file mode 100644
index 584dceb..0000000
--- a/mbEditorPro/arcane/zones/mobile/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
diff --git a/mbEditorPro/mbEditorPro.py b/mbEditorPro/mbEditorPro.py
deleted file mode 100644
index a164c59..0000000
--- a/mbEditorPro/mbEditorPro.py
+++ /dev/null
@@ -1,223 +0,0 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
-
-import glob
-import json
-import os
-import sys
-
-from arcane.enums.arc_object import *
-from arcane.objects import *
-from arcane.util import *
-from arcane.zones import *
-
-DUMP_DIRECTORY = 'ARCANE_DUMP'
-WORKING_DIRECTORY = os.path.dirname(__file__)
-TARGET_DIRECTORY = os.path.join(WORKING_DIRECTORY, DUMP_DIRECTORY)
-COBJECTS_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'COBJECTS')
-CZONE_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'CZONE')
-COBJECTS_MAGIC = 0x434c4e54
-
-COBJECTS_MAP = {
- OBJECT_TYPE_LIGHT: ArcObj,
- OBJECT_TYPE_DOOR: ArcDoorObject,
- OBJECT_TYPE_STATIC: ArcStaticObject,
- OBJECT_TYPE_STRUCTURE: ArcStructureObject,
- OBJECT_TYPE_ASSETSTRUCTURE: ArcAssetStructureObject,
- OBJECT_TYPE_DUNGEONUNIT: ArcDungeonUnitObject,
- OBJECT_TYPE_DUNGEONEXIT: ArcDungeonExitObject,
- OBJECT_TYPE_DUNGEONSTAIR: ArcDungeonStairObject,
- OBJECT_TYPE_ITEM: ArcItem,
- OBJECT_TYPE_PLAYER: ArcCharacter,
- OBJECT_TYPE_MOBILE: ArcCharacter,
- OBJECT_TYPE_RUNE: ArcRune,
- OBJECT_TYPE_CONTAINER: ArcContainerObject,
- OBJECT_TYPE_DEED: ArcDeed,
- OBJECT_TYPE_KEY: ArcKey,
- OBJECT_TYPE_ASSET: ArcCityAssetTemplate,
- OBJECT_TYPE_OBJECT: ArcObj,
-}
-
-
-def init_cobjects():
- for type in COBJECTS_MAP:
- directory_path = os.path.join(COBJECTS_DIRECTORY, OBJECT_TYPE_TO_STRING[type])
- os.makedirs(directory_path, exist_ok=True)
-
-
-def init_czones():
- directory_path = CZONE_DIRECTORY
- os.makedirs(directory_path, exist_ok=True)
-
-
-def unpack_cobjects():
- init_cobjects()
-
- resources = load_cache_file('CObjects.cache')
-
- for res_id, data in resources:
- in_stream = ResStream(data)
- magic = in_stream.read_dword()
- obj_type = in_stream.read_dword()
-
- arc_object = COBJECTS_MAP[obj_type]()
- filepath = os.path.join(
- COBJECTS_DIRECTORY,
- OBJECT_TYPE_TO_STRING[obj_type],
- f'{res_id:020d}.json'
- )
- arc_object.load_binary(in_stream)
- parsed = arc_object.save_json()
- with open(filepath, 'w') as fp:
- json.dump(parsed, fp, indent=2)
-
-
-def pack_cobjects():
- init_cobjects()
-
- resources = []
- for obj_type in COBJECTS_MAP:
- directory = os.path.join(
- COBJECTS_DIRECTORY,
- OBJECT_TYPE_TO_STRING[obj_type]
- )
- for filepath in glob.glob(os.path.join(directory, '*.json')):
- filename = os.path.basename(filepath)
- res_id = int(filename.split('.json')[0])
- json_data = json.load(open(filepath))
-
- out_stream = ResStream()
- out_stream.write_dword(COBJECTS_MAGIC)
- out_stream.write_dword(obj_type)
-
- arc_object = COBJECTS_MAP[obj_type]()
- try:
- arc_object.load_json(json_data)
- arc_object.save_binary(out_stream)
- except:
- print(res_id)
- raise
-
- resources.append([res_id, out_stream.get_bytes()])
-
- save_cache_file('CObjects.cache.new', resources)
-
-
-def test_cobjects():
- resources = load_cache_file('CObjects.cache')
-
- for res_id, data in resources:
- in_stream = ResStream(data)
- out_stream = ResStream()
-
- magic = in_stream.read_dword()
- o_type = in_stream.read_dword()
- out_stream.write_dword(magic)
- out_stream.write_dword(o_type)
-
- arc_in = COBJECTS_MAP[o_type]()
- arc_out = COBJECTS_MAP[o_type]()
-
- arc_in.load_binary(in_stream)
- parsed = arc_in.save_json()
- arc_out.load_json(parsed)
- arc_out.save_binary(out_stream)
- try:
- assert in_stream.get_bytes() == out_stream.get_bytes()
- except:
- print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
- print()
-
-
-def unpack_czones():
- init_czones()
-
- resources = load_cache_file('CZone.cache')
-
- for res_id, data in resources:
- arc_zone = ArcZone()
- in_stream = ResStream(data)
- filepath = os.path.join(
- CZONE_DIRECTORY,
- f'{res_id:020d}.json'
- )
- arc_zone.load_binary(in_stream)
- parsed = arc_zone.save_json()
- with open(filepath, 'w') as fp:
- json.dump(parsed, fp, indent=2)
-
-
-def pack_czones():
- init_czones()
-
- resources = []
- directory = CZONE_DIRECTORY
- for filepath in glob.glob(os.path.join(directory, '*.json')):
- filename = os.path.basename(filepath)
- res_id = int(filename.split('.json')[0])
- json_data = json.load(open(filepath))
-
- out_stream = ResStream()
- arc_object = ArcZone()
- try:
- arc_object.load_json(json_data)
- arc_object.save_binary(out_stream)
- except:
- print(res_id)
- raise
-
- resources.append([res_id, out_stream.get_bytes()])
-
- save_cache_file('CZone.cache.new', resources)
-
-
-def test_czones():
- resources = load_cache_file('CZone.cache')
- for res_id, data in resources:
- in_stream = ResStream(data)
- out_stream = ResStream()
-
- arc_in = ArcZone()
- arc_out = ArcZone()
-
- arc_in.load_binary(in_stream)
- parsed = arc_in.save_json()
- arc_out.load_json(parsed)
- arc_out.save_binary(out_stream)
- try:
- assert in_stream.get_bytes() == out_stream.get_bytes()
- except:
- print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
- print()
-
-
-def usage():
- print('mbEditorPro commands:')
- print('usage: {} unpack cobjects'.format(sys.argv[0]))
- print('usage: {} pack cobjects'.format(sys.argv[0]))
- print('usage: {} unpack czones'.format(sys.argv[0]))
- print('usage: {} pack czones'.format(sys.argv[0]))
- exit(1)
-
-
-def main():
- if not sys.argv[2:]:
- usage()
-
- if sys.argv[1] not in ['pack', 'unpack']:
- usage()
-
- if sys.argv[2] not in ['cobjects', 'czones']:
- usage()
-
- method = '_'.join(sys.argv[1:3]) + '()'
- print(method)
- exec(method)
-
-
-main()
diff --git a/mbEditorPro/LICENSE b/mbEditorPro2.0/LICENSE
similarity index 100%
rename from mbEditorPro/LICENSE
rename to mbEditorPro2.0/LICENSE
diff --git a/mbEditorPro/README.md b/mbEditorPro2.0/README.md
similarity index 81%
rename from mbEditorPro/README.md
rename to mbEditorPro2.0/README.md
index f00d99e..0ccc35f 100644
--- a/mbEditorPro/README.md
+++ b/mbEditorPro2.0/README.md
@@ -8,34 +8,32 @@
www.magicbane.com
```
-# mbEditorPro v 1.0
+# mbEditorPro v 2.0
![Example Output](https://cdn.discordapp.com/attachments/399623779531096074/1029063849640468550/unknown.png)
Team Magicbane presents to the community technology allowing MagicBox administrators
to fully modify their game using nothing more than notepad.exe.
-- Tool directly converts Shadowbane .cache files to and from a high fidality pure JSON representation.
+- Tool directly converts Shadowbane .cache files to and from a high fidelity pure JSON representation.
- Enumerations are used throughout hiding from the user ugly signed ulong values.
- Written in Python and open-source allowing modification and extension with ease.
- Want to raise all weapon damage by x%; Just modify item values as they are being parsed!
-The tool currently parses both the CObject.cache and the Czones.cache files. These were chosen
-to start with as they will allow a MagicBox administrator to modify the game. The remainder of the
-existing .cache files modify how the game looks and will be added soon.
+The tool built with Edltirch Technologies parses all Shadowbane .cache files giving the user complete control over the game
Team Magicbane aims to deliver you the best crackhead free MMO technology around; all for free!
### Usage:
```
mbEditorPro.py unpack cobjects
-mbEditorPro.py unpack czones
+mbEditorPro.py unpack all
```
JSON output will be in a folder **ARCANE DUMP**
```
-mbEditorPro.py pack cobjects
-mbEditorPro.py pack czones
+mbEditorPro.py pack textures
+mbEditorPro.py pack all
```
New binary cache file will be built from the JSON and output in the current directory.
>
@@ -60,9 +58,8 @@ The tool generating pure JSON has the following benefits:
mbEditorPro will be the cornerstone of Magicbane's data project. The Team's goal is threefold:
-- Build tooling to generate high fidality Magicbane databases from the JSON data.
-- Build up the tool and technology to parse the remaining .cache file.
-- Ship MagicBox 1.5 with both Aerynth and Vorringia mapsets available.
+- Ship MagicBox 1.5 with both Aerynth and Vorringia mapsets available.
+- Integrate Magicbane's wpak extractor technology into the tool
diff --git a/mbEditorPro2.0/arcane/ArcImage.py b/mbEditorPro2.0/arcane/ArcImage.py
new file mode 100644
index 0000000..5841828
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcImage.py
@@ -0,0 +1,70 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from PIL import Image, ImageOps
+
+from arcane.util import ResStream
+
+
+class ArcTexture:
+ VALUE_TO_MODE = {
+ (4, 8, 2): 'RGBA',
+ (3, 0, 0): 'RGB',
+ (1, 0, 0): 'L',
+ (1, 8, 2): 'P',
+ }
+
+ MODE_TO_VALUE = {value: key for key, value in VALUE_TO_MODE.items()}
+
+ def load_binary(self, stream: ResStream):
+ self.image_width = stream.read_dword()
+ self.image_height = stream.read_dword()
+ self.image_color_depth = stream.read_dword()
+ self.image_alpha = stream.read_dword()
+ self.image_type = stream.read_dword()
+ self.image_compressed = stream.read_bool()
+ self.image_linear = stream.read_bool()
+ data_size = stream.read_dword()
+ self.image_data = stream.read_bytes(data_size)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.image_width)
+ stream.write_dword(self.image_height)
+ stream.write_dword(self.image_color_depth)
+ stream.write_dword(self.image_alpha)
+ stream.write_dword(self.image_type)
+ stream.write_bool(self.image_compressed)
+ stream.write_bool(self.image_linear)
+ stream.write_dword(len(self.image_data))
+ stream.write_bytes(self.image_data)
+
+ def load_img(self, filepath):
+ img = Image.open(filepath)
+ img = ImageOps.mirror(img).rotate(180)
+ self.image_width = img.width
+ self.image_height = img.height
+ self.image_color_depth, self.image_alpha, self.image_type = self.MODE_TO_VALUE[img.mode]
+ self.image_compressed = True
+ self.image_linear = True
+ self.image_data = img.tobytes()
+
+ def save_img(self, filepath):
+ mode = self.VALUE_TO_MODE[
+ (self.image_color_depth, self.image_alpha, self.image_type)
+ ]
+ img = Image.frombytes(mode, (self.image_width, self.image_height), self.image_data)
+ img = ImageOps.mirror(img.rotate(180))
+ img.save(filepath)
+
+
+class ArcTerrain(ArcTexture):
+ VALUE_TO_MODE = {
+ (1, 1, 0): 'P',
+ }
+
+ MODE_TO_VALUE = {value: key for key, value in VALUE_TO_MODE.items()}
diff --git a/mbEditorPro2.0/arcane/ArcMesh.py b/mbEditorPro2.0/arcane/ArcMesh.py
new file mode 100644
index 0000000..ebbcc91
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcMesh.py
@@ -0,0 +1,113 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+
+class ArcMesh:
+ def load_binary(self, stream: ResStream):
+ self.mesh_name = stream.read_string()
+ self.mesh_distance = stream.read_float()
+ self.mesh_start_point = stream.read_tuple()
+ self.mesh_end_point = stream.read_tuple()
+ self.mesh_ref_point = stream.read_tuple()
+ self.mesh_use_face_normals = stream.read_bool()
+ self.mesh_use_tangent_basis = stream.read_bool()
+ num_vertices = stream.read_dword()
+ self.mesh_vertices = [stream.read_tuple() for _ in range(num_vertices)]
+ num_other_vertices = stream.read_dword()
+ self.mesh_normals = [stream.read_tuple() for _ in range(num_other_vertices)]
+ num = stream.read_dword()
+ self.mesh_uv = [
+ [
+ stream.read_float(),
+ stream.read_float(),
+ ] for _ in range(num)
+ ]
+ if self.mesh_use_tangent_basis:
+ num_tangent_vertices = stream.read_dword()
+ self.mesh_tanget_vertices = [stream.read_tuple() for _ in range(num_tangent_vertices)]
+ num_indicies = stream.read_dword()
+ self.mesh_indices = [stream.read_word() for _ in range(num_indicies)]
+ num = stream.read_dword()
+ self.mesh_extra_indices = [
+ [
+ stream.read_dword(),
+ stream.read_dword(),
+ [stream.read_word() for _ in range(stream.read_dword())],
+ ] for _ in range(num)
+ ]
+
+ def save_binary(self, stream: ResStream):
+ stream.write_string(self.mesh_name)
+ stream.write_float(self.mesh_distance)
+ stream.write_tuple(self.mesh_start_point)
+ stream.write_tuple(self.mesh_end_point)
+ stream.write_tuple(self.mesh_ref_point)
+ stream.write_bool(self.mesh_use_face_normals)
+ stream.write_bool(self.mesh_use_tangent_basis)
+ stream.write_dword(len(self.mesh_vertices))
+ for i in range(len(self.mesh_vertices)):
+ stream.write_tuple(self.mesh_vertices[i])
+ stream.write_dword(len(self.mesh_normals))
+ for i in range(len(self.mesh_normals)):
+ stream.write_tuple(self.mesh_normals[i])
+ stream.write_dword(len(self.mesh_uv))
+ for i in range(len(self.mesh_uv)):
+ stream.write_float(self.mesh_uv[i][0])
+ stream.write_float(self.mesh_uv[i][1])
+ if self.mesh_use_tangent_basis:
+ stream.write_dword(len(self.mesh_tanget_vertices))
+ for i in range(len(self.mesh_tanget_vertices)):
+ stream.write_tuple(self.mesh_tanget_vertices[i])
+ stream.write_dword(len(self.mesh_indices))
+ for i in range(len(self.mesh_indices)):
+ stream.write_word(self.mesh_indices[i])
+ stream.write_dword(len(self.mesh_extra_indices))
+ for i in range(len(self.mesh_extra_indices)):
+ stream.write_dword(self.mesh_extra_indices[i][0])
+ stream.write_dword(self.mesh_extra_indices[i][1])
+ stream.write_dword(len(self.mesh_extra_indices[i][2]))
+ for j in range(len(self.mesh_extra_indices[i][2])):
+ stream.write_word(self.mesh_extra_indices[i][2][j])
+
+ def load_json(self, data):
+ self.mesh_name = data['mesh_name']
+ self.mesh_distance = data['mesh_distance']
+ self.mesh_start_point = data['mesh_start_point']
+ self.mesh_end_point = data['mesh_end_point']
+ self.mesh_ref_point = data['mesh_ref_point']
+ self.mesh_use_face_normals = data['mesh_use_face_normals']
+ self.mesh_use_tangent_basis = data['mesh_use_tangent_basis']
+ self.mesh_vertices = data['mesh_vertices']
+ self.mesh_normals = data['mesh_normals']
+ self.mesh_uv = data['mesh_uv']
+ if self.mesh_use_tangent_basis:
+ self.mesh_tanget_vertices = data['mesh_tanget_vertices']
+ self.mesh_indices = data['mesh_indices']
+ self.mesh_extra_indices = data['mesh_extra_indices']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['mesh_name'] = self.mesh_name
+ data['mesh_distance'] = self.mesh_distance
+ data['mesh_start_point'] = self.mesh_start_point
+ data['mesh_end_point'] = self.mesh_end_point
+ data['mesh_ref_point'] = self.mesh_ref_point
+ data['mesh_use_face_normals'] = self.mesh_use_face_normals
+ data['mesh_use_tangent_basis'] = self.mesh_use_tangent_basis
+ data['mesh_vertices'] = self.mesh_vertices
+ data['mesh_normals'] = self.mesh_normals
+ data['mesh_uv'] = self.mesh_uv
+ if self.mesh_use_tangent_basis:
+ data['mesh_tanget_vertices'] = self.mesh_tanget_vertices
+ data['mesh_indices'] = self.mesh_indices
+ data['mesh_extra_indices'] = self.mesh_extra_indices
+ return data
diff --git a/mbEditorPro2.0/arcane/ArcMotion.py b/mbEditorPro2.0/arcane/ArcMotion.py
new file mode 100644
index 0000000..c2323d0
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcMotion.py
@@ -0,0 +1,89 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+
+class ArcMotion:
+ def load_binary(self, stream: ResStream):
+ self.motion_file = stream.read_string()
+ self.motion_smoothed_count = stream.read_dword()
+ self.motion_smoothed_value = stream.read_dword()
+ self.motion_smoothed_factor = stream.read_float()
+ self.motion_sound = stream.read_qword()
+ self.motion_sheath = stream.read_dword()
+ self.motion_reset_loc = stream.read_bool()
+ self.motion_leave_ground = stream.read_bool()
+ self.motion_force = stream.read_float()
+ self.motion_disable_blend = stream.read_bool()
+ num_parts = stream.read_dword()
+ self.motion_parts = [stream.read_string() for _ in range(num_parts)]
+ num_smoothing = stream.read_dword()
+ self.motion_smoothing = [
+ [
+ stream.read_float() for _ in range(10)
+ ] for _ in range(num_smoothing)
+ ]
+ num_target_frames = stream.read_dword()
+ self.motion_target_frames = [stream.read_dword() for _ in range(num_target_frames)]
+
+ def save_binary(self, stream: ResStream):
+ stream.write_string(self.motion_file)
+ stream.write_dword(self.motion_smoothed_count)
+ stream.write_dword(self.motion_smoothed_value)
+ stream.write_float(self.motion_smoothed_factor)
+ stream.write_qword(self.motion_sound)
+ stream.write_dword(self.motion_sheath)
+ stream.write_bool(self.motion_reset_loc)
+ stream.write_bool(self.motion_leave_ground)
+ stream.write_float(self.motion_force)
+ stream.write_bool(self.motion_disable_blend)
+ stream.write_dword(len(self.motion_parts))
+ for i in range(len(self.motion_parts)):
+ stream.write_string(self.motion_parts[i])
+ stream.write_dword(len(self.motion_smoothing))
+ for i in range(len(self.motion_smoothing)):
+ for j in range(10):
+ stream.write_float(self.motion_smoothing[i][j])
+ stream.write_dword(len(self.motion_target_frames))
+ for i in range(len(self.motion_target_frames)):
+ stream.write_dword(self.motion_target_frames[i])
+
+ def load_json(self, data):
+ self.motion_file = data['motion_file']
+ self.motion_smoothed_count = data['motion_smoothed_count']
+ self.motion_smoothed_value = data['motion_smoothed_value']
+ self.motion_smoothed_factor = data['motion_smoothed_factor']
+ self.motion_sound = data['motion_sound']
+ self.motion_sheath = data['motion_sheath']
+ self.motion_reset_loc = data['motion_reset_loc']
+ self.motion_leave_ground = data['motion_leave_ground']
+ self.motion_force = data['motion_force']
+ self.motion_disable_blend = data['motion_disable_blend']
+ self.motion_parts = data['motion_parts']
+ self.motion_smoothing = data['motion_smoothing']
+ self.motion_target_frames = data['motion_target_frames']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['motion_file'] = self.motion_file
+ data['motion_smoothed_count'] = self.motion_smoothed_count
+ data['motion_smoothed_value'] = self.motion_smoothed_value
+ data['motion_smoothed_factor'] = self.motion_smoothed_factor
+ data['motion_sound'] = self.motion_sound
+ data['motion_sheath'] = self.motion_sheath
+ data['motion_reset_loc'] = self.motion_reset_loc
+ data['motion_leave_ground'] = self.motion_leave_ground
+ data['motion_force'] = self.motion_force
+ data['motion_disable_blend'] = self.motion_disable_blend
+ data['motion_parts'] = self.motion_parts
+ data['motion_smoothing'] = self.motion_smoothing
+ data['motion_target_frames'] = self.motion_target_frames
+ return data
diff --git a/mbEditorPro2.0/arcane/ArcRender.py b/mbEditorPro2.0/arcane/ArcRender.py
new file mode 100644
index 0000000..62c43e8
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcRender.py
@@ -0,0 +1,644 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+TRACKER_TO_STRING = {
+ 0: 'NONE',
+ 1: 'XY',
+ 2: 'Y',
+}
+STRING_TO_TRACKER = {value: key for key, value in TRACKER_TO_STRING.items()}
+
+TRANSPARENT_TO_STRING = {
+ 0: 'NONE',
+ 1: 'PINK',
+ 2: 'BLACK',
+ 3: 'WHITE',
+ 4: 'SEMI',
+ 6: 'ALPHA',
+}
+STRING_TO_TRANSPARENT = {value: key for key, value in TRANSPARENT_TO_STRING.items()}
+
+TEXTURE_TO_STRING = {
+ 0: 'SINGLE_TEXTURE',
+ 1: 'COLOR_TEXTURE',
+ 3: 'ANIMATED_TEXTURE',
+}
+STRING_TO_TEXTURE = {value: key for key, value in TEXTURE_TO_STRING.items()}
+
+LIGHT_TYPE_TO_STRING = {
+ 0xb6787258: 'ArcLightPoint',
+ 0x54e8ff1d: 'ArcLightAffectorAttach',
+ 0xa73bd9d4: 'ArcLightAffectorFlicker',
+}
+STRING_TO_LIGHT_TYPE = {value: key for key, value in LIGHT_TYPE_TO_STRING.items()}
+
+
+class ArcSinglePolyMesh:
+ def load_binary(self, stream: ResStream):
+ self.polymesh_id = stream.read_qword()
+ self.polymesh_decal = stream.read_bool()
+ self.polymesh_double_sided = stream.read_bool()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_qword(self.polymesh_id)
+ stream.write_bool(self.polymesh_decal)
+ stream.write_bool(self.polymesh_double_sided)
+
+ def load_json(self, data):
+ self.polymesh_id = data['polymesh_id']
+ self.polymesh_decal = data['polymesh_decal']
+ self.polymesh_double_sided = data['polymesh_double_sided']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['polymesh_id'] = self.polymesh_id
+ data['polymesh_decal'] = self.polymesh_decal
+ data['polymesh_double_sided'] = self.polymesh_double_sided
+ return data
+
+
+class ArcMeshSet:
+ def load_binary(self, stream: ResStream):
+ num = stream.read_dword()
+ self.mesh_set = [ArcSinglePolyMesh() for _ in range(num)]
+ for mesh in self.mesh_set:
+ mesh.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(len(self.mesh_set))
+ for mesh in self.mesh_set:
+ mesh.save_binary(stream)
+
+ def load_json(self, data):
+ self.mesh_set = []
+ for mesh_data in data['mesh_set']:
+ mesh = ArcSinglePolyMesh()
+ mesh.load_json(mesh_data)
+ self.mesh_set.append(mesh)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['mesh_set'] = []
+ for mesh in self.mesh_set:
+ data['mesh_set'].append(mesh.save_json())
+ return data
+
+
+class ArcRenderTemplate:
+ def load_binary(self, stream: ResStream):
+ self.template_object_can_fade = stream.read_bool()
+ self.template_tracker = stream.read_dword()
+ self.template_illuminated = stream.read_bool()
+ self.template_bone_length = stream.read_float()
+ self.template_clip_map = stream.read_dword()
+ self.template_light_two_side = stream.read_dword()
+ self.template_cull_face = stream.read_dword()
+ self.template_specular_map = stream.read_qword()
+ self.template_shininess = stream.read_float()
+ self.template_has_mesh = stream.read_bool()
+ if self.template_has_mesh:
+ self.template_mesh = ArcMeshSet()
+ self.template_mesh.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_bool(self.template_object_can_fade)
+ stream.write_dword(self.template_tracker)
+ stream.write_bool(self.template_illuminated)
+ stream.write_float(self.template_bone_length)
+ stream.write_dword(self.template_clip_map)
+ stream.write_dword(self.template_light_two_side)
+ stream.write_dword(self.template_cull_face)
+ stream.write_qword(self.template_specular_map)
+ stream.write_float(self.template_shininess)
+ stream.write_bool(self.template_has_mesh)
+ if self.template_has_mesh:
+ self.template_mesh.save_binary(stream)
+
+ def load_json(self, data):
+ self.template_object_can_fade = data['template_object_can_fade']
+ self.template_tracker = STRING_TO_TRACKER[data['template_tracker']]
+ self.template_illuminated = data['template_illuminated']
+ self.template_bone_length = data['template_bone_length']
+ self.template_clip_map = data['template_clip_map']
+ self.template_light_two_side = data['template_light_two_side']
+ self.template_cull_face = data['template_cull_face']
+ self.template_specular_map = data['template_specular_map']
+ self.template_shininess = data['template_shininess']
+ self.template_has_mesh = data['template_has_mesh']
+ if self.template_has_mesh:
+ self.template_mesh = ArcMeshSet()
+ self.template_mesh.load_json(data['template_mesh'])
+
+ def save_json(self):
+ data = OrderedDict()
+ data['template_object_can_fade'] = self.template_object_can_fade
+ data['template_tracker'] = TRACKER_TO_STRING[self.template_tracker]
+ data['template_illuminated'] = self.template_illuminated
+ data['template_bone_length'] = self.template_bone_length
+ data['template_clip_map'] = self.template_clip_map
+ data['template_light_two_side'] = self.template_light_two_side
+ data['template_cull_face'] = self.template_cull_face
+ data['template_specular_map'] = self.template_specular_map
+ data['template_shininess'] = self.template_shininess
+ data['template_has_mesh'] = self.template_has_mesh
+ if self.template_has_mesh:
+ data['template_mesh'] = self.template_mesh.save_json()
+ return data
+
+
+class ArcSingleTexture:
+ def load_binary(self, stream: ResStream):
+ self.texture_id = stream.read_qword()
+ self.texture_transparent = stream.read_dword()
+ self.texture_compress = stream.read_bool()
+ self.texture_normal_map = stream.read_bool()
+ self.texture_detail_normal_map = stream.read_bool()
+ self.texture_create_mip_maps = stream.read_bool()
+ self.texture_x0 = stream.read_string()
+ self.texture_x1 = stream.read_string()
+ self.texture_x2 = stream.read_dword()
+ self.texture_x3 = stream.read_dword()
+ self.texture_x4 = stream.read_bool()
+ self.texture_wrap = stream.read_bool()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_qword(self.texture_id)
+ stream.write_dword(self.texture_transparent)
+ stream.write_bool(self.texture_compress)
+ stream.write_bool(self.texture_normal_map)
+ stream.write_bool(self.texture_detail_normal_map)
+ stream.write_bool(self.texture_create_mip_maps)
+ stream.write_string(self.texture_x0)
+ stream.write_string(self.texture_x1)
+ stream.write_dword(self.texture_x2)
+ stream.write_dword(self.texture_x3)
+ stream.write_bool(self.texture_x4)
+ stream.write_bool(self.texture_wrap)
+
+ def load_json(self, data):
+ self.texture_id = data['texture_id']
+ self.texture_transparent = STRING_TO_TRANSPARENT[data['texture_transparent']]
+ self.texture_compress = data['texture_compress']
+ self.texture_normal_map = data['texture_normal_map']
+ self.texture_detail_normal_map = data['texture_detail_normal_map']
+ self.texture_create_mip_maps = data['texture_create_mip_maps']
+ self.texture_x0 = ''
+ self.texture_x1 = ''
+ self.texture_x2 = 255
+ self.texture_x3 = 0
+ self.texture_x4 = False
+ self.texture_wrap = data['texture_wrap']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['texture_id'] = self.texture_id
+ data['texture_transparent'] = TRANSPARENT_TO_STRING[self.texture_transparent]
+ data['texture_compress'] = self.texture_compress
+ data['texture_normal_map'] = self.texture_normal_map
+ data['texture_detail_normal_map'] = self.texture_detail_normal_map
+ data['texture_create_mip_maps'] = self.texture_create_mip_maps
+ data['texture_wrap'] = self.texture_wrap
+ return data
+
+
+class ArcColorTexture(ArcSingleTexture):
+ pass
+
+
+class ArcAnimatedTexture:
+ def load_binary(self, stream: ResStream):
+ self.animated_texture_id = stream.read_qword()
+ self.animated_texture_transparent = stream.read_dword()
+ self.animated_texture_compress = stream.read_bool()
+ self.animated_texture_normal_map = stream.read_bool()
+ self.animated_texture_detail_normal_map = stream.read_bool()
+ self.animated_texture_create_mip_maps = stream.read_bool()
+ self.animated_texture_frame_timer = stream.read_float()
+ self.animated_texture_x0 = stream.read_float()
+ self.animated_texture_frame_rand = stream.read_dword()
+
+ num = stream.read_dword()
+ self.animated_texture_sets = [ArcTextureSet() for _ in range(num)]
+ for texture in self.animated_texture_sets:
+ texture.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_qword(self.animated_texture_id)
+ stream.write_dword(self.animated_texture_transparent)
+ stream.write_bool(self.animated_texture_compress)
+ stream.write_bool(self.animated_texture_normal_map)
+ stream.write_bool(self.animated_texture_detail_normal_map)
+ stream.write_bool(self.animated_texture_create_mip_maps)
+ stream.write_float(self.animated_texture_frame_timer)
+ stream.write_float(self.animated_texture_x0)
+ stream.write_dword(self.animated_texture_frame_rand)
+
+ stream.write_dword(len(self.animated_texture_sets))
+ for texture in self.animated_texture_sets:
+ texture.save_binary(stream)
+
+ def load_json(self, data):
+ self.animated_texture_id = data['animated_texture_id']
+ self.animated_texture_transparent = STRING_TO_TRANSPARENT[data['animated_texture_transparent']]
+ self.animated_texture_compress = data['animated_texture_compress']
+ self.animated_texture_normal_map = data['animated_texture_normal_map']
+ self.animated_texture_detail_normal_map = data['animated_texture_detail_normal_map']
+ self.animated_texture_create_mip_maps = data['animated_texture_create_mip_maps']
+ self.animated_texture_frame_timer = data['animated_texture_frame_timer']
+ self.animated_texture_x0 = 0.0
+ self.animated_texture_frame_rand = data['animated_texture_frame_rand']
+ self.animated_texture_sets = []
+ for texture_data in data['animated_texture_sets']:
+ texture = ArcTextureSet()
+ texture.load_json(texture_data)
+ self.animated_texture_sets.append(texture)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['animated_texture_id'] = self.animated_texture_id
+ data['animated_texture_transparent'] = TRANSPARENT_TO_STRING[self.animated_texture_transparent]
+ data['animated_texture_compress'] = self.animated_texture_compress
+ data['animated_texture_normal_map'] = self.animated_texture_normal_map
+ data['animated_texture_detail_normal_map'] = self.animated_texture_detail_normal_map
+ data['animated_texture_create_mip_maps'] = self.animated_texture_create_mip_maps
+ data['animated_texture_frame_timer'] = self.animated_texture_frame_timer
+ data['animated_texture_frame_rand'] = self.animated_texture_frame_rand
+ data['animated_texture_sets'] = []
+ for texture in self.animated_texture_sets:
+ data['animated_texture_sets'].append(texture.save_json())
+ return data
+
+
+class ArcTextureSet:
+ def load_binary(self, stream: ResStream):
+ self.texture_type = stream.read_dword()
+ if self.texture_type == 0:
+ self.texture_data = ArcSingleTexture()
+ elif self.texture_type == 1:
+ self.texture_data = ArcColorTexture()
+ elif self.texture_type == 3:
+ self.texture_data = ArcAnimatedTexture()
+ self.texture_data.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.texture_type)
+ self.texture_data.save_binary(stream)
+
+ def load_json(self, data):
+ self.texture_type = STRING_TO_TEXTURE[data['texture_type']]
+ if self.texture_type == 0:
+ self.texture_data = ArcSingleTexture()
+ elif self.texture_type == 1:
+ self.texture_data = ArcColorTexture()
+ elif self.texture_type == 3:
+ self.texture_data = ArcAnimatedTexture()
+ self.texture_data.load_json(data['texture_data'])
+
+ def save_json(self):
+ data = OrderedDict()
+ data['texture_type'] = TEXTURE_TO_STRING[self.texture_type]
+ data['texture_data'] = self.texture_data.save_json()
+ return data
+
+
+class ArcLightPoint:
+ def load_binary(self, stream: ResStream):
+ self.lightpoint_x0 = stream.read_dword()
+ self.lightpoint_x1 = stream.read_bool()
+ self.lightpoint_shader = stream.read_bool()
+ self.lightpoint_update_offscreen = stream.read_bool()
+ self.lightpoint_radius = stream.read_float()
+ self.lightpoint_position = stream.read_tuple()
+ self.lightpoint_diffuse_color = [stream.read_float() for _ in range(4)]
+ self.lightpoint_x2 = stream.read_dword()
+ self.lightpoint_orientation = [stream.read_float() for _ in range(4)]
+ self.lightpoint_cubemap = stream.read_dword()
+ self.lightpoint_x3 = stream.read_bool()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.lightpoint_x0)
+ stream.write_bool(self.lightpoint_x1)
+ stream.write_bool(self.lightpoint_shader)
+ stream.write_bool(self.lightpoint_update_offscreen)
+ stream.write_float(self.lightpoint_radius)
+ stream.write_tuple(self.lightpoint_position)
+ for i in range(4):
+ stream.write_float(self.lightpoint_diffuse_color[i])
+ stream.write_dword(self.lightpoint_x2)
+ for i in range(4):
+ stream.write_float(self.lightpoint_orientation[i])
+ stream.write_dword(self.lightpoint_cubemap)
+ stream.write_bool(self.lightpoint_x3)
+
+ def load_json(self, data):
+ self.lightpoint_x0 = 1
+ self.lightpoint_x1 = True
+ self.lightpoint_shader = data['lightpoint_shader']
+ self.lightpoint_update_offscreen = data['lightpoint_update_offscreen']
+ self.lightpoint_radius = data['lightpoint_radius']
+ self.lightpoint_position = data['lightpoint_position']
+ self.lightpoint_diffuse_color = data['lightpoint_diffuse_color']
+ self.lightpoint_x2 = 1
+ self.lightpoint_orientation = data['lightpoint_orientation']
+ self.lightpoint_cubemap = data['lightpoint_cubemap']
+ self.lightpoint_x3 = False
+
+ def save_json(self):
+ data = OrderedDict()
+ data['lightpoint_shader'] = self.lightpoint_shader
+ data['lightpoint_update_offscreen'] = self.lightpoint_update_offscreen
+ data['lightpoint_radius'] = self.lightpoint_radius
+ data['lightpoint_position'] = self.lightpoint_position
+ data['lightpoint_diffuse_color'] = self.lightpoint_diffuse_color
+ data['lightpoint_orientation'] = self.lightpoint_orientation
+ data['lightpoint_cubemap'] = self.lightpoint_cubemap
+ return data
+
+
+class ArcLightAffectorAttach:
+ def load_binary(self, stream: ResStream):
+ self.attach_x0 = stream.read_dword()
+ self.attach_offset = stream.read_tuple()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.attach_x0)
+ stream.write_tuple(self.attach_offset)
+
+ def load_json(self, data):
+ self.attach_x0 = 1
+ self.attach_offset = data['attach_offset']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['attach_offset'] = self.attach_offset
+ return data
+
+
+class ArcLightAffectorFlicker:
+ def load_binary(self, stream: ResStream):
+ self.flicker_x0 = stream.read_dword()
+ self.flicker_avg_period = stream.read_float()
+ self.flicker_std_dev_radius = stream.read_float()
+ self.flicker_std_dev_period = stream.read_float()
+ self.flicker_falloff = stream.read_float()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.flicker_x0)
+ stream.write_float(self.flicker_avg_period)
+ stream.write_float(self.flicker_std_dev_radius)
+ stream.write_float(self.flicker_std_dev_period)
+ stream.write_float(self.flicker_falloff)
+
+ def load_json(self, data):
+ self.flicker_x0 = 1
+ self.flicker_avg_period = data['flicker_avg_period']
+ self.flicker_std_dev_radius = data['flicker_std_dev_radius']
+ self.flicker_std_dev_period = data['flicker_std_dev_period']
+ self.flicker_falloff = data['flicker_falloff']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['flicker_avg_period'] = self.flicker_avg_period
+ data['flicker_std_dev_radius'] = self.flicker_std_dev_radius
+ data['flicker_std_dev_period'] = self.flicker_std_dev_period
+ data['flicker_falloff'] = self.flicker_falloff
+ return data
+
+
+class ArcLightAffectors:
+ def load_binary(self, stream: ResStream):
+ self.light_affector_type = stream.read_dword()
+
+ if self.light_affector_type == 0x54e8ff1d:
+ self.light_affector_data = ArcLightAffectorAttach()
+ elif self.light_affector_type == 0xa73bd9d4:
+ self.light_affector_data = ArcLightAffectorFlicker()
+ self.light_affector_data.load_binary(stream)
+
+ self.light_affector_0xdaed = stream.read_dword()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.light_affector_type)
+ self.light_affector_data.save_binary(stream)
+ stream.write_dword(self.light_affector_0xdaed)
+
+ def load_json(self, data):
+ self.light_affector_type = STRING_TO_LIGHT_TYPE[data['light_affector_type']]
+ if self.light_affector_type == 0x54e8ff1d:
+ self.light_affector_data = ArcLightAffectorAttach()
+ elif self.light_affector_type == 0xa73bd9d4:
+ self.light_affector_data = ArcLightAffectorFlicker()
+ self.light_affector_data.load_json(data['light_affector_data'])
+ self.light_affector_0xdaed = 0xddaaeedd
+
+ def save_json(self):
+ data = OrderedDict()
+ data['light_affector_type'] = LIGHT_TYPE_TO_STRING[self.light_affector_type]
+ data['light_affector_data'] = self.light_affector_data.save_json()
+ return data
+
+
+class ArcLight:
+ def load_binary(self, stream: ResStream):
+ self.light_x0 = stream.read_dword()
+ self.light_x1 = stream.read_bool()
+ self.light_type = stream.read_dword()
+
+ if self.light_type == 0xb6787258:
+ self.light_data = ArcLightPoint()
+ self.light_data.load_binary(stream)
+
+ self.light_0xdaed = stream.read_dword()
+
+ num = stream.read_dword()
+ self.light_affectors = [ArcLightAffectors() for _ in range(num)]
+ for extra in self.light_affectors:
+ extra.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.light_x0)
+ stream.write_bool(self.light_x1)
+ stream.write_dword(self.light_type)
+ self.light_data.save_binary(stream)
+ stream.write_dword(self.light_0xdaed)
+
+ stream.write_dword(len(self.light_affectors))
+ for extra in self.light_affectors:
+ extra.save_binary(stream)
+
+ def load_json(self, data):
+ self.light_x0 = 1
+ self.light_x1 = True
+ self.light_type = STRING_TO_LIGHT_TYPE[data['light_type']]
+ if self.light_type == 0xb6787258:
+ self.light_data = ArcLightPoint()
+ self.light_data.load_json(data['light_data'])
+ self.light_0xdaed = 0xddaaeedd
+
+ self.light_affectors = []
+ for extra_data in data['light_affectors']:
+ extra = ArcLightAffectors()
+ extra.load_json(extra_data)
+ self.light_affectors.append(extra)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['light_type'] = LIGHT_TYPE_TO_STRING[self.light_type]
+ data['light_data'] = self.light_data.save_json()
+
+ data['light_affectors'] = []
+ for extra in self.light_affectors:
+ data['light_affectors'].append(extra.save_json())
+ return data
+
+
+class ArcRender:
+ def load_binary(self, stream: ResStream):
+ self.render_template = ArcRenderTemplate()
+ self.render_template.load_binary(stream)
+ self.render_target_bone = stream.read_string()
+ self.render_scale = stream.read_tuple()
+ self.render_has_loc = stream.read_dword()
+ if self.render_has_loc:
+ self.render_loc = stream.read_tuple()
+ num_children = stream.read_dword()
+ self.render_children = [stream.read_qword() for _ in range(num_children)]
+ self.render_has_texture_set = stream.read_bool()
+ if self.render_has_texture_set:
+ num = stream.read_dword()
+ self.render_texture_set = [ArcTextureSet() for _ in range(num)]
+ for texture in self.render_texture_set:
+ texture.load_binary(stream)
+ self.render_collides = stream.read_bool()
+ self.render_calculate_bounding_box = stream.read_bool()
+ self.render_nation_crest = stream.read_bool()
+ self.render_guild_crest = stream.read_bool()
+ self.render_bumped = stream.read_bool()
+ self.render_vp_active = stream.read_bool()
+ if self.render_vp_active:
+ self.render_vp_name = stream.read_string()
+ num_params = stream.read_dword()
+ self.render_vp_params = [
+ [
+ stream.read_dword(),
+ stream.read_float(),
+ stream.read_float(),
+ stream.read_float(),
+ stream.read_float(),
+ ] for _ in range(num_params)
+ ]
+ self.render_has_light_effects = stream.read_bool()
+ if self.render_has_light_effects:
+ num_effects = stream.read_dword()
+ self.render_light_effects = [ArcLight() for _ in range(num_effects)]
+ for effect in self.render_light_effects:
+ effect.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ self.render_template.save_binary(stream)
+ stream.write_string(self.render_target_bone)
+ stream.write_tuple(self.render_scale)
+ stream.write_dword(self.render_has_loc)
+ if self.render_has_loc:
+ stream.write_tuple(self.render_loc)
+ stream.write_dword(len(self.render_children))
+ for child in self.render_children:
+ stream.write_qword(child)
+ stream.write_bool(self.render_has_texture_set)
+ if self.render_has_texture_set:
+ stream.write_dword(len(self.render_texture_set))
+ for texture in self.render_texture_set:
+ texture.save_binary(stream)
+ stream.write_bool(self.render_collides)
+ stream.write_bool(self.render_calculate_bounding_box)
+ stream.write_bool(self.render_nation_crest)
+ stream.write_bool(self.render_guild_crest)
+ stream.write_bool(self.render_bumped)
+ stream.write_bool(self.render_vp_active)
+ if self.render_vp_active:
+ stream.write_string(self.render_vp_name)
+
+ stream.write_dword(len(self.render_vp_params))
+ for param in self.render_vp_params:
+ stream.write_dword(param[0])
+ stream.write_float(param[1])
+ stream.write_float(param[2])
+ stream.write_float(param[3])
+ stream.write_float(param[4])
+ stream.write_bool(self.render_has_light_effects)
+ if self.render_has_light_effects:
+ stream.write_dword(len(self.render_light_effects))
+ for effect in self.render_light_effects:
+ effect.save_binary(stream)
+
+ def load_json(self, data):
+ self.render_template = ArcRenderTemplate()
+ self.render_template.load_json(data['render_template'])
+ self.render_target_bone = data['render_target_bone']
+ self.render_scale = data['render_scale']
+ self.render_has_loc = data['render_has_loc']
+ if self.render_has_loc:
+ self.render_loc = data['render_loc']
+ self.render_children = data['render_children']
+ self.render_has_texture_set = data['render_has_texture_set']
+ if self.render_has_texture_set:
+ self.render_texture_set = []
+ for texture_data in data['render_texture_set']:
+ texture = ArcTextureSet()
+ texture.load_json(texture_data)
+ self.render_texture_set.append(texture)
+ self.render_collides = data['render_collides']
+ self.render_calculate_bounding_box = data['render_calculate_bounding_box']
+ self.render_nation_crest = data['render_nation_crest']
+ self.render_guild_crest = data['render_guild_crest']
+ self.render_bumped = data['render_bumped']
+ self.render_vp_active = data['render_vp_active']
+ if self.render_vp_active:
+ self.render_vp_name = data['render_vp_name']
+ self.render_vp_params = data['render_vp_params']
+ self.render_has_light_effects = data['render_has_light_effects']
+ if self.render_has_light_effects:
+ self.render_light_effects = []
+ for effect_data in data['render_light_effects']:
+ effect = ArcLight()
+ effect.load_json(effect_data)
+ self.render_light_effects.append(effect)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['render_template'] = self.render_template.save_json()
+ data['render_target_bone'] = self.render_target_bone
+ data['render_scale'] = self.render_scale
+ data['render_has_loc'] = self.render_has_loc
+ if self.render_has_loc:
+ data['render_loc'] = self.render_loc
+ data['render_children'] = self.render_children
+ data['render_has_texture_set'] = self.render_has_texture_set
+ if self.render_has_texture_set:
+ data['render_texture_set'] = []
+ for texture in self.render_texture_set:
+ data['render_texture_set'].append(texture.save_json())
+ data['render_collides'] = self.render_collides
+ data['render_calculate_bounding_box'] = self.render_calculate_bounding_box
+ data['render_nation_crest'] = self.render_nation_crest
+ data['render_guild_crest'] = self.render_guild_crest
+ data['render_bumped'] = self.render_bumped
+ data['render_vp_active'] = self.render_vp_active
+ if self.render_vp_active:
+ data['render_vp_name'] = self.render_vp_name
+ data['render_vp_params'] = self.render_vp_params
+ data['render_has_light_effects'] = self.render_has_light_effects
+ if self.render_has_light_effects:
+ data['render_light_effects'] = []
+ for effect in self.render_light_effects:
+ data['render_light_effects'].append(effect.save_json())
+ return data
diff --git a/mbEditorPro2.0/arcane/ArcSkeleton.py b/mbEditorPro2.0/arcane/ArcSkeleton.py
new file mode 100644
index 0000000..89fe942
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcSkeleton.py
@@ -0,0 +1,125 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+
+class ArcBone:
+ def load_binary(self, stream: ResStream):
+ self.bone_id = stream.read_dword()
+ self.bone_name = stream.read_string()
+ self.bone_direction = stream.read_tuple()
+ self.bone_length = stream.read_float()
+ self.bone_axis = stream.read_tuple()
+ self.bone_dof = stream.read_string()
+ self.bone_order = stream.read_tuple()
+ self.bone_position = stream.read_tuple()
+ self.bone_orientation = stream.read_tuple()
+ self.bone_u0 = stream.read_bool()
+ self.bone_u1 = stream.read_bool()
+
+ num = stream.read_dword()
+ self.bone_hierarchy = [ArcBone() for _ in range(num)]
+ for bone in self.bone_hierarchy:
+ bone.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.bone_id)
+ stream.write_string(self.bone_name)
+ stream.write_tuple(self.bone_direction)
+ stream.write_float(self.bone_length)
+ stream.write_tuple(self.bone_axis)
+ stream.write_string(self.bone_dof)
+ stream.write_tuple(self.bone_order)
+ stream.write_tuple(self.bone_position)
+ stream.write_tuple(self.bone_orientation)
+ stream.write_bool(self.bone_u0)
+ stream.write_bool(self.bone_u1)
+
+ stream.write_dword(len(self.bone_hierarchy))
+ for bone in self.bone_hierarchy:
+ bone.save_binary(stream)
+
+ def load_json(self, data):
+ self.bone_id = data['bone_id']
+ self.bone_name = data['bone_name']
+ self.bone_direction = data['bone_direction']
+ self.bone_length = data['bone_length']
+ self.bone_axis = data['bone_axis']
+ self.bone_dof = data['bone_dof']
+ self.bone_order = data['bone_order']
+ self.bone_position = data['bone_position']
+ self.bone_orientation = data['bone_orientation']
+ self.bone_u0 = data['bone_u0']
+ self.bone_u1 = data['bone_u1']
+
+ self.bone_hierarchy = []
+ for bone_data in data['bone_hierarchy']:
+ bone = ArcBone()
+ bone.load_json(bone_data)
+ self.bone_hierarchy.append(bone)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['bone_id'] = self.bone_id
+ data['bone_name'] = self.bone_name
+ data['bone_direction'] = self.bone_direction
+ data['bone_length'] = self.bone_length
+ data['bone_axis'] = self.bone_axis
+ data['bone_dof'] = self.bone_dof
+ data['bone_order'] = self.bone_order
+ data['bone_position'] = self.bone_position
+ data['bone_orientation'] = self.bone_orientation
+ data['bone_u0'] = self.bone_u0
+ data['bone_u1'] = self.bone_u1
+
+ data['bone_hierarchy'] = []
+ for bone in self.bone_hierarchy:
+ data['bone_hierarchy'].append(bone.save_json())
+ return data
+
+
+class ArcSkeleton:
+ def load_binary(self, stream: ResStream):
+ self.skeleton_name = stream.read_string()
+
+ num = stream.read_dword()
+ self.skeleton_motion = [
+ [
+ stream.read_qword(),
+ stream.read_qword(),
+ ] for _ in range(num)
+ ]
+
+ self.skeleton_root = ArcBone()
+ self.skeleton_root.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_string(self.skeleton_name)
+
+ stream.write_dword(len(self.skeleton_motion))
+ for i in range(len(self.skeleton_motion)):
+ stream.write_qword(self.skeleton_motion[i][0])
+ stream.write_qword(self.skeleton_motion[i][1])
+
+ self.skeleton_root.save_binary(stream)
+
+ def load_json(self, data):
+ self.skeleton_name = data['skeleton_name']
+ self.skeleton_motion = data['skeleton_motion']
+ self.skeleton_root = ArcBone()
+ self.skeleton_root.load_json(data['skeleton_root'])
+
+ def save_json(self):
+ data = OrderedDict()
+ data['skeleton_name'] = self.skeleton_name
+ data['skeleton_motion'] = self.skeleton_motion
+ data['skeleton_root'] = self.skeleton_root.save_json()
+ return data
diff --git a/mbEditorPro2.0/arcane/ArcSound.py b/mbEditorPro2.0/arcane/ArcSound.py
new file mode 100644
index 0000000..2aeade3
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcSound.py
@@ -0,0 +1,40 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from wave import Wave_read, Wave_write
+
+from arcane.util import ResStream
+
+
+class ArcSound:
+ def load_binary(self, stream: ResStream):
+ data_size = stream.read_dword()
+ self.sound_frame_rate = stream.read_dword()
+ self.sound_n_channels = stream.read_dword()
+ self.sound_sample_width = stream.read_dword()
+ self.sound_data = stream.read_bytes(data_size)
+
+ def save_binary(self, stream: ResStream):
+ data_size = len(self.sound_data)
+ stream.write_dword(data_size)
+ stream.write_dword(self.sound_frame_rate)
+ stream.write_dword(self.sound_n_channels)
+ stream.write_dword(self.sound_sample_width)
+ stream.write_bytes(self.sound_data)
+
+ def load_wav(self, stream: Wave_read):
+ self.sound_frame_rate = stream.getframerate()
+ self.sound_n_channels = stream.getnchannels()
+ self.sound_sample_width = stream.getsampwidth() * 8
+ self.sound_data = stream.readframes(stream.getnframes())
+
+ def save_wav(self, stream: Wave_write):
+ stream.setframerate(self.sound_frame_rate)
+ stream.setnchannels(self.sound_n_channels)
+ stream.setsampwidth(self.sound_sample_width // 8)
+ stream.writeframes(self.sound_data)
diff --git a/mbEditorPro2.0/arcane/ArcTile.py b/mbEditorPro2.0/arcane/ArcTile.py
new file mode 100644
index 0000000..ec96476
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcTile.py
@@ -0,0 +1,242 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+TILE_TO_STRING = {
+ 0: "UNKNOWN",
+ 1: "Regular",
+ 2: "Slope",
+ 3: "Road",
+}
+STRING_TO_TILE = {value: key for key, value in TILE_TO_STRING.items()}
+
+MASK_TO_STRING = {
+ 0: "UNKNOWN",
+ 1: "Transition",
+ 2: "Road",
+}
+STRING_TO_MASK = {value: key for key, value in MASK_TO_STRING.items()}
+
+
+class ArcTile:
+ def load_binary(self, stream: ResStream):
+ self.tile_row_0 = stream.read_dword()
+ self.tile_row_1 = stream.read_dword()
+ self.tile_row_2 = stream.read_dword()
+ self.tile_row_3 = stream.read_dword()
+ self.tile_prob = stream.read_float()
+ self.tile_type = stream.read_dword()
+
+ num_alts = stream.read_dword()
+ self.tile_alts = [stream.read_dword() for _ in range(num_alts)]
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.tile_row_0)
+ stream.write_dword(self.tile_row_1)
+ stream.write_dword(self.tile_row_2)
+ stream.write_dword(self.tile_row_3)
+ stream.write_float(self.tile_prob)
+ stream.write_dword(self.tile_type)
+ stream.write_dword(len(self.tile_alts))
+ for i in range(len(self.tile_alts)):
+ stream.write_dword(self.tile_alts[i])
+
+ def load_json(self, data):
+ self.tile_row_0 = data['tile_row_0']
+ self.tile_row_1 = data['tile_row_1']
+ self.tile_row_2 = data['tile_row_2']
+ self.tile_row_3 = data['tile_row_3']
+ self.tile_prob = data['tile_prob']
+ self.tile_type = STRING_TO_TILE[data['tile_type']]
+ self.tile_alts = data['tile_alts']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['tile_row_0'] = self.tile_row_0
+ data['tile_row_1'] = self.tile_row_1
+ data['tile_row_2'] = self.tile_row_2
+ data['tile_row_3'] = self.tile_row_3
+ data['tile_prob'] = self.tile_prob
+ data['tile_type'] = TILE_TO_STRING[self.tile_type]
+ data['tile_alts'] = self.tile_alts
+ return data
+
+
+class ArcTileMask:
+ def load_binary(self, stream: ResStream):
+ self.mask_row_0 = stream.read_dword()
+ self.mask_row_1 = stream.read_dword()
+ self.mask_row_2 = stream.read_dword()
+ self.mask_row_3 = stream.read_dword()
+ self.mask_prob = stream.read_float()
+ self.mask_start = stream.read_dword()
+ self.mask_end = stream.read_dword()
+ self.mask_end1 = stream.read_dword()
+ self.mask_end2 = stream.read_dword()
+ self.mask_type = stream.read_dword()
+ self.mask_width = stream.read_dword()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.mask_row_0)
+ stream.write_dword(self.mask_row_1)
+ stream.write_dword(self.mask_row_2)
+ stream.write_dword(self.mask_row_3)
+ stream.write_float(self.mask_prob)
+ stream.write_dword(self.mask_start)
+ stream.write_dword(self.mask_end)
+ stream.write_dword(self.mask_end1)
+ stream.write_dword(self.mask_end2)
+ stream.write_dword(self.mask_type)
+ stream.write_dword(self.mask_width)
+
+ def load_json(self, data):
+ self.mask_row_0 = data['mask_row_0']
+ self.mask_row_1 = data['mask_row_1']
+ self.mask_row_2 = data['mask_row_2']
+ self.mask_row_3 = data['mask_row_3']
+ self.mask_prob = data['mask_prob']
+ self.mask_start = data['mask_start']
+ self.mask_end = data['mask_end']
+ self.mask_end1 = data['mask_end1']
+ self.mask_end2 = data['mask_end2']
+ self.mask_type = STRING_TO_MASK[data['mask_type']]
+ self.mask_width = data['mask_width']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['mask_row_0'] = self.mask_row_0
+ data['mask_row_1'] = self.mask_row_1
+ data['mask_row_2'] = self.mask_row_2
+ data['mask_row_3'] = self.mask_row_3
+ data['mask_prob'] = self.mask_prob
+ data['mask_start'] = self.mask_start
+ data['mask_end'] = self.mask_end
+ data['mask_end1'] = self.mask_end1
+ data['mask_end2'] = self.mask_end2
+ data['mask_type'] = MASK_TO_STRING[self.mask_type]
+ data['mask_width'] = self.mask_width
+ return data
+
+
+class ArcTilePattern:
+ def load_binary(self, stream: ResStream):
+ self.pattern_row_0 = stream.read_dword()
+ self.pattern_row_1 = stream.read_dword()
+ self.pattern_row_2 = stream.read_dword()
+ self.pattern_row_3 = stream.read_dword()
+ self.pattern_prob = stream.read_float()
+ self.pattern_patx = stream.read_dword()
+ self.pattern_patz = stream.read_dword()
+ num_tiles = stream.read_dword()
+ self.pattern_tiles = [stream.read_dword() for _ in range(num_tiles)]
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.pattern_row_0)
+ stream.write_dword(self.pattern_row_1)
+ stream.write_dword(self.pattern_row_2)
+ stream.write_dword(self.pattern_row_3)
+ stream.write_float(self.pattern_prob)
+ stream.write_dword(self.pattern_patx)
+ stream.write_dword(self.pattern_patz)
+ stream.write_dword(len(self.pattern_tiles))
+ for i in range(len(self.pattern_tiles)):
+ stream.write_dword(self.pattern_tiles[i])
+
+ def load_json(self, data):
+ self.pattern_row_0 = data['pattern_row_0']
+ self.pattern_row_1 = data['pattern_row_1']
+ self.pattern_row_2 = data['pattern_row_2']
+ self.pattern_row_3 = data['pattern_row_3']
+ self.pattern_prob = data['pattern_prob']
+ self.pattern_patx = data['pattern_patx']
+ self.pattern_patz = data['pattern_patz']
+ self.pattern_tiles = data['pattern_tiles']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['pattern_row_0'] = self.pattern_row_0
+ data['pattern_row_1'] = self.pattern_row_1
+ data['pattern_row_2'] = self.pattern_row_2
+ data['pattern_row_3'] = self.pattern_row_3
+ data['pattern_prob'] = self.pattern_prob
+ data['pattern_patx'] = self.pattern_patx
+ data['pattern_patz'] = self.pattern_patz
+ data['pattern_tiles'] = self.pattern_tiles
+ return data
+
+
+class ArcTileManager:
+ def load_binary(self, stream: ResStream):
+ self.manager_texture_width = stream.read_dword()
+ self.manager_tile_width = stream.read_dword()
+ self.manager_tile_texture = stream.read_qword()
+ num_tiles = stream.read_dword()
+ self.manager_tiles = [ArcTile() for _ in range(num_tiles)]
+ for tile in self.manager_tiles:
+ tile.load_binary(stream)
+ num_masks = stream.read_dword()
+ self.manager_masks = [ArcTileMask() for _ in range(num_masks)]
+ for mask in self.manager_masks:
+ mask.load_binary(stream)
+ num_patterns = stream.read_dword()
+ self.manager_patterns = [ArcTilePattern() for _ in range(num_patterns)]
+ for pattern in self.manager_patterns:
+ pattern.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.manager_texture_width)
+ stream.write_dword(self.manager_tile_width)
+ stream.write_qword(self.manager_tile_texture)
+ stream.write_dword(len(self.manager_tiles))
+ for tile in self.manager_tiles:
+ tile.save_binary(stream)
+ stream.write_dword(len(self.manager_masks))
+ for mask in self.manager_masks:
+ mask.save_binary(stream)
+ stream.write_dword(len(self.manager_patterns))
+ for pattern in self.manager_patterns:
+ pattern.save_binary(stream)
+
+ def load_json(self, data):
+ self.manager_texture_width = data['manager_texture_width']
+ self.manager_tile_width = data['manager_tile_width']
+ self.manager_tile_texture = data['manager_tile_texture']
+ self.manager_tiles = []
+ for tile_data in data['manager_tiles']:
+ tile = ArcTile()
+ tile.load_json(tile_data)
+ self.manager_tiles.append(tile)
+ self.manager_masks = []
+ for mask_data in data['manager_masks']:
+ mask = ArcTileMask()
+ mask.load_json(mask_data)
+ self.manager_masks.append(mask)
+ self.manager_patterns = []
+ for pattern_data in data['manager_patterns']:
+ pattern = ArcTilePattern()
+ pattern.load_json(pattern_data)
+ self.manager_patterns.append(pattern)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['manager_texture_width'] = self.manager_texture_width
+ data['manager_tile_width'] = self.manager_tile_width
+ data['manager_tile_texture'] = self.manager_tile_texture
+ data['manager_tiles'] = []
+ for tile in self.manager_tiles:
+ data['manager_tiles'].append(tile.save_json())
+ data['manager_masks'] = []
+ for mask in self.manager_masks:
+ data['manager_masks'].append(mask.save_json())
+ data['manager_patterns'] = []
+ for pattern in self.manager_patterns:
+ data['manager_patterns'].append(pattern.save_json())
+ return data
diff --git a/mbEditorPro2.0/arcane/ArcVisual.py b/mbEditorPro2.0/arcane/ArcVisual.py
new file mode 100644
index 0000000..6c9f8d9
--- /dev/null
+++ b/mbEditorPro2.0/arcane/ArcVisual.py
@@ -0,0 +1,396 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+#
+
+
+from base64 import b64decode, b64encode
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+EFFETCT_TO_STRING = {
+ 0: 'PARTICLE',
+ 1: 'LIGHTNING',
+ 2: 'GEOMETRY',
+}
+
+STRING_TO_EFFECT = {value: key for key, value in EFFETCT_TO_STRING.items()}
+
+
+class ArcParticle:
+ def load_binary(self, stream: ResStream):
+ self.particle_attached_bone = stream.read_dword()
+ self.particle_count = stream.read_dword()
+ self.particle_size = stream.read_float()
+ self.particle_life = stream.read_float()
+ self.particle_life_rand = stream.read_float()
+ self.particle_shape_and_pos = stream.read_dword()
+ self.particle_emitter_scale = stream.read_float()
+ self.particle_pos_offset = stream.read_tuple()
+ self.particle_ppos_reference = stream.read_tuple()
+ self.particle_initial_velocities = stream.read_dword()
+ self.particle_velocity_scale = stream.read_float()
+ self.particle_vel_reference = stream.read_tuple()
+ self.particle_dir_random = stream.read_float()
+ self.particle_spd_random = stream.read_float()
+ self.particle_initial_rot = stream.read_float()
+ self.particle_initial_rot_random = stream.read_float()
+ self.particle_incremental_rot = stream.read_float()
+ self.particle_incremental_rot_random = stream.read_float()
+ self.particle_color_keys = [
+ [
+ stream.read_float(),
+ stream.read_float(),
+ stream.read_float(),
+ stream.read_float(),
+ ] for _ in range(5)
+ ]
+ self.particle_color_keytimes = [stream.read_float() for _ in range(5)]
+ self.particle_size_keys = [stream.read_float() for _ in range(5)]
+ self.particle_targettype = stream.read_dword()
+ self.particle_lifetime = stream.read_float()
+ self.particle_texture = stream.read_dword()
+ self.particle_blend_type = stream.read_dword()
+ self.particle_attractor_bone = stream.read_dword()
+ self.particle_directional_grav = stream.read_tuple()
+ self.particle_field_function = stream.read_dword()
+ self.particle_gravity_strength = stream.read_float()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.particle_attached_bone)
+ stream.write_dword(self.particle_count)
+ stream.write_float(self.particle_size)
+ stream.write_float(self.particle_life)
+ stream.write_float(self.particle_life_rand)
+ stream.write_dword(self.particle_shape_and_pos)
+ stream.write_float(self.particle_emitter_scale)
+ stream.write_tuple(self.particle_pos_offset)
+ stream.write_tuple(self.particle_ppos_reference)
+ stream.write_dword(self.particle_initial_velocities)
+ stream.write_float(self.particle_velocity_scale)
+ stream.write_tuple(self.particle_vel_reference)
+ stream.write_float(self.particle_dir_random)
+ stream.write_float(self.particle_spd_random)
+ stream.write_float(self.particle_initial_rot)
+ stream.write_float(self.particle_initial_rot_random)
+ stream.write_float(self.particle_incremental_rot)
+ stream.write_float(self.particle_incremental_rot_random)
+ for i in range(5):
+ stream.write_float(self.particle_color_keys[i][0])
+ stream.write_float(self.particle_color_keys[i][1])
+ stream.write_float(self.particle_color_keys[i][2])
+ stream.write_float(self.particle_color_keys[i][3])
+ for i in range(5):
+ stream.write_float(self.particle_color_keytimes[i])
+ for i in range(5):
+ stream.write_float(self.particle_size_keys[i])
+ stream.write_dword(self.particle_targettype)
+ stream.write_float(self.particle_lifetime)
+ stream.write_dword(self.particle_texture)
+ stream.write_dword(self.particle_blend_type)
+ stream.write_dword(self.particle_attractor_bone)
+ stream.write_tuple(self.particle_directional_grav)
+ stream.write_dword(self.particle_field_function)
+ stream.write_float(self.particle_gravity_strength)
+
+ def load_json(self, data):
+ self.particle_attached_bone = data['particle_attached_bone']
+ self.particle_count = data['particle_count']
+ self.particle_size = data['particle_size']
+ self.particle_life = data['particle_life']
+ self.particle_life_rand = data['particle_life_rand']
+ self.particle_shape_and_pos = data['particle_shape_and_pos']
+ self.particle_emitter_scale = data['particle_emitter_scale']
+ self.particle_pos_offset = data['particle_pos_offset']
+ self.particle_ppos_reference = data['particle_ppos_reference']
+ self.particle_initial_velocities = data['particle_initial_velocities']
+ self.particle_velocity_scale = data['particle_velocity_scale']
+ self.particle_vel_reference = data['particle_vel_reference']
+ self.particle_dir_random = data['particle_dir_random']
+ self.particle_spd_random = data['particle_spd_random']
+ self.particle_initial_rot = data['particle_initial_rot']
+ self.particle_initial_rot_random = data['particle_initial_rot_random']
+ self.particle_incremental_rot = data['particle_incremental_rot']
+ self.particle_incremental_rot_random = data['particle_incremental_rot_random']
+ self.particle_color_keys = data['particle_color_keys']
+ self.particle_color_keytimes = data['particle_color_keytimes']
+ self.particle_size_keys = data['particle_size_keys']
+ self.particle_targettype = data['particle_targettype']
+ self.particle_lifetime = data['particle_lifetime']
+ self.particle_texture = data['particle_texture']
+ self.particle_blend_type = data['particle_blend_type']
+ self.particle_attractor_bone = data['particle_attractor_bone']
+ self.particle_directional_grav = data['particle_directional_grav']
+ self.particle_field_function = data['particle_field_function']
+ self.particle_gravity_strength = data['particle_gravity_strength']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['particle_attached_bone'] = self.particle_attached_bone
+ data['particle_count'] = self.particle_count
+ data['particle_size'] = self.particle_size
+ data['particle_life'] = self.particle_life
+ data['particle_life_rand'] = self.particle_life_rand
+ data['particle_shape_and_pos'] = self.particle_shape_and_pos
+ data['particle_emitter_scale'] = self.particle_emitter_scale
+ data['particle_pos_offset'] = self.particle_pos_offset
+ data['particle_ppos_reference'] = self.particle_ppos_reference
+ data['particle_initial_velocities'] = self.particle_initial_velocities
+ data['particle_velocity_scale'] = self.particle_velocity_scale
+ data['particle_vel_reference'] = self.particle_vel_reference
+ data['particle_dir_random'] = self.particle_dir_random
+ data['particle_spd_random'] = self.particle_spd_random
+ data['particle_initial_rot'] = self.particle_initial_rot
+ data['particle_initial_rot_random'] = self.particle_initial_rot_random
+ data['particle_incremental_rot'] = self.particle_incremental_rot
+ data['particle_incremental_rot_random'] = self.particle_incremental_rot_random
+ data['particle_color_keys'] = self.particle_color_keys
+ data['particle_color_keytimes'] = self.particle_color_keytimes
+ data['particle_size_keys'] = self.particle_size_keys
+ data['particle_targettype'] = self.particle_targettype
+ data['particle_lifetime'] = self.particle_lifetime
+ data['particle_texture'] = self.particle_texture
+ data['particle_blend_type'] = self.particle_blend_type
+ data['particle_attractor_bone'] = self.particle_attractor_bone
+ data['particle_directional_grav'] = self.particle_directional_grav
+ data['particle_field_function'] = self.particle_field_function
+ data['particle_gravity_strength'] = self.particle_gravity_strength
+ return data
+
+
+class ArcLightning:
+ def load_binary(self, stream: ResStream):
+ self.lightning_texture = stream.read_dword()
+ self.lightning_src_bone = stream.read_dword()
+ self.lightning_dst_bone = stream.read_dword()
+ self.lightning_width = stream.read_float()
+ self.lightning_random_factor = stream.read_float()
+ self.lightning_sine_factor = stream.read_float()
+ self.lightning_sine_phase = stream.read_float()
+ self.lightning_sine_phase_rep = stream.read_float()
+ self.lightning_length = stream.read_float()
+ self.lightning_random_move_speed = stream.read_float()
+ self.lightning_color = stream.read_tuple()
+ self.lightning_lifetime = stream.read_float()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.lightning_texture)
+ stream.write_dword(self.lightning_src_bone)
+ stream.write_dword(self.lightning_dst_bone)
+ stream.write_float(self.lightning_width)
+ stream.write_float(self.lightning_random_factor)
+ stream.write_float(self.lightning_sine_factor)
+ stream.write_float(self.lightning_sine_phase)
+ stream.write_float(self.lightning_sine_phase_rep)
+ stream.write_float(self.lightning_length)
+ stream.write_float(self.lightning_random_move_speed)
+ stream.write_tuple(self.lightning_color)
+ stream.write_float(self.lightning_lifetime)
+
+ def load_json(self, data):
+ self.lightning_texture = data['lightning_texture']
+ self.lightning_src_bone = data['lightning_src_bone']
+ self.lightning_dst_bone = data['lightning_dst_bone']
+ self.lightning_width = data['lightning_width']
+ self.lightning_random_factor = data['lightning_random_factor']
+ self.lightning_sine_factor = data['lightning_sine_factor']
+ self.lightning_sine_phase = data['lightning_sine_phase']
+ self.lightning_sine_phase_rep = data['lightning_sine_phase_rep']
+ self.lightning_length = data['lightning_length']
+ self.lightning_random_move_speed = data['lightning_random_move_speed']
+ self.lightning_color = data['lightning_color']
+ self.lightning_lifetime = data['lightning_lifetime']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['lightning_texture'] = self.lightning_texture
+ data['lightning_src_bone'] = self.lightning_src_bone
+ data['lightning_dst_bone'] = self.lightning_dst_bone
+ data['lightning_width'] = self.lightning_width
+ data['lightning_random_factor'] = self.lightning_random_factor
+ data['lightning_sine_factor'] = self.lightning_sine_factor
+ data['lightning_sine_phase'] = self.lightning_sine_phase
+ data['lightning_sine_phase_rep'] = self.lightning_sine_phase_rep
+ data['lightning_length'] = self.lightning_length
+ data['lightning_random_move_speed'] = self.lightning_random_move_speed
+ data['lightning_color'] = self.lightning_color
+ data['lightning_lifetime'] = self.lightning_lifetime
+ return data
+
+
+class ArcGeometry:
+ def load_binary(self, stream: ResStream):
+ self.geometry_texture = stream.read_dword()
+ self.geometry_src_bone = stream.read_dword()
+ self.geometry_lifetime = stream.read_float()
+ self.geometry_tex_trans_x = stream.read_float()
+ self.geometry_tex_trans_y = stream.read_float()
+ self.geometry_tex_rot = stream.read_float()
+ self.geometry_grow = stream.read_tuple()
+ self.geometry_tesselation = stream.read_float()
+ self.geometry_size = stream.read_tuple()
+ self.geometry_geo_rot_x = stream.read_float()
+ self.geometry_fade_falloff = stream.read_float()
+ self.geometry_fadein = stream.read_float()
+ self.geometry_fadeout = stream.read_float()
+ self.geometry_color = [stream.read_float() for _ in range(4)]
+ self.geometry_type = stream.read_dword()
+ self.geometry_texture_proj = stream.read_dword()
+ self.geometry_fade_dir = stream.read_dword()
+ self.geometry_offset = stream.read_tuple()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.geometry_texture)
+ stream.write_dword(self.geometry_src_bone)
+ stream.write_float(self.geometry_lifetime)
+ stream.write_float(self.geometry_tex_trans_x)
+ stream.write_float(self.geometry_tex_trans_y)
+ stream.write_float(self.geometry_tex_rot)
+ stream.write_tuple(self.geometry_grow)
+ stream.write_float(self.geometry_tesselation)
+ stream.write_tuple(self.geometry_size)
+ stream.write_float(self.geometry_geo_rot_x)
+ stream.write_float(self.geometry_fade_falloff)
+ stream.write_float(self.geometry_fadein)
+ stream.write_float(self.geometry_fadeout)
+ for i in range(4):
+ stream.write_float(self.geometry_color[i])
+ stream.write_dword(self.geometry_type)
+ stream.write_dword(self.geometry_texture_proj)
+ stream.write_dword(self.geometry_fade_dir)
+ stream.write_tuple(self.geometry_offset)
+
+ def load_json(self, data):
+ self.geometry_texture = data['geometry_texture']
+ self.geometry_src_bone = data['geometry_src_bone']
+ self.geometry_lifetime = data['geometry_lifetime']
+ self.geometry_tex_trans_x = data['geometry_tex_trans_x']
+ self.geometry_tex_trans_y = data['geometry_tex_trans_y']
+ self.geometry_tex_rot = data['geometry_tex_rot']
+ self.geometry_grow = data['geometry_grow']
+ self.geometry_tesselation = data['geometry_tesselation']
+ self.geometry_size = data['geometry_size']
+ self.geometry_geo_rot_x = data['geometry_geo_rot_x']
+ self.geometry_fade_falloff = data['geometry_fade_falloff']
+ self.geometry_fadein = data['geometry_fadein']
+ self.geometry_fadeout = data['geometry_fadeout']
+ self.geometry_color = data['geometry_color']
+ self.geometry_type = data['geometry_type']
+ self.geometry_texture_proj = data['geometry_texture_proj']
+ self.geometry_fade_dir = data['geometry_fade_dir']
+ self.geometry_offset = data['geometry_offset']
+
+ def save_json(self):
+ data = OrderedDict()
+ data['geometry_texture'] = self.geometry_texture
+ data['geometry_src_bone'] = self.geometry_src_bone
+ data['geometry_lifetime'] = self.geometry_lifetime
+ data['geometry_tex_trans_x'] = self.geometry_tex_trans_x
+ data['geometry_tex_trans_y'] = self.geometry_tex_trans_y
+ data['geometry_tex_rot'] = self.geometry_tex_rot
+ data['geometry_grow'] = self.geometry_grow
+ data['geometry_tesselation'] = self.geometry_tesselation
+ data['geometry_size'] = self.geometry_size
+ data['geometry_geo_rot_x'] = self.geometry_geo_rot_x
+ data['geometry_fade_falloff'] = self.geometry_fade_falloff
+ data['geometry_fadein'] = self.geometry_fadein
+ data['geometry_fadeout'] = self.geometry_fadeout
+ data['geometry_color'] = self.geometry_color
+ data['geometry_type'] = self.geometry_type
+ data['geometry_texture_proj'] = self.geometry_texture_proj
+ data['geometry_fade_dir'] = self.geometry_fade_dir
+ data['geometry_offset'] = self.geometry_offset
+ return data
+
+
+class ArcVisualEffect:
+ def load_binary(self, stream: ResStream):
+ self.effect_type = stream.read_dword()
+ self.effect_time = stream.read_float()
+
+ if self.effect_type == 0:
+ self.effect = ArcParticle()
+ elif self.effect_type == 1:
+ self.effect = ArcLightning()
+ elif self.effect_type == 2:
+ self.effect = ArcGeometry()
+ self.effect.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(self.effect_type)
+ stream.write_float(self.effect_time)
+ self.effect.save_binary(stream)
+
+ def load_json(self, data):
+ self.effect_type = STRING_TO_EFFECT[data['effect_type']]
+ self.effect_time = data['effect_time']
+ if self.effect_type == 0:
+ self.effect = ArcParticle()
+ elif self.effect_type == 1:
+ self.effect = ArcLightning()
+ elif self.effect_type == 2:
+ self.effect = ArcGeometry()
+ self.effect.load_json(data['effect'])
+
+ def save_json(self):
+ data = OrderedDict()
+ data['effect_type'] = EFFETCT_TO_STRING[self.effect_type]
+ data['effect_time'] = self.effect_time
+ data['effect'] = self.effect.save_json()
+ return data
+
+
+class ArcVisual:
+ def load_binary(self, stream: ResStream):
+ num_effects = stream.read_dword()
+
+ self.vfx_fail = None
+ if num_effects == 1617156728:
+ stream.buffer.seek(0, 0)
+ self.vfx_fail = stream.buffer.read()
+ return
+
+ self.vfx_duration = stream.read_float()
+ self.vfx_effects = [ArcVisualEffect() for _ in range(num_effects)]
+ for effect in self.vfx_effects:
+ effect.load_binary(stream)
+
+ def save_binary(self, stream: ResStream):
+ if self.vfx_fail:
+ stream.buffer.write(self.vfx_fail)
+ return
+
+ stream.write_dword(len(self.vfx_effects))
+ stream.write_float(self.vfx_duration)
+ for effect in self.vfx_effects:
+ effect.save_binary(stream)
+
+ def load_json(self, data):
+ self.vfx_fail = data.get('vfx_fail')
+ if self.vfx_fail:
+ self.vfx_fail = b64decode(self.vfx_fail)
+ return
+
+ self.vfx_duration = data['vfx_duration']
+ self.vfx_effects = []
+ for effect_data in data['vfx_effects']:
+ effect = ArcVisualEffect()
+ effect.load_json(effect_data)
+ self.vfx_effects.append(effect)
+
+ def save_json(self):
+ data = OrderedDict()
+ if self.vfx_fail:
+ data['vfx_fail'] = b64encode(self.vfx_fail).decode()
+ return data
+
+ data['vfx_duration'] = self.vfx_duration
+ data['vfx_effects'] = []
+ for effect in self.vfx_effects:
+ data['vfx_effects'].append(effect.save_json())
+ return data
diff --git a/mbEditorPro2.0/arcane/__init__.py b/mbEditorPro2.0/arcane/__init__.py
new file mode 100644
index 0000000..3f769e0
--- /dev/null
+++ b/mbEditorPro2.0/arcane/__init__.py
@@ -0,0 +1,7 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
diff --git a/mbEditorPro2.0/arcane/enums/__init__.py b/mbEditorPro2.0/arcane/enums/__init__.py
new file mode 100644
index 0000000..3f769e0
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/__init__.py
@@ -0,0 +1,7 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
diff --git a/mbEditorPro/arcane/enums/arc_combat.py b/mbEditorPro2.0/arcane/enums/arc_combat.py
similarity index 61%
rename from mbEditorPro/arcane/enums/arc_combat.py
rename to mbEditorPro2.0/arcane/enums/arc_combat.py
index f3edeaf..4486ebd 100644
--- a/mbEditorPro/arcane/enums/arc_combat.py
+++ b/mbEditorPro2.0/arcane/enums/arc_combat.py
@@ -1,12 +1,12 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
-ATTACK_RESIST_UNKOWN = 0
+ATTACK_RESIST_UNKNOWN = 0
ATTACK_RESIST_SLASHING = 1
ATTACK_RESIST_CRUSHING = 2
ATTACK_RESIST_PIERCING = 3
@@ -24,7 +24,7 @@ ATTACK_RESIST_UNHOLY = 14
ATTACK_RESIST_ANTISIEGE = 15
ATTACK_RESIST_TO_STRING = {
- ATTACK_RESIST_UNKOWN: 'UNKOWN',
+ ATTACK_RESIST_UNKNOWN: 'UNKNOWN',
ATTACK_RESIST_SLASHING: 'SLASHING',
ATTACK_RESIST_CRUSHING: 'CRUSHING',
ATTACK_RESIST_PIERCING: 'PIERCING',
@@ -43,7 +43,7 @@ ATTACK_RESIST_TO_STRING = {
}
STRING_TO_ATTACK_RESIST = {
- 'UNKOWN': ATTACK_RESIST_UNKOWN,
+ 'UNKNOWN': ATTACK_RESIST_UNKNOWN,
'SLASHING': ATTACK_RESIST_SLASHING,
'CRUSHING': ATTACK_RESIST_CRUSHING,
'PIERCING': ATTACK_RESIST_PIERCING,
diff --git a/mbEditorPro/arcane/enums/arc_door.py b/mbEditorPro2.0/arcane/enums/arc_door.py
similarity index 52%
rename from mbEditorPro/arcane/enums/arc_door.py
rename to mbEditorPro2.0/arcane/enums/arc_door.py
index 7ec2dd4..9becaf0 100644
--- a/mbEditorPro/arcane/enums/arc_door.py
+++ b/mbEditorPro2.0/arcane/enums/arc_door.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
DOOR_TYPE_ROTATE = 0
DOOR_TYPE_SLIDE = 1
diff --git a/mbEditorPro/arcane/enums/arc_item.py b/mbEditorPro2.0/arcane/enums/arc_item.py
similarity index 89%
rename from mbEditorPro/arcane/enums/arc_item.py
rename to mbEditorPro2.0/arcane/enums/arc_item.py
index 4ff6a9c..625daa5 100644
--- a/mbEditorPro/arcane/enums/arc_item.py
+++ b/mbEditorPro2.0/arcane/enums/arc_item.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
ITEM_FLAG_NONE = 1 << 0
ITEM_FLAG_INDESTRUCTIBLE = 1 << 1
@@ -241,26 +241,26 @@ STRING_TO_ITEM_USE_FLAGS = {
'EMPTY_NEWITEM': ITEM_USE_FLAGS_EMPTY_NEWITEM,
}
-ITEM_SHEATHSLOT_UNKOWN = 0
+ITEM_SHEATHSLOT_UNKNOWN = 0
ITEM_SHEATHSLOT_BACK = 1
ITEM_SHEATHSLOT_WAIST = 2
ITEM_SHEATHSLOT_NONE = 4
ITEM_SHEATHSLOT_TO_STRING = {
ITEM_SHEATHSLOT_NONE: 'NONE',
- ITEM_SHEATHSLOT_UNKOWN: 'UNKOWN',
+ ITEM_SHEATHSLOT_UNKNOWN: 'UNKNOWN',
ITEM_SHEATHSLOT_BACK: 'BACK',
ITEM_SHEATHSLOT_WAIST: 'WAIST',
}
STRING_TO_ITEM_SHEATHSLOT = {
'NONE': ITEM_SHEATHSLOT_NONE,
- 'UNKOWN': ITEM_SHEATHSLOT_UNKOWN,
+ 'UNKNOWN': ITEM_SHEATHSLOT_UNKNOWN,
'BACK': ITEM_SHEATHSLOT_BACK,
'WAIST': ITEM_SHEATHSLOT_WAIST,
}
-DAMAGE_UNKOWN = 0
+DAMAGE_UNKNOWN = 0
DAMAGE_SLASHING = 1
DAMAGE_CRUSHING = 2
DAMAGE_PIERCING = 3
@@ -278,7 +278,7 @@ DAMAGE_UNHOLY = 14
DAMAGE_ANTISIEGE = 15
DAMAGE_TO_STRING = {
- DAMAGE_UNKOWN: 'UNKOWN',
+ DAMAGE_UNKNOWN: 'UNKNOWN',
DAMAGE_SLASHING: 'SLASHING',
DAMAGE_CRUSHING: 'CRUSHING',
DAMAGE_PIERCING: 'PIERCING',
@@ -297,7 +297,7 @@ DAMAGE_TO_STRING = {
}
STRING_TO_DAMAGE = {
- 'UNKOWN': DAMAGE_UNKOWN,
+ 'UNKNOWN': DAMAGE_UNKNOWN,
'SLASHING': DAMAGE_SLASHING,
'CRUSHING': DAMAGE_CRUSHING,
'PIERCING': DAMAGE_PIERCING,
diff --git a/mbEditorPro/arcane/enums/arc_object.py b/mbEditorPro2.0/arcane/enums/arc_object.py
similarity index 85%
rename from mbEditorPro/arcane/enums/arc_object.py
rename to mbEditorPro2.0/arcane/enums/arc_object.py
index b102973..d157046 100644
--- a/mbEditorPro/arcane/enums/arc_object.py
+++ b/mbEditorPro2.0/arcane/enums/arc_object.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
OBJECT_TYPE_LIGHT = 1
OBJECT_TYPE_DOOR = 2
diff --git a/mbEditorPro/arcane/enums/arc_rune.py b/mbEditorPro2.0/arcane/enums/arc_rune.py
similarity index 59%
rename from mbEditorPro/arcane/enums/arc_rune.py
rename to mbEditorPro2.0/arcane/enums/arc_rune.py
index 1dbe103..7bf58e7 100644
--- a/mbEditorPro/arcane/enums/arc_rune.py
+++ b/mbEditorPro2.0/arcane/enums/arc_rune.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
RUNE_UNKNOWN = 0
RUNE_RACE = 1
diff --git a/mbEditorPro/arcane/enums/arc_sparse.py b/mbEditorPro2.0/arcane/enums/arc_sparse.py
similarity index 91%
rename from mbEditorPro/arcane/enums/arc_sparse.py
rename to mbEditorPro2.0/arcane/enums/arc_sparse.py
index 747551e..e76f091 100644
--- a/mbEditorPro/arcane/enums/arc_sparse.py
+++ b/mbEditorPro2.0/arcane/enums/arc_sparse.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
SPARSE_VAL_LONG = 0 # dword
SPARSE_VAL_FLOAT = 1 # float
diff --git a/mbEditorPro/arcane/enums/arc_structure.py b/mbEditorPro2.0/arcane/enums/arc_structure.py
similarity index 56%
rename from mbEditorPro/arcane/enums/arc_structure.py
rename to mbEditorPro2.0/arcane/enums/arc_structure.py
index 131663f..3ae0586 100644
--- a/mbEditorPro/arcane/enums/arc_structure.py
+++ b/mbEditorPro2.0/arcane/enums/arc_structure.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
REGION_CONTENTBEHAVIOR_SHOWNONE = 0
REGION_CONTENTBEHAVIOR_SHOWCHARACTERS = 1
diff --git a/mbEditorPro2.0/arcane/enums/common/__init__.py b/mbEditorPro2.0/arcane/enums/common/__init__.py
new file mode 100644
index 0000000..3f769e0
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/common/__init__.py
@@ -0,0 +1,7 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
diff --git a/mbEditorPro2.0/arcane/enums/common/arc_inventory.py b/mbEditorPro2.0/arcane/enums/common/arc_inventory.py
new file mode 100644
index 0000000..abfd9f4
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/common/arc_inventory.py
@@ -0,0 +1,23 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+INVENTORY_TYPE_GOLD = 1
+INVENTORY_TYPE_ITEM = 2
+INVENTORY_TYPE_BOOTYTABLE = 3
+
+INVENTORY_TYPE_TO_STRING = {
+ INVENTORY_TYPE_GOLD: 'GOLD',
+ INVENTORY_TYPE_ITEM: 'ITEM',
+ INVENTORY_TYPE_BOOTYTABLE: 'BOOTYTABLE',
+}
+
+STRING_TO_INVENTORY_TYPE = {
+ 'GOLD': INVENTORY_TYPE_GOLD,
+ 'ITEM': INVENTORY_TYPE_ITEM,
+ 'BOOTYTABLE': INVENTORY_TYPE_BOOTYTABLE,
+}
diff --git a/mbEditorPro2.0/arcane/enums/hashes/__init__.py b/mbEditorPro2.0/arcane/enums/hashes/__init__.py
new file mode 100644
index 0000000..0abdcaa
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/hashes/__init__.py
@@ -0,0 +1,41 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+import glob
+import os
+
+from arcane.util.hasher import hash_string
+
+_STRING_TO_HASH = {}
+_HASH_TO_STRING = {}
+
+
+def load_files():
+ directory = os.path.dirname(__file__)
+
+ for filepath in glob.glob(os.path.join(directory, '*.txt')):
+ lines = list(map(lambda s: s.strip(), open(filepath).readlines()))
+
+ _STRING_TO_HASH.update({
+ s: hash_string(s) for s in lines
+ })
+
+ _HASH_TO_STRING.update({
+ hash_string(s): s for s in lines
+ })
+
+
+def string_to_hash(s):
+ return _STRING_TO_HASH.get(s, s)
+
+
+def hash_to_string(h):
+ return _HASH_TO_STRING.get(h, h)
+
+
+load_files()
diff --git a/mbEditorPro/arcane/enums/hashes/attrs.txt b/mbEditorPro2.0/arcane/enums/hashes/attrs.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/attrs.txt
rename to mbEditorPro2.0/arcane/enums/hashes/attrs.txt
diff --git a/mbEditorPro/arcane/enums/hashes/classes.txt b/mbEditorPro2.0/arcane/enums/hashes/classes.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/classes.txt
rename to mbEditorPro2.0/arcane/enums/hashes/classes.txt
diff --git a/mbEditorPro/arcane/enums/hashes/discipline.txt b/mbEditorPro2.0/arcane/enums/hashes/discipline.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/discipline.txt
rename to mbEditorPro2.0/arcane/enums/hashes/discipline.txt
diff --git a/mbEditorPro/arcane/enums/hashes/effects.txt b/mbEditorPro2.0/arcane/enums/hashes/effects.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/effects.txt
rename to mbEditorPro2.0/arcane/enums/hashes/effects.txt
diff --git a/mbEditorPro/arcane/enums/hashes/environment.txt b/mbEditorPro2.0/arcane/enums/hashes/environment.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/environment.txt
rename to mbEditorPro2.0/arcane/enums/hashes/environment.txt
diff --git a/mbEditorPro/arcane/enums/hashes/poweractions.txt b/mbEditorPro2.0/arcane/enums/hashes/poweractions.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/poweractions.txt
rename to mbEditorPro2.0/arcane/enums/hashes/poweractions.txt
diff --git a/mbEditorPro/arcane/enums/hashes/powers.txt b/mbEditorPro2.0/arcane/enums/hashes/powers.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/powers.txt
rename to mbEditorPro2.0/arcane/enums/hashes/powers.txt
diff --git a/mbEditorPro/arcane/enums/hashes/races.txt b/mbEditorPro2.0/arcane/enums/hashes/races.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/races.txt
rename to mbEditorPro2.0/arcane/enums/hashes/races.txt
diff --git a/mbEditorPro/arcane/enums/hashes/resources.txt b/mbEditorPro2.0/arcane/enums/hashes/resources.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/resources.txt
rename to mbEditorPro2.0/arcane/enums/hashes/resources.txt
diff --git a/mbEditorPro/arcane/enums/hashes/skills.txt b/mbEditorPro2.0/arcane/enums/hashes/skills.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/skills.txt
rename to mbEditorPro2.0/arcane/enums/hashes/skills.txt
diff --git a/mbEditorPro/arcane/enums/hashes/soundtables.txt b/mbEditorPro2.0/arcane/enums/hashes/soundtables.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/soundtables.txt
rename to mbEditorPro2.0/arcane/enums/hashes/soundtables.txt
diff --git a/mbEditorPro/arcane/enums/hashes/talents.txt b/mbEditorPro2.0/arcane/enums/hashes/talents.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/talents.txt
rename to mbEditorPro2.0/arcane/enums/hashes/talents.txt
diff --git a/mbEditorPro/arcane/enums/hashes/weather.txt b/mbEditorPro2.0/arcane/enums/hashes/weather.txt
similarity index 100%
rename from mbEditorPro/arcane/enums/hashes/weather.txt
rename to mbEditorPro2.0/arcane/enums/hashes/weather.txt
diff --git a/mbEditorPro2.0/arcane/enums/zone/arc_mobile.py b/mbEditorPro2.0/arcane/enums/zone/arc_mobile.py
new file mode 100644
index 0000000..68dbb7e
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/zone/arc_mobile.py
@@ -0,0 +1,38 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+MOBILE = 1
+BANKER = 2
+SHOPKEEPER = 3
+TRAINER = 4
+MERCHANT = 8
+HIRELING = 9
+PET = 10
+MINION = 11
+
+MOBILE_TO_STRING = {
+ MOBILE: 'MOBILE',
+ BANKER: 'BANKER',
+ SHOPKEEPER: 'SHOPKEEPER',
+ TRAINER: 'TRAINER',
+ MERCHANT: 'MERCHANT',
+ HIRELING: 'HIRELING',
+ PET: 'PET',
+ MINION: 'MINION',
+}
+
+STRING_TO_MOBILE = {
+ 'MOBILE': MOBILE,
+ 'BANKER': BANKER,
+ 'SHOPKEEPER': SHOPKEEPER,
+ 'TRAINER': TRAINER,
+ 'MERCHANT': MERCHANT,
+ 'HIRELING': HIRELING,
+ 'PET': PET,
+ 'MINION': MINION,
+}
diff --git a/mbEditorPro2.0/arcane/enums/zone/arc_prop.py b/mbEditorPro2.0/arcane/enums/zone/arc_prop.py
new file mode 100644
index 0000000..29af9d8
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/zone/arc_prop.py
@@ -0,0 +1,23 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+PROP = 5
+CITY = 6
+CONTAINER = 7
+
+PROP_TO_STRING = {
+ PROP: 'PROP',
+ CITY: 'CITY',
+ CONTAINER: 'CONTAINER',
+}
+
+STRING_TO_PROP = {
+ 'PROP': PROP,
+ 'CITY': CITY,
+ 'CONTAINER': CONTAINER,
+}
diff --git a/mbEditorPro2.0/arcane/enums/zone/arc_terraingen.py b/mbEditorPro2.0/arcane/enums/zone/arc_terraingen.py
new file mode 100644
index 0000000..e1da3e3
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/zone/arc_terraingen.py
@@ -0,0 +1,35 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+PEAKED = 1
+RIDGED = 2
+ROLLING = 3
+MESA = 5
+PLANAR = 4
+MESH = 6
+TARGA = 7
+
+TERRAIN_TYPE_TO_STRING = {
+ PEAKED: 'PEAKED',
+ RIDGED: 'RIDGED',
+ ROLLING: 'ROLLING',
+ MESA: 'MESA',
+ PLANAR: 'PLANAR',
+ MESH: 'MESH',
+ TARGA: 'TARGA',
+}
+
+STRING_TO_TERRAIN_TYPE = {
+ 'PEAKED': PEAKED,
+ 'RIDGED': RIDGED,
+ 'ROLLING': ROLLING,
+ 'MESA': MESA,
+ 'PLANAR': PLANAR,
+ 'MESH': MESH,
+ 'TARGA': TARGA,
+}
diff --git a/mbEditorPro2.0/arcane/enums/zone/arc_zone.py b/mbEditorPro2.0/arcane/enums/zone/arc_zone.py
new file mode 100644
index 0000000..08fd94a
--- /dev/null
+++ b/mbEditorPro2.0/arcane/enums/zone/arc_zone.py
@@ -0,0 +1,62 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+ELLIPTICAL = 0
+RECTANGULAR = 1
+
+ZONE_TO_STRING = {
+ ELLIPTICAL: 'ELLIPTICAL',
+ RECTANGULAR: 'RECTANGULAR',
+}
+
+STRING_TO_ZONE = {
+ 'ELLIPTICAL': ELLIPTICAL,
+ 'RECTANGULAR': RECTANGULAR,
+}
+
+GLOBAL = 0
+LOCAL = 1
+
+TILECOORD_TO_STRING = {
+ GLOBAL: 'GLOBAL',
+ LOCAL: 'LOCAL',
+}
+
+STRING_TO_TILECOORD = {
+ 'GLOBAL': GLOBAL,
+ 'LOCAL': LOCAL,
+}
+
+ADJACENT = 0
+RANDOM = 1
+
+PATTERN_TO_STRING = {
+ ADJACENT: 'ADJACENT',
+ RANDOM: 'RANDOM',
+}
+
+STRING_TO_PATTERN = {
+ 'ADJACENT': ADJACENT,
+ 'RANDOM': RANDOM,
+}
+
+PARENT = 0
+WORLD = 1
+SELF = 2
+
+SEALEVEL_TO_STRING = {
+ PARENT: 'PARENT',
+ WORLD: 'WORLD',
+ SELF: 'SELF',
+}
+
+STRING_TO_SEALEVEL = {
+ 'PARENT': PARENT,
+ 'WORLD': WORLD,
+ 'SELF': SELF,
+}
diff --git a/mbEditorPro/arcane/enums/zone/arc_zone_goal.py b/mbEditorPro2.0/arcane/enums/zone/arc_zone_goal.py
similarity index 50%
rename from mbEditorPro/arcane/enums/zone/arc_zone_goal.py
rename to mbEditorPro2.0/arcane/enums/zone/arc_zone_goal.py
index 6287172..b4e237a 100644
--- a/mbEditorPro/arcane/enums/zone/arc_zone_goal.py
+++ b/mbEditorPro2.0/arcane/enums/zone/arc_zone_goal.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
GOAL_TYPE_NONE = 0
GOAL_TYPE_POINTS_ORDERED = 1
diff --git a/mbEditorPro2.0/arcane/objects/ArcAssetStructureObject.py b/mbEditorPro2.0/arcane/objects/ArcAssetStructureObject.py
new file mode 100644
index 0000000..43a5353
--- /dev/null
+++ b/mbEditorPro2.0/arcane/objects/ArcAssetStructureObject.py
@@ -0,0 +1,29 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from arcane.util import ResStream
+from .ArcStructureObject import ArcStructureObject
+
+
+class ArcAssetStructureObject(ArcStructureObject):
+ def load_binary(self, stream: ResStream):
+ super().load_binary(stream)
+ self.asset_structure_template_id = stream.read_qword()
+
+ def save_binary(self, stream: ResStream):
+ super().save_binary(stream)
+ stream.write_qword(self.asset_structure_template_id)
+
+ def load_json(self, data):
+ super().load_json(data)
+ self.asset_structure_template_id = data['asset_structure_template_id']
+
+ def save_json(self):
+ data = super().save_json()
+ data['asset_structure_template_id'] = self.asset_structure_template_id
+ return data
diff --git a/mbEditorPro/arcane/objects/ArcCityAssetTemplate.py b/mbEditorPro2.0/arcane/objects/ArcCityAssetTemplate.py
similarity index 91%
rename from mbEditorPro/arcane/objects/ArcCityAssetTemplate.py
rename to mbEditorPro2.0/arcane/objects/ArcCityAssetTemplate.py
index 357caf4..f837119 100644
--- a/mbEditorPro/arcane/objects/ArcCityAssetTemplate.py
+++ b/mbEditorPro2.0/arcane/objects/ArcCityAssetTemplate.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
@@ -130,13 +130,13 @@ class ArcCityAssetTemplate():
self.template_energy_set = stream.read_dword()
self.template_use_trigger = stream.read_string()
- self.template_unkown_check1 = stream.read_bool()
- if self.template_unkown_check1:
+ self.template_unknown_check1 = stream.read_bool()
+ if self.template_unknown_check1:
pass
self.template_loot_trigger = stream.read_string()
- self.template_unkown_check2 = stream.read_bool()
- if self.template_unkown_check2:
+ self.template_unknown_check2 = stream.read_bool()
+ if self.template_unknown_check2:
pass
self.has_embedded_template = stream.read_bool()
@@ -199,7 +199,7 @@ class ArcCityAssetTemplate():
stream.read_dword(),
] for _ in range(num_resource_limit)
]
- self.template_unkown = stream.read_dword()
+ self.template_unknown = stream.read_dword()
def save_binary(self, stream: ResStream):
stream.write_dword(self.template_max_ranks)
@@ -232,9 +232,9 @@ class ArcCityAssetTemplate():
stream.write_dword(self.template_damage_set)
stream.write_dword(self.template_energy_set)
stream.write_string(self.template_use_trigger)
- stream.write_bool(self.template_unkown_check1)
+ stream.write_bool(self.template_unknown_check1)
stream.write_string(self.template_loot_trigger)
- stream.write_bool(self.template_unkown_check2)
+ stream.write_bool(self.template_unknown_check2)
stream.write_bool(self.has_embedded_template)
if self.has_embedded_template:
self.template_embed_template.save_binary(stream)
@@ -276,7 +276,7 @@ class ArcCityAssetTemplate():
stream.write_dword(resource[0])
stream.write_dword(resource[1])
stream.write_dword(resource[2])
- stream.write_dword(self.template_unkown)
+ stream.write_dword(self.template_unknown)
def load_json(self, data):
self.template_max_ranks = data['template_max_ranks']
@@ -307,9 +307,9 @@ class ArcCityAssetTemplate():
self.template_damage_set = data['template_damage_set']
self.template_energy_set = data['template_energy_set']
self.template_use_trigger = data['template_use_trigger']
- self.template_unkown_check1 = data['template_unkown_check1']
+ self.template_unknown_check1 = data['template_unknown_check1']
self.template_loot_trigger = data['template_loot_trigger']
- self.template_unkown_check2 = data['template_unkown_check2']
+ self.template_unknown_check2 = data['template_unknown_check2']
self.has_embedded_template = data['has_embedded_template']
if self.has_embedded_template:
self.template_embed_template = ArcCityAssetTemplate()
@@ -330,7 +330,7 @@ class ArcCityAssetTemplate():
self.template_placement_type = data['template_placement_type']
self.template_offering_adjustment = data['template_offering_adjustment']
self.template_resource_limit = data['template_resource_limit']
- self.template_unkown = data['template_unkown']
+ self.template_unknown = data['template_unknown']
def save_json(self):
data = OrderedDict()
@@ -362,9 +362,9 @@ class ArcCityAssetTemplate():
data['template_damage_set'] = self.template_damage_set
data['template_energy_set'] = self.template_energy_set
data['template_use_trigger'] = self.template_use_trigger
- data['template_unkown_check1'] = self.template_unkown_check1
+ data['template_unknown_check1'] = self.template_unknown_check1
data['template_loot_trigger'] = self.template_loot_trigger
- data['template_unkown_check2'] = self.template_unkown_check2
+ data['template_unknown_check2'] = self.template_unknown_check2
data['has_embedded_template'] = self.has_embedded_template
if self.has_embedded_template:
data['template_embed_template'] = self.template_embed_template.save_json()
@@ -382,5 +382,5 @@ class ArcCityAssetTemplate():
data['template_placement_type'] = self.template_placement_type
data['template_offering_adjustment'] = self.template_offering_adjustment
data['template_resource_limit'] = self.template_resource_limit
- data['template_unkown'] = self.template_unkown
+ data['template_unknown'] = self.template_unknown
return data
diff --git a/mbEditorPro/arcane/objects/ArcCombatObj.py b/mbEditorPro2.0/arcane/objects/ArcCombatObj.py
similarity index 70%
rename from mbEditorPro/arcane/objects/ArcCombatObj.py
rename to mbEditorPro2.0/arcane/objects/ArcCombatObj.py
index 472b46b..8cae9b9 100644
--- a/mbEditorPro/arcane/objects/ArcCombatObj.py
+++ b/mbEditorPro2.0/arcane/objects/ArcCombatObj.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/objects/ArcContainerObject.py b/mbEditorPro2.0/arcane/objects/ArcContainerObject.py
similarity index 76%
rename from mbEditorPro/arcane/objects/ArcContainerObject.py
rename to mbEditorPro2.0/arcane/objects/ArcContainerObject.py
index d1820bd..53796fe 100644
--- a/mbEditorPro/arcane/objects/ArcContainerObject.py
+++ b/mbEditorPro2.0/arcane/objects/ArcContainerObject.py
@@ -1,10 +1,11 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
from arcane.util import ResStream
from .ArcItem import ArcItem
from .common.Inventory import Inventory
diff --git a/mbEditorPro/arcane/objects/ArcDeed.py b/mbEditorPro2.0/arcane/objects/ArcDeed.py
similarity index 78%
rename from mbEditorPro/arcane/objects/ArcDeed.py
rename to mbEditorPro2.0/arcane/objects/ArcDeed.py
index a1c443b..acf3b88 100644
--- a/mbEditorPro/arcane/objects/ArcDeed.py
+++ b/mbEditorPro2.0/arcane/objects/ArcDeed.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
from .ArcItem import ArcItem
diff --git a/mbEditorPro/arcane/objects/ArcDoorObject.py b/mbEditorPro2.0/arcane/objects/ArcDoorObject.py
similarity index 81%
rename from mbEditorPro/arcane/objects/ArcDoorObject.py
rename to mbEditorPro2.0/arcane/objects/ArcDoorObject.py
index 8b65dfa..6e53bc3 100644
--- a/mbEditorPro/arcane/objects/ArcDoorObject.py
+++ b/mbEditorPro2.0/arcane/objects/ArcDoorObject.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/objects/ArcDungeonUnitObject.py b/mbEditorPro2.0/arcane/objects/ArcDungeonUnitObject.py
similarity index 54%
rename from mbEditorPro/arcane/objects/ArcDungeonUnitObject.py
rename to mbEditorPro2.0/arcane/objects/ArcDungeonUnitObject.py
index 949a93b..c557fd4 100644
--- a/mbEditorPro/arcane/objects/ArcDungeonUnitObject.py
+++ b/mbEditorPro2.0/arcane/objects/ArcDungeonUnitObject.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util.ResStream import ResStream
from .ArcStructureObject import ArcStructureObject
diff --git a/mbEditorPro/arcane/objects/ArcItem.py b/mbEditorPro2.0/arcane/objects/ArcItem.py
similarity index 96%
rename from mbEditorPro/arcane/objects/ArcItem.py
rename to mbEditorPro2.0/arcane/objects/ArcItem.py
index 24c8b6c..0c90e82 100644
--- a/mbEditorPro/arcane/objects/ArcItem.py
+++ b/mbEditorPro2.0/arcane/objects/ArcItem.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/objects/ArcKey.py b/mbEditorPro2.0/arcane/objects/ArcKey.py
similarity index 56%
rename from mbEditorPro/arcane/objects/ArcKey.py
rename to mbEditorPro2.0/arcane/objects/ArcKey.py
index c352251..83a1d76 100644
--- a/mbEditorPro/arcane/objects/ArcKey.py
+++ b/mbEditorPro2.0/arcane/objects/ArcKey.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
from .ArcItem import ArcItem
diff --git a/mbEditorPro/arcane/objects/ArcObj.py b/mbEditorPro2.0/arcane/objects/ArcObj.py
similarity index 87%
rename from mbEditorPro/arcane/objects/ArcObj.py
rename to mbEditorPro2.0/arcane/objects/ArcObj.py
index bbef6b5..b198198 100644
--- a/mbEditorPro/arcane/objects/ArcObj.py
+++ b/mbEditorPro2.0/arcane/objects/ArcObj.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/objects/ArcRune.py b/mbEditorPro2.0/arcane/objects/ArcRune.py
similarity index 95%
rename from mbEditorPro/arcane/objects/ArcRune.py
rename to mbEditorPro2.0/arcane/objects/ArcRune.py
index a2631e0..1bf5cf7 100644
--- a/mbEditorPro/arcane/objects/ArcRune.py
+++ b/mbEditorPro2.0/arcane/objects/ArcRune.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/objects/ArcStaticObject.py b/mbEditorPro2.0/arcane/objects/ArcStaticObject.py
similarity index 80%
rename from mbEditorPro/arcane/objects/ArcStaticObject.py
rename to mbEditorPro2.0/arcane/objects/ArcStaticObject.py
index ca429e6..7b3f52f 100644
--- a/mbEditorPro/arcane/objects/ArcStaticObject.py
+++ b/mbEditorPro2.0/arcane/objects/ArcStaticObject.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/objects/ArcStructureObject.py b/mbEditorPro2.0/arcane/objects/ArcStructureObject.py
similarity index 88%
rename from mbEditorPro/arcane/objects/ArcStructureObject.py
rename to mbEditorPro2.0/arcane/objects/ArcStructureObject.py
index 704da80..6f19123 100644
--- a/mbEditorPro/arcane/objects/ArcStructureObject.py
+++ b/mbEditorPro2.0/arcane/objects/ArcStructureObject.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
@@ -30,9 +30,9 @@ class Region:
stream.read_byte(),
stream.read_byte()
]
- self.region_unkown2 = stream.read_byte()
- self.region_unkown3 = stream.read_byte()
- self.region_unkown4 = stream.read_tuple()
+ self.region_unknown2 = stream.read_byte()
+ self.region_unknown3 = stream.read_byte()
+ self.region_unknown4 = stream.read_tuple()
def save_binary(self, stream: ResStream):
stream.write_dword(len(self.region_points))
@@ -46,9 +46,9 @@ class Region:
if self.region_has_stairs:
stream.write_byte(self.region_stairs[0])
stream.write_byte(self.region_stairs[1])
- stream.write_byte(self.region_unkown2)
- stream.write_byte(self.region_unkown3)
- stream.write_tuple(self.region_unkown4)
+ stream.write_byte(self.region_unknown2)
+ stream.write_byte(self.region_unknown3)
+ stream.write_tuple(self.region_unknown4)
def load_json(self, data):
self.region_points = data['region_points']
@@ -61,9 +61,9 @@ class Region:
self.region_has_stairs = data['region_has_stairs']
if self.region_has_stairs:
self.region_stairs = data['region_stairs']
- self.region_unkown2 = data['region_unkown2']
- self.region_unkown3 = data['region_unkown3']
- self.region_unkown4 = data['region_unkown4']
+ self.region_unknown2 = data['region_unknown2']
+ self.region_unknown3 = data['region_unknown3']
+ self.region_unknown4 = data['region_unknown4']
def save_json(self):
data = OrderedDict()
@@ -77,9 +77,9 @@ class Region:
data['region_has_stairs'] = self.region_has_stairs
if self.region_has_stairs:
data['region_stairs'] = self.region_stairs
- data['region_unkown2'] = self.region_unkown2
- data['region_unkown3'] = self.region_unkown3
- data['region_unkown4'] = self.region_unkown4
+ data['region_unknown2'] = self.region_unknown2
+ data['region_unknown3'] = self.region_unknown3
+ data['region_unknown4'] = self.region_unknown4
return data
diff --git a/mbEditorPro2.0/arcane/objects/__init__.py b/mbEditorPro2.0/arcane/objects/__init__.py
new file mode 100644
index 0000000..3c6c3fc
--- /dev/null
+++ b/mbEditorPro2.0/arcane/objects/__init__.py
@@ -0,0 +1,21 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from .ArcAssetStructureObject import ArcAssetStructureObject
+from .ArcCityAssetTemplate import ArcCityAssetTemplate
+from .ArcCombatObj import ArcCombatObj, ArcCharacter
+from .ArcContainerObject import ArcContainerObject
+from .ArcDeed import ArcDeed
+from .ArcDoorObject import ArcDoorObject
+from .ArcDungeonUnitObject import ArcDungeonUnitObject, ArcDungeonExitObject, ArcDungeonStairObject
+from .ArcItem import ArcItem
+from .ArcKey import ArcKey
+from .ArcObj import ArcObj
+from .ArcRune import ArcRune
+from .ArcStaticObject import ArcStaticObject
+from .ArcStructureObject import ArcStructureObject
diff --git a/mbEditorPro/arcane/objects/common/Arcane.py b/mbEditorPro2.0/arcane/objects/common/Arcane.py
similarity index 90%
rename from mbEditorPro/arcane/objects/common/Arcane.py
rename to mbEditorPro2.0/arcane/objects/common/Arcane.py
index 3c3128d..2b6d7ba 100644
--- a/mbEditorPro/arcane/objects/common/Arcane.py
+++ b/mbEditorPro2.0/arcane/objects/common/Arcane.py
@@ -1,10 +1,11 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
from collections import OrderedDict
from arcane.enums.hashes import hash_to_string, string_to_hash
diff --git a/mbEditorPro/arcane/objects/common/Class.py b/mbEditorPro2.0/arcane/objects/common/Class.py
similarity index 54%
rename from mbEditorPro/arcane/objects/common/Class.py
rename to mbEditorPro2.0/arcane/objects/common/Class.py
index af22e1a..0a0757c 100644
--- a/mbEditorPro/arcane/objects/common/Class.py
+++ b/mbEditorPro2.0/arcane/objects/common/Class.py
@@ -1,10 +1,11 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
from collections import OrderedDict
from arcane.enums.hashes import hash_to_string, string_to_hash
diff --git a/mbEditorPro2.0/arcane/objects/common/Discipline.py b/mbEditorPro2.0/arcane/objects/common/Discipline.py
new file mode 100644
index 0000000..2881b48
--- /dev/null
+++ b/mbEditorPro2.0/arcane/objects/common/Discipline.py
@@ -0,0 +1,41 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.enums.hashes import hash_to_string, string_to_hash
+from arcane.util import ResStream
+
+
+class DiscRequired:
+ def load_binary(self, stream: ResStream):
+ discs = stream.read_dword()
+ self.disc_restrict = stream.read_bool()
+ self.disc_values = [
+ stream.read_dword() for _ in range(discs)
+ ]
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(len(self.disc_values))
+ stream.write_bool(self.disc_restrict)
+ for disc in self.disc_values:
+ stream.write_dword(disc)
+
+ def load_json(self, data):
+ self.disc_restrict = data['restrict']
+ self.disc_values = []
+ for disc in data['discs']:
+ self.disc_values.append(string_to_hash(disc))
+
+ def save_json(self):
+ data = OrderedDict()
+ data['restrict'] = self.disc_restrict
+ data['discs'] = []
+ for disc in self.disc_values:
+ data['discs'].append(hash_to_string(disc))
+ return data
diff --git a/mbEditorPro/arcane/objects/common/Inventory.py b/mbEditorPro2.0/arcane/objects/common/Inventory.py
similarity index 72%
rename from mbEditorPro/arcane/objects/common/Inventory.py
rename to mbEditorPro2.0/arcane/objects/common/Inventory.py
index bd3fbd3..1f86cee 100644
--- a/mbEditorPro/arcane/objects/common/Inventory.py
+++ b/mbEditorPro2.0/arcane/objects/common/Inventory.py
@@ -1,10 +1,11 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
from collections import OrderedDict
from arcane.enums.common.arc_inventory import *
diff --git a/mbEditorPro2.0/arcane/objects/common/Race.py b/mbEditorPro2.0/arcane/objects/common/Race.py
new file mode 100644
index 0000000..e683398
--- /dev/null
+++ b/mbEditorPro2.0/arcane/objects/common/Race.py
@@ -0,0 +1,41 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.enums.hashes import hash_to_string, string_to_hash
+from arcane.util import ResStream
+
+
+class RaceRequired:
+ def load_binary(self, stream: ResStream):
+ races = stream.read_dword()
+ self.race_restrict = stream.read_bool()
+ self.race_values = [
+ stream.read_dword() for _ in range(races)
+ ]
+
+ def save_binary(self, stream: ResStream):
+ stream.write_dword(len(self.race_values))
+ stream.write_bool(self.race_restrict)
+ for race in self.race_values:
+ stream.write_dword(race)
+
+ def load_json(self, data):
+ self.race_restrict = data['restrict']
+ self.race_values = []
+ for race in data['races']:
+ self.race_values.append(string_to_hash(race))
+
+ def save_json(self):
+ data = OrderedDict()
+ data['restrict'] = self.race_restrict
+ data['races'] = []
+ for race in self.race_values:
+ data['races'].append(hash_to_string(race))
+ return data
diff --git a/mbEditorPro/arcane/objects/common/SparseData.py b/mbEditorPro2.0/arcane/objects/common/SparseData.py
similarity index 78%
rename from mbEditorPro/arcane/objects/common/SparseData.py
rename to mbEditorPro2.0/arcane/objects/common/SparseData.py
index d5418e9..b22f6a8 100644
--- a/mbEditorPro/arcane/objects/common/SparseData.py
+++ b/mbEditorPro2.0/arcane/objects/common/SparseData.py
@@ -1,10 +1,11 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
from collections import OrderedDict
from arcane.enums.arc_sparse import *
diff --git a/mbEditorPro2.0/arcane/objects/common/__init__.py b/mbEditorPro2.0/arcane/objects/common/__init__.py
new file mode 100644
index 0000000..3f769e0
--- /dev/null
+++ b/mbEditorPro2.0/arcane/objects/common/__init__.py
@@ -0,0 +1,7 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
diff --git a/mbEditorPro/arcane/util/ArcFileCache.py b/mbEditorPro2.0/arcane/util/ArcFileCache.py
similarity index 75%
rename from mbEditorPro/arcane/util/ArcFileCache.py
rename to mbEditorPro2.0/arcane/util/ArcFileCache.py
index f6ccd14..9b94758 100644
--- a/mbEditorPro/arcane/util/ArcFileCache.py
+++ b/mbEditorPro2.0/arcane/util/ArcFileCache.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
import struct
import zlib
diff --git a/mbEditorPro/arcane/util/ResStream.py b/mbEditorPro2.0/arcane/util/ResStream.py
similarity index 64%
rename from mbEditorPro/arcane/util/ResStream.py
rename to mbEditorPro2.0/arcane/util/ResStream.py
index dc12936..3eee3d4 100644
--- a/mbEditorPro/arcane/util/ResStream.py
+++ b/mbEditorPro2.0/arcane/util/ResStream.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
import struct
from io import BytesIO
@@ -18,6 +18,14 @@ class ResStream:
data = self.buffer.read(1)
return struct.unpack(' 0xFFFFFFFF:
+ raise OverflowError
+ if x > 0x7FFFFFFF:
+ x = int(0x100000000 - x)
+ if x < 2147483648:
+ return -x
+ else:
+ return -2147483648
+ return x
diff --git a/mbEditorPro2.0/arcane/zones/ArcDungeonInfo.py b/mbEditorPro2.0/arcane/zones/ArcDungeonInfo.py
new file mode 100644
index 0000000..0020745
--- /dev/null
+++ b/mbEditorPro2.0/arcane/zones/ArcDungeonInfo.py
@@ -0,0 +1,39 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from collections import OrderedDict
+
+from arcane.util import ResStream
+
+
+class ArcDungeonInfo:
+ def load_binary(self, stream: ResStream):
+ self.dungeon_template_id = stream.read_qword()
+ self.dungeon_unknown = stream.read_qword()
+ self.dungeon_spawn_location = stream.read_tuple()
+ self.dungeon_y_offset = stream.read_float()
+
+ def save_binary(self, stream: ResStream):
+ stream.write_qword(self.dungeon_template_id)
+ stream.write_qword(self.dungeon_unknown)
+ stream.write_tuple(self.dungeon_spawn_location)
+ stream.write_float(self.dungeon_y_offset)
+
+ def save_json(self):
+ data = OrderedDict()
+ data['dungeon_template_id'] = self.dungeon_template_id
+ data['dungeon_unknown'] = self.dungeon_unknown
+ data['dungeon_spawn_location'] = self.dungeon_spawn_location
+ data['dungeon_y_offset'] = self.dungeon_y_offset
+ return data
+
+ def load_json(self, data):
+ self.dungeon_template_id = data['dungeon_template_id']
+ self.dungeon_unknown = data['dungeon_unknown']
+ self.dungeon_spawn_location = data['dungeon_spawn_location']
+ self.dungeon_y_offset = data['dungeon_y_offset']
diff --git a/mbEditorPro/arcane/zones/ArcMobile.py b/mbEditorPro2.0/arcane/zones/ArcMobile.py
similarity index 75%
rename from mbEditorPro/arcane/zones/ArcMobile.py
rename to mbEditorPro2.0/arcane/zones/ArcMobile.py
index 12fbfc3..497b418 100644
--- a/mbEditorPro/arcane/zones/ArcMobile.py
+++ b/mbEditorPro2.0/arcane/zones/ArcMobile.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/ArcProp.py b/mbEditorPro2.0/arcane/zones/ArcProp.py
similarity index 92%
rename from mbEditorPro/arcane/zones/ArcProp.py
rename to mbEditorPro2.0/arcane/zones/ArcProp.py
index 38651b2..d6d8ad9 100644
--- a/mbEditorPro/arcane/zones/ArcProp.py
+++ b/mbEditorPro2.0/arcane/zones/ArcProp.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/ArcSoundInfo.py b/mbEditorPro2.0/arcane/zones/ArcSoundInfo.py
similarity index 58%
rename from mbEditorPro/arcane/zones/ArcSoundInfo.py
rename to mbEditorPro2.0/arcane/zones/ArcSoundInfo.py
index e6fed98..60a7b4d 100644
--- a/mbEditorPro/arcane/zones/ArcSoundInfo.py
+++ b/mbEditorPro2.0/arcane/zones/ArcSoundInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/ArcTerrainGen.py b/mbEditorPro2.0/arcane/zones/ArcTerrainGen.py
similarity index 87%
rename from mbEditorPro/arcane/zones/ArcTerrainGen.py
rename to mbEditorPro2.0/arcane/zones/ArcTerrainGen.py
index fef01ed..74af660 100644
--- a/mbEditorPro/arcane/zones/ArcTerrainGen.py
+++ b/mbEditorPro2.0/arcane/zones/ArcTerrainGen.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/ArcZone.py b/mbEditorPro2.0/arcane/zones/ArcZone.py
similarity index 94%
rename from mbEditorPro/arcane/zones/ArcZone.py
rename to mbEditorPro2.0/arcane/zones/ArcZone.py
index 37fe557..bbfc45d 100644
--- a/mbEditorPro/arcane/zones/ArcZone.py
+++ b/mbEditorPro2.0/arcane/zones/ArcZone.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
@@ -41,7 +41,7 @@ class ArcZone:
self.zone_min_blend = stream.read_float()
self.zone_max_blend = stream.read_float()
self.zone_influence = stream.read_float()
- self.zone_unkown1 = stream.read_float()
+ self.zone_unknown1 = stream.read_float()
self.zone_y_offset = stream.read_float()
self.zone_global_height = stream.read_float()
self.zone_transition_height = stream.read_float()
@@ -154,7 +154,7 @@ class ArcZone:
stream.write_float(self.zone_min_blend)
stream.write_float(self.zone_max_blend)
stream.write_float(self.zone_influence)
- stream.write_float(self.zone_unkown1)
+ stream.write_float(self.zone_unknown1)
stream.write_float(self.zone_y_offset)
stream.write_float(self.zone_global_height)
stream.write_float(self.zone_transition_height)
@@ -255,7 +255,7 @@ class ArcZone:
data['zone_min_blend'] = self.zone_min_blend
data['zone_max_blend'] = self.zone_max_blend
data['zone_influence'] = self.zone_influence
- data['zone_unkown1'] = self.zone_unkown1
+ data['zone_unknown1'] = self.zone_unknown1
data['zone_y_offset'] = self.zone_y_offset
data['zone_global_height'] = self.zone_global_height
data['zone_transition_height'] = self.zone_transition_height
@@ -330,7 +330,7 @@ class ArcZone:
self.zone_min_blend = data['zone_min_blend']
self.zone_max_blend = data['zone_max_blend']
self.zone_influence = data['zone_influence']
- self.zone_unkown1 = data['zone_unkown1']
+ self.zone_unknown1 = data['zone_unknown1']
self.zone_y_offset = data['zone_y_offset']
self.zone_global_height = data['zone_global_height']
self.zone_transition_height = data['zone_transition_height']
diff --git a/mbEditorPro/arcane/zones/ArcZoneBiomState.py b/mbEditorPro2.0/arcane/zones/ArcZoneBiomState.py
similarity index 57%
rename from mbEditorPro/arcane/zones/ArcZoneBiomState.py
rename to mbEditorPro2.0/arcane/zones/ArcZoneBiomState.py
index 9183dc8..5c5509e 100644
--- a/mbEditorPro/arcane/zones/ArcZoneBiomState.py
+++ b/mbEditorPro2.0/arcane/zones/ArcZoneBiomState.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/ArcZoneEvent.py b/mbEditorPro2.0/arcane/zones/ArcZoneEvent.py
similarity index 67%
rename from mbEditorPro/arcane/zones/ArcZoneEvent.py
rename to mbEditorPro2.0/arcane/zones/ArcZoneEvent.py
index 4050d0e..c5e0e17 100644
--- a/mbEditorPro/arcane/zones/ArcZoneEvent.py
+++ b/mbEditorPro2.0/arcane/zones/ArcZoneEvent.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
@@ -14,7 +14,7 @@ class ArcZTriggerAction:
self.zone_trigger_action_type = stream.read_dword()
self.zone_trigger_action_unknown1 = stream.read_bool()
self.zone_trigger_action_is_timed = stream.read_bool()
- self.zone_trigger_action_unkown2 = stream.read_bool()
+ self.zone_trigger_action_unknown2 = stream.read_bool()
if self.zone_trigger_action_is_timed:
self.zone_trigger_action_time_begin = stream.read_float()
@@ -36,11 +36,11 @@ class ArcZoneEventInfo:
self.zone_event_spawn_radius = stream.read_float()
self.zone_event_fc_label = stream.read_string()
self.zone_event_event_name = stream.read_string()
- self.zone_event_unkown1 = stream.read_dword()
+ self.zone_event_unknown1 = stream.read_dword()
self.zone_event_spawn_location = stream.read_tuple()
self.zone_event_parent_name = stream.read_string()
- self.zone_event_unkown2 = stream.read_dword()
- self.zone_event_unkown3 = stream.read_bool()
+ self.zone_event_unknown2 = stream.read_dword()
+ self.zone_event_unknown3 = stream.read_bool()
num_triggers = stream.read_dword()
self.zone_event_triggers = [ArcZTriggerAction() for _ in range(num_triggers)]
for action in self.zone_event_triggers:
diff --git a/mbEditorPro/arcane/zones/ArcZoneGoal.py b/mbEditorPro2.0/arcane/zones/ArcZoneGoal.py
similarity index 81%
rename from mbEditorPro/arcane/zones/ArcZoneGoal.py
rename to mbEditorPro2.0/arcane/zones/ArcZoneGoal.py
index b862a7d..65b8339 100644
--- a/mbEditorPro/arcane/zones/ArcZoneGoal.py
+++ b/mbEditorPro2.0/arcane/zones/ArcZoneGoal.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/TerrainObjectInfo.py b/mbEditorPro2.0/arcane/zones/TerrainObjectInfo.py
similarity index 79%
rename from mbEditorPro/arcane/zones/TerrainObjectInfo.py
rename to mbEditorPro2.0/arcane/zones/TerrainObjectInfo.py
index 60a881f..00803c0 100644
--- a/mbEditorPro/arcane/zones/TerrainObjectInfo.py
+++ b/mbEditorPro2.0/arcane/zones/TerrainObjectInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
@@ -26,7 +26,7 @@ class TerrainObjectInfo:
self.terrain_object_max_slope = stream.read_float()
self.terrain_object_max_pop = stream.read_dword()
self.terrain_object_is_fractal_pop = stream.read_bool()
- self.terrain_object_unkown1 = stream.read_dword()
+ self.terrain_object_unknown1 = stream.read_dword()
self.terrain_object_y_offset = stream.read_float()
self.terrain_object_pop_image_id = stream.read_qword()
self.terrain_object_image_min_y = stream.read_float()
@@ -45,7 +45,7 @@ class TerrainObjectInfo:
stream.write_float(self.terrain_object_max_slope)
stream.write_dword(self.terrain_object_max_pop)
stream.write_bool(self.terrain_object_is_fractal_pop)
- stream.write_dword(self.terrain_object_unkown1)
+ stream.write_dword(self.terrain_object_unknown1)
stream.write_float(self.terrain_object_y_offset)
stream.write_qword(self.terrain_object_pop_image_id)
stream.write_float(self.terrain_object_image_min_y)
@@ -65,7 +65,7 @@ class TerrainObjectInfo:
data['terrain_object_max_slope'] = self.terrain_object_max_slope
data['terrain_object_max_pop'] = self.terrain_object_max_pop
data['terrain_object_is_fractal_pop'] = self.terrain_object_is_fractal_pop
- data['terrain_object_unkown1'] = self.terrain_object_unkown1
+ data['terrain_object_unknown1'] = self.terrain_object_unknown1
data['terrain_object_y_offset'] = self.terrain_object_y_offset
data['terrain_object_pop_image_id'] = self.terrain_object_pop_image_id
data['terrain_object_image_min_y'] = self.terrain_object_image_min_y
@@ -85,7 +85,7 @@ class TerrainObjectInfo:
self.terrain_object_max_slope = data['terrain_object_max_slope']
self.terrain_object_max_pop = data['terrain_object_max_pop']
self.terrain_object_is_fractal_pop = data['terrain_object_is_fractal_pop']
- self.terrain_object_unkown1 = data['terrain_object_unkown1']
+ self.terrain_object_unknown1 = data['terrain_object_unknown1']
self.terrain_object_y_offset = data['terrain_object_y_offset']
self.terrain_object_pop_image_id = data['terrain_object_pop_image_id']
self.terrain_object_image_min_y = data['terrain_object_image_min_y']
diff --git a/mbEditorPro/arcane/zones/WaterInfo.py b/mbEditorPro2.0/arcane/zones/WaterInfo.py
similarity index 80%
rename from mbEditorPro/arcane/zones/WaterInfo.py
rename to mbEditorPro2.0/arcane/zones/WaterInfo.py
index 96de52d..b6bdf6a 100644
--- a/mbEditorPro/arcane/zones/WaterInfo.py
+++ b/mbEditorPro2.0/arcane/zones/WaterInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro/arcane/zones/WeatherEventInfo.py b/mbEditorPro2.0/arcane/zones/WeatherEventInfo.py
similarity index 72%
rename from mbEditorPro/arcane/zones/WeatherEventInfo.py
rename to mbEditorPro2.0/arcane/zones/WeatherEventInfo.py
index 4c33c34..ad2b7fc 100644
--- a/mbEditorPro/arcane/zones/WeatherEventInfo.py
+++ b/mbEditorPro2.0/arcane/zones/WeatherEventInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
diff --git a/mbEditorPro2.0/arcane/zones/__init__.py b/mbEditorPro2.0/arcane/zones/__init__.py
new file mode 100644
index 0000000..3136759
--- /dev/null
+++ b/mbEditorPro2.0/arcane/zones/__init__.py
@@ -0,0 +1,9 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from .ArcZone import ArcZone
diff --git a/mbEditorPro/arcane/zones/mobile/ArcBasicZoneObjectInfo.py b/mbEditorPro2.0/arcane/zones/mobile/ArcBasicZoneObjectInfo.py
similarity index 72%
rename from mbEditorPro/arcane/zones/mobile/ArcBasicZoneObjectInfo.py
rename to mbEditorPro2.0/arcane/zones/mobile/ArcBasicZoneObjectInfo.py
index b9e6d54..2cfb3f6 100644
--- a/mbEditorPro/arcane/zones/mobile/ArcBasicZoneObjectInfo.py
+++ b/mbEditorPro2.0/arcane/zones/mobile/ArcBasicZoneObjectInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
@@ -21,10 +21,10 @@ class ArcBasicZoneObjectInfo:
self.basic_zone_spawn_radius = stream.read_float()
self.basic_zone_y_rot = stream.read_float()
self.basic_zone_template_id = stream.read_qword()
- self.basic_zone_unkown1 = stream.read_qword()
+ self.basic_zone_unknown1 = stream.read_qword()
self.basic_zone_level_number = stream.read_dword()
self.basic_zone_room_number = stream.read_dword()
- self.basic_zone_unkown2 = stream.read_qword()
+ self.basic_zone_unknown2 = stream.read_qword()
self.basic_zone_dungeon_level = stream.read_dword()
self.basic_zone_dungeon_row = stream.read_dword()
self.basic_zone_dungeon_column = stream.read_dword()
@@ -38,10 +38,10 @@ class ArcBasicZoneObjectInfo:
stream.write_float(self.basic_zone_spawn_radius)
stream.write_float(self.basic_zone_y_rot)
stream.write_qword(self.basic_zone_template_id)
- stream.write_qword(self.basic_zone_unkown1)
+ stream.write_qword(self.basic_zone_unknown1)
stream.write_dword(self.basic_zone_level_number)
stream.write_dword(self.basic_zone_room_number)
- stream.write_qword(self.basic_zone_unkown2)
+ stream.write_qword(self.basic_zone_unknown2)
stream.write_dword(self.basic_zone_dungeon_level)
stream.write_dword(self.basic_zone_dungeon_row)
stream.write_dword(self.basic_zone_dungeon_column)
@@ -55,10 +55,10 @@ class ArcBasicZoneObjectInfo:
data['basic_zone_spawn_radius'] = self.basic_zone_spawn_radius
data['basic_zone_y_rot'] = self.basic_zone_y_rot
data['basic_zone_template_id'] = self.basic_zone_template_id
- data['basic_zone_unkown1'] = self.basic_zone_unkown1
+ data['basic_zone_unknown1'] = self.basic_zone_unknown1
data['basic_zone_level_number'] = self.basic_zone_level_number
data['basic_zone_room_number'] = self.basic_zone_room_number
- data['basic_zone_unkown2'] = self.basic_zone_unkown2
+ data['basic_zone_unknown2'] = self.basic_zone_unknown2
data['basic_zone_dungeon_level'] = self.basic_zone_dungeon_level
data['basic_zone_dungeon_row'] = self.basic_zone_dungeon_row
data['basic_zone_dungeon_column'] = self.basic_zone_dungeon_column
@@ -72,10 +72,10 @@ class ArcBasicZoneObjectInfo:
self.basic_zone_spawn_radius = data['basic_zone_spawn_radius']
self.basic_zone_y_rot = data['basic_zone_y_rot']
self.basic_zone_template_id = data['basic_zone_template_id']
- self.basic_zone_unkown1 = data['basic_zone_unkown1']
+ self.basic_zone_unknown1 = data['basic_zone_unknown1']
self.basic_zone_level_number = data['basic_zone_level_number']
self.basic_zone_room_number = data['basic_zone_room_number']
- self.basic_zone_unkown2 = data['basic_zone_unkown2']
+ self.basic_zone_unknown2 = data['basic_zone_unknown2']
self.basic_zone_dungeon_level = data['basic_zone_dungeon_level']
self.basic_zone_dungeon_row = data['basic_zone_dungeon_row']
self.basic_zone_dungeon_column = data['basic_zone_dungeon_column']
diff --git a/mbEditorPro/arcane/zones/mobile/HirelingInfo.py b/mbEditorPro2.0/arcane/zones/mobile/HirelingInfo.py
similarity index 87%
rename from mbEditorPro/arcane/zones/mobile/HirelingInfo.py
rename to mbEditorPro2.0/arcane/zones/mobile/HirelingInfo.py
index 89d2e95..31e45d1 100644
--- a/mbEditorPro/arcane/zones/mobile/HirelingInfo.py
+++ b/mbEditorPro2.0/arcane/zones/mobile/HirelingInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
from .MerchantInfo import MerchantInfo
diff --git a/mbEditorPro/arcane/zones/mobile/MerchantInfo.py b/mbEditorPro2.0/arcane/zones/mobile/MerchantInfo.py
similarity index 67%
rename from mbEditorPro/arcane/zones/mobile/MerchantInfo.py
rename to mbEditorPro2.0/arcane/zones/mobile/MerchantInfo.py
index c526eb4..727eec0 100644
--- a/mbEditorPro/arcane/zones/mobile/MerchantInfo.py
+++ b/mbEditorPro2.0/arcane/zones/mobile/MerchantInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
from .MobileInfo import MobileInfo
diff --git a/mbEditorPro2.0/arcane/zones/mobile/MinionInfo.py b/mbEditorPro2.0/arcane/zones/mobile/MinionInfo.py
new file mode 100644
index 0000000..8c39fc3
--- /dev/null
+++ b/mbEditorPro2.0/arcane/zones/mobile/MinionInfo.py
@@ -0,0 +1,16 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+
+from arcane.util import ResStream
+from .HirelingInfo import HirelingInfo
+
+
+class MinionInfo(HirelingInfo):
+ def load_binary(self, stream: ResStream):
+ super().load_binary(stream)
+ self.minion_info_u = stream.read_string()
diff --git a/mbEditorPro/arcane/zones/mobile/MobileInfo.py b/mbEditorPro2.0/arcane/zones/mobile/MobileInfo.py
similarity index 92%
rename from mbEditorPro/arcane/zones/mobile/MobileInfo.py
rename to mbEditorPro2.0/arcane/zones/mobile/MobileInfo.py
index abfa208..b0bb0a2 100644
--- a/mbEditorPro/arcane/zones/mobile/MobileInfo.py
+++ b/mbEditorPro2.0/arcane/zones/mobile/MobileInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from collections import OrderedDict
@@ -16,24 +16,21 @@ from arcane.util import ResStream
from .ArcBasicZoneObjectInfo import ArcBasicZoneObjectInfo
-class Unkown:
+class Unknown:
def load_binary(self, stream: ResStream):
- self.unkown_u = stream.read_dword()
- self.unkown_u = stream.read_dword()
- self.unkown_u = stream.read_dword()
- self.unkown_check = stream.read_bool()
- if self.unkown_check:
- self.unkown_u = stream.read_qword()
+ self.unknown_u = stream.read_dword()
+ self.unknown_u = stream.read_dword()
+ self.unknown_u = stream.read_dword()
+ self.unknown_check = stream.read_bool()
+ if self.unknown_check:
+ self.unknown_u = stream.read_qword()
else:
- self.unkown_u = stream.read_dword()
- self.unkown_u = stream.read_string()
- self.unkown_u = stream.read_float()
+ self.unknown_u = stream.read_dword()
+ self.unknown_u = stream.read_string()
+ self.unknown_u = stream.read_float()
class InventoryContents:
- def __init__(self):
- self.mobile_inventory_check = None
-
def load_binary(self, stream: ResStream):
self.mobile_inventory_u = stream.read_qword()
self.mobile_inventory_u = stream.read_qword()
@@ -59,7 +56,7 @@ class InventoryContents:
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_u = stream.read_dword()
num = stream.read_dword()
- self.mobile_inventory_u = [Unkown() for _ in range(num)]
+ self.mobile_inventory_u = [Unknown() for _ in range(num)]
self.mobile_inventory_u = stream.read_dword()
self.mobile_inventory_check = stream.read_bool()
if self.mobile_inventory_check:
@@ -88,9 +85,6 @@ class InventoryContents:
class MobileInfo:
- def __init__(self):
- self.mobile_inventory_contents = None
-
def load_binary(self, stream: ResStream):
self.mobile_base_zone = ArcBasicZoneObjectInfo()
self.mobile_base_zone.load_binary(stream)
diff --git a/mbEditorPro/arcane/zones/mobile/ShopKeeperInfo.py b/mbEditorPro2.0/arcane/zones/mobile/ShopKeeperInfo.py
similarity index 65%
rename from mbEditorPro/arcane/zones/mobile/ShopKeeperInfo.py
rename to mbEditorPro2.0/arcane/zones/mobile/ShopKeeperInfo.py
index 7feaeff..2b2e3e2 100644
--- a/mbEditorPro/arcane/zones/mobile/ShopKeeperInfo.py
+++ b/mbEditorPro2.0/arcane/zones/mobile/ShopKeeperInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
from .MobileInfo import MobileInfo
diff --git a/mbEditorPro/arcane/zones/mobile/TrainerInfo.py b/mbEditorPro2.0/arcane/zones/mobile/TrainerInfo.py
similarity index 51%
rename from mbEditorPro/arcane/zones/mobile/TrainerInfo.py
rename to mbEditorPro2.0/arcane/zones/mobile/TrainerInfo.py
index ebe7229..835d00d 100644
--- a/mbEditorPro/arcane/zones/mobile/TrainerInfo.py
+++ b/mbEditorPro2.0/arcane/zones/mobile/TrainerInfo.py
@@ -1,10 +1,10 @@
-# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
-# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
-# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
-# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
-# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
-# Magicbane Emulator Project © 2013 - 2022
-# www.magicbane.com
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
from arcane.util import ResStream
from .MobileInfo import MobileInfo
diff --git a/mbEditorPro2.0/arcane/zones/mobile/__init__.py b/mbEditorPro2.0/arcane/zones/mobile/__init__.py
new file mode 100644
index 0000000..3f769e0
--- /dev/null
+++ b/mbEditorPro2.0/arcane/zones/mobile/__init__.py
@@ -0,0 +1,7 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
diff --git a/mbEditorPro2.0/mbEditorPro.py b/mbEditorPro2.0/mbEditorPro.py
new file mode 100644
index 0000000..f4d443b
--- /dev/null
+++ b/mbEditorPro2.0/mbEditorPro.py
@@ -0,0 +1,875 @@
+# • ▌ ▄ ·. ▄▄▄▄· ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄▄▄ ▄▄▄ ▄▄▄·▄▄▄
+# ·██ ▐███▪▐█ ▀█▪ ▀▄.▀·██▪ ██ ██ •██ ▪ ▀▄ █· ▐█ ▄█▀▄ █·▪
+# ▐█ ▌▐▌▐█·▐█▀▀█▄ ▐▀▀▪▄▐█· ▐█▌▐█· ▐█.▪ ▄█▀▄ ▐▀▀▄ ██▀·▐▀▀▄ ▄█▀▄
+# ██ ██▌▐█▌██▄▪▐█ ▐█▄▄▌██. ██ ▐█▌ ▐█▌·▐█▌.▐▌▐█•█▌ ▐█▪·•▐█•█▌▐█▌.▐▌
+# ▀▀ █▪▀▀▀·▀▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ .▀ .▀ ▀ ▀█▄▀▪
+# Magicbane Emulator Project © 2013 - 2022
+# www.magicbane.com
+#
+
+import glob
+import io
+import json
+import os
+import sys
+import wave
+
+from arcane.ArcImage import *
+from arcane.ArcMesh import *
+from arcane.ArcMotion import *
+from arcane.ArcRender import *
+from arcane.ArcSkeleton import *
+from arcane.ArcSound import *
+from arcane.ArcTile import *
+from arcane.ArcVisual import *
+from arcane.enums.arc_object import *
+from arcane.objects import *
+from arcane.objects import ArcObj, ArcDoorObject, ArcStaticObject, ArcStructureObject, ArcAssetStructureObject, \
+ ArcDungeonUnitObject, ArcDungeonExitObject, ArcDungeonStairObject, ArcItem, ArcCharacter
+from arcane.util import *
+from arcane.zones import *
+
+DUMP_DIRECTORY = 'ARCANE_DUMP'
+WORKING_DIRECTORY = os.path.dirname(__file__)
+TARGET_DIRECTORY = os.path.join(WORKING_DIRECTORY, DUMP_DIRECTORY)
+COBJECTS_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'COBJECTS')
+CZONE_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'CZONE')
+SOUND_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'SOUND')
+TEXTURE_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'TEXTURE')
+TERRAIN_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'TERRAIN')
+MESH_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'MESH')
+VISUAL_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'VISUAL')
+MOTION_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'MOTION')
+TILE_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'TILE')
+SKELETON_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'SKELETON')
+RENDER_DIRECTORY = os.path.join(TARGET_DIRECTORY, 'RENDER')
+COBJECTS_MAGIC = 0x434c4e54
+
+COBJECTS_MAP = {
+ OBJECT_TYPE_LIGHT: ArcObj,
+ OBJECT_TYPE_DOOR: ArcDoorObject,
+ OBJECT_TYPE_STATIC: ArcStaticObject,
+ OBJECT_TYPE_STRUCTURE: ArcStructureObject,
+ OBJECT_TYPE_ASSETSTRUCTURE: ArcAssetStructureObject,
+ OBJECT_TYPE_DUNGEONUNIT: ArcDungeonUnitObject,
+ OBJECT_TYPE_DUNGEONEXIT: ArcDungeonExitObject,
+ OBJECT_TYPE_DUNGEONSTAIR: ArcDungeonStairObject,
+ OBJECT_TYPE_ITEM: ArcItem,
+ OBJECT_TYPE_PLAYER: ArcCharacter,
+ OBJECT_TYPE_MOBILE: ArcCharacter,
+ OBJECT_TYPE_RUNE: ArcRune,
+ OBJECT_TYPE_CONTAINER: ArcContainerObject,
+ OBJECT_TYPE_DEED: ArcDeed,
+ OBJECT_TYPE_KEY: ArcKey,
+ OBJECT_TYPE_ASSET: ArcCityAssetTemplate,
+ OBJECT_TYPE_OBJECT: ArcObj,
+}
+
+EDITOR_COMMANDS = [
+ 'pack',
+ 'unpack',
+ 'test'
+]
+
+EDITOR_TARGETS = [
+ 'cobjects',
+ 'czones',
+ 'sound',
+ 'texture',
+ 'mesh',
+ 'visual',
+ 'motion',
+ 'tile',
+ 'skeleton',
+ 'terrain',
+ 'render',
+ 'all'
+]
+
+
+def init_cobjects():
+ for obj_type in COBJECTS_MAP:
+ directory_path = os.path.join(COBJECTS_DIRECTORY, OBJECT_TYPE_TO_STRING[obj_type])
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_czones():
+ directory_path = CZONE_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_sound():
+ directory_path = SOUND_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_texture():
+ directory_path = TEXTURE_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_terrain():
+ directory_path = TERRAIN_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_mesh():
+ directory_path = MESH_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_visual():
+ directory_path = VISUAL_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_motion():
+ directory_path = MOTION_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_tile():
+ directory_path = TILE_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_skeleton():
+ directory_path = SKELETON_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def init_render():
+ directory_path = RENDER_DIRECTORY
+ os.makedirs(directory_path, exist_ok=True)
+
+
+def unpack_cobjects():
+ init_cobjects()
+
+ resources = load_cache_file('CObjects.cache')
+
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ magic = in_stream.read_dword()
+ obj_type = in_stream.read_dword()
+
+ arc_in = COBJECTS_MAP[obj_type]()
+ filepath = os.path.join(
+ COBJECTS_DIRECTORY,
+ OBJECT_TYPE_TO_STRING[obj_type],
+ f'{res_id:d}.json'
+ )
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_cobjects():
+ init_cobjects()
+
+ resources = []
+ for obj_type in COBJECTS_MAP:
+ directory = os.path.join(
+ COBJECTS_DIRECTORY,
+ OBJECT_TYPE_TO_STRING[obj_type]
+ )
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ out_stream.write_dword(COBJECTS_MAGIC)
+ out_stream.write_dword(obj_type)
+
+ arc_in = COBJECTS_MAP[obj_type]()
+ arc_in.load_json(json_data)
+ arc_in.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('CObjects.cache.new', resources)
+
+
+def test_cobjects():
+ resources = load_cache_file('CObjects.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ magic = in_stream.read_dword()
+ o_type = in_stream.read_dword()
+ out_stream.write_dword(magic)
+ out_stream.write_dword(o_type)
+
+ arc_in = COBJECTS_MAP[o_type]()
+ arc_out = COBJECTS_MAP[o_type]()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_czones():
+ init_czones()
+
+ resources = load_cache_file('CZone.cache')
+
+ for res_id, data in resources:
+ arc_zone = ArcZone()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ CZONE_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_zone.load_binary(in_stream)
+ parsed = arc_zone.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_czones():
+ init_czones()
+
+ resources = []
+ directory = CZONE_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_zone = ArcZone()
+ arc_zone.load_json(json_data)
+ arc_zone.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('CZone.cache.new', resources)
+
+
+def test_czones():
+ resources = load_cache_file('CZone.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcZone()
+ arc_out = ArcZone()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_sound():
+ init_sound()
+
+ resources = load_cache_file('Sound.cache')
+
+ for res_id, data in resources:
+ arc_sound = ArcSound()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ SOUND_DIRECTORY,
+ f'{res_id:d}.wav'
+ )
+
+ arc_sound.load_binary(in_stream)
+ with open(filepath, 'wb') as fp:
+ wave_writer = wave.Wave_write(fp)
+ arc_sound.save_wav(wave_writer)
+ wave_writer.close()
+
+
+def pack_sound():
+ init_sound()
+
+ resources = []
+ directory = SOUND_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.wav')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.wav')[0])
+ wav_reader = Wave_read(open(filepath, 'rb'))
+
+ out_stream = ResStream()
+ arc_sound = ArcSound()
+ arc_sound.load_wav(wav_reader)
+ arc_sound.save_binary(out_stream)
+ wav_reader.close()
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Sound.cache.new', resources, False)
+
+
+def test_sound():
+ resources = load_cache_file('Sound.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcSound()
+ arc_out = ArcSound()
+
+ arc_in.load_binary(in_stream)
+
+ temp = io.BytesIO()
+ writer = wave.Wave_write(temp)
+ arc_in.save_wav(writer)
+
+ temp.seek(0, 0)
+
+ reader = wave.Wave_read(temp)
+ arc_out.load_wav(reader)
+ reader.close()
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_texture():
+ init_texture()
+
+ resources = load_cache_file('Textures.cache')
+ for res_id, data in resources:
+ filepath = os.path.join(
+ TEXTURE_DIRECTORY,
+ f'{res_id:d}.tga'
+ )
+
+ arc_texture = ArcTexture()
+ in_stream = ResStream(data)
+ arc_texture.load_binary(in_stream)
+ arc_texture.save_img(filepath)
+
+
+def pack_texture():
+ init_texture()
+
+ resources = []
+ directory = TEXTURE_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.tga')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.tga')[0])
+
+ arc_texture = ArcTexture()
+ out_stream = ResStream()
+ arc_texture.load_img(filepath)
+ arc_texture.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Textures.cache.new', resources)
+
+
+def test_texture():
+ resources = load_cache_file('Textures.cache')
+ temp = 'temp.tga'
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcTexture()
+ arc_out = ArcTexture()
+
+ temp = 'temp.tga'
+
+ arc_in.load_binary(in_stream)
+ arc_in.save_img(temp)
+
+ arc_out.load_img(temp)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+ try:
+ os.unlink(temp)
+ except:
+ pass
+
+
+def unpack_terrain():
+ init_terrain()
+
+ resources = load_cache_file('TerrainAlpha.cache')
+ for res_id, data in resources:
+ filepath = os.path.join(
+ TERRAIN_DIRECTORY,
+ f'{res_id:d}.tga'
+ )
+
+ arc_terrain = ArcTerrain()
+ in_stream = ResStream(data)
+ arc_terrain.load_binary(in_stream)
+ arc_terrain.save_img(filepath)
+
+
+def pack_terrain():
+ init_terrain()
+
+ resources = []
+ directory = TERRAIN_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.tga')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.tga')[0])
+
+ arc_terrain = ArcTerrain()
+ out_stream = ResStream()
+ arc_terrain.load_img(filepath)
+ arc_terrain.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('TerrainAlpha.cache.new', resources)
+
+
+def test_terrain():
+ resources = load_cache_file('TerrainAlpha.cache')
+ temp = 'temp.tga'
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcTerrain()
+ arc_out = ArcTerrain()
+
+ temp = 'temp.tga'
+
+ arc_in.load_binary(in_stream)
+ arc_in.save_img(temp)
+
+ arc_out.load_img(temp)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+ print()
+ break
+
+ try:
+ os.unlink(temp)
+ except:
+ pass
+
+
+def unpack_mesh():
+ init_mesh()
+
+ resources = load_cache_file('Mesh.cache')
+
+ for res_id, data in resources:
+ arc_mesh = ArcMesh()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ MESH_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_mesh.load_binary(in_stream)
+ parsed = arc_mesh.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_mesh():
+ init_mesh()
+
+ resources = []
+ directory = MESH_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_mesh = ArcMesh()
+ arc_mesh.load_json(json_data)
+ arc_mesh.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Mesh.cache.new', resources)
+
+
+def test_mesh():
+ resources = load_cache_file('Mesh.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcMesh()
+ arc_out = ArcMesh()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_visual():
+ init_visual()
+
+ resources = load_cache_file('Visual.cache')
+
+ for res_id, data in resources:
+ arc_visual = ArcVisual()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ VISUAL_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_visual.load_binary(in_stream)
+ parsed = arc_visual.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_visual():
+ init_visual()
+
+ resources = []
+ directory = VISUAL_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_visual = ArcVisual()
+ arc_visual.load_json(json_data)
+ arc_visual.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Visual.cache.new', resources)
+
+
+def test_visual():
+ resources = load_cache_file('Visual.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcVisual()
+ arc_out = ArcVisual()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_motion():
+ init_motion()
+
+ resources = load_cache_file('Motion.cache')
+
+ for res_id, data in resources:
+ arc_motion = ArcMotion()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ MOTION_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_motion.load_binary(in_stream)
+ parsed = arc_motion.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_motion():
+ init_motion()
+
+ resources = []
+ directory = MOTION_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_motion = ArcMotion()
+ arc_motion.load_json(json_data)
+ arc_motion.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Motion.cache.new', resources)
+
+
+def test_motion():
+ resources = load_cache_file('Motion.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcMotion()
+ arc_out = ArcMotion()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_tile():
+ init_tile()
+
+ resources = load_cache_file('Tile.cache')
+
+ for res_id, data in resources:
+ arc_tile = ArcTileManager()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ TILE_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_tile.load_binary(in_stream)
+ parsed = arc_tile.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_tile():
+ init_tile()
+
+ resources = []
+ directory = TILE_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_tile = ArcTileManager()
+ arc_tile.load_json(json_data)
+ arc_tile.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Tile.cache.new', resources)
+
+
+def test_tile():
+ resources = load_cache_file('Tile.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcTileManager()
+ arc_out = ArcTileManager()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_skeleton():
+ init_skeleton()
+
+ resources = load_cache_file('Skeleton.cache')
+
+ for res_id, data in resources:
+ arc_skeleton = ArcSkeleton()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ SKELETON_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_skeleton.load_binary(in_stream)
+
+ parsed = arc_skeleton.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_skeleton():
+ init_skeleton()
+
+ resources = []
+ directory = SKELETON_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_skeleton = ArcSkeleton()
+ arc_skeleton.load_json(json_data)
+ arc_skeleton.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Skeleton.cache.new', resources)
+
+
+def test_skeleton():
+ resources = load_cache_file('Skeleton.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcSkeleton()
+ arc_out = ArcSkeleton()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_render():
+ init_render()
+
+ resources = load_cache_file('render.cache')
+
+ for res_id, data in resources:
+ arc_render = ArcRender()
+ in_stream = ResStream(data)
+ filepath = os.path.join(
+ RENDER_DIRECTORY,
+ f'{res_id:d}.json'
+ )
+ arc_render.load_binary(in_stream)
+
+ parsed = arc_render.save_json()
+ with open(filepath, 'w') as fp:
+ json.dump(parsed, fp, indent=2)
+
+
+def pack_render():
+ init_render()
+
+ resources = []
+ directory = RENDER_DIRECTORY
+ for filepath in glob.glob(os.path.join(directory, '*.json')):
+ filename = os.path.basename(filepath)
+ res_id = int(filename.split('.json')[0])
+ json_data = json.load(open(filepath))
+
+ out_stream = ResStream()
+ arc_render = ArcRender()
+ arc_render.load_json(json_data)
+ arc_render.save_binary(out_stream)
+
+ resources.append([res_id, out_stream.get_bytes()])
+
+ save_cache_file('Render.cache.new', resources)
+
+
+def test_render():
+ resources = load_cache_file('Render.cache')
+ for res_id, data in resources:
+ in_stream = ResStream(data)
+ out_stream = ResStream()
+
+ arc_in = ArcRender()
+ arc_out = ArcRender()
+
+ arc_in.load_binary(in_stream)
+ parsed = arc_in.save_json()
+ arc_out.load_json(parsed)
+ arc_out.save_binary(out_stream)
+ try:
+ assert in_stream.get_bytes() == out_stream.get_bytes()
+ except:
+ print(res_id, in_stream.buffer.tell(), out_stream.buffer.tell())
+
+
+def unpack_all():
+ for cache_type in EDITOR_TARGETS[:-1]:
+ method = 'unpack_' + cache_type + '()'
+ print(method)
+ try:
+ exec(method)
+ except:
+ print('***Error: Missing or corrupt ' + cache_type + ' cache.')
+
+
+def pack_all():
+ for cache_type in EDITOR_TARGETS[:-1]:
+ method = 'pack_' + cache_type + '()'
+ print(method)
+ try:
+ exec(method)
+ except:
+ print('***Error: Missing or corrupt ' + cache_type + ' cache.')
+
+
+def test_all():
+ for cache_type in EDITOR_TARGETS[:-1]:
+ method = 'test_' + cache_type + '()'
+ print(method)
+ try:
+ exec(method)
+ except:
+ print('***Error: Missing or corrupt ' + cache_type + ' cache.')
+
+
+def usage():
+ print('_____________mbEditorPro_2.0_______________')
+ print(' www.magicbane.com | repo.magicbane.com')
+ print('')
+ print('Commands: ')
+ print(*EDITOR_COMMANDS)
+ print('Targets: ')
+ print(*EDITOR_TARGETS)
+ print('')
+ print('example: unpack texture')
+ print('example: pack texture')
+ exit(1)
+
+
+def main():
+ if not sys.argv[2:]:
+ usage()
+
+ if sys.argv[1] not in EDITOR_COMMANDS:
+ usage()
+
+ if sys.argv[2] not in EDITOR_TARGETS:
+ usage()
+
+ method = '_'.join(sys.argv[1:3]) + '()'
+ print(method)
+ exec(method)
+
+
+main()
diff --git a/mbEditorPro2.0/requirements.txt b/mbEditorPro2.0/requirements.txt
new file mode 100644
index 0000000..c5a1f25
--- /dev/null
+++ b/mbEditorPro2.0/requirements.txt
@@ -0,0 +1 @@
+pillow==9.3.0