diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index 412eeda7..00000000
--- a/.gitattributes
+++ /dev/null
@@ -1,22 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-
-# Custom for Visual Studio
-*.cs diff=csharp
-*.sln merge=union
-*.csproj merge=union
-*.vbproj merge=union
-*.fsproj merge=union
-*.dbproj merge=union
-
-# Standard to msysgit
-*.doc diff=astextplain
-*.DOC diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot diff=astextplain
-*.DOT diff=astextplain
-*.pdf diff=astextplain
-*.PDF diff=astextplain
-*.rtf diff=astextplain
-*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
index 423f9416..2f11e8ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,9 @@
+#################
+# EasyFarm Specific
+#################
+Maps/
+.idea/*
+
#################
## Eclipse
#################
@@ -227,4 +233,160 @@ Build/tools/*
# Test Reports
coverage/
-results.xml
\ No newline at end of file
+results.xml
+
+
+# Created by https://www.toptal.com/developers/gitignore/api/jetbrains,rider
+# Edit at https://www.toptal.com/developers/gitignore?templates=jetbrains,rider
+
+### JetBrains ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### JetBrains Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+# https://plugins.jetbrains.com/plugin/7973-sonarlint
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator-enh.xml
+.idea/**/markdown-navigator/
+
+# Cache file creation bug
+# See https://youtrack.jetbrains.com/issue/JBR-2257
+.idea/$CACHE_FILE$
+
+# CodeStream plugin
+# https://plugins.jetbrains.com/plugin/12206-codestream
+.idea/codestream.xml
+
+### Rider ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+
+# Generated files
+
+# Sensitive or high-churn files
+
+# Gradle
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+
+# Mongo Explorer plugin
+
+# File-based project format
+
+# IntelliJ
+
+# mpeltonen/sbt-idea plugin
+
+# JIRA plugin
+
+# Cursive Clojure plugin
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+
+# Editor-based Rest Client
+
+# Android studio 3.1+ serialized cache file
+
+# End of https://www.toptal.com/developers/gitignore/api/jetbrains,rider
+/.idea/.idea.EasyFarm/.idea/
+/.idea/.idea.EasyFarm/
diff --git a/.idea/.idea.EasyFarm/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.EasyFarm/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..7ad1bf11
--- /dev/null
+++ b/.idea/.idea.EasyFarm/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.EasyFarm/.idea/contentModel.xml b/.idea/.idea.EasyFarm/.idea/contentModel.xml
new file mode 100644
index 00000000..390fb1ce
--- /dev/null
+++ b/.idea/.idea.EasyFarm/.idea/contentModel.xml
@@ -0,0 +1,540 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.EasyFarm/.idea/projectSettingsUpdater.xml b/.idea/.idea.EasyFarm/.idea/projectSettingsUpdater.xml
new file mode 100644
index 00000000..4bb9f4d2
--- /dev/null
+++ b/.idea/.idea.EasyFarm/.idea/projectSettingsUpdater.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Data/Zones/Bastok_Markets.json b/Data/Zones/Bastok_Markets.json
new file mode 100644
index 00000000..711880e1
--- /dev/null
+++ b/Data/Zones/Bastok_Markets.json
@@ -0,0 +1,131 @@
+{
+ 'Name': 'Bastok_Markets',
+ 'Boundaries': [
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -365.0,
+ 'Y': 0.0,
+ 'Z': -185.0
+ },
+ 'ToPosition': {
+ 'X': 258.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -366.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ },
+ 'ToPosition': {
+ 'X': 259.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -187.0
+ },
+ 'ToPosition': {
+ 'X': 259.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': 258.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ },
+ 'ToPosition': {
+ 'X': 258.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': 258.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ },
+ 'ToPosition': {
+ 'X': 258.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -364.0,
+ 'Y': 0.0,
+ 'Z': -186.0
+ },
+ 'ToPosition': {
+ 'X': 260.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -365.0,
+ 'Y': 0.0,
+ 'Z': -185.0
+ },
+ 'ToPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -365.0,
+ 'Y': 0.0,
+ 'Z': -185.0
+ },
+ 'ToPosition': {
+ 'X': 259.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Gustaberg_South',
+ 'FromZone': 'Bastok_Markets',
+ 'FromPosition': {
+ 'X': -366.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ },
+ 'ToPosition': {
+ 'X': 259.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Data/Zones/Gustaberg_South.json b/Data/Zones/Gustaberg_South.json
new file mode 100644
index 00000000..d4e87f42
--- /dev/null
+++ b/Data/Zones/Gustaberg_South.json
@@ -0,0 +1,173 @@
+{
+ 'Name': 'Gustaberg_South',
+ 'Boundaries': [
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 260.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -364.0,
+ 'Y': 0.0,
+ 'Z': -183.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 262.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -357.0,
+ 'Y': 0.0,
+ 'Z': -179.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -364.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': -362.0,
+ 'Y': 0.0,
+ 'Z': -185.0
+ },
+ 'ToPosition': {
+ 'X': -362.0,
+ 'Y': 0.0,
+ 'Z': -185.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': 261.0,
+ 'Y': 0.0,
+ 'Z': -181.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ },
+ 'ToPosition': {
+ 'X': -363.0,
+ 'Y': 0.0,
+ 'Z': -184.0
+ }
+ },
+ {
+ 'ToZone': 'Bastok_Markets',
+ 'FromZone': 'Gustaberg_South',
+ 'FromPosition': {
+ 'X': -344.0,
+ 'Y': 0.0,
+ 'Z': -154.0
+ },
+ 'ToPosition': {
+ 'X': -344.0,
+ 'Y': 0.0,
+ 'Z': -154.0
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Data/Zones/Ronfaure_East.json b/Data/Zones/Ronfaure_East.json
new file mode 100644
index 00000000..eca87321
--- /dev/null
+++ b/Data/Zones/Ronfaure_East.json
@@ -0,0 +1,313 @@
+{
+ 'Name': 'Ronfaure_East',
+ 'Boundaries': [
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 109.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 279.0
+ },
+ 'ToPosition': {
+ 'X': 112.0,
+ 'Y': 0.0,
+ 'Z': -53.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -54.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 109.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 109.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': 280.0
+ },
+ 'ToPosition': {
+ 'X': 111.0,
+ 'Y': 0.0,
+ 'Z': -53.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -196.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -205.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -194.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -193.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -193.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -195.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -198.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -197.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -187.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -198.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 126.0,
+ 'Y': 0.0,
+ 'Z': -188.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -205.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -54.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 109.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 79.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ },
+ 'ToPosition': {
+ 'X': 111.0,
+ 'Y': 0.0,
+ 'Z': -54.0
+ }
+ },
+ {
+ 'ToZone': 'Southern_San_dOria',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 280.0
+ },
+ 'ToPosition': {
+ 'X': 110.0,
+ 'Y': 0.0,
+ 'Z': -55.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -196.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -193.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Ronfaure_East',
+ 'FromPosition': {
+ 'X': 60.0,
+ 'Y': 0.0,
+ 'Z': -196.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': -195.0
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Data/Zones/Southern_San_dOria.json b/Data/Zones/Southern_San_dOria.json
new file mode 100644
index 00000000..926f9772
--- /dev/null
+++ b/Data/Zones/Southern_San_dOria.json
@@ -0,0 +1,918 @@
+{
+ 'Name': 'Southern_San_dOria',
+ 'PointsToExplore': [],
+ 'NextPointToExplore': null,
+ 'Explored': [],
+ 'Boundaries': [
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': 272.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 85.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': 272.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 114.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 85.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 85.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 86.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 86.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 87.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 89.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 89.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 114.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 89.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ },
+ 'ToPosition': {
+ 'X': 89.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': 272.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 87.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 87.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -128.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -127.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -112.0,
+ 'Y': 0.0,
+ 'Z': -58.0
+ },
+ 'ToPosition': {
+ 'X': -125.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 85.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 86.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 87.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 114.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': -127.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -125.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -124.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -124.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -129.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -126.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 86.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 87.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 89.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 83.0,
+ 'Y': 0.0,
+ 'Z': 271.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 84.0,
+ 'Y': 0.0,
+ 'Z': 272.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 85.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 86.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 87.0,
+ 'Y': 0.0,
+ 'Z': 275.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 88.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 89.0,
+ 'Y': 0.0,
+ 'Z': 277.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 86.0,
+ 'Y': 0.0,
+ 'Z': 274.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_East',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': 113.0,
+ 'Y': 0.0,
+ 'Z': -56.0
+ },
+ 'ToPosition': {
+ 'X': 82.0,
+ 'Y': 0.0,
+ 'Z': 270.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -124.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -125.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -125.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -124.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -113.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -128.0,
+ 'Y': 0.0,
+ 'Z': 276.0
+ }
+ },
+ {
+ 'ToZone': 'Ronfaure_West',
+ 'FromZone': 'Southern_San_dOria',
+ 'FromPosition': {
+ 'X': -112.0,
+ 'Y': 0.0,
+ 'Z': -57.0
+ },
+ 'ToPosition': {
+ 'X': -125.0,
+ 'Y': 0.0,
+ 'Z': 273.0
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/EasyFarm.Tests/Classes/DialogTests.cs b/EasyFarm.Tests/Classes/DialogTests.cs
new file mode 100644
index 00000000..5e5eba3b
--- /dev/null
+++ b/EasyFarm.Tests/Classes/DialogTests.cs
@@ -0,0 +1,25 @@
+using EasyFarm.Tests.TestTypes.Mocks;
+using Xunit;
+
+namespace EasyFarm.Tests.Classes
+{
+ class DialogTests
+ {
+
+ private readonly MockGameAPI _mockApi = new MockGameAPI();
+
+ [Fact]
+ public void DisengageWhenFightingWillStopAttacking()
+ {
+ //// Fixture setup
+ //_mockApi.Dialog.Text = "Select a type of equipment.\a\vReturn to previous selection.\aItem level 119 weapons/shields.\aItem level 119 headgear.\aItem level 119 chestgear.\aItem level 119 handgear.\aItem level 119 leggear.\aItem level 119 footgear.\aLevel 99 equipment.\aLevel 98 and lower equipment.\aAccessories.\u007f1";
+ //// Excercise system
+ //Player.Disengage(_mockApi);
+ //// Verify outcome
+ //Assert.Equal(Constants.AttackOff, _mockApi.Mock.Windower.LastCommand);
+ //// Teardown
+ }
+
+ //"Select a type of equipment.\a\vReturn to previous selection.\aItem level 119 weapons/shields.\aItem level 119 headgear.\aItem level 119 chestgear.\aItem level 119 handgear.\aItem level 119 leggear.\aItem level 119 footgear.\aLevel 99 equipment.\aLevel 98 and lower equipment.\aAccessories.\u007f1"
+ }
+}
diff --git a/EasyFarm.Tests/Classes/NavigatorTests.cs b/EasyFarm.Tests/Classes/NavigatorTests.cs
new file mode 100644
index 00000000..bec894bb
--- /dev/null
+++ b/EasyFarm.Tests/Classes/NavigatorTests.cs
@@ -0,0 +1,26 @@
+using EasyFarm.Tests.TestTypes.Mocks;
+
+namespace EasyFarm.Tests.Classes
+{
+ public class NavigatorTests
+ {
+ private readonly MockGameAPI _mockApi = new MockGameAPI();
+
+ //[Fact]
+ //public void DisengageWhenFightingWillStopAttacking()
+ //{
+ // // Fixture setup
+ // _mockApi.Mock.Player.Status = Status.Fighting;
+ // //Navigator navigator = new Navigator(_mockApi);
+ // // Create a list of 3 IUnits with different distances, making the second one the closest distance
+
+ // // Excercise system
+ // // run get closest person
+
+ // // Verify outcome
+ // // verify that the closest IUnit returned was the second one.
+ // Assert.Equal(Constants.AttackOff, _mockApi.Mock.Windower.LastCommand);
+ // // Teardown
+ //}
+ }
+}
\ No newline at end of file
diff --git a/EasyFarm.Tests/Classes/PlayerTests.cs b/EasyFarm.Tests/Classes/PlayerTests.cs
index d71b8998..296b55d6 100644
--- a/EasyFarm.Tests/Classes/PlayerTests.cs
+++ b/EasyFarm.Tests/Classes/PlayerTests.cs
@@ -148,5 +148,20 @@ public void StopRunningWhenRunningWillStopRunning()
Assert.False(_mockApi.Mock.Navigator.IsRunning);
// Teardown
}
+
+ //[Fact]
+ //public void IfItemIsEquipedDoNothing()
+ //{
+ // // Fixture setup
+ // string slot = "Head";
+ // string name = "Really Cool Hat";
+ // _mockApi.Mock.Player.Equipment.Add();
+
+ // _mockApi.Mock.Player.Equipment[0].Id = 1234;
+ // // Excercise sytem
+ // bool currentlyEquipped = Player.CompareEquipedItem(_mockApi, slot, name);
+ // // Verify outcome
+ // Assert.True(currentlyEquipped);
+ //}
}
}
diff --git a/EasyFarm.Tests/Classes/SerializationTests.cs b/EasyFarm.Tests/Classes/SerializationTests.cs
index 06a26f7c..be58b695 100644
--- a/EasyFarm.Tests/Classes/SerializationTests.cs
+++ b/EasyFarm.Tests/Classes/SerializationTests.cs
@@ -17,7 +17,6 @@
// ///////////////////////////////////////////////////////////////////
using System;
using System.IO;
-using System.Linq;
using EasyFarm.Classes;
using EasyFarm.Persistence;
using EasyFarm.UserSettings;
diff --git a/EasyFarm.Tests/Classes/SpotFactoryTests.cs b/EasyFarm.Tests/Classes/SpotFactoryTests.cs
new file mode 100644
index 00000000..0fdeb4d5
--- /dev/null
+++ b/EasyFarm.Tests/Classes/SpotFactoryTests.cs
@@ -0,0 +1,135 @@
+using EasyFarm.Mapping;
+using MemoryAPI.Navigation;
+using Xunit;
+
+namespace EasyFarm.Tests.Classes
+{
+ public class SpotFactoryTests
+ {
+ [Fact]
+ public void SpotFactoryCanCreateASpotFromAPosition()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 1,
+ Y = 1,
+ Z = 1
+ };
+ Position testPosition = new Position { H = 1, X = 1, Y = 1, Z = 1 };
+ // when
+ ISpot actualSpot = SpotFactory.SpotFromPosition(testPosition);
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void SpotFactoryAlwaysRoundsFloatsDown()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 1,
+ Y = 1,
+ Z = 1
+ };
+ Position testPosition = new Position { H = 1, X = (float)1.99, Y = (float)1.5, Z = (float)1.1 };
+ // when
+ ISpot actualSpot = SpotFactory.SpotFromPosition(testPosition);
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void SpotFactoryAlwaysRoundsFloatsDownWhenNegative()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = -1,
+ Y = -10,
+ Z = -123
+ };
+ Position testPosition = new Position { H = 1, X = (float)-1.99, Y = (float)-10.8, Z = (float)-123.9 };
+ // when
+ ISpot actualSpot = SpotFactory.SpotFromPosition(testPosition);
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void SpotFactoryAddsDistanceFromStartingPositionToX()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 5,
+ Y = 0,
+ Z = 0
+ };
+
+ // when
+ ISpot spot = new Spot
+ {
+ X = 0,
+ Y = 0,
+ Z = 0
+ };
+ ISpot actualSpot = SpotFactory.SpotFromSpotOffset(spot, 5, 0, 0);
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void SpotFactoryAddsDistanceFromStartingPositionToZ()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 0,
+ Y = 0,
+ Z = 3
+ };
+
+ // when
+ ISpot spot = new Spot
+ {
+ X = 0,
+ Y = 0,
+ Z = 0
+ };
+ ISpot actualSpot = SpotFactory.SpotFromSpotOffset(spot, zOffset:3);
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void SpotFactoryAddsDistanceFromStartingPositionToXAndZ()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 5,
+ Y = 0,
+ Z = 3
+ };
+
+ // when
+ ISpot spot = new Spot
+ {
+ X = 0,
+ Y = 0,
+ Z = 0
+ };
+ ISpot actualSpot = SpotFactory.SpotFromSpotOffset(spot, 5, 0, 3);
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+ }
+}
diff --git a/EasyFarm.Tests/Classes/SpotTests.cs b/EasyFarm.Tests/Classes/SpotTests.cs
new file mode 100644
index 00000000..d28862ff
--- /dev/null
+++ b/EasyFarm.Tests/Classes/SpotTests.cs
@@ -0,0 +1,96 @@
+using EasyFarm.Mapping;
+using MemoryAPI.Navigation;
+using Xunit;
+
+namespace EasyFarm.Tests.Classes
+{
+ public class SpotTests
+ {
+ [Fact]
+ public void EqualityWorksWhenSpotsAreTheSame()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 1,
+ Y = 1,
+ Z = 1
+ };
+ Position testPosition = new Position {H = 1, X = 1, Y = 1, Z = 1};
+ // when
+ ISpot actualSpot = new Spot
+ {
+ X = 1,
+ Y = 1,
+ Z = 1
+ };
+
+ // Then
+ Assert.Equal(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void NullSpotIsNotEqualToARealSpot()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 1,
+ Y = 1,
+ Z = 1
+ };
+ ISpot actualSpot = new Spot();
+
+ // Then
+ Assert.NotEqual(expectedSpot, actualSpot);
+ }
+
+ [Fact]
+ public void DifferentSpotsAreNotEqual()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 2,
+ Y = 1,
+ Z = 1
+ };
+ Position testPosition = new Position {H = 1, X = 1, Y = 1, Z = 1};
+ // when
+ ISpot actualSpot = SpotFactory.SpotFromPosition(testPosition);
+
+ // Then
+ Assert.NotEqual(expectedSpot, actualSpot);
+ }
+
+
+ [Fact]
+ public void SpotsCanBeWalls()
+ {
+ // given
+ ISpot expectedSpot = new Spot
+ {
+ X = 1,
+ Y = 1,
+ Z = 1,
+ F = 0,
+ G = 0,
+ H = 1,
+ Neighbors = null,
+ Previous = null,
+ IsWall = true
+ };
+ Position testPosition = new Position { H = 1, X = 1, Y = 1, Z = 1 };
+
+ // When
+ ISpot actualSpot = SpotFactory.SpotFromPosition(testPosition);
+ actualSpot.IsWall = true;
+
+ // then
+ Assert.Equal(expectedSpot, actualSpot);
+
+
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/EasyFarm.Tests/Classes/ZoneMapFactoryTests.cs b/EasyFarm.Tests/Classes/ZoneMapFactoryTests.cs
new file mode 100644
index 00000000..13468cd9
--- /dev/null
+++ b/EasyFarm.Tests/Classes/ZoneMapFactoryTests.cs
@@ -0,0 +1,219 @@
+using System.Collections.Generic;
+using EasyFarm.Mapping;
+using MemoryAPI.Navigation;
+using Xunit;
+
+namespace EasyFarm.Tests.Classes
+{
+ public class ZoneMapFactoryTests
+ {
+ [Fact]
+ public void ZoneMapCorrectlyReturnsSameWhenTheyAreTheSameValues()
+ {
+ // Given
+ IZoneMap expectedZoneMap = new ZoneMap();
+
+ expectedZoneMap.Spots = new List
+ {
+ (Spot) SpotFactory.SpotFromPosition(new Position() {H = 1, X = 1, Y = 1, Z = 1})
+ };
+
+ // When
+ IZoneMap actualZoneMap = new ZoneMap();
+ actualZoneMap.Spots = new List
+ {
+ (Spot) SpotFactory.SpotFromPosition(new Position() {H = 1, X = 1, Y = 1, Z = 1})
+ };
+
+ // Then
+ Assert.Equal(expectedZoneMap, actualZoneMap);
+ }
+
+ [Fact]
+ public void ZonesCorrectlyReturnDifferentWhenSpotsAreDifferent()
+ {
+ // Given
+ IZoneMap expectedZoneMap = new ZoneMap();
+
+ expectedZoneMap.Spots = new List
+ {
+ (Spot) SpotFactory.SpotFromPosition(new Position() {H = 1, X = 1, Y = 1, Z = 1}),
+ (Spot) SpotFactory.SpotFromPosition(new Position() {H = 2, X = 2, Y = 2, Z = 2})
+ };
+
+ // When
+ IZoneMap actualZoneMap = new ZoneMap();
+ actualZoneMap.Spots = new List
+ {
+ (Spot) SpotFactory.SpotFromPosition(new Position() {H = 1, X = 1, Y = 1, Z = 1})
+ };
+
+ // Then
+ Assert.NotEqual(expectedZoneMap, actualZoneMap);
+ }
+
+ [Fact]
+ public void ZoneMapFactoryCreatesAMapFromASizeAndPosition()
+ {
+ // Given
+ Position startingPosition = new Position
+ {
+ H = 0,
+ X = 0,
+ Y = 0,
+ Z = 0
+ };
+
+ IZoneMap expectedZoneMap = new ZoneMap();
+ expectedZoneMap.Spots = new List
+ {
+ // start
+ new Spot {X = 0, Y = 0, Z = 0},
+
+ // up
+ new Spot {X = 0, Y = 0, Z = 1},
+ // upper right
+ new Spot {X = 1, Y = 0, Z = 1},
+ // right middle
+ new Spot {X = 1, Y = 0, Z = 0},
+ // down right
+ new Spot {X = 1, Y = 0, Z = -1},
+ // down
+ new Spot {X = 0, Y = 0, Z = -1},
+ // down left
+ new Spot {X = -1, Y = 0, Z = -1},
+ // left middle
+ new Spot {X = -1, Y = 0, Z = 0},
+ // upper left
+ new Spot {X = -1, Y = 0, Z = 1},
+ };
+
+ // When
+ IZoneMap actualZoneMap = ZoneMapFactory.GenerateZoneMap(startingPosition, 1);
+
+ // Then
+ Assert.Equal(expectedZoneMap, actualZoneMap);
+ }
+
+ [Fact]
+ public void ZoneMapFactoryCreatesAMapFromASizeAndPositionCanMakeABiggerMap()
+ {
+ // Given
+ Position startingPosition = new Position
+ {
+ H = 0,
+ X = 0,
+ Y = 0,
+ Z = 0
+ };
+
+ IZoneMap expectedZoneMap = new ZoneMap();
+ expectedZoneMap.Spots = new List
+ {
+ // start
+ new Spot {X = 0, Y = 0, Z = 0},
+
+ // up
+ new Spot {X = 0, Y = 0, Z = 1},
+ new Spot {X = 0, Y = 0, Z = 2},
+ new Spot {X = 0, Y = 0, Z = 3},
+
+ // upper right
+ new Spot {X = 1, Y = 0, Z = 1},
+
+ new Spot {X = 1, Y = 0, Z = 2},
+ new Spot {X = 2, Y = 0, Z = 1},
+ new Spot {X = 2, Y = 0, Z = 2},
+
+ new Spot {X = 3, Y = 0, Z = 1},
+ new Spot {X = 3, Y = 0, Z = 2},
+ new Spot {X = 1, Y = 0, Z = 3},
+ new Spot {X = 2, Y = 0, Z = 3},
+ new Spot {X = 3, Y = 0, Z = 3},
+
+ // right middle
+ new Spot {X = 1, Y = 0, Z = 0},
+ new Spot {X = 2, Y = 0, Z = 0},
+ new Spot {X = 3, Y = 0, Z = 0},
+
+ // down right
+ new Spot {X = 1, Y = 0, Z = -1},
+
+ new Spot {X = 1, Y = 0, Z = -2},
+ new Spot {X = 2, Y = 0, Z = -1},
+ new Spot {X = 2, Y = 0, Z = -2},
+
+ new Spot {X = 3, Y = 0, Z = -1},
+ new Spot {X = 3, Y = 0, Z = -2},
+ new Spot {X = 1, Y = 0, Z = -3},
+ new Spot {X = 2, Y = 0, Z = -3},
+ new Spot {X = 3, Y = 0, Z = -3},
+
+ // down
+ new Spot {X = 0, Y = 0, Z = -1},
+ new Spot {X = 0, Y = 0, Z = -2},
+ new Spot {X = 0, Y = 0, Z = -3},
+
+ // down left
+ new Spot {X = -1, Y = 0, Z = -1},
+
+ new Spot {X = -1, Y = 0, Z = -2},
+ new Spot {X = -2, Y = 0, Z = -1},
+ new Spot {X = -2, Y = 0, Z = -2},
+
+ new Spot {X = -3, Y = 0, Z = -1},
+ new Spot {X = -3, Y = 0, Z = -2},
+ new Spot {X = -1, Y = 0, Z = -3},
+ new Spot {X = -2, Y = 0, Z = -3},
+ new Spot {X = -3, Y = 0, Z = -3},
+
+ // left middle
+ new Spot {X = -1, Y = 0, Z = 0},
+ new Spot {X = -2, Y = 0, Z = 0},
+ new Spot {X = -3, Y = 0, Z = 0},
+
+ // upper left
+ new Spot {X = -1, Y = 0, Z = 1},
+
+ new Spot {X = -1, Y = 0, Z = 2},
+ new Spot {X = -2, Y = 0, Z = 1},
+ new Spot {X = -2, Y = 0, Z = 2},
+
+ new Spot {X = -3, Y = 0, Z = 1},
+ new Spot {X = -3, Y = 0, Z = 2},
+ new Spot {X = -1, Y = 0, Z = 3},
+ new Spot {X = -2, Y = 0, Z = 3},
+ new Spot {X = -3, Y = 0, Z = 3},
+ };
+
+ // When
+ IZoneMap actualZoneMap = ZoneMapFactory.GenerateZoneMap(startingPosition, 3);
+
+ // Then
+ Assert.Equal(expectedZoneMap, actualZoneMap);
+ }
+
+
+ [Fact]
+ public void TestHugeMap()
+ {
+ // Given
+ Position startingPosition = new Position
+ {
+ H = 0,
+ X = 0,
+ Y = 0,
+ Z = 0
+ };
+
+ // When
+ IZoneMap actualZoneMap = ZoneMapFactory.GenerateZoneMap(startingPosition, 1000);
+
+ // Then
+ Assert.IsType(actualZoneMap);
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/EasyFarm.Tests/Context/MockPlayer.cs b/EasyFarm.Tests/Context/MockPlayer.cs
index c8d4fd3b..967abd27 100644
--- a/EasyFarm.Tests/Context/MockPlayer.cs
+++ b/EasyFarm.Tests/Context/MockPlayer.cs
@@ -28,5 +28,12 @@ public class MockPlayer : IPlayer
public Zone Zone { get; set; }
public int Str { get; set; }
public int MppCurrent { get; set; }
+ public int JobLevel { get; set; }
+ public int SubJobLevel { get; set; }
+ public Job Job { get; set; }
+ public Job SubJob { get; set; }
+ public Zone Homepoint { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }
+ public string CurrentGoal { get; set; }
+ public string Nation { get; set; }
}
}
\ No newline at end of file
diff --git a/EasyFarm.Tests/Context/TestContext.cs b/EasyFarm.Tests/Context/TestContext.cs
index 1fa261fd..534ceb94 100644
--- a/EasyFarm.Tests/Context/TestContext.cs
+++ b/EasyFarm.Tests/Context/TestContext.cs
@@ -16,12 +16,18 @@
// If not, see .
// ///////////////////////////////////////////////////////////////////
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using EasyFarm.Classes;
using EasyFarm.Context;
using EasyFarm.States;
using EasyFarm.Tests.TestTypes.Mocks;
using EasyFarm.UserSettings;
using MemoryAPI;
+using Pathfinder.Map;
+using Pathfinder.People;
+using Pathfinder.Travel;
+using Zone = Pathfinder.Map.Zone;
+
namespace EasyFarm.Tests.Context
{
@@ -37,6 +43,15 @@ public class TestContext : IGameContext
public StateMemory Memory { get; set; }
public MockEliteAPI MockAPI { get; set; }
+ public IDialog Dialog { get; set; }
+ public IMenu Menu { get; set; }
+ public IInventory Inventory { get; set; }
+ public INavigator Navigator { get; set; }
+ public ZoneMapFactory ZoneMapFactory { get; set; }
+ public ObservableCollection Npcs { get; set; }
+ public ObservableCollection Mobs { get; set; }
+ public Traveler Traveler { get; set; }
+ public PeopleOverseer NpcOverseer { get; set; }
public TestContext()
{
diff --git a/EasyFarm.Tests/EasyFarm.Tests.csproj b/EasyFarm.Tests/EasyFarm.Tests.csproj
index fe6a57f8..127d58dd 100644
--- a/EasyFarm.Tests/EasyFarm.Tests.csproj
+++ b/EasyFarm.Tests/EasyFarm.Tests.csproj
@@ -1,5 +1,6 @@
+
Debug
@@ -64,6 +65,9 @@
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\portable-net45+win8+wp8+wpa81\System.Numerics.Vectors.dll
+
@@ -87,8 +91,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -135,6 +157,10 @@
+
+ {8ae72a1d-6503-4464-873d-c30a67d99c8a}
+ Pathfinder
+
{14508978-627b-46ae-9779-1f6b4fb0611e}
EasyFarm
@@ -150,6 +176,7 @@
+
@@ -157,6 +184,7 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+