diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 000000000..b7085d7cc
Binary files /dev/null and b/.DS_Store differ
diff --git a/ClassicUO.licenseheader b/ClassicUO.licenseheader
deleted file mode 100644
index 8e792d850..000000000
--- a/ClassicUO.licenseheader
+++ /dev/null
@@ -1,30 +0,0 @@
-extensions: .cs
-#region license
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#endregion
\ No newline at end of file
diff --git a/ClassicUO.sln b/ClassicUO.sln
deleted file mode 100644
index 72a688832..000000000
--- a/ClassicUO.sln
+++ /dev/null
@@ -1,142 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.4.33205.214
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{36371756-8DDA-41A4-BB9A-B7651459ADC1}"
- ProjectSection(SolutionItems) = preProject
- README.md = README.md
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{FD7202D2-B96B-4425-8C61-F0D5254A06F7}"
- ProjectSection(SolutionItems) = preProject
- scripts\build.cmd = scripts\build.cmd
- scripts\build.sh = scripts\build.sh
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{D5E764E7-2719-4937-AC10-0D2D789A1134}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManifestCreator", "tools\ManifestCreator\ManifestCreator.csproj", "{6F193271-70B3-48EC-9CE5-B8EE1A5CA89E}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "monokickstart", "monokickstart", "{D7DD340F-1EE2-4F8A-AA3E-A8FC76098AD6}"
- ProjectSection(SolutionItems) = preProject
- tools\monokickstart\Accessibility.dll = tools\monokickstart\Accessibility.dll
- tools\monokickstart\ClassicUO = tools\monokickstart\ClassicUO
- tools\monokickstart\ClassicUO.bin.osx = tools\monokickstart\ClassicUO.bin.osx
- tools\monokickstart\ClassicUO.bin.x86_64 = tools\monokickstart\ClassicUO.bin.x86_64
- tools\monokickstart\Microsoft.CSharp.dll = tools\monokickstart\Microsoft.CSharp.dll
- tools\monokickstart\Mono.Posix.dll = tools\monokickstart\Mono.Posix.dll
- tools\monokickstart\Mono.Security.dll = tools\monokickstart\Mono.Security.dll
- tools\monokickstart\monoconfig = tools\monokickstart\monoconfig
- tools\monokickstart\monomachineconfig = tools\monokickstart\monomachineconfig
- tools\monokickstart\mscorlib.dll = tools\monokickstart\mscorlib.dll
- tools\monokickstart\Newtonsoft.Json.dll = tools\monokickstart\Newtonsoft.Json.dll
- tools\monokickstart\System.Configuration.dll = tools\monokickstart\System.Configuration.dll
- tools\monokickstart\System.Core.dll = tools\monokickstart\System.Core.dll
- tools\monokickstart\System.Data.dll = tools\monokickstart\System.Data.dll
- tools\monokickstart\System.dll = tools\monokickstart\System.dll
- tools\monokickstart\System.Drawing.dll = tools\monokickstart\System.Drawing.dll
- tools\monokickstart\System.IO.Compression.dll = tools\monokickstart\System.IO.Compression.dll
- tools\monokickstart\System.IO.Compression.FileSystem.dll = tools\monokickstart\System.IO.Compression.FileSystem.dll
- tools\monokickstart\System.Numerics.dll = tools\monokickstart\System.Numerics.dll
- tools\monokickstart\System.Runtime.Serialization.dll = tools\monokickstart\System.Runtime.Serialization.dll
- tools\monokickstart\System.Security.dll = tools\monokickstart\System.Security.dll
- tools\monokickstart\System.Windows.Forms.dll = tools\monokickstart\System.Windows.Forms.dll
- tools\monokickstart\System.Xml.dll = tools\monokickstart\System.Xml.dll
- tools\monokickstart\System.Xml.Linq.dll = tools\monokickstart\System.Xml.Linq.dll
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "settings", "settings", "{21AF20E5-1A3A-414D-9B1F-AB8F3800E567}"
- ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- ClassicUO.licenseheader = ClassicUO.licenseheader
- ClassicUO.sln.DotSettings = ClassicUO.sln.DotSettings
- Directory.Build.props = Directory.Build.props
- FNA.Settings.props = FNA.Settings.props
- EndProjectSection
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{B766E918-7350-473A-B28D-63C344385924}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicUO.UnitTests", "tests\ClassicUO.UnitTests\ClassicUO.UnitTests.csproj", "{85972CEA-4AB1-45DC-922C-00C4E17764B5}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FNA.Core", "external\FNA\FNA.Core.csproj", "{3F9AB6CE-3AD1-40B6-B2AA-C4D82F76258F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicUO.Client", "src\ClassicUO.Client\ClassicUO.Client.csproj", "{D7EE32B0-ED1C-4263-B017-6C3EC74FD731}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicUO.Assets", "src\ClassicUO.Assets\ClassicUO.Assets.csproj", "{DDF690A2-7588-44BC-8E2E-9080C746A49C}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicUO.Utility", "src\ClassicUO.Utility\ClassicUO.Utility.csproj", "{6B932930-D24C-43BB-8877-85B4F3F7A57B}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "external", "external", "{FA5D7AB8-3570-4E55-95B0-35BA6842FEE3}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicUO.Renderer", "src\ClassicUO.Renderer\ClassicUO.Renderer.csproj", "{535BE739-1314-4F8D-B24B-06890DDD3B8D}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassicUO.IO", "src\ClassicUO.IO\ClassicUO.IO.csproj", "{69C1A629-F519-4F5A-85D5-4E0317CD267F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP3Sharp", "external\MP3Sharp\MP3Sharp\MP3Sharp.csproj", "{5AF00B6D-70C2-4CB0-A5D8-41F488F0DDF2}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FontStashSharp.FNA.Core", "external\FontStashSharp\src\XNA\FontStashSharp.FNA.Core.csproj", "{5ACA68DA-A282-434D-919F-B243A801D4C3}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6F193271-70B3-48EC-9CE5-B8EE1A5CA89E}.Debug|x64.ActiveCfg = Debug|x64
- {6F193271-70B3-48EC-9CE5-B8EE1A5CA89E}.Release|x64.ActiveCfg = Release|x64
- {85972CEA-4AB1-45DC-922C-00C4E17764B5}.Debug|x64.ActiveCfg = Debug|x64
- {85972CEA-4AB1-45DC-922C-00C4E17764B5}.Release|x64.ActiveCfg = Release|x64
- {3F9AB6CE-3AD1-40B6-B2AA-C4D82F76258F}.Debug|x64.ActiveCfg = Debug|x64
- {3F9AB6CE-3AD1-40B6-B2AA-C4D82F76258F}.Debug|x64.Build.0 = Debug|x64
- {3F9AB6CE-3AD1-40B6-B2AA-C4D82F76258F}.Release|x64.ActiveCfg = Release|x64
- {3F9AB6CE-3AD1-40B6-B2AA-C4D82F76258F}.Release|x64.Build.0 = Release|x64
- {D7EE32B0-ED1C-4263-B017-6C3EC74FD731}.Debug|x64.ActiveCfg = Debug|x64
- {D7EE32B0-ED1C-4263-B017-6C3EC74FD731}.Debug|x64.Build.0 = Debug|x64
- {D7EE32B0-ED1C-4263-B017-6C3EC74FD731}.Release|x64.ActiveCfg = Release|x64
- {D7EE32B0-ED1C-4263-B017-6C3EC74FD731}.Release|x64.Build.0 = Release|x64
- {DDF690A2-7588-44BC-8E2E-9080C746A49C}.Debug|x64.ActiveCfg = Debug|x64
- {DDF690A2-7588-44BC-8E2E-9080C746A49C}.Debug|x64.Build.0 = Debug|x64
- {DDF690A2-7588-44BC-8E2E-9080C746A49C}.Release|x64.ActiveCfg = Release|x64
- {DDF690A2-7588-44BC-8E2E-9080C746A49C}.Release|x64.Build.0 = Release|x64
- {6B932930-D24C-43BB-8877-85B4F3F7A57B}.Debug|x64.ActiveCfg = Debug|x64
- {6B932930-D24C-43BB-8877-85B4F3F7A57B}.Debug|x64.Build.0 = Debug|x64
- {6B932930-D24C-43BB-8877-85B4F3F7A57B}.Release|x64.ActiveCfg = Release|x64
- {6B932930-D24C-43BB-8877-85B4F3F7A57B}.Release|x64.Build.0 = Release|x64
- {535BE739-1314-4F8D-B24B-06890DDD3B8D}.Debug|x64.ActiveCfg = Debug|x64
- {535BE739-1314-4F8D-B24B-06890DDD3B8D}.Debug|x64.Build.0 = Debug|x64
- {535BE739-1314-4F8D-B24B-06890DDD3B8D}.Release|x64.ActiveCfg = Release|x64
- {535BE739-1314-4F8D-B24B-06890DDD3B8D}.Release|x64.Build.0 = Release|x64
- {69C1A629-F519-4F5A-85D5-4E0317CD267F}.Debug|x64.ActiveCfg = Debug|x64
- {69C1A629-F519-4F5A-85D5-4E0317CD267F}.Debug|x64.Build.0 = Debug|x64
- {69C1A629-F519-4F5A-85D5-4E0317CD267F}.Release|x64.ActiveCfg = Release|x64
- {69C1A629-F519-4F5A-85D5-4E0317CD267F}.Release|x64.Build.0 = Release|x64
- {5AF00B6D-70C2-4CB0-A5D8-41F488F0DDF2}.Debug|x64.ActiveCfg = Debug|x64
- {5AF00B6D-70C2-4CB0-A5D8-41F488F0DDF2}.Debug|x64.Build.0 = Debug|x64
- {5AF00B6D-70C2-4CB0-A5D8-41F488F0DDF2}.Release|x64.ActiveCfg = Release|x64
- {5AF00B6D-70C2-4CB0-A5D8-41F488F0DDF2}.Release|x64.Build.0 = Release|x64
- {5ACA68DA-A282-434D-919F-B243A801D4C3}.Debug|x64.ActiveCfg = Debug|Any CPU
- {5ACA68DA-A282-434D-919F-B243A801D4C3}.Debug|x64.Build.0 = Debug|Any CPU
- {5ACA68DA-A282-434D-919F-B243A801D4C3}.Release|x64.ActiveCfg = Release|Any CPU
- {5ACA68DA-A282-434D-919F-B243A801D4C3}.Release|x64.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {6F193271-70B3-48EC-9CE5-B8EE1A5CA89E} = {D5E764E7-2719-4937-AC10-0D2D789A1134}
- {D7DD340F-1EE2-4F8A-AA3E-A8FC76098AD6} = {D5E764E7-2719-4937-AC10-0D2D789A1134}
- {85972CEA-4AB1-45DC-922C-00C4E17764B5} = {B766E918-7350-473A-B28D-63C344385924}
- {3F9AB6CE-3AD1-40B6-B2AA-C4D82F76258F} = {FA5D7AB8-3570-4E55-95B0-35BA6842FEE3}
- {D7EE32B0-ED1C-4263-B017-6C3EC74FD731} = {36371756-8DDA-41A4-BB9A-B7651459ADC1}
- {DDF690A2-7588-44BC-8E2E-9080C746A49C} = {36371756-8DDA-41A4-BB9A-B7651459ADC1}
- {6B932930-D24C-43BB-8877-85B4F3F7A57B} = {36371756-8DDA-41A4-BB9A-B7651459ADC1}
- {535BE739-1314-4F8D-B24B-06890DDD3B8D} = {36371756-8DDA-41A4-BB9A-B7651459ADC1}
- {69C1A629-F519-4F5A-85D5-4E0317CD267F} = {36371756-8DDA-41A4-BB9A-B7651459ADC1}
- {5AF00B6D-70C2-4CB0-A5D8-41F488F0DDF2} = {FA5D7AB8-3570-4E55-95B0-35BA6842FEE3}
- {5ACA68DA-A282-434D-919F-B243A801D4C3} = {FA5D7AB8-3570-4E55-95B0-35BA6842FEE3}
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {0A99E91A-ADAB-45C3-8170-2656140F6EFA}
- EndGlobalSection
-EndGlobal
diff --git a/ClassicUO.sln.DotSettings b/ClassicUO.sln.DotSettings
deleted file mode 100644
index 176e5ac53..000000000
--- a/ClassicUO.sln.DotSettings
+++ /dev/null
@@ -1,11 +0,0 @@
-
- DO_NOT_SHOW
- DO_NOT_SHOW
- DO_NOT_SHOW
- DO_NOT_SHOW
- UO
- <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
-
- True
- True
- True
\ No newline at end of file
diff --git a/Directory.Build.props b/Directory.Build.props
deleted file mode 100644
index 39a22ac87..000000000
--- a/Directory.Build.props
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
- net472
- Preview
- x64
- x64
- true
- true
- true
- true
- false
- false
- PackageReference
-
-
-
- ClassicUO
- KaRaShO'
- 0.1.11.0
- 0.1.11.0
- ClassicUO
- https://www.classicuo.eu/
- An open source implementation of the Ultima Online Classic Client.
-
-
-
- $(DefineConstants);DEV_BUILD
-
-
-
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
\ No newline at end of file
diff --git a/FNA.Settings.props b/FNA.Settings.props
deleted file mode 100644
index 3bfb82dfc..000000000
--- a/FNA.Settings.props
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/LICENSE.md b/LICENSE.md
deleted file mode 100644
index 4ebfb6cc4..000000000
--- a/LICENSE.md
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2022, andreakarasho
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. All advertising materials mentioning features or use of this software
- must display the following acknowledgement:
- This product includes software developed by andreakarasho - https://github.com/andreakarasho
-4. Neither the name of the copyright holder nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
deleted file mode 100644
index ff5479d8c..000000000
--- a/README.md
+++ /dev/null
@@ -1,470 +0,0 @@
-

-
-
-
-
-
-------------------------------------------------------------------
-
-
-Release: [](https://github.com/bittiez/TazUO/actions/workflows/build-test.yml) Dev: [](https://github.com/bittiez/TazUO/actions/workflows/build-test.yml)
-
-
-Join TazUO's discord for ideas/support/updates -> https://discord.gg/SqwtB5g95H
-
-Check out our [wiki](../../wiki) for details on all of the changes TazUO has made for players!
-
-This version of CUO adds [grid containers](../../wiki/TazUO.Grid-Containers) and many other features to the regular CUO client
-
- Searchable
-
- Resizable
-
- Scrollable
-
- Can lock items in specific place
-
- Quick preview for containers inside *if the client has already cached that bag*
-
- Item scaling!
-
-[Cool down bars](../../wiki/TazUO.Cooldown-bars)
-
-[Follow mode improvements](../../wiki/TazUO.Follow-mode)
-
-[Improved journal](../../wiki/TazUO.Journal)
-
-[Nameplate healthbars](../../wiki/TazUO.Nameplate-Healthbars)
-
-And others in our [wiki](../../wiki)
-
-
-
-
-
-
-
-
-
-
-
-
-# Original CUO Readme:
-------------------------------------------------------------------
-
-An open source implementation of the Ultima Online Classic Client.
-
-[](https://github.com/dust765/ClassicUO/actions)
-[](https://github.com/dust765/ClassicUO/actions)
-
-# Project dust765
-This project is to address a problem constructed within the toxicity of this community. This is to show the community, open source projects are not meant for cliques and high school drama but rather the expansion of something greater, innovation. -A penny for your thoughts, the adder that prays beneath the rose.
-
-
-
-# BRANCHES
-
-main is 1:1 from upstream (Karasho)
-
-dev_dust765 stable release
-
-dev_dust765_activedev stable work in progress releases
-
-dev_dust765_x_tazuo Dust765 and TazUO merged
-
-# contact and team info
-
-Discord: dust765#2787
-
-Dust765: 7 Link, 6 Gaechti, 5 Syrupz
-
-Join me on TazUO discord:
-
-
-
-# feature showcase
-
-[Video Part 1 on YouTube](https://youtu.be/aqHiiOhx8Q8)
-
-[Video Part 2 on YouTube](https://youtu.be/P7YBrI3s6ZI)
-
-[Video Part 3 on YouTube](https://youtu.be/074Osj1Fcrg)
-
-# art / hue changes
-
-Stealth footsteps color
-
-Energy Bolt - art and color
-
-Gold - art and color
-
-Tree to stumps / tiles and color
-
-Blockers to stumps / tiles and color
-
-# visual helpers
-
-Highlight tiles at range
-
-Highlight tiles at range if spell is up
-
-Preview field spells, wall of stone and area of effect spells
-
-Glowing weapons
-
-Color own aura by HP
-
-Highlight lasttarget (more colors and options)
-
-# healthbar
-
-highlight lasttarget healthbar
-
-color border by state
-
-flashing outline (many options)
-
-# cursor
-
-Show spell on cursor (and runout countdown)
-
-Color game cursor when targeting (hostile / friendly)
-
-# overhead / underchar
-
-Distance
-
-# oldhealthlines
-
-old healthbars
-
-mana / stamina lines, for self and party,
-
-bigger version and transparency
-
-# misc
-
-Offscreen targeting
-
-Razor lasttarget sync (Razor lasttarget string - set this to the same lasttarget overhead string as set in Razor, so the ClassicUO lasttarget will be the same as in Razor.)
-
-Black Outline for statics
-
-Ignore stamina check
-
-Block Wall of Stone rubberband
-
-Block Energy Field rubberband
-
-# misc2
-
-wireframe view
-
-hue impassable tiles
-
-transparent / invisible house and items by Z level from player and min Z from ground
-
-draw mobiles with surface overhead
-
-ignore list for circle of transparency (txt file created in your /Data/Client folder)
-
-show death location on worldmap
-
-# nameoverhead
-
-hp line in nameoverheads
-
-more filters for nameoverheads
-
-# UI gumps
-
-sticky last target healthbar (healthbar that always will be your last targets healthbar)
-
-bandage gump (bandage timer UI)
-
-# texturemanager
-
-texture manager (arrow or halo on mobiles)
-
-# UCC UI
-
-UI UCC LINES - Draws a line to HUMANS on your screen.
-
-Please specify the correct settings to make theese properly work!
-
-UI UCC AL - Is an autoloot feature / UI. Only works with GridLoot enabled. You can add items to the txt file created in your /Data/Client folder. Recommendation is to set high value items to the autolootlist.txt (items you potentialy would go gray for) and low value items to autolootlistlow. If you check SL (SafeLoot (available for both lists)), items will ONLY be auto looted if you have looting rights. Loot Above ID adds all items to the loot list higher than X, so you dont have to add hundreds of items to the list.
-
-UI UCC BUFFBAR - Provides a visible timer for next swing and disarm. You can enable lines individually enable them and also lock the UI to prevent moving it. There is a txt in /Data/Client to modify the timers for weapons. It does NOT change calculation with SSI or the like.
-
-UI UCC SELF - Is an Automation feature to bandaid yourself, use pouches, pots and enhanced apple (auto rearms a weapon after being disarmed).
-
-Checkboxes on the UI
-
-Rearm Pot - Auto rearm after pot.
-
-Armorer Guild - Auto rearm after being disarmed.
-
-Thiefes Guild - Disables any actions when hidden.
-
-Mages Guild - Disables any actions when a spellcursor is up.
-
-Tavern - Diable auto disarm.
-
-# features macros
-
-HighlightTileAtRange (toggle)
-
-ToggleTransparentHouses (toggle)
-
-ToggleInvisibleHouses (toggle)
-
-UCCLinesToggleLT (toggle)
-
-UCCLinesToggleHM (toggle)
-
-AutoMeditate (toggle)
-
-ToggleECBuffGump / ToggleECDebuffGump / ToggleECStateGump / ToggleModernCooldownBar (toggle)
-
-# simple macros
-
-ObjectInfo (-info command)
-
-OpenCorpses (open corpses in 2 tiles)
-
-OpenJournal2 (open second journal)
-
-SetTargetClientSide (set target client side only)
-
-LastTargetRC (LastTarget with RangeCheck)
-
-HideX (removes a game object)
-
-HealOnHPChange (keep pressed, casts greater heal as soon as HP change)
-
-HarmOnSwing (keep pressed, casts harm as soon as a swinganimation is issued from server)
-
-CureGH (cure or gheal)
-
-# advanced macros
-
-OpenCorpsesSafe (open corpses in 2 tiles safe to loot)
-
-GrabFriendlyBars, GrabEnemyBars, GrabPartyAllyBars (grab all bars with hotkey)
-
-AutoPot (one pot button)
-
-DefendSelfKey, DefendPartyKey (clever defend self or party)
-
-CustomInterrupt (interrupt current spellcast)
-
-EquipManager (fast equip)
-
-SetMimic_PlayerSerial (set master or custom serial for EquipManager)
-
-# commands
-
-type command in chat
-
--mimic (mimic casting of master)
-
--marker X Y (add world marker)
-
-auto add marker for T-Maps
-
--df (defender)
-
--automed (auto meditate)
-
--engage (auto pathfind and attack lasttarget)
-
--autorange (auto show range indicator when weapon is equipped) (edit autorange.txt in /Data/Client to adjust range for individual weapons)
-
-# outlands
-
-disabled features due to client enforcement (code updates NOT maintained)
-
-inferno bridge solver (color specific land tiles)
-
-overhead: Summon timer (also on healthbar)
-
-overhead: Peace timer (also on healthbar)
-
-underchar: Hamstrung timer (also on healthbar)
-
-buffbar: hamstrung
-
-# lobby
-
-connect multiple Dust765 clients to a lobby server to issue commands
-
-[Dust765's LobbyServer] (https://github.com/dust765/LobbyServer)
-
-features: send your lasttarget to be everyones, drop everyones spell on lasttarget, make everyone cast a spell, everyone attack lasttarget
-
-autostealthposition: command: -autohid ((needs connected lobby) broadcast your position when hidden, everyone will see your position
-
-commands: see options for a full list
-
-macros: see options for a full list
-
-# POC
-
-proof of concepts
-
-guardlines: show guardlines on land tiles (disabled due to performance)
-
-# gridloot
-
-The order in which items are shown in grid-loot will now depend on item type.
-
-Motivation: some items are likely to be always looted (e.g. gold, gems) and when looting is performed automatically (e.g. by Razor macros) it makes items to move in a grid making it harder to browse their properties. Hence, items like gold should be at the end of the grid.
-
-# multi journal
-
-Replaces journal with multiple nameable and much better configurable journals
-
-note: edit journals.xml in your profile folder, set hue to 0 if you wish to reset color to default
-
-(use macro OpenJournal2 for old journal)
-
-# status gump
-
-adds a version of the status gump with health / mana / stamina bar when expanded
-
-# modern cooldown bar
-
-adds a macro to open a BuffGump for each type (blue, green, red) similar to the EC client
-
-note: edit ecbuffs.txt / ecdebuffs.txt / ecstates.txt in /Data/Client to swap icons arround
-
-adds a modern version of the cooldown bar
-
-note: filter displayed buffs with modernbuffs.txt in /Data/Client, the EC txt are used to determine color
-
-# on casting gump
-
-shows a little gump on cursor when casting (can be hidden)
-
-main purpose being, to prevent rubberband on servers that dont send a freeze packet during casting
-
-(mod by Mark)
-
-# show all layers
-
-shows all equipment layers on mobiles (covered items should show)
-
-(mod by Mark)
-
-show additional equipment slots on paperdoll (for torso/arms/pants/shoes/cloak)
-
-# thief supreme
-
-override container open range (ie. backpacks dont close until paperdoll gets closed)
-
-hide X macro has been update to hide items inside containers
-
-# visual response manager (WIP)
-
-goal is to have a visual response on your character from various triggers.
-
-bandies, pots, clilocs,....
-
-# Added files
-
-/src/Dust765
-
-/src/Dust765/External
-
-/src/halo.png
-
-/src/arrow.png
-
-/src/Dust765/Macros
-
-/src/Dust765/Managers
-
-/src/Dust765/Autos
-
-/src/Dust765/Shared
-
-/src/Dust765/Lobby
-
-# changed constants
-
-WAIT_FOR_TARGET_DELAY 5000 -> 4000
-
-MAX_CIRCLE_OF_TRANSPARENCY_RADIUS 200 -> 1000
-
-DEATH_SCREEN_TIMER 1500 -> 750
-
-MAX_JOURNAL_HISTORY_COUNT 100 -> 250
-
-# Original readme
-Individuals/hobbyists: support continued maintenance and development via the monthly Patreon:
-
[](http://www.patreon.com/classicuo)
-
-Individuals/hobbyists: support continued maintenance and development via PayPal:
-
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9ZWJBY6MS99D8)
-
-
-
-
-# Introduction
-ClassicUO is an open source implementation of the Ultima Online Classic Client. This client is intended to emulate all standard client versions and is primarily tested against Ultima Online free shards.
-
-The client is currently under heavy development but is functional. The code is based on the [FNA-XNA](https://fna-xna.github.io/) framework. C# is chosen because there is a large community of developers working on Ultima Online server emulators in C#, because FNA-XNA exists and seems reasonably suitable for creating this type of game.
-
-
-
-
-ClassicUO is natively cross platform and supports:
-* Browser [Chrome]
-* Windows [DirectX 11, OpenGL, Vulkan]
-* Linux [OpenGL, Vulkan]
-* macOS [Metal, OpenGL, MoltenVK]
-
-# Download & Play!
-| Platform | Link |
-| --- | --- |
-| Browser | [Play!](https://play.classicuo.org) |
-| Windows x64 | [Download](https://www.classicuo.eu/launcher/win-x64/ClassicUOLauncher-win-x64-release.zip) |
-| Linux x64 | [Download](https://www.classicuo.eu/launcher/linux-x64/ClassicUOLauncher-linux-x64-release.zip) |
-| macOS | [Download](https://www.classicuo.eu/launcher/osx/ClassicUOLauncher-osx-x64-release.zip) |
-
-Or visit the [ClassicUO Website](https://www.classicuo.eu/)
-
-# How to build the project
-
-Clone repository with:
-```
-git config --global url."https://".insteadOf git://
-git clone --recursive https://github.com/ClassicUO/ClassicUO.git
-```
-
-Build the project:
-```
-dotnet build -c Release
-```
-
-# Contribute
-Everyone is welcome to contribute! The GitHub issues and project tracker are kept up to date with tasks that need work.
-
-# Legal
-The code itself has been written using the following projects as a reference:
-
-* [OrionUO](https://github.com/hotride/orionuo)
-* [Razor](https://github.com/msturgill/razor)
-* [UltimaXNA](https://github.com/ZaneDubya/UltimaXNA)
-* [ServUO](https://github.com/servuo/servuo)
-
-Backend:
-* [FNA](https://github.com/FNA-XNA/FNA)
-
-This work is released under the BSD 4 license. This project does not distribute any copyrighted game assets. In order to run this client you'll need to legally obtain a copy of the Ultima Online Classic Client.
-Using a custom client to connect to official UO servers is strictly forbidden. We do not assume any responsibility of the usage of this client.
-
-Ultima Online(R) © 2022 Electronic Arts Inc. All Rights Reserved.
diff --git a/external/FNA b/external/FNA
deleted file mode 160000
index 591b3a37c..000000000
--- a/external/FNA
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 591b3a37cdeabf3ccbd6b66f6ce71e67a4407337
diff --git a/external/FontStashSharp b/external/FontStashSharp
deleted file mode 160000
index f11f97b70..000000000
--- a/external/FontStashSharp
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f11f97b709e50960dd8ce1f727974744c4f8a0dd
diff --git a/external/MP3Sharp b/external/MP3Sharp
deleted file mode 160000
index db2d71d0a..000000000
--- a/external/MP3Sharp
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit db2d71d0aa2ed2fd1609d3ce06db0727ac63eecf
diff --git a/external/cuoapi/cuoapi.dll b/external/cuoapi/cuoapi.dll
deleted file mode 100644
index 77716eebf..000000000
Binary files a/external/cuoapi/cuoapi.dll and /dev/null differ
diff --git a/external/lib64/libFAudio.so.0 b/external/lib64/libFAudio.so.0
deleted file mode 100644
index d63e03266..000000000
Binary files a/external/lib64/libFAudio.so.0 and /dev/null differ
diff --git a/external/lib64/libFNA3D.so.0 b/external/lib64/libFNA3D.so.0
deleted file mode 100644
index 088e15d45..000000000
Binary files a/external/lib64/libFNA3D.so.0 and /dev/null differ
diff --git a/external/lib64/libSDL2-2.0.so.0 b/external/lib64/libSDL2-2.0.so.0
deleted file mode 100644
index 5d2b303ed..000000000
Binary files a/external/lib64/libSDL2-2.0.so.0 and /dev/null differ
diff --git a/external/lib64/libtheorafile.so b/external/lib64/libtheorafile.so
deleted file mode 100644
index d75c3d51a..000000000
Binary files a/external/lib64/libtheorafile.so and /dev/null differ
diff --git a/external/osx/libFAudio.0.dylib b/external/osx/libFAudio.0.dylib
deleted file mode 100644
index 695a59f36..000000000
Binary files a/external/osx/libFAudio.0.dylib and /dev/null differ
diff --git a/external/osx/libFNA3D.0.dylib b/external/osx/libFNA3D.0.dylib
deleted file mode 100644
index b6d848399..000000000
Binary files a/external/osx/libFNA3D.0.dylib and /dev/null differ
diff --git a/external/osx/libMoltenVK.dylib b/external/osx/libMoltenVK.dylib
deleted file mode 100644
index 9cf069dbf..000000000
Binary files a/external/osx/libMoltenVK.dylib and /dev/null differ
diff --git a/external/osx/libSDL2-2.0.0.dylib b/external/osx/libSDL2-2.0.0.dylib
deleted file mode 100644
index 0c714ced6..000000000
Binary files a/external/osx/libSDL2-2.0.0.dylib and /dev/null differ
diff --git a/external/osx/libtheorafile.dylib b/external/osx/libtheorafile.dylib
deleted file mode 100644
index e0ef91a91..000000000
Binary files a/external/osx/libtheorafile.dylib and /dev/null differ
diff --git a/external/osx/libvulkan.1.dylib b/external/osx/libvulkan.1.dylib
deleted file mode 100644
index ff138d4d2..000000000
Binary files a/external/osx/libvulkan.1.dylib and /dev/null differ
diff --git a/external/vulkan/icd.d/MoltenVK_icd.json b/external/vulkan/icd.d/MoltenVK_icd.json
deleted file mode 100644
index 6e4d9ae91..000000000
--- a/external/vulkan/icd.d/MoltenVK_icd.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "file_format_version" : "1.0.0",
- "ICD": {
- "library_path": "../../../MacOS/osx/libMoltenVK.dylib",
- "api_version" : "1.1.0"
- }
-}
diff --git a/external/x64/FAudio.dll b/external/x64/FAudio.dll
deleted file mode 100644
index 2d8fe4fe7..000000000
Binary files a/external/x64/FAudio.dll and /dev/null differ
diff --git a/external/x64/FNA3D.dll b/external/x64/FNA3D.dll
deleted file mode 100644
index b30095267..000000000
Binary files a/external/x64/FNA3D.dll and /dev/null differ
diff --git a/external/x64/SDL2.dll b/external/x64/SDL2.dll
deleted file mode 100644
index 4553fa951..000000000
Binary files a/external/x64/SDL2.dll and /dev/null differ
diff --git a/external/x64/libtheorafile.dll b/external/x64/libtheorafile.dll
deleted file mode 100644
index 93f791595..000000000
Binary files a/external/x64/libtheorafile.dll and /dev/null differ
diff --git a/external/x64/vcruntime140.dll b/external/x64/vcruntime140.dll
deleted file mode 100644
index 459166dc7..000000000
Binary files a/external/x64/vcruntime140.dll and /dev/null differ
diff --git a/external/x64/zlib.dll b/external/x64/zlib.dll
deleted file mode 100644
index c092b8a7c..000000000
Binary files a/external/x64/zlib.dll and /dev/null differ
diff --git a/scripts/build.cmd b/scripts/build.cmd
deleted file mode 100644
index 86a8ee4fa..000000000
--- a/scripts/build.cmd
+++ /dev/null
@@ -1,2 +0,0 @@
-dotnet build "../src/ClassicUO.csproj" -c Release
-dotnet publish "../src/ClassicUO.csproj" -c Release /p:DefineConstants="STANDARD_BUILD" -p:IS_DEV_BUILD=true
\ No newline at end of file
diff --git a/scripts/build.sh b/scripts/build.sh
deleted file mode 100755
index ae686895e..000000000
--- a/scripts/build.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-output="../bin/"
-config="$1"
-
-if [ -z "$1" ] || [ "$1" = "release" ]; then
- config="Release"
-elif [ "$1" = "debug" ]; then
- config="Debug"
-fi
-
-
-if [ "${config}" = "Debug" ]; then
- echo "\n\n*** WARNING: USING DEBUG CONFIGURATION. IT WILL AFFECT PERFORMANCES OF THE GAME!! ***\n\n"
-fi
-
-
-echo "OUTPUT PATH: ${output}${config}"
-
-
-msbuild "../src/ClassicUO.csproj" /p:Configuration=$config /p:OutputPath="${output}${config}"
diff --git a/src/ClassicUO.Assets/AnimDataLoader.cs b/src/ClassicUO.Assets/AnimDataLoader.cs
deleted file mode 100644
index 6033d8198..000000000
--- a/src/ClassicUO.Assets/AnimDataLoader.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using System;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class AnimDataLoader : UOFileLoader
- {
- private static AnimDataLoader _instance;
- private UOFileMul _file;
-
- private AnimDataLoader()
- {
- }
-
- public static AnimDataLoader Instance => _instance ?? (_instance = new AnimDataLoader());
-
- public UOFile AnimDataFile => _file;
-
- public override Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string path = UOFileManager.GetUOFilePath("animdata.mul");
-
- if (File.Exists(path))
- {
- _file = new UOFileMul(path);
- }
- }
- );
- }
-
- public unsafe AnimDataFrame CalculateCurrentGraphic(ushort graphic)
- {
- IntPtr address = _file?.StartAddress ?? IntPtr.Zero;
-
- if (address != IntPtr.Zero)
- {
- IntPtr addr = address + (graphic * 68 + 4 * ((graphic >> 3) + 1));
-
- if (addr.ToInt64() < address.ToInt64() + _file.Length)
- {
- ref AnimDataFrame a = ref Unsafe.AsRef((void*)addr);
-
- return a;
- }
- }
-
- return default;
- }
- }
-
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public unsafe struct AnimDataFrame
- {
- public fixed sbyte FrameData[64];
- public byte Unknown;
- public byte FrameCount;
- public byte FrameInterval;
- public byte FrameStart;
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/AnimationsLoader.cs b/src/ClassicUO.Assets/AnimationsLoader.cs
deleted file mode 100644
index 2fd708c43..000000000
--- a/src/ClassicUO.Assets/AnimationsLoader.cs
+++ /dev/null
@@ -1,1838 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public unsafe class AnimationsLoader : UOFileLoader
- {
- public const int MAX_ACTIONS = 80; // gargoyle is like 78
- public const int MAX_DIRECTIONS = 5;
-
- private static AnimationsLoader _instance;
-
- [ThreadStatic]
- private static FrameInfo[] _frames;
-
- [ThreadStatic]
- private static byte[] _decompressedData;
-
- private readonly UOFileMul[] _files = new UOFileMul[5];
- private readonly UOFileUop[] _filesUop = new UOFileUop[4];
-
- private readonly Dictionary> _equipConv = new Dictionary>();
- private readonly Dictionary _mobTypes = new Dictionary();
- private readonly Dictionary _bodyInfos = new Dictionary();
- private readonly Dictionary _corpseInfos = new Dictionary();
- private readonly Dictionary _bodyConvInfos = new Dictionary();
- private readonly Dictionary _uopInfos = new Dictionary();
-
- private AnimationsLoader() { }
-
- public static AnimationsLoader Instance =>
- _instance ?? (_instance = new AnimationsLoader());
-
- public IReadOnlyDictionary> EquipConversions => _equipConv;
-
- public List<(ushort, byte)>[] GroupReplaces { get; } =
- new List<(ushort, byte)>[2]
- {
- new List<(ushort, byte)>(),
- new List<(ushort, byte)>()
- };
-
- private unsafe void LoadInternal()
- {
- bool loaduop = false;
- int[] un = { 0x40000, 0x10000, 0x20000, 0x20000, 0x20000 };
-
- for (int i = 0; i < 5; i++)
- {
- string pathmul = UOFileManager.GetUOFilePath(
- "anim" + (i == 0 ? string.Empty : (i + 1).ToString()) + ".mul"
- );
-
- string pathidx = UOFileManager.GetUOFilePath(
- "anim" + (i == 0 ? string.Empty : (i + 1).ToString()) + ".idx"
- );
-
- if (File.Exists(pathmul) && File.Exists(pathidx))
- {
- _files[i] = new UOFileMul(pathmul, pathidx, un[i], i == 0 ? 6 : -1);
- }
-
- if (i > 0 && UOFileManager.IsUOPInstallation)
- {
- string pathuop = UOFileManager.GetUOFilePath($"AnimationFrame{i}.uop");
-
- if (File.Exists(pathuop))
- {
- _filesUop[i - 1] = new UOFileUop(
- pathuop,
- "build/animationlegacyframe/{0:D6}/{0:D2}.bin"
- );
-
- if (!loaduop)
- {
- loaduop = true;
- }
- }
- }
- }
-
- if (loaduop)
- {
- LoadUop();
- }
-
- if (UOFileManager.Version >= ClientVersion.CV_500A)
- {
- string path = UOFileManager.GetUOFilePath("mobtypes.txt");
-
- if (File.Exists(path))
- {
- var typeNames = new string[5]
- {
- "monster",
- "sea_monster",
- "animal",
- "human",
- "equipment"
- };
-
- using (var reader = new StreamReader(File.OpenRead(path)))
- {
- string line;
-
- while ((line = reader.ReadLine()) != null)
- {
- line = line.Trim();
-
- if (line.Length == 0 || line[0] == '#' || !char.IsNumber(line[0]))
- {
- continue;
- }
-
- string[] parts = line.Split(
- new[] { '\t', ' ' },
- StringSplitOptions.RemoveEmptyEntries
- );
-
- if (parts.Length < 3)
- {
- continue;
- }
-
- int id = int.Parse(parts[0]);
- string testType = parts[1].ToLower();
- int commentIdx = parts[2].IndexOf('#');
-
- if (commentIdx > 0)
- {
- parts[2] = parts[2].Substring(0, commentIdx - 1);
- }
- else if (commentIdx == 0)
- {
- continue;
- }
-
- uint number = uint.Parse(parts[2], NumberStyles.HexNumber);
-
- for (int i = 0; i < 5; i++)
- {
- if (
- testType.Equals(
- typeNames[i],
- StringComparison.InvariantCultureIgnoreCase
- )
- )
- {
- _mobTypes[id] = new MobTypeInfo()
- {
- Type = (AnimationGroupsType)i,
- Flags = (AnimationFlags )(0x80000000 | number)
- };
-
- break;
- }
- }
- }
- }
- }
- }
-
- string file = UOFileManager.GetUOFilePath("Anim1.def");
-
- if (File.Exists(file))
- {
- using (DefReader defReader = new DefReader(file))
- {
- while (defReader.Next())
- {
- ushort group = (ushort)defReader.ReadInt();
-
- if (group == 0xFFFF)
- {
- continue;
- }
-
- int replace = defReader.ReadGroupInt();
-
- GroupReplaces[0].Add((group, (byte)replace));
- }
- }
- }
-
- file = UOFileManager.GetUOFilePath("Anim2.def");
-
- if (File.Exists(file))
- {
- using (DefReader defReader = new DefReader(file))
- {
- while (defReader.Next())
- {
- ushort group = (ushort)defReader.ReadInt();
-
- if (group == 0xFFFF)
- {
- continue;
- }
-
- int replace = defReader.ReadGroupInt();
-
- GroupReplaces[1].Add((group, (byte)replace));
- }
- }
- }
-
- ProcessEquipConvDef();
- ProcessBodyDef();
- ProcessCorpseDef();
- }
-
- public bool ReplaceBody(ref ushort body, ref ushort hue)
- {
- if (_bodyInfos.TryGetValue(body, out var bodyInfo))
- {
- body = bodyInfo.Graphic;
- hue = bodyInfo.Hue;
-
- return true;
- }
-
- return false;
- }
-
- public bool ReplaceCorpse(ref ushort body, ref ushort hue)
- {
- if (_corpseInfos.TryGetValue(body, out var bodyInfo))
- {
- body = bodyInfo.Graphic;
- hue = bodyInfo.Hue;
-
- return true;
- }
-
- return false;
- }
-
- public bool ReplaceUopGroup(ushort body, ref byte group)
- {
- if (_uopInfos.TryGetValue(body, out var uopInfo))
- {
- group = (byte)uopInfo.ReplacedAnimations[group];
-
- return true;
- }
-
- return false;
- }
-
- public ReadOnlySpan GetIndices
- (
- ClientVersion clientVersion,
- ushort body,
- ref ushort hue,
- ref AnimationFlags flags,
- out int fileIndex,
- out AnimationGroupsType animType,
- out sbyte mountHeight
- )
- {
- fileIndex = 0;
- animType = AnimationGroupsType.Unknown;
- mountHeight = 0;
-
- if (!_mobTypes.TryGetValue(body, out var mobInfo))
- {
- mobInfo.Flags = AnimationFlags.None;
- mobInfo.Type = AnimationGroupsType.Unknown;
- }
-
- flags = mobInfo.Flags;
-
- if (mobInfo.Flags.HasFlag(AnimationFlags.UseUopAnimation))
- {
- if (animType == AnimationGroupsType.Unknown)
- animType = mobInfo.Type != AnimationGroupsType.Unknown ? mobInfo.Type : CalculateTypeByGraphic(body);
-
- var replaceFound = _uopInfos.TryGetValue(body, out var uopInfo);
- mountHeight = uopInfo.HeightOffset;
- var animIndices = Array.Empty();
-
- for (int actioIdx = 0; actioIdx < MAX_ACTIONS; ++actioIdx)
- {
- var action = replaceFound ? uopInfo.ReplacedAnimations[actioIdx] : actioIdx;
- var hashString = $"build/animationlegacyframe/{body:D6}/{action:D2}.bin";
- var hash = UOFileUop.CreateHash(hashString);
-
- for (int index = 0; index < _filesUop.Length; ++index)
- {
- if (_filesUop[index] != null && _filesUop[index].TryGetUOPData(hash, out var data))
- {
- if (animIndices.Length == 0)
- animIndices = new AnimIdxBlock[MAX_ACTIONS];
-
- fileIndex = index;
-
- ref var animIndex = ref animIndices[actioIdx];
- animIndex.Position = (uint)data.Offset;
- animIndex.Size = (uint)data.Length;
- animIndex.Unknown = (uint)data.DecompressedLength;
-
- break;
- }
- }
- }
-
- return animIndices;
- }
-
- if (_bodyConvInfos.TryGetValue(body, out var bodyConvInfo))
- {
- hue = bodyConvInfo.Hue;
- body = bodyConvInfo.Graphic;
- fileIndex = bodyConvInfo.FileIndex;
- mountHeight = bodyConvInfo.MountHeight;
-
- if (clientVersion < ClientVersion.CV_500A)
- animType = bodyConvInfo.AnimType;
- }
-
- if (animType == AnimationGroupsType.Unknown)
- animType = mobInfo.Type != AnimationGroupsType.Unknown ? mobInfo.Type : CalculateTypeByGraphic(body, fileIndex);
-
- var fileIdx = _files[fileIndex].IdxFile;
- var offsetAddress = CalculateOffset(body, animType, flags, out var actionCount);
-
- var offset = fileIdx.StartAddress.ToInt64() + offsetAddress;
- var end = fileIdx.StartAddress.ToInt64() + fileIdx.Length;
-
- if (offset >= end)
- {
- return ReadOnlySpan.Empty;
- }
-
- if (offset + (actionCount * MAX_DIRECTIONS * sizeof(AnimIdxBlock)) > end)
- {
- return ReadOnlySpan.Empty;
- }
-
- var animIdxSpan = new ReadOnlySpan(
- (void*)offset,
- actionCount * MAX_DIRECTIONS
- );
-
- return animIdxSpan;
- }
-
- private long CalculateOffset(
- ushort graphic,
- AnimationGroupsType type,
- AnimationFlags flags,
- out int groupCount
- )
- {
- long result = 0;
- groupCount = 0;
-
- var group = AnimationGroups.None;
-
- switch (type)
- {
- case AnimationGroupsType.Monster:
-
- if ((flags & AnimationFlags.CalculateOffsetByPeopleGroup) != 0)
- {
- group = AnimationGroups.People;
- }
- else if ((flags & AnimationFlags.CalculateOffsetByLowGroup) != 0)
- {
- group = AnimationGroups.Low;
- }
- else
- {
- group = AnimationGroups.High;
- }
-
- break;
-
- case AnimationGroupsType.SeaMonster:
- result = CalculateHighGroupOffset(graphic);
- groupCount = (int)LowAnimationGroup.AnimationCount;
-
- break;
-
- case AnimationGroupsType.Animal:
-
- if ((flags & AnimationFlags.CalculateOffsetLowGroupExtended) != 0)
- {
- if ((flags & AnimationFlags.CalculateOffsetByPeopleGroup) != 0)
- {
- group = AnimationGroups.People;
- }
- else if ((flags & AnimationFlags.CalculateOffsetByLowGroup) != 0)
- {
- group = AnimationGroups.Low;
- }
- else
- {
- group = AnimationGroups.High;
- }
- }
- else
- {
- group = AnimationGroups.Low;
- }
-
- break;
-
- default:
- group = AnimationGroups.People;
-
- break;
- }
-
- switch (group)
- {
- case AnimationGroups.Low:
- result = CalculateLowGroupOffset(graphic);
- groupCount = (int)LowAnimationGroup.AnimationCount;
-
- break;
-
- case AnimationGroups.High:
- result = CalculateHighGroupOffset(graphic);
- groupCount = (int)HighAnimationGroup.AnimationCount;
-
- break;
-
- case AnimationGroups.People:
- result = CalculatePeopleGroupOffset(graphic);
- groupCount = (int)PeopleAnimationGroup.AnimationCount;
-
- break;
- }
-
- return result;
- }
-
- public override unsafe Task Load()
- {
- return Task.Run(LoadInternal);
- }
-
- private void ProcessEquipConvDef()
- {
- if (UOFileManager.Version < ClientVersion.CV_300)
- {
- return;
- }
-
- var file = UOFileManager.GetUOFilePath("Equipconv.def");
-
- if (File.Exists(file))
- {
- using (DefReader defReader = new DefReader(file, 5))
- {
- while (defReader.Next())
- {
- ushort body = (ushort)defReader.ReadInt();
- ushort graphic = (ushort)defReader.ReadInt();
- ushort newGraphic = (ushort)defReader.ReadInt();
- int gump = defReader.ReadInt();
-
- if (gump > ushort.MaxValue)
- {
- continue;
- }
-
- if (gump == 0)
- {
- gump = graphic;
- }
- else if (gump == 0xFFFF || gump == -1)
- {
- gump = newGraphic;
- }
-
- ushort color = (ushort)defReader.ReadInt();
-
- if (!_equipConv.TryGetValue(body, out var dict))
- {
- _equipConv[body] = (dict = new Dictionary());
- }
-
- dict[graphic] = new EquipConvData(newGraphic, (ushort)gump, color);
- }
- }
- }
- }
-
- public void ProcessBodyConvDef(BodyConvFlags flags)
- {
- if (UOFileManager.Version < ClientVersion.CV_300)
- {
- return;
- }
-
- var file = UOFileManager.GetUOFilePath("Bodyconv.def");
-
- if (!File.Exists(file))
- return;
-
- using (var defReader = new DefReader(file))
- {
- while (defReader.Next())
- {
- ushort index = (ushort)defReader.ReadInt();
-
- for (int i = 1; i < defReader.PartsCount; i++)
- {
- int body = defReader.ReadInt();
- if (body < 0)
- {
- continue;
- }
-
- // Ensure the client is allowed to use these new graphics
- if (i == 1)
- {
- if (!flags.HasFlag(BodyConvFlags.Anim1))
- {
- continue;
- }
- }
- else if (i == 2)
- {
- if (!flags.HasFlag(BodyConvFlags.Anim2))
- {
- continue;
- }
- }
-
- // NOTE: for fileindex >= 3 the client automatically accepts body conversion.
- // Probably it ignores the flags
- /*else if (i == 3)
- {
- if (flags.HasFlag(BodyConvFlags.Anim3))
- {
- continue;
- }
- }
- else if (i == 4)
- {
- if (flags.HasFlag(BodyConvFlags.Anim4))
- {
- continue;
- }
- }
- */
-
- sbyte mountedHeightOffset = 0;
- if (i == 1)
- {
- if (index == 0x00C0 || index == 793)
- {
- mountedHeightOffset = -9;
- }
- }
- else if (i == 2)
- {
- if (index == 0x0579)
- {
- mountedHeightOffset = 9;
- }
- }
- else if (i == 4)
- {
- mountedHeightOffset = -9;
-
- if (index == 0x0115 || index == 0x00C0)
- {
- mountedHeightOffset = 0;
- }
- else if (index == 0x042D)
- {
- mountedHeightOffset = 3;
- }
- }
-
- if (i >= _files.Length || _files[i] == null)
- {
- continue;
- }
-
- _bodyConvInfos[index] = new BodyConvInfo()
- {
- FileIndex = i,
- Graphic = (ushort)body,
- // TODO: fix for UOFileManager.Version < ClientVersion.CV_500A
- AnimType = CalculateTypeByGraphic((ushort)body, i),
- MountHeight = mountedHeightOffset
- };
- }
- }
- }
- }
-
- private void ProcessBodyDef()
- {
- if (UOFileManager.Version < ClientVersion.CV_300)
- {
- return;
- }
-
- var file = UOFileManager.GetUOFilePath("Body.def");
-
- if (!File.Exists(file))
- return;
-
- using (var defReader = new DefReader(file, 1))
- {
- while (defReader.Next())
- {
- int index = defReader.ReadInt();
-
- if (_bodyInfos.TryGetValue(index, out var info) && info.Graphic != 0)
- {
- continue;
- }
-
- int[] group = defReader.ReadGroup();
-
- if (group == null)
- {
- continue;
- }
-
- int color = defReader.ReadInt();
-
- //Yes, this is actually how this is supposed to work.
- var checkIndex = group.Length >= 3 ? group[2] : group[0];
-
- _bodyInfos[index] = new BodyInfo()
- {
- Graphic = (ushort)checkIndex,
- Hue = (ushort)color
- };
- }
- }
- }
-
- private void ProcessCorpseDef()
- {
- if (UOFileManager.Version < ClientVersion.CV_300)
- {
- return;
- }
-
- var file = UOFileManager.GetUOFilePath("Corpse.def");
-
- if (!File.Exists(file))
- return;
-
- using (var defReader = new DefReader(file, 1))
- {
- while (defReader.Next())
- {
- int index = defReader.ReadInt();
-
- if (_corpseInfos.TryGetValue(index, out var b) && b.Graphic != 0)
- {
- continue;
- }
-
- int[] group = defReader.ReadGroup();
-
- if (group == null)
- {
- continue;
- }
-
- int color = defReader.ReadInt();
- int checkIndex = group.Length >= 3 ? group[2] : group[0];
-
- _corpseInfos[index] = new BodyInfo()
- {
- Graphic = (ushort)checkIndex,
- Hue = (ushort)color
- };
- }
- }
- }
-
- private void LoadUop()
- {
- if (UOFileManager.Version <= ClientVersion.CV_60144)
- {
- return;
- }
-
- string animationSequencePath = UOFileManager.GetUOFilePath("AnimationSequence.uop");
-
- if (!File.Exists(animationSequencePath))
- {
- Log.Warn("AnimationSequence.uop not found");
-
- return;
- }
-
- // ==========================
- // credit: @tristran
- // ==========================
- // u32 animid
- // 12 times: [
- // u32 unk0 //often zero
- // ]
- // //--------------
- // u32 replace
- // replace times: [
- // u32 oldgroup
- // u32 framecount
- // u32 newgroup
- // //if newgroup not is -1 then this animation group is replaced by that group
- // u32 flags1 //unsure what these mean often 0x41100000
- // 16 times: [ //maybe something to do with mounts but...
- // u8 unk1 //if newgroup ==-1 usually -128 else usually 0
- // ]
- // 8 times: [
- // u32 unk2 //often 0 animation 826 has something different...
- // ]
- // u32 num1 //rarely present but human (400) has them for oldgroup 0,1,2,3,23,24,35 (stand/walk/run)
- // num1 times: [
- // u32 w0
- // u32 w1
- // u32 w2
- // u32 w3
- // u32 w4
- // u32 w5
- // u16 s6
- // u32 w7
- // u16 s8
- // ]
- // u32 num2
- // num2 times: [
- // u32 unk3
- // ]
- // ]
- // //-----------
- // u32 xtra
- // xtra times: [
- // u8 mob_mode //identifies the "mode" this defintion belongs to combat(0)/id(1)/ride (2) /fly(3)/fly combat?(4)/fly idle(5) /sit(6)
- // s8 b2 //fallback mode?
- // u32 def_action // default action (fallback if action not in following structure)
- // u32 num1
- // num1 times: [ //transition to other mode? (see gargoyle (666))
- // u8 b6 //mode
- // u32 n5 //anim/group
- // ]
- // u32 num2 //usually 3 (stand, walk, run)
- // num2 times: [
- // u8 action
- // u32 anim1h //one handed?
- // u32 anim2h //two handed?
- // ]
- // u32 num3 // NewCharacterAnimation
- // num3 times: [
- // s8 type //actual action fight etc
- // s8 action //sub action
- // u32 num4 //random select one of the list
- // num4 times: [
- // u32 anim //group
- // ]
- // ]
- // ]
-
- /*
- based on the current "mode" the mobile is in (e.g. IsFlying check) select the right set of definitions from the xtra array
- then consult the num2 based list for stand/walk/run
- and the num3 based list for NewCharacterAnimation packets
- /
- / flags
- 41100000
- 41400000 usually group 22,24 (walk run?)
- 40C00000 often group 31
- 42860000 anim 692 Animated weapon
- 41F80000 anim 692
- 41300000 anim 1246,1247 , group 0 (jack o lantern)
- */
-
- /*
- based on the current "mode" the mobile is in (e.g. IsFlying check) select the right set of definitions from the xtra array
- then consult the num2 based list for stand/walk/run
- and the num3 based list for NewCharacterAnimation packets
- /
- / flags
- 41100000
- 41400000 usually group 22,24 (walk run?)
- 40C00000 often group 31
- 42860000 anim 692 Animated weapon
- 41F80000 anim 692
- 41300000 anim 1246,1247 , group 0 (jack o lantern)
- */
-
- var animSeq = new UOFileUop(
- animationSequencePath,
- "build/animationsequence/{0:D8}.bin"
- );
- //var animseqEntries = new UOFileIndex[animSeq.TotalEntriesCount];
- //animSeq.FillEntries(ref animseqEntries);
-
- Span spanAlloc = stackalloc byte[1024];
-
- foreach (var pair in animSeq.Hashes)
- {
- var entry = pair.Value;
-
- if (entry.Offset == 0)
- {
- continue;
- }
-
- animSeq.Seek(entry.Offset);
-
- byte[] buffer = null;
-
- Span span =
- entry.DecompressedLength <= 1024
- ? spanAlloc
- : (
- buffer = System.Buffers.ArrayPool.Shared.Rent(
- entry.DecompressedLength
- )
- );
-
- try
- {
- fixed (byte* destPtr = span)
- {
- var result = ZLib.Decompress(
- animSeq.PositionAddress,
- entry.Length,
- 0,
- (IntPtr)destPtr,
- entry.DecompressedLength
- );
-
- if (result != ZLib.ZLibError.Okay)
- {
- Log.Error($"error reading animationsequence {result}");
- return;
- }
- }
-
- var reader = new StackDataReader(span.Slice(0, entry.DecompressedLength));
-
- uint animID = reader.ReadUInt32LE();
- reader.Skip(48);
- int replaces = reader.ReadInt32LE();
-
- var uopInfo = new UopInfo();
- var replacedAnimSpan = uopInfo.ReplacedAnimations;
- for (var j = 0; j < replacedAnimSpan.Length; ++j)
- replacedAnimSpan[j] = j;
-
- if (replaces != 48 && replaces != 68)
- {
- for (int k = 0; k < replaces; k++)
- {
- int oldGroup = reader.ReadInt32LE();
- uint frameCount = reader.ReadUInt32LE();
- int newGroup = reader.ReadInt32LE();
-
- if (frameCount == 0)
- {
- replacedAnimSpan[oldGroup] = newGroup;
- }
-
- reader.Skip(60);
- }
-
- if (
- animID == 0x04E7
- || animID == 0x042D
- || animID == 0x04E6
- || animID == 0x05F7
- || animID == 0x05A1
- )
- {
- uopInfo.HeightOffset = 18;
- }
- else if (
- animID == 0x01B0
- || animID == 0x0579
- || animID == 0x05F6
- || animID == 0x05A0
- )
- {
- uopInfo.HeightOffset = 9;
- }
- }
-
- _uopInfos[(int)animID] = uopInfo;
-
- reader.Release();
- }
- finally
- {
- if (buffer != null)
- {
- System.Buffers.ArrayPool.Shared.Return(buffer);
- }
- }
- }
-
- animSeq.Dispose();
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static unsafe uint CalculatePeopleGroupOffset(ushort graphic)
- {
- return (uint)(((graphic - 400) * 175 + 35000) * sizeof(AnimIdxBlock));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static unsafe uint CalculateHighGroupOffset(ushort graphic)
- {
- return (uint)(graphic * 110 * sizeof(AnimIdxBlock));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static unsafe uint CalculateLowGroupOffset(ushort graphic)
- {
- return (uint)(((graphic - 200) * 65 + 22000) * sizeof(AnimIdxBlock));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private AnimationGroupsType CalculateTypeByGraphic(ushort graphic, int fileIndex = 0)
- {
- if (fileIndex == 1) // anim2
- {
- return graphic < 200 ? AnimationGroupsType.Monster : AnimationGroupsType.Animal;
- }
-
- if (fileIndex == 2) // anim3
- {
- return graphic < 300
- ? AnimationGroupsType.Animal
- : graphic < 400
- ? AnimationGroupsType.Monster
- : AnimationGroupsType.Human;
- }
-
- return graphic < 200
- ? AnimationGroupsType.Monster
- : graphic < 400
- ? AnimationGroupsType.Animal
- : AnimationGroupsType.Human;
- }
-
- public override void ClearResources() { }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void GetAnimDirection(ref byte dir, ref bool mirror)
- {
- switch (dir)
- {
- case 2:
- case 4:
- mirror = dir == 2;
- dir = 1;
-
- break;
-
- case 1:
- case 5:
- mirror = dir == 1;
- dir = 2;
-
- break;
-
- case 0:
- case 6:
- mirror = dir == 0;
- dir = 3;
-
- break;
-
- case 3:
- dir = 0;
-
- break;
-
- case 7:
- dir = 4;
-
- break;
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void GetSittingAnimDirection(ref byte dir, ref bool mirror, ref int x, ref int y)
- {
- switch (dir)
- {
- case 0:
- mirror = true;
- dir = 3;
-
- break;
-
- case 2:
- mirror = true;
- dir = 1;
-
- break;
-
- case 4:
- mirror = false;
- dir = 1;
-
- break;
-
- case 6:
- mirror = false;
- dir = 3;
-
- break;
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void FixSittingDirection(
- ref byte direction,
- ref bool mirror,
- ref int x,
- ref int y,
- ref SittingInfoData data
- )
- {
- switch (direction)
- {
- case 7:
- case 0:
- {
- if (data.Direction1 == -1)
- {
- if (direction == 7)
- {
- direction = (byte)data.Direction4;
- }
- else
- {
- direction = (byte)data.Direction2;
- }
- }
- else
- {
- direction = (byte)data.Direction1;
- }
-
- break;
- }
-
- case 1:
- case 2:
- {
- if (data.Direction2 == -1)
- {
- if (direction == 1)
- {
- direction = (byte)data.Direction1;
- }
- else
- {
- direction = (byte)data.Direction3;
- }
- }
- else
- {
- direction = (byte)data.Direction2;
- }
-
- break;
- }
-
- case 3:
- case 4:
- {
- if (data.Direction3 == -1)
- {
- if (direction == 3)
- {
- direction = (byte)data.Direction2;
- }
- else
- {
- direction = (byte)data.Direction4;
- }
- }
- else
- {
- direction = (byte)data.Direction3;
- }
-
- break;
- }
-
- case 5:
- case 6:
- {
- if (data.Direction4 == -1)
- {
- if (direction == 5)
- {
- direction = (byte)data.Direction3;
- }
- else
- {
- direction = (byte)data.Direction1;
- }
- }
- else
- {
- direction = (byte)data.Direction4;
- }
-
- break;
- }
- }
-
- GetSittingAnimDirection(ref direction, ref mirror, ref x, ref y);
-
- const int SITTING_OFFSET_X = 8;
-
- int offsX = SITTING_OFFSET_X;
-
- if (mirror)
- {
- if (direction == 3)
- {
- y += 25 + data.MirrorOffsetY;
- x += offsX - 4;
- }
- else
- {
- y += data.OffsetY + 9;
- }
- }
- else
- {
- if (direction == 3)
- {
- y += 23 + data.MirrorOffsetY;
- x -= 3;
- }
- else
- {
- y += 10 + data.OffsetY;
- x -= offsX + 1;
- }
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public AnimationGroups GetGroupIndex(ushort graphic, AnimationGroupsType animType)
- {
- switch (animType)
- {
- case AnimationGroupsType.Animal:
- return AnimationGroups.Low;
-
- case AnimationGroupsType.Monster:
- case AnimationGroupsType.SeaMonster:
- return AnimationGroups.High;
-
- case AnimationGroupsType.Human:
- case AnimationGroupsType.Equipment:
- return AnimationGroups.People;
- }
-
- return AnimationGroups.High;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public byte GetDeathAction(
- ushort animID,
- AnimationFlags animFlags,
- AnimationGroupsType animType,
- bool second,
- bool isRunning = false
- )
- {
- //ConvertBodyIfNeeded(ref animID);
-
- if (animFlags.HasFlag(AnimationFlags.CalculateOffsetByLowGroup))
- {
- animType = AnimationGroupsType.Animal;
- }
-
- switch (animType)
- {
- case AnimationGroupsType.Animal:
-
- if (
- (animFlags & AnimationFlags.Use2IfHittedWhileRunning) != 0
- || (animFlags & AnimationFlags.CanFlying) != 0
- )
- {
- return 2;
- }
-
- if ((animFlags & AnimationFlags.UseUopAnimation) != 0)
- {
- return (byte)(second ? 3 : 2);
- }
-
- return (byte)(
- second ? LowAnimationGroup.Die2 : LowAnimationGroup.Die1
- );
-
- case AnimationGroupsType.SeaMonster:
- {
- if (!isRunning)
- {
- return 8;
- }
-
- goto case AnimationGroupsType.Monster;
- }
-
- case AnimationGroupsType.Monster:
-
- if ((animFlags & AnimationFlags.UseUopAnimation) != 0)
- {
- return (byte)(second ? 3 : 2);
- }
-
- return (byte)(
- second ? HighAnimationGroup.Die2 : HighAnimationGroup.Die1
- );
-
- case AnimationGroupsType.Human:
- case AnimationGroupsType.Equipment:
- return (byte)(
- second ? PeopleAnimationGroup.Die2 : PeopleAnimationGroup.Die1
- );
- }
-
- return 0;
- }
-
- public Span ReadUOPAnimationFrames(
- ushort animID,
- byte animGroup,
- byte direction,
- AnimationGroupsType type,
- int fileIndex,
- AnimationsLoader.AnimIdxBlock index
- )
- {
- if (fileIndex < 0 || fileIndex >= _filesUop.Length)
- {
- return Span.Empty;
- }
-
- var file = _filesUop[fileIndex];
-
- if (index.Position == 0 && index.Size == 0)
- {
- return Span.Empty;
- }
-
- if (_frames == null)
- {
- _frames = new FrameInfo[22];
- }
-
- if (
- fileIndex == 0
- && index.Size == 0
- && index.Unknown == 0
- && index.Position == 0
- )
- {
- Log.Warn("uop animData is null");
-
- return Span.Empty;
- }
-
- file.Seek(index.Position);
-
- if (_decompressedData == null || index.Unknown > _decompressedData.Length)
- {
- _decompressedData = new byte[index.Unknown];
- }
-
- fixed (byte* ptr = _decompressedData.AsSpan())
- {
- var result = ZLib.Decompress(
- file.PositionAddress,
- (int)index.Size,
- 0,
- (IntPtr)ptr,
- (int)index.Unknown
- );
-
- if (result != ZLib.ZLibError.Okay)
- {
- Log.Error($"error reading uop animation. AnimID: {animID} | Group: {animGroup} | Dir: {direction} | FileIndex: {fileIndex}");
-
- return Span.Empty;
- }
- }
-
- var reader = new StackDataReader(
- _decompressedData.AsSpan().Slice(0, (int)index.Unknown)
- );
- reader.Skip(32);
-
- long end = (long)reader.StartAddress + reader.Length;
-
- int fc = reader.ReadInt32LE();
- uint dataStart = reader.ReadUInt32LE();
- reader.Seek(dataStart);
-
- byte frameCount = (byte)(
- type < AnimationGroupsType.Equipment ? Math.Round(fc / (float) MAX_DIRECTIONS) : MAX_DIRECTIONS * 2
- );
- if (frameCount > _frames.Length)
- {
- _frames = new FrameInfo[frameCount];
- }
-
- var frames = _frames.AsSpan(0, frameCount);
-
- /* If the UOP files didn't omit frames, we could just do this:
- * reader.Skip(sizeof(UOPAnimationHeader) * direction * frameCount);
- * but we can't. So we have to walk through the frames to seek to where we need to go.
- */
- UOPAnimationHeader* animHeaderInfo = (UOPAnimationHeader*)reader.PositionAddress;
-
- for (ushort currentDir = 0; currentDir <= direction; currentDir++)
- {
- for (ushort frameNum = 0; frameNum < frameCount; frameNum++)
- {
- long start = reader.Position;
- animHeaderInfo = (UOPAnimationHeader*)reader.PositionAddress;
-
- if (animHeaderInfo->Group != animGroup)
- {
- /* Something bad has happened. Just return. */
- return Span.Empty;
- }
-
- /* FrameID is 1's based and just keeps increasing, regardless of direction.
- * So north will be 1-22, northeast will be 23-44, etc. And it's possible for frames
- * to be missing. */
- ushort headerFrameNum = (ushort)((animHeaderInfo->FrameID - 1) % frameCount);
-
- ref var frame = ref frames[frameNum];
-
- // we need to zero-out the frame or we will see ghost animations coming from other animation queries
- frame.Num = frameNum;
- frame.CenterX = 0;
- frame.CenterY = 0;
- frame.Width = 0;
- frame.Height = 0;
-
- if (frameNum < headerFrameNum)
- {
- /* Missing frame. Keep walking forward. */
- continue;
- }
-
- if (frameNum > headerFrameNum)
- {
- /* We've reached the next direction early */
- break;
- }
-
- if (currentDir == direction)
- {
- /* We're on the direction we actually wanted to read */
- if (start + animHeaderInfo->DataOffset >= reader.Length)
- {
- /* File seems to be corrupt? Skip loading. */
- continue;
- }
-
- reader.Skip((int)animHeaderInfo->DataOffset);
-
- var palette = new ReadOnlySpan(reader.PositionAddress.ToPointer(), 512 / sizeof(ushort));
- reader.Skip(512);
-
- ReadSpriteData(ref reader, palette, ref frame, true);
- }
-
- reader.Seek(start + sizeof(UOPAnimationHeader));
- }
- }
-
- reader.Release();
-
- return frames;
- }
-
- public Span ReadMULAnimationFrames(int fileIndex, AnimIdxBlock index)
- {
- if (fileIndex < 0 || fileIndex >= _files.Length)
- {
- return Span.Empty;
- }
-
- if (index.Position == 0 && index.Size == 0)
- {
- return Span.Empty;
- }
-
- if (index.Position == 0xFFFF_FFFF || index.Size == 0xFFFF_FFFF)
- {
- return Span.Empty;
- }
-
- var file = _files[fileIndex];
-
- var reader = new StackDataReader(
- new ReadOnlySpan(
- (byte*)file.StartAddress.ToPointer() + index.Position,
- (int)index.Size
- )
- );
- reader.Seek(0);
-
- var palette = new ReadOnlySpan(reader.PositionAddress.ToPointer(), 512 / sizeof(ushort));
- reader.Skip(512);
-
- long dataStart = reader.Position;
- uint frameCount = reader.ReadUInt32LE();
- var frameOffset = new ReadOnlySpan((uint*)reader.PositionAddress, (int)frameCount);
-
- if (_frames == null || frameCount > _frames.Length)
- {
- _frames = new FrameInfo[frameCount];
- }
-
- var frames = _frames.AsSpan().Slice(0, (int)frameCount);
-
- for (int i = 0; i < frameCount; i++)
- {
- reader.Seek(dataStart + frameOffset[i]);
-
- frames[i].Num = i;
- ReadSpriteData(ref reader, palette, ref frames[i], false);
- }
-
- return frames;
- }
-
- private void ReadSpriteData(
- ref StackDataReader reader,
- ReadOnlySpan palette,
- ref FrameInfo frame,
- bool alphaCheck
- )
- {
- frame.CenterX = reader.ReadInt16LE();
- frame.CenterY = reader.ReadInt16LE();
- frame.Width = reader.ReadInt16LE();
- frame.Height = reader.ReadInt16LE();
-
- if (frame.Width <= 0 || frame.Height <= 0)
- {
- return;
- }
-
- int bufferSize = frame.Width * frame.Height;
-
- if (frame.Pixels == null || frame.Pixels.Length < bufferSize)
- {
- frame.Pixels = new uint[bufferSize];
- }
- else
- {
- frame.Pixels.AsSpan().Slice(0, bufferSize).Fill(0);
- }
-
- Span data = frame.Pixels;
-
- uint header = reader.ReadUInt32LE();
-
- while (header != 0x7FFF7FFF && reader.Position < reader.Length)
- {
- ushort runLength = (ushort)(header & 0x0FFF);
- int x = (int)((header >> 22) & 0x03FF);
-
- if ((x & 0x0200) > 0)
- {
- x |= unchecked((int)0xFFFFFE00);
- }
-
- int y = (int)((header >> 12) & 0x3FF);
-
- if ((y & 0x0200) > 0)
- {
- y |= unchecked((int)0xFFFFFE00);
- }
-
- x += frame.CenterX;
- y += frame.CenterY + frame.Height;
-
- int block = y * frame.Width + x;
-
- for (int k = 0; k < runLength; ++k, ++block)
- {
- ushort val = palette[reader.ReadUInt8()];
-
- // FIXME: same of MUL ? Keep it as original for the moment
- if (!alphaCheck || val != 0)
- {
- data[block] = HuesHelper.Color16To32(val) | 0xFF_00_00_00;
- }
- else
- {
- data[block] = 0;
- }
- }
-
- header = reader.ReadUInt32LE();
- }
- }
-
- public struct FrameInfo
- {
- public int Num;
- public short CenterX;
- public short CenterY;
- public short Width;
- public short Height;
- public uint[] Pixels;
- }
-
- public struct SittingInfoData
- {
- public SittingInfoData(
- ushort graphic,
- sbyte d1,
- sbyte d2,
- sbyte d3,
- sbyte d4,
- sbyte offsetY,
- sbyte mirrorOffsetY,
- bool drawback
- )
- {
- Graphic = graphic;
- Direction1 = d1;
- Direction2 = d2;
- Direction3 = d3;
- Direction4 = d4;
- OffsetY = offsetY;
- MirrorOffsetY = mirrorOffsetY;
- DrawBack = drawback;
- }
-
- public readonly ushort Graphic;
- public readonly sbyte Direction1,
- Direction2,
- Direction3,
- Direction4;
- public readonly sbyte OffsetY,
- MirrorOffsetY;
- public readonly bool DrawBack;
-
- public static SittingInfoData Empty = new SittingInfoData();
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct AnimIdxBlock
- {
- public uint Position;
- public uint Size;
- public uint Unknown;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- ref struct UOPAnimationHeader
- {
- public ushort Group;
- public ushort FrameID;
-
- public ushort Unk0;
- public ushort Unk1;
- public ushort Unk2;
- public ushort Unk3;
-
- public uint DataOffset;
- }
- }
-
- public enum AnimationGroups
- {
- None = 0,
- Low,
- High,
- People
- }
-
- public enum AnimationGroupsType
- {
- Monster = 0,
- SeaMonster,
- Animal,
- Human,
- Equipment,
- Unknown
- }
-
- public enum HighAnimationGroup
- {
- Walk = 0,
- Stand,
- Die1,
- Die2,
- Attack1,
- Attack2,
- Attack3,
- Misc1,
- Misc2,
- Misc3,
- Stumble,
- SlapGround,
- Cast,
- GetHit1,
- Misc4,
- GetHit2,
- GetHit3,
- Fidget1,
- Fidget2,
- Fly,
- Land,
- DieInFlight,
- AnimationCount
- }
-
- public enum PeopleAnimationGroup
- {
- WalkUnarmed = 0,
- WalkArmed,
- RunUnarmed,
- RunArmed,
- Stand,
- Fidget1,
- Fidget2,
- StandOnehandedAttack,
- StandTwohandedAttack,
- AttackOnehanded,
- AttackUnarmed1,
- AttackUnarmed2,
- AttackTwohandedDown,
- AttackTwohandedWide,
- AttackTwohandedJab,
- WalkWarmode,
- CastDirected,
- CastArea,
- AttackBow,
- AttackCrossbow,
- GetHit,
- Die1,
- Die2,
- OnmountRideSlow,
- OnmountRideFast,
- OnmountStand,
- OnmountAttack,
- OnmountAttackBow,
- OnmountAttackCrossbow,
- OnmountSlapHorse,
- Turn,
- AttackUnarmedAndWalk,
- EmoteBow,
- EmoteSalute,
- Fidget3,
- AnimationCount
- }
-
- public enum LowAnimationGroup
- {
- Walk = 0,
- Run,
- Stand,
- Eat,
- Unknown,
- Attack1,
- Attack2,
- Attack3,
- Die1,
- Fidget1,
- Fidget2,
- LieDown,
- Die2,
- AnimationCount
- }
-
- [Flags]
- public enum AnimationFlags : uint
- {
- None = 0x00000,
- Unknown1 = 0x00001,
- Use2IfHittedWhileRunning = 0x00002,
- IdleAt8Frame = 0x00004,
- CanFlying = 0x00008,
- Unknown10 = 0x00010,
- CalculateOffsetLowGroupExtended = 0x00020,
- CalculateOffsetByLowGroup = 0x00040,
- Unknown80 = 0x00080,
- Unknown100 = 0x00100,
- Unknown200 = 0x00200,
- CalculateOffsetByPeopleGroup = 0x00400,
- Unknown800 = 0x00800,
- Unknown1000 = 0x01000,
- Unknown2000 = 0x02000,
- Unknown4000 = 0x04000,
- Unknown8000 = 0x08000,
- UseUopAnimation = 0x10000,
- Unknown20000 = 0x20000,
- Unknown40000 = 0x40000,
- Unknown80000 = 0x80000,
- Found = 0x80000000
- }
-
- public struct EquipConvData : IEquatable
- {
- public EquipConvData(ushort graphic, ushort gump, ushort color)
- {
- Graphic = graphic;
- Gump = gump;
- Color = color;
- }
-
- public ushort Graphic;
- public ushort Gump;
- public ushort Color;
-
- public override int GetHashCode()
- {
- return (Graphic, Gump, Color).GetHashCode();
- }
-
- public override bool Equals(object obj)
- {
- return obj is EquipConvData v && Equals(v);
- }
-
- public bool Equals(EquipConvData other)
- {
- return (Graphic, Gump, Color) == (other.Graphic, other.Gump, other.Color);
- }
- }
-
- struct MobTypeInfo
- {
- public AnimationGroupsType Type;
- public AnimationFlags Flags;
- }
-
- struct BodyInfo
- {
- public ushort Graphic;
- public ushort Hue;
- }
-
- struct BodyConvInfo
- {
- public int FileIndex;
- public AnimationGroupsType AnimType;
- public ushort Graphic;
- public ushort Hue;
- public sbyte MountHeight;
- }
-
- unsafe struct UopInfo
- {
- private fixed int _replacedAnim[AnimationsLoader.MAX_ACTIONS];
-
- public Span ReplacedAnimations
- {
- get
- {
-
- fixed (int* ptr = _replacedAnim)
- {
- return new Span(ptr, AnimationsLoader.MAX_ACTIONS);
- }
- }
- }
-
- public sbyte HeightOffset;
- }
-
- [Flags]
- public enum BodyConvFlags
- {
- Anim1 = 0x1,
- Anim2 = 0x2,
- Anim3 = 0x4,
- Anim4 = 0x8,
- Anim5 = 0x10,
- }
-}
diff --git a/src/ClassicUO.Assets/ArtLoader.cs b/src/ClassicUO.Assets/ArtLoader.cs
deleted file mode 100644
index d1a498ab7..000000000
--- a/src/ClassicUO.Assets/ArtLoader.cs
+++ /dev/null
@@ -1,389 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class ArtLoader : UOFileLoader
- {
- private static ArtLoader _instance;
- private UOFile _file;
- private readonly ushort _graphicMask;
-
- [ThreadStatic]
- private static uint[] _data = null;
-
- public const int MAX_LAND_DATA_INDEX_COUNT = 0x4000;
- public const int MAX_STATIC_DATA_INDEX_COUNT = 0x14000;
-
- private ArtLoader(int staticCount, int landCount)
- {
- _graphicMask = UOFileManager.IsUOPInstallation ? (ushort)0xFFFF : (ushort)0x3FFF;
- }
-
- public static ArtLoader Instance =>
- _instance
- ?? (_instance = new ArtLoader(MAX_STATIC_DATA_INDEX_COUNT, MAX_LAND_DATA_INDEX_COUNT));
-
- public override Task Load()
- {
- return Task.Run(() =>
- {
- string filePath = UOFileManager.GetUOFilePath("artLegacyMUL.uop");
-
- if (UOFileManager.IsUOPInstallation && File.Exists(filePath))
- {
- _file = new UOFileUop(filePath, "build/artlegacymul/{0:D8}.tga");
- Entries = new UOFileIndex[
- Math.Max(((UOFileUop)_file).TotalEntriesCount, MAX_STATIC_DATA_INDEX_COUNT)
- ];
- }
- else
- {
- filePath = UOFileManager.GetUOFilePath("art.mul");
- string idxPath = UOFileManager.GetUOFilePath("artidx.mul");
-
- if (File.Exists(filePath) && File.Exists(idxPath))
- {
- _file = new UOFileMul(filePath, idxPath, MAX_STATIC_DATA_INDEX_COUNT);
- }
- }
-
- _file.FillEntries(ref Entries);
- });
- }
-
- // public Rectangle GetRealArtBounds(int index) =>
- // index + 0x4000 >= _spriteInfos.Length
- // ? Rectangle.Empty
- // : _spriteInfos[index + 0x4000].ArtBounds;
-
- private bool LoadData(Span data, int g, out short width, out short height)
- {
- ref var entry = ref GetValidRefEntry(g);
-
- if (entry.Length == 0)
- {
- width = 0;
- height = 0;
-
- return false;
- }
-
- _file.SetData(entry.Address, entry.FileSize);
- _file.Seek(entry.Offset);
- //var flags = _file.ReadUInt();
-
- //if (flags > 0xFFFF || flags == 0)
- if (g < 0x4000)
- {
- width = 44;
- height = 44;
-
- if (data == null || data.Length < (width * height))
- {
- return false;
- }
-
- /*
- * Since the data only contains the diamond shape, we may not actually read
- * into every pixel in 'data'. We must zero the buffer here since it is
- * re-used. But we only have to zero out the (44 * 44) worth.
- */
- data.Slice(0, (width * height)).Fill(0);
-
- for (int i = 0; i < 22; ++i)
- {
- int start = 22 - (i + 1);
- int pos = i * 44 + start;
- int end = start + ((i + 1) << 1);
-
- for (int j = start; j < end; ++j)
- {
- data[pos++] = HuesHelper.Color16To32(_file.ReadUShort()) | 0xFF_00_00_00;
- }
- }
-
- for (int i = 0; i < 22; ++i)
- {
- int pos = (i + 22) * 44 + i;
- int end = i + ((22 - i) << 1);
-
- for (int j = i; j < end; ++j)
- {
- data[pos++] = HuesHelper.Color16To32(_file.ReadUShort()) | 0xFF_00_00_00;
- }
- }
- }
- else
- {
- var flags = _file.ReadUInt();
- width = _file.ReadShort();
- height = _file.ReadShort();
-
- if (width <= 0 || height <= 0 || data.Length < (width * height))
- {
- return false;
- }
-
- /*
- * Since the data is run-length-encoded, we may not actually read
- * into every pixel in 'data'. We must zero the buffer here since it is
- * re-used. But we only have to zero out the (width * height) worth.
- */
- data.Slice(0, (width * height)).Fill(0);
-
- ushort fixedGraphic = (ushort)(g - 0x4000);
-
- if (ReadData(data, width, height, _file))
- {
- // keep the cursor graphic check to cleanup edges
- //if ((fixedGraphic >= 0x2053 && fixedGraphic <= 0x2062) || (fixedGraphic >= 0x206A && fixedGraphic <= 0x2079))
- //{
- // for (int i = 0; i < width; i++)
- // {
- // data[i] = 0;
- // data[(height - 1) * width + i] = 0;
- // }
-
- // for (int i = 0; i < height; i++)
- // {
- // data[i * width] = 0;
- // data[i * width + width - 1] = 0;
- // }
- //}
- }
- }
-
- return true;
- }
-
- public Span GetRawImage(uint g, out short width, out short height)
- {
- if (!LoadData(_data, (int)g, out width, out height))
- {
- if (_data != null && width * height < _data.Length)
- {
- return Span.Empty;
- }
-
- _data = new uint[width * height];
-
- if (!LoadData(_data, (int)g, out width, out height))
- {
- return Span.Empty;
- }
- }
-
- return _data.AsSpan(0, width * height);
- }
-
- private bool ReadHeader(
- DataReader file,
- ref UOFileIndex entry,
- out short width,
- out short height
- )
- {
- if (entry.Length == 0)
- {
- width = 0;
- height = 0;
-
- return false;
- }
-
- file.SetData(entry.Address, entry.FileSize);
- file.Seek(entry.Offset);
- file.Skip(4);
- width = file.ReadShort();
- height = file.ReadShort();
-
- return width > 0 && height > 0;
- }
-
- private unsafe bool ReadData(Span pixels, int width, int height, DataReader file)
- {
- ushort* ptr = (ushort*)file.PositionAddress;
- ushort* lineoffsets = ptr;
- byte* datastart = (byte*)ptr + height * 2;
- int x = 0;
- int y = 0;
- ptr = (ushort*)(datastart + lineoffsets[0] * 2);
-
- while (y < height)
- {
- ushort xoffs = *ptr++;
- ushort run = *ptr++;
-
- if (xoffs + run >= 2048)
- {
- return false;
- }
-
- if (xoffs + run != 0)
- {
- x += xoffs;
- int pos = y * width + x;
-
- for (int j = 0; j < run; ++j, ++pos)
- {
- ushort val = *ptr++;
-
- if (val != 0)
- {
- pixels[pos] = HuesHelper.Color16To32(val) | 0xFF_00_00_00;
- }
- }
-
- x += run;
- }
- else
- {
- x = 0;
- ++y;
- ptr = (ushort*)(datastart + lineoffsets[y] * 2);
- }
- }
-
- return true;
- }
-
- // private void FinalizeData(
- // Span pixels,
- // ref UOFileIndex entry,
- // ushort graphic,
- // int width,
- // int height,
- // out Rectangle bounds
- // )
- // {
- // int pos1 = 0;
- // int minX = width,
- // minY = height,
- // maxX = 0,
- // maxY = 0;
-
- // /* Temporarily broken. This isn't the right way to do it anyway since it can't be toggled on/off.
- // if (StaticFilters.IsCave(graphic) && ProfileManager.CurrentProfile != null && ProfileManager.CurrentProfile.EnableCaveBorder)
- // {
- // AddBlackBorder(pixels, width, height);
- // }
- // */
-
- // for (int y = 0; y < height; ++y)
- // {
- // for (int x = 0; x < width; ++x)
- // {
- // if (pixels[pos1++] != 0)
- // {
- // minX = Math.Min(minX, x);
- // maxX = Math.Max(maxX, x);
- // minY = Math.Min(minY, y);
- // maxY = Math.Max(maxY, y);
- // }
- // }
- // }
-
- // entry.Width = (short)((width >> 1) - 22);
- // entry.Height = (short)(height - 44);
-
- // bounds.X = minX;
- // bounds.Y = minY;
- // bounds.Width = maxX - minX;
- // bounds.Height = maxY - minY;
- // }
-
- private void AddBlackBorder(Span pixels, int width, int height)
- {
- for (int yy = 0; yy < height; yy++)
- {
- int startY = yy != 0 ? -1 : 0;
- int endY = yy + 1 < height ? 2 : 1;
-
- for (int xx = 0; xx < width; xx++)
- {
- ref uint pixel = ref pixels[yy * width + xx];
-
- if (pixel == 0)
- {
- continue;
- }
-
- int startX = xx != 0 ? -1 : 0;
- int endX = xx + 1 < width ? 2 : 1;
-
- for (int i = startY; i < endY; i++)
- {
- int currentY = yy + i;
-
- for (int j = startX; j < endX; j++)
- {
- int currentX = xx + j;
-
- ref uint currentPixel = ref pixels[currentY * width + currentX];
-
- if (currentPixel == 0u)
- {
- pixel = 0xFF_00_00_00;
- }
- }
- }
- }
- }
- }
-
- public ArtInfo GetArt(uint idx)
- {
- var pixels = GetRawImage(idx, out var width, out var height);
-
- return new ArtInfo()
- {
- Pixels = pixels,
- Width = width,
- Height = height
- };
- }
- }
-
- public ref struct ArtInfo
- {
- public Span Pixels;
- public int Width;
- public int Height;
- }
-}
diff --git a/src/ClassicUO.Assets/ClassicUO.Assets.csproj b/src/ClassicUO.Assets/ClassicUO.Assets.csproj
deleted file mode 100644
index 52717bc63..000000000
--- a/src/ClassicUO.Assets/ClassicUO.Assets.csproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- Library
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ClassicUO.Assets/ClilocLoader.cs b/src/ClassicUO.Assets/ClilocLoader.cs
deleted file mode 100644
index c9a45be5c..000000000
--- a/src/ClassicUO.Assets/ClilocLoader.cs
+++ /dev/null
@@ -1,381 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class ClilocLoader : UOFileLoader
- {
- private static ClilocLoader _instance;
- private string _cliloc;
- private readonly Dictionary _entries = new Dictionary();
-
- private ClilocLoader()
- {
- }
-
- public static ClilocLoader Instance => _instance ?? (_instance = new ClilocLoader());
-
- public Task Load(string lang)
- {
- if (string.IsNullOrEmpty(lang))
- {
- lang = "enu";
- }
-
- _cliloc = $"Cliloc.{lang}";
- Log.Trace($"searching for: '{_cliloc}'");
-
- if (!File.Exists(UOFileManager.GetUOFilePath(_cliloc)))
- {
- Log.Warn($"'{_cliloc}' not found. Rolled back to Cliloc.enu");
-
- _cliloc = "Cliloc.enu";
- }
-
- return Load();
- }
-
- public override Task Load()
- {
- return Task.Run
- (
- () =>
- {
- if (string.IsNullOrEmpty(_cliloc))
- {
- _cliloc = "Cliloc.enu";
- }
-
- string path = UOFileManager.GetUOFilePath(_cliloc);
-
- if (!File.Exists(path))
- {
- Log.Error($"cliloc not found: '{path}'");
- return;
- }
-
- if (string.Compare(_cliloc, "cliloc.enu", StringComparison.InvariantCultureIgnoreCase) != 0)
- {
- string enupath = UOFileManager.GetUOFilePath("Cliloc.enu");
-
- using (BinaryReader reader = new BinaryReader(new FileStream(enupath, FileMode.Open, FileAccess.Read)))
- {
- reader.ReadInt32();
- reader.ReadInt16();
-
- byte[] buffer = System.Buffers.ArrayPool.Shared.Rent(1024);
-
- try
- {
- while (reader.BaseStream.Length != reader.BaseStream.Position)
- {
- int number = reader.ReadInt32();
- byte flag = reader.ReadByte();
- int length = reader.ReadInt16();
-
- if (length > buffer.Length)
- {
- System.Buffers.ArrayPool.Shared.Return(buffer);
-
- buffer = System.Buffers.ArrayPool.Shared.Rent((length + 1023) & ~1023);
- }
-
- reader.Read(buffer, 0, length);
- string text = string.Intern(Encoding.UTF8.GetString(buffer, 0, length));
-
- _entries[number] = text;
- }
- }
- finally
- {
- System.Buffers.ArrayPool.Shared.Return(buffer);
- }
- }
- }
-
- using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)))
- {
- reader.ReadInt32();
- reader.ReadInt16();
- byte[] buffer = System.Buffers.ArrayPool.Shared.Rent(1024);
-
- try
- {
- while (reader.BaseStream.Length != reader.BaseStream.Position)
- {
- int number = reader.ReadInt32();
- byte flag = reader.ReadByte();
- int length = reader.ReadInt16();
-
- if (length > buffer.Length)
- {
- System.Buffers.ArrayPool.Shared.Return(buffer);
-
- buffer = System.Buffers.ArrayPool.Shared.Rent((length + 1023) & ~1023);
- }
-
- reader.Read(buffer, 0, length);
- string text = string.Intern(Encoding.UTF8.GetString(buffer, 0, length));
-
- _entries[number] = text;
- }
- }
- finally
- {
- System.Buffers.ArrayPool.Shared.Return(buffer);
- }
- }
- }
- );
- }
-
- public override void ClearResources()
- {
- _entries.Clear();
- }
-
- public string GetString(int number)
- {
- _entries.TryGetValue(number, out string text);
-
- return text;
- }
-
- public string GetString(int number, string replace)
- {
- string s = GetString(number);
-
- if (string.IsNullOrEmpty(s))
- {
- s = replace;
- }
-
- return s;
- }
-
- public string GetString(int number, bool camelcase, string replace = "")
- {
- string s = GetString(number);
-
- if (string.IsNullOrEmpty(s) && !string.IsNullOrEmpty(replace))
- {
- s = replace;
- }
-
- if (camelcase && !string.IsNullOrEmpty(s))
- {
- s = StringHelper.CapitalizeAllWords(s);
- }
-
- return s;
- }
-
- public unsafe string Translate(int clilocNum, string arg = "", bool capitalize = false)
- {
- string baseCliloc = GetString(clilocNum);
-
- if (baseCliloc == null)
- {
- return null;
- }
-
- if (arg == null)
- {
- arg = "";
- }
-
- var roChars = arg.AsSpan();
-
-
- // get count of valid args
- int i = 0;
- int totalArgs = 0;
- int trueStart = -1;
-
- for (; i < roChars.Length; ++i)
- {
- if (roChars[i] != '\t')
- {
- if (trueStart == -1)
- {
- trueStart = i;
- }
- }
- else if (trueStart >= 0)
- {
- ++totalArgs;
- }
- }
-
- if (trueStart == -1)
- {
- trueStart = 0;
- }
-
- // store index locations
- Span<(int, int)> locations = stackalloc (int, int)[++totalArgs];
- i = trueStart;
- for (int j = 0; i < roChars.Length; ++i)
- {
- if (roChars[i] == '\t')
- {
- locations[j].Item1 = trueStart;
- locations[j].Item2 = i;
-
- trueStart = i + 1;
-
- ++j;
- }
- }
-
- bool has_arguments = totalArgs - 1 > 0;
-
- locations[totalArgs - 1].Item1 = trueStart;
- locations[totalArgs - 1].Item2 = i;
-
- ValueStringBuilder sb = new ValueStringBuilder(baseCliloc.AsSpan());
- {
- int index, pos = 0;
-
- while (pos < sb.Length)
- {
- int poss = pos;
- pos = sb.RawChars.Slice(pos, sb.Length - pos).IndexOf('~');
-
- if (pos == -1)
- {
- break;
- }
-
- pos += poss;
-
- int pos2 = sb.RawChars.Slice(pos + 1, sb.Length - (pos + 1)).IndexOf('~');
-
- if (pos2 == -1) //non valid arg
- {
- break;
- }
-
- pos2 += pos + 1;
-
- index = sb.RawChars.Slice(pos + 1, pos2 - (pos + 1)).IndexOf('_');
-
- if (index == -1)
- {
- //there is no underscore inside the bounds, so we use all the part to get the number of argument
- index = pos2;
- }
- else
- {
- index += pos + 1;
- }
-
- int start = pos + 1;
- int max = index - start;
- int count = 0;
-
- for (; count < max; count++)
- {
- if (!char.IsNumber(sb.RawChars[start + count]))
- {
- break;
- }
- }
-
- if (!int.TryParse(sb.RawChars.Slice(start, count).ToString(), out index))
- {
- return $"MegaCliloc: error for {clilocNum}";
- }
-
- --index;
-
- var a = index < 0 || index >= totalArgs ? string.Empty.AsSpan() : arg.AsSpan().Slice(locations[index].Item1, locations[index].Item2 - locations[index].Item1);
-
- if (a.Length > 1)
- {
- if (a[0] == '#')
- {
- if (int.TryParse(a.Slice(1).ToString(), out int id1))
- {
- var ss = GetString(id1);
-
- if (string.IsNullOrEmpty(ss))
- {
- a = string.Empty.AsSpan();
- }
- else
- {
- a = ss.AsSpan();
- }
- }
- }
- else if (has_arguments && int.TryParse(a.ToString(), out int clil))
- {
- if (_entries.TryGetValue(clil, out string value) && !string.IsNullOrEmpty(value))
- {
- a = value.AsSpan();
- }
- }
- }
-
- sb.Remove(pos, pos2 - pos + 1);
- sb.Insert(pos, a);
-
- if (index >= 0 && index < totalArgs)
- {
- pos += a.Length /*locations[index].Y - locations[index].X*/;
- }
- }
-
- baseCliloc = sb.ToString();
-
- sb.Dispose();
-
- if (capitalize)
- {
- baseCliloc = StringHelper.CapitalizeAllWords(baseCliloc);
- }
-
- return baseCliloc;
- }
- }
- }
-}
diff --git a/src/ClassicUO.Assets/FontsLoader.cs b/src/ClassicUO.Assets/FontsLoader.cs
deleted file mode 100644
index 42be47560..000000000
--- a/src/ClassicUO.Assets/FontsLoader.cs
+++ /dev/null
@@ -1,3829 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Collections;
-using ClassicUO.Utility.Logging;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class FontsLoader : UOFileLoader
- {
- private const int UOFONT_SOLID = 0x0001;
- private const int UOFONT_ITALIC = 0x0002;
- private const int UOFONT_INDENTION = 0x0004;
- private const int UOFONT_BLACK_BORDER = 0x0008;
- private const int UOFONT_UNDERLINE = 0x0010;
- private const int UOFONT_FIXED = 0x0020;
- private const int UOFONT_CROPPED = 0x0040;
- private const int UOFONT_BQ = 0x0080;
- private const int UOFONT_EXTRAHEIGHT = 0x0100;
- private const int UOFONT_CROPTEXTURE = 0x0200;
- private const int UOFONT_FIXEDHEIGHT = 0x0400;
- private const int UNICODE_SPACE_WIDTH = 8;
- private const int MAX_HTML_TEXT_HEIGHT = 18;
- private const byte NOPRINT_CHARS = 32;
- private const float ITALIC_FONT_KOEFFICIENT = 3.3f;
-
- private static FontsLoader _instance;
-
- public struct Margin
- {
- public int X, Y, Width, Height;
-
- public Margin()
- {
- this = default;
- }
-
- public Margin(int x, int y, int width, int height)
- {
- X = x; Y = y; Width = width; Height = height;
- }
-
-
- public readonly int Right => X + Width;
- public readonly int Bottom => Y + Height;
-
- public readonly bool Contains(int x, int y)
- {
- return (x >= X && x < Right && y >= Y && y < Bottom);
- }
-
- public static readonly Margin Empty = new Margin();
- }
-
- struct HtmlStatus
- {
- public uint BackgroundColor;
- public uint VisitedWebLinkColor;
- public uint WebLinkColor;
- public uint Color;
- public Margin Margins;
-
- public bool IsHtmlBackgroundColored;
- }
-
- private HtmlStatus _htmlStatus;
-
- private FontCharacterData[,] _fontData;
- private readonly IntPtr[] _unicodeFontAddress = new IntPtr[20];
- private readonly long[] _unicodeFontSize = new long[20];
- private readonly Dictionary _webLinks = new Dictionary();
- private readonly int[] _offsetCharTable = { 2, 0, 2, 2, 0, 0, 2, 2, 0, 0 };
- private readonly int[] _offsetSymbolTable = { 1, 0, 1, 1, -1, 0, 1, 1, 0, 0 };
-
- private FontsLoader() { }
-
- public static FontsLoader Instance => _instance ?? (_instance = new FontsLoader());
-
- public int FontCount { get; private set; }
-
- public bool UnusePartialHue { get; set; } = false;
-
- public bool RecalculateWidthByInfo { get; set; } = false;
-
- public bool IsUsingHTML { get; set; }
-
- public override unsafe Task Load()
- {
- return Task.Run(() =>
- {
- UOFileMul fonts = new UOFileMul(UOFileManager.GetUOFilePath("fonts.mul"));
- UOFileMul[] uniFonts = new UOFileMul[20];
-
- for (int i = 0; i < 20; i++)
- {
- string path = UOFileManager.GetUOFilePath(
- "unifont" + (i == 0 ? "" : i.ToString()) + ".mul"
- );
-
- if (File.Exists(path))
- {
- uniFonts[i] = new UOFileMul(path);
-
- _unicodeFontAddress[i] = uniFonts[i].StartAddress;
-
- _unicodeFontSize[i] = uniFonts[i].Length;
- }
- }
-
- int fontHeaderSize = sizeof(FontHeader);
- FontCount = 0;
-
- while (fonts.Position < fonts.Length)
- {
- bool exit = false;
- fonts.Skip(1);
-
- for (int i = 0; i < 224; i++)
- {
- FontHeader* fh = (FontHeader*)fonts.PositionAddress;
-
- if (fonts.Position + fontHeaderSize >= fonts.Length)
- {
- continue;
- }
-
- fonts.Skip(fontHeaderSize);
- int bcount = fh->Width * fh->Height * 2;
-
- if (fonts.Position + bcount > fonts.Length)
- {
- exit = true;
-
- break;
- }
-
- fonts.Skip(bcount);
- }
-
- if (exit)
- {
- break;
- }
-
- FontCount++;
- }
-
- if (FontCount < 1)
- {
- FontCount = 0;
-
- return;
- }
-
- _fontData = new FontCharacterData[FontCount, 224];
- fonts.Seek(0);
-
- for (int i = 0; i < FontCount; i++)
- {
- byte header = fonts.ReadByte();
-
- for (int j = 0; j < 224; j++)
- {
- if (fonts.Position + 3 >= fonts.Length)
- {
- continue;
- }
-
- byte w = fonts.ReadByte();
- byte h = fonts.ReadByte();
- fonts.Skip(1);
- _fontData[i, j] = new FontCharacterData(
- w,
- h,
- (ushort*)fonts.PositionAddress
- );
- fonts.Skip(w * h * sizeof(ushort));
- }
- }
-
- if (_unicodeFontAddress[1] == IntPtr.Zero)
- {
- _unicodeFontAddress[1] = _unicodeFontAddress[0];
- _unicodeFontSize[1] = _unicodeFontSize[0];
- }
- });
- }
-
- public bool UnicodeFontExists(byte font)
- {
- return font < 20 && _unicodeFontAddress[font] != IntPtr.Zero;
- }
-
- /// Get the index in ASCII fonts of a character.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private int GetASCIIIndex(char c)
- {
- byte ch = (byte)c; // ASCII fonts cover only 256 characters
-
- if (ch < NOPRINT_CHARS)
- {
- return 0;
- }
-
- return ch - NOPRINT_CHARS;
- }
-
- public int GetWidthASCII(byte font, string str)
- {
- if (font >= FontCount || string.IsNullOrEmpty(str))
- {
- return 0;
- }
-
- int textLength = 0;
-
- foreach (char c in str)
- {
- textLength += _fontData[font, GetASCIIIndex(c)].Width;
- }
-
- return textLength;
- }
-
- public int GetCharWidthASCII(byte font, char c)
- {
- if (font >= FontCount || c == 0 || c == '\r')
- {
- return 0;
- }
-
- if (c < NOPRINT_CHARS)
- {
- return _fontData[font, 0].Width;
- }
-
- int index = c - NOPRINT_CHARS;
-
- if (index < _fontData.GetLength(1))
- {
- return _fontData[font, index].Width;
- }
-
- return 0;
- }
-
- public int GetWidthExASCII(
- byte font,
- string text,
- int maxwidth,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- if (font > FontCount || string.IsNullOrEmpty(text))
- {
- return 0;
- }
-
- MultilinesFontInfo info = GetInfoASCII(font, text, text.Length, align, flags, maxwidth);
-
- int textWidth = 0;
-
- while (info != null)
- {
- if (info.Width > textWidth)
- {
- textWidth = info.Width;
- }
-
- MultilinesFontInfo ptr = info;
- info = info.Next;
- ptr.Data.Clear();
- ptr = null;
- }
-
- return textWidth;
- }
-
- private int GetHeightASCII(MultilinesFontInfo info)
- {
- int textHeight = 0;
-
- while (info != null)
- {
- textHeight += info.MaxHeight;
- info = info.Next;
- }
-
- return textHeight;
- }
-
- public int GetHeightASCII(
- byte font,
- string str,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- if (width == 0)
- {
- width = GetWidthASCII(font, str);
- }
-
- MultilinesFontInfo info = GetInfoASCII(font, str, str.Length, align, flags, width);
-
- int textHeight = 0;
-
- while (info != null)
- {
- if (IsUsingHTML)
- {
- textHeight += MAX_HTML_TEXT_HEIGHT;
- }
- else
- {
- textHeight += info.MaxHeight;
- }
-
- MultilinesFontInfo ptr = info;
- info = info.Next;
- ptr.Data.Clear();
- ptr = null;
- }
-
- return textHeight;
- }
-
- public struct FontInfo
- {
- public uint[] Data;
- public int Width;
- public int Height;
-
- public int LineCount;
- public FastList Links;
-
- public static FontInfo Empty = new FontInfo() { Data = null };
- }
-
- public FontInfo GenerateASCII(
- byte font,
- string str,
- ushort color,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- bool saveHitmap,
- int height
- )
- {
- if (string.IsNullOrEmpty(str))
- {
- return FontInfo.Empty;
- }
-
- if (
- (flags & UOFONT_FIXED) != 0
- || (flags & UOFONT_CROPPED) != 0
- || (flags & UOFONT_CROPTEXTURE) != 0
- )
- {
- if (width == 0 || string.IsNullOrEmpty(str))
- {
- return FontInfo.Empty;
- }
-
- int realWidth = GetWidthASCII(font, str);
-
- if (realWidth > width)
- {
- string newstr = GetTextByWidthASCII(
- font,
- str,
- width,
- (flags & UOFONT_CROPPED) != 0,
- align,
- flags
- );
-
- if ((flags & UOFONT_CROPTEXTURE) != 0 && !string.IsNullOrEmpty(newstr))
- {
- int totalheight = 0;
-
- while (totalheight < height)
- {
- totalheight += GetHeightASCII(font, newstr, width, align, flags);
-
- if (str.Length > newstr.Length)
- {
- newstr += GetTextByWidthASCII(
- font,
- str.Substring(newstr.Length),
- width,
- (flags & UOFONT_CROPPED) != 0,
- align,
- flags
- );
- }
- else
- {
- break;
- }
- }
- }
-
- return GeneratePixelsASCII(
- font,
- newstr,
- color,
- width,
- align,
- flags,
- saveHitmap
- );
- }
- }
-
- return GeneratePixelsASCII(font, str, color, width, align, flags, saveHitmap);
- }
-
- public string GetTextByWidthASCII(
- byte font,
- string str,
- int width,
- bool isCropped,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- if (font >= FontCount || string.IsNullOrEmpty(str))
- {
- return string.Empty;
- }
-
- int strLen = str.Length;
-
- Span span = stackalloc char[strLen];
- ValueStringBuilder sb = new ValueStringBuilder(span);
-
- if (IsUsingHTML)
- {
- unsafe
- {
- HTMLChar* chars = stackalloc HTMLChar[strLen];
-
- GetHTMLData(chars, font, str.AsSpan(), ref strLen, align, flags);
- }
-
- int size = str.Length - strLen;
-
- if (size > 0)
- {
- sb.Append(str.Substring(0, size));
- str = str.Substring(str.Length - strLen, strLen);
-
- if (GetWidthASCII(font, str) < width)
- {
- isCropped = false;
- }
- }
- }
-
- if (isCropped)
- {
- width -= _fontData[font, '.' - NOPRINT_CHARS].Width * 3;
- }
-
- int textLength = 0;
-
- foreach (char c in str)
- {
- textLength += _fontData[font, GetASCIIIndex(c)].Width;
-
- if (textLength > width)
- {
- break;
- }
-
- sb.Append(c);
- }
-
- if (isCropped)
- {
- sb.Append("...");
- }
-
- string ss = sb.ToString();
-
- sb.Dispose();
-
- return ss;
- }
-
- private unsafe FontInfo GeneratePixelsASCII(
- byte font,
- string str,
- ushort color,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- bool saveHitmap
- )
- {
- if (font >= FontCount)
- {
- return FontInfo.Empty;
- }
-
- int len = str.Length;
-
- if (len == 0)
- {
- return FontInfo.Empty;
- }
-
- if (width <= 0)
- {
- width = GetWidthASCII(font, str);
- }
-
- if (width <= 0)
- {
- return FontInfo.Empty;
- }
-
- MultilinesFontInfo info = GetInfoASCII(font, str, len, align, flags, width);
-
- if (info == null)
- {
- return FontInfo.Empty;
- }
-
- width += 4;
- int height = GetHeightASCII(info);
-
- if (height <= 0)
- {
- MultilinesFontInfo ptr1 = info;
-
- while (ptr1 != null)
- {
- info = ptr1;
- ptr1 = ptr1.Next;
- info.Data.Clear();
- info = null;
- }
-
- return FontInfo.Empty;
- }
-
- int blocksize = height * width;
- uint[] pData = new uint[blocksize]; // System.Buffers.ArrayPool.Shared.Rent(blocksize);
-
- try
- {
- int lineOffsY = 0;
- MultilinesFontInfo ptr = info;
- bool isPartial = font != 5 && font != 8 && !UnusePartialHue;
- int font6OffsetY = font == 6 ? 7 : 0;
- int linesCount = 0; // this value should be added to TextTexture.LineCount += linesCount
-
- while (ptr != null)
- {
- info = ptr;
- linesCount++;
- int w = 0;
-
- switch (ptr.Align)
- {
- case TEXT_ALIGN_TYPE.TS_CENTER:
- {
- w = (width - ptr.Width) >> 1;
-
- if (w < 0)
- {
- w = 0;
- }
-
- break;
- }
-
- case TEXT_ALIGN_TYPE.TS_RIGHT:
- {
- w = width - 10 - ptr.Width;
-
- if (w < 0)
- {
- w = width;
- }
-
- break;
- }
-
- case TEXT_ALIGN_TYPE.TS_LEFT when (flags & UOFONT_INDENTION) != 0:
- w = ptr.IndentionOffset;
-
- break;
- }
-
- var count = ptr.Data.Length;
-
- for (int i = 0; i < count; i++)
- {
- byte index = (byte)ptr.Data[i].Item;
-
- int offsY = GetFontOffsetY(font, index);
-
- ref FontCharacterData fcd = ref _fontData[
- font,
- GetASCIIIndex(ptr.Data[i].Item)
- ];
-
- int dw = fcd.Width;
- int dh = fcd.Height;
- ushort charColor = color;
-
- for (int y = 0; y < dh; y++)
- {
- int testY = y + lineOffsY + offsY;
-
- if (testY >= height)
- {
- break;
- }
-
- for (int x = 0; x < dw; x++)
- {
- if (x + w >= width)
- {
- break;
- }
-
- ushort pic = fcd.Data[y * dw + x];
-
- if (pic != 0)
- {
- uint pcl;
-
- if (isPartial)
- {
- pcl = HuesLoader.Instance.GetPartialHueColor(
- pic,
- charColor
- );
- }
- else
- {
- pcl = HuesLoader.Instance.ApplyHueRgba8888(pic, charColor);
- }
-
- int block = testY * width + x + w;
-
- if (block >= 0)
- {
- pData[block] = pcl | 0xFF_00_00_00;
- }
- }
- }
- }
-
- w += dw;
- }
-
- lineOffsY += ptr.MaxHeight - font6OffsetY;
- ptr = ptr.Next;
- info.Data.Clear();
- info = null;
- }
-
- FontInfo fi = new FontInfo();
- fi.LineCount = linesCount;
- fi.Data = pData;
- fi.Width = width;
- fi.Height = height;
- fi.Links = null;
-
- return fi;
- }
- finally
- {
- //System.Buffers.ArrayPool.Shared.Return(pData, true);
- }
- }
-
- private int GetFontOffsetY(byte font, byte index)
- {
- if (index == 0xB8)
- {
- return 1;
- }
-
- if (
- !(index >= 0x41 && index <= 0x5A)
- && !(index >= 0xC0 && index <= 0xDF)
- && index != 0xA8
- )
- {
- if (font < 10)
- {
- if (index >= 0x61 && index <= 0x7A)
- {
- return _offsetCharTable[font];
- }
-
- return _offsetSymbolTable[font];
- }
-
- return 2;
- }
-
- return 0;
- }
-
- public MultilinesFontInfo GetInfoASCII(
- byte font,
- string str,
- int len,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- int width,
- bool countret = false,
- bool countspaces = false
- )
- {
- if (font >= FontCount)
- {
- return null;
- }
-
- MultilinesFontInfo info = new MultilinesFontInfo();
- info.Reset();
- info.Align = align;
- MultilinesFontInfo ptr = info;
- int indentionOffset = 0;
- ptr.IndentionOffset = 0;
- bool isFixed = (flags & UOFONT_FIXED) != 0;
- bool isCropped = (flags & UOFONT_CROPPED) != 0;
- int charCount = 0;
- int lastSpace = 0;
- int readWidth = 0;
- int newlineval = countret ? 1 : 0;
-
- for (int i = 0; i < len; i++)
- {
- char si = str[i];
-
- if ( /*si == '\r' ||*/
- si == '\n')
- {
- if (si == '\r' || isFixed || isCropped)
- {
- continue;
- }
- }
-
- if (si == ' ')
- {
- lastSpace = i;
- ptr.Width += readWidth;
- readWidth = 0;
- ptr.CharCount += charCount;
- charCount = 0;
- }
-
- ref FontCharacterData fcd = ref _fontData[font, GetASCIIIndex(si)];
- int eval = ptr.CharStart;
-
- if (si == '\n' || ptr.Width + readWidth + fcd.Width > width)
- {
- if (lastSpace == ptr.CharStart && lastSpace == 0 && si != '\n')
- {
- ++eval;
- }
-
- if (si == '\n')
- {
- ptr.Width += readWidth;
- ptr.CharCount += charCount + newlineval;
- lastSpace = i;
-
- if (ptr.Width == 0)
- {
- ptr.Width = 1;
- }
-
- if (ptr.MaxHeight == 0)
- {
- ptr.MaxHeight = 14;
- }
-
- ptr.Data.Length = ptr.CharCount - newlineval;
-
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
- ptr.Align = align;
- ptr.CharStart = i + 1;
- readWidth = 0;
- charCount = 0;
- indentionOffset = 0;
- ptr.IndentionOffset = 0;
-
- continue;
- }
-
- if (lastSpace + 1 == eval && !isFixed && !isCropped)
- {
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
-
- if (ptr.Width == 0)
- {
- ptr.Width = 1;
- }
-
- if (ptr.MaxHeight == 0)
- {
- ptr.MaxHeight = 14;
- }
-
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
- ptr.Align = align;
- ptr.CharStart = i;
- lastSpace = i - 1;
- charCount = 0;
-
- if (ptr.Align == TEXT_ALIGN_TYPE.TS_LEFT && (flags & UOFONT_INDENTION) != 0)
- {
- indentionOffset = 14;
- }
-
- ptr.IndentionOffset = indentionOffset;
- readWidth = indentionOffset;
- }
- else
- {
- if (isFixed)
- {
- MultilinesFontData mfd1 = new MultilinesFontData(
- 0xFFFFFFFF,
- flags,
- font,
- si,
- 0
- );
-
- ptr.Data.Add(mfd1);
- readWidth += fcd.Width;
-
- if (fcd.Height > ptr.MaxHeight)
- {
- ptr.MaxHeight = fcd.Height;
- }
-
- charCount++;
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
- }
-
- i = lastSpace + 1;
- si = i < len ? str[i] : '\0';
-
- if (ptr.Width == 0)
- {
- ptr.Width = 1;
- }
- else if (countspaces && si != '\0' && lastSpace - eval == ptr.CharCount)
- {
- ptr.CharCount++;
- }
-
- if (ptr.MaxHeight == 0)
- {
- ptr.MaxHeight = 14;
- }
-
- //ptr.CharCount = charCount;
- charCount = 0;
- ptr.Data.Length = ptr.CharCount;
-
- if (isFixed || isCropped)
- {
- break;
- }
-
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
- ptr.Align = align;
- ptr.CharStart = i;
-
- if (ptr.Align == TEXT_ALIGN_TYPE.TS_LEFT && (flags & UOFONT_INDENTION) != 0)
- {
- indentionOffset = 14;
- }
-
- ptr.IndentionOffset = indentionOffset;
- readWidth = indentionOffset;
- }
- }
-
- MultilinesFontData mfd = new MultilinesFontData(0xFFFFFFFF, flags, font, si, 0);
-
- ptr.Data.Add(mfd);
- readWidth += si == '\r' ? 0 : fcd.Width;
-
- if (fcd.Height > ptr.MaxHeight)
- {
- ptr.MaxHeight = fcd.Height;
- }
-
- charCount++;
- }
-
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
-
- if (readWidth == 0 && len > 0 && (str[len - 1] == '\n' || str[len - 1] == '\r'))
- {
- ptr.Width = 1;
- ptr.MaxHeight = 14;
- }
-
- if (font == 4)
- {
- ptr = info;
-
- while (ptr != null)
- {
- if (ptr.Width > 1)
- {
- ptr.MaxHeight = ptr.MaxHeight + 2;
- }
- else
- {
- ptr.MaxHeight = ptr.MaxHeight + 6;
- }
-
- ptr = ptr.Next;
- }
- }
-
- return info;
- }
-
- public void SetUseHTML(
- bool value,
- uint htmlStartColor = 0xFFFFFFFF,
- bool backgroundCanBeColored = false
- )
- {
- IsUsingHTML = value;
- _htmlStatus.Color = htmlStartColor;
- _htmlStatus.IsHtmlBackgroundColored = backgroundCanBeColored;
- }
-
- public FontInfo GenerateUnicode(
- byte font,
- string str,
- ushort color,
- byte cell,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- bool saveHitmap,
- int height
- )
- {
- if (string.IsNullOrEmpty(str))
- {
- return FontInfo.Empty;
- }
-
- if (
- (flags & UOFONT_FIXED) != 0
- || (flags & UOFONT_CROPPED) != 0
- || (flags & UOFONT_CROPTEXTURE) != 0
- )
- {
- if (width == 0)
- {
- return FontInfo.Empty;
- }
-
- int realWidth = GetWidthUnicode(font, str.AsSpan());
-
- if (realWidth > width)
- {
- string newstr = GetTextByWidthUnicode(
- font,
- str.AsSpan(),
- width,
- (flags & UOFONT_CROPPED) != 0,
- align,
- flags
- );
-
- if ((flags & UOFONT_CROPTEXTURE) != 0 && !string.IsNullOrEmpty(newstr))
- {
- int totalheight = 0;
-
- while (totalheight < height)
- {
- totalheight += GetHeightUnicode(font, newstr, width, align, flags);
-
- if (str.Length > newstr.Length)
- {
- newstr += GetTextByWidthUnicode(
- font,
- str.AsSpan(0, newstr.Length),
- width,
- (flags & UOFONT_CROPPED) != 0,
- align,
- flags
- );
- }
- else
- {
- break;
- }
- }
- }
-
- return GeneratePixelsUnicode(
- font,
- newstr,
- color,
- cell,
- width,
- align,
- flags,
- saveHitmap
- );
- }
- }
-
- return GeneratePixelsUnicode(font, str, color, cell, width, align, flags, saveHitmap);
- }
-
- public unsafe string GetTextByWidthUnicode(
- byte font,
- ReadOnlySpan str,
- int width,
- bool isCropped,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || str.IsEmpty)
- {
- return string.Empty;
- }
-
- uint* table = (uint*)_unicodeFontAddress[font];
- int strLen = str.Length;
-
- Span span = stackalloc char[strLen];
- ValueStringBuilder sb = new ValueStringBuilder(span);
-
- if (IsUsingHTML)
- {
- unsafe
- {
- HTMLChar* data = stackalloc HTMLChar[strLen];
-
- GetHTMLData(data, font, str, ref strLen, align, flags);
- }
-
- int size = str.Length - strLen;
-
- if (size > 0)
- {
- sb.Append(str.Slice(0, size));
- str = str.Slice(str.Length - strLen, strLen);
-
- if (GetWidthUnicode(font, str) < width)
- {
- isCropped = false;
- }
- }
- }
-
- if (isCropped)
- {
- uint offset = table['.'];
-
- if (offset != 0 && offset != 0xFFFFFFFF)
- {
- width -= *(byte*)((IntPtr)table + (int)offset + 2) * 3 + 3;
- }
- }
-
- int textLength = 0;
-
- foreach (char c in str)
- {
- uint offset = table[c];
- sbyte charWidth = 0;
-
- if (offset != 0 && offset != 0xFFFFFFFF)
- {
- byte* ptr = (byte*)((IntPtr)table + (int)offset);
- charWidth = (sbyte)((sbyte)ptr[0] + (sbyte)ptr[2] + 1);
- }
- else if (c == ' ')
- {
- charWidth = UNICODE_SPACE_WIDTH;
- }
-
- if (charWidth != 0)
- {
- textLength += charWidth;
-
- if (textLength > width)
- {
- break;
- }
-
- sb.Append(c);
- }
- }
-
- if (isCropped)
- {
- sb.Append("...");
- }
-
- string ss = sb.ToString();
-
- sb.Dispose();
-
- return ss;
- }
-
- public int GetWidthUnicode(byte font, string str)
- {
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || string.IsNullOrEmpty(str))
- {
- return 0;
- }
-
- return GetWidthUnicode(font, str.AsSpan());
- }
-
- private unsafe int GetWidthUnicode(byte font, ReadOnlySpan str)
- {
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || str.IsEmpty)
- {
- return 0;
- }
-
- uint* table = (uint*)_unicodeFontAddress[font];
- int textLength = 0;
- int maxTextLenght = 0;
-
- foreach (char c in str)
- {
- uint offset = table[c];
-
- if (c != '\r' && offset != 0 && offset != 0xFFFFFFFF)
- {
- byte* ptr = (byte*)((IntPtr)table + (int)offset);
- textLength += (sbyte)ptr[0] + (sbyte)ptr[2] + 1;
- }
- else if (c == ' ')
- {
- textLength += UNICODE_SPACE_WIDTH;
- }
- else if (c == '\n')
- {
- maxTextLenght = Math.Max(maxTextLenght, textLength);
- textLength = 0;
- }
- }
-
- return Math.Max(maxTextLenght, textLength);
- }
-
- public unsafe int GetCharWidthUnicode(byte font, char c)
- {
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || c == 0 || c == '\r')
- {
- return 0;
- }
-
- uint* table = (uint*)_unicodeFontAddress[font];
- uint offset = table[c];
-
- if (offset != 0 && offset != 0xFFFFFFFF)
- {
- byte* ptr = (byte*)((IntPtr)table + (int)offset);
-
- return (sbyte)ptr[0] + (sbyte)ptr[2] + 1;
- }
-
- if (c == ' ')
- {
- return UNICODE_SPACE_WIDTH;
- }
-
- return 0;
- }
-
- public int GetWidthExUnicode(
- byte font,
- string text,
- int maxwidth,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- if (
- font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || string.IsNullOrEmpty(text)
- )
- {
- return 0;
- }
-
- MultilinesFontInfo info = GetInfoUnicode(
- font,
- text,
- text.Length,
- align,
- flags,
- maxwidth
- );
-
- int textWidth = 0;
-
- while (info != null)
- {
- if (info.Width > textWidth)
- {
- textWidth = info.Width;
- }
-
- MultilinesFontInfo ptr = info;
- info = info.Next;
- ptr.Data.Clear();
- ptr = null;
- }
-
- return textWidth + 4;
- }
-
- public unsafe MultilinesFontInfo GetInfoUnicode(
- byte font,
- string str,
- int len,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- int width,
- bool countret = false,
- bool countspaces = false
- )
- {
- _htmlStatus.WebLinkColor = 0xFF0000FF;
- _htmlStatus.VisitedWebLinkColor = 0x0000FFFF;
- _htmlStatus.BackgroundColor = 0;
- _htmlStatus.Margins = Margin.Empty;
-
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero)
- {
- return null;
- }
-
- if (IsUsingHTML)
- {
- return GetInfoHTML(font, str, len, align, flags, width);
- }
-
- uint* table = (uint*)_unicodeFontAddress[font];
- MultilinesFontInfo info = new MultilinesFontInfo();
- info.Reset();
- info.Align = align;
- MultilinesFontInfo ptr = info;
- int indetionOffset = 0;
- ptr.IndentionOffset = 0;
- int charCount = 0;
- int lastSpace = 0;
- int readWidth = 0;
- int newlineval = countret ? 1 : 0;
- int extraheight = (flags & UOFONT_EXTRAHEIGHT) != 0 ? 4 : 0;
- bool isFixed = (flags & UOFONT_FIXED) != 0;
- bool isCropped = (flags & UOFONT_CROPPED) != 0;
- TEXT_ALIGN_TYPE current_align = align;
- ushort current_flags = flags;
- byte current_font = font;
- uint charcolor = 0xFFFFFFFF;
- uint current_charcolor = 0xFFFFFFFF;
- uint lastspace_charcolor = 0xFFFFFFFF;
- uint lastaspace_current_charcolor = 0xFFFFFFFF;
-
- for (int i = 0; i < len; i++)
- {
- char si = str[i];
-
- if (si == '\n')
- {
- if (isFixed || isCropped)
- {
- si = (char)0;
- }
- }
-
- if (
- (table[si] == 0 || table[si] == 0xFFFFFFFF)
- && si != ' '
- && si != '\n'
- && si != '\r'
- )
- {
- continue;
- }
-
- byte* data = (byte*)((IntPtr)table + (int)table[si]);
-
- if (si == ' ')
- {
- lastSpace = i;
- ptr.Width += readWidth;
- readWidth = 0;
- ptr.CharCount += charCount;
- charCount = 0;
- lastspace_charcolor = charcolor;
- lastaspace_current_charcolor = current_charcolor;
- }
-
- int eval = ptr.CharStart;
-
- if (ptr.Width + readWidth + (sbyte)data[0] + (sbyte)data[2] > width || si == '\n')
- {
- if (lastSpace == ptr.CharStart && lastSpace == 0 && si != '\n')
- {
- ++eval;
- }
-
- if (si == '\n')
- {
- ptr.Width += readWidth;
- ptr.CharCount += charCount + newlineval;
- lastSpace = i;
-
- if (ptr.Width == 0)
- {
- ptr.Width = 1;
- }
-
- if (ptr.MaxHeight == 0)
- {
- ptr.MaxHeight = 14 + extraheight;
- }
-
- ptr.Data.Length = ptr.CharCount - newlineval;
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
- ptr.Align = current_align;
- ptr.CharStart = i + 1;
- readWidth = 0;
- charCount = 0;
- indetionOffset = 0;
- ptr.IndentionOffset = 0;
-
- continue;
- }
-
- if (lastSpace + 1 == eval && !isFixed && !isCropped)
- {
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
-
- if (ptr.Width == 0)
- {
- ptr.Width = 1;
- }
-
- if (ptr.MaxHeight == 0)
- {
- ptr.MaxHeight = 14 + extraheight;
- }
-
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
- ptr.Align = current_align;
- ptr.CharStart = i;
- lastSpace = i - 1;
- charCount = 0;
-
- if (
- ptr.Align == TEXT_ALIGN_TYPE.TS_LEFT
- && (current_flags & UOFONT_INDENTION) != 0
- )
- {
- indetionOffset = 14;
- }
-
- ptr.IndentionOffset = indetionOffset;
- readWidth = indetionOffset;
- }
- else
- {
- if (isFixed)
- {
- MultilinesFontData mfd1 = new MultilinesFontData(
- current_charcolor,
- current_flags,
- current_font,
- si,
- 0
- );
-
- ptr.Data.Add(mfd1);
- readWidth += si == '\r' ? 0 : (sbyte)data[0] + (sbyte)data[2] + 1;
-
- if ((sbyte)data[1] + (sbyte)data[3] > ptr.MaxHeight)
- {
- ptr.MaxHeight = (sbyte)data[1] + (sbyte)data[3] + extraheight;
- }
-
- charCount++;
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
- }
-
- i = lastSpace + 1;
- charcolor = lastspace_charcolor;
- current_charcolor = lastspace_charcolor;
- si = i < str.Length ? str[i] : '\0';
-
- if (ptr.Width == 0)
- {
- ptr.Width = 1;
- }
- else if (countspaces && si != '\0' && lastSpace - eval == ptr.CharCount)
- {
- ptr.CharCount++;
- }
-
- if (ptr.MaxHeight == 0)
- {
- ptr.MaxHeight = 14 + extraheight;
- }
-
- //ptr.CharCount = charCount;
-
- charCount = 0;
- ptr.Data.Length = ptr.CharCount;
-
- if (isFixed || isCropped)
- {
- break;
- }
-
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
- ptr.Align = current_align;
- ptr.CharStart = i;
- charCount = 0;
-
- if (
- ptr.Align == TEXT_ALIGN_TYPE.TS_LEFT
- && (current_flags & UOFONT_INDENTION) != 0
- )
- {
- indetionOffset = 14;
- }
-
- ptr.IndentionOffset = indetionOffset;
- readWidth = indetionOffset;
- }
- }
-
- MultilinesFontData mfd = new MultilinesFontData(
- current_charcolor,
- current_flags,
- current_font,
- si,
- 0
- );
-
- ptr.Data.Add(mfd);
-
- if (si == ' ')
- {
- readWidth += UNICODE_SPACE_WIDTH;
-
- if (ptr.MaxHeight <= 0)
- {
- ptr.MaxHeight = 5 + extraheight;
- }
- }
- else
- {
- readWidth += si == '\r' ? 0 : (sbyte)data[0] + (sbyte)data[2] + 1;
-
- if ((sbyte)data[1] + (sbyte)data[3] > ptr.MaxHeight)
- {
- ptr.MaxHeight = (sbyte)data[1] + (sbyte)data[3] + extraheight;
- }
- }
-
- charCount++;
- }
-
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
-
- if (readWidth == 0 && len != 0)
- {
- switch (str[len - 1])
- {
- case '\n':
- ptr.CharCount += newlineval;
- goto case '\r';
-
- case '\r':
- ptr.Width = 1;
- ptr.MaxHeight = 14;
-
- break;
- }
- }
-
- return info;
- }
-
- private unsafe FontInfo GeneratePixelsUnicode(
- byte font,
- string str,
- ushort color,
- byte cell,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- bool saveHitmap
- )
- {
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero)
- {
- return FontInfo.Empty;
- }
-
- int len = str.Length;
-
- if (len == 0)
- {
- return FontInfo.Empty;
- }
-
- int oldWidth = width;
-
- if (width == 0)
- {
- width = GetWidthUnicode(font, str.AsSpan());
-
- if (width == 0)
- {
- return FontInfo.Empty;
- }
- }
-
- MultilinesFontInfo info = GetInfoUnicode(font, str, len, align, flags, width);
-
- if (info == null)
- {
- return FontInfo.Empty;
- }
-
- if (IsUsingHTML && (_htmlStatus.Margins.X != 0 || _htmlStatus.Margins.Width != 0))
- {
- while (info != null)
- {
- MultilinesFontInfo ptr1 = info.Next;
- info.Data.Clear();
- info = null;
- info = ptr1;
- }
-
- int newWidth = width - (_htmlStatus.Margins.Right);
-
- if (newWidth < 10)
- {
- newWidth = 10;
- }
-
- info = GetInfoUnicode(font, str, len, align, flags, newWidth);
-
- if (info == null)
- {
- return FontInfo.Empty;
- }
- }
-
- if (oldWidth == 0 && RecalculateWidthByInfo)
- {
- MultilinesFontInfo ptr1 = info;
- width = 0;
-
- while (ptr1 != null)
- {
- if (ptr1.Width > width)
- {
- width = ptr1.Width;
- }
-
- ptr1 = ptr1.Next;
- }
- }
-
- width += 4;
- int height = GetHeightUnicode(info);
-
- if (height == 0)
- {
- while (info != null)
- {
- MultilinesFontInfo ptr1 = info;
- info = info.Next;
- ptr1.Data.Clear();
- ptr1 = null;
- }
-
- return FontInfo.Empty;
- }
-
- height += _htmlStatus.Margins.Y + _htmlStatus.Margins.Height + 4;
- int blocksize = height * width;
- uint[] pData = new uint[blocksize]; // System.Buffers.ArrayPool.Shared.Rent(blocksize);
-
- try
- {
- uint* table = (uint*)_unicodeFontAddress[font];
- int lineOffsY = _htmlStatus.Margins.Y;
- MultilinesFontInfo ptr = info;
- uint datacolor = 0;
-
- if (color == 0xFFFF)
- {
- datacolor = 0xFEFFFFFF;
- }
- else
- {
- datacolor =
- HuesHelper.RgbaToArgb((HuesLoader.Instance.GetHueColorRgba8888(cell, color) << 8) | 0xFF);
- }
-
- bool isItalic = (flags & UOFONT_ITALIC) != 0;
- bool isSolid = (flags & UOFONT_SOLID) != 0;
- bool isBlackBorder = (flags & UOFONT_BLACK_BORDER) != 0;
- bool isUnderline = (flags & UOFONT_UNDERLINE) != 0;
- uint blackColor = 0xFF010101;
- bool isLink = false;
- int linkStartX = 0;
- int linkStartY = 0;
- int linesCount = 0;
- var links = new FastList();
-
- while (ptr != null)
- {
- info = ptr;
- linesCount++;
- int w = _htmlStatus.Margins.Y;
-
- switch (ptr.Align)
- {
- case TEXT_ALIGN_TYPE.TS_CENTER:
- {
- w += (width - 8) / 2 - ptr.Width / 2;
-
- if (w < 0)
- {
- w = 0;
- }
-
- break;
- }
-
- case TEXT_ALIGN_TYPE.TS_RIGHT:
- {
- w += width - 10 - ptr.Width;
-
- if (w < 0)
- {
- w = 0;
- }
-
- break;
- }
-
- case TEXT_ALIGN_TYPE.TS_LEFT when (flags & UOFONT_INDENTION) != 0:
- w += ptr.IndentionOffset;
-
- break;
- }
-
- ushort oldLink = 0;
- var dataSize = ptr.Data.Length;
-
- for (int i = 0; i < dataSize; i++)
- {
- ref MultilinesFontData dataPtr = ref ptr.Data.Buffer[i];
- char si = dataPtr.Item;
- table = (uint*)_unicodeFontAddress[dataPtr.Font];
-
- if (!isLink)
- {
- oldLink = dataPtr.LinkID;
-
- if (oldLink != 0)
- {
- isLink = true;
- linkStartX = w;
- linkStartY = lineOffsY + 3;
- }
- }
- else if (dataPtr.LinkID == 0 || i + 1 == dataSize)
- {
- isLink = false;
- int linkHeight = lineOffsY - linkStartY;
-
- if (linkHeight < 14)
- {
- linkHeight = 14;
- }
-
- int ofsX = 0;
-
- if (si == ' ')
- {
- ofsX = UNICODE_SPACE_WIDTH;
- }
- else if ((table[si] == 0 || table[si] == 0xFFFFFFFF) && si != ' ') { }
- else
- {
- byte* xData = (byte*)((IntPtr)table + (int)table[si]);
- ofsX = (sbyte)xData[2];
- }
-
- WebLinkRect wlr = new WebLinkRect
- {
- LinkID = oldLink,
- Bounds = new Margin(linkStartX, linkStartY, w - ofsX, linkHeight)
- };
-
- links.Add(wlr);
- oldLink = 0;
- }
-
- if ((table[si] == 0 || table[si] == 0xFFFFFFFF) && si != ' ')
- {
- continue;
- }
-
- byte* data = (byte*)((IntPtr)table + (int)table[si]);
- int offsX = 0;
- int offsY = 0;
- int dw = 0;
- int dh = 0;
-
- if (si == ' ')
- {
- offsX = 0;
- dw = UNICODE_SPACE_WIDTH;
- }
- else
- {
- offsX = (sbyte)data[0] + 1;
- offsY = (sbyte)data[1];
- dw = data[2];
- dh = data[3];
- data += 4;
- }
-
- int tmpW = w;
- uint charcolor = datacolor;
-
- bool isBlackPixel =
- ((charcolor >> 0) & 0xFF) <= 8
- && ((charcolor >> 8) & 0xFF) <= 8
- && ((charcolor >> 16) & 0xFF) <= 8;
-
- if (si != ' ')
- {
- if (IsUsingHTML && i < ptr.Data.Length)
- {
- isItalic = (dataPtr.Flags & UOFONT_ITALIC) != 0;
- isSolid = (dataPtr.Flags & UOFONT_SOLID) != 0;
- isBlackBorder = (dataPtr.Flags & UOFONT_BLACK_BORDER) != 0;
- isUnderline = (dataPtr.Flags & UOFONT_UNDERLINE) != 0;
-
- if (dataPtr.Color != 0xFFFFFFFF)
- {
- charcolor = HuesHelper.RgbaToArgb(dataPtr.Color);
-
- //isBlackPixel = ((charcolor >> 24) & 0xFF) <= 8 && ((charcolor >> 16) & 0xFF) <= 8 && ((charcolor >> 8) & 0xFF) <= 8;
- isBlackPixel =
- ((charcolor >> 0) & 0xFF) <= 8
- && ((charcolor >> 8) & 0xFF) <= 8
- && ((charcolor >> 16) & 0xFF) <= 8;
- }
- }
-
- int scanlineCount = ((dw - 1) >> 3) + 1;
-
- for (int y = 0; y < dh; y++)
- {
- int testY = offsY + lineOffsY + y;
-
- if (testY < 0)
- {
- testY = 0;
- }
-
- if (testY >= height)
- {
- break;
- }
-
- byte* scanlines = data;
- data += scanlineCount;
-
- int italicOffset = 0;
-
- if (isItalic)
- {
- italicOffset = (int)((dh - y) / ITALIC_FONT_KOEFFICIENT);
- }
-
- int testX = w + offsX + italicOffset + (isSolid ? 1 : 0);
-
- for (int c = 0; c < scanlineCount; c++)
- {
- int coff = c << 3;
-
- for (int j = 0; j < 8; j++)
- {
- int x = coff + j;
-
- if (x >= dw)
- {
- break;
- }
-
- int nowX = testX + x;
-
- if (nowX >= width)
- {
- break;
- }
-
- byte cl = (byte)(scanlines[c] & (1 << (7 - j)));
- int block = testY * width + nowX;
-
- if (cl != 0)
- {
- pData[block] = charcolor;
- }
- }
- }
- }
-
- if (isSolid)
- {
- uint solidColor = blackColor;
-
- if (solidColor == charcolor)
- {
- solidColor++;
- }
-
- int minXOk = w + offsX > 0 ? -1 : 0;
- int maxXOk = w + offsX + dw < width ? 1 : 0;
- maxXOk += dw;
-
- for (int cy = 0; cy < dh; cy++)
- {
- int testY = offsY + lineOffsY + cy;
-
- if (testY >= height)
- {
- break;
- }
-
- if (testY < 0)
- {
- testY = 0;
- }
-
- int italicOffset = 0;
-
- if (isItalic && cy < dh)
- {
- italicOffset = (int)((dh - cy) / ITALIC_FONT_KOEFFICIENT);
- }
-
- for (int cx = minXOk; cx < maxXOk; cx++)
- {
- int testX = cx + w + offsX + italicOffset;
-
- if (testX >= width)
- {
- break;
- }
-
- int block = testY * width + testX;
-
- if (pData[block] == 0 && pData[block] != solidColor)
- {
- int endX = cx < dw ? 2 : 1;
-
- if (endX == 2 && testX + 1 >= width)
- {
- endX--;
- }
-
- for (int x = 0; x < endX; x++)
- {
- int nowX = testX + x;
- int testBlock = testY * width + nowX;
-
- if (
- pData[testBlock] != 0
- && pData[testBlock] != solidColor
- )
- {
- pData[block] = solidColor;
-
- break;
- }
- }
- }
- }
- }
-
- for (int cy = 0; cy < dh; cy++)
- {
- int testY = offsY + lineOffsY + cy;
-
- if (testY >= height)
- {
- break;
- }
-
- if (testY < 0)
- {
- testY = 0;
- }
-
- int italicOffset = 0;
-
- if (isItalic)
- {
- italicOffset = (int)((dh - cy) / ITALIC_FONT_KOEFFICIENT);
- }
-
- for (int cx = 0; cx < dw; cx++)
- {
- int testX = cx + w + offsX + italicOffset;
-
- if (testX >= width)
- {
- break;
- }
-
- int block = testY * width + testX;
-
- if (pData[block] == solidColor)
- {
- pData[block] = charcolor;
- }
- }
- }
- }
-
- if (isBlackBorder && !isBlackPixel)
- {
- int minXOk = w + offsX > 0 ? -1 : 0;
- int minYOk = offsY + lineOffsY > 0 ? -1 : 0;
- int maxXOk = w + offsX + dw < width ? 1 : 0;
- int maxYOk = offsY + lineOffsY + dh < height ? 1 : 0;
- maxXOk += dw;
- maxYOk += dh;
-
- for (int cy = minYOk; cy < maxYOk; cy++)
- {
- int testY = offsY + lineOffsY + cy;
-
- if (testY < 0)
- {
- testY = 0;
- }
-
- if (testY >= height)
- {
- break;
- }
-
- int italicOffset = 0;
-
- if (isItalic && cy >= 0 && cy < dh)
- {
- italicOffset = (int)((dh - cy) / ITALIC_FONT_KOEFFICIENT);
- }
-
- for (int cx = minXOk; cx < maxXOk; cx++)
- {
- int testX = cx + w + offsX + italicOffset;
-
- if (testX >= width)
- {
- break;
- }
-
- int block = testY * width + testX;
-
- if (pData[block] == 0 && pData[block] != blackColor)
- {
- int startX = cx > 0 ? -1 : 0;
- int startY = cy > 0 ? -1 : 0;
- int endX = cx < dw - 1 ? 2 : 1;
- int endY = cy < dh - 1 ? 2 : 1;
-
- if (endX == 2 && testX + 1 >= width)
- {
- endX--;
- }
-
- bool passed = false;
-
- for (int x = startX; x < endX; x++)
- {
- int nowX = testX + x;
-
- for (int y = startY; y < endY; y++)
- {
- int testBlock = (testY + y) * width + nowX;
-
- if (testBlock < 0)
- {
- continue;
- }
-
- if (
- testBlock < pData.Length
- && pData[testBlock] != 0
- && pData[testBlock] != blackColor
- )
- {
- pData[block] = blackColor;
- passed = true;
-
- break;
- }
- }
-
- if (passed)
- {
- break;
- }
- }
- }
- }
- }
- }
-
- w += dw + offsX + (isSolid ? 1 : 0);
- }
- else if (si == ' ')
- {
- w += UNICODE_SPACE_WIDTH;
-
- if (IsUsingHTML)
- {
- isUnderline = (dataPtr.Flags & UOFONT_UNDERLINE) != 0;
-
- if (dataPtr.Color != 0xFFFFFFFF)
- {
- charcolor = HuesHelper.RgbaToArgb(dataPtr.Color);
-
- isBlackPixel =
- ((charcolor >> 0) & 0xFF) <= 8
- && ((charcolor >> 8) & 0xFF) <= 8
- && ((charcolor >> 16) & 0xFF) <= 8;
- }
- }
- }
-
- if (isUnderline)
- {
- int minXOk = tmpW + offsX > 0 ? -1 : 0;
- int maxXOk = w + offsX + dw < width ? 1 : 0;
- byte* aData = (byte*)((IntPtr)table + (int)table[(byte)'a']);
- int testY = lineOffsY + (sbyte)aData[1] + (sbyte)aData[3];
-
- if (testY >= height)
- {
- break;
- }
-
- if (testY < 0)
- {
- testY = 0;
- }
-
- for (int cx = minXOk; cx < dw + maxXOk; cx++)
- {
- int testX = cx + tmpW + offsX + (isSolid ? 1 : 0);
-
- if (testX >= width)
- {
- break;
- }
-
- int block = testY * width + testX;
- pData[block] = charcolor;
- }
- }
- }
-
- lineOffsY += ptr.MaxHeight;
- ptr = ptr.Next;
- info.Data.Clear();
- info = null;
- }
-
- if (
- IsUsingHTML
- && _htmlStatus.IsHtmlBackgroundColored
- && _htmlStatus.BackgroundColor != 0
- )
- {
- _htmlStatus.BackgroundColor |= 0xFF;
-
- uint hue = HuesHelper.RgbaToArgb(_htmlStatus.BackgroundColor);
-
- for (int y = 0; y < height; y++)
- {
- int yPos = y * width;
-
- for (int x = 0; x < width; x++)
- {
- ref uint p = ref pData[yPos + x];
-
- if (p == 0)
- {
- p = hue;
- }
- }
- }
- }
-
- FontInfo fi = new FontInfo();
-
- fi.LineCount = linesCount;
- fi.Width = width;
- fi.Height = height;
- fi.Data = pData;
- fi.Links = links;
- return fi;
- }
- finally
- {
- //System.Buffers.ArrayPool.Shared.Return(pData, true);
- }
- }
-
- private unsafe MultilinesFontInfo GetInfoHTML(
- byte font,
- string str,
- int len,
- TEXT_ALIGN_TYPE align,
- ushort flags,
- int width
- )
- {
- if (len <= 0)
- {
- return null;
- }
-
- HTMLChar* htmlData = stackalloc HTMLChar[len];
-
- GetHTMLData(htmlData, font, str.AsSpan(), ref len, align, flags);
-
- if (len <= 0)
- {
- return null;
- }
-
- MultilinesFontInfo info = new MultilinesFontInfo();
- info.Reset();
- info.Align = align;
- MultilinesFontInfo ptr = info;
- int indentionOffset = 0;
- ptr.IndentionOffset = indentionOffset;
- int charCount = 0;
- int lastSpace = 0;
- int readWidth = 0;
- bool isFixed = (flags & UOFONT_FIXED) != 0;
- bool isCropped = (flags & UOFONT_CROPPED) != 0;
-
- if (len != 0)
- {
- ptr.Align = htmlData[0].Align;
- }
-
- for (int i = 0; i < len; i++)
- {
- char si = htmlData[i].Char;
-
- uint* table = (uint*)_unicodeFontAddress[htmlData[i].Font];
-
- if (si == 0x000D || si == '\n')
- {
- if (si == 0x000D || isFixed || isCropped)
- {
- si = (char)0;
- }
- else
- {
- si = '\n';
- }
- }
-
- if ((table[si] == 0 || table[si] == 0xFFFFFFFF) && si != ' ' && si != '\n')
- {
- continue;
- }
-
- byte* data = (byte*)((IntPtr)table + (int)table[si]);
-
- if (si == ' ')
- {
- lastSpace = i;
- ptr.Width += readWidth;
- readWidth = 0;
- ptr.CharCount += charCount;
- charCount = 0;
- }
-
- int solidWidth = htmlData[i].Flags & UOFONT_SOLID;
-
- if (
- ptr.Width + readWidth + (sbyte)data[0] + (sbyte)data[2] + solidWidth > width
- || si == '\n'
- )
- {
- if (lastSpace == ptr.CharStart && lastSpace == 0 && si != '\n')
- {
- ptr.CharStart = 1;
- }
-
- if (si == '\n')
- {
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
- lastSpace = i;
-
- if (ptr.Width <= 0)
- {
- ptr.Width = 1;
- }
-
- ptr.MaxHeight = MAX_HTML_TEXT_HEIGHT;
- ptr.Data.Length = ptr.CharCount;
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
-
- ptr.Align = htmlData[i].Align;
-
- ptr.CharStart = i + 1;
- readWidth = 0;
- charCount = 0;
- indentionOffset = 0;
- ptr.IndentionOffset = indentionOffset;
-
- continue;
- }
-
- if (lastSpace + 1 == ptr.CharStart && !isFixed && !isCropped)
- {
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
-
- if (ptr.Width <= 0)
- {
- ptr.Width = 1;
- }
-
- ptr.MaxHeight = MAX_HTML_TEXT_HEIGHT;
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
-
- ptr.Align = htmlData[i].Align;
-
- ptr.CharStart = i;
- lastSpace = i - 1;
- charCount = 0;
-
- if (
- ptr.Align == TEXT_ALIGN_TYPE.TS_LEFT
- && (htmlData[i].Flags & UOFONT_INDENTION) != 0
- )
- {
- indentionOffset = 14;
- }
-
- ptr.IndentionOffset = indentionOffset;
- readWidth = indentionOffset;
- }
- else
- {
- if (isFixed)
- {
- MultilinesFontData mfd1 = new MultilinesFontData(
- htmlData[i].Color,
- htmlData[i].Flags,
- htmlData[i].Font,
- si,
- htmlData[i].LinkID
- );
-
- ptr.Data.Add(mfd1);
- readWidth += (sbyte)data[0] + (sbyte)data[2] + 1;
- ptr.MaxHeight = MAX_HTML_TEXT_HEIGHT;
- charCount++;
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
- }
-
- i = lastSpace + 1;
-
- if (i >= len)
- {
- break;
- }
-
- si = htmlData[i].Char;
-
- solidWidth = htmlData[i].Flags & UOFONT_SOLID;
-
- if (ptr.Width <= 0)
- {
- ptr.Width = 1;
- }
-
- ptr.MaxHeight = MAX_HTML_TEXT_HEIGHT;
- ptr.Data.Length = ptr.CharCount;
- charCount = 0;
-
- if (isFixed || isCropped)
- {
- break;
- }
-
- MultilinesFontInfo newptr = new MultilinesFontInfo();
- newptr.Reset();
- ptr.Next = newptr;
- ptr = newptr;
-
- ptr.Align = htmlData[i].Align;
-
- ptr.CharStart = i;
-
- if (
- ptr.Align == TEXT_ALIGN_TYPE.TS_LEFT
- && (htmlData[i].Flags & UOFONT_INDENTION) != 0
- )
- {
- indentionOffset = 14;
- }
-
- ptr.IndentionOffset = indentionOffset;
- readWidth = indentionOffset;
- }
- }
-
- MultilinesFontData mfd = new MultilinesFontData(
- htmlData[i].Color,
- htmlData[i].Flags,
- htmlData[i].Font,
- si,
- htmlData[i].LinkID
- );
-
- ptr.Data.Add(mfd);
-
- if (si == ' ')
- {
- readWidth += UNICODE_SPACE_WIDTH;
- }
- else
- {
- readWidth += (sbyte)data[0] + (sbyte)data[2] + 1 + solidWidth;
- }
-
- charCount++;
- }
-
- ptr.Width += readWidth;
- ptr.CharCount += charCount;
- ptr.MaxHeight = MAX_HTML_TEXT_HEIGHT;
-
- return info;
- }
-
- private unsafe void GetHTMLData(
- HTMLChar* data,
- byte font,
- ReadOnlySpan str,
- ref int len,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- int newlen = 0;
-
- HTMLDataInfo info = new HTMLDataInfo
- {
- Tag = HTML_TAG_TYPE.HTT_NONE,
- Align = align,
- Flags = flags,
- Font = font,
- Color = _htmlStatus.Color,
- Link = 0
- };
-
- var stack = new FastList();
- stack.Add(info);
- HTMLDataInfo currentInfo = info;
-
- for (int i = 0; i < len; i++)
- {
- char si = str[i];
-
- if (si == '<')
- {
- bool endTag = false;
-
- HTMLDataInfo newInfo = new HTMLDataInfo
- {
- Tag = HTML_TAG_TYPE.HTT_NONE,
- Align = TEXT_ALIGN_TYPE.TS_LEFT,
- Flags = 0,
- Font = 0xFF,
- Color = 0,
- Link = 0
- };
-
- HTML_TAG_TYPE tag = ParseHTMLTag(str, len, ref i, ref endTag, ref newInfo);
-
- if (tag == HTML_TAG_TYPE.HTT_NONE)
- {
- continue;
- }
-
- if (!endTag)
- {
- if (newInfo.Font == 0xFF)
- {
- newInfo.Font = stack[stack.Length - 1].Font;
- }
-
- if (tag != HTML_TAG_TYPE.HTT_BODY)
- {
- stack.Add(newInfo);
- }
- else
- {
- stack.Clear();
- newlen = 0;
-
- if (newInfo.Color != 0)
- {
- info.Color = newInfo.Color;
- }
-
- stack.Add(info);
- }
- }
- else if (stack.Length > 1)
- {
- //int index = -1;
-
- for (var j = stack.Length - 1; j >= 1; j--)
- {
- if (stack[j].Tag == tag)
- {
- stack.RemoveAt(j); // MAYBE ERROR?
-
- break;
- }
- }
- }
-
- GetCurrentHTMLInfo(ref stack, ref currentInfo);
-
- switch (tag)
- {
- case HTML_TAG_TYPE.HTT_LEFT:
- case HTML_TAG_TYPE.HTT_CENTER:
- case HTML_TAG_TYPE.HTT_RIGHT:
-
- if (newlen != 0)
- {
- endTag = true;
- }
-
- goto case HTML_TAG_TYPE.HTT_P;
-
- case HTML_TAG_TYPE.HTT_P:
-
- if (endTag)
- {
- si = '\n';
- }
- else
- {
- si = (char)0;
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_BODYBGCOLOR:
- case HTML_TAG_TYPE.HTT_BR:
- case HTML_TAG_TYPE.HTT_BQ:
- si = '\n';
-
- break;
-
- default:
- si = (char)0;
-
- break;
- }
- }
-
- if (si != 0)
- {
- ref HTMLChar c = ref data[newlen];
-
- c.Char = si;
- c.Font = currentInfo.Font;
- c.Align = currentInfo.Align;
- c.Flags = currentInfo.Flags;
- c.Color = currentInfo.Color;
- c.LinkID = currentInfo.Link;
-
- ++newlen;
- }
- }
-
- len = newlen;
- }
-
- private void GetCurrentHTMLInfo(ref FastList list, ref HTMLDataInfo info)
- {
- info.Tag = HTML_TAG_TYPE.HTT_NONE;
- info.Align = TEXT_ALIGN_TYPE.TS_LEFT;
- info.Flags = 0;
- info.Font = 0xFF;
- info.Color = 0;
- info.Link = 0;
-
- for (int i = 0; i < list.Length; i++)
- {
- ref var current = ref list.Buffer[i];
-
- switch (current.Tag)
- {
- case HTML_TAG_TYPE.HTT_NONE:
- info = current;
-
- break;
-
- case HTML_TAG_TYPE.HTT_B:
- case HTML_TAG_TYPE.HTT_I:
- case HTML_TAG_TYPE.HTT_U:
- case HTML_TAG_TYPE.HTT_P:
- info.Flags |= current.Flags;
- info.Align = current.Align;
-
- break;
-
- case HTML_TAG_TYPE.HTT_A:
- info.Flags |= current.Flags;
- info.Color = current.Color;
- info.Link = current.Link;
-
- break;
-
- case HTML_TAG_TYPE.HTT_BIG:
- case HTML_TAG_TYPE.HTT_SMALL:
-
- if (
- current.Font != 0xFF && _unicodeFontAddress[current.Font] != IntPtr.Zero
- )
- {
- info.Font = current.Font;
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_BASEFONT:
-
- if (
- current.Font != 0xFF && _unicodeFontAddress[current.Font] != IntPtr.Zero
- )
- {
- info.Font = current.Font;
- }
-
- if (current.Color != 0)
- {
- info.Color = current.Color;
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_H1:
- case HTML_TAG_TYPE.HTT_H2:
- case HTML_TAG_TYPE.HTT_H4:
- case HTML_TAG_TYPE.HTT_H5:
- info.Flags |= current.Flags;
- goto case HTML_TAG_TYPE.HTT_H3;
-
- case HTML_TAG_TYPE.HTT_H3:
- case HTML_TAG_TYPE.HTT_H6:
-
- if (
- current.Font != 0xFF && _unicodeFontAddress[current.Font] != IntPtr.Zero
- )
- {
- info.Font = current.Font;
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_BQ:
- info.Color = current.Color;
- info.Flags |= current.Flags;
-
- break;
-
- case HTML_TAG_TYPE.HTT_LEFT:
- case HTML_TAG_TYPE.HTT_CENTER:
- case HTML_TAG_TYPE.HTT_RIGHT:
- info.Align = current.Align;
-
- break;
-
- case HTML_TAG_TYPE.HTT_DIV:
- info.Align = current.Align;
-
- break;
- }
- }
- }
-
- private HTML_TAG_TYPE ParseHTMLTag(
- ReadOnlySpan str,
- int len,
- ref int i,
- ref bool endTag,
- ref HTMLDataInfo info
- )
- {
- HTML_TAG_TYPE tag = HTML_TAG_TYPE.HTT_NONE;
- i++;
-
- if (i < len && str[i] == '/')
- {
- endTag = true;
- i++;
- }
-
- while (i < len && str[i] == ' ')
- {
- i++;
- }
-
- int j = i;
-
- for (; i < len; i++)
- {
- // special case for single <{TAG}/>
- if (str[i] == '/')
- {
- endTag = true;
-
- break;
- }
-
- if (str[i] == ' ' || str[i] == '>')
- {
- break;
- }
- }
-
- if (j != i && i < len)
- {
- int cmdLen = i - j;
-
- int startIndex = j;
-
- j = i;
-
- while (i < len && str[i] != '>')
- {
- i++;
- }
-
- ReadOnlySpan span = str.Slice(startIndex, cmdLen);
-
- if (span.Equals("b".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_B;
- }
- else if (span.Equals("i".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_I;
- }
- else if (span.Equals("a".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_A;
- }
- else if (span.Equals("u".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_U;
- }
- else if (span.Equals("p".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_P;
- }
- else if (span.Equals("big".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_BIG;
- }
- else if (span.Equals("small".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_SMALL;
- }
- else if (span.Equals("body".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_BODY;
- }
- else if (
- span.Equals("basefont".AsSpan(), StringComparison.InvariantCultureIgnoreCase)
- )
- {
- tag = HTML_TAG_TYPE.HTT_BASEFONT;
- }
- else if (span.Equals("h1".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_H1;
- }
- else if (span.Equals("h2".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_H2;
- }
- else if (span.Equals("h3".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_H3;
- }
- else if (span.Equals("h4".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_H4;
- }
- else if (span.Equals("h5".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_H5;
- }
- else if (span.Equals("h6".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_H6;
- }
- else if (span.Equals("br".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_BR;
- }
- else if (span.Equals("bq".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_BQ;
- }
- else if (span.Equals("left".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_LEFT;
- }
- else if (
- span.Equals("center".AsSpan(), StringComparison.InvariantCultureIgnoreCase)
- )
- {
- tag = HTML_TAG_TYPE.HTT_CENTER;
- }
- else if (span.Equals("right".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_RIGHT;
- }
- else if (span.Equals("div".AsSpan(), StringComparison.InvariantCultureIgnoreCase))
- {
- tag = HTML_TAG_TYPE.HTT_DIV;
- }
- else
- {
- if (
- str.IndexOf(
- "bodybgcolor".AsSpan(),
- StringComparison.InvariantCultureIgnoreCase
- ) >= 0
- )
- {
- tag = HTML_TAG_TYPE.HTT_BODYBGCOLOR;
- j = str.IndexOf(
- "bgcolor".AsSpan(),
- StringComparison.InvariantCultureIgnoreCase
- );
- endTag = false;
- }
- else if (
- str.IndexOf(
- "basefont".AsSpan(),
- StringComparison.InvariantCultureIgnoreCase
- ) >= 0
- )
- {
- tag = HTML_TAG_TYPE.HTT_BASEFONT;
- j = str.IndexOf(
- "color".AsSpan(),
- StringComparison.InvariantCultureIgnoreCase
- );
- endTag = false;
- }
- else if (
- str.IndexOf(
- "bodytext".AsSpan(),
- StringComparison.InvariantCultureIgnoreCase
- ) >= 0
- )
- {
- tag = HTML_TAG_TYPE.HTT_BODY;
- j = str.IndexOf(
- "text".AsSpan(),
- StringComparison.InvariantCultureIgnoreCase
- );
- endTag = false;
- }
- else
- {
- Log.Warn($"Unhandled HTML param:\t{str.ToString()}");
- }
- }
-
- if (!endTag)
- {
- GetHTMLInfoFromTag(tag, ref info);
-
- if (i < len && j != i)
- {
- switch (tag)
- {
- case HTML_TAG_TYPE.HTT_BODYBGCOLOR:
- case HTML_TAG_TYPE.HTT_BODY:
- case HTML_TAG_TYPE.HTT_BASEFONT:
- case HTML_TAG_TYPE.HTT_A:
- case HTML_TAG_TYPE.HTT_DIV:
- case HTML_TAG_TYPE.HTT_P:
- cmdLen = i - j;
-
- if (str.Length != 0 && str.Length > j && str.Length >= cmdLen)
- {
- GetHTMLInfoFromContent(ref info, str, j, cmdLen);
- }
-
- break;
- }
- }
- }
- }
-
- return tag;
- }
-
- private unsafe void GetHTMLInfoFromContent(
- ref HTMLDataInfo info,
- ReadOnlySpan content,
- int start,
- int length
- )
- {
- int i = 0;
-
- if (!content.IsEmpty)
- {
- while (i < length && char.IsWhiteSpace(content[i + start]))
- {
- ++i;
- }
- }
- else
- {
- return;
- }
-
- char* bufferCmd = stackalloc char[128];
- char* bufferValue = stackalloc char[512];
-
- for (int cmdLenght = 0; i < length; ++i)
- {
- char c = content[i + start];
-
- bufferCmd[cmdLenght++] = /*char.IsLetter(c) ? char.ToLowerInvariant(c) :*/
- c;
-
- if (c == ' ' || c == '=' || c == '\\')
- {
- ++i;
- bool inside = false;
- int valueLength = 0;
- for (; i < length; ++i)
- {
- c = content[i + start];
-
- if (c == ' ' || c == '\\' || c == '<' || c == '>' || (c == '=' && !inside))
- {
- break;
- }
-
- if (c != '"')
- {
- bufferValue[valueLength++] = /*char.IsLetter(c) ? char.ToLowerInvariant(c) :*/
- c;
- }
- else
- {
- inside = !inside;
- }
- }
-
- if (valueLength != 0)
- {
- switch (info.Tag)
- {
- case HTML_TAG_TYPE.HTT_BODY:
- case HTML_TAG_TYPE.HTT_BODYBGCOLOR:
-
- if (StringHelper.UnsafeCompare(bufferCmd, "text", cmdLenght))
- {
- ReadColorFromTextBuffer(
- bufferValue,
- valueLength,
- ref info.Color
- );
- }
- else if (
- StringHelper.UnsafeCompare(bufferCmd, "bgcolor", cmdLenght)
- )
- {
- if (_htmlStatus.IsHtmlBackgroundColored)
- {
- ReadColorFromTextBuffer(
- bufferValue,
- valueLength,
- ref _htmlStatus.BackgroundColor
- );
- }
- }
- else if (StringHelper.UnsafeCompare(bufferCmd, "link", cmdLenght))
- {
- ReadColorFromTextBuffer(
- bufferValue,
- valueLength,
- ref _htmlStatus.WebLinkColor
- );
- }
- else if (StringHelper.UnsafeCompare(bufferCmd, "vlink", cmdLenght))
- {
- ReadColorFromTextBuffer(
- bufferValue,
- valueLength,
- ref _htmlStatus.VisitedWebLinkColor
- );
- }
- else if (
- StringHelper.UnsafeCompare(bufferCmd, "leftmargin", cmdLenght)
- )
- {
- _htmlStatus.Margins.X = int.Parse(
- new string(bufferValue, 0, valueLength)
- );
- }
- else if (
- StringHelper.UnsafeCompare(bufferCmd, "topmargin", cmdLenght)
- )
- {
- _htmlStatus.Margins.Y = int.Parse(
- new string(bufferValue, 0, valueLength)
- );
- }
- else if (
- StringHelper.UnsafeCompare(bufferCmd, "rightmargin", cmdLenght)
- )
- {
- _htmlStatus.Margins.Width = int.Parse(
- new string(bufferValue, 0, valueLength)
- );
- }
- else if (
- StringHelper.UnsafeCompare(bufferCmd, "bottommargin", cmdLenght)
- )
- {
- _htmlStatus.Margins.Height = int.Parse(
- new string(bufferValue, 0, valueLength)
- );
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_BASEFONT:
-
- if (StringHelper.UnsafeCompare(bufferCmd, "color", cmdLenght))
- {
- ReadColorFromTextBuffer(
- bufferValue,
- valueLength,
- ref info.Color
- );
- }
- else if (StringHelper.UnsafeCompare(bufferCmd, "size", cmdLenght))
- {
- byte font = byte.Parse(new string(bufferValue, 0, valueLength));
-
- if (font == 0 || font == 4)
- {
- info.Font = 1;
- }
- else if (font < 4)
- {
- info.Font = 2;
- }
- else
- {
- info.Font = 0;
- }
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_A:
-
- if (StringHelper.UnsafeCompare(bufferCmd, "href", cmdLenght))
- {
- info.Flags = UOFONT_UNDERLINE;
- info.Color = _htmlStatus.WebLinkColor;
- info.Link = GetWebLinkID(
- bufferValue,
- valueLength,
- ref info.Color
- );
- }
-
- break;
-
- case HTML_TAG_TYPE.HTT_P:
- case HTML_TAG_TYPE.HTT_DIV:
-
- if (StringHelper.UnsafeCompare(bufferCmd, "align", cmdLenght))
- {
- if (
- StringHelper.UnsafeCompare(bufferValue, "left", valueLength)
- )
- {
- info.Align = TEXT_ALIGN_TYPE.TS_LEFT;
- }
- else if (
- StringHelper.UnsafeCompare(
- bufferValue,
- "center",
- valueLength
- )
- )
- {
- info.Align = TEXT_ALIGN_TYPE.TS_CENTER;
- }
- else if (
- StringHelper.UnsafeCompare(
- bufferValue,
- "right",
- valueLength
- )
- )
- {
- info.Align = TEXT_ALIGN_TYPE.TS_RIGHT;
- }
- }
-
- break;
- }
- }
-
- cmdLenght = 0;
- }
- }
- }
-
- private unsafe ushort GetWebLinkID(char* link, int linkLength, ref uint color)
- {
- foreach (KeyValuePair ll in _webLinks)
- {
- if (
- ll.Value.Link.Length == linkLength
- && StringHelper.UnsafeCompare(link, ll.Value.Link, linkLength)
- )
- {
- if (ll.Value.IsVisited)
- {
- color = _htmlStatus.VisitedWebLinkColor;
- }
-
- return ll.Key;
- }
- }
-
- ushort linkID = (ushort)(_webLinks.Count + 1);
-
- if (!_webLinks.TryGetValue(linkID, out WebLink webLink))
- {
- webLink = new WebLink();
- webLink.IsVisited = false;
- webLink.Link = new string(link, 0, linkLength);
-
- _webLinks[linkID] = webLink;
- }
-
- return linkID;
- }
-
- public bool GetWebLink(ushort link, out WebLink result)
- {
- if (!_webLinks.TryGetValue(link, out result))
- {
- return false;
- }
-
- result.IsVisited = true;
-
- return true;
- }
-
- private unsafe void ReadColorFromTextBuffer(char* buffer, int length, ref uint color)
- {
- color = 0x00_00_00_00;
-
- if (length > 0)
- {
- if (buffer[0] == '#')
- {
- if (length > 1)
- {
- int startIndex = buffer[1] == '0' && buffer[2] == 'x' ? 3 : 1;
-
- string temp = new string(buffer, startIndex, length - startIndex);
- uint.TryParse(
- temp,
- NumberStyles.HexNumber,
- CultureInfo.InvariantCulture,
- out var cc
- );
-
- byte* clrbuf = (byte*)&cc;
- color = (uint)(
- (clrbuf[0] << 24) | (clrbuf[1] << 16) | (clrbuf[2] << 8) | 0xFF
- );
- }
- }
- else if (char.IsNumber(buffer[0]))
- {
- color = Convert.ToUInt32(new string(buffer, 0, length), 16);
- }
- else
- {
- if (StringHelper.UnsafeCompare(buffer, "red", length))
- {
- color = 0x0000FFFF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "cyan", length))
- {
- color = 0xFFFF00FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "blue", length))
- {
- color = 0xFF0000FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "darkblue", length))
- {
- color = 0xA00000FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "lightblue", length))
- {
- color = 0xE6D8ADFF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "purple", length))
- {
- color = 0x800080FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "yellow", length))
- {
- color = 0x00FFFFFF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "lime", length))
- {
- color = 0x00FF00FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "magenta", length))
- {
- color = 0xFF00FFFF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "white", length))
- {
- color = 0xFFFEFEFF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "silver", length))
- {
- color = 0xC0C0C0FF;
- }
- else if (
- StringHelper.UnsafeCompare(buffer, "gray", length)
- || StringHelper.UnsafeCompare(buffer, "grey", length)
- )
- {
- color = 0x808080FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "black", length))
- {
- color = 0x010101FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "orange", length))
- {
- color = 0x00A5FFFF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "brown", length))
- {
- color = 0x2A2AA5FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "maroon", length))
- {
- color = 0x000080FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "green", length))
- {
- color = 0x008000FF;
- }
- else if (StringHelper.UnsafeCompare(buffer, "olive", length))
- {
- color = 0x008080FF;
- }
- }
- }
- }
-
- private void GetHTMLInfoFromTag(HTML_TAG_TYPE tag, ref HTMLDataInfo info)
- {
- info.Tag = tag;
- info.Align = TEXT_ALIGN_TYPE.TS_LEFT;
- info.Flags = 0;
- info.Font = 0xFF;
- info.Color = 0;
- info.Link = 0;
-
- switch (tag)
- {
- case HTML_TAG_TYPE.HTT_B:
- info.Flags = UOFONT_SOLID;
-
- break;
-
- case HTML_TAG_TYPE.HTT_I:
- info.Flags = UOFONT_ITALIC;
-
- break;
-
- case HTML_TAG_TYPE.HTT_U:
- info.Flags = UOFONT_UNDERLINE;
-
- break;
-
- case HTML_TAG_TYPE.HTT_P:
- info.Flags = UOFONT_INDENTION;
-
- break;
-
- case HTML_TAG_TYPE.HTT_BIG:
- info.Font = 0;
-
- break;
-
- case HTML_TAG_TYPE.HTT_SMALL:
- info.Font = 2;
-
- break;
-
- case HTML_TAG_TYPE.HTT_H1:
- info.Flags = UOFONT_SOLID | UOFONT_UNDERLINE;
- info.Font = 0;
-
- break;
-
- case HTML_TAG_TYPE.HTT_H2:
- info.Flags = UOFONT_SOLID;
- info.Font = 0;
-
- break;
-
- case HTML_TAG_TYPE.HTT_H3:
- info.Font = 0;
-
- break;
-
- case HTML_TAG_TYPE.HTT_H4:
- info.Flags = UOFONT_SOLID;
- info.Font = 2;
-
- break;
-
- case HTML_TAG_TYPE.HTT_H5:
- info.Flags = UOFONT_ITALIC;
- info.Font = 2;
-
- break;
-
- case HTML_TAG_TYPE.HTT_H6:
- info.Font = 2;
-
- break;
-
- case HTML_TAG_TYPE.HTT_BQ:
- info.Flags = UOFONT_BQ;
- info.Color = 0x008000FF;
-
- break;
-
- case HTML_TAG_TYPE.HTT_LEFT:
- info.Align = TEXT_ALIGN_TYPE.TS_LEFT;
-
- break;
-
- case HTML_TAG_TYPE.HTT_CENTER:
- info.Align = TEXT_ALIGN_TYPE.TS_CENTER;
-
- break;
-
- case HTML_TAG_TYPE.HTT_RIGHT:
- info.Align = TEXT_ALIGN_TYPE.TS_RIGHT;
-
- break;
- }
- }
-
- private int GetHeightUnicode(MultilinesFontInfo info)
- {
- int textHeight = 0;
-
- for (; info != null; info = info.Next)
- {
- if (IsUsingHTML)
- {
- textHeight += MAX_HTML_TEXT_HEIGHT;
- }
- else
- {
- textHeight += info.MaxHeight;
- }
- }
-
- return textHeight;
- }
-
- public int GetHeightUnicode(
- byte font,
- string str,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || string.IsNullOrEmpty(str))
- {
- return 0;
- }
-
- if (width <= 0)
- {
- width = GetWidthUnicode(font, str.AsSpan());
- }
-
- MultilinesFontInfo info = GetInfoUnicode(font, str, str.Length, align, flags, width);
-
- int textHeight = 0;
-
- while (info != null)
- {
- if (IsUsingHTML)
- {
- textHeight += MAX_HTML_TEXT_HEIGHT;
- }
- else
- {
- textHeight += info.MaxHeight;
- }
-
- MultilinesFontInfo ptr = info;
- info = info.Next;
- ptr.Data.Clear();
- ptr = null;
- }
-
- return textHeight;
- }
-
- public unsafe (int, int) GetCaretPosUnicode(
- byte font,
- string str,
- int pos,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- int x = 0;
- int y = 0;
-
- switch (align)
- {
- case TEXT_ALIGN_TYPE.TS_CENTER:
- x = width >> 1;
-
- break;
-
- case TEXT_ALIGN_TYPE.TS_RIGHT:
- x = width;
-
- break;
- }
-
- if (font >= 20 || _unicodeFontAddress[font] == IntPtr.Zero || string.IsNullOrEmpty(str))
- {
- return (x, y);
- }
-
- if (width == 0)
- {
- width = GetWidthUnicode(font, str.AsSpan());
- }
-
- MultilinesFontInfo info = GetInfoUnicode(font, str, str.Length, align, flags, width);
-
- if (info == null)
- {
- return (x, y);
- }
-
- uint* table = (uint*)_unicodeFontAddress[font];
-
- while (info != null)
- {
- switch (info.Align)
- {
- case TEXT_ALIGN_TYPE.TS_CENTER:
- x = (width - info.Width) >> 1;
-
- if (x < 0)
- {
- x = 0;
- }
-
- break;
-
- case TEXT_ALIGN_TYPE.TS_RIGHT:
- x = width;
-
- break;
-
- default:
- x = 0;
-
- break;
- }
-
- int len = info.CharCount;
-
- if (info.CharStart == pos)
- {
- return (x, y);
- }
-
- if (pos <= info.CharStart + len && info.Data.Length >= len)
- {
- for (int i = 0; i < len; i++)
- {
- char ch = info.Data[i].Item;
-
- uint offset = table[ch];
-
- if (ch != '\r' && offset != 0 && offset != 0xFFFFFFFF)
- {
- byte* cptr = (byte*)((IntPtr)table + (int)offset);
- x += (sbyte)cptr[0] + (sbyte)cptr[2] + 1;
- }
- else if (ch == ' ')
- {
- x += UNICODE_SPACE_WIDTH;
- }
-
- if (info.CharStart + i + 1 == pos)
- {
- return (x, y);
- }
- }
- }
- else
- {
- x = width;
- }
-
- if (info.Next != null)
- {
- y += info.MaxHeight;
- }
-
- MultilinesFontInfo ptr = info;
- info = info.Next;
- ptr.Data.Clear();
- ptr = null;
- }
-
- return (x, y);
- }
-
- public (int, int) GetCaretPosASCII(
- byte font,
- string str,
- int pos,
- int width,
- TEXT_ALIGN_TYPE align,
- ushort flags
- )
- {
- int x = 0;
- int y = 0;
-
- switch (align)
- {
- case TEXT_ALIGN_TYPE.TS_CENTER:
- x = width >> 1;
-
- break;
-
- case TEXT_ALIGN_TYPE.TS_RIGHT:
- x = width;
-
- break;
- }
-
- if (font >= FontCount || string.IsNullOrEmpty(str))
- {
- return (x, y);
- }
-
- if (width == 0)
- {
- width = GetWidthASCII(font, str);
- }
-
- MultilinesFontInfo info = GetInfoASCII(font, str, str.Length, align, flags, width);
-
- if (info == null)
- {
- return (x, y);
- }
-
- while (info != null)
- {
- switch (info.Align)
- {
- case TEXT_ALIGN_TYPE.TS_CENTER:
- x = (width - info.Width) >> 1;
-
- if (x < 0)
- {
- x = 0;
- }
-
- break;
-
- case TEXT_ALIGN_TYPE.TS_RIGHT:
- x = width;
-
- break;
-
- default:
- x = 0;
-
- break;
- }
-
- int len = info.CharCount;
-
- if (info.CharStart == pos)
- {
- return (x, y);
- }
-
- if (pos <= info.CharStart + len && info.Data.Length >= len)
- {
- for (int i = 0; i < len; i++)
- {
- x += _fontData[font, GetASCIIIndex(info.Data[i].Item)].Width;
-
- if (info.CharStart + i + 1 == pos)
- {
- return (x, y);
- }
- }
- }
- else
- {
- x = width;
- }
-
- if (info.Next != null)
- {
- y += info.MaxHeight;
- }
-
- MultilinesFontInfo ptr1 = info;
- info = info.Next;
- ptr1.Data.Clear();
- ptr1 = null;
- }
-
- return (x, y);
- }
- }
-
- public enum TEXT_ALIGN_TYPE
- {
- TS_LEFT = 0,
- TS_CENTER,
- TS_RIGHT
- }
-
- public enum HTML_TAG_TYPE
- {
- HTT_NONE = 0,
- HTT_B,
- HTT_I,
- HTT_A,
- HTT_U,
- HTT_P,
- HTT_BIG,
- HTT_SMALL,
- HTT_BODY,
- HTT_BASEFONT,
- HTT_H1,
- HTT_H2,
- HTT_H3,
- HTT_H4,
- HTT_H5,
- HTT_H6,
- HTT_BR,
- HTT_BQ,
- HTT_LEFT,
- HTT_CENTER,
- HTT_RIGHT,
- HTT_DIV,
-
- HTT_BODYBGCOLOR
- }
-
- [StructLayout(LayoutKind.Sequential)]
- public ref struct FontHeader
- {
- public byte Width,
- Height,
- Unknown;
- }
-
- public unsafe struct FontCharacterData
- {
- public FontCharacterData(byte w, byte h, ushort* data)
- {
- Width = w;
- Height = h;
- Data = data;
- }
-
- public byte Width,
- Height;
- public ushort* Data;
- }
-
- public sealed class MultilinesFontInfo
- {
- public TEXT_ALIGN_TYPE Align;
- public int CharCount;
- public int CharStart;
- public FastList Data = new FastList();
- public int IndentionOffset;
- public int MaxHeight;
- public MultilinesFontInfo Next;
- public int Width;
-
- public void Reset()
- {
- Width = 0;
- IndentionOffset = 0;
- MaxHeight = 0;
- CharStart = 0;
- CharCount = 0;
- Align = TEXT_ALIGN_TYPE.TS_LEFT;
- Next = null;
- }
- }
-
- public struct MultilinesFontData
- {
- public MultilinesFontData(uint color, ushort flags, byte font, char item, ushort linkid)
- {
- Color = color;
- Flags = flags;
- Font = font;
- Item = item;
- LinkID = linkid;
- }
-
- public uint Color;
- public ushort Flags;
- public byte Font;
- public char Item;
- public ushort LinkID;
- //public MultilinesFontData Next;
- }
-
- public struct WebLinkRect
- {
- public ushort LinkID;
- public FontsLoader.Margin Bounds;
- }
-
- public class WebLink
- {
- public bool IsVisited;
- public string Link;
- }
-
- public struct HTMLChar
- {
- public char Char;
- public byte Font;
- public TEXT_ALIGN_TYPE Align;
- public ushort Flags;
- public uint Color;
- public ushort LinkID;
- }
-
- public struct HTMLDataInfo
- {
- public HTML_TAG_TYPE Tag;
- public TEXT_ALIGN_TYPE Align;
- public ushort Flags;
- public byte Font;
- public uint Color;
- public ushort Link;
- }
-}
diff --git a/src/ClassicUO.Assets/GumpsLoader.cs b/src/ClassicUO.Assets/GumpsLoader.cs
deleted file mode 100644
index c43f25686..000000000
--- a/src/ClassicUO.Assets/GumpsLoader.cs
+++ /dev/null
@@ -1,257 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class GumpsLoader : UOFileLoader
- {
- private static GumpsLoader _instance;
- private UOFile _file;
-
- public const int MAX_GUMP_DATA_INDEX_COUNT = 0x10000;
-
- private GumpsLoader(int count) { }
-
- public static GumpsLoader Instance =>
- _instance ?? (_instance = new GumpsLoader(MAX_GUMP_DATA_INDEX_COUNT));
-
- public bool UseUOPGumps = false;
-
- public override Task Load()
- {
- return Task.Run(() =>
- {
- string path = UOFileManager.GetUOFilePath("gumpartLegacyMUL.uop");
-
- if (UOFileManager.IsUOPInstallation && File.Exists(path))
- {
- _file = new UOFileUop(path, "build/gumpartlegacymul/{0:D8}.tga", true);
- Entries = new UOFileIndex[
- Math.Max(((UOFileUop)_file).TotalEntriesCount, MAX_GUMP_DATA_INDEX_COUNT)
- ];
- UseUOPGumps = true;
- }
- else
- {
- path = UOFileManager.GetUOFilePath("gumpart.mul");
- string pathidx = UOFileManager.GetUOFilePath("gumpidx.mul");
-
- if (!File.Exists(path))
- {
- path = UOFileManager.GetUOFilePath("Gumpart.mul");
- }
-
- if (!File.Exists(pathidx))
- {
- pathidx = UOFileManager.GetUOFilePath("Gumpidx.mul");
- }
-
- _file = new UOFileMul(path, pathidx, MAX_GUMP_DATA_INDEX_COUNT, 12);
-
- UseUOPGumps = false;
- }
-
- _file.FillEntries(ref Entries);
-
- string pathdef = UOFileManager.GetUOFilePath("gump.def");
-
- if (!File.Exists(pathdef))
- {
- return;
- }
-
- using (DefReader defReader = new DefReader(pathdef, 3))
- {
- while (defReader.Next())
- {
- int ingump = defReader.ReadInt();
-
- if (
- ingump < 0
- || ingump >= MAX_GUMP_DATA_INDEX_COUNT
- || ingump >= Entries.Length
- || Entries[ingump].Length > 0
- )
- {
- continue;
- }
-
- int[] group = defReader.ReadGroup();
-
- if (group == null)
- {
- continue;
- }
-
- for (int i = 0; i < group.Length; i++)
- {
- int checkIndex = group[i];
-
- if (
- checkIndex < 0
- || checkIndex >= MAX_GUMP_DATA_INDEX_COUNT
- || checkIndex >= Entries.Length
- || Entries[checkIndex].Length <= 0
- )
- {
- continue;
- }
-
- Entries[ingump] = Entries[checkIndex];
-
- Entries[ingump].Hue = (ushort)defReader.ReadInt();
-
- break;
- }
- }
- }
- });
- }
-
- public unsafe GumpInfo GetGump(uint index)
- {
- ref UOFileIndex entry = ref GetValidRefEntry((int)index);
-
- if (entry.Width <= 0 && entry.Height <= 0)
- {
- return default;
- }
-
- ushort color = entry.Hue;
-
- _file.SetData(entry.Address, entry.FileSize);
- _file.Seek(entry.Offset);
-
- IntPtr dataStart = _file.PositionAddress;
-
- var pixels = new uint[entry.Width * entry.Height];
-
- int* lookuplist = (int*)dataStart;
-
- int gsize;
-
- for (int y = 0, half_len = entry.Length >> 2; y < entry.Height; y++)
- {
- if (y < entry.Height - 1)
- {
- gsize = lookuplist[y + 1] - lookuplist[y];
- }
- else
- {
- gsize = half_len - lookuplist[y];
- }
-
- GumpBlock* gmul = (GumpBlock*)(dataStart + (lookuplist[y] << 2));
-
- int pos = y * entry.Width;
-
- for (int i = 0; i < gsize; i++)
- {
- uint val = gmul[i].Value;
-
- if (color != 0 && val != 0)
- {
- val = HuesLoader.Instance.ApplyHueRgba5551(gmul[i].Value, color);
- }
-
- if (val != 0)
- {
- //val = 0x8000 | val;
- val = HuesHelper.Color16To32(gmul[i].Value) | 0xFF_00_00_00;
- }
-
- var count = gmul[i].Run;
- pixels.AsSpan().Slice(pos, count).Fill(val);
- pos += count;
- }
- }
-
- return new GumpInfo()
- {
- Pixels = pixels,
- Width = entry.Width,
- Height = entry.Height
- };
- }
-
- //private unsafe void AddPNGSpriteToAtlas(TextureAtlas atlas, uint index, Texture2D texture)
- //{
- // uint[] buffer = null;
-
- // Span pixels = texture.Width * texture.Height <= 1024 ? stackalloc uint[1024] : (buffer = System.Buffers.ArrayPool.Shared.Rent(texture.Width * texture.Height));
-
- // Color[] pixelColors = new Color[texture.Width * texture.Height];
- // texture.GetData(pixelColors);
-
- // for (int i = 0; i < pixelColors.Length; i++)
- // {
- // pixels[i] = pixelColors[i].PackedValue;
- // }
-
- // try
- // {
- // ref var spriteInfo = ref _spriteInfos[index];
-
- // spriteInfo.Texture = atlas.AddSprite(pixels, texture.Width, texture.Height, out spriteInfo.UV);
- // _picker.Set(index, texture.Width, texture.Height, pixels);
- // }
- // finally
- // {
- // if (buffer != null)
- // {
- // System.Buffers.ArrayPool.Shared.Return(buffer, true);
- // }
- // }
- //}
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- private ref struct GumpBlock
- {
- public readonly ushort Value;
- public readonly ushort Run;
- }
- }
-
- public ref struct GumpInfo
- {
- public Span Pixels;
- public int Width;
- public int Height;
- }
-}
diff --git a/src/ClassicUO.Assets/HuesLoader.cs b/src/ClassicUO.Assets/HuesLoader.cs
deleted file mode 100644
index 84891cdeb..000000000
--- a/src/ClassicUO.Assets/HuesLoader.cs
+++ /dev/null
@@ -1,238 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using Microsoft.Xna.Framework;
-using System;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class HuesLoader : UOFileLoader
- {
- private static HuesLoader _instance;
-
- private HuesLoader()
- {
- }
-
- public static HuesLoader Instance => _instance ?? (_instance = new HuesLoader());
-
- public HuesGroup[] HuesRange { get; private set; }
-
- public int HuesCount { get; private set; }
-
- public ushort[] RadarCol { get; private set; }
-
- public override unsafe Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string path = UOFileManager.GetUOFilePath("hues.mul");
-
- FileSystemHelper.EnsureFileExists(path);
-
- UOFileMul file = new UOFileMul(path);
- int groupSize = Marshal.SizeOf();
- int entrycount = (int) file.Length / groupSize;
- HuesCount = entrycount * 8;
- HuesRange = new HuesGroup[entrycount];
- ulong addr = (ulong) file.StartAddress;
-
- for (int i = 0; i < entrycount; i++)
- {
- HuesRange[i] = Marshal.PtrToStructure((IntPtr)(addr + (ulong) (i * groupSize)));
- }
-
- path = UOFileManager.GetUOFilePath("radarcol.mul");
-
- FileSystemHelper.EnsureFileExists(path);
-
- UOFileMul radarcol = new UOFileMul(path);
- RadarCol = new ushort[(int)(radarcol.Length >> 1)];
-
- fixed (ushort* ptr = RadarCol)
- {
- Unsafe.CopyBlockUnaligned((void*)(byte*)ptr, radarcol.PositionAddress.ToPointer(), (uint)radarcol.Length);
- }
-
- file.Dispose();
- radarcol.Dispose();
- }
- );
- }
-
- public void CreateShaderColors(uint[] buffer)
- {
- int len = HuesRange.Length;
-
- int idx = 0;
-
- for (int r = 0; r < len; r++)
- {
- for (int y = 0; y < 8; y++)
- {
- for (int x = 0; x < 32; x++)
- {
- buffer[idx++] = HuesHelper.Color16To32(HuesRange[r].Entries[y].ColorTable[x]) | 0xFF_00_00_00;
-
- if (idx >= buffer.Length)
- {
- return;
- }
- }
- }
- }
- }
-
- /* Look up the hue and return the color for the given index. Index must be between 0 and 31.
- * The returned color is a 16 bit color in R5B5G5A1 format. */
- public ushort GetHueColorRgba5551(ushort index, ushort hue)
- {
- if (hue != 0 && hue < HuesCount)
- {
- hue -= 1;
- int g = hue >> 3;
- int e = hue % 8;
-
- return (ushort)(0x8000 | HuesRange[g].Entries[e].ColorTable[index]);
- }
-
- return 0x8000;
- }
-
- /* Look up the hue and return the color for the given index. Index must be between 0 and 31.
- * The returned color is a 32 bit color in R8G8B8A8 format. */
- public uint GetHueColorRgba8888(ushort index, ushort hue)
- {
- return HuesHelper.Color16To32(GetHueColorRgba5551(index, hue));
- }
-
- /* Apply the hue to the given gray color, returning a 16 bit color. */
- public ushort ApplyHueRgba5551(ushort gray, ushort hue)
- {
- return GetHueColorRgba5551((ushort)((gray >> 10) & 0x1F), hue);
- }
-
- /* Apply the hue to the given gray color, returning a 32 bit color. */
- public uint ApplyHueRgba8888(ushort gray, ushort hue)
- {
- return HuesHelper.Color16To32(ApplyHueRgba5551(gray, hue));
- }
-
- public uint GetPartialHueColor(ushort color, ushort hue)
- {
- uint cl = HuesHelper.Color16To32(color);
- byte R = (byte)(cl & 0xFF);
- byte G = (byte)((cl >> 8) & 0xFF);
- byte B = (byte)((cl >> 16) & 0xFF);
-
- if (R != G || R != B)
- {
- /* Not gray. Don't apply hue. */
- return HuesHelper.Color16To32(color);
- }
-
- if (hue == 0 || hue >= HuesCount)
- {
- /* Invalid hue. */
- return HuesHelper.Color16To32(color);
- }
-
- return ApplyHueRgba8888(color, hue);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ushort GetRadarColorData(int c)
- {
- if (c >= 0 && c < RadarCol.Length)
- {
- return RadarCol[c];
- }
-
- return 0;
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct HuesBlock
- {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public ushort[] ColorTable;
- public ushort TableStart;
- public ushort TableEnd;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
- public char[] Name;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct HuesGroup
- {
- public uint Header;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public HuesBlock[] Entries;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public readonly struct VerdataHuesBlock
- {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public readonly ushort[] ColorTable;
- public readonly ushort TableStart;
- public readonly ushort TableEnd;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
- public readonly char[] Name;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public readonly ushort[] Unk;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public readonly struct VerdataHuesGroup
- {
- public readonly uint Header;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public readonly VerdataHuesBlock[] Entries;
- }
-
- public struct FloatHues
- {
- //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
- public float[] Palette;
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/LightsLoader.cs b/src/ClassicUO.Assets/LightsLoader.cs
deleted file mode 100644
index a0bb195e3..000000000
--- a/src/ClassicUO.Assets/LightsLoader.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class LightsLoader : UOFileLoader
- {
- private static LightsLoader _instance;
- private UOFileMul _file;
-
- public const int MAX_LIGHTS_DATA_INDEX_COUNT = 100;
-
- private LightsLoader(int count) { }
-
- public static LightsLoader Instance =>
- _instance ?? (_instance = new LightsLoader(MAX_LIGHTS_DATA_INDEX_COUNT));
-
- public UOFileMul File => _file;
-
- public override Task Load()
- {
- return Task.Run(() =>
- {
- string path = UOFileManager.GetUOFilePath("light.mul");
- string pathidx = UOFileManager.GetUOFilePath("lightidx.mul");
-
- FileSystemHelper.EnsureFileExists(path);
- FileSystemHelper.EnsureFileExists(pathidx);
-
- _file = new UOFileMul(path, pathidx, MAX_LIGHTS_DATA_INDEX_COUNT);
- _file.FillEntries(ref Entries);
- });
- }
-
- public LightInfo GetLight(uint idx)
- {
- ref var entry = ref GetValidRefEntry((int)idx);
-
- if (entry.Width == 0 && entry.Height == 0)
- {
- return default;
- }
-
- var buffer = new uint[entry.Width * entry.Height];
- _file.SetData(entry.Address, entry.FileSize);
- _file.Seek(entry.Offset);
-
- for (int i = 0; i < entry.Height; i++)
- {
- int pos = i * entry.Width;
-
- for (int j = 0; j < entry.Width; j++)
- {
- ushort val = _file.ReadByte();
- // Light can be from -31 to 31. When they are below 0 they are bit inverted
- if (val > 0x1F)
- {
- val = (ushort)(~val & 0x1F);
- }
- uint rgb24 = (uint)((val << 19) | (val << 11) | (val << 3));
-
- if (val != 0)
- {
- buffer[pos + j] = rgb24 | 0xFF_00_00_00;
- }
- }
- }
-
- return new LightInfo()
- {
- Pixels = buffer,
- Width = entry.Width,
- Height = entry.Height
- };
- }
- }
-
- public ref struct LightInfo
- {
- public Span Pixels;
- public int Width;
- public int Height;
- }
-}
diff --git a/src/ClassicUO.Assets/MapLoader.cs b/src/ClassicUO.Assets/MapLoader.cs
deleted file mode 100644
index f8388e5b0..000000000
--- a/src/ClassicUO.Assets/MapLoader.cs
+++ /dev/null
@@ -1,686 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using System;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class MapLoader : UOFileLoader
- {
- private static MapLoader _instance;
- private UOFileMul[] _mapDif;
- private UOFileMul[] _mapDifl;
- private UOFileMul[] _staDif;
- private UOFileMul[] _staDifi;
- private UOFileMul[] _staDifl;
-
- // cannot be a const, due to UOLive implementation
- public static int MAPS_COUNT = 6;
-
- protected MapLoader()
- {
- }
-
- public static MapLoader Instance
- {
- get => _instance ?? (_instance = new MapLoader());
- set
- {
- _instance?.Dispose();
- _instance = value;
- }
- }
-
- public static string MapsLayouts { get; set; }
-
- public IndexMap[][] BlockData { get; private set; }
-
- public int[,] MapBlocksSize { get; private set; }
-
- // ReSharper disable RedundantExplicitArraySize
- public int[,] MapsDefaultSize { get; protected set; } = new int[6, 2]
- // ReSharper restore RedundantExplicitArraySize
- {
- {
- 7168, 4096
- },
- {
- 7168, 4096
- },
- {
- 2304, 1600
- },
- {
- 2560, 2048
- },
- {
- 1448, 1448
- },
- {
- 1280, 4096
- }
- };
-
- public int PatchesCount { get; private set; }
- public int[] MapPatchCount { get; private set; }
- public int[] StaticPatchCount { get; private set; }
-
- protected UOFileMul[] _filesIdxStatics;
- protected UOFile[] _filesMap;
- protected UOFileMul[] _filesStatics;
-
- protected static UOFile GetMapFile(int map)
- {
- return map < Instance._filesMap.Length ? Instance._filesMap[map] : null;
- }
-
- protected void Initialize()
- {
- _filesMap = new UOFile[MAPS_COUNT];
- _filesStatics = new UOFileMul[MAPS_COUNT];
- _filesIdxStatics = new UOFileMul[MAPS_COUNT];
-
- MapPatchCount = new int[MAPS_COUNT];
- StaticPatchCount = new int[MAPS_COUNT];
- MapBlocksSize = new int[MAPS_COUNT, 2];
-
- BlockData = new IndexMap[MAPS_COUNT][];
-
- _mapDif = new UOFileMul[MAPS_COUNT];
- _mapDifl = new UOFileMul[MAPS_COUNT];
- _staDif = new UOFileMul[MAPS_COUNT];
- _staDifi = new UOFileMul[MAPS_COUNT];
- _staDifl = new UOFileMul[MAPS_COUNT];
- }
-
- public override unsafe Task Load()
- {
- return Task.Run
- (
- () =>
- {
- bool foundOneMap = false;
-
- if (!string.IsNullOrEmpty(MapsLayouts))
- {
- string[] values = MapsLayouts.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
-
- MAPS_COUNT = values.Length;
- MapsDefaultSize = new int[values.Length, 2];
-
- Log.Trace($"default maps size overraided. [count: {MAPS_COUNT}]");
-
-
- int index = 0;
-
- char[] splitchar = new char[1] { ',' };
-
- foreach (string s in values)
- {
- string[] v = s.Split(splitchar, StringSplitOptions.RemoveEmptyEntries);
-
- if (v.Length >= 2 && int.TryParse(v[0], out int width) && int.TryParse(v[1], out int height))
- {
- MapsDefaultSize[index, 0] = width;
- MapsDefaultSize[index, 1] = height;
-
- Log.Trace($"overraided map size: {width},{height} [index: {index}]");
- }
- else
- {
- Log.Error($"Error parsing 'width,height' values: '{s}'");
- }
-
- ++index;
- }
- }
-
-
- Initialize();
-
- for (var i = 0; i < MAPS_COUNT; ++i)
- {
- string path = UOFileManager.GetUOFilePath($"map{i}LegacyMUL.uop");
-
- if (UOFileManager.IsUOPInstallation && File.Exists(path))
- {
- _filesMap[i] = new UOFileUop(path, $"build/map{i}legacymul/{{0:D8}}.dat");
- foundOneMap = true;
- }
- else
- {
- path = UOFileManager.GetUOFilePath($"map{i}.mul");
-
- if (File.Exists(path))
- {
- _filesMap[i] = new UOFileMul(path);
-
- foundOneMap = true;
- }
-
- path = UOFileManager.GetUOFilePath($"mapdifl{i}.mul");
-
- if (File.Exists(path))
- {
- _mapDifl[i] = new UOFileMul(path);
- _mapDif[i] = new UOFileMul(UOFileManager.GetUOFilePath($"mapdif{i}.mul"));
- _staDifl[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadifl{i}.mul"));
- _staDifi[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadifi{i}.mul"));
- _staDif[i] = new UOFileMul(UOFileManager.GetUOFilePath($"stadif{i}.mul"));
- }
- }
-
- path = UOFileManager.GetUOFilePath($"statics{i}.mul");
-
- if (File.Exists(path))
- {
- _filesStatics[i] = new UOFileMul(path);
- }
-
- path = UOFileManager.GetUOFilePath($"staidx{i}.mul");
-
- if (File.Exists(path))
- {
- _filesIdxStatics[i] = new UOFileMul(path);
- }
- }
-
- if (!foundOneMap)
- {
- throw new FileNotFoundException("No maps found.");
- }
-
-
- int mapblocksize = sizeof(MapBlock);
-
- if (_filesMap[0].Length / mapblocksize == 393216 || UOFileManager.Version < ClientVersion.CV_4011D)
- {
- MapsDefaultSize[0, 0] = MapsDefaultSize[1, 0] = 6144;
- }
-
- // This is an hack to patch correctly all maps when you have to fake map1
- if (_filesMap[1] == null || _filesMap[1].StartAddress == IntPtr.Zero)
- {
- _filesMap[1] = _filesMap[0];
- _filesStatics[1] = _filesStatics[0];
- _filesIdxStatics[1] = _filesIdxStatics[0];
- }
-
- var res = Parallel.For(0, MAPS_COUNT, i =>
- {
- MapBlocksSize[i, 0] = MapsDefaultSize[i, 0] >> 3;
- MapBlocksSize[i, 1] = MapsDefaultSize[i, 1] >> 3;
- LoadMap(i);
- });
- }
- );
- }
-
- public unsafe void LoadMap(int i)
- {
- if (i < 0 || i + 1 > MAPS_COUNT || _filesMap[i] == null)
- {
- i = 0;
- }
-
- if (BlockData[i] != null || _filesMap[i] == null)
- {
- return;
- }
-
- int mapblocksize = sizeof(MapBlock);
- int staticidxblocksize = sizeof(StaidxBlock);
- int staticblocksize = sizeof(StaticsBlock);
- int width = MapBlocksSize[i, 0];
- int height = MapBlocksSize[i, 1];
- int maxblockcount = width * height;
- BlockData[i] = new IndexMap[maxblockcount];
- UOFile file = _filesMap[i];
- UOFile fileidx = _filesIdxStatics[i];
- UOFile staticfile = _filesStatics[i];
-
- if (fileidx == null && i == 1)
- {
- fileidx = _filesIdxStatics[0];
- }
-
- if (staticfile == null && i == 1)
- {
- staticfile = _filesStatics[0];
- }
-
- ulong staticidxaddress = (ulong) fileidx.StartAddress;
- ulong endstaticidxaddress = staticidxaddress + (ulong) fileidx.Length;
- ulong staticaddress = (ulong) staticfile.StartAddress;
- ulong endstaticaddress = staticaddress + (ulong) staticfile.Length;
- ulong mapddress = (ulong) file.StartAddress;
- ulong endmapaddress = mapddress + (ulong) file.Length;
- ulong uopoffset = 0;
- int fileNumber = -1;
- bool isuop = file is UOFileUop;
-
- for (int block = 0; block < maxblockcount; block++)
- {
- ulong realmapaddress = 0, realstaticaddress = 0;
- uint realstaticcount = 0;
- int blocknum = block;
-
- if (isuop)
- {
- blocknum &= 4095;
- int shifted = block >> 12;
-
- if (fileNumber != shifted)
- {
- fileNumber = shifted;
- var uop = file as UOFileUop;
-
- if (shifted < uop.TotalEntriesCount)
- {
- var hash = UOFileUop.CreateHash(string.Format(uop.Pattern, shifted));
-
- if (uop.TryGetUOPData(hash, out var dataIndex))
- {
- uopoffset = (ulong)dataIndex.Offset;
- }
- }
- }
- }
-
- ulong address = mapddress + uopoffset + (ulong) (blocknum * mapblocksize);
-
- if (address < endmapaddress)
- {
- realmapaddress = address;
- }
-
- ulong stidxaddress = staticidxaddress + (ulong) (block * staticidxblocksize);
- StaidxBlock* bb = (StaidxBlock*) stidxaddress;
-
- if (stidxaddress < endstaticidxaddress && bb->Size > 0 && bb->Position != 0xFFFFFFFF)
- {
- ulong address1 = staticaddress + bb->Position;
-
- if (address1 < endstaticaddress)
- {
- realstaticaddress = address1;
- realstaticcount = (uint) (bb->Size / staticblocksize);
-
- if (realstaticcount > 1024)
- {
- realstaticcount = 1024;
- }
- }
- }
-
- ref IndexMap data = ref BlockData[i][block];
- data.MapAddress = realmapaddress;
- data.StaticAddress = realstaticaddress;
- data.StaticCount = realstaticcount;
- data.OriginalMapAddress = realmapaddress;
- data.OriginalStaticAddress = realstaticaddress;
- data.OriginalStaticCount = realstaticcount;
- }
-
- if (isuop)
- {
- // TODO: UOLive needs hashes! we need to find out a better solution, but keep 'em for the moment
- //((UOFileUop)file)?.ClearHashes();
- }
- }
-
- public void PatchMapBlock(ulong block, ulong address)
- {
- int w = MapBlocksSize[0, 0];
- int h = MapBlocksSize[0, 1];
-
- int maxBlockCount = w * h;
-
- if (maxBlockCount < 1)
- {
- return;
- }
-
- BlockData[0][block].OriginalMapAddress = address;
- BlockData[0][block].MapAddress = address;
- }
-
-
- public unsafe void PatchStaticBlock(ulong block, ulong address, uint count)
- {
- int w = MapBlocksSize[0, 0];
- int h = MapBlocksSize[0, 1];
-
- int maxBlockCount = w * h;
-
- if (maxBlockCount < 1)
- {
- return;
- }
-
- BlockData[0][block].StaticAddress = BlockData[0][block].OriginalStaticAddress = address;
-
- count = (uint) (count / (sizeof(StaidxBlockVerdata)));
-
- if (count > 1024)
- {
- count = 1024;
- }
-
- BlockData[0][block].StaticCount = BlockData[0][block].OriginalStaticCount = count;
- }
-
- public unsafe bool ApplyPatches(ref StackDataReader reader)
- {
- ResetPatchesInBlockTable();
-
- PatchesCount = (int) reader.ReadUInt32BE();
-
- if (PatchesCount < 0)
- {
- PatchesCount = 0;
- }
-
- if (PatchesCount > MAPS_COUNT)
- {
- PatchesCount = MAPS_COUNT;
- }
-
- Array.Clear(MapPatchCount, 0, MapPatchCount.Length);
- Array.Clear(StaticPatchCount, 0, StaticPatchCount.Length);
-
- bool result = false;
-
- for (int i = 0; i < PatchesCount; i++)
- {
- int idx = i;
-
- //SanitizeMapIndex(ref idx);
-
- if (_filesMap[idx] == null || _filesMap[idx].StartAddress == IntPtr.Zero)
- {
- reader.Skip(8);
-
- continue;
- }
-
- int mapPatchesCount = (int) reader.ReadUInt32BE();
- MapPatchCount[i] = mapPatchesCount;
- int staticPatchesCount = (int) reader.ReadUInt32BE();
- StaticPatchCount[i] = staticPatchesCount;
-
- int w = MapBlocksSize[i, 0];
- int h = MapBlocksSize[i, 1];
-
- int maxBlockCount = w * h;
-
- if (mapPatchesCount != 0)
- {
- UOFileMul difl = _mapDifl[i];
- UOFileMul dif = _mapDif[i];
-
- if (difl == null || dif == null || difl.Length == 0 || dif.Length == 0)
- {
- continue;
- }
-
- mapPatchesCount = Math.Min(mapPatchesCount, (int) difl.Length >> 2);
-
- difl.Seek(0);
- dif.Seek(0);
-
- for (int j = 0; j < mapPatchesCount; j++)
- {
- uint blockIndex = difl.ReadUInt();
-
- if (blockIndex < maxBlockCount)
- {
- BlockData[idx][blockIndex].MapAddress = (ulong) dif.PositionAddress;
-
- result = true;
- }
-
- dif.Skip(sizeof(MapBlock));
- }
- }
-
- if (staticPatchesCount != 0)
- {
- UOFileMul difl = _staDifl[i];
- UOFileMul difi = _staDifi[i];
-
- if (difl == null || difi == null || _staDif[i] == null || difl.Length == 0 || difi.Length == 0 || _staDif[i].Length == 0)
- {
- continue;
- }
-
- ulong startAddress = (ulong) _staDif[i].StartAddress;
-
- staticPatchesCount = Math.Min(staticPatchesCount, (int) difl.Length >> 2);
-
- difl.Seek(0);
- difi.Seek(0);
-
- int sizeOfStaicsBlock = sizeof(StaticsBlock);
- int sizeOfStaidxBlock = sizeof(StaidxBlock);
-
- for (int j = 0; j < staticPatchesCount; j++)
- {
- if (difl.IsEOF || difi.IsEOF)
- {
- break;
- }
-
- uint blockIndex = difl.ReadUInt();
-
- StaidxBlock* sidx = (StaidxBlock*) difi.PositionAddress;
-
- difi.Skip(sizeOfStaidxBlock);
-
- if (blockIndex < maxBlockCount)
- {
- ulong realStaticAddress = 0;
- int realStaticCount = 0;
-
- if (sidx->Size > 0 && sidx->Position != 0xFFFF_FFFF)
- {
- realStaticAddress = startAddress + sidx->Position;
- realStaticCount = (int) (sidx->Size / sizeOfStaicsBlock);
-
- if (realStaticCount > 0)
- {
- if (realStaticCount > 1024)
- {
- realStaticCount = 1024;
- }
- }
- }
-
- BlockData[idx][blockIndex].StaticAddress = realStaticAddress;
-
- BlockData[idx][blockIndex].StaticCount = (uint) realStaticCount;
-
- result = true;
- }
- }
- }
- }
-
- return result;
- }
-
- private void ResetPatchesInBlockTable()
- {
- for (int i = 0; i < MAPS_COUNT; i++)
- {
- IndexMap[] list = BlockData[i];
-
- if (list == null)
- {
- continue;
- }
-
- int w = MapBlocksSize[i, 0];
- int h = MapBlocksSize[i, 1];
-
- int maxBlockCount = w * h;
-
- if (maxBlockCount < 1)
- {
- return;
- }
-
- if (_filesMap[i] is UOFileMul mul && mul.StartAddress != IntPtr.Zero)
- {
- if (_filesIdxStatics[i] is UOFileMul stIdxMul && stIdxMul.StartAddress != IntPtr.Zero)
- {
- if (_filesStatics[i] is UOFileMul stMul && stMul.StartAddress != IntPtr.Zero)
- {
- for (int block = 0; block < maxBlockCount; block++)
- {
- ref IndexMap index = ref list[block];
- index.MapAddress = index.OriginalMapAddress;
- index.StaticAddress = index.OriginalStaticAddress;
- index.StaticCount = index.OriginalStaticCount;
- }
- }
- }
- }
- }
- }
-
- public void SanitizeMapIndex(ref int map)
- {
- if (map == 1 && (_filesMap[1] == null || _filesMap[1].StartAddress == IntPtr.Zero || _filesStatics[1] == null || _filesStatics[1].StartAddress == IntPtr.Zero || _filesIdxStatics[1] == null || _filesIdxStatics[1].StartAddress == IntPtr.Zero))
- {
- map = 0;
- }
- }
-
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ref IndexMap GetIndex(int map, int x, int y)
- {
- int block = x * MapBlocksSize[map, 1] + y;
-
- return ref BlockData[map][block];
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public ref struct StaticsBlock
- {
- public ushort Color;
- public byte X;
- public byte Y;
- public sbyte Z;
- public ushort Hue;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public ref struct StaidxBlock
- {
- public uint Position;
- public uint Size;
- public uint Unknown;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public ref struct StaidxBlockVerdata
- {
- public uint Position;
- public ushort Size;
- public byte Unknown;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public ref struct MapCells
- {
- public ushort TileID;
- public sbyte Z;
- }
-
- //[StructLayout(LayoutKind.Sequential, Pack = 1)]
- //public struct MapBlock
- //{
- // public readonly uint Header;
- // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
- // public MapCells[] Cells;
- //}
-
- [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 4 + 64 * 3)]
- public ref struct MapBlock
- {
- public uint Header;
- public unsafe MapCells* Cells;
- }
-
- //[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 4 + 64 * 3)]
- //public struct MapBlock2
- //{
- // public readonly uint Header;
- // public IntPtr Cells;
- //}
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct RadarMapcells
- {
- public ushort Graphic;
- public sbyte Z;
- public bool IsLand;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct RadarMapBlock
- {
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
- public RadarMapcells[,] Cells;
- }
-
- public struct IndexMap
- {
- public ulong MapAddress;
- public ulong OriginalMapAddress;
- public ulong OriginalStaticAddress;
- public uint OriginalStaticCount;
- public ulong StaticAddress;
- public uint StaticCount;
- public static IndexMap Invalid = new IndexMap();
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/MultiLoader.cs b/src/ClassicUO.Assets/MultiLoader.cs
deleted file mode 100644
index f81e64f74..000000000
--- a/src/ClassicUO.Assets/MultiLoader.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class MultiLoader : UOFileLoader
- {
- private static MultiLoader _instance;
-
- public const int MAX_MULTI_DATA_INDEX_COUNT = 0x2200;
-
- private MultiLoader()
- {
- }
-
- public static MultiLoader Instance => _instance ?? (_instance = new MultiLoader());
-
- public int Count { get; private set; }
- public UOFile File { get; private set; }
-
- public bool IsUOP { get; private set; }
- public int Offset { get; private set; }
-
-
- public override unsafe Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string uopPath = UOFileManager.GetUOFilePath("MultiCollection.uop");
-
- if (UOFileManager.IsUOPInstallation && System.IO.File.Exists(uopPath))
- {
- Count = MAX_MULTI_DATA_INDEX_COUNT;
- File = new UOFileUop(uopPath, "build/multicollection/{0:D6}.bin");
- Entries = new UOFileIndex[Count];
- IsUOP = true;
- }
- else
- {
- string path = UOFileManager.GetUOFilePath("multi.mul");
- string pathidx = UOFileManager.GetUOFilePath("multi.idx");
-
- if (System.IO.File.Exists(path) && System.IO.File.Exists(pathidx))
- {
- File = new UOFileMul(path, pathidx, MAX_MULTI_DATA_INDEX_COUNT, 14);
-
- Count = Offset = UOFileManager.Version >= ClientVersion.CV_7090 ? sizeof(MultiBlockNew) + 2 : sizeof(MultiBlock);
- }
- }
-
- File.FillEntries(ref Entries);
- }
- );
- }
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public ref struct MultiBlock
- {
- public ushort ID;
- public short X;
- public short Y;
- public short Z;
- public uint Flags;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public ref struct MultiBlockNew
- {
- public ushort ID;
- public short X;
- public short Y;
- public short Z;
- public ushort Flags;
- public uint Unknown;
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/MultiMapLoader.cs b/src/ClassicUO.Assets/MultiMapLoader.cs
deleted file mode 100644
index f1cc0e009..000000000
--- a/src/ClassicUO.Assets/MultiMapLoader.cs
+++ /dev/null
@@ -1,315 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using System;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class MultiMapLoader : UOFileLoader
- {
- private static MultiMapLoader _instance;
- private UOFileMul[] _facets;
- private UOFile _file;
-
- private MultiMapLoader()
- {
- }
-
- public static MultiMapLoader Instance => _instance ?? (_instance = new MultiMapLoader());
-
- public bool HasFacet(int map)
- {
- return map >= 0 && map < _facets.Length && _facets[map] != null;
- }
-
- public override Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string path = UOFileManager.GetUOFilePath("Multimap.rle");
-
- if (File.Exists(path))
- {
- _file = new UOFile(path, true);
- }
-
- var facetFiles = Directory.GetFiles(UOFileManager.BasePath, "*.mul", SearchOption.TopDirectoryOnly)
- .Select(s => Regex.Match(s, "facet0.*\\.mul", RegexOptions.IgnoreCase))
- .Where(s => s.Success)
- .Select(s => Path.Combine(UOFileManager.BasePath, s.Value))
- .ToArray();
-
- _facets = new UOFileMul[facetFiles.Length];
-
- for (int i = 0; i < facetFiles.Length; i++)
- {
- _facets[i] = new UOFileMul(facetFiles[i]);
- }
- }
- );
- }
-
- public unsafe MultiMapInfo LoadMap
- (
- int width,
- int height,
- int startx,
- int starty,
- int endx,
- int endy
- )
- {
- if (_file == null || _file.Length == 0)
- {
- Log.Warn("MultiMap.rle is not loaded!");
-
- return default;
- }
-
- _file.Seek(0);
-
- int w = _file.ReadInt();
- int h = _file.ReadInt();
-
- if (w < 1 || h < 1)
- {
- Log.Warn("Failed to load bounds from MultiMap.rle");
-
- return default;
- }
-
- int mapSize = width * height;
-
- startx = startx >> 1;
- endx = endx >> 1;
-
- int widthDivisor = endx - startx;
-
- if (widthDivisor == 0)
- {
- widthDivisor++;
- }
-
- starty = starty >> 1;
- endy = endy >> 1;
-
- int heightDivisor = endy - starty;
-
- if (heightDivisor == 0)
- {
- heightDivisor++;
- }
-
- int pwidth = (width << 8) / widthDivisor;
- int pheight = (height << 8) / heightDivisor;
-
- byte[] data = new byte[mapSize];
-
- int x = 0, y = 0;
-
- int maxPixelValue = 1;
- int startHeight = starty * pheight;
-
- while (_file.Position < _file.Length)
- {
- byte pic = _file.ReadByte();
- byte size = (byte) (pic & 0x7F);
- bool colored = (pic & 0x80) != 0;
-
- int currentHeight = y * pheight;
- int posY = width * ((currentHeight - startHeight) >> 8);
-
- for (int i = 0; i < size; i++)
- {
- if (colored && x >= startx && x < endx && y >= starty && y < endy)
- {
- int position = posY + ((pwidth * (x - startx)) >> 8);
-
- ref byte pixel = ref data[position];
-
- if (pixel < 0xFF)
- {
- if (pixel == maxPixelValue)
- {
- maxPixelValue++;
- }
-
- pixel++;
- }
- }
-
- x++;
-
- if (x >= w)
- {
- x = 0;
- y++;
- currentHeight += pheight;
- posY = width * ((currentHeight - startHeight) >> 8);
- }
- }
- }
-
- if (maxPixelValue <= 0)
- {
- return default;
- }
-
- int s = Marshal.SizeOf();
- IntPtr ptr = Marshal.AllocHGlobal(s * HuesLoader.Instance.HuesRange.Length);
-
- for (int i = 0; i < HuesLoader.Instance.HuesRange.Length; i++)
- {
- Marshal.StructureToPtr(HuesLoader.Instance.HuesRange[i], ptr + i * s, false);
- }
-
- ushort* huesData = (ushort*)(byte*)(ptr + 30800);
-
- Span colorTable = stackalloc uint[byte.MaxValue];
- var pixels = new uint[mapSize];
-
- try
- {
- int colorOffset = 31 * maxPixelValue;
-
- for (int i = 0; i < maxPixelValue; i++)
- {
- colorOffset -= 31;
- colorTable[i] = HuesHelper.Color16To32(huesData[colorOffset / maxPixelValue]) | 0xFF_00_00_00;
- }
-
- for (int i = 0; i < mapSize; i++)
- {
- pixels[i] = data[i] != 0 ? colorTable[data[i] - 1] : 0;
- }
- }
- finally
- {
- if (ptr != IntPtr.Zero)
- Marshal.FreeHGlobal(ptr);
- }
-
- return new MultiMapInfo()
- {
- Pixels = pixels,
- Width = width,
- Height = height,
- };
- }
-
- public MultiMapInfo LoadFacet
- (
- int facet,
- int width,
- int height,
- int startx,
- int starty,
- int endx,
- int endy
- )
- {
- if (_file == null || facet < 0 || facet > MapLoader.MAPS_COUNT || facet >= _facets.Length || _facets[facet] == null)
- {
- return default;
- }
-
- _facets[facet].Seek(0);
-
- int w = _facets[facet].ReadShort();
-
- int h = _facets[facet].ReadShort();
-
- if (w < 1 || h < 1)
- {
- return default;
- }
-
- int startX = startx;
- int endX = endx <= 0 ? width : endx;
-
- int startY = starty;
- int endY = endy <= 0 ? height : endy;
-
- int pwidth = endX - startX;
- int pheight = endY - startY;
-
- var pixels = new uint[pwidth * pheight];
-
- for (int y = 0; y < h; y++)
- {
- int x = 0;
-
- int colorCount = _facets[facet].ReadInt() / 3;
-
- for (int i = 0; i < colorCount; i++)
- {
- int size = _facets[facet].ReadByte();
-
- uint color = HuesHelper.Color16To32(_facets[facet].ReadUShort()) | 0xFF_00_00_00;
-
- for (int j = 0; j < size; j++)
- {
- if (x >= startX && x < endX && y >= startY && y < endY)
- {
- pixels[(y - startY) * pwidth + (x - startX)] = color;
- }
-
- x++;
- }
- }
- }
-
- return new MultiMapInfo()
- {
- Pixels = pixels,
- Width = pwidth,
- Height = pheight,
- };
- }
- }
-
- public ref struct MultiMapInfo
- {
- public Span Pixels;
- public int Width, Height;
- }
-}
diff --git a/src/ClassicUO.Assets/PNGLoader.cs b/src/ClassicUO.Assets/PNGLoader.cs
deleted file mode 100644
index 22eba727e..000000000
--- a/src/ClassicUO.Assets/PNGLoader.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Graphics;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.Remoting.Messaging;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class PNGLoader
- {
- private const string IMAGES_FOLDER = "ExternalImages", GUMP_EXTERNAL_FOLDER = "gumps", ART_EXTERNAL_FOLDER = "art";
-
- private string exePath;
-
- private uint[] gump_availableIDs;
- private Dictionary gump_textureCache = new Dictionary();
-
- private uint[] art_availableIDs;
- private Dictionary art_textureCache = new Dictionary();
-
- public GraphicsDevice GraphicsDevice { set; get; }
-
- public static PNGLoader _instance;
- public static PNGLoader Instance => _instance ?? (_instance = new PNGLoader());
-
- public Texture2D GetImageTexture(string fullImagePath)
- {
- Texture2D texture = null;
-
- if (GraphicsDevice != null && File.Exists(fullImagePath))
- {
- FileStream titleStream = File.OpenRead(fullImagePath);
- texture = Texture2D.FromStream(GraphicsDevice, titleStream);
- titleStream.Close();
- Color[] buffer = new Color[texture.Width * texture.Height];
- texture.GetData(buffer);
- for (int i = 0; i < buffer.Length; i++)
- buffer[i] = Color.FromNonPremultiplied(buffer[i].R, buffer[i].G, buffer[i].B, buffer[i].A);
- texture.SetData(buffer);
- }
-
- return texture;
- }
-
- public GumpInfo LoadGumpTexture(uint graphic)
- {
- Texture2D texture;
-
- if (gump_availableIDs == null)
- return new GumpInfo();
- int index = Array.IndexOf(gump_availableIDs, graphic);
- if (index == -1) return new GumpInfo();
-
- gump_textureCache.TryGetValue(graphic, out texture);
-
- if (exePath != null && texture == null && GraphicsDevice != null)
- {
- string fullImagePath = Path.Combine(exePath, IMAGES_FOLDER, GUMP_EXTERNAL_FOLDER, ((int)graphic).ToString() + ".png");
-
- if (File.Exists(fullImagePath))
- {
- FileStream titleStream = File.OpenRead(fullImagePath);
- texture = Texture2D.FromStream(GraphicsDevice, titleStream);
- titleStream.Close();
- Color[] buffer = new Color[texture.Width * texture.Height];
- texture.GetData(buffer);
- for (int i = 0; i < buffer.Length; i++)
- buffer[i] = Color.FromNonPremultiplied(buffer[i].R, buffer[i].G, buffer[i].B, buffer[i].A);
- texture.SetData(buffer);
-
- gump_textureCache.Add(graphic, texture);
- }
- }
-
- if(texture == null)
- {
- return new GumpInfo();
- }
-
- return new GumpInfo()
- {
- Pixels = GetPixels(texture),
- Width = texture.Width,
- Height = texture.Height
- };
- }
-
- public ArtInfo LoadArtTexture(uint graphic)
- {
- Texture2D texture;
-
- if (art_availableIDs == null)
- return new ArtInfo();
-
- int index = Array.IndexOf(art_availableIDs, graphic);
- if (index == -1) return new ArtInfo();
-
- art_textureCache.TryGetValue(graphic, out texture);
-
- if (exePath != null && texture == null && GraphicsDevice != null)
- {
- string fullImagePath = Path.Combine(exePath, IMAGES_FOLDER, ART_EXTERNAL_FOLDER, (graphic -= 0x4000).ToString() + ".png");
-
- if (File.Exists(fullImagePath))
- {
- FileStream titleStream = File.OpenRead(fullImagePath);
- texture = Texture2D.FromStream(GraphicsDevice, titleStream);
- titleStream.Close();
- Color[] buffer = new Color[texture.Width * texture.Height];
- texture.GetData(buffer);
- for (int i = 0; i < buffer.Length; i++)
- buffer[i] = Color.FromNonPremultiplied(buffer[i].R, buffer[i].G, buffer[i].B, buffer[i].A);
- texture.SetData(buffer);
-
- art_textureCache.Add(graphic, texture);
- }
- }
-
- return new ArtInfo()
- {
- Pixels = GetPixels(texture),
- Width = texture.Width,
- Height = texture.Height,
- };
- }
-
- private uint[] GetPixels(Texture2D texture)
- {
- if(texture == null)
- {
- return new uint[0];
- }
- Span pixels = texture.Width * texture.Height <= 1024 ? stackalloc uint[1024] : stackalloc uint[texture.Width * texture.Height];
-
- Color[] pixelColors = new Color[texture.Width * texture.Height];
- texture.GetData(pixelColors);
-
- for (int i = 0; i < pixelColors.Length; i++)
- {
- pixels[i] = pixelColors[i].PackedValue;
- }
-
- return pixels.ToArray();
- }
-
- public Task Load()
- {
- return Task.Run
- (() =>
- {
- string strExeFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
- exePath = Path.GetDirectoryName(strExeFilePath);
-
- string gumpPath = Path.Combine(exePath, IMAGES_FOLDER, GUMP_EXTERNAL_FOLDER);
- if (Directory.Exists(gumpPath))
- {
- string[] files = Directory.GetFiles(gumpPath, "*.png", SearchOption.TopDirectoryOnly);
- gump_availableIDs = new uint[files.Length];
-
- for (int i = 0; i < files.Length; i++)
- {
- string fname = Path.GetFileName(files[i]);
- uint.TryParse(fname.Substring(0, fname.Length - 4), out gump_availableIDs[i]);
- }
- }
-
- string artPath = Path.Combine(exePath, IMAGES_FOLDER, ART_EXTERNAL_FOLDER);
- if (Directory.Exists(artPath))
- {
- string[] files = Directory.GetFiles(artPath, "*.png", SearchOption.TopDirectoryOnly);
- art_availableIDs = new uint[files.Length];
-
- for (int i = 0; i < files.Length; i++)
- {
- string fname = Path.GetFileName(files[i]);
- if(uint.TryParse(fname.Substring(0, fname.Length - 4), out uint gfx))
- {
- art_availableIDs[i] = gfx + 0x4000;
- }
- }
- }
- });
- }
- }
-}
diff --git a/src/ClassicUO.Assets/ProfessionLoader.cs b/src/ClassicUO.Assets/ProfessionLoader.cs
deleted file mode 100644
index d27d3deb9..000000000
--- a/src/ClassicUO.Assets/ProfessionLoader.cs
+++ /dev/null
@@ -1,434 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class ProfessionInfo
- {
- public static readonly int[,] _VoidSkills = new int[4, 2]
- {
- { 0, InitialSkillValue }, { 0, InitialSkillValue },
- { 0, UOFileManager.Version < ClientVersion.CV_70160 ? 0 : InitialSkillValue }, { 0, InitialSkillValue }
- };
- public static readonly int[] _VoidStats = new int[3] { 60, RemainStatValue, RemainStatValue };
- public static int InitialSkillValue => UOFileManager.Version >= ClientVersion.CV_70160 ? 30 : 50;
- public static int RemainStatValue => UOFileManager.Version >= ClientVersion.CV_70160 ? 15 : 10;
- public string Name { get; set; }
- public string TrueName { get; set; }
- public int Localization { get; set; }
- public int Description { get; set; }
- public int DescriptionIndex { get; set; }
- public ProfessionLoader.PROF_TYPE Type { get; set; }
-
- public ushort Graphic { get; set; }
-
- public bool TopLevel { get; set; }
- public int[,] SkillDefVal { get; set; } = _VoidSkills;
- public int[] StatsVal { get; set; } = _VoidStats;
- public List Children { get; set; }
- }
-
- public class ProfessionLoader : UOFileLoader
- {
- private static ProfessionLoader _instance;
- private readonly string[] _Keys =
- {
- "begin", "name", "truename", "desc", "toplevel", "gump", "type", "children", "skill",
- "stat", "str", "int", "dex", "end", "true", "category", "nameid", "descid"
- };
-
- private ProfessionLoader()
- {
- }
-
- public static ProfessionLoader Instance => _instance ?? (_instance = new ProfessionLoader());
-
- public Dictionary> Professions { get; } = new Dictionary>();
-
- public override Task Load()
- {
- return Task.Run
- (
- () =>
- {
- bool result = false;
-
- FileInfo file = new FileInfo(UOFileManager.GetUOFilePath("Prof.txt"));
-
- if (file.Exists)
- {
- if (file.Length > 0x100000) //1megabyte limit of string file
- {
- throw new InternalBufferOverflowException($"{file.FullName} exceeds the maximum 1Megabyte allowed size for a string text file, please, check that the file is correct and not corrupted -> {file.Length} file size");
- }
-
- //what if file doesn't exist? we skip section completely...directly into advanced selection
- TextFileParser read = new TextFileParser(File.ReadAllText(file.FullName), new[] { ' ', '\t', ',' }, new[] { '#', ';' }, new[] { '"', '"' });
-
- while (!read.IsEOF())
- {
- List strings = read.ReadTokens();
-
- if (strings.Count > 0)
- {
- if (strings[0].ToLower() == "begin")
- {
- result = ParseFilePart(read);
-
- if (!result)
- {
- break;
- }
- }
- }
- }
- }
-
- Professions[new ProfessionInfo
- {
- Name = "Advanced",
- Localization = 1061176,
- Description = 1061226,
- Graphic = 5545,
- TopLevel = true,
- Type = PROF_TYPE.PROFESSION,
- DescriptionIndex = -1,
- TrueName = "advanced"
- }] = null;
-
- foreach (KeyValuePair> kvp in Professions)
- {
- kvp.Key.Children = null;
-
- if (kvp.Value != null)
- {
- foreach (ProfessionInfo info in kvp.Value)
- {
- info.Children = null;
- }
- }
- }
- }
- );
- }
-
- private int GetKeyCode(string key)
- {
- key = key.ToLowerInvariant();
- int result = 0;
-
- for (int i = 0; i < _Keys.Length && result <= 0; i++)
- {
- if (key == _Keys[i])
- {
- result = i + 1;
- }
- }
-
- return result;
- }
-
- private bool ParseFilePart(TextFileParser file)
- {
- List childrens = new List();
- PROF_TYPE type = PROF_TYPE.NO_PROF;
- string name = string.Empty;
- string trueName = string.Empty;
- int nameClilocID = 0;
- int descriptionClilocID = 0;
- int descriptionIndex = 0;
- ushort gump = 0;
- bool topLevel = false;
- int[,] skillIndex = new int[4, 2] { { 0xFF, 0 }, { 0xFF, 0 }, { 0xFF, 0 }, { 0xFF, 0 } };
- int[] stats = new int[3] { 0, 0, 0 };
-
- bool exit = false;
-
- while (!file.IsEOF() && !exit)
- {
- List strings = file.ReadTokens();
-
- if (strings.Count < 1)
- {
- continue;
- }
-
- int code = GetKeyCode(strings[0]);
-
- switch ((PM_CODE) code)
- {
- case PM_CODE.BEGIN:
- case PM_CODE.END:
-
- {
- exit = true;
-
- break;
- }
-
- case PM_CODE.NAME:
-
- {
- name = strings[1];
-
- break;
- }
-
- case PM_CODE.TRUENAME:
-
- {
- trueName = strings[1];
-
- break;
- }
-
- case PM_CODE.DESC:
-
- {
- int.TryParse(strings[1], out descriptionIndex);
-
- break;
- }
-
- case PM_CODE.TOPLEVEL:
-
- {
- topLevel = GetKeyCode(strings[1]) == (int) PM_CODE.TRUE;
-
- break;
- }
-
- case PM_CODE.GUMP:
-
- {
- ushort.TryParse(strings[1], out gump);
-
- break;
- }
-
- case PM_CODE.TYPE:
-
- {
- if (GetKeyCode(strings[1]) == (int) PM_CODE.CATEGORY)
- {
- type = PROF_TYPE.CATEGORY;
- }
- else
- {
- type = PROF_TYPE.PROFESSION;
- }
-
- break;
- }
-
- case PM_CODE.CHILDREN:
-
- {
- for (int j = 1; j < strings.Count; j++)
- {
- childrens.Add(strings[j]);
- }
-
- break;
- }
-
- case PM_CODE.SKILL:
-
- {
- if (strings.Count > 2)
- {
- int idx = 0;
-
- for (int i = 0, len = skillIndex.GetLength(0); i < len; i++)
- {
- if (skillIndex[i, 0] == 0xFF)
- {
- idx = i;
-
- break;
- }
- }
-
- for (int j = 0; j < SkillsLoader.Instance.SkillsCount; j++)
- {
- SkillEntry skill = SkillsLoader.Instance.Skills[j];
-
- if (strings[1] == skill.Name || ((SkillEntry.HardCodedName) skill.Index).ToString().ToLower() == strings[1].ToLower())
- {
- skillIndex[idx, 0] = j;
- int.TryParse(strings[2], out skillIndex[idx, 1]);
-
- break;
- }
- }
- }
-
- break;
- }
-
- case PM_CODE.STAT:
-
- {
- if (strings.Count > 2)
- {
- code = GetKeyCode(strings[1]);
- int.TryParse(strings[2], out int val);
-
- if ((PM_CODE) code == PM_CODE.STR)
- {
- stats[0] = val;
- }
- else if ((PM_CODE) code == PM_CODE.INT)
- {
- stats[1] = val;
- }
- else if ((PM_CODE) code == PM_CODE.DEX)
- {
- stats[2] = val;
- }
- }
-
- break;
- }
-
- case PM_CODE.NAME_CLILOC_ID:
-
- {
- int.TryParse(strings[1], out nameClilocID);
- name = ClilocLoader.Instance.GetString(nameClilocID, true, name);
-
- break;
- }
-
- case PM_CODE.DESCRIPTION_CLILOC_ID:
-
- {
- int.TryParse(strings[1], out descriptionClilocID);
-
- break;
- }
- }
- }
-
- ProfessionInfo info = null;
- List list = null;
-
- if (type == PROF_TYPE.CATEGORY)
- {
- info = new ProfessionInfo
- {
- Children = childrens
- };
-
- list = new List();
- }
- else if (type == PROF_TYPE.PROFESSION)
- {
- info = new ProfessionInfo
- {
- StatsVal = stats,
- SkillDefVal = skillIndex
- };
- }
-
- bool result = type != PROF_TYPE.NO_PROF;
-
- if (info != null)
- {
- info.Localization = nameClilocID;
- info.Description = descriptionClilocID;
- info.Name = name;
- info.TrueName = trueName;
- info.DescriptionIndex = descriptionIndex;
- info.TopLevel = topLevel;
- info.Graphic = gump;
- info.Type = type;
-
- if (topLevel)
- {
- Professions[info] = list;
- }
- else
- {
- foreach (KeyValuePair> kvp in Professions)
- {
- if (kvp.Key.Children != null && kvp.Value != null && kvp.Key.Children.Contains(trueName))
- {
- Professions[kvp.Key].Add(info);
-
- result = true;
-
- break;
- }
- }
- }
- }
-
- return result;
- }
-
- public enum PROF_TYPE
- {
- NO_PROF = 0,
- CATEGORY,
- PROFESSION
- }
-
- private enum PM_CODE
- {
- BEGIN = 1,
- NAME,
- TRUENAME,
- DESC,
- TOPLEVEL,
- GUMP,
- TYPE,
- CHILDREN,
- SKILL,
- STAT,
- STR,
- INT,
- DEX,
- END,
- TRUE,
- CATEGORY,
- NAME_CLILOC_ID,
- DESCRIPTION_CLILOC_ID
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/Roboto-Regular.ttf b/src/ClassicUO.Assets/Roboto-Regular.ttf
deleted file mode 100644
index 3033308a6..000000000
Binary files a/src/ClassicUO.Assets/Roboto-Regular.ttf and /dev/null differ
diff --git a/src/ClassicUO.Assets/SkillsLoader.cs b/src/ClassicUO.Assets/SkillsLoader.cs
deleted file mode 100644
index 563182f36..000000000
--- a/src/ClassicUO.Assets/SkillsLoader.cs
+++ /dev/null
@@ -1,190 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class SkillsLoader : UOFileLoader
- {
- private static SkillsLoader _instance;
- private UOFileMul _file;
-
- private SkillsLoader()
- {
- }
-
- public static SkillsLoader Instance => _instance ?? (_instance = new SkillsLoader());
-
- public int SkillsCount => Skills.Count;
- public readonly List Skills = new List();
- public readonly List SortedSkills = new List();
-
- public override unsafe Task Load()
- {
- return Task.Run
- (
- () =>
- {
- if (SkillsCount > 0)
- {
- return;
- }
-
- string path = UOFileManager.GetUOFilePath("skills.mul");
- string pathidx = UOFileManager.GetUOFilePath("Skills.idx");
-
- FileSystemHelper.EnsureFileExists(path);
- FileSystemHelper.EnsureFileExists(pathidx);
-
- _file = new UOFileMul(path, pathidx, 0, 16);
- _file.FillEntries(ref Entries);
-
- for (int i = 0, count = 0; i < Entries.Length; i++)
- {
- ref UOFileIndex entry = ref GetValidRefEntry(i);
-
- if (entry.Length > 0)
- {
- _file.SetData(entry.Address, entry.FileSize);
- _file.Seek(entry.Offset);
-
- bool hasAction = _file.ReadBool();
- string name = Encoding.UTF8.GetString((byte*)_file.PositionAddress, entry.Length - 1).TrimEnd('\0');
-
- Skills.Add(new SkillEntry(count++, name, hasAction));
- }
- }
-
- SortedSkills.AddRange(Skills);
- SortedSkills.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.InvariantCulture));
- }
- );
- }
-
- public int GetSortedIndex(int index)
- {
- if (index < SkillsCount)
- {
- return SortedSkills[index].Index;
- }
-
- return -1;
- }
- }
-
- public class SkillEntry
- {
- public SkillEntry(int index, string name, bool hasAction)
- {
- Index = index;
- Name = name;
- HasAction = hasAction;
- }
-
- public bool HasAction;
- public readonly int Index;
- public string Name;
-
- public override string ToString()
- {
- return Name;
- }
-
- public enum HardCodedName
- {
- Alchemy,
- Anatomy,
- AnimalLore,
- ItemID, // T2A
- ArmsLore,
- Parrying,
- Begging,
- Blacksmith,
- Bowcraft,
- Peacemaking,
- Camping,
- Carpentry,
- Cartography,
- Cooking,
- DetectHidden,
- Enticement,
- EvaluateIntelligence,
- Healing,
- Fishing,
- ForensicEvaluation,
- Herding,
- Hiding,
- Provocation,
- Inscription,
- Lockpicking,
- Magery,
- ResistingSpells,
- Tactics,
- Snooping,
- Musicanship,
- Poisoning,
- Archery,
- SpiritSpeak,
- Stealing,
- Tailoring,
- AnimalTaming,
- TasteIdentification,
- Tinkering,
- Tracking,
- Veterinary,
- Swordsmanship,
- MaceFighting,
- Fencing,
- Wrestling,
- Lumberjacking,
- Mining,
- Meditation,
- Stealth,
- Disarm,
- Necromancy,
- Focus,
- Chivalry,
- Bushido,
- Ninjitsu,
- Spellweaving,
- Mysticism,
- Imbuing,
- Throwing
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/SoundOverrideLoader.cs b/src/ClassicUO.Assets/SoundOverrideLoader.cs
deleted file mode 100644
index 0d019bb8c..000000000
--- a/src/ClassicUO.Assets/SoundOverrideLoader.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- internal class SoundOverrideLoader
- {
- public static SoundOverrideLoader Instance { get; private set; } = new SoundOverrideLoader();
-
- private const string SOUND_OVERRIDE_FOLDER = "SoundOverrides";
- private string exePath;
- private Dictionary> soundCache = new Dictionary>();
- private bool loaded = false;
-
- private SoundOverrideLoader()
- {
- string strExeFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
- exePath = Path.GetDirectoryName(strExeFilePath);
-
- Task.Factory.StartNew(() =>
- {
- if (Directory.Exists(Path.Combine(exePath, SOUND_OVERRIDE_FOLDER)))
- {
- string[] files = Directory.GetFiles(Path.Combine(exePath, SOUND_OVERRIDE_FOLDER), "*.mp3", SearchOption.TopDirectoryOnly);
-
- for (int i = 0; i < files.Length; i++)
- {
- var fname = Path.GetFileName(files[i]);
- if (int.TryParse(fname.Substring(0, fname.Length - 4), out int fID))
- {
- soundCache.Add(fID, new Tuple(fname, File.ReadAllBytes(files[i])));
- }
- }
-
- loaded = true;
- }
- });
- }
-
- public bool TryGetSoundOverride(int id, out byte[] data, out string name)
- {
- if (loaded)
- {
- if (soundCache.ContainsKey(id))
- {
- data = soundCache[id].Item2;
- name = soundCache[id].Item1;
- return true;
- }
- }
- name = null;
- data = null;
- return false;
- }
- }
-}
diff --git a/src/ClassicUO.Assets/SoundsLoader.cs b/src/ClassicUO.Assets/SoundsLoader.cs
deleted file mode 100644
index a712fd4c2..000000000
--- a/src/ClassicUO.Assets/SoundsLoader.cs
+++ /dev/null
@@ -1,378 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class SoundsLoader : UOFileLoader
- {
- private static readonly char[] _configFileDelimiters = { ' ', ',', '\t' };
- private static readonly Dictionary> _musicData = new Dictionary>();
-
- private static SoundsLoader _instance;
-
- public const int MAX_SOUND_DATA_INDEX_COUNT = 0xFFFF;
-
- private UOFile _file;
-
- private SoundsLoader()
- {
- }
-
- public static SoundsLoader Instance => _instance ?? (_instance = new SoundsLoader());
-
- public override Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string path = UOFileManager.GetUOFilePath("soundLegacyMUL.uop");
-
- if (UOFileManager.IsUOPInstallation && File.Exists(path))
- {
- _file = new UOFileUop(path, "build/soundlegacymul/{0:D8}.dat");
- Entries = new UOFileIndex[Math.Max(((UOFileUop) _file).TotalEntriesCount, MAX_SOUND_DATA_INDEX_COUNT)];
- }
- else
- {
- path = UOFileManager.GetUOFilePath("sound.mul");
- string idxpath = UOFileManager.GetUOFilePath("soundidx.mul");
-
- if (File.Exists(path) && File.Exists(idxpath))
- {
- _file = new UOFileMul(path, idxpath, MAX_SOUND_DATA_INDEX_COUNT);
- }
- else
- {
- throw new FileNotFoundException("no sounds found");
- }
- }
-
- _file.FillEntries(ref Entries);
-
- string def = UOFileManager.GetUOFilePath("Sound.def");
-
- if (File.Exists(def))
- {
- using (DefReader reader = new DefReader(def))
- {
- while (reader.Next())
- {
- int index = reader.ReadInt();
-
- if (index < 0 || index >= MAX_SOUND_DATA_INDEX_COUNT || index >= _file.Length || Entries[index].Length != 0)
- {
- continue;
- }
-
- int[] group = reader.ReadGroup();
-
- if (group == null)
- {
- continue;
- }
-
- for (int i = 0; i < group.Length; i++)
- {
- int checkIndex = group[i];
-
- if (checkIndex < -1 || checkIndex >= MAX_SOUND_DATA_INDEX_COUNT)
- {
- continue;
- }
-
- ref UOFileIndex ind = ref Entries[index];
-
- if (checkIndex == -1)
- {
- ind = default;
- }
- else
- {
- ref readonly UOFileIndex outInd = ref Entries[checkIndex];
-
- if (outInd.Length == 0)
- {
- continue;
- }
-
- Entries[index] = Entries[checkIndex];
- }
- }
- }
- }
- }
-
- path = UOFileManager.GetUOFilePath(UOFileManager.Version >= ClientVersion.CV_4011C ? @"Music/Digital/Config.txt" : @"Music/Config.txt");
-
- if (File.Exists(path))
- {
- using (StreamReader reader = new StreamReader(path))
- {
- string line;
-
- while ((line = reader.ReadLine()) != null)
- {
- if (TryParseConfigLine(line, out Tuple songData))
- {
- _musicData[songData.Item1] = new Tuple(songData.Item2, songData.Item3);
- }
- }
- }
- }
- else
- {
- _musicData.Add(0, new Tuple("oldult01", true));
- _musicData.Add(1, new Tuple("create1", false));
- _musicData.Add(2, new Tuple("dragflit", false));
- _musicData.Add(3, new Tuple("oldult02", true));
- _musicData.Add(4, new Tuple("oldult03", true));
- _musicData.Add(5, new Tuple("oldult04", true));
- _musicData.Add(6, new Tuple("oldult05", true));
- _musicData.Add(7, new Tuple("oldult06", true));
- _musicData.Add(8, new Tuple("stones2", true));
- _musicData.Add(9, new Tuple("britain1", true));
- _musicData.Add(10, new Tuple("britain2", true));
- _musicData.Add(11, new Tuple("bucsden", true));
- _musicData.Add(12, new Tuple("jhelom", false));
- _musicData.Add(13, new Tuple("lbcastle", false));
- _musicData.Add(14, new Tuple("linelle", false));
- _musicData.Add(15, new Tuple("magincia", true));
- _musicData.Add(16, new Tuple("minoc", true));
- _musicData.Add(17, new Tuple("ocllo", true));
- _musicData.Add(18, new Tuple("samlethe", false));
- _musicData.Add(19, new Tuple("serpents", true));
- _musicData.Add(20, new Tuple("skarabra", true));
- _musicData.Add(21, new Tuple("trinsic", true));
- _musicData.Add(22, new Tuple("vesper", true));
- _musicData.Add(23, new Tuple("wind", true));
- _musicData.Add(24, new Tuple("yew", true));
- _musicData.Add(25, new Tuple("cave01", false));
- _musicData.Add(26, new Tuple("dungeon9", false));
- _musicData.Add(27, new Tuple("forest_a", false));
- _musicData.Add(28, new Tuple("intown01", false));
- _musicData.Add(29, new Tuple("jungle_a", false));
- _musicData.Add(30, new Tuple("mountn_a", false));
- _musicData.Add(31, new Tuple("plains_a", false));
- _musicData.Add(32, new Tuple("sailing", false));
- _musicData.Add(33, new Tuple("swamp_a", false));
- _musicData.Add(34, new Tuple("tavern01", false));
- _musicData.Add(35, new Tuple("tavern02", false));
- _musicData.Add(36, new Tuple("tavern03", false));
- _musicData.Add(37, new Tuple("tavern04", false));
- _musicData.Add(38, new Tuple("combat1", false));
- _musicData.Add(39, new Tuple("combat2", false));
- _musicData.Add(40, new Tuple("combat3", false));
- _musicData.Add(41, new Tuple("approach", false));
- _musicData.Add(42, new Tuple("death", false));
- _musicData.Add(43, new Tuple("victory", false));
- _musicData.Add(44, new Tuple("btcastle", false));
- _musicData.Add(45, new Tuple("nujelm", true));
- _musicData.Add(46, new Tuple("dungeon2", false));
- _musicData.Add(47, new Tuple("cove", true));
- _musicData.Add(48, new Tuple("moonglow", true));
- _musicData.Add(49, new Tuple("zento", true));
- _musicData.Add(50, new Tuple("tokunodungeon", true));
- _musicData.Add(51, new Tuple("Taiko", true));
- _musicData.Add(52, new Tuple("dreadhornarea", true));
- _musicData.Add(53, new Tuple("elfcity", true));
- _musicData.Add(54, new Tuple("grizzledungeon", true));
- _musicData.Add(55, new Tuple("melisandeslair", true));
- _musicData.Add(56, new Tuple("paroxysmuslair", true));
- _musicData.Add(57, new Tuple("gwennoconversation", true));
- _musicData.Add(58, new Tuple("goodendgame", true));
- _musicData.Add(59, new Tuple("goodvsevil", true));
- _musicData.Add(60, new Tuple("greatearthserpents", true));
- _musicData.Add(61, new Tuple("humanoids_u9", true));
- _musicData.Add(62, new Tuple("minocnegative", true));
- _musicData.Add(63, new Tuple("paws", true));
- _musicData.Add(64, new Tuple("selimsbar", true));
- _musicData.Add(65, new Tuple("serpentislecombat_u7", true));
- _musicData.Add(66, new Tuple("valoriaships", true));
- }
- }
- );
- }
-
- public unsafe bool TryGetSound(int sound, out byte[] data, out string name)
- {
- data = null;
- name = null;
-
- if (sound < 0)
- {
- return false;
- }
-
- if (SoundOverrideLoader.Instance.TryGetSoundOverride(sound, out data, out name))
- {
- return true;
- }
-
- ref UOFileIndex entry = ref GetValidRefEntry(sound);
-
- _file.SetData(entry.Address, entry.FileSize);
- _file.Seek(entry.Offset);
-
- long offset = _file.Position;
-
- if (offset < 0 || entry.Length <= 0)
- {
- return false;
- }
-
- _file.Seek(offset);
-
- const int STRING_BUFFER_SIZE = 40;
-
- for (int i = 0; i < STRING_BUFFER_SIZE; ++i)
- {
- if (_file.ReadByte() == 0)
- {
- name = Encoding.UTF8.GetString((byte*)(_file.StartAddress.ToInt64() + offset), i);
-
- break;
- }
- }
-
- _file.Seek(offset + STRING_BUFFER_SIZE);
-
- data = new byte[entry.Length - STRING_BUFFER_SIZE];
-
- for (int i = 0; i < data.Length; ++i)
- {
- data[i] = _file.ReadByte();
- }
-
- return true;
- }
-
- ///
- /// Attempts to parse a line from UO's music Config.txt.
- ///
- /// A line from the file.
- /// If successful, contains a tuple with these fields: int songIndex, string songName, bool doesLoop
- /// true if line could be parsed, false otherwise.
- private bool TryParseConfigLine(string line, out Tuple songData)
- {
- songData = null;
-
- string[] splits = line.Split(_configFileDelimiters);
-
- if (splits.Length < 2 || splits.Length > 3)
- {
- return false;
- }
-
- int index = int.Parse(splits[0]);
-
- // check if name exists as file, ignoring case since UO isn't consistent with file case (necessary for *nix)
- // also, not every filename in Config.txt has a file extension, so let's strip it out just in case.
- string name = GetTrueFileName(Path.GetFileNameWithoutExtension(splits[1]));
-
- bool doesLoop = splits.Length == 3 && splits[2] == "loop";
-
- songData = new Tuple(index, name, doesLoop);
-
- return true;
- }
-
- ///
- /// Returns true filename from name, ignoring case since UO isn't consistent with file case (necessary for *nix)
- ///
- /// The filename from the music Config.txt
- /// a string with the true case sensitive filename
- private static string GetTrueFileName(string name)
- {
- // don't worry about subdirectories, we'll recursively search them all
- string dir = UOFileManager.BasePath + $"/Music";
-
- // Enumerate all files in the directory, using the file name as a pattern
- // This will list all case variants of the filename even on file systems that
- // are case sensitive.
- Regex pattern = new Regex($"^{name}.mp3", RegexOptions.IgnoreCase);
- //string[] fileList = Directory.GetFiles(dir, "*.mp3", SearchOption.AllDirectories).Where(path => pattern.IsMatch(Path.GetFileName(path))).ToArray();
- string[] fileList = Directory.GetFiles(dir, "*.mp3", SearchOption.AllDirectories);
- fileList = Array.FindAll(fileList, path => pattern.IsMatch(Path.GetFileName(path)));
-
- if (fileList != null && fileList.Length != 0)
- {
- if (fileList.Length > 1)
- {
- // More than one file with the same name but different case spelling found
- Log.Warn($"Ambiguous File reference for {name}. More than one file found with different spellings.");
- }
-
- Log.Debug($"Loading music:\t\t{fileList[0]}");
-
- return Path.GetFileName(fileList[0]);
- }
-
- // If we've made it this far, there is no file with that name, regardless of case spelling
- // return name and GetMusic will fail gracefully (play nothing)
- Log.Warn($"No File found known as {name}");
- return name;
- }
-
- public bool TryGetMusicData(int index, out string name, out bool doesLoop)
- {
- name = null;
- doesLoop = false;
-
- if (_musicData.ContainsKey(index))
- {
- name = _musicData[index].Item1;
-
- doesLoop = _musicData[index].Item2;
-
- return true;
- }
-
- return false;
- }
-
- public override void ClearResources()
- {
- _musicData.Clear();
- }
- }
-}
diff --git a/src/ClassicUO.Assets/SpeechesLoader.cs b/src/ClassicUO.Assets/SpeechesLoader.cs
deleted file mode 100644
index be2412c5a..000000000
--- a/src/ClassicUO.Assets/SpeechesLoader.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class SpeechesLoader : UOFileLoader
- {
- private static SpeechesLoader _instance;
- private SpeechEntry[] _speech;
-
- private SpeechesLoader()
- {
- }
-
- public static SpeechesLoader Instance => _instance ?? (_instance = new SpeechesLoader());
-
- public override unsafe Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string path = UOFileManager.GetUOFilePath("speech.mul");
-
- if (!File.Exists(path))
- {
- _speech = Array.Empty();
-
- return;
- }
-
- UOFileMul file = new UOFileMul(path);
- List entries = new List();
-
- while (file.Position < file.Length)
- {
- int id = file.ReadUShortReversed();
- int length = file.ReadUShortReversed();
-
- if (length > 0)
- {
- entries.Add(new SpeechEntry(id, string.Intern(Encoding.UTF8.GetString((byte*) file.PositionAddress, length))));
-
- file.Skip(length);
- }
- }
-
- _speech = entries.ToArray();
- file.Dispose();
- }
- );
- }
-
- public bool IsMatch(string input, in SpeechEntry entry)
- {
- string[] split = entry.Keywords;
- //string[] words = input.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
-
- for (int i = 0; i < split.Length; i++)
- {
- if (split[i].Length > input.Length || split[i].Length == 0)
- {
- continue;
- }
-
- if (!entry.CheckStart)
- {
- if (input.IndexOf(split[i], 0, split[i].Length, StringComparison.InvariantCultureIgnoreCase) == -1)
- {
- continue;
- }
- }
-
- if (!entry.CheckEnd)
- {
- if (input.IndexOf(split[i], input.Length - split[i].Length, StringComparison.InvariantCultureIgnoreCase) == -1)
- {
- continue;
- }
- }
-
- int idx = input.IndexOf(split[i], StringComparison.InvariantCultureIgnoreCase);
- while (idx >= 0)
- {
- // "bank" or " bank" or "bank " or " bank " or "!bank" or "bank!"
- if ((idx - 1 < 0 || char.IsWhiteSpace(input[idx - 1]) || !char.IsLetter(input[idx - 1])) &&
- (idx + split[i].Length >= input.Length || char.IsWhiteSpace(input[idx + split[i].Length]) || !char.IsLetter(input[idx + split[i].Length]) ))
- {
- return true;
- }
-
-
-
- idx = input.IndexOf(split[i], idx + 1, StringComparison.InvariantCultureIgnoreCase);
- }
- }
-
- return false;
- }
-
- public List GetKeywords(string text)
- {
- List list = new List();
-
- if (UOFileManager.Version < ClientVersion.CV_305D)
- {
- return list;
- }
-
- text = text.TrimStart(' ').TrimEnd(' ');
-
- for (int i = 0; i < _speech.Length; i++)
- {
- SpeechEntry entry = _speech[i];
-
- if (IsMatch(text, in entry))
- {
- list.Add(entry);
- }
- }
-
- list.Sort();
-
- return list;
- }
- }
-
- public readonly struct SpeechEntry : IComparable
- {
- public SpeechEntry(int id, string keyword)
- {
- KeywordID = (short) id;
-
- Keywords = keyword.Split
- (
- new[]
- {
- '*'
- },
- StringSplitOptions.RemoveEmptyEntries
- );
-
- CheckStart = keyword.Length > 0 && keyword[0] == '*';
- CheckEnd = keyword.Length > 0 && keyword[keyword.Length - 1] == '*';
- }
-
- public string[] Keywords { get; }
-
- public short KeywordID { get; }
-
- public bool CheckStart { get; }
-
- public bool CheckEnd { get; }
-
- public int CompareTo(SpeechEntry obj)
- {
- if (KeywordID < obj.KeywordID)
- {
- return -1;
- }
-
- return KeywordID > obj.KeywordID ? 1 : 0;
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/TexmapsLoader.cs b/src/ClassicUO.Assets/TexmapsLoader.cs
deleted file mode 100644
index 3f769705c..000000000
--- a/src/ClassicUO.Assets/TexmapsLoader.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.IO;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class TexmapsLoader : UOFileLoader
- {
- private static TexmapsLoader _instance;
- private UOFile _file;
-
- public const int MAX_LAND_TEXTURES_DATA_INDEX_COUNT = 0x4000;
-
- private TexmapsLoader(int count) { }
-
- public static TexmapsLoader Instance =>
- _instance ?? (_instance = new TexmapsLoader(MAX_LAND_TEXTURES_DATA_INDEX_COUNT));
-
- public override Task Load()
- {
- return Task.Run(() =>
- {
- string path = UOFileManager.GetUOFilePath("texmaps.mul");
- string pathidx = UOFileManager.GetUOFilePath("texidx.mul");
-
- FileSystemHelper.EnsureFileExists(path);
- FileSystemHelper.EnsureFileExists(pathidx);
-
- _file = new UOFileMul(path, pathidx, MAX_LAND_TEXTURES_DATA_INDEX_COUNT, 10);
- _file.FillEntries(ref Entries);
- string pathdef = UOFileManager.GetUOFilePath("TexTerr.def");
-
- if (File.Exists(pathdef))
- {
- using (DefReader defReader = new DefReader(pathdef))
- {
- while (defReader.Next())
- {
- int index = defReader.ReadInt();
-
- if (index < 0 || index >= Entries.Length)
- {
- continue;
- }
-
- int[] group = defReader.ReadGroup();
-
- if (group == null)
- {
- continue;
- }
-
- for (int i = 0; i < group.Length; i++)
- {
- int checkindex = group[i];
-
- if (checkindex < 0 || checkindex >= Entries.Length)
- {
- continue;
- }
-
- Entries[index] = Entries[checkindex];
- }
- }
- }
- }
- });
- }
-
- public TexmapInfo GetTexmap(uint idx)
- {
- ref UOFileIndex entry = ref GetValidRefEntry((int)idx);
-
- if (entry.Length <= 0)
- {
- return default;
- }
-
- _file.SetData(entry.Address, entry.FileSize);
- _file.Seek(entry.Offset);
-
- var size = entry.Length == 0x2000 ? 64 : 128;
- var data = new uint[size * size];
-
- for (int i = 0; i < size; ++i)
- {
- int pos = i * size;
-
- for (int j = 0; j < size; ++j)
- {
- data[pos + j] = HuesHelper.Color16To32(_file.ReadUShort()) | 0xFF_00_00_00;
- }
- }
-
- return new TexmapInfo()
- {
- Pixels = data,
- Width = size,
- Height = size
- };
- }
- }
-
- public ref struct TexmapInfo
- {
- public Span Pixels;
- public int Width;
- public int Height;
- }
-}
diff --git a/src/ClassicUO.Assets/TileDataLoader.cs b/src/ClassicUO.Assets/TileDataLoader.cs
deleted file mode 100644
index 106cd6b00..000000000
--- a/src/ClassicUO.Assets/TileDataLoader.cs
+++ /dev/null
@@ -1,627 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using System;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class TileDataLoader : UOFileLoader
- {
- private static TileDataLoader _instance;
-
- private static StaticTiles[] _staticData;
- private static LandTiles[] _landData;
-
- private TileDataLoader()
- {
- }
-
- public static TileDataLoader Instance => _instance ?? (_instance = new TileDataLoader());
-
- public ref LandTiles[] LandData => ref _landData;
- public ref StaticTiles[] StaticData => ref _staticData;
-
- public override unsafe Task Load()
- {
- return Task.Run
- (
- () =>
- {
- string path = UOFileManager.GetUOFilePath("tiledata.mul");
-
- FileSystemHelper.EnsureFileExists(path);
-
- UOFileMul tileData = new UOFileMul(path);
-
-
- bool isold = UOFileManager.Version < ClientVersion.CV_7090;
- const int LAND_SIZE = 512;
-
- int land_group = isold ? Marshal.SizeOf() : Marshal.SizeOf();
- int static_group = isold ? Marshal.SizeOf() : Marshal.SizeOf();
- int staticscount = (int) ((tileData.Length - LAND_SIZE * land_group) / static_group);
-
- if (staticscount > 2048)
- {
- staticscount = 2048;
- }
-
- tileData.Seek(0);
-
- _landData = new LandTiles[ArtLoader.MAX_LAND_DATA_INDEX_COUNT];
- _staticData = new StaticTiles[staticscount * 32];
-
- byte* bufferString = stackalloc byte[20];
-
- for (int i = 0; i < 512; i++)
- {
- tileData.Skip(4);
-
- for (int j = 0; j < 32; j++)
- {
- if (tileData.Position + (isold ? 4 : 8) + 2 + 20 > tileData.Length)
- {
- goto END;
- }
-
- int idx = i * 32 + j;
- ulong flags = isold ? tileData.ReadUInt() : tileData.ReadULong();
- ushort textId = tileData.ReadUShort();
-
- for (int k = 0; k < 20; ++k)
- {
- bufferString[k] = tileData.ReadByte();
- }
-
- string name = string.Intern(Encoding.UTF8.GetString(bufferString, 20).TrimEnd('\0'));
-
- LandData[idx] = new LandTiles(flags, textId, name);
- }
- }
-
- END:
-
- for (int i = 0; i < staticscount; i++)
- {
- if (tileData.Position >= tileData.Length)
- {
- break;
- }
-
- tileData.Skip(4);
-
- for (int j = 0; j < 32; j++)
- {
- if (tileData.Position + (isold ? 4 : 8) + 13 + 20 > tileData.Length)
- {
- goto END_2;
- }
-
- int idx = i * 32 + j;
-
- ulong flags = isold ? tileData.ReadUInt() : tileData.ReadULong();
- byte weight = tileData.ReadByte();
- byte layer = tileData.ReadByte();
- int count = tileData.ReadInt();
- ushort animId = tileData.ReadUShort();
- ushort hue = tileData.ReadUShort();
- ushort lightIndex = tileData.ReadUShort();
- byte height = tileData.ReadByte();
-
- for (int k = 0; k < 20; ++k)
- {
- bufferString[k] = tileData.ReadByte();
- }
-
- string name = string.Intern(Encoding.UTF8.GetString(bufferString, 20).TrimEnd('\0'));
-
- StaticData[idx] = new StaticTiles
- (
- flags,
- weight,
- layer,
- count,
- animId,
- hue,
- lightIndex,
- height,
- name
- );
- }
- }
-
-
- //path = Path.Combine(FileManager.UoFolderPath, "tileart.uop");
-
- //if (File.Exists(path))
- //{
- // UOFileUop uop = new UOFileUop(path, ".bin");
- // DataReader reader = new DataReader();
- // for (int i = 0; i < uop.Entries.Length; i++)
- // {
- // long offset = uop.Entries[i].Offset;
- // int csize = uop.Entries[i].Length;
- // int dsize = uop.Entries[i].DecompressedLength;
-
- // if (offset == 0)
- // continue;
-
- // uop.Seek(offset);
- // byte[] cdata = uop.ReadArray(csize);
- // byte[] ddata = new byte[dsize];
-
- // ZLib.Decompress(cdata, 0, ddata, dsize);
-
- // reader.SetData(ddata, dsize);
-
- // ushort version = reader.ReadUShort();
- // uint stringDicOffset = reader.ReadUInt();
- // uint tileID = reader.ReadUInt();
-
- // reader.Skip(1 + // bool unk
- // 1 + // unk
- // 4 + // float unk
- // 4 + // float unk
- // 4 + // fixed zero ?
- // 4 + // old id ?
- // 4 + // unk
- // 4 + // unk
- // 1 + // unk
- // 4 + // 3F800000
- // 4 + // unk
- // 4 + // float light
- // 4 + // float light
- // 4 // unk
- // );
-
- // ulong flags = reader.ReadULong();
- // ulong flags2 = reader.ReadULong();
-
- // reader.Skip(4); // unk
-
- // reader.Skip(24); // EC IMAGE OFFSET
- // byte[] imageOffset = reader.ReadArray(24); // 2D IMAGE OFFSET
-
-
- // if (tileID + 0x4000 == 0xa28d)
- // {
- // TileFlag f = (TileFlag) flags;
-
- // }
-
- // int count = reader.ReadByte();
- // for (int j = 0; j < count; j++)
- // {
- // byte prop = reader.ReadByte();
- // uint value = reader.ReadUInt();
- // }
-
- // count = reader.ReadByte();
- // for (int j = 0; j < count; j++)
- // {
- // byte prop = reader.ReadByte();
- // uint value = reader.ReadUInt();
- // }
-
- // count = reader.ReadInt(); // Gold Silver
- // for (int j = 0; j < count; j++)
- // {
- // uint amount = reader.ReadUInt();
- // uint id = reader.ReadUInt();
- // }
-
- // count = reader.ReadInt();
-
- // for (int j = 0; j < count; j++)
- // {
- // byte val = reader.ReadByte();
-
- // if (val != 0)
- // {
- // if (val == 1)
- // {
- // byte unk = reader.ReadByte();
- // uint unk1 = reader.ReadUInt();
- // }
-
- // }
- // else
- // {
- // int subCount = reader.ReadInt();
-
- // for (int k = 0; k < subCount; k++)
- // {
- // uint unk = reader.ReadUInt();
- // uint unk1 = reader.ReadUInt();
- // }
- // }
- // }
-
- // count = reader.ReadByte();
-
- // if (count != 0)
- // {
- // uint unk = reader.ReadUInt();
- // uint unk1 = reader.ReadUInt();
- // uint unk2 = reader.ReadUInt();
- // uint unk3 = reader.ReadUInt();
- // }
-
-
- // if (StaticData[tileID].AnimID == 0)
- // {
- // //StaticData[tileID] = new StaticTiles(flags, 0, 0, 0, );
- // }
-
-
- // }
-
- // uop.Dispose();
- // reader.ReleaseData();
- //}
-
-
-
- END_2:
- tileData.Dispose();
- }
- );
- }
- }
-
- public struct LandTiles
- {
- public LandTiles(ulong flags, ushort textId, string name)
- {
- Flags = (TileFlag) flags;
- TexID = textId;
- Name = name;
- }
-
- public TileFlag Flags;
- public ushort TexID;
- public string Name;
-
- public bool IsWet => (Flags & TileFlag.Wet) != 0;
- public bool IsImpassable => (Flags & TileFlag.Impassable) != 0;
- public bool IsNoDiagonal => (Flags & TileFlag.NoDiagonal) != 0;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct LandGroup
- {
- public uint Unknown;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public LandTiles[] Tiles;
- }
-
- public struct StaticTiles
- {
- public StaticTiles
- (
- ulong flags,
- byte weight,
- byte layer,
- int count,
- ushort animId,
- ushort hue,
- ushort lightIndex,
- byte height,
- string name
- )
- {
- Flags = (TileFlag) flags;
- Weight = weight;
- Layer = layer;
- Count = count;
- AnimID = animId;
- Hue = hue;
- LightIndex = lightIndex;
- Height = height;
- Name = name;
- }
-
- public TileFlag Flags;
- public byte Weight;
- public byte Layer;
- public int Count;
- public ushort AnimID;
- public ushort Hue;
- public ushort LightIndex;
- public byte Height;
- public string Name;
-
- public bool IsAnimated => (Flags & TileFlag.Animation) != 0;
- public bool IsBridge => (Flags & TileFlag.Bridge) != 0;
- public bool IsImpassable => (Flags & TileFlag.Impassable) != 0;
- public bool IsSurface => (Flags & TileFlag.Surface) != 0;
- public bool IsWearable => (Flags & TileFlag.Wearable) != 0;
- public bool IsInternal => (Flags & TileFlag.Internal) != 0;
- public bool IsBackground => (Flags & TileFlag.Background) != 0;
- public bool IsNoDiagonal => (Flags & TileFlag.NoDiagonal) != 0;
- public bool IsWet => (Flags & TileFlag.Wet) != 0;
- public bool IsFoliage => (Flags & TileFlag.Foliage) != 0;
- public bool IsRoof => (Flags & TileFlag.Roof) != 0;
- public bool IsTranslucent => (Flags & TileFlag.Translucent) != 0;
- public bool IsPartialHue => (Flags & TileFlag.PartialHue) != 0;
- public bool IsStackable => (Flags & TileFlag.Generic) != 0;
- public bool IsTransparent => (Flags & TileFlag.Transparent) != 0;
- public bool IsContainer => (Flags & TileFlag.Container) != 0;
- public bool IsDoor => (Flags & TileFlag.Door) != 0;
- public bool IsWall => (Flags & TileFlag.Wall) != 0;
- public bool IsLight => (Flags & TileFlag.LightSource) != 0;
- public bool IsNoShoot => (Flags & TileFlag.NoShoot) != 0;
- public bool IsWeapon => (Flags & TileFlag.Weapon) != 0;
- public bool IsMultiMovable => (Flags & TileFlag.MultiMovable) != 0;
- public bool IsWindow => (Flags & TileFlag.Window) != 0;
- }
-
- // old
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct LandGroupOld
- {
- public uint Unknown;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public LandTilesOld[] Tiles;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct LandTilesOld
- {
- public uint Flags;
- public ushort TexID;
- [MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
- public string Name;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct StaticGroupOld
- {
- public uint Unk;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public StaticTilesOld[] Tiles;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct StaticTilesOld
- {
- public uint Flags;
- public byte Weight;
- public byte Layer;
- public int Count;
- public ushort AnimID;
- public ushort Hue;
- public ushort LightIndex;
- public byte Height;
- [MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
- public string Name;
- }
-
- // new
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct LandGroupNew
- {
- public uint Unknown;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public LandTilesNew[] Tiles;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct LandTilesNew
- {
- public TileFlag Flags;
- public ushort TexID;
- [MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
- public string Name;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct StaticGroupNew
- {
- public uint Unk;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- public StaticTilesNew[] Tiles;
- }
-
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct StaticTilesNew
- {
- public TileFlag Flags;
- public byte Weight;
- public byte Layer;
- public int Count;
- public ushort AnimID;
- public ushort Hue;
- public ushort LightIndex;
- public byte Height;
- [MarshalAs(UnmanagedType.LPStr, SizeConst = 20)]
- public string Name;
- }
-
- [Flags]
- public enum TileFlag : ulong
- {
- ///
- /// Nothing is flagged.
- ///
- None = 0x00000000,
- ///
- /// Not yet documented.
- ///
- Background = 0x00000001,
- ///
- /// Not yet documented.
- ///
- Weapon = 0x00000002,
- ///
- /// Not yet documented.
- ///
- Transparent = 0x00000004,
- ///
- /// The tile is rendered with partial alpha-transparency.
- ///
- Translucent = 0x00000008,
- ///
- /// The tile is a wall.
- ///
- Wall = 0x00000010,
- ///
- /// The tile can cause damage when moved over.
- ///
- Damaging = 0x00000020,
- ///
- /// The tile may not be moved over or through.
- ///
- Impassable = 0x00000040,
- ///
- /// Not yet documented.
- ///
- Wet = 0x00000080,
- ///
- /// Unknown.
- ///
- Unknown1 = 0x00000100,
- ///
- /// The tile is a surface. It may be moved over, but not through.
- ///
- Surface = 0x00000200,
- ///
- /// The tile is a stair, ramp, or ladder.
- ///
- Bridge = 0x00000400,
- ///
- /// The tile is stackable
- ///
- Generic = 0x00000800,
- ///
- /// The tile is a window. Like , tiles with this flag block line of sight.
- ///
- Window = 0x00001000,
- ///
- /// The tile blocks line of sight.
- ///
- NoShoot = 0x00002000,
- ///
- /// For single-amount tiles, the string "a " should be prepended to the tile name.
- ///
- ArticleA = 0x00004000,
- ///
- /// For single-amount tiles, the string "an " should be prepended to the tile name.
- ///
- ArticleAn = 0x00008000,
- ///
- /// Not yet documented.
- ///
- Internal = 0x00010000,
- ///
- /// The tile becomes translucent when walked behind. Boat masts also have this flag.
- ///
- Foliage = 0x00020000,
- ///
- /// Only gray pixels will be hued
- ///
- PartialHue = 0x00040000,
- ///
- /// Unknown.
- ///
- NoHouse = 0x00080000,
- ///
- /// The tile is a map--in the cartography sense. Unknown usage.
- ///
- Map = 0x00100000,
- ///
- /// The tile is a container.
- ///
- Container = 0x00200000,
- ///
- /// The tile may be equiped.
- ///
- Wearable = 0x00400000,
- ///
- /// The tile gives off light.
- ///
- LightSource = 0x00800000,
- ///
- /// The tile is animated.
- ///
- Animation = 0x01000000,
- ///
- /// Gargoyles can fly over
- ///
- NoDiagonal = 0x02000000,
- ///
- /// Unknown.
- ///
- Unknown2 = 0x04000000,
- ///
- /// Not yet documented.
- ///
- Armor = 0x08000000,
- ///
- /// The tile is a slanted roof.
- ///
- Roof = 0x10000000,
- ///
- /// The tile is a door. Tiles with this flag can be moved through by ghosts and GMs.
- ///
- Door = 0x20000000,
- ///
- /// Not yet documented.
- ///
- StairBack = 0x40000000,
- ///
- /// Not yet documented.
- ///
- StairRight = 0x80000000,
- /// Blend Alphas, tile blending.
- AlphaBlend = 0x0100000000,
- /// Uses new art style?
- UseNewArt = 0x0200000000,
- /// Has art being used?
- ArtUsed = 0x0400000000,
- /// Disallow shadow on this tile, lightsource? lava?
- NoShadow = 0x1000000000,
- /// Let pixels bleed in to other tiles? Is this Disabling Texture Clamp?
- PixelBleed = 0x2000000000,
- /// Play tile animation once.
- PlayAnimOnce = 0x4000000000,
- /// Movable multi? Cool ships and vehicles etc?
- MultiMovable = 0x10000000000
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/TrueTypeLoader.cs b/src/ClassicUO.Assets/TrueTypeLoader.cs
deleted file mode 100644
index 2477fb800..000000000
--- a/src/ClassicUO.Assets/TrueTypeLoader.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-#region license
-
-// Copyright (c) 2021, jaedan
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using FontStashSharp;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public class TrueTypeLoader
- {
- public const string EMBEDDED_FONT = "Roboto-Regular";
-
- private Dictionary _fonts = new();
-
- private TrueTypeLoader()
- {
- }
-
- private static TrueTypeLoader _instance;
- public static TrueTypeLoader Instance => _instance ??= new TrueTypeLoader();
-
- public Task Load()
- {
- var settings = new FontSystemSettings
- {
- FontResolutionFactor = 1,
- KernelWidth = 1,
- KernelHeight = 1
- };
-
- string _fontPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Fonts");
-
- if (!Directory.Exists(_fontPath))
- Directory.CreateDirectory(_fontPath);
-
- foreach (var ttf in Directory.GetFiles(_fontPath, "*.ttf"))
- {
- var fontSystem = new FontSystem(settings);
- fontSystem.AddFont(File.ReadAllBytes(ttf));
-
- _fonts[Path.GetFileNameWithoutExtension(ttf)] = fontSystem;
- }
-
- if (!_fonts.ContainsKey("Roboto-Regular"))
- {
- var assembly = this.GetType().Assembly;
- var resourceName = assembly.GetName().Name + ".Roboto-Regular.ttf";
- System.Console.WriteLine(resourceName);
- Stream stream = assembly.GetManifestResourceStream(resourceName);
- if (stream != null)
- {
- var memoryStream = new MemoryStream();
-
- stream.CopyTo(memoryStream);
- var fontSystem = new FontSystem(settings);
- fontSystem.AddFont(memoryStream.ToArray());
- _fonts["Roboto-Regular"] = fontSystem;
- }
- }
-
- return Task.CompletedTask;
- }
-
- public SpriteFontBase GetFont(string name, float size)
- {
- if (_fonts.TryGetValue(name, out var font))
- {
- return font.GetFont(size);
- }
-
- if (_fonts.Count > 0)
- return _fonts.First().Value.GetFont(size);
-
- return null;
- }
-
- public SpriteFontBase GetFont(string name)
- {
- return GetFont(name, 12);
- }
-
- public string[] Fonts => _fonts.Keys.ToArray();
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Assets/UOFileManager.cs b/src/ClassicUO.Assets/UOFileManager.cs
deleted file mode 100644
index 3204ade05..000000000
--- a/src/ClassicUO.Assets/UOFileManager.cs
+++ /dev/null
@@ -1,395 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using ClassicUO.Utility.Platforms;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Threading.Tasks;
-
-namespace ClassicUO.Assets
-{
- public static class UOFileManager
- {
- public static string GetUOFilePath(string file)
- {
- if (!UOFilesOverrideMap.Instance.TryGetValue(file.ToLowerInvariant(), out string uoFilePath))
- {
- uoFilePath = Path.Combine(BasePath, file);
- }
-
- //If the file with the given name doesn't exist, check for it with alternative casing if not on windows
- if (!PlatformHelper.IsWindows && !File.Exists(uoFilePath))
- {
- FileInfo finfo = new FileInfo(uoFilePath);
- var dir = Path.GetFullPath(finfo.DirectoryName ?? BasePath);
-
- if (Directory.Exists(dir))
- {
- var files = Directory.GetFiles(dir);
- var matches = 0;
-
- foreach (var f in files)
- {
- if (string.Equals(f, uoFilePath, StringComparison.OrdinalIgnoreCase))
- {
- matches++;
- uoFilePath = f;
- }
- }
-
- if (matches > 1)
- {
- Log.Warn($"Multiple files with ambiguous case found for {file}, using {Path.GetFileName(uoFilePath)}. Check your data directory for duplicate files.");
- }
- }
- }
-
- return uoFilePath;
- }
-
- public static ClientVersion Version;
- public static string BasePath;
- public static bool IsUOPInstallation;
-
- public static void Load(ClientVersion version, string basePath, bool useVerdata, string lang)
- {
- Stopwatch stopwatch = Stopwatch.StartNew();
-
- Version = version;
- BasePath = basePath;
-
- UOFilesOverrideMap.Instance.Load(); // need to load this first so that it manages can perform the file overrides if needed
-
- IsUOPInstallation = Version >= ClientVersion.CV_7000 && File.Exists(GetUOFilePath("MainMisc.uop"));
-
- List tasks = new List
- {
- AnimationsLoader.Instance.Load(),
- AnimDataLoader.Instance.Load(),
- ArtLoader.Instance.Load(),
- MapLoader.Instance.Load(),
- ClilocLoader.Instance.Load(lang),
- GumpsLoader.Instance.Load(),
- FontsLoader.Instance.Load(),
- HuesLoader.Instance.Load(),
- TileDataLoader.Instance.Load(),
- MultiLoader.Instance.Load(),
- SkillsLoader.Instance.Load().ContinueWith(t => ProfessionLoader.Instance.Load()),
- TexmapsLoader.Instance.Load(),
- SpeechesLoader.Instance.Load(),
- LightsLoader.Instance.Load(),
- SoundsLoader.Instance.Load(),
- MultiMapLoader.Instance.Load(),
- PNGLoader.Instance.Load(),
- TrueTypeLoader.Instance.Load()
- };
-
- if (!Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(15)))
- {
- Log.Panic("Loading files timeout.");
- }
-
- Read_Art_def();
-
- UOFileMul verdata = Verdata.File;
-
- bool forceVerdata = Version < ClientVersion.CV_500A || verdata != null && verdata.Length != 0 && Verdata.Patches.Length != 0;
-
- if (!useVerdata && forceVerdata)
- {
- useVerdata = true;
- }
-
- Log.Trace($"Use verdata.mul: {(useVerdata ? "Yes" : "No")}");
-
- if (useVerdata)
- {
- if (verdata != null && Verdata.Patches.Length != 0)
- {
- Log.Info(">> PATCHING WITH VERDATA.MUL");
-
- for (int i = 0; i < Verdata.Patches.Length; i++)
- {
- ref UOFileIndex5D vh = ref Verdata.Patches[i];
- Log.Info($">>> patching FileID: {vh.FileID} - BlockID: {vh.BlockID}");
-
- if (vh.FileID == 0)
- {
- MapLoader.Instance.PatchMapBlock(vh.BlockID, vh.Position);
- }
- else if (vh.FileID == 2)
- {
- MapLoader.Instance.PatchStaticBlock(vh.BlockID, ((ulong) verdata.StartAddress.ToInt64() + vh.Position), vh.Length);
- }
- else if (vh.FileID == 4)
- {
- if (vh.BlockID < ArtLoader.Instance.Entries.Length)
- {
- ArtLoader.Instance.Entries[vh.BlockID] = new UOFileIndex
- (
- verdata.StartAddress,
- (uint) verdata.Length,
- vh.Position,
- (int) vh.Length,
- 0
- );
- }
- }
- else if (vh.FileID == 12)
- {
- GumpsLoader.Instance.Entries[vh.BlockID] = new UOFileIndex
- (
- verdata.StartAddress,
- (uint) verdata.Length,
- vh.Position,
- (int) vh.Length,
- 0,
- (short) (vh.GumpData >> 16),
- (short) (vh.GumpData & 0xFFFF)
- );
- }
- else if (vh.FileID == 14 && vh.BlockID < MultiLoader.Instance.Count)
- {
- MultiLoader.Instance.Entries[vh.BlockID] = new UOFileIndex
- (
- verdata.StartAddress,
- (uint) verdata.Length,
- vh.Position,
- (int) vh.Length,
- 0
- );
- }
- else if (vh.FileID == 16 && vh.BlockID < SkillsLoader.Instance.SkillsCount)
- {
- SkillEntry skill = SkillsLoader.Instance.Skills[(int) vh.BlockID];
-
- if (skill != null)
- {
- unsafe
- {
- StackDataReader reader = new StackDataReader(new ReadOnlySpan((byte*)verdata.StartAddress, (int) verdata.Length));
-
- skill.HasAction = reader.ReadUInt8() != 0;
- skill.Name = reader.ReadASCII((int)(vh.Length - 1));
-
- reader.Release();
- }
- }
- }
- else if (vh.FileID == 30)
- {
- verdata.Seek(0);
- verdata.Skip((int) vh.Position);
-
- if (vh.Length == 836)
- {
- int offset = (int) (vh.BlockID * 32);
-
- if (offset + 32 > TileDataLoader.Instance.LandData.Length)
- {
- continue;
- }
-
- verdata.ReadUInt();
-
- for (int j = 0; j < 32; j++)
- {
- ulong flags;
-
- if (Version < ClientVersion.CV_7090)
- {
- flags = verdata.ReadUInt();
- }
- else
- {
- flags = verdata.ReadULong();
- }
-
- TileDataLoader.Instance.LandData[offset + j] = new LandTiles(flags, verdata.ReadUShort(), verdata.ReadASCII(20));
- }
- }
- else if (vh.Length == 1188)
- {
- int offset = (int) ((vh.BlockID - 0x0200) * 32);
-
- if (offset + 32 > TileDataLoader.Instance.StaticData.Length)
- {
- continue;
- }
-
- verdata.ReadUInt();
-
- for (int j = 0; j < 32; j++)
- {
- ulong flags;
-
- if (Version < ClientVersion.CV_7090)
- {
- flags = verdata.ReadUInt();
- }
- else
- {
- flags = verdata.ReadULong();
- }
-
- TileDataLoader.Instance.StaticData[offset + j] = new StaticTiles
- (
- flags,
- verdata.ReadByte(),
- verdata.ReadByte(),
- verdata.ReadInt(),
- verdata.ReadUShort(),
- verdata.ReadUShort(),
- verdata.ReadUShort(),
- verdata.ReadByte(),
- verdata.ReadASCII(20)
- );
- }
- }
- }
- else if (vh.FileID == 32)
- {
- if (vh.BlockID < HuesLoader.Instance.HuesCount)
- {
- VerdataHuesGroup group = Marshal.PtrToStructure(verdata.StartAddress + (int) vh.Position);
-
- HuesGroup[] hues = HuesLoader.Instance.HuesRange;
-
- hues[vh.BlockID].Header = group.Header;
-
- for (int j = 0; j < 8; j++)
- {
- Array.Copy(group.Entries[j].ColorTable, hues[vh.BlockID].Entries[j].ColorTable, 32);
- }
- }
- }
- else if (vh.FileID != 5 && vh.FileID != 6)
- {
- Log.Warn($"Unused verdata block\tFileID: {vh.FileID}\tBlockID: {vh.BlockID}");
- }
- }
-
- Log.Info("<< PATCHED.");
- }
- }
-
-
- Log.Trace($"Files loaded in: {stopwatch.ElapsedMilliseconds} ms!");
- stopwatch.Stop();
- }
-
- public static void MapLoaderReLoad(MapLoader newloader)
- {
- MapLoader.Instance?.Dispose();
- MapLoader.Instance = newloader;
- }
-
- private static void Read_Art_def()
- {
- string pathdef = GetUOFilePath("art.def");
-
- if (File.Exists(pathdef))
- {
- TileDataLoader tiledataLoader = TileDataLoader.Instance;
- ArtLoader artLoader = ArtLoader.Instance;
-
- using (DefReader reader = new DefReader(pathdef, 1))
- {
- while (reader.Next())
- {
- int index = reader.ReadInt();
-
- if (index < 0 || index >= ArtLoader.MAX_LAND_DATA_INDEX_COUNT + tiledataLoader.StaticData.Length)
- {
- continue;
- }
-
- int[] group = reader.ReadGroup();
-
- if (group == null)
- {
- continue;
- }
-
- for (int i = 0; i < group.Length; i++)
- {
- int checkIndex = group[i];
-
- if (checkIndex < 0 || checkIndex >= ArtLoader.MAX_LAND_DATA_INDEX_COUNT + tiledataLoader.StaticData.Length)
- {
- continue;
- }
-
- if (index < artLoader.Entries.Length && checkIndex < artLoader.Entries.Length)
- {
- ref UOFileIndex currentEntry = ref artLoader.GetValidRefEntry(index);
- ref UOFileIndex checkEntry = ref artLoader.GetValidRefEntry(checkIndex);
-
- if (currentEntry.Equals(UOFileIndex.Invalid) && !checkEntry.Equals(UOFileIndex.Invalid))
- {
- artLoader.Entries[index] = artLoader.Entries[checkIndex];
- }
- }
-
- if (index < ArtLoader.MAX_LAND_DATA_INDEX_COUNT &&
- checkIndex < ArtLoader.MAX_LAND_DATA_INDEX_COUNT &&
- checkIndex < tiledataLoader.LandData.Length &&
- index < tiledataLoader.LandData.Length &&
- !tiledataLoader.LandData[checkIndex].Equals(default) &&
- tiledataLoader.LandData[index].Equals(default))
- {
- tiledataLoader.LandData[index] = tiledataLoader.LandData[checkIndex];
-
- break;
- }
-
- if (index >= ArtLoader.MAX_LAND_DATA_INDEX_COUNT && checkIndex >= ArtLoader.MAX_LAND_DATA_INDEX_COUNT &&
- index < tiledataLoader.StaticData.Length && checkIndex < tiledataLoader.StaticData.Length &&
- tiledataLoader.StaticData[index].Equals(default) && !tiledataLoader.StaticData[checkIndex].Equals(default))
- {
- tiledataLoader.StaticData[index] = tiledataLoader.StaticData[checkIndex];
-
- break;
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/src/ClassicUO.Assets/Verdata.cs b/src/ClassicUO.Assets/Verdata.cs
deleted file mode 100644
index 1abcde70f..000000000
--- a/src/ClassicUO.Assets/Verdata.cs
+++ /dev/null
@@ -1,96 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.IO;
-using System.Runtime.CompilerServices;
-
-namespace ClassicUO.Assets
-{
- public static class Verdata
- {
- unsafe static Verdata()
- {
- string path = UOFileManager.GetUOFilePath("verdata.mul");
-
- if (!System.IO.File.Exists(path))
- {
- Patches = new UOFileIndex5D[0];
- File = null;
- }
- else
- {
- File = new UOFileMul(path);
-
- // the scope of this try/catch is to avoid unexpected crashes if servers redestribuite wrong verdata
- try
- {
- int len = File.ReadInt();
- Patches = new UOFileIndex5D[len];
-
- fixed (UOFileIndex5D* ptr = Patches)
- {
- Unsafe.CopyBlockUnaligned((void*)ptr, (void*) File.PositionAddress, (uint) (len * Unsafe.SizeOf()));
- }
- }
- catch
- {
- Patches = new UOFileIndex5D[0];
- }
- }
- }
-
- // FileIDs
- //0 - map0.mul
- //1 - staidx0.mul
- //2 - statics0.mul
- //3 - artidx.mul
- //4 - art.mul
- //5 - anim.idx
- //6 - anim.mul
- //7 - soundidx.mul
- //8 - sound.mul
- //9 - texidx.mul
- //10 - texmaps.mul
- //11 - gumpidx.mul
- //12 - gumps.mul
- //13 - multi.idx
- //14 - multi.mul
- //15 - skills.idx
- //16 - skills.mul
- //30 - tiledata.mul
- //31 - animdata.mul
-
- public static UOFileIndex5D[] Patches { get; }
-
- public static UOFileMul File { get; }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Client/CUOEnviroment.cs b/src/ClassicUO.Client/CUOEnviroment.cs
deleted file mode 100644
index 04fc42f3c..000000000
--- a/src/ClassicUO.Client/CUOEnviroment.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using System;
-using System.IO;
-using System.Reflection;
-using System.Threading;
-
-namespace ClassicUO
-{
- internal static class CUOEnviroment
- {
- public static Thread GameThread;
- public static float DPIScaleFactor = 1.0f;
- public static bool NoSound;
- public static string[] Args;
- public static string[] Plugins;
- public static bool Debug;
- public static bool IsHighDPI;
- public static uint CurrentRefreshRate;
- public static bool SkipLoginScreen;
- public static bool IsOutlands;
- public static bool NoServerPing;
- public static Assembly Assembly => Assembly.GetEntryAssembly();
-
- public static readonly bool IsUnix = Environment.OSVersion.Platform != PlatformID.Win32NT && Environment.OSVersion.Platform != PlatformID.Win32Windows && Environment.OSVersion.Platform != PlatformID.Win32S && Environment.OSVersion.Platform != PlatformID.WinCE;
-
- public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version;
- public static readonly string ExecutablePath =
-#if NETFRAMEWORK
- Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
-#else
- Environment.CurrentDirectory;
-#endif
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Client/ClassicUO.Client.csproj b/src/ClassicUO.Client/ClassicUO.Client.csproj
deleted file mode 100644
index e37413e13..000000000
--- a/src/ClassicUO.Client/ClassicUO.Client.csproj
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
- WinExe
- cuoicon.ico
- ClassicUO
- ClassicUO
- 3.19.0
- 3.19.0
-
-
-
- $(ProjectDir)..\..\bin\Release\
- $(ProjectDir)..\..\bin\dist\
- true
-
-
-
- $(ProjectDir)..\..\bin\Debug\
- $(DefineConstants)TRACE
-
-
-
- WinExe
-
-
-
-
- <_Parameter1>ClassicUO.UnitTests
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- ResErrorMessages.resx
-
-
- True
- True
- ResGeneral.resx
-
-
- True
- True
- ResGumps.resx
-
-
-
-
-
- PublicResXFileCodeGenerator
- ResErrorMessages.Designer.cs
-
-
- PublicResXFileCodeGenerator
- ResGeneral.Designer.cs
-
-
- PublicResXFileCodeGenerator
- ResGumps.Designer.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\..\external\cuoapi\cuoapi.dll
-
-
- ..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Net.Http.dll
-
-
- ..\..\..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\System.Windows.Forms.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ClassicUO.Client/Client.cs b/src/ClassicUO.Client/Client.cs
deleted file mode 100644
index 902899366..000000000
--- a/src/ClassicUO.Client/Client.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.Assets;
-using ClassicUO.Configuration;
-using ClassicUO.Game;
-using ClassicUO.Game.Data;
-using ClassicUO.Network;
-using ClassicUO.Network.Encryption;
-using ClassicUO.Resources;
-using ClassicUO.Utility;
-using ClassicUO.Utility.Logging;
-using ClassicUO.Utility.Platforms;
-using SDL2;
-using System;
-using System.Diagnostics;
-using System.IO;
-
-namespace ClassicUO
-{
- internal static class Client
- {
- public static ClientVersion Version { get; private set; }
- public static ClientFlags Protocol { get; set; }
- public static string ClientPath { get; private set; }
- public static GameController Game { get; private set; }
-
-
- public static void Run()
- {
- Debug.Assert(Game == null);
-
- ScriptCompiler.InvokeAfterCompiling("Configure");
-
- Load();
-
- Log.Trace("Running game...");
-
- using (Game = new GameController())
- {
- // https://github.com/FNA-XNA/FNA/wiki/7:-FNA-Environment-Variables#fna_graphics_enable_highdpi
- CUOEnviroment.IsHighDPI = Environment.GetEnvironmentVariable("FNA_GRAPHICS_ENABLE_HIGHDPI") == "1";
-
- if (CUOEnviroment.IsHighDPI)
- {
- Log.Trace("HIGH DPI - ENABLED");
- }
-
- Log.Trace("Loading plugins...");
-
- foreach (string p in Settings.GlobalSettings.Plugins)
- {
- Plugin.Create(p);
- }
-
- Log.Trace("Done!");
-
- UoAssist.Start();
-
- ScriptCompiler.InvokeAfterCompiling("Initialize");
-
- Game.Run();
- }
-
- Log.Trace("Exiting game...");
- }
-
- public static void ShowErrorMessage(string msg)
- {
- SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR, "ERROR", msg, IntPtr.Zero);
- }
-
-
- private static void Load()
- {
- string clientPath = Settings.GlobalSettings.UltimaOnlineDirectory;
- Log.Trace($"Ultima Online installation folder: {clientPath}");
-
- Log.Trace("Loading files...");
-
- if (!string.IsNullOrWhiteSpace(Settings.GlobalSettings.ClientVersion))
- {
- // sanitize client version
- Settings.GlobalSettings.ClientVersion = Settings.GlobalSettings.ClientVersion.Replace(",", ".").Replace(" ", "").ToLower();
- }
-
- string clientVersionText = Settings.GlobalSettings.ClientVersion;
-
- // check if directory is good
- if (!Directory.Exists(clientPath))
- {
- Log.Error("Invalid client directory: " + clientPath);
- ShowErrorMessage(string.Format(ResErrorMessages.ClientPathIsNotAValidUODirectory, clientPath));
-
- throw new InvalidClientDirectory($"'{clientPath}' is not a valid directory");
- }
-
- // try to load the client version
- if (!ClientVersionHelper.IsClientVersionValid(clientVersionText, out ClientVersion clientVersion))
- {
- Log.Warn($"Client version [{clientVersionText}] is invalid, let's try to read the client.exe");
-
- // mmm something bad happened, try to load from client.exe
- if (!ClientVersionHelper.TryParseFromFile(Path.Combine(clientPath, "client.exe"), out clientVersionText) || !ClientVersionHelper.IsClientVersionValid(clientVersionText, out clientVersion))
- {
- Log.Error("Invalid client version: " + clientVersionText);
- ShowErrorMessage(string.Format(ResGumps.ImpossibleToDefineTheClientVersion0, clientVersionText));
-
- throw new InvalidClientVersion($"Invalid client version: '{clientVersionText}'");
- }
-
- Log.Trace($"Found a valid client.exe [{clientVersionText} - {clientVersion}]");
-
- // update the wrong/missing client version in settings.json
- Settings.GlobalSettings.ClientVersion = clientVersionText;
- }
-
- Version = clientVersion;
- ClientPath = clientPath;
-
- Protocol = ClientFlags.CF_T2A;
-
- if (Version >= ClientVersion.CV_200)
- {
- Protocol |= ClientFlags.CF_RE;
- }
-
- if (Version >= ClientVersion.CV_300)
- {
- Protocol |= ClientFlags.CF_TD;
- }
-
- if (Version >= ClientVersion.CV_308)
- {
- Protocol |= ClientFlags.CF_LBR;
- }
-
- if (Version >= ClientVersion.CV_308Z)
- {
- Protocol |= ClientFlags.CF_AOS;
- }
-
- if (Version >= ClientVersion.CV_405A)
- {
- Protocol |= ClientFlags.CF_SE;
- }
-
- if (Version >= ClientVersion.CV_60144)
- {
- Protocol |= ClientFlags.CF_SA;
- }
-
- Log.Trace($"Client path: '{clientPath}'");
- Log.Trace($"Client version: {clientVersion}");
- Log.Trace($"Protocol: {Protocol}");
-
- // ok now load uo files
- UOFileManager.Load(Version, Settings.GlobalSettings.UltimaOnlineDirectory, Settings.GlobalSettings.UseVerdata, Settings.GlobalSettings.Language);
- StaticFilters.Load();
-
- BuffTable.Load();
- ChairTable.Load();
-
- Log.Trace("Network calibration...");
- //ATTENTION: you will need to enable ALSO ultimalive server-side, or this code will have absolutely no effect!
- UltimaLive.Enable();
- PacketsTable.AdjustPacketSizeByVersion(Version);
-
- if (Settings.GlobalSettings.Encryption != 0)
- {
- Log.Trace("Calculating encryption by client version...");
- EncryptionHelper.CalculateEncryption(Version);
- Log.Trace($"encryption: {EncryptionHelper.Type}");
-
- if (EncryptionHelper.Type != (ENCRYPTION_TYPE)Settings.GlobalSettings.Encryption)
- {
- Log.Warn($"Encryption found: {EncryptionHelper.Type}");
- Settings.GlobalSettings.Encryption = (byte)EncryptionHelper.Type;
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Client/ClientException.cs b/src/ClassicUO.Client/ClientException.cs
deleted file mode 100644
index 11b2df6ca..000000000
--- a/src/ClassicUO.Client/ClientException.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using System;
-
-namespace ClassicUO
-{
- internal class InvalidClientVersion : Exception
- {
- public InvalidClientVersion(string msg) : base(msg)
- {
- }
- }
-
- internal class InvalidClientDirectory : Exception
- {
- public InvalidClientDirectory(string msg) : base(msg)
- {
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Client/Configuration/ConfigurationResolver.cs b/src/ClassicUO.Client/Configuration/ConfigurationResolver.cs
deleted file mode 100644
index e5074fe07..000000000
--- a/src/ClassicUO.Client/Configuration/ConfigurationResolver.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using System.IO;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Text.RegularExpressions;
-using ClassicUO.Utility.Logging;
-
-namespace ClassicUO.Configuration
-{
- internal static class ConfigurationResolver
- {
- public static T Load(string file, JsonSerializerContext ctx) where T : class
- {
- if (!File.Exists(file))
- {
- Log.Warn(file + " not found.");
-
- return null;
- }
-
- var text = File.ReadAllText(file);
-
- text = Regex.Replace
- (
- text,
- @"(?(T obj, string file, JsonSerializerContext ctx) where T : class
- {
- // this try catch is necessary when multiples cuo instances points to this file.
- try
- {
- var fileInfo = new FileInfo(file);
-
- if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
- {
- fileInfo.Directory.Create();
- }
-
- var json = JsonSerializer.Serialize(obj, typeof(T), ctx);
- File.WriteAllText(file, json);
- }
- catch (IOException e)
- {
- Log.Error(e.ToString());
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Client/Configuration/Json/FNAPointJsonConverter.cs b/src/ClassicUO.Client/Configuration/Json/FNAPointJsonConverter.cs
deleted file mode 100644
index 3153f754d..000000000
--- a/src/ClassicUO.Client/Configuration/Json/FNAPointJsonConverter.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-using System;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using Microsoft.Xna.Framework;
-
-namespace ClassicUO.Configuration.Json
-{
- sealed class Point2Converter : JsonConverter
- {
- public override Point Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- if (reader.TokenType != JsonTokenType.StartObject)
- {
- return Point.Zero;
- }
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.PropertyName)
- {
- return Point.Zero;
- }
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.Number)
- {
- return Point.Zero;
- }
-
- var point = new Point();
-
- point.X = reader.GetInt32();
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.PropertyName)
- {
- return Point.Zero;
- }
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.Number)
- {
- return Point.Zero;
- }
-
- point.Y = reader.GetInt32();
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.EndObject)
- {
- return Point.Zero;
- }
-
- return point;
- }
-
- public override void Write(Utf8JsonWriter writer, Point value, JsonSerializerOptions options)
- {
- writer.WriteStartObject();
- writer.WriteNumber("X", value.X);
- writer.WriteNumber("Y", value.Y);
- writer.WriteEndObject();
- }
- }
-
- sealed class NullablePoint2Converter : JsonConverter
- {
- public override Point? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
- {
- if (reader.TokenType != JsonTokenType.StartObject)
- {
- return Point.Zero;
- }
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.PropertyName)
- {
- return Point.Zero;
- }
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.Number)
- {
- return Point.Zero;
- }
-
- var point = new Point();
-
- point.X = reader.GetInt32();
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.PropertyName)
- {
- return Point.Zero;
- }
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.Number)
- {
- return Point.Zero;
- }
-
- point.Y = reader.GetInt32();
-
- reader.Read();
-
- if (reader.TokenType != JsonTokenType.EndObject)
- {
- return Point.Zero;
- }
-
- return point;
- }
-
- public override void Write(Utf8JsonWriter writer, Point? value, JsonSerializerOptions options)
- {
- writer.WriteStartObject();
- writer.WriteNumber("X", value.Value.X);
- writer.WriteNumber("Y", value.Value.Y);
- writer.WriteEndObject();
- }
- }
-}
\ No newline at end of file
diff --git a/src/ClassicUO.Client/Configuration/Language.cs b/src/ClassicUO.Client/Configuration/Language.cs
deleted file mode 100644
index 80afb8117..000000000
--- a/src/ClassicUO.Client/Configuration/Language.cs
+++ /dev/null
@@ -1,575 +0,0 @@
-using System.IO;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace ClassicUO.Configuration
-{
- public class Language
- {
- public ModernOptionsGumpLanguage GetModernOptionsGumpLanguage { get; set; } = new ModernOptionsGumpLanguage();
- public ErrorsLanguage ErrorsLanguage { get; set; } = new ErrorsLanguage();
- public MapLanguage MapLanguage { get; set; } = new MapLanguage();
-
- [JsonIgnore]
- public static Language Instance { get; private set; } = new Language();
-
- public static void Load()
- {
- if (File.Exists(languageFilePath))
- {
- Language f = JsonSerializer.Deserialize(File.ReadAllText(languageFilePath));
- Instance = f;
- Save(); //To update language file with new additions as needed
- }
- else
- {
- CreateNewLanguageFile();
- }
- }
-
- private static void CreateNewLanguageFile()
- {
- Directory.CreateDirectory(Path.Combine(CUOEnviroment.ExecutablePath, "Data"));
-
- string defaultLanguage = JsonSerializer.Serialize(Instance, new JsonSerializerOptions() { WriteIndented = true });
- File.WriteAllText(languageFilePath, defaultLanguage);
- }
-
- private static void Save()
- {
- string language = JsonSerializer.Serialize(Instance, new JsonSerializerOptions() { WriteIndented = true });
- File.WriteAllText(languageFilePath, language);
- }
-
- private static string languageFilePath { get { return Path.Combine(CUOEnviroment.ExecutablePath, "Data", "Language.json"); } }
- }
-
- public class ModernOptionsGumpLanguage
- {
- public string OptionsTitle { get; set; } = "Options";
- public string Search { get; set; } = "Search";
-
- public string ButtonGeneral { get; set; } = "General";
- public string ButtonSound { get; set; } = "Sound";
- public string ButtonVideo { get; set; } = "Video";
- public string ButtonMacros { get; set; } = "Macros";
- public string ButtonTooltips { get; set; } = "Tooltips";
- public string ButtonSpeech { get; set; } = "Speech";
- public string ButtonCombatSpells { get; set; } = "Combat & Spells";
- public string ButtonCounters { get; set; } = "Counters";
- public string ButtonInfobar { get; set; } = "Infobar";
- public string ButtonContainers { get; set; } = "Containers";
- public string ButtonExperimental { get; set; } = "Experimental";
- public string ButtonIgnoreList { get; set; } = "Ignore List";
- public string ButtonNameplates { get; set; } = "Nameplate Options";
- public string ButtonCooldowns { get; set; } = "Cooldown bars";
- public string ButtonTazUO { get; set; } = "TazUO Specific";
- public string ButtonMobiles { get; set; } = "Mobiles";
- public string ButtonGumpContext { get; set; } = "Gumps & Context";
- public string ButtonMisc { get; set; } = "Misc";
- public string ButtonTerrainStatics { get; set; } = "Terrain & Statics";
- public string ButtonGameWindow { get; set; } = "Game window";
- public string ButtonZoom { get; set; } = "Zoom";
- public string ButtonLighting { get; set; } = "Lighting";
- public string ButtonShadows { get; set; } = "Shadows";
-
- public General GetGeneral { get; set; } = new General();
- public Video GetVideo { get; set; } = new Video();
- public Sound GetSound { get; set; } = new Sound();
- public Macros GetMacros { get; set; } = new Macros();
- public ToolTips GetToolTips { get; set; } = new ToolTips();
- public Speech GetSpeech { get; set; } = new Speech();
- public CombatSpells GetCombatSpells { get; set; } = new CombatSpells();
- public Counters GetCounters { get; set; } = new Counters();
- public InfoBars GetInfoBars { get; set; } = new InfoBars();
- public Containers GetContainers { get; set; } = new Containers();
- public Experimental GetExperimental { get; set; } = new Experimental();
- public NamePlates GetNamePlates { get; set; } = new NamePlates();
- public Cooldowns GetCooldowns { get; set; } = new Cooldowns();
- public TazUO GetTazUO { get; set; } = new TazUO();
-
- public class General
- {
- public string SharedNone { get; set; } = "None";
- public string SharedShift { get; set; } = "Shift";
- public string SharedCtrl { get; set; } = "Ctrl";
-
- #region General->General
- public string HighlightObjects { get; set; } = "Highlight objects under cursor";
- public string Pathfinding { get; set; } = "Enable pathfinding";
- public string ShiftPathfinding { get; set; } = "Use shift for pathfinding";
- public string SingleClickPathfind { get; set; } = "Single click for pathfinding";
- public string AlwaysRun { get; set; } = "Always run";
- public string RunUnlessHidden { get; set; } = "Unless hidden";
- public string AutoOpenDoors { get; set; } = "Automatically open doors";
- public string AutoOpenPathfinding { get; set; } = "Open doors while pathfinding";
- public string AutoOpenCorpse { get; set; } = "Automatically open corpses";
- public string CorpseOpenDistance { get; set; } = "Corpse open distance";
- public string CorpseSkipEmpty { get; set; } = "Skip empty corpses";
- public string CorpseOpenOptions { get; set; } = "Corpse open options";
- public string CorpseOptNone { get; set; } = "None";
- public string CorpseOptNotTarg { get; set; } = "Not targeting";
- public string CorpseOptNotHiding { get; set; } = "Not hiding";
- public string CorpseOptBoth { get; set; } = "Both";
- public string OutRangeColor { get; set; } = "No color for out of range objects";
- public string SallosEasyGrab { get; set; } = "Enable sallos easy grab";
- public string SallosTooltip { get; set; } = "Sallos easy grab is not recommended with grid containers enabled.";
- public string ShowHouseContent { get; set; } = "Show house content";
- public string SmoothBoat { get; set; } = "Smooth boat movements";
- #endregion
-
- #region General->Mobiles
- public string ShowMobileHP { get; set; } = "Show mobile's HP";
- public string MobileHPType { get; set; } = "Type";
- public string HPTypePerc { get; set; } = "Percentage";
- public string HPTypeBar { get; set; } = "Bar";
- public string HPTypeNBoth { get; set; } = "Both";
- public string HPShowWhen { get; set; } = "Show when";
- public string HPShowWhen_Always { get; set; } = "Always";
- public string HPShowWhen_Less100 { get; set; } = "Less than 100%";
- public string HPShowWhen_Smart { get; set; } = "Smart";
- public string HighlightPoisoned { get; set; } = "Highlight poisoned mobiles";
- public string PoisonHighlightColor { get; set; } = "Highlight color";
- public string HighlightPara { get; set; } = "Highlight paralyzed mobiles";
- public string ParaHighlightColor { get; set; } = "Highlight color";
- public string HighlightInvul { get; set; } = "Highlight invulnerable mobiles";
- public string InvulHighlightColor { get; set; } = "Highlight color";
- public string IncomingMobiles { get; set; } = "Show incoming mobile names";
- public string IncomingCorpses { get; set; } = "Show incoming corpse names";
- public string AuraUnderFeet { get; set; } = "Show aura under feet";
- public string AuraOptDisabled { get; set; } = "Disabled";
- public string AuroOptWarmode { get; set; } = "Warmode";
- public string AuraOptCtrlShift { get; set; } = "Ctrl + Shift";
- public string AuraOptAlways { get; set; } = "Always";
- public string AuraForParty { get; set; } = "Use a custom color for party members";
- public string AuraPartyColor { get; set; } = "Party aura color";
- #endregion
-
- #region General->Gumps
- public string DisableTopMenu { get; set; } = "Disable top menu bar";
- public string AltForAnchorsGumps { get; set; } = "Require alt to close anchored gumps";
- public string AltToMoveGumps { get; set; } = "Require alt to move gumps";
- public string CloseEntireAnchorWithRClick { get; set; } = "Close entire group of anchored gumps with right click";
- public string OriginalSkillsGump { get; set; } = "Use original skills gump";
- public string OldStatusGump { get; set; } = "Use old status gump";
- public string PartyInviteGump { get; set; } = "Show party invite gump";
- public string ModernHealthBars { get; set; } = "Use modern health bar gumps";
- public string ModernHPBlackBG { get; set; } = "Use black background";
- public string SaveHPBars { get; set; } = "Save health bars on logout";
- public string CloseHPGumpsWhen { get; set; } = "Close health bars when";
- public string CloseHPOptDisable { get; set; } = "Disabled";
- public string CloseHPOptOOR { get; set; } = "Out of range";
- public string CloseHPOptDead { get; set; } = "Dead";
- public string CloseHPOptBoth { get; set; } = "Both";
- public string GridLoot { get; set; } = "Grid Loot";
- public string GridLootOptDisable { get; set; } = "Disabled";
- public string GridLootOptOnly { get; set; } = "Grid loot only";
- public string GridLootOptBoth { get; set; } = "Grid loot and normal container";
- public string GridLootTooltip { get; set; } = "This is not the same as Grid Containers, this is a simple grid gump used for looting corpses.";
- public string ShiftContext { get; set; } = "Require shift to open context menus";
- public string ShiftSplit { get; set; } = "Require shift to split stacks of items";
-
- #endregion
-
- #region General->Misc
- public string EnableCOT { get; set; } = "Enable circle of transparency";
- public string COTDistance { get; set; } = "Distance";
- public string COTType { get; set; } = "Type";
- public string COTTypeOptFull { get; set; } = "Full";
- public string COTTypeOptGrad { get; set; } = "Gradient";
- public string COTTypeOptModern { get; set; } = "Modern";
- public string HideScreenshotMessage { get; set; } = "Hide 'screenshot stored in' message";
- public string ObjFade { get; set; } = "Enable object fading";
- public string TextFade { get; set; } = "Enable text fading";
- public string CursorRange { get; set; } = "Show target range indicator";
- public string DragSelectHP { get; set; } = "Enable drag select for health bars";
- public string DragKeyMod { get; set; } = "Key modifier";
- public string DragPlayersOnly { get; set; } = "Players only";
- public string DragMobsOnly { get; set; } = "Monsters only";
- public string DragNameplatesOnly { get; set; } = "Visible nameplates only";
- public string DragX { get; set; } = "X Position of healthbars";
- public string DragY { get; set; } = "Y Position of healthbars";
- public string DragAnchored { get; set; } = "Anchor opened health bars together";
- public string ShowStatsChangedMsg { get; set; } = "Show stats changed messages";
- public string ShowSkillsChangedMsg { get; set; } = "Show skills changed messages";
- public string ChangeVolume { get; set; } = "Changed by";
- #endregion
-
- #region General->TerrainStatics
- public string HideRoof { get; set; } = "Hide roof tiles";
- public string TreesToStump { get; set; } = "Change trees to stumps";
- public string HideVegetation { get; set; } = "Hide vegetation";
- public string MagicFieldType { get; set; } = "Field types";
- public string MagicFieldOpt_Normal { get; set; } = "Normal";
- public string MagicFieldOpt_Static { get; set; } = "Static";
- public string MagicFieldOpt_Tile { get; set; } = "Tile";
- #endregion
- }
-
- public class Sound
- {
- public string SharedVolume { get; set; } = "Volume";
-
- public string EnableSound { get; set; } = "Enable sound";
- public string EnableMusic { get; set; } = "Enable music";
- public string LoginMusic { get; set; } = "Enable login page music";
- public string PlayFootsteps { get; set; } = "Play footsteps";
- public string CombatMusic { get; set; } = "Combat music";
- public string BackgroundMusic { get; set; } = "Play sound when UO is not in focus";
- }
-
- public class Video
- {
- #region GameWindow
- public string FPSCap { get; set; } = "FPS Cap";
- public string BackgroundFPS { get; set; } = "Reduce FPS when game is not in focus";
- public string FullsizeViewport { get; set; } = "Always use fullsize game world viewport";
- public string FullScreen { get; set; } = "Fullscreen window";
- public string LockViewport { get; set; } = "Lock game world viewport position/size";
- public string ViewportX { get; set; } = "Viewport position X";
- public string ViewportY { get; set; } = "Viewport position Y";
- public string ViewportW { get; set; } = "Viewport width";
- public string ViewportH { get; set; } = "Viewport height";
- #endregion
-
- #region Zoom
- public string DefaultZoom { get; set; } = "Default zoom";
- public string ZoomWheel { get; set; } = "Enable zooming with ctrl + mousewheel";
- public string ReturnDefaultZoom { get; set; } = "Return to default zoom after ctrl is released";
- #endregion
-
- #region Lighting
- public string AltLights { get; set; } = "Alternative lights";
- public string CustomLLevel { get; set; } = "Custom light level";
- public string Level { get; set; } = "Light level";
- public string LightType { get; set; } = "Light level type";
- public string LightType_Absolute { get; set; } = "Absolute";
- public string LightType_Minimum { get; set; } = "Minimum";
- public string DarkNight { get; set; } = "Dark nights";
- public string ColoredLight { get; set; } = "Colored lighting";
- #endregion
-
- #region Misc
- public string EnableDeathScreen { get; set; } = "Enable death screen";
- public string BWDead { get; set; } = "Black and white mode while dead";
- public string MouseThread { get; set; } = "Run mouse in seperate thread";
- public string TargetAura { get; set; } = "Aura on mouse target";
- public string AnimWater { get; set; } = "Animated water effect";
- #endregion
-
- #region Shadows
- public string EnableShadows { get; set; } = "Enable shadows";
- public string RockTreeShadows { get; set; } = "Rock and tree shadows";
- public string TerrainShadowLevel { get; set; } = "Terrain shadow level";
- #endregion
- }
-
- public class Macros
- {
- public string NewMacro { get; set; } = "New Macro";
- public string DelMacro { get; set; } = "Delete Macro";
- }
-
- public class ToolTips
- {
- public string EnableToolTips { get; set; } = "Enable tooltips";
- public string ToolTipDelay { get; set; } = "Tooltip delay";
- public string ToolTipBG { get; set; } = "Tooltip background opacity";
- public string ToolTipFont { get; set; } = "Default tooltip font color";
- }
-
- public class Speech
- {
- public string ScaleSpeechDelay { get; set; } = "Scale speech delay";
- public string SpeechDelay { get; set; } = "Delay";
- public string SaveJournalE { get; set; } = "Save journal entries to file";
- public string ChatEnterActivation { get; set; } = "Activate chat by pressing Enter";
- public string ChatEnterSpecial { get; set; } = "Also activate with common keys( ! ; : / \\ \\ , . [ | ~ )";
- public string ShiftEnterChat { get; set; } = "Use Shift + Enter to send message without closing chat";
- public string ChatGradient { get; set; } = "Hide chat gradient";
- public string HideGuildChat { get; set; } = "Hide guild chat";
- public string HideAllianceChat { get; set; } = "Hide alliance chat";
- public string SpeechColor { get; set; } = "Speech color";
- public string YellColor { get; set; } = "Yell color";
- public string PartyColor { get; set; } = "Party color";
- public string AllianceColor { get; set; } = "Alliance color";
- public string EmoteColor { get; set; } = "Emote color";
- public string WhisperColor { get; set; } = "Whisper color";
- public string GuildColor { get; set; } = "Guild color";
- public string CharColor { get; set; } = "Chat color";
- }
-
- public class CombatSpells
- {
- public string HoldTabForCombat { get; set; } = "Hold tab for combat";
- public string QueryBeforeAttack { get; set; } = "Query before attack";
- public string QueryBeforeBeneficial { get; set; } = "Query before beneficial acts on murderers/criminals/gray";
- public string EnableOverheadSpellFormat { get; set; } = "Enable overhead spell format";
- public string EnableOverheadSpellHue { get; set; } = "Enable overhead spell hue";
- public string SingleClickForSpellIcons { get; set; } = "Single click for spell icons";
- public string ShowBuffDurationOnOldStyleBuffBar { get; set; } = "Show buff duration on old style buff bar";
- public string EnableFastSpellHotkeyAssigning { get; set; } = "Enable fast spell hotkey assigning";
- public string TooltipFastSpellAssign { get; set; } = "Ctrl + Alt + Click a spell icon the open a gump to set a hotkey";
- public string InnocentColor { get; set; } = "Innocent color";
- public string BeneficialSpell { get; set; } = "Beneficial spell";
- public string FriendColor { get; set; } = "Friend color";
- public string HarmfulSpell { get; set; } = "Harmful spell";
- public string Criminal { get; set; } = "Criminal";
- public string NeutralSpell { get; set; } = "Neutral spell";
- public string CanBeAttackedHue { get; set; } = "Can be attacked hue";
- public string Murderer { get; set; } = "Murderer";
- public string Enemy { get; set; } = "Enemy";
- public string SpellOverheadFormat { get; set; } = "Spell overhead format";
- public string TooltipSpellFormat { get; set; } = "{power} for powerword, {spell} for spell name";
- }
-
- public class Counters
- {
- public string EnableCounters { get; set; } = "Enable counters";
- public string HighlightItemsOnUse { get; set; } = "Highlight items on use";
- public string AbbreviatedValues { get; set; } = "Abbreviated values";
- public string AbbreviateIfAmountExceeds { get; set; } = "Abbreviate if amount exceeds";
- public string HighlightRedWhenAmountIsLow { get; set; } = "Highlight red when amount is low";
- public string HighlightRedIfAmountIsBelow { get; set; } = "Highlight red if amount is below";
- public string CounterLayout { get; set; } = "Counter layout";
- public string GridSize { get; set; } = "Grid size";
- public string Rows { get; set; } = "Rows";
- public string Columns { get; set; } = "Columns";
- }
-
- public class InfoBars
- {
- public string ShowInfoBar { get; set; } = "Show info bar";
- public string HighlightType { get; set; } = "Highlight type";
- public string HighLightOpt_TextColor { get; set; } = "Text color";
- public string HighLightOpt_ColoredBars { get; set; } = "Colored bars";
- public string AddItem { get; set; } = "+ Add item";
- public string Hp { get; set; } = "HP";
- public string Label { get; set; } = "Label";
- public string Color { get; set; } = "Color";
- public string Data { get; set; } = "Data";
- }
-
- public class Containers
- {
- public string Description { get; set; } = "These settings are for original container gumps, for grid container settings visit the TazUO section";
- public string CharacterBackpackStyle { get; set; } = "Character backpack style";
- public string BackpackOpt_Default { get; set; } = "Default";
- public string BackpackOpt_Suede { get; set; } = "Suede";
- public string BackpackOpt_PolarBear { get; set; } = "Polar bear";
- public string BackpackOpt_GhoulSkin { get; set; } = "Ghoul skin";
- public string ContainerScale { get; set; } = "Container scale";
- public string AlsoScaleItems { get; set; } = "Also scale items";
- public string UseLargeContainerGumps { get; set; } = "Use large container gumps";
- public string DoubleClickToLootItemsInsideContainers { get; set; } = "Double click to loot items inside containers";
- public string RelativeDragAndDropItemsInContainers { get; set; } = "Relative drag and drop items in containers";
- public string HighlightContainerOnGroundWhenMouseIsOverAContainerGump { get; set; } = "Highlight container on ground when mouse is over a container gump";
- public string RecolorContainerGumpByWithContainerHue { get; set; } = "Recolor container gump by with container hue";
- public string OverrideContainerGumpLocations { get; set; } = "Override container gump locations";
- public string OverridePosition { get; set; } = "Override position";
- public string PositionOpt_NearContainer { get; set; } = "Near container";
- public string PositionOpt_TopRight { get; set; } = "Top right";
- public string PositionOpt_LastDraggedPosition { get; set; } = "Last dragged position";
- public string RememberEachContainer { get; set; } = "Remember each container";
- public string RebuildContainersTxt { get; set; } = "Rebuild containers.txt";
- }
-
- public class Experimental
- {
- public string DisableDefaultUoHotkeys { get; set; } = "Disable default UO hotkeys";
- public string DisableArrowsNumlockArrowsPlayerMovement { get; set; } = "Disable arrows & numlock arrows(player movement)";
- public string DisableTabToggleWarmode { get; set; } = "Disable tab (toggle warmode)";
- public string DisableCtrlQWMessageHistory { get; set; } = "Disable Ctrl + Q/W (message history)";
- public string DisableRightLeftClickAutoMove { get; set; } = "Disable right + left click auto move";
- }
-
- public class NamePlates
- {
- public string NewEntry { get; set; } = "New entry";
- public string NameOverheadEntryName { get; set; } = "Name overhead entry name";
- public string DeleteEntry { get; set; } = "Delete entry";
- }
-
- public class Cooldowns
- {
- public string CustomCooldownBars { get; set; } = "Custom cooldown bars";
- public string PositionX { get; set; } = "Position X";
- public string PositionY { get; set; } = "Position Y";
- public string UseLastMovedBarPosition { get; set; } = "Use last moved bar position";
- public string Conditions { get; set; } = "Conditions";
- public string AddCondition { get; set; } = "+ Add condition";
- }
-
- public class TazUO
- {
- #region General
- public string GridContainers { get; set; } = "Grid containers";
- public string EnableGridContainers { get; set; } = "Enable grid containers";
- public string GridContainerScale { get; set; } = "Grid container scale";
- public string AlsoScaleItems { get; set; } = "Also scale items";
- public string GridItemBorderOpacity { get; set; } = "Grid item border opacity";
- public string BorderColor { get; set; } = "Border color";
- public string ContainerOpacity { get; set; } = "Container opacity";
- public string BackgroundColor { get; set; } = "Background color";
- public string UseContainersHue { get; set; } = "Use container's hue";
- public string SearchStyle { get; set; } = "Search style";
- public string OnlyShow { get; set; } = "Only show";
- public string Highlight { get; set; } = "Highlight";
- public string EnableContainerPreview { get; set; } = "Enable container preview";
- public string TooltipPreview { get; set; } = "This only works on containers that you have opened, otherwise the client does not have that information yet.";
- public string MakeAnchorable { get; set; } = "Make anchorable";
- public string TooltipGridAnchor { get; set; } = "This will allow grid containers to be anchored to other containers/world map/journal";
- public string ContainerStyle { get; set; } = "Container style";
- public string HideBorders { get; set; } = "Hide borders";
- public string DefaultGridRows { get; set; } = "Default grid rows";
- public string DefaultGridColumns { get; set; } = "Default grid columns";
- public string GridHighlightSettings { get; set; } = "Grid highlight settings";
- public string GridHighlightSize { get; set; } = "Grid highlight size";
- #endregion
-
- #region Journal
- public string Journal { get; set; } = "Journal";
- public string MaxJournalEntries { get; set; } = "Max journal entries";
- public string JournalOpacity { get; set; } = "Journal opacity";
- public string JournalBackgroundColor { get; set; } = "Background color";
- public string JournalStyle { get; set; } = "Journal style";
- public string JournalHideBorders { get; set; } = "Hide borders";
- public string HideTimestamp { get; set; } = "Hide timestamp";
- #endregion
-
- #region ModernPaperdoll
- public string ModernPaperdoll { get; set; } = "Modern paperdoll";
- public string EnableModernPaperdoll { get; set; } = "Enable modern paperdoll";
- public string PaperdollHue { get; set; } = "Paperdoll hue";
- public string DurabilityBarHue { get; set; } = "Durability bar hue";
- public string ShowDurabilityBarBelow { get; set; } = "Show durability bar below %";
- #endregion
-
- #region Nameplates
- public string Nameplates { get; set; } = "Nameplates";
- public string NameplatesAlsoActAsHealthBars { get; set; } = "Nameplates also act as health bars";
- public string HpOpacity { get; set; } = "HP opacity";
- public string HideNameplatesIfFullHealth { get; set; } = "Hide nameplates if full health";
- public string OnlyInWarmode { get; set; } = "Only in warmode";
- public string BorderOpacity { get; set; } = "Border opacity";
- public string BackgroundOpacity { get; set; } = "Background opacity";
- #endregion
-
- #region Mobile
- public string Mobiles { get; set; } = "Mobiles";
- public string DamageToSelf { get; set; } = "Damage to self";
- public string DamageToOthers { get; set; } = "Damage to others";
- public string DamageToPets { get; set; } = "Damage to pets";
- public string DamageToAllies { get; set; } = "Damage to allies";
- public string DamageToLastAttack { get; set; } = "Damage to last attack";
- public string DisplayPartyChatOverPlayerHeads { get; set; } = "Display party chat over player heads";
- public string TooltipPartyChat { get; set; } = "If a party member uses party chat their text will also show above their head to you";
- public string OverheadTextWidth { get; set; } = "Overhead text width";
- public string TooltipOverheadText { get; set; } = "This adjusts the maximum width for text over players, setting to 0 will allow it to use any width needed to stay one line";
- public string BelowMobileHealthBarScale { get; set; } = "Below mobile health bar scale";
- public string AutomaticallyOpenHealthBarsForLastAttack { get; set; } = "Automatically open health bars for last attack";
- public string UpdateOneBarAsLastAttack { get; set; } = "Update one bar as last attack";
- public string HiddenPlayerOpacity { get; set; } = "Hidden player opacity";
- public string HiddenPlayerHue { get; set; } = "Hidden player hue";
- public string RegularPlayerOpacity { get; set; } = "Regular player opacity";
- public string AutoFollowDistance { get; set; } = "Auto follow distance";
- public string DisableMouseInteractionsForOverheadText { get; set; } = "Disable mouse interactions for overhead text";
- public string OverridePartyMemberHues { get; set; } = "Override party member body hues with friendly hue";
- #endregion
-
- #region Misc
- public string Misc { get; set; } = "Misc";
- public string DisableSystemChat { get; set; } = "Disable system chat";
- public string EnableImprovedBuffGump { get; set; } = "Enable improved buff gump";
- public string BuffGumpHue { get; set; } = "Buff gump hue";
- public string MainGameWindowBackground { get; set; } = "Main game window background";
- public string EnableHealthIndicatorBorder { get; set; } = "Enable health indicator border";
- public string OnlyShowBelowHp { get; set; } = "Only show below hp %";
- public string Size { get; set; } = "Size";
- public string SpellIconScale { get; set; } = "Spell icon scale";
- public string DisplayMatchingHotkeysOnSpellIcons { get; set; } = "Display matching hotkeys on spell icons";
- public string HotkeyTextHue { get; set; } = "Hotkey text hue";
- public string EnableGumpOpacityAdjustViaAltScroll { get; set; } = "Enable gump opacity adjust via Alt + Scroll";
- public string EnableAdvancedShopGump { get; set; } = "Enable advanced shop gump";
- public string DisplaySkillProgressBarOnSkillChanges { get; set; } = "Display skill progress bar on skill changes";
- public string TextFormat { get; set; } = "Text format";
- public string EnableSpellIndicatorSystem { get; set; } = "Enable spell indicator system";
- public string ImportFromUrl { get; set; } = "Import from url";
- public string InputRequestUrl { get; set; } = "Enter the url for the spell config. /c[red]This will override your current config.";
- public string Download { get; set; } = "Download";
- public string Cancel { get; set; } = "Cancel";
- public string AttemptingToDownloadSpellConfig { get; set; } = "Attempting to download spell config..";
- public string SuccesfullyDownloadedNewSpellConfig { get; set; } = "Succesfully downloaded new spell config.";
- public string FailedToDownloadTheSpellConfigExMessage { get; set; } = "Failed to download the spell config. ({0})";
- public string AlsoCloseAnchoredHealthbarsWhenAutoClosingHealthbars { get; set; } = "Also close anchored healthbars when auto closing healthbars";
- public string EnableAutoResyncOnHangDetection { get; set; } = "Enable auto resync on hang detection";
- public string PlayerOffsetX { get; set; } = "Player Offset X";
- public string PlayerOffsetY { get; set; } = "Player Offset Y";
- public string UseLandTexturesWhereAvailable { get; set; } = "Use land textures where available(Experimental)";
- public string SOSGumpID { get; set; } = "SOS Gump ID";
- #endregion
-
- #region Tooltips
- public string Tooltips { get; set; } = "Tooltips";
- public string AlignTooltipsToTheLeftSide { get; set; } = "Align tooltips to the left side";
- public string AlignMobileTooltipsToCenter { get; set; } = "Align mobile tooltips to center";
- public string BackgroundHue { get; set; } = "Background hue";
- public string HeaderFormatItemName { get; set; } = "Header format(Item name)";
- public string TooltipOverrideSettings { get; set; } = "Tooltip override settings";
- #endregion
-
- #region Fontsettings
- public string FontSettings { get; set; } = "Font settings";
- public string TtfFontBorder { get; set; } = "TTF Font border";
- public string InfobarFont { get; set; } = "Infobar font";
- public string SharedSize { get; set; } = "Size";
- public string SystemChatFont { get; set; } = "System chat font";
- public string TooltipFont { get; set; } = "Tooltip font";
- public string OverheadFont { get; set; } = "Overhead font";
- public string JournalFont { get; set; } = "Journal font";
- #endregion
-
- #region Controller
- public string Controller { get; set; } = "Controller";
- public string MouseSesitivity { get; set; } = "Mouse Sensitivity";
- #endregion
-
- #region SettingsTransfer
- public string SettingsTransfers { get; set; } = "Settings transfers";
- public string SettingsWarning { get; set; } = "/es/c[red]! Warning !/cd\n" +
- "This will override other character's profile options!\n" +
- "This is not reversable!\n" +
- "You have {0} other profiles that will may overridden with the settings in this profile.\n\n" +
- "This will not override: Macros, skill groups, info bar, grid container data, or gump saved positions.";
- public string OverrideAll { get; set; } = "Override {0} other profiles with this one.";
- public string OverrideSuccess { get; set; } = "{0} profiles overriden.";
- public string OverrideSame { get; set; } = "Override {0} other profiles on this same server with this one.";
- #endregion
-
- #region GumpScaling
- public string GumpScaling { get; set; } = "Gump scaling";
- public string ScalingInfo { get; set; } = "Some of these settings may only take effect after closing and reopening. Visual bugs may occur until the gump is closed and reopened.";
- public string PaperdollGump { get; set; } = "Paperdoll Gump";
- #endregion
-
- public string AutoLoot { get; set; } = "Autoloot";
-
- #region VisibileLayers
- public string VisibleLayers { get; set; } = "Visible Layers";
- public string VisLayersInfo { get; set; } = "These settings are to hide layers on in-game mobiles. Check the box to hide that layer.";
- public string OnlyForYourself { get; set; } = "Only for yourself";
- #endregion
- }
- }
-
- public class ErrorsLanguage
- {
- public string CommandNotFound { get; set; } = "Command was not found: {0}";
- }
-
- public class MapLanguage
- {
- public string Follow { get; set; } = "Follow";
- public string Yourself { get; set; } = "Yourself";
- }
-}
diff --git a/src/ClassicUO.Client/Configuration/Profile.cs b/src/ClassicUO.Client/Configuration/Profile.cs
deleted file mode 100644
index e4b45057c..000000000
--- a/src/ClassicUO.Client/Configuration/Profile.cs
+++ /dev/null
@@ -1,1074 +0,0 @@
-#region license
-
-// Copyright (c) 2021, andreakarasho
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// 3. All advertising materials mentioning features or use of this software
-// must display the following acknowledgement:
-// This product includes software developed by andreakarasho - https://github.com/andreakarasho
-// 4. Neither the name of the copyright holder nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using ClassicUO.Configuration.Json;
-using ClassicUO.Game;
-using ClassicUO.Game.Data;
-using ClassicUO.Game.GameObjects;
-using ClassicUO.Game.Managers;
-using ClassicUO.Game.UI.Gumps;
-using ClassicUO.Utility.Logging;
-using Microsoft.Xna.Framework;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using System.Xml;
-
-namespace ClassicUO.Configuration
-{
- //[JsonSourceGenerationOptions(WriteIndented = true, PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified)]
- [JsonSerializable(typeof(Profile), GenerationMode = JsonSourceGenerationMode.Metadata)]
- sealed partial class ProfileJsonContext : JsonSerializerContext
- {
- sealed class SnakeCaseNamingPolicy : JsonNamingPolicy
- {
- public static SnakeCaseNamingPolicy Instance { get; } = new SnakeCaseNamingPolicy();
-
- public override string ConvertName(string name)
- {
- // Conversion to other naming convention goes here. Like SnakeCase, KebabCase etc.
- return string.Concat(name.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
- }
- }
-
- private static Lazy _jsonOptions { get; } = new Lazy(() =>
- {
- var options = new JsonSerializerOptions();
- options.WriteIndented = true;
- options.PropertyNamingPolicy = SnakeCaseNamingPolicy.Instance;
- return options;
- });
-
- public static ProfileJsonContext DefaultToUse { get; } = new ProfileJsonContext(_jsonOptions.Value);
- }
-
-
-
- public sealed class Profile
- {
- [JsonIgnore] public string Username { get; set; }
- [JsonIgnore] public string ServerName { get; set; }
- [JsonIgnore] public string CharacterName { get; set; }
-
- // sounds
- public bool EnableSound { get; set; } = true;
- public int SoundVolume { get; set; } = 100;
- public bool EnableMusic { get; set; } = true;
- public int MusicVolume { get; set; } = 100;
- public bool EnableFootstepsSound { get; set; } = true;
- public bool EnableCombatMusic { get; set; } = true;
- public bool ReproduceSoundsInBackground { get; set; }
-
- // fonts and speech
- public byte ChatFont { get; set; } = 1;
- public int SpeechDelay { get; set; } = 100;
- public bool ScaleSpeechDelay { get; set; } = true;
- public bool SaveJournalToFile { get; set; } = false;
- public bool ForceUnicodeJournal { get; set; }
- public bool IgnoreAllianceMessages { get; set; }
- public bool IgnoreGuildMessages { get; set; }
-
- // hues
- public ushort SpeechHue { get; set; } = 0x02B2;
- public ushort WhisperHue { get; set; } = 0x0033;
- public ushort EmoteHue { get; set; } = 0x0021;
- public ushort YellHue { get; set; } = 0x0021;
- public ushort PartyMessageHue { get; set; } = 0x0044;
- public ushort GuildMessageHue { get; set; } = 0x0044;
- public ushort AllyMessageHue { get; set; } = 0x0057;
- public ushort ChatMessageHue { get; set; } = 0x0256;
- public ushort InnocentHue { get; set; } = 0x005A;
- public ushort PartyAuraHue { get; set; } = 0x0044;
- public ushort FriendHue { get; set; } = 0x0044;
- public ushort CriminalHue { get; set; } = 0x03B2;
- public ushort CanAttackHue { get; set; } = 0x03B2;
- public ushort EnemyHue { get; set; } = 0x0031;
- public ushort MurdererHue { get; set; } = 0x0023;
- public ushort BeneficHue { get; set; } = 0x0059;
- public ushort HarmfulHue { get; set; } = 0x0020;
- public ushort NeutralHue { get; set; } = 0x03B1;
- public bool EnabledSpellHue { get; set; }
- public bool EnabledSpellFormat { get; set; }
- public string SpellDisplayFormat { get; set; } = "{power} [{spell}]";
- public ushort PoisonHue { get; set; } = 0x0044;
- public ushort ParalyzedHue { get; set; } = 0x014C;
- public ushort InvulnerableHue { get; set; } = 0x0030;
- public ushort AltJournalBackgroundHue { get; set; } = 0x0000;
- public ushort AltGridContainerBackgroundHue { get; set; } = 0x0000;
- public bool OverridePartyAndGuildHue { get; set; } = false;
-
- // visual
- public bool EnabledCriminalActionQuery { get; set; } = true;
- public bool EnabledBeneficialCriminalActionQuery { get; set; } = false;
- public bool EnableStatReport { get; set; } = true;
- public bool EnableSkillReport { get; set; } = true;
- public bool UseOldStatusGump { get; set; }
- public int BackpackStyle { get; set; }
- public bool HighlightGameObjects { get; set; }
- public bool HighlightMobilesByParalize { get; set; } = true;
- public bool HighlightMobilesByPoisoned { get; set; } = true;
- public bool HighlightMobilesByInvul { get; set; } = true;
- public bool ShowMobilesHP { get; set; }
- public int MobileHPType { get; set; } // 0 = %, 1 = line, 2 = both
- public int MobileHPShowWhen { get; set; } // 0 = Always, 1 - <100%
- public bool DrawRoofs { get; set; } = true;
- public bool TreeToStumps { get; set; }
- public bool EnableCaveBorder { get; set; }
- public bool HideVegetation { get; set; }
- public int FieldsType { get; set; } // 0 = normal, 1 = static, 2 = tile
- public bool NoColorObjectsOutOfRange { get; set; }
- public bool UseCircleOfTransparency { get; set; }
- public int CircleOfTransparencyRadius { get; set; } = Constants.MAX_CIRCLE_OF_TRANSPARENCY_RADIUS / 2;
- public int CircleOfTransparencyType { get; set; } // 0 = normal, 1 = like original client
- public int VendorGumpHeight { get; set; } = 60; //original vendor gump size
- public float DefaultScale { get; set; } = 1.0f;
- public bool EnableMousewheelScaleZoom { get; set; }
- public bool SaveScaleAfterClose { get; set; }
- public bool RestoreScaleAfterUnpressCtrl { get; set; }
- public bool BandageSelfOld { get; set; } = true;
- public bool EnableDeathScreen { get; set; } = true;
- public bool EnableBlackWhiteEffect { get; set; } = true;
- public ushort HiddenBodyHue { get; set; } = 0x038E;
- public byte HiddenBodyAlpha { get; set; } = 40;
- public int PlayerConstantAlpha { get; set; } = 100;
-
- // tooltip
- public bool UseTooltip { get; set; } = true;
- public ushort TooltipTextHue { get; set; } = 0xFFFF;
- public int TooltipDelayBeforeDisplay { get; set; } = 250;
- public int TooltipDisplayZoom { get; set; } = 100;
- public int TooltipBackgroundOpacity { get; set; } = 70;
- public byte TooltipFont { get; set; } = 1;
-
- // movements
- public bool EnablePathfind { get; set; }
- public bool UseShiftToPathfind { get; set; }
- public bool PathfindSingleClick { get; set; }
- public bool AlwaysRun { get; set; }
- public bool AlwaysRunUnlessHidden { get; set; }
- public bool SmoothMovements { get; set; } = true;
- public bool HoldDownKeyTab { get; set; } = true;
- public bool HoldShiftForContext { get; set; } = false;
- public bool HoldShiftToSplitStack { get; set; } = false;
-
- // general
- [JsonConverter(typeof(Point2Converter))] public Point WindowClientBounds { get; set; } = new Point(600, 480);
- [JsonConverter(typeof(Point2Converter))] public Point ContainerDefaultPosition { get; set; } = new Point(24, 24);
- [JsonConverter(typeof(Point2Converter))] public Point GameWindowPosition { get; set; } = new Point(10, 10);
- public bool GameWindowLock { get; set; }
- public bool GameWindowFullSize { get; set; }
- public bool WindowBorderless { get; set; } = false;
- [JsonConverter(typeof(Point2Converter))] public Point GameWindowSize { get; set; } = new Point(600, 480);
- [JsonConverter(typeof(Point2Converter))] public Point TopbarGumpPosition { get; set; } = new Point(0, 0);
- public bool TopbarGumpIsMinimized { get; set; }
- public bool TopbarGumpIsDisabled { get; set; }
- public bool UseAlternativeLights { get; set; }
- public bool UseCustomLightLevel { get; set; }
- public byte LightLevel { get; set; }
- public int LightLevelType { get; set; } // 0 = absolute, 1 = minimum
- public bool UseColoredLights { get; set; } = true;
- public bool UseDarkNights { get; set; }
- public int CloseHealthBarType { get; set; } // 0 = none, 1 == not exists, 2 == is dead
- public bool ActivateChatAfterEnter { get; set; }
- public bool ActivateChatAdditionalButtons { get; set; } = true;
- public bool ActivateChatShiftEnterSupport { get; set; } = true;
- public bool UseObjectsFading { get; set; } = true;
- public bool HoldDownKeyAltToCloseAnchored { get; set; } = true;
- public bool CloseAllAnchoredGumpsInGroupWithRightClick { get; set; } = false;
- public bool HoldAltToMoveGumps { get; set; }
- public byte JournalOpacity { get; set; } = 50;
- public int JournalStyle { get; set; } = 0;
- public bool HideScreenshotStoredInMessage { get; set; }
- public bool UseModernPaperdoll { get; set; } = false;
- public bool OpenModernPaperdollAtMinimizeLoc { get; set; } = false;
-
- // Experimental
- public bool CastSpellsByOneClick { get; set; }
- public bool BuffBarTime { get; set; }
- public bool FastSpellsAssign { get; set; }
- public bool AutoOpenDoors { get; set; }
- public bool SmoothDoors { get; set; }
- public bool AutoOpenCorpses { get; set; }
- public int AutoOpenCorpseRange { get; set; } = 2;
- public int CorpseOpenOptions { get; set; } = 3;
- public bool SkipEmptyCorpse { get; set; }
- public bool DisableDefaultHotkeys { get; set; }
- public bool DisableArrowBtn { get; set; }
- public bool DisableTabBtn { get; set; }
- public bool DisableCtrlQWBtn { get; set; }
- public bool DisableAutoMove { get; set; }
- public bool EnableDragSelect { get; set; }
- public int DragSelectModifierKey { get; set; } // 0 = none, 1 = control, 2 = shift
- public int DragSelect_PlayersModifier { get; set; } = 0;
- public int DragSelect_MonstersModifier { get; set; } = 0;
- public int DragSelect_NameplateModifier { get; set; } = 0;
- public bool OverrideContainerLocation { get; set; }
-
- public int OverrideContainerLocationSetting { get; set; } // 0 = container position, 1 = top right of screen, 2 = last dragged position, 3 = remember every container
-
- [JsonConverter(typeof(Point2Converter))] public Point OverrideContainerLocationPosition { get; set; } = new Point(200, 200);
- public bool HueContainerGumps { get; set; } = true;
- public bool DragSelectHumanoidsOnly { get; set; }
- public int DragSelectStartX { get; set; } = 100;
- public int DragSelectStartY { get; set; } = 100;
- public bool DragSelectAsAnchor { get; set; } = false;
- public string LastActiveNameOverheadOption { get; set; } = "All";
- public bool NameOverheadToggled { get; set; } = false;
- public bool ShowTargetRangeIndicator { get; set; }
- public bool PartyInviteGump { get; set; }
- public bool CustomBarsToggled { get; set; }
- public bool CBBlackBGToggled { get; set; }
-
- public bool ShowInfoBar { get; set; }
- public int InfoBarHighlightType { get; set; } // 0 = text colour changes, 1 = underline
-
- public bool CounterBarEnabled { get; set; }
- public bool CounterBarHighlightOnUse { get; set; }
- public bool CounterBarHighlightOnAmount { get; set; }
- public bool CounterBarDisplayAbbreviatedAmount { get; set; }
- public int CounterBarAbbreviatedAmount { get; set; } = 1000;
- public int CounterBarHighlightAmount { get; set; } = 5;
- public int CounterBarCellSize { get; set; } = 40;
- public int CounterBarRows { get; set; } = 1;
- public int CounterBarColumns { get; set; } = 1;
-
- public bool ShowSkillsChangedMessage { get; set; } = true;
- public int ShowSkillsChangedDeltaValue { get; set; } = 1;
- public bool ShowStatsChangedMessage { get; set; } = true;
-
-
- public bool ShadowsEnabled { get; set; } = true;
- public bool ShadowsStatics { get; set; } = true;
- public int TerrainShadowsLevel { get; set; } = 15;
- public int AuraUnderFeetType { get; set; } // 0 = NO, 1 = in warmode, 2 = ctrl+shift, 3 = always
- public bool AuraOnMouse { get; set; } = true;
- public bool AnimatedWaterEffect { get; set; } = false;
-
- public bool PartyAura { get; set; }
-
- public bool UseXBR { get; set; } = true;
-
- public bool HideChatGradient { get; set; } = false;
-
- public bool StandardSkillsGump { get; set; } = true;
-
- public bool ShowNewMobileNameIncoming { get; set; } = true;
- public bool ShowNewCorpseNameIncoming { get; set; } = true;
-
- public uint GrabBagSerial { get; set; }
-
- public int GridLootType { get; set; } // 0 = none, 1 = only grid, 2 = both
-
- public bool ReduceFPSWhenInactive { get; set; } = true;
-
- public bool OverrideAllFonts { get; set; }
- public bool OverrideAllFontsIsUnicode { get; set; } = true;
-
- public bool SallosEasyGrab { get; set; }
-
- public bool JournalDarkMode { get; set; }
-
- public byte ContainersScale { get; set; } = 100;
-
- public byte ContainerOpacity { get; set; } = 50;
-
- public bool ScaleItemsInsideContainers { get; set; }
-
- public bool DoubleClickToLootInsideContainers { get; set; }
-
- public bool UseLargeContainerGumps { get; set; } = false;
-
- public bool RelativeDragAndDropItems { get; set; }
-
- public bool HighlightContainerWhenSelected { get; set; }
-
- public bool ShowHouseContent { get; set; }
- public bool SaveHealthbars { get; set; }
- public bool TextFading { get; set; } = true;
-
- public bool UseSmoothBoatMovement { get; set; } = false;
-
- public bool IgnoreStaminaCheck { get; set; } = false;
-
- public bool ShowJournalClient { get; set; } = true;
- public bool ShowJournalObjects { get; set; } = true;
- public bool ShowJournalSystem { get; set; } = true;
- public bool ShowJournalGuildAlly { get; set; } = true;
-
- public int WorldMapWidth { get; set; } = 400;
- public int WorldMapHeight { get; set; } = 400;
- public int WorldMapFont { get; set; } = 3;
- public bool WorldMapFlipMap { get; set; } = true;
- public bool WorldMapTopMost { get; set; }
- public bool WorldMapFreeView { get; set; }
- public bool WorldMapShowParty { get; set; } = true;
- public int WorldMapZoomIndex { get; set; } = 4;
- public bool WorldMapShowCoordinates { get; set; } = true;
- public bool WorldMapShowMouseCoordinates { get; set; } = true;
- public bool WorldMapShowCorpse { get; set; } = true;
- public bool WorldMapShowMobiles { get; set; } = true;
- public bool WorldMapShowPlayerName { get; set; } = true;
- public bool WorldMapShowPlayerBar { get; set; } = true;
- public bool WorldMapShowGroupName { get; set; } = true;
- public bool WorldMapShowGroupBar { get; set; } = true;
- public bool WorldMapShowMarkers { get; set; } = true;
- public bool WorldMapShowMarkersNames { get; set; } = true;
- public bool WorldMapShowMultis { get; set; } = true;
- public string WorldMapHiddenMarkerFiles { get; set; } = string.Empty;
- public string WorldMapHiddenZoneFiles { get; set; } = string.Empty;
- public bool WorldMapShowGridIfZoomed { get; set; } = true;
- public bool WorldMapAllowPositionalTarget { get; set; } = true;
-
- public int AutoFollowDistance { get; set; } = 2;
- [JsonConverter(typeof(Point2Converter))] public Point ResizeJournalSize { get; set; } = new Point(410, 350);
- public bool FollowingMode { get; set; } = false;
- public uint FollowingTarget { get; set; }
- public bool NamePlateHealthBar { get; set; } = true;
- public byte NamePlateOpacity { get; set; } = 75;
- public byte NamePlateHealthBarOpacity { get; set; } = 50;
- public bool NamePlateHideAtFullHealth { get; set; } = true;
- public bool NamePlateHideAtFullHealthInWarmode { get; set; } = true;
- public byte NamePlateBorderOpacity { get; set; } = 50;
-
- public bool LeftAlignToolTips { get; set; } = false;
- public bool ForceCenterAlignTooltipMobiles { get; set; } = false;
-
- public bool CorpseSingleClickLoot { get; set; } = false;
-
- public bool DisableSystemChat { get; set; } = false;
-
- #region GRID CONTAINER
- public bool UseGridLayoutContainerGumps { get; set; } = true;
- public int GridContainerSearchMode { get; set; } = 1;
- public bool EnableGridContainerAnchor { get; set; } = false;
- public byte GridBorderAlpha { get; set; } = 75;
- public ushort GridBorderHue { get; set; } = 0;
- public byte GridContainersScale { get; set; } = 100;
- public bool GridContainerScaleItems { get; set; } = true;
- public bool GridEnableContPreview { get; set; } = true;
- public int Grid_BorderStyle { get; set; } = 0;
- public int Grid_DefaultColumns { get; set; } = 4;
- public int Grid_DefaultRows { get; set; } = 4;
- public bool Grid_UseContainerHue { get; set; } = false;
- public bool Grid_HideBorder { get; set; } = false;
- #endregion
-
- #region COOLDOWNS
- public int CoolDownX { get; set; } = 50;
- public int CoolDownY { get; set; } = 50;
-
- public List Condition_Hue { get; set; } = new List();
- public List Condition_Label { get; set; } = new List();
- public List Condition_Duration { get; set; } = new List();
- public List Condition_Trigger { get; set; } = new List();
- public List Condition_Type { get; set; } = new List();
- public List Condition_ReplaceIfExists { get; set; } = new List();
- public int CoolDownConditionCount
- {
- get
- {
- return Condition_Hue.Count;
- }
- set { }
- }
- #endregion
-
- #region IMPROVED BUFF BAR
- public bool UseImprovedBuffBar { get; set; } = true;
- public ushort ImprovedBuffBarHue { get; set; } = 905;
- #endregion
-
- #region DAMAGE NUMBER HUES
- public ushort DamageHueSelf { get; set; } = 0x0034;
- public ushort DamageHuePet { get; set; } = 0x0033;
- public ushort DamageHueAlly { get; set; } = 0x0030;
- public ushort DamageHueLastAttck { get; set; } = 0x1F;
- public ushort DamageHueOther { get; set; } = 0x0021;
- #endregion
-
- #region GridHighlightingProps
- public List GridHighlight_Name { get; set; } = new List();
- public List GridHighlight_Hue { get; set; } = new List();
- public List> GridHighlight_PropNames { get; set; } = new List>();
- public List> GridHighlight_PropMinVal { get; set; } = new List>();
- public bool GridHighlight_CorpseOnly { get; set; } = false;
- public int GridHightlightSize { get; set; } = 1;
- #endregion
-
- #region Modern paperdoll
- public ushort ModernPaperDollHue { get; set; } = 0;
- public ushort ModernPaperDollDurabilityHue { get; set; } = 32;
- public int ModernPaperDoll_DurabilityPercent { get; set; } = 90;
- [JsonConverter(typeof(Point2Converter))] public Point ModernPaperdollPosition { get; set; } = new Point(100, 100);
- #endregion
-
- #region Health indicator
- public float ShowHealthIndicatorBelow { get; set; } = 0.9f;
- public bool EnableHealthIndicator { get; set; } = true;
- public int HealthIndicatorWidth { get; set; } = 10;
- #endregion
-
- public ushort MainWindowBackgroundHue { get; set; } = 1;
-
- public int MoveMultiObjectDelay { get; set; } = 1000;
-
- public bool SpellIcon_DisplayHotkey { get; set; } = true;
- public ushort SpellIcon_HotkeyHue { get; set; } = 1;
-
- public int SpellIconScale { get; set; } = 100;
-
- public bool EnableAlphaScrollingOnGumps { get; set; } = true;
-
- [JsonConverter(typeof(Point2Converter))] public Point WorldMapPosition { get; set; } = new Point(100, 100);
- [JsonConverter(typeof(Point2Converter))] public Point PaperdollPosition { get; set; } = new Point(100, 100);
- [JsonConverter(typeof(Point2Converter))] public Point JournalPosition { get; set; } = new Point(100, 100);
- [JsonConverter(typeof(Point2Converter))] public Point StatusGumpPosition { get; set; } = new Point(100, 100);
- [JsonConverter(typeof(Point2Converter))] public Point BackpackGridPosition { get; set; } = new Point(100, 100);
- [JsonConverter(typeof(Point2Converter))] public Point BackpackGridSize { get; set; } = new Point(300, 300);
- public bool WorldMapLocked { get; set; } = false;
- public bool PaperdollLocked { get; set; } = false;
- public bool JournalLocked { get; set; } = false;
- public bool StatusGumpLocked { get; set; } = false;
- public bool BackPackLocked { get; set; } = false;
-
- public bool DisplayPartyChatOverhead { get; set; } = true;
-
- public string SelectedTTFJournalFont { get; set; } = "avadonian";
- public int SelectedJournalFontSize { get; set; } = 20;
-
- public string SelectedToolTipFont { get; set; } = "Roboto-Regular";
- public int SelectedToolTipFontSize { get; set; } = 20;
-
- public string GameWindowSideChatFont { get; set; } = "avadonian";
- public int GameWindowSideChatFontSize { get; set; } = 20;
-
- public string OverheadChatFont { get; set; } = "avadonian";
- public int OverheadChatFontSize { get; set; } = 20;
- public int OverheadChatWidth { get; set; } = 200;
-
- public string DefaultTTFFont { get; set; } = "Roboto-Regular";
- public int TextBorderSize { get; set; } = 1;
-
- public bool UseModernShopGump { get; set; } = false;
-
- public int MaxJournalEntries { get; set; } = 750;
- public bool HideJournalBorder { get; set; } = false;
- public bool HideJournalTimestamp { get; set; } = false;
-
- public int HealthLineSizeMultiplier { get; set; } = 1;
-
- public bool OpenHealthBarForLastAttack { get; set; } = true;
- [JsonConverter(typeof(Point2Converter))]
- public Point LastTargetHealthBarPos { get; set; } = Point.Zero;
- public ushort ToolTipBGHue { get; set; } = 0;
-
- public string LastVersionHistoryShown { get; set; }
-
- public int AdvancedSkillsGumpHeight { get; set; } = 310;
-
- #region ToolTip Overrides
- public List ToolTipOverride_SearchText { get; set; } = new List() { "Physical Res", "Fire Res", "Cold Res", "Poison Res", "Energy Res" };
- public List ToolTipOverride_NewFormat { get; set; } = new List() { "/c[#5f423c]Physical Resist {1}%", "/c[red]Fire Resist {1}%", "/c[blue]Cold Resist {1}%", "/c[green]Poison Resist {1}%", "/c[purple]Energy Resist {1}%" };
- public List ToolTipOverride_MinVal1 { get; set; } = new List() { -1, -1, -1, -1, -1 };
- public List ToolTipOverride_MinVal2 { get; set; } = new List() { -1, -1, -1, -1, -1 };
- public List ToolTipOverride_MaxVal1 { get; set; } = new List() { 100, 100, 100, 100, 100 };
- public List ToolTipOverride_MaxVal2 { get; set; } = new List() { 100, 100, 100, 100, 100 };
- public List ToolTipOverride_Layer { get; set; } = new List() { (byte)TooltipLayers.Any, (byte)TooltipLayers.Any, (byte)TooltipLayers.Any, (byte)TooltipLayers.Any, (byte)TooltipLayers.Any };
- #endregion
-
- public string TooltipHeaderFormat { get; set; } = "/c[yellow]{0}";
-
- public bool DisplaySkillBarOnChange { get; set; } = true;
- public string SkillBarFormat { get; set; } = "{0}: {1} / {2}";
-
- public bool DisplayRadius { get; set; } = false;
- public int DisplayRadiusDistance { get; set; } = 10;
- public ushort DisplayRadiusHue { get; set; } = 22;
-
- public bool EnableSpellIndicators { get; set; } = true;
-
- public bool EnableAutoLoot { get; set; } = false;
-
- public static uint GumpsVersion { get; private set; }
-
- [JsonConverter(typeof(Point2Converter))]
- public Point InfoBarSize { get; set; } = new Point(400, 20);
- public bool InfoBarLocked { get; set; } = false;
- public string InfoBarFont { get; set; } = "Roboto-Regular";
- public int InfoBarFontSize { get; set; } = 18;
-
- public int LastJournalTab { get; set; } = 0;
- public Dictionary JournalTabs { get; set; } = new Dictionary()
- {
- { "All", new MessageType[] {
- MessageType.Alliance, MessageType.Command, MessageType.Emote,
- MessageType.Encoded, MessageType.Focus, MessageType.Guild,
- MessageType.Label, MessageType.Limit3Spell, MessageType.Party,
- MessageType.Regular, MessageType.Spell, MessageType.System,
- MessageType.Whisper, MessageType.Yell, MessageType.ChatSystem }
- },
- { "Chat", new MessageType[] {
- MessageType.Regular,
- MessageType.Guild,
- MessageType.Alliance,
- MessageType.Emote,
- MessageType.Party,
- MessageType.Whisper,
- MessageType.Yell,
- MessageType.ChatSystem }
- },
- {
- "Guild|Party", new MessageType[] {
- MessageType.Guild,
- MessageType.Alliance,
- MessageType.Party }
- },
- {
- "System", new MessageType[] {
- MessageType.System }
- }
- };
-
- public bool UseLastMovedCooldownPosition { get; set; } = false;
- public bool CloseHealthBarIfAnchored { get; set; } = false;
-
- [JsonConverter(typeof(Point2Converter))]
- public Point SkillProgressBarPosition { get; set; } = Point.Zero;
-
- public bool ForceResyncOnHang { get; set; } = false;
-
- public bool UseOneHPBarForLastAttack { get; set; } = false;
-
- public bool DisableMouseInteractionOverheadText { get; set; } = false;
-
- public List