diff --git a/.appveyor.yml b/.appveyor.yml
new file mode 100644
index 000000000..e8b177725
--- /dev/null
+++ b/.appveyor.yml
@@ -0,0 +1,39 @@
+version: 0.50.9.{build}
+
+branches:
+ only:
+ - master
+
+environment:
+ COMPILER: msys2
+ BUILDTOOL: cmake
+ MSYS2_DIR: msys64
+ MSYSTEM: MINGW32
+
+init:
+ - cmd: set PATH=C:\%MSYS2_DIR%\%MSYSTEM%\bin;C:\%MSYS2_DIR%\usr\bin;%PATH%
+
+build_script:
+ - ps: |
+ mkdir msys2
+
+ cd C:/msys64
+
+ C:\msys64\usr\bin\bash -lc ("for i in {1..3}; do pacman --noconfirm -Syu --force coreutils && break || sleep 15; done");
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Su"
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S git"
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-gcc"
+
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S make"
+
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-cmake"
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-libpng"
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-SDL2"
+ C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-i686-pkg-config"
+
+ cd C:/projects/ivan
+
+ cmake -G "MSYS Makefiles" -DCMAKE_CXX_FLAGS=-DWIZARD -DCMAKE_INSTALL_PREFIX=C:/projects/ivan/build
+ cmake .
+ make -j4 install
+
diff --git a/.devsPrefs/AquariusPower/.cproject b/.devsPrefs/AquariusPower/.cproject
new file mode 100644
index 000000000..1a5e13926
--- /dev/null
+++ b/.devsPrefs/AquariusPower/.cproject
@@ -0,0 +1,279 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.devsPrefs/AquariusPower/.gitignore.AquariusPower b/.devsPrefs/AquariusPower/.gitignore.AquariusPower
new file mode 100644
index 000000000..04bc83fd9
--- /dev/null
+++ b/.devsPrefs/AquariusPower/.gitignore.AquariusPower
@@ -0,0 +1,84 @@
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+ivan
+igor/igor
+mihail/mihail
+
+# Editor backup/swap files
+*~
+*.swp
+*.swap
+
+# CMake generated files
+CMakeCache.txt
+CMakeFiles
+CMakeScripts
+cmake_install.cmake
+install_manifest.txt
+Makefile
+
+# Folders and misc stuff like f. ex. save folders :)
+Bones
+/ivan.cfg
+/HScore.dat
+Save
+/Debug/
+/Linux/
+
+# OS / IDE files
+.DS_Store
+
+######
+## Eclipse developers preferences over different operational systems
+## and personalized configurations.
+######
+
+# link to some user folder at /.devsPrefs
+/.devsPrefs/Current
+
+# direct links to preferences at /.devsPrefs/Current
+/.cproject
+/.project
+/.settings
+
+# Git ignore files are special. They are relative to their current path!
+# If the one at '/.devsPrefs/SomeUserName/.gitignore' remains named like that,
+# git will recognize and ignore files as that sub folder is a root folder!
+# Therefore ONLY that file must be named like: '/.devsPrefs/SomeUserName/.gitignore.SomeUserName'
+# And after creating the link to it, the link itself must be renamed to '.gitignore' to be again recognized by git.
+/.gitignore
+
+
+######################### my preferences ############################
+dbgmsg.h
+dbgmsg.cpp
+/Linux/
+/SDL2-2.0.4/
+build
+build.*
diff --git a/.devsPrefs/AquariusPower/.project b/.devsPrefs/AquariusPower/.project
new file mode 100644
index 000000000..678a6a2db
--- /dev/null
+++ b/.devsPrefs/AquariusPower/.project
@@ -0,0 +1,27 @@
+
+
+ Ivan
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/.devsPrefs/AquariusPower/.settings/language.settings.xml b/.devsPrefs/AquariusPower/.settings/language.settings.xml
new file mode 100644
index 000000000..beff3fb72
--- /dev/null
+++ b/.devsPrefs/AquariusPower/.settings/language.settings.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.devsPrefs/AquariusPower/.settings/org.eclipse.cdt.codan.core.prefs b/.devsPrefs/AquariusPower/.settings/org.eclipse.cdt.codan.core.prefs
new file mode 100755
index 000000000..067d6fd2b
--- /dev/null
+++ b/.devsPrefs/AquariusPower/.settings/org.eclipse.cdt.codan.core.prefs
@@ -0,0 +1,73 @@
+eclipse.preferences.version=1
+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
+org.eclipse.cdt.codan.checkers.noreturn=Error
+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
+org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
+org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
diff --git a/.devsPrefs/Attnam/.cproject b/.devsPrefs/Attnam/.cproject
new file mode 100644
index 000000000..8a90643bc
--- /dev/null
+++ b/.devsPrefs/Attnam/.cproject
@@ -0,0 +1,262 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.devsPrefs/Attnam/.gitignore.Attnam
similarity index 100%
rename from .gitignore
rename to .devsPrefs/Attnam/.gitignore.Attnam
diff --git a/.devsPrefs/Attnam/.project b/.devsPrefs/Attnam/.project
new file mode 100644
index 000000000..678a6a2db
--- /dev/null
+++ b/.devsPrefs/Attnam/.project
@@ -0,0 +1,27 @@
+
+
+ Ivan
+
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/.devsPrefs/prepareUser.sh b/.devsPrefs/prepareUser.sh
new file mode 100755
index 000000000..65b2c6c81
--- /dev/null
+++ b/.devsPrefs/prepareUser.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+if [[ ! -L Current ]];then echo "must be run at .devsPrefs folder where is the relative link to the curren usesr: 'Current'!";exit 1;fi
+
+ls -l Current&&:
+echo
+
+strUser="`readlink Current`"
+strUser="`basename "$strUser"`" #grant is is relativised
+declare -p strUser
+echo
+
+cd ..
+pwd
+echo
+
+echo "--------------"
+ls -l .gitignore .cproject .project&&:
+echo
+
+echo ">>>>>>>>>>>>>>> .cproject"
+trash -v .cproject&&:
+ln -vsf .devsPrefs/Current/.cproject .cproject
+echo
+
+echo ">>>>>>>>>>>>>>> .project"
+trash -v .project&&:
+ln -vsf .devsPrefs/Current/.project .project
+echo
+
+echo ">>>>>>>>>>>>>>> .gitignore"
+trash -v .gitignore&&:
+ln -vsf ".devsPrefs/Current/.gitignore.$strUser" .gitignore
+echo
+
+echo "--------------"
+ls -l .gitignore .cproject .project&&:
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..244a643d2
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+indent_size = 2
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.mak]
+indent_style = tab
diff --git a/.travis.yml b/.travis.yml
index ec01a98e4..53fd46643 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,32 +1,92 @@
+# If you want to set up another Travis CI service for your fork (not branch),
+# you can alter it to disable tests and notification for the official repo.
+if: repo = Attnam/ivan
+
sudo: required
dist: trusty
language: cpp
-compiler:
- - clang
- - gcc
+matrix:
+
+ include:
+
+ - env: CXXFLAGS= IVAN_PLATFORM=
+ os: linux
+ compiler: clang
+
+ - env: CXXFLAGS=-DWIZARD IVAN_PLATFORM=
+ os: linux
+ compiler: clang
+
+ - env: CXXFLAGS= IVAN_PLATFORM=
+ os: osx
+ compiler: clang
+
+ - env: CXXFLAGS=-DWIZARD IVAN_PLATFORM=
+ os: osx
+ compiler: clang
+
+ - env: CXXFLAGS= IVAN_PLATFORM=
+ os: linux
+ compiler: gcc
+
+ - env: CXXFLAGS=-DWIZARD IVAN_PLATFORM=
+ os: linux
+ compiler: gcc
+
+ - env: CXXFLAGS= IVAN_PLATFORM=
+ os: osx
+ compiler: gcc
+
+ - env: CXXFLAGS=-DWIZARD IVAN_PLATFORM=
+ os: osx
+ compiler: gcc
+
+ - env: CXXFLAGS=-DWIZARD IVAN_PLATFORM=win
+ os: linux
+ compiler: gcc
+
+ - env: CXXFLAGS=-DWIZARD IVAN_PLATFORM=osx SDL2DIR=$HOME/Thirdparty/Frameworks
+ os: osx
+ compiler: clang
+
+cache:
+ directories:
+ - $HOME/Thirdparty/Frameworks
-os:
- - linux
- - osx
+addons:
+ apt:
+ packages:
+ - libsdl2-dev
+ - libsdl2-mixer-dev
before_install:
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update -qq; fi
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libsdl2-dev; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2; fi
+ - export IVAN_BUILD_DIR=${TRAVIS_BUILD_DIR}/build
+ - export IVAN_FILE_VERSION=${TRAVIS_TAG#v}
+ - if [[ "$TRAVIS_OS_NAME" = osx ]]; then ./ci/osx/requirements.sh; fi
+ - if [[ "$IVAN_PLATFORM" = win ]]; then ./ci/win/requirements.sh; fi
script:
- mkdir build
- cd build
- - cmake -G "Unix Makefiles" -DCMAKE_CXX_FLAGS=$CXXFLAGS ..
+ - if [[ -z "$IVAN_PLATFORM" ]]; then cmake .. -G "Unix Makefiles" -DCMAKE_CXX_FLAGS="-Werror -Wno-format-security -Wno-undefined-var-template -Wno-unknown-warning-option ${CXXFLAGS}"; fi
+ - if [[ -n "$IVAN_PLATFORM" ]]; then "../ci/$IVAN_PLATFORM/build.sh"; fi
- make
- make igor
- make mihail
- - sudo make install
+ - if [[ -z "$IVAN_PLATFORM" ]]; then sudo make install; fi
+ - if [[ -n "$IVAN_PLATFORM" ]]; then make install; fi
+ - if [[ -n "$IVAN_PLATFORM" ]]; then "../ci/$IVAN_PLATFORM/package.sh"; fi
-env:
- matrix:
- - CXXFLAGS=""
- - CXXFLAGS="-DWIZARD"
+deploy:
+ provider: releases
+ api_key: $GH_API_KEY
+ skip_cleanup: true
+ file_glob: true
+ file: $IVAN_BUILD_DIR/$IVAN_PLATFORM/*.zip
+ on:
+ condition: '"$IVAN_PLATFORM" =~ ^(win|osx)$'
+ repo: Attnam/ivan
+ tags: true
+ branch: master
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 91d61154c..13e143edc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,29 +1,52 @@
cmake_minimum_required(VERSION 2.8.12.2)
-
project(ivan CXX C)
-set(PROJECT_VERSION 0.50.7)
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+
+set(VERSION_MAJOR 0)
+set(VERSION_MINOR 54)
+set(PROJECT_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}")
+#set(VERSION_PATCH 0)
+#set(PROJECT_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
add_definitions(-DIVAN_VERSION="${PROJECT_VERSION}" -DUSE_SDL)
+option(BUILD_MAC_APP "Build standalone application for MacOS" OFF)
+
if(UNIX)
add_definitions(-DUNIX)
include(GNUInstallDirs)
- install(DIRECTORY Graphics Script Music DESTINATION "${CMAKE_INSTALL_DATADIR}/ivan")
- add_definitions(-DDATADIR="${CMAKE_INSTALL_FULL_DATADIR}"
- -DLOCAL_STATE_DIR="${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/ivan")
+
+ if(BUILD_MAC_APP)
+ install(DIRECTORY Graphics Script Music Sound DESTINATION "ivan")
+ install(FILES AUTHORS COPYING INSTALL LICENSING NEWS README README.md DESTINATION "docs")
+ add_definitions(-DMAC_APP)
+ else()
+ install(DIRECTORY Graphics Script Music Sound DESTINATION "${CMAKE_INSTALL_DATADIR}/ivan")
+ add_definitions(-DDATADIR="${CMAKE_INSTALL_FULL_DATADIR}"
+ -DLOCAL_STATE_DIR="${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/ivan")
+ endif()
+
elseif(WIN32)
- install(DIRECTORY Graphics Script Music DESTINATION "ivan")
+ install(DIRECTORY Graphics Script Music Sound DESTINATION "ivan")
+ install(FILES AUTHORS COPYING INSTALL LICENSING NEWS README README.md DESTINATION "ivan")
add_definitions(-DWIN32)
+ if(MINGW)
+ set(CMAKE_EXE_LINKER_FLAGS -mwindows)
+ endif(MINGW)
+
# This is bad. To remove below defines, FeLib should switch to std::chrono and serialize time since common epoch.
# 32 bit TIME_T has year 2038 problem. Moreover, serialized value is not portable for time_t in general.
# Switching to std::chrono should not be hard, but it's not a topic for this pull request.
add_definitions(-D_USE_32BIT_TIME_T)
-endif()
+endif(UNIX)
add_subdirectory(FeLib)
add_subdirectory(audio)
add_subdirectory(Main)
add_subdirectory(igor)
add_subdirectory(mihail)
+add_subdirectory(xbrzscale)
+add_subdirectory(fantasyname)
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..a23e18c8f
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,74 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level of experience,
+nationality, personal appearance, race, religion, or sexual identity and
+orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at capristo@attnam.com. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
diff --git a/Doc/HelperScripts/prepareCmdsDescrCode.sh b/Doc/HelperScripts/prepareCmdsDescrCode.sh
new file mode 100755
index 000000000..2ceebf30b
--- /dev/null
+++ b/Doc/HelperScripts/prepareCmdsDescrCode.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+echo "//this script will prepare the full code to determine what commands will enable stretched/scaledup blitting regions"
+echo "//just paste the output in the proper source file!"
+
+cd ../../Main/Source
+
+sedCollectDescription='s@[^"]*"([^"]*)".*@\1@'
+sedPrepareCode='s@.*@if(strcmp(str,"&")==0)return true;@'
+
+egrep "new command" command.cpp \
+ |sed -r \
+ -e "$sedCollectDescription" \
+ -e "$sedPrepareCode" # already in alphabetic order for user cmds
diff --git a/Doc/Misc/DefinesValidator.txt b/Doc/Misc/DefinesValidator.txt
new file mode 100644
index 000000000..0aa1731e3
--- /dev/null
+++ b/Doc/Misc/DefinesValidator.txt
@@ -0,0 +1,18 @@
+To see how it works, modify the define.dat file like
+
+1) change ex. TORSO value to 2 (so that it will differ from TORSO value at ivandef.h, could be other .h file tho),
+actually the problem will happen when someone create a new value at define.dat and use another value at c++ .h files with the same `#define` identifier,
+or when someone changes a value only at `define.dat` or at some c++ .h file, so they we be out of sync.
+
+2) compile and install the game.
+
+3) go to that option and toggle it to yes.
+
+4) the file `definesvalidator.h` will be created at the same path where the `ivan.conf` is located.
+
+5) move `definesvalidator.h` to the project development path at `Main/Include/definesvalidator.h` overwriting it
+
+6) compile and install again so that the validator will know what value the c++ `#define` should have, based on the define.dat file.
+in case c++ has no such define, it will be ignored ex.: the check will be performed only `#ifdef EMISSARY` (currently not used in c++ .h files)
+
+7) run and activate that option to `yes`, it will abort complaining about TORSO value with this message: "Defined TORSO with value 2 from .dat file mismatches hardcoded c++ define value of 1!"
diff --git a/Doc/Misc/MirrorFlipRotateToDegrees.jpg b/Doc/Misc/MirrorFlipRotateToDegrees.jpg
new file mode 100644
index 000000000..e6c6d4b1a
Binary files /dev/null and b/Doc/Misc/MirrorFlipRotateToDegrees.jpg differ
diff --git a/Doc/Misc/SaveGameImportingOldVersion.txt b/Doc/Misc/SaveGameImportingOldVersion.txt
new file mode 100644
index 000000000..e32cec314
--- /dev/null
+++ b/Doc/Misc/SaveGameImportingOldVersion.txt
@@ -0,0 +1,47 @@
+(changed from: https://github.com/Attnam/ivan/issues/346)
+
+Based on the version collected on the savegame binary file, a simple code can implemented like this:
+
+if(loadedSavegameFileVersion >= 132){
+// load new stuff from 132
+}
+
+if(loadedSavegameFileVersion >= 133){
+// load new stuff from 133
+}
+
+Only to load the savegame of course, and at all related classes that may have new stuff.
+
+ex.:
+v132 [ some old data ] [ some old dataaaaaaa ] [ some old dataaaaaaaaaaaaaa ]
+v133 [ some old data ] [ some old dataaaaaaa ] [ some NEW v133 data ] [ some old dataaaaaaaaaaaaaa ]
+
+The importer at v133 to load v132, if it just skip loading "some NEW v133 data" from v132, even if it is not in the end of the file, may work well, just test it!
+
+=====================================
+
+Being simple means no compatibilization should be coded, ex. if gameplay was too easy, when importing an old save, the result shall not be modified to make it adequate to the new way things work.
+
+So, after the import ends, the things that were not imported (from the end of the savegame binary file), that were missing, "will probably/expectedly" receive default values equivalent to when starting a new game.
+That's why an import "may" work. The user may try the importer, or just continue playing using the old game version til char's death.
+
+Anyway, if in some special case, something severe changes breaking the game to an unplayable point, the import will fail, may be from save version 131 to 141 too many critical things changed and it could fail, but if the user upgrade the save, thru all "game versions" "importer" one by one, then instead of importing directly to save version 141, going every step (132, 133, 134 etc) could probably make it work better, may be...
+
+
+
+
+
+
+
+
+
+
+
+/////////////////////////////// TODO one day may be //////////////////////////////////////
+
+Another thing I thought would be to create savegames structure based on tokens/IDs for each data sector.
+
+Not necessarily a xml file, neither a non binary save (user readable/editable would not be good),
+so it could be some kind of binary with tokens delimiting sectors.
+
+That way these gaps, or saved data position changing, created by new savegame versions could (probably) not be a problem at all, and there would (probably) not have compatibility problems.
diff --git a/ChangeLog b/Doc/Obsolete/ChangeLog
similarity index 100%
rename from ChangeLog
rename to Doc/Obsolete/ChangeLog
diff --git a/Doc/Obsolete/convertSoundEffectsFileToNewCfgFormat.sh b/Doc/Obsolete/convertSoundEffectsFileToNewCfgFormat.sh
new file mode 100755
index 000000000..24236dd22
--- /dev/null
+++ b/Doc/Obsolete/convertSoundEffectsFileToNewCfgFormat.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+##############
+#### sed commands also restores CR for windows users
+##############
+sedB4EndCR='s@.*@&\r@'
+sedGet1stFileName='s"([^.]*)[.]wav.*"\1"'
+
+IFS=$'\n' read -d '' -r -a astrList < <(cat config.txt |tr -d '\r'); #removes CR too
+for((i=0;i<${#astrList[@]};i++));do
+ strLine="${astrList[i]}";
+
+ if((i%2==0));then
+ strRegex="$strLine";
+ else
+ strFiles="`echo "$strLine" |tr ' ' ',' |sed 's",", "g'`"
+ strDesc="`echo "$strFiles" |sed -r "$sedGet1stFileName"`"
+ echo "$strDesc; $strFiles;$strRegex"; # the sound files is the 2nd line
+ fi;
+done \
+ |sort \
+ |sed -r "$sedB4EndCR" \
+ >SoundEffects.cfg
+
+if((`cat config.txt |wc -l` != (`cat SoundEffects.cfg |wc -l`*2) ));then
+ echo "SOME PROBLEM HAPPENED!"
+fi
+
+# prettyfiing readability
+sedGetDesc='s"([^;]*);.*"\1"'
+IFS=$'\n' read -d '' -r -a astrList < <(cat SoundEffects.cfg |tr -d '\r'); #removes CR too
+for((i=0;i<${#astrList[@]};i++));do
+ strLine="${astrList[i]}";
+ strDesc="`echo "$strLine" |sed -r "$sedGetDesc"`"
+
+ if [[ "$strDescPrev" != "$strDesc" ]];then
+ strFullDesc="### $strDesc ###"
+ strDescOutline="`printf "%0${#strFullDesc}d\n" 0 |tr '0' '#'`"
+
+ echo "$strDescOutline"
+ echo "$strFullDesc"
+ echo "$strDescOutline"
+ fi
+
+ echo "$strLine"
+ echo
+
+ strDescPrev="$strDesc"
+done >SoundEffects.cfg
diff --git a/Doc/Obsolete/sortSoundEffectsFile.sh b/Doc/Obsolete/sortSoundEffectsFile.sh
new file mode 100755
index 000000000..783e8dde2
--- /dev/null
+++ b/Doc/Obsolete/sortSoundEffectsFile.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+#~ ls -l config.txt
+#~ echo "newline, word, character, byte, maximum line length"
+#~ wc -cmlwL config.txt
+#~ echo
+
+#~ cat config.txt |tr -d '\r' >config.NoCR.txt
+#~ ls -l config.NoCR.txt
+#~ wc -cmlwL config.NoCR.txt
+#~ echo
+
+##############
+#### sed commands also restores CR for windows users
+##############
+sedMiddleCRNL='s@[\]n@\r\n@'
+sedB4EndCR='s@.*@&\r@'
+
+IFS=$'\n' read -d '' -r -a astrList < <(cat config.txt |tr -d '\r'); #removes CR too
+#IFS=$'\n' read -d '' -r -a astrList < <(cat config.NoCR.txt); #removes CR too
+str2="";
+for((i=0;i<${#astrList[@]};i++));do
+ strLine="${astrList[i]}";
+
+ str2+="$strLine";
+ if((i%2==0));then
+ str2+="\n"; # add NL readable marker
+ else
+ echo "$str2";
+ str2="";
+ fi;
+done \
+ |sort \
+ |sed -r \
+ -e "$sedB4EndCR" \
+ -e "$sedMiddleCRNL" \
+ >config.SORTED.txt
+
+#~ ls -l config.SORTED.txt
+#~ echo "newline, word, character, byte, maximum line length"
+#~ wc -cmlwL config.SORTED.txt
+#~ echo
+
+#~ if read -p "all seems ok? (hit ctrl+c to stop)" -n 1;then
+ #~ mv -v config.SORTED.txt config.txt
+ #~ ls -l config*
+ #~ echo "newline, word, character, byte, maximum line length"
+ #~ wc -cmlwL config.txt
+#~ fi
+
+if((`cat config.txt |wc -l`==`cat config.SORTED.txt |wc -l`));then
+ mv -v config.SORTED.txt config.txt
+fi
diff --git a/Doc/OutlinedGraphicsHowTo/Char.xcf b/Doc/OutlinedGraphicsHowTo/Char.xcf
new file mode 100644
index 000000000..a881b24f6
Binary files /dev/null and b/Doc/OutlinedGraphicsHowTo/Char.xcf differ
diff --git a/Doc/OutlinedGraphicsHowTo/CharExample-HowToConvert.txt b/Doc/OutlinedGraphicsHowTo/CharExample-HowToConvert.txt
new file mode 100644
index 000000000..38ae41b7f
--- /dev/null
+++ b/Doc/OutlinedGraphicsHowTo/CharExample-HowToConvert.txt
@@ -0,0 +1,29 @@
+Outline pixel quality for new additions, using gimp (see Char.xcf for details)
+
+- use the wand [fuzzy select tool] on the background of "LatestWork"
+- invert selection (so pictures are now the content of the OutlineSelection)
+- ctrl+c to copy the OutlineSelection and just paste what will create a floating layer and make it become a real new layer "LatestPictures"
+
+- grow OutlineSelection by 1
+- create a new layer OutlineSimpleAfterGrow1 (below "LatestPictures") and paint the inside of the selections with black (0,0,0)
+- zoom in and take care of the outline corners to avoid getting too bold. just look on the already done work as reference.
+
+- open Char.png on gimp, and temporarily merge all visible layers on Char.xcf (and undo just after) to copy the final result inside Char.png, to keep the correct file format after you select "overwrite" to save it.
+
+
+TIP: fast click on one layer eye to see the differences of old and new pictures
+
+
+TIP: convert from pcx to png (there may have a better way but...)
+
+ in this order:
+ - open the pcx file on gimp
+ - copy the png file to a new one (I will call it new.png)
+ - open new.png on gimp
+ - copy the contents of pcx file into new.png
+ - save overwriting
+
+ this will keep the correct file format.
+
+
+TIP: these stuff can be done in many ways, these are just the way I found, if you find a better way we would like to know :)
diff --git a/Doc/OutlinedGraphicsHowTo/Humanoid.xcf b/Doc/OutlinedGraphicsHowTo/Humanoid.xcf
new file mode 100644
index 000000000..985d760ae
Binary files /dev/null and b/Doc/OutlinedGraphicsHowTo/Humanoid.xcf differ
diff --git a/Doc/OutlinedGraphicsHowTo/Item.xcf b/Doc/OutlinedGraphicsHowTo/Item.xcf
new file mode 100644
index 000000000..2a02060e4
Binary files /dev/null and b/Doc/OutlinedGraphicsHowTo/Item.xcf differ
diff --git a/Doc/OutlinedGraphicsHowTo/char.pcx b/Doc/OutlinedGraphicsHowTo/char.pcx
new file mode 100644
index 000000000..f346b9e6b
Binary files /dev/null and b/Doc/OutlinedGraphicsHowTo/char.pcx differ
diff --git a/Doc/OutlinedGraphicsHowTo/humanoid.pcx b/Doc/OutlinedGraphicsHowTo/humanoid.pcx
new file mode 100644
index 000000000..0bf54f273
Binary files /dev/null and b/Doc/OutlinedGraphicsHowTo/humanoid.pcx differ
diff --git a/Doc/OutlinedGraphicsHowTo/item.pcx b/Doc/OutlinedGraphicsHowTo/item.pcx
new file mode 100644
index 000000000..f0f5b9064
Binary files /dev/null and b/Doc/OutlinedGraphicsHowTo/item.pcx differ
diff --git a/FeLib/CMakeLists.txt b/FeLib/CMakeLists.txt
index 80362a4be..c28c44753 100644
--- a/FeLib/CMakeLists.txt
+++ b/FeLib/CMakeLists.txt
@@ -1,21 +1,19 @@
file(GLOB FELIB_SOURCES Include/*.h Source/*.cpp)
-if(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_definitions(-DGCC) # TODO: Use __GNUC__ in the code instead.
endif()
-add_library(FeLib ${FELIB_SOURCES})
+option(IGNORE_EXTRA_WHITESPACES "Sets CMP0004 to OLD" OFF)
-set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
-find_package(SDL2)
-if(SDL2_FOUND)
- message(STATUS "Using SDL2")
-else()
- message(WARNING "SDL2 not found")
- find_package(SDL 1.2.0 REQUIRED)
- message(STATUS "Using SDL1")
+if(IGNORE_EXTRA_WHITESPACES)
+ cmake_policy(SET CMP0004 OLD)
endif()
+add_library(FeLib ${FELIB_SOURCES})
+
+find_package(SDL2 REQUIRED)
+
if(MSVC)
# Not very pretty solution. This finds SDL2.dll from SDL2.lib path, so that it can be installed where ivan.exe will end up.
message("SDL2_LIBRARY ${SDL2_LIBRARY}")
@@ -33,11 +31,36 @@ if(MINGW)
message("sdl_lib_dir ${sdl_lib_dir}")
get_filename_component(sdl_lib_dir "${sdl_lib_dir}" DIRECTORY)
message("sdl_lib_dir ${sdl_lib_dir}")
- install(FILES "${sdl_lib_dir}/../bin/SDL2.dll" DESTINATION "ivan")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
+ if((NOT BUILD_SHARED_LIBS) AND BUILD_STATIC_LIBS)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
+ set(SDL2_LIBRARIES ${SDL2_LIBRARY} ${SDL2_LDFLAGS})
+ else()
+ install(FILES "${sdl_lib_dir}/../bin/SDL2.dll" DESTINATION "ivan")
+ endif()
+endif()
+
+# Try finding libpng using pkg-config first, because find_package(PNG) finds a
+# mismatching header + library combination for me.
+include(FindPkgConfig)
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PNG libpng)
+ set(PNG_LIBRARIES ${PNG_LDFLAGS})
+endif()
+if(NOT PNG_FOUND)
+ find_package(PNG REQUIRED)
+ add_definitions(${PNG_DEFINITIONS})
endif()
target_include_directories(FeLib PUBLIC Include)
-target_include_directories(FeLib SYSTEM PUBLIC ${SDL2_INCLUDE_DIR})
-target_link_libraries(FeLib ${SDL2_LIBRARY})
+target_include_directories(FeLib SYSTEM PUBLIC ${SDL2_INCLUDE_DIR} PRIVATE ${PNG_INCLUDE_DIRS})
+target_include_directories(FeLib PUBLIC ../xbrzscale ../xbrzscale/xbrz)
+
+if((NOT BUILD_SHARED_LIBS) AND BUILD_STATIC_LIBS)
+ target_link_libraries(FeLib ${PNG_LIBRARIES} ${SDL2_LIBRARIES} -static-libgcc -static-libstdc++)
+else()
+ target_link_libraries(FeLib ${SDL2_LIBRARY} ${PNG_LIBRARIES})
+endif()
+
+target_compile_options(FeLib PUBLIC ${SDL2_CFLAGS} ${SDL2_CFLAGS_OTHER})
+
diff --git a/FeLib/Include/bitmap.h b/FeLib/Include/bitmap.h
index 5534e3600..bbeb3e287 100644
--- a/FeLib/Include/bitmap.h
+++ b/FeLib/Include/bitmap.h
@@ -14,6 +14,7 @@
#define __BITMAP_H__
#include "v2.h"
+#include "SDL.h"
class bitmap;
class rawbitmap;
@@ -37,6 +38,7 @@ struct blitdata
col16 MaskColor;
ulong CustomData;
};
+#define DEFAULT_BLITDATA {NULL,{0,0},{0,0},{0,0}, {0}, TRANSPARENT_COLOR,0} //easy initializer TODO should be TRANSPARENT_COLOR? TODO update everywere with this default and just apply there differences to shrink the code?
class bitmap
{
@@ -83,6 +85,11 @@ class bitmap
void DrawHorizontalLine(int, int, int, col16, truth = false);
void StretchBlit(cblitdata&) const;
+ void StretchBlitXbrz(cblitdata&,bool) const;
+ SDL_Surface* CopyToSurface(v2 v2TopLeft, v2 v2Size, col16 MaskColor = TRANSPARENT_COLOR, SDL_Surface* srf = NULL) const;
+
+ static void ResetBlitdataRotation(blitdata& B);
+ static void ConfigureBlitdataRotation(blitdata& B,int i);
void DrawRectangle(int, int, int, int, col16, truth = false);
void DrawRectangle(v2, int, int, col16, truth = false);
@@ -132,6 +139,10 @@ class bitmap
void MoveLineVertically(int, int);
void MoveLineHorizontally(int, int);
void InterLace();
+
+ truth HasColor(col16 findColor);
+ void ReplaceColor(col16 findColor,col16 replaceWith);
+ void CopyLineFrom(int iYDest, bitmap* bmpFrom, int iYFrom, int iSize, bool bFailSafe=false);
protected:
v2 Size;
ulong XSizeTimesYSize : 31;
@@ -140,6 +151,8 @@ class bitmap
packalpha** AlphaMap;
packpriority** PriorityMap;
truth* RandMap;
+ SDL_Surface* img;
+ SDL_Surface* imgStretched;
};
inline void bitmap::SafeUpdateRandMap(v2 Pos, truth What)
diff --git a/FeLib/Include/config.h b/FeLib/Include/config.h
index 265e458b4..74dbf632d 100644
--- a/FeLib/Include/config.h
+++ b/FeLib/Include/config.h
@@ -31,7 +31,7 @@ class configsystem
static truth Save();
static truth Load();
static void Show(void (*)() = 0, void (*)(felist&) = 0, truth = false);
- static void AddOption(configoption*);
+ static void AddOption(festring fsCategory, configoption*);
static void NormalStringDisplayer(const stringoption*, festring&);
static void NormalNumberDisplayer(const numberoption*, festring&);
static void NormalTruthDisplayer(const truthoption*, festring&);
@@ -62,9 +62,10 @@ struct configoption
virtual void SaveValue(std::ofstream&) const = 0;
virtual void LoadValue(inputfile&) = 0;
virtual truth ActivateChangeInterface() = 0;
- virtual void DisplayeValue(festring&) const = 0;
+ virtual void DisplayValue(festring&) const = 0;
cchar* Name;
cchar* Description;
+ festring fsCategory;
};
struct stringoption : public configoption
@@ -78,7 +79,7 @@ struct stringoption : public configoption
= &configsystem::NormalStringChanger);
virtual void SaveValue(std::ofstream&) const;
virtual void LoadValue(inputfile&);
- virtual void DisplayeValue(festring& Entry) const
+ virtual void DisplayValue(festring& Entry) const
{ ValueDisplayer(this, Entry); }
virtual truth ActivateChangeInterface() { return ChangeInterface(this); }
void ChangeValue(cfestring& What) { ValueChanger(this, What); }
@@ -99,7 +100,7 @@ struct numberoption : public configoption
= &configsystem::NormalNumberChanger);
virtual void SaveValue(std::ofstream&) const;
virtual void LoadValue(inputfile&);
- virtual void DisplayeValue(festring& Entry) const
+ virtual void DisplayValue(festring& Entry) const
{ ValueDisplayer(this, Entry); }
virtual truth ActivateChangeInterface() { return ChangeInterface(this); }
void ChangeValue(long What) { ValueChanger(this, What); }
@@ -131,7 +132,7 @@ struct truthoption : public configoption
= &configsystem::NormalTruthChanger);
virtual void SaveValue(std::ofstream&) const;
virtual void LoadValue(inputfile&);
- virtual void DisplayeValue(festring& Entry) const
+ virtual void DisplayValue(festring& Entry) const
{ ValueDisplayer(this, Entry); }
virtual truth ActivateChangeInterface() { return ChangeInterface(this); }
void ChangeValue(truth What) { ValueChanger(this, What); }
@@ -152,7 +153,7 @@ struct cycleoption : public configoption
= &configsystem::NormalCycleChanger);
virtual void SaveValue(std::ofstream&) const;
virtual void LoadValue(inputfile&);
- virtual void DisplayeValue(festring& Entry) const
+ virtual void DisplayValue(festring& Entry) const
{ ValueDisplayer(this, Entry); }
virtual truth ActivateChangeInterface() { return ChangeInterface(this); }
void ChangeValue(long What) { ValueChanger(this, What); }
diff --git a/FeLib/Include/dbgmsgproj.h b/FeLib/Include/dbgmsgproj.h
new file mode 100644
index 000000000..8b1264a42
--- /dev/null
+++ b/FeLib/Include/dbgmsgproj.h
@@ -0,0 +1,109 @@
+#ifndef INCLUDE_DBGMSGPROJ_H_
+#define INCLUDE_DBGMSGPROJ_H_
+
+// just copy this file freely anywhere or it's contents
+#ifdef DBGMSG
+ #include "dbgmsg.h"
+
+ /************************************************************
+ * CUSTOM / PROJECT SPECIFIC, modify at will
+ ************************************************************/
+ #ifndef DBGMSG_OBJ //do NOT define this in your project cpp files!
+ #include
+
+ #define DBGCHAR(ch,info) DBG8(info, ch->CHAR_NAME(DEFINITE), ch->GetAssignedName().CStr(), ch, ch->GetID(), ch->IsPlayer(), ch->GetStack()->GetItems(), ch->GetEquipments() ) //, std::bitset<16>(ch->GetFlags()) )
+ #define DBGITEM(it,info) DBG3(info,it,(it==NULL?0:it->GetID()))
+ #define DBGABORT(x...) ABORT(x) //will only abort in development mode
+
+ class dbgmsgprj{
+ public:
+
+ #ifdef DBGMSG_STRETCHREGION
+ #define DBGMSG_BLITDATA // alows the dependency
+ #define DBGSRI(info) DBG1( dbgmsgprj::dbgSRI(rSR,info).str())
+ #define DBGSR DBGSRI("")
+ static std::stringstream dbgSRI(stretchRegion& SR,const char* strInfo){
+ blitdata& rB=SR.B;
+ std::stringstream ss;
+ ss<GetSize()
+ if(rB.Bitmap!=NULL)ss<<"BitmapSize="<GetSize().X<<","<GetSize().Y<<"/";
+ return ss;
+ }
+ #endif //DBGMSG_BLITDATA
+
+ #ifdef DBGMSG_V2
+ #define DBGAV2(v2) dbgmsgprj::dbgV2(v2,DBGTOSTR(v2)).str()
+ #define DBGSV2(v2) DBGSS(DBGAV2(v2))
+ static std::stringstream dbgV2(v2 v2Val,const char* c){
+ std::stringstream ss;
+ ss< Entry;
@@ -79,6 +86,11 @@ class felist
uint UpKey;
uint DownKey;
entrydrawer EntryDrawer;
+ v2 v2FinalPageSize;
+ static v2 v2SelectedPos;
+ static col16 colSelectedBkg;
+ v2 v2OriginalPos;
+ static v2 v2DefaultEntryImageSize;
};
#endif
diff --git a/FeLib/Include/graphics.h b/FeLib/Include/graphics.h
index 5f8862547..ade274034 100644
--- a/FeLib/Include/graphics.h
+++ b/FeLib/Include/graphics.h
@@ -13,6 +13,8 @@
#ifndef __GRAPHICS_H__
#define __GRAPHICS_H__
+#include
+
#ifdef USE_SDL
#include "SDL.h"
#endif
@@ -27,38 +29,78 @@ class bitmap;
class rawbitmap;
class festring;
+typedef void (*drawabove)(bitmap*);
+
class graphics
{
public:
friend class bitmap;
static void Init();
static void DeInit();
+
#ifdef USE_SDL
+ static void SetScale(int);
static void SwitchMode();
+ static void SetMode(cchar*, cchar*, v2, int, int, truth);
#endif
+
#ifdef __DJGPP__
static void SwitchMode() { }
-#endif
static void SetMode(cchar*, cchar*, v2, truth);
+#endif
+
+ static void Stretch(bool, bitmap*, blitdata&, bool);
+ static void DrawRectangleOutlineAround(bitmap* bmpAt, v2 v2TopLeft, v2 v2Border, col16 color, bool wide);
static void BlitDBToScreen();
+
+ static void DrawAboveAll(bitmap* bmpDest);
+ static void AddDrawAboveAll(drawabove da, int iPriority, const char* desc);
+
static v2 GetRes() { return Res; }
static bitmap* GetDoubleBuffer() { return DoubleBuffer; }
static void LoadDefaultFont(cfestring&);
static rawbitmap* GetDefaultFont() { return DefaultFont; }
- static void SetSwitchModeHandler(void (*What)())
- { SwitchModeHandler = What; }
+ static void SetSwitchModeHandler(void (*What)()){ SwitchModeHandler = What; }
+
+ static int AddStretchRegion(blitdata B,const char* strId);
+ static int GetTotSRegions();
+ static void SetSpecialListItemAltPos(bool b){bSpecialListItemAltPos=b;}
+ static void SetAllowStretchedBlit(){bAllowStretchedRegionsBlit=true;} //as the dungeon shows most of the time,
+ static void SetDenyStretchedBlit(){bAllowStretchedRegionsBlit=false;} //it should be denied only during a few moments.
+ static bool isStretchedRegionsAllowed();
+ static void PrepareBeforeDrawingFelist();
+ static void DrawAtDoubleBufferBeforeFelistPage();
+ static bitmap* PrepareBuffer();
+
+ //TODO utility class for sregion?
+ static bool IsSRegionEnabled(int iIndex);
+ static void SetSRegionEnabled(int iIndex, bool b);
+ static void SetSRegionUseXBRZ(int iIndex, bool b);
+ static void SetSRegionDrawAfterFelist(int iIndex, bool b);
+ static void SetSRegionDrawAlways(int iIndex, bool b);
+ static void SetSRegionDrawBeforeFelistPage(int iIndex, bool, bool);
+ static void SetSRegionDrawRectangleOutline(int iIndex, bool b);
+ static void SetSRegionSrcBitmapOverride(int iIndex, bitmap* bmp, int iStretch, v2 v2Dest);
+ static void SetSRegionListItem(int iIndex);
+ static int SetSRegionBlitdata(int iIndex, blitdata B);
+ static void SetSRegionClearSquaresAt(int iIndex, v2 v2Size, std::vector vv2);
+
#ifdef USE_SDL
-#if SDL_MAJOR_VERSION == 1
- static SDL_Surface* Screen;
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- static SDL_Surface* TempSurface;
-#endif
-#else
- static SDL_Window* Window;
- static SDL_Renderer *Renderer;
- static SDL_Texture *Texture;
-#endif
+ #if SDL_MAJOR_VERSION == 1
+ static SDL_Surface* Screen;
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ static SDL_Surface* TempSurface;
+ #endif
+ #else
+ public:
+ static SDL_Window* GetWindow(){return Window;};
+ private:
+ static SDL_Window* Window;
+ static SDL_Renderer *Renderer;
+ static SDL_Texture *Texture;
+ #endif
#endif
+
private:
static void (*SwitchModeHandler)();
#ifdef __DJGPP__
@@ -114,7 +156,11 @@ class graphics
} ModeInfo;
#endif
static bitmap* DoubleBuffer;
+ static bitmap* StretchedBuffer;
+ static truth bAllowStretchedRegionsBlit;
+ static truth bSpecialListItemAltPos;
static v2 Res;
+ static int Scale;
static int ColorDepth;
static rawbitmap* DefaultFont;
};
diff --git a/FeLib/Include/hscore.h b/FeLib/Include/hscore.h
index 4caf3ff3d..f3857a334 100644
--- a/FeLib/Include/hscore.h
+++ b/FeLib/Include/hscore.h
@@ -19,11 +19,11 @@
#include "festring.h"
#ifdef UNIX
-#define HIGH_SCORE_FILENAME LOCAL_STATE_DIR "/ivan-highscore.scores"
+#define HIGH_SCORE_FILENAME "ivan-highscore.scores"
#endif
#if defined(WIN32) || defined(__DJGPP__)
-#define HIGH_SCORE_FILENAME CONST_S("HScore.dat")
+#define HIGH_SCORE_FILENAME "HScore.dat"
#endif
class festring;
@@ -31,11 +31,11 @@ class festring;
class highscore
{
public:
- highscore(cfestring& = HIGH_SCORE_FILENAME);
+ highscore(cfestring&);
truth Add(long, cfestring&);
void Draw() const;
- void Save(cfestring& = HIGH_SCORE_FILENAME) const;
- void Load(cfestring& = HIGH_SCORE_FILENAME);
+ void Save(cfestring& = "") const;
+ void Load(cfestring& = "");
truth LastAddFailed() const;
void AddToFile(highscore*) const;
truth MergeToFile(highscore*) const;
@@ -54,6 +54,7 @@ class highscore
std::vector RandomID;
int LastAdd;
ushort Version;
+ cfestring DefaultFile;
};
#endif
diff --git a/FeLib/Include/rawbit.h b/FeLib/Include/rawbit.h
index a234cbbf8..5d1df428b 100644
--- a/FeLib/Include/rawbit.h
+++ b/FeLib/Include/rawbit.h
@@ -29,6 +29,7 @@ typedef std::map> fontcache;
class rawbitmap
{
public:
+ friend class bitmap;
rawbitmap(cfestring&);
rawbitmap(v2);
~rawbitmap();
diff --git a/FeLib/Include/save.h b/FeLib/Include/save.h
index 014caccb8..e639a6f36 100644
--- a/FeLib/Include/save.h
+++ b/FeLib/Include/save.h
@@ -14,7 +14,7 @@
#define __SAVE_H__
#include
-#include
+#include
#include
#include
#include
@@ -40,30 +40,28 @@ inline inputfile& operator>>(inputfile& SaveFile, type& Value)\
typedef std::map valuemap;
-/* fstream seems to bug with DJGPP, so we use FILE* here */
-
class outputfile
{
public:
outputfile(cfestring&, truth = true);
- ~outputfile();
- void Put(char What) { fputc(What, Buffer); }
- void Write(cchar* Offset, long Size)
- { fwrite(Offset, 1, Size, Buffer); }
- truth IsOpen() { return Buffer != 0; }
- void Close() { fclose(Buffer); Buffer = 0; }
- void Flush() { fflush(Buffer); }
- void ReOpen();
+ void Put(char What) { File.put(What); }
+ void Write(cchar* Data, long Size) { File.write(Data, Size); }
+ truth IsOpen() { return File.is_open(); }
+ void Close();
+ ~outputfile(){Close();}
+ static void SetSafeSaving(truth b);
private:
- FILE* Buffer;
+ static truth bakcupBeforeSaving;
+ static truth saveOnNewFileAlways;
+ std::ofstream File;
festring FileName;
+ festring FileNameNewTmp;
};
class inputfile
{
public:
inputfile(cfestring&, const valuemap* = 0, truth = true);
- ~inputfile();
festring ReadWord(truth = true);
void ReadWord(festring&, truth = true);
char ReadLetter(truth = true);
@@ -71,23 +69,22 @@ class inputfile
festring ReadStringOrNumber (long *num, truth *isString, truth PreserveTerminator=false);
v2 ReadVector2d();
rect ReadRect();
- int Get() { return fgetc(Buffer); }
- void Read(char* Offset, long Size) { fread(Offset, 1, Size, Buffer); }
- truth IsOpen() { return Buffer != 0; }
- truth Eof() { return feof(Buffer); }
- void ClearFlags() { clearerr(Buffer); }
- void SeekPosBegin(long Offset) { fseek(Buffer, Offset, SEEK_SET); }
- void SeekPosCurrent(long Offset) { fseek(Buffer, Offset, SEEK_CUR); }
- void SeekPosEnd(long Offset) { fseek(Buffer, Offset, SEEK_END); }
- long TellPos() { return ftell(Buffer); }
+ int Get() { return File.get(); }
+ void Read(char* Data, long Size) { File.read(Data, Size); }
+ truth IsOpen() { return File.is_open(); }
+ truth Eof() { return File.eof(); }
+ void SeekPosBegin(long Offset) { File.seekg(Offset, std::ios::beg); }
+ void SeekPosCurrent(long Offset) { File.seekg(Offset, std::ios::cur); }
+ void SeekPosEnd(long Offset) { File.seekg(Offset, std::ios::end); }
+ long TellPos() { return File.tellg(); }
ulong TellLine() { return TellLineOfPos(TellPos()); }
ulong TellLineOfPos(long);
cfestring& GetFileName() const { return FileName; }
- void Close() { fclose(Buffer); Buffer = 0; }
+ void Close() { File.close(); }
private:
festring ReadNumberIntr (int CallLevel, long *num, truth *isString, truth allowStr, truth PreserveTerminator);
int HandlePunct(festring&, int, int);
- FILE* Buffer;
+ std::ifstream File;
festring FileName;
const valuemap* ValueMap;
truth lastWordWasString;
diff --git a/FeLib/Include/whandler.h b/FeLib/Include/whandler.h
index 7fab8afb2..c5fb6a500 100644
--- a/FeLib/Include/whandler.h
+++ b/FeLib/Include/whandler.h
@@ -28,12 +28,24 @@
#define GET_KEY globalwindowhandler::GetKey
#define READ_KEY globalwindowhandler::ReadKey
#define GET_TICK globalwindowhandler::GetTick
+#define WAIT_FOR_KEY_DOWN globalwindowhandler::WaitForKeyDown
+#define WAIT_FOR_KEY_UP globalwindowhandler::WaitForKeyUp
class globalwindowhandler
{
public:
+ static void CheckKeyTimeout();
+ static truth IsKeyTimeoutEnabled();
+ static void SetKeyTimeout(int iTimeoutMillis,int iDefaultReturnedKey);
+ static void SetPlayInBackground(truth b){playInBackground=b;}
+ static float GetFPS(bool bInsta);
+ static truth HasKeysOnBuffer();
static int GetKey(truth = true);
static int ReadKey();
+ static truth WaitForKeyEvent(uint Key);
+ static truth WaitForKeyDown(){return WaitForKeyEvent(SDL_KEYDOWN);}
+ static truth WaitForKeyUp (){return WaitForKeyEvent(SDL_KEYUP );}
+ static truth IsLastSDLkeyEventWasKeyUp();
static void InstallControlLoop(truth (*)());
static void DeInstallControlLoop(truth (*)());
static ulong GetTick() { return Tick; }
@@ -41,13 +53,12 @@ class globalwindowhandler
static void EnableControlLoops() { ControlLoopsEnabled = true; }
static void DisableControlLoops() { ControlLoopsEnabled = false; }
static truth ShiftIsDown();
- static void SetScrshotDirectory(cfestring& DirectoryName)
- { ScrshotDirectoryName = DirectoryName; }
+ static void SetScrshotDirectory(cfestring& DirectoryName){ ScrshotDirectoryName = DirectoryName; }
static festring ScrshotNameHandler(); // Number successive screenshots based on existing filenames
+ static void SetAddFrameSkip(int i);
#ifdef USE_SDL
static void Init();
- static void SetQuitMessageHandler(truth (*What)())
- { QuitMessageHandler = What; }
+ static void SetQuitMessageHandler(truth (*What)()){ QuitMessageHandler = What; }
static ulong UpdateTick() { return Tick = SDL_GetTicks() / 40; }
#endif
#ifdef __DJGPP__
@@ -65,6 +76,7 @@ class globalwindowhandler
static int Controls;
static ulong Tick;
static truth ControlLoopsEnabled;
+ static truth playInBackground;
static festring ScrshotDirectoryName;
};
diff --git a/FeLib/Source/bitmap.cpp b/FeLib/Source/bitmap.cpp
index c5265679a..01953b945 100644
--- a/FeLib/Source/bitmap.cpp
+++ b/FeLib/Source/bitmap.cpp
@@ -12,6 +12,8 @@
#include
#include
+#include
+#include
#include "bitmap.h"
#include "graphics.h"
@@ -19,6 +21,10 @@
#include "allocate.h"
#include "femath.h"
#include "rawbit.h"
+#include "libxbrzscale.h"
+
+#define DBGMSG_V2
+#include "dbgmsgproj.h"
/*
* Blitting must be as fast as possible, even if no optimizations are used;
@@ -109,56 +115,21 @@ int Blue;\
bitmap::bitmap(cfestring& FileName)
: FastFlag(0), AlphaMap(0), PriorityMap(0), RandMap(0)
{
- inputfile File(FileName.CStr(), 0, false);
-
- if(!File.IsOpen())
- ABORT("Bitmap %s not found!", FileName.CStr());
-
- uchar Palette[768];
- File.SeekPosEnd(-768);
- File.Read(reinterpret_cast(Palette), 768);
- File.SeekPosBegin(8);
- Size.X = File.Get();
- Size.X += (File.Get() << 8) + 1;
- Size.Y = File.Get();
- Size.Y += (File.Get() << 8) + 1;
+ rawbitmap Temp(FileName);
+ Size = Temp.Size;
XSizeTimesYSize = Size.X * Size.Y;
- File.SeekPosBegin(128);
Alloc2D(Image, Size.Y, Size.X);
packcol16* Buffer = Image[0];
+ paletteindex* TempBuffer = Temp.PaletteBuffer[0];
for(int y = 0; y < Size.Y; ++y)
for(int x = 0; x < Size.X; ++x)
{
- int Char1 = File.Get();
-
- if(Char1 > 192)
- {
- --x;
- int Char2 = File.Get();
- int Char3 = Char2 + (Char2 << 1);
- int Color = int(Palette[Char3] >> 3) << 11
- | int(Palette[Char3 + 1] >> 2) << 5
- | int(Palette[Char3 + 2] >> 3);
-
- for(; Char1 > 192; --Char1)
- {
- *Buffer++ = Color;
-
- if(++x == Size.X)
- {
- x = 0;
- ++y;
- }
- }
- }
- else
- {
- int Char3 = Char1 + (Char1 << 1);
- *Buffer++ = int(Palette[Char3] >> 3) << 11
- | int(Palette[Char3 + 1] >> 2) << 5
- | int(Palette[Char3 + 2] >> 3);
- }
+ int Char1 = *TempBuffer++;
+ int Char3 = Char1 + (Char1 << 1);
+ *Buffer++ = int(Temp.Palette[Char3] >> 3) << 11
+ | int(Temp.Palette[Char3 + 1] >> 2) << 5
+ | int(Temp.Palette[Char3 + 2] >> 3);
}
}
@@ -331,6 +302,30 @@ void bitmap::ClearToColor(col16 Color)
}
}
+truth bitmap::HasColor(col16 findColor)
+{
+ for(int iY=0;iY=Size.Y)return;
+ memcpy(&Image[iYDest][0], &bmpFrom->Image[iYFrom][0], iSize);
+}
+
void bitmap::NormalBlit(cblitdata& BlitData) const
{
blitdata B = BlitData;
@@ -1192,6 +1187,191 @@ void bitmap::FadeToScreen(bitmapeditor BitmapEditor)
graphics::BlitDBToScreen();
}
+std::vector vSurfaceCache;
+SDL_Surface* SurfaceCache(blitdata B,bool bUseScale){ // good to prevent memory hungryness
+ int iW=B.Border.X;
+ if(bUseScale)iW*=B.Stretch;
+
+ int iH=B.Border.Y;
+ if(bUseScale)iH*=B.Stretch;
+
+ for(int i=0;iw==iW && vSurfaceCache[i]->h==iH){
+ return vSurfaceCache[i];
+ }
+ }
+
+ DBG4("Cache not found for surface w=",iW," h=",iH);
+ SDL_Surface* srf = libxbrzscale::createARGBSurface(iW, iH); //src img for look zoom at least is always 16x16 tho
+
+ vSurfaceCache.push_back(srf);DBG3(srf,DBGI(srf->w),DBGI(srf->h));
+ DBGSI(vSurfaceCache.size());
+
+ return srf;
+}
+
+void bitmap::ResetBlitdataRotation(blitdata& B)
+{
+ B.Flags &= ~MIRROR;
+ B.Flags &= ~FLIP;
+ B.Flags &= ~ROTATE;
+}
+
+void bitmap::ConfigureBlitdataRotation(blitdata& B,int iR){
+ ResetBlitdataRotation(B);
+
+ // set
+ iR %= 4;
+ /****
+ * 1 1
+ * 2 2
+ * 3 3
+ * 4 0->4
+ * 5 1
+ * 6 2
+ * 7 3
+ * 8 0->4
+ */
+ if(iR==0)iR = 4 * (iR>0 ? 1 : -1);
+ /*** the blade side is inverted, so invert the rotation
+ * -1 -> -4
+ * -2 -> -3
+ * -3 -> -2
+ * -4 -> -1
+ */
+ switch(iR){
+ case -1:iR=-4;break;
+ case -2:iR=-3;break;
+ case -3:iR=-2;break;
+ case -4:iR=-1;break;
+ }
+
+ switch(iR){
+ case 1: // 1st step always rotate once
+ B.Flags |= ROTATE; //90 degrees
+ break;
+ case 2:
+ B.Flags |= FLIP|MIRROR; //180 degrees
+ break;
+ case 3:
+ B.Flags |= ROTATE|FLIP|MIRROR; //270 degrees
+ break;
+ case 4:
+ // initial/default rotation
+ break;
+ case -1: // 1st step always rotate once
+ B.Flags |= MIRROR; //-90 degrees
+ break;
+ case -2:
+ B.Flags |= FLIP|ROTATE; //-180 degrees
+ break;
+ case -3:
+ B.Flags |= FLIP; //-270 degrees
+ break;
+ case -4:
+ B.Flags |= MIRROR|ROTATE; //-0 degrees (like a mirrored image :))
+ break;
+ }
+}
+
+SDL_PixelFormat* fmt = SDL_AllocFormat(SDL_PIXELFORMAT_RGBA8888); //format based on xbrzscale code
+
+SDL_Surface* bitmap::CopyToSurface(v2 v2TopLeft, v2 v2Size, col16 MaskColor, SDL_Surface* srf) const
+{
+ if(srf==NULL) srf = libxbrzscale::createARGBSurface(this->Size.X,this->Size.Y);
+
+ // copy pixels to surface
+ Uint32 color32bit;
+ packcol16 PixelFrom;
+ unsigned char ca=0xff;
+ for(int x1 = 0; x1 < v2Size.X; x1++)
+ {
+ for(int y1 = 0; y1 < v2Size.Y; y1++)
+ {
+ PixelFrom = Image[v2TopLeft.Y + y1][v2TopLeft.X + x1];
+
+ if(PixelFrom == MaskColor){ //0 invisible, 0xff opaque
+ ca = 0;
+// static packcol16 DarkestNotBlack = MakeRGB16(1,1,1);
+// PixelFrom = DarkestNotBlack; //didnt work :(
+ PixelFrom = WHITE; //xBRZ blends countours perfectly this way
+ }else{
+ ca = 0xff;
+ }
+
+ color32bit = SDL_MapRGBA(
+ fmt,
+ (unsigned char)GetRed16(PixelFrom),
+ (unsigned char)GetGreen16(PixelFrom),
+ (unsigned char)GetBlue16(PixelFrom),
+ ca
+ );
+ libxbrzscale::SDL_PutPixel(srf, x1, y1, color32bit);
+ }
+ }
+
+ return srf;
+}
+
+/**
+ * stretch from 2 to 6 only!
+ */
+void bitmap::StretchBlitXbrz(cblitdata& BlitDataTo, bool bAllowTransparency) const
+{
+ if(
+ (BlitDataTo.Src.X+BlitDataTo.Border.X) > Size.X
+ ||
+ (BlitDataTo.Src.Y+BlitDataTo.Border.Y) > Size.Y
+ ){
+ ABORT("requested copy from rectangle pos=%d,%d size=%d,%d outside of limits=%d,%d",BlitDataTo.Src.X,BlitDataTo.Src.Y,BlitDataTo.Border.X,BlitDataTo.Border.Y,Size.X,Size.Y);
+ }
+
+ blitdata Bto = BlitDataTo;DBGLN; //to easy coding
+ if(Bto.Dest.X>=Bto.Bitmap->GetSize().X || Bto.Dest.Y>=Bto.Bitmap->GetSize().Y){
+ ABORT("invalid stretch destination %d,%d on target bitmap size %d,%d",Bto.Dest.X,Bto.Dest.Y,Bto.Bitmap->GetSize().X,Bto.Bitmap->GetSize().Y);
+ }
+
+ static bool bXbrzLibCfgInitialized=false;
+ if(!bXbrzLibCfgInitialized){ //TODO this config should be placed more globally?
+ libxbrzscale::setUseCache(true);DBGLN;
+#ifdef DBGMSG
+ libxbrzscale::setDebugMsg(true);DBGLN;
+#endif
+ libxbrzscale::setFreeSurfaceAfterScale(false,false);DBGLN;
+ bXbrzLibCfgInitialized=true;DBGLN;
+ }
+
+ bool bFreeImg=false;DBGLN;
+
+ DBG2(Bto.Bitmap,DBGAV2(Bto.Bitmap->GetSize()));
+ SDL_Surface* imgCopy = CopyToSurface(Bto.Src, Bto.Border, Bto.MaskColor, SurfaceCache(Bto,false));DBGLN;
+
+ Uint32 color32bit;DBGLN;
+ unsigned char cr,cg,cb,ca;DBGLN;
+ SDL_Surface* imgStretchedCopy=NULL;DBGLN;
+ imgStretchedCopy=libxbrzscale::scale(SurfaceCache(Bto,true), imgCopy, Bto.Stretch);DBG3(imgStretchedCopy,DBGI(imgStretchedCopy->w),DBGI(imgStretchedCopy->h));
+// if( ((Bto.Dest.X+imgStretchedCopy->w) >= Bto.Bitmap->GetSize().X) ||
+// ((Bto.Dest.Y+imgStretchedCopy->h) >= Bto.Bitmap->GetSize().Y) )ABORT("blit %d,%d + %d,%d outside dest bitmap %d,%d",Bto.Dest.X,Bto.Dest.Y,imgStretchedCopy->w,imgStretchedCopy->h,Bto.Bitmap->GetSize().X,Bto.Bitmap->GetSize().Y);
+ // copy from surface the scaled image back to where it is expected TODO comment a more precise info...
+ for(int x1 = 0; x1 < imgStretchedCopy->w; ++x1)
+ {
+ for(int y1 = 0; y1 < imgStretchedCopy->h; ++y1)
+ {
+ color32bit = libxbrzscale::SDL_GetPixel(imgStretchedCopy,x1,y1);//DBGLN;
+ SDL_GetRGBA(color32bit,fmt,&cr,&cg,&cb,&ca);//DBGLN;
+ if(!bAllowTransparency || ca==0xff){ //TODO ca==0xff may work better than ca!=0 the day xBRZScale blends from opaque to transparent with a half-transparent alpha value as result!?
+ if((Bto.Dest.X+x1)GetSize().X && (Bto.Dest.Y+y1)GetSize().Y){
+ Bto.Bitmap->Image[Bto.Dest.Y+y1][Bto.Dest.X+x1] = MakeRGB16(cr,cg,cb);//DBGLN; //TODO does alpha make any sense here anyway?
+ }
+ }
+ }
+ }
+ DBGLN;
+
+// SDL_FreeSurface(imgCopy);
+// SDL_FreeSurface(imgStretchedCopy);
+}
+
void bitmap::StretchBlit(cblitdata& BlitData) const
{
blitdata B = BlitData;
diff --git a/FeLib/Source/config.cpp b/FeLib/Source/config.cpp
index 81f936f95..e2e99d8e2 100644
--- a/FeLib/Source/config.cpp
+++ b/FeLib/Source/config.cpp
@@ -19,7 +19,12 @@ configoption* configsystem::Option[MAX_CONFIG_OPTIONS];
festring configsystem::ConfigFileName;
int configsystem::Options;
-void configsystem::AddOption(configoption* O) { Option[Options++] = O; }
+void configsystem::AddOption(festring fsCategory, configoption* O) {
+ for(int i=0;iName, O->Description); //help developers to prevent duplicated entries
+
+ O->fsCategory=fsCategory;
+ Option[Options++] = O;
+}
void configsystem::NormalStringChanger(stringoption* O, cfestring& What)
{ O->Value = What; }
void configsystem::NormalNumberChanger(numberoption* O, long What)
@@ -134,7 +139,7 @@ void configsystem::Show(void (*BackGroundDrawer)(),
int Chosen;
truth TruthChange = false;
- felist List(CONST_S("Which setting do you wish to configure?"));
+ felist List(CONST_S("Which setting do you wish to configure? (* - req. restart)"));
List.AddDescription(CONST_S(""));
List.AddDescription(CONST_S("Setting Value"));
@@ -145,12 +150,19 @@ void configsystem::Show(void (*BackGroundDrawer)(),
List.Empty();
+ festring fsLastCategory;
for(int c = 0; c < Options; ++c)
{
festring Entry = Option[c]->Description;
Entry.Capitalize();
Entry.Resize(60);
- Option[c]->DisplayeValue(Entry);
+ Option[c]->DisplayValue(Entry);
+
+ if(fsLastCategory!=Option[c]->fsCategory){
+ List.AddEntry(Option[c]->fsCategory, WHITE, 0, NO_IMAGE, false);
+ fsLastCategory=Option[c]->fsCategory;
+ }
+
List.AddEntry(Entry, LIGHT_GRAY);
}
diff --git a/FeLib/Source/error.cpp b/FeLib/Source/error.cpp
index af78c334f..b5c9d4894 100644
--- a/FeLib/Source/error.cpp
+++ b/FeLib/Source/error.cpp
@@ -26,6 +26,11 @@
#include
#else
#include
+#include
+#include
+#include
+#include
+#include
#endif
#ifdef VC
@@ -36,6 +41,8 @@
#define set_new_handler std::set_new_handler
#endif
+#include "dbgmsgproj.h"
+
#include "error.h"
/* Shouldn't be initialized here! */
@@ -58,6 +65,16 @@ int globalerrorhandler::Signal[SIGNALS]
= { SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGINT, SIGKILL, SIGQUIT };
#endif
+#ifndef WIN32
+void globalerrorhandler::DumpStackTraceToStdErr(int Signal){
+ // Prints stack trace to stderr.
+ void* CallStack[128];
+ size_t Frames = backtrace(CallStack, 128);
+ if(Signal>-1)std::cerr << strsignal(Signal) << std::endl;
+ backtrace_symbols_fd(CallStack, Frames, STDERR_FILENO);
+}
+#endif
+
void globalerrorhandler::Install()
{
static truth AlreadyInstalled = false;
@@ -88,6 +105,10 @@ void globalerrorhandler::DeInstall()
void globalerrorhandler::Abort(cchar* Format, ...)
{
+#ifndef WIN32
+ DumpStackTraceToStdErr();
+#endif
+
char Buffer[512];
va_list AP;
@@ -110,6 +131,7 @@ void globalerrorhandler::Abort(cchar* Format, ...)
std::cout << Buffer << std::endl;
#endif
+ DBGSTK;DBG2("ABORT:",Buffer);
exit(4);
}
diff --git a/FeLib/Source/feio.cpp b/FeLib/Source/feio.cpp
index 1500025ac..f5f1adec0 100644
--- a/FeLib/Source/feio.cpp
+++ b/FeLib/Source/feio.cpp
@@ -13,7 +13,16 @@
#include
#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
#ifdef WIN32
+#define stat _stat
#include
#endif
@@ -21,21 +30,27 @@
#include
#include
#include
-#include
-#include
+#include
+#include
+#include
+#include
#endif
#ifdef __DJGPP__
#include
#endif
-#include "graphics.h"
+#include "bitmap.h"
+#include "error.h"
#include "feio.h"
-#include "whandler.h"
#include "felist.h"
-#include "rawbit.h"
#include "festring.h"
-#include "bitmap.h"
+#include "graphics.h"
+#include "rawbit.h"
+#include "save.h"
+#include "whandler.h"
+
+#include "dbgmsgproj.h"
#define PENT_WIDTH 70
@@ -110,6 +125,12 @@ int CountChars(char cSF, cfestring& sSH)
return iReturnCounter;
}
+truth bMenuIsActive=false;
+
+truth iosystem::IsOnMenu(){
+ return bMenuIsActive;
+}
+
/* Draws a menu on bitmap BackGround to position Pos. festring Topic
is the text that is shown before the choices '\r' is a line-ending
character. Topic must end with a '\r'. sMS is a list of choices
@@ -132,6 +153,7 @@ int iosystem::Menu(cbitmap* BackGround, v2 Pos,
if(CountChars('\r', sMS) < 1)
return (-1);
+ bMenuIsActive=true;
truth bReady = false;
int iSelected = 0;
bitmap Backup(DOUBLE_BUFFER);
@@ -140,9 +162,18 @@ int iosystem::Menu(cbitmap* BackGround, v2 Pos,
Buffer.ActivateFastFlag();
int c = 0;
- if(BackGround)
- BackGround->FastBlit(&Buffer);
- else
+ if(BackGround){
+ //vanilla was 800x600 as the background menu image. TODO provide calculations for lower than 800x600 one day?
+ if(RES.X < BackGround->GetSize().X)ABORT("invalid window width %d",RES.X);
+ if(RES.Y < BackGround->GetSize().Y)ABORT("invalid window height %d",RES.Y);
+
+ if( (RES.X!=BackGround->GetSize().X) || (RES.Y!=BackGround->GetSize().Y) ){
+ Buffer.ClearToColor(0);
+ BackGround->FastBlit(&Buffer,{(RES.X-BackGround->GetSize().X)/2, (RES.Y-BackGround->GetSize().Y)/2});
+ }else{
+ BackGround->FastBlit(&Buffer);
+ }
+ }else
Buffer.ClearToColor(0);
festring sCopyOfMS;
@@ -185,7 +216,7 @@ int iosystem::Menu(cbitmap* BackGround, v2 Pos,
FONT->Printf(&Buffer, v2(XPos, YPos), Color, "%d. %s",
i + 1, VeryUnGuruPrintf.CStr());
- }
+ }
sCopyOfMS = SmallText1;
@@ -260,11 +291,14 @@ int iosystem::Menu(cbitmap* BackGround, v2 Pos,
break;
default:
- if(k > 0x30 && k < 0x31 + CountChars('\r', sMS))
+ if(k > 0x30 && k < 0x31 + CountChars('\r', sMS)){
+ bMenuIsActive=false;
return k - 0x31;
+ }
}
}
+ bMenuIsActive=false;
return iSelected;
}
@@ -356,7 +390,7 @@ int iosystem::StringQuestion(festring& Input,
if(LastKey == KEY_BACK_SPACE)
{
- if(CursorPos)
+ if(CursorPos > 0)
Input.Erase(static_cast(--CursorPos), 1);
continue;
@@ -373,25 +407,23 @@ int iosystem::StringQuestion(festring& Input,
}
}
- if(LastKey == KEY_LEFT)
+ if(LastKey == KEY_HOME)
{
- if(CursorPos)
- --CursorPos;
+ CursorPos = 0;
continue;
}
- if(LastKey == KEY_RIGHT)
+ if(LastKey == KEY_END)
{
- if(CursorPos < static_cast(Input.GetSize()))
- ++CursorPos;
+ CursorPos = static_cast(Input.GetSize());
continue;
}
if(LastKey == KEY_LEFT)
{
- if(CursorPos)
+ if(CursorPos > 0)
--CursorPos;
continue;
@@ -405,9 +437,9 @@ int iosystem::StringQuestion(festring& Input,
continue;
}
- if(LastKey >= 0x20 && Input.GetSize() < MaxLetters
+ if(LastKey >= 0x20 && LastKey < 0x7F
&& (LastKey != ' ' || !Input.IsEmpty())
- && LastKey != KEY_UP && LastKey != KEY_DOWN)
+ && Input.GetSize() < MaxLetters)
Input.Insert(static_cast(CursorPos++),
static_cast(LastKey));
}
@@ -472,13 +504,14 @@ long iosystem::NumberQuestion(cfestring& Topic, v2 Pos, col16 Color,
while(!isdigit(LastKey) && LastKey != KEY_BACK_SPACE
&& LastKey != KEY_ENTER && LastKey != KEY_ESC
+ && LastKey != KEY_HOME && LastKey != KEY_END
&& LastKey != KEY_LEFT && LastKey != KEY_RIGHT
&& (LastKey != '-' || !Input.IsEmpty()))
LastKey = GET_KEY(false);
if(LastKey == KEY_BACK_SPACE)
{
- if(CursorPos)
+ if(CursorPos > 0)
Input.Erase(static_cast(--CursorPos), 1);
continue;
@@ -495,9 +528,23 @@ long iosystem::NumberQuestion(cfestring& Topic, v2 Pos, col16 Color,
break;
}
+ if(LastKey == KEY_HOME)
+ {
+ CursorPos = 0;
+
+ continue;
+ }
+
+ if(LastKey == KEY_END)
+ {
+ CursorPos = static_cast(Input.GetSize());
+
+ continue;
+ }
+
if(LastKey == KEY_LEFT)
{
- if(CursorPos)
+ if(CursorPos > 0)
--CursorPos;
continue;
@@ -644,6 +691,7 @@ long iosystem::ScrollBarQuestion(cfestring& Topic, v2 Pos,
while(!isdigit(LastKey) && LastKey != KEY_ESC
&& LastKey != KEY_BACK_SPACE && LastKey != KEY_ENTER
&& LastKey != KEY_SPACE && LastKey != '<' && LastKey != '>'
+ && LastKey != KEY_HOME && LastKey != KEY_END
&& LastKey != RightKey && LastKey != LeftKey
&& LastKey != KEY_RIGHT && LastKey != KEY_LEFT)
LastKey = GET_KEY(false);
@@ -665,6 +713,24 @@ long iosystem::ScrollBarQuestion(cfestring& Topic, v2 Pos,
if(LastKey == KEY_ENTER || LastKey == KEY_SPACE)
break;
+ if(LastKey == KEY_HOME)
+ {
+ BarValue = Min;
+
+ Input.Empty();
+ Input << BarValue;
+ continue;
+ }
+
+ if(LastKey == KEY_END)
+ {
+ BarValue = Max;
+
+ Input.Empty();
+ Input << BarValue;
+ continue;
+ }
+
if(LastKey == '<' || LastKey == LeftKey || LastKey == KEY_LEFT)
{
BarValue -= Step;
@@ -696,133 +762,538 @@ long iosystem::ScrollBarQuestion(cfestring& Topic, v2 Pos,
return BarValue;
}
-/* DirectoryName is the directory where the savefiles are located. Returns
- the selected file or "" if an error occures or if no files are found. */
+//TODO dropped in favor of non crashing (for old saves) new code protection, clean this commented code later
+///**
+// * this will surely work if savegame sorting is disabled
+// */
+//festring ContinueMenuOldAndSafe(col16 TopicColor, col16 ListColor,
+// cfestring& DirectoryName)
+//{
+//#ifdef WIN32
+// struct _finddata_t Found;
+// long hFile;
+// int Check = 0;
+// festring Buffer;
+// felist List(CONST_S("Choose a file and be sorry:"), TopicColor);
+// hFile = _findfirst(festring(DirectoryName + "*.sav").CStr(), &Found);
+//
+// /* No file found */
+// if(hFile == -1L)
+// {
+// iosystem::TextScreen(CONST_S("You don't have any previous saves."), ZERO_V2, TopicColor);
+// return "";
+// }
+//
+// while(!Check)
+// {
+// /* Copy all the filenames to Buffer */
+// /* Buffer = Found.name; Doesn't work because of a festring bug */
+//
+// Buffer.Empty();
+// Buffer << Found.name;
+// List.AddEntry(Buffer, ListColor);
+// Check = _findnext(hFile, &Found);
+// }
+//
+// Check = List.Draw();
+//
+// /* an error has occured in felist */
+//
+// if(Check & FELIST_ERROR_BIT)
+// return "";
+//
+// return List.GetEntry(Check);
+//#endif
+//
+//#ifdef UNIX
+// DIR* dp;
+// struct dirent* ep;
+// festring Buffer;
+// felist List(CONST_S("Choose a file and be sorry:"), TopicColor);
+// dp = opendir(DirectoryName.CStr());
+//
+// if(dp)
+// {
+// while((ep = readdir(dp)))
+// {
+// /* Buffer = ep->d_name; Doesn't work because of a festring bug */
+// Buffer.Empty();
+// Buffer << ep->d_name;
+// /* Add to List all save files */
+// if(Buffer.Find(".sav") != Buffer.NPos)
+// List.AddEntry(Buffer, ListColor);
+// }
+//
+// closedir(dp);
+//
+// if(List.IsEmpty())
+// {
+// iosystem::TextScreen(CONST_S("You don't have any previous saves."), ZERO_V2, TopicColor);
+// return "";
+// }
+// else
+// {
+// int Check = List.Draw();
+//
+// if(Check & FELIST_ERROR_BIT)
+// return "";
+//
+// return List.GetEntry(Check);
+// }
+//
+// }
+//
+// return "";
+//#endif
+//
+//#ifdef __DJGPP__
+// struct ffblk Found;
+// int Check = 0;
+// festring Buffer;
+// felist List(CONST_S("Choose a file and be sorry:"), TopicColor);
+//
+// /* get all filenames ending with .sav. Accepts all files even if they
+// FA_HIDDEN or FA_ARCH flags are set (ie. they are hidden or archives */
+//
+// Check = findfirst(festring(DirectoryName + "*.sav").CStr(),
+// &Found, FA_HIDDEN | FA_ARCH);
+//
+// if(Check)
+// {
+// iosystem::TextScreen(CONST_S("You don't have any previous saves."), ZERO_V2, TopicColor);
+// return "";
+// }
+//
+// while(!Check)
+// {
+// /* Buffer = Found.ff_name; Doesn't work because of a festring bug */
+// Buffer.Empty();
+// Buffer << Found.ff_name;
+// List.AddEntry(Buffer, ListColor);
+// Check = findnext(&Found);
+// }
+//
+// Check = List.Draw();
+//
+// if(Check & FELIST_ERROR_BIT)
+// return "";
+//
+// return List.GetEntry(Check);
+//#endif
+//}
+
+bool AlertConfirmMsg(const char* cMsg, bool bAbortIfNot=true) //TODO this method could be more global
+{
+ v2 v2Border(700,100);
+ v2 v2TL(RES.X/2-v2Border.X/2,RES.Y/2-v2Border.Y/2);
+
+ DOUBLE_BUFFER->Fill(v2TL,v2Border,RED);
+ graphics::DrawRectangleOutlineAround(DOUBLE_BUFFER, v2TL, v2Border, YELLOW, true);
+
+ v2TL+=v2(16,16);
+ FONT->Printf(DOUBLE_BUFFER, v2(v2TL.X,v2TL.Y ), WHITE, "%s", cMsg);
+ FONT->Printf(DOUBLE_BUFFER, v2(v2TL.X,v2TL.Y+32), WHITE, "%s", "(y)es, any other key to ignore this message.");
+
+ graphics::BlitDBToScreen(); //as the final blit may be from StretchedBuffer
+ if(GET_KEY() == 'y')return true;
+
+ return false;
+}
+
+static bool bSaveGameSortModeByDtTm;
+static bool bSaveGameSortModeProgress;
+static bool bSaveGameSortModeReversed;
+void iosystem::SetSaveGameSortMode(int i){
+ bSaveGameSortModeByDtTm=false;
+ bSaveGameSortModeProgress=false;
+ bSaveGameSortModeReversed=false;
+
+ switch(i){
+ case 0:
+ bSaveGameSortModeReversed=true;
+ bSaveGameSortModeByDtTm=true;
+ break;
+ case 1:
+ bSaveGameSortModeReversed=true;
+ bSaveGameSortModeByDtTm=true;
+ bSaveGameSortModeProgress=true;
+ break;
+ case 2: //alphanum is essential
+ break;
+ case 3:
+ bSaveGameSortModeProgress=true;
+ break;
+ default:
+ ABORT("unsupported savegame sort option %d",i);
+ }
+}
+struct fileInfo{
+ int Version = -1;
+ char* GameScript = 0; //dummy
+ int CurrentDungeonIndex = -1;
+ int CurrentLevelIndex = -1;
+ v2 Camera; //dummy
+ truth WizardMode;
+ festring fileName=festring(); //TODO this init helps with festring? is it buggy?
+ festring absFileName=festring(); //contains the full path
+ festring time=festring();
+ festring idOnList=festring();
+ festring dungeonID=festring();
+ festring fileNameAutoSave=festring();
+ std::vector vBackups;
+ bool bIsBkp = false;
+};
+std::vector vFiles;
+bool addFileInfo(const char* c){
+ // skippers
+ if(strcmp(c,".")==0)return false;
+ if(strcmp(c,"..")==0)return false;
+
+ // do add
+ fileInfo fi;
+ fi.fileName<d_name);
+ closedir(dp);
+ }
+ }
+#endif
+
#ifdef WIN32
struct _finddata_t Found;
long hFile;
int Check = 0;
- festring Buffer;
- felist List(CONST_S("Choose a file and be sorry:"), TopicColor);
- hFile = _findfirst(festring(DirectoryName + "*.sav").CStr(), &Found);
+ hFile = _findfirst(festring(DirectoryName + "*").CStr(), &Found);
/* No file found */
- if(hFile == -1L)
+ if(hFile != -1L)
{
- TextScreen(CONST_S("You don't have any previous saves."), ZERO_V2, TopicColor);
- return "";
+ while(!Check)
+ {
+ addFileInfo(Found.name);
+ Check = _findnext(hFile, &Found);
+ }
}
+#endif
- while(!Check)
- {
- /* Copy all the filenames to Buffer */
- /* Buffer = Found.name; Doesn't work because of a festring bug */
+#ifdef __DJGPP__
+ struct ffblk Found;
+ int Check = 0;
- Buffer.Empty();
- Buffer << Found.name;
- List.AddEntry(Buffer, ListColor);
- Check = _findnext(hFile, &Found);
- }
+ /* get all filenames. Accepts all files even if they
+ FA_HIDDEN or FA_ARCH flags are set (ie. they are hidden or archives */
- Check = List.Draw();
+ Check = findfirst(festring(DirectoryName + "*").CStr(),
+ &Found, FA_HIDDEN | FA_ARCH);
- /* an error has occured in felist */
+ if(!Check)
+ {
+ while(!Check){
+ addFileInfo(Found.ff_name);
+ Check = findnext(&Found);
+ }
+ }
+#endif
- if(Check & FELIST_ERROR_BIT)
+ if(vFiles.size()==0){
+ iosystem::TextScreen(CONST_S("You don't have any previous saves."), ZERO_V2, TopicColor);
return "";
+ }
- return List.GetEntry(Check);
-#endif
+ /////////////////////////////// sort work //////////////////////////////////////
-#ifdef UNIX
- DIR* dp;
- struct dirent* ep;
- festring Buffer;
- felist List(CONST_S("Choose a file and be sorry:"), TopicColor);
- dp = opendir(DirectoryName.CStr());
+// /**
+// * this is rerquired when there is only one savegame and it is just an ...AutoSave.sav
+// */
+// static festring fsLastChangeDetector="_Last_Change_Detector_.sav";
+// addFileInfo(fsLastChangeDetector.CStr());
- if(dp)
+ int iTmSz=100;
+ struct stat attr;
+ for(int i=0;id_name; Doesn't work because of a festring bug */
- Buffer.Empty();
- Buffer << ep->d_name;
- /* Add to List all save files */
- if(Buffer.Find(".sav") != Buffer.NPos)
- List.AddEntry(Buffer, ListColor);
- }
+ vFiles[i].absFileName< vIds,vInvIds,vBackups;
+ std::vector vComponents;
+ festring autoSaveFound("");
+ int iPrepareSavFileIndex=-1;
+ int iAutoSaveSavFileIndex=-1;
+ std::string sPrettyNamePrevious="";
+ for(int i=0;i-1){
+ // but has .AutoSave.sav and will use it
+ iPrepareSavFileIndex=iAutoSaveSavFileIndex;
+ sPrettyNameWork=sPrettyNamePrevious;
+ // bNextFile will remain false, so at next loop step it will use the current one again.
+ }
}
- else
- {
- int Check = List.Draw();
- if(Check & FELIST_ERROR_BIT)
- return "";
+ if(iPrepareSavFileIndex==-1){
+// if(vFiles[i].fileName == fsLastChangeDetector){
+// break;
+// }else
+ if(vFiles[i].fileName.Find(".wm" ) != vFiles[i].fileName.NPos){
+ //skipped from the list
+ }else
+ if(vFiles[i].fileName.Find(".bkp") != vFiles[i].fileName.NPos){ //skipped from the list
+ vBackups.push_back(vFiles[i].absFileName);
+ vFiles[i].bIsBkp=true;
+ }else
+ if(vFiles[i].fileName.Find(".AutoSave.") != vFiles[i].fileName.NPos){ //skipped from the list
+ if(vFiles[i].fileName.Find(".AutoSave.sav") != vFiles[i].fileName.NPos){ // the correct autosave to be returned
+ autoSaveFound=vFiles[i].fileName;
+ iAutoSaveSavFileIndex=i;
+ }
+ }else
+ if(vFiles[i].fileName.Find(".sav") != vFiles[i].fileName.NPos){
+ iPrepareSavFileIndex=i;
+ }else{ //dungeon IDs TODO this will mess if player's name has dots '.', prevent it during filename creation as spaces are
+ std::string s=vFiles[i].fileName.CStr();
+ s=s.substr(s.find(".")+1);
+ vFiles[i].dungeonID<-1){
+ fileInfo& rfi = vFiles[iPrepareSavFileIndex];
+
+ festring id("");
+
+ // savegame version (save structure taken from game::Load())
+ inputfile SaveFile(rfi.absFileName, 0, false);
+ SaveFile >> rfi.Version; DBGSI(rfi.Version);
+ if(skipSeek==NULL)ABORT("SkipSeek function not set");
+ skipSeek(&SaveFile); //DUMMY (for here) binary data skipper
+ //TODO the current dungeon and many other useful info could be stored in a simple text file just to be used during this game loading list!
+ SaveFile >> rfi.CurrentDungeonIndex >> rfi.CurrentLevelIndex; DBG2(rfi.CurrentDungeonIndex,rfi.CurrentLevelIndex);
+ SaveFile >> rfi.Camera; //skipper
+ SaveFile >> rfi.WizardMode;
+ SaveFile.Close();
+
+ festring fsVer("");
+ if(rfi.Version != iSaveFileVersion)
+ fsVer<<"(v"<0)id<<" ";
+ if(vComponents[k].dungeonID == currentDungeonLevel){
+ id<<"@"<0){
+ id<<" has backup(s)!";
+ rfi.vBackups=vBackups; //makes a copy
+ }
- /* get all filenames ending with .sav. Accepts all files even if they
- FA_HIDDEN or FA_ARCH flags are set (ie. they are hidden or archives */
+ rfi.idOnList<= iOldSavegameVersionImportSince)
+ bValid=true;
+
+ if(bValid){
+ vIds.push_back(id);DBG2("ok",DBGC(id.CStr()));
+ }else{
+ vInvIds.push_back(id);DBG2("invalid",DBGC(id.CStr()));
+ }
- Check = findfirst(festring(DirectoryName + "*.sav").CStr(),
- &Found, FA_HIDDEN | FA_ARCH);
+ //reset to for next .sav fillup
+ vComponents.clear();
+ vBackups.clear();
+ autoSaveFound.Empty();
+ iPrepareSavFileIndex=-1;
+ iAutoSaveSavFileIndex=-1;
+ }
- if(Check)
- {
- TextScreen(CONST_S("You don't have any previous saves."), ZERO_V2, TopicColor);
- return "";
+ sPrettyNamePrevious=sPrettyName;
+
+ if(bNextFile)i++;
}
- while(!Check)
+ // this will sort the ids alphabetically even if by time (so will sort the time as a string)
+ std::sort( vIds .begin(), vIds .end(), [ ]( const festring& l, const festring& r ){return l < r;} );
+ std::sort( vInvIds.begin(), vInvIds.end(), [ ]( const festring& l, const festring& r ){return l < r;} );
+
+ // reversed or normal
+ int iFirst,iFirstI,iStopAt,iStopAtI,iDir; //TODO implement something more readable...
+ if(bSaveGameSortModeReversed){
+ iDir=-1; iFirst=vIds.size()-1; iStopAt=-1 ; iFirstI=vInvIds.size()-1; iStopAtI=-1 ; }else{
+ iDir= 1; iFirst=0 ; iStopAt=vIds.size(); iFirstI=0 ; iStopAtI=vInvIds.size();
+ }
+ for(int i=iFirst ;i!=iStopAt ;i+=iDir){List.AddEntry(vIds [i],ListColor,0,NO_IMAGE,true ); DBG2(DBGC(vIds[i].CStr()) ,"ok" );}
+ for(int i=iFirstI;i!=iStopAtI;i+=iDir){List.AddEntry(vInvIds[i],DARK_GRAY,0,NO_IMAGE,false); DBG2(DBGC(vInvIds[i].CStr()),"invalid");}
+
+ if(List.IsEmpty() || vIds.empty())
{
- /* Buffer = Found.ff_name; Doesn't work because of a festring bug */
- Buffer.Empty();
- Buffer << Found.ff_name;
- List.AddEntry(Buffer, ListColor);
- Check = findnext(&Found);
+ iosystem::TextScreen(CONST_S("You don't have any valid previous saves."), ZERO_V2, TopicColor);
+ return "";
}
+ else
+ {
+ int Check = List.Draw();
- Check = List.Draw();
+ /* an error has occured in felist */
+ if(Check & FELIST_ERROR_BIT)
+ return "";
- if(Check & FELIST_ERROR_BIT)
- return "";
+ festring chosen;chosen<& rvBackups = vFiles[i].vBackups;
+ if(rvBackups.size()>0){
+ if(AlertConfirmMsg("Try to restore the backup?")){
+ for(int b=0;b' || Key == '?' || Key == '*'
|| Key == '/' || Key == '\\' || Key == ':')
return false;
- if(Key < 0x20
- && !(Key == KEY_BACK_SPACE || Key == KEY_ENTER || Key == KEY_ESC))
+ if(Key == KEY_BACK_SPACE || Key == KEY_ENTER || Key == KEY_ESC
+ || Key == KEY_HOME || Key == KEY_END || Key == KEY_LEFT || Key == KEY_RIGHT)
+ return true;
+
+ if(Key < 0x20 || Key >= 0x7F)
return false;
return true;
diff --git a/FeLib/Source/felist.cpp b/FeLib/Source/felist.cpp
index 4a60b9567..7258d8b6a 100644
--- a/FeLib/Source/felist.cpp
+++ b/FeLib/Source/felist.cpp
@@ -19,12 +19,55 @@
#include "rawbit.h"
#include "save.h"
#include "festring.h"
+#include "dbgmsgproj.h"
const felist* FelistCurrentlyDrawn = 0;
+col16 felist::colSelectedBkg = MakeRGB16(8,8,8);//TRANSPARENT_COLOR;
+v2 felist::v2SelectedPos = v2(0,0);
+v2 felist::v2DefaultEntryImageSize=v2(0,0);
+
+truth felist::isAnyFelistCurrentlyDrawn(){
+ return FelistCurrentlyDrawn!=NULL;
+}
+
+bool felist::PrepareListItemAltPosBackground(blitdata& rB,bool bAltPosFullBkg){
+ if(FelistCurrentlyDrawn==NULL)return false;
+
+ rB.Src = felist::GetCurrentListSelectedItemPos();
+
+// v2 v2ItemFinalSize(rB.Border.X*rB.Stretch, rB.Border.Y*rB.Stretch);
+ v2 v2ItemFinalSize(rB.Border*rB.Stretch);
+
+ int iExtraH = v2ItemFinalSize.Y/4;
+
+ // scaled up item pos
+ rB.Dest.X=FelistCurrentlyDrawn->v2OriginalPos.X;//B.Dest.X=5;
+ rB.Dest.Y=rB.Src.Y - v2ItemFinalSize.Y/2;
+ if(rB.Dest.Y<0)rB.Dest.Y=0;
+
+ // full background where all items will be drawn above it
+ if(bAltPosFullBkg){
+ v2 v2TopLeft;
+ v2TopLeft.X = FelistCurrentlyDrawn->v2OriginalPos.X;
+ v2TopLeft.Y = FelistCurrentlyDrawn->Pos.Y - iExtraH;
+
+ v2 v2Border;
+ v2Border.X = v2ItemFinalSize.X;
+ v2Border.Y = FelistCurrentlyDrawn->v2FinalPageSize.Y + iExtraH*2;
+
+ rB.Bitmap->Fill(v2TopLeft, v2Border, BLACK);
+
+ // full background outline
+ graphics::DrawRectangleOutlineAround(rB.Bitmap, v2TopLeft, v2Border, DARK_GRAY, true);
+ }
+
+ return true;
+}
+
truth FelistDrawController()
{
- FelistCurrentlyDrawn->DrawPage(DOUBLE_BUFFER);
+ FelistCurrentlyDrawn->DrawPage(DOUBLE_BUFFER,NULL);
return true;
}
@@ -73,7 +116,7 @@ struct felistdescription
felist::felist(cfestring& Topic, col16 TopicColor, uint Maximum)
: Maximum(Maximum), Selected(0), Pos(10, 10), Width(780),
PageLength(30), BackColor(0), Flags(SELECTABLE|FADE),
- UpKey(KEY_UP), DownKey(KEY_DOWN), EntryDrawer(0)
+ UpKey(KEY_UP), DownKey(KEY_DOWN), EntryDrawer(0), v2FinalPageSize(0,0)
{
AddDescription(Topic, TopicColor);
}
@@ -109,13 +152,33 @@ void felist::Pop()
uint felist::Draw()
{
+ if(Flags & SELECTABLE){
+ if(PageLength > 26)PageLength=26; //constraint limit from aA to zZ as there is no coded support beyond these keys anyways...
+ }else{
+ for(int i=0;iImageKey != NO_IMAGE){
+ /**
+ * This allows much more visible entries when the list have no images.
+ *
+ * But this is still a dumb guesser, because it considers all entries will have images.
+ *
+ * The difficulty is because having a fixed page length, even if the contents of each page may differ,
+ * we are unable to precisely calculate how many entries will fit on each page.
+ *
+ * So, opting for the worst case (all are images) is the safest option.
+ */
+ PageLength/=2;
+ break;
+ }
+ }
+
while(Entry.size() && Entry[GetLastEntryIndex()]->String.IsEmpty())
Pop();
if(Entry.empty())
return LIST_WAS_EMPTY;
- FelistCurrentlyDrawn = this;
+ FelistCurrentlyDrawn = this;DBGLN;
if(globalwindowhandler::ControlLoopsInstalled())
globalwindowhandler::InstallControlLoop(FelistDrawController);
@@ -154,9 +217,13 @@ uint felist::Draw()
else
PageBegin = 0;
+ bool bWaitKeyUp=false;
+ bool bClearKeyBufferOnce=false;
+ graphics::PrepareBeforeDrawingFelist();
for(;;)
{
- truth AtTheEnd = DrawPage(Buffer);
+ graphics::DrawAtDoubleBufferBeforeFelistPage(); // here prevents full dungeon blink
+ truth AtTheEnd = DrawPage(Buffer,&v2FinalPageSize);
if(Flags & FADE)
{
@@ -170,24 +237,33 @@ uint felist::Draw()
JustSelectMove = false;
}
- else
+ else{
graphics::BlitDBToScreen();
+ graphics::DrawAtDoubleBufferBeforeFelistPage(); // here helps on hiding unstretched static squares
+ }
- uint Pressed = GET_KEY(false);
+ bool bClearKeyBuffer=false;
+ if(bClearKeyBufferOnce){
+ bClearKeyBuffer=true;
+ bClearKeyBufferOnce=false;
+ }
+ uint Pressed = GET_KEY(bClearKeyBuffer);DBGLN;
- if(Flags & SELECTABLE && Pressed > 64
+ if(Flags & SELECTABLE && Pressed > 64 // 65='A' 90='Z'
&& Pressed < 91 && Pressed - 65 < PageLength
&& Pressed - 65 + PageBegin < Selectables)
{
Return = Selected = Pressed - 65 + PageBegin;
+ bWaitKeyUp=true;
break;
}
- if(Flags & SELECTABLE && Pressed > 96
+ if(Flags & SELECTABLE && Pressed > 96 // 97='a' 122='z'
&& Pressed < 123 && Pressed - 97 < PageLength
&& Pressed - 97 + PageBegin < Selectables)
{
Return = Selected = Pressed - 97 + PageBegin;
+ bWaitKeyUp=true;
break;
}
@@ -222,6 +298,9 @@ uint felist::Draw()
}
}
+ if(globalwindowhandler::IsLastSDLkeyEventWasKeyUp())
+ bClearKeyBufferOnce=true;
+
continue;
}
@@ -249,12 +328,16 @@ uint felist::Draw()
Selected = PageBegin = 0;
}
+ if(globalwindowhandler::IsLastSDLkeyEventWasKeyUp())
+ bClearKeyBufferOnce=true;
+
continue;
}
if(Flags & SELECTABLE && Pressed == KEY_ENTER)
{
Return = Selected;
+ bWaitKeyUp=true;
break;
}
@@ -286,22 +369,39 @@ uint felist::Draw()
if(!(Flags & FADE))
{
- if(Flags & DRAW_BACKGROUND_AFTERWARDS)
+ if(Flags & DRAW_BACKGROUND_AFTERWARDS){
BackGround.FastBlit(DOUBLE_BUFFER);
+ }
- if(Flags & BLIT_AFTERWARDS)
+ if(Flags & BLIT_AFTERWARDS){
graphics::BlitDBToScreen();
+ }
}
else
delete Buffer;
globalwindowhandler::DeInstallControlLoop(FelistDrawController);
+
+ FelistCurrentlyDrawn=NULL;DBGLN;
+
+ #ifdef FELIST_WAITKEYUP
+ if(bWaitKeyUp && !globalwindowhandler::IsLastSDLkeyEventWasKeyUp())
+ for(;;)
+ if(WAIT_FOR_KEY_UP()) //TODO it is NOT waiting, why? that's the reason of `for(;;)` above...
+ break;
+ #endif
+
return Return;
}
static festring Str;
-truth felist::DrawPage(bitmap* Buffer) const
+bool felist::IsEntryDrawingAtValidPos(bitmap* Buffer,v2 pos){
+ if(v2DefaultEntryImageSize.X==0 || v2DefaultEntryImageSize.Y==0)ABORT("v2DefaultEntryImageSize not set.");
+ return Buffer->IsValidPos(pos.X+v2DefaultEntryImageSize.X, pos.Y+v2DefaultEntryImageSize.Y);
+}
+
+truth felist::DrawPage(bitmap* Buffer, v2* pv2FinalPageSize) const
{
uint LastFillBottom = Pos.Y + 23 + Description.size() * 10;
DrawDescription(Buffer);
@@ -328,21 +428,30 @@ truth felist::DrawPage(bitmap* Buffer) const
Str << Entry[c]->String;
+ truth isTheSelectedOne = Flags & SELECTABLE && Entry[c]->Selectable && Selected == i;
+
+ col16 colBkg = BackColor;
+ if(isTheSelectedOne && colSelectedBkg!=TRANSPARENT_COLOR) //colBkg==BLACK
+ colBkg=colSelectedBkg;
+
if(Entry[c]->ImageKey != NO_IMAGE)
{
if(Str.GetSize() <= (Width - 50) >> 3)
{
- Buffer->Fill(Pos.X + 3, LastFillBottom, Width - 6, 20, BackColor);
+ Buffer->Fill(Pos.X + 3, LastFillBottom, Width - 6, 20, colBkg);
- if(EntryDrawer)
+ v2 v2EntryPos = v2(Pos.X + 13, LastFillBottom);
+ if(EntryDrawer && IsEntryDrawingAtValidPos(Buffer,v2EntryPos)){
EntryDrawer(Buffer,
- v2(Pos.X + 13, LastFillBottom),
+ v2EntryPos,
Entry[c]->ImageKey);
+ }
- if(Flags & SELECTABLE && Entry[c]->Selectable && Selected == i)
+ if(isTheSelectedOne){
FONT->PrintfUnshaded(Buffer, v2(Pos.X + 38, LastFillBottom + 5),
WHITE, "%s", Str.CStr());
- else
+ felist::v2SelectedPos = v2EntryPos;
+ }else
FONT->Printf(Buffer, v2(Pos.X + 37, LastFillBottom + 4),
Entry[c]->Color, "%s", Str.CStr());
@@ -355,24 +464,28 @@ truth felist::DrawPage(bitmap* Buffer) const
Marginal);
uint PictureTop = LastFillBottom + ChapterSize * 5 - 9;
+ v2 v2EntryPos = v2(Pos.X + 13, PictureTop);
+
for(uint l = 0; l < ChapterSize; ++l)
{
- Buffer->Fill(Pos.X + 3, LastFillBottom, Width - 6, 10, BackColor);
+ Buffer->Fill(Pos.X + 3, LastFillBottom, Width - 6, 10, colBkg);
- if(Flags & SELECTABLE && Entry[c]->Selectable && Selected == i)
+ if(isTheSelectedOne) {
FONT->PrintfUnshaded(Buffer, v2(Pos.X + 38, LastFillBottom + 1),
WHITE, "%s", Chapter[l].CStr());
- else
+ felist::v2SelectedPos = v2EntryPos;
+ } else
FONT->Printf(Buffer, v2(Pos.X + 37, LastFillBottom),
Entry[c]->Color, "%s", Chapter[l].CStr());
LastFillBottom += 10;
}
- if(EntryDrawer)
+ if(EntryDrawer && IsEntryDrawingAtValidPos(Buffer,v2EntryPos)){
EntryDrawer(Buffer,
- v2(Pos.X + 13, PictureTop),
+ v2EntryPos,
Entry[c]->ImageKey);
+ }
}
}
else
@@ -383,12 +496,12 @@ truth felist::DrawPage(bitmap* Buffer) const
for(uint l = 0; l < ChapterSize; ++l)
{
- Buffer->Fill(Pos.X + 3, LastFillBottom, Width - 6, 10, BackColor);
+ Buffer->Fill(Pos.X + 3, LastFillBottom, Width - 6, 10, colBkg);
- if(Flags & SELECTABLE && Entry[c]->Selectable && Selected == i)
+ if(Flags & SELECTABLE && Entry[c]->Selectable && Selected == i){
FONT->PrintfUnshaded(Buffer, v2(Pos.X + 14, LastFillBottom + 1),
WHITE, "%s", Chapter[l].CStr());
- else
+ }else
FONT->Printf(Buffer, v2(Pos.X + 13, LastFillBottom),
Entry[c]->Color, "%s", Chapter[l].CStr());
@@ -396,8 +509,11 @@ truth felist::DrawPage(bitmap* Buffer) const
}
}
- if((i - PageBegin == PageLength - 1 && Entry[c]->Selectable)
- || c == Entry.size() - 1)
+ if(
+ (i - PageBegin == PageLength - 1 && Entry[c]->Selectable)
+ ||
+ c == Entry.size() - 1
+ )
{
if((!(Flags & INVERSE_MODE) && c != Entry.size() - 1)
|| (Flags & INVERSE_MODE && PageBegin))
@@ -413,8 +529,17 @@ truth felist::DrawPage(bitmap* Buffer) const
LastFillBottom += 10;
}
- Buffer->DrawRectangle(Pos.X + 1, Pos.Y + 1, Pos.X + Width - 2,
- LastFillBottom + 1, DARK_GRAY, true);
+ int iLeft = Pos.X + 1,
+ iTop = Pos.Y + 1,
+ iRight = Pos.X + Width - 2,
+ iBottom = LastFillBottom + 1;
+ Buffer->DrawRectangle(iLeft,iTop,iRight,iBottom, DARK_GRAY, true);
+
+ if(pv2FinalPageSize!=NULL){
+ pv2FinalPageSize->X = iRight-iLeft;
+ pv2FinalPageSize->Y = iBottom-iTop;
+ }
+
break;
}
@@ -465,12 +590,12 @@ void felist::QuickDraw(bitmap* Bitmap, uint PageLength) const
for(uint c2 = 0; c2 < ChapterSize; ++c2)
{
col16 Color = CurrentEntry->Color;
- Color = MakeRGB16(GetRed16(Color) - ((GetRed16(Color) * 3
- * Index / PageLength) >> 2),
+ Color = MakeRGB16(GetRed16(Color) - ((GetRed16(Color) * 3
+ * Index / PageLength) >> 2),
GetGreen16(Color) - ((GetGreen16(Color) * 3
* Index / PageLength) >> 2),
- GetBlue16(Color) - ((GetBlue16(Color) * 3
- * Index / PageLength) >> 2));
+ GetBlue16(Color) - ((GetBlue16(Color) * 3
+ * Index / PageLength) >> 2));
FONT->Printf(Bitmap, v2(13, Bottom), Color, "%s",
Chapter[ChapterSize - c2 - 1].CStr());
Bottom -= 10;
diff --git a/FeLib/Source/graphics.cpp b/FeLib/Source/graphics.cpp
index 814cd6ffb..34d304da8 100644
--- a/FeLib/Source/graphics.cpp
+++ b/FeLib/Source/graphics.cpp
@@ -20,11 +20,16 @@
#include
#endif
+#include
+#include
+
#include "graphics.h"
#include "bitmap.h"
#include "whandler.h"
#include "error.h"
#include "rawbit.h"
+#include "felist.h"
+#include "feio.h"
void (*graphics::SwitchModeHandler)();
@@ -48,8 +53,54 @@ graphics::vesainfo graphics::VesaInfo;
graphics::modeinfo graphics::ModeInfo;
#endif
-bitmap* graphics::DoubleBuffer;
+//TODO create a utility `class sregion{}` to set it's values outside here w/o using graphics::...
+struct stretchRegion //TODO all these booleans could be a single uint32? unnececessarily complicated?
+{
+ int iIndex;
+ const char* strId;
+ bool bEnabled;
+ blitdata B;
+ bitmap* bmpOverride;
+
+ bool bUseXBRZ;
+ bool bUseXBRZDrawBeforeFelistPage;
+ bool bDrawBeforeFelistPage;
+ bool bDrawAfterFelist;
+ bool bDrawAlways;
+ bool bSpecialListItem;
+ bool bDrawRectangleOutline;
+ bool bAllowTransparency; //mask
+
+ v2 v2SquareSize; //to clear
+
+ std::vector vv2ClearSquaresAt; //these are the relative top left square's pixels at BClearSquares.Bitmap
+ blitdata BClearSquares; //intermediary, it's bitmap will be filled to serve as source
+
+ bitmap* CacheBitmap;
+};
+#define DBGMSG_STRETCHREGION
+#include "dbgmsgproj.h"
+
+const stretchRegion SRdefault = {
+ -1,"READABLE ID NOT SET!!!",true,DEFAULT_BLITDATA,NULL,
+ false,false,false, false,false,false, false,false,
+ v2(),
+ std::vector(), DEFAULT_BLITDATA,
+ NULL
+};
+bool graphics::bSpecialListItemAltPos=false;
+bool bPrepareCacheBitmapsBeforeFelist=false;
+bool bDrawCacheBitmapsBeforeFelist=false;
+
+/* !!! USE GetSRegion(), never access this vector indexes directly !!! */
+std::vector vStretchRegion;
+
+truth graphics::bAllowStretchedRegionsBlit=false;
+
+bitmap* graphics::DoubleBuffer=NULL;
+bitmap* graphics::StretchedBuffer=NULL; //this is actually a 3rd buffer...
v2 graphics::Res;
+int graphics::Scale;
int graphics::ColorDepth;
rawbitmap* graphics::DefaultFont = 0;
@@ -113,7 +164,8 @@ void graphics::DeInit()
#ifdef USE_SDL
void graphics::SetMode(cchar* Title, cchar* IconName,
- v2 NewRes, truth FullScreen)
+ v2 NewRes, int NewScale, int ScalingQuality,
+ truth FullScreen)
{
#if SDL_MAJOR_VERSION == 1
if(IconName)
@@ -169,34 +221,10 @@ void graphics::SetMode(cchar* Title, cchar* IconName,
SDL_RenderSetLogicalSize(Renderer, NewRes.X, NewRes.Y);
- /* The following code will determine whether to use nearest neighbor or
- * linear interpolation when scaling the game in fullscreen mode. */
-
- SDL_DisplayMode VirtualDisplayMode;
- if(SDL_GetDesktopDisplayMode(0, &VirtualDisplayMode) == 0)
- {
- v2 ActualWindowRes; // On high-DPI displays this is greater than NewRes.
- SDL_GL_GetDrawableSize(Window, &ActualWindowRes.X, &ActualWindowRes.Y);
-
- v2 ActualDisplayRes;
- if(SDL_GetWindowFlags(Window) & SDL_WINDOW_FULLSCREEN_DESKTOP)
- ActualDisplayRes = ActualWindowRes;
- else
- ActualDisplayRes = v2(ActualWindowRes.X / NewRes.X * VirtualDisplayMode.w,
- ActualWindowRes.Y / NewRes.Y * VirtualDisplayMode.h);
-
- if((ActualDisplayRes.Y % NewRes.Y == 0
- && ActualDisplayRes.X >= ActualDisplayRes.Y / NewRes.Y * NewRes.X)
- || (ActualDisplayRes.X % NewRes.X == 0
- && ActualDisplayRes.Y >= ActualDisplayRes.X / NewRes.X * NewRes.Y))
- /* In-game pixels can be safely mapped one-on-one to rectangular
- * units consisting of one or more on-screen pixels. */
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
- else
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+ switch(ScalingQuality){
+ case 1: SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); break;
+ default: SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
}
- else
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
Texture = SDL_CreateTexture(Renderer,
SDL_PIXELFORMAT_RGB565,
@@ -206,7 +234,9 @@ void graphics::SetMode(cchar* Title, cchar* IconName,
globalwindowhandler::Init();
DoubleBuffer = new bitmap(NewRes);
+ StretchedBuffer = new bitmap(NewRes); DBG2("StretchedBuffer",StretchedBuffer);
Res = NewRes;
+ SetScale(NewScale);
ColorDepth = 16;
#if SDL_MAJOR_VERSION == 1
@@ -253,6 +283,387 @@ void graphics::BlitDBToScreen()
#else
+void graphics::Stretch(bool bXbrzMode, bitmap* pBmpFrom, blitdata& rBto, bool bAllowTransparency){
+ if(bXbrzMode){
+ pBmpFrom->StretchBlitXbrz(rBto,bAllowTransparency);
+ }else{
+ pBmpFrom->StretchBlit(rBto);
+ }
+}
+
+/* if on class, make it private */
+stretchRegion& GetSRegion(int iIndex){ // vectors are too permissive, it eveb accepts -1 index and will cause a lot of weirdness...
+ if(iIndex>=vStretchRegion.size() || iIndex<0)ABORT("Invalid SRegion index=%d (tot=%d)",iIndex,(int)vStretchRegion.size());
+ return vStretchRegion[iIndex];
+}
+
+bool graphics::IsSRegionEnabled(int iIndex){
+ if(iIndex>=vStretchRegion.size())return false; //not ready yet
+ return GetSRegion(iIndex).bEnabled;
+}
+void graphics::SetSRegionEnabled(int iIndex, bool b){
+ GetSRegion(iIndex).bEnabled=b; DBG2(iIndex,vStretchRegion.size());DBGEXEC(if(b){stretchRegion& rSR = GetSRegion(iIndex);DBGSR;});
+}
+void graphics::SetSRegionUseXBRZ(int iIndex, bool b){
+ GetSRegion(iIndex).bUseXBRZ=b;
+}
+void graphics::SetSRegionDrawBeforeFelistPage(int iIndex, bool bDrawBeforeFelistPage, bool bUseXBRZDrawBeforeFelistPage){
+ stretchRegion& rSR = GetSRegion(iIndex);
+ rSR.bDrawBeforeFelistPage=bDrawBeforeFelistPage;
+ rSR.bUseXBRZDrawBeforeFelistPage=bUseXBRZDrawBeforeFelistPage;
+}
+void graphics::SetSRegionDrawAfterFelist(int iIndex, bool b){
+ GetSRegion(iIndex).bDrawAfterFelist=b;
+}
+void graphics::SetSRegionDrawAlways(int iIndex, bool b){
+ GetSRegion(iIndex).bDrawAlways=b;
+}
+void graphics::SetSRegionDrawRectangleOutline(int iIndex, bool b){
+ GetSRegion(iIndex).bDrawRectangleOutline=b;
+}
+void graphics::SetSRegionClearSquaresAt(int iIndex, v2 v2Size, std::vector vv2){
+ stretchRegion& rSR = GetSRegion(iIndex);
+ rSR.vv2ClearSquaresAt=vv2;
+ rSR.v2SquareSize=v2Size;
+ rSR.bAllowTransparency=true;
+}
+/**
+ * there can only be one set at a time
+ */
+void graphics::SetSRegionListItem(int iIndex){
+ stretchRegion& rSR = GetSRegion(iIndex);
+ if(rSR.bSpecialListItem)return; //permissive on redundant setup
+
+ for(int i=0;iGetSize();
+
+ rSR.B.Stretch=iStretch;
+
+ rSR.B.Dest=v2Dest;
+}
+
+int graphics::AddStretchRegion(blitdata B,const char* strId){
+ int i = SetSRegionBlitdata(-1, B);
+ stretchRegion& rSR = vStretchRegion[i];
+ rSR.strId=strId;DBGSRI("AddOk");
+ return i;
+}
+
+bitmap* SRegionPrepareClearedSquares(bitmap* DoubleBuffer, stretchRegion& rSR){
+ blitdata& rB = rSR.B;
+ blitdata& rBC = rSR.BClearSquares;
+ if(rBC.Bitmap==NULL || rBC.Bitmap->GetSize()!=rB.Border){
+ if(rBC.Bitmap!=NULL)delete rBC.Bitmap;
+ rBC.Bitmap = new bitmap(rB.Border);
+ }
+
+ rBC.Src = rB.Src;DBGLN;
+ rBC.Dest = {0,0};DBGLN;
+ rBC.Border = rB.Border;DBGLN;
+ DBGBLD(rBC);
+ DoubleBuffer->NormalBlit(rBC);DBGLN;
+
+ for(int i=0;iFill(rSR.vv2ClearSquaresAt[i],rSR.v2SquareSize,TRANSPARENT_COLOR);
+ }
+ rSR.vv2ClearSquaresAt.clear();
+
+ rB.Src=v2(); //as the blitdata for cleared squares will now be the source to be stretched from
+ return rBC.Bitmap;
+}
+
+bool graphics::isStretchedRegionsAllowed(){
+ return
+ bAllowStretchedRegionsBlit
+ &&
+ !iosystem::IsOnMenu() //main menu
+ &&
+ vStretchRegion.size()>0
+ ;
+}
+
+void graphics::PrepareBeforeDrawingFelist(){
+ if(!isStretchedRegionsAllowed())return;
+
+ for(int i=0;iGetSize() != rB.Border)){
+ if(rSR.CacheBitmap!=NULL){
+ delete rSR.CacheBitmap;
+ }
+
+ rSR.CacheBitmap = new bitmap(rB.Border * rB.Stretch);
+ }
+
+ blitdata B = rSR.B; //copy
+ B.Bitmap = rSR.CacheBitmap;
+ B.Dest=v2(0,0);
+
+ Stretch(rSR.bUseXBRZ && rSR.bUseXBRZDrawBeforeFelistPage, DoubleBuffer, B, false);
+ }
+}
+
+void graphics::DrawAtDoubleBufferBeforeFelistPage(){
+ if(!isStretchedRegionsAllowed())return;
+
+ for(int i=0;iFastBlit(DoubleBuffer, rSR.B.Dest); // is a cache substitute to the region scaling
+ }
+}
+
+void debugTinyDungeon(bitmap* DoubleBuffer, bitmap* StretchedBuffer){
+ static bool bDbgTinyDungeon = [](){const char* c=std::getenv("IVAN_DebugShowTinyDungeon");return c!=NULL && strcmp(c,"true")==0;}();
+ if(bDbgTinyDungeon){
+ blitdata Bdbg=DEFAULT_BLITDATA;
+ Bdbg.Bitmap=StretchedBuffer;
+ Bdbg.Border={400,300};
+ DoubleBuffer->NormalBlit(Bdbg);
+ }
+}
+
+bitmap* graphics::PrepareBuffer(){
+ bitmap* ReturnBuffer = DoubleBuffer;
+
+// if(felist::isAnyFelistCurrentlyDrawn())graphics::DrawAtDoubleBufferBeforeFelistPage();
+
+ if(isStretchedRegionsAllowed()){ // !!!!!!!!!!!!!!!!!!!!!!!! DO NOT MODIFY DoubleBuffer HERE (chaotic recursive blitting problem) !!!!!!!!!!!!!!!!!!!!!!!!
+ bool bDidStretch=false;
+ bool bOk=true;
+
+ for(int i=0;i=0 && rB.Border.Y>=0))ABORT("invalid SRegion border (negatives are critical) %d,%d",rB.Border.X,rB.Border.Y);
+ if(bOk)if(rB.Border.X==0 || rB.Border.Y==0){DBGSB(bOk);
+ if(rB.Border.Is0()){DBGSB(bOk); //being 0,0 may mean it is not ready yet (wouldnt be accepted to blit anyway).
+ bOk=false;DBGSB(bOk);
+ }else{DBGSB(bOk);
+ if(!(rB.Border.X>0 && rB.Border.Y>0))ABORT("SRegion border: minimum (if not 0,0) is 1,1: %d,%d",rB.Border.X,rB.Border.Y);
+ }
+ }
+
+ if(!(rB.Dest.X>=0 && rB.Dest.Y>=0))ABORT("invalid SRegion Dest (negatives are critical) %d,%d",rB.Dest.X,rB.Dest.Y);DBGSB(bOk);
+
+ if(bOk){
+ if(!bDidStretch){
+ // first time, if there is at least one stretching, prepare "background/base" on the stretched
+ DoubleBuffer->FastBlit(StretchedBuffer); //simple copy (like a 3rd buffer)
+ ReturnBuffer = StretchedBuffer; //and set stretched as the final source
+ }
+
+ if(rSR.bSpecialListItem){ DBGSRI("ListItem");
+ rB.Src = felist::GetCurrentListSelectedItemPos(); //the tiny one
+ }
+
+ bool bDrawSROutline=rSR.bDrawRectangleOutline;
+ if(rSR.bSpecialListItem){
+ if(bSpecialListItemAltPos){
+ bool bAltPosFullBkg=false; //TODO user option ? doesnt look too good anyway..
+ // let felist re-configure the blitdata before the stretching below
+ felist::PrepareListItemAltPosBackground(rB,bAltPosFullBkg);
+ if(bAltPosFullBkg)bDrawSROutline=false;
+ }
+ }
+
+ if(bDrawSROutline){
+ graphics::DrawRectangleOutlineAround(rB.Bitmap, rB.Dest, (rB.Border) * (rB.Stretch), DARK_GRAY, true);
+ }
+
+ bitmap* pbmpFrom = DoubleBuffer;
+ if(rSR.bmpOverride!=NULL){
+ pbmpFrom = rSR.bmpOverride;
+ }else
+ if(rSR.vv2ClearSquaresAt.size()>0){
+ pbmpFrom = SRegionPrepareClearedSquares(DoubleBuffer,rSR);
+ }
+
+ DBGSRI("STRETCHING FROM DoubleBuffer TO StretchedBuffer");
+ Stretch(rSR.bUseXBRZ, pbmpFrom, rB, rSR.bAllowTransparency);
+
+ bDidStretch=true;
+ }
+ }
+
+ debugTinyDungeon(DoubleBuffer,StretchedBuffer);
+ }
+
+ DrawAboveAll(ReturnBuffer);
+
+ return ReturnBuffer;
+}
+
+struct drawaboveentry{
+ drawabove da;
+ int iPriority;
+ const char* desc; //to help on development
+};
+std::vector vDrawabove;
+void graphics::DrawAboveAll(bitmap* bmpDest)
+{
+ for(int i=0;i vDrawaboveTmp(vDrawabove);
+ vDrawaboveTmp.push_back(dae);
+
+ vDrawabove.clear();
+
+ while(vDrawaboveTmp.size()>0){
+ drawaboveentry daeLowestPriority;
+ daeLowestPriority.iPriority=1000000000; //TODO should be max int
+ int iIndexLP=-1;
+ for(int i=0;iGetSize().X-iMargin;if(v2BottomRight.X>iMMax)v2BottomRight.X=iMMax;
+ iMMax=bmpAt->GetSize().Y-iMargin;if(v2BottomRight.Y>iMMax)v2BottomRight.Y=iMMax;
+
+ bmpAt->DrawRectangle(v2TopLeft, v2BottomRight, color, bWide);
+}
+
+int graphics::GetTotSRegions(){
+ return vStretchRegion.size();
+}
+
void graphics::BlitDBToScreen()
{
#if SDL_MAJOR_VERSION == 1
@@ -273,16 +684,20 @@ void graphics::BlitDBToScreen()
SDL_UpdateRect(Screen, 0, 0, Res.X, Res.Y);
#else
- packcol16* SrcPtr = DoubleBuffer->GetImage()[0];
+ packcol16* SrcPtr = PrepareBuffer()->GetImage()[0];
void* DestPtr;
int Pitch;
- if (SDL_LockTexture(Texture, NULL, &DestPtr, &Pitch) < 0)
- ABORT("Can't lock texture");
-
- memcpy(DestPtr, SrcPtr, Res.Y * Pitch);
-
- SDL_UnlockTexture(Texture);
+ if (SDL_LockTexture(Texture, NULL, &DestPtr, &Pitch) == 0)
+ {
+ memcpy(DestPtr, SrcPtr, Res.Y * Pitch);
+ SDL_UnlockTexture(Texture);
+ }
+ else
+ {
+ // Try to use the slower SDL_UpdateTexture() as a fallback if SDL_LockTexture() fails.
+ SDL_UpdateTexture(Texture, NULL, SrcPtr, Res.X * sizeof(packcol16));
+ }
SDL_RenderClear(Renderer);
SDL_RenderCopy(Renderer, Texture, NULL, NULL);
@@ -292,6 +707,23 @@ void graphics::BlitDBToScreen()
#endif
+void graphics::SetScale(int NewScale)
+{
+ Scale = NewScale;
+#if SDL_MAJOR_VERSION == 1
+#warning Graphics scaling not implemented for SDL v1
+#else
+ // Scale the window, maintaining its center position.
+ v2 WindowPos, OldSize, NewSize = Res * NewScale;
+ SDL_GetWindowPosition(Window, &WindowPos.X, &WindowPos.Y);
+ SDL_GetWindowSize(Window, &OldSize.X, &OldSize.Y);
+ WindowPos += (OldSize - NewSize) / 2;
+ SDL_SetWindowPosition(Window, WindowPos.X, WindowPos.Y);
+ SDL_SetWindowSize(Window, Res.X * NewScale, Res.Y * NewScale);
+ SDL_RenderSetScale(Renderer, NewScale, NewScale);
+#endif
+}
+
void graphics::SwitchMode()
{
#if SDL_MAJOR_VERSION == 1
@@ -320,6 +752,7 @@ void graphics::SwitchMode()
{
SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowFullscreen(Window, 0);
+ SetScale(Scale);
}
else
{
diff --git a/FeLib/Source/hscore.cpp b/FeLib/Source/hscore.cpp
index d0d740e6d..a72b4a5b0 100644
--- a/FeLib/Source/hscore.cpp
+++ b/FeLib/Source/hscore.cpp
@@ -17,13 +17,13 @@
#include "femath.h"
/* Increment this if changes make highscores incompatible */
-#define HIGH_SCORE_VERSION 127
+#define HIGH_SCORE_VERSION 129
cfestring& highscore::GetEntry(int I) const { return Entry[I]; }
long highscore::GetScore(int I) const { return Score[I]; }
long highscore::GetSize() const { return Entry.size(); }
-highscore::highscore(cfestring& File) : LastAdd(0xFF), Version(HIGH_SCORE_VERSION) { Load(File); }
+highscore::highscore(cfestring& File) : LastAdd(0xFF), Version(HIGH_SCORE_VERSION), DefaultFile(File) { Load(File); }
truth highscore::Add(long NewScore, cfestring& NewEntry,
time_t NewTime, long NewRandomID)
@@ -100,7 +100,7 @@ void highscore::Draw() const
void highscore::Save(cfestring& File) const
{
- outputfile HighScore(File);
+ outputfile HighScore(File.GetSize() > 0 ? File : DefaultFile);
long CheckSum = HIGH_SCORE_VERSION + LastAdd;
for(ushort c = 0; c < Score.size(); ++c)
{
@@ -114,8 +114,10 @@ void highscore::Save(cfestring& File) const
/* This function needs much more error handling */
void highscore::Load(cfestring& File)
{
+ cfestring Path = File.GetSize() > 0 ? File : DefaultFile;
+
{
- inputfile HighScore(File, 0, false);
+ inputfile HighScore(Path, 0, false);
if(!HighScore.IsOpen())
return;
@@ -126,7 +128,7 @@ void highscore::Load(cfestring& File)
return;
}
- inputfile HighScore(File, 0, false);
+ inputfile HighScore(Path, 0, false);
HighScore >> Version;
HighScore >> Score >> Entry >> Time >> RandomID >> LastAdd;
}
diff --git a/FeLib/Source/rawbit.cpp b/FeLib/Source/rawbit.cpp
index a8aca922e..eb07c6118 100644
--- a/FeLib/Source/rawbit.cpp
+++ b/FeLib/Source/rawbit.cpp
@@ -11,6 +11,9 @@
*/
#include
+#include
+
+#include "png.h"
#include "allocate.h"
#include "rawbit.h"
@@ -22,38 +25,61 @@ void rawbitmap::MaskedBlit(bitmap* Bitmap, packcol16* Color) const { MaskedBlit(
rawbitmap::rawbitmap(cfestring& FileName)
{
- inputfile File(FileName.CStr(), 0, false);
+ std::shared_ptr File(fopen(FileName.CStr(), "rb"), fclose);
- if(!File.IsOpen())
+ if(!File)
ABORT("Bitmap %s not found!", FileName.CStr());
- File.SeekPosEnd(-768);
+ png_structp PNGStruct = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+
+ if(!PNGStruct)
+ ABORT("Couldn't read PNG file %s!", FileName.CStr());
+
+ png_infop PNGInfo = png_create_info_struct(PNGStruct);
+
+ if(!PNGInfo)
+ abort();
+
+ if(setjmp(png_jmpbuf(PNGStruct)) != 0)
+ abort();
+
+ png_init_io(PNGStruct, File.get());
+ png_read_info(PNGStruct, PNGInfo);
+
+ Size.X = png_get_image_width(PNGStruct, PNGInfo);
+ Size.Y = png_get_image_height(PNGStruct, PNGInfo);
+
+ if(png_get_bit_depth(PNGStruct, PNGInfo) != 8)
+ ABORT("%s has wrong bit depth %d, should be 8!", FileName.CStr(),
+ int(png_get_bit_depth(PNGStruct, PNGInfo)));
+
+ png_colorp PNGPalette;
+ int PaletteSize;
+
+ if(!png_get_PLTE(PNGStruct, PNGInfo, &PNGPalette, &PaletteSize))
+ ABORT("%s is not in indexed color mode!", FileName.CStr());
+
+ if(PaletteSize != 256)
+ ABORT("%s has wrong palette size %d, should be 256!", FileName.CStr(), PaletteSize);
+
Palette = new uchar[768];
- File.Read(reinterpret_cast(Palette), 768);
- File.SeekPosBegin(8);
- Size.X = File.Get();
- Size.X += (File.Get() << 8) + 1;
- Size.Y = File.Get();
- Size.Y += (File.Get() << 8) + 1;
- File.SeekPosBegin(128);
+
+ for(int i = 0; i < PaletteSize; ++i)
+ {
+ Palette[i * 3 + 0] = PNGPalette[255 - i].red;
+ Palette[i * 3 + 1] = PNGPalette[255 - i].green;
+ Palette[i * 3 + 2] = PNGPalette[255 - i].blue;
+ }
+
Alloc2D(PaletteBuffer, Size.Y, Size.X);
+ png_read_image(PNGStruct, PaletteBuffer);
paletteindex* Buffer = PaletteBuffer[0];
paletteindex* End = &PaletteBuffer[Size.Y - 1][Size.X];
- while(Buffer != End)
- {
- int Char1 = File.Get();
-
- if(Char1 > 192)
- {
- int Char2 = File.Get();
+ for(; Buffer != End; ++Buffer)
+ *Buffer = 255 - *Buffer;
- for(; Char1 > 192; Char1--)
- *Buffer++ = Char2;
- }
- else
- *Buffer++ = Char1;
- }
+ png_destroy_read_struct(&PNGStruct, &PNGInfo, nullptr);
}
rawbitmap::rawbitmap(v2 Size) : Size(Size)
@@ -74,36 +100,41 @@ rawbitmap::~rawbitmap()
}
}
-/* A lousy bitmap saver that uses the pcx format but doesn't do any compression. */
-
void rawbitmap::Save(cfestring& FileName)
{
- char PCXHeader[128];
- memset(PCXHeader, 0, 128);
- *reinterpret_cast(PCXHeader) = 0x0801050A;
- PCXHeader[65] = 0x01;
- PCXHeader[66] = Size.X & 0xFF;
- PCXHeader[67] = (Size.X >> 8) & 0xFF;
- PCXHeader[0x08] = (Size.X - 1) & 0xFF;
- PCXHeader[0x09] = ((Size.X - 1) >> 8) & 0xFF;
- PCXHeader[0x0A] = (Size.Y - 1) & 0xFF;
- PCXHeader[0x0B] = ((Size.Y - 1) >> 8) & 0xFF;
- outputfile SaveFile(FileName);
- SaveFile.Write(PCXHeader, 128);
+ std::shared_ptr File(fopen(FileName.CStr(), "wb"), fclose);
+ png_structp PNGStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ png_infop PNGInfo = png_create_info_struct(PNGStruct);
+ png_init_io(PNGStruct, File.get());
+
+ png_color PNGPalette[256];
+
+ for(int i = 0; i < 256; ++i)
+ {
+ PNGPalette[255 - i].red = Palette[i * 3 + 0];
+ PNGPalette[255 - i].green = Palette[i * 3 + 1];
+ PNGPalette[255 - i].blue = Palette[i * 3 + 2];
+ }
+
+ png_set_IHDR(PNGStruct, PNGInfo, Size.X, Size.Y, 8, PNG_COLOR_TYPE_PALETTE,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_set_PLTE(PNGStruct, PNGInfo, PNGPalette, 256);
+ png_write_info(PNGStruct, PNGInfo);
+
paletteindex* Buffer = PaletteBuffer[0];
paletteindex* End = &PaletteBuffer[Size.Y - 1][Size.X];
- while(Buffer != End)
- {
- paletteindex Char = *Buffer++;
+ for(; Buffer != End; ++Buffer)
+ *Buffer = 255 - *Buffer;
- if(Char >= 192)
- SaveFile.Put(char(193));
+ png_write_image(PNGStruct, PaletteBuffer);
+ png_write_end(PNGStruct, PNGInfo);
+ png_destroy_write_struct(&PNGStruct, &PNGInfo);
- SaveFile.Put(Char);
- }
+ Buffer = PaletteBuffer[0];
- SaveFile.Write(reinterpret_cast(Palette), 768);
+ for(; Buffer != End; ++Buffer)
+ *Buffer = 255 - *Buffer;
}
void rawbitmap::MaskedBlit(bitmap* Bitmap, v2 Src, v2 Dest, v2 Border, packcol16* Color) const
@@ -338,15 +369,15 @@ bitmap* rawbitmap::Colorize(v2 Pos, v2 Border, v2 Move, cpackcol16* Color, alpha
Blue >>= 1;
}
- if(Burnt && BurnData[ColorIndex]
- && (BurnData[ColorIndex] & 3UL)
- > (BurnSeed[ColorIndex] = BurnSeed[ColorIndex] * 1103515245 + 12345) >> 30)
- {
- Max >>= 2;
- Red = Max + (Red >> 3);
- Green = Max + (Green >> 3);
- Blue = Max + (Blue >> 3);
- }
+ if(Burnt && BurnData[ColorIndex]
+ && (BurnData[ColorIndex] & 3UL)
+ > (BurnSeed[ColorIndex] = BurnSeed[ColorIndex] * 1103515245 + 12345) >> 30)
+ {
+ Max >>= 2;
+ Red = Max + (Red >> 3);
+ Green = Max + (Green >> 3);
+ Blue = Max + (Blue >> 3);
+ }
if(Red > 0x7FF)
Red = 0x7FF;
diff --git a/FeLib/Source/save.cpp b/FeLib/Source/save.cpp
index 7c3a73d3a..0ae3194c0 100644
--- a/FeLib/Source/save.cpp
+++ b/FeLib/Source/save.cpp
@@ -13,7 +13,7 @@
#include
#ifdef WIN32
-#include
+#include
#include // for _mkdir
#else
#include
@@ -23,9 +23,46 @@
#include "save.h"
#include "femath.h"
-outputfile::outputfile(cfestring& FileName, truth AbortOnErr)
-: FileName(FileName)
+#include "dbgmsgproj.h"
+
+truth outputfile::bakcupBeforeSaving = false;
+truth outputfile::saveOnNewFileAlways = false;
+
+void outputfile::SetSafeSaving(truth b){DBGLN;
+ bakcupBeforeSaving=b;
+ saveOnNewFileAlways=b;
+}
+
+void outputfile::Close() { DBG3(FileNameNewTmp.CStr(),FileName.CStr(),saveOnNewFileAlways);
+ File.close();
+
+ if(saveOnNewFileAlways){ // This moves the new .tmp file to the correct filename, before removing it.
+ if(FileNameNewTmp.IsEmpty())
+ ABORT("new tmp filename is empty, 'save on new file always' option was properly set before this output file '%s' ?",FileName.CStr());
+
+ std::ifstream newTmpFile(FileNameNewTmp.CStr(), std::ios::binary);
+ if(newTmpFile.good()){
+ std::remove(FileName.CStr()); //just to not let existing one create any doubts if some crash happens here
+
+ std::ofstream final(FileName.CStr(), std::ios::binary);
+ final << newTmpFile.rdbuf();
+
+ final.close();
+ newTmpFile.close();
+
+ std::remove(FileNameNewTmp.CStr()); //last thing
+ }else{
+ ABORT("the new tmp file '%s' should exist!",FileNameNewTmp.CStr());
+ }
+ }
+}
+
+outputfile::outputfile(cfestring& fileName, truth AbortOnErr)
+: FileName(fileName)
{
+ if(FileName.IsEmpty())
+ ABORT("empty output filename");
+
// If FileName contains a directory, make sure the directory exists first.
festring::csizetype LastPathSeparatorPos = FileName.FindLast('/');
if(LastPathSeparatorPos != festring::NPos)
@@ -35,28 +72,46 @@ outputfile::outputfile(cfestring& FileName, truth AbortOnErr)
MakePath(DirectoryPath);
}
- Buffer = fopen(FileName.CStr(), "wb");
+ if(bakcupBeforeSaving){ // this is not that useful, the tmp files are better as they prevent overwriting the final files in case the game crashes
+ std::ifstream orig(FileName.CStr(), std::ios::binary);
+ if(orig.good()){
+ festring fsBkp("");fsBkp << FileName << ".bkp";
+ std::remove(fsBkp.CStr()); //just to have a granted clean new backup
- if(AbortOnErr && !IsOpen())
- ABORT("Can't open %s for output!", FileName.CStr());
-}
+ std::ofstream bkp(fsBkp.CStr(), std::ios::binary);
+ bkp << orig.rdbuf();
-outputfile::~outputfile()
-{
- if(Buffer)
- fclose(Buffer);
-}
+ orig.close();
+ bkp.close();
-void outputfile::ReOpen()
-{
- fclose(Buffer);
- Buffer = fopen(FileName.CStr(), "ab");
+ // backups are kept until leaving the game
+ }
+ }
+
+ festring FileNameNew("");
+ FileNameNew<')
@@ -416,20 +465,20 @@ festring inputfile::ReadNumberIntr(int CallLevel, long *num, truth *isString, tr
}
else
{
- ungetc('>', Buffer);
- ungetc('>', Buffer);
+ File.putback('>');
+ File.putback('>');
*num = Value;
return res;
}
else
- ungetc(Next, Buffer);
+ File.putback(Next);
}
if(First == '(')
{
if(NumberCorrect)
{
- ungetc('(', Buffer);
+ File.putback('(');
*num = Value;
return res;
}
@@ -446,7 +495,7 @@ festring inputfile::ReadNumberIntr(int CallLevel, long *num, truth *isString, tr
if(First == '#') // for #defines
{
- ungetc('#', Buffer);
+ File.putback('#');
*num = Value;
return res;
}
@@ -695,7 +744,7 @@ ulong inputfile::TellLineOfPos(long Pos)
SeekPosBegin(0);
while(TellPos() != Pos)
- if(fgetc(Buffer) == '\n')
+ if(Get() == '\n')
++Line;
if(TellPos() != BackupPos)
diff --git a/FeLib/Source/whandler.cpp b/FeLib/Source/whandler.cpp
index a7321fcf6..0c6a6c94a 100644
--- a/FeLib/Source/whandler.cpp
+++ b/FeLib/Source/whandler.cpp
@@ -11,12 +11,18 @@
*/
#include
+#include
+#include
+#include
-#include "whandler.h"
-#include "graphics.h"
-#include "error.h"
#include "bitmap.h"
+#include "error.h"
+#include "graphics.h"
#include "festring.h"
+#include "rawbit.h"
+#include "whandler.h"
+
+#include "dbgmsgproj.h"
#if SDL_MAJOR_VERSION == 1
/* redefine SDL2 to SDL1 */
@@ -38,7 +44,9 @@ truth (*globalwindowhandler::ControlLoop[MAX_CONTROLS])();
int globalwindowhandler::Controls = 0;
ulong globalwindowhandler::Tick;
truth globalwindowhandler::ControlLoopsEnabled = true;
+truth globalwindowhandler::playInBackground=false;
festring globalwindowhandler::ScrshotDirectoryName = "";
+truth bLastSDLkeyEventIsKeyUp=false;
void globalwindowhandler::InstallControlLoop(truth (*What)())
{
@@ -137,6 +145,189 @@ void globalwindowhandler::Init()
#endif
}
+int iCountFPS=0;
+int iLastSecondFPS=0;
+std::chrono::high_resolution_clock::time_point tpLastSecondFPS;
+int MeasureLastSecondRealFPS(){ //call this every new frame request
+ iCountFPS++;
+
+ using namespace std::chrono;
+ high_resolution_clock::time_point tpNow = high_resolution_clock::now();
+ duration delay = tpNow - tpLastSecondFPS;
+ if(delay.count() > 1000){ //1s
+ iLastSecondFPS=iCountFPS;
+ iCountFPS=0; //reset
+ tpLastSecondFPS = tpNow; //reset
+ }
+
+ return iLastSecondFPS;
+}
+
+std::chrono::high_resolution_clock::time_point tpPreviousFrameTime;
+double InstaCalcFPS(){ //call this every new frame request
+ using namespace std::chrono;
+ high_resolution_clock::time_point tpNow = high_resolution_clock::now();
+ duration delay = tpNow - tpPreviousFrameTime;
+ tpPreviousFrameTime = tpNow;
+ double d = delay.count();
+ if(d==0)d=1; //TODO this may never happen?
+ return 1000/d;
+}
+
+bool bAllowFrameSkip=true;
+int iFrameSkip=0;
+std::chrono::high_resolution_clock::time_point tpBefore;
+std::chrono::duration delay;
+int iLastSecCountFPS;
+float fInstaFPS;
+double dLastFrameTimeMS;
+int iDefaultDelayMS=10;
+int iAddFrameSkip=0;
+
+void globalwindowhandler::SetAddFrameSkip(int i){
+ iAddFrameSkip=i;
+ bAllowFrameSkip = iAddFrameSkip!=0;
+}
+
+/**
+ * to let user input be more responsive as full dungeon xBRZ may be too heavy
+ * return SDL delay in ms
+ */
+int FrameSkipOrDraw(){ //TODO could this be simplified?
+ bool bWaitAKeyPress=false;
+ bool bDoAutoFrameSkip=false;
+ bool bDrawFrame=false;
+ bool bDelay1MS=false;
+
+ if(iFrameSkip<0)ABORT("iFrameSkip is %d < 0",iFrameSkip);
+
+ if(iAddFrameSkip==-2){
+ if(dLastFrameTimeMS>142){ //if it is too slow <= 7 fps
+ bWaitAKeyPress=true;
+ }else{
+ bDoAutoFrameSkip=true;
+ }
+ }else
+ if(iAddFrameSkip==-1){
+ bDoAutoFrameSkip=true;
+ }
+
+ if(!bWaitAKeyPress){ // if waiting a key press, there will have no stand-by animation at all...
+ if(iFrameSkip==0){
+ bDrawFrame=true;
+
+ // setup next
+ if(bDoAutoFrameSkip){ //TODO improve this automatic mode?
+ if(dLastFrameTimeMS>250){ //4fps
+ iFrameSkip=10;
+ }else
+ if(dLastFrameTimeMS>200){ //5fps
+ iFrameSkip=5;
+ }else
+ if(dLastFrameTimeMS>150){
+ iFrameSkip=3;
+ }else
+ if(dLastFrameTimeMS>100){ //10fps
+ iFrameSkip=1;
+ }
+
+ bDelay1MS=true;
+ }else{
+ if(iAddFrameSkip==0){ //vanilla (wont be reached tho cuz of bAllowFrameSkip=false), kept for completeness (in case it changes before calling this method)
+ bDrawFrame=true;
+ }else
+ if(iAddFrameSkip>0){ //fixed
+ iFrameSkip=iAddFrameSkip;
+
+ bDelay1MS=true;
+ }
+ }
+ }
+ }
+
+ if(bDrawFrame){
+ tpBefore = std::chrono::high_resolution_clock::now();
+ graphics::BlitDBToScreen();
+ delay = std::chrono::high_resolution_clock::now() - tpBefore;
+ dLastFrameTimeMS = delay.count();
+
+ //call these ONLY when the frame is actually DRAWN!!! (despite not being actually used yet)
+ iLastSecCountFPS = MeasureLastSecondRealFPS();
+ fInstaFPS = InstaCalcFPS();
+ //DBG5(DBGF(fInstaFPS),DBGI(iLastSecCountFPS),DBGF(dLastFrameTimeMS),DBGI(iAddFrameSkip),DBGI(iFrameSkip));
+ }else{
+ if(iFrameSkip>0)iFrameSkip--;
+ //DBGSI(iFrameSkip);
+ }
+
+ if(bDelay1MS){
+ return 1;
+ }else{
+ return iDefaultDelayMS;
+ }
+}
+
+int iTimeoutDelay=0; // must init with 0
+int iTimeoutDefaultKey;
+long keyTimeoutRequestedAt;
+/**
+ * This is intended to remain active ONLY until the user hits any key.
+ */
+void globalwindowhandler::SetKeyTimeout(int iTimeoutMillis,int iDefaultReturnedKey)//,int iIgnoreKeyWhenDisabling)
+{
+ iTimeoutDelay = (iTimeoutMillis/1000.0) * CLOCKS_PER_SEC;
+ if(iTimeoutDelay>0 && iTimeoutDelay<10)iTimeoutDelay=10; // we are unable to issue commands if it is too low TODO could be less than 10ms?
+
+ iTimeoutDefaultKey=iDefaultReturnedKey;
+}
+truth globalwindowhandler::IsKeyTimeoutEnabled()
+{
+ return iTimeoutDelay>0;
+}
+void globalwindowhandler::CheckKeyTimeout()
+{
+ if(iTimeoutDelay>0){ // timeout mode is enalbed
+ if(!KeyBuffer.empty()){ // user pressed some key
+ keyTimeoutRequestedAt=clock(); // resets reference time to wait from
+ }else{
+ if( clock() > (keyTimeoutRequestedAt+iTimeoutDelay) ) //wait for the timeout to...
+ KeyBuffer.push_back(iTimeoutDefaultKey); //...simulate the keypress
+ }
+ }
+}
+
+float globalwindowhandler::GetFPS(bool bInsta){
+ if(bInsta)return fInstaFPS;
+ return iLastSecCountFPS;
+}
+
+truth globalwindowhandler::HasKeysOnBuffer(){
+ return KeyBuffer.size()>0;
+}
+
+void ShowFPS(){ //TODO still flickers sometimes cuz of silhouette?
+ static long lTimePrevious=clock();
+ static bool bShowFPS = [](){const char* c=std::getenv("IVAN_SHOWFPS");return c!=NULL && strcmp(c,"true")==0;}();
+ if(bShowFPS){
+// if(clock()%(CLOCKS_PER_SEC*3) CLOCKS_PER_SEC*1){
+ static int iMargin=2;
+ static v2 v2Margin(iMargin,iMargin);
+ static char c[100];
+
+ sprintf(c,"FPS:ls=%.1f,insta=%.1f",globalwindowhandler::GetFPS(false),globalwindowhandler::GetFPS(true));
+ int iDistX = strlen(c)*8 + 10;
+ v2 v2Pos = RES-v2(iDistX,RES.Y)+v2Margin;
+ v2 v2Size(iDistX, 8+iMargin*2);
+
+ DOUBLE_BUFFER->Fill(v2Pos,v2Size,BLACK);
+ FONT->Printf(DOUBLE_BUFFER,v2Pos+v2Margin,WHITE,"%s",c);
+ lTimePrevious=lTime;
+ }
+ }
+}
+
int globalwindowhandler::GetKey(truth EmptyBuffer)
{
SDL_Event Event;
@@ -149,7 +340,11 @@ int globalwindowhandler::GetKey(truth EmptyBuffer)
KeyBuffer.clear();
}
- for(;;)
+ keyTimeoutRequestedAt=clock();
+ int iDelayMS=iDefaultDelayMS;
+ for(;;){
+ CheckKeyTimeout();
+
if(!KeyBuffer.empty())
{
int Key = KeyBuffer[0];
@@ -163,14 +358,18 @@ int globalwindowhandler::GetKey(truth EmptyBuffer)
}
else
{
- if(SDL_PollEvent(&Event))
+ bool bHasEvents=false;
+ while(SDL_PollEvent(&Event)){
ProcessMessage(&Event);
- else
+ bHasEvents=true;
+ }
+
+ if(!bHasEvents)
{
#if SDL_MAJOR_VERSION == 1
if(SDL_GetAppState() & SDL_APPACTIVE
#else
- if(SDL_GetWindowFlags(graphics::Window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS)
+ if( (playInBackground || (SDL_GetWindowFlags(graphics::GetWindow()) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS)))
#endif
&& Controls && ControlLoopsEnabled)
{
@@ -186,11 +385,22 @@ int globalwindowhandler::GetKey(truth EmptyBuffer)
if(ControlLoop[c]())
Draw = true;
- if(Draw)
- graphics::BlitDBToScreen();
+ /******************
+ * the stand-by animation
+ */
+ ShowFPS();
+ if(!bAllowFrameSkip){
+ if(Draw)
+ graphics::BlitDBToScreen();
+
+ iDelayMS=iDefaultDelayMS;
+ }else{
+ iDelayMS = FrameSkipOrDraw();
+ }
+
}
- SDL_Delay(10);
+ SDL_Delay(iDelayMS);
}
else
{
@@ -199,6 +409,8 @@ int globalwindowhandler::GetKey(truth EmptyBuffer)
}
}
}
+
+ }
}
int globalwindowhandler::ReadKey()
@@ -208,7 +420,7 @@ int globalwindowhandler::ReadKey()
#if SDL_MAJOR_VERSION == 1
if(SDL_GetAppState() & SDL_APPACTIVE)
#else
- if(SDL_GetWindowFlags(graphics::Window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS))
+ if(SDL_GetWindowFlags(graphics::GetWindow()) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS))
#endif
{
while(SDL_PollEvent(&Event))
@@ -223,6 +435,37 @@ int globalwindowhandler::ReadKey()
return KeyBuffer.size() ? GetKey(false) : 0;
}
+truth globalwindowhandler::WaitForKeyEvent(uint Key)
+{
+ SDL_Event Event;
+
+#if SDL_MAJOR_VERSION == 1
+ if(SDL_GetAppState() & SDL_APPACTIVE)
+#else
+ if(SDL_GetWindowFlags(graphics::GetWindow()) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS))
+#endif
+ {
+#if SDL_MAJOR_VERSION == 2
+ while(SDL_PollEvent(&Event))
+ if(Event.type == Key)
+ return true;
+#else
+ while(SDL_PollEvent(&Event))
+ if(Event.active.type == Key)
+ return true;
+#endif
+ }
+ else
+ SDL_WaitEvent(&Event);
+
+ return false;
+}
+
+truth globalwindowhandler::IsLastSDLkeyEventWasKeyUp()
+{
+ return bLastSDLkeyEventIsKeyUp;
+}
+
void globalwindowhandler::ProcessMessage(SDL_Event* Event)
{
int KeyPressed = 0;
@@ -253,7 +496,12 @@ void globalwindowhandler::ProcessMessage(SDL_Event* Event)
exit(0);
return;
+
+ case SDL_KEYUP:
+ bLastSDLkeyEventIsKeyUp=true;
+ break;
case SDL_KEYDOWN:
+ bLastSDLkeyEventIsKeyUp=false;
switch(Event->key.keysym.sym)
{
case SDLK_RETURN:
@@ -334,18 +582,17 @@ void globalwindowhandler::ProcessMessage(SDL_Event* Event)
if(!KeyPressed)
return;
}
- if(std::find(KeyBuffer.begin(), KeyBuffer.end(), KeyPressed)
- == KeyBuffer.end())
+ if( std::find(KeyBuffer.begin(), KeyBuffer.end(), KeyPressed) == KeyBuffer.end() )
KeyBuffer.push_back(KeyPressed);
break;
#if SDL_MAJOR_VERSION == 2
case SDL_TEXTINPUT:
KeyPressed = Event->text.text[0];
- if(std::find(KeyBuffer.begin(), KeyBuffer.end(), KeyPressed)
- == KeyBuffer.end())
+ if( std::find(KeyBuffer.begin(), KeyBuffer.end(), KeyPressed) == KeyBuffer.end() )
KeyBuffer.push_back(KeyPressed);
#endif
}
+
}
// returns true if shift is being pressed
diff --git a/Graphics/Char-outlined.png b/Graphics/Char-outlined.png
new file mode 100644
index 000000000..6829f4cb1
Binary files /dev/null and b/Graphics/Char-outlined.png differ
diff --git a/Graphics/Char.pcx b/Graphics/Char.pcx
deleted file mode 100644
index 861fe149d..000000000
Binary files a/Graphics/Char.pcx and /dev/null differ
diff --git a/Graphics/Char.png b/Graphics/Char.png
new file mode 100644
index 000000000..38feb08d2
Binary files /dev/null and b/Graphics/Char.png differ
diff --git a/Graphics/Cursor.pcx b/Graphics/Cursor.pcx
deleted file mode 100644
index 2a293fccc..000000000
Binary files a/Graphics/Cursor.pcx and /dev/null differ
diff --git a/Graphics/Cursor.png b/Graphics/Cursor.png
new file mode 100644
index 000000000..bf46ef627
Binary files /dev/null and b/Graphics/Cursor.png differ
diff --git a/Graphics/Effect.pcx b/Graphics/Effect.pcx
deleted file mode 100644
index f3b9ffe15..000000000
Binary files a/Graphics/Effect.pcx and /dev/null differ
diff --git a/Graphics/Effect.png b/Graphics/Effect.png
new file mode 100644
index 000000000..4af7a5385
Binary files /dev/null and b/Graphics/Effect.png differ
diff --git a/Graphics/Enner.pcx b/Graphics/Enner.pcx
deleted file mode 100644
index de2ade64c..000000000
Binary files a/Graphics/Enner.pcx and /dev/null differ
diff --git a/Graphics/Enner.png b/Graphics/Enner.png
new file mode 100644
index 000000000..d9332d2cb
Binary files /dev/null and b/Graphics/Enner.png differ
diff --git a/Graphics/FOW.pcx b/Graphics/FOW.pcx
deleted file mode 100644
index b6762ace1..000000000
Binary files a/Graphics/FOW.pcx and /dev/null differ
diff --git a/Graphics/FOW.png b/Graphics/FOW.png
new file mode 100644
index 000000000..de7905de2
Binary files /dev/null and b/Graphics/FOW.png differ
diff --git a/Graphics/Font.pcx b/Graphics/Font.pcx
deleted file mode 100644
index e5cb28c2b..000000000
Binary files a/Graphics/Font.pcx and /dev/null differ
diff --git a/Graphics/Font.png b/Graphics/Font.png
new file mode 100644
index 000000000..aeabd4e9d
Binary files /dev/null and b/Graphics/Font.png differ
diff --git a/Graphics/GLTerra.pcx b/Graphics/GLTerra.pcx
deleted file mode 100644
index d803da1ee..000000000
Binary files a/Graphics/GLTerra.pcx and /dev/null differ
diff --git a/Graphics/GLTerra.png b/Graphics/GLTerra.png
new file mode 100644
index 000000000..745c96e01
Binary files /dev/null and b/Graphics/GLTerra.png differ
diff --git a/Graphics/Humanoid-outlined.png b/Graphics/Humanoid-outlined.png
new file mode 100644
index 000000000..776a09589
Binary files /dev/null and b/Graphics/Humanoid-outlined.png differ
diff --git a/Graphics/Humanoid.pcx b/Graphics/Humanoid.pcx
deleted file mode 100644
index 8dcd5a41d..000000000
Binary files a/Graphics/Humanoid.pcx and /dev/null differ
diff --git a/Graphics/Humanoid.png b/Graphics/Humanoid.png
new file mode 100644
index 000000000..39081fa4a
Binary files /dev/null and b/Graphics/Humanoid.png differ
diff --git a/Graphics/IVlad.pcx b/Graphics/IVlad.pcx
deleted file mode 100644
index 438f2a5b5..000000000
Binary files a/Graphics/IVlad.pcx and /dev/null differ
diff --git a/Graphics/IVlad.png b/Graphics/IVlad.png
new file mode 100644
index 000000000..61a29e8c2
Binary files /dev/null and b/Graphics/IVlad.png differ
diff --git a/Graphics/Item-outlined.png b/Graphics/Item-outlined.png
new file mode 100644
index 000000000..7c068482b
Binary files /dev/null and b/Graphics/Item-outlined.png differ
diff --git a/Graphics/Item.pcx b/Graphics/Item.pcx
deleted file mode 100644
index d02652a12..000000000
Binary files a/Graphics/Item.pcx and /dev/null differ
diff --git a/Graphics/Item.png b/Graphics/Item.png
new file mode 100644
index 000000000..511246663
Binary files /dev/null and b/Graphics/Item.png differ
diff --git a/Graphics/Menu.pcx b/Graphics/Menu.pcx
deleted file mode 100644
index dbf1c7081..000000000
Binary files a/Graphics/Menu.pcx and /dev/null differ
diff --git a/Graphics/Menu.png b/Graphics/Menu.png
new file mode 100644
index 000000000..264e9ea36
Binary files /dev/null and b/Graphics/Menu.png differ
diff --git a/Graphics/OLTerra.pcx b/Graphics/OLTerra.pcx
deleted file mode 100644
index 94a3e71c2..000000000
Binary files a/Graphics/OLTerra.pcx and /dev/null differ
diff --git a/Graphics/OLTerra.png b/Graphics/OLTerra.png
new file mode 100644
index 000000000..9948d5e71
Binary files /dev/null and b/Graphics/OLTerra.png differ
diff --git a/Graphics/Smiley.pcx b/Graphics/Smiley.pcx
deleted file mode 100644
index 3e38a4b0f..000000000
Binary files a/Graphics/Smiley.pcx and /dev/null differ
diff --git a/Graphics/Smiley.png b/Graphics/Smiley.png
new file mode 100644
index 000000000..000251163
Binary files /dev/null and b/Graphics/Smiley.png differ
diff --git a/Graphics/Symbol.pcx b/Graphics/Symbol.pcx
deleted file mode 100644
index de75b6bc6..000000000
Binary files a/Graphics/Symbol.pcx and /dev/null differ
diff --git a/Graphics/Symbol.png b/Graphics/Symbol.png
new file mode 100644
index 000000000..a8fa62256
Binary files /dev/null and b/Graphics/Symbol.png differ
diff --git a/Graphics/WTerra.pcx b/Graphics/WTerra.pcx
deleted file mode 100644
index d18e71b0d..000000000
Binary files a/Graphics/WTerra.pcx and /dev/null differ
diff --git a/Graphics/WTerra.png b/Graphics/WTerra.png
new file mode 100644
index 000000000..3df8fc411
Binary files /dev/null and b/Graphics/WTerra.png differ
diff --git a/INSTALL b/INSTALL
index ea62f3ec8..091dd02f1 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,6 +1,17 @@
Compiling IVAN under different systems
--------------------------------------
+To build IVAN from source, you need to have the following dependencies
+installed on your system:
+
+- compiler with C++11 support (e.g. Clang 3.3 or newer, GCC 4.8 or newer)
+- CMake (https://cmake.org) version 2.8.12.2 or newer
+- SDL (https://www.libsdl.org) version 1.2 or newer, at least 2.0 recommended
+- libpng (http://www.libpng.org/pub/png/libpng.html)
+- pcre, not pcre2 (ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/)
+
+--------------------------------------
+
Under Linux and OS X, type:
cmake .
@@ -9,10 +20,19 @@ make install
Note: Wizard Mode is disabled by default. To enable it run:
-cmake -D CMAKE_CXX_FLAGS=-DWIZARD .
+cmake -D CMAKE_CXX_FLAGS="-DWIZARD" .
make -j
make install
+To install IVAN to a custom prefix, pass the additional flag
+-DCMAKE_INSTALL_PREFIX=/your/prefix/path to the cmake invocation.
+(In particular, simply doing `make DESTDIR=/your/prefix/path install`
+doesn't work because IVAN needs the prefix information at build-time.)
+
+If config options toggle is too fast, you can add this flag -DFELIST_WAITKEYUP,
+like this: CMAKE_CXX_FLAGS="-DFELIST_WAITKEYUP -DWIZARD" (you may chose what
+flags to add independently of each other).
+
--------------------------------------
Under DOS:
@@ -22,11 +42,6 @@ installed, type:
make -f ivandj.mak
-You need to install SDL development libraries,
-which can be downloaded from:
-
-http://www.libsdl.org/
-
--------------------------------------
Under Windows - Visual Studio:
@@ -90,3 +105,76 @@ If you get a lot of weird compilation errors, try invoking cmake again with
Now you can run ivan from D:/buildy/ivan/inst_mingw/ivan/ directory.
+--------------------------------------
+
+Under Windows - MSYS2:
+
+
+Download MSYS2 from http://www.msys2.org/ selecting the right download for your architecture.
+Follow instructions on the page to install correctly.
+
+Run MSYS2.exe from either the "-msys64" or "-msys32" folder, depending on your system, and type these commands
+$ pacman -Syu
+Proceed with installation (option Y), then exit by closing the terminal window. The terminal window will crash and burn eventually but may take some time to do so.
+
+Run MSYS2.exe again:
+$ pacman -Su
+proceed with installation (option Y). This will take a long time to download all the packages, depending on your download speed
+
+$ pacman -S git
+Proceed with installation (option Y) etcetera
+
+$ pacman -S mingw-w64-i686-gcc
+
+$ pacman -S make
+
+$ pacman -S mingw-w64-i686-cmake
+
+$ pacman -S mingw-w64-i686-libpng
+
+$ pacman -S mingw-w64-i686-SDL2
+
+$ pacman -S mingw-w64-i686-SDL2_mixer
+
+$ pacman -S mingw-w64-i686-pkg-config
+
+Now the MSYS2 build system is installed, you only need to follow the instructions below to keep IVAN up to date
+
+Create an empty folder in \ivan\ called msys2
+run MinGW32.exe (from your "-msys64" or "-msys32" folder, whichever is applicable) and change directory to your newly created \ivan\msys2\ folder
+
+In MinGW32.exe type the following commands, respecting the direction of the slashes:
+$ cmake .. -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=C:/ivan/inst_msys2
+$ make -j4 install
+
+Navigate to \ivan\inst_msys2\ivan and you will find the ivan.exe executable!
+
+You will probably need to copy a bunch of DLLs into the directory where ivan.exe is located. These may include the following, likely not an exhaustive list, but they can be found under for example C:\-msys64\mingw32\bin:
+libpng16-16.dll
+libstdc++-6.dll
+libwinpthread-1.dll
+zlib.dll
+libgcc_s_dw2-1.dll
+libSDL2_mixer-2-0-0.dll
+libmad-0.dll
+
+
+Use dependencywalker if you need to check for missing libraries, and if you get the message: "error cannot find entrypoint inflateValidate (in dll libpng16-16.dll)" then you need to include zlib1.dll
+
+--------------------------------------
+
+To build standalone application on MacOS:
+
+Using Homebrew: https://brew.sh/
+
+$ export SDL2DIR="$HOME/Downloads/SDL2Frameworks"
+$ export BUILD_MAC_APP=ON
+$ export IVAN_BUILD_DIR="$PWD/build"
+$ mkdir build && cd build
+$ ../ci/osx/requirements.sh
+$ ../ci/osx/build.sh
+$ make install
+$ ../ci/osx/package.sh
+$ ls ./osx
+
+The user data will be stored at "$HOME/Library/Application Support/IVAN".
diff --git a/LICENSING b/LICENSING
index fa52f0438..8eae4f084 100644
--- a/LICENSING
+++ b/LICENSING
@@ -4,21 +4,219 @@ Licensing
All files contained in this release are part of Iter Vehemens ad Necem.
Iter Vehemens ad Necem is Copyright (C) 2001, 2002, 2003, 2004
-Timo Kiviluoto.
+Timo Kiviluoto.
-Iter Vehemens ad Necem is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as published
+Iter Vehemens ad Necem is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
+your option) any later version.
-Iter Vehemens ad Necem is distributed in the hope that it will be useful,
+Iter Vehemens ad Necem is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
+General Public License for more details.
You should have received a copy of the GNU General Public License
-along with Iter Vehemens ad Necem; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Iter Vehemens ad Necem; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The GNU General Public License can be found in the file `COPYING' in
-this release.
+this release.
+
+The thirdparty components bundled with the IVAN.app are:
+
+* libpcre.dylib: uses the BSD-3-clause license
+* libpng.dylib: uses the zlib license
+* SDL2.framework and SDL2_mixer.framework: use the zlib license
+
+The verbatim copy of their licenses are provided below and they do not conflict
+with the license of Iter Vehemens ad Necem. Each of them start after the line
+`LICENSE of ':
+
+LICENCE of libpcre.dylib
+------------------------
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * 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.
+
+ * Neither the name of the University of Cambridge nor the name of Google
+ Inc. nor the names of their 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 AND CONTRIBUTORS "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 OWNER OR CONTRIBUTORS 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.
+
+LICENCE of libpng.dylib
+-----------------------
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+This code is released under the libpng license.
+
+libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
+derived from libpng-1.0.6, and are distributed according to the same
+disclaimer and license as libpng-1.0.6 with the following individuals
+added to the list of Contributing Authors:
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Mans Rullgard
+ Cosmin Truta
+ Gilles Vollant
+ James Yu
+ Mandar Sahastrabuddhe
+ Google Inc.
+ Vadim Barkov
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+Some files in the "contrib" directory and some configure-generated
+files that are distributed with libpng have other copyright owners and
+are released under other open source licenses.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
+libpng-0.96, and are distributed according to the same disclaimer and
+license as libpng-0.96, with the following individuals added to the list
+of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
+and are distributed according to the same disclaimer and license as
+libpng-0.88, with the following individuals added to the list of
+Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+Some files in the "scripts" directory have other copyright owners
+but are released under this license.
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented.
+
+ 2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+ 3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE.
+
+TRADEMARK:
+
+The name "libpng" has not been registered by the Copyright owner
+as a trademark in any jurisdiction. However, because libpng has
+been distributed and maintained world-wide, continually since 1995,
+the Copyright owner claims "common-law trademark protection" in any
+jurisdiction where common-law trademark is recognized.
+
+OSI CERTIFICATION:
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is
+a certification mark of the Open Source Initiative. OSI has not addressed
+the additional disclaimers inserted at version 1.0.7.
+
+EXPORT CONTROL:
+
+The Copyright owner believes that the Export Control Classification
+Number (ECCN) for libpng is EAR99, which means not subject to export
+controls or International Traffic in Arms Regulations (ITAR) because
+it is open source, publicly available software, that does not contain
+any encryption software. See the EAR, paragraphs 734.3(b)(3) and
+734.7(b).
+
+Glenn Randers-Pehrson
+glennrp at users.sourceforge.net
+September 29, 2017
+
+LICENSE of SDL2.framework and SDL2_mixer.framework
+--------------------------------------------------
+
+Simple DirectMedia Layer
+Copyright (C) 1997-2018 Sam Lantinga
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any damages
+arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
diff --git a/Main/CMakeLists.txt b/Main/CMakeLists.txt
index bc34ab12d..ed9506a38 100644
--- a/Main/CMakeLists.txt
+++ b/Main/CMakeLists.txt
@@ -1,22 +1,34 @@
+include(FindPkgConfig)
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(PCRE libpcre)
+ set(PCRE_LIBRARIES ${PCRE_LDFLAGS})
+endif()
+if(NOT PCRE_FOUND)
+ find_package(PCRE REQUIRED)
+ add_definitions(${PCRE_DEFINITIONS})
+endif()
+
+find_package(SDL2 REQUIRED)
+
file(GLOB IVAN_SOURCES Include/*.h Source/*.cpp)
# The following files are #included from other .cpp files and so shouldn't be
# compiled directly. Setting the HEADER_FILE_ONLY property to TRUE prevents it.
set_source_files_properties(
- Source/action.cpp Source/actions.cpp Source/area.cpp Source/bodypart.cpp
- Source/char.cpp Source/cont.cpp Source/database.cpp Source/entity.cpp
- Source/fluid.cpp Source/gear.cpp Source/god.cpp Source/gods.cpp
- Source/human.cpp Source/item.cpp Source/level.cpp Source/lsquare.cpp
- Source/lterra.cpp Source/lterras.cpp Source/materia.cpp Source/materias.cpp
- Source/miscitem.cpp Source/nonhuman.cpp Source/pool.cpp Source/proto.cpp
- Source/rain.cpp Source/room.cpp Source/rooms.cpp Source/slot.cpp
- Source/smoke.cpp Source/square.cpp Source/stack.cpp Source/team.cpp
- Source/terra.cpp Source/trap.cpp Source/traps.cpp Source/worldmap.cpp
- Source/wsquare.cpp Source/wterra.cpp Source/wterras.cpp
+ Source/action.cpp Source/actions.cpp Source/area.cpp Source/bodypart.cpp
+ Source/char.cpp Source/cont.cpp Source/database.cpp Source/entity.cpp
+ Source/fluid.cpp Source/gear.cpp Source/god.cpp Source/gods.cpp
+ Source/human.cpp Source/item.cpp Source/level.cpp Source/lsquare.cpp
+ Source/lterra.cpp Source/lterras.cpp Source/materia.cpp Source/materias.cpp
+ Source/miscitem.cpp Source/nonhuman.cpp Source/pool.cpp Source/proto.cpp
+ Source/rain.cpp Source/room.cpp Source/rooms.cpp Source/slot.cpp
+ Source/smoke.cpp Source/square.cpp Source/stack.cpp Source/team.cpp
+ Source/terra.cpp Source/trap.cpp Source/traps.cpp Source/worldmap.cpp
+ Source/wsquare.cpp Source/wterra.cpp Source/wterras.cpp Source/hiteffect.cpp
PROPERTIES HEADER_FILE_ONLY TRUE)
add_executable(ivan ${IVAN_SOURCES} Resource/Ivan.rc)
-target_include_directories(ivan PUBLIC Include ../Felib/Include ../audio)
-target_link_libraries(ivan FeLib FeAudio)
+target_include_directories(ivan PUBLIC Include ../Felib/Include ../audio ../fantasyname ${PCRE_INCLUDE_DIRS} ${SDL2_mixer_INCLUDE_DIR})
+target_link_libraries(ivan FeLib FeAudio xbrzscale fantasyname ${PCRE_LIBRARIES} ${SDL2_mixer_LIBRARY})
if(UNIX)
install(TARGETS ivan DESTINATION "${CMAKE_INSTALL_BINDIR}")
diff --git a/Main/Include/area.h b/Main/Include/area.h
index 6b24fbcba..7cb37a36a 100644
--- a/Main/Include/area.h
+++ b/Main/Include/area.h
@@ -45,6 +45,8 @@ class area
truth IsValidPos(int X, int Y) const { return X >= 0 && Y >= 0 && X < XSize && Y < YSize; }
const rect& GetBorder() const { return Border; }
void SetEntryPos(int, v2);
+ static v2 getTopLeftCorner(); //this is equal to camera screen coordinates tho
+ static int getOutlineThickness(); //TODO this should be more global...
protected:
square*** Map;
uchar** FlagMap;
@@ -52,6 +54,8 @@ class area
ulong XSizeTimesYSize;
rect Border;
std::map EntryMap;
+ static v2 topLeftCorner;
+ static int iOutlineThickness;
};
#endif
diff --git a/Main/Include/bodypart.h b/Main/Include/bodypart.h
index 017d1c2c8..4ee387d2d 100644
--- a/Main/Include/bodypart.h
+++ b/Main/Include/bodypart.h
@@ -111,6 +111,7 @@ ITEM(bodypart, item)
virtual int GetSpecialFlags() const;
virtual truth IsRepairable(ccharacter*) const;
truth IsWarm() const;
+ truth IsWarmBlooded() const;
truth UseMaterialAttributes() const;
truth CanRegenerate() const;
virtual square* GetSquareUnder(int = 0) const;
@@ -126,6 +127,8 @@ ITEM(bodypart, item)
virtual void UpdatePictures();
item* GetExternalBodyArmor() const;
item* GetExternalCloak() const;
+ item* GetExternalHelmet() const;
+ item* GetExternalBelt() const;
virtual void ReceiveAcid(material*, cfestring&, long);
virtual truth ShowFluids() const { return false; }
virtual void TryToRust(long);
@@ -228,6 +231,8 @@ ITEM(head, bodypart)
virtual int GetEquipments() const { return 2; }
int GetBaseBiteStrength() const { return BaseBiteStrength; }
void SetBaseBiteStrength(long What) { BaseBiteStrength = What; }
+ int GetBonusBiteStrength() const { return BonusBiteStrength; }
+ void SetBonusBiteStrength(long What) { BonusBiteStrength = What; }
virtual void CalculateDamage();
virtual void CalculateToHitValue();
virtual void CalculateAPCost();
@@ -235,11 +240,13 @@ ITEM(head, bodypart)
virtual head* Behead();
virtual item* GetArmorToReceiveFluid(truth) const;
virtual void SignalPossibleUsabilityChange();
+ virtual truth IsHelmet(ccharacter*) const { return true; }
protected:
void UpdateHeadArmorPictures(graphicdata&) const;
gearslot HelmetSlot;
gearslot AmuletSlot;
int BaseBiteStrength;
+ int BonusBiteStrength;
double BiteToHitValue;
double BiteDamage;
long BiteAPCost;
@@ -344,6 +351,8 @@ ITEM(arm, bodypart)
virtual void SignalEquipmentAdd(gearslot*);
virtual void SignalEquipmentRemoval(gearslot*, citem*);
void ApplyDexterityPenalty(item*);
+ void ApplyStrengthBonus(item*);
+ void ApplyDexterityBonus(item*);
virtual truth DamageArmor(character*, int, int);
truth CheckIfWeaponTooHeavy(cchar*) const;
virtual truth EditAllAttributes(int);
@@ -449,6 +458,8 @@ ITEM(leg, bodypart)
virtual void CalculateAttributeBonuses();
virtual void SignalEquipmentAdd(gearslot*);
void ApplyAgilityPenalty(item*);
+ void ApplyStrengthBonus(item*);
+ void ApplyAgilityBonus(item*);
virtual void SignalVolumeAndWeightChange();
virtual truth DamageArmor(character*, int, int);
virtual truth EditAllAttributes(int);
diff --git a/Main/Include/char.h b/Main/Include/char.h
index 0c8868d0f..0a860ab21 100644
--- a/Main/Include/char.h
+++ b/Main/Include/char.h
@@ -140,6 +140,7 @@ struct characterdatabase : public databasebase
int PoisonResistance;
int ElectricityResistance;
int AcidResistance;
+ int SoundResistance;
int ConsumeFlags;
long TotalVolume;
packv2 HeadBitmapPos;
@@ -176,6 +177,7 @@ struct characterdatabase : public databasebase
int BaseUnarmedStrength;
int BaseBiteStrength;
int BaseKickStrength;
+ int BonusBiteStrength;
int AttackStyle;
long ClassStates;
fearray Alias;
@@ -297,7 +299,7 @@ class character : public entity, public id
truth ReadItem(item*);
truth TestForPickup(item*) const;
void ThrowItem(int, item*);
- truth TryMove(v2, truth, truth);
+ truth TryMove(v2, truth, truth, truth* =NULL);
truth HasHeadOfElpuri() const;
truth HasGoldenEagleShirt() const;
truth HasEncryptedScroll() const;
@@ -333,6 +335,7 @@ class character : public entity, public id
virtual truth MoveRandomly();
void ReceiveNutrition(long);
void ReceiveOmmelUrine(long);
+ void ReceiveOmmelBlood(long);
void ReceivePepsi(long);
void ReceiveSchoolFood(long);
void Regenerate();
@@ -345,12 +348,12 @@ class character : public entity, public id
void FallTo(character*, v2);
truth CheckCannibalism(cmaterial*) const;
void ActivateTemporaryState(long What) { TemporaryState |= What; }
- void DeActivateTemporaryState(long What) { TemporaryState &= ~What; }
+ void DeActivateTemporaryState(long What);
void ActivateEquipmentState(long What) { EquipmentState |= What; }
void DeActivateEquipmentState(long What) { EquipmentState &= ~What; }
- truth TemporaryStateIsActivated(long What) const { return TemporaryState & What; }
+ truth TemporaryStateIsActivated(long What) const;
truth EquipmentStateIsActivated(long What) const { return EquipmentState & What; }
- truth StateIsActivated(long What) const { return TemporaryState & What || EquipmentState & What; }
+ truth StateIsActivated(long What) const;
truth LoseConsciousness(int, truth = false);
void SetTemporaryStateCounter(long, int);
void DeActivateVoluntaryAction(cfestring& = CONST_S(""));
@@ -434,11 +437,13 @@ class character : public entity, public id
virtual int GetEquipments() const { return 0; }
virtual sorter EquipmentSorter(int) const { return 0; }
virtual void SetEquipment(int, item*) { }
+ truth IsESPBlockedByEquipment () const;
void AddHealingLiquidConsumeEndMessage() const;
void AddSchoolFoodConsumeEndMessage() const;
void AddSchoolFoodHitMessage() const;
void AddOmmelConsumeEndMessage() const;
void AddPepsiConsumeEndMessage() const;
+ void AddCocaColaConsumeEndMessage() const;
void AddFrogFleshConsumeEndMessage() const;
void AddKoboldFleshConsumeEndMessage() const;
void AddKoboldFleshHitMessage() const;
@@ -447,6 +452,7 @@ class character : public entity, public id
void AddGrayUnicornConsumeEndMessage() const;
void AddWhiteUnicornConsumeEndMessage() const;
void AddOmmelBoneConsumeEndMessage() const;
+ void AddLiquidHorrorConsumeEndMessage() const;
void PrintInfo() const;
virtual item* SevereBodyPart(int, truth = false, stack* = 0);
virtual void IgniteBodyPart(int, int);
@@ -455,6 +461,7 @@ class character : public entity, public id
bodypart* CreateBodyPart(int, int = 0);
virtual truth EquipmentIsAllowed(int) const { return true; }
truth CanUseEquipment(int) const;
+ void MemorizeEquipedItems();
const database* GetDataBase() const { return DataBase; }
void SetParameters(int) { }
virtual double GetNaturalExperience(int) const;
@@ -483,6 +490,7 @@ class character : public entity, public id
DATA_BASE_VALUE(int, PoisonResistance);
DATA_BASE_VALUE(int, ElectricityResistance);
DATA_BASE_VALUE(int, AcidResistance);
+ DATA_BASE_VALUE(int, SoundResistance);
DATA_BASE_VALUE(int, ConsumeFlags);
DATA_BASE_VALUE(long, TotalVolume);
virtual DATA_BASE_VALUE(v2, HeadBitmapPos);
@@ -522,6 +530,7 @@ class character : public entity, public id
DATA_BASE_VALUE(int, BaseUnarmedStrength);
DATA_BASE_VALUE(int, BaseBiteStrength);
DATA_BASE_VALUE(int, BaseKickStrength);
+ DATA_BASE_VALUE(int, BonusBiteStrength);
DATA_BASE_VALUE(int, AttackStyle);
DATA_BASE_TRUTH(CanUseEquipment);
DATA_BASE_TRUTH(CanKick);
@@ -610,6 +619,7 @@ class character : public entity, public id
DATA_BASE_VALUE(const fearray&, AllowedDungeons);
int GetType() const { return GetProtoType()->GetIndex(); }
void TeleportRandomly(truth = false);
+ void DoDetecting();
truth TeleportNear(character*);
virtual void InitSpecialAttributes() { }
virtual void Kick(lsquare*, int, truth = false) = 0;
@@ -653,6 +663,12 @@ class character : public entity, public id
void PrintEndSearchingMessage() const;
void PrintBeginHiccupsMessage() const;
void PrintEndHiccupsMessage() const;
+ void PrintBeginVampirismMessage() const;
+ void PrintEndVampirismMessage() const;
+ void PrintBeginFearlessMessage() const;
+ void PrintEndFearlessMessage() const;
+ void PrintBeginFastingMessage() const;
+ void PrintEndFastingMessage() const;
void EndPolymorph();
character* ForceEndPolymorph();
void LycanthropyHandler();
@@ -667,6 +683,9 @@ class character : public entity, public id
void HiccupsHandler();
void BeginEthereality();
void EndEthereality();
+ void BeginSwimming();
+ void EndSwimming();
+ void VampirismHandler();
character* PolymorphRandomly(int, int, int);
virtual truth EquipmentEasilyRecognized(int) const { return true; }
void StartReading(item*, long);
@@ -681,6 +700,8 @@ class character : public entity, public id
void PrintEndESPMessage() const;
void PrintBeginEtherealityMessage() const;
void PrintEndEtherealityMessage() const;
+ void PrintBeginSwimmingMessage() const;
+ void PrintEndSwimmingMessage() const;
truth CanBeSeenByPlayer(truth = false, truth = false) const;
truth CanBeSeenBy(ccharacter*, truth = false, truth = false) const;
void AttachBodyPart(bodypart*);
@@ -692,6 +713,7 @@ class character : public entity, public id
void PrintBeginPoisonedMessage() const;
void PrintEndPoisonedMessage() const;
truth IsWarm() const;
+ truth IsWarmBlooded() const;
void CalculateEquipmentState();
void Draw(blitdata&) const;
virtual void DrawBodyParts(blitdata&) const;
@@ -700,11 +722,24 @@ class character : public entity, public id
void PrintBeginTeleportMessage() const;
void PrintEndTeleportMessage() const;
void TeleportHandler();
+ void PrintBeginDetectMessage() const;
+ void PrintEndDetectMessage() const;
+ void DetectHandler();
void PrintEndTeleportControlMessage() const;
void PrintBeginTeleportControlMessage() const;
void PolymorphHandler();
void PrintEndPolymorphMessage() const;
void PrintBeginPolymorphMessage() const;
+ void PrintBeginPolymorphLockMessage() const;
+ void PrintEndPolymorphLockMessage() const;
+ void PolymorphLockHandler();
+ void PrintBeginRegenerationMessage() const;
+ void PrintEndRegenerationMessage() const;
+ void PrintBeginDiseaseImmunityMessage() const;
+ void PrintEndDiseaseImmunityMessage() const;
+ void PrintBeginTeleportLockMessage() const;
+ void PrintEndTeleportLockMessage() const;
+ void TeleportLockHandler();
virtual void DisplayStethoscopeInfo(character*) const;
virtual truth CanUseStethoscope(truth) const;
virtual truth IsUsingArms() const;
@@ -717,6 +752,7 @@ class character : public entity, public id
virtual lsquare* GetNeighbourLSquare(int) const;
virtual wsquare* GetNeighbourWSquare(int) const;
stack* GetStackUnder(int I = 0) const { return static_cast(GetSquareUnder(I))->GetStack(); }
+ stack* GetStackUnderSafely() const;
square* GetNearSquare(v2 Pos) const { return GetSquareUnder()->GetArea()->GetSquare(Pos); }
square* GetNearSquare(int x, int y) const { return GetSquareUnder()->GetArea()->GetSquare(x, y); }
lsquare* GetNearLSquare(v2 Pos) const { return static_cast(GetSquareUnder()->GetArea()->GetSquare(Pos)); }
@@ -724,7 +760,9 @@ class character : public entity, public id
wsquare* GetNearWSquare(v2) const;
wsquare* GetNearWSquare(int, int) const;
v2 GetPos(int I = 0) const { return GetSquareUnder(I)->GetPos(); }
+ v2 GetPosSafely() const;
square* GetSquareUnder(int I = 0) const { return !MotherEntity ? SquareUnder[I] : MotherEntity->GetSquareUnderEntity(I); }
+ square* GetSquareUnderSafely() const;
virtual square* GetSquareUnderEntity(int I = 0) const { return GetSquareUnder(I); }
lsquare* GetLSquareUnder(int I = 0) const { return static_cast(GetSquareUnder(I)); }
int GetRandomNonVitalBodyPart() const;
@@ -744,6 +782,7 @@ class character : public entity, public id
void CalculateMaxHP();
int GetHP() const { return HP; }
int GetMaxHP() const { return MaxHP; }
+ int GetTotalCharacterWeight() const;
void CalculateBodyPartMaxHPs(ulong = MAY_CHANGE_HPS|CHECK_USABILITY);
truth IsInitializing() const { return Flags & C_INITIALIZING; }
truth IsInNoMsgMode() const { return Flags & C_IN_NO_MSG_MODE; }
@@ -770,12 +809,12 @@ class character : public entity, public id
virtual void CreateBlockPossibilityVector(blockvector&, double) const { }
virtual truth SpecialUnarmedEffect(character*, v2, int, int, truth) { return false; }
virtual truth SpecialKickEffect(character*, v2, int, int, truth) { return false; }
- virtual truth SpecialBiteEffect(character*, v2, int, int, truth) { return false; }
- truth HitEffect(character*, item*, v2, int, int, int, truth);
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int) { return false; }
+ truth HitEffect(character*, item*, v2, int, int, int, truth, truth, int);
void WeaponSkillHit(item*, int, int);
character* Duplicate(ulong = 0);
room* GetRoom(int I = 0) const { return GetLSquareUnder(I)->GetRoom(); }
- truth TryToEquip(item*);
+ truth TryToEquip(item*, truth onlyIfEmpty=false, int onlyAt=-1);
truth TryToConsume(item*);
void UpdateESPLOS() const;
int GetCWeaponSkillLevel(citem*) const;
@@ -836,6 +875,9 @@ class character : public entity, public id
void PrintBeginParasitizedMessage() const;
void PrintEndParasitizedMessage() const;
void ParasitizedHandler();
+ void PrintBeginMindwormedMessage() const;
+ void PrintEndMindwormedMessage() const;
+ void MindwormedHandler();
truth CanFollow() const;
truth LeftOversAreUnique() const;
virtual festring GetKillName() const;
@@ -866,6 +908,7 @@ class character : public entity, public id
void PrintBeginGasImmunityMessage() const;
void PrintEndGasImmunityMessage() const;
void ShowAdventureInfo() const;
+ void ShowAdventureInfoAlt() const;
virtual truth BoundToUse(citem*, int) const { return false; }
virtual truth IsBananaGrower() const { return false; }
virtual int GetRandomApplyBodyPart() const;
@@ -960,7 +1003,7 @@ class character : public entity, public id
item* SearchForItem(ccharacter*, sorter) const;
virtual character* CreateZombie() const { return 0; }
virtual festring GetZombieDescription() const;
- virtual festring GetSpiritDescription() const;
+ virtual festring GetGhostDescription() const;
virtual truth CanAttack() const { return true; }
truth DetectMaterial(cmaterial*) const;
truth CheckIfTooScaredToHit(ccharacter*) const;
@@ -1073,6 +1116,7 @@ class character : public entity, public id
int GetRandomBodyPart(ulong = ALL_BODYPART_FLAGS) const;
virtual truth CanChokeOnWeb(web*) const { return CanChoke(); }
virtual truth BrainsHurt() const { return false; }
+ virtual truth IsHeadless() const { return false; }
truth IsSwimming() const;
truth IsAnimated() const;
virtual truth IsPlayerKind() const { return false; }
@@ -1097,10 +1141,11 @@ class character : public entity, public id
item* GiveMostExpensiveItem(character*);
void ReceiveItemAsPresent(item*);
item* FindMostExpensiveItem() const;
- void ReceiveSirenSong(character* Siren);
+ truth ReceiveSirenSong(character* Siren);
character* GetNearestEnemy() const;
truth IsInfectedByMindWorm() const { return !CounterToMindWormHatch; }
void SetCounterToMindWormHatch(int What) { CounterToMindWormHatch = What; }
+ int GetCounterToMindWormHatch() const { return CounterToMindWormHatch; }
truth MindWormCanPenetrateSkull(mindworm*) const;
truth CanTameWithDulcis(const character*) const;
truth CanTameWithLyre(const character*) const;
@@ -1115,6 +1160,8 @@ class character : public entity, public id
void SignalBurn();
void Extinguish(truth);
truth IsBurnt() const;
+ truth IsPlayerAutoPlay();
+ truth CheckAIZapOpportunity();
protected:
static truth DamageTypeDestroysBodyPart(int);
virtual void LoadSquaresUnder();
@@ -1144,6 +1191,20 @@ class character : public entity, public id
void StandIdleAI();
virtual void CreateCorpse(lsquare*);
void GetPlayerCommand();
+
+ truth AutoPlayAICommand(int&);
+ static void AutoPlayAIDebugDrawSquareRect(v2 v2SqrPos, col16 color, int iPrintIndex=-1, bool bWide=false, bool bKeepColor=false);
+ static void AutoPlayAIDebugDrawOverlay();
+ static bool AutoPlayAICheckAreaLevelChangedAndReset();
+ truth AutoPlayAIDropThings();
+ truth AutoPlayAIEquipAndPickup(bool bPlayerHasLantern);
+ int AutoPlayAIFindWalkDist(v2 v2To);
+ truth AutoPlayAITestValidPathTo(v2 v2To);
+ truth AutoPlayAINavigateDungeon(bool bPlayerHasLantern);
+ truth AutoPlayAISetAndValidateKeepGoingTo(v2 v2KGTo);
+ void AutoPlayAITeleport(bool bDeathCountBased);
+ void AutoPlayAIReset(bool bFailedToo);
+
virtual void GetAICommand();
truth MoveTowardsTarget(truth);
virtual cchar* FirstPersonUnarmedHitVerb() const;
@@ -1224,6 +1285,8 @@ class character : public entity, public id
trapdata* TrapData;
expmodifiermap ExpModifierMap;
int CounterToMindWormHatch;
+ ulong MemorizedEquippedItemIDs[MAX_EQUIPMENT_SLOTS];
+ v2 v2HoldPos;
virtual truth NeedsBurningPostFix() const { return false; }
};
diff --git a/Main/Include/command.h b/Main/Include/command.h
index 58e340764..3cd6e0a4b 100644
--- a/Main/Include/command.h
+++ b/Main/Include/command.h
@@ -40,6 +40,9 @@ class commandsystem
{
public:
static command* GetCommand(int I) { return Command[I]; }
+ static truth IsForRegionListItem(int iIndex);
+ static truth IsForRegionSilhouette(int iIndex);
+ static void PlayerDiedLookMode(bool bSeeWholeMapCheatMode=false);
private:
static truth Apply(character*);
static truth Close(character*);
@@ -72,6 +75,7 @@ class commandsystem
static truth Zap(character*);
static truth Rest(character*);
static truth Sit(character*);
+ static truth ShowMap(character*);
static truth Go(character*);
static truth ShowConfigScreen(character*);
static truth ScrollMessagesDown(character*);
@@ -83,6 +87,7 @@ class commandsystem
static truth Consume(character*, cchar*, cchar*, sorter, truth = false);
#ifdef WIZARD
static truth WizardMode(character*);
+ static truth AutoPlay(character* Char);
static truth RaiseStats(character*);
static truth LowerStats(character*);
static truth SeeWholeMap(character*);
diff --git a/Main/Include/confdef.h b/Main/Include/confdef.h
index cc99a64b1..0c64a0cb5 100644
--- a/Main/Include/confdef.h
+++ b/Main/Include/confdef.h
@@ -20,190 +20,420 @@
#define SOLID_ID (1 << 12)
#define VALPURIUM (SOLID_ID + 1)
-#define GRAVEL (SOLID_ID + 2)
-#define MORAINE (SOLID_ID + 3)
-#define OCTIRON (SOLID_ID + 4)
-#define GLASS (SOLID_ID + 5)
-#define PARCHMENT (SOLID_ID + 6)
-#define CLOTH (SOLID_ID + 7)
-#define MITHRIL (SOLID_ID + 8)
-#define MARBLE (SOLID_ID + 9)
-#define GOLD (SOLID_ID + 10)
-#define GRASS (SOLID_ID + 11)
-#define LEATHER (SOLID_ID + 12)
-#define LEAF (SOLID_ID + 13)
-#define FABRIC (SOLID_ID + 14)
-#define PALM_LEAF (SOLID_ID + 15)
-#define SULFUR (SOLID_ID + 16)
-#define UNICORN_HORN (SOLID_ID + 17)
-#define DIAMOND (SOLID_ID + 18)
-#define SILVER (SOLID_ID + 19)
-#define SAPPHIRE (SOLID_ID + 20)
-#define RUBY (SOLID_ID + 21)
-#define BRONZE (SOLID_ID + 22)
-#define COPPER (SOLID_ID + 23)
-#define TIN (SOLID_ID + 24)
-#define SPIDER_SILK (SOLID_ID + 25)
-#define KEVLAR (SOLID_ID + 26)
-#define OMMEL_HAIR (SOLID_ID + 27)
-#define HARDENED_LEATHER (SOLID_ID + 28)
-#define TROLL_HIDE (SOLID_ID + 29)
-#define NYMPH_HAIR (SOLID_ID + 30)
-#define ANGEL_HAIR (SOLID_ID + 31)
-#define PHOENIX_FEATHER (SOLID_ID + 32)
-#define GOLDEN_EAGLE_FEATHER (SOLID_ID + 33)
-#define ICE (SOLID_ID + 34)
-#define DRAGON_HIDE (SOLID_ID + 35)
-#define ARCANITE (SOLID_ID + 36)
-#define ILLITHIUM (SOLID_ID + 37)
-#define BALSA_WOOD (SOLID_ID + 38)
-#define PINE_WOOD (SOLID_ID + 39)
-#define FIR_WOOD (SOLID_ID + 40)
-#define BIRCH_WOOD (SOLID_ID + 41)
-#define OAK_WOOD (SOLID_ID + 42)
-#define TEAK_WOOD (SOLID_ID + 43)
-#define EBONY_WOOD (SOLID_ID + 44)
-#define BLUE_CRYSTAL (SOLID_ID + 45)
-#define PURPLE_CRYSTAL (SOLID_ID + 46)
-#define GREEN_CRYSTAL (SOLID_ID + 47)
-#define SAND_STONE (SOLID_ID + 48)
-#define LIME_STONE (SOLID_ID + 49)
-#define CALCITE (SOLID_ID + 50)
-#define OBSIDIAN (SOLID_ID + 51)
-#define GNEISS (SOLID_ID + 52)
-#define SLATE (SOLID_ID + 53)
-#define GRANITE (SOLID_ID + 54)
-#define BASALT (SOLID_ID + 55)
-#define MILKY_QUARTZ (SOLID_ID + 56)
-#define FLINT (SOLID_ID + 57)
-#define QUARTZITE (SOLID_ID + 58)
-#define AMETHYST (SOLID_ID + 59)
-#define CITRINE (SOLID_ID + 60)
-#define ROSE_QUARTZ (SOLID_ID + 61)
-#define JASPER (SOLID_ID + 62)
-#define ROCK_CRYSTAL (SOLID_ID + 63)
-#define DARK_GRASS (SOLID_ID + 64)
-#define LEAD (SOLID_ID + 65)
-#define BLACK_GRANITE (SOLID_ID + 66)
+#define TIN (SOLID_ID + 2)
+#define COPPER (SOLID_ID + 3)
+#define BRONZE (SOLID_ID + 4)
+#define VERDIGRIS (SOLID_ID + 5)
+#define DEEP_BRONZE (SOLID_ID + 6)
+#define BRASS (SOLID_ID + 7)
+#define HEPATIZON (SOLID_ID + 8)
+#define OCTIRON (SOLID_ID + 9)
+#define ORICHALCUM (SOLID_ID + 10)
+#define SILVER (SOLID_ID + 11)
+#define MOON_SILVER (SOLID_ID + 12)
+#define FAIRY_STEEL (SOLID_ID + 13)
+#define MITHRIL (SOLID_ID + 14)
+#define GALVORN (SOLID_ID + 15)
+#define STAR_METAL (SOLID_ID + 16)
+#define PLATINUM (SOLID_ID + 17)
+#define LEAD (SOLID_ID + 18)
+#define GOLD (SOLID_ID + 19)
+#define DARK_GOLD (SOLID_ID + 20)
+#define DARK_MATTER (SOLID_ID + 21)
+#define PETRIFIED_DARK (SOLID_ID + 22)
+#define ELECTRUM (SOLID_ID + 23)
+#define ALUMINIUM (SOLID_ID + 24)
+#define NICKEL (SOLID_ID + 25)
+#define COBALT (SOLID_ID + 26)
+#define TUNGSTEN (SOLID_ID + 27)
+#define IRIDIUM (SOLID_ID + 28)
+#define PALLADIUM (SOLID_ID + 29)
+#define CHROME (SOLID_ID + 30)
+#define TITANITE (SOLID_ID + 31)
+#define LINEN_CLOTH (SOLID_ID + 32)
+#define HEMP_CLOTH (SOLID_ID + 33)
+#define WOOL_CLOTH (SOLID_ID + 34)
+#define FELT (SOLID_ID + 35)
+#define FABRIC (SOLID_ID + 36)
+#define ELF_CLOTH (SOLID_ID + 37)
+#define NYMPH_HAIR (SOLID_ID + 38)
+#define OMMEL_HAIR (SOLID_ID + 39)
+#define TROLL_WOOL (SOLID_ID + 40)
+#define ANGEL_HAIR (SOLID_ID + 41)
+#define SPIDER_SILK (SOLID_ID + 42)
+#define GOSSAMER (SOLID_ID + 43)
+#define SPIRIT_CLOTH (SOLID_ID + 44)
+#define HUMAN_SKIN (SOLID_ID + 45)
+#define WOLF_SKIN (SOLID_ID + 46)
+#define BEAR_SKIN (SOLID_ID + 47)
+#define SNAKE_SKIN (SOLID_ID + 48)
+#define CROCODILE_SKIN (SOLID_ID + 49)
+#define BASILISK_SKIN (SOLID_ID + 50)
+#define NAGA_SKIN (SOLID_ID + 51)
+#define WYVERN_HIDE (SOLID_ID + 52)
+#define HYDRA_HIDE (SOLID_ID + 53)
+#define LEATHER (SOLID_ID + 54)
+#define BLACK_LEATHER (SOLID_ID + 55)
+#define HARDENED_LEATHER (SOLID_ID + 56)
+#define BOILED_LEATHER (SOLID_ID + 57)
+#define QUILTED_LEATHER (SOLID_ID + 58)
+#define STUDDED_LEATHER (SOLID_ID + 59)
+#define TROLL_HIDE (SOLID_ID + 60)
+#define IMP_HIDE (SOLID_ID + 61)
+#define DRAGON_HIDE (SOLID_ID + 62)
+#define OUROBOROS_HIDE (SOLID_ID + 63)
+#define OSTRICH_FEATHER (SOLID_ID + 64)
+#define HARPY_FEATHER (SOLID_ID + 65)
+#define GRIFFON_FEATHER (SOLID_ID + 66)
+#define PHOENIX_FEATHER (SOLID_ID + 67)
+#define STYMPHALIAN_FEATHER (SOLID_ID + 68)
+#define GOLDEN_EAGLE_FEATHER (SOLID_ID + 69)
+#define SEA_WEED (SOLID_ID + 70)
+#define FISH_SCALE (SOLID_ID + 71)
+#define MERMAID_HAIR (SOLID_ID + 72)
+#define SELKIE_SKIN (SOLID_ID + 73)
+#define SEA_SERPENT_SCALE (SOLID_ID + 74)
+#define KRAKEN_HIDE (SOLID_ID + 75)
+#define LEVIATHAN_HIDE (SOLID_ID + 76)
+#define DREAM_CLOTH (SOLID_ID + 77)
+#define RAINBOW_CLOTH (SOLID_ID + 78)
+#define SHADOW_CLOTH (SOLID_ID + 79)
+#define NYLON (SOLID_ID + 80)
+#define ELASTI_CLOTH (SOLID_ID + 81)
+#define ETEX_CLOTH (SOLID_ID + 82)
+#define SMART_CLOTH (SOLID_ID + 83)
+#define FLEXI_CLOTH (SOLID_ID + 84)
+#define KEVLAR (SOLID_ID + 85)
+#define SYNTH_CLOTH (SOLID_ID + 86)
+#define NANO_FIBER (SOLID_ID + 87)
+#define LATEX (SOLID_ID + 88)
+#define RUBBER (SOLID_ID + 89)
+#define PLASTIC (SOLID_ID + 90)
+#define HARDENED_PLASTIC (SOLID_ID + 91)
+#define STAINLESS_STEEL (SOLID_ID + 92)
+#define PLASTIC_STEEL (SOLID_ID + 93)
+#define DURALLOY (SOLID_ID + 94)
+#define VITRELLOY (SOLID_ID + 95)
+#define CHAR_COAL (SOLID_ID + 96)
+#define COAL (SOLID_ID + 97)
+#define JET (SOLID_ID + 98)
+#define CARBIDE (SOLID_ID + 99)
+#define FOLDED_CARBIDE (SOLID_ID + 100)
+#define FULLERITE (SOLID_ID + 101)
+#define URANIUM (SOLID_ID + 102)
+#define SOLARIUM (SOLID_ID + 103)
+#define NEUTRONIUM (SOLID_ID + 104)
+#define MAGIC_CRYSTAL (SOLID_ID + 105)
+#define ARCANITE (SOLID_ID + 106)
+#define OCCULTUM (SOLID_ID + 107)
+#define SAND_STONE (SOLID_ID + 108)
+#define RED_SAND_STONE (SOLID_ID + 109)
+#define GLASS (SOLID_ID + 110)
+#define PEARL_GLASS (SOLID_ID + 111)
+#define ILLITHIUM (SOLID_ID + 112)
+#define ICE (SOLID_ID + 113)
+#define RED_ICE (SOLID_ID + 114)
+#define JOTUN_ICE (SOLID_ID + 115)
+#define PRIMORDIAL_ICE (SOLID_ID + 116)
+#define GRASS (SOLID_ID + 117)
+#define DARK_GRASS (SOLID_ID + 118)
+#define MYCELIUM (SOLID_ID + 119)
+#define LEAF (SOLID_ID + 120)
+#define PALM_LEAF (SOLID_ID + 121)
+#define WITCH_BARK (SOLID_ID + 122)
+#define DARK_PETAL (SOLID_ID + 123)
+#define STEEL_LEAF (SOLID_ID + 124)
+#define CHLOROPHYTE (SOLID_ID + 125)
+#define PAPYRUS (SOLID_ID + 126)
+#define PARCHMENT (SOLID_ID + 127)
+#define VELLUM (SOLID_ID + 128)
+#define PAPER_BOARD (SOLID_ID + 129)
+#define FUNGI_WOOD (SOLID_ID + 130)
+#define SPRUCE_WOOD (SOLID_ID + 131)
+#define SYCAMORE_WOOD (SOLID_ID + 132)
+#define ELM_WOOD (SOLID_ID + 133)
+#define ASH_WOOD (SOLID_ID + 134)
+#define CYPRESS_WOOD (SOLID_ID + 135)
+#define HOLLY_WOOD (SOLID_ID + 136)
+#define YEW_WOOD (SOLID_ID + 137)
+#define BEECH_WOOD (SOLID_ID + 138)
+#define BAMBOO_WOOD (SOLID_ID + 139)
+#define MAHOGANY_WOOD (SOLID_ID + 140)
+#define BALSA_WOOD (SOLID_ID + 141)
+#define PINE_WOOD (SOLID_ID + 142)
+#define FIR_WOOD (SOLID_ID + 143)
+#define BIRCH_WOOD (SOLID_ID + 144)
+#define OAK_WOOD (SOLID_ID + 145)
+#define TEAK_WOOD (SOLID_ID + 146)
+#define EBONY_WOOD (SOLID_ID + 147)
+#define KAURI_WOOD (SOLID_ID + 148)
+#define RATA_WOOD (SOLID_ID + 149)
+#define SIDGURE_WOOD (SOLID_ID + 150)
+#define PETRIFIED_WOOD (SOLID_ID + 151)
+#define HUMAN_NAIL (SOLID_ID + 152)
+#define CHITINE (SOLID_ID + 153)
+#define BUFFALO_HORN (SOLID_ID + 154)
+#define MOOSE_ANTLER (SOLID_ID + 155)
+#define UNICORN_HORN (SOLID_ID + 156)
+#define TURTLE_SHELL (SOLID_ID + 157)
+#define SEA_SHELL (SOLID_ID + 158)
+#define DRAGON_BONE (SOLID_ID + 159)
+#define WAX (SOLID_ID + 160)
+#define GRAVEL (SOLID_ID + 161)
+#define MORAINE (SOLID_ID + 162)
+#define COBBLE_STONE (SOLID_ID + 163)
+#define LIME_STONE (SOLID_ID + 164)
+#define SHALE (SOLID_ID + 165)
+#define OBSIDIAN (SOLID_ID + 166)
+#define MARBLE (SOLID_ID + 167)
+#define BASALT (SOLID_ID + 168)
+#define JASPER (SOLID_ID + 169)
+#define JACINTH (SOLID_ID + 170)
+#define AGATE (SOLID_ID + 172)
+#define TOURMALINE (SOLID_ID + 173)
+#define CHALCEDONY (SOLID_ID + 174)
+#define CALCITE (SOLID_ID + 175)
+#define GNEISS (SOLID_ID + 176)
+#define SLATE (SOLID_ID + 177)
+#define GRANITE (SOLID_ID + 178)
+#define BLACK_GRANITE (SOLID_ID + 179)
+#define CHALK (SOLID_ID + 180)
+#define FLINT (SOLID_ID + 181)
+#define CITRINE (SOLID_ID + 182)
+#define LAPIS_LAZULI (SOLID_ID + 183)
+#define AMBER (SOLID_ID + 184)
+#define OPAL (SOLID_ID + 185)
+#define ONYX (SOLID_ID + 186)
+#define SLADE (SOLID_ID + 187)
+#define NACRE (SOLID_ID + 188)
+#define PEARL (SOLID_ID + 189)
+#define CORAL (SOLID_ID + 190)
+#define DEEP_CORAL (SOLID_ID + 191)
+#define HALCYON (SOLID_ID + 192)
+#define MILKY_QUARTZ (SOLID_ID + 193)
+#define QUARTZITE (SOLID_ID + 194)
+#define ROSE_QUARTZ (SOLID_ID + 195)
+#define NETHER_QUARTZ (SOLID_ID + 196)
+#define AMETHYST (SOLID_ID + 197)
+#define TOPAZ (SOLID_ID + 198)
+#define SAPPHIRE (SOLID_ID + 199)
+#define EMERALD (SOLID_ID + 200)
+#define RUBY (SOLID_ID + 201)
+#define DIAMOND (SOLID_ID + 202)
+#define BLACK_DIAMOND (SOLID_ID + 203)
+#define JADEITE (SOLID_ID + 204)
+#define MALACHITE (SOLID_ID + 205)
+#define NEPHRITE (SOLID_ID + 206)
+#define BLACK_JADE (SOLID_ID + 207)
+#define RED_JADE (SOLID_ID + 208)
+#define GREEN_JADE (SOLID_ID + 209)
+#define BLUE_JADE (SOLID_ID + 210)
+#define WHITE_JADE (SOLID_ID + 211)
+#define ROCK_CRYSTAL (SOLID_ID + 212)
+#define PURPLE_CRYSTAL (SOLID_ID + 213)
+#define BLUE_CRYSTAL (SOLID_ID + 214)
+#define GREEN_CRYSTAL (SOLID_ID + 215)
+#define SUN_CRYSTAL (SOLID_ID + 216)
+#define CONCRETE (SOLID_ID + 217)
+#define HARDENED_CONCRETE (SOLID_ID + 218)
+#define SUPER_CONCRETE (SOLID_ID + 219)
+#define SULFUR (SOLID_ID + 220)
+#define BRIM_STONE (SOLID_ID + 221)
+#define CLAY (SOLID_ID + 222)
+#define HARDENED_CLAY (SOLID_ID + 223)
+#define PORCELAIN (SOLID_ID + 224)
+#define ROCK_SALT (SOLID_ID + 225)
+#define AEGI_SALT (SOLID_ID + 226)
+#define ALABASTER (SOLID_ID + 227)
+#define HEMATITE (SOLID_ID + 228)
+#define PYRITE (SOLID_ID + 229)
+#define HARDENED_ASH (SOLID_ID + 230)
+#define PSYPHER (SOLID_ID + 231)
#define ORGANIC_ID (2 << 12)
-#define BANANA_FLESH (ORGANIC_ID + 1)
-#define SCHOOL_FOOD (ORGANIC_ID + 2)
+#define PLANT_FIBER (ORGANIC_ID + 1)
+#define MUTANT_PLANT_FIBER (ORGANIC_ID + 2)
#define BANANA_PEEL (ORGANIC_ID + 3)
-#define KIWI_FLESH (ORGANIC_ID + 4)
-#define PINEAPPLE_FLESH (ORGANIC_ID + 5)
-#define PLANT_FIBER (ORGANIC_ID + 6)
-#define MUTANT_PLANT_FIBER (ORGANIC_ID + 7)
-#define BONE (ORGANIC_ID + 8)
-#define BREAD (ORGANIC_ID + 9)
-#define HOLY_BANANA_FLESH (ORGANIC_ID + 10)
-#define CARROT_FLESH (ORGANIC_ID + 11)
-#define OMMEL_CERUMEN (ORGANIC_ID + 12)
-#define OMMEL_BONE (ORGANIC_ID + 13)
-#define OMMEL_TOOTH (ORGANIC_ID + 14)
+#define BANANA_FLESH (ORGANIC_ID + 4)
+#define HOLY_BANANA_FLESH (ORGANIC_ID + 5)
+#define KIWI_FLESH (ORGANIC_ID + 6)
+#define PINEAPPLE_FLESH (ORGANIC_ID + 7)
+#define CARROT_FLESH (ORGANIC_ID + 8)
+#define MANGO_FLESH (ORGANIC_ID + 9)
+#define KELP (ORGANIC_ID + 10)
+#define PLANKTON (ORGANIC_ID + 11)
+#define DARK_BREAD (ORGANIC_ID + 12)
+#define FLAT_BREAD (ORGANIC_ID + 13)
+#define RYE_BREAD (ORGANIC_ID + 14)
+#define BANANA_STOLLEN (ORGANIC_ID + 15)
+#define CHEESE (ORGANIC_ID + 16)
+#define CHOCOLATE (ORGANIC_ID + 17)
+#define SCHOOL_FOOD (ORGANIC_ID + 18)
+#define OMMEL_CERUMEN (ORGANIC_ID + 19)
+#define BONE (ORGANIC_ID + 20)
+#define WHALE_BONE (ORGANIC_ID + 21)
+#define WRAITH_BONE (ORGANIC_ID + 22)
+#define OMMEL_BONE (ORGANIC_ID + 23)
+#define SHARK_TOOTH (ORGANIC_ID + 24)
+#define TROLL_TUSK (ORGANIC_ID + 25)
+#define MAMMOTH_TUSK (ORGANIC_ID + 26)
+#define OMMEL_TOOTH (ORGANIC_ID + 27)
+#define RESIDUUM (ORGANIC_ID + 28)
#define GAS_ID (3 << 12)
#define AIR (GAS_ID + 1)
-#define MAGICAL_AIR (GAS_ID + 2)
-#define SMOKE (GAS_ID + 3)
-#define SKUNK_SMELL (GAS_ID + 4)
-#define GHOST (GAS_ID + 5)
-#define MAGIC_VAPOUR (GAS_ID + 6)
-#define EVIL_WONDER_STAFF_VAPOUR (GAS_ID + 7)
-#define GOOD_WONDER_STAFF_VAPOUR (GAS_ID + 8)
-#define FART (GAS_ID + 9)
-#define MUSTARD_GAS (GAS_ID + 10)
+#define VACUUM (GAS_ID + 2)
+#define ETHER (GAS_ID + 3)
+#define SMOKE (GAS_ID + 4)
+#define SKUNK_SMELL (GAS_ID + 5)
+#define ECTOPLASM (GAS_ID + 6)
+#define MAGIC_VAPOUR (GAS_ID + 7)
+#define EVIL_WONDER_STAFF_VAPOUR (GAS_ID + 8)
+#define GOOD_WONDER_STAFF_VAPOUR (GAS_ID + 9)
+#define FART (GAS_ID + 10)
+#define MUSTARD_GAS (GAS_ID + 11)
+#define SLEEPING_GAS (GAS_ID + 12)
#define LIQUID_ID (4 << 12)
-#define OMMEL_URINE (LIQUID_ID + 1)
-#define PEPSI (LIQUID_ID + 2)
-#define WATER (LIQUID_ID + 3)
-#define HEALING_LIQUID (LIQUID_ID + 4)
-#define BLOOD (LIQUID_ID + 5)
-#define BROWN_SLIME (LIQUID_ID + 6)
-#define POISON_LIQUID (LIQUID_ID + 7)
-#define VALDEMAR (LIQUID_ID + 8)
-#define ANTIDOTE_LIQUID (LIQUID_ID + 9)
-#define VODKA (LIQUID_ID + 10)
-#define TROLL_BLOOD (LIQUID_ID + 11)
-#define DARK_FROG_BLOOD (LIQUID_ID + 12)
-#define SPIDER_BLOOD (LIQUID_ID + 13)
-#define VOMIT (LIQUID_ID + 14)
-#define ACIDOUS_BLOOD (LIQUID_ID + 15)
-#define SULPHURIC_ACID (LIQUID_ID + 16)
-#define DOG_DROOL (LIQUID_ID + 17)
-#define PEA_SOUP (LIQUID_ID + 18)
-#define OMMEL_SWEAT (LIQUID_ID + 19)
-#define OMMEL_TEARS (LIQUID_ID + 20)
-#define OMMEL_SNOT (LIQUID_ID + 21)
-#define SWEAT (LIQUID_ID + 22)
-#define GLOWING_BLOOD (LIQUID_ID + 23)
-#define YELLOW_SLIME (LIQUID_ID + 24)
-#define SICK_BLOOD (LIQUID_ID + 25)
-#define MUSTARD_GAS_LIQUID (LIQUID_ID + 26)
+#define ANTIDOTE_LIQUID (LIQUID_ID + 1)
+#define CURE_ALL_LIQUID (LIQUID_ID + 2)
+#define HEALING_LIQUID (LIQUID_ID + 3)
+#define MAGIC_LIQUID (LIQUID_ID + 4)
+#define PEA_SOUP (LIQUID_ID + 5)
+#define CHICKEN_SOUP (LIQUID_ID + 6)
+#define PORRIDGE (LIQUID_ID + 7)
+#define CUSTARD (LIQUID_ID + 8)
+#define MILK (LIQUID_ID + 9)
+#define HONEY (LIQUID_ID + 10)
+#define COCA_COLA (LIQUID_ID + 11)
+#define INK (LIQUID_ID + 12)
+#define BRINE (LIQUID_ID + 13)
+#define WATER (LIQUID_ID + 14)
+#define VALDEMAR (LIQUID_ID + 15)
+#define VODKA (LIQUID_ID + 16)
+#define CIDER (LIQUID_ID + 17)
+#define WHITE_WINE (LIQUID_ID + 18)
+#define RED_WINE (LIQUID_ID + 19)
+#define BEER (LIQUID_ID + 20)
+#define ELF_ALE (LIQUID_ID + 21)
+#define DWARF_BEER (LIQUID_ID + 22)
+#define BROWN_SLIME (LIQUID_ID + 23)
+#define GREEN_SLIME (LIQUID_ID + 24)
+#define POISON_LIQUID (LIQUID_ID + 25)
+#define PEPSI (LIQUID_ID + 26)
+#define SULPHURIC_ACID (LIQUID_ID + 27)
+#define MUSTARD_GAS_LIQUID (LIQUID_ID + 28)
+#define LIQUID_DARKNESS (LIQUID_ID + 29)
+#define LIQUID_FEAR (LIQUID_ID + 30)
+#define ASPHALT (LIQUID_ID + 31)
+#define VOMIT (LIQUID_ID + 32)
+#define DOG_DROOL (LIQUID_ID + 33)
+#define SWEAT (LIQUID_ID + 34)
+#define BLOOD (LIQUID_ID + 35)
+#define GREEN_BLOOD (LIQUID_ID + 36)
+#define BLUE_BLOOD (LIQUID_ID + 37)
+#define PLANT_SAP (LIQUID_ID + 38)
+#define GLOWING_BLOOD (LIQUID_ID + 39)
+#define TROLL_BLOOD (LIQUID_ID + 40)
+#define DARK_FROG_BLOOD (LIQUID_ID + 41)
+#define SPIDER_BLOOD (LIQUID_ID + 42)
+#define ACIDOUS_BLOOD (LIQUID_ID + 43)
+#define SICK_BLOOD (LIQUID_ID + 44)
+#define LIGHT_FROG_BLOOD (LIQUID_ID + 45)
+#define OMMEL_BLOOD (LIQUID_ID + 46)
+#define OMMEL_URINE (LIQUID_ID + 47)
+#define OMMEL_SWEAT (LIQUID_ID + 48)
+#define OMMEL_TEARS (LIQUID_ID + 49)
+#define OMMEL_SNOT (LIQUID_ID + 50)
+#define MERCURY (LIQUID_ID + 51)
+#define QUICK_SILVER (LIQUID_ID + 52)
+#define MUD (LIQUID_ID + 53)
+#define QUICK_SAND (LIQUID_ID + 54)
#define FLESH_ID (5 << 12)
-#define GOBLINOID_FLESH (FLESH_ID + 1)
-#define PORK (FLESH_ID + 2)
-#define BEEF (FLESH_ID + 3)
-#define FROG_FLESH (FLESH_ID + 4)
-#define ELPURI_FLESH (FLESH_ID + 5)
-#define HUMAN_FLESH (FLESH_ID + 6)
-#define DOLPHIN_FLESH (FLESH_ID + 7)
-#define BEAR_FLESH (FLESH_ID + 8)
-#define WOLF_FLESH (FLESH_ID + 9)
-#define DOG_FLESH (FLESH_ID + 10)
-#define ENNER_BEAST_FLESH (FLESH_ID + 11)
-#define SPIDER_FLESH (FLESH_ID + 12)
-#define JACKAL_FLESH (FLESH_ID + 13)
-#define MUTANT_ASS_FLESH (FLESH_ID + 14)
-#define BAT_FLESH (FLESH_ID + 15)
-#define WERE_WOLF_FLESH (FLESH_ID + 16)
-#define KOBOLD_FLESH (FLESH_ID + 17)
-#define GIBBERLING_FLESH (FLESH_ID + 18)
-#define CAT_FLESH (FLESH_ID + 19)
-#define RAT_FLESH (FLESH_ID + 20)
-#define ANGEL_FLESH (FLESH_ID + 21)
-#define DWARF_FLESH (FLESH_ID + 22)
-#define DAEMON_FLESH (FLESH_ID + 23)
-#define MAMMOTH_FLESH (FLESH_ID + 24)
-#define BLACK_UNICORN_FLESH (FLESH_ID + 25)
-#define GRAY_UNICORN_FLESH (FLESH_ID + 26)
-#define WHITE_UNICORN_FLESH (FLESH_ID + 27)
-#define LION_FLESH (FLESH_ID + 28)
-#define BUFFALO_FLESH (FLESH_ID + 29)
-#define SNAKE_FLESH (FLESH_ID + 30)
-#define ORC_FLESH (FLESH_ID + 31)
-#define OSTRICH_FLESH (FLESH_ID + 32)
-#define CHAMELEON_FLESH (FLESH_ID + 33)
-#define FLOATING_EYE_FLESH (FLESH_ID + 34)
-#define MUSHROOM_FLESH (FLESH_ID + 35)
-#define MOOSE_FLESH (FLESH_ID + 36)
-#define MAGPIE_FLESH (FLESH_ID + 37)
-#define SKUNK_FLESH (FLESH_ID + 38)
-#define HEDGEHOG_FLESH (FLESH_ID + 39)
-#define MUTANT_BUNNY_FLESH (FLESH_ID + 40)
-#define HATTIFATTENER_FLESH (FLESH_ID + 41)
-#define BLINK_DOG_FLESH (FLESH_ID + 42)
-#define MAGIC_MUSHROOM_FLESH (FLESH_ID + 43)
-#define SICK_SPIDER_FLESH (FLESH_ID + 44)
+#define PORK (FLESH_ID + 1)
+#define BEEF (FLESH_ID + 2)
+#define VENISON (FLESH_ID + 3)
+#define MYSTERY_MEAT (FLESH_ID + 4)
+#define SNAKE_JERKY (FLESH_ID + 5)
+#define TUNA (FLESH_ID + 6)
+#define SARDINE (FLESH_ID + 7)
+#define GOBLINOID_FLESH (FLESH_ID + 8)
+#define FROG_FLESH (FLESH_ID + 9)
+#define ELPURI_FLESH (FLESH_ID + 10)
+#define HUMAN_FLESH (FLESH_ID + 11)
+#define DOLPHIN_FLESH (FLESH_ID + 12)
+#define BEAR_FLESH (FLESH_ID + 13)
+#define WOLF_FLESH (FLESH_ID + 14)
+#define DOG_FLESH (FLESH_ID + 15)
+#define ENNER_BEAST_FLESH (FLESH_ID + 16)
+#define SPIDER_FLESH (FLESH_ID + 17)
+#define JACKAL_FLESH (FLESH_ID + 18)
+#define MUTANT_ASS_FLESH (FLESH_ID + 19)
+#define BAT_FLESH (FLESH_ID + 20)
+#define WERE_WOLF_FLESH (FLESH_ID + 21)
+#define KOBOLD_FLESH (FLESH_ID + 22)
+#define GIBBERLING_FLESH (FLESH_ID + 23)
+#define CAT_FLESH (FLESH_ID + 24)
+#define RAT_FLESH (FLESH_ID + 25)
+#define ANGEL_FLESH (FLESH_ID + 26)
+#define DWARF_FLESH (FLESH_ID + 27)
+#define DAEMON_FLESH (FLESH_ID + 28)
+#define MAMMOTH_FLESH (FLESH_ID + 29)
+#define BLACK_UNICORN_FLESH (FLESH_ID + 30)
+#define GRAY_UNICORN_FLESH (FLESH_ID + 31)
+#define WHITE_UNICORN_FLESH (FLESH_ID + 32)
+#define LION_FLESH (FLESH_ID + 33)
+#define BUFFALO_FLESH (FLESH_ID + 34)
+#define SNAKE_FLESH (FLESH_ID + 35)
+#define ORC_FLESH (FLESH_ID + 36)
+#define OSTRICH_FLESH (FLESH_ID + 37)
+#define CHAMELEON_FLESH (FLESH_ID + 38)
+#define FLOATING_EYE_FLESH (FLESH_ID + 39)
+#define MUSHROOM_FLESH (FLESH_ID + 40)
+#define MOOSE_FLESH (FLESH_ID + 41)
+#define MAGPIE_FLESH (FLESH_ID + 42)
+#define SKUNK_FLESH (FLESH_ID + 43)
+#define HEDGEHOG_FLESH (FLESH_ID + 44)
+#define MUTANT_BUNNY_FLESH (FLESH_ID + 45)
+#define HATTIFATTENER_FLESH (FLESH_ID + 46)
+#define BLINK_DOG_FLESH (FLESH_ID + 47)
+#define MAGIC_MUSHROOM_FLESH (FLESH_ID + 48)
+#define SICK_SPIDER_FLESH (FLESH_ID + 49)
+#define MIND_WORM_FLESH (FLESH_ID + 50)
+#define VAMPIRE_FLESH (FLESH_ID + 51)
+#define ELF_FLESH (FLESH_ID + 52)
#define POWDER_ID (6 << 12)
#define GUN_POWDER (POWDER_ID + 1)
-#define SNOW (POWDER_ID + 2)
-#define SAND (POWDER_ID + 3)
+#define SALT (POWDER_ID + 2)
+#define SNOW (POWDER_ID + 3)
+#define SAND (POWDER_ID + 4)
+#define RED_SAND (POWDER_ID + 5)
+#define BLACK_SAND (POWDER_ID + 6)
+#define DIRT (POWDER_ID + 7)
+#define SOIL (POWDER_ID + 8)
+#define ASH (POWDER_ID + 9)
+#define SOOT (POWDER_ID + 10)
#define IRON_ALLOY_ID (7 << 12)
-#define IRON (IRON_ALLOY_ID + 1)
-#define STEEL (IRON_ALLOY_ID + 2)
-#define METEORIC_STEEL (IRON_ALLOY_ID + 3)
-#define ADAMANT (IRON_ALLOY_ID + 4)
+#define PIG_IRON (IRON_ALLOY_ID + 1)
+#define IRON (IRON_ALLOY_ID + 2)
+#define STEEL (IRON_ALLOY_ID + 3)
+#define DWARF_STEEL (IRON_ALLOY_ID + 4)
+#define METEORIC_STEEL (IRON_ALLOY_ID + 5)
+#define UKKU_STEEL (IRON_ALLOY_ID + 6)
+#define ADAMANT (IRON_ALLOY_ID + 7)
+#define BLACK_IRON (IRON_ALLOY_ID + 8)
+#define SOUL_STEEL (IRON_ALLOY_ID + 9)
+#define BLOOD_IRON (IRON_ALLOY_ID + 10)
+#define BLOOD_STEEL (IRON_ALLOY_ID + 11)
#define LONG_SWORD 1
#define TWO_HANDED_SWORD 2
@@ -221,6 +451,15 @@
#define SCYTHE 14
#define QUARTER_STAFF 15
#define HAMMER 16
+#define GRAND_STOLLEN_KNIFE 17
+#define MAGE_STAFF 18
+#define ROLLING_PIN 19
+#define FRYING_PAN 20
+#define CLAW 21
+#define MEAT_CLEAVER 22
+#define RUNE_SWORD 23
+
+#define PUPPY_SKULL 1
#define GOROVITS_HAMMER 1
#define GOROVITS_SICKLE 2
@@ -247,6 +486,8 @@
#define WAND_OF_ACID_RAIN 12
#define WAND_OF_MIRRORING 13
#define WAND_OF_NECROMANCY 14
+#define WAND_OF_WEBBING 15
+#define WAND_OF_ALCHEMY 16
#define RUNED_WHIP 1
@@ -299,6 +540,19 @@
#define BRAVERY 1
#define FEAR 2
+#define CONFUSION 3
+#define HEALING 4
+#define PLENTY 5
+
+#define POTTED_CACTUS 1
+#define POTTED_PLANT 2
+#define DEAD_FISH 3
+#define BONE_FISH 4
+#define SMALL_CLOCK 5
+#define LARGE_CLOCK 6
+
+#define IMPRISONED_FARMER 1
+#define CULTIST 2
#define ROOKIE 1
#define VETERAN 2
@@ -327,24 +581,41 @@
#define CONICAL 1
#define FLAT 2
+#define SKELETON_DOG 1
+
#define LARGE 1
#define GIANT 2
+#define ARANEA 3
+
+#define IMPRISONED_HUNTER 1
#define BLACK_BEAR 1
#define GRIZZLY_BEAR 2
#define CAVE_BEAR 3
#define POLAR_BEAR 4
+#define PANDA_BEAR 6
+
+#define IMPRISONED_FEMALE 1
+/* 2 reserved for ATTNAM */
+/* 3 reserved for NEW_ATTNAM */
+#define JESTER 4
#define ZOMBIE_OF_KHAZ_ZADM 1
+#define IMPRISONED_ZOMBIE 2
#define TORTURING_CHIEF 1
#define WHIP_CHAMPION 2
#define WAR_LADY 3
#define QUEEN 4
-#define CHIEFTAIN 1
-#define LORD 2
+#define DRUID 1
+
+#define HUNTER 2
#define PATRIARCH 3
+#define ASSASSIN 4
+#define MASTER_ASSASSIN 5
+
+#define LORD 1
#define GREATER 1
#define GIANT 2
@@ -354,6 +625,7 @@
#define OFFICER 3
#define GENERAL 4
#define MARSHAL 5
+#define REPRESENTATIVE 6
#define APPRENTICE 1
#define BATTLE_MAGE 2
@@ -378,6 +650,20 @@
#define BOY 1
#define GIRL 2
+#define LIGHT_ASIAN_SIREN 1
+#define DARK_ASIAN_SIREN 2
+#define CAUCASIAN_SIREN 3
+#define DARK_SIREN 4
+#define GREEN_SIREN 5
+#define BLUE_SIREN 6
+#define RED_SIREN 7
+#define PINK_SIREN 8
+#define HISPANIC_SIREN 9
+#define AMBASSADOR_SIREN 10
+
+#define HATCHLING 1
+#define BOIL 2
+
#define PARQUET 1
#define FLOOR 2
#define GROUND 3
@@ -404,19 +690,19 @@
#define HOLY_TREE 3
#define CARPET 4
#define COUCH 5
-#define DOUBLE_BED 6
-#define POOL_BORDER 7
-#define POOL_CORNER 8
-#define PALM 9
-#define SNOW_PINE 10
-#define SNOW_FIR 11
-#define ANVIL 12
-#define SHARD 13
-#define CACTUS 14
-#define OAK 15
-#define BIRCH 16
-#define TEAK 17
-#define DWARF_BIRCH 18
+#define DOUBLE_BED 9
+#define POOL_BORDER 13
+#define POOL_CORNER 14
+#define PALM 15
+#define SNOW_PINE 16
+#define SNOW_FIR 17
+#define ANVIL 18
+#define SHARD 19
+#define CACTUS 20
+#define OAK 21
+#define BIRCH 22
+#define TEAK 23
+#define DWARF_BIRCH 24
#define SNOW_BOULDER 4
diff --git a/Main/Include/definesvalidator.h b/Main/Include/definesvalidator.h
new file mode 100644
index 000000000..c26fb6fb0
--- /dev/null
+++ b/Main/Include/definesvalidator.h
@@ -0,0 +1,9165 @@
+/****
+ * AUTO-GENERATED CODE FILE, DO NOT MODIFY as modifications will be overwritten !!!
+ *
+ * After it is generated, update the one at source code path with it and
+ * recompile so the results on the abort message (if happens) will be updated !!!
+ */
+
+#ifndef _DEFINESVALIDATOR_H_
+#define _DEFINESVALIDATOR_H_
+
+class definesvalidator{ public: static void Validate() {
+
+ std::stringstream ssErrors;
+ std::bitset<32> bsA, bsB;
+
+
+#ifdef AC // DO NOT MODIFY!
+ bsA = 8;
+ bsB = AC;
+ if(bsA!=bsB)
+ ssErrors << "Defined AC with value 8 from .dat file mismatches hardcoded c++ define value of " << AC << "!" << std::endl;
+#endif
+
+
+#ifdef ACID // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ACID;
+ if(bsA!=bsB)
+ ssErrors << "Defined ACID with value 4 from .dat file mismatches hardcoded c++ define value of " << ACID << "!" << std::endl;
+#endif
+
+
+#ifdef ACIDOUS_BLOOD // DO NOT MODIFY!
+ bsA = 16427;
+ bsB = ACIDOUS_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined ACIDOUS_BLOOD with value 16427 from .dat file mismatches hardcoded c++ define value of " << ACIDOUS_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef ACM // DO NOT MODIFY!
+ bsA = 9;
+ bsB = ACM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ACM with value 9 from .dat file mismatches hardcoded c++ define value of " << ACM << "!" << std::endl;
+#endif
+
+
+#ifdef ACMM // DO NOT MODIFY!
+ bsA = 10;
+ bsB = ACMM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ACMM with value 10 from .dat file mismatches hardcoded c++ define value of " << ACMM << "!" << std::endl;
+#endif
+
+
+#ifdef ACP // DO NOT MODIFY!
+ bsA = 7;
+ bsB = ACP;
+ if(bsA!=bsB)
+ ssErrors << "Defined ACP with value 7 from .dat file mismatches hardcoded c++ define value of " << ACP << "!" << std::endl;
+#endif
+
+
+#ifdef ADAMANT // DO NOT MODIFY!
+ bsA = 28679;
+ bsB = ADAMANT;
+ if(bsA!=bsB)
+ ssErrors << "Defined ADAMANT with value 28679 from .dat file mismatches hardcoded c++ define value of " << ADAMANT << "!" << std::endl;
+#endif
+
+
+#ifdef ADULT_FEMALE // DO NOT MODIFY!
+ bsA = 5;
+ bsB = ADULT_FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ADULT_FEMALE with value 5 from .dat file mismatches hardcoded c++ define value of " << ADULT_FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef ADULT_MALE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ADULT_MALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ADULT_MALE with value 4 from .dat file mismatches hardcoded c++ define value of " << ADULT_MALE << "!" << std::endl;
+#endif
+
+
+#ifdef AEGIS_SHIELD // DO NOT MODIFY!
+ bsA = 2;
+ bsB = AEGIS_SHIELD;
+ if(bsA!=bsB)
+ ssErrors << "Defined AEGIS_SHIELD with value 2 from .dat file mismatches hardcoded c++ define value of " << AEGIS_SHIELD << "!" << std::endl;
+#endif
+
+
+#ifdef AEGI_SALT // DO NOT MODIFY!
+ bsA = 4322;
+ bsB = AEGI_SALT;
+ if(bsA!=bsB)
+ ssErrors << "Defined AEGI_SALT with value 4322 from .dat file mismatches hardcoded c++ define value of " << AEGI_SALT << "!" << std::endl;
+#endif
+
+
+#ifdef AFFECT_INSIDE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = AFFECT_INSIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined AFFECT_INSIDE with value 8 from .dat file mismatches hardcoded c++ define value of " << AFFECT_INSIDE << "!" << std::endl;
+#endif
+
+
+#ifdef AGATE // DO NOT MODIFY!
+ bsA = 4268;
+ bsB = AGATE;
+ if(bsA!=bsB)
+ ssErrors << "Defined AGATE with value 4268 from .dat file mismatches hardcoded c++ define value of " << AGATE << "!" << std::endl;
+#endif
+
+
+#ifdef AGILITY // DO NOT MODIFY!
+ bsA = 10;
+ bsB = AGILITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined AGILITY with value 10 from .dat file mismatches hardcoded c++ define value of " << AGILITY << "!" << std::endl;
+#endif
+
+
+#ifdef AIR // DO NOT MODIFY!
+ bsA = 12289;
+ bsB = AIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined AIR with value 12289 from .dat file mismatches hardcoded c++ define value of " << AIR << "!" << std::endl;
+#endif
+
+
+#ifdef AL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = AL;
+ if(bsA!=bsB)
+ ssErrors << "Defined AL with value 2 from .dat file mismatches hardcoded c++ define value of " << AL << "!" << std::endl;
+#endif
+
+
+#ifdef ALABASTER // DO NOT MODIFY!
+ bsA = 4323;
+ bsB = ALABASTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALABASTER with value 4323 from .dat file mismatches hardcoded c++ define value of " << ALABASTER << "!" << std::endl;
+#endif
+
+
+#ifdef ALL // DO NOT MODIFY!
+ bsA = 255;
+ bsB = ALL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALL with value 255 from .dat file mismatches hardcoded c++ define value of " << ALL << "!" << std::endl;
+#endif
+
+
+#ifdef ALL_DUNGEONS // DO NOT MODIFY!
+ bsA = 32767;
+ bsB = ALL_DUNGEONS;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALL_DUNGEONS with value 32767 from .dat file mismatches hardcoded c++ define value of " << ALL_DUNGEONS << "!" << std::endl;
+#endif
+
+
+#ifdef ALM // DO NOT MODIFY!
+ bsA = 3;
+ bsB = ALM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALM with value 3 from .dat file mismatches hardcoded c++ define value of " << ALM << "!" << std::endl;
+#endif
+
+
+#ifdef ALP // DO NOT MODIFY!
+ bsA = 1;
+ bsB = ALP;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALP with value 1 from .dat file mismatches hardcoded c++ define value of " << ALP << "!" << std::endl;
+#endif
+
+
+#ifdef ALPP // DO NOT MODIFY!
+ bsA = 0;
+ bsB = ALPP;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALPP with value 0 from .dat file mismatches hardcoded c++ define value of " << ALPP << "!" << std::endl;
+#endif
+
+
+#ifdef ALUMINIUM // DO NOT MODIFY!
+ bsA = 4120;
+ bsB = ALUMINIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ALUMINIUM with value 4120 from .dat file mismatches hardcoded c++ define value of " << ALUMINIUM << "!" << std::endl;
+#endif
+
+
+#ifdef AMBASSADOR_SIREN // DO NOT MODIFY!
+ bsA = 10;
+ bsB = AMBASSADOR_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMBASSADOR_SIREN with value 10 from .dat file mismatches hardcoded c++ define value of " << AMBASSADOR_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef AMBER // DO NOT MODIFY!
+ bsA = 4280;
+ bsB = AMBER;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMBER with value 4280 from .dat file mismatches hardcoded c++ define value of " << AMBER << "!" << std::endl;
+#endif
+
+
+#ifdef AMETHYST // DO NOT MODIFY!
+ bsA = 4293;
+ bsB = AMETHYST;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMETHYST with value 4293 from .dat file mismatches hardcoded c++ define value of " << AMETHYST << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET // DO NOT MODIFY!
+ bsA = 2;
+ bsB = AMULET;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET with value 2 from .dat file mismatches hardcoded c++ define value of " << AMULET << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_INDEX // DO NOT MODIFY!
+ bsA = 1;
+ bsB = AMULET_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_INDEX with value 1 from .dat file mismatches hardcoded c++ define value of " << AMULET_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_DIMENSION_ANCHOR // DO NOT MODIFY!
+ bsA = 8;
+ bsB = AMULET_OF_DIMENSION_ANCHOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_DIMENSION_ANCHOR with value 8 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_DIMENSION_ANCHOR << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_DISEASE_IMMUNITY // DO NOT MODIFY!
+ bsA = 7;
+ bsB = AMULET_OF_DISEASE_IMMUNITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_DISEASE_IMMUNITY with value 7 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_DISEASE_IMMUNITY << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_ESP // DO NOT MODIFY!
+ bsA = 2;
+ bsB = AMULET_OF_ESP;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_ESP with value 2 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_ESP << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_LIFE_SAVING // DO NOT MODIFY!
+ bsA = 1;
+ bsB = AMULET_OF_LIFE_SAVING;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_LIFE_SAVING with value 1 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_LIFE_SAVING << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_PHASING // DO NOT MODIFY!
+ bsA = 6;
+ bsB = AMULET_OF_PHASING;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_PHASING with value 6 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_PHASING << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_SPEED // DO NOT MODIFY!
+ bsA = 5;
+ bsB = AMULET_OF_SPEED;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_SPEED with value 5 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_SPEED << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_UNBREATHING // DO NOT MODIFY!
+ bsA = 4;
+ bsB = AMULET_OF_UNBREATHING;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_UNBREATHING with value 4 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_UNBREATHING << "!" << std::endl;
+#endif
+
+
+#ifdef AMULET_OF_WARDING // DO NOT MODIFY!
+ bsA = 3;
+ bsB = AMULET_OF_WARDING;
+ if(bsA!=bsB)
+ ssErrors << "Defined AMULET_OF_WARDING with value 3 from .dat file mismatches hardcoded c++ define value of " << AMULET_OF_WARDING << "!" << std::endl;
+#endif
+
+
+#ifdef AN // DO NOT MODIFY!
+ bsA = 5;
+ bsB = AN;
+ if(bsA!=bsB)
+ ssErrors << "Defined AN with value 5 from .dat file mismatches hardcoded c++ define value of " << AN << "!" << std::endl;
+#endif
+
+
+#ifdef ANGEL_FLESH // DO NOT MODIFY!
+ bsA = 20506;
+ bsB = ANGEL_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANGEL_FLESH with value 20506 from .dat file mismatches hardcoded c++ define value of " << ANGEL_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef ANGEL_HAIR // DO NOT MODIFY!
+ bsA = 4137;
+ bsB = ANGEL_HAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANGEL_HAIR with value 4137 from .dat file mismatches hardcoded c++ define value of " << ANGEL_HAIR << "!" << std::endl;
+#endif
+
+
+#ifdef ANM // DO NOT MODIFY!
+ bsA = 6;
+ bsB = ANM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANM with value 6 from .dat file mismatches hardcoded c++ define value of " << ANM << "!" << std::endl;
+#endif
+
+
+#ifdef ANP // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ANP;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANP with value 4 from .dat file mismatches hardcoded c++ define value of " << ANP << "!" << std::endl;
+#endif
+
+
+#ifdef ANTIDOTE_LIQUID // DO NOT MODIFY!
+ bsA = 16385;
+ bsB = ANTIDOTE_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANTIDOTE_LIQUID with value 16385 from .dat file mismatches hardcoded c++ define value of " << ANTIDOTE_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef ANVIL // DO NOT MODIFY!
+ bsA = 18;
+ bsB = ANVIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANVIL with value 18 from .dat file mismatches hardcoded c++ define value of " << ANVIL << "!" << std::endl;
+#endif
+
+
+#ifdef ANY_CATEGORY // DO NOT MODIFY!
+ bsA = 2147483647;
+ bsB = ANY_CATEGORY;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANY_CATEGORY with value 2147483647 from .dat file mismatches hardcoded c++ define value of " << ANY_CATEGORY << "!" << std::endl;
+#endif
+
+
+#ifdef ANY_MOVE // DO NOT MODIFY!
+ bsA = 15;
+ bsB = ANY_MOVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ANY_MOVE with value 15 from .dat file mismatches hardcoded c++ define value of " << ANY_MOVE << "!" << std::endl;
+#endif
+
+
+#ifdef APPRENTICE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = APPRENTICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined APPRENTICE with value 1 from .dat file mismatches hardcoded c++ define value of " << APPRENTICE << "!" << std::endl;
+#endif
+
+
+#ifdef APPRENTICE_NECROMANCER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = APPRENTICE_NECROMANCER;
+ if(bsA!=bsB)
+ ssErrors << "Defined APPRENTICE_NECROMANCER with value 1 from .dat file mismatches hardcoded c++ define value of " << APPRENTICE_NECROMANCER << "!" << std::endl;
+#endif
+
+
+#ifdef ARANEA // DO NOT MODIFY!
+ bsA = 3;
+ bsB = ARANEA;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARANEA with value 3 from .dat file mismatches hardcoded c++ define value of " << ARANEA << "!" << std::endl;
+#endif
+
+
+#ifdef ARCANITE // DO NOT MODIFY!
+ bsA = 4202;
+ bsB = ARCANITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARCANITE with value 4202 from .dat file mismatches hardcoded c++ define value of " << ARCANITE << "!" << std::endl;
+#endif
+
+
+#ifdef ARCH_MAGE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ARCH_MAGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARCH_MAGE with value 4 from .dat file mismatches hardcoded c++ define value of " << ARCH_MAGE << "!" << std::endl;
+#endif
+
+
+#ifdef ARMOR_OF_GREAT_HEALTH // DO NOT MODIFY!
+ bsA = 3;
+ bsB = ARMOR_OF_GREAT_HEALTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARMOR_OF_GREAT_HEALTH with value 3 from .dat file mismatches hardcoded c++ define value of " << ARMOR_OF_GREAT_HEALTH << "!" << std::endl;
+#endif
+
+
+#ifdef ARMS // DO NOT MODIFY!
+ bsA = 12;
+ bsB = ARMS;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARMS with value 12 from .dat file mismatches hardcoded c++ define value of " << ARMS << "!" << std::endl;
+#endif
+
+
+#ifdef ARM_CHAIR // DO NOT MODIFY!
+ bsA = 7;
+ bsB = ARM_CHAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARM_CHAIR with value 7 from .dat file mismatches hardcoded c++ define value of " << ARM_CHAIR << "!" << std::endl;
+#endif
+
+
+#ifdef ARM_MAIN_COLOR // DO NOT MODIFY!
+ bsA = 256;
+ bsB = ARM_MAIN_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARM_MAIN_COLOR with value 256 from .dat file mismatches hardcoded c++ define value of " << ARM_MAIN_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef ARM_SPECIAL_COLOR // DO NOT MODIFY!
+ bsA = 1024;
+ bsB = ARM_SPECIAL_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARM_SPECIAL_COLOR with value 1024 from .dat file mismatches hardcoded c++ define value of " << ARM_SPECIAL_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef ARM_STRENGTH // DO NOT MODIFY!
+ bsA = 7;
+ bsB = ARM_STRENGTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARM_STRENGTH with value 7 from .dat file mismatches hardcoded c++ define value of " << ARM_STRENGTH << "!" << std::endl;
+#endif
+
+
+#ifdef ARTICLE_BIT // DO NOT MODIFY!
+ bsA = 2;
+ bsB = ARTICLE_BIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined ARTICLE_BIT with value 2 from .dat file mismatches hardcoded c++ define value of " << ARTICLE_BIT << "!" << std::endl;
+#endif
+
+
+#ifdef ASH // DO NOT MODIFY!
+ bsA = 24585;
+ bsB = ASH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ASH with value 24585 from .dat file mismatches hardcoded c++ define value of " << ASH << "!" << std::endl;
+#endif
+
+
+#ifdef ASH_WOOD // DO NOT MODIFY!
+ bsA = 4230;
+ bsB = ASH_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined ASH_WOOD with value 4230 from .dat file mismatches hardcoded c++ define value of " << ASH_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef ASPHALT // DO NOT MODIFY!
+ bsA = 16415;
+ bsB = ASPHALT;
+ if(bsA!=bsB)
+ ssErrors << "Defined ASPHALT with value 16415 from .dat file mismatches hardcoded c++ define value of " << ASPHALT << "!" << std::endl;
+#endif
+
+
+#ifdef ASSASSIN // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ASSASSIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined ASSASSIN with value 4 from .dat file mismatches hardcoded c++ define value of " << ASSASSIN << "!" << std::endl;
+#endif
+
+
+#ifdef ATAVUS // DO NOT MODIFY!
+ bsA = 3;
+ bsB = ATAVUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined ATAVUS with value 3 from .dat file mismatches hardcoded c++ define value of " << ATAVUS << "!" << std::endl;
+#endif
+
+
+#ifdef ATHEIST // DO NOT MODIFY!
+ bsA = 16;
+ bsB = ATHEIST;
+ if(bsA!=bsB)
+ ssErrors << "Defined ATHEIST with value 16 from .dat file mismatches hardcoded c++ define value of " << ATHEIST << "!" << std::endl;
+#endif
+
+
+#ifdef ATTACHABLE // DO NOT MODIFY!
+ bsA = 24;
+ bsB = ATTACHABLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ATTACHABLE with value 24 from .dat file mismatches hardcoded c++ define value of " << ATTACHABLE << "!" << std::endl;
+#endif
+
+
+#ifdef ATTNAM // DO NOT MODIFY!
+ bsA = 2;
+ bsB = ATTNAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ATTNAM with value 2 from .dat file mismatches hardcoded c++ define value of " << ATTNAM << "!" << std::endl;
+#endif
+
+
+#ifdef ATTNAM_TEAM // DO NOT MODIFY!
+ bsA = 2;
+ bsB = ATTNAM_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ATTNAM_TEAM with value 2 from .dat file mismatches hardcoded c++ define value of " << ATTNAM_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef ATTRIBUTES // DO NOT MODIFY!
+ bsA = 11;
+ bsB = ATTRIBUTES;
+ if(bsA!=bsB)
+ ssErrors << "Defined ATTRIBUTES with value 11 from .dat file mismatches hardcoded c++ define value of " << ATTRIBUTES << "!" << std::endl;
+#endif
+
+
+#ifdef AXE // DO NOT MODIFY!
+ bsA = 5;
+ bsB = AXE;
+ if(bsA!=bsB)
+ ssErrors << "Defined AXE with value 5 from .dat file mismatches hardcoded c++ define value of " << AXE << "!" << std::endl;
+#endif
+
+
+#ifdef AXES // DO NOT MODIFY!
+ bsA = 7;
+ bsB = AXES;
+ if(bsA!=bsB)
+ ssErrors << "Defined AXES with value 7 from .dat file mismatches hardcoded c++ define value of " << AXES << "!" << std::endl;
+#endif
+
+
+#ifdef BABY_FEMALE // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BABY_FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BABY_FEMALE with value 3 from .dat file mismatches hardcoded c++ define value of " << BABY_FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef BABY_MALE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BABY_MALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BABY_MALE with value 2 from .dat file mismatches hardcoded c++ define value of " << BABY_MALE << "!" << std::endl;
+#endif
+
+
+#ifdef BALSA_WOOD // DO NOT MODIFY!
+ bsA = 4237;
+ bsB = BALSA_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BALSA_WOOD with value 4237 from .dat file mismatches hardcoded c++ define value of " << BALSA_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef BAMBOO_WOOD // DO NOT MODIFY!
+ bsA = 4235;
+ bsB = BAMBOO_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BAMBOO_WOOD with value 4235 from .dat file mismatches hardcoded c++ define value of " << BAMBOO_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef BANANA_FLESH // DO NOT MODIFY!
+ bsA = 8196;
+ bsB = BANANA_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BANANA_FLESH with value 8196 from .dat file mismatches hardcoded c++ define value of " << BANANA_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef BANANA_PEEL // DO NOT MODIFY!
+ bsA = 8195;
+ bsB = BANANA_PEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BANANA_PEEL with value 8195 from .dat file mismatches hardcoded c++ define value of " << BANANA_PEEL << "!" << std::endl;
+#endif
+
+
+#ifdef BANANA_STOLLEN // DO NOT MODIFY!
+ bsA = 8207;
+ bsB = BANANA_STOLLEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BANANA_STOLLEN with value 8207 from .dat file mismatches hardcoded c++ define value of " << BANANA_STOLLEN << "!" << std::endl;
+#endif
+
+
+#ifdef BANANA_TREE // DO NOT MODIFY!
+ bsA = 36;
+ bsB = BANANA_TREE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BANANA_TREE with value 36 from .dat file mismatches hardcoded c++ define value of " << BANANA_TREE << "!" << std::endl;
+#endif
+
+
+#ifdef BARDOOR // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BARDOOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined BARDOOR with value 1 from .dat file mismatches hardcoded c++ define value of " << BARDOOR << "!" << std::endl;
+#endif
+
+
+#ifdef BASALT // DO NOT MODIFY!
+ bsA = 4264;
+ bsB = BASALT;
+ if(bsA!=bsB)
+ ssErrors << "Defined BASALT with value 4264 from .dat file mismatches hardcoded c++ define value of " << BASALT << "!" << std::endl;
+#endif
+
+
+#ifdef BASE_ATTRIBUTES // DO NOT MODIFY!
+ bsA = 7;
+ bsB = BASE_ATTRIBUTES;
+ if(bsA!=bsB)
+ ssErrors << "Defined BASE_ATTRIBUTES with value 7 from .dat file mismatches hardcoded c++ define value of " << BASE_ATTRIBUTES << "!" << std::endl;
+#endif
+
+
+#ifdef BASILISK_SKIN // DO NOT MODIFY!
+ bsA = 4146;
+ bsB = BASILISK_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BASILISK_SKIN with value 4146 from .dat file mismatches hardcoded c++ define value of " << BASILISK_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef BASTARD_SWORD // DO NOT MODIFY!
+ bsA = 12;
+ bsB = BASTARD_SWORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BASTARD_SWORD with value 12 from .dat file mismatches hardcoded c++ define value of " << BASTARD_SWORD << "!" << std::endl;
+#endif
+
+
+#ifdef BATTLE_AXE // DO NOT MODIFY!
+ bsA = 13;
+ bsB = BATTLE_AXE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BATTLE_AXE with value 13 from .dat file mismatches hardcoded c++ define value of " << BATTLE_AXE << "!" << std::endl;
+#endif
+
+
+#ifdef BATTLE_MAGE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BATTLE_MAGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BATTLE_MAGE with value 2 from .dat file mismatches hardcoded c++ define value of " << BATTLE_MAGE << "!" << std::endl;
+#endif
+
+
+#ifdef BAT_FLESH // DO NOT MODIFY!
+ bsA = 20500;
+ bsB = BAT_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BAT_FLESH with value 20500 from .dat file mismatches hardcoded c++ define value of " << BAT_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_ACID_RAIN // DO NOT MODIFY!
+ bsA = 11;
+ bsB = BEAM_ACID_RAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_ACID_RAIN with value 11 from .dat file mismatches hardcoded c++ define value of " << BEAM_ACID_RAIN << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_ALCHEMY // DO NOT MODIFY!
+ bsA = 14;
+ bsB = BEAM_ALCHEMY;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_ALCHEMY with value 14 from .dat file mismatches hardcoded c++ define value of " << BEAM_ALCHEMY << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_DOOR_CREATION // DO NOT MODIFY!
+ bsA = 10;
+ bsB = BEAM_DOOR_CREATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_DOOR_CREATION with value 10 from .dat file mismatches hardcoded c++ define value of " << BEAM_DOOR_CREATION << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_DUPLICATE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = BEAM_DUPLICATE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_DUPLICATE with value 8 from .dat file mismatches hardcoded c++ define value of " << BEAM_DUPLICATE << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_FIRE_BALL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BEAM_FIRE_BALL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_FIRE_BALL with value 2 from .dat file mismatches hardcoded c++ define value of " << BEAM_FIRE_BALL << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_HASTE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = BEAM_HASTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_HASTE with value 4 from .dat file mismatches hardcoded c++ define value of " << BEAM_HASTE << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_INVISIBILITY // DO NOT MODIFY!
+ bsA = 7;
+ bsB = BEAM_INVISIBILITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_INVISIBILITY with value 7 from .dat file mismatches hardcoded c++ define value of " << BEAM_INVISIBILITY << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_LIGHTNING // DO NOT MODIFY!
+ bsA = 9;
+ bsB = BEAM_LIGHTNING;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_LIGHTNING with value 9 from .dat file mismatches hardcoded c++ define value of " << BEAM_LIGHTNING << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_NECROMANCY // DO NOT MODIFY!
+ bsA = 12;
+ bsB = BEAM_NECROMANCY;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_NECROMANCY with value 12 from .dat file mismatches hardcoded c++ define value of " << BEAM_NECROMANCY << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_POLYMORPH // DO NOT MODIFY!
+ bsA = 0;
+ bsB = BEAM_POLYMORPH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_POLYMORPH with value 0 from .dat file mismatches hardcoded c++ define value of " << BEAM_POLYMORPH << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_RESURRECT // DO NOT MODIFY!
+ bsA = 6;
+ bsB = BEAM_RESURRECT;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_RESURRECT with value 6 from .dat file mismatches hardcoded c++ define value of " << BEAM_RESURRECT << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_SLOW // DO NOT MODIFY!
+ bsA = 5;
+ bsB = BEAM_SLOW;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_SLOW with value 5 from .dat file mismatches hardcoded c++ define value of " << BEAM_SLOW << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_STRIKE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BEAM_STRIKE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_STRIKE with value 1 from .dat file mismatches hardcoded c++ define value of " << BEAM_STRIKE << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_STYLES // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BEAM_STYLES;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_STYLES with value 3 from .dat file mismatches hardcoded c++ define value of " << BEAM_STYLES << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_TELEPORT // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BEAM_TELEPORT;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_TELEPORT with value 3 from .dat file mismatches hardcoded c++ define value of " << BEAM_TELEPORT << "!" << std::endl;
+#endif
+
+
+#ifdef BEAM_WEBBING // DO NOT MODIFY!
+ bsA = 13;
+ bsB = BEAM_WEBBING;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAM_WEBBING with value 13 from .dat file mismatches hardcoded c++ define value of " << BEAM_WEBBING << "!" << std::endl;
+#endif
+
+
+#ifdef BEAR_FLESH // DO NOT MODIFY!
+ bsA = 20493;
+ bsB = BEAR_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAR_FLESH with value 20493 from .dat file mismatches hardcoded c++ define value of " << BEAR_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef BEAR_SKIN // DO NOT MODIFY!
+ bsA = 4143;
+ bsB = BEAR_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEAR_SKIN with value 4143 from .dat file mismatches hardcoded c++ define value of " << BEAR_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef BEECH_WOOD // DO NOT MODIFY!
+ bsA = 4234;
+ bsB = BEECH_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEECH_WOOD with value 4234 from .dat file mismatches hardcoded c++ define value of " << BEECH_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef BEEF // DO NOT MODIFY!
+ bsA = 20482;
+ bsB = BEEF;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEEF with value 20482 from .dat file mismatches hardcoded c++ define value of " << BEEF << "!" << std::endl;
+#endif
+
+
+#ifdef BEER // DO NOT MODIFY!
+ bsA = 16404;
+ bsB = BEER;
+ if(bsA!=bsB)
+ ssErrors << "Defined BEER with value 16404 from .dat file mismatches hardcoded c++ define value of " << BEER << "!" << std::endl;
+#endif
+
+
+#ifdef BELT // DO NOT MODIFY!
+ bsA = 256;
+ bsB = BELT;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT with value 256 from .dat file mismatches hardcoded c++ define value of " << BELT << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_COLOR // DO NOT MODIFY!
+ bsA = 32;
+ bsB = BELT_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_COLOR with value 32 from .dat file mismatches hardcoded c++ define value of " << BELT_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_INDEX // DO NOT MODIFY!
+ bsA = 4;
+ bsB = BELT_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_INDEX with value 4 from .dat file mismatches hardcoded c++ define value of " << BELT_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_OF_CARRYING // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BELT_OF_CARRYING;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_OF_CARRYING with value 1 from .dat file mismatches hardcoded c++ define value of " << BELT_OF_CARRYING << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_OF_GIANT_STRENGTH // DO NOT MODIFY!
+ bsA = 4;
+ bsB = BELT_OF_GIANT_STRENGTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_OF_GIANT_STRENGTH with value 4 from .dat file mismatches hardcoded c++ define value of " << BELT_OF_GIANT_STRENGTH << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_OF_LEVITATION // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BELT_OF_LEVITATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_OF_LEVITATION with value 2 from .dat file mismatches hardcoded c++ define value of " << BELT_OF_LEVITATION << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_OF_PROTECTION // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BELT_OF_PROTECTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_OF_PROTECTION with value 3 from .dat file mismatches hardcoded c++ define value of " << BELT_OF_PROTECTION << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_OF_REGENERATION // DO NOT MODIFY!
+ bsA = 6;
+ bsB = BELT_OF_REGENERATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_OF_REGENERATION with value 6 from .dat file mismatches hardcoded c++ define value of " << BELT_OF_REGENERATION << "!" << std::endl;
+#endif
+
+
+#ifdef BELT_OF_THIEF // DO NOT MODIFY!
+ bsA = 5;
+ bsB = BELT_OF_THIEF;
+ if(bsA!=bsB)
+ ssErrors << "Defined BELT_OF_THIEF with value 5 from .dat file mismatches hardcoded c++ define value of " << BELT_OF_THIEF << "!" << std::endl;
+#endif
+
+
+#ifdef BENCH // DO NOT MODIFY!
+ bsA = 8;
+ bsB = BENCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BENCH with value 8 from .dat file mismatches hardcoded c++ define value of " << BENCH << "!" << std::endl;
+#endif
+
+
+#ifdef BERSERKER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BERSERKER;
+ if(bsA!=bsB)
+ ssErrors << "Defined BERSERKER with value 1 from .dat file mismatches hardcoded c++ define value of " << BERSERKER << "!" << std::endl;
+#endif
+
+
+#ifdef BETRAYED_TEAM // DO NOT MODIFY!
+ bsA = 11;
+ bsB = BETRAYED_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined BETRAYED_TEAM with value 11 from .dat file mismatches hardcoded c++ define value of " << BETRAYED_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef BIG_MINE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BIG_MINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BIG_MINE with value 1 from .dat file mismatches hardcoded c++ define value of " << BIG_MINE << "!" << std::endl;
+#endif
+
+
+#ifdef BIRCH // DO NOT MODIFY!
+ bsA = 22;
+ bsB = BIRCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BIRCH with value 22 from .dat file mismatches hardcoded c++ define value of " << BIRCH << "!" << std::endl;
+#endif
+
+
+#ifdef BIRCH_WOOD // DO NOT MODIFY!
+ bsA = 4240;
+ bsB = BIRCH_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BIRCH_WOOD with value 4240 from .dat file mismatches hardcoded c++ define value of " << BIRCH_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef BITE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BITE with value 2 from .dat file mismatches hardcoded c++ define value of " << BITE << "!" << std::endl;
+#endif
+
+
+#ifdef BITE_ATTACK // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BITE_ATTACK;
+ if(bsA!=bsB)
+ ssErrors << "Defined BITE_ATTACK with value 3 from .dat file mismatches hardcoded c++ define value of " << BITE_ATTACK << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK // DO NOT MODIFY!
+ bsA = 0;
+ bsB = BLACK;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK with value 0 from .dat file mismatches hardcoded c++ define value of " << BLACK << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_BEAR // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BLACK_BEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_BEAR with value 1 from .dat file mismatches hardcoded c++ define value of " << BLACK_BEAR << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_DIAMOND // DO NOT MODIFY!
+ bsA = 4299;
+ bsB = BLACK_DIAMOND;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_DIAMOND with value 4299 from .dat file mismatches hardcoded c++ define value of " << BLACK_DIAMOND << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_GRANITE // DO NOT MODIFY!
+ bsA = 4275;
+ bsB = BLACK_GRANITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_GRANITE with value 4275 from .dat file mismatches hardcoded c++ define value of " << BLACK_GRANITE << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_IRON // DO NOT MODIFY!
+ bsA = 28680;
+ bsB = BLACK_IRON;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_IRON with value 28680 from .dat file mismatches hardcoded c++ define value of " << BLACK_IRON << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_JADE // DO NOT MODIFY!
+ bsA = 4303;
+ bsB = BLACK_JADE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_JADE with value 4303 from .dat file mismatches hardcoded c++ define value of " << BLACK_JADE << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_LEATHER // DO NOT MODIFY!
+ bsA = 4151;
+ bsB = BLACK_LEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_LEATHER with value 4151 from .dat file mismatches hardcoded c++ define value of " << BLACK_LEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_SAND // DO NOT MODIFY!
+ bsA = 24582;
+ bsB = BLACK_SAND;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_SAND with value 24582 from .dat file mismatches hardcoded c++ define value of " << BLACK_SAND << "!" << std::endl;
+#endif
+
+
+#ifdef BLACK_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 20510;
+ bsB = BLACK_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLACK_UNICORN_FLESH with value 20510 from .dat file mismatches hardcoded c++ define value of " << BLACK_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef BLINK_DOG_FLESH // DO NOT MODIFY!
+ bsA = 20527;
+ bsB = BLINK_DOG_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLINK_DOG_FLESH with value 20527 from .dat file mismatches hardcoded c++ define value of " << BLINK_DOG_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef BLOOD // DO NOT MODIFY!
+ bsA = 16419;
+ bsB = BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLOOD with value 16419 from .dat file mismatches hardcoded c++ define value of " << BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef BLOOD_IRON // DO NOT MODIFY!
+ bsA = 28682;
+ bsB = BLOOD_IRON;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLOOD_IRON with value 28682 from .dat file mismatches hardcoded c++ define value of " << BLOOD_IRON << "!" << std::endl;
+#endif
+
+
+#ifdef BLOOD_STEEL // DO NOT MODIFY!
+ bsA = 28683;
+ bsB = BLOOD_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLOOD_STEEL with value 28683 from .dat file mismatches hardcoded c++ define value of " << BLOOD_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef BLUE // DO NOT MODIFY!
+ bsA = 10943;
+ bsB = BLUE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUE with value 10943 from .dat file mismatches hardcoded c++ define value of " << BLUE << "!" << std::endl;
+#endif
+
+
+#ifdef BLUE_BLOOD // DO NOT MODIFY!
+ bsA = 16421;
+ bsB = BLUE_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUE_BLOOD with value 16421 from .dat file mismatches hardcoded c++ define value of " << BLUE_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef BLUE_CRYSTAL // DO NOT MODIFY!
+ bsA = 4310;
+ bsB = BLUE_CRYSTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUE_CRYSTAL with value 4310 from .dat file mismatches hardcoded c++ define value of " << BLUE_CRYSTAL << "!" << std::endl;
+#endif
+
+
+#ifdef BLUE_FRACTAL // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BLUE_FRACTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUE_FRACTAL with value 3 from .dat file mismatches hardcoded c++ define value of " << BLUE_FRACTAL << "!" << std::endl;
+#endif
+
+
+#ifdef BLUE_JADE // DO NOT MODIFY!
+ bsA = 4306;
+ bsB = BLUE_JADE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUE_JADE with value 4306 from .dat file mismatches hardcoded c++ define value of " << BLUE_JADE << "!" << std::endl;
+#endif
+
+
+#ifdef BLUE_SIREN // DO NOT MODIFY!
+ bsA = 6;
+ bsB = BLUE_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUE_SIREN with value 6 from .dat file mismatches hardcoded c++ define value of " << BLUE_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef BLUNT // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BLUNT;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUNT with value 1 from .dat file mismatches hardcoded c++ define value of " << BLUNT << "!" << std::endl;
+#endif
+
+
+#ifdef BLUNT_WEAPONS // DO NOT MODIFY!
+ bsA = 6;
+ bsB = BLUNT_WEAPONS;
+ if(bsA!=bsB)
+ ssErrors << "Defined BLUNT_WEAPONS with value 6 from .dat file mismatches hardcoded c++ define value of " << BLUNT_WEAPONS << "!" << std::endl;
+#endif
+
+
+#ifdef BODY_ARMOR // DO NOT MODIFY!
+ bsA = 8;
+ bsB = BODY_ARMOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined BODY_ARMOR with value 8 from .dat file mismatches hardcoded c++ define value of " << BODY_ARMOR << "!" << std::endl;
+#endif
+
+
+#ifdef BODY_ARMOR_INDEX // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BODY_ARMOR_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined BODY_ARMOR_INDEX with value 3 from .dat file mismatches hardcoded c++ define value of " << BODY_ARMOR_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef BOIL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BOIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOIL with value 2 from .dat file mismatches hardcoded c++ define value of " << BOIL << "!" << std::endl;
+#endif
+
+
+#ifdef BOILED_LEATHER // DO NOT MODIFY!
+ bsA = 4153;
+ bsB = BOILED_LEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOILED_LEATHER with value 4153 from .dat file mismatches hardcoded c++ define value of " << BOILED_LEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef BONE // DO NOT MODIFY!
+ bsA = 8212;
+ bsB = BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BONE with value 8212 from .dat file mismatches hardcoded c++ define value of " << BONE << "!" << std::endl;
+#endif
+
+
+#ifdef BONE_FISH // DO NOT MODIFY!
+ bsA = 4;
+ bsB = BONE_FISH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BONE_FISH with value 4 from .dat file mismatches hardcoded c++ define value of " << BONE_FISH << "!" << std::endl;
+#endif
+
+
+#ifdef BONUS_LIVES // DO NOT MODIFY!
+ bsA = 0;
+ bsB = BONUS_LIVES;
+ if(bsA!=bsB)
+ ssErrors << "Defined BONUS_LIVES with value 0 from .dat file mismatches hardcoded c++ define value of " << BONUS_LIVES << "!" << std::endl;
+#endif
+
+
+#ifdef BOOK // DO NOT MODIFY!
+ bsA = 8192;
+ bsB = BOOK;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOK with value 8192 from .dat file mismatches hardcoded c++ define value of " << BOOK << "!" << std::endl;
+#endif
+
+
+#ifdef BOOK_CASE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BOOK_CASE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOK_CASE with value 1 from .dat file mismatches hardcoded c++ define value of " << BOOK_CASE << "!" << std::endl;
+#endif
+
+
+#ifdef BOOT // DO NOT MODIFY!
+ bsA = 512;
+ bsB = BOOT;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOT with value 512 from .dat file mismatches hardcoded c++ define value of " << BOOT << "!" << std::endl;
+#endif
+
+
+#ifdef BOOT_COLOR // DO NOT MODIFY!
+ bsA = 64;
+ bsB = BOOT_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOT_COLOR with value 64 from .dat file mismatches hardcoded c++ define value of " << BOOT_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef BOOT_OF_AGILITY // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BOOT_OF_AGILITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOT_OF_AGILITY with value 2 from .dat file mismatches hardcoded c++ define value of " << BOOT_OF_AGILITY << "!" << std::endl;
+#endif
+
+
+#ifdef BOOT_OF_KICKING // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BOOT_OF_KICKING;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOT_OF_KICKING with value 3 from .dat file mismatches hardcoded c++ define value of " << BOOT_OF_KICKING << "!" << std::endl;
+#endif
+
+
+#ifdef BOOT_OF_STRENGTH // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BOOT_OF_STRENGTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOOT_OF_STRENGTH with value 1 from .dat file mismatches hardcoded c++ define value of " << BOOT_OF_STRENGTH << "!" << std::endl;
+#endif
+
+
+#ifdef BOY // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BOY;
+ if(bsA!=bsB)
+ ssErrors << "Defined BOY with value 1 from .dat file mismatches hardcoded c++ define value of " << BOY << "!" << std::endl;
+#endif
+
+
+#ifdef BRASS // DO NOT MODIFY!
+ bsA = 4103;
+ bsB = BRASS;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRASS with value 4103 from .dat file mismatches hardcoded c++ define value of " << BRASS << "!" << std::endl;
+#endif
+
+
+#ifdef BRAVERY // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BRAVERY;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRAVERY with value 1 from .dat file mismatches hardcoded c++ define value of " << BRAVERY << "!" << std::endl;
+#endif
+
+
+#ifdef BRICK_FINE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BRICK_FINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRICK_FINE with value 1 from .dat file mismatches hardcoded c++ define value of " << BRICK_FINE << "!" << std::endl;
+#endif
+
+
+#ifdef BRICK_OLD // DO NOT MODIFY!
+ bsA = 3;
+ bsB = BRICK_OLD;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRICK_OLD with value 3 from .dat file mismatches hardcoded c++ define value of " << BRICK_OLD << "!" << std::endl;
+#endif
+
+
+#ifdef BRICK_PRIMITIVE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = BRICK_PRIMITIVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRICK_PRIMITIVE with value 4 from .dat file mismatches hardcoded c++ define value of " << BRICK_PRIMITIVE << "!" << std::endl;
+#endif
+
+
+#ifdef BRICK_PRIMITIVE_PROPAGANDA // DO NOT MODIFY!
+ bsA = 5;
+ bsB = BRICK_PRIMITIVE_PROPAGANDA;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRICK_PRIMITIVE_PROPAGANDA with value 5 from .dat file mismatches hardcoded c++ define value of " << BRICK_PRIMITIVE_PROPAGANDA << "!" << std::endl;
+#endif
+
+
+#ifdef BRICK_PROPAGANDA // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BRICK_PROPAGANDA;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRICK_PROPAGANDA with value 2 from .dat file mismatches hardcoded c++ define value of " << BRICK_PROPAGANDA << "!" << std::endl;
+#endif
+
+
+#ifdef BRIM_STONE // DO NOT MODIFY!
+ bsA = 4317;
+ bsB = BRIM_STONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRIM_STONE with value 4317 from .dat file mismatches hardcoded c++ define value of " << BRIM_STONE << "!" << std::endl;
+#endif
+
+
+#ifdef BRINE // DO NOT MODIFY!
+ bsA = 16397;
+ bsB = BRINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRINE with value 16397 from .dat file mismatches hardcoded c++ define value of " << BRINE << "!" << std::endl;
+#endif
+
+
+#ifdef BROKEN // DO NOT MODIFY!
+ bsA = 128;
+ bsB = BROKEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BROKEN with value 128 from .dat file mismatches hardcoded c++ define value of " << BROKEN << "!" << std::endl;
+#endif
+
+
+#ifdef BROKEN_BARWALL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = BROKEN_BARWALL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BROKEN_BARWALL with value 1 from .dat file mismatches hardcoded c++ define value of " << BROKEN_BARWALL << "!" << std::endl;
+#endif
+
+
+#ifdef BROKEN_LOCK // DO NOT MODIFY!
+ bsA = 32768;
+ bsB = BROKEN_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined BROKEN_LOCK with value 32768 from .dat file mismatches hardcoded c++ define value of " << BROKEN_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef BROKEN_WALL // DO NOT MODIFY!
+ bsA = 8;
+ bsB = BROKEN_WALL;
+ if(bsA!=bsB)
+ ssErrors << "Defined BROKEN_WALL with value 8 from .dat file mismatches hardcoded c++ define value of " << BROKEN_WALL << "!" << std::endl;
+#endif
+
+
+#ifdef BRONZE // DO NOT MODIFY!
+ bsA = 4100;
+ bsB = BRONZE;
+ if(bsA!=bsB)
+ ssErrors << "Defined BRONZE with value 4100 from .dat file mismatches hardcoded c++ define value of " << BRONZE << "!" << std::endl;
+#endif
+
+
+#ifdef BROWN_SLIME // DO NOT MODIFY!
+ bsA = 16407;
+ bsB = BROWN_SLIME;
+ if(bsA!=bsB)
+ ssErrors << "Defined BROWN_SLIME with value 16407 from .dat file mismatches hardcoded c++ define value of " << BROWN_SLIME << "!" << std::endl;
+#endif
+
+
+#ifdef BUFFALO_FLESH // DO NOT MODIFY!
+ bsA = 20514;
+ bsB = BUFFALO_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined BUFFALO_FLESH with value 20514 from .dat file mismatches hardcoded c++ define value of " << BUFFALO_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef BUFFALO_HORN // DO NOT MODIFY!
+ bsA = 4250;
+ bsB = BUFFALO_HORN;
+ if(bsA!=bsB)
+ ssErrors << "Defined BUFFALO_HORN with value 4250 from .dat file mismatches hardcoded c++ define value of " << BUFFALO_HORN << "!" << std::endl;
+#endif
+
+
+#ifdef BUTCHER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = BUTCHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined BUTCHER with value 2 from .dat file mismatches hardcoded c++ define value of " << BUTCHER << "!" << std::endl;
+#endif
+
+
+#ifdef Base // DO NOT MODIFY!
+ bsA = 73;
+ bsB = Base;
+ if(bsA!=bsB)
+ ssErrors << "Defined Base with value 73 from .dat file mismatches hardcoded c++ define value of " << Base << "!" << std::endl;
+#endif
+
+
+#ifdef CACTUS // DO NOT MODIFY!
+ bsA = 20;
+ bsB = CACTUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CACTUS with value 20 from .dat file mismatches hardcoded c++ define value of " << CACTUS << "!" << std::endl;
+#endif
+
+
+#ifdef CALCITE // DO NOT MODIFY!
+ bsA = 4271;
+ bsB = CALCITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CALCITE with value 4271 from .dat file mismatches hardcoded c++ define value of " << CALCITE << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_BE_DESTROYED // DO NOT MODIFY!
+ bsA = 16;
+ bsB = CAN_BE_DESTROYED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_BE_DESTROYED with value 16 from .dat file mismatches hardcoded c++ define value of " << CAN_BE_DESTROYED << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_BE_MIRRORED // DO NOT MODIFY!
+ bsA = 64;
+ bsB = CAN_BE_MIRRORED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_BE_MIRRORED with value 64 from .dat file mismatches hardcoded c++ define value of " << CAN_BE_MIRRORED << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_BE_TAILORED // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CAN_BE_TAILORED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_BE_TAILORED with value 4 from .dat file mismatches hardcoded c++ define value of " << CAN_BE_TAILORED << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_BE_WISHED // DO NOT MODIFY!
+ bsA = 8;
+ bsB = CAN_BE_WISHED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_BE_WISHED with value 8 from .dat file mismatches hardcoded c++ define value of " << CAN_BE_WISHED << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_BURN // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CAN_BURN;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_BURN with value 1 from .dat file mismatches hardcoded c++ define value of " << CAN_BURN << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_DISSOLVE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CAN_DISSOLVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_DISSOLVE with value 4 from .dat file mismatches hardcoded c++ define value of " << CAN_DISSOLVE << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_EXPLODE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CAN_EXPLODE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_EXPLODE with value 2 from .dat file mismatches hardcoded c++ define value of " << CAN_EXPLODE << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_HAVE_PARASITE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CAN_HAVE_PARASITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_HAVE_PARASITE with value 4 from .dat file mismatches hardcoded c++ define value of " << CAN_HAVE_PARASITE << "!" << std::endl;
+#endif
+
+
+#ifdef CAN_REGENERATE // DO NOT MODIFY!
+ bsA = 16;
+ bsB = CAN_REGENERATE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAN_REGENERATE with value 16 from .dat file mismatches hardcoded c++ define value of " << CAN_REGENERATE << "!" << std::endl;
+#endif
+
+
+#ifdef CAP_COLOR // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CAP_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAP_COLOR with value 2 from .dat file mismatches hardcoded c++ define value of " << CAP_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef CARBIDE // DO NOT MODIFY!
+ bsA = 4195;
+ bsB = CARBIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CARBIDE with value 4195 from .dat file mismatches hardcoded c++ define value of " << CARBIDE << "!" << std::endl;
+#endif
+
+
+#ifdef CARPET // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CARPET;
+ if(bsA!=bsB)
+ ssErrors << "Defined CARPET with value 4 from .dat file mismatches hardcoded c++ define value of " << CARPET << "!" << std::endl;
+#endif
+
+
+#ifdef CARROT_FLESH // DO NOT MODIFY!
+ bsA = 8200;
+ bsB = CARROT_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CARROT_FLESH with value 8200 from .dat file mismatches hardcoded c++ define value of " << CARROT_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CAT_FLESH // DO NOT MODIFY!
+ bsA = 20504;
+ bsB = CAT_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAT_FLESH with value 20504 from .dat file mismatches hardcoded c++ define value of " << CAT_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CAUCASIAN_SIREN // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CAUCASIAN_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAUCASIAN_SIREN with value 3 from .dat file mismatches hardcoded c++ define value of " << CAUCASIAN_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef CAVE_BEAR // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CAVE_BEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined CAVE_BEAR with value 3 from .dat file mismatches hardcoded c++ define value of " << CAVE_BEAR << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_ANTIDOTE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = CEM_ANTIDOTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_ANTIDOTE with value 8 from .dat file mismatches hardcoded c++ define value of " << CEM_ANTIDOTE << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_BLACK_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 12;
+ bsB = CEM_BLACK_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_BLACK_UNICORN_FLESH with value 12 from .dat file mismatches hardcoded c++ define value of " << CEM_BLACK_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_BONE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CEM_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_BONE with value 2 from .dat file mismatches hardcoded c++ define value of " << CEM_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_COCA_COLA // DO NOT MODIFY!
+ bsA = 16;
+ bsB = CEM_COCA_COLA;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_COCA_COLA with value 16 from .dat file mismatches hardcoded c++ define value of " << CEM_COCA_COLA << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_ESP // DO NOT MODIFY!
+ bsA = 9;
+ bsB = CEM_ESP;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_ESP with value 9 from .dat file mismatches hardcoded c++ define value of " << CEM_ESP << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_FROG_FLESH // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CEM_FROG_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_FROG_FLESH with value 3 from .dat file mismatches hardcoded c++ define value of " << CEM_FROG_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_GRAY_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 13;
+ bsB = CEM_GRAY_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_GRAY_UNICORN_FLESH with value 13 from .dat file mismatches hardcoded c++ define value of " << CEM_GRAY_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_HEALING_LIQUID // DO NOT MODIFY!
+ bsA = 7;
+ bsB = CEM_HEALING_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_HEALING_LIQUID with value 7 from .dat file mismatches hardcoded c++ define value of " << CEM_HEALING_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_HOLY_BANANA // DO NOT MODIFY!
+ bsA = 10;
+ bsB = CEM_HOLY_BANANA;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_HOLY_BANANA with value 10 from .dat file mismatches hardcoded c++ define value of " << CEM_HOLY_BANANA << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_KOBOLD_FLESH // DO NOT MODIFY!
+ bsA = 6;
+ bsB = CEM_KOBOLD_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_KOBOLD_FLESH with value 6 from .dat file mismatches hardcoded c++ define value of " << CEM_KOBOLD_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_LIQUID_HORROR // DO NOT MODIFY!
+ bsA = 17;
+ bsB = CEM_LIQUID_HORROR;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_LIQUID_HORROR with value 17 from .dat file mismatches hardcoded c++ define value of " << CEM_LIQUID_HORROR << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_NOTHING // DO NOT MODIFY!
+ bsA = 0;
+ bsB = CEM_NOTHING;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_NOTHING with value 0 from .dat file mismatches hardcoded c++ define value of " << CEM_NOTHING << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_OMMEL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CEM_OMMEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_OMMEL with value 4 from .dat file mismatches hardcoded c++ define value of " << CEM_OMMEL << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_OMMEL_BONE // DO NOT MODIFY!
+ bsA = 15;
+ bsB = CEM_OMMEL_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_OMMEL_BONE with value 15 from .dat file mismatches hardcoded c++ define value of " << CEM_OMMEL_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_PEA_SOUP // DO NOT MODIFY!
+ bsA = 11;
+ bsB = CEM_PEA_SOUP;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_PEA_SOUP with value 11 from .dat file mismatches hardcoded c++ define value of " << CEM_PEA_SOUP << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_PEPSI // DO NOT MODIFY!
+ bsA = 5;
+ bsB = CEM_PEPSI;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_PEPSI with value 5 from .dat file mismatches hardcoded c++ define value of " << CEM_PEPSI << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_SCHOOL_FOOD // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CEM_SCHOOL_FOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_SCHOOL_FOOD with value 1 from .dat file mismatches hardcoded c++ define value of " << CEM_SCHOOL_FOOD << "!" << std::endl;
+#endif
+
+
+#ifdef CEM_WHITE_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 14;
+ bsB = CEM_WHITE_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CEM_WHITE_UNICORN_FLESH with value 14 from .dat file mismatches hardcoded c++ define value of " << CEM_WHITE_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CENTER // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CENTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined CENTER with value 4 from .dat file mismatches hardcoded c++ define value of " << CENTER << "!" << std::endl;
+#endif
+
+
+#ifdef CHAIN_MAIL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CHAIN_MAIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHAIN_MAIL with value 1 from .dat file mismatches hardcoded c++ define value of " << CHAIN_MAIL << "!" << std::endl;
+#endif
+
+
+#ifdef CHAIR // DO NOT MODIFY!
+ bsA = 6;
+ bsB = CHAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHAIR with value 6 from .dat file mismatches hardcoded c++ define value of " << CHAIR << "!" << std::endl;
+#endif
+
+
+#ifdef CHALCEDONY // DO NOT MODIFY!
+ bsA = 4270;
+ bsB = CHALCEDONY;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHALCEDONY with value 4270 from .dat file mismatches hardcoded c++ define value of " << CHALCEDONY << "!" << std::endl;
+#endif
+
+
+#ifdef CHALK // DO NOT MODIFY!
+ bsA = 4276;
+ bsB = CHALK;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHALK with value 4276 from .dat file mismatches hardcoded c++ define value of " << CHALK << "!" << std::endl;
+#endif
+
+
+#ifdef CHAMELEON_FLESH // DO NOT MODIFY!
+ bsA = 20518;
+ bsB = CHAMELEON_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHAMELEON_FLESH with value 20518 from .dat file mismatches hardcoded c++ define value of " << CHAMELEON_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef CHARISMA // DO NOT MODIFY!
+ bsA = 5;
+ bsB = CHARISMA;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHARISMA with value 5 from .dat file mismatches hardcoded c++ define value of " << CHARISMA << "!" << std::endl;
+#endif
+
+
+#ifdef CHAR_COAL // DO NOT MODIFY!
+ bsA = 4192;
+ bsB = CHAR_COAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHAR_COAL with value 4192 from .dat file mismatches hardcoded c++ define value of " << CHAR_COAL << "!" << std::endl;
+#endif
+
+
+#ifdef CHEAP // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CHEAP;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHEAP with value 1 from .dat file mismatches hardcoded c++ define value of " << CHEAP << "!" << std::endl;
+#endif
+
+
+#ifdef CHEAP_BED // DO NOT MODIFY!
+ bsA = 10;
+ bsB = CHEAP_BED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHEAP_BED with value 10 from .dat file mismatches hardcoded c++ define value of " << CHEAP_BED << "!" << std::endl;
+#endif
+
+
+#ifdef CHEESE // DO NOT MODIFY!
+ bsA = 8208;
+ bsB = CHEESE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHEESE with value 8208 from .dat file mismatches hardcoded c++ define value of " << CHEESE << "!" << std::endl;
+#endif
+
+
+#ifdef CHEST // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CHEST;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHEST with value 2 from .dat file mismatches hardcoded c++ define value of " << CHEST << "!" << std::endl;
+#endif
+
+
+#ifdef CHEST_OF_DRAWERS // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CHEST_OF_DRAWERS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHEST_OF_DRAWERS with value 2 from .dat file mismatches hardcoded c++ define value of " << CHEST_OF_DRAWERS << "!" << std::endl;
+#endif
+
+
+#ifdef CHICKEN_SOUP // DO NOT MODIFY!
+ bsA = 16390;
+ bsB = CHICKEN_SOUP;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHICKEN_SOUP with value 16390 from .dat file mismatches hardcoded c++ define value of " << CHICKEN_SOUP << "!" << std::endl;
+#endif
+
+
+#ifdef CHILD // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CHILD;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHILD with value 3 from .dat file mismatches hardcoded c++ define value of " << CHILD << "!" << std::endl;
+#endif
+
+
+#ifdef CHITINE // DO NOT MODIFY!
+ bsA = 4249;
+ bsB = CHITINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHITINE with value 4249 from .dat file mismatches hardcoded c++ define value of " << CHITINE << "!" << std::endl;
+#endif
+
+
+#ifdef CHLOROPHYTE // DO NOT MODIFY!
+ bsA = 4221;
+ bsB = CHLOROPHYTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHLOROPHYTE with value 4221 from .dat file mismatches hardcoded c++ define value of " << CHLOROPHYTE << "!" << std::endl;
+#endif
+
+
+#ifdef CHOCOLATE // DO NOT MODIFY!
+ bsA = 8209;
+ bsB = CHOCOLATE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHOCOLATE with value 8209 from .dat file mismatches hardcoded c++ define value of " << CHOCOLATE << "!" << std::endl;
+#endif
+
+
+#ifdef CHROME // DO NOT MODIFY!
+ bsA = 4126;
+ bsB = CHROME;
+ if(bsA!=bsB)
+ ssErrors << "Defined CHROME with value 4126 from .dat file mismatches hardcoded c++ define value of " << CHROME << "!" << std::endl;
+#endif
+
+
+#ifdef CIDER // DO NOT MODIFY!
+ bsA = 16401;
+ bsB = CIDER;
+ if(bsA!=bsB)
+ ssErrors << "Defined CIDER with value 16401 from .dat file mismatches hardcoded c++ define value of " << CIDER << "!" << std::endl;
+#endif
+
+
+#ifdef CITRINE // DO NOT MODIFY!
+ bsA = 4278;
+ bsB = CITRINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CITRINE with value 4278 from .dat file mismatches hardcoded c++ define value of " << CITRINE << "!" << std::endl;
+#endif
+
+
+#ifdef CLAW // DO NOT MODIFY!
+ bsA = 21;
+ bsB = CLAW;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLAW with value 21 from .dat file mismatches hardcoded c++ define value of " << CLAW << "!" << std::endl;
+#endif
+
+
+#ifdef CLAY // DO NOT MODIFY!
+ bsA = 4318;
+ bsB = CLAY;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLAY with value 4318 from .dat file mismatches hardcoded c++ define value of " << CLAY << "!" << std::endl;
+#endif
+
+
+#ifdef CLEPTIA // DO NOT MODIFY!
+ bsA = 10;
+ bsB = CLEPTIA;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLEPTIA with value 10 from .dat file mismatches hardcoded c++ define value of " << CLEPTIA << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CLOAK;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK with value 4 from .dat file mismatches hardcoded c++ define value of " << CLOAK << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_INDEX // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CLOAK_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_INDEX with value 2 from .dat file mismatches hardcoded c++ define value of " << CLOAK_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_ACID_RESISTANCE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CLOAK_OF_ACID_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_ACID_RESISTANCE with value 4 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_ACID_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_ELECTRICITY_RESISTANCE // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CLOAK_OF_ELECTRICITY_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_ELECTRICITY_RESISTANCE with value 3 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_ELECTRICITY_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_FIRE_RESISTANCE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CLOAK_OF_FIRE_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_FIRE_RESISTANCE with value 2 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_FIRE_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_FLYING // DO NOT MODIFY!
+ bsA = 8;
+ bsB = CLOAK_OF_FLYING;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_FLYING with value 8 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_FLYING << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_INVISIBILITY // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CLOAK_OF_INVISIBILITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_INVISIBILITY with value 1 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_INVISIBILITY << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_ORCS // DO NOT MODIFY!
+ bsA = 7;
+ bsB = CLOAK_OF_ORCS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_ORCS with value 7 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_ORCS << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_PROTECTION // DO NOT MODIFY!
+ bsA = 10;
+ bsB = CLOAK_OF_PROTECTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_PROTECTION with value 10 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_PROTECTION << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_QUICKNESS // DO NOT MODIFY!
+ bsA = 9;
+ bsB = CLOAK_OF_QUICKNESS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_QUICKNESS with value 9 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_QUICKNESS << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_SHADOWS // DO NOT MODIFY!
+ bsA = 5;
+ bsB = CLOAK_OF_SHADOWS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_SHADOWS with value 5 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_SHADOWS << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_VAMPIRE // DO NOT MODIFY!
+ bsA = 11;
+ bsB = CLOAK_OF_VAMPIRE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_VAMPIRE with value 11 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_VAMPIRE << "!" << std::endl;
+#endif
+
+
+#ifdef CLOAK_OF_WEREWOLF // DO NOT MODIFY!
+ bsA = 6;
+ bsB = CLOAK_OF_WEREWOLF;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOAK_OF_WEREWOLF with value 6 from .dat file mismatches hardcoded c++ define value of " << CLOAK_OF_WEREWOLF << "!" << std::endl;
+#endif
+
+
+#ifdef CLOTH_COLOR // DO NOT MODIFY!
+ bsA = 2834;
+ bsB = CLOTH_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined CLOTH_COLOR with value 2834 from .dat file mismatches hardcoded c++ define value of " << CLOTH_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef COAL // DO NOT MODIFY!
+ bsA = 4193;
+ bsB = COAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined COAL with value 4193 from .dat file mismatches hardcoded c++ define value of " << COAL << "!" << std::endl;
+#endif
+
+
+#ifdef COBALT // DO NOT MODIFY!
+ bsA = 4122;
+ bsB = COBALT;
+ if(bsA!=bsB)
+ ssErrors << "Defined COBALT with value 4122 from .dat file mismatches hardcoded c++ define value of " << COBALT << "!" << std::endl;
+#endif
+
+
+#ifdef COBBLE_STONE // DO NOT MODIFY!
+ bsA = 4259;
+ bsB = COBBLE_STONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined COBBLE_STONE with value 4259 from .dat file mismatches hardcoded c++ define value of " << COBBLE_STONE << "!" << std::endl;
+#endif
+
+
+#ifdef COCA_COLA // DO NOT MODIFY!
+ bsA = 16395;
+ bsB = COCA_COLA;
+ if(bsA!=bsB)
+ ssErrors << "Defined COCA_COLA with value 16395 from .dat file mismatches hardcoded c++ define value of " << COCA_COLA << "!" << std::endl;
+#endif
+
+
+#ifdef COLONIST_TEAM // DO NOT MODIFY!
+ bsA = 8;
+ bsB = COLONIST_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined COLONIST_TEAM with value 8 from .dat file mismatches hardcoded c++ define value of " << COLONIST_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef CONCRETE // DO NOT MODIFY!
+ bsA = 4313;
+ bsB = CONCRETE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CONCRETE with value 4313 from .dat file mismatches hardcoded c++ define value of " << CONCRETE << "!" << std::endl;
+#endif
+
+
+#ifdef CONFUSED // DO NOT MODIFY!
+ bsA = 16384;
+ bsB = CONFUSED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CONFUSED with value 16384 from .dat file mismatches hardcoded c++ define value of " << CONFUSED << "!" << std::endl;
+#endif
+
+
+#ifdef CONFUSION // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CONFUSION;
+ if(bsA!=bsB)
+ ssErrors << "Defined CONFUSION with value 3 from .dat file mismatches hardcoded c++ define value of " << CONFUSION << "!" << std::endl;
+#endif
+
+
+#ifdef CONICAL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CONICAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CONICAL with value 1 from .dat file mismatches hardcoded c++ define value of " << CONICAL << "!" << std::endl;
+#endif
+
+
+#ifdef COPPER // DO NOT MODIFY!
+ bsA = 4099;
+ bsB = COPPER;
+ if(bsA!=bsB)
+ ssErrors << "Defined COPPER with value 4099 from .dat file mismatches hardcoded c++ define value of " << COPPER << "!" << std::endl;
+#endif
+
+
+#ifdef CORAL // DO NOT MODIFY!
+ bsA = 4286;
+ bsB = CORAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CORAL with value 4286 from .dat file mismatches hardcoded c++ define value of " << CORAL << "!" << std::endl;
+#endif
+
+
+#ifdef COUCH // DO NOT MODIFY!
+ bsA = 5;
+ bsB = COUCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined COUCH with value 5 from .dat file mismatches hardcoded c++ define value of " << COUCH << "!" << std::endl;
+#endif
+
+
+#ifdef CRAZED_FARMER // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CRAZED_FARMER;
+ if(bsA!=bsB)
+ ssErrors << "Defined CRAZED_FARMER with value 3 from .dat file mismatches hardcoded c++ define value of " << CRAZED_FARMER << "!" << std::endl;
+#endif
+
+
+#ifdef CREATE_DIVINE_CONFIGURATIONS // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CREATE_DIVINE_CONFIGURATIONS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CREATE_DIVINE_CONFIGURATIONS with value 4 from .dat file mismatches hardcoded c++ define value of " << CREATE_DIVINE_CONFIGURATIONS << "!" << std::endl;
+#endif
+
+
+#ifdef CROCODILE_SKIN // DO NOT MODIFY!
+ bsA = 4145;
+ bsB = CROCODILE_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined CROCODILE_SKIN with value 4145 from .dat file mismatches hardcoded c++ define value of " << CROCODILE_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef CRUENTUS // DO NOT MODIFY!
+ bsA = 14;
+ bsB = CRUENTUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CRUENTUS with value 14 from .dat file mismatches hardcoded c++ define value of " << CRUENTUS << "!" << std::endl;
+#endif
+
+
+#ifdef CRYSTAL_LEVEL // DO NOT MODIFY!
+ bsA = 3;
+ bsB = CRYSTAL_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CRYSTAL_LEVEL with value 3 from .dat file mismatches hardcoded c++ define value of " << CRYSTAL_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef CT_BONE // DO NOT MODIFY!
+ bsA = 32;
+ bsB = CT_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_BONE with value 32 from .dat file mismatches hardcoded c++ define value of " << CT_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef CT_FRUIT // DO NOT MODIFY!
+ bsA = 1;
+ bsB = CT_FRUIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_FRUIT with value 1 from .dat file mismatches hardcoded c++ define value of " << CT_FRUIT << "!" << std::endl;
+#endif
+
+
+#ifdef CT_GAS // DO NOT MODIFY!
+ bsA = 512;
+ bsB = CT_GAS;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_GAS with value 512 from .dat file mismatches hardcoded c++ define value of " << CT_GAS << "!" << std::endl;
+#endif
+
+
+#ifdef CT_LIQUID // DO NOT MODIFY!
+ bsA = 16;
+ bsB = CT_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_LIQUID with value 16 from .dat file mismatches hardcoded c++ define value of " << CT_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef CT_MEAT // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CT_MEAT;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_MEAT with value 2 from .dat file mismatches hardcoded c++ define value of " << CT_MEAT << "!" << std::endl;
+#endif
+
+
+#ifdef CT_METAL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = CT_METAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_METAL with value 4 from .dat file mismatches hardcoded c++ define value of " << CT_METAL << "!" << std::endl;
+#endif
+
+
+#ifdef CT_MINERAL // DO NOT MODIFY!
+ bsA = 8;
+ bsB = CT_MINERAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_MINERAL with value 8 from .dat file mismatches hardcoded c++ define value of " << CT_MINERAL << "!" << std::endl;
+#endif
+
+
+#ifdef CT_MISC_ORGANIC // DO NOT MODIFY!
+ bsA = 128;
+ bsB = CT_MISC_ORGANIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_MISC_ORGANIC with value 128 from .dat file mismatches hardcoded c++ define value of " << CT_MISC_ORGANIC << "!" << std::endl;
+#endif
+
+
+#ifdef CT_PLASTIC // DO NOT MODIFY!
+ bsA = 256;
+ bsB = CT_PLASTIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_PLASTIC with value 256 from .dat file mismatches hardcoded c++ define value of " << CT_PLASTIC << "!" << std::endl;
+#endif
+
+
+#ifdef CT_PROCESSED // DO NOT MODIFY!
+ bsA = 64;
+ bsB = CT_PROCESSED;
+ if(bsA!=bsB)
+ ssErrors << "Defined CT_PROCESSED with value 64 from .dat file mismatches hardcoded c++ define value of " << CT_PROCESSED << "!" << std::endl;
+#endif
+
+
+#ifdef CULTIST // DO NOT MODIFY!
+ bsA = 2;
+ bsB = CULTIST;
+ if(bsA!=bsB)
+ ssErrors << "Defined CULTIST with value 2 from .dat file mismatches hardcoded c++ define value of " << CULTIST << "!" << std::endl;
+#endif
+
+
+#ifdef CURE_ALL_LIQUID // DO NOT MODIFY!
+ bsA = 16386;
+ bsB = CURE_ALL_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined CURE_ALL_LIQUID with value 16386 from .dat file mismatches hardcoded c++ define value of " << CURE_ALL_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef CUSTARD // DO NOT MODIFY!
+ bsA = 16392;
+ bsB = CUSTARD;
+ if(bsA!=bsB)
+ ssErrors << "Defined CUSTARD with value 16392 from .dat file mismatches hardcoded c++ define value of " << CUSTARD << "!" << std::endl;
+#endif
+
+
+#ifdef CYPRESS_WOOD // DO NOT MODIFY!
+ bsA = 4231;
+ bsB = CYPRESS_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined CYPRESS_WOOD with value 4231 from .dat file mismatches hardcoded c++ define value of " << CYPRESS_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef DAEMON_FLESH // DO NOT MODIFY!
+ bsA = 20508;
+ bsB = DAEMON_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DAEMON_FLESH with value 20508 from .dat file mismatches hardcoded c++ define value of " << DAEMON_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef DAGGER // DO NOT MODIFY!
+ bsA = 10;
+ bsB = DAGGER;
+ if(bsA!=bsB)
+ ssErrors << "Defined DAGGER with value 10 from .dat file mismatches hardcoded c++ define value of " << DAGGER << "!" << std::endl;
+#endif
+
+
+#ifdef DARK // DO NOT MODIFY!
+ bsA = 1;
+ bsB = DARK;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK with value 1 from .dat file mismatches hardcoded c++ define value of " << DARK << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_ASIAN_SIREN // DO NOT MODIFY!
+ bsA = 2;
+ bsB = DARK_ASIAN_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_ASIAN_SIREN with value 2 from .dat file mismatches hardcoded c++ define value of " << DARK_ASIAN_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_BREAD // DO NOT MODIFY!
+ bsA = 8204;
+ bsB = DARK_BREAD;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_BREAD with value 8204 from .dat file mismatches hardcoded c++ define value of " << DARK_BREAD << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_FROG_BLOOD // DO NOT MODIFY!
+ bsA = 16425;
+ bsB = DARK_FROG_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_FROG_BLOOD with value 16425 from .dat file mismatches hardcoded c++ define value of " << DARK_FROG_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_GOLD // DO NOT MODIFY!
+ bsA = 4116;
+ bsB = DARK_GOLD;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_GOLD with value 4116 from .dat file mismatches hardcoded c++ define value of " << DARK_GOLD << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_GRASS // DO NOT MODIFY!
+ bsA = 4214;
+ bsB = DARK_GRASS;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_GRASS with value 4214 from .dat file mismatches hardcoded c++ define value of " << DARK_GRASS << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_GRASS_TERRAIN // DO NOT MODIFY!
+ bsA = 7;
+ bsB = DARK_GRASS_TERRAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_GRASS_TERRAIN with value 7 from .dat file mismatches hardcoded c++ define value of " << DARK_GRASS_TERRAIN << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_GRAY // DO NOT MODIFY!
+ bsA = 21130;
+ bsB = DARK_GRAY;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_GRAY with value 21130 from .dat file mismatches hardcoded c++ define value of " << DARK_GRAY << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_LEVEL // DO NOT MODIFY!
+ bsA = 8;
+ bsB = DARK_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_LEVEL with value 8 from .dat file mismatches hardcoded c++ define value of " << DARK_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_MATTER // DO NOT MODIFY!
+ bsA = 4117;
+ bsB = DARK_MATTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_MATTER with value 4117 from .dat file mismatches hardcoded c++ define value of " << DARK_MATTER << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_PETAL // DO NOT MODIFY!
+ bsA = 4219;
+ bsB = DARK_PETAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_PETAL with value 4219 from .dat file mismatches hardcoded c++ define value of " << DARK_PETAL << "!" << std::endl;
+#endif
+
+
+#ifdef DARK_SIREN // DO NOT MODIFY!
+ bsA = 4;
+ bsB = DARK_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined DARK_SIREN with value 4 from .dat file mismatches hardcoded c++ define value of " << DARK_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef DEAD_FISH // DO NOT MODIFY!
+ bsA = 3;
+ bsB = DEAD_FISH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEAD_FISH with value 3 from .dat file mismatches hardcoded c++ define value of " << DEAD_FISH << "!" << std::endl;
+#endif
+
+
+#ifdef DEAD_TREE // DO NOT MODIFY!
+ bsA = 37;
+ bsB = DEAD_TREE;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEAD_TREE with value 37 from .dat file mismatches hardcoded c++ define value of " << DEAD_TREE << "!" << std::endl;
+#endif
+
+
+#ifdef DEEP_BRONZE // DO NOT MODIFY!
+ bsA = 4102;
+ bsB = DEEP_BRONZE;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEEP_BRONZE with value 4102 from .dat file mismatches hardcoded c++ define value of " << DEEP_BRONZE << "!" << std::endl;
+#endif
+
+
+#ifdef DEEP_CORAL // DO NOT MODIFY!
+ bsA = 4287;
+ bsB = DEEP_CORAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEEP_CORAL with value 4287 from .dat file mismatches hardcoded c++ define value of " << DEEP_CORAL << "!" << std::endl;
+#endif
+
+
+#ifdef DEFAULT_TEAM // DO NOT MODIFY!
+ bsA = 255;
+ bsB = DEFAULT_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEFAULT_TEAM with value 255 from .dat file mismatches hardcoded c++ define value of " << DEFAULT_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef DEFINITE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = DEFINITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEFINITE with value 2 from .dat file mismatches hardcoded c++ define value of " << DEFINITE << "!" << std::endl;
+#endif
+
+
+#ifdef DEPENDS_ON_ATTRIBUTES // DO NOT MODIFY!
+ bsA = 65535;
+ bsB = DEPENDS_ON_ATTRIBUTES;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEPENDS_ON_ATTRIBUTES with value 65535 from .dat file mismatches hardcoded c++ define value of " << DEPENDS_ON_ATTRIBUTES << "!" << std::endl;
+#endif
+
+
+#ifdef DESERT // DO NOT MODIFY!
+ bsA = 1;
+ bsB = DESERT;
+ if(bsA!=bsB)
+ ssErrors << "Defined DESERT with value 1 from .dat file mismatches hardcoded c++ define value of " << DESERT << "!" << std::endl;
+#endif
+
+
+#ifdef DESK // DO NOT MODIFY!
+ bsA = 31;
+ bsB = DESK;
+ if(bsA!=bsB)
+ ssErrors << "Defined DESK with value 31 from .dat file mismatches hardcoded c++ define value of " << DESK << "!" << std::endl;
+#endif
+
+
+#ifdef DETECTING // DO NOT MODIFY!
+ bsA = 16777216;
+ bsB = DETECTING;
+ if(bsA!=bsB)
+ ssErrors << "Defined DETECTING with value 16777216 from .dat file mismatches hardcoded c++ define value of " << DETECTING << "!" << std::endl;
+#endif
+
+
+#ifdef DEXTERITY // DO NOT MODIFY!
+ bsA = 9;
+ bsB = DEXTERITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined DEXTERITY with value 9 from .dat file mismatches hardcoded c++ define value of " << DEXTERITY << "!" << std::endl;
+#endif
+
+
+#ifdef DIAMOND // DO NOT MODIFY!
+ bsA = 4298;
+ bsB = DIAMOND;
+ if(bsA!=bsB)
+ ssErrors << "Defined DIAMOND with value 4298 from .dat file mismatches hardcoded c++ define value of " << DIAMOND << "!" << std::endl;
+#endif
+
+
+#ifdef DIRT // DO NOT MODIFY!
+ bsA = 24583;
+ bsB = DIRT;
+ if(bsA!=bsB)
+ ssErrors << "Defined DIRT with value 24583 from .dat file mismatches hardcoded c++ define value of " << DIRT << "!" << std::endl;
+#endif
+
+
+#ifdef DISEASE_IMMUNITY // DO NOT MODIFY!
+ bsA = 134217728;
+ bsB = DISEASE_IMMUNITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined DISEASE_IMMUNITY with value 134217728 from .dat file mismatches hardcoded c++ define value of " << DISEASE_IMMUNITY << "!" << std::endl;
+#endif
+
+
+#ifdef DOG_DROOL // DO NOT MODIFY!
+ bsA = 16417;
+ bsB = DOG_DROOL;
+ if(bsA!=bsB)
+ ssErrors << "Defined DOG_DROOL with value 16417 from .dat file mismatches hardcoded c++ define value of " << DOG_DROOL << "!" << std::endl;
+#endif
+
+
+#ifdef DOG_FLESH // DO NOT MODIFY!
+ bsA = 20495;
+ bsB = DOG_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DOG_FLESH with value 20495 from .dat file mismatches hardcoded c++ define value of " << DOG_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef DOLPHIN_FLESH // DO NOT MODIFY!
+ bsA = 20492;
+ bsB = DOLPHIN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DOLPHIN_FLESH with value 20492 from .dat file mismatches hardcoded c++ define value of " << DOLPHIN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef DONT_CHANGE_EQUIPMENT // DO NOT MODIFY!
+ bsA = 4;
+ bsB = DONT_CHANGE_EQUIPMENT;
+ if(bsA!=bsB)
+ ssErrors << "Defined DONT_CHANGE_EQUIPMENT with value 4 from .dat file mismatches hardcoded c++ define value of " << DONT_CHANGE_EQUIPMENT << "!" << std::endl;
+#endif
+
+
+#ifdef DONT_CONSUME_ANYTHING_VALUABLE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = DONT_CONSUME_ANYTHING_VALUABLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined DONT_CONSUME_ANYTHING_VALUABLE with value 8 from .dat file mismatches hardcoded c++ define value of " << DONT_CONSUME_ANYTHING_VALUABLE << "!" << std::endl;
+#endif
+
+
+#ifdef DOUBLE_BED // DO NOT MODIFY!
+ bsA = 9;
+ bsB = DOUBLE_BED;
+ if(bsA!=bsB)
+ ssErrors << "Defined DOUBLE_BED with value 9 from .dat file mismatches hardcoded c++ define value of " << DOUBLE_BED << "!" << std::endl;
+#endif
+
+
+#ifdef DOWN // DO NOT MODIFY!
+ bsA = 1;
+ bsB = DOWN;
+ if(bsA!=bsB)
+ ssErrors << "Defined DOWN with value 1 from .dat file mismatches hardcoded c++ define value of " << DOWN << "!" << std::endl;
+#endif
+
+
+#ifdef DRAGON_BONE // DO NOT MODIFY!
+ bsA = 4255;
+ bsB = DRAGON_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined DRAGON_BONE with value 4255 from .dat file mismatches hardcoded c++ define value of " << DRAGON_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef DRAGON_HIDE // DO NOT MODIFY!
+ bsA = 4158;
+ bsB = DRAGON_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined DRAGON_HIDE with value 4158 from .dat file mismatches hardcoded c++ define value of " << DRAGON_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef DRAIN // DO NOT MODIFY!
+ bsA = 128;
+ bsB = DRAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined DRAIN with value 128 from .dat file mismatches hardcoded c++ define value of " << DRAIN << "!" << std::endl;
+#endif
+
+
+#ifdef DREAM_CLOTH // DO NOT MODIFY!
+ bsA = 4173;
+ bsB = DREAM_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DREAM_CLOTH with value 4173 from .dat file mismatches hardcoded c++ define value of " << DREAM_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef DRUID // DO NOT MODIFY!
+ bsA = 1;
+ bsB = DRUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined DRUID with value 1 from .dat file mismatches hardcoded c++ define value of " << DRUID << "!" << std::endl;
+#endif
+
+
+#ifdef DUAL_ENNER_BEAST_LEVEL // DO NOT MODIFY!
+ bsA = 5;
+ bsB = DUAL_ENNER_BEAST_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined DUAL_ENNER_BEAST_LEVEL with value 5 from .dat file mismatches hardcoded c++ define value of " << DUAL_ENNER_BEAST_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef DULCIS // DO NOT MODIFY!
+ bsA = 4;
+ bsB = DULCIS;
+ if(bsA!=bsB)
+ ssErrors << "Defined DULCIS with value 4 from .dat file mismatches hardcoded c++ define value of " << DULCIS << "!" << std::endl;
+#endif
+
+
+#ifdef DURALLOY // DO NOT MODIFY!
+ bsA = 4190;
+ bsB = DURALLOY;
+ if(bsA!=bsB)
+ ssErrors << "Defined DURALLOY with value 4190 from .dat file mismatches hardcoded c++ define value of " << DURALLOY << "!" << std::endl;
+#endif
+
+
+#ifdef DWARF_BEER // DO NOT MODIFY!
+ bsA = 16406;
+ bsB = DWARF_BEER;
+ if(bsA!=bsB)
+ ssErrors << "Defined DWARF_BEER with value 16406 from .dat file mismatches hardcoded c++ define value of " << DWARF_BEER << "!" << std::endl;
+#endif
+
+
+#ifdef DWARF_BIRCH // DO NOT MODIFY!
+ bsA = 24;
+ bsB = DWARF_BIRCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DWARF_BIRCH with value 24 from .dat file mismatches hardcoded c++ define value of " << DWARF_BIRCH << "!" << std::endl;
+#endif
+
+
+#ifdef DWARF_FLESH // DO NOT MODIFY!
+ bsA = 20507;
+ bsB = DWARF_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined DWARF_FLESH with value 20507 from .dat file mismatches hardcoded c++ define value of " << DWARF_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef DWARF_STEEL // DO NOT MODIFY!
+ bsA = 28676;
+ bsB = DWARF_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined DWARF_STEEL with value 28676 from .dat file mismatches hardcoded c++ define value of " << DWARF_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef EBONY_WOOD // DO NOT MODIFY!
+ bsA = 4243;
+ bsB = EBONY_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined EBONY_WOOD with value 4243 from .dat file mismatches hardcoded c++ define value of " << EBONY_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef ECTOPLASM // DO NOT MODIFY!
+ bsA = 12294;
+ bsB = ECTOPLASM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ECTOPLASM with value 12294 from .dat file mismatches hardcoded c++ define value of " << ECTOPLASM << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_ANTIDOTE // DO NOT MODIFY!
+ bsA = 9;
+ bsB = EFFECT_ANTIDOTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_ANTIDOTE with value 9 from .dat file mismatches hardcoded c++ define value of " << EFFECT_ANTIDOTE << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_BLACK_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 20;
+ bsB = EFFECT_BLACK_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_BLACK_UNICORN_FLESH with value 20 from .dat file mismatches hardcoded c++ define value of " << EFFECT_BLACK_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_CONFUSE // DO NOT MODIFY!
+ bsA = 10;
+ bsB = EFFECT_CONFUSE;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_CONFUSE with value 10 from .dat file mismatches hardcoded c++ define value of " << EFFECT_CONFUSE << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_DARKNESS // DO NOT MODIFY!
+ bsA = 2;
+ bsB = EFFECT_DARKNESS;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_DARKNESS with value 2 from .dat file mismatches hardcoded c++ define value of " << EFFECT_DARKNESS << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_ESP // DO NOT MODIFY!
+ bsA = 12;
+ bsB = EFFECT_ESP;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_ESP with value 12 from .dat file mismatches hardcoded c++ define value of " << EFFECT_ESP << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_EVIL_WONDER_STAFF_VAPOUR // DO NOT MODIFY!
+ bsA = 17;
+ bsB = EFFECT_EVIL_WONDER_STAFF_VAPOUR;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_EVIL_WONDER_STAFF_VAPOUR with value 17 from .dat file mismatches hardcoded c++ define value of " << EFFECT_EVIL_WONDER_STAFF_VAPOUR << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_GOOD_WONDER_STAFF_VAPOUR // DO NOT MODIFY!
+ bsA = 18;
+ bsB = EFFECT_GOOD_WONDER_STAFF_VAPOUR;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_GOOD_WONDER_STAFF_VAPOUR with value 18 from .dat file mismatches hardcoded c++ define value of " << EFFECT_GOOD_WONDER_STAFF_VAPOUR << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_GRAY_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 21;
+ bsB = EFFECT_GRAY_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_GRAY_UNICORN_FLESH with value 21 from .dat file mismatches hardcoded c++ define value of " << EFFECT_GRAY_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_HEAL // DO NOT MODIFY!
+ bsA = 6;
+ bsB = EFFECT_HEAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_HEAL with value 6 from .dat file mismatches hardcoded c++ define value of " << EFFECT_HEAL << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_HOLY_BANANA // DO NOT MODIFY!
+ bsA = 16;
+ bsB = EFFECT_HOLY_BANANA;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_HOLY_BANANA with value 16 from .dat file mismatches hardcoded c++ define value of " << EFFECT_HOLY_BANANA << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_IS_GOOD // DO NOT MODIFY!
+ bsA = 16;
+ bsB = EFFECT_IS_GOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_IS_GOOD with value 16 from .dat file mismatches hardcoded c++ define value of " << EFFECT_IS_GOOD << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_KOBOLD_FLESH // DO NOT MODIFY!
+ bsA = 5;
+ bsB = EFFECT_KOBOLD_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_KOBOLD_FLESH with value 5 from .dat file mismatches hardcoded c++ define value of " << EFFECT_KOBOLD_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_LYCANTHROPY // DO NOT MODIFY!
+ bsA = 7;
+ bsB = EFFECT_LYCANTHROPY;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_LYCANTHROPY with value 7 from .dat file mismatches hardcoded c++ define value of " << EFFECT_LYCANTHROPY << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_MAGIC_MUSHROOM // DO NOT MODIFY!
+ bsA = 14;
+ bsB = EFFECT_MAGIC_MUSHROOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_MAGIC_MUSHROOM with value 14 from .dat file mismatches hardcoded c++ define value of " << EFFECT_MAGIC_MUSHROOM << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_MUSHROOM // DO NOT MODIFY!
+ bsA = 24;
+ bsB = EFFECT_MUSHROOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_MUSHROOM with value 24 from .dat file mismatches hardcoded c++ define value of " << EFFECT_MUSHROOM << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_MUSTARD_GAS // DO NOT MODIFY!
+ bsA = 30;
+ bsB = EFFECT_MUSTARD_GAS;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_MUSTARD_GAS with value 30 from .dat file mismatches hardcoded c++ define value of " << EFFECT_MUSTARD_GAS << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_MUSTARD_GAS_LIQUID // DO NOT MODIFY!
+ bsA = 31;
+ bsB = EFFECT_MUSTARD_GAS_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_MUSTARD_GAS_LIQUID with value 31 from .dat file mismatches hardcoded c++ define value of " << EFFECT_MUSTARD_GAS_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_NOTHING // DO NOT MODIFY!
+ bsA = 0;
+ bsB = EFFECT_NOTHING;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_NOTHING with value 0 from .dat file mismatches hardcoded c++ define value of " << EFFECT_NOTHING << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_BLOOD // DO NOT MODIFY!
+ bsA = 34;
+ bsB = EFFECT_OMMEL_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_BLOOD with value 34 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_BONE // DO NOT MODIFY!
+ bsA = 29;
+ bsB = EFFECT_OMMEL_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_BONE with value 29 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_CERUMEN // DO NOT MODIFY!
+ bsA = 25;
+ bsB = EFFECT_OMMEL_CERUMEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_CERUMEN with value 25 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_CERUMEN << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_SNOT // DO NOT MODIFY!
+ bsA = 28;
+ bsB = EFFECT_OMMEL_SNOT;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_SNOT with value 28 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_SNOT << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_SWEAT // DO NOT MODIFY!
+ bsA = 26;
+ bsB = EFFECT_OMMEL_SWEAT;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_SWEAT with value 26 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_SWEAT << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_TEARS // DO NOT MODIFY!
+ bsA = 27;
+ bsB = EFFECT_OMMEL_TEARS;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_TEARS with value 27 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_TEARS << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_OMMEL_URINE // DO NOT MODIFY!
+ bsA = 3;
+ bsB = EFFECT_OMMEL_URINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_OMMEL_URINE with value 3 from .dat file mismatches hardcoded c++ define value of " << EFFECT_OMMEL_URINE << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_PANACEA // DO NOT MODIFY!
+ bsA = 33;
+ bsB = EFFECT_PANACEA;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_PANACEA with value 33 from .dat file mismatches hardcoded c++ define value of " << EFFECT_PANACEA << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_PANIC // DO NOT MODIFY!
+ bsA = 35;
+ bsB = EFFECT_PANIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_PANIC with value 35 from .dat file mismatches hardcoded c++ define value of " << EFFECT_PANIC << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_PEA_SOUP // DO NOT MODIFY!
+ bsA = 19;
+ bsB = EFFECT_PEA_SOUP;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_PEA_SOUP with value 19 from .dat file mismatches hardcoded c++ define value of " << EFFECT_PEA_SOUP << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_PEPSI // DO NOT MODIFY!
+ bsA = 4;
+ bsB = EFFECT_PEPSI;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_PEPSI with value 4 from .dat file mismatches hardcoded c++ define value of " << EFFECT_PEPSI << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_POISON // DO NOT MODIFY!
+ bsA = 1;
+ bsB = EFFECT_POISON;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_POISON with value 1 from .dat file mismatches hardcoded c++ define value of " << EFFECT_POISON << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_POLYMORPH // DO NOT MODIFY!
+ bsA = 11;
+ bsB = EFFECT_POLYMORPH;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_POLYMORPH with value 11 from .dat file mismatches hardcoded c++ define value of " << EFFECT_POLYMORPH << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_SCHOOL_FOOD // DO NOT MODIFY!
+ bsA = 8;
+ bsB = EFFECT_SCHOOL_FOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_SCHOOL_FOOD with value 8 from .dat file mismatches hardcoded c++ define value of " << EFFECT_SCHOOL_FOOD << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_SKUNK_SMELL // DO NOT MODIFY!
+ bsA = 13;
+ bsB = EFFECT_SKUNK_SMELL;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_SKUNK_SMELL with value 13 from .dat file mismatches hardcoded c++ define value of " << EFFECT_SKUNK_SMELL << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_TELEPORT_CONTROL // DO NOT MODIFY!
+ bsA = 23;
+ bsB = EFFECT_TELEPORT_CONTROL;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_TELEPORT_CONTROL with value 23 from .dat file mismatches hardcoded c++ define value of " << EFFECT_TELEPORT_CONTROL << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_TRAIN_PERCEPTION // DO NOT MODIFY!
+ bsA = 15;
+ bsB = EFFECT_TRAIN_PERCEPTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_TRAIN_PERCEPTION with value 15 from .dat file mismatches hardcoded c++ define value of " << EFFECT_TRAIN_PERCEPTION << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_TRAIN_WISDOM // DO NOT MODIFY!
+ bsA = 36;
+ bsB = EFFECT_TRAIN_WISDOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_TRAIN_WISDOM with value 36 from .dat file mismatches hardcoded c++ define value of " << EFFECT_TRAIN_WISDOM << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_VAMPIRISM // DO NOT MODIFY!
+ bsA = 32;
+ bsB = EFFECT_VAMPIRISM;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_VAMPIRISM with value 32 from .dat file mismatches hardcoded c++ define value of " << EFFECT_VAMPIRISM << "!" << std::endl;
+#endif
+
+
+#ifdef EFFECT_WHITE_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 22;
+ bsB = EFFECT_WHITE_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined EFFECT_WHITE_UNICORN_FLESH with value 22 from .dat file mismatches hardcoded c++ define value of " << EFFECT_WHITE_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef ELASTI_CLOTH // DO NOT MODIFY!
+ bsA = 4177;
+ bsB = ELASTI_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELASTI_CLOTH with value 4177 from .dat file mismatches hardcoded c++ define value of " << ELASTI_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef ELDER // DO NOT MODIFY!
+ bsA = 3;
+ bsB = ELDER;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELDER with value 3 from .dat file mismatches hardcoded c++ define value of " << ELDER << "!" << std::endl;
+#endif
+
+
+#ifdef ELECTRICITY // DO NOT MODIFY!
+ bsA = 16;
+ bsB = ELECTRICITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELECTRICITY with value 16 from .dat file mismatches hardcoded c++ define value of " << ELECTRICITY << "!" << std::endl;
+#endif
+
+
+#ifdef ELECTRUM // DO NOT MODIFY!
+ bsA = 4119;
+ bsB = ELECTRUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELECTRUM with value 4119 from .dat file mismatches hardcoded c++ define value of " << ELECTRUM << "!" << std::endl;
+#endif
+
+
+#ifdef ELF_ALE // DO NOT MODIFY!
+ bsA = 16405;
+ bsB = ELF_ALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELF_ALE with value 16405 from .dat file mismatches hardcoded c++ define value of " << ELF_ALE << "!" << std::endl;
+#endif
+
+
+#ifdef ELF_CLOTH // DO NOT MODIFY!
+ bsA = 4133;
+ bsB = ELF_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELF_CLOTH with value 4133 from .dat file mismatches hardcoded c++ define value of " << ELF_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef ELF_FLESH // DO NOT MODIFY!
+ bsA = 20532;
+ bsB = ELF_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELF_FLESH with value 20532 from .dat file mismatches hardcoded c++ define value of " << ELF_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef ELITE // DO NOT MODIFY!
+ bsA = 6;
+ bsB = ELITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELITE with value 6 from .dat file mismatches hardcoded c++ define value of " << ELITE << "!" << std::endl;
+#endif
+
+
+#ifdef ELITE_FEMALE // DO NOT MODIFY!
+ bsA = 16;
+ bsB = ELITE_FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELITE_FEMALE with value 16 from .dat file mismatches hardcoded c++ define value of " << ELITE_FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef ELM_WOOD // DO NOT MODIFY!
+ bsA = 4229;
+ bsB = ELM_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELM_WOOD with value 4229 from .dat file mismatches hardcoded c++ define value of " << ELM_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef ELPURI_CAVE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = ELPURI_CAVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELPURI_CAVE with value 1 from .dat file mismatches hardcoded c++ define value of " << ELPURI_CAVE << "!" << std::endl;
+#endif
+
+
+#ifdef ELPURI_FLESH // DO NOT MODIFY!
+ bsA = 20490;
+ bsB = ELPURI_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ELPURI_FLESH with value 20490 from .dat file mismatches hardcoded c++ define value of " << ELPURI_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef EMERALD // DO NOT MODIFY!
+ bsA = 4296;
+ bsB = EMERALD;
+ if(bsA!=bsB)
+ ssErrors << "Defined EMERALD with value 4296 from .dat file mismatches hardcoded c++ define value of " << EMERALD << "!" << std::endl;
+#endif
+
+
+#ifdef EMISSARY // DO NOT MODIFY!
+ bsA = 12;
+ bsB = EMISSARY;
+ if(bsA!=bsB)
+ ssErrors << "Defined EMISSARY with value 12 from .dat file mismatches hardcoded c++ define value of " << EMISSARY << "!" << std::endl;
+#endif
+
+
+#ifdef EMPTY_AREA // DO NOT MODIFY!
+ bsA = 5;
+ bsB = EMPTY_AREA;
+ if(bsA!=bsB)
+ ssErrors << "Defined EMPTY_AREA with value 5 from .dat file mismatches hardcoded c++ define value of " << EMPTY_AREA << "!" << std::endl;
+#endif
+
+
+#ifdef ENDURANCE // DO NOT MODIFY!
+ bsA = 0;
+ bsB = ENDURANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ENDURANCE with value 0 from .dat file mismatches hardcoded c++ define value of " << ENDURANCE << "!" << std::endl;
+#endif
+
+
+#ifdef ENERGY // DO NOT MODIFY!
+ bsA = 32;
+ bsB = ENERGY;
+ if(bsA!=bsB)
+ ssErrors << "Defined ENERGY with value 32 from .dat file mismatches hardcoded c++ define value of " << ENERGY << "!" << std::endl;
+#endif
+
+
+#ifdef ENNER_BEAST_FLESH // DO NOT MODIFY!
+ bsA = 20496;
+ bsB = ENNER_BEAST_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ENNER_BEAST_FLESH with value 20496 from .dat file mismatches hardcoded c++ define value of " << ENNER_BEAST_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef ENNER_BEAST_LEVEL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ENNER_BEAST_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ENNER_BEAST_LEVEL with value 4 from .dat file mismatches hardcoded c++ define value of " << ENNER_BEAST_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef ESP // DO NOT MODIFY!
+ bsA = 256;
+ bsB = ESP;
+ if(bsA!=bsB)
+ ssErrors << "Defined ESP with value 256 from .dat file mismatches hardcoded c++ define value of " << ESP << "!" << std::endl;
+#endif
+
+
+#ifdef ETEX_CLOTH // DO NOT MODIFY!
+ bsA = 4178;
+ bsB = ETEX_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ETEX_CLOTH with value 4178 from .dat file mismatches hardcoded c++ define value of " << ETEX_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef ETHER // DO NOT MODIFY!
+ bsA = 12291;
+ bsB = ETHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined ETHER with value 12291 from .dat file mismatches hardcoded c++ define value of " << ETHER << "!" << std::endl;
+#endif
+
+
+#ifdef ETHEREAL // DO NOT MODIFY!
+ bsA = 8;
+ bsB = ETHEREAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ETHEREAL with value 8 from .dat file mismatches hardcoded c++ define value of " << ETHEREAL << "!" << std::endl;
+#endif
+
+
+#ifdef ETHEREAL_MOVING // DO NOT MODIFY!
+ bsA = 2097152;
+ bsB = ETHEREAL_MOVING;
+ if(bsA!=bsB)
+ ssErrors << "Defined ETHEREAL_MOVING with value 2097152 from .dat file mismatches hardcoded c++ define value of " << ETHEREAL_MOVING << "!" << std::endl;
+#endif
+
+
+#ifdef EUNUCH // DO NOT MODIFY!
+ bsA = 3;
+ bsB = EUNUCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined EUNUCH with value 3 from .dat file mismatches hardcoded c++ define value of " << EUNUCH << "!" << std::endl;
+#endif
+
+
+#ifdef EVERGREEN_FOREST // DO NOT MODIFY!
+ bsA = 5;
+ bsB = EVERGREEN_FOREST;
+ if(bsA!=bsB)
+ ssErrors << "Defined EVERGREEN_FOREST with value 5 from .dat file mismatches hardcoded c++ define value of " << EVERGREEN_FOREST << "!" << std::endl;
+#endif
+
+
+#ifdef EVIL // DO NOT MODIFY!
+ bsA = 3;
+ bsB = EVIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined EVIL with value 3 from .dat file mismatches hardcoded c++ define value of " << EVIL << "!" << std::endl;
+#endif
+
+
+#ifdef EVIL_WONDER_STAFF_VAPOUR // DO NOT MODIFY!
+ bsA = 12296;
+ bsB = EVIL_WONDER_STAFF_VAPOUR;
+ if(bsA!=bsB)
+ ssErrors << "Defined EVIL_WONDER_STAFF_VAPOUR with value 12296 from .dat file mismatches hardcoded c++ define value of " << EVIL_WONDER_STAFF_VAPOUR << "!" << std::endl;
+#endif
+
+
+#ifdef EXPENSIVE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = EXPENSIVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined EXPENSIVE with value 2 from .dat file mismatches hardcoded c++ define value of " << EXPENSIVE << "!" << std::endl;
+#endif
+
+
+#ifdef EXPENSIVE_BED // DO NOT MODIFY!
+ bsA = 12;
+ bsB = EXPENSIVE_BED;
+ if(bsA!=bsB)
+ ssErrors << "Defined EXPENSIVE_BED with value 12 from .dat file mismatches hardcoded c++ define value of " << EXPENSIVE_BED << "!" << std::endl;
+#endif
+
+
+#ifdef EYE_COLOR // DO NOT MODIFY!
+ bsA = 8;
+ bsB = EYE_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined EYE_COLOR with value 8 from .dat file mismatches hardcoded c++ define value of " << EYE_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef FABRIC // DO NOT MODIFY!
+ bsA = 4132;
+ bsB = FABRIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined FABRIC with value 4132 from .dat file mismatches hardcoded c++ define value of " << FABRIC << "!" << std::endl;
+#endif
+
+
+#ifdef FAIRY_STEEL // DO NOT MODIFY!
+ bsA = 4109;
+ bsB = FAIRY_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined FAIRY_STEEL with value 4109 from .dat file mismatches hardcoded c++ define value of " << FAIRY_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef FART // DO NOT MODIFY!
+ bsA = 12298;
+ bsB = FART;
+ if(bsA!=bsB)
+ ssErrors << "Defined FART with value 12298 from .dat file mismatches hardcoded c++ define value of " << FART << "!" << std::endl;
+#endif
+
+
+#ifdef FASTING // DO NOT MODIFY!
+ bsA = 1073741824;
+ bsB = FASTING;
+ if(bsA!=bsB)
+ ssErrors << "Defined FASTING with value 1073741824 from .dat file mismatches hardcoded c++ define value of " << FASTING << "!" << std::endl;
+#endif
+
+
+#ifdef FEAR // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined FEAR with value 2 from .dat file mismatches hardcoded c++ define value of " << FEAR << "!" << std::endl;
+#endif
+
+
+#ifdef FEARLESS // DO NOT MODIFY!
+ bsA = 536870912;
+ bsB = FEARLESS;
+ if(bsA!=bsB)
+ ssErrors << "Defined FEARLESS with value 536870912 from .dat file mismatches hardcoded c++ define value of " << FEARLESS << "!" << std::endl;
+#endif
+
+
+#ifdef FELT // DO NOT MODIFY!
+ bsA = 4131;
+ bsB = FELT;
+ if(bsA!=bsB)
+ ssErrors << "Defined FELT with value 4131 from .dat file mismatches hardcoded c++ define value of " << FELT << "!" << std::endl;
+#endif
+
+
+#ifdef FEMALE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FEMALE with value 2 from .dat file mismatches hardcoded c++ define value of " << FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef FIR // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined FIR with value 2 from .dat file mismatches hardcoded c++ define value of " << FIR << "!" << std::endl;
+#endif
+
+
+#ifdef FIRE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = FIRE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FIRE with value 8 from .dat file mismatches hardcoded c++ define value of " << FIRE << "!" << std::endl;
+#endif
+
+
+#ifdef FIR_WOOD // DO NOT MODIFY!
+ bsA = 4239;
+ bsB = FIR_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined FIR_WOOD with value 4239 from .dat file mismatches hardcoded c++ define value of " << FIR_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef FISH_SCALE // DO NOT MODIFY!
+ bsA = 4167;
+ bsB = FISH_SCALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FISH_SCALE with value 4167 from .dat file mismatches hardcoded c++ define value of " << FISH_SCALE << "!" << std::endl;
+#endif
+
+
+#ifdef FLAT // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FLAT;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLAT with value 2 from .dat file mismatches hardcoded c++ define value of " << FLAT << "!" << std::endl;
+#endif
+
+
+#ifdef FLAT_BREAD // DO NOT MODIFY!
+ bsA = 8205;
+ bsB = FLAT_BREAD;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLAT_BREAD with value 8205 from .dat file mismatches hardcoded c++ define value of " << FLAT_BREAD << "!" << std::endl;
+#endif
+
+
+#ifdef FLEE_FROM_ENEMIES // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FLEE_FROM_ENEMIES;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLEE_FROM_ENEMIES with value 2 from .dat file mismatches hardcoded c++ define value of " << FLEE_FROM_ENEMIES << "!" << std::endl;
+#endif
+
+
+#ifdef FLESH_ID // DO NOT MODIFY!
+ bsA = 20480;
+ bsB = FLESH_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLESH_ID with value 20480 from .dat file mismatches hardcoded c++ define value of " << FLESH_ID << "!" << std::endl;
+#endif
+
+
+#ifdef FLEXI_CLOTH // DO NOT MODIFY!
+ bsA = 4180;
+ bsB = FLEXI_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLEXI_CLOTH with value 4180 from .dat file mismatches hardcoded c++ define value of " << FLEXI_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef FLINT // DO NOT MODIFY!
+ bsA = 4277;
+ bsB = FLINT;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLINT with value 4277 from .dat file mismatches hardcoded c++ define value of " << FLINT << "!" << std::endl;
+#endif
+
+
+#ifdef FLIP // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FLIP;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLIP with value 2 from .dat file mismatches hardcoded c++ define value of " << FLIP << "!" << std::endl;
+#endif
+
+
+#ifdef FLOATING_EYE_FLESH // DO NOT MODIFY!
+ bsA = 20519;
+ bsB = FLOATING_EYE_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLOATING_EYE_FLESH with value 20519 from .dat file mismatches hardcoded c++ define value of " << FLOATING_EYE_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef FLOOR // DO NOT MODIFY!
+ bsA = 2;
+ bsB = FLOOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLOOR with value 2 from .dat file mismatches hardcoded c++ define value of " << FLOOR << "!" << std::endl;
+#endif
+
+
+#ifdef FLY // DO NOT MODIFY!
+ bsA = 4;
+ bsB = FLY;
+ if(bsA!=bsB)
+ ssErrors << "Defined FLY with value 4 from .dat file mismatches hardcoded c++ define value of " << FLY << "!" << std::endl;
+#endif
+
+
+#ifdef FOLDED_CARBIDE // DO NOT MODIFY!
+ bsA = 4196;
+ bsB = FOLDED_CARBIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FOLDED_CARBIDE with value 4196 from .dat file mismatches hardcoded c++ define value of " << FOLDED_CARBIDE << "!" << std::endl;
+#endif
+
+
+#ifdef FOLLOW_PLAYER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = FOLLOW_PLAYER;
+ if(bsA!=bsB)
+ ssErrors << "Defined FOLLOW_PLAYER with value 1 from .dat file mismatches hardcoded c++ define value of " << FOLLOW_PLAYER << "!" << std::endl;
+#endif
+
+
+#ifdef FOOD // DO NOT MODIFY!
+ bsA = 1024;
+ bsB = FOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined FOOD with value 1024 from .dat file mismatches hardcoded c++ define value of " << FOOD << "!" << std::endl;
+#endif
+
+
+#ifdef FORCE_THE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = FORCE_THE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FORCE_THE with value 8 from .dat file mismatches hardcoded c++ define value of " << FORCE_THE << "!" << std::endl;
+#endif
+
+
+#ifdef FORGE // DO NOT MODIFY!
+ bsA = 26;
+ bsB = FORGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FORGE with value 26 from .dat file mismatches hardcoded c++ define value of " << FORGE << "!" << std::endl;
+#endif
+
+
+#ifdef FOUNTAIN // DO NOT MODIFY!
+ bsA = 65535;
+ bsB = FOUNTAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined FOUNTAIN with value 65535 from .dat file mismatches hardcoded c++ define value of " << FOUNTAIN << "!" << std::endl;
+#endif
+
+
+#ifdef FRIEND // DO NOT MODIFY!
+ bsA = 4;
+ bsB = FRIEND;
+ if(bsA!=bsB)
+ ssErrors << "Defined FRIEND with value 4 from .dat file mismatches hardcoded c++ define value of " << FRIEND << "!" << std::endl;
+#endif
+
+
+#ifdef FROG_FLESH // DO NOT MODIFY!
+ bsA = 20489;
+ bsB = FROG_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined FROG_FLESH with value 20489 from .dat file mismatches hardcoded c++ define value of " << FROG_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef FRYING_PAN // DO NOT MODIFY!
+ bsA = 20;
+ bsB = FRYING_PAN;
+ if(bsA!=bsB)
+ ssErrors << "Defined FRYING_PAN with value 20 from .dat file mismatches hardcoded c++ define value of " << FRYING_PAN << "!" << std::endl;
+#endif
+
+
+#ifdef FULLERITE // DO NOT MODIFY!
+ bsA = 4197;
+ bsB = FULLERITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FULLERITE with value 4197 from .dat file mismatches hardcoded c++ define value of " << FULLERITE << "!" << std::endl;
+#endif
+
+
+#ifdef FULL_HELMET // DO NOT MODIFY!
+ bsA = 1;
+ bsB = FULL_HELMET;
+ if(bsA!=bsB)
+ ssErrors << "Defined FULL_HELMET with value 1 from .dat file mismatches hardcoded c++ define value of " << FULL_HELMET << "!" << std::endl;
+#endif
+
+
+#ifdef FUNGI_WOOD // DO NOT MODIFY!
+ bsA = 4226;
+ bsB = FUNGI_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined FUNGI_WOOD with value 4226 from .dat file mismatches hardcoded c++ define value of " << FUNGI_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef FURNACE // DO NOT MODIFY!
+ bsA = 27;
+ bsB = FURNACE;
+ if(bsA!=bsB)
+ ssErrors << "Defined FURNACE with value 27 from .dat file mismatches hardcoded c++ define value of " << FURNACE << "!" << std::endl;
+#endif
+
+
+#ifdef GALVORN // DO NOT MODIFY!
+ bsA = 4111;
+ bsB = GALVORN;
+ if(bsA!=bsB)
+ ssErrors << "Defined GALVORN with value 4111 from .dat file mismatches hardcoded c++ define value of " << GALVORN << "!" << std::endl;
+#endif
+
+
+#ifdef GAS_ID // DO NOT MODIFY!
+ bsA = 12288;
+ bsB = GAS_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined GAS_ID with value 12288 from .dat file mismatches hardcoded c++ define value of " << GAS_ID << "!" << std::endl;
+#endif
+
+
+#ifdef GAS_IMMUNITY // DO NOT MODIFY!
+ bsA = 131072;
+ bsB = GAS_IMMUNITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined GAS_IMMUNITY with value 131072 from .dat file mismatches hardcoded c++ define value of " << GAS_IMMUNITY << "!" << std::endl;
+#endif
+
+
+#ifdef GAUNTLET // DO NOT MODIFY!
+ bsA = 128;
+ bsB = GAUNTLET;
+ if(bsA!=bsB)
+ ssErrors << "Defined GAUNTLET with value 128 from .dat file mismatches hardcoded c++ define value of " << GAUNTLET << "!" << std::endl;
+#endif
+
+
+#ifdef GAUNTLET_COLOR // DO NOT MODIFY!
+ bsA = 512;
+ bsB = GAUNTLET_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined GAUNTLET_COLOR with value 512 from .dat file mismatches hardcoded c++ define value of " << GAUNTLET_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef GAUNTLET_OF_DEXTERITY // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GAUNTLET_OF_DEXTERITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined GAUNTLET_OF_DEXTERITY with value 2 from .dat file mismatches hardcoded c++ define value of " << GAUNTLET_OF_DEXTERITY << "!" << std::endl;
+#endif
+
+
+#ifdef GAUNTLET_OF_STRENGTH // DO NOT MODIFY!
+ bsA = 1;
+ bsB = GAUNTLET_OF_STRENGTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined GAUNTLET_OF_STRENGTH with value 1 from .dat file mismatches hardcoded c++ define value of " << GAUNTLET_OF_STRENGTH << "!" << std::endl;
+#endif
+
+
+#ifdef GENERAL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = GENERAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined GENERAL with value 4 from .dat file mismatches hardcoded c++ define value of " << GENERAL << "!" << std::endl;
+#endif
+
+
+#ifdef GIANT // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GIANT;
+ if(bsA!=bsB)
+ ssErrors << "Defined GIANT with value 2 from .dat file mismatches hardcoded c++ define value of " << GIANT << "!" << std::endl;
+#endif
+
+
+#ifdef GIANT_DARK // DO NOT MODIFY!
+ bsA = 3;
+ bsB = GIANT_DARK;
+ if(bsA!=bsB)
+ ssErrors << "Defined GIANT_DARK with value 3 from .dat file mismatches hardcoded c++ define value of " << GIANT_DARK << "!" << std::endl;
+#endif
+
+
+#ifdef GIANT_LIGHT // DO NOT MODIFY!
+ bsA = 6;
+ bsB = GIANT_LIGHT;
+ if(bsA!=bsB)
+ ssErrors << "Defined GIANT_LIGHT with value 6 from .dat file mismatches hardcoded c++ define value of " << GIANT_LIGHT << "!" << std::endl;
+#endif
+
+
+#ifdef GIBBERLING_FLESH // DO NOT MODIFY!
+ bsA = 20503;
+ bsB = GIBBERLING_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined GIBBERLING_FLESH with value 20503 from .dat file mismatches hardcoded c++ define value of " << GIBBERLING_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef GIRL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GIRL;
+ if(bsA!=bsB)
+ ssErrors << "Defined GIRL with value 2 from .dat file mismatches hardcoded c++ define value of " << GIRL << "!" << std::endl;
+#endif
+
+
+#ifdef GLACIER // DO NOT MODIFY!
+ bsA = 7;
+ bsB = GLACIER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GLACIER with value 7 from .dat file mismatches hardcoded c++ define value of " << GLACIER << "!" << std::endl;
+#endif
+
+
+#ifdef GLASS // DO NOT MODIFY!
+ bsA = 4206;
+ bsB = GLASS;
+ if(bsA!=bsB)
+ ssErrors << "Defined GLASS with value 4206 from .dat file mismatches hardcoded c++ define value of " << GLASS << "!" << std::endl;
+#endif
+
+
+#ifdef GLOWING_BLOOD // DO NOT MODIFY!
+ bsA = 16423;
+ bsB = GLOWING_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined GLOWING_BLOOD with value 16423 from .dat file mismatches hardcoded c++ define value of " << GLOWING_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef GNEISS // DO NOT MODIFY!
+ bsA = 4272;
+ bsB = GNEISS;
+ if(bsA!=bsB)
+ ssErrors << "Defined GNEISS with value 4272 from .dat file mismatches hardcoded c++ define value of " << GNEISS << "!" << std::endl;
+#endif
+
+
+#ifdef GOBLINOID_FLESH // DO NOT MODIFY!
+ bsA = 20488;
+ bsB = GOBLINOID_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOBLINOID_FLESH with value 20488 from .dat file mismatches hardcoded c++ define value of " << GOBLINOID_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef GOLD // DO NOT MODIFY!
+ bsA = 4115;
+ bsB = GOLD;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOLD with value 4115 from .dat file mismatches hardcoded c++ define value of " << GOLD << "!" << std::endl;
+#endif
+
+
+#ifdef GOLDEN_EAGLE_FEATHER // DO NOT MODIFY!
+ bsA = 4165;
+ bsB = GOLDEN_EAGLE_FEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOLDEN_EAGLE_FEATHER with value 4165 from .dat file mismatches hardcoded c++ define value of " << GOLDEN_EAGLE_FEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef GOOD // DO NOT MODIFY!
+ bsA = 1;
+ bsB = GOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOOD with value 1 from .dat file mismatches hardcoded c++ define value of " << GOOD << "!" << std::endl;
+#endif
+
+
+#ifdef GOOD_WONDER_STAFF_VAPOUR // DO NOT MODIFY!
+ bsA = 12297;
+ bsB = GOOD_WONDER_STAFF_VAPOUR;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOOD_WONDER_STAFF_VAPOUR with value 12297 from .dat file mismatches hardcoded c++ define value of " << GOOD_WONDER_STAFF_VAPOUR << "!" << std::endl;
+#endif
+
+
+#ifdef GOROVITS_FAMILY_GAS_MASK // DO NOT MODIFY!
+ bsA = 6;
+ bsB = GOROVITS_FAMILY_GAS_MASK;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOROVITS_FAMILY_GAS_MASK with value 6 from .dat file mismatches hardcoded c++ define value of " << GOROVITS_FAMILY_GAS_MASK << "!" << std::endl;
+#endif
+
+
+#ifdef GOROVITS_HAMMER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = GOROVITS_HAMMER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOROVITS_HAMMER with value 1 from .dat file mismatches hardcoded c++ define value of " << GOROVITS_HAMMER << "!" << std::endl;
+#endif
+
+
+#ifdef GOROVITS_SCIMITAR // DO NOT MODIFY!
+ bsA = 3;
+ bsB = GOROVITS_SCIMITAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOROVITS_SCIMITAR with value 3 from .dat file mismatches hardcoded c++ define value of " << GOROVITS_SCIMITAR << "!" << std::endl;
+#endif
+
+
+#ifdef GOROVITS_SICKLE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GOROVITS_SICKLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOROVITS_SICKLE with value 2 from .dat file mismatches hardcoded c++ define value of " << GOROVITS_SICKLE << "!" << std::endl;
+#endif
+
+
+#ifdef GOSSAMER // DO NOT MODIFY!
+ bsA = 4139;
+ bsB = GOSSAMER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GOSSAMER with value 4139 from .dat file mismatches hardcoded c++ define value of " << GOSSAMER << "!" << std::endl;
+#endif
+
+
+#ifdef GRAND_MASTER // DO NOT MODIFY!
+ bsA = 8;
+ bsB = GRAND_MASTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRAND_MASTER with value 8 from .dat file mismatches hardcoded c++ define value of " << GRAND_MASTER << "!" << std::endl;
+#endif
+
+
+#ifdef GRAND_STOLLEN_KNIFE // DO NOT MODIFY!
+ bsA = 17;
+ bsB = GRAND_STOLLEN_KNIFE;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRAND_STOLLEN_KNIFE with value 17 from .dat file mismatches hardcoded c++ define value of " << GRAND_STOLLEN_KNIFE << "!" << std::endl;
+#endif
+
+
+#ifdef GRANITE // DO NOT MODIFY!
+ bsA = 4274;
+ bsB = GRANITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRANITE with value 4274 from .dat file mismatches hardcoded c++ define value of " << GRANITE << "!" << std::endl;
+#endif
+
+
+#ifdef GRASS // DO NOT MODIFY!
+ bsA = 4213;
+ bsB = GRASS;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRASS with value 4213 from .dat file mismatches hardcoded c++ define value of " << GRASS << "!" << std::endl;
+#endif
+
+
+#ifdef GRASS_TERRAIN // DO NOT MODIFY!
+ bsA = 4;
+ bsB = GRASS_TERRAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRASS_TERRAIN with value 4 from .dat file mismatches hardcoded c++ define value of " << GRASS_TERRAIN << "!" << std::endl;
+#endif
+
+
+#ifdef GRAVEL // DO NOT MODIFY!
+ bsA = 4257;
+ bsB = GRAVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRAVEL with value 4257 from .dat file mismatches hardcoded c++ define value of " << GRAVEL << "!" << std::endl;
+#endif
+
+
+#ifdef GRAVE_KEEPER // DO NOT MODIFY!
+ bsA = 5;
+ bsB = GRAVE_KEEPER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRAVE_KEEPER with value 5 from .dat file mismatches hardcoded c++ define value of " << GRAVE_KEEPER << "!" << std::endl;
+#endif
+
+
+#ifdef GRAY_FRACTAL // DO NOT MODIFY!
+ bsA = 0;
+ bsB = GRAY_FRACTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRAY_FRACTAL with value 0 from .dat file mismatches hardcoded c++ define value of " << GRAY_FRACTAL << "!" << std::endl;
+#endif
+
+
+#ifdef GRAY_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 20511;
+ bsB = GRAY_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRAY_UNICORN_FLESH with value 20511 from .dat file mismatches hardcoded c++ define value of " << GRAY_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef GREATER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = GREATER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREATER with value 1 from .dat file mismatches hardcoded c++ define value of " << GREATER << "!" << std::endl;
+#endif
+
+
+#ifdef GREATER_DARK // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GREATER_DARK;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREATER_DARK with value 2 from .dat file mismatches hardcoded c++ define value of " << GREATER_DARK << "!" << std::endl;
+#endif
+
+
+#ifdef GREATER_LIGHT // DO NOT MODIFY!
+ bsA = 5;
+ bsB = GREATER_LIGHT;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREATER_LIGHT with value 5 from .dat file mismatches hardcoded c++ define value of " << GREATER_LIGHT << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN // DO NOT MODIFY!
+ bsA = 2016;
+ bsB = GREEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN with value 2016 from .dat file mismatches hardcoded c++ define value of " << GREEN << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN_BLOOD // DO NOT MODIFY!
+ bsA = 16420;
+ bsB = GREEN_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN_BLOOD with value 16420 from .dat file mismatches hardcoded c++ define value of " << GREEN_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN_CRYSTAL // DO NOT MODIFY!
+ bsA = 4311;
+ bsB = GREEN_CRYSTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN_CRYSTAL with value 4311 from .dat file mismatches hardcoded c++ define value of " << GREEN_CRYSTAL << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN_FRACTAL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GREEN_FRACTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN_FRACTAL with value 2 from .dat file mismatches hardcoded c++ define value of " << GREEN_FRACTAL << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN_JADE // DO NOT MODIFY!
+ bsA = 4305;
+ bsB = GREEN_JADE;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN_JADE with value 4305 from .dat file mismatches hardcoded c++ define value of " << GREEN_JADE << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN_SIREN // DO NOT MODIFY!
+ bsA = 5;
+ bsB = GREEN_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN_SIREN with value 5 from .dat file mismatches hardcoded c++ define value of " << GREEN_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef GREEN_SLIME // DO NOT MODIFY!
+ bsA = 16408;
+ bsB = GREEN_SLIME;
+ if(bsA!=bsB)
+ ssErrors << "Defined GREEN_SLIME with value 16408 from .dat file mismatches hardcoded c++ define value of " << GREEN_SLIME << "!" << std::endl;
+#endif
+
+
+#ifdef GRIFFON_FEATHER // DO NOT MODIFY!
+ bsA = 4162;
+ bsB = GRIFFON_FEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRIFFON_FEATHER with value 4162 from .dat file mismatches hardcoded c++ define value of " << GRIFFON_FEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef GRIZZLY_BEAR // DO NOT MODIFY!
+ bsA = 2;
+ bsB = GRIZZLY_BEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined GRIZZLY_BEAR with value 2 from .dat file mismatches hardcoded c++ define value of " << GRIZZLY_BEAR << "!" << std::endl;
+#endif
+
+
+#ifdef GROIN // DO NOT MODIFY!
+ bsA = 16;
+ bsB = GROIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined GROIN with value 16 from .dat file mismatches hardcoded c++ define value of " << GROIN << "!" << std::endl;
+#endif
+
+
+#ifdef GROIN_INDEX // DO NOT MODIFY!
+ bsA = 4;
+ bsB = GROIN_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined GROIN_INDEX with value 4 from .dat file mismatches hardcoded c++ define value of " << GROIN_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef GROUND // DO NOT MODIFY!
+ bsA = 3;
+ bsB = GROUND;
+ if(bsA!=bsB)
+ ssErrors << "Defined GROUND with value 3 from .dat file mismatches hardcoded c++ define value of " << GROUND << "!" << std::endl;
+#endif
+
+
+#ifdef GUN_POWDER // DO NOT MODIFY!
+ bsA = 24577;
+ bsB = GUN_POWDER;
+ if(bsA!=bsB)
+ ssErrors << "Defined GUN_POWDER with value 24577 from .dat file mismatches hardcoded c++ define value of " << GUN_POWDER << "!" << std::endl;
+#endif
+
+
+#ifdef HAIR_COLOR // DO NOT MODIFY!
+ bsA = 4;
+ bsB = HAIR_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined HAIR_COLOR with value 4 from .dat file mismatches hardcoded c++ define value of " << HAIR_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef HALBERD // DO NOT MODIFY!
+ bsA = 6;
+ bsB = HALBERD;
+ if(bsA!=bsB)
+ ssErrors << "Defined HALBERD with value 6 from .dat file mismatches hardcoded c++ define value of " << HALBERD << "!" << std::endl;
+#endif
+
+
+#ifdef HALCYON // DO NOT MODIFY!
+ bsA = 4288;
+ bsB = HALCYON;
+ if(bsA!=bsB)
+ ssErrors << "Defined HALCYON with value 4288 from .dat file mismatches hardcoded c++ define value of " << HALCYON << "!" << std::endl;
+#endif
+
+
+#ifdef HAMMER // DO NOT MODIFY!
+ bsA = 16;
+ bsB = HAMMER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HAMMER with value 16 from .dat file mismatches hardcoded c++ define value of " << HAMMER << "!" << std::endl;
+#endif
+
+
+#ifdef HARDENED_ASH // DO NOT MODIFY!
+ bsA = 4326;
+ bsB = HARDENED_ASH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HARDENED_ASH with value 4326 from .dat file mismatches hardcoded c++ define value of " << HARDENED_ASH << "!" << std::endl;
+#endif
+
+
+#ifdef HARDENED_CLAY // DO NOT MODIFY!
+ bsA = 4319;
+ bsB = HARDENED_CLAY;
+ if(bsA!=bsB)
+ ssErrors << "Defined HARDENED_CLAY with value 4319 from .dat file mismatches hardcoded c++ define value of " << HARDENED_CLAY << "!" << std::endl;
+#endif
+
+
+#ifdef HARDENED_CONCRETE // DO NOT MODIFY!
+ bsA = 4314;
+ bsB = HARDENED_CONCRETE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HARDENED_CONCRETE with value 4314 from .dat file mismatches hardcoded c++ define value of " << HARDENED_CONCRETE << "!" << std::endl;
+#endif
+
+
+#ifdef HARDENED_LEATHER // DO NOT MODIFY!
+ bsA = 4152;
+ bsB = HARDENED_LEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HARDENED_LEATHER with value 4152 from .dat file mismatches hardcoded c++ define value of " << HARDENED_LEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef HARDENED_PLASTIC // DO NOT MODIFY!
+ bsA = 4187;
+ bsB = HARDENED_PLASTIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined HARDENED_PLASTIC with value 4187 from .dat file mismatches hardcoded c++ define value of " << HARDENED_PLASTIC << "!" << std::endl;
+#endif
+
+
+#ifdef HARPY_FEATHER // DO NOT MODIFY!
+ bsA = 4161;
+ bsB = HARPY_FEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HARPY_FEATHER with value 4161 from .dat file mismatches hardcoded c++ define value of " << HARPY_FEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef HASTE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HASTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HASTE with value 2 from .dat file mismatches hardcoded c++ define value of " << HASTE << "!" << std::endl;
+#endif
+
+
+#ifdef HAS_CHARACTER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HAS_CHARACTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HAS_CHARACTER with value 2 from .dat file mismatches hardcoded c++ define value of " << HAS_CHARACTER << "!" << std::endl;
+#endif
+
+
+#ifdef HAS_NO_OTERRAIN // DO NOT MODIFY!
+ bsA = 32;
+ bsB = HAS_NO_OTERRAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined HAS_NO_OTERRAIN with value 32 from .dat file mismatches hardcoded c++ define value of " << HAS_NO_OTERRAIN << "!" << std::endl;
+#endif
+
+
+#ifdef HAS_SECONDARY_MATERIAL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HAS_SECONDARY_MATERIAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined HAS_SECONDARY_MATERIAL with value 2 from .dat file mismatches hardcoded c++ define value of " << HAS_SECONDARY_MATERIAL << "!" << std::endl;
+#endif
+
+
+#ifdef HATCHLING // DO NOT MODIFY!
+ bsA = 1;
+ bsB = HATCHLING;
+ if(bsA!=bsB)
+ ssErrors << "Defined HATCHLING with value 1 from .dat file mismatches hardcoded c++ define value of " << HATCHLING << "!" << std::endl;
+#endif
+
+
+#ifdef HATTIFATTENER_FLESH // DO NOT MODIFY!
+ bsA = 20526;
+ bsB = HATTIFATTENER_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HATTIFATTENER_FLESH with value 20526 from .dat file mismatches hardcoded c++ define value of " << HATTIFATTENER_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef HEAD // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HEAD;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEAD with value 2 from .dat file mismatches hardcoded c++ define value of " << HEAD << "!" << std::endl;
+#endif
+
+
+#ifdef HEAD_INDEX // DO NOT MODIFY!
+ bsA = 1;
+ bsB = HEAD_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEAD_INDEX with value 1 from .dat file mismatches hardcoded c++ define value of " << HEAD_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef HEALING // DO NOT MODIFY!
+ bsA = 4;
+ bsB = HEALING;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEALING with value 4 from .dat file mismatches hardcoded c++ define value of " << HEALING << "!" << std::endl;
+#endif
+
+
+#ifdef HEALING_LIQUID // DO NOT MODIFY!
+ bsA = 16387;
+ bsB = HEALING_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEALING_LIQUID with value 16387 from .dat file mismatches hardcoded c++ define value of " << HEALING_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef HEART_SHAPED_LOCK // DO NOT MODIFY!
+ bsA = 19456;
+ bsB = HEART_SHAPED_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEART_SHAPED_LOCK with value 19456 from .dat file mismatches hardcoded c++ define value of " << HEART_SHAPED_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef HEAVILY_BURNT // DO NOT MODIFY!
+ bsA = 3;
+ bsB = HEAVILY_BURNT;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEAVILY_BURNT with value 3 from .dat file mismatches hardcoded c++ define value of " << HEAVILY_BURNT << "!" << std::endl;
+#endif
+
+
+#ifdef HEDGEHOG_FLESH // DO NOT MODIFY!
+ bsA = 20524;
+ bsB = HEDGEHOG_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEDGEHOG_FLESH with value 20524 from .dat file mismatches hardcoded c++ define value of " << HEDGEHOG_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef HELMET // DO NOT MODIFY!
+ bsA = 1;
+ bsB = HELMET;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELMET with value 1 from .dat file mismatches hardcoded c++ define value of " << HELMET << "!" << std::endl;
+#endif
+
+
+#ifdef HELMET_INDEX // DO NOT MODIFY!
+ bsA = 0;
+ bsB = HELMET_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELMET_INDEX with value 0 from .dat file mismatches hardcoded c++ define value of " << HELMET_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_ATTRACTIVITY // DO NOT MODIFY!
+ bsA = 5;
+ bsB = HELM_OF_ATTRACTIVITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_ATTRACTIVITY with value 5 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_ATTRACTIVITY << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_BRILLIANCE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = HELM_OF_BRILLIANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_BRILLIANCE with value 4 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_BRILLIANCE << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_ENLIGHTENMENT // DO NOT MODIFY!
+ bsA = 10;
+ bsB = HELM_OF_ENLIGHTENMENT;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_ENLIGHTENMENT with value 10 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_ENLIGHTENMENT << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_MANA // DO NOT MODIFY!
+ bsA = 11;
+ bsB = HELM_OF_MANA;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_MANA with value 11 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_MANA << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_PERCEPTION // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HELM_OF_PERCEPTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_PERCEPTION with value 2 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_PERCEPTION << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_TELEPATHY // DO NOT MODIFY!
+ bsA = 8;
+ bsB = HELM_OF_TELEPATHY;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_TELEPATHY with value 8 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_TELEPATHY << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_TELEPORTATION // DO NOT MODIFY!
+ bsA = 9;
+ bsB = HELM_OF_TELEPORTATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_TELEPORTATION with value 9 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_TELEPORTATION << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_UNDERSTANDING // DO NOT MODIFY!
+ bsA = 3;
+ bsB = HELM_OF_UNDERSTANDING;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_UNDERSTANDING with value 3 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_UNDERSTANDING << "!" << std::endl;
+#endif
+
+
+#ifdef HELM_OF_WILLPOWER // DO NOT MODIFY!
+ bsA = 7;
+ bsB = HELM_OF_WILLPOWER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HELM_OF_WILLPOWER with value 7 from .dat file mismatches hardcoded c++ define value of " << HELM_OF_WILLPOWER << "!" << std::endl;
+#endif
+
+
+#ifdef HEMATITE // DO NOT MODIFY!
+ bsA = 4324;
+ bsB = HEMATITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEMATITE with value 4324 from .dat file mismatches hardcoded c++ define value of " << HEMATITE << "!" << std::endl;
+#endif
+
+
+#ifdef HEMP_CLOTH // DO NOT MODIFY!
+ bsA = 4129;
+ bsB = HEMP_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEMP_CLOTH with value 4129 from .dat file mismatches hardcoded c++ define value of " << HEMP_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef HEPATIZON // DO NOT MODIFY!
+ bsA = 4104;
+ bsB = HEPATIZON;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEPATIZON with value 4104 from .dat file mismatches hardcoded c++ define value of " << HEPATIZON << "!" << std::endl;
+#endif
+
+
+#ifdef HEXAGONAL_LOCK // DO NOT MODIFY!
+ bsA = 17408;
+ bsB = HEXAGONAL_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined HEXAGONAL_LOCK with value 17408 from .dat file mismatches hardcoded c++ define value of " << HEXAGONAL_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef HICCUPS // DO NOT MODIFY!
+ bsA = 1048576;
+ bsB = HICCUPS;
+ if(bsA!=bsB)
+ ssErrors << "Defined HICCUPS with value 1048576 from .dat file mismatches hardcoded c++ define value of " << HICCUPS << "!" << std::endl;
+#endif
+
+
+#ifdef HISPANIC_SIREN // DO NOT MODIFY!
+ bsA = 9;
+ bsB = HISPANIC_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined HISPANIC_SIREN with value 9 from .dat file mismatches hardcoded c++ define value of " << HISPANIC_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef HM_ANTIDOTE // DO NOT MODIFY!
+ bsA = 7;
+ bsB = HM_ANTIDOTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_ANTIDOTE with value 7 from .dat file mismatches hardcoded c++ define value of " << HM_ANTIDOTE << "!" << std::endl;
+#endif
+
+
+#ifdef HM_CONFUSE // DO NOT MODIFY!
+ bsA = 8;
+ bsB = HM_CONFUSE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_CONFUSE with value 8 from .dat file mismatches hardcoded c++ define value of " << HM_CONFUSE << "!" << std::endl;
+#endif
+
+
+#ifdef HM_FROG_FLESH // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HM_FROG_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_FROG_FLESH with value 2 from .dat file mismatches hardcoded c++ define value of " << HM_FROG_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef HM_HEALING_LIQUID // DO NOT MODIFY!
+ bsA = 6;
+ bsB = HM_HEALING_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_HEALING_LIQUID with value 6 from .dat file mismatches hardcoded c++ define value of " << HM_HEALING_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef HM_HOLY_BANANA // DO NOT MODIFY!
+ bsA = 9;
+ bsB = HM_HOLY_BANANA;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_HOLY_BANANA with value 9 from .dat file mismatches hardcoded c++ define value of " << HM_HOLY_BANANA << "!" << std::endl;
+#endif
+
+
+#ifdef HM_KOBOLD_FLESH // DO NOT MODIFY!
+ bsA = 5;
+ bsB = HM_KOBOLD_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_KOBOLD_FLESH with value 5 from .dat file mismatches hardcoded c++ define value of " << HM_KOBOLD_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef HM_NOTHING // DO NOT MODIFY!
+ bsA = 0;
+ bsB = HM_NOTHING;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_NOTHING with value 0 from .dat file mismatches hardcoded c++ define value of " << HM_NOTHING << "!" << std::endl;
+#endif
+
+
+#ifdef HM_OMMEL // DO NOT MODIFY!
+ bsA = 3;
+ bsB = HM_OMMEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_OMMEL with value 3 from .dat file mismatches hardcoded c++ define value of " << HM_OMMEL << "!" << std::endl;
+#endif
+
+
+#ifdef HM_PEPSI // DO NOT MODIFY!
+ bsA = 4;
+ bsB = HM_PEPSI;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_PEPSI with value 4 from .dat file mismatches hardcoded c++ define value of " << HM_PEPSI << "!" << std::endl;
+#endif
+
+
+#ifdef HM_SCHOOL_FOOD // DO NOT MODIFY!
+ bsA = 1;
+ bsB = HM_SCHOOL_FOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined HM_SCHOOL_FOOD with value 1 from .dat file mismatches hardcoded c++ define value of " << HM_SCHOOL_FOOD << "!" << std::endl;
+#endif
+
+
+#ifdef HOARD_MASTER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HOARD_MASTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HOARD_MASTER with value 2 from .dat file mismatches hardcoded c++ define value of " << HOARD_MASTER << "!" << std::endl;
+#endif
+
+
+#ifdef HOLLY_WOOD // DO NOT MODIFY!
+ bsA = 4232;
+ bsB = HOLLY_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined HOLLY_WOOD with value 4232 from .dat file mismatches hardcoded c++ define value of " << HOLLY_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef HOLY_BANANA_FLESH // DO NOT MODIFY!
+ bsA = 8197;
+ bsB = HOLY_BANANA_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HOLY_BANANA_FLESH with value 8197 from .dat file mismatches hardcoded c++ define value of " << HOLY_BANANA_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef HOLY_TREE // DO NOT MODIFY!
+ bsA = 3;
+ bsB = HOLY_TREE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HOLY_TREE with value 3 from .dat file mismatches hardcoded c++ define value of " << HOLY_TREE << "!" << std::endl;
+#endif
+
+
+#ifdef HONEY // DO NOT MODIFY!
+ bsA = 16394;
+ bsB = HONEY;
+ if(bsA!=bsB)
+ ssErrors << "Defined HONEY with value 16394 from .dat file mismatches hardcoded c++ define value of " << HONEY << "!" << std::endl;
+#endif
+
+
+#ifdef HONOR // DO NOT MODIFY!
+ bsA = 11;
+ bsB = HONOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined HONOR with value 11 from .dat file mismatches hardcoded c++ define value of " << HONOR << "!" << std::endl;
+#endif
+
+
+#ifdef HOSTILE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = HOSTILE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HOSTILE with value 1 from .dat file mismatches hardcoded c++ define value of " << HOSTILE << "!" << std::endl;
+#endif
+
+
+#ifdef HUMAN_FLESH // DO NOT MODIFY!
+ bsA = 20491;
+ bsB = HUMAN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined HUMAN_FLESH with value 20491 from .dat file mismatches hardcoded c++ define value of " << HUMAN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef HUMAN_NAIL // DO NOT MODIFY!
+ bsA = 4248;
+ bsB = HUMAN_NAIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined HUMAN_NAIL with value 4248 from .dat file mismatches hardcoded c++ define value of " << HUMAN_NAIL << "!" << std::endl;
+#endif
+
+
+#ifdef HUMAN_SKIN // DO NOT MODIFY!
+ bsA = 4141;
+ bsB = HUMAN_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined HUMAN_SKIN with value 4141 from .dat file mismatches hardcoded c++ define value of " << HUMAN_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef HUNTER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = HUNTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined HUNTER with value 2 from .dat file mismatches hardcoded c++ define value of " << HUNTER << "!" << std::endl;
+#endif
+
+
+#ifdef HUSBAND // DO NOT MODIFY!
+ bsA = 1;
+ bsB = HUSBAND;
+ if(bsA!=bsB)
+ ssErrors << "Defined HUSBAND with value 1 from .dat file mismatches hardcoded c++ define value of " << HUSBAND << "!" << std::endl;
+#endif
+
+
+#ifdef HYDRA_HIDE // DO NOT MODIFY!
+ bsA = 4149;
+ bsB = HYDRA_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined HYDRA_HIDE with value 4149 from .dat file mismatches hardcoded c++ define value of " << HYDRA_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef ICE // DO NOT MODIFY!
+ bsA = 4209;
+ bsB = ICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ICE with value 4209 from .dat file mismatches hardcoded c++ define value of " << ICE << "!" << std::endl;
+#endif
+
+
+#ifdef ICE_WALL // DO NOT MODIFY!
+ bsA = 7;
+ bsB = ICE_WALL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ICE_WALL with value 7 from .dat file mismatches hardcoded c++ define value of " << ICE_WALL << "!" << std::endl;
+#endif
+
+
+#ifdef IGNORE_BROKEN_PRICE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = IGNORE_BROKEN_PRICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IGNORE_BROKEN_PRICE with value 2 from .dat file mismatches hardcoded c++ define value of " << IGNORE_BROKEN_PRICE << "!" << std::endl;
+#endif
+
+
+#ifdef ILLITHIUM // DO NOT MODIFY!
+ bsA = 4208;
+ bsB = ILLITHIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ILLITHIUM with value 4208 from .dat file mismatches hardcoded c++ define value of " << ILLITHIUM << "!" << std::endl;
+#endif
+
+
+#ifdef IMPRISONED_FARMER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IMPRISONED_FARMER;
+ if(bsA!=bsB)
+ ssErrors << "Defined IMPRISONED_FARMER with value 1 from .dat file mismatches hardcoded c++ define value of " << IMPRISONED_FARMER << "!" << std::endl;
+#endif
+
+
+#ifdef IMPRISONED_FEMALE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IMPRISONED_FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IMPRISONED_FEMALE with value 1 from .dat file mismatches hardcoded c++ define value of " << IMPRISONED_FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef IMPRISONED_HUNTER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IMPRISONED_HUNTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined IMPRISONED_HUNTER with value 1 from .dat file mismatches hardcoded c++ define value of " << IMPRISONED_HUNTER << "!" << std::endl;
+#endif
+
+
+#ifdef IMPRISONED_NECROMANCER // DO NOT MODIFY!
+ bsA = 9;
+ bsB = IMPRISONED_NECROMANCER;
+ if(bsA!=bsB)
+ ssErrors << "Defined IMPRISONED_NECROMANCER with value 9 from .dat file mismatches hardcoded c++ define value of " << IMPRISONED_NECROMANCER << "!" << std::endl;
+#endif
+
+
+#ifdef IMPRISONED_ZOMBIE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = IMPRISONED_ZOMBIE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IMPRISONED_ZOMBIE with value 2 from .dat file mismatches hardcoded c++ define value of " << IMPRISONED_ZOMBIE << "!" << std::endl;
+#endif
+
+
+#ifdef IMP_HIDE // DO NOT MODIFY!
+ bsA = 4157;
+ bsB = IMP_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IMP_HIDE with value 4157 from .dat file mismatches hardcoded c++ define value of " << IMP_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef INDEFINE_BIT // DO NOT MODIFY!
+ bsA = 4;
+ bsB = INDEFINE_BIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined INDEFINE_BIT with value 4 from .dat file mismatches hardcoded c++ define value of " << INDEFINE_BIT << "!" << std::endl;
+#endif
+
+
+#ifdef INDEFINITE // DO NOT MODIFY!
+ bsA = 6;
+ bsB = INDEFINITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined INDEFINITE with value 6 from .dat file mismatches hardcoded c++ define value of " << INDEFINITE << "!" << std::endl;
+#endif
+
+
+#ifdef INFRA_VISION // DO NOT MODIFY!
+ bsA = 128;
+ bsB = INFRA_VISION;
+ if(bsA!=bsB)
+ ssErrors << "Defined INFRA_VISION with value 128 from .dat file mismatches hardcoded c++ define value of " << INFRA_VISION << "!" << std::endl;
+#endif
+
+
+#ifdef INFUSCOR // DO NOT MODIFY!
+ bsA = 13;
+ bsB = INFUSCOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined INFUSCOR with value 13 from .dat file mismatches hardcoded c++ define value of " << INFUSCOR << "!" << std::endl;
+#endif
+
+
+#ifdef INK // DO NOT MODIFY!
+ bsA = 16396;
+ bsB = INK;
+ if(bsA!=bsB)
+ ssErrors << "Defined INK with value 16396 from .dat file mismatches hardcoded c++ define value of " << INK << "!" << std::endl;
+#endif
+
+
+#ifdef INTELLIGENCE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = INTELLIGENCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined INTELLIGENCE with value 2 from .dat file mismatches hardcoded c++ define value of " << INTELLIGENCE << "!" << std::endl;
+#endif
+
+
+#ifdef INVISIBLE // DO NOT MODIFY!
+ bsA = 64;
+ bsB = INVISIBLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined INVISIBLE with value 64 from .dat file mismatches hardcoded c++ define value of " << INVISIBLE << "!" << std::endl;
+#endif
+
+
+#ifdef IN_ROOM // DO NOT MODIFY!
+ bsA = 4;
+ bsB = IN_ROOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined IN_ROOM with value 4 from .dat file mismatches hardcoded c++ define value of " << IN_ROOM << "!" << std::endl;
+#endif
+
+
+#ifdef IRIDIUM // DO NOT MODIFY!
+ bsA = 4124;
+ bsB = IRIDIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined IRIDIUM with value 4124 from .dat file mismatches hardcoded c++ define value of " << IRIDIUM << "!" << std::endl;
+#endif
+
+
+#ifdef IRON // DO NOT MODIFY!
+ bsA = 28674;
+ bsB = IRON;
+ if(bsA!=bsB)
+ ssErrors << "Defined IRON with value 28674 from .dat file mismatches hardcoded c++ define value of " << IRON << "!" << std::endl;
+#endif
+
+
+#ifdef IRON_ALLOY_ID // DO NOT MODIFY!
+ bsA = 28672;
+ bsB = IRON_ALLOY_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined IRON_ALLOY_ID with value 28672 from .dat file mismatches hardcoded c++ define value of " << IRON_ALLOY_ID << "!" << std::endl;
+#endif
+
+
+#ifdef IS_ABSTRACT // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IS_ABSTRACT;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_ABSTRACT with value 1 from .dat file mismatches hardcoded c++ define value of " << IS_ABSTRACT << "!" << std::endl;
+#endif
+
+
+#ifdef IS_AFFECTED_BY_MUSTARD_GAS // DO NOT MODIFY!
+ bsA = 32;
+ bsB = IS_AFFECTED_BY_MUSTARD_GAS;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_AFFECTED_BY_MUSTARD_GAS with value 32 from .dat file mismatches hardcoded c++ define value of " << IS_AFFECTED_BY_MUSTARD_GAS << "!" << std::endl;
+#endif
+
+
+#ifdef IS_ALIVE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IS_ALIVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_ALIVE with value 1 from .dat file mismatches hardcoded c++ define value of " << IS_ALIVE << "!" << std::endl;
+#endif
+
+
+#ifdef IS_BEVERAGE // DO NOT MODIFY!
+ bsA = 64;
+ bsB = IS_BEVERAGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_BEVERAGE with value 64 from .dat file mismatches hardcoded c++ define value of " << IS_BEVERAGE << "!" << std::endl;
+#endif
+
+
+#ifdef IS_BLOOD // DO NOT MODIFY!
+ bsA = 2;
+ bsB = IS_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_BLOOD with value 2 from .dat file mismatches hardcoded c++ define value of " << IS_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef IS_GOLEM_MATERIAL // DO NOT MODIFY!
+ bsA = 32;
+ bsB = IS_GOLEM_MATERIAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_GOLEM_MATERIAL with value 32 from .dat file mismatches hardcoded c++ define value of " << IS_GOLEM_MATERIAL << "!" << std::endl;
+#endif
+
+
+#ifdef IS_LEADER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IS_LEADER;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_LEADER with value 1 from .dat file mismatches hardcoded c++ define value of " << IS_LEADER << "!" << std::endl;
+#endif
+
+
+#ifdef IS_MASTER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = IS_MASTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_MASTER with value 2 from .dat file mismatches hardcoded c++ define value of " << IS_MASTER << "!" << std::endl;
+#endif
+
+
+#ifdef IS_METAL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = IS_METAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_METAL with value 1 from .dat file mismatches hardcoded c++ define value of " << IS_METAL << "!" << std::endl;
+#endif
+
+
+#ifdef IS_SCARY // DO NOT MODIFY!
+ bsA = 16;
+ bsB = IS_SCARY;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_SCARY with value 16 from .dat file mismatches hardcoded c++ define value of " << IS_SCARY << "!" << std::endl;
+#endif
+
+
+#ifdef IS_SPARKLING // DO NOT MODIFY!
+ bsA = 8;
+ bsB = IS_SPARKLING;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_SPARKLING with value 8 from .dat file mismatches hardcoded c++ define value of " << IS_SPARKLING << "!" << std::endl;
+#endif
+
+
+#ifdef IS_VALUABLE // DO NOT MODIFY!
+ bsA = 32;
+ bsB = IS_VALUABLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_VALUABLE with value 32 from .dat file mismatches hardcoded c++ define value of " << IS_VALUABLE << "!" << std::endl;
+#endif
+
+
+#ifdef IS_WARM // DO NOT MODIFY!
+ bsA = 2;
+ bsB = IS_WARM;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_WARM with value 2 from .dat file mismatches hardcoded c++ define value of " << IS_WARM << "!" << std::endl;
+#endif
+
+
+#ifdef IS_WARM_BLOODED // DO NOT MODIFY!
+ bsA = 32;
+ bsB = IS_WARM_BLOODED;
+ if(bsA!=bsB)
+ ssErrors << "Defined IS_WARM_BLOODED with value 32 from .dat file mismatches hardcoded c++ define value of " << IS_WARM_BLOODED << "!" << std::endl;
+#endif
+
+
+#ifdef IVAN_LEVEL // DO NOT MODIFY!
+ bsA = 7;
+ bsB = IVAN_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined IVAN_LEVEL with value 7 from .dat file mismatches hardcoded c++ define value of " << IVAN_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef IVAN_TEAM // DO NOT MODIFY!
+ bsA = 6;
+ bsB = IVAN_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined IVAN_TEAM with value 6 from .dat file mismatches hardcoded c++ define value of " << IVAN_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef JACINTH // DO NOT MODIFY!
+ bsA = 4266;
+ bsB = JACINTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined JACINTH with value 4266 from .dat file mismatches hardcoded c++ define value of " << JACINTH << "!" << std::endl;
+#endif
+
+
+#ifdef JACKAL_FLESH // DO NOT MODIFY!
+ bsA = 20498;
+ bsB = JACKAL_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined JACKAL_FLESH with value 20498 from .dat file mismatches hardcoded c++ define value of " << JACKAL_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef JADEITE // DO NOT MODIFY!
+ bsA = 4300;
+ bsB = JADEITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined JADEITE with value 4300 from .dat file mismatches hardcoded c++ define value of " << JADEITE << "!" << std::endl;
+#endif
+
+
+#ifdef JASPER // DO NOT MODIFY!
+ bsA = 4265;
+ bsB = JASPER;
+ if(bsA!=bsB)
+ ssErrors << "Defined JASPER with value 4265 from .dat file mismatches hardcoded c++ define value of " << JASPER << "!" << std::endl;
+#endif
+
+
+#ifdef JESTER // DO NOT MODIFY!
+ bsA = 4;
+ bsB = JESTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined JESTER with value 4 from .dat file mismatches hardcoded c++ define value of " << JESTER << "!" << std::endl;
+#endif
+
+
+#ifdef JET // DO NOT MODIFY!
+ bsA = 4194;
+ bsB = JET;
+ if(bsA!=bsB)
+ ssErrors << "Defined JET with value 4194 from .dat file mismatches hardcoded c++ define value of " << JET << "!" << std::endl;
+#endif
+
+
+#ifdef JOTUN_ICE // DO NOT MODIFY!
+ bsA = 4211;
+ bsB = JOTUN_ICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined JOTUN_ICE with value 4211 from .dat file mismatches hardcoded c++ define value of " << JOTUN_ICE << "!" << std::endl;
+#endif
+
+
+#ifdef JUNGLE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = JUNGLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined JUNGLE with value 2 from .dat file mismatches hardcoded c++ define value of " << JUNGLE << "!" << std::endl;
+#endif
+
+
+#ifdef KAURI_WOOD // DO NOT MODIFY!
+ bsA = 4244;
+ bsB = KAURI_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined KAURI_WOOD with value 4244 from .dat file mismatches hardcoded c++ define value of " << KAURI_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef KELP // DO NOT MODIFY!
+ bsA = 8202;
+ bsB = KELP;
+ if(bsA!=bsB)
+ ssErrors << "Defined KELP with value 8202 from .dat file mismatches hardcoded c++ define value of " << KELP << "!" << std::endl;
+#endif
+
+
+#ifdef KEVLAR // DO NOT MODIFY!
+ bsA = 4181;
+ bsB = KEVLAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined KEVLAR with value 4181 from .dat file mismatches hardcoded c++ define value of " << KEVLAR << "!" << std::endl;
+#endif
+
+
+#ifdef KICK // DO NOT MODIFY!
+ bsA = 1;
+ bsB = KICK;
+ if(bsA!=bsB)
+ ssErrors << "Defined KICK with value 1 from .dat file mismatches hardcoded c++ define value of " << KICK << "!" << std::endl;
+#endif
+
+
+#ifdef KICK_ATTACK // DO NOT MODIFY!
+ bsA = 2;
+ bsB = KICK_ATTACK;
+ if(bsA!=bsB)
+ ssErrors << "Defined KICK_ATTACK with value 2 from .dat file mismatches hardcoded c++ define value of " << KICK_ATTACK << "!" << std::endl;
+#endif
+
+
+#ifdef KING // DO NOT MODIFY!
+ bsA = 4;
+ bsB = KING;
+ if(bsA!=bsB)
+ ssErrors << "Defined KING with value 4 from .dat file mismatches hardcoded c++ define value of " << KING << "!" << std::endl;
+#endif
+
+
+#ifdef KIWI_FLESH // DO NOT MODIFY!
+ bsA = 8198;
+ bsB = KIWI_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined KIWI_FLESH with value 8198 from .dat file mismatches hardcoded c++ define value of " << KIWI_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef KOBOLD_FLESH // DO NOT MODIFY!
+ bsA = 20502;
+ bsB = KOBOLD_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined KOBOLD_FLESH with value 20502 from .dat file mismatches hardcoded c++ define value of " << KOBOLD_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef KRAKEN_HIDE // DO NOT MODIFY!
+ bsA = 4171;
+ bsB = KRAKEN_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined KRAKEN_HIDE with value 4171 from .dat file mismatches hardcoded c++ define value of " << KRAKEN_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef LANDING_SITE // DO NOT MODIFY!
+ bsA = 5;
+ bsB = LANDING_SITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined LANDING_SITE with value 5 from .dat file mismatches hardcoded c++ define value of " << LANDING_SITE << "!" << std::endl;
+#endif
+
+
+#ifdef LAPIS_LAZULI // DO NOT MODIFY!
+ bsA = 4279;
+ bsB = LAPIS_LAZULI;
+ if(bsA!=bsB)
+ ssErrors << "Defined LAPIS_LAZULI with value 4279 from .dat file mismatches hardcoded c++ define value of " << LAPIS_LAZULI << "!" << std::endl;
+#endif
+
+
+#ifdef LARGE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LARGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined LARGE with value 1 from .dat file mismatches hardcoded c++ define value of " << LARGE << "!" << std::endl;
+#endif
+
+
+#ifdef LARGE_CHEST // DO NOT MODIFY!
+ bsA = 3;
+ bsB = LARGE_CHEST;
+ if(bsA!=bsB)
+ ssErrors << "Defined LARGE_CHEST with value 3 from .dat file mismatches hardcoded c++ define value of " << LARGE_CHEST << "!" << std::endl;
+#endif
+
+
+#ifdef LARGE_CLOCK // DO NOT MODIFY!
+ bsA = 6;
+ bsB = LARGE_CLOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined LARGE_CLOCK with value 6 from .dat file mismatches hardcoded c++ define value of " << LARGE_CLOCK << "!" << std::endl;
+#endif
+
+
+#ifdef LARGE_SWORDS // DO NOT MODIFY!
+ bsA = 5;
+ bsB = LARGE_SWORDS;
+ if(bsA!=bsB)
+ ssErrors << "Defined LARGE_SWORDS with value 5 from .dat file mismatches hardcoded c++ define value of " << LARGE_SWORDS << "!" << std::endl;
+#endif
+
+
+#ifdef LATEX // DO NOT MODIFY!
+ bsA = 4184;
+ bsB = LATEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LATEX with value 4184 from .dat file mismatches hardcoded c++ define value of " << LATEX << "!" << std::endl;
+#endif
+
+
+#ifdef LAW_STUDENT // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LAW_STUDENT;
+ if(bsA!=bsB)
+ ssErrors << "Defined LAW_STUDENT with value 1 from .dat file mismatches hardcoded c++ define value of " << LAW_STUDENT << "!" << std::endl;
+#endif
+
+
+#ifdef LEAD // DO NOT MODIFY!
+ bsA = 4114;
+ bsB = LEAD;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEAD with value 4114 from .dat file mismatches hardcoded c++ define value of " << LEAD << "!" << std::endl;
+#endif
+
+
+#ifdef LEAF // DO NOT MODIFY!
+ bsA = 4216;
+ bsB = LEAF;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEAF with value 4216 from .dat file mismatches hardcoded c++ define value of " << LEAF << "!" << std::endl;
+#endif
+
+
+#ifdef LEAFY_FOREST // DO NOT MODIFY!
+ bsA = 4;
+ bsB = LEAFY_FOREST;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEAFY_FOREST with value 4 from .dat file mismatches hardcoded c++ define value of " << LEAFY_FOREST << "!" << std::endl;
+#endif
+
+
+#ifdef LEATHER // DO NOT MODIFY!
+ bsA = 4150;
+ bsB = LEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEATHER with value 4150 from .dat file mismatches hardcoded c++ define value of " << LEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT // DO NOT MODIFY!
+ bsA = 0;
+ bsB = LEFT;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT with value 0 from .dat file mismatches hardcoded c++ define value of " << LEFT << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_ARM // DO NOT MODIFY!
+ bsA = 8;
+ bsB = LEFT_ARM;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_ARM with value 8 from .dat file mismatches hardcoded c++ define value of " << LEFT_ARM << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_ARM_INDEX // DO NOT MODIFY!
+ bsA = 3;
+ bsB = LEFT_ARM_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_ARM_INDEX with value 3 from .dat file mismatches hardcoded c++ define value of " << LEFT_ARM_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_BOOT_INDEX // DO NOT MODIFY!
+ bsA = 12;
+ bsB = LEFT_BOOT_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_BOOT_INDEX with value 12 from .dat file mismatches hardcoded c++ define value of " << LEFT_BOOT_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_GAUNTLET_INDEX // DO NOT MODIFY!
+ bsA = 10;
+ bsB = LEFT_GAUNTLET_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_GAUNTLET_INDEX with value 10 from .dat file mismatches hardcoded c++ define value of " << LEFT_GAUNTLET_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_LEG // DO NOT MODIFY!
+ bsA = 64;
+ bsB = LEFT_LEG;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_LEG with value 64 from .dat file mismatches hardcoded c++ define value of " << LEFT_LEG << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_LEG_INDEX // DO NOT MODIFY!
+ bsA = 6;
+ bsB = LEFT_LEG_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_LEG_INDEX with value 6 from .dat file mismatches hardcoded c++ define value of " << LEFT_LEG_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_RING_INDEX // DO NOT MODIFY!
+ bsA = 8;
+ bsB = LEFT_RING_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_RING_INDEX with value 8 from .dat file mismatches hardcoded c++ define value of " << LEFT_RING_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef LEFT_WIELDED_INDEX // DO NOT MODIFY!
+ bsA = 6;
+ bsB = LEFT_WIELDED_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEFT_WIELDED_INDEX with value 6 from .dat file mismatches hardcoded c++ define value of " << LEFT_WIELDED_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef LEGIFER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = LEGIFER;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEGIFER with value 2 from .dat file mismatches hardcoded c++ define value of " << LEGIFER << "!" << std::endl;
+#endif
+
+
+#ifdef LEGS // DO NOT MODIFY!
+ bsA = 96;
+ bsB = LEGS;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEGS with value 96 from .dat file mismatches hardcoded c++ define value of " << LEGS << "!" << std::endl;
+#endif
+
+
+#ifdef LEG_MAIN_COLOR // DO NOT MODIFY!
+ bsA = 2048;
+ bsB = LEG_MAIN_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEG_MAIN_COLOR with value 2048 from .dat file mismatches hardcoded c++ define value of " << LEG_MAIN_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef LEG_SPECIAL_COLOR // DO NOT MODIFY!
+ bsA = 4096;
+ bsB = LEG_SPECIAL_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEG_SPECIAL_COLOR with value 4096 from .dat file mismatches hardcoded c++ define value of " << LEG_SPECIAL_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef LEG_STRENGTH // DO NOT MODIFY!
+ bsA = 8;
+ bsB = LEG_STRENGTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEG_STRENGTH with value 8 from .dat file mismatches hardcoded c++ define value of " << LEG_STRENGTH << "!" << std::endl;
+#endif
+
+
+#ifdef LEPROSY // DO NOT MODIFY!
+ bsA = 524288;
+ bsB = LEPROSY;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEPROSY with value 524288 from .dat file mismatches hardcoded c++ define value of " << LEPROSY << "!" << std::endl;
+#endif
+
+
+#ifdef LEVIATHAN_HIDE // DO NOT MODIFY!
+ bsA = 4172;
+ bsB = LEVIATHAN_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEVIATHAN_HIDE with value 4172 from .dat file mismatches hardcoded c++ define value of " << LEVIATHAN_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef LEVITATION // DO NOT MODIFY!
+ bsA = 262144;
+ bsB = LEVITATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined LEVITATION with value 262144 from .dat file mismatches hardcoded c++ define value of " << LEVITATION << "!" << std::endl;
+#endif
+
+
+#ifdef LIFE_SAVED // DO NOT MODIFY!
+ bsA = 16;
+ bsB = LIFE_SAVED;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIFE_SAVED with value 16 from .dat file mismatches hardcoded c++ define value of " << LIFE_SAVED << "!" << std::endl;
+#endif
+
+
+#ifdef LIGHT // DO NOT MODIFY!
+ bsA = 4;
+ bsB = LIGHT;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIGHT with value 4 from .dat file mismatches hardcoded c++ define value of " << LIGHT << "!" << std::endl;
+#endif
+
+
+#ifdef LIGHTNING_BEAM // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LIGHTNING_BEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIGHTNING_BEAM with value 1 from .dat file mismatches hardcoded c++ define value of " << LIGHTNING_BEAM << "!" << std::endl;
+#endif
+
+
+#ifdef LIGHT_ASIAN_SIREN // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LIGHT_ASIAN_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIGHT_ASIAN_SIREN with value 1 from .dat file mismatches hardcoded c++ define value of " << LIGHT_ASIAN_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef LIGHT_FROG_BLOOD // DO NOT MODIFY!
+ bsA = 16429;
+ bsB = LIGHT_FROG_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIGHT_FROG_BLOOD with value 16429 from .dat file mismatches hardcoded c++ define value of " << LIGHT_FROG_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef LIGHT_GRAY // DO NOT MODIFY!
+ bsA = 38066;
+ bsB = LIGHT_GRAY;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIGHT_GRAY with value 38066 from .dat file mismatches hardcoded c++ define value of " << LIGHT_GRAY << "!" << std::endl;
+#endif
+
+
+#ifdef LIME_STONE // DO NOT MODIFY!
+ bsA = 4260;
+ bsB = LIME_STONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIME_STONE with value 4260 from .dat file mismatches hardcoded c++ define value of " << LIME_STONE << "!" << std::endl;
+#endif
+
+
+#ifdef LINEN_CLOTH // DO NOT MODIFY!
+ bsA = 4128;
+ bsB = LINEN_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined LINEN_CLOTH with value 4128 from .dat file mismatches hardcoded c++ define value of " << LINEN_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef LION_FLESH // DO NOT MODIFY!
+ bsA = 20513;
+ bsB = LION_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined LION_FLESH with value 20513 from .dat file mismatches hardcoded c++ define value of " << LION_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef LIQUID_DARKNESS // DO NOT MODIFY!
+ bsA = 16413;
+ bsB = LIQUID_DARKNESS;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIQUID_DARKNESS with value 16413 from .dat file mismatches hardcoded c++ define value of " << LIQUID_DARKNESS << "!" << std::endl;
+#endif
+
+
+#ifdef LIQUID_FEAR // DO NOT MODIFY!
+ bsA = 16414;
+ bsB = LIQUID_FEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIQUID_FEAR with value 16414 from .dat file mismatches hardcoded c++ define value of " << LIQUID_FEAR << "!" << std::endl;
+#endif
+
+
+#ifdef LIQUID_ID // DO NOT MODIFY!
+ bsA = 16384;
+ bsB = LIQUID_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined LIQUID_ID with value 16384 from .dat file mismatches hardcoded c++ define value of " << LIQUID_ID << "!" << std::endl;
+#endif
+
+
+#ifdef LOCKED // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LOCKED;
+ if(bsA!=bsB)
+ ssErrors << "Defined LOCKED with value 1 from .dat file mismatches hardcoded c++ define value of " << LOCKED << "!" << std::endl;
+#endif
+
+
+#ifdef LOCK_DELTA // DO NOT MODIFY!
+ bsA = 1024;
+ bsB = LOCK_DELTA;
+ if(bsA!=bsB)
+ ssErrors << "Defined LOCK_DELTA with value 1024 from .dat file mismatches hardcoded c++ define value of " << LOCK_DELTA << "!" << std::endl;
+#endif
+
+
+#ifdef LONG_SWORD // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LONG_SWORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined LONG_SWORD with value 1 from .dat file mismatches hardcoded c++ define value of " << LONG_SWORD << "!" << std::endl;
+#endif
+
+
+#ifdef LORD // DO NOT MODIFY!
+ bsA = 1;
+ bsB = LORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined LORD with value 1 from .dat file mismatches hardcoded c++ define value of " << LORD << "!" << std::endl;
+#endif
+
+
+#ifdef LORICATUS // DO NOT MODIFY!
+ bsA = 8;
+ bsB = LORICATUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined LORICATUS with value 8 from .dat file mismatches hardcoded c++ define value of " << LORICATUS << "!" << std::endl;
+#endif
+
+
+#ifdef LOST_RUBY_FLAMING_SWORD // DO NOT MODIFY!
+ bsA = 2;
+ bsB = LOST_RUBY_FLAMING_SWORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined LOST_RUBY_FLAMING_SWORD with value 2 from .dat file mismatches hardcoded c++ define value of " << LOST_RUBY_FLAMING_SWORD << "!" << std::endl;
+#endif
+
+
+#ifdef LYCANTHROPY // DO NOT MODIFY!
+ bsA = 32;
+ bsB = LYCANTHROPY;
+ if(bsA!=bsB)
+ ssErrors << "Defined LYCANTHROPY with value 32 from .dat file mismatches hardcoded c++ define value of " << LYCANTHROPY << "!" << std::endl;
+#endif
+
+
+#ifdef MACE // DO NOT MODIFY!
+ bsA = 7;
+ bsB = MACE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MACE with value 7 from .dat file mismatches hardcoded c++ define value of " << MACE << "!" << std::endl;
+#endif
+
+
+#ifdef MAGE_STAFF // DO NOT MODIFY!
+ bsA = 18;
+ bsB = MAGE_STAFF;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAGE_STAFF with value 18 from .dat file mismatches hardcoded c++ define value of " << MAGE_STAFF << "!" << std::endl;
+#endif
+
+
+#ifdef MAGIC_CRYSTAL // DO NOT MODIFY!
+ bsA = 4201;
+ bsB = MAGIC_CRYSTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAGIC_CRYSTAL with value 4201 from .dat file mismatches hardcoded c++ define value of " << MAGIC_CRYSTAL << "!" << std::endl;
+#endif
+
+
+#ifdef MAGIC_LIQUID // DO NOT MODIFY!
+ bsA = 16388;
+ bsB = MAGIC_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAGIC_LIQUID with value 16388 from .dat file mismatches hardcoded c++ define value of " << MAGIC_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef MAGIC_MUSHROOM_FLESH // DO NOT MODIFY!
+ bsA = 20528;
+ bsB = MAGIC_MUSHROOM_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAGIC_MUSHROOM_FLESH with value 20528 from .dat file mismatches hardcoded c++ define value of " << MAGIC_MUSHROOM_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MAGIC_VAPOUR // DO NOT MODIFY!
+ bsA = 12295;
+ bsB = MAGIC_VAPOUR;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAGIC_VAPOUR with value 12295 from .dat file mismatches hardcoded c++ define value of " << MAGIC_VAPOUR << "!" << std::endl;
+#endif
+
+
+#ifdef MAGPIE_FLESH // DO NOT MODIFY!
+ bsA = 20522;
+ bsB = MAGPIE_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAGPIE_FLESH with value 20522 from .dat file mismatches hardcoded c++ define value of " << MAGPIE_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MAHOGANY_WOOD // DO NOT MODIFY!
+ bsA = 4236;
+ bsB = MAHOGANY_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAHOGANY_WOOD with value 4236 from .dat file mismatches hardcoded c++ define value of " << MAHOGANY_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef MALACHITE // DO NOT MODIFY!
+ bsA = 4301;
+ bsB = MALACHITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MALACHITE with value 4301 from .dat file mismatches hardcoded c++ define value of " << MALACHITE << "!" << std::endl;
+#endif
+
+
+#ifdef MALE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = MALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MALE with value 1 from .dat file mismatches hardcoded c++ define value of " << MALE << "!" << std::endl;
+#endif
+
+
+#ifdef MAMMOTH_FLESH // DO NOT MODIFY!
+ bsA = 20509;
+ bsB = MAMMOTH_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAMMOTH_FLESH with value 20509 from .dat file mismatches hardcoded c++ define value of " << MAMMOTH_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MAMMOTH_TUSK // DO NOT MODIFY!
+ bsA = 8218;
+ bsB = MAMMOTH_TUSK;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAMMOTH_TUSK with value 8218 from .dat file mismatches hardcoded c++ define value of " << MAMMOTH_TUSK << "!" << std::endl;
+#endif
+
+
+#ifdef MANA // DO NOT MODIFY!
+ bsA = 6;
+ bsB = MANA;
+ if(bsA!=bsB)
+ ssErrors << "Defined MANA with value 6 from .dat file mismatches hardcoded c++ define value of " << MANA << "!" << std::endl;
+#endif
+
+
+#ifdef MANGO_FLESH // DO NOT MODIFY!
+ bsA = 8201;
+ bsB = MANGO_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MANGO_FLESH with value 8201 from .dat file mismatches hardcoded c++ define value of " << MANGO_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MARBLE // DO NOT MODIFY!
+ bsA = 4263;
+ bsB = MARBLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MARBLE with value 4263 from .dat file mismatches hardcoded c++ define value of " << MARBLE << "!" << std::endl;
+#endif
+
+
+#ifdef MARSHAL // DO NOT MODIFY!
+ bsA = 5;
+ bsB = MARSHAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined MARSHAL with value 5 from .dat file mismatches hardcoded c++ define value of " << MARSHAL << "!" << std::endl;
+#endif
+
+
+#ifdef MARTIAL_SKILL_CATEGORIES // DO NOT MODIFY!
+ bsA = 3;
+ bsB = MARTIAL_SKILL_CATEGORIES;
+ if(bsA!=bsB)
+ ssErrors << "Defined MARTIAL_SKILL_CATEGORIES with value 3 from .dat file mismatches hardcoded c++ define value of " << MARTIAL_SKILL_CATEGORIES << "!" << std::endl;
+#endif
+
+
+#ifdef MASK // DO NOT MODIFY!
+ bsA = 12;
+ bsB = MASK;
+ if(bsA!=bsB)
+ ssErrors << "Defined MASK with value 12 from .dat file mismatches hardcoded c++ define value of " << MASK << "!" << std::endl;
+#endif
+
+
+#ifdef MASTER // DO NOT MODIFY!
+ bsA = 7;
+ bsB = MASTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MASTER with value 7 from .dat file mismatches hardcoded c++ define value of " << MASTER << "!" << std::endl;
+#endif
+
+
+#ifdef MASTER_ASSASSIN // DO NOT MODIFY!
+ bsA = 5;
+ bsB = MASTER_ASSASSIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined MASTER_ASSASSIN with value 5 from .dat file mismatches hardcoded c++ define value of " << MASTER_ASSASSIN << "!" << std::endl;
+#endif
+
+
+#ifdef MASTER_NECROMANCER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = MASTER_NECROMANCER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MASTER_NECROMANCER with value 2 from .dat file mismatches hardcoded c++ define value of " << MASTER_NECROMANCER << "!" << std::endl;
+#endif
+
+
+#ifdef MASTER_TORTURER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = MASTER_TORTURER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MASTER_TORTURER with value 1 from .dat file mismatches hardcoded c++ define value of " << MASTER_TORTURER << "!" << std::endl;
+#endif
+
+
+#ifdef MAX_PRICE // DO NOT MODIFY!
+ bsA = 2147483647;
+ bsB = MAX_PRICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAX_PRICE with value 2147483647 from .dat file mismatches hardcoded c++ define value of " << MAX_PRICE << "!" << std::endl;
+#endif
+
+
+#ifdef MAZE_ROOM // DO NOT MODIFY!
+ bsA = 3;
+ bsB = MAZE_ROOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined MAZE_ROOM with value 3 from .dat file mismatches hardcoded c++ define value of " << MAZE_ROOM << "!" << std::endl;
+#endif
+
+
+#ifdef MEAT_CLEAVER // DO NOT MODIFY!
+ bsA = 22;
+ bsB = MEAT_CLEAVER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MEAT_CLEAVER with value 22 from .dat file mismatches hardcoded c++ define value of " << MEAT_CLEAVER << "!" << std::endl;
+#endif
+
+
+#ifdef MELLIS // DO NOT MODIFY!
+ bsA = 9;
+ bsB = MELLIS;
+ if(bsA!=bsB)
+ ssErrors << "Defined MELLIS with value 9 from .dat file mismatches hardcoded c++ define value of " << MELLIS << "!" << std::endl;
+#endif
+
+
+#ifdef MERCURY // DO NOT MODIFY!
+ bsA = 16435;
+ bsB = MERCURY;
+ if(bsA!=bsB)
+ ssErrors << "Defined MERCURY with value 16435 from .dat file mismatches hardcoded c++ define value of " << MERCURY << "!" << std::endl;
+#endif
+
+
+#ifdef MERMAID_HAIR // DO NOT MODIFY!
+ bsA = 4168;
+ bsB = MERMAID_HAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined MERMAID_HAIR with value 4168 from .dat file mismatches hardcoded c++ define value of " << MERMAID_HAIR << "!" << std::endl;
+#endif
+
+
+#ifdef METEORIC_STEEL // DO NOT MODIFY!
+ bsA = 28677;
+ bsB = METEORIC_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined METEORIC_STEEL with value 28677 from .dat file mismatches hardcoded c++ define value of " << METEORIC_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef MILK // DO NOT MODIFY!
+ bsA = 16393;
+ bsB = MILK;
+ if(bsA!=bsB)
+ ssErrors << "Defined MILK with value 16393 from .dat file mismatches hardcoded c++ define value of " << MILK << "!" << std::endl;
+#endif
+
+
+#ifdef MILKY_QUARTZ // DO NOT MODIFY!
+ bsA = 4289;
+ bsB = MILKY_QUARTZ;
+ if(bsA!=bsB)
+ ssErrors << "Defined MILKY_QUARTZ with value 4289 from .dat file mismatches hardcoded c++ define value of " << MILKY_QUARTZ << "!" << std::endl;
+#endif
+
+
+#ifdef MIND_WORM_FLESH // DO NOT MODIFY!
+ bsA = 20530;
+ bsB = MIND_WORM_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MIND_WORM_FLESH with value 20530 from .dat file mismatches hardcoded c++ define value of " << MIND_WORM_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MIRROR // DO NOT MODIFY!
+ bsA = 1;
+ bsB = MIRROR;
+ if(bsA!=bsB)
+ ssErrors << "Defined MIRROR with value 1 from .dat file mismatches hardcoded c++ define value of " << MIRROR << "!" << std::endl;
+#endif
+
+
+#ifdef MISC // DO NOT MODIFY!
+ bsA = 131072;
+ bsB = MISC;
+ if(bsA!=bsB)
+ ssErrors << "Defined MISC with value 131072 from .dat file mismatches hardcoded c++ define value of " << MISC << "!" << std::endl;
+#endif
+
+
+#ifdef MITHRIL // DO NOT MODIFY!
+ bsA = 4110;
+ bsB = MITHRIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined MITHRIL with value 4110 from .dat file mismatches hardcoded c++ define value of " << MITHRIL << "!" << std::endl;
+#endif
+
+
+#ifdef MODERATELY_BURNT // DO NOT MODIFY!
+ bsA = 2;
+ bsB = MODERATELY_BURNT;
+ if(bsA!=bsB)
+ ssErrors << "Defined MODERATELY_BURNT with value 2 from .dat file mismatches hardcoded c++ define value of " << MODERATELY_BURNT << "!" << std::endl;
+#endif
+
+
+#ifdef MONK // DO NOT MODIFY!
+ bsA = 5;
+ bsB = MONK;
+ if(bsA!=bsB)
+ ssErrors << "Defined MONK with value 5 from .dat file mismatches hardcoded c++ define value of " << MONK << "!" << std::endl;
+#endif
+
+
+#ifdef MONSTER_TEAM // DO NOT MODIFY!
+ bsA = 1;
+ bsB = MONSTER_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined MONSTER_TEAM with value 1 from .dat file mismatches hardcoded c++ define value of " << MONSTER_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef MOON_SILVER // DO NOT MODIFY!
+ bsA = 4108;
+ bsB = MOON_SILVER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MOON_SILVER with value 4108 from .dat file mismatches hardcoded c++ define value of " << MOON_SILVER << "!" << std::endl;
+#endif
+
+
+#ifdef MOOSE_ANTLER // DO NOT MODIFY!
+ bsA = 4251;
+ bsB = MOOSE_ANTLER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MOOSE_ANTLER with value 4251 from .dat file mismatches hardcoded c++ define value of " << MOOSE_ANTLER << "!" << std::endl;
+#endif
+
+
+#ifdef MOOSE_FLESH // DO NOT MODIFY!
+ bsA = 20521;
+ bsB = MOOSE_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MOOSE_FLESH with value 20521 from .dat file mismatches hardcoded c++ define value of " << MOOSE_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MORAINE // DO NOT MODIFY!
+ bsA = 4258;
+ bsB = MORAINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MORAINE with value 4258 from .dat file mismatches hardcoded c++ define value of " << MORAINE << "!" << std::endl;
+#endif
+
+
+#ifdef MORTIFER // DO NOT MODIFY!
+ bsA = 15;
+ bsB = MORTIFER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MORTIFER with value 15 from .dat file mismatches hardcoded c++ define value of " << MORTIFER << "!" << std::endl;
+#endif
+
+
+#ifdef MUD // DO NOT MODIFY!
+ bsA = 16437;
+ bsB = MUD;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUD with value 16437 from .dat file mismatches hardcoded c++ define value of " << MUD << "!" << std::endl;
+#endif
+
+
+#ifdef MUSHROOM_FLESH // DO NOT MODIFY!
+ bsA = 20520;
+ bsB = MUSHROOM_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUSHROOM_FLESH with value 20520 from .dat file mismatches hardcoded c++ define value of " << MUSHROOM_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MUSTARD_GAS // DO NOT MODIFY!
+ bsA = 12299;
+ bsB = MUSTARD_GAS;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUSTARD_GAS with value 12299 from .dat file mismatches hardcoded c++ define value of " << MUSTARD_GAS << "!" << std::endl;
+#endif
+
+
+#ifdef MUSTARD_GAS_DAMAGE // DO NOT MODIFY!
+ bsA = 256;
+ bsB = MUSTARD_GAS_DAMAGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUSTARD_GAS_DAMAGE with value 256 from .dat file mismatches hardcoded c++ define value of " << MUSTARD_GAS_DAMAGE << "!" << std::endl;
+#endif
+
+
+#ifdef MUSTARD_GAS_LIQUID // DO NOT MODIFY!
+ bsA = 16412;
+ bsB = MUSTARD_GAS_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUSTARD_GAS_LIQUID with value 16412 from .dat file mismatches hardcoded c++ define value of " << MUSTARD_GAS_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef MUTANT_ASS_FLESH // DO NOT MODIFY!
+ bsA = 20499;
+ bsB = MUTANT_ASS_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUTANT_ASS_FLESH with value 20499 from .dat file mismatches hardcoded c++ define value of " << MUTANT_ASS_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MUTANT_BEAR // DO NOT MODIFY!
+ bsA = 5;
+ bsB = MUTANT_BEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUTANT_BEAR with value 5 from .dat file mismatches hardcoded c++ define value of " << MUTANT_BEAR << "!" << std::endl;
+#endif
+
+
+#ifdef MUTANT_BUNNY_FLESH // DO NOT MODIFY!
+ bsA = 20525;
+ bsB = MUTANT_BUNNY_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUTANT_BUNNY_FLESH with value 20525 from .dat file mismatches hardcoded c++ define value of " << MUTANT_BUNNY_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef MUTANT_PLANT_FIBER // DO NOT MODIFY!
+ bsA = 8194;
+ bsB = MUTANT_PLANT_FIBER;
+ if(bsA!=bsB)
+ ssErrors << "Defined MUTANT_PLANT_FIBER with value 8194 from .dat file mismatches hardcoded c++ define value of " << MUTANT_PLANT_FIBER << "!" << std::endl;
+#endif
+
+
+#ifdef MYCELIUM // DO NOT MODIFY!
+ bsA = 4215;
+ bsB = MYCELIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined MYCELIUM with value 4215 from .dat file mismatches hardcoded c++ define value of " << MYCELIUM << "!" << std::endl;
+#endif
+
+
+#ifdef MYSTERY_MEAT // DO NOT MODIFY!
+ bsA = 20484;
+ bsB = MYSTERY_MEAT;
+ if(bsA!=bsB)
+ ssErrors << "Defined MYSTERY_MEAT with value 20484 from .dat file mismatches hardcoded c++ define value of " << MYSTERY_MEAT << "!" << std::endl;
+#endif
+
+
+#ifdef NACRE // DO NOT MODIFY!
+ bsA = 4284;
+ bsB = NACRE;
+ if(bsA!=bsB)
+ ssErrors << "Defined NACRE with value 4284 from .dat file mismatches hardcoded c++ define value of " << NACRE << "!" << std::endl;
+#endif
+
+
+#ifdef NAGA_SKIN // DO NOT MODIFY!
+ bsA = 4147;
+ bsB = NAGA_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined NAGA_SKIN with value 4147 from .dat file mismatches hardcoded c++ define value of " << NAGA_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef NANO_FIBER // DO NOT MODIFY!
+ bsA = 4183;
+ bsB = NANO_FIBER;
+ if(bsA!=bsB)
+ ssErrors << "Defined NANO_FIBER with value 4183 from .dat file mismatches hardcoded c++ define value of " << NANO_FIBER << "!" << std::endl;
+#endif
+
+
+#ifdef NECRO_CHAMBER_LEVEL // DO NOT MODIFY!
+ bsA = 6;
+ bsB = NECRO_CHAMBER_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined NECRO_CHAMBER_LEVEL with value 6 from .dat file mismatches hardcoded c++ define value of " << NECRO_CHAMBER_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef NEFAS // DO NOT MODIFY!
+ bsA = 11;
+ bsB = NEFAS;
+ if(bsA!=bsB)
+ ssErrors << "Defined NEFAS with value 11 from .dat file mismatches hardcoded c++ define value of " << NEFAS << "!" << std::endl;
+#endif
+
+
+#ifdef NEPHRITE // DO NOT MODIFY!
+ bsA = 4302;
+ bsB = NEPHRITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined NEPHRITE with value 4302 from .dat file mismatches hardcoded c++ define value of " << NEPHRITE << "!" << std::endl;
+#endif
+
+
+#ifdef NETHER_QUARTZ // DO NOT MODIFY!
+ bsA = 4292;
+ bsB = NETHER_QUARTZ;
+ if(bsA!=bsB)
+ ssErrors << "Defined NETHER_QUARTZ with value 4292 from .dat file mismatches hardcoded c++ define value of " << NETHER_QUARTZ << "!" << std::endl;
+#endif
+
+
+#ifdef NEUTRAL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = NEUTRAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined NEUTRAL with value 2 from .dat file mismatches hardcoded c++ define value of " << NEUTRAL << "!" << std::endl;
+#endif
+
+
+#ifdef NEUTRONIUM // DO NOT MODIFY!
+ bsA = 4200;
+ bsB = NEUTRONIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined NEUTRONIUM with value 4200 from .dat file mismatches hardcoded c++ define value of " << NEUTRONIUM << "!" << std::endl;
+#endif
+
+
+#ifdef NEW_ATTNAM // DO NOT MODIFY!
+ bsA = 3;
+ bsB = NEW_ATTNAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined NEW_ATTNAM with value 3 from .dat file mismatches hardcoded c++ define value of " << NEW_ATTNAM << "!" << std::endl;
+#endif
+
+
+#ifdef NEW_ATTNAM_TEAM // DO NOT MODIFY!
+ bsA = 7;
+ bsB = NEW_ATTNAM_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined NEW_ATTNAM_TEAM with value 7 from .dat file mismatches hardcoded c++ define value of " << NEW_ATTNAM_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef NICKEL // DO NOT MODIFY!
+ bsA = 4121;
+ bsB = NICKEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined NICKEL with value 4121 from .dat file mismatches hardcoded c++ define value of " << NICKEL << "!" << std::endl;
+#endif
+
+
+#ifdef NONE // DO NOT MODIFY!
+ bsA = 0;
+ bsB = NONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined NONE with value 0 from .dat file mismatches hardcoded c++ define value of " << NONE << "!" << std::endl;
+#endif
+
+
+#ifdef NOT_BURNT // DO NOT MODIFY!
+ bsA = 0;
+ bsB = NOT_BURNT;
+ if(bsA!=bsB)
+ ssErrors << "Defined NOT_BURNT with value 0 from .dat file mismatches hardcoded c++ define value of " << NOT_BURNT << "!" << std::endl;
+#endif
+
+
+#ifdef NOT_IN_ROOM // DO NOT MODIFY!
+ bsA = 8;
+ bsB = NOT_IN_ROOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined NOT_IN_ROOM with value 8 from .dat file mismatches hardcoded c++ define value of " << NOT_IN_ROOM << "!" << std::endl;
+#endif
+
+
+#ifdef NOT_RUSTED // DO NOT MODIFY!
+ bsA = 0;
+ bsB = NOT_RUSTED;
+ if(bsA!=bsB)
+ ssErrors << "Defined NOT_RUSTED with value 0 from .dat file mismatches hardcoded c++ define value of " << NOT_RUSTED << "!" << std::endl;
+#endif
+
+
+#ifdef NOT_WALKABLE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = NOT_WALKABLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined NOT_WALKABLE with value 1 from .dat file mismatches hardcoded c++ define value of " << NOT_WALKABLE << "!" << std::endl;
+#endif
+
+
+#ifdef NO_ARTICLE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = NO_ARTICLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_ARTICLE with value 4 from .dat file mismatches hardcoded c++ define value of " << NO_ARTICLE << "!" << std::endl;
+#endif
+
+
+#ifdef NO_BROKEN // DO NOT MODIFY!
+ bsA = 1;
+ bsB = NO_BROKEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_BROKEN with value 1 from .dat file mismatches hardcoded c++ define value of " << NO_BROKEN << "!" << std::endl;
+#endif
+
+
+#ifdef NO_LIMIT // DO NOT MODIFY!
+ bsA = 65535;
+ bsB = NO_LIMIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_LIMIT with value 65535 from .dat file mismatches hardcoded c++ define value of " << NO_LIMIT << "!" << std::endl;
+#endif
+
+
+#ifdef NO_MONSTER_GENERATION // DO NOT MODIFY!
+ bsA = 1;
+ bsB = NO_MONSTER_GENERATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_MONSTER_GENERATION with value 1 from .dat file mismatches hardcoded c++ define value of " << NO_MONSTER_GENERATION << "!" << std::endl;
+#endif
+
+
+#ifdef NO_MOVE // DO NOT MODIFY!
+ bsA = 0;
+ bsB = NO_MOVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_MOVE with value 0 from .dat file mismatches hardcoded c++ define value of " << NO_MOVE << "!" << std::endl;
+#endif
+
+
+#ifdef NO_PARAMETERS // DO NOT MODIFY!
+ bsA = 255;
+ bsB = NO_PARAMETERS;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_PARAMETERS with value 255 from .dat file mismatches hardcoded c++ define value of " << NO_PARAMETERS << "!" << std::endl;
+#endif
+
+
+#ifdef NO_TAMING // DO NOT MODIFY!
+ bsA = -1;
+ bsB = NO_TAMING;
+ if(bsA!=bsB)
+ ssErrors << "Defined NO_TAMING with value -1 from .dat file mismatches hardcoded c++ define value of " << NO_TAMING << "!" << std::endl;
+#endif
+
+
+#ifdef NYLON // DO NOT MODIFY!
+ bsA = 4176;
+ bsB = NYLON;
+ if(bsA!=bsB)
+ ssErrors << "Defined NYLON with value 4176 from .dat file mismatches hardcoded c++ define value of " << NYLON << "!" << std::endl;
+#endif
+
+
+#ifdef NYMPH_HAIR // DO NOT MODIFY!
+ bsA = 4134;
+ bsB = NYMPH_HAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined NYMPH_HAIR with value 4134 from .dat file mismatches hardcoded c++ define value of " << NYMPH_HAIR << "!" << std::endl;
+#endif
+
+
+#ifdef N_LOCK_ID // DO NOT MODIFY!
+ bsA = 1024;
+ bsB = N_LOCK_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined N_LOCK_ID with value 1024 from .dat file mismatches hardcoded c++ define value of " << N_LOCK_ID << "!" << std::endl;
+#endif
+
+
+#ifdef OAK // DO NOT MODIFY!
+ bsA = 21;
+ bsB = OAK;
+ if(bsA!=bsB)
+ ssErrors << "Defined OAK with value 21 from .dat file mismatches hardcoded c++ define value of " << OAK << "!" << std::endl;
+#endif
+
+
+#ifdef OAK_WOOD // DO NOT MODIFY!
+ bsA = 4241;
+ bsB = OAK_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined OAK_WOOD with value 4241 from .dat file mismatches hardcoded c++ define value of " << OAK_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef OBSIDIAN // DO NOT MODIFY!
+ bsA = 4262;
+ bsB = OBSIDIAN;
+ if(bsA!=bsB)
+ ssErrors << "Defined OBSIDIAN with value 4262 from .dat file mismatches hardcoded c++ define value of " << OBSIDIAN << "!" << std::endl;
+#endif
+
+
+#ifdef OCCULTUM // DO NOT MODIFY!
+ bsA = 4203;
+ bsB = OCCULTUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined OCCULTUM with value 4203 from .dat file mismatches hardcoded c++ define value of " << OCCULTUM << "!" << std::endl;
+#endif
+
+
+#ifdef OCTAGONAL_LOCK // DO NOT MODIFY!
+ bsA = 18432;
+ bsB = OCTAGONAL_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined OCTAGONAL_LOCK with value 18432 from .dat file mismatches hardcoded c++ define value of " << OCTAGONAL_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef OCTIRON // DO NOT MODIFY!
+ bsA = 4105;
+ bsB = OCTIRON;
+ if(bsA!=bsB)
+ ssErrors << "Defined OCTIRON with value 4105 from .dat file mismatches hardcoded c++ define value of " << OCTIRON << "!" << std::endl;
+#endif
+
+
+#ifdef OFFICER // DO NOT MODIFY!
+ bsA = 3;
+ bsB = OFFICER;
+ if(bsA!=bsB)
+ ssErrors << "Defined OFFICER with value 3 from .dat file mismatches hardcoded c++ define value of " << OFFICER << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_BLOOD // DO NOT MODIFY!
+ bsA = 16430;
+ bsB = OMMEL_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_BLOOD with value 16430 from .dat file mismatches hardcoded c++ define value of " << OMMEL_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_BONE // DO NOT MODIFY!
+ bsA = 8215;
+ bsB = OMMEL_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_BONE with value 8215 from .dat file mismatches hardcoded c++ define value of " << OMMEL_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_CERUMEN // DO NOT MODIFY!
+ bsA = 8211;
+ bsB = OMMEL_CERUMEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_CERUMEN with value 8211 from .dat file mismatches hardcoded c++ define value of " << OMMEL_CERUMEN << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_CUIRASS // DO NOT MODIFY!
+ bsA = 4;
+ bsB = OMMEL_CUIRASS;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_CUIRASS with value 4 from .dat file mismatches hardcoded c++ define value of " << OMMEL_CUIRASS << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_HAIR // DO NOT MODIFY!
+ bsA = 4135;
+ bsB = OMMEL_HAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_HAIR with value 4135 from .dat file mismatches hardcoded c++ define value of " << OMMEL_HAIR << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_SNOT // DO NOT MODIFY!
+ bsA = 16434;
+ bsB = OMMEL_SNOT;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_SNOT with value 16434 from .dat file mismatches hardcoded c++ define value of " << OMMEL_SNOT << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_SWEAT // DO NOT MODIFY!
+ bsA = 16432;
+ bsB = OMMEL_SWEAT;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_SWEAT with value 16432 from .dat file mismatches hardcoded c++ define value of " << OMMEL_SWEAT << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_TEARS // DO NOT MODIFY!
+ bsA = 16433;
+ bsB = OMMEL_TEARS;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_TEARS with value 16433 from .dat file mismatches hardcoded c++ define value of " << OMMEL_TEARS << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_TOOTH // DO NOT MODIFY!
+ bsA = 8219;
+ bsB = OMMEL_TOOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_TOOTH with value 8219 from .dat file mismatches hardcoded c++ define value of " << OMMEL_TOOTH << "!" << std::endl;
+#endif
+
+
+#ifdef OMMEL_URINE // DO NOT MODIFY!
+ bsA = 16431;
+ bsB = OMMEL_URINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined OMMEL_URINE with value 16431 from .dat file mismatches hardcoded c++ define value of " << OMMEL_URINE << "!" << std::endl;
+#endif
+
+
+#ifdef ONYX // DO NOT MODIFY!
+ bsA = 4282;
+ bsB = ONYX;
+ if(bsA!=bsB)
+ ssErrors << "Defined ONYX with value 4282 from .dat file mismatches hardcoded c++ define value of " << ONYX << "!" << std::endl;
+#endif
+
+
+#ifdef OPAL // DO NOT MODIFY!
+ bsA = 4281;
+ bsB = OPAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined OPAL with value 4281 from .dat file mismatches hardcoded c++ define value of " << OPAL << "!" << std::endl;
+#endif
+
+
+#ifdef ORC_FLESH // DO NOT MODIFY!
+ bsA = 20516;
+ bsB = ORC_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined ORC_FLESH with value 20516 from .dat file mismatches hardcoded c++ define value of " << ORC_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef OREE_LAIR // DO NOT MODIFY!
+ bsA = 12;
+ bsB = OREE_LAIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined OREE_LAIR with value 12 from .dat file mismatches hardcoded c++ define value of " << OREE_LAIR << "!" << std::endl;
+#endif
+
+
+#ifdef OREE_LAIR_ENTRY // DO NOT MODIFY!
+ bsA = 300;
+ bsB = OREE_LAIR_ENTRY;
+ if(bsA!=bsB)
+ ssErrors << "Defined OREE_LAIR_ENTRY with value 300 from .dat file mismatches hardcoded c++ define value of " << OREE_LAIR_ENTRY << "!" << std::endl;
+#endif
+
+
+#ifdef OREE_LAIR_EXIT // DO NOT MODIFY!
+ bsA = 400;
+ bsB = OREE_LAIR_EXIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined OREE_LAIR_EXIT with value 400 from .dat file mismatches hardcoded c++ define value of " << OREE_LAIR_EXIT << "!" << std::endl;
+#endif
+
+
+#ifdef ORGANIC_ID // DO NOT MODIFY!
+ bsA = 8192;
+ bsB = ORGANIC_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined ORGANIC_ID with value 8192 from .dat file mismatches hardcoded c++ define value of " << ORGANIC_ID << "!" << std::endl;
+#endif
+
+
+#ifdef ORICHALCUM // DO NOT MODIFY!
+ bsA = 4106;
+ bsB = ORICHALCUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ORICHALCUM with value 4106 from .dat file mismatches hardcoded c++ define value of " << ORICHALCUM << "!" << std::endl;
+#endif
+
+
+#ifdef OSTRICH_FEATHER // DO NOT MODIFY!
+ bsA = 4160;
+ bsB = OSTRICH_FEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined OSTRICH_FEATHER with value 4160 from .dat file mismatches hardcoded c++ define value of " << OSTRICH_FEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef OSTRICH_FLESH // DO NOT MODIFY!
+ bsA = 20517;
+ bsB = OSTRICH_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined OSTRICH_FLESH with value 20517 from .dat file mismatches hardcoded c++ define value of " << OSTRICH_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef OTHER // DO NOT MODIFY!
+ bsA = 128;
+ bsB = OTHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined OTHER with value 128 from .dat file mismatches hardcoded c++ define value of " << OTHER << "!" << std::endl;
+#endif
+
+
+#ifdef OUROBOROS_HIDE // DO NOT MODIFY!
+ bsA = 4159;
+ bsB = OUROBOROS_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined OUROBOROS_HIDE with value 4159 from .dat file mismatches hardcoded c++ define value of " << OUROBOROS_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef OVEN // DO NOT MODIFY!
+ bsA = 28;
+ bsB = OVEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined OVEN with value 28 from .dat file mismatches hardcoded c++ define value of " << OVEN << "!" << std::endl;
+#endif
+
+
+#ifdef PALLADIUM // DO NOT MODIFY!
+ bsA = 4125;
+ bsB = PALLADIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PALLADIUM with value 4125 from .dat file mismatches hardcoded c++ define value of " << PALLADIUM << "!" << std::endl;
+#endif
+
+
+#ifdef PALM // DO NOT MODIFY!
+ bsA = 15;
+ bsB = PALM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PALM with value 15 from .dat file mismatches hardcoded c++ define value of " << PALM << "!" << std::endl;
+#endif
+
+
+#ifdef PALM_LEAF // DO NOT MODIFY!
+ bsA = 4217;
+ bsB = PALM_LEAF;
+ if(bsA!=bsB)
+ ssErrors << "Defined PALM_LEAF with value 4217 from .dat file mismatches hardcoded c++ define value of " << PALM_LEAF << "!" << std::endl;
+#endif
+
+
+#ifdef PANDA_BEAR // DO NOT MODIFY!
+ bsA = 6;
+ bsB = PANDA_BEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined PANDA_BEAR with value 6 from .dat file mismatches hardcoded c++ define value of " << PANDA_BEAR << "!" << std::endl;
+#endif
+
+
+#ifdef PANIC // DO NOT MODIFY!
+ bsA = 8192;
+ bsB = PANIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined PANIC with value 8192 from .dat file mismatches hardcoded c++ define value of " << PANIC << "!" << std::endl;
+#endif
+
+
+#ifdef PAPER_BOARD // DO NOT MODIFY!
+ bsA = 4225;
+ bsB = PAPER_BOARD;
+ if(bsA!=bsB)
+ ssErrors << "Defined PAPER_BOARD with value 4225 from .dat file mismatches hardcoded c++ define value of " << PAPER_BOARD << "!" << std::endl;
+#endif
+
+
+#ifdef PAPYRUS // DO NOT MODIFY!
+ bsA = 4222;
+ bsB = PAPYRUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined PAPYRUS with value 4222 from .dat file mismatches hardcoded c++ define value of " << PAPYRUS << "!" << std::endl;
+#endif
+
+
+#ifdef PARASITE_MIND_WORM // DO NOT MODIFY!
+ bsA = 2147483648;
+ bsB = PARASITE_MIND_WORM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PARASITE_MIND_WORM with value 2147483648 from .dat file mismatches hardcoded c++ define value of " << PARASITE_MIND_WORM << "!" << std::endl;
+#endif
+
+
+#ifdef PARASITE_TAPE_WORM // DO NOT MODIFY!
+ bsA = 32768;
+ bsB = PARASITE_TAPE_WORM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PARASITE_TAPE_WORM with value 32768 from .dat file mismatches hardcoded c++ define value of " << PARASITE_TAPE_WORM << "!" << std::endl;
+#endif
+
+
+#ifdef PARCHMENT // DO NOT MODIFY!
+ bsA = 4223;
+ bsB = PARCHMENT;
+ if(bsA!=bsB)
+ ssErrors << "Defined PARCHMENT with value 4223 from .dat file mismatches hardcoded c++ define value of " << PARCHMENT << "!" << std::endl;
+#endif
+
+
+#ifdef PARQUET // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PARQUET;
+ if(bsA!=bsB)
+ ssErrors << "Defined PARQUET with value 1 from .dat file mismatches hardcoded c++ define value of " << PARQUET << "!" << std::endl;
+#endif
+
+
+#ifdef PARTICLE_BEAM // DO NOT MODIFY!
+ bsA = 0;
+ bsB = PARTICLE_BEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PARTICLE_BEAM with value 0 from .dat file mismatches hardcoded c++ define value of " << PARTICLE_BEAM << "!" << std::endl;
+#endif
+
+
+#ifdef PATRIARCH // DO NOT MODIFY!
+ bsA = 3;
+ bsB = PATRIARCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined PATRIARCH with value 3 from .dat file mismatches hardcoded c++ define value of " << PATRIARCH << "!" << std::endl;
+#endif
+
+
+#ifdef PATROL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = PATROL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PATROL with value 4 from .dat file mismatches hardcoded c++ define value of " << PATROL << "!" << std::endl;
+#endif
+
+
+#ifdef PEARL // DO NOT MODIFY!
+ bsA = 4285;
+ bsB = PEARL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PEARL with value 4285 from .dat file mismatches hardcoded c++ define value of " << PEARL << "!" << std::endl;
+#endif
+
+
+#ifdef PEARL_GLASS // DO NOT MODIFY!
+ bsA = 4207;
+ bsB = PEARL_GLASS;
+ if(bsA!=bsB)
+ ssErrors << "Defined PEARL_GLASS with value 4207 from .dat file mismatches hardcoded c++ define value of " << PEARL_GLASS << "!" << std::endl;
+#endif
+
+
+#ifdef PEA_SOUP // DO NOT MODIFY!
+ bsA = 16389;
+ bsB = PEA_SOUP;
+ if(bsA!=bsB)
+ ssErrors << "Defined PEA_SOUP with value 16389 from .dat file mismatches hardcoded c++ define value of " << PEA_SOUP << "!" << std::endl;
+#endif
+
+
+#ifdef PEDESTAL // DO NOT MODIFY!
+ bsA = 25;
+ bsB = PEDESTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PEDESTAL with value 25 from .dat file mismatches hardcoded c++ define value of " << PEDESTAL << "!" << std::endl;
+#endif
+
+
+#ifdef PEPSI // DO NOT MODIFY!
+ bsA = 16410;
+ bsB = PEPSI;
+ if(bsA!=bsB)
+ ssErrors << "Defined PEPSI with value 16410 from .dat file mismatches hardcoded c++ define value of " << PEPSI << "!" << std::endl;
+#endif
+
+
+#ifdef PERCEPTION // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PERCEPTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined PERCEPTION with value 1 from .dat file mismatches hardcoded c++ define value of " << PERCEPTION << "!" << std::endl;
+#endif
+
+
+#ifdef PETRIFIED_DARK // DO NOT MODIFY!
+ bsA = 4118;
+ bsB = PETRIFIED_DARK;
+ if(bsA!=bsB)
+ ssErrors << "Defined PETRIFIED_DARK with value 4118 from .dat file mismatches hardcoded c++ define value of " << PETRIFIED_DARK << "!" << std::endl;
+#endif
+
+
+#ifdef PETRIFIED_WOOD // DO NOT MODIFY!
+ bsA = 4247;
+ bsB = PETRIFIED_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined PETRIFIED_WOOD with value 4247 from .dat file mismatches hardcoded c++ define value of " << PETRIFIED_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef PHOENIX_FEATHER // DO NOT MODIFY!
+ bsA = 4163;
+ bsB = PHOENIX_FEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined PHOENIX_FEATHER with value 4163 from .dat file mismatches hardcoded c++ define value of " << PHOENIX_FEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef PHOENIX_SHIELD // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PHOENIX_SHIELD;
+ if(bsA!=bsB)
+ ssErrors << "Defined PHOENIX_SHIELD with value 1 from .dat file mismatches hardcoded c++ define value of " << PHOENIX_SHIELD << "!" << std::endl;
+#endif
+
+
+#ifdef PHYSICAL_DAMAGE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PHYSICAL_DAMAGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PHYSICAL_DAMAGE with value 1 from .dat file mismatches hardcoded c++ define value of " << PHYSICAL_DAMAGE << "!" << std::endl;
+#endif
+
+
+#ifdef PIERCE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = PIERCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PIERCE with value 4 from .dat file mismatches hardcoded c++ define value of " << PIERCE << "!" << std::endl;
+#endif
+
+
+#ifdef PIG_IRON // DO NOT MODIFY!
+ bsA = 28673;
+ bsB = PIG_IRON;
+ if(bsA!=bsB)
+ ssErrors << "Defined PIG_IRON with value 28673 from .dat file mismatches hardcoded c++ define value of " << PIG_IRON << "!" << std::endl;
+#endif
+
+
+#ifdef PINE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PINE with value 1 from .dat file mismatches hardcoded c++ define value of " << PINE << "!" << std::endl;
+#endif
+
+
+#ifdef PINEAPPLE_FLESH // DO NOT MODIFY!
+ bsA = 8199;
+ bsB = PINEAPPLE_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined PINEAPPLE_FLESH with value 8199 from .dat file mismatches hardcoded c++ define value of " << PINEAPPLE_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef PINE_WOOD // DO NOT MODIFY!
+ bsA = 4238;
+ bsB = PINE_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined PINE_WOOD with value 4238 from .dat file mismatches hardcoded c++ define value of " << PINE_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef PINK // DO NOT MODIFY!
+ bsA = 61470;
+ bsB = PINK;
+ if(bsA!=bsB)
+ ssErrors << "Defined PINK with value 61470 from .dat file mismatches hardcoded c++ define value of " << PINK << "!" << std::endl;
+#endif
+
+
+#ifdef PINK_SIREN // DO NOT MODIFY!
+ bsA = 8;
+ bsB = PINK_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined PINK_SIREN with value 8 from .dat file mismatches hardcoded c++ define value of " << PINK_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef PLAIN_BED // DO NOT MODIFY!
+ bsA = 11;
+ bsB = PLAIN_BED;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLAIN_BED with value 11 from .dat file mismatches hardcoded c++ define value of " << PLAIN_BED << "!" << std::endl;
+#endif
+
+
+#ifdef PLANKTON // DO NOT MODIFY!
+ bsA = 8203;
+ bsB = PLANKTON;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLANKTON with value 8203 from .dat file mismatches hardcoded c++ define value of " << PLANKTON << "!" << std::endl;
+#endif
+
+
+#ifdef PLANT_FIBER // DO NOT MODIFY!
+ bsA = 8193;
+ bsB = PLANT_FIBER;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLANT_FIBER with value 8193 from .dat file mismatches hardcoded c++ define value of " << PLANT_FIBER << "!" << std::endl;
+#endif
+
+
+#ifdef PLANT_SAP // DO NOT MODIFY!
+ bsA = 16422;
+ bsB = PLANT_SAP;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLANT_SAP with value 16422 from .dat file mismatches hardcoded c++ define value of " << PLANT_SAP << "!" << std::endl;
+#endif
+
+
+#ifdef PLASTIC // DO NOT MODIFY!
+ bsA = 4186;
+ bsB = PLASTIC;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLASTIC with value 4186 from .dat file mismatches hardcoded c++ define value of " << PLASTIC << "!" << std::endl;
+#endif
+
+
+#ifdef PLASTIC_STEEL // DO NOT MODIFY!
+ bsA = 4189;
+ bsB = PLASTIC_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLASTIC_STEEL with value 4189 from .dat file mismatches hardcoded c++ define value of " << PLASTIC_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef PLATE_MAIL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = PLATE_MAIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLATE_MAIL with value 2 from .dat file mismatches hardcoded c++ define value of " << PLATE_MAIL << "!" << std::endl;
+#endif
+
+
+#ifdef PLATINUM // DO NOT MODIFY!
+ bsA = 4113;
+ bsB = PLATINUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLATINUM with value 4113 from .dat file mismatches hardcoded c++ define value of " << PLATINUM << "!" << std::endl;
+#endif
+
+
+#ifdef PLAYER_TEAM // DO NOT MODIFY!
+ bsA = 0;
+ bsB = PLAYER_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLAYER_TEAM with value 0 from .dat file mismatches hardcoded c++ define value of " << PLAYER_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef PLENTY // DO NOT MODIFY!
+ bsA = 5;
+ bsB = PLENTY;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLENTY with value 5 from .dat file mismatches hardcoded c++ define value of " << PLENTY << "!" << std::endl;
+#endif
+
+
+#ifdef PLURAL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PLURAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PLURAL with value 1 from .dat file mismatches hardcoded c++ define value of " << PLURAL << "!" << std::endl;
+#endif
+
+
+#ifdef POISON // DO NOT MODIFY!
+ bsA = 64;
+ bsB = POISON;
+ if(bsA!=bsB)
+ ssErrors << "Defined POISON with value 64 from .dat file mismatches hardcoded c++ define value of " << POISON << "!" << std::endl;
+#endif
+
+
+#ifdef POISONED // DO NOT MODIFY!
+ bsA = 512;
+ bsB = POISONED;
+ if(bsA!=bsB)
+ ssErrors << "Defined POISONED with value 512 from .dat file mismatches hardcoded c++ define value of " << POISONED << "!" << std::endl;
+#endif
+
+
+#ifdef POISON_LIQUID // DO NOT MODIFY!
+ bsA = 16409;
+ bsB = POISON_LIQUID;
+ if(bsA!=bsB)
+ ssErrors << "Defined POISON_LIQUID with value 16409 from .dat file mismatches hardcoded c++ define value of " << POISON_LIQUID << "!" << std::endl;
+#endif
+
+
+#ifdef POLAR_BEAR // DO NOT MODIFY!
+ bsA = 4;
+ bsB = POLAR_BEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined POLAR_BEAR with value 4 from .dat file mismatches hardcoded c++ define value of " << POLAR_BEAR << "!" << std::endl;
+#endif
+
+
+#ifdef POLE_ARMS // DO NOT MODIFY!
+ bsA = 8;
+ bsB = POLE_ARMS;
+ if(bsA!=bsB)
+ ssErrors << "Defined POLE_ARMS with value 8 from .dat file mismatches hardcoded c++ define value of " << POLE_ARMS << "!" << std::endl;
+#endif
+
+
+#ifdef POLYMORPH // DO NOT MODIFY!
+ bsA = 2048;
+ bsB = POLYMORPH;
+ if(bsA!=bsB)
+ ssErrors << "Defined POLYMORPH with value 2048 from .dat file mismatches hardcoded c++ define value of " << POLYMORPH << "!" << std::endl;
+#endif
+
+
+#ifdef POLYMORPHED // DO NOT MODIFY!
+ bsA = 1;
+ bsB = POLYMORPHED;
+ if(bsA!=bsB)
+ ssErrors << "Defined POLYMORPHED with value 1 from .dat file mismatches hardcoded c++ define value of " << POLYMORPHED << "!" << std::endl;
+#endif
+
+
+#ifdef POLYMORPH_CONTROL // DO NOT MODIFY!
+ bsA = 8;
+ bsB = POLYMORPH_CONTROL;
+ if(bsA!=bsB)
+ ssErrors << "Defined POLYMORPH_CONTROL with value 8 from .dat file mismatches hardcoded c++ define value of " << POLYMORPH_CONTROL << "!" << std::endl;
+#endif
+
+
+#ifdef POLYMORPH_LOCK // DO NOT MODIFY!
+ bsA = 33554432;
+ bsB = POLYMORPH_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined POLYMORPH_LOCK with value 33554432 from .dat file mismatches hardcoded c++ define value of " << POLYMORPH_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef POOL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = POOL;
+ if(bsA!=bsB)
+ ssErrors << "Defined POOL with value 1 from .dat file mismatches hardcoded c++ define value of " << POOL << "!" << std::endl;
+#endif
+
+
+#ifdef POOL_BORDER // DO NOT MODIFY!
+ bsA = 13;
+ bsB = POOL_BORDER;
+ if(bsA!=bsB)
+ ssErrors << "Defined POOL_BORDER with value 13 from .dat file mismatches hardcoded c++ define value of " << POOL_BORDER << "!" << std::endl;
+#endif
+
+
+#ifdef POOL_CORNER // DO NOT MODIFY!
+ bsA = 14;
+ bsB = POOL_CORNER;
+ if(bsA!=bsB)
+ ssErrors << "Defined POOL_CORNER with value 14 from .dat file mismatches hardcoded c++ define value of " << POOL_CORNER << "!" << std::endl;
+#endif
+
+
+#ifdef PORCELAIN // DO NOT MODIFY!
+ bsA = 4320;
+ bsB = PORCELAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined PORCELAIN with value 4320 from .dat file mismatches hardcoded c++ define value of " << PORCELAIN << "!" << std::endl;
+#endif
+
+
+#ifdef PORK // DO NOT MODIFY!
+ bsA = 20481;
+ bsB = PORK;
+ if(bsA!=bsB)
+ ssErrors << "Defined PORK with value 20481 from .dat file mismatches hardcoded c++ define value of " << PORK << "!" << std::endl;
+#endif
+
+
+#ifdef PORRIDGE // DO NOT MODIFY!
+ bsA = 16391;
+ bsB = PORRIDGE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PORRIDGE with value 16391 from .dat file mismatches hardcoded c++ define value of " << PORRIDGE << "!" << std::endl;
+#endif
+
+
+#ifdef POTION // DO NOT MODIFY!
+ bsA = 2048;
+ bsB = POTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined POTION with value 2048 from .dat file mismatches hardcoded c++ define value of " << POTION << "!" << std::endl;
+#endif
+
+
+#ifdef POTTED_CACTUS // DO NOT MODIFY!
+ bsA = 1;
+ bsB = POTTED_CACTUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined POTTED_CACTUS with value 1 from .dat file mismatches hardcoded c++ define value of " << POTTED_CACTUS << "!" << std::endl;
+#endif
+
+
+#ifdef POTTED_PLANT // DO NOT MODIFY!
+ bsA = 2;
+ bsB = POTTED_PLANT;
+ if(bsA!=bsB)
+ ssErrors << "Defined POTTED_PLANT with value 2 from .dat file mismatches hardcoded c++ define value of " << POTTED_PLANT << "!" << std::endl;
+#endif
+
+
+#ifdef POWDER_ID // DO NOT MODIFY!
+ bsA = 24576;
+ bsB = POWDER_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined POWDER_ID with value 24576 from .dat file mismatches hardcoded c++ define value of " << POWDER_ID << "!" << std::endl;
+#endif
+
+
+#ifdef PRIMORDIAL_ICE // DO NOT MODIFY!
+ bsA = 4212;
+ bsB = PRIMORDIAL_ICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PRIMORDIAL_ICE with value 4212 from .dat file mismatches hardcoded c++ define value of " << PRIMORDIAL_ICE << "!" << std::endl;
+#endif
+
+
+#ifdef PRINCE // DO NOT MODIFY!
+ bsA = 3;
+ bsB = PRINCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PRINCE with value 3 from .dat file mismatches hardcoded c++ define value of " << PRINCE << "!" << std::endl;
+#endif
+
+
+#ifdef PRISONER_TEAM // DO NOT MODIFY!
+ bsA = 15;
+ bsB = PRISONER_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined PRISONER_TEAM with value 15 from .dat file mismatches hardcoded c++ define value of " << PRISONER_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef PSYPHER // DO NOT MODIFY!
+ bsA = 4327;
+ bsB = PSYPHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined PSYPHER with value 4327 from .dat file mismatches hardcoded c++ define value of " << PSYPHER << "!" << std::endl;
+#endif
+
+
+#ifdef PUPPY_SKULL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = PUPPY_SKULL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PUPPY_SKULL with value 1 from .dat file mismatches hardcoded c++ define value of " << PUPPY_SKULL << "!" << std::endl;
+#endif
+
+
+#ifdef PURPLE_CRYSTAL // DO NOT MODIFY!
+ bsA = 4309;
+ bsB = PURPLE_CRYSTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined PURPLE_CRYSTAL with value 4309 from .dat file mismatches hardcoded c++ define value of " << PURPLE_CRYSTAL << "!" << std::endl;
+#endif
+
+
+#ifdef PYRITE // DO NOT MODIFY!
+ bsA = 4325;
+ bsB = PYRITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined PYRITE with value 4325 from .dat file mismatches hardcoded c++ define value of " << PYRITE << "!" << std::endl;
+#endif
+
+
+#ifdef QUARTER_STAFF // DO NOT MODIFY!
+ bsA = 15;
+ bsB = QUARTER_STAFF;
+ if(bsA!=bsB)
+ ssErrors << "Defined QUARTER_STAFF with value 15 from .dat file mismatches hardcoded c++ define value of " << QUARTER_STAFF << "!" << std::endl;
+#endif
+
+
+#ifdef QUARTZITE // DO NOT MODIFY!
+ bsA = 4290;
+ bsB = QUARTZITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined QUARTZITE with value 4290 from .dat file mismatches hardcoded c++ define value of " << QUARTZITE << "!" << std::endl;
+#endif
+
+
+#ifdef QUEEN // DO NOT MODIFY!
+ bsA = 4;
+ bsB = QUEEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined QUEEN with value 4 from .dat file mismatches hardcoded c++ define value of " << QUEEN << "!" << std::endl;
+#endif
+
+
+#ifdef QUICK_SAND // DO NOT MODIFY!
+ bsA = 16438;
+ bsB = QUICK_SAND;
+ if(bsA!=bsB)
+ ssErrors << "Defined QUICK_SAND with value 16438 from .dat file mismatches hardcoded c++ define value of " << QUICK_SAND << "!" << std::endl;
+#endif
+
+
+#ifdef QUICK_SILVER // DO NOT MODIFY!
+ bsA = 16436;
+ bsB = QUICK_SILVER;
+ if(bsA!=bsB)
+ ssErrors << "Defined QUICK_SILVER with value 16436 from .dat file mismatches hardcoded c++ define value of " << QUICK_SILVER << "!" << std::endl;
+#endif
+
+
+#ifdef QUILTED_LEATHER // DO NOT MODIFY!
+ bsA = 4154;
+ bsB = QUILTED_LEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined QUILTED_LEATHER with value 4154 from .dat file mismatches hardcoded c++ define value of " << QUILTED_LEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef RAINBOW_CLOTH // DO NOT MODIFY!
+ bsA = 4174;
+ bsB = RAINBOW_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined RAINBOW_CLOTH with value 4174 from .dat file mismatches hardcoded c++ define value of " << RAINBOW_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef RANDOM // DO NOT MODIFY!
+ bsA = 0;
+ bsB = RANDOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined RANDOM with value 0 from .dat file mismatches hardcoded c++ define value of " << RANDOM << "!" << std::endl;
+#endif
+
+
+#ifdef RANDOM_COLOR // DO NOT MODIFY!
+ bsA = 65536;
+ bsB = RANDOM_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined RANDOM_COLOR with value 65536 from .dat file mismatches hardcoded c++ define value of " << RANDOM_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef RATA_WOOD // DO NOT MODIFY!
+ bsA = 4245;
+ bsB = RATA_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined RATA_WOOD with value 4245 from .dat file mismatches hardcoded c++ define value of " << RATA_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef RAT_FLESH // DO NOT MODIFY!
+ bsA = 20505;
+ bsB = RAT_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined RAT_FLESH with value 20505 from .dat file mismatches hardcoded c++ define value of " << RAT_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef RECTANGLE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = RECTANGLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RECTANGLE with value 1 from .dat file mismatches hardcoded c++ define value of " << RECTANGLE << "!" << std::endl;
+#endif
+
+
+#ifdef RED // DO NOT MODIFY!
+ bsA = 63488;
+ bsB = RED;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED with value 63488 from .dat file mismatches hardcoded c++ define value of " << RED << "!" << std::endl;
+#endif
+
+
+#ifdef RED_FRACTAL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = RED_FRACTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_FRACTAL with value 1 from .dat file mismatches hardcoded c++ define value of " << RED_FRACTAL << "!" << std::endl;
+#endif
+
+
+#ifdef RED_ICE // DO NOT MODIFY!
+ bsA = 4210;
+ bsB = RED_ICE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_ICE with value 4210 from .dat file mismatches hardcoded c++ define value of " << RED_ICE << "!" << std::endl;
+#endif
+
+
+#ifdef RED_JADE // DO NOT MODIFY!
+ bsA = 4304;
+ bsB = RED_JADE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_JADE with value 4304 from .dat file mismatches hardcoded c++ define value of " << RED_JADE << "!" << std::endl;
+#endif
+
+
+#ifdef RED_SAND // DO NOT MODIFY!
+ bsA = 24581;
+ bsB = RED_SAND;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_SAND with value 24581 from .dat file mismatches hardcoded c++ define value of " << RED_SAND << "!" << std::endl;
+#endif
+
+
+#ifdef RED_SAND_STONE // DO NOT MODIFY!
+ bsA = 4205;
+ bsB = RED_SAND_STONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_SAND_STONE with value 4205 from .dat file mismatches hardcoded c++ define value of " << RED_SAND_STONE << "!" << std::endl;
+#endif
+
+
+#ifdef RED_SIREN // DO NOT MODIFY!
+ bsA = 7;
+ bsB = RED_SIREN;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_SIREN with value 7 from .dat file mismatches hardcoded c++ define value of " << RED_SIREN << "!" << std::endl;
+#endif
+
+
+#ifdef RED_WINE // DO NOT MODIFY!
+ bsA = 16403;
+ bsB = RED_WINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RED_WINE with value 16403 from .dat file mismatches hardcoded c++ define value of " << RED_WINE << "!" << std::endl;
+#endif
+
+
+#ifdef REGENERATION // DO NOT MODIFY!
+ bsA = 67108864;
+ bsB = REGENERATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined REGENERATION with value 67108864 from .dat file mismatches hardcoded c++ define value of " << REGENERATION << "!" << std::endl;
+#endif
+
+
+#ifdef REPRESENTATIVE // DO NOT MODIFY!
+ bsA = 6;
+ bsB = REPRESENTATIVE;
+ if(bsA!=bsB)
+ ssErrors << "Defined REPRESENTATIVE with value 6 from .dat file mismatches hardcoded c++ define value of " << REPRESENTATIVE << "!" << std::endl;
+#endif
+
+
+#ifdef RESIDUUM // DO NOT MODIFY!
+ bsA = 8220;
+ bsB = RESIDUUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined RESIDUUM with value 8220 from .dat file mismatches hardcoded c++ define value of " << RESIDUUM << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT // DO NOT MODIFY!
+ bsA = 3;
+ bsB = RIGHT;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT with value 3 from .dat file mismatches hardcoded c++ define value of " << RIGHT << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_ARM // DO NOT MODIFY!
+ bsA = 4;
+ bsB = RIGHT_ARM;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_ARM with value 4 from .dat file mismatches hardcoded c++ define value of " << RIGHT_ARM << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_ARM_INDEX // DO NOT MODIFY!
+ bsA = 2;
+ bsB = RIGHT_ARM_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_ARM_INDEX with value 2 from .dat file mismatches hardcoded c++ define value of " << RIGHT_ARM_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_BOOT_INDEX // DO NOT MODIFY!
+ bsA = 11;
+ bsB = RIGHT_BOOT_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_BOOT_INDEX with value 11 from .dat file mismatches hardcoded c++ define value of " << RIGHT_BOOT_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_GAUNTLET_INDEX // DO NOT MODIFY!
+ bsA = 9;
+ bsB = RIGHT_GAUNTLET_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_GAUNTLET_INDEX with value 9 from .dat file mismatches hardcoded c++ define value of " << RIGHT_GAUNTLET_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_LEG // DO NOT MODIFY!
+ bsA = 32;
+ bsB = RIGHT_LEG;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_LEG with value 32 from .dat file mismatches hardcoded c++ define value of " << RIGHT_LEG << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_LEG_INDEX // DO NOT MODIFY!
+ bsA = 5;
+ bsB = RIGHT_LEG_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_LEG_INDEX with value 5 from .dat file mismatches hardcoded c++ define value of " << RIGHT_LEG_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_RING_INDEX // DO NOT MODIFY!
+ bsA = 7;
+ bsB = RIGHT_RING_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_RING_INDEX with value 7 from .dat file mismatches hardcoded c++ define value of " << RIGHT_RING_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef RIGHT_WIELDED_INDEX // DO NOT MODIFY!
+ bsA = 5;
+ bsB = RIGHT_WIELDED_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined RIGHT_WIELDED_INDEX with value 5 from .dat file mismatches hardcoded c++ define value of " << RIGHT_WIELDED_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef RING // DO NOT MODIFY!
+ bsA = 64;
+ bsB = RING;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING with value 64 from .dat file mismatches hardcoded c++ define value of " << RING << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_ACID_RESISTANCE // DO NOT MODIFY!
+ bsA = 11;
+ bsB = RING_OF_ACID_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_ACID_RESISTANCE with value 11 from .dat file mismatches hardcoded c++ define value of " << RING_OF_ACID_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_BRAVERY // DO NOT MODIFY!
+ bsA = 17;
+ bsB = RING_OF_BRAVERY;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_BRAVERY with value 17 from .dat file mismatches hardcoded c++ define value of " << RING_OF_BRAVERY << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_DETECTION // DO NOT MODIFY!
+ bsA = 14;
+ bsB = RING_OF_DETECTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_DETECTION with value 14 from .dat file mismatches hardcoded c++ define value of " << RING_OF_DETECTION << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_ELECTRICITY_RESISTANCE // DO NOT MODIFY!
+ bsA = 9;
+ bsB = RING_OF_ELECTRICITY_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_ELECTRICITY_RESISTANCE with value 9 from .dat file mismatches hardcoded c++ define value of " << RING_OF_ELECTRICITY_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_FIRE_RESISTANCE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = RING_OF_FIRE_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_FIRE_RESISTANCE with value 1 from .dat file mismatches hardcoded c++ define value of " << RING_OF_FIRE_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_INFRA_VISION // DO NOT MODIFY!
+ bsA = 3;
+ bsB = RING_OF_INFRA_VISION;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_INFRA_VISION with value 3 from .dat file mismatches hardcoded c++ define value of " << RING_OF_INFRA_VISION << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_INVISIBILITY // DO NOT MODIFY!
+ bsA = 8;
+ bsB = RING_OF_INVISIBILITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_INVISIBILITY with value 8 from .dat file mismatches hardcoded c++ define value of " << RING_OF_INVISIBILITY << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_LIGHT // DO NOT MODIFY!
+ bsA = 12;
+ bsB = RING_OF_LIGHT;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_LIGHT with value 12 from .dat file mismatches hardcoded c++ define value of " << RING_OF_LIGHT << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_MAGIC_RESISTANCE // DO NOT MODIFY!
+ bsA = 13;
+ bsB = RING_OF_MAGIC_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_MAGIC_RESISTANCE with value 13 from .dat file mismatches hardcoded c++ define value of " << RING_OF_MAGIC_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_POISON_RESISTANCE // DO NOT MODIFY!
+ bsA = 7;
+ bsB = RING_OF_POISON_RESISTANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_POISON_RESISTANCE with value 7 from .dat file mismatches hardcoded c++ define value of " << RING_OF_POISON_RESISTANCE << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_POLYMORPH // DO NOT MODIFY!
+ bsA = 6;
+ bsB = RING_OF_POLYMORPH;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_POLYMORPH with value 6 from .dat file mismatches hardcoded c++ define value of " << RING_OF_POLYMORPH << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_POLYMORPH_CONTROL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = RING_OF_POLYMORPH_CONTROL;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_POLYMORPH_CONTROL with value 2 from .dat file mismatches hardcoded c++ define value of " << RING_OF_POLYMORPH_CONTROL << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_POLYMORPH_LOCK // DO NOT MODIFY!
+ bsA = 15;
+ bsB = RING_OF_POLYMORPH_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_POLYMORPH_LOCK with value 15 from .dat file mismatches hardcoded c++ define value of " << RING_OF_POLYMORPH_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_SEARCHING // DO NOT MODIFY!
+ bsA = 10;
+ bsB = RING_OF_SEARCHING;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_SEARCHING with value 10 from .dat file mismatches hardcoded c++ define value of " << RING_OF_SEARCHING << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_TELEPORTATION // DO NOT MODIFY!
+ bsA = 4;
+ bsB = RING_OF_TELEPORTATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_TELEPORTATION with value 4 from .dat file mismatches hardcoded c++ define value of " << RING_OF_TELEPORTATION << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_TELEPORT_CONTROL // DO NOT MODIFY!
+ bsA = 5;
+ bsB = RING_OF_TELEPORT_CONTROL;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_TELEPORT_CONTROL with value 5 from .dat file mismatches hardcoded c++ define value of " << RING_OF_TELEPORT_CONTROL << "!" << std::endl;
+#endif
+
+
+#ifdef RING_OF_WORM // DO NOT MODIFY!
+ bsA = 16;
+ bsB = RING_OF_WORM;
+ if(bsA!=bsB)
+ ssErrors << "Defined RING_OF_WORM with value 16 from .dat file mismatches hardcoded c++ define value of " << RING_OF_WORM << "!" << std::endl;
+#endif
+
+
+#ifdef RISES_FROM_ASHES // DO NOT MODIFY!
+ bsA = 64;
+ bsB = RISES_FROM_ASHES;
+ if(bsA!=bsB)
+ ssErrors << "Defined RISES_FROM_ASHES with value 64 from .dat file mismatches hardcoded c++ define value of " << RISES_FROM_ASHES << "!" << std::endl;
+#endif
+
+
+#ifdef ROCK_CRYSTAL // DO NOT MODIFY!
+ bsA = 4308;
+ bsB = ROCK_CRYSTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROCK_CRYSTAL with value 4308 from .dat file mismatches hardcoded c++ define value of " << ROCK_CRYSTAL << "!" << std::endl;
+#endif
+
+
+#ifdef ROCK_SALT // DO NOT MODIFY!
+ bsA = 4321;
+ bsB = ROCK_SALT;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROCK_SALT with value 4321 from .dat file mismatches hardcoded c++ define value of " << ROCK_SALT << "!" << std::endl;
+#endif
+
+
+#ifdef ROLLING_PIN // DO NOT MODIFY!
+ bsA = 19;
+ bsB = ROLLING_PIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROLLING_PIN with value 19 from .dat file mismatches hardcoded c++ define value of " << ROLLING_PIN << "!" << std::endl;
+#endif
+
+
+#ifdef ROOKIE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = ROOKIE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOKIE with value 1 from .dat file mismatches hardcoded c++ define value of " << ROOKIE << "!" << std::endl;
+#endif
+
+
+#ifdef ROOKIE_FEMALE // DO NOT MODIFY!
+ bsA = 14;
+ bsB = ROOKIE_FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOKIE_FEMALE with value 14 from .dat file mismatches hardcoded c++ define value of " << ROOKIE_FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef ROOM_BANANA_DROP_AREA // DO NOT MODIFY!
+ bsA = 5;
+ bsB = ROOM_BANANA_DROP_AREA;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOM_BANANA_DROP_AREA with value 5 from .dat file mismatches hardcoded c++ define value of " << ROOM_BANANA_DROP_AREA << "!" << std::endl;
+#endif
+
+
+#ifdef ROOM_CATHEDRAL // DO NOT MODIFY!
+ bsA = 3;
+ bsB = ROOM_CATHEDRAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOM_CATHEDRAL with value 3 from .dat file mismatches hardcoded c++ define value of " << ROOM_CATHEDRAL << "!" << std::endl;
+#endif
+
+
+#ifdef ROOM_LIBRARY // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ROOM_LIBRARY;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOM_LIBRARY with value 4 from .dat file mismatches hardcoded c++ define value of " << ROOM_LIBRARY << "!" << std::endl;
+#endif
+
+
+#ifdef ROOM_NORMAL // DO NOT MODIFY!
+ bsA = 1;
+ bsB = ROOM_NORMAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOM_NORMAL with value 1 from .dat file mismatches hardcoded c++ define value of " << ROOM_NORMAL << "!" << std::endl;
+#endif
+
+
+#ifdef ROOM_SHOP // DO NOT MODIFY!
+ bsA = 2;
+ bsB = ROOM_SHOP;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOM_SHOP with value 2 from .dat file mismatches hardcoded c++ define value of " << ROOM_SHOP << "!" << std::endl;
+#endif
+
+
+#ifdef ROOM_SUMO_ARENA // DO NOT MODIFY!
+ bsA = 6;
+ bsB = ROOM_SUMO_ARENA;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROOM_SUMO_ARENA with value 6 from .dat file mismatches hardcoded c++ define value of " << ROOM_SUMO_ARENA << "!" << std::endl;
+#endif
+
+
+#ifdef ROSE_QUARTZ // DO NOT MODIFY!
+ bsA = 4291;
+ bsB = ROSE_QUARTZ;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROSE_QUARTZ with value 4291 from .dat file mismatches hardcoded c++ define value of " << ROSE_QUARTZ << "!" << std::endl;
+#endif
+
+
+#ifdef ROTATE // DO NOT MODIFY!
+ bsA = 4;
+ bsB = ROTATE;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROTATE with value 4 from .dat file mismatches hardcoded c++ define value of " << ROTATE << "!" << std::endl;
+#endif
+
+
+#ifdef ROUND_CORNERS // DO NOT MODIFY!
+ bsA = 2;
+ bsB = ROUND_CORNERS;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROUND_CORNERS with value 2 from .dat file mismatches hardcoded c++ define value of " << ROUND_CORNERS << "!" << std::endl;
+#endif
+
+
+#ifdef ROUND_LOCK // DO NOT MODIFY!
+ bsA = 2048;
+ bsB = ROUND_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined ROUND_LOCK with value 2048 from .dat file mismatches hardcoded c++ define value of " << ROUND_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef RUBBER // DO NOT MODIFY!
+ bsA = 4185;
+ bsB = RUBBER;
+ if(bsA!=bsB)
+ ssErrors << "Defined RUBBER with value 4185 from .dat file mismatches hardcoded c++ define value of " << RUBBER << "!" << std::endl;
+#endif
+
+
+#ifdef RUBY // DO NOT MODIFY!
+ bsA = 4297;
+ bsB = RUBY;
+ if(bsA!=bsB)
+ ssErrors << "Defined RUBY with value 4297 from .dat file mismatches hardcoded c++ define value of " << RUBY << "!" << std::endl;
+#endif
+
+
+#ifdef RUNED_WHIP // DO NOT MODIFY!
+ bsA = 1;
+ bsB = RUNED_WHIP;
+ if(bsA!=bsB)
+ ssErrors << "Defined RUNED_WHIP with value 1 from .dat file mismatches hardcoded c++ define value of " << RUNED_WHIP << "!" << std::endl;
+#endif
+
+
+#ifdef RUNE_SWORD // DO NOT MODIFY!
+ bsA = 23;
+ bsB = RUNE_SWORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined RUNE_SWORD with value 23 from .dat file mismatches hardcoded c++ define value of " << RUNE_SWORD << "!" << std::endl;
+#endif
+
+
+#ifdef RUSTED // DO NOT MODIFY!
+ bsA = 2;
+ bsB = RUSTED;
+ if(bsA!=bsB)
+ ssErrors << "Defined RUSTED with value 2 from .dat file mismatches hardcoded c++ define value of " << RUSTED << "!" << std::endl;
+#endif
+
+
+#ifdef RYE_BREAD // DO NOT MODIFY!
+ bsA = 8206;
+ bsB = RYE_BREAD;
+ if(bsA!=bsB)
+ ssErrors << "Defined RYE_BREAD with value 8206 from .dat file mismatches hardcoded c++ define value of " << RYE_BREAD << "!" << std::endl;
+#endif
+
+
+#ifdef SALT // DO NOT MODIFY!
+ bsA = 24578;
+ bsB = SALT;
+ if(bsA!=bsB)
+ ssErrors << "Defined SALT with value 24578 from .dat file mismatches hardcoded c++ define value of " << SALT << "!" << std::endl;
+#endif
+
+
+#ifdef SAND // DO NOT MODIFY!
+ bsA = 24580;
+ bsB = SAND;
+ if(bsA!=bsB)
+ ssErrors << "Defined SAND with value 24580 from .dat file mismatches hardcoded c++ define value of " << SAND << "!" << std::endl;
+#endif
+
+
+#ifdef SAND_STONE // DO NOT MODIFY!
+ bsA = 4204;
+ bsB = SAND_STONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SAND_STONE with value 4204 from .dat file mismatches hardcoded c++ define value of " << SAND_STONE << "!" << std::endl;
+#endif
+
+
+#ifdef SAND_TERRAIN // DO NOT MODIFY!
+ bsA = 8;
+ bsB = SAND_TERRAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined SAND_TERRAIN with value 8 from .dat file mismatches hardcoded c++ define value of " << SAND_TERRAIN << "!" << std::endl;
+#endif
+
+
+#ifdef SAPPHIRE // DO NOT MODIFY!
+ bsA = 4295;
+ bsB = SAPPHIRE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SAPPHIRE with value 4295 from .dat file mismatches hardcoded c++ define value of " << SAPPHIRE << "!" << std::endl;
+#endif
+
+
+#ifdef SARDINE // DO NOT MODIFY!
+ bsA = 20487;
+ bsB = SARDINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SARDINE with value 20487 from .dat file mismatches hardcoded c++ define value of " << SARDINE << "!" << std::endl;
+#endif
+
+
+#ifdef SCABIES // DO NOT MODIFY!
+ bsA = 12;
+ bsB = SCABIES;
+ if(bsA!=bsB)
+ ssErrors << "Defined SCABIES with value 12 from .dat file mismatches hardcoded c++ define value of " << SCABIES << "!" << std::endl;
+#endif
+
+
+#ifdef SCHOOL_FOOD // DO NOT MODIFY!
+ bsA = 8210;
+ bsB = SCHOOL_FOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SCHOOL_FOOD with value 8210 from .dat file mismatches hardcoded c++ define value of " << SCHOOL_FOOD << "!" << std::endl;
+#endif
+
+
+#ifdef SCROLL // DO NOT MODIFY!
+ bsA = 4096;
+ bsB = SCROLL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SCROLL with value 4096 from .dat file mismatches hardcoded c++ define value of " << SCROLL << "!" << std::endl;
+#endif
+
+
+#ifdef SCYTHE // DO NOT MODIFY!
+ bsA = 14;
+ bsB = SCYTHE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SCYTHE with value 14 from .dat file mismatches hardcoded c++ define value of " << SCYTHE << "!" << std::endl;
+#endif
+
+
+#ifdef SEARCHING // DO NOT MODIFY!
+ bsA = 65536;
+ bsB = SEARCHING;
+ if(bsA!=bsB)
+ ssErrors << "Defined SEARCHING with value 65536 from .dat file mismatches hardcoded c++ define value of " << SEARCHING << "!" << std::endl;
+#endif
+
+
+#ifdef SEA_SERPENT_SCALE // DO NOT MODIFY!
+ bsA = 4170;
+ bsB = SEA_SERPENT_SCALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SEA_SERPENT_SCALE with value 4170 from .dat file mismatches hardcoded c++ define value of " << SEA_SERPENT_SCALE << "!" << std::endl;
+#endif
+
+
+#ifdef SEA_SHELL // DO NOT MODIFY!
+ bsA = 4254;
+ bsB = SEA_SHELL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SEA_SHELL with value 4254 from .dat file mismatches hardcoded c++ define value of " << SEA_SHELL << "!" << std::endl;
+#endif
+
+
+#ifdef SEA_WEED // DO NOT MODIFY!
+ bsA = 4166;
+ bsB = SEA_WEED;
+ if(bsA!=bsB)
+ ssErrors << "Defined SEA_WEED with value 4166 from .dat file mismatches hardcoded c++ define value of " << SEA_WEED << "!" << std::endl;
+#endif
+
+
+#ifdef SECRET_DOOR // DO NOT MODIFY!
+ bsA = 2;
+ bsB = SECRET_DOOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined SECRET_DOOR with value 2 from .dat file mismatches hardcoded c++ define value of " << SECRET_DOOR << "!" << std::endl;
+#endif
+
+
+#ifdef SEGES // DO NOT MODIFY!
+ bsA = 5;
+ bsB = SEGES;
+ if(bsA!=bsB)
+ ssErrors << "Defined SEGES with value 5 from .dat file mismatches hardcoded c++ define value of " << SEGES << "!" << std::endl;
+#endif
+
+
+#ifdef SELKIE_SKIN // DO NOT MODIFY!
+ bsA = 4169;
+ bsB = SELKIE_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined SELKIE_SKIN with value 4169 from .dat file mismatches hardcoded c++ define value of " << SELKIE_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef SHACKLES // DO NOT MODIFY!
+ bsA = 35;
+ bsB = SHACKLES;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHACKLES with value 35 from .dat file mismatches hardcoded c++ define value of " << SHACKLES << "!" << std::endl;
+#endif
+
+
+#ifdef SHADOW_CLOTH // DO NOT MODIFY!
+ bsA = 4175;
+ bsB = SHADOW_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHADOW_CLOTH with value 4175 from .dat file mismatches hardcoded c++ define value of " << SHADOW_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef SHALE // DO NOT MODIFY!
+ bsA = 4261;
+ bsB = SHALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHALE with value 4261 from .dat file mismatches hardcoded c++ define value of " << SHALE << "!" << std::endl;
+#endif
+
+
+#ifdef SHARD // DO NOT MODIFY!
+ bsA = 19;
+ bsB = SHARD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHARD with value 19 from .dat file mismatches hardcoded c++ define value of " << SHARD << "!" << std::endl;
+#endif
+
+
+#ifdef SHARK_TOOTH // DO NOT MODIFY!
+ bsA = 8216;
+ bsB = SHARK_TOOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHARK_TOOTH with value 8216 from .dat file mismatches hardcoded c++ define value of " << SHARK_TOOTH << "!" << std::endl;
+#endif
+
+
+#ifdef SHELF // DO NOT MODIFY!
+ bsA = 3;
+ bsB = SHELF;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHELF with value 3 from .dat file mismatches hardcoded c++ define value of " << SHELF << "!" << std::endl;
+#endif
+
+
+#ifdef SHIELD // DO NOT MODIFY!
+ bsA = 32;
+ bsB = SHIELD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHIELD with value 32 from .dat file mismatches hardcoded c++ define value of " << SHIELD << "!" << std::endl;
+#endif
+
+
+#ifdef SHIELDS // DO NOT MODIFY!
+ bsA = 10;
+ bsB = SHIELDS;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHIELDS with value 10 from .dat file mismatches hardcoded c++ define value of " << SHIELDS << "!" << std::endl;
+#endif
+
+
+#ifdef SHIELD_BEAM // DO NOT MODIFY!
+ bsA = 2;
+ bsB = SHIELD_BEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHIELD_BEAM with value 2 from .dat file mismatches hardcoded c++ define value of " << SHIELD_BEAM << "!" << std::endl;
+#endif
+
+
+#ifdef SHOP // DO NOT MODIFY!
+ bsA = 5;
+ bsB = SHOP;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHOP with value 5 from .dat file mismatches hardcoded c++ define value of " << SHOP << "!" << std::endl;
+#endif
+
+
+#ifdef SHORT_SWORD // DO NOT MODIFY!
+ bsA = 11;
+ bsB = SHORT_SWORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHORT_SWORD with value 11 from .dat file mismatches hardcoded c++ define value of " << SHORT_SWORD << "!" << std::endl;
+#endif
+
+
+#ifdef SHOW_MATERIAL // DO NOT MODIFY!
+ bsA = 16;
+ bsB = SHOW_MATERIAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SHOW_MATERIAL with value 16 from .dat file mismatches hardcoded c++ define value of " << SHOW_MATERIAL << "!" << std::endl;
+#endif
+
+
+#ifdef SICKLE // DO NOT MODIFY!
+ bsA = 9;
+ bsB = SICKLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SICKLE with value 9 from .dat file mismatches hardcoded c++ define value of " << SICKLE << "!" << std::endl;
+#endif
+
+
+#ifdef SICK_BLOOD // DO NOT MODIFY!
+ bsA = 16428;
+ bsB = SICK_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SICK_BLOOD with value 16428 from .dat file mismatches hardcoded c++ define value of " << SICK_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef SICK_SPIDER_FLESH // DO NOT MODIFY!
+ bsA = 20529;
+ bsB = SICK_SPIDER_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SICK_SPIDER_FLESH with value 20529 from .dat file mismatches hardcoded c++ define value of " << SICK_SPIDER_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef SIDGURE_WOOD // DO NOT MODIFY!
+ bsA = 4246;
+ bsB = SIDGURE_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SIDGURE_WOOD with value 4246 from .dat file mismatches hardcoded c++ define value of " << SIDGURE_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef SILVA // DO NOT MODIFY!
+ bsA = 7;
+ bsB = SILVA;
+ if(bsA!=bsB)
+ ssErrors << "Defined SILVA with value 7 from .dat file mismatches hardcoded c++ define value of " << SILVA << "!" << std::endl;
+#endif
+
+
+#ifdef SILVER // DO NOT MODIFY!
+ bsA = 4107;
+ bsB = SILVER;
+ if(bsA!=bsB)
+ ssErrors << "Defined SILVER with value 4107 from .dat file mismatches hardcoded c++ define value of " << SILVER << "!" << std::endl;
+#endif
+
+
+#ifdef SKELETON_DOG // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SKELETON_DOG;
+ if(bsA!=bsB)
+ ssErrors << "Defined SKELETON_DOG with value 1 from .dat file mismatches hardcoded c++ define value of " << SKELETON_DOG << "!" << std::endl;
+#endif
+
+
+#ifdef SKIN_COLOR // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SKIN_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined SKIN_COLOR with value 1 from .dat file mismatches hardcoded c++ define value of " << SKIN_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef SKUNK_FLESH // DO NOT MODIFY!
+ bsA = 20523;
+ bsB = SKUNK_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SKUNK_FLESH with value 20523 from .dat file mismatches hardcoded c++ define value of " << SKUNK_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef SKUNK_SMELL // DO NOT MODIFY!
+ bsA = 12293;
+ bsB = SKUNK_SMELL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SKUNK_SMELL with value 12293 from .dat file mismatches hardcoded c++ define value of " << SKUNK_SMELL << "!" << std::endl;
+#endif
+
+
+#ifdef SLADE // DO NOT MODIFY!
+ bsA = 4283;
+ bsB = SLADE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLADE with value 4283 from .dat file mismatches hardcoded c++ define value of " << SLADE << "!" << std::endl;
+#endif
+
+
+#ifdef SLASH // DO NOT MODIFY!
+ bsA = 2;
+ bsB = SLASH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLASH with value 2 from .dat file mismatches hardcoded c++ define value of " << SLASH << "!" << std::endl;
+#endif
+
+
+#ifdef SLATE // DO NOT MODIFY!
+ bsA = 4273;
+ bsB = SLATE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLATE with value 4273 from .dat file mismatches hardcoded c++ define value of " << SLATE << "!" << std::endl;
+#endif
+
+
+#ifdef SLAUGHTERER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SLAUGHTERER;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLAUGHTERER with value 1 from .dat file mismatches hardcoded c++ define value of " << SLAUGHTERER << "!" << std::endl;
+#endif
+
+
+#ifdef SLAYER // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SLAYER;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLAYER with value 1 from .dat file mismatches hardcoded c++ define value of " << SLAYER << "!" << std::endl;
+#endif
+
+
+#ifdef SLEEPING_GAS // DO NOT MODIFY!
+ bsA = 12300;
+ bsB = SLEEPING_GAS;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLEEPING_GAS with value 12300 from .dat file mismatches hardcoded c++ define value of " << SLEEPING_GAS << "!" << std::endl;
+#endif
+
+
+#ifdef SLIGHTLY_BURNT // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SLIGHTLY_BURNT;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLIGHTLY_BURNT with value 1 from .dat file mismatches hardcoded c++ define value of " << SLIGHTLY_BURNT << "!" << std::endl;
+#endif
+
+
+#ifdef SLIGHTLY_RUSTED // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SLIGHTLY_RUSTED;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLIGHTLY_RUSTED with value 1 from .dat file mismatches hardcoded c++ define value of " << SLIGHTLY_RUSTED << "!" << std::endl;
+#endif
+
+
+#ifdef SLOW // DO NOT MODIFY!
+ bsA = 4;
+ bsB = SLOW;
+ if(bsA!=bsB)
+ ssErrors << "Defined SLOW with value 4 from .dat file mismatches hardcoded c++ define value of " << SLOW << "!" << std::endl;
+#endif
+
+
+#ifdef SMALL_CHEST // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SMALL_CHEST;
+ if(bsA!=bsB)
+ ssErrors << "Defined SMALL_CHEST with value 1 from .dat file mismatches hardcoded c++ define value of " << SMALL_CHEST << "!" << std::endl;
+#endif
+
+
+#ifdef SMALL_CLOCK // DO NOT MODIFY!
+ bsA = 5;
+ bsB = SMALL_CLOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined SMALL_CLOCK with value 5 from .dat file mismatches hardcoded c++ define value of " << SMALL_CLOCK << "!" << std::endl;
+#endif
+
+
+#ifdef SMALL_SWORDS // DO NOT MODIFY!
+ bsA = 4;
+ bsB = SMALL_SWORDS;
+ if(bsA!=bsB)
+ ssErrors << "Defined SMALL_SWORDS with value 4 from .dat file mismatches hardcoded c++ define value of " << SMALL_SWORDS << "!" << std::endl;
+#endif
+
+
+#ifdef SMART_CLOTH // DO NOT MODIFY!
+ bsA = 4179;
+ bsB = SMART_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SMART_CLOTH with value 4179 from .dat file mismatches hardcoded c++ define value of " << SMART_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef SMOKE // DO NOT MODIFY!
+ bsA = 12292;
+ bsB = SMOKE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SMOKE with value 12292 from .dat file mismatches hardcoded c++ define value of " << SMOKE << "!" << std::endl;
+#endif
+
+
+#ifdef SNAKE_FLESH // DO NOT MODIFY!
+ bsA = 20515;
+ bsB = SNAKE_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNAKE_FLESH with value 20515 from .dat file mismatches hardcoded c++ define value of " << SNAKE_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef SNAKE_JERKY // DO NOT MODIFY!
+ bsA = 20485;
+ bsB = SNAKE_JERKY;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNAKE_JERKY with value 20485 from .dat file mismatches hardcoded c++ define value of " << SNAKE_JERKY << "!" << std::endl;
+#endif
+
+
+#ifdef SNAKE_SKIN // DO NOT MODIFY!
+ bsA = 4144;
+ bsB = SNAKE_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNAKE_SKIN with value 4144 from .dat file mismatches hardcoded c++ define value of " << SNAKE_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef SNOW // DO NOT MODIFY!
+ bsA = 24579;
+ bsB = SNOW;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNOW with value 24579 from .dat file mismatches hardcoded c++ define value of " << SNOW << "!" << std::endl;
+#endif
+
+
+#ifdef SNOW_BOULDER // DO NOT MODIFY!
+ bsA = 4;
+ bsB = SNOW_BOULDER;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNOW_BOULDER with value 4 from .dat file mismatches hardcoded c++ define value of " << SNOW_BOULDER << "!" << std::endl;
+#endif
+
+
+#ifdef SNOW_FIR // DO NOT MODIFY!
+ bsA = 17;
+ bsB = SNOW_FIR;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNOW_FIR with value 17 from .dat file mismatches hardcoded c++ define value of " << SNOW_FIR << "!" << std::endl;
+#endif
+
+
+#ifdef SNOW_PINE // DO NOT MODIFY!
+ bsA = 16;
+ bsB = SNOW_PINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNOW_PINE with value 16 from .dat file mismatches hardcoded c++ define value of " << SNOW_PINE << "!" << std::endl;
+#endif
+
+
+#ifdef SNOW_TERRAIN // DO NOT MODIFY!
+ bsA = 6;
+ bsB = SNOW_TERRAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined SNOW_TERRAIN with value 6 from .dat file mismatches hardcoded c++ define value of " << SNOW_TERRAIN << "!" << std::endl;
+#endif
+
+
+#ifdef SOIL // DO NOT MODIFY!
+ bsA = 24584;
+ bsB = SOIL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOIL with value 24584 from .dat file mismatches hardcoded c++ define value of " << SOIL << "!" << std::endl;
+#endif
+
+
+#ifdef SOLARIUM // DO NOT MODIFY!
+ bsA = 4199;
+ bsB = SOLARIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOLARIUM with value 4199 from .dat file mismatches hardcoded c++ define value of " << SOLARIUM << "!" << std::endl;
+#endif
+
+
+#ifdef SOLID_ID // DO NOT MODIFY!
+ bsA = 4096;
+ bsB = SOLID_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOLID_ID with value 4096 from .dat file mismatches hardcoded c++ define value of " << SOLID_ID << "!" << std::endl;
+#endif
+
+
+#ifdef SOL_STONE // DO NOT MODIFY!
+ bsA = 1;
+ bsB = SOL_STONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOL_STONE with value 1 from .dat file mismatches hardcoded c++ define value of " << SOL_STONE << "!" << std::endl;
+#endif
+
+
+#ifdef SOOT // DO NOT MODIFY!
+ bsA = 24586;
+ bsB = SOOT;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOOT with value 24586 from .dat file mismatches hardcoded c++ define value of " << SOOT << "!" << std::endl;
+#endif
+
+
+#ifdef SOPHOS // DO NOT MODIFY!
+ bsA = 6;
+ bsB = SOPHOS;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOPHOS with value 6 from .dat file mismatches hardcoded c++ define value of " << SOPHOS << "!" << std::endl;
+#endif
+
+
+#ifdef SOUL_STEEL // DO NOT MODIFY!
+ bsA = 28681;
+ bsB = SOUL_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOUL_STEEL with value 28681 from .dat file mismatches hardcoded c++ define value of " << SOUL_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef SOUND // DO NOT MODIFY!
+ bsA = 2;
+ bsB = SOUND;
+ if(bsA!=bsB)
+ ssErrors << "Defined SOUND with value 2 from .dat file mismatches hardcoded c++ define value of " << SOUND << "!" << std::endl;
+#endif
+
+
+#ifdef SPEAR // DO NOT MODIFY!
+ bsA = 4;
+ bsB = SPEAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPEAR with value 4 from .dat file mismatches hardcoded c++ define value of " << SPEAR << "!" << std::endl;
+#endif
+
+
+#ifdef SPIDER_BLOOD // DO NOT MODIFY!
+ bsA = 16426;
+ bsB = SPIDER_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPIDER_BLOOD with value 16426 from .dat file mismatches hardcoded c++ define value of " << SPIDER_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef SPIDER_FLESH // DO NOT MODIFY!
+ bsA = 20497;
+ bsB = SPIDER_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPIDER_FLESH with value 20497 from .dat file mismatches hardcoded c++ define value of " << SPIDER_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef SPIDER_LEVEL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = SPIDER_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPIDER_LEVEL with value 4 from .dat file mismatches hardcoded c++ define value of " << SPIDER_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef SPIDER_SILK // DO NOT MODIFY!
+ bsA = 4138;
+ bsB = SPIDER_SILK;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPIDER_SILK with value 4138 from .dat file mismatches hardcoded c++ define value of " << SPIDER_SILK << "!" << std::endl;
+#endif
+
+
+#ifdef SPIRIT_CLOTH // DO NOT MODIFY!
+ bsA = 4140;
+ bsB = SPIRIT_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPIRIT_CLOTH with value 4140 from .dat file mismatches hardcoded c++ define value of " << SPIRIT_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef SPRUCE_WOOD // DO NOT MODIFY!
+ bsA = 4227;
+ bsB = SPRUCE_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SPRUCE_WOOD with value 4227 from .dat file mismatches hardcoded c++ define value of " << SPRUCE_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef SQUAD_LEADER // DO NOT MODIFY!
+ bsA = 2;
+ bsB = SQUAD_LEADER;
+ if(bsA!=bsB)
+ ssErrors << "Defined SQUAD_LEADER with value 2 from .dat file mismatches hardcoded c++ define value of " << SQUAD_LEADER << "!" << std::endl;
+#endif
+
+
+#ifdef SQUARE_LOCK // DO NOT MODIFY!
+ bsA = 3072;
+ bsB = SQUARE_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined SQUARE_LOCK with value 3072 from .dat file mismatches hardcoded c++ define value of " << SQUARE_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef STAINLESS_STEEL // DO NOT MODIFY!
+ bsA = 4188;
+ bsB = STAINLESS_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined STAINLESS_STEEL with value 4188 from .dat file mismatches hardcoded c++ define value of " << STAINLESS_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef STAIRS_DOWN // DO NOT MODIFY!
+ bsA = 200;
+ bsB = STAIRS_DOWN;
+ if(bsA!=bsB)
+ ssErrors << "Defined STAIRS_DOWN with value 200 from .dat file mismatches hardcoded c++ define value of " << STAIRS_DOWN << "!" << std::endl;
+#endif
+
+
+#ifdef STAIRS_UP // DO NOT MODIFY!
+ bsA = 100;
+ bsB = STAIRS_UP;
+ if(bsA!=bsB)
+ ssErrors << "Defined STAIRS_UP with value 100 from .dat file mismatches hardcoded c++ define value of " << STAIRS_UP << "!" << std::endl;
+#endif
+
+
+#ifdef STAR_METAL // DO NOT MODIFY!
+ bsA = 4112;
+ bsB = STAR_METAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined STAR_METAL with value 4112 from .dat file mismatches hardcoded c++ define value of " << STAR_METAL << "!" << std::endl;
+#endif
+
+
+#ifdef STEEL // DO NOT MODIFY!
+ bsA = 28675;
+ bsB = STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined STEEL with value 28675 from .dat file mismatches hardcoded c++ define value of " << STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef STEEL_LEAF // DO NOT MODIFY!
+ bsA = 4220;
+ bsB = STEEL_LEAF;
+ if(bsA!=bsB)
+ ssErrors << "Defined STEEL_LEAF with value 4220 from .dat file mismatches hardcoded c++ define value of " << STEEL_LEAF << "!" << std::endl;
+#endif
+
+
+#ifdef STEPPE // DO NOT MODIFY!
+ bsA = 3;
+ bsB = STEPPE;
+ if(bsA!=bsB)
+ ssErrors << "Defined STEPPE with value 3 from .dat file mismatches hardcoded c++ define value of " << STEPPE << "!" << std::endl;
+#endif
+
+
+#ifdef STONE_WALL // DO NOT MODIFY!
+ bsA = 6;
+ bsB = STONE_WALL;
+ if(bsA!=bsB)
+ ssErrors << "Defined STONE_WALL with value 6 from .dat file mismatches hardcoded c++ define value of " << STONE_WALL << "!" << std::endl;
+#endif
+
+
+#ifdef STRANGE_TREE // DO NOT MODIFY!
+ bsA = 38;
+ bsB = STRANGE_TREE;
+ if(bsA!=bsB)
+ ssErrors << "Defined STRANGE_TREE with value 38 from .dat file mismatches hardcoded c++ define value of " << STRANGE_TREE << "!" << std::endl;
+#endif
+
+
+#ifdef STRONG_BOX // DO NOT MODIFY!
+ bsA = 4;
+ bsB = STRONG_BOX;
+ if(bsA!=bsB)
+ ssErrors << "Defined STRONG_BOX with value 4 from .dat file mismatches hardcoded c++ define value of " << STRONG_BOX << "!" << std::endl;
+#endif
+
+
+#ifdef STUDDED_LEATHER // DO NOT MODIFY!
+ bsA = 4155;
+ bsB = STUDDED_LEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined STUDDED_LEATHER with value 4155 from .dat file mismatches hardcoded c++ define value of " << STUDDED_LEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef STYMPHALIAN_FEATHER // DO NOT MODIFY!
+ bsA = 4164;
+ bsB = STYMPHALIAN_FEATHER;
+ if(bsA!=bsB)
+ ssErrors << "Defined STYMPHALIAN_FEATHER with value 4164 from .dat file mismatches hardcoded c++ define value of " << STYMPHALIAN_FEATHER << "!" << std::endl;
+#endif
+
+
+#ifdef SULFUR // DO NOT MODIFY!
+ bsA = 4316;
+ bsB = SULFUR;
+ if(bsA!=bsB)
+ ssErrors << "Defined SULFUR with value 4316 from .dat file mismatches hardcoded c++ define value of " << SULFUR << "!" << std::endl;
+#endif
+
+
+#ifdef SULPHURIC_ACID // DO NOT MODIFY!
+ bsA = 16411;
+ bsB = SULPHURIC_ACID;
+ if(bsA!=bsB)
+ ssErrors << "Defined SULPHURIC_ACID with value 16411 from .dat file mismatches hardcoded c++ define value of " << SULPHURIC_ACID << "!" << std::endl;
+#endif
+
+
+#ifdef SUMO_ARENA_ENTRY // DO NOT MODIFY!
+ bsA = 700;
+ bsB = SUMO_ARENA_ENTRY;
+ if(bsA!=bsB)
+ ssErrors << "Defined SUMO_ARENA_ENTRY with value 700 from .dat file mismatches hardcoded c++ define value of " << SUMO_ARENA_ENTRY << "!" << std::endl;
+#endif
+
+
+#ifdef SUMO_ARENA_EXIT // DO NOT MODIFY!
+ bsA = 800;
+ bsB = SUMO_ARENA_EXIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined SUMO_ARENA_EXIT with value 800 from .dat file mismatches hardcoded c++ define value of " << SUMO_ARENA_EXIT << "!" << std::endl;
+#endif
+
+
+#ifdef SUMO_TEAM // DO NOT MODIFY!
+ bsA = 3;
+ bsB = SUMO_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined SUMO_TEAM with value 3 from .dat file mismatches hardcoded c++ define value of " << SUMO_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef SUN_CRYSTAL // DO NOT MODIFY!
+ bsA = 4312;
+ bsB = SUN_CRYSTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined SUN_CRYSTAL with value 4312 from .dat file mismatches hardcoded c++ define value of " << SUN_CRYSTAL << "!" << std::endl;
+#endif
+
+
+#ifdef SUPER_CONCRETE // DO NOT MODIFY!
+ bsA = 4315;
+ bsB = SUPER_CONCRETE;
+ if(bsA!=bsB)
+ ssErrors << "Defined SUPER_CONCRETE with value 4315 from .dat file mismatches hardcoded c++ define value of " << SUPER_CONCRETE << "!" << std::endl;
+#endif
+
+
+#ifdef SWEAT // DO NOT MODIFY!
+ bsA = 16418;
+ bsB = SWEAT;
+ if(bsA!=bsB)
+ ssErrors << "Defined SWEAT with value 16418 from .dat file mismatches hardcoded c++ define value of " << SWEAT << "!" << std::endl;
+#endif
+
+
+#ifdef SWIM // DO NOT MODIFY!
+ bsA = 2;
+ bsB = SWIM;
+ if(bsA!=bsB)
+ ssErrors << "Defined SWIM with value 2 from .dat file mismatches hardcoded c++ define value of " << SWIM << "!" << std::endl;
+#endif
+
+
+#ifdef SWIMMING // DO NOT MODIFY!
+ bsA = 8388608;
+ bsB = SWIMMING;
+ if(bsA!=bsB)
+ ssErrors << "Defined SWIMMING with value 8388608 from .dat file mismatches hardcoded c++ define value of " << SWIMMING << "!" << std::endl;
+#endif
+
+
+#ifdef SYCAMORE_WOOD // DO NOT MODIFY!
+ bsA = 4228;
+ bsB = SYCAMORE_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined SYCAMORE_WOOD with value 4228 from .dat file mismatches hardcoded c++ define value of " << SYCAMORE_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef SYNTH_CLOTH // DO NOT MODIFY!
+ bsA = 4182;
+ bsB = SYNTH_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined SYNTH_CLOTH with value 4182 from .dat file mismatches hardcoded c++ define value of " << SYNTH_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef S_LOCK_ID // DO NOT MODIFY!
+ bsA = 16384;
+ bsB = S_LOCK_ID;
+ if(bsA!=bsB)
+ ssErrors << "Defined S_LOCK_ID with value 16384 from .dat file mismatches hardcoded c++ define value of " << S_LOCK_ID << "!" << std::endl;
+#endif
+
+
+#ifdef TABLE // DO NOT MODIFY!
+ bsA = 33;
+ bsB = TABLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined TABLE with value 33 from .dat file mismatches hardcoded c++ define value of " << TABLE << "!" << std::endl;
+#endif
+
+
+#ifdef TEAK // DO NOT MODIFY!
+ bsA = 23;
+ bsB = TEAK;
+ if(bsA!=bsB)
+ ssErrors << "Defined TEAK with value 23 from .dat file mismatches hardcoded c++ define value of " << TEAK << "!" << std::endl;
+#endif
+
+
+#ifdef TEAK_WOOD // DO NOT MODIFY!
+ bsA = 4242;
+ bsB = TEAK_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined TEAK_WOOD with value 4242 from .dat file mismatches hardcoded c++ define value of " << TEAK_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef TELEPORT // DO NOT MODIFY!
+ bsA = 1024;
+ bsB = TELEPORT;
+ if(bsA!=bsB)
+ ssErrors << "Defined TELEPORT with value 1024 from .dat file mismatches hardcoded c++ define value of " << TELEPORT << "!" << std::endl;
+#endif
+
+
+#ifdef TELEPORT_CONTROL // DO NOT MODIFY!
+ bsA = 4096;
+ bsB = TELEPORT_CONTROL;
+ if(bsA!=bsB)
+ ssErrors << "Defined TELEPORT_CONTROL with value 4096 from .dat file mismatches hardcoded c++ define value of " << TELEPORT_CONTROL << "!" << std::endl;
+#endif
+
+
+#ifdef TELEPORT_LOCK // DO NOT MODIFY!
+ bsA = 268435456;
+ bsB = TELEPORT_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined TELEPORT_LOCK with value 268435456 from .dat file mismatches hardcoded c++ define value of " << TELEPORT_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef TEMPLAR // DO NOT MODIFY!
+ bsA = 4;
+ bsB = TEMPLAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined TEMPLAR with value 4 from .dat file mismatches hardcoded c++ define value of " << TEMPLAR << "!" << std::endl;
+#endif
+
+
+#ifdef TERRA // DO NOT MODIFY!
+ bsA = 7;
+ bsB = TERRA;
+ if(bsA!=bsB)
+ ssErrors << "Defined TERRA with value 7 from .dat file mismatches hardcoded c++ define value of " << TERRA << "!" << std::endl;
+#endif
+
+
+#ifdef THROW // DO NOT MODIFY!
+ bsA = 32768;
+ bsB = THROW;
+ if(bsA!=bsB)
+ ssErrors << "Defined THROW with value 32768 from .dat file mismatches hardcoded c++ define value of " << THROW << "!" << std::endl;
+#endif
+
+
+#ifdef TIN // DO NOT MODIFY!
+ bsA = 4098;
+ bsB = TIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined TIN with value 4098 from .dat file mismatches hardcoded c++ define value of " << TIN << "!" << std::endl;
+#endif
+
+
+#ifdef TITANITE // DO NOT MODIFY!
+ bsA = 4127;
+ bsB = TITANITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined TITANITE with value 4127 from .dat file mismatches hardcoded c++ define value of " << TITANITE << "!" << std::endl;
+#endif
+
+
+#ifdef TOMB_ENTRY // DO NOT MODIFY!
+ bsA = 9;
+ bsB = TOMB_ENTRY;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOMB_ENTRY with value 9 from .dat file mismatches hardcoded c++ define value of " << TOMB_ENTRY << "!" << std::endl;
+#endif
+
+
+#ifdef TOMB_ENTRY_MASTER // DO NOT MODIFY!
+ bsA = 10;
+ bsB = TOMB_ENTRY_MASTER;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOMB_ENTRY_MASTER with value 10 from .dat file mismatches hardcoded c++ define value of " << TOMB_ENTRY_MASTER << "!" << std::endl;
+#endif
+
+
+#ifdef TOOL // DO NOT MODIFY!
+ bsA = 32768;
+ bsB = TOOL;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOOL with value 32768 from .dat file mismatches hardcoded c++ define value of " << TOOL << "!" << std::endl;
+#endif
+
+
+#ifdef TOPAZ // DO NOT MODIFY!
+ bsA = 4294;
+ bsB = TOPAZ;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOPAZ with value 4294 from .dat file mismatches hardcoded c++ define value of " << TOPAZ << "!" << std::endl;
+#endif
+
+
+#ifdef TORSO // DO NOT MODIFY!
+ bsA = 1;
+ bsB = TORSO;
+ if(bsA!=bsB)
+ ssErrors << "Defined TORSO with value 1 from .dat file mismatches hardcoded c++ define value of " << TORSO << "!" << std::endl;
+#endif
+
+
+#ifdef TORSO_INDEX // DO NOT MODIFY!
+ bsA = 0;
+ bsB = TORSO_INDEX;
+ if(bsA!=bsB)
+ ssErrors << "Defined TORSO_INDEX with value 0 from .dat file mismatches hardcoded c++ define value of " << TORSO_INDEX << "!" << std::endl;
+#endif
+
+
+#ifdef TORSO_MAIN_COLOR // DO NOT MODIFY!
+ bsA = 16;
+ bsB = TORSO_MAIN_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined TORSO_MAIN_COLOR with value 16 from .dat file mismatches hardcoded c++ define value of " << TORSO_MAIN_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef TORSO_SPECIAL_COLOR // DO NOT MODIFY!
+ bsA = 128;
+ bsB = TORSO_SPECIAL_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined TORSO_SPECIAL_COLOR with value 128 from .dat file mismatches hardcoded c++ define value of " << TORSO_SPECIAL_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef TORTURE_RACK // DO NOT MODIFY!
+ bsA = 30;
+ bsB = TORTURE_RACK;
+ if(bsA!=bsB)
+ ssErrors << "Defined TORTURE_RACK with value 30 from .dat file mismatches hardcoded c++ define value of " << TORTURE_RACK << "!" << std::endl;
+#endif
+
+
+#ifdef TORTURING_CHIEF // DO NOT MODIFY!
+ bsA = 1;
+ bsB = TORTURING_CHIEF;
+ if(bsA!=bsB)
+ ssErrors << "Defined TORTURING_CHIEF with value 1 from .dat file mismatches hardcoded c++ define value of " << TORTURING_CHIEF << "!" << std::endl;
+#endif
+
+
+#ifdef TOURIST_GUIDE_TEAM // DO NOT MODIFY!
+ bsA = 9;
+ bsB = TOURIST_GUIDE_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOURIST_GUIDE_TEAM with value 9 from .dat file mismatches hardcoded c++ define value of " << TOURIST_GUIDE_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef TOURIST_TEAM // DO NOT MODIFY!
+ bsA = 10;
+ bsB = TOURIST_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOURIST_TEAM with value 10 from .dat file mismatches hardcoded c++ define value of " << TOURIST_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef TOURMALINE // DO NOT MODIFY!
+ bsA = 4269;
+ bsB = TOURMALINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined TOURMALINE with value 4269 from .dat file mismatches hardcoded c++ define value of " << TOURMALINE << "!" << std::endl;
+#endif
+
+
+#ifdef TRAINEE // DO NOT MODIFY!
+ bsA = 13;
+ bsB = TRAINEE;
+ if(bsA!=bsB)
+ ssErrors << "Defined TRAINEE with value 13 from .dat file mismatches hardcoded c++ define value of " << TRAINEE << "!" << std::endl;
+#endif
+
+
+#ifdef TRANSPARENT_COLOR // DO NOT MODIFY!
+ bsA = 63519;
+ bsB = TRANSPARENT_COLOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined TRANSPARENT_COLOR with value 63519 from .dat file mismatches hardcoded c++ define value of " << TRANSPARENT_COLOR << "!" << std::endl;
+#endif
+
+
+#ifdef TRANSSEXUAL // DO NOT MODIFY!
+ bsA = 3;
+ bsB = TRANSSEXUAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined TRANSSEXUAL with value 3 from .dat file mismatches hardcoded c++ define value of " << TRANSSEXUAL << "!" << std::endl;
+#endif
+
+
+#ifdef TRIANGULAR_LOCK // DO NOT MODIFY!
+ bsA = 4096;
+ bsB = TRIANGULAR_LOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined TRIANGULAR_LOCK with value 4096 from .dat file mismatches hardcoded c++ define value of " << TRIANGULAR_LOCK << "!" << std::endl;
+#endif
+
+
+#ifdef TROLL_BLOOD // DO NOT MODIFY!
+ bsA = 16424;
+ bsB = TROLL_BLOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined TROLL_BLOOD with value 16424 from .dat file mismatches hardcoded c++ define value of " << TROLL_BLOOD << "!" << std::endl;
+#endif
+
+
+#ifdef TROLL_HIDE // DO NOT MODIFY!
+ bsA = 4156;
+ bsB = TROLL_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined TROLL_HIDE with value 4156 from .dat file mismatches hardcoded c++ define value of " << TROLL_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef TROLL_TUSK // DO NOT MODIFY!
+ bsA = 8217;
+ bsB = TROLL_TUSK;
+ if(bsA!=bsB)
+ ssErrors << "Defined TROLL_TUSK with value 8217 from .dat file mismatches hardcoded c++ define value of " << TROLL_TUSK << "!" << std::endl;
+#endif
+
+
+#ifdef TROLL_WOOL // DO NOT MODIFY!
+ bsA = 4136;
+ bsB = TROLL_WOOL;
+ if(bsA!=bsB)
+ ssErrors << "Defined TROLL_WOOL with value 4136 from .dat file mismatches hardcoded c++ define value of " << TROLL_WOOL << "!" << std::endl;
+#endif
+
+
+#ifdef TUNA // DO NOT MODIFY!
+ bsA = 20486;
+ bsB = TUNA;
+ if(bsA!=bsB)
+ ssErrors << "Defined TUNA with value 20486 from .dat file mismatches hardcoded c++ define value of " << TUNA << "!" << std::endl;
+#endif
+
+
+#ifdef TUNDRA // DO NOT MODIFY!
+ bsA = 6;
+ bsB = TUNDRA;
+ if(bsA!=bsB)
+ ssErrors << "Defined TUNDRA with value 6 from .dat file mismatches hardcoded c++ define value of " << TUNDRA << "!" << std::endl;
+#endif
+
+
+#ifdef TUNGSTEN // DO NOT MODIFY!
+ bsA = 4123;
+ bsB = TUNGSTEN;
+ if(bsA!=bsB)
+ ssErrors << "Defined TUNGSTEN with value 4123 from .dat file mismatches hardcoded c++ define value of " << TUNGSTEN << "!" << std::endl;
+#endif
+
+
+#ifdef TURTLE_SHELL // DO NOT MODIFY!
+ bsA = 4253;
+ bsB = TURTLE_SHELL;
+ if(bsA!=bsB)
+ ssErrors << "Defined TURTLE_SHELL with value 4253 from .dat file mismatches hardcoded c++ define value of " << TURTLE_SHELL << "!" << std::endl;
+#endif
+
+
+#ifdef TWO_HANDED_SCIMITAR // DO NOT MODIFY!
+ bsA = 3;
+ bsB = TWO_HANDED_SCIMITAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined TWO_HANDED_SCIMITAR with value 3 from .dat file mismatches hardcoded c++ define value of " << TWO_HANDED_SCIMITAR << "!" << std::endl;
+#endif
+
+
+#ifdef TWO_HANDED_SWORD // DO NOT MODIFY!
+ bsA = 2;
+ bsB = TWO_HANDED_SWORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined TWO_HANDED_SWORD with value 2 from .dat file mismatches hardcoded c++ define value of " << TWO_HANDED_SWORD << "!" << std::endl;
+#endif
+
+
+#ifdef UKKU_STEEL // DO NOT MODIFY!
+ bsA = 28678;
+ bsB = UKKU_STEEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined UKKU_STEEL with value 28678 from .dat file mismatches hardcoded c++ define value of " << UKKU_STEEL << "!" << std::endl;
+#endif
+
+
+#ifdef UNARMED // DO NOT MODIFY!
+ bsA = 0;
+ bsB = UNARMED;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNARMED with value 0 from .dat file mismatches hardcoded c++ define value of " << UNARMED << "!" << std::endl;
+#endif
+
+
+#ifdef UNARMED_ATTACK // DO NOT MODIFY!
+ bsA = 0;
+ bsB = UNARMED_ATTACK;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNARMED_ATTACK with value 0 from .dat file mismatches hardcoded c++ define value of " << UNARMED_ATTACK << "!" << std::endl;
+#endif
+
+
+#ifdef UNARTICLED // DO NOT MODIFY!
+ bsA = 0;
+ bsB = UNARTICLED;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNARTICLED with value 0 from .dat file mismatches hardcoded c++ define value of " << UNARTICLED << "!" << std::endl;
+#endif
+
+
+#ifdef UNCARING // DO NOT MODIFY!
+ bsA = 2;
+ bsB = UNCARING;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNCARING with value 2 from .dat file mismatches hardcoded c++ define value of " << UNCARING << "!" << std::endl;
+#endif
+
+
+#ifdef UNCATEGORIZED // DO NOT MODIFY!
+ bsA = 3;
+ bsB = UNCATEGORIZED;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNCATEGORIZED with value 3 from .dat file mismatches hardcoded c++ define value of " << UNCATEGORIZED << "!" << std::endl;
+#endif
+
+
+#ifdef UNDEFINED // DO NOT MODIFY!
+ bsA = 0;
+ bsB = UNDEFINED;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNDEFINED with value 0 from .dat file mismatches hardcoded c++ define value of " << UNDEFINED << "!" << std::endl;
+#endif
+
+
+#ifdef UNDERGROUND_LAKE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = UNDERGROUND_LAKE;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNDERGROUND_LAKE with value 2 from .dat file mismatches hardcoded c++ define value of " << UNDERGROUND_LAKE << "!" << std::endl;
+#endif
+
+
+#ifdef UNDER_WATER_TUNNEL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = UNDER_WATER_TUNNEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNDER_WATER_TUNNEL with value 4 from .dat file mismatches hardcoded c++ define value of " << UNDER_WATER_TUNNEL << "!" << std::endl;
+#endif
+
+
+#ifdef UNDER_WATER_TUNNEL_EXIT // DO NOT MODIFY!
+ bsA = 128;
+ bsB = UNDER_WATER_TUNNEL_EXIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNDER_WATER_TUNNEL_EXIT with value 128 from .dat file mismatches hardcoded c++ define value of " << UNDER_WATER_TUNNEL_EXIT << "!" << std::endl;
+#endif
+
+
+#ifdef UNICORN_HORN // DO NOT MODIFY!
+ bsA = 4252;
+ bsB = UNICORN_HORN;
+ if(bsA!=bsB)
+ ssErrors << "Defined UNICORN_HORN with value 4252 from .dat file mismatches hardcoded c++ define value of " << UNICORN_HORN << "!" << std::endl;
+#endif
+
+
+#ifdef UP // DO NOT MODIFY!
+ bsA = 2;
+ bsB = UP;
+ if(bsA!=bsB)
+ ssErrors << "Defined UP with value 2 from .dat file mismatches hardcoded c++ define value of " << UP << "!" << std::endl;
+#endif
+
+
+#ifdef URANIUM // DO NOT MODIFY!
+ bsA = 4198;
+ bsB = URANIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined URANIUM with value 4198 from .dat file mismatches hardcoded c++ define value of " << URANIUM << "!" << std::endl;
+#endif
+
+
+#ifdef USE_ADJECTIVE_AN // DO NOT MODIFY!
+ bsA = 2;
+ bsB = USE_ADJECTIVE_AN;
+ if(bsA!=bsB)
+ ssErrors << "Defined USE_ADJECTIVE_AN with value 2 from .dat file mismatches hardcoded c++ define value of " << USE_ADJECTIVE_AN << "!" << std::endl;
+#endif
+
+
+#ifdef USE_AN // DO NOT MODIFY!
+ bsA = 1;
+ bsB = USE_AN;
+ if(bsA!=bsB)
+ ssErrors << "Defined USE_AN with value 1 from .dat file mismatches hardcoded c++ define value of " << USE_AN << "!" << std::endl;
+#endif
+
+
+#ifdef USE_ARMS // DO NOT MODIFY!
+ bsA = 1;
+ bsB = USE_ARMS;
+ if(bsA!=bsB)
+ ssErrors << "Defined USE_ARMS with value 1 from .dat file mismatches hardcoded c++ define value of " << USE_ARMS << "!" << std::endl;
+#endif
+
+
+#ifdef USE_HEAD // DO NOT MODIFY!
+ bsA = 4;
+ bsB = USE_HEAD;
+ if(bsA!=bsB)
+ ssErrors << "Defined USE_HEAD with value 4 from .dat file mismatches hardcoded c++ define value of " << USE_HEAD << "!" << std::endl;
+#endif
+
+
+#ifdef USE_LEGS // DO NOT MODIFY!
+ bsA = 2;
+ bsB = USE_LEGS;
+ if(bsA!=bsB)
+ ssErrors << "Defined USE_LEGS with value 2 from .dat file mismatches hardcoded c++ define value of " << USE_LEGS << "!" << std::endl;
+#endif
+
+
+#ifdef USE_MATERIAL_ATTRIBUTES // DO NOT MODIFY!
+ bsA = 8;
+ bsB = USE_MATERIAL_ATTRIBUTES;
+ if(bsA!=bsB)
+ ssErrors << "Defined USE_MATERIAL_ATTRIBUTES with value 8 from .dat file mismatches hardcoded c++ define value of " << USE_MATERIAL_ATTRIBUTES << "!" << std::endl;
+#endif
+
+
+#ifdef VACUUM // DO NOT MODIFY!
+ bsA = 12290;
+ bsB = VACUUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined VACUUM with value 12290 from .dat file mismatches hardcoded c++ define value of " << VACUUM << "!" << std::endl;
+#endif
+
+
+#ifdef VALDEMAR // DO NOT MODIFY!
+ bsA = 16399;
+ bsB = VALDEMAR;
+ if(bsA!=bsB)
+ ssErrors << "Defined VALDEMAR with value 16399 from .dat file mismatches hardcoded c++ define value of " << VALDEMAR << "!" << std::endl;
+#endif
+
+
+#ifdef VALPURIUM // DO NOT MODIFY!
+ bsA = 4097;
+ bsB = VALPURIUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined VALPURIUM with value 4097 from .dat file mismatches hardcoded c++ define value of " << VALPURIUM << "!" << std::endl;
+#endif
+
+
+#ifdef VALPURUS // DO NOT MODIFY!
+ bsA = 1;
+ bsB = VALPURUS;
+ if(bsA!=bsB)
+ ssErrors << "Defined VALPURUS with value 1 from .dat file mismatches hardcoded c++ define value of " << VALPURUS << "!" << std::endl;
+#endif
+
+
+#ifdef VALUABLE // DO NOT MODIFY!
+ bsA = 65536;
+ bsB = VALUABLE;
+ if(bsA!=bsB)
+ ssErrors << "Defined VALUABLE with value 65536 from .dat file mismatches hardcoded c++ define value of " << VALUABLE << "!" << std::endl;
+#endif
+
+
+#ifdef VAMPIRE_FLESH // DO NOT MODIFY!
+ bsA = 20531;
+ bsB = VAMPIRE_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined VAMPIRE_FLESH with value 20531 from .dat file mismatches hardcoded c++ define value of " << VAMPIRE_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef VAMPIRISM // DO NOT MODIFY!
+ bsA = 4194304;
+ bsB = VAMPIRISM;
+ if(bsA!=bsB)
+ ssErrors << "Defined VAMPIRISM with value 4194304 from .dat file mismatches hardcoded c++ define value of " << VAMPIRISM << "!" << std::endl;
+#endif
+
+
+#ifdef VELLUM // DO NOT MODIFY!
+ bsA = 4224;
+ bsB = VELLUM;
+ if(bsA!=bsB)
+ ssErrors << "Defined VELLUM with value 4224 from .dat file mismatches hardcoded c++ define value of " << VELLUM << "!" << std::endl;
+#endif
+
+
+#ifdef VENISON // DO NOT MODIFY!
+ bsA = 20483;
+ bsB = VENISON;
+ if(bsA!=bsB)
+ ssErrors << "Defined VENISON with value 20483 from .dat file mismatches hardcoded c++ define value of " << VENISON << "!" << std::endl;
+#endif
+
+
+#ifdef VERDIGRIS // DO NOT MODIFY!
+ bsA = 4101;
+ bsB = VERDIGRIS;
+ if(bsA!=bsB)
+ ssErrors << "Defined VERDIGRIS with value 4101 from .dat file mismatches hardcoded c++ define value of " << VERDIGRIS << "!" << std::endl;
+#endif
+
+
+#ifdef VERY_RUSTED // DO NOT MODIFY!
+ bsA = 3;
+ bsB = VERY_RUSTED;
+ if(bsA!=bsB)
+ ssErrors << "Defined VERY_RUSTED with value 3 from .dat file mismatches hardcoded c++ define value of " << VERY_RUSTED << "!" << std::endl;
+#endif
+
+
+#ifdef VESANA_LEVEL // DO NOT MODIFY!
+ bsA = 2;
+ bsB = VESANA_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined VESANA_LEVEL with value 2 from .dat file mismatches hardcoded c++ define value of " << VESANA_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef VETERAN // DO NOT MODIFY!
+ bsA = 2;
+ bsB = VETERAN;
+ if(bsA!=bsB)
+ ssErrors << "Defined VETERAN with value 2 from .dat file mismatches hardcoded c++ define value of " << VETERAN << "!" << std::endl;
+#endif
+
+
+#ifdef VETERAN_FEMALE // DO NOT MODIFY!
+ bsA = 15;
+ bsB = VETERAN_FEMALE;
+ if(bsA!=bsB)
+ ssErrors << "Defined VETERAN_FEMALE with value 15 from .dat file mismatches hardcoded c++ define value of " << VETERAN_FEMALE << "!" << std::endl;
+#endif
+
+
+#ifdef VITRELLOY // DO NOT MODIFY!
+ bsA = 4191;
+ bsB = VITRELLOY;
+ if(bsA!=bsB)
+ ssErrors << "Defined VITRELLOY with value 4191 from .dat file mismatches hardcoded c++ define value of " << VITRELLOY << "!" << std::endl;
+#endif
+
+
+#ifdef VODKA // DO NOT MODIFY!
+ bsA = 16400;
+ bsB = VODKA;
+ if(bsA!=bsB)
+ ssErrors << "Defined VODKA with value 16400 from .dat file mismatches hardcoded c++ define value of " << VODKA << "!" << std::endl;
+#endif
+
+
+#ifdef VOMIT // DO NOT MODIFY!
+ bsA = 16416;
+ bsB = VOMIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined VOMIT with value 16416 from .dat file mismatches hardcoded c++ define value of " << VOMIT << "!" << std::endl;
+#endif
+
+
+#ifdef WALK // DO NOT MODIFY!
+ bsA = 1;
+ bsB = WALK;
+ if(bsA!=bsB)
+ ssErrors << "Defined WALK with value 1 from .dat file mismatches hardcoded c++ define value of " << WALK << "!" << std::endl;
+#endif
+
+
+#ifdef WAND // DO NOT MODIFY!
+ bsA = 16384;
+ bsB = WAND;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND with value 16384 from .dat file mismatches hardcoded c++ define value of " << WAND << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_ACID_RAIN // DO NOT MODIFY!
+ bsA = 12;
+ bsB = WAND_OF_ACID_RAIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_ACID_RAIN with value 12 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_ACID_RAIN << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_ALCHEMY // DO NOT MODIFY!
+ bsA = 16;
+ bsB = WAND_OF_ALCHEMY;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_ALCHEMY with value 16 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_ALCHEMY << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_CLONING // DO NOT MODIFY!
+ bsA = 10;
+ bsB = WAND_OF_CLONING;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_CLONING with value 10 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_CLONING << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_DOOR_CREATION // DO NOT MODIFY!
+ bsA = 8;
+ bsB = WAND_OF_DOOR_CREATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_DOOR_CREATION with value 8 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_DOOR_CREATION << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_FIRE_BALLS // DO NOT MODIFY!
+ bsA = 3;
+ bsB = WAND_OF_FIRE_BALLS;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_FIRE_BALLS with value 3 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_FIRE_BALLS << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_HASTE // DO NOT MODIFY!
+ bsA = 5;
+ bsB = WAND_OF_HASTE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_HASTE with value 5 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_HASTE << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_INVISIBILITY // DO NOT MODIFY!
+ bsA = 9;
+ bsB = WAND_OF_INVISIBILITY;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_INVISIBILITY with value 9 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_INVISIBILITY << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_LIGHTNING // DO NOT MODIFY!
+ bsA = 11;
+ bsB = WAND_OF_LIGHTNING;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_LIGHTNING with value 11 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_LIGHTNING << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_MIRRORING // DO NOT MODIFY!
+ bsA = 13;
+ bsB = WAND_OF_MIRRORING;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_MIRRORING with value 13 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_MIRRORING << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_NECROMANCY // DO NOT MODIFY!
+ bsA = 14;
+ bsB = WAND_OF_NECROMANCY;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_NECROMANCY with value 14 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_NECROMANCY << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_POLYMORPH // DO NOT MODIFY!
+ bsA = 1;
+ bsB = WAND_OF_POLYMORPH;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_POLYMORPH with value 1 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_POLYMORPH << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_RESURRECTION // DO NOT MODIFY!
+ bsA = 7;
+ bsB = WAND_OF_RESURRECTION;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_RESURRECTION with value 7 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_RESURRECTION << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_SLOW // DO NOT MODIFY!
+ bsA = 6;
+ bsB = WAND_OF_SLOW;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_SLOW with value 6 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_SLOW << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_STRIKING // DO NOT MODIFY!
+ bsA = 2;
+ bsB = WAND_OF_STRIKING;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_STRIKING with value 2 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_STRIKING << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_TELEPORTATION // DO NOT MODIFY!
+ bsA = 4;
+ bsB = WAND_OF_TELEPORTATION;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_TELEPORTATION with value 4 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_TELEPORTATION << "!" << std::endl;
+#endif
+
+
+#ifdef WAND_OF_WEBBING // DO NOT MODIFY!
+ bsA = 15;
+ bsB = WAND_OF_WEBBING;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAND_OF_WEBBING with value 15 from .dat file mismatches hardcoded c++ define value of " << WAND_OF_WEBBING << "!" << std::endl;
+#endif
+
+
+#ifdef WARLOCK // DO NOT MODIFY!
+ bsA = 6;
+ bsB = WARLOCK;
+ if(bsA!=bsB)
+ ssErrors << "Defined WARLOCK with value 6 from .dat file mismatches hardcoded c++ define value of " << WARLOCK << "!" << std::endl;
+#endif
+
+
+#ifdef WARRIOR // DO NOT MODIFY!
+ bsA = 1;
+ bsB = WARRIOR;
+ if(bsA!=bsB)
+ ssErrors << "Defined WARRIOR with value 1 from .dat file mismatches hardcoded c++ define value of " << WARRIOR << "!" << std::endl;
+#endif
+
+
+#ifdef WAR_HAMMER // DO NOT MODIFY!
+ bsA = 8;
+ bsB = WAR_HAMMER;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAR_HAMMER with value 8 from .dat file mismatches hardcoded c++ define value of " << WAR_HAMMER << "!" << std::endl;
+#endif
+
+
+#ifdef WAR_LADY // DO NOT MODIFY!
+ bsA = 3;
+ bsB = WAR_LADY;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAR_LADY with value 3 from .dat file mismatches hardcoded c++ define value of " << WAR_LADY << "!" << std::endl;
+#endif
+
+
+#ifdef WAR_LORD // DO NOT MODIFY!
+ bsA = 2;
+ bsB = WAR_LORD;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAR_LORD with value 2 from .dat file mismatches hardcoded c++ define value of " << WAR_LORD << "!" << std::endl;
+#endif
+
+
+#ifdef WATER // DO NOT MODIFY!
+ bsA = 16398;
+ bsB = WATER;
+ if(bsA!=bsB)
+ ssErrors << "Defined WATER with value 16398 from .dat file mismatches hardcoded c++ define value of " << WATER << "!" << std::endl;
+#endif
+
+
+#ifdef WAX // DO NOT MODIFY!
+ bsA = 4256;
+ bsB = WAX;
+ if(bsA!=bsB)
+ ssErrors << "Defined WAX with value 4256 from .dat file mismatches hardcoded c++ define value of " << WAX << "!" << std::endl;
+#endif
+
+
+#ifdef WEAPON // DO NOT MODIFY!
+ bsA = 16;
+ bsB = WEAPON;
+ if(bsA!=bsB)
+ ssErrors << "Defined WEAPON with value 16 from .dat file mismatches hardcoded c++ define value of " << WEAPON << "!" << std::endl;
+#endif
+
+
+#ifdef WEAPON_ATTACK // DO NOT MODIFY!
+ bsA = 1;
+ bsB = WEAPON_ATTACK;
+ if(bsA!=bsB)
+ ssErrors << "Defined WEAPON_ATTACK with value 1 from .dat file mismatches hardcoded c++ define value of " << WEAPON_ATTACK << "!" << std::endl;
+#endif
+
+
+#ifdef WEAPON_SKILL_CATEGORIES // DO NOT MODIFY!
+ bsA = 11;
+ bsB = WEAPON_SKILL_CATEGORIES;
+ if(bsA!=bsB)
+ ssErrors << "Defined WEAPON_SKILL_CATEGORIES with value 11 from .dat file mismatches hardcoded c++ define value of " << WEAPON_SKILL_CATEGORIES << "!" << std::endl;
+#endif
+
+
+#ifdef WELL // DO NOT MODIFY!
+ bsA = 34;
+ bsB = WELL;
+ if(bsA!=bsB)
+ ssErrors << "Defined WELL with value 34 from .dat file mismatches hardcoded c++ define value of " << WELL << "!" << std::endl;
+#endif
+
+
+#ifdef WERE_WOLF_FLESH // DO NOT MODIFY!
+ bsA = 20501;
+ bsB = WERE_WOLF_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined WERE_WOLF_FLESH with value 20501 from .dat file mismatches hardcoded c++ define value of " << WERE_WOLF_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef WHALE_BONE // DO NOT MODIFY!
+ bsA = 8213;
+ bsB = WHALE_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHALE_BONE with value 8213 from .dat file mismatches hardcoded c++ define value of " << WHALE_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef WHIPS // DO NOT MODIFY!
+ bsA = 9;
+ bsB = WHIPS;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHIPS with value 9 from .dat file mismatches hardcoded c++ define value of " << WHIPS << "!" << std::endl;
+#endif
+
+
+#ifdef WHIP_CHAMPION // DO NOT MODIFY!
+ bsA = 2;
+ bsB = WHIP_CHAMPION;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHIP_CHAMPION with value 2 from .dat file mismatches hardcoded c++ define value of " << WHIP_CHAMPION << "!" << std::endl;
+#endif
+
+
+#ifdef WHITE // DO NOT MODIFY!
+ bsA = 65535;
+ bsB = WHITE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHITE with value 65535 from .dat file mismatches hardcoded c++ define value of " << WHITE << "!" << std::endl;
+#endif
+
+
+#ifdef WHITE_JADE // DO NOT MODIFY!
+ bsA = 4307;
+ bsB = WHITE_JADE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHITE_JADE with value 4307 from .dat file mismatches hardcoded c++ define value of " << WHITE_JADE << "!" << std::endl;
+#endif
+
+
+#ifdef WHITE_UNICORN_FLESH // DO NOT MODIFY!
+ bsA = 20512;
+ bsB = WHITE_UNICORN_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHITE_UNICORN_FLESH with value 20512 from .dat file mismatches hardcoded c++ define value of " << WHITE_UNICORN_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef WHITE_WINE // DO NOT MODIFY!
+ bsA = 16402;
+ bsB = WHITE_WINE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WHITE_WINE with value 16402 from .dat file mismatches hardcoded c++ define value of " << WHITE_WINE << "!" << std::endl;
+#endif
+
+
+#ifdef WIFE // DO NOT MODIFY!
+ bsA = 2;
+ bsB = WIFE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WIFE with value 2 from .dat file mismatches hardcoded c++ define value of " << WIFE << "!" << std::endl;
+#endif
+
+
+#ifdef WILL_POWER // DO NOT MODIFY!
+ bsA = 4;
+ bsB = WILL_POWER;
+ if(bsA!=bsB)
+ ssErrors << "Defined WILL_POWER with value 4 from .dat file mismatches hardcoded c++ define value of " << WILL_POWER << "!" << std::endl;
+#endif
+
+
+#ifdef WINDOW // DO NOT MODIFY!
+ bsA = 1024;
+ bsB = WINDOW;
+ if(bsA!=bsB)
+ ssErrors << "Defined WINDOW with value 1024 from .dat file mismatches hardcoded c++ define value of " << WINDOW << "!" << std::endl;
+#endif
+
+
+#ifdef WISDOM // DO NOT MODIFY!
+ bsA = 3;
+ bsB = WISDOM;
+ if(bsA!=bsB)
+ ssErrors << "Defined WISDOM with value 3 from .dat file mismatches hardcoded c++ define value of " << WISDOM << "!" << std::endl;
+#endif
+
+
+#ifdef WITCH_BARK // DO NOT MODIFY!
+ bsA = 4218;
+ bsB = WITCH_BARK;
+ if(bsA!=bsB)
+ ssErrors << "Defined WITCH_BARK with value 4218 from .dat file mismatches hardcoded c++ define value of " << WITCH_BARK << "!" << std::endl;
+#endif
+
+
+#ifdef WOLF_FLESH // DO NOT MODIFY!
+ bsA = 20494;
+ bsB = WOLF_FLESH;
+ if(bsA!=bsB)
+ ssErrors << "Defined WOLF_FLESH with value 20494 from .dat file mismatches hardcoded c++ define value of " << WOLF_FLESH << "!" << std::endl;
+#endif
+
+
+#ifdef WOLF_SKIN // DO NOT MODIFY!
+ bsA = 4142;
+ bsB = WOLF_SKIN;
+ if(bsA!=bsB)
+ ssErrors << "Defined WOLF_SKIN with value 4142 from .dat file mismatches hardcoded c++ define value of " << WOLF_SKIN << "!" << std::endl;
+#endif
+
+
+#ifdef WOODEN_HORSE // DO NOT MODIFY!
+ bsA = 29;
+ bsB = WOODEN_HORSE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WOODEN_HORSE with value 29 from .dat file mismatches hardcoded c++ define value of " << WOODEN_HORSE << "!" << std::endl;
+#endif
+
+
+#ifdef WOOL_CLOTH // DO NOT MODIFY!
+ bsA = 4130;
+ bsB = WOOL_CLOTH;
+ if(bsA!=bsB)
+ ssErrors << "Defined WOOL_CLOTH with value 4130 from .dat file mismatches hardcoded c++ define value of " << WOOL_CLOTH << "!" << std::endl;
+#endif
+
+
+#ifdef WORK_BENCH // DO NOT MODIFY!
+ bsA = 32;
+ bsB = WORK_BENCH;
+ if(bsA!=bsB)
+ ssErrors << "Defined WORK_BENCH with value 32 from .dat file mismatches hardcoded c++ define value of " << WORK_BENCH << "!" << std::endl;
+#endif
+
+
+#ifdef WORLD_MAP // DO NOT MODIFY!
+ bsA = 255;
+ bsB = WORLD_MAP;
+ if(bsA!=bsB)
+ ssErrors << "Defined WORLD_MAP with value 255 from .dat file mismatches hardcoded c++ define value of " << WORLD_MAP << "!" << std::endl;
+#endif
+
+
+#ifdef WRAITH_BONE // DO NOT MODIFY!
+ bsA = 8214;
+ bsB = WRAITH_BONE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WRAITH_BONE with value 8214 from .dat file mismatches hardcoded c++ define value of " << WRAITH_BONE << "!" << std::endl;
+#endif
+
+
+#ifdef WYVERN_HIDE // DO NOT MODIFY!
+ bsA = 4148;
+ bsB = WYVERN_HIDE;
+ if(bsA!=bsB)
+ ssErrors << "Defined WYVERN_HIDE with value 4148 from .dat file mismatches hardcoded c++ define value of " << WYVERN_HIDE << "!" << std::endl;
+#endif
+
+
+#ifdef XINROCH_TOMB // DO NOT MODIFY!
+ bsA = 6;
+ bsB = XINROCH_TOMB;
+ if(bsA!=bsB)
+ ssErrors << "Defined XINROCH_TOMB with value 6 from .dat file mismatches hardcoded c++ define value of " << XINROCH_TOMB << "!" << std::endl;
+#endif
+
+
+#ifdef XINROCH_TOMB_ENTRANCE // DO NOT MODIFY!
+ bsA = 900;
+ bsB = XINROCH_TOMB_ENTRANCE;
+ if(bsA!=bsB)
+ ssErrors << "Defined XINROCH_TOMB_ENTRANCE with value 900 from .dat file mismatches hardcoded c++ define value of " << XINROCH_TOMB_ENTRANCE << "!" << std::endl;
+#endif
+
+
+#ifdef XINROCH_TOMB_ENTRY_TEAM // DO NOT MODIFY!
+ bsA = 12;
+ bsB = XINROCH_TOMB_ENTRY_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined XINROCH_TOMB_ENTRY_TEAM with value 12 from .dat file mismatches hardcoded c++ define value of " << XINROCH_TOMB_ENTRY_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef XINROCH_TOMB_EXIT // DO NOT MODIFY!
+ bsA = 1000;
+ bsB = XINROCH_TOMB_EXIT;
+ if(bsA!=bsB)
+ ssErrors << "Defined XINROCH_TOMB_EXIT with value 1000 from .dat file mismatches hardcoded c++ define value of " << XINROCH_TOMB_EXIT << "!" << std::endl;
+#endif
+
+
+#ifdef XINROCH_TOMB_KAMIKAZE_DWARF_TEAM // DO NOT MODIFY!
+ bsA = 14;
+ bsB = XINROCH_TOMB_KAMIKAZE_DWARF_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined XINROCH_TOMB_KAMIKAZE_DWARF_TEAM with value 14 from .dat file mismatches hardcoded c++ define value of " << XINROCH_TOMB_KAMIKAZE_DWARF_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef XINROCH_TOMB_NECRO_TEAM // DO NOT MODIFY!
+ bsA = 13;
+ bsB = XINROCH_TOMB_NECRO_TEAM;
+ if(bsA!=bsB)
+ ssErrors << "Defined XINROCH_TOMB_NECRO_TEAM with value 13 from .dat file mismatches hardcoded c++ define value of " << XINROCH_TOMB_NECRO_TEAM << "!" << std::endl;
+#endif
+
+
+#ifdef YELLOW // DO NOT MODIFY!
+ bsA = 65504;
+ bsB = YELLOW;
+ if(bsA!=bsB)
+ ssErrors << "Defined YELLOW with value 65504 from .dat file mismatches hardcoded c++ define value of " << YELLOW << "!" << std::endl;
+#endif
+
+
+#ifdef YELLOW_FRACTAL // DO NOT MODIFY!
+ bsA = 4;
+ bsB = YELLOW_FRACTAL;
+ if(bsA!=bsB)
+ ssErrors << "Defined YELLOW_FRACTAL with value 4 from .dat file mismatches hardcoded c++ define value of " << YELLOW_FRACTAL << "!" << std::endl;
+#endif
+
+
+#ifdef YEW_WOOD // DO NOT MODIFY!
+ bsA = 4233;
+ bsB = YEW_WOOD;
+ if(bsA!=bsB)
+ ssErrors << "Defined YEW_WOOD with value 4233 from .dat file mismatches hardcoded c++ define value of " << YEW_WOOD << "!" << std::endl;
+#endif
+
+
+#ifdef ZOMBIE_LEVEL // DO NOT MODIFY!
+ bsA = 5;
+ bsB = ZOMBIE_LEVEL;
+ if(bsA!=bsB)
+ ssErrors << "Defined ZOMBIE_LEVEL with value 5 from .dat file mismatches hardcoded c++ define value of " << ZOMBIE_LEVEL << "!" << std::endl;
+#endif
+
+
+#ifdef ZOMBIE_OF_KHAZ_ZADM // DO NOT MODIFY!
+ bsA = 1;
+ bsB = ZOMBIE_OF_KHAZ_ZADM;
+ if(bsA!=bsB)
+ ssErrors << "Defined ZOMBIE_OF_KHAZ_ZADM with value 1 from .dat file mismatches hardcoded c++ define value of " << ZOMBIE_OF_KHAZ_ZADM << "!" << std::endl;
+#endif
+
+
+ if(ssErrors.str().length() > 0) ABORT(ssErrors.str().c_str());
+
+}};
+
+#endif // _DEFINESVALIDATOR_H_
diff --git a/Main/Include/dungeon.h b/Main/Include/dungeon.h
index 29475035a..1dfe28971 100644
--- a/Main/Include/dungeon.h
+++ b/Main/Include/dungeon.h
@@ -40,7 +40,7 @@ class dungeon
const levelscript* GetLevelScript(int);
v2 GetWorldMapPos() { return WorldMapPos; }
void SetWorldMapPos(v2 What) { WorldMapPos = What; }
- festring GetLevelDescription(int);
+ festring GetLevelDescription(int,bool bPretty = false);
festring GetShortLevelDescription(int);
level* LoadLevel(inputfile&, int);
truth IsGenerated(int I) const { return Generated[I]; }
diff --git a/Main/Include/fluid.h b/Main/Include/fluid.h
index 22a585ceb..26059fe29 100644
--- a/Main/Include/fluid.h
+++ b/Main/Include/fluid.h
@@ -95,7 +95,7 @@ class fluid : public entity
/* AlphaSum / (non-transparent pixels in Picture), used to synchronise
gear pictures with the main image */
packalpha AlphaAverage;
- /* The position of a gear picture in humanoid.pcx which binds the fluid;
+ /* The position of a gear picture in Humanoid.png which binds the fluid;
remembered so that it can be easily determined whether the fluid needs
to be redistributed due to a major graphics change */
v2 ShadowPos;
diff --git a/Main/Include/game.h b/Main/Include/game.h
index 34419d8ef..753236bfb 100644
--- a/Main/Include/game.h
+++ b/Main/Include/game.h
@@ -166,12 +166,24 @@ typedef std::vector charactervector;
class quitrequest { };
class areachangerequest { };
+typedef void (*dbgdrawoverlay)();
+
class game
{
public:
static truth Init(cfestring& = CONST_S(""));
static void DeInit();
static void Run();
+ static void PrepareStretchRegionsLazy();
+ static void UpdateSRegionsXBRZ();
+ static void RegionSilhouetteEnable(bool b);
+ static void RegionListItemEnable(bool b);
+ static void UpdatePosAroundForXBRZ(v2 ScreenPos);
+ static void SRegionAroundDisable();
+ static void SRegionAroundAllow();
+ static void SRegionAroundDeny();
+ static void PrepareToClearNonVisibleSquaresAround(v2);
+ static void UpdatePlayerOnScreenSBSBlitdata();
static int GetMoveCommandKey(int);
static cv2 GetMoveVector(int I) { return MoveVector[I]; }
static cv2 GetClockwiseMoveVector(int I) { return ClockwiseMoveVector[I]; }
@@ -196,10 +208,18 @@ class game
static cchar* Insult();
static truth TruthQuestion(cfestring&, int = 0, int = 0);
static void DrawEverything();
+ static void UpdateShowItemsAtPos(bool bAllowed,v2 v2AtPos=v2(0,0));
+ static void UpdateAltSilhouette(bool bAllowed);
+ static v2 CalculateStretchedBufferCoordinatesFromDungeonSquarePos(v2 v2SqrPos);
+ static int ItemUnderCode(int iCycleValue);
+ static int ItemUnderCorner(int val);
+ static int ItemUnderZoom(int val);
+ static bool ItemUnderHV(int val);
static truth Save(cfestring& = SaveName(""));
static int Load(cfestring& = SaveName(""));
+ static int GetCurrentSavefileVersion();
static truth IsRunning() { return Running; }
- static void SetIsRunning(truth What) { Running = What; }
+ static void SetIsRunning(truth What);
static void UpdateCameraX(int);
static void UpdateCameraY(int);
static int GetCurrentLevelIndex() { return CurrentLevelIndex; }
@@ -217,9 +237,9 @@ class game
static void CalculateGodNumber();
static void IncreaseTick() { ++Tick; }
static ulong GetTick() { return Tick; }
- static festring GetAutoSaveFileName() { return AutoSaveFileName; }
+ static festring GetAutoSaveFileName() { return SaveName() + ".AutoSave"; }
static int DirectionQuestion(cfestring&, truth = true, truth = false);
- static void RemoveSaves(truth = true);
+ static void RemoveSaves(truth = true,truth onlyBackups=false);
static truth IsInWilderness() { return InWilderness; }
static void SetIsInWilderness(truth What) { InWilderness = What; }
static worldmap* GetWorldMap() { return WorldMap; }
@@ -254,10 +274,13 @@ class game
static void SetPetrus(character* What) { Petrus = What; }
static truth HandleQuitMessage();
static int GetDirectionForVector(v2);
+ static int GetPlayerAlignment();
static cchar* GetVerbalPlayerAlignment();
static void CreateGods();
- static int GetScreenXSize() { return 42; }
- static int GetScreenYSize() { return 26; }
+ static int GetScreenXSize();
+ static int GetScreenYSize();
+ static int GetMaxScreenXSize();
+ static int GetMaxScreenYSize();
static v2 CalculateScreenCoordinates(v2);
static void BusyAnimation();
static void BusyAnimation(bitmap*, truth);
@@ -269,6 +292,7 @@ class game
static void InitScript();
static valuemap& GetGlobalValueMap() { return GlobalValueMap; }
static void InitGlobalValueMap();
+ static void GenerateDefinesValidator(bool bValidade);
static void TextScreen(cfestring&, v2 = ZERO_V2, col16 = 0xFFFF, truth = true, truth = true, bitmapeditor = 0);
static void SetCursorPos(v2 What) { CursorPos = What; }
static truth DoZoom() { return Zoom; }
@@ -322,6 +346,7 @@ class game
static festring GetSaveDir();
static festring GetScrshotDir();
static festring GetDataDir();
+ static festring GetStateDir();
static festring GetBoneDir();
static festring GetMusicDir();
static truth PlayerWasHurtByExplosion() { return PlayerHurtByExplosion; }
@@ -340,9 +365,17 @@ class game
static truth MassacreListsEmpty();
static void PlayVictoryMusic();
static void PlayDefeatMusic();
+ static bool ToggleDrawMapOverlay();
+ static void SetDrawMapOverlay(bool b);
+ static void DrawMapOverlay(bitmap* =NULL);
+
#ifdef WIZARD
static void ActivateWizardMode() { WizardMode = true; }
static truth WizardModeIsActive() { return WizardMode; }
+ static void IncAutoPlayMode();
+ static int GetAutoPlayMode() { return AutoPlayMode; }
+ static void AutoPlayModeApply();
+ static void DisableAutoPlayMode() {AutoPlayMode=0;AutoPlayModeApply();}
static void SeeWholeMap();
static int GetSeeWholeMapCheatMode() { return SeeWholeMapCheatMode; }
static truth GoThroughWallsCheatIsActive() { return GoThroughWallsCheat; }
@@ -351,7 +384,9 @@ class game
static truth WizardModeIsActive() { return false; }
static int GetSeeWholeMapCheatMode() { return 0; }
static truth GoThroughWallsCheatIsActive() { return false; }
+ static int GetAutoPlayMode() { return 0; }
#endif
+
static truth WizardModeIsReallyActive() { return WizardMode; }
static void CreateBone();
static int GetQuestMonstersFound() { return QuestMonstersFound; }
@@ -401,7 +436,7 @@ class game
static int DefaultQuestion(festring&, festring, festring&, truth, stringkeyhandler = 0);
static void GetTime(ivantime&);
static long GetTurn() { return Turn; }
- static void IncreaseTurn() { ++Turn; }
+ static void IncreaseTurn() { ++Turn; ++iCurrentDungeonTurn; }
static int GetTotalMinutes() { return Tick * 60 / 2000; }
static truth PolymorphControlKeyHandler(int, festring&);
static ulong* GetEquipmentMemory() { return EquipmentMemory; }
@@ -432,12 +467,14 @@ class game
static void LearnAbout(god*);
static truth PlayerKnowsAllGods();
static void AdjustRelationsToAllGods(int);
+ static void SetRelationsToAllGods(int);
static void ShowDeathSmiley(bitmap*, truth);
static void SetEnterImage(cbitmap* What) { EnterImage = What; }
- static void SetEnterTextDisplacement(v2 What)
- {
- EnterTextDisplacement = What;
- }
+ static void SetEnterTextDisplacement(v2 What){ EnterTextDisplacement = What; }
+ static int getDefaultItemsListWidth(){ return iListWidth; }
+ static void AddDebugDrawOverlayFunction(dbgdrawoverlay ddo){vDbgDrawOverlayFunctions.push_back(ddo);}
+ static int GetCurrentDungeonTurnsCount(){return iCurrentDungeonTurn;}
+ static int GetSaveFileVersion();
private:
static void UpdateCameraCoordinate(int&, int, int, int);
static cchar* const Alignment[];
@@ -457,7 +494,7 @@ class game
static character* Player;
static v2 Camera;
static ulong Tick;
- static festring AutoSaveFileName;
+ static festring* AutoSaveFileName;
static truth InWilderness;
static worldmap* WorldMap;
static area* AreaInLoad;
@@ -509,6 +546,7 @@ class game
static long PetMassacreAmount;
static long MiscMassacreAmount;
static truth WizardMode;
+ static int AutoPlayMode;
static int SeeWholeMapCheatMode;
static truth GoThroughWallsCheat;
static int QuestMonstersFound;
@@ -548,6 +586,10 @@ class game
static truth PlayerHasReceivedAllGodsKnownBonus;
static cbitmap* EnterImage;
static v2 EnterTextDisplacement;
+ static blitdata bldAroundOnScreenTMP;
+ const static int iListWidth = 652;
+ static std::vector vDbgDrawOverlayFunctions;
+ static int iCurrentDungeonTurn;
};
inline void game::CombineLights(col24& L1, col24 L2)
diff --git a/Main/Include/gear.h b/Main/Include/gear.h
index f771c2589..a62cf5417 100644
--- a/Main/Include/gear.h
+++ b/Main/Include/gear.h
@@ -18,7 +18,7 @@
ITEM(meleeweapon, item)
{
public:
- meleeweapon() = default;
+ meleeweapon() = default;
meleeweapon(const meleeweapon&);
virtual ~meleeweapon();
virtual truth HitEffect(character*, character*, v2, int, int, truth);
@@ -60,6 +60,7 @@ ITEM(meleeweapon, item)
virtual void CalculateEnchantment();
virtual truth AllowFluids() const { return true; }
virtual int GetSparkleFlags() const;
+ virtual truth IsRuneSword() const;
protected:
virtual long GetMaterialPrice() const;
virtual truth CalculateHasBe() const;
@@ -197,6 +198,7 @@ ITEM(armor, item)
protected:
virtual void AddPostFix(festring&, int) const;
virtual void PostConstruct();
+ virtual cfestring& GetNameSingular() const;
int Enchantment;
};
@@ -209,7 +211,6 @@ ITEM(bodyarmor, armor)
protected:
virtual cchar* GetBreakVerb() const;
virtual truth AddAdjective(festring&, truth) const;
- virtual cfestring& GetNameSingular() const;
};
ITEM(goldeneagleshirt, bodyarmor)
@@ -342,6 +343,18 @@ ITEM(decosadshirt, bodyarmor)
ulong EquippedTicks;
};
+ITEM(filthytunic, bodyarmor)
+{
+ public:
+ filthytunic() { Enable(); }
+ virtual void Be();
+ protected:
+ virtual truth CalculateHasBe() const { return true; }
+ virtual int GetClassAnimationFrames() const;
+ virtual col16 GetOutlineColor(int) const;
+ virtual alpha GetOutlineAlpha(int) const;
+};
+
ITEM(weepblade, meleeweapon)
{
public:
@@ -369,4 +382,66 @@ ITEM(chastitybelt, lockablebelt)
virtual int GetFormModifier() const { return item::GetFormModifier(); }
};
+ITEM(darkaxe, meleeweapon)
+{
+ public:
+ darkaxe() { Enable(); }
+ virtual void Be();
+protected:
+ virtual truth CalculateHasBe() const { return true; }
+};
+
+ITEM(slowaxe, meleeweapon)
+{
+ public:
+ virtual truth HitEffect(character*, character*, v2, int, int, truth);
+};
+
+ITEM(terrorscythe, meleeweapon)
+{
+ public:
+ virtual truth HitEffect(character*, character*, v2, int, int, truth);
+};
+
+ITEM(bansheesickle, meleeweapon)
+{
+ public:
+ virtual truth HitEffect(character*, character*, v2, int, int, truth);
+};
+
+ITEM(rustscythe, meleeweapon)
+{
+ public:
+ virtual truth HitEffect(character*, character*, v2, int, int, truth);
+ virtual void BlockEffect(character*, character*, item*, int Type);
+};
+
+ITEM(sharpaxe, meleeweapon)
+{
+ public:
+ virtual truth HitEffect(character*, character*, v2, int, int, truth);
+};
+
+ITEM(taiaha, meleeweapon)
+{
+ public:
+ virtual truth AllowAlphaEverywhere() const { return true; }
+ virtual void Save(outputfile&) const;
+ virtual void Load(inputfile&);
+ virtual void ChargeFully(character*) { TimesUsed = 0; }
+ virtual truth IsAppliable(ccharacter*) const { return false; }
+ virtual truth IsZappable(ccharacter*) const { return true; }
+ virtual truth IsChargeable(ccharacter*) const { return true; }
+ virtual truth Zap(character*, v2, int);
+ virtual void AddInventoryEntry(ccharacter*, festring&, int, truth) const; //this?
+ virtual truth IsExplosive() const { return true; }
+ protected:
+ virtual int GetClassAnimationFrames() const;
+ virtual col16 GetOutlineColor(int) const;
+ virtual alpha GetOutlineAlpha(int) const;
+ virtual void PostConstruct();
+ int Charges;
+ int TimesUsed;
+};
+
#endif
diff --git a/Main/Include/hiteffect.h b/Main/Include/hiteffect.h
new file mode 100644
index 000000000..638b43f11
--- /dev/null
+++ b/Main/Include/hiteffect.h
@@ -0,0 +1,76 @@
+/*
+ *
+ * Iter Vehemens ad Necem (IVAN)
+ * Copyright (C) Timo Kiviluoto
+ * Released under the GNU General
+ * Public License
+ *
+ * See LICENSING which should be included
+ * along with this file for more details
+ *
+ */
+
+#ifndef __HITEFFECT_H_
+#define __HITEFFECT_H_
+
+#include
+
+#include "entity.h"
+#include "v2.h"
+
+class lsquare;
+class blitdata;
+
+/**
+ * temporary, less than 1s, not to be saved
+ */
+struct hiteffectSetup { //TODO some of these are not actually an external setup...
+ truth Critical;
+ int GivenDir;
+ int Type;
+ character* WhoHits;
+ character* WhoIsHit;
+ item* itemEffectReference;
+ int iMode;
+ lsquare* LSquareUnder;
+};
+class hiteffect : public entity
+{
+ public:
+ /* Come To The Dark Side */
+ hiteffect* Next;
+ public:
+ hiteffect();
+ hiteffect(hiteffectSetup);
+ virtual ~hiteffect();
+ virtual void Be();
+ virtual void Draw() const;
+ truth DrawStep();
+ void PrepareBlitdata(const blitdata& bld);
+ virtual square* GetSquareUnderEntity(int = 0) const;
+ virtual truth IsOnGround() const { return true; } //TODO false?
+ void End();
+ protected:
+ truth CheckIntegrity(int iDbgState) const;
+ void cleanup();
+ void chkCleanupAlready() const;
+ int iDrawCount; //TODO use realtime??? may not be good on slow machines?
+ int iCleanCount;
+ bitmap* bmpHitEffect;
+ hiteffectSetup setup;
+ blitdata bldFinalDraw;
+ v2 v2CamPos;
+ truth bBlitdataWasSet;
+ lsquare* LSquareUnderOfWhoHits;
+ std::vector vExtraSquares;
+ v2 v2HitFromSqrPos;
+ v2 v2HitToSqrPos;
+ v2 v2HitFromToSqrDiff;
+ bool bWhoIsHitDied;
+ long lStartTime;
+
+ int iState;
+ void SetIntegrityState(int i);
+};
+
+#endif //__HITEFFECT_H_
diff --git a/Main/Include/human.h b/Main/Include/human.h
index b2d5c9c68..156a38100 100644
--- a/Main/Include/human.h
+++ b/Main/Include/human.h
@@ -162,13 +162,20 @@ CHARACTER(humanoid, character)
virtual truth AllowUnconsciousness() const;
virtual truth CanChokeOnWeb(web*) const;
virtual truth BrainsHurt() const;
+ virtual truth IsHeadless() const;
virtual cchar* GetRunDescriptionLine(int) const;
virtual cchar* GetNormalDeathMessage() const;
virtual void ApplySpecialAttributeBonuses();
virtual truth MindWormCanPenetrateSkull(mindworm*) const;
truth HasSadistWeapon() const;
+ truth CheckAIZapOpportunity();
virtual truth HasSadistAttackMode() const;
+ truth AutoPlayAIequip();
+ static v2 GetSilhouetteWhere(){return SilhouetteWhere;}
+ static v2 GetSilhouetteWhereDefault(){return SilhouetteWhereDefault;}
+ static void SetSilhouetteWhere(v2 pos){SilhouetteWhere=pos;}
protected:
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
virtual v2 GetBodyPartBitmapPos(int, truth = false) const;
virtual col16 GetBodyPartColorB(int, truth = false) const;
virtual col16 GetBodyPartColorC(int, truth = false) const;
@@ -190,6 +197,8 @@ CHARACTER(humanoid, character)
sweaponskill* CurrentRightSWeaponSkill;
sweaponskill* CurrentLeftSWeaponSkill;
static cint DrawOrder[];
+ static v2 SilhouetteWhereDefault;
+ static v2 SilhouetteWhere;
};
CHARACTER(playerkind, humanoid)
@@ -276,8 +285,9 @@ CHARACTER(shopkeeper, humanoid)
CHARACTER(priest, humanoid)
{
protected:
- virtual void GetAICommand() { StandIdleAI(); }
+ virtual void GetAICommand();
virtual void BeTalkedTo();
+ void CallForMonsters();
};
CHARACTER(oree, humanoid)
@@ -296,6 +306,9 @@ CHARACTER(oree, humanoid)
CHARACTER(darkknight, humanoid)
{
+ public:
+ virtual truth SpecialEnemySightedReaction(character*);
+ virtual truth CheckForUsefulItemsOnGround(truth = true);
protected:
virtual int ModifyBodyPartHitPreference(int, int) const;
virtual int ModifyBodyPartToHitChance(int, int) const;
@@ -339,6 +352,8 @@ CHARACTER(skeleton, humanoid)
CHARACTER(goblin, humanoid)
{
+ public:
+ virtual void GetAICommand();
};
CHARACTER(golem, humanoid)
@@ -405,6 +420,7 @@ CHARACTER(housewife, humanoid)
{
public:
virtual truth SpecialEnemySightedReaction(character*);
+ virtual void CreateInitialEquipment(int);
protected:
virtual int GetHairColor() const;
virtual v2 GetHeadBitmapPos() const;
@@ -445,14 +461,14 @@ CHARACTER(zombie, humanoid)
festring Description;
};
-CHARACTER(spirit, humanoid)
+CHARACTER(ghost, humanoid)
{
public:
- spirit() : Active(true) { }
+ ghost() : Active(true) { }
virtual truth BodyPartIsVital(int) const;
// virtual void CreateBodyParts(int); // as per zombies, in case some body parts are missing?
void SetDescription(cfestring What) { Description = What; }
- virtual festring GetSpiritDescription() const;
+ virtual festring GetGhostDescription() const;
virtual void AddName(festring&, int) const;
virtual void Save(outputfile&) const;
virtual void Load(inputfile&);
@@ -477,7 +493,7 @@ CHARACTER(spirit, humanoid)
festring Description;
};
-CHARACTER(bonesghost, spirit)
+CHARACTER(bonesghost, ghost)
{
public:
virtual col16 GetHairColor() const { return HairColor; }
@@ -494,11 +510,12 @@ CHARACTER(bonesghost, spirit)
col16 EyeColor;
};
-CHARACTER(xinrochghost, spirit)
+CHARACTER(xinrochghost, ghost)
{
public:
virtual truth IsNameable() const { return false; }
virtual truth IsPolymorphable() const { return false; }
+ virtual truth CheckForUsefulItemsOnGround(truth = true) { return false; }
protected:
virtual void GetAICommand();
virtual void CreateCorpse(lsquare*);
@@ -506,6 +523,8 @@ CHARACTER(xinrochghost, spirit)
CHARACTER(imp, humanoid)
{
+ protected:
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
};
CHARACTER(mistress, humanoid)
@@ -524,6 +543,14 @@ CHARACTER(werewolfwolf, humanoid)
{
public:
virtual festring GetKillName() const;
+ protected:
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
+};
+
+CHARACTER(vampire, humanoid)
+{
+ protected:
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
};
CHARACTER(kobold, humanoid)
@@ -583,6 +610,8 @@ CHARACTER(genie, humanoid)
CHARACTER(orc, humanoid)
{
+ public:
+ virtual truth MoveRandomly();
protected:
virtual void PostConstruct();
};
@@ -715,6 +744,7 @@ CHARACTER(siren, humanoid)
{
public:
virtual void GetAICommand();
+ virtual truth MoveRandomly();
protected:
virtual truth TryToSing();
};
@@ -723,4 +753,22 @@ CHARACTER(punisher, humanoid)
{
};
+CHARACTER(child, humanoid)
+{
+};
+
+CHARACTER(bum, humanoid)
+{
+};
+
+CHARACTER(nihil, humanoid)
+{
+ public:
+ virtual truth BodyPartIsVital(int) const;
+ virtual truth CanCreateBodyPart(int) const;
+ virtual int GetAttribute(int, truth = true) const;
+ virtual col24 GetBaseEmitation() const { return MakeRGB24(150, 110, 110); }
+ virtual cfestring& GetStandVerb() const { return character::GetStandVerb(); }
+};
+
#endif
diff --git a/Main/Include/iconf.h b/Main/Include/iconf.h
index 77245f839..3adbc5f72 100644
--- a/Main/Include/iconf.h
+++ b/Main/Include/iconf.h
@@ -20,23 +20,61 @@ class ivanconfig
{
public:
static cfestring& GetDefaultName() { return DefaultName.Value; }
+ static cfestring& GetFantasyNamePattern() { return FantasyNamePattern.Value; }
static cfestring& GetDefaultPetName() { return DefaultPetName.Value; }
+ static cfestring& GetSelectedBkgColor() { return SelectedBkgColor.Value; }
static long GetAutoSaveInterval() { return AutoSaveInterval.Value; }
static long GetContrast() { return Contrast.Value; }
+ static long GetHitIndicator() { return HitIndicator.Value; }
+ static long GetShowItemsAtPlayerSquare(){ return ShowItemsAtPlayerSquare.Value; }
+ static long GetStartingWindowWidth() { return iStartingWindowWidth; }
+ static long GetStartingWindowHeight() { return iStartingWindowHeight; }
+ static long GetFrameSkip() { return FrameSkip.Value; }
+ static long GetGoOnStopMode() { return GoOnStopMode.Value; }
+ static long GetHoldPosMaxDist() { return HoldPosMaxDist.Value; }
+ static truth IsSavegameSafely(){ return SavegameSafely.Value; }
+ static truth IsAllowImportOldSavegame(){ return AllowImportOldSavegame.Value; }
+ static long GetAltSilhouette() { return AltSilhouette.Value; }
+ static truth IsHideWeirdHitAnimationsThatLookLikeMiss(){return HideWeirdHitAnimationsThatLookLikeMiss.Value;}
+ static truth IsGenerateDefinesValidator(){return GenerateDefinesValidator.Value;}
+ static int GetAltSilhouettePreventColorGlitch(){return AltSilhouettePreventColorGlitch.Value;}
+ static int GetShowMap(){return ShowMap.Value;}
+ static truth IsShowMapAtDetectMaterial() { return ShowMapAtDetectMaterial.Value; }
+ static truth IsWaitNeutralsMoveAway() { return WaitNeutralsMoveAway.Value; }
+ static int GetMemorizeEquipmentMode() { return MemorizeEquipmentMode.Value; }
+ static truth IsShowFullDungeonName() { return ShowFullDungeonName.Value; }
+ static truth IsCenterOnPlayerAfterLook(){ return CenterOnPlayerAfterLook.Value; }
+ static truth IsShowGodInfo(){ return ShowGodInfo.Value; }
static truth GetWarnAboutDanger() { return WarnAboutDanger.Value; }
static truth GetAutoDropLeftOvers() { return AutoDropLeftOvers.Value; }
static truth GetLookZoom() { return LookZoom.Value; }
+ static truth IsXBRZScale() { return XBRZScale.Value; }
+ static truth IsAltAdentureInfo() { return AltAdentureInfo.Value; }
+ static int GetXBRZSquaresAroundPlayer() { return XBRZSquaresAroundPlayer.Value; }
+ static int GetStartingDungeonGfxScale() { return iStartingDungeonGfxScale; }
+ static int GetSilhouetteScale() { return SilhouetteScale.Value; }
+ static int GetRotateTimesPerSquare() { return RotateTimesPerSquare.Value; }
static long GetDirectionKeyMap() { return DirectionKeyMap.Value; }
+ static int GetAltListItemWidth() { return AltListItemWidth.Value; }
+ static int GetStackListPageLength() { return StackListPageLength.Value; }
static truth GetSmartOpenCloseApply() { return SmartOpenCloseApply.Value; }
static truth GetBeNice() { return BeNice.Value; }
+ static int GetAltListItemPos() { return AltListItemPos.Value; }
+ static truth GetPlaySounds() { return PlaySounds.Value; }
+ static truth IsShowTurn() { return ShowTurn.Value; }
+ static truth IsStartingOutlinedGfx() { return bStartingOutlinedGfx; }
static long GetVolume() { return Volume.Value; }
static long GetMIDIOutputDevice() { return MIDIOutputDevice.Value; }
+
#ifndef __DJGPP__
+ static int GetGraphicsScale() { return GraphicsScale.Value; }
+ static int GetScalingQuality() { return ScalingQuality.Value; }
static truth GetFullScreenMode() { return FullScreenMode.Value; }
static void SwitchModeHandler();
#else
static truth GetFullScreenMode() { return true; }
#endif
+
static long ApplyContrastTo(long);
static void Save() { configsystem::Save(); }
static void Load() { configsystem::Load(); }
@@ -44,43 +82,148 @@ class ivanconfig
static col24 GetContrastLuminance() { return ContrastLuminance; }
static void Initialize();
static void Show();
+
private:
static v2 GetQuestionPos();
static void AutoSaveIntervalDisplayer(const numberoption*, festring&);
+ static void XBRZSquaresAroundPlayerDisplayer(const numberoption* O, festring& Entry);
+ static void ShowMapDisplayer(const cycleoption* O, festring& Entry);
+ static void GoOnStopModeDisplayer(const cycleoption* O, festring& Entry);
+ static void ShowItemsAtPlayerSquareDisplayer(const cycleoption* O, festring& Entry);
+ static void RotateTimesPerSquareDisplayer(const cycleoption* O, festring& Entry);
+ static void AltSilhouettePreventColorGlitchDisplayer(const cycleoption* O, festring& Entry);
+ static void HoldPosMaxDistDisplayer(const cycleoption* O, festring& Entry);
+ static void HitIndicatorDisplayer(const cycleoption* O, festring& Entry);
+ static void WindowWidthDisplayer(const numberoption* O, festring& Entry);
+ static void WindowHeightDisplayer(const numberoption* O, festring& Entry);
+ static void StackListPageLengthDisplayer(const numberoption* O, festring& Entry);
+ static void FrameSkipDisplayer(const numberoption* O, festring& Entry);
+ static void AltListItemWidthDisplayer(const numberoption* O, festring& Entry);
static void ContrastDisplayer(const numberoption*, festring&);
static void DirectionKeyMapDisplayer(const cycleoption*, festring&);
static truth DefaultNameChangeInterface(stringoption*);
+ static truth FantasyNameChangeInterface(stringoption* O);
+ static truth SelectedBkgColorChangeInterface(stringoption* O);
static truth DefaultPetNameChangeInterface(stringoption*);
static truth AutoSaveIntervalChangeInterface(numberoption*);
+ static truth XBRZSquaresAroundPlayerChangeInterface(numberoption* O);
+ static truth ShowItemsAtPlayerSquareChangeInterface(cycleoption* O);
+ static truth WindowWidthChangeInterface(numberoption* O);
+ static truth WindowHeightChangeInterface(numberoption* O);
+ static truth StackListPageLengthChangeInterface(numberoption* O);
+ static truth FrameSkipChangeInterface(numberoption* O);
+ static truth AltListItemWidthChangeInterface(numberoption* O);
static truth ContrastChangeInterface(numberoption*);
+ static void SelectedBkgColorChanger(stringoption* O, cfestring& What);
static void AutoSaveIntervalChanger(numberoption*, long);
+ static void XBRZSquaresAroundPlayerChanger(numberoption* O, long What);
+ static void ShowItemsAtPlayerSquareChanger(cycleoption* O, long What);
+ static void WindowWidthChanger(numberoption* O, long What);
+ static void WindowHeightChanger(numberoption* O, long What);
+ static void StackListPageLengthChanger(numberoption* O, long What);
+ static void FrameSkipChanger(numberoption* O, long What);
+ static void AltListItemWidthChanger(numberoption* O, long What);
static void ContrastChanger(numberoption*, long);
+ static void MemorizeEquipmentModeDisplayer(const cycleoption* O, festring& Entry);
static void MIDIOutputDeviceDisplayer(const cycleoption*, festring&);
static void VolumeDisplayer(const numberoption*, festring&);
static truth VolumeChangeInterface(numberoption*);
static void VolumeChanger(numberoption*, long);
+ static void AltSilhouetteDisplayer(const cycleoption* O, festring& Entry);
+
#ifndef __DJGPP__
+ static void GraphicsScaleDisplayer(const cycleoption*, festring&);
+ static void ScalingQualityDisplayer(const cycleoption*, festring&);
+ static truth GraphicsScaleChangeInterface(cycleoption*);
+ static void GraphicsScaleChanger(cycleoption*, long);
static void FullScreenModeChanger(truthoption*, truth);
#endif
+
+ static void DungeonGfxScaleDisplayer(const cycleoption*, festring&);
+ static void SilhouetteScaleDisplayer(const cycleoption* O, festring& Entry);
+ static void AltListItemPosDisplayer(const cycleoption* O, festring& Entry);
+ static void SaveGameSortModeDisplayer(const cycleoption* O, festring& Entry);
+ static truth DungeonGfxScaleChangeInterface(cycleoption*);
+ static truth SilhouetteScaleChangeInterface(cycleoption*);
+ static void DungeonGfxScaleChanger(cycleoption*, long);
+ static void SilhouetteScaleChanger(cycleoption*, long);
+ static void SaveGameSortModeChanger(cycleoption* O, long What);
+ static void XBRZScaleChanger(truthoption*, truth);
+ static void SavegameSafelyChanger(truthoption* O, truth What);
+ static void GenerateDefinesValidatorChanger(truthoption* O, truth What);
static void ContrastHandler(long);
static void VolumeHandler(long);
static void BackGroundDrawer();
+
static stringoption DefaultName;
+ static stringoption FantasyNamePattern;
static stringoption DefaultPetName;
+ static stringoption SelectedBkgColor;
static numberoption AutoSaveInterval;
+ static truthoption AltAdentureInfo;
+ static truthoption CenterOnPlayerAfterLook;
static scrollbaroption Contrast;
+ static truthoption ShowGodInfo;
+
+ static numberoption WindowWidth;
+ static int iStartingWindowWidth;
+
+ static numberoption WindowHeight;
+ static int iStartingWindowHeight;
+
+ static cycleoption HoldPosMaxDist;
+ static numberoption FrameSkip;
+ static truthoption ShowFullDungeonName;
+ static truthoption AllowImportOldSavegame;
+ static truthoption SavegameSafely;
+ static cycleoption ShowItemsAtPlayerSquare;
+ static truthoption HideWeirdHitAnimationsThatLookLikeMiss;
+ static truthoption GenerateDefinesValidator;
+ static cycleoption AltSilhouettePreventColorGlitch;
+ static cycleoption ShowMap;
+ static truthoption ShowMapAtDetectMaterial;
+ static truthoption WaitNeutralsMoveAway;
+
+ static cycleoption MemorizeEquipmentMode;
+
static truthoption WarnAboutDanger;
static truthoption AutoDropLeftOvers;
static truthoption LookZoom;
+ static truthoption XBRZScale;
+
+ static cycleoption SaveGameSortMode;
+
+ static cycleoption DungeonGfxScale;
+ static int iStartingDungeonGfxScale;
+
+ static truthoption OutlinedGfx;
+ static bool bStartingOutlinedGfx;
+
+ static numberoption XBRZSquaresAroundPlayer;
static cycleoption DirectionKeyMap;
+ static cycleoption GoOnStopMode;
+ static cycleoption SilhouetteScale;
+ static cycleoption AltSilhouette;
+ static cycleoption AltListItemPos;
+ static cycleoption RotateTimesPerSquare;
+ static numberoption AltListItemWidth;
+ static numberoption StackListPageLength;
+ static cycleoption HitIndicator;
+
static truthoption SmartOpenCloseApply;
static truthoption BeNice;
static scrollbaroption Volume;
static cycleoption MIDIOutputDevice;
+
#ifndef __DJGPP__
+ static cycleoption GraphicsScale;
static truthoption FullScreenMode;
+ static cycleoption ScalingQuality;
#endif
+
static col24 ContrastLuminance;
+ static truthoption PlaySounds;
+ static truthoption ShowTurn;
};
inline long ivanconfig::ApplyContrastTo(long L)
diff --git a/Main/Include/igraph.h b/Main/Include/igraph.h
index cb18cbe57..248a3ce00 100644
--- a/Main/Include/igraph.h
+++ b/Main/Include/igraph.h
@@ -117,6 +117,7 @@ class igraph
static bitmap* GetSilhouetteCache(int I1, int I2, int I3) { return SilhouetteCache[I1][I2][I3]; }
static cbitmap* GetBackGround() { return BackGround; }
static void BlitBackGround(v2, v2);
+ static void BlitBackGround(bitmap* bmpAt, v2 Pos, v2 Border);
static void CreateBackGround(int);
static bitmap* GenerateScarBitmap(int, int, int);
static cbitmap* GetSmileyGraphic() { return Graphic[GR_SMILEY]; }
diff --git a/Main/Include/item.h b/Main/Include/item.h
index 31275723f..5b9078460 100644
--- a/Main/Include/item.h
+++ b/Main/Include/item.h
@@ -131,11 +131,13 @@ struct itemdatabase : public databasebase
truth CanBeBurned;
truth CanBePiled;
long Category;
+ int EnergyResistance;
int FireResistance;
int PoisonResistance;
int ElectricityResistance;
int AcidResistance;
int StrengthModifier;
+ int SoundResistance;
int FormModifier;
int DefaultSize;
long DefaultMainVolume;
@@ -247,18 +249,23 @@ class item : public object
virtual liquid* CreateDipLiquid(long MaxVolume = 500) { return 0; }
virtual item* BetterVersion() const { return 0; }
virtual int GetOfferValue(int) const;
- virtual void Fly(character*, int, int);
+ virtual void Fly(character*, int, int, truth=false);
int HitCharacter(character*, character*, int, double, int);
virtual truth DogWillCatchAndConsume(ccharacter*) const { return false; }
virtual truth Apply(character*);
virtual truth Zap(character*, v2, int) { return false; }
virtual truth Polymorph(character*, stack*);
+ virtual truth Alchemize(character*, stack*);
virtual truth CheckPickUpEffect(character*) { return true; }
virtual void StepOnEffect(character*) { }
virtual truth IsTheAvatar() const { return false; }
virtual void SignalSquarePositionChange(int);
virtual truth CanBeEatenByAI(ccharacter*) const;
virtual truth IsExplosive() const { return false; }
+ virtual void SetLabel(cfestring& What);
+ virtual cfestring& GetLabel() const { return label; }
+ virtual void AddName(festring&, int) const;
+ virtual void AddName(festring& a, int b, int c) const {object::AddName(a,b,c);} //required because of AddName(festring&,int)
virtual void Save(outputfile&) const;
virtual void Load(inputfile&);
virtual void ChargeFully(character*) { }
@@ -320,10 +327,12 @@ class item : public object
DATA_BASE_VALUE(int, WeaponCategory);
DATA_BASE_TRUTH(IsAutoInitializable);
DATA_BASE_VALUE(long, Category);
+ DATA_BASE_VALUE(int, EnergyResistance);
DATA_BASE_VALUE(int, FireResistance);
DATA_BASE_VALUE(int, PoisonResistance);
DATA_BASE_VALUE(int, ElectricityResistance);
DATA_BASE_VALUE(int, AcidResistance);
+ DATA_BASE_VALUE(int, SoundResistance);
DATA_BASE_VALUE(int, StrengthModifier);
virtual DATA_BASE_VALUE(int, FormModifier);
DATA_BASE_VALUE(int, DefaultSize);
@@ -487,6 +496,7 @@ class item : public object
virtual truth IsEncryptedScroll() const { return false; }
virtual truth IsShadowVeil() const { return false; }
virtual truth IsLostRubyFlamingSword() const { return false; }
+ virtual truth IsRuneSword() const { return false; }
cchar* GetStrengthValueDescription() const;
cchar* GetBaseToHitValueDescription() const;
cchar* GetBaseBlockValueDescription() const;
@@ -625,7 +635,9 @@ class item : public object
fluid** Fluid;
int SquaresUnder;
int LifeExpectancy;
+ festring label;
ulong ItemFlags;
+ int iRotateFlyingThrownStep;
virtual truth NeedsBurningPostFix() const { return IsBurning(); }
};
diff --git a/Main/Include/ivandef.h b/Main/Include/ivandef.h
index 1c2a22a6c..2a4042dfa 100644
--- a/Main/Include/ivandef.h
+++ b/Main/Include/ivandef.h
@@ -122,7 +122,7 @@ const name##prototype name::ProtoType
#define BLOATED 5
#define OVER_FED 6
-#define STATES 22
+#define STATES 32
#define POLYMORPHED (1 << 0)
#define HASTE (1 << 1)
@@ -139,13 +139,24 @@ const name##prototype name::ProtoType
#define TELEPORT_CONTROL (1 << 12)
#define PANIC (1 << 13)
#define CONFUSED (1 << 14)
-#define PARASITIZED (1 << 15)
+#define PARASITE_TAPE_WORM (1 << 15)
#define SEARCHING (1 << 16)
#define GAS_IMMUNITY (1 << 17)
#define LEVITATION (1 << 18)
#define LEPROSY (1 << 19)
#define HICCUPS (1 << 20)
#define ETHEREAL_MOVING (1 << 21)
+#define VAMPIRISM (1 << 22)
+#define SWIMMING (1 << 23)
+#define DETECTING (1 << 24)
+#define POLYMORPH_LOCK (1 << 25)
+#define REGENERATION (1 << 26)
+#define DISEASE_IMMUNITY (1 << 27)
+#define TELEPORT_LOCK (1 << 28)
+#define FEARLESS (1 << 29)
+#define FASTING (1 << 30)
+#define PARASITE_MIND_WORM (1 << 31)
+
#define TORSO 1
#define HEAD 2
@@ -278,7 +289,7 @@ const name##prototype name::ProtoType
#define WOBBLE_FREQ_SHIFT 4
#define WOBBLE_FREQ_RANGE (3 << WOBBLE_FREQ_SHIFT)
-cv2 SILHOUETTE_SIZE(48, 64);
+cv2 SILHOUETTE_SIZE(48, 64); // it is TILE_SIZE*3,TILE_SIZE*4 tho..
#define ITEM_CATEGORIES 18
@@ -381,6 +392,11 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define EFFECT_OMMEL_BONE 29
#define EFFECT_MUSTARD_GAS 30
#define EFFECT_MUSTARD_GAS_LIQUID 31
+#define EFFECT_VAMPIRISM 32
+#define EFFECT_PANACEA 33
+#define EFFECT_OMMEL_BLOOD 34
+#define EFFECT_PANIC 35
+#define EFFECT_TRAIN_WISDOM 36
/* CEM = Consume End Message */
@@ -400,6 +416,8 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define CEM_GRAY_UNICORN_FLESH 13
#define CEM_WHITE_UNICORN_FLESH 14
#define CEM_OMMEL_BONE 15
+#define CEM_COCA_COLA 16
+#define CEM_LIQUID_HORROR 17
/* HM = Hit Message */
@@ -499,6 +517,7 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define NO_MATERIALS 8
#define NO_EQUIPMENT 16
#define NO_SIGNALS 32
+#define NO_SEVERED_LIMBS 64
#define NOT_WALKABLE 1
#define HAS_CHARACTER 2
@@ -529,7 +548,8 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define DARK_LEVEL 8
#define OREE_LAIR 12
-#define DUAL_ENNER_BEAST_LEVEL 7
+#define DUAL_ENNER_BEAST_LEVEL 5
+#define NECRO_CHAMBER_LEVEL 6
/* stack::DrawContents flags */
@@ -576,7 +596,7 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define HIT 1
#define CATCHED 2
-#define BEAM_EFFECTS 13
+#define BEAM_EFFECTS 15
#define BEAM_POLYMORPH 0
#define BEAM_STRIKE 1
@@ -591,6 +611,8 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define BEAM_DOOR_CREATION 10
#define BEAM_ACID_RAIN 11
#define BEAM_NECROMANCY 12
+#define BEAM_WEBBING 13
+#define BEAM_ALCHEMY 14
#define BEAM_STYLES 3
@@ -660,7 +682,7 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define LOCK_BITS 0xFC00
-#define BROKEN_LOCK S_LOCK_ID
+#define BROKEN_LOCK 32768
/* Normal lock types, which can be randomized */
@@ -1093,6 +1115,7 @@ cv2 SILHOUETTE_SIZE(48, 64);
#define CAN_HAVE_PARASITE 4
#define USE_MATERIAL_ATTRIBUTES 8
#define CAN_REGENERATE 16
+#define IS_WARM_BLOODED 32
/* InteractionFlags */
#define CAN_BURN 1
diff --git a/Main/Include/level.h b/Main/Include/level.h
index d2067794e..e79944d44 100644
--- a/Main/Include/level.h
+++ b/Main/Include/level.h
@@ -193,6 +193,7 @@ class level : public area
void Explosion(character*, cfestring&, v2, int, truth = true, truth = false);
truth CollectCreatures(charactervector&, character*, truth);
void ApplyLSquareScript(const squarescript*);
+ void DrawHitEffects(cint XMin,cint XMax,cint YMin,cint YMax) const;
virtual void Draw(truth) const;
v2 GetEntryPos(ccharacter*, int) const;
void GenerateRectangularRoom(std::vector&, std::vector&, std::vector&, const roomscript*, room*, v2, v2);
diff --git a/Main/Include/lsquare.h b/Main/Include/lsquare.h
index 2dd46841c..b35283614 100644
--- a/Main/Include/lsquare.h
+++ b/Main/Include/lsquare.h
@@ -28,12 +28,14 @@ class fluid;
class material;
class item;
class smoke;
+class hiteffect;
class gas;
class bodypart;
class liquid;
class rain;
class trap;
struct sortdata;
+struct hiteffectSetup;
typedef std::vector- itemvector;
typedef truth (item::*sorter)(ccharacter*) const;
@@ -124,6 +126,7 @@ class lsquare : public square
void UpdateMemorizedDescription(truth = false);
truth BeKicked(character*, item*, bodypart*, double, double, int, int, truth, truth);
int GetDivineMaster() const;
+ void DrawHitEffect();
void Draw(blitdata&) const;
void UpdateMemorized();
truth CanBeDug() const;
@@ -180,6 +183,8 @@ class lsquare : public square
truth DoorCreation(const beamdata&);
truth AcidRain(const beamdata&);
truth Necromancy(const beamdata&);
+ truth Webbing(const beamdata&);
+ truth Alchemize(const beamdata&);
truth WaterRain(const beamdata&);
int GetLevelIndex() const { return static_cast(AreaUnder)->GetIndex(); }
int GetDungeonIndex() const { return static_cast(AreaUnder)->GetDungeon()->GetIndex(); }
@@ -193,6 +198,9 @@ class lsquare : public square
void AddSmoke(gas*);
truth IsFlyable() const { return !OLTerrain || (OLTerrain->GetWalkability() & FLY); }
truth IsTransparent() const { return Flags & IS_TRANSPARENT; }
+ truth IsMaterialDetected() const { return bMaterialDetected; }
+ hiteffect* AddHitEffect(hiteffectSetup);
+ void RemoveHitEffect(hiteffect* ToBeRemoved);
void SignalSmokeAlphaChange(int);
void ShowSmokeMessage() const;
void DisplaySmokeInfo(festring&) const;
@@ -275,6 +283,8 @@ class lsquare : public square
} StaticContentCache;
fluid* Fluid;
smoke* Smoke;
+ hiteffect* HitEffect;
+ truth bMaterialDetected; //temporary
rain* Rain;
trap* Trap;
emittervector Emitter;
diff --git a/Main/Include/lterras.h b/Main/Include/lterras.h
index 112e3c377..30e72d1d3 100644
--- a/Main/Include/lterras.h
+++ b/Main/Include/lterras.h
@@ -15,8 +15,6 @@
#include "lterra.h"
-class ghost;
-
OLTERRAIN(wall, olterrain)
{
};
@@ -266,4 +264,13 @@ OLTERRAIN(ironmaiden, olterrain)
truth Opened;
};
+OLTERRAIN(christmastree, olterrain)
+{
+ public:
+ virtual int GetSparkleFlags() const;
+ protected:
+ virtual int GetClassAnimationFrames() const;
+ virtual v2 GetBitmapPos(int) const;
+};
+
#endif
diff --git a/Main/Include/materia.h b/Main/Include/materia.h
index 2c78006e3..09959d01e 100644
--- a/Main/Include/materia.h
+++ b/Main/Include/materia.h
@@ -62,9 +62,11 @@ struct materialdatabase : public databasebase
int Acidicity;
contentscript
- NaturalForm;
int HardenedMaterial;
+ int SoftenedMaterial;
int IntelligenceRequirement;
int Stickiness;
truth DisablesPanicWhenConsumed;
+ truth BlockESP;
int FireResistance;
int BurnModifier;
};
@@ -104,7 +106,7 @@ class material
material(int NewConfig, long InitVolume = 0, truth Load = false)
: MotherEntity(0) { Initialize(NewConfig, InitVolume, Load); }
material() : MotherEntity(0) { }
- virtual ~material() = default;
+ virtual ~material() = default;
void AddName(festring&, truth = false, truth = true) const;
festring GetName(truth = false, truth = true) const;
material* TakeDipVolumeAway(long MaxVolume = 500);
@@ -208,6 +210,7 @@ class material
virtual void SetIsInfectedByLeprosy(truth) { }
virtual truth AddRustLevelDescription(festring&, truth) const { return false; }
int GetHardenedMaterial(citem*) const;
+ int GetSoftenedMaterial(citem*) const;
int GetHardenModifier(citem*) const;
virtual int GetSpoilPercentage() const { return 0; }
virtual truth Spoils() const { return false; }
@@ -216,6 +219,7 @@ class material
material* Duplicate() const { return DataBase->ProtoType->Clone(this); }
truth IsStuckTo(ccharacter*) const;
DATA_BASE_TRUTH(DisablesPanicWhenConsumed);
+ DATA_BASE_TRUTH(BlockESP);
DATA_BASE_VALUE(int, FireResistance);
virtual void SetIsBurning(int What) { Burning = What; }
virtual int IsBurning() const { return Burning; }
@@ -237,7 +241,7 @@ class material
const database* DataBase;
entity* MotherEntity;
long Volume;
- int Burning;
+ int Burning;
};
template
diff --git a/Main/Include/message.h b/Main/Include/message.h
index 6ab97ff43..a463269c1 100644
--- a/Main/Include/message.h
+++ b/Main/Include/message.h
@@ -39,6 +39,7 @@ class msgsystem
static void EnterBigMessageMode() { BigMessageMode = true; }
static void LeaveBigMessageMode();
static void Init();
+ static void DeInit();
static void InitMessagesSinceLastKeyScan();
static void ThyMessagesAreNowOld();
private:
@@ -54,4 +55,28 @@ class msgsystem
static int LastMessageLines;
};
+#ifndef NOSOUND
+#include "SDL_mixer.h"
+#include
+#include "festring.h"
+
+class soundsystem
+{
+ friend class msgsystem;
+
+ public:
+ static void playSound(festring Buffer);
+
+ private:
+ static int SoundState;
+ static void initSound();
+ static void deInitSound();
+ static std::vector files;
+ static std::vector patterns;
+ static int addFile(festring filename);
+ static truth matches(festring Pattern, festring Buffer);
+ static struct SoundFile *findMatchingSound(festring Buffer);
+};
+#endif
+
#endif
diff --git a/Main/Include/miscitem.h b/Main/Include/miscitem.h
index 746905922..5a344a0ba 100644
--- a/Main/Include/miscitem.h
+++ b/Main/Include/miscitem.h
@@ -192,6 +192,25 @@ ITEM(scrollofteleportation, scroll)
virtual void FinishReading(character*);
};
+ITEM(scrolloffireballs, scroll)
+{
+ public:
+ virtual void FinishReading(character*);
+ virtual truth IsExplosive() const { return true; }
+};
+
+ITEM(scrollofearthquake, scroll)
+{
+ public:
+ virtual void FinishReading(character*);
+};
+
+ITEM(scrollofbodyswitch, scroll)
+{
+ public:
+ virtual void FinishReading(character*);
+};
+
ITEM(scrollofcharging, scroll)
{
public:
@@ -291,6 +310,7 @@ ITEM(backpack, materialcontainer)
public:
virtual truth Apply(character*);
virtual truth IsAppliable(ccharacter*) const { return true; }
+ virtual truth IsCloak(ccharacter*) const { return true; }
virtual truth ReceiveDamage(character*, int, int, int);
virtual truth IsExplosive() const;
virtual long GetTotalExplosivePower() const;
@@ -496,6 +516,7 @@ ITEM(skull, item)
{
public:
virtual truth IsASkull() const { return true; }
+ virtual truth IsHelmet(ccharacter*) const { return true; }
};
ITEM(skullofxinroch, item)
@@ -503,6 +524,9 @@ ITEM(skullofxinroch, item)
public:
virtual truth IsASkull() const { return true; }
virtual void Be() { }
+ virtual bool SpecialOfferEffect(int);
+ virtual truth AllowSpoil() const { return false; }
+ virtual truth Spoils() const { return false; }
protected:
virtual int GetClassAnimationFrames() const { return 32; }
virtual col16 GetOutlineColor(int) const;
@@ -628,6 +652,22 @@ ITEM(pantheonbook, holybook)
virtual col16 GetMaterialColorA(int) const;
};
+ITEM(celestialmonograph, holybook)
+{
+ public:
+ virtual void FinishReading(character*);
+ protected:
+ virtual col16 GetMaterialColorA(int) const;
+};
+
+ITEM(materialmanual, holybook)
+{
+ public:
+ virtual void FinishReading(character*);
+ protected:
+ virtual col16 GetMaterialColorA(int) const;
+};
+
ITEM(gorovitscopyoflenin, item)
{
protected:
@@ -644,4 +684,73 @@ ITEM(firstbornchild, item)
virtual col16 GetMaterialColorB(int) const;
};
+ITEM(ullrbone, item)
+{
+ public:
+ ullrbone() : TimesUsed(0), Charges(8) { }
+ virtual truth Zap(character*, v2, int);
+ virtual void ChargeFully(character*) { TimesUsed = 0; }
+ virtual truth IsZappable(const character*) const { return true; }
+ virtual truth IsChargeable(const character*) const { return true; }
+ virtual truth HitEffect(character*, character*, v2, int, int, truth);
+ virtual void Be() { }
+ virtual void AddInventoryEntry(const character*, festring&, int, truth) const;
+ virtual truth AllowAlphaEverywhere() const { return true; }
+ protected:
+ int TimesUsed;
+ int Charges;
+ virtual int GetClassAnimationFrames() const { return 32; }
+ virtual col16 GetOutlineColor(int) const;
+ virtual alpha GetOutlineAlpha(int) const;
+};
+
+ITEM(mango, item)
+{
+};
+
+ITEM(sausage, item)
+{
+};
+
+ITEM(cauldron, materialcontainer)
+{
+ public:
+ virtual item* BetterVersion() const;
+ virtual void DipInto(liquid*, character*);
+ virtual liquid* CreateDipLiquid();
+ virtual truth IsDippable(ccharacter*) const { return !SecondaryMaterial; }
+ virtual truth IsDipDestination(ccharacter*) const;
+ virtual truth IsExplosive() const;
+ virtual truth HasBetterVersion() const { return !SecondaryMaterial; }
+ virtual truth EffectIsGood() const;
+ virtual truth IsKamikazeWeapon(ccharacter*) const { return IsExplosive(); }
+ protected:
+ virtual void AddPostFix(festring& String, int) const { AddContainerPostFix(String); }
+ virtual truth AddAdjective(festring&, truth) const;
+};
+
+ITEM(trinket, item)
+{
+ public:
+ virtual material* RemoveMaterial(material* Material);
+ virtual truth Necromancy(character*);
+ virtual truth RaiseTheDead(character*);
+ protected:
+ virtual col16 GetMaterialColorB(int) const;
+ virtual col16 GetMaterialColorC(int) const;
+};
+
+ITEM(gastrap, itemtrap)
+{
+ public:
+ virtual void StepOnEffect(character*);
+ virtual truth ReceiveDamage(character*, int, int, int);
+ virtual truth Apply(character* User);
+ virtual truth IsDangerous(ccharacter*) const { return Active; }
+ virtual truth CheckPickUpEffect(character*);
+ protected:
+ virtual truth AddAdjective(festring&, truth) const;
+ virtual void AddPostFix(festring& String, int) const { AddContainerPostFix(String); }
+};
+
#endif
diff --git a/Main/Include/nonhuman.h b/Main/Include/nonhuman.h
index ac503309c..066de201c 100644
--- a/Main/Include/nonhuman.h
+++ b/Main/Include/nonhuman.h
@@ -122,6 +122,7 @@ CHARACTER(dog, canine)
virtual truth Catches(item*);
virtual void BeTalkedTo();
protected:
+ virtual void CreateCorpse(lsquare*);
virtual bodypart* MakeBodyPart(int) const;
virtual void GetAICommand();
};
@@ -131,7 +132,7 @@ CHARACTER(spider, nonhumanoid)
public:
virtual truth IsSpider() const { return true; }
protected:
- virtual truth SpecialBiteEffect(character*, v2, int, int, truth);
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
virtual void GetAICommand();
virtual bodypart* MakeBodyPart(int) const;
};
@@ -161,6 +162,12 @@ CHARACTER(bat, nonhumanoid)
virtual bodypart* MakeBodyPart(int) const;
};
+CHARACTER(vampirebat, bat)
+{
+ protected:
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
+};
+
CHARACTER(largecat, nonhumanoid)
{
public:
@@ -208,7 +215,7 @@ CHARACTER(buffalo, nonhumanoid)
CHARACTER(snake, nonhumanoid)
{
protected:
- virtual truth SpecialBiteEffect(character*, v2, int, int, truth);
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
};
CHARACTER(ostrich, nonhumanoid)
@@ -282,33 +289,6 @@ CHARACTER(magicmushroom, mushroom)
virtual void GetAICommand();
};
-CHARACTER(ghost, nonhumanoid)
-{
- public:
- ghost() : Active(true) { }
- virtual void AddName(festring&, int) const;
- virtual void Save(outputfile&) const;
- virtual void Load(inputfile&);
- void SetOwnerSoul(cfestring& What) { OwnerSoul = What; }
- virtual truth IsNameable() const { return OwnerSoul.IsEmpty(); }
- virtual truth RaiseTheDead(character*);
- virtual int ReceiveBodyPartDamage(character*, int, int, int, int = 8, truth = false, truth = false, truth = true, truth = false);
- virtual truth SpecialEnemySightedReaction(character*);
- void SetIsActive(truth What) { Active = What; }
- virtual truth IsPolymorphable() const { return MaxHP < 100; }
- protected:
- virtual int GetBodyPartWobbleData(int) const;
- virtual cchar* FirstPersonBiteVerb() const;
- virtual cchar* FirstPersonCriticalBiteVerb() const;
- virtual cchar* ThirdPersonBiteVerb() const;
- virtual cchar* ThirdPersonCriticalBiteVerb() const;
- virtual truth AttackIsBlockable(int) const { return false; }
- virtual truth AttackMayDamageArmor() const { return false; }
- virtual void GetAICommand();
- festring OwnerSoul;
- truth Active;
-};
-
CHARACTER(twoheadedmoose, nonhumanoid)
{
public:
@@ -464,7 +444,7 @@ CHARACTER(lobhse, largecreature)
public:
virtual truth IsSpider() const { return true; }
protected:
- virtual truth SpecialBiteEffect(character*, v2, int, int, truth);
+ virtual truth SpecialBiteEffect(character*, v2, int, int, truth, truth, int);
virtual void GetAICommand();
virtual void CreateCorpse(lsquare*);
virtual truth MustBeRemovedFromBone() const;
@@ -475,7 +455,7 @@ CHARACTER(mindworm, nonhumanoid)
{
protected:
virtual void GetAICommand();
- virtual void TryToImplantLarvae(character*);
+ virtual truth TryToImplantLarvae(character*);
virtual void PsiAttack(character*);
};
#endif
diff --git a/Main/Include/proto.h b/Main/Include/proto.h
index 68ef091f4..113140077 100644
--- a/Main/Include/proto.h
+++ b/Main/Include/proto.h
@@ -82,14 +82,14 @@ class protosystem
#ifdef WIZARD
static void CreateEveryCharacter(charactervector&);
static void CreateEveryItem(itemvectorvector&);
- static void CreateEveryMaterial(std::vector&);
#endif
static void Initialize();
static void InitCharacterDataBaseFlags();
static void SaveCharacterDataBaseFlags(outputfile&);
static void LoadCharacterDataBaseFlags(inputfile&);
static void CreateEverySeenCharacter(charactervector&);
- static void CreateEveryMaterial(std::vector&, const god*, ccharacter*);
+ static void CreateEveryGodlyMaterial(std::vector&, const god*, ccharacter*);
+ static void CreateEveryMaterial(std::vector&);
private:
static itemdatabase** ItemConfigData;
static int ItemConfigDataSize;
diff --git a/Main/Include/stack.h b/Main/Include/stack.h
index c6e717df4..ffd875874 100644
--- a/Main/Include/stack.h
+++ b/Main/Include/stack.h
@@ -94,6 +94,7 @@ class stack
truth SortedItems(ccharacter*, sorter) const;
void BeKicked(character*, int, int);
void Polymorph(character*);
+ void Alchemize(character*);
void CheckForStepOnEffect(character*);
lsquare* GetLSquareTrulyUnder(int) const;
void ReceiveDamage(character*, int, int, int = YOURSELF);
@@ -154,6 +155,9 @@ class stack
ccharacter* FindCarrier() const;
void Haste();
void Slow();
+ static void SetStandardPageLength(uint l){ StandardPageLength = l; };
+ static uint GetStandardPageLength(){ return StandardPageLength; };
+ static uint GetDefaultPageLength(){ return 12; };
private:
void RemoveElement(stackslot*);
void AddContentsToList(felist&, ccharacter*, cfestring&, int, int, sorter) const;
@@ -169,6 +173,7 @@ class stack
col24 Emitation : 24;
ulong Flags : 8;
int Items;
+ static uint StandardPageLength;
};
#endif
diff --git a/Main/Source/actions.cpp b/Main/Source/actions.cpp
index 596a20bdb..22f456424 100644
--- a/Main/Source/actions.cpp
+++ b/Main/Source/actions.cpp
@@ -243,11 +243,23 @@ void dig::Handle()
int Damage = Actor->GetAttribute(ARM_STRENGTH) * Digger->GetMainMaterial()->GetStrengthValue() / 500;
Terrain->EditHP(-Max(Damage, 1));
+
+ /* Save these here because the EditNP call below can cause 'this' to be terminated
+ and deleted, if the player decides to stop digging because of becoming hungry. */
+
+ truth MoveDigger = this->MoveDigger;
+ ulong RightBackupID = this->RightBackupID;
+ ulong LeftBackupID = this->LeftBackupID;
+
Actor->EditExperience(ARM_STRENGTH, 200, 1 << 5);
Actor->EditAP(-200000 / APBonus(Actor->GetAttribute(DEXTERITY)));
Actor->EditNP(-500);
- if(Terrain->GetHP() <= 0)
+ truth TerrainDestroyed = Terrain->GetHP() <= 0;
+ truth AlreadyTerminated = Actor->GetAction() != this;
+ truth StoppedDigging = TerrainDestroyed || AlreadyTerminated;
+
+ if(TerrainDestroyed)
{
if(Square->CanBeSeenByPlayer())
ADD_MESSAGE("%s", Terrain->GetDigMessage().CStr());
@@ -259,6 +271,12 @@ void dig::Handle()
if(!Actor->IsEnabled())
return;
+ if(!AlreadyTerminated)
+ Terminate(true);
+ }
+
+ if(StoppedDigging)
+ {
if(MoveDigger && Actor->GetMainWielded())
Actor->GetMainWielded()->MoveTo(Actor->GetStack());
@@ -277,10 +295,9 @@ void dig::Handle()
LeftBackup->RemoveFromSlot();
Actor->SetLeftWielded(LeftBackup);
}
-
- Terminate(true);
}
- else
+
+ if(!TerrainDestroyed)
game::DrawEverything();
}
diff --git a/Main/Source/area.cpp b/Main/Source/area.cpp
index 328244673..5d833f531 100644
--- a/Main/Source/area.cpp
+++ b/Main/Source/area.cpp
@@ -59,6 +59,12 @@ void area::Load(inputfile& SaveFile)
SaveFile.Read(reinterpret_cast(FlagMap[0]), XSizeTimesYSize * sizeof(uchar));
}
+v2 area::topLeftCorner=v2(16,32);
+int area::iOutlineThickness=2;
+
+int area::getOutlineThickness(){return iOutlineThickness;}
+v2 area::getTopLeftCorner(){return topLeftCorner;}
+
void area::SendNewDrawRequest()
{
cint XMin = Max(game::GetCamera().X, 0);
@@ -71,13 +77,13 @@ void area::SendNewDrawRequest()
Map[x][y]->SendStrongNewDrawRequest();
igraph::GetBackGround()->FastBlit(DOUBLE_BUFFER);
- DOUBLE_BUFFER->DrawRectangle(14, 30,
- 17 + (game::GetScreenXSize() << 4),
- 33 + (game::GetScreenYSize() << 4),
+ DOUBLE_BUFFER->DrawRectangle(topLeftCorner.X-iOutlineThickness, topLeftCorner.Y-iOutlineThickness,
+ 17 + (game::GetScreenXSize() << 4), //outline of (possibly shrinked) dungeon area related to camera too
+ 33 + (game::GetScreenYSize() << 4), //outline of (possibly shrinked) dungeon area related to camera too
DARK_GRAY, true);
- DOUBLE_BUFFER->Fill(16, 32,
- game::GetScreenXSize() << 4,
- game::GetScreenYSize() << 4,
+ DOUBLE_BUFFER->Fill(topLeftCorner.X, topLeftCorner.Y,
+ game::GetScreenXSize() << 4, // unknown area (possibly shrinked) dungeon area related to camera too
+ game::GetScreenYSize() << 4, // unknown area (possibly shrinked) dungeon area related to camera too
BLACK);
}
diff --git a/Main/Source/bodypart.cpp b/Main/Source/bodypart.cpp
index 889bfb7c7..6c00ddce7 100644
--- a/Main/Source/bodypart.cpp
+++ b/Main/Source/bodypart.cpp
@@ -12,12 +12,15 @@
/* Compiled through itemset.cpp */
+#include "dbgmsgproj.h"
+
int bodypart::GetGraphicsContainerIndex() const { return GR_HUMANOID; }
int bodypart::GetArticleMode() const { return IsUnique() ? FORCE_THE : 0; }
truth bodypart::IsAlive() const { return MainMaterial->GetBodyFlags() & IS_ALIVE; }
int bodypart::GetSpecialFlags() const { return SpecialFlags|ST_OTHER_BODYPART; }
col16 bodypart::GetMaterialColorA(int) const { return GetMainMaterial()->GetSkinColor(); }
truth bodypart::IsWarm() const { return MainMaterial->GetBodyFlags() & IS_WARM || IsBurning(); }
+truth bodypart::IsWarmBlooded() const { return MainMaterial->GetBodyFlags() & IS_WARM_BLOODED; }
truth bodypart::UseMaterialAttributes() const
{ return MainMaterial->GetBodyFlags() & USE_MATERIAL_ATTRIBUTES || !Master || Master->AlwaysUseMaterialAttributes(); }
truth bodypart::CanRegenerate() const { return MainMaterial->GetBodyFlags() & CAN_REGENERATE; }
@@ -27,6 +30,8 @@ lsquare* bodypart::GetLSquareUnder(int I) const
{ return static_cast(Master ? Slot[0]->GetSquareUnder(I) : Slot[I]->GetSquareUnder()); }
item* bodypart::GetExternalBodyArmor() const { return GetHumanoidMaster()->GetBodyArmor(); }
item* bodypart::GetExternalCloak() const { return GetHumanoidMaster()->GetCloak(); }
+item* bodypart::GetExternalHelmet() const { return GetHumanoidMaster()->GetHelmet(); }
+item* bodypart::GetExternalBelt() const { return GetHumanoidMaster()->GetBelt(); }
truth bodypart::AllowFluidBe() const { return !Master || !Master->IsPolymorphed(); }
int head::GetBodyPartIndex() const { return HEAD_INDEX; }
@@ -193,14 +198,14 @@ int leg::GetTotalResistance(int Type) const
void head::Save(outputfile& SaveFile) const
{
bodypart::Save(SaveFile);
- SaveFile << BaseBiteStrength;
+ SaveFile << BaseBiteStrength << BonusBiteStrength;
SaveFile << HelmetSlot << AmuletSlot;
}
void head::Load(inputfile& SaveFile)
{
bodypart::Load(SaveFile);
- SaveFile >> BaseBiteStrength;
+ SaveFile >> BaseBiteStrength >> BonusBiteStrength;
SaveFile >> HelmetSlot >> AmuletSlot;
}
@@ -249,7 +254,7 @@ void leg::Load(inputfile& SaveFile)
}
truth bodypart::ReceiveDamage(character* Damager, int Damage, int Type, int Direction)
-{
+{DBG1(Damager);
if(Master)
{
if(Type & POISON && !IsAlive())
@@ -265,7 +270,7 @@ truth bodypart::ReceiveDamage(character* Damager, int Damage, int Type, int Dire
EditHP(1, -Damage);
- if(Type & DRAIN && IsAlive())
+ if(Damager!=NULL && (Type & DRAIN) && IsAlive())
for(int c = 0; c < Damage; ++c)
Damager->HealHitPoint();
@@ -498,7 +503,10 @@ void head::CalculateDamage()
if(!Master)
return;
- BiteDamage = 7.07e-6 * GetBaseBiteStrength() * GetHumanoidMaster()->GetCWeaponSkill(BITE)->GetBonus();
+ if(Master->StateIsActivated(VAMPIRISM))
+ BiteDamage = 7.07e-6 * (GetBaseBiteStrength() + GetBonusBiteStrength()) * GetHumanoidMaster()->GetCWeaponSkill(BITE)->GetBonus();
+ else
+ BiteDamage = 7.07e-6 * GetBaseBiteStrength() * GetHumanoidMaster()->GetCWeaponSkill(BITE)->GetBonus();
}
void head::CalculateToHitValue()
@@ -1171,6 +1179,7 @@ void leg::EditExperience(int Identifier, double Value, double Speed)
void head::InitSpecialAttributes()
{
BaseBiteStrength = Master->GetBaseBiteStrength();
+ BonusBiteStrength = Master->GetBonusBiteStrength();
}
void arm::InitSpecialAttributes()
@@ -1655,7 +1664,7 @@ void arm::WieldedSkillHit(int Hits)
}
}
-head::head(const head& Head) : mybase(Head), BaseBiteStrength(Head.BaseBiteStrength)
+head::head(const head& Head) : mybase(Head), BaseBiteStrength(Head.BaseBiteStrength), BonusBiteStrength(Head.BonusBiteStrength)
{
HelmetSlot.Init(this, HELMET_INDEX);
AmuletSlot.Init(this, AMULET_INDEX);
@@ -2077,6 +2086,14 @@ void arm::CalculateAttributeBonuses()
{
ApplyDexterityPenalty(GetExternalCloak());
ApplyDexterityPenalty(GetExternalBodyArmor());
+ ApplyStrengthBonus(GetExternalHelmet());
+ ApplyStrengthBonus(GetExternalCloak());
+ ApplyStrengthBonus(GetExternalBodyArmor());
+ ApplyStrengthBonus(GetExternalBelt());
+ ApplyDexterityBonus(GetExternalHelmet());
+ ApplyDexterityBonus(GetExternalCloak());
+ ApplyDexterityBonus(GetExternalBodyArmor());
+ ApplyDexterityBonus(GetExternalBelt());
}
if(!UseMaterialAttributes())
@@ -2107,6 +2124,14 @@ void leg::CalculateAttributeBonuses()
{
ApplyAgilityPenalty(GetExternalCloak());
ApplyAgilityPenalty(GetExternalBodyArmor());
+ ApplyStrengthBonus(GetExternalHelmet());
+ ApplyStrengthBonus(GetExternalCloak());
+ ApplyStrengthBonus(GetExternalBodyArmor());
+ ApplyStrengthBonus(GetExternalBelt());
+ ApplyAgilityBonus(GetExternalHelmet());
+ ApplyAgilityBonus(GetExternalCloak());
+ ApplyAgilityBonus(GetExternalBodyArmor());
+ ApplyAgilityBonus(GetExternalBelt());
}
if(!UseMaterialAttributes())
@@ -2162,6 +2187,30 @@ int arm::GetWieldedHitStrength() const
return HitStrength - Requirement;
}
+void arm::ApplyStrengthBonus(item* Item)
+{
+ if(Item && Item->AffectsArmStrength())
+ StrengthBonus += Item->GetEnchantment() / 2;
+}
+
+void arm::ApplyDexterityBonus(item* Item)
+{
+ if(Item && Item->AffectsDexterity())
+ DexterityBonus += Item->GetEnchantment() / 2;
+}
+
+void leg::ApplyStrengthBonus(item* Item)
+{
+ if(Item && Item->AffectsLegStrength())
+ StrengthBonus += Item->GetEnchantment() / 2;
+}
+
+void leg::ApplyAgilityBonus(item* Item)
+{
+ if(Item && Item->AffectsAgility())
+ AgilityBonus += Item->GetEnchantment() / 2;
+}
+
void arm::ApplyDexterityPenalty(item* Item)
{
if(Item)
@@ -2377,7 +2426,6 @@ truth arm::CheckIfWeaponTooHeavy(cchar* WeaponDescription) const
else
ADD_MESSAGE("%sIt is somewhat difficult for %s to use %s%s.", OtherHandInfo.CStr(),
Master->CHAR_DESCRIPTION(DEFINITE), WeaponDescription, HandInfo);
-
return !game::TruthQuestion(CONST_S("Continue anyway? [y/N]"));
}
}
@@ -3668,7 +3716,7 @@ truth bodypart::IsDestroyable(ccharacter*) const
truth bodypart::DamageTypeCanScar(int Type)
{
- return !(Type == POISON || Type == DRAIN);
+ return !(Type == POISON || Type == DRAIN || Type == PSI);
}
void bodypart::GenerateScar(int Damage, int Type)
diff --git a/Main/Source/char.cpp b/Main/Source/char.cpp
index 253342ba8..f091a7ead 100644
--- a/Main/Source/char.cpp
+++ b/Main/Source/char.cpp
@@ -23,6 +23,11 @@
* These flags can be found in ivandef.h. RANDOMIZABLE sets all source
* & duration flags at once. */
+#include "hiteffect.h" //TODO move to charsset.cpp?
+
+#define DBGMSG_V2
+#include "dbgmsgproj.h"
+
struct statedata
{
cchar* Description;
@@ -79,7 +84,7 @@ statedata StateData[STATES] =
0,
0
}, {
- "LifeSaved",
+ "Life Saved",
SECRET,
&character::PrintBeginLifeSaveMessage,
&character::PrintEndLifeSaveMessage,
@@ -188,7 +193,7 @@ statedata StateData[STATES] =
&character::CanBeConfused,
&character::ConfusedSituationDangerModifier
}, {
- "Parasitized",
+ "Parasite (tapeworm)",
SECRET|(RANDOMIZABLE&~DUR_TEMPORARY),
&character::PrintBeginParasitizedMessage,
&character::PrintEndParasitizedMessage,
@@ -208,7 +213,7 @@ statedata StateData[STATES] =
0,
0
}, {
- "GasImmunity",
+ "Gas Immunity",
SECRET|(RANDOMIZABLE&~(SRC_GOOD|SRC_EVIL)),
&character::PrintBeginGasImmunityMessage,
&character::PrintEndGasImmunityMessage,
@@ -256,6 +261,106 @@ statedata StateData[STATES] =
0,
0,
0
+ }, {
+ "Vampirism",
+ DUR_FLAGS,
+ &character::PrintBeginVampirismMessage,
+ &character::PrintEndVampirismMessage,
+ 0,
+ 0,
+ &character::VampirismHandler,
+ 0,
+ 0
+ }, {
+ "Swimming",
+ SECRET|(RANDOMIZABLE&~SRC_EVIL),
+ &character::PrintBeginSwimmingMessage,
+ &character::PrintEndSwimmingMessage,
+ &character::BeginSwimming, &character::EndSwimming,
+ 0,
+ 0,
+ 0
+ }, {
+ "Detecting",
+ SECRET|(RANDOMIZABLE&~(SRC_MUSHROOM|SRC_EVIL)),
+ &character::PrintBeginDetectMessage,
+ &character::PrintEndDetectMessage,
+ 0,
+ 0,
+ &character::DetectHandler,
+ 0,
+ 0
+ }, {
+ "Polymorph Locked",
+ SECRET|(RANDOMIZABLE&~SRC_EVIL),
+ &character::PrintBeginPolymorphLockMessage,
+ &character::PrintEndPolymorphLockMessage,
+ 0,
+ 0,
+ &character::PolymorphLockHandler,
+ 0,
+ 0
+ }, {
+ "Regenerating",
+ SECRET|(RANDOMIZABLE&~SRC_EVIL),
+ &character::PrintBeginRegenerationMessage,
+ &character::PrintEndRegenerationMessage,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, {
+ "Disease Immunity",
+ SECRET|(RANDOMIZABLE&~SRC_EVIL),
+ &character::PrintBeginDiseaseImmunityMessage,
+ &character::PrintEndDiseaseImmunityMessage,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, {
+ "Teleport Locked",
+ SECRET,
+ &character::PrintBeginTeleportLockMessage,
+ &character::PrintEndTeleportLockMessage,
+ 0,
+ 0,
+ &character::TeleportLockHandler,
+ 0,
+ 0
+ }, {
+ "Fearless",
+ RANDOMIZABLE&~SRC_EVIL,
+ &character::PrintBeginFearlessMessage,
+ &character::PrintEndFearlessMessage,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, {
+ "Fasting",
+ SECRET|(RANDOMIZABLE&~SRC_EVIL),
+ &character::PrintBeginFastingMessage,
+ &character::PrintEndFastingMessage,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ }, {
+ "Parasite (mindworm)",
+ SECRET|(RANDOMIZABLE&~DUR_TEMPORARY),
+ &character::PrintBeginMindwormedMessage,
+ &character::PrintEndMindwormedMessage,
+ 0,
+ 0,
+ &character::MindwormedHandler,
+ &character::CanBeParasitized, // We are using TorsoIsAlive right now, but I think it's OK,
+ // because with unliving torso, your head will not be much better for mind worms.
+ &character::ParasitizedSituationDangerModifier
}
};
@@ -355,7 +460,10 @@ int character::GetMoveType() const
: DataBase->MoveType | FLY) |
(!StateIsActivated(ETHEREAL_MOVING)
? DataBase->MoveType
- : DataBase->MoveType | ETHEREAL)); }
+ : DataBase->MoveType | ETHEREAL) |
+ (!StateIsActivated(SWIMMING)
+ ? DataBase->MoveType
+ : DataBase->MoveType | WALK|SWIM)); }
festring character::GetZombieDescription() const
{ return " of " + GetName(INDEFINITE); }
truth character::BodyPartCanBeSevered(int I) const { return I; }
@@ -364,7 +472,7 @@ truth character::HasBeenSeen() const
truth character::IsTemporary() const
{ return GetTorso()->GetLifeExpectancy(); }
cchar* character::GetNormalDeathMessage() const { return "killed @k"; }
-festring character::GetSpiritDescription() const
+festring character::GetGhostDescription() const
{ return " of " + GetName(INDEFINITE); }
int characterdatabase::* ExpPtr[ATTRIBUTES] =
@@ -422,6 +530,11 @@ character::character(ccharacter& Char)
int c;
+ for(c = 0; c < MAX_EQUIPMENT_SLOTS; c++)
+ MemorizedEquippedItemIDs[c] = Char.MemorizedEquippedItemIDs[c];
+
+ v2HoldPos=Char.v2HoldPos;
+
for(c = 0; c < STATES; ++c)
TemporaryStateCounter[c] = Char.TemporaryStateCounter[c];
@@ -471,6 +584,13 @@ character::character()
WarnFlags(0), ScienceTalks(0), TrapData(0), CounterToMindWormHatch(0)
{
Stack = new stack(0, this, HIDDEN);
+
+ int c;
+
+ for(c = 0; c < MAX_EQUIPMENT_SLOTS; c++)
+ MemorizedEquippedItemIDs[c]=0;
+
+ v2HoldPos=v2(0,0);
}
character::~character()
@@ -558,6 +678,32 @@ int character::TakeHit(character* Enemy, item* Weapon,
int Success, int Type, int GivenDir,
truth Critical, truth ForceHit)
{
+ hiteffectSetup* pHitEff=NULL;DBGLN;
+ bool bShowHitEffect = false;
+ static bool bHardestMode = false; //TODO make these an user hardcore combat option?
+ if(!bHardestMode){
+ //w/o ESP/infravision and if the square is visible even if both fighting are invisible
+ static bool bPlayerCanHearWhereTheFightIsHappening = true; //TODO this feels like cheating? making things easier? if so, set it to false
+ static bool bPlayerCanSensePetFighting = true; //TODO this feels like cheating? making things easier? if so, set it to false
+
+ if(bPlayerCanHearWhereTheFightIsHappening) //TODO should then also show at non directly visible squares?
+ if(GetLSquareUnder()->CanBeSeenByPlayer() || Enemy->GetLSquareUnder()->CanBeSeenByPlayer())bShowHitEffect = true;
+
+ if(bPlayerCanSensePetFighting && IsPet())bShowHitEffect=true; // override for team awareness
+ }
+ if(CanBeSeenByPlayer() || Enemy->CanBeSeenByPlayer())bShowHitEffect=true; //throwing hits in the air is valid (seen) if the other one is invisible
+ if(IsPlayer())bShowHitEffect=true; //override
+ if(bShowHitEffect){DBGLN;
+ pHitEff=new hiteffectSetup();
+ pHitEff->Critical=Critical;
+ pHitEff->GivenDir=GivenDir;
+ pHitEff->Type=Type;
+ pHitEff->WhoHits=Enemy; DBGLN;DBG2(Enemy,"WhoHits"); DBGSV2(Enemy->GetPos()); DBG1(Enemy->GetName(DEFINITE).CStr());
+ pHitEff->WhoIsHit=this;
+ pHitEff->itemEffectReference = Weapon;
+ if(pHitEff->itemEffectReference==NULL)pHitEff->itemEffectReference=EnemyBodyPart;
+ }
+
int Dir = Type == BITE_ATTACK ? YOURSELF : GivenDir;
double DodgeValue = GetDodgeValue();
@@ -619,6 +765,7 @@ int character::TakeHit(character* Enemy, item* Weapon,
else
DeActivateVoluntaryAction(CONST_S("The attack interrupts you."));
+// if(hitEff!=NULL)hitEff->End();
return HAS_DODGED;
}
@@ -702,6 +849,7 @@ int character::TakeHit(character* Enemy, item* Weapon,
else
DeActivateVoluntaryAction(CONST_S("The attack interrupts you."));
+// if(hitEff!=NULL)hitEff->End();
return HAS_BLOCKED;
}
}
@@ -714,7 +862,7 @@ int character::TakeHit(character* Enemy, item* Weapon,
&& Enemy->BiteCapturesBodyPart());
truth Succeeded = (GetBodyPart(BodyPart)
&& HitEffect(Enemy, Weapon, HitPos, Type,
- BodyPart, Dir, !DoneDamage))
+ BodyPart, Dir, !DoneDamage, Critical, DoneDamage))
|| DoneDamage;
if(Succeeded)
@@ -722,6 +870,9 @@ int character::TakeHit(character* Enemy, item* Weapon,
if(Weapon)
{
+// if(CanBeSeenByPlayer())
+// GetLSquareUnder()->AddHitEffect(Weapon,this,Enemy);
+
if(Weapon->Exists() && DoneDamage < TrueDamage)
Weapon->ReceiveDamage(Enemy, TrueDamage - DoneDamage, PHYSICAL_DAMAGE);
@@ -744,9 +895,15 @@ int character::TakeHit(character* Enemy, item* Weapon,
else
DeActivateVoluntaryAction(CONST_S("The attack interrupts you."));
+// if(hitEff!=NULL)hitEff->End();
return DID_NO_DAMAGE;
}
+ if(pHitEff!=NULL){DBGLN;
+ GetLSquareUnder()->AddHitEffect(*pHitEff); //after all returns of failure and before any other returns
+ delete pHitEff; //already copied
+ }
+
if(CheckDeath(GetNormalDeathMessage(), Enemy,
Enemy->IsPlayer() ? FORCE_MSG : 0))
return HAS_DIED;
@@ -875,14 +1032,12 @@ void character::Be()
}
}
audio::IntensityLevel( audio::MAX_INTENSITY_VOLUME - MinHPPercent );
-
-
}
if(Stamina != MaxStamina)
RegenerateStamina();
- if(HP != MaxHP)
+ if(HP != MaxHP || StateIsActivated(REGENERATION))
Regenerate();
if(Action && AP >= 1000)
@@ -924,7 +1079,9 @@ void character::Be()
Search(GetAttribute(PERCEPTION));
if(!Action)
+ {
GetPlayerCommand();
+ }
else
{
if(Action->ShowEnvironment())
@@ -940,8 +1097,11 @@ void character::Be()
msgsystem::ThyMessagesAreNowOld();
- if(Action->IsVoluntary() && READ_KEY())
+ if(Action->IsVoluntary() && WAIT_FOR_KEY_DOWN())
+ {
+ READ_KEY();
Action->Terminate(false);
+ }
}
}
else
@@ -1192,7 +1352,7 @@ int character::CalculateNewSquaresUnder(lsquare** NewSquare, v2 Pos) const
return 0;
}
-truth character::TryMove(v2 MoveVector, truth Important, truth Run)
+truth character::TryMove(v2 MoveVector, truth Important, truth Run, truth* pbWaitNeutralMove)
{
lsquare* MoveToSquare[MAX_SQUARES_UNDER];
character* Pet[MAX_SQUARES_UNDER];
@@ -1251,22 +1411,27 @@ truth character::TryMove(v2 MoveVector, truth Important, truth Run)
return Hit(Hostile[Index], HostilePos[Index], Direction);
}
- if(Neutrals == 1)
- {
- if(!IsPlayer() && !Pets && Important && CanMoveOn(MoveToSquare[0]))
- return HandleCharacterBlockingTheWay(Neutral[0], NeutralPos[0], Direction);
- else
- return IsPlayer() && Hit(Neutral[0], NeutralPos[0], Direction);
- }
- else if(Neutrals)
- {
- if(IsPlayer())
+ if(Neutrals>0 && ivanconfig::IsWaitNeutralsMoveAway() && pbWaitNeutralMove!=NULL){
+ (*pbWaitNeutralMove)=true;
+ return false;
+ }else{
+ if(Neutrals == 1)
{
- int Index = RAND() % Neutrals;
- return Hit(Neutral[Index], NeutralPos[Index], Direction);
+ if(!IsPlayer() && !Pets && Important && CanMoveOn(MoveToSquare[0]))
+ return HandleCharacterBlockingTheWay(Neutral[0], NeutralPos[0], Direction);
+ else
+ return IsPlayer() && Hit(Neutral[0], NeutralPos[0], Direction);
+ }
+ else if(Neutrals)
+ {
+ if(IsPlayer())
+ {
+ int Index = RAND() % Neutrals;
+ return Hit(Neutral[Index], NeutralPos[Index], Direction);
+ }
+ else
+ return false;
}
- else
- return false;
}
if(!IsPlayer())
@@ -1315,9 +1480,10 @@ truth character::TryMove(v2 MoveVector, truth Important, truth Run)
{
/* not sure if this is better than "the door is locked", but I guess it _might_ be slightly better */
ADD_MESSAGE("The %s is locked.", Terrain->GetNameSingular().CStr());
- return false;
+ if(!IsPlayerAutoPlay())return false;
}
- else if(Important && CheckKick())
+
+ if(Important && CheckKick())
{
room* Room = MoveToSquare[c]->GetRoom();
@@ -1446,6 +1612,32 @@ void character::CreateCorpse(lsquare* Square)
SendToHell();
}
+void character::AutoPlayAITeleport(bool bDeathCountBased)
+{
+ bool bTeleportNow=false;
+
+ if(bDeathCountBased){ // this is good to prevent autoplay AI getting stuck endless dieing
+ static int iDieMax=10;
+ static int iDieTeleportCountDown=iDieMax;
+ if(iDieTeleportCountDown==0){ //this helps on defeating not so strong enemies in spot
+ if(IsPlayerAutoPlay())
+ bTeleportNow=true;
+ iDieTeleportCountDown=iDieMax;
+ }else{
+ static v2 v2DiePos(0,0);
+ if(v2DiePos==GetPos()){
+ iDieTeleportCountDown--;
+ }else{
+ v2DiePos=GetPos();
+ iDieTeleportCountDown=iDieMax;
+ }
+ }
+ }
+
+ if(bTeleportNow)
+ Move(GetLevel()->GetRandomSquare(this), true); //not using teleport function to avoid prompts, but this code is from there TODO and should be in sync! create TeleportRandomDirectly() ?
+}
+
void character::Die(ccharacter* Killer, cfestring& Msg, ulong DeathFlags)
{
/* Note: This function musn't delete any objects, since one of these may be
@@ -1464,7 +1656,10 @@ void character::Die(ccharacter* Killer, cfestring& Msg, ulong DeathFlags)
{
game::DrawEverything();
- if(!game::TruthQuestion(CONST_S("Do you want to do this, cheater? [y/n]"), REQUIRES_ANSWER))
+ bool bInstaResurrect=false;
+ if(!bInstaResurrect && IsPlayerAutoPlay())bInstaResurrect=true;
+ if(!bInstaResurrect && !game::TruthQuestion(CONST_S("Do you want to do this, cheater? [y/n]"), REQUIRES_ANSWER))bInstaResurrect=true;
+ if(bInstaResurrect)
{
RestoreBodyParts();
ResetSpoiling();
@@ -1479,6 +1674,7 @@ void character::Die(ccharacter* Killer, cfestring& Msg, ulong DeathFlags)
ResetStates();
SetNP(SATIATED_LEVEL);
SendNewDrawRequest();
+ if(IsPlayerAutoPlay())AutoPlayAITeleport(true);
return;
}
}
@@ -1579,6 +1775,7 @@ void character::Die(ccharacter* Killer, cfestring& Msg, ulong DeathFlags)
for(int c = 0; c < GetSquaresUnder(); ++c)
LSquareUnder[c]->SetTemporaryEmitation(GetEmitation());
+ game::SRegionAroundDisable();
game::PlayDefeatMusic();
ShowAdventureInfo();
@@ -1984,6 +2181,9 @@ void character::Save(outputfile& SaveFile) const
SaveFile << CWeaponSkill[c];
SaveFile << static_cast(GetConfig());
+
+ for(c = 0; c < MAX_EQUIPMENT_SLOTS; c++)
+ SaveFile << MemorizedEquippedItemIDs[c];
}
void character::Load(inputfile& SaveFile)
@@ -2042,6 +2242,13 @@ void character::Load(inputfile& SaveFile)
databasecreator::InstallDataBase(this, ReadType(SaveFile));
+ if(game::GetCurrentSavefileVersion()>=132){
+ for(c = 0; c < MAX_EQUIPMENT_SLOTS; c++)
+ SaveFile >> MemorizedEquippedItemIDs[c];
+ }
+
+ /////////////// loading ended /////////////////////////
+
if(IsEnabled() && !game::IsInWilderness())
for(c = 1; c < GetSquaresUnder(); ++c)
GetSquareUnder(c)->SetCharacter(this);
@@ -2113,7 +2320,7 @@ void character::AddScoreEntry(cfestring& Description, double Multiplier, truth A
{
if(!game::WizardModeIsReallyActive())
{
- highscore HScore;
+ highscore HScore(game::GetStateDir() + HIGH_SCORE_FILENAME);
if(!HScore.CheckVersion())
{
@@ -2229,7 +2436,7 @@ truth character::CheckDeath(cfestring& Msg, ccharacter* Murderer, ulong DeathFla
truth character::CheckStarvationDeath(cfestring& Msg)
{
- if(GetNP() < 1 && UsesNutrition())
+ if(GetNP() < 1 && UsesNutrition() && !(StateIsActivated(FASTING)))
return CheckDeath(Msg, 0, FORCE_DEATH);
else
return false;
@@ -2240,7 +2447,8 @@ void character::ThrowItem(int Direction, item* ToBeThrown)
if(Direction > 7)
ABORT("Throw in TOO odd direction...");
- ToBeThrown->Fly(this, Direction, GetAttribute(ARM_STRENGTH));
+ ToBeThrown->Fly(this, Direction, GetAttribute(ARM_STRENGTH),
+ ToBeThrown->IsWeapon(this) && !ToBeThrown->IsBroken());
}
void character::HasBeenHitByItem(character* Thrower, item* Thingy, int Damage, double ToHitValue, int Direction)
@@ -2254,7 +2462,7 @@ void character::HasBeenHitByItem(character* Thrower, item* Thingy, int Damage, d
int WeaponSkillHits = Thrower ? CalculateWeaponSkillHits(Thrower) : 0;
int DoneDamage = ReceiveBodyPartDamage(Thrower, Damage, PHYSICAL_DAMAGE, BodyPart, Direction);
truth Succeeded = (GetBodyPart(BodyPart) && HitEffect(Thrower, Thingy, Thingy->GetPos(), THROW_ATTACK,
- BodyPart, Direction, !DoneDamage)) || DoneDamage;
+ BodyPart, Direction, !DoneDamage, false, DoneDamage)) || DoneDamage;
if(Succeeded && Thrower)
Thrower->WeaponSkillHit(Thingy, THROW_ATTACK, WeaponSkillHits);
@@ -2280,15 +2488,782 @@ truth character::DodgesFlyingItem(item* Item, double ToHitValue)
return !Item->EffectIsGood() && RAND() % int(100 + ToHitValue / DodgeValue * 100) < 100;
}
+character* AutoPlayLastChar=NULL;
+const int iMaxWanderTurns=20;
+const int iMinWanderTurns=3;
+
+/**
+ * 5 seems good, broken cheap weapons, stones, very cheap weapons non broken etc
+ * btw, lantern price is currently 10.
+ */
+static int iMaxValueless = 5;
+
+v2 v2KeepGoingTo=v2(0,0);
+v2 v2TravelingToAnotherDungeon=v2(0,0);
+int iWanderTurns=iMinWanderTurns;
+bool bAutoPlayUseRandomNavTargetOnce=false;
+std::vector vv2DebugDrawSqrPrevious;
+v2 v2LastDropPlayerWasAt=v2(0,0);
+std::vector vv2FailTravelToTargets;
+std::vector vv2WrongGoingTo;
+
+void character::AutoPlayAIReset(bool bFailedToo)
+{ DBG7(bFailedToo,iWanderTurns,DBGAV2(v2KeepGoingTo),DBGAV2(v2TravelingToAnotherDungeon),DBGAV2(v2LastDropPlayerWasAt),vv2FailTravelToTargets.size(),vv2DebugDrawSqrPrevious.size());
+ v2KeepGoingTo=v2(0,0); //will retry
+ v2TravelingToAnotherDungeon=v2(0,0);
+ iWanderTurns=0; // warning: this other code was messing the logic ---> if(iWanderTurnsTerminateGoingTo();
+
+ if(bFailedToo){
+ vv2FailTravelToTargets.clear();
+ vv2WrongGoingTo.clear();
+ }
+}
+truth character::AutoPlayAISetAndValidateKeepGoingTo(v2 v2KGTo)
+{
+ v2KeepGoingTo=v2KGTo;
+ SetGoingTo(v2KeepGoingTo); DBG3(DBGAV2(GetPos()),DBGAV2(GoingTo),DBGAV2(v2KeepGoingTo));
+ CreateRoute();
+ if(!Route.empty())
+ return true;
+
+ DBG1("RouteCreationFailed");
+ TerminateGoingTo(); //redundant?
+ vv2FailTravelToTargets.push_back(v2KeepGoingTo); DBG3("BlockGoToDestination",DBGAV2(v2KeepGoingTo),vv2FailTravelToTargets.size());
+ bAutoPlayUseRandomNavTargetOnce=true;
+
+ AutoPlayAIReset(false);
+
+ return false;
+}
+
+void character::AutoPlayAIDebugDrawSquareRect(v2 v2SqrPos, col16 color, int iPrintIndex, bool bWide, bool bKeepColor)
+{
+ static v2 v2ScrPos=v2(0,0); //static to avoid instancing
+ static int iAddPos;iAddPos=bWide?2:1;
+ static int iSubBorder;iSubBorder=bWide?3:2;
+ if(game::OnScreen(v2SqrPos)){
+ v2ScrPos=game::CalculateScreenCoordinates(v2SqrPos);
+
+ DOUBLE_BUFFER->DrawRectangle(
+ v2ScrPos.X+iAddPos, v2ScrPos.Y+iAddPos,
+ v2ScrPos.X+TILE_SIZE-iSubBorder, v2ScrPos.Y+TILE_SIZE-iSubBorder,
+ color, bWide);
+
+ if(iPrintIndex>-1)
+ FONT->Printf(DOUBLE_BUFFER, v2(v2ScrPos.X+1,v2ScrPos.Y+5), DARK_GRAY, "%d", iPrintIndex);
+
+ if(!bKeepColor)
+ vv2DebugDrawSqrPrevious.push_back(v2SqrPos);
+ }
+}
+
+const int iVisitAgainMax=10;
+int iVisitAgainCount=iVisitAgainMax;
+std::vector vv2AllDungeonSquares;
+bool character::AutoPlayAICheckAreaLevelChangedAndReset()
+{
+ static area* areaPrevious=NULL;
+ area* Area = game::GetCurrentArea();
+ if(Area != areaPrevious){
+ areaPrevious=Area;
+
+ iVisitAgainCount=iVisitAgainMax;
+
+ vv2DebugDrawSqrPrevious.clear();
+
+ vv2AllDungeonSquares.clear();
+ if(!game::IsInWilderness())
+ for(int iY=0;iYGetYSize();iY++){ for(int iX=0;iXGetXSize();iX++){
+ vv2AllDungeonSquares.push_back(game::GetCurrentLevel()->GetLSquare(iX, iY));
+ }}
+
+ return true;
+ }
+
+ return false;
+}
+
+void character::AutoPlayAIDebugDrawOverlay()
+{
+ if(!game::WizardModeIsActive())return;
+
+ AutoPlayAICheckAreaLevelChangedAndReset();
+
+ // redraw previous to clean them
+ area* Area = game::GetCurrentArea(); //got the Area to draw in the wilderness too and TODO navigate there one day
+ std::vector vv2DebugDrawSqrPreviousCopy(vv2DebugDrawSqrPrevious);
+ for(int i=0;iGetSquare(vv2DebugDrawSqrPrevious[i])->SendNewDrawRequest();
+// square* sqr = Area->GetSquare(vv2DebugDrawSqrPrevious[i]);
+// if(sqr)sqr->SendStrongNewDrawRequest(); //TODO sqr NULL?
+ AutoPlayAIDebugDrawSquareRect(vv2DebugDrawSqrPreviousCopy[i],DARK_GRAY);
+ }
+
+ // draw new ones
+ vv2DebugDrawSqrPrevious.clear(); //empty before fillup below
+
+ for(int i=0;iRoute.empty())
+ for(int i=0;iRoute.size();i++)
+ AutoPlayAIDebugDrawSquareRect(PLAYER->Route[i],GREEN);
+
+ if(!v2KeepGoingTo.Is0())
+ AutoPlayAIDebugDrawSquareRect(v2KeepGoingTo,BLUE,PLAYER->Route.size(),true);
+ else if(iWanderTurns>0)
+ AutoPlayAIDebugDrawSquareRect(PLAYER->GetPos(),YELLOW,iWanderTurns);
+
+ for(int i=0;iIsBroken()){ DBG2("chkDropBroken",eqDropChk);
+ eqBroken=eqDropChk;
+ bDropSomething=true;
+ break;
+ }
+ }
+
+ if(!bDropSomething && GetBurdenState() == STRESSED){
+ if(clock()%100<5){ //5% chance to drop something weighty randomly every turn
+ bDropSomething=true; DBGLN;
+ }
+ }
+
+ if(!bDropSomething && GetBurdenState() == OVER_LOADED){
+ bDropSomething=true;
+ }
+
+ if(bDropSomething){ DBG1("DropSomething");
+ item* dropMe=NULL;
+ if(eqBroken!=NULL)dropMe=eqBroken;
+
+ item* heaviest=NULL;
+ item* cheapest=NULL;
+
+// bool bFound=false;
+// for(int k=0;k<2;k++){
+// if(dropMe!=NULL)break;
+// static item* eqDropChk=NULL;
+// for(int i=0;iIsBroken()){
+// dropMe=eqDropChk;
+// break;
+// }
+// }
+
+ if(dropMe==NULL){
+ static itemvector vit;vit.clear();GetStack()->FillItemVector(vit);
+ for(int i=0;iGetName(DEFINITE).CStr(),vit[i]->GetTruePrice(),vit[i]->GetWeight());
+ if(vit[i]->IsEncryptedScroll())continue;
+// if(!bPlayerHasLantern && dynamic_cast(vit[i])!=NULL){
+// bPlayerHasLantern=true; //will keep only the 1st lantern
+// continue;
+// }
+
+ if(vit[i]->IsBroken()){ //TODO use repair scroll?
+ dropMe=vit[i];
+ break;
+ }
+
+ if(heaviest==NULL)heaviest=vit[i];
+ if(cheapest==NULL)cheapest=vit[i];
+
+// switch(k){
+// case 0: //better not implement this as a user function as that will remove the doubt about items values what is another fun challenge :)
+ if(vit[i]->GetTruePrice() < cheapest->GetTruePrice()) //cheapest
+ cheapest=vit[i];
+// break;
+// case 1: //this could be added as user function to avoid browsing the drop list, but may not be that good...
+ if(vit[i]->GetWeight() > heaviest->GetWeight()) //heaviest
+ heaviest=vit[i];
+// break;
+// }
+ }
+ }
+
+ if(heaviest!=NULL && cheapest!=NULL){
+ if(dropMe==NULL && heaviest==cheapest)
+ dropMe=heaviest;
+
+ if(dropMe==NULL && cheapest->GetTruePrice()<=iMaxValueless){ DBG2("DropValueless",cheapest->GetName(DEFINITE).CStr());
+ dropMe=cheapest;
+ }
+
+ if(dropMe==NULL){
+ // the worst price VS weight will be dropped
+ float fC = cheapest ->GetTruePrice()/(float)cheapest ->GetWeight();
+ float fW = heaviest->GetTruePrice()/(float)heaviest->GetWeight(); DBG3("PriceVsWeightRatio",fC,fW);
+ if(fC < fW){
+ dropMe = cheapest;
+ }else{
+ dropMe = heaviest;
+ }
+ }
+
+ if(dropMe==NULL)
+ dropMe = clock()%2==0 ? heaviest : cheapest;
+ }
+
+ // chose a throw direction
+ if(dropMe!=NULL){
+ static std::vector vv2DirBase;static bool bDummyInit = [](){for(int i=0;i<8;i++)vv2DirBase.push_back(i);return true;}();
+ std::vector vv2Dir(vv2DirBase);
+ int iDirOk=-1;
+ v2 v2DropAt(0,0);
+ lsquare* lsqrDropAt=NULL;
+ for(int i=0;i<8;i++){
+ int k = clock()%vv2Dir.size(); //random chose from remaining TODO could be where there is NPC foe
+ int iDir = vv2Dir[k]; //collect direction value
+ vv2Dir.erase(vv2Dir.begin() + k); //remove using the chosen index to prepare next random choice
+
+ v2 v2Dir = game::GetMoveVector(iDir);
+ v2 v2Chk = GetPos() + v2Dir;
+ if(game::GetCurrentLevel()->IsValidPos(v2Chk)){
+ lsquare* lsqrChk=game::GetCurrentLevel()->GetLSquare(v2Chk);
+ if(lsqrChk->IsFlyable()){
+ iDirOk = iDir;
+ v2DropAt = v2Chk;
+ lsqrDropAt=lsqrChk;
+ break;
+ }
+ }
+ };DBGLN;
+
+ if(iDirOk==-1){iDirOk=clock()%8;DBG2("RandomDir",iDirOk);}DBGLN; //TODO should just drop may be? unless hitting w/e is there could help
+
+ if(iDirOk>-1){DBG2("KickOrThrow",iDirOk);
+ static itemcontainer* itc;itc = dynamic_cast(dropMe);DBGLN;
+ static humanoid* h;h = dynamic_cast(this);DBGLN;
+ DBG8("CanKickLockedChest",lsqrDropAt,itc,itc?itc->IsLocked():-1,CanKick(),h,h?h->GetLeftLeg():0,h?h->GetRightLeg():0);
+ if(lsqrDropAt && itc && itc->IsLocked() && CanKick() && h && h->GetLeftLeg() && h->GetRightLeg()){DBGLN;
+ dropMe->MoveTo(lsqrDropAt->GetStack());DBGLN; //drop in front..
+ Kick(lsqrDropAt,iDirOk,true);DBGLN; // ..to kick it
+ }else{DBGLN;
+ ThrowItem(iDirOk, dropMe); DBG5("DropThrow",iDirOk,dropMe->GetName(DEFINITE).CStr(),dropMe->GetTruePrice(),dropMe->GetWeight());
+ }
+ }else{DBGLN;
+ dropMe->MoveTo(GetLSquareUnder()->GetStack());DBGLN; //just drop
+ }
+
+ v2LastDropPlayerWasAt=GetPos();DBGSV2(v2LastDropPlayerWasAt);
+
+ return true;
+ }
+
+ DBG1("AutoPlayNeedsImprovement:DropItem");
+ ADD_MESSAGE("%s says \"I need more intelligence to drop trash...\"", CHAR_NAME(DEFINITE)); // improve the dropping AI
+ //TODO stop autoplay mode? if not, something random may happen some time and wont reach here ex.: spoil, fire, etc..
+ }
+
+ return false;
+}
+
+truth character::AutoPlayAIEquipAndPickup(bool bPlayerHasLantern)
+{
+ static humanoid* h;h = dynamic_cast(this);
+ if(h==NULL)return false;
+
+ if(h->AutoPlayAIequip())
+ return true;
+
+ if(GetBurdenState()!=OVER_LOADED){ //DBG2("",CommandFlags&DONT_CHANGE_EQUIPMENT);
+ if(v2LastDropPlayerWasAt!=GetPos()){
+ static bool bHoarder=true; //TODO wizard autoplay AI config exclusive felist
+
+ if(CheckForUsefulItemsOnGround(false))
+ if(!bHoarder)
+ return true;
+
+ //just pick up any useful stuff
+ static itemvector vit;vit.clear();GetStackUnder()->FillItemVector(vit);
+ for(uint c = 0; c < vit.size(); ++c){
+ if(!vit[c]->CanBeSeenBy(this))continue;
+ if(!vit[c]->IsPickable(this))continue;
+ if(vit[c]->GetSquaresUnder()!=1)continue; //avoid big corpses 2x2
+
+ if(!bPlayerHasLantern && vit[c]->IsOnFire(this)){
+ //ok
+ }else{
+ if(vit[c]->IsBroken())continue;
+ if(vit[c]->GetTruePrice()<=iMaxValueless)continue; //mainly to avoid all rocks from broken walls
+ if(vit[c]->GetSpoilLevel()>0)continue;
+ }
+
+ static itemcontainer* itc;itc = dynamic_cast(vit[c]);
+ if(itc && !itc->IsLocked()){
+ static itemvector vitItc;vitItc.clear();itc->GetContained()->FillItemVector(vitItc);
+ for(uint d = 0; d < vitItc.size(); ++d)
+ vitItc[d]->MoveTo(itc->GetLSquareUnder()->GetStack());
+ continue;
+ }
+
+ vit[c]->MoveTo(GetStack()); DBG2("pickup",vit[c]->GetNameSingular().CStr());
+// if(GetBurdenState()==OVER_LOADED)ThrowItem(clock()%8,ItemVector[c]);
+// return true;
+ if(!bHoarder)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static const int iMoreThanMaxDist=10000000; //TODO should be max integer but this will do for now in 2018 :)
+truth character::AutoPlayAITestValidPathTo(v2 v2To)
+{
+ return AutoPlayAIFindWalkDist(v2To) < iMoreThanMaxDist;
+}
+
+int character::AutoPlayAIFindWalkDist(v2 v2To)
+{
+ static bool bUseSimpleDirectDist=false; //very bad navigation this is
+ if(bUseSimpleDirectDist)return (v2To - GetPos()).GetLengthSquare();
+
+ static v2 GoingToBkp;GoingToBkp = GoingTo; //IsGoingSomeWhere() ? GoingTo : v2(0,0);
+
+ SetGoingTo(v2To);
+ CreateRoute();
+ static int iDist;iDist=Route.size();
+ TerminateGoingTo();
+
+ if(GoingToBkp!=ERROR_V2){ DBG2("Warning:WrongUsage:ShouldBeGoingNoWhere",DBGAV2(GoingToBkp));
+ SetGoingTo(GoingToBkp);
+ CreateRoute();
+ }
+
+ return iDist>0?iDist:iMoreThanMaxDist;
+}
+
+truth character::AutoPlayAINavigateDungeon(bool bPlayerHasLantern)
+{
+ /**
+ * navigate the unknown dungeon
+ */
+ std::vector v2Exits;
+ if(v2KeepGoingTo.Is0()){ DBG1("TryNewMoveTarget");
+ // target undiscovered squares to explore
+ v2 v2PreferedTarget(0,0);
+
+ int iNearestLanterOnFloorDist = iMoreThanMaxDist;
+ v2 v2PreferedLanternOnFloorTarget(0,0);
+
+ v2 v2NearestUndiscovered(0,0);
+ int iNearestUndiscoveredDist=iMoreThanMaxDist;
+ std::vector vv2UndiscoveredValidPathSquares;
+
+ lsquare* lsqrNearestSquareWithWallLantern=NULL;
+ lsquare* lsqrNearestDropWallLanternAt=NULL;
+ stack* stkNearestDropWallLanternAt = NULL;
+ int iNearestSquareWithWallLanternDist=iMoreThanMaxDist;
+ item* itNearestWallLantern=NULL;
+
+ /***************************************************************
+ * scan whole dungeon squares
+ */
+ for(int iY=0;iYGetYSize();iY++){ for(int iX=0;iXGetXSize();iX++){
+ lsquare* lsqr = game::GetCurrentLevel()->GetLSquare(iX,iY);
+
+ olterrain* olt = lsqr->GetOLTerrain();
+ if(olt && (olt->GetConfig() == STAIRS_UP || olt->GetConfig() == STAIRS_DOWN)){
+ v2Exits.push_back(v2(lsqr->GetPos())); DBGSV2(v2Exits[v2Exits.size()-1]);
+ }
+
+ stack* stkSqr = lsqr->GetStack();
+ static itemvector vit;vit.clear();stkSqr->FillItemVector(vit);
+ bool bAddValidTargetSquare=true;
+
+ // find nearest wall lantern
+ if(!bPlayerHasLantern && !CanMoveOn(lsqr)){ //probably a wall
+ for(int n=0;nIsLanternOnWall() && !vit[n]->IsBroken()){
+ static stack* stkDropWallLanternAt;stkDropWallLanternAt = lsqr->GetStackOfAdjacentSquare(vit[n]->GetSquarePosition());
+ static lsquare* lsqrDropWallLanternAt;lsqrDropWallLanternAt =
+ stkDropWallLanternAt?stkDropWallLanternAt->GetLSquareUnder():NULL;
+
+ if(stkDropWallLanternAt && lsqrDropWallLanternAt && CanMoveOn(lsqrDropWallLanternAt)){
+ int iDist = AutoPlayAIFindWalkDist(lsqrDropWallLanternAt->GetPos()); //(lsqr->GetPos() - GetPos()).GetLengthSquare();
+ if(lsqrNearestSquareWithWallLantern==NULL || iDistGetPos()),DBGAV2(GetPos()));
+ lsqrNearestDropWallLanternAt=lsqrDropWallLanternAt;
+ stkNearestDropWallLanternAt=stkDropWallLanternAt;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ if(bAddValidTargetSquare && !CanMoveOn(lsqr))
+ bAddValidTargetSquare=false;
+
+ bool bIsFailToTravelSquare=false;
+ if(bAddValidTargetSquare){
+ for(int j=0;jGetPos()){
+ bAddValidTargetSquare=false;
+ bIsFailToTravelSquare=true;
+ break;
+ }
+ }
+
+ if(!bIsFailToTravelSquare){
+
+// if(bAddValidTargetSquare && v2PreferedTarget.Is0() && (lsqr->HasBeenSeen() || !bPlayerHasLantern)){
+ if(bAddValidTargetSquare && (lsqr->HasBeenSeen() || !bPlayerHasLantern)){
+ bool bVisitAgain=false;
+ if(iVisitAgainCount>0 || !bPlayerHasLantern){
+ if(stkSqr!=NULL && stkSqr->GetItems()>0){
+ for(int n=0;nGetID());DBG1(vit[n]->GetType());DBG3("VisitAgain:ChkItem",vit[n]->GetNameSingular().CStr(),vit.size());
+ if(vit[n]->IsBroken())continue; DBGLN;
+
+ static bool bIsLanternOnFloor;bIsLanternOnFloor = dynamic_cast(vit[n])!=NULL;// || vit[n]->IsOnFire(this); DBGLN;
+
+ if( // if is useful to the AutoPlay AI endless tests
+ vit[n]->IsShield (this) ||
+ vit[n]->IsWeapon (this) ||
+ vit[n]->IsArmor (this) ||
+ vit[n]->IsAmulet (this) ||
+ vit[n]->IsZappable(this) ||
+ vit[n]->IsRing (this) ||
+ bIsLanternOnFloor
+ ){
+ bVisitAgain=true;
+
+ if(bIsLanternOnFloor && !bPlayerHasLantern){
+ static int iDist;iDist = AutoPlayAIFindWalkDist(lsqr->GetPos()); //(lsqr->GetPos() - GetPos()).GetLengthSquare();
+ if(iDistGetPos(); DBG2("PreferLanternAt",DBGAV2(lsqr->GetPos()))
+ }
+ }else{
+ iVisitAgainCount--;
+ }
+
+ DBG4(bVisitAgain,DBGAV2(lsqr->GetPos()),iVisitAgainCount,bIsLanternOnFloor);
+ break;
+ }
+ }
+ }
+ }
+
+ if(!bVisitAgain)bAddValidTargetSquare=false;
+ }
+
+ }
+
+ if(bAddValidTargetSquare){ DBG2("addValidSqr",DBGAV2(lsqr->GetPos()));
+ static int iDist;iDist=AutoPlayAIFindWalkDist(lsqr->GetPos()); //(lsqr->GetPos() - GetPos()).GetLengthSquare();
+
+ if(iDistGetPos());
+
+ if(iDistGetPos(); DBG3(iNearestUndiscoveredDist,DBGAV2(lsqr->GetPos()),DBGAV2(GetPos()));
+ }
+ }
+ }} DBG2(DBGAV2(v2PreferedTarget),vv2UndiscoveredValidPathSquares.size());
+
+ /***************************************************************
+ * define prefered navigation target
+ */
+ if(!bPlayerHasLantern && v2PreferedTarget.Is0()){
+ bool bUseWallLantern=false;
+ if(!v2PreferedLanternOnFloorTarget.Is0() && lsqrNearestSquareWithWallLantern!=NULL){
+ if(iNearestLanterOnFloorDist <= iNearestSquareWithWallLanternDist){
+ v2PreferedTarget=v2PreferedLanternOnFloorTarget;
+ }else{
+ bUseWallLantern=true;
+ }
+ }else if(!v2PreferedLanternOnFloorTarget.Is0()){
+ v2PreferedTarget=v2PreferedLanternOnFloorTarget;
+ }else if(lsqrNearestSquareWithWallLantern!=NULL){
+ bUseWallLantern=true;
+ }
+
+ if(bUseWallLantern){
+ /**
+ * target to nearest wall lantern
+ * check for lanterns on walls of adjacent squares if none found on floors
+ */
+ itNearestWallLantern->MoveTo(stkNearestDropWallLanternAt); // the AI is prepared to get things from the floor only so "magically" drop it :)
+ v2PreferedTarget = lsqrNearestDropWallLanternAt->GetPos(); DBG2("PreferWallLanternAt",DBGAV2(lsqrNearestDropWallLanternAt->GetPos()))
+ }
+
+ }
+
+ /***************************************************************
+ * validate and set new navigation target
+ */
+// DBG9("AllNavigatePossibilities",DBGAV2(v2PreferedTarget),DBGAV2(v2PreferedLanternOnFloorTarget),DBGAV2(),DBGAV2(),DBGAV2(),DBGAV2(),DBGAV2(),DBGAV2(),DBGAV2(),DBGAV2());
+ v2 v2NewKGTo=v2(0,0);
+
+ if(v2NewKGTo.Is0()){
+ //TODO if(!v2PreferedTarget.Is0){ // how can this not be compiled? error: cannot convert ‘v2::Is0’ from type ‘truth (v2::)() const {aka bool (v2::)() const}’ to type ‘bool’
+ if(v2PreferedTarget.GetLengthSquare()>0)
+ if(AutoPlayAITestValidPathTo(v2PreferedTarget))
+ v2NewKGTo=v2PreferedTarget; DBGSV2(v2PreferedTarget);
+ }
+
+ if(v2NewKGTo.Is0()){
+ if(bAutoPlayUseRandomNavTargetOnce){ //these targets were already path validated and are safe to use!
+ v2NewKGTo=vv2UndiscoveredValidPathSquares[clock()%vv2UndiscoveredValidPathSquares.size()]; DBG2("RandomTarget",DBGAV2(v2NewKGTo));
+ bAutoPlayUseRandomNavTargetOnce=false;
+ }else{ //find nearest
+ if(!v2NearestUndiscovered.Is0()){
+ v2NewKGTo=v2NearestUndiscovered; DBGSV2(v2NearestUndiscovered);
+ }
+ }
+ }
+
+ if(v2NewKGTo.Is0()){ //no new destination: fully explored
+ if(v2Exits.size()>0){
+ if(game::GetCurrentDungeonTurnsCount()==0){ DBG1("Dungeon:FullyExplored:FirstTurn");
+ iWanderTurns=100+clock()%300; DBG2("WanderALotOnFullyExploredLevel",iWanderTurns); //just move around a lot, some NPC may spawn
+ }else{
+ // travel between dungeons if current fully explored
+ v2 v2Try = v2Exits[clock()%v2Exits.size()];
+ if(AutoPlayAITestValidPathTo(v2Try))
+ v2NewKGTo = v2TravelingToAnotherDungeon = v2Try; DBGSV2(v2TravelingToAnotherDungeon);
+ }
+ }else{
+ DBG1("AutoPlayNeedsImprovement:Navigation")
+ ADD_MESSAGE("%s says \"I need more intelligence to move around...\"", CHAR_NAME(DEFINITE)); // improve the dropping AI
+ //TODO stop autoplay mode?
+ }
+ }
+
+ if(v2NewKGTo.Is0()){ DBG1("Desperately:TryAnyRandomTargetNavWithValidPath");
+ std::vector vlsqrChk(vv2AllDungeonSquares);
+
+ while(vlsqrChk.size()>0){
+ static int i;i=clock()%vlsqrChk.size();
+ static v2 v2Chk; v2Chk = vlsqrChk[i]->GetPos();
+
+ if(!AutoPlayAITestValidPathTo(v2Chk)){
+ vlsqrChk.erase(vlsqrChk.begin()+i);
+ }else{
+ v2NewKGTo=v2Chk;
+ break;
+ }
+ }
+ }
+
+ if(!v2NewKGTo.Is0()){
+ AutoPlayAISetAndValidateKeepGoingTo(v2NewKGTo);
+ }
+
+ DBG1("TODO:too complex paths are failing... improve create path method?");
+ }
+
+ if(!v2KeepGoingTo.Is0()){
+ if(v2KeepGoingTo==GetPos()){ DBG3("ReachedDestination",DBGAV2(v2KeepGoingTo),DBGAV2(GoingTo));
+ //wander a bit before following new target destination
+ iWanderTurns=(clock()%iMaxWanderTurns)+iMinWanderTurns; DBG2("WanderAroundAtReachedDestination",iWanderTurns);
+
+// v2KeepGoingTo=v2(0,0);
+// TerminateGoingTo();
+ AutoPlayAIReset(false);
+ return true;
+ }
+
+// CheckForUsefulItemsOnGround(false); DBGSV2(GoingTo);
+// CheckForEnemies(false, true, false, false); DBGSV2(GoingTo);
+
+// if(!IsGoingSomeWhere() || v2KeepGoingTo!=GoingTo){ DBG3("ForceKeepGoingTo",DBGAV2(v2KeepGoingTo),DBGAV2(GoingTo));
+// SetGoingTo(v2KeepGoingTo);
+// }
+ static int iForceGoingToCountDown=10;
+ static v2 v2GoingToBkp;v2GoingToBkp=GoingTo;
+ if(!v2KeepGoingTo.IsAdjacent(GoingTo)){
+ if(iForceGoingToCountDown==0){
+ DBG4("ForceKeepGoingTo",DBGAV2(v2KeepGoingTo),DBGAV2(GoingTo),DBGAV2(GetPos()));
+
+ if(!AutoPlayAISetAndValidateKeepGoingTo(v2KeepGoingTo)){
+ static int iSetFailTeleportCountDown=10;
+ iSetFailTeleportCountDown--;
+ vv2WrongGoingTo.push_back(v2GoingToBkp);
+ if(iSetFailTeleportCountDown==0){
+ AutoPlayAITeleport(false);
+ AutoPlayAIReset(true); //refresh to test/try it all again
+ iSetFailTeleportCountDown=10;
+ }
+ }
+ DBGSV2(GoingTo);
+ return true;
+ }else{
+ iForceGoingToCountDown--;
+ }
+ }else{
+ iForceGoingToCountDown=10;
+ }
+
+ /**
+ * Determinedly blindly moves towards target, the goal is to Navigate!
+ *
+ * this has several possible status if returning false...
+ * so better do not decide anything based on it?
+ */
+ MoveTowardsTarget(false);
+
+// if(!MoveTowardsTarget(false)){ DBG3("OrFailedGoingTo,OrReachedDestination...",DBGAV2(GoingTo),DBGAV2(GetPos())); // MoveTowardsTarget may break the GoingTo EVEN if it succeeds?????
+// TerminateGoingTo();
+// v2KeepGoingTo=v2(0,0); //reset only this one to try again
+// GetAICommand(); //wander once for randomicity
+// }
+
+ return true;
+ }
+
+ return false;
+}
+
+truth character::AutoPlayAICommand(int& rKey)
+{ DBGSV2(GetPos());
+ if(AutoPlayLastChar!=this){
+ AutoPlayAIReset(true);
+ AutoPlayLastChar=this;
+ }
+
+ if(AutoPlayAICheckAreaLevelChangedAndReset()){
+ AutoPlayAIReset(true);
+ }
+
+ static bool bDummy_initDbg = [](){game::AddDebugDrawOverlayFunction(&AutoPlayAIDebugDrawOverlay);return true;}();
+
+ truth bPlayerHasLantern=false;
+ static itemvector vit;vit.clear();GetStack()->FillItemVector(vit);
+ for(int i=0;i(vit[i])!=NULL || vit[i]->IsOnFire(this)){
+ bPlayerHasLantern=true; //will keep only the 1st lantern
+ break;
+ }
+ }
+
+ if(StateIsActivated(PANIC)){ DBG1("Wandering:InPanic");
+ for(int c = 1; c <= GODS; ++c)
+ if(game::GetGod(c)->IsKnown())
+ if(clock()%10==0){
+ game::GetGod(c)->Pray(); DBG2("PrayingTo",game::GetGod(c)->GetName());
+ break;
+ }
+
+ iWanderTurns=1; // to regain control as soon it is a ghost anymore as it can break navigation when inside walls
+ }
+
+ //TODO this doesnt work??? -> if(IsPolymorphed()){ //to avoid some issues TODO but could just check if is a ghost
+// if(dynamic_cast(this) == NULL){ //this avoid some issues TODO but could just check if is a ghost
+// if(StateIsActivated(ETHEREAL_MOVING)){ //this avoid many issues
+ if(dynamic_cast(this) != NULL){ DBG1("Wandering:Ghost"); //this avoid many issues
+ iWanderTurns=1; // to regain control as soon it is a ghost anymore as it can break navigation when inside walls
+ }
+
+ if(AutoPlayAIDropThings())
+ return true;
+
+ if(AutoPlayAIEquipAndPickup(bPlayerHasLantern))
+ return true;
+
+ if(iWanderTurns>0){
+ GetAICommand(); DBG2("Wandering",iWanderTurns); //fallback to default TODO never reached?
+ iWanderTurns--;
+ return true;
+ }
+
+ /***************************************************************************************************
+ * WANDER above here
+ * NAVIGATE below here
+ ***************************************************************************************************/
+
+ /**
+ * travel between dungeons
+ */
+ if(!v2TravelingToAnotherDungeon.Is0() && GetPos() == v2TravelingToAnotherDungeon){
+ bool bTravel=false;
+ lsquare* lsqr = game::GetCurrentLevel()->GetLSquare(v2TravelingToAnotherDungeon);
+// square* sqr = Area->GetSquare(v2TravelingToAnotherDungeon);
+ olterrain* ot = lsqr->GetOLTerrain();
+// oterrain* ot = sqr->GetOTerrain();
+ if(ot){
+ if(ot->GetConfig() == STAIRS_UP){
+ rKey='<';
+ bTravel=true;
+ }
+
+ if(ot->GetConfig() == STAIRS_DOWN){
+ rKey='>';
+ bTravel=true;
+ }
+ }
+
+ if(bTravel){ DBG3("travel",DBGAV2(v2TravelingToAnotherDungeon),rKey);
+ AutoPlayAIReset(true);
+ return false; //so the new/changed key will be used as command, otherwise it would be ignored
+ }
+ }
+
+ if(AutoPlayAINavigateDungeon(bPlayerHasLantern))
+ return true;
+
+ /****************************************
+ * Twighlight zone
+ */
+
+ ADD_MESSAGE("%s says \"I need more intelligence to do things by myself...\"", CHAR_NAME(DEFINITE)); DBG1("TODO: AI needs improvement");
+
+ static int iDesperateResetCountDown=10;
+ if(iDesperateResetCountDown==0){
+ iDesperateResetCountDown=10;
+
+ AutoPlayAIReset(true);
+
+ // AFTER THE RESET!!!
+ iWanderTurns=iMaxWanderTurns; DBG2("DesperateResetToSeeIfAIWorksAgain",iWanderTurns);
+ }else{
+ GetAICommand(); DBG2("WanderingDesperatelyNotKnowingWhatToDo",iDesperateResetCountDown); // :)
+ iDesperateResetCountDown--;
+ }
+
+ return true;
+}
+
void character::GetPlayerCommand()
{
truth HasActed = false;
while(!HasActed)
{
+ graphics::SetAllowStretchedBlit(); //overall great/single location to re-enable stretched blit!
+
game::DrawEverything();
- if(game::GetDangerFound())
+ if(!StateIsActivated(FEARLESS) && game::GetDangerFound())
{
if(game::GetDangerFound() > 500.)
{
@@ -2315,33 +3290,69 @@ void character::GetPlayerCommand()
int Key = GET_KEY();
game::SetIsInGetCommand(false);
- if(Key != '+' && Key != '-' && Key != 'M') // gum
+ if(Key != '+' && Key != '-' && Key != 'M') // gum (these are the messages keys M=ShowHistory +-=ScrollHistUpDown)
msgsystem::ThyMessagesAreNowOld();
truth ValidKeyPressed = false;
int c;
- for(c = 0; c < DIRECTION_COMMAND_KEYS; ++c)
- if(Key == game::GetMoveCommandKey(c))
- {
- HasActed = TryMove(ApplyStateModification(game::GetMoveVector(c)), true, game::PlayerIsRunning());
- ValidKeyPressed = true;
+#ifdef WIZARD
+ if(IsPlayerAutoPlay()){
+ if(Key=='.'){ // pressed or simulated
+ if(game::IsInWilderness()){
+ Key='>'; //blindly tries to go back to the dungeon safety :) TODO target and move to other dungeons/towns in the wilderness
+ }else{
+ HasActed = AutoPlayAICommand(Key); DBG2("Simulated",Key);
+ if(HasActed)ValidKeyPressed = true; //valid simulated action
+ }
+ }else{
+ /**
+ * if the user hits any key during the autoplay mode that runs by itself, it will be disabled.
+ * at non auto mode, can be moved around but cannot rest or will move by itself
+ */
+ if(game::GetAutoPlayMode()>=2 && Key!='~'){
+ game::DisableAutoPlayMode();
+ AutoPlayAIReset(true); // this will help on re-randomizing things, mainly paths
+ }
}
+ }
+#endif
- for(c = 1; commandsystem::GetCommand(c); ++c)
- if(Key == commandsystem::GetCommand(c)->GetKey())
- {
- if(game::IsInWilderness() && !commandsystem::GetCommand(c)->IsUsableInWilderness())
- ADD_MESSAGE("This function cannot be used while in wilderness.");
- else
- if(!game::WizardModeIsActive() && commandsystem::GetCommand(c)->IsWizardModeFunction())
- ADD_MESSAGE("Activate wizardmode to use this function.");
+ if(!HasActed){
+
+ for(c = 0; c < DIRECTION_COMMAND_KEYS; ++c)
+ if(Key == game::GetMoveCommandKey(c))
+ {
+ bool bWaitNeutralMove=false;
+ HasActed = TryMove(ApplyStateModification(game::GetMoveVector(c)), true, game::PlayerIsRunning(), &bWaitNeutralMove);
+ if(!HasActed && bWaitNeutralMove){
+ //cant access.. HasActed = commandsystem::NOP(this);
+ Key = '.'; //TODO request NOP()'s key instead of this '.' hardcoded here. how?
+ }
+ ValidKeyPressed = true;
+ }
+
+ for(c = 1; commandsystem::GetCommand(c); ++c)
+ if(Key == commandsystem::GetCommand(c)->GetKey())
+ {
+ if(game::IsInWilderness() && !commandsystem::GetCommand(c)->IsUsableInWilderness())
+ ADD_MESSAGE("This function cannot be used while in wilderness.");
else
- HasActed = commandsystem::GetCommand(c)->GetLinkedFunction()(this);
+ if(!game::WizardModeIsActive() && commandsystem::GetCommand(c)->IsWizardModeFunction())
+ ADD_MESSAGE("Activate wizardmode to use this function.");
+ else{
+ game::RegionListItemEnable(commandsystem::IsForRegionListItem(c));
+ game::RegionSilhouetteEnable(commandsystem::IsForRegionSilhouette(c));
+ HasActed = commandsystem::GetCommand(c)->GetLinkedFunction()(this);
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
+ }
- ValidKeyPressed = true;
- break;
- }
+ ValidKeyPressed = true;
+ break;
+ }
+
+ }
if(!ValidKeyPressed)
ADD_MESSAGE("Unknown key. Press '?' for a list of commands.");
@@ -2375,12 +3386,12 @@ void character::Vomit(v2 Pos, int Amount, truth ShowMsg)
CheckStarvationDeath(CONST_S("vomited himself to death"));
}
- if(StateIsActivated(PARASITIZED) && !(RAND() & 7))
+ if(StateIsActivated(PARASITE_TAPE_WORM) && !(RAND() & 7))
{
if(IsPlayer())
ADD_MESSAGE("You notice a dead broad tapeworm among your former stomach contents.");
- DeActivateTemporaryState(PARASITIZED);
+ DeActivateTemporaryState(PARASITE_TAPE_WORM);
}
if(!game::IsInWilderness())
@@ -2595,6 +3606,14 @@ truth character::LoseConsciousness(int Counter, truth HungerFaint)
return true;
}
+void character::DeActivateTemporaryState(long What)
+{
+ if(PolymorphBackup)
+ PolymorphBackup->TemporaryState &= ~What;
+
+ TemporaryState &= ~What;
+}
+
void character::DeActivateVoluntaryAction(cfestring& Reason)
{
if(GetAction() && GetAction()->IsVoluntary())
@@ -2683,7 +3702,7 @@ truth character::CheckForEnemies(truth CheckDoors, truth CheckGround, truth MayM
if(SpecialEnemySightedReaction(NearestChar))
return true;
- if(IsExtraCoward() && !StateIsActivated(PANIC) && NearestChar->GetRelativeDanger(this) >= 0.5)
+ if(IsExtraCoward() && !StateIsActivated(PANIC) && NearestChar->GetRelativeDanger(this) >= 0.5 && !StateIsActivated(FEARLESS))
{
if(CanBeSeenByPlayer())
ADD_MESSAGE("%s sees %s.", CHAR_NAME(DEFINITE), NearestChar->CHAR_DESCRIPTION(DEFINITE));
@@ -2791,26 +3810,40 @@ truth character::FollowLeader(character* Leader)
if(!Leader || Leader == this || !IsEnabled())
return false;
- if(CommandFlags & FOLLOW_LEADER && Leader->CanBeSeenBy(this) && Leader->SquareUnderCanBeSeenBy(this, true))
- {
- v2 Distance = GetPos() - GoingTo;
+ if(CommandFlags & FOLLOW_LEADER && Leader->CanBeSeenBy(this) && Leader->SquareUnderCanBeSeenBy(this, true)){
+ v2HoldPos = GoingTo; //will keep the last reference position possible
+ v2 Distance = GetPos() - GoingTo; //set by SeekLeader()
if(abs(Distance.X) <= 2 && abs(Distance.Y) <= 2)
return false;
else
return MoveTowardsTarget(false);
}
- else
- if(IsGoingSomeWhere())
- if(!MoveTowardsTarget(true))
- {
- TerminateGoingTo();
+
+ if(IsGoingSomeWhere()){
+ if(!MoveTowardsTarget(true)){
+ TerminateGoingTo();
+ return false;
+ }else{
+ return true;
+ }
+ }else{
+ // just hold near position
+ if(v2HoldPos.Is0())
+ v2HoldPos=GetPos(); //when the game is loaded keep current pos TODO could be savegamed tho
+ if(ivanconfig::GetHoldPosMaxDist()>0){
+ v2 v2HoldDist = GetPos() - v2HoldPos;
+ if(abs(v2HoldDist.X) < ivanconfig::GetHoldPosMaxDist() && abs(v2HoldDist.Y) < ivanconfig::GetHoldPosMaxDist()){
+ // will do other things
return false;
- }
- else
+ }else{
+ SetGoingTo(v2HoldPos); DBG4(GetNameSingular().CStr(),DBGAV2(v2HoldPos),DBGAV2(Leader->GetPos()),DBGAV2(v2HoldDist));
return true;
- else
- return false;
+ }
+ }
+ }
+
+ return false;
}
void character::SeekLeader(ccharacter* Leader)
@@ -2826,7 +3859,7 @@ void character::SeekLeader(ccharacter* Leader)
{
team* Team = GetTeam();
- for(character* p : Team->GetMember())
+ for(character* p : Team->GetMember()){
if(p->IsEnabled()
&& p->GetID() != GetID()
&& (CommandFlags & FOLLOW_LEADER)
@@ -2842,6 +3875,10 @@ void character::SeekLeader(ccharacter* Leader)
break;
}
}
+ }
+
+// if(!IsGoingSomeWhere()){ // couldnt follow leader neather team mate
+// }
}
}
}
@@ -3162,8 +4199,63 @@ void character::GoOn(go* Go, truth FirstStep)
if(GetStackUnder()->GetVisibleItems(this))
{
- Go->Terminate(false);
- return;
+ bool bUseless=false,bTooCheap=false,bEncumbering=false;
+
+ switch(ivanconfig::GetGoOnStopMode()){
+ case 0: Go->Terminate(false); return;
+ case 1:bUseless=true;break;
+ case 2:bTooCheap=true;break;
+ case 3:bEncumbering=true;break;
+ default:
+ ABORT("unsupported go on stop mode %d",ivanconfig::GetGoOnStopMode());
+ break;
+ }
+
+ itemvector vit;
+ GetStackUnder()->FillItemVector(vit);
+ for(int i=0;iGetNameSingular().CStr(), vit[i]->AllowEquip(), vit[i]->IsAppliable(this), vit[i]->IsConsumable(),
+ vit[i]->IsEatable(this), vit[i]->IsDrinkable(this), vit[i]->IsOpenable(this), vit[i]->IsReadable(this), vit[i]->IsZappable(this) );
+ DBG8(vit[i]->GetNameSingular().CStr(),vit[i]->IsWeapon(this),vit[i]->IsArmor(this),vit[i]->IsBodyArmor(this),vit[i]->IsHelmet(this),
+ vit[i]->IsGauntlet(this),vit[i]->IsBoot(this),vit[i]->IsBelt(this) );
+ if( //TODO ? vit[i]->GetSpoilLevel()==0
+ vit[i]->IsOpenable(this) //doors are not items, but works for chests too
+ ||
+ (bUseless &&
+ (
+ vit[i]->IsAppliable(this) ||
+ vit[i]->IsZappable(this) ||
+
+ // bad! vit[i]->IsConsumable() ||
+ vit[i]->IsEatable(this) ||
+ vit[i]->IsDrinkable(this) ||
+
+ // bad! vit[i]->AllowEquip() ||
+ vit[i]->IsWeapon(this) ||
+ vit[i]->IsArmor(this) || //all armor slots
+// vit[i]->IsBodyArmor(this) ||
+// vit[i]->IsHelmet(this) ||
+// vit[i]->IsGauntlet(this) ||
+// vit[i]->IsBoot(this) ||
+// vit[i]->IsBelt(this) ||
+
+ vit[i]->IsAmulet(this) ||
+ vit[i]->IsRing(this) ||
+
+ vit[i]->IsReadable(this)
+ )
+ ) ||
+ (bTooCheap &&
+ (vit[i]->GetTruePrice() > iMaxValueless)
+ ) ||
+ (bEncumbering && //calc in float price vs weight
+ (vit[i]->GetTruePrice()/(vit[i]->GetWeight()/1000.0)) > (iMaxValueless*2)
+ )
+ ){
+ Go->Terminate(false);
+ return;
+ }
+ }
}
game::DrawEverything();
@@ -3368,6 +4460,12 @@ void character::TeleportRandomly(truth Intentional)
{
v2 TelePos = ERROR_V2;
+ if(StateIsActivated(TELEPORT_LOCK))
+ {
+ ADD_MESSAGE("You flicker for a second.");
+ return;
+ }
+
if(StateIsActivated(TELEPORT_CONTROL))
{
if(IsPlayer())
@@ -3442,6 +4540,70 @@ void character::TeleportRandomly(truth Intentional)
if(GetAction() && GetAction()->IsVoluntary())
GetAction()->Terminate(false);
+
+ if(IsPlayerAutoPlay())
+ AutoPlayAIReset(true);
+}
+
+truth character::IsPlayerAutoPlay()
+{
+ return IsPlayer() && game::GetAutoPlayMode()>0;
+}
+
+void character::DoDetecting()
+{
+ if(IsPlayerAutoPlay())return;
+
+ material* TempMaterial;
+
+ for(;;)
+ {
+ festring Temp;
+
+ if(game::DefaultQuestion(Temp, CONST_S("What material do you want to detect?"),
+ game::GetDefaultDetectMaterial(), true) == ABORTED)
+ {
+ if(game::TruthQuestion(CONST_S("Really cancel? [y/N]")))
+ return;
+ else
+ continue;
+ }
+
+ TempMaterial = protosystem::CreateMaterial(Temp);
+
+ if(TempMaterial)
+ break;
+ else
+ game::DrawEverythingNoBlit();
+ }
+
+ level* Level = GetLevel();
+ int Squares = Level->DetectMaterial(TempMaterial);
+
+ if(Squares > GetAttribute(INTELLIGENCE) * (25 + RAND() % 51))
+ {
+ ADD_MESSAGE("An enormous burst of geographical information overwhelms your consciousness. Your mind cannot cope with it and your memories blur.");
+ Level->BlurMemory();
+ BeginTemporaryState(CONFUSED, 1000 + RAND() % 1000);
+ EditExperience(INTELLIGENCE, -100, 1 << 12);
+ }
+ else if(!Squares)
+ {
+ ADD_MESSAGE("You feel a sudden urge to imagine the dark void of a starless night sky.");
+ EditExperience(INTELLIGENCE, 20, 1 << 12);
+ }
+ else
+ {
+ ADD_MESSAGE("You feel attracted to all things made of %s.", TempMaterial->GetName(false, false).CStr());
+ game::SetDrawMapOverlay(ivanconfig::IsShowMapAtDetectMaterial());
+ game::PositionQuestion(CONST_S("Detecting material [direction keys move cursor, space exits]"), GetPos(), 0, 0, false);
+ game::SetDrawMapOverlay(false);
+ EditExperience(INTELLIGENCE, 30, 1 << 12);
+ }
+
+ delete TempMaterial;
+ Level->CalculateLuminances();
+ game::SendLOSUpdateRequest();
}
void character::RestoreHP()
@@ -3502,6 +4664,38 @@ truth character::AllowDamageTypeBloodSpill(int Type)
return false;
}
+v2 character::GetPosSafely() const
+{
+ square* sqr = GetSquareUnderSafely();
+ if(sqr!=NULL)return sqr->GetPos();
+ return v2();
+}
+
+square* character::GetSquareUnderSafely() const
+{ //prevents crash if polymorphed (here at least)
+ if(SquareUnder[0]!=NULL){DBGLN;
+ return SquareUnder[0];
+ }DBGLN;
+
+ if(IsPolymorphed()){DBGLN;
+ character* pb = GetPolymorphBackup();
+ if(pb!=NULL && pb->SquareUnder[0]!=NULL){ DBG1(pb->GetNameSingular().CStr()); //TODO to use square under index here may cause inconsistencies?
+ return pb->SquareUnder[0];
+ }
+ }DBGLN;
+
+ return NULL;
+}
+
+stack* character::GetStackUnderSafely() const
+{
+ square* sqr = GetSquareUnderSafely();
+ lsquare* lsqr = dynamic_cast(sqr);
+ if(lsqr!=NULL)return lsqr->GetStack();
+ return NULL;
+}
+
+
/* Returns truly done damage */
int character::ReceiveBodyPartDamage(character* Damager, int Damage, int Type, int BodyPartIndex,
@@ -3599,10 +4793,18 @@ int character::ReceiveBodyPartDamage(character* Damager, int Damage, int Type, i
{
/** No multi-tile humanoid support! */
- GetStackUnder()->AddItem(Severed);
-
- if(Direction != YOURSELF)
- Severed->Fly(0, Direction, Damage);
+ stack* su = GetStackUnderSafely();
+ if(su){
+ su->AddItem(Severed);
+
+ if(Direction != YOURSELF)
+ Severed->Fly(0, Direction, Damage);
+ }else{
+ /**
+ * this may happen when polymorphing (tests were made as a snake) during an explosion that severe body parts
+ */
+ GetStack()->AddItem(Severed); DBGLN;
+ }
}
else
GetStack()->AddItem(Severed);
@@ -3618,7 +4820,9 @@ int character::ReceiveBodyPartDamage(character* Damager, int Damage, int Type, i
if(CanPanicFromSeveredBodyPart()
&& RAND() % 100 < GetPanicLevel()
- && !StateIsActivated(PANIC) && !IsDead())
+ && !StateIsActivated(PANIC)
+ && !StateIsActivated(FEARLESS)
+ && !IsDead())
BeginTemporaryState(PANIC, 1000 + RAND() % 1001);
SpecialBodyPartSeverReaction();
@@ -3639,6 +4843,9 @@ item* character::SevereBodyPart(int BodyPartIndex, truth ForceDisappearance, sta
if(StateIsActivated(LEPROSY))
BodyPart->GetMainMaterial()->SetIsInfectedByLeprosy(true);
+ if(BodyPartIndex == HEAD_INDEX && StateIsActivated(PARASITE_MIND_WORM))
+ DeActivateTemporaryState(PARASITE_MIND_WORM);
+
if(ForceDisappearance
|| BodyPartsDisappearWhenSevered()
|| StateIsActivated(POLYMORPHED)
@@ -3836,7 +5043,6 @@ int character::GetResistance(int Type) const
switch(Type&0xFFF)
{
case PHYSICAL_DAMAGE:
- case SOUND:
case DRAIN:
case MUSTARD_GAS_DAMAGE:
case PSI:
@@ -3846,6 +5052,7 @@ int character::GetResistance(int Type) const
case POISON: return GetPoisonResistance();
case ELECTRICITY: return GetElectricityResistance();
case ACID: return GetAcidResistance();
+ case SOUND: return GetSoundResistance();
}
ABORT("Resistance lack detected!");
@@ -3854,6 +5061,21 @@ int character::GetResistance(int Type) const
void character::Regenerate()
{
+ if(StateIsActivated(REGENERATION) && !(RAND() % 3000))
+ {
+ bodypart* NewBodyPart = GenerateRandomBodyPart();
+
+ if(NewBodyPart)
+ {
+ NewBodyPart->SetHP(1);
+
+ if(IsPlayer())
+ ADD_MESSAGE("You grow a new %s.", NewBodyPart->GetBodyPartName().CStr());
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s grows a new %s.", CHAR_NAME(DEFINITE), NewBodyPart->GetBodyPartName().CStr());
+ }
+ }
+
if(HP == MaxHP)
return;
@@ -4246,7 +5468,7 @@ void character::ReceiveHeal(long Amount)
if(RAND() % 10 < Amount)
HealHitPoint();
- if(Amount >= 250 || RAND() % 250 < Amount)
+ if(Amount >= 1000 || RAND() % 1000 < Amount)
{
bodypart* NewBodyPart = GenerateRandomBodyPart();
@@ -4306,6 +5528,15 @@ void character::ReceiveNutrition(long SizeOfEffect)
EditNP(SizeOfEffect);
}
+void character::ReceiveOmmelBlood(long Amount)
+{
+ EditExperience(WILL_POWER, 500, Amount << 4);
+ EditExperience(MANA, 500, Amount << 4);
+
+ if(IsPlayer())
+ game::DoEvilDeed(Amount / 25);
+}
+
void character::ReceiveOmmelUrine(long Amount)
{
EditExperience(ARM_STRENGTH, 500, Amount << 4);
@@ -4398,6 +5629,14 @@ void character::AddPepsiConsumeEndMessage() const
ADD_MESSAGE("%s looks very lame.", CHAR_NAME(DEFINITE));
}
+void character::AddCocaColaConsumeEndMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel your guruism rising!");
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s looks awesome.", CHAR_NAME(DEFINITE));
+}
+
void character::ReceiveDarkness(long Amount)
{
EditExperience(INTELLIGENCE, -Amount / 5, 1 << 13);
@@ -4474,11 +5713,11 @@ void character::DrawPanel(truth AnimationDraw) const
return;
}
- igraph::BlitBackGround(v2(19 + (game::GetScreenXSize() << 4), 0),
- v2(RES.X - 19 - (game::GetScreenXSize() << 4), RES.Y));
- igraph::BlitBackGround(v2(16, 45 + (game::GetScreenYSize() << 4)),
- v2(game::GetScreenXSize() << 4, 9));
- FONT->Printf(DOUBLE_BUFFER, v2(16, 45 + (game::GetScreenYSize() << 4)), WHITE, "%s", GetPanelName().CStr());
+ igraph::BlitBackGround(v2(19 + (game::GetMaxScreenXSize() << 4), 0),
+ v2(RES.X - 19 - (game::GetMaxScreenXSize() << 4), RES.Y));
+ igraph::BlitBackGround(v2(16, 45 + (game::GetMaxScreenYSize() << 4)),
+ v2(game::GetMaxScreenXSize() << 4, 9));
+ FONT->Printf(DOUBLE_BUFFER, v2(16, 45 + (game::GetMaxScreenYSize() << 4)), WHITE, "%s", GetPanelName().CStr());
game::UpdateAttributeMemory();
int PanelPosX = RES.X - 96;
int PanelPosY = DrawStats(false);
@@ -4486,9 +5725,12 @@ void character::DrawPanel(truth AnimationDraw) const
PrintAttribute("Per", PERCEPTION, PanelPosX, PanelPosY++);
PrintAttribute("Int", INTELLIGENCE, PanelPosX, PanelPosY++);
PrintAttribute("Wis", WISDOM, PanelPosX, PanelPosY++);
- PrintAttribute("Wil", WILL_POWER, PanelPosX, PanelPosY++);
+ PrintAttribute("Will", WILL_POWER, PanelPosX, PanelPosY++);
PrintAttribute("Cha", CHARISMA, PanelPosX, PanelPosY++);
- FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10), WHITE, "Siz %d", GetSize());
+ PrintAttribute("Mana", MANA, PanelPosX, PanelPosY++);
+ FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10), WHITE, "Ht %d cm", GetSize());
+ FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10), WHITE, "Wt %d kg", GetTotalCharacterWeight());
+ ++PanelPosY;
FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10),
IsInBadCondition() ? RED : WHITE, "HP %d/%d", GetHP(), GetMaxHP());
++PanelPosY;
@@ -4524,22 +5766,22 @@ void character::DrawPanel(truth AnimationDraw) const
(1 << c) & EquipmentState || TemporaryStateCounter[c] >= PERMANENT ? BLUE : WHITE,
"%s", StateData[c].Description);
- static cchar* HungerStateStrings[] = { "Starving", "Very hungry", "Hungry", "", "Satiated", "Bloated", "Overfed!" };
- static cpackcol16 HungerStateColors[] = { RED, BLUE, BLUE, 0, WHITE, WHITE, WHITE };
+ static cchar* HungerStateStrings[] = { "Starving!", "Very hungry", "Hungry", "", "Satiated", "Bloated", "Overfed!" };
+ static cpackcol16 HungerStateColors[] = { RED, RED, YELLOW, 0, WHITE, WHITE, YELLOW };
int HungerState = GetHungerState();
if(HungerState != NOT_HUNGRY)
FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10),
HungerStateColors[HungerState], HungerStateStrings[HungerState]);
static cchar* BurdenStateStrings[] = { "Overload!", "Stressed", "Burdened" };
- static cpackcol16 BurdenStateColors[] = { RED, BLUE, BLUE };
+ static cpackcol16 BurdenStateColors[] = { RED, RED, YELLOW };
int BurdenState = GetBurdenState();
if(BurdenState != UNBURDENED)
FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10),
BurdenStateColors[BurdenState], BurdenStateStrings[BurdenState]);
- static cchar* TirednessStateStrings[] = { "Fainting", "Exhausted" };
- static cpackcol16 TirednessStateColors[] = { RED, WHITE };
+ static cchar* TirednessStateStrings[] = { "Fainting!", "Exhausted" };
+ static cpackcol16 TirednessStateColors[] = { RED, YELLOW };
int TirednessState = GetTirednessState();
if(TirednessState != UNTIRED)
FONT->Printf(DOUBLE_BUFFER, v2(PanelPosX, PanelPosY++ * 10),
@@ -4848,6 +6090,46 @@ void character::PrintEndLycanthropyMessage() const
ADD_MESSAGE("You feel the wolf inside you has had enough of your bad habits.");
}
+void character::PrintBeginVampirismMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You suddenly decide you have always hated garlic.");
+}
+
+void character::PrintEndVampirismMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You recall your delight of the morning sunshine back in New Attnam.");
+}
+
+void character::PrintBeginFearlessMessage () const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You shout: \"I am invincible!\"");
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s looks very calm.", CHAR_NAME(DEFINITE));
+}
+
+void character::PrintEndFearlessMessage () const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Everything looks much more dangerous now.");
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s seems to have lost all confidence.", CHAR_NAME(DEFINITE));
+}
+
+void character::PrintBeginFastingMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel your life-force invigorating your entire body.");
+}
+
+void character::PrintEndFastingMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Your stomach growls in discontent.");
+}
+
void character::PrintBeginInvisibilityMessage() const
{
if((PLAYER->StateIsActivated(INFRA_VISION) && IsWarm())
@@ -4902,6 +6184,22 @@ void character::PrintEndEtherealityMessage() const
ADD_MESSAGE("Suddenly %s displaces the air with a puff.", CHAR_NAME(INDEFINITE));
}
+void character::PrintBeginSwimmingMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You fondly remember the sound of ocean waves.");
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s looks wet.", CHAR_NAME(DEFINITE));
+}
+
+void character::PrintEndSwimmingMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You suddenly remember how you nearly drowned as a child.");
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("Suddenly %s looks less wet.", CHAR_NAME(INDEFINITE));
+}
+
void character::PrintBeginInfraVisionMessage() const
{
if(IsPlayer())
@@ -5028,6 +6326,12 @@ character* character::ForceEndPolymorph()
void character::LycanthropyHandler()
{
+ if(StateIsActivated(POLYMORPH_LOCK))
+ return;
+
+ if(GetType() == werewolfwolf::ProtoType.GetIndex())
+ return;
+
if(!(RAND() % 2000))
{
if(StateIsActivated(POLYMORPH_CONTROL)
@@ -5098,9 +6402,14 @@ character* character::PolymorphRandomly(int MinDanger, int MaxDanger, int Time)
{
character* NewForm = 0;
+ if(StateIsActivated(POLYMORPH_LOCK))
+ {
+ ADD_MESSAGE("You feel uncertain about your body for a moment.");
+ return NewForm;
+ }
if(StateIsActivated(POLYMORPH_CONTROL))
{
- if(IsPlayer())
+ if(IsPlayer() && !IsPlayerAutoPlay())
{
if(!GetNewFormForPolymorphWithControl(NewForm))
return NewForm;
@@ -5149,7 +6458,7 @@ truth character::CanBeSeenByPlayer(truth Theoretically, truth IgnoreESP) const
{
if(IsEnabled() && !game::IsGenerating() && (Theoretically || GetSquareUnder()))
{
- truth MayBeESPSeen = PLAYER->IsEnabled() && !IgnoreESP && PLAYER->StateIsActivated(ESP) && GetAttribute(INTELLIGENCE) >= 5;
+ truth MayBeESPSeen = PLAYER->IsEnabled() && !IgnoreESP && PLAYER->StateIsActivated(ESP) && GetAttribute(INTELLIGENCE) >= 5 && !IsESPBlockedByEquipment();
truth MayBeInfraSeen = PLAYER->IsEnabled() && PLAYER->StateIsActivated(INFRA_VISION) && IsWarm();
truth Visible = !StateIsActivated(INVISIBLE) || MayBeESPSeen || MayBeInfraSeen;
@@ -5451,6 +6760,11 @@ truth character::IsWarm() const
return combinebodypartpredicates()(this, &bodypart::IsWarm, 1);
}
+truth character::IsWarmBlooded() const
+{
+ return combinebodypartpredicates()(this, &bodypart::IsWarmBlooded, 1);
+}
+
void character::BeginInvisibility()
{
UpdatePictures();
@@ -5474,6 +6788,10 @@ void character::BeginEthereality()
{
}
+void character::BeginSwimming()
+{
+}
+
void character::EndInvisibility()
{
UpdatePictures();
@@ -5497,6 +6815,10 @@ void character::EndEthereality()
{
}
+void character::EndSwimming()
+{
+}
+
void character::Draw(blitdata& BlitData) const
{
col24 L = BlitData.Luminance;
@@ -5560,6 +6882,18 @@ void character::PrintEndTeleportMessage() const
ADD_MESSAGE("You suddenly realize you've always preferred walking to jumping.");
}
+void character::PrintBeginDetectMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel curious about your surroundings.");
+}
+
+void character::PrintEndDetectMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You decide to rely on your own sight from now on.");
+}
+
void character::TeleportHandler()
{
if(!(RAND() % 1500) && !game::IsInWilderness())
@@ -5573,6 +6907,20 @@ void character::TeleportHandler()
}
}
+void character::DetectHandler()
+{
+ if(IsPlayer()) //the AI can't be asked position questions! So only the player can have this state really.
+ {
+ if(!(RAND() % 3000) && !game::IsInWilderness())
+ {
+ ADD_MESSAGE("Your mind wanders in search of something.");
+ DoDetecting();
+ }
+ }
+ else
+ return;
+}
+
void character::PrintBeginPolymorphMessage() const
{
if(IsPlayer())
@@ -5591,6 +6939,28 @@ void character::PolymorphHandler()
PolymorphRandomly(1, 999999, 200 + RAND() % 800);
}
+void character::PrintBeginPolymorphLockMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel incredibly stubborn about who you are.");
+}
+
+void character::PrintEndPolymorphLockMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel more open to new ideas.");
+}
+
+void character::PolymorphLockHandler()
+{
+ if (TemporaryStateIsActivated(POLYMORPHED))
+ {
+ EditTemporaryStateCounter(POLYMORPHED, 1);
+ if (GetTemporaryStateCounter(POLYMORPHED) < 1000)
+ EditTemporaryStateCounter(POLYMORPHED, 1);
+ }
+}
+
void character::PrintBeginTeleportControlMessage() const
{
if(IsPlayer())
@@ -5603,16 +6973,67 @@ void character::PrintEndTeleportControlMessage() const
ADD_MESSAGE("You feel your control slipping.");
}
+void character::PrintBeginRegenerationMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Your heart races.");
+}
+
+void character::PrintEndRegenerationMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Your rapid heartbeat calms down.");
+}
+
+void character::PrintBeginDiseaseImmunityMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel especially healthy.");
+}
+
+void character::PrintEndDiseaseImmunityMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You develop a sudden fear of germs.");
+}
+
+void character::PrintBeginTeleportLockMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You feel firmly planted in reality.");
+}
+
+void character::PrintEndTeleportLockMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Your mind soars far and wide.");
+}
+
+void character::TeleportLockHandler()
+{
+ if (StateIsActivated(TELEPORT_LOCK))
+ {
+ EditTemporaryStateCounter(TELEPORT_LOCK, 1);
+ if (GetTemporaryStateCounter(TELEPORT_LOCK) < 1000)
+ EditTemporaryStateCounter(TELEPORT_LOCK, 1);
+ }
+}
+
void character::DisplayStethoscopeInfo(character*) const
{
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
felist Info(CONST_S("Information about ") + GetDescription(DEFINITE));
AddSpecialStethoscopeInfo(Info);
Info.AddEntry(CONST_S("Endurance: ") + GetAttribute(ENDURANCE), LIGHT_GRAY);
Info.AddEntry(CONST_S("Perception: ") + GetAttribute(PERCEPTION), LIGHT_GRAY);
Info.AddEntry(CONST_S("Intelligence: ") + GetAttribute(INTELLIGENCE), LIGHT_GRAY);
Info.AddEntry(CONST_S("Wisdom: ") + GetAttribute(WISDOM), LIGHT_GRAY);
- //Info.AddEntry(CONST_S("Willpower: ") + GetAttribute(WILL_POWER), LIGHT_GRAY);
+ Info.AddEntry(CONST_S("Willpower: ") + GetAttribute(WILL_POWER), LIGHT_GRAY);
Info.AddEntry(CONST_S("Charisma: ") + GetAttribute(CHARISMA), LIGHT_GRAY);
+ Info.AddEntry(CONST_S("Mana: ") + GetAttribute(MANA), LIGHT_GRAY);
+ Info.AddEntry(CONST_S("Height: ") + GetSize() + " cm", LIGHT_GRAY);
+ Info.AddEntry(CONST_S("Weight: ") + GetTotalCharacterWeight() + " kg", LIGHT_GRAY);
Info.AddEntry(CONST_S("HP: ") + GetHP() + "/" + GetMaxHP(), IsInBadCondition() ? RED : LIGHT_GRAY);
if(GetAction())
@@ -5651,6 +7072,14 @@ truth character::CanUseStethoscope(truth PrintReason) const
void character::TeleportSomePartsAway(int NumberToTeleport)
{
+ if(StateIsActivated(TELEPORT_LOCK))
+ {
+ if(IsPlayer())
+ ADD_MESSAGE("You feel very itchy for a moment.");
+
+ return;
+ }
+
for(int c = 0; c < NumberToTeleport; ++c)
{
int RandomBodyPart = GetRandomNonVitalBodyPart();
@@ -5709,10 +7138,27 @@ int character::GetRandomNonVitalBodyPart() const
int OKBodyParts = 0;
for(int c = 0; c < BodyParts; ++c)
- if(GetBodyPart(c) && !BodyPartIsVital(c))
- OKBodyPart[OKBodyParts++] = c;
+ if(GetBodyPart(c) && !BodyPartIsVital(c))
+ OKBodyPart[OKBodyParts++] = c;
+
+ return OKBodyParts ? OKBodyPart[RAND() % OKBodyParts] : NONE_INDEX;
+}
+
+int character::GetTotalCharacterWeight() const
+{
+ int CharacterWeight = 0;
+
+ for(int c = 0; c < BodyParts; ++c)
+ {
+ bodypart* BodyPart = GetBodyPart(c);
- return OKBodyParts ? OKBodyPart[RAND() % OKBodyParts] : NONE_INDEX;
+ if(BodyPart)
+ {
+ CharacterWeight += BodyPart->GetWeight();
+ }
+ }
+
+ return (floor(CharacterWeight / 1000));
}
void character::CalculateVolumeAndWeight()
@@ -6104,7 +7550,7 @@ truth character::ContentsCanBeSeenBy(ccharacter* Viewer) const
}
truth character::HitEffect(character* Enemy, item* Weapon, v2 HitPos, int Type,
- int BodyPartIndex, int Direction, truth BlockedByArmour)
+ int BodyPartIndex, int Direction, truth BlockedByArmour, truth Critical, int DoneDamage)
{
if(Weapon)
return Weapon->HitEffect(this, Enemy, HitPos, BodyPartIndex, Direction, BlockedByArmour);
@@ -6116,7 +7562,7 @@ truth character::HitEffect(character* Enemy, item* Weapon, v2 HitPos, int Type,
case KICK_ATTACK:
return Enemy->SpecialKickEffect(this, HitPos, BodyPartIndex, Direction, BlockedByArmour);
case BITE_ATTACK:
- return Enemy->SpecialBiteEffect(this, HitPos, BodyPartIndex, Direction, BlockedByArmour);
+ return Enemy->SpecialBiteEffect(this, HitPos, BodyPartIndex, Direction, BlockedByArmour, Critical, DoneDamage);
}
return false;
@@ -6181,7 +7627,7 @@ character* character::Duplicate(ulong Flags)
return Char;
}
-truth character::TryToEquip(item* Item)
+truth character::TryToEquip(item* Item, truth onlyIfEmpty, int onlyAt)
{
if(!Item->AllowEquip()
|| !CanUseEquipment()
@@ -6189,7 +7635,9 @@ truth character::TryToEquip(item* Item)
|| Item->GetSquaresUnder() != 1)
return false;
- for(int e = 0; e < GetEquipments(); ++e)
+ for(int e = 0; e < GetEquipments(); ++e){
+ if(onlyAt>-1 && e!=onlyAt)continue;
+
if(GetBodyPartOfEquipment(e) && EquipmentIsAllowed(e))
{
sorter Sorter = EquipmentSorter(e);
@@ -6201,6 +7649,7 @@ truth character::TryToEquip(item* Item)
&& AllowEquipment(Item, e))
{
item* OldEquipment = GetEquipment(e);
+ if(onlyIfEmpty && OldEquipment!=NULL)continue;
if(BoundToUse(OldEquipment, e))
continue;
@@ -6277,6 +7726,7 @@ truth character::TryToEquip(item* Item)
}
}
}
+ }
return false;
}
@@ -6322,7 +7772,7 @@ void character::PrintEndPanicMessage() const
void character::CheckPanic(int Ticks)
{
if(GetPanicLevel() > 1 && !StateIsActivated(PANIC)
- && GetHP() * 100 < RAND() % (GetPanicLevel() * GetMaxHP() << 1))
+ && GetHP() * 100 < RAND() % (GetPanicLevel() * GetMaxHP() << 1) && !StateIsActivated(FEARLESS))
BeginTemporaryState(PANIC, ((Ticks * 3) >> 2) + RAND() % ((Ticks >> 1) + 1)); // 25% randomness to ticks...
}
@@ -6507,16 +7957,25 @@ void character::ReceiveAntidote(long Amount)
}
}
- if((Amount >= 100 || RAND_N(100) < Amount) && StateIsActivated(PARASITIZED))
+ if((Amount > 500 || RAND_N(1000) < Amount) && StateIsActivated(PARASITE_TAPE_WORM))
{
if(IsPlayer())
ADD_MESSAGE("Something in your belly didn't seem to like this stuff.");
- DeActivateTemporaryState(PARASITIZED);
+ DeActivateTemporaryState(PARASITE_TAPE_WORM);
+ Amount -= Min(100L, Amount);
+ }
+
+ if((Amount > 500 || RAND_N(1000) < Amount) && StateIsActivated(PARASITE_MIND_WORM))
+ {
+ if(IsPlayer())
+ ADD_MESSAGE("Something in your head screeches in pain.");
+
+ DeActivateTemporaryState(PARASITE_MIND_WORM);
Amount -= Min(100L, Amount);
}
- if((Amount >= 100 || RAND_N(100) < Amount) && StateIsActivated(LEPROSY))
+ if((Amount > 500 || RAND_N(1000) < Amount) && StateIsActivated(LEPROSY))
{
if(IsPlayer())
ADD_MESSAGE("You are not falling to pieces anymore.");
@@ -6774,7 +8233,11 @@ truth character::SelectFromPossessions(itemvector& ReturnVector, cfestring& Topi
List.SetFlags(SELECTABLE|DRAW_BACKGROUND_AFTERWARDS);
List.SetEntryDrawer(game::ItemEntryDrawer);
game::DrawEverythingNoBlit();
+ game::RegionListItemEnable(true);
+ game::RegionSilhouetteEnable(true);
int Chosen = List.Draw();
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
game::ClearItemDrawVector();
if(Chosen != ESCAPED)
@@ -6938,14 +8401,14 @@ void character::PrintEndParasitizedMessage() const
void character::ParasitizedHandler()
{
- EditNP(-5);
+ EditNP(-10);
if(!(RAND() % 250))
{
if(IsPlayer())
ADD_MESSAGE("Ugh. You feel something violently carving its way through your intestines.");
- ReceiveDamage(0, 1, POISON, TORSO, 8, false, false, false, false);
+ ReceiveDamage(0, 1, DRAIN, TORSO, 8, false, false, false, false); // Use DRAIN here so that resistances do not apply.
CheckDeath(CONST_S("killed by a vile parasite"), 0);
}
}
@@ -6974,7 +8437,16 @@ festring character::GetPanelName() const
festring Name;
Name << AssignedName << " the " << game::GetVerbalPlayerAlignment() << ' ';
id::AddName(Name, UNARTICLED);
- return Name;
+
+ festring PanelName;
+ if(!game::IsInWilderness()){
+ PanelName << Name;
+ if(ivanconfig::IsShowFullDungeonName()){
+ PanelName << " (at " << game::GetCurrentDungeon()->GetLevelDescription(game::GetCurrentLevelIndex(), true) << ')';
+ }
+ }
+
+ return PanelName;
}
long character::GetMoveAPRequirement(int Difficulty) const
@@ -7139,7 +8611,10 @@ void character::GetHitByExplosion(const explosion* Explosion, int Damage)
truth Pummeled = ReceiveDamage(Explosion->Terrorist, Explosion->FireOnly ? 0 : (Damage >> 1),
PHYSICAL_DAMAGE, ALL, DamageDirection, true, false, false, false);
- if(Pummeled && GetArea()->IsValidPos(SpillPos))
+ // The ReceiveDamage calls above might cause 'this' to be polymorphed, in which case
+ // SquareUnder[0] is null and calling GetArea or SpillBlood will crash.
+ // See https://github.com/Attnam/ivan/issues/237 for details.
+ if(SquareUnder[0] && Pummeled && GetArea()->IsValidPos(SpillPos))
GetTorso()->SpillBlood((8 - Explosion->Size + RAND() % (8 - Explosion->Size)) >> 1, SpillPos);
festring Msg;
@@ -7261,27 +8736,85 @@ void character::PrintEndGasImmunityMessage() const
ADD_MESSAGE("Yuck! The world smells bad again.");
}
+void inventoryInfo(const character* pC){
+ game::RegionListItemEnable(true);
+ game::RegionSilhouetteEnable(true);
+
+ pC->GetStack()->DrawContents(pC, CONST_S("Your inventory"), REMEMBER_SELECTED);
+
+ for(stackiterator i = pC->GetStack()->GetBottom(); i.HasItem(); ++i)
+ i->DrawContents(pC);
+
+ doforequipmentswithparam()(pC, &item::DrawContents, pC);
+
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
+}
+
void character::ShowAdventureInfo() const
{
- if(GetStack()->GetItems()
- && game::TruthQuestion(CONST_S("Do you want to see your inventory? [y/n]"), REQUIRES_ANSWER))
+ graphics::SetAllowStretchedBlit();
+
+ if(ivanconfig::IsAltAdentureInfo())
+ {
+ ShowAdventureInfoAlt();
+ }
+ else
{
- GetStack()->DrawContents(this, CONST_S("Your inventory"), NO_SELECT);
+ if(GetStack()->GetItems()
+ && game::TruthQuestion(CONST_S("Do you want to see your inventory? [y/n]"), REQUIRES_ANSWER))
+ {
+ inventoryInfo(this);
+ }
- for(stackiterator i = GetStack()->GetBottom(); i.HasItem(); ++i)
- i->DrawContents(this);
+ if(game::TruthQuestion(CONST_S("Do you want to see your message history? [y/n]"), REQUIRES_ANSWER))
+ msgsystem::DrawMessageHistory();
- doforequipmentswithparam()(this, &item::DrawContents, this);
+ if(!game::MassacreListsEmpty()
+ && game::TruthQuestion(CONST_S("Do you want to see your massacre history? [y/n]"), REQUIRES_ANSWER))
+ {
+ game::DisplayMassacreLists();
+ }
}
- if(game::TruthQuestion(CONST_S("Do you want to see your message history? [y/n]"), REQUIRES_ANSWER))
- msgsystem::DrawMessageHistory();
+ graphics::SetDenyStretchedBlit(); //back to menu
+}
+
+void character::ShowAdventureInfoAlt() const
+{
+ while(true) {
+#ifdef WIZARD
+ int Answer =
+ game::KeyQuestion(
+ CONST_S("See (i)nventory, (m)essage history, (k)ill list, (l)ook, (x) cheat look or [ESC]/(n)othing?"),
+ 'z', 13, 'i','I', 'm','M', 'k','K', 'l','L', 'x','X', 'N','n', KEY_ESC); //default answer 'z' is ignored
+#else
+ int Answer =
+ game::KeyQuestion(
+ CONST_S("See (i)nventory, (m)essage history, (k)ill list, (l)ook or [ESC]/(n)othing?"),
+ 'z', 11, 'i','I', 'm','M', 'k','K', 'l','L', 'n','N', KEY_ESC); //default answer 'z' is ignored
+#endif
- if(!game::MassacreListsEmpty()
- && game::TruthQuestion(CONST_S("Do you want to see your massacre history? [y/n]"), REQUIRES_ANSWER))
- game::DisplayMassacreLists();
+ if(Answer == 'i' || Answer == 'I'){
+ inventoryInfo(this);
+ }else if(Answer == 'm' || Answer == 'M'){
+ msgsystem::DrawMessageHistory();
+ }else if(Answer == 'k' || Answer == 'K'){
+ game::DisplayMassacreLists();
+#ifdef WIZARD
+ }else if(Answer == 'l' || Answer == 'L' || Answer == 'x' || Answer == 'X'){
+ commandsystem::PlayerDiedLookMode(Answer == 'x' || Answer == 'X');
+#else
+ }else if(Answer == 'l' || Answer == 'L'){
+ commandsystem::PlayerDiedLookMode();
+#endif
+ }else if(Answer == 'n' || Answer == 'N' || Answer == KEY_ESC){
+ return;
+ }
+ }
}
+
truth character::EditAllAttributes(int Amount)
{
if(!Amount)
@@ -8178,6 +9711,18 @@ void character::EditExperience(int Identifier, double Value, double Speed)
if(IsPlayerKind())
UpdatePictures();
+ break;
+ case WILL_POWER:
+ if(Change > 0)
+ {
+ PlayerMsg = "You feel incredibly stubborn.";
+ NPCMsg = "You notice %s looks much more determined.";
+ }
+ else
+ {
+ PlayerMsg = "You loose your determination.";
+ NPCMsg = "You notice how wimpy %s looks.";
+ }
break;
case CHARISMA:
if(Change > 0)
@@ -8220,8 +9765,18 @@ void character::EditExperience(int Identifier, double Value, double Speed)
PlayerMsg = "You feel your magical abilities withering slowly.";
NPCMsg = "You notice strange vibrations in the air around %s. But they disappear rapidly.";
}
-
break;
+ default:
+ if(Change > 0)
+ {
+ PlayerMsg = "You feel more awesome!";
+ NPCMsg = "You notice how cool %s looks.";
+ }
+ else
+ {
+ PlayerMsg = "You feel a strange sensation, but then it passes.";
+ NPCMsg = "You notice there is something different about %s.";
+ }
}
if(IsPlayer())
@@ -8272,6 +9827,9 @@ int character::GetAttribute(int Identifier, truth AllowBonus) const
if(AllowBonus && Identifier == INTELLIGENCE && BrainsHurt())
return Max((A + AttributeBonus[INTELLIGENCE]) / 3, 1);
+ if(AllowBonus && Identifier == PERCEPTION && IsHeadless())
+ return 0;
+
return A && AllowBonus ? Max(A + AttributeBonus[Identifier], 1) : A;
}
@@ -8323,7 +9881,8 @@ void character::CheckIfSeen()
void character::SignalSeen()
{
if(!(WarnFlags & WARNED)
- && GetRelation(PLAYER) == HOSTILE)
+ && GetRelation(PLAYER) == HOSTILE
+ && !StateIsActivated(FEARLESS))
{
double Danger = GetRelativeDanger(PLAYER);
@@ -8385,8 +9944,36 @@ truth character::CanUseEquipment(int I) const
return CanUseEquipment() && I < GetEquipments() && GetBodyPartOfEquipment(I) && EquipmentIsAllowed(I);
}
-/* Target mustn't have any equipment */
+void character::MemorizeEquipedItems(){DBGCHAR(this,"");
+ int iEqCount=0;
+ for(int c = 0; c < MAX_EQUIPMENT_SLOTS; ++c)
+ {
+ item* Item = NULL;
+ if(CanUseEquipment(c))Item=GetEquipment(c);
+
+ if(Item!=NULL){
+ MemorizedEquippedItemIDs[c]=Item->GetID(); DBGSI(MemorizedEquippedItemIDs[c]);
+ iEqCount++;
+ }else{
+ MemorizedEquippedItemIDs[c]=0;
+ }
+ }
+}
+
+void addPolymorphBkpToVector(character* CharIni,std::vector* pvCharMemory){
+ character* CharMemory = CharIni;
+ while(CharMemory!=NULL){
+ if(std::find(pvCharMemory->begin(), pvCharMemory->end(), CharMemory) == pvCharMemory->end()){ //if not already in vector
+ pvCharMemory->push_back(CharMemory); DBGCHAR(CharMemory,"");
+ }
+
+ CharMemory=CharMemory->GetPolymorphBackup();
+
+ if(CharMemory==CharIni){DBG1("weirdRecurrentPolymorphBkp?");break;} //TODO keep this? just in case some weird thing happens out of here? it probably would mean inconsistency?
+ }
+}
+/* Target mustn't have any equipment */
void character::DonateEquipmentTo(character* Character)
{
if(IsPlayer())
@@ -8415,8 +10002,7 @@ void character::DonateEquipmentTo(character* Character)
else if(EquipmentMemory[c]
&& Character->CanUseEquipment(c))
{
- for(stackiterator i = Character->GetStack()->GetBottom();
- i.HasItem(); ++i)
+ for(stackiterator i = Character->GetStack()->GetBottom(); i.HasItem(); ++i)
if(i->GetID() == EquipmentMemory[c])
{
item* Item = *i;
@@ -8431,10 +10017,36 @@ void character::DonateEquipmentTo(character* Character)
}
else
{
+ bool bImprovedEquipping =
+ ivanconfig::GetMemorizeEquipmentMode()==2 ||
+ (ivanconfig::GetMemorizeEquipmentMode()==1 && IsPet());
+
+ if(bImprovedEquipping)MemorizeEquipedItems();
+
for(int c = 0; c < GetEquipments(); ++c)
{
item* Item = GetEquipment(c);
+ if(bImprovedEquipping && Item==NULL){
+ /**
+ *
+ * Looks as much far as possible for Equipped memories.
+ */
+ std::vector vCharMemory;
+ addPolymorphBkpToVector(Character,&vCharMemory);
+ addPolymorphBkpToVector(this,&vCharMemory); DBGSI(vCharMemory.size());
+
+ /* The target has all items on it's inventory now, so search at it only. */
+ DBGCHAR(Character,""); DBGCHAR(this,"");
+ for(int i=0;iSearchForItem(CharMemory->MemorizedEquippedItemIDs[c]);
+ if(Item!=NULL){
+ DBG5("FoundMemEqAtInv",DBGI(Item->GetID()),DBGI(CharMemory->GetID()),DBGI(this->GetID()),DBGI(Character->GetID()));
+ break;
+ }
+ }
+ }
+
if(Item)
{
if(Character->CanUseEquipment(c))
@@ -8443,7 +10055,13 @@ void character::DonateEquipmentTo(character* Character)
Character->SetEquipment(c, Item);
}
else
- Item->MoveTo(Character->GetStackUnder());
+ {
+ if(bImprovedEquipping){
+ Item->MoveTo(Character->GetStack());
+ }else{
+ Item->MoveTo(Character->GetStackUnder());
+ }
+ }
}
}
}
@@ -8681,8 +10299,9 @@ void character::ReceiveWhiteUnicorn(long Amount)
BeginTemporaryState(TELEPORT, Amount / 100);
DecreaseStateCounter(LYCANTHROPY, -Amount / 100);
DecreaseStateCounter(POISONED, -Amount / 100);
- DecreaseStateCounter(PARASITIZED, -Amount / 100);
+ DecreaseStateCounter(PARASITE_TAPE_WORM, -Amount / 100);
DecreaseStateCounter(LEPROSY, -Amount / 100);
+ DecreaseStateCounter(VAMPIRISM, -Amount / 100);
}
/* Counter should be negative. Removes intrinsics. */
@@ -8723,7 +10342,7 @@ void character::DecreaseStateCounter(long State, int Counter)
truth character::IsImmuneToLeprosy() const
{
- return DataBase->IsImmuneToLeprosy || UseMaterialAttributes();
+ return DataBase->IsImmuneToLeprosy || UseMaterialAttributes() || StateIsActivated(DISEASE_IMMUNITY);
}
void character::LeprosyHandler()
@@ -8739,6 +10358,12 @@ void character::LeprosyHandler()
CheckDeath(CONST_S("killed by leprosy"));
}
+void character::VampirismHandler()
+{
+ EditExperience(WISDOM, -25, 1 << 1);
+ CheckDeath(CONST_S("killed by vampirism"));
+}
+
bodypart* character::SearchForOriginalBodyPart(int I) const
{
for(stackiterator i = GetStackUnder()->GetBottom(); i.HasItem(); ++i)
@@ -8894,7 +10519,7 @@ void character::SignalDisappearance()
truth character::HornOfFearWorks() const
{
- return CanHear() && GetPanicLevel() > RAND() % 33;
+ return CanHear() && GetPanicLevel() > RAND() % 33 && !StateIsActivated(FEARLESS);
}
void character::BeginLeprosy()
@@ -9008,7 +10633,13 @@ truth character::ChatMenu()
truth character::ChangePetEquipment()
{
- if(EquipmentScreen(PLAYER->GetStack(), GetStack()))
+ game::RegionListItemEnable(true);
+ game::RegionSilhouetteEnable(true);
+ bool b = EquipmentScreen(PLAYER->GetStack(), GetStack());
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
+
+ if(b)
{
DexterityAction(3);
return true;
@@ -9026,6 +10657,9 @@ truth character::TakePetItems()
{
itemvector ToTake;
game::DrawEverythingNoBlit();
+
+ game::RegionListItemEnable(true);
+ game::RegionSilhouetteEnable(true);
GetStack()->DrawContents(ToTake,
0,
PLAYER,
@@ -9035,6 +10669,8 @@ truth character::TakePetItems()
GetDescription(DEFINITE) + " is " + GetVerbalBurdenState(),
GetVerbalBurdenStateColor(),
REMEMBER_SELECTED);
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
if(ToTake.empty())
break;
@@ -9064,6 +10700,9 @@ truth character::GivePetItems()
{
itemvector ToGive;
game::DrawEverythingNoBlit();
+
+ game::RegionListItemEnable(true);
+ game::RegionSilhouetteEnable(true);
PLAYER->GetStack()->DrawContents(ToGive,
0,
this,
@@ -9073,6 +10712,8 @@ truth character::GivePetItems()
GetDescription(DEFINITE) + " is " + GetVerbalBurdenState(),
GetVerbalBurdenStateColor(),
REMEMBER_SELECTED);
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
if(ToGive.empty())
break;
@@ -9312,12 +10953,22 @@ truth character::GetNewFormForPolymorphWithControl(character*& NewForm)
festring Topic, Temp;
NewForm = 0;
+ if(StateIsActivated(POLYMORPH_LOCK))
+ {
+ ADD_MESSAGE("You feel uncertain about your body for a moment.");
+ return false;
+ }
+
while(!NewForm)
{
festring Temp;
+ game::RegionListItemEnable(true);
+ game::RegionSilhouetteEnable(true); //polymorphing may unequip items, so taking a look at them is good
int Return = game::DefaultQuestion(Temp, CONST_S("What do you want to become? [press '?' for a list]"),
game::GetDefaultPolymorphTo(), true,
&game::PolymorphControlKeyHandler);
+ game::RegionListItemEnable(false);
+ game::RegionSilhouetteEnable(false);
if(Return == ABORTED)
{
ADD_MESSAGE("You choose not to polymorph.");
@@ -9368,7 +11019,7 @@ liquid* character::CreateSweat(long Volume) const
truth character::TeleportRandomItem(truth TryToHinderVisibility)
{
- if(IsImmuneToItemTeleport())
+ if(IsImmuneToItemTeleport() || StateIsActivated(TELEPORT_LOCK))
return false;
itemvector ItemVector;
@@ -9565,7 +11216,7 @@ void character::PoisonedSituationDangerModifier(double& Danger) const
void character::PolymorphingSituationDangerModifier(double& Danger) const
{
- if(!StateIsActivated(POLYMORPH_CONTROL))
+ if((!StateIsActivated(POLYMORPH_CONTROL)) && (!StateIsActivated(POLYMORPH_LOCK)))
Danger *= 1.5;
}
@@ -9630,11 +11281,6 @@ void character::AddRandomScienceName(festring& String) const
Prefix.Empty();
}
- int L = Prefix.GetSize();
-
- if(L && Prefix[L - 1] == Science[0])
- Science.Erase(0, 1);
-
if(!NoAttrib && !NoSecondAdjective == !RAND_GOOD(3))
{
int S1 = NoSecondAdjective ? 0 : GetScienceTalkAdjectiveAttribute().Size;
@@ -9964,7 +11610,7 @@ truth character::AllowUnconsciousness() const
truth character::CanPanic() const
{
- return !Action || !Action->IsUnconsciousness();
+ return !Action || !Action->IsUnconsciousness() || !StateIsActivated(FEARLESS);
}
int character::GetRandomBodyPart(ulong Possible) const
@@ -10024,6 +11670,14 @@ void character::AddOmmelBoneConsumeEndMessage() const
ADD_MESSAGE("For a moment %s looks extremely ferocious. You shudder.", CHAR_NAME(DEFINITE));
}
+void character::AddLiquidHorrorConsumeEndMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Untold horrors flash before your eyes. The melancholy of the world is on your shoulders!");
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s looks as if the true terror of existence flashed before %s eyes!.", CHAR_NAME(DEFINITE), GetPossessivePronoun().CStr());
+}
+
int character::GetBodyPartSparkleFlags(int) const
{
return ((GetNaturalSparkleFlags() & SKIN_COLOR ? SPARKLING_A : 0)
@@ -10285,67 +11939,66 @@ void character::ApplyAllGodsKnownBonus()
pantheonbook* NewBook = pantheonbook::Spawn();
AddPlace->AddItem(NewBook);
- ADD_MESSAGE("\"MORTAL! BEHOLD THE HOLY SAGA\"");
+ ADD_MESSAGE("\"MORTAL! BEHOLD THE HOLY SAGA!\"");
ADD_MESSAGE("%s materializes near your feet.",
NewBook->CHAR_NAME(INDEFINITE));
}
-void character::ReceiveSirenSong(character* Siren)
+truth character::ReceiveSirenSong(character* Siren)
{
- if(Siren->GetTeam() == GetTeam())
- return;
+ if(Siren->GetRelation(this) != HOSTILE)
+ return false;
if(!RAND_N(4))
{
if(IsPlayer())
- ADD_MESSAGE("The beautiful melody of %s makes you feel sleepy.",
- Siren->CHAR_NAME(DEFINITE));
+ ADD_MESSAGE("The beautiful melody of %s makes you feel sleepy.", Siren->CHAR_NAME(DEFINITE));
else if(CanBeSeenByPlayer())
- ADD_MESSAGE("The beautiful melody of %s makes %s look sleepy.",
- Siren->CHAR_NAME(DEFINITE), CHAR_NAME(DEFINITE));
+ ADD_MESSAGE("The beautiful melody of %s makes %s look sleepy.", Siren->CHAR_NAME(DEFINITE), CHAR_NAME(DEFINITE));
+ else
+ ADD_MESSAGE("You hear a beautiful song.");
Stamina -= (1 + RAND_N(4)) * 10000;
- return;
+ return true;
}
- if(!IsPlayer() && IsCharmable() && !RAND_N(5))
+ if(!IsPlayer() && IsCharmable() && CanTameWithDulcis(Siren) && !RAND_N(5))
{
ChangeTeam(Siren->GetTeam());
- ADD_MESSAGE("%s seems to be totally brainwashed by %s melodies.", CHAR_NAME(DEFINITE),
- Siren->CHAR_NAME(DEFINITE));
- return;
+
+ if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s seems to be totally brainwashed by %s melodies.", CHAR_NAME(DEFINITE), Siren->CHAR_NAME(DEFINITE));
+ else
+ ADD_MESSAGE("You hear a beautiful song.");
+
+ return true;
}
- if(!RAND_N(4))
+ if(!IsImmuneToWhipOfThievery() && !RAND_N(4))
{
item* What = GiveMostExpensiveItem(Siren);
if(What)
{
if(IsPlayer())
- {
- ADD_MESSAGE("%s music persuades you to give %s to %s as a present.",
- Siren->CHAR_NAME(DEFINITE), What->CHAR_NAME(DEFINITE),
- Siren->CHAR_OBJECT_PRONOUN);
- }
- else
- {
+ ADD_MESSAGE("%s song persuades you to give %s to %s as a present.",
+ Siren->CHAR_NAME(DEFINITE), What->CHAR_NAME(DEFINITE), Siren->CHAR_OBJECT_PRONOUN);
+ else if(CanBeSeenByPlayer())
ADD_MESSAGE("%s is persuaded to give %s to %s because of %s beautiful singing.",
- CHAR_NAME(DEFINITE),
- What->CHAR_NAME(INDEFINITE),
- Siren->CHAR_NAME(DEFINITE),
- Siren->CHAR_OBJECT_PRONOUN);
-
- }
+ CHAR_NAME(DEFINITE), What->CHAR_NAME(INDEFINITE), Siren->CHAR_NAME(DEFINITE), Siren->CHAR_OBJECT_PRONOUN);
+ else
+ ADD_MESSAGE("You hear a beautiful song.");
}
else
{
if(IsPlayer())
ADD_MESSAGE("You would like to give something to %s.", Siren->CHAR_NAME(DEFINITE));
+ else
+ ADD_MESSAGE("You hear a beautiful song.");
}
-
- return;
+ return true;
}
+ return false;
}
// return 0, if no item found
@@ -10434,9 +12087,64 @@ character* character::GetNearestEnemy() const
return NearestEnemy;
}
+void character::PrintBeginMindwormedMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("You have a killer headache.");
+}
+
+void character::PrintEndMindwormedMessage() const
+{
+ if(IsPlayer())
+ ADD_MESSAGE("Your headache finally subsides.");
+}
+
truth character::MindWormCanPenetrateSkull(mindworm*) const
{
- return false;
+ if(!(RAND() % 2))
+ return true;
+ else
+ return false;
+}
+
+void character::MindwormedHandler()
+{
+ if(!(RAND() % 200))
+ {
+ if(IsPlayer())
+ ADD_MESSAGE("Your brain hurts!");
+
+ BeginTemporaryState(CONFUSED, 100 + RAND_N(100));
+ return;
+ }
+
+ // Multiple mind worm hatchlings can hatch, because multiple eggs could have been implanted.
+ if(!game::IsInWilderness() && !(RAND() % 500))
+ {
+ character* Spawned = mindworm::Spawn(HATCHLING);
+ v2 Pos = game::GetCurrentLevel()->GetNearestFreeSquare(Spawned, GetPos());
+
+ if(Pos == ERROR_V2)
+ {
+ delete Spawned;
+ return;
+ }
+
+ Spawned->SetTeam(game::GetTeam(MONSTER_TEAM));
+ Spawned->PutTo(Pos);
+
+ if(IsPlayer())
+ {
+ ADD_MESSAGE("%s suddenly digs out of your skull.", Spawned->CHAR_NAME(INDEFINITE));
+ }
+ else if(CanBeSeenByPlayer())
+ {
+ ADD_MESSAGE("%s suddenly digs out of %s's skull.", Spawned->CHAR_NAME(INDEFINITE), CHAR_NAME(DEFINITE));
+ }
+
+ ReceiveDamage(0, 1, DRAIN, HEAD, 8, false, false, false, false); // Use DRAIN here so that AV does not apply.
+ CheckDeath(CONST_S("killed by giving birth to ") + Spawned->GetName(INDEFINITE));
+ }
}
truth character::CanTameWithDulcis(const character* Tamer) const
@@ -10568,3 +12276,177 @@ void character::Slow()
doforequipments()(this, &item::Slow);
BeginTemporaryState(SLOW, 500 + RAND() % 1000);
}
+
+truth character::IsESPBlockedByEquipment() const
+{
+ for(int c = 0; c < GetEquipments(); ++c)
+ {
+ item *Item = GetEquipment(c);
+
+ if (Item && Item->IsHelmet(this) &&
+ ((Item->GetMainMaterial() && Item->GetMainMaterial()->BlockESP()) ||
+ (Item->GetSecondaryMaterial() && Item->GetSecondaryMaterial()->BlockESP())))
+ return !(Item->IsBroken());
+ }
+ return false;
+}
+
+truth character::TemporaryStateIsActivated (long What) const
+{
+ if((What&PANIC) && (TemporaryState&PANIC) && StateIsActivated(FEARLESS))
+ {
+ return ((TemporaryState&What) & (~PANIC));
+ }
+ if((What&ESP) && (TemporaryState&ESP) && IsESPBlockedByEquipment())
+ {
+ return ((TemporaryState&What) & (~ESP));
+ }
+ return (TemporaryState & What);
+}
+
+truth character::StateIsActivated (long What) const
+{
+ if ((What & PANIC) && ((TemporaryState|EquipmentState) & PANIC) && StateIsActivated(FEARLESS))
+ {
+ return ((TemporaryState & What) & (~PANIC)) || ((EquipmentState & What) & (~PANIC));
+ }
+ if ((What & ESP) && ((TemporaryState|EquipmentState) & ESP) && IsESPBlockedByEquipment())
+ {
+ return ((TemporaryState & What) & (~ESP)) || ((EquipmentState & What) & (~ESP));
+ }
+ return (TemporaryState & What) || (EquipmentState & What);
+}
+
+truth character::CheckAIZapOpportunity()
+{
+ if(!CanZap() || !IsHumanoid() || !IsEnabled())
+ return false;
+
+ // Check visible area for hostiles:
+ v2 Pos = GetPos();
+ v2 TestPos;
+ int SensibleRange = 5;
+ int RangeMax = GetLOSRange();
+
+ if(RangeMax < SensibleRange)
+ SensibleRange = RangeMax;
+
+ int CandidateDirections[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ int HostileFound = 0;
+
+ for(int r = 2; r <= SensibleRange; ++r)
+ {
+ for(int dir = 0; dir < 8; ++dir)
+ {
+ switch(dir)
+ {
+ case 0:
+ TestPos = v2(Pos.X - r, Pos.Y - r);
+ break;
+ case 1:
+ TestPos = v2(Pos.X, Pos.Y - r);
+ break;
+ case 2:
+ TestPos = v2(Pos.X + r, Pos.Y - r);
+ break;
+ case 3:
+ TestPos = v2(Pos.X - r, Pos.Y);
+ break;
+ case 4:
+ TestPos = v2(Pos.X + r, Pos.Y);
+ break;
+ case 5:
+ TestPos = v2(Pos.X - r, Pos.Y + r);
+ break;
+ case 6:
+ TestPos = v2(Pos.X, Pos.Y + r);
+ break;
+ case 7:
+ TestPos = v2(Pos.X + r, Pos.Y + r);
+ break;
+ }
+
+ level* Level = GetLevel();
+
+ if(Level->IsValidPos(TestPos))
+ {
+ square* TestSquare = GetNearSquare(TestPos);
+ character* Dude = TestSquare->GetCharacter();
+
+ if((Dude && Dude->IsEnabled() && (GetRelation(Dude) != HOSTILE)
+ && Dude->SquareUnderCanBeSeenBy(this, false)))
+ {
+ CandidateDirections[dir] = BLOCKED;
+ }
+
+ if(Dude && Dude->IsEnabled() && (GetRelation(Dude) == HOSTILE)
+ && Dude->SquareUnderCanBeSeenBy(this, false)
+ && (CandidateDirections[dir] != BLOCKED))
+ {
+ CandidateDirections[dir] = SUCCESS;
+ HostileFound = 1;
+ }
+ }
+ }
+ }
+
+ int ZapDirection = 0;
+ int TargetFound = 0;
+
+ if(HostileFound)
+ {
+ for(uint dir = 0; dir < 8; ++dir)
+ {
+ if((CandidateDirections[dir] == SUCCESS) && !TargetFound)
+ {
+ ZapDirection = dir;
+ TargetFound = 1;
+ }
+ }
+ if(!TargetFound)
+ {
+ return false;
+ }
+ }
+ else
+ return false;
+
+
+ // Check inventory for zappable item.
+ itemvector ItemVector;
+ GetStack()->FillItemVector(ItemVector);
+ item* ToBeZapped = 0;
+
+ for(uint c = 0; c < ItemVector.size(); ++c)
+ if((ItemVector[c]->GetMinCharges() > 0) && ItemVector[c]->GetPrice()) // Empty wands have zero price!
+ {
+ ToBeZapped = ItemVector[c];
+
+ if(!(RAND() % 3)) // Do not always pick the first available wand to zap.
+ break;
+ }
+
+ if(!ToBeZapped)
+ return false;
+
+ if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s zaps %s.", CHAR_NAME(DEFINITE), ToBeZapped->CHAR_NAME(INDEFINITE));
+
+ if(ToBeZapped->Zap(this, GetPos(), ZapDirection))
+ {
+ EditAP(-100000 / APBonus(GetAttribute(PERCEPTION)));
+ return true;
+ }
+ else
+ return false;
+
+ TerminateGoingTo(); // Is this useful here? I don't think the code will ever
+ return true; // get down here.
+
+ // Steps:
+ // (1) - Acquire target as nearest enemy.
+ // (2) - Check that this enemy is in range, and is in appropriate direction.
+ // No friendly fire!
+ // (3) - Check inventory for zappable item.
+ // (4) - Zap item in direction where the enemy is.
+}
diff --git a/Main/Source/command.cpp b/Main/Source/command.cpp
index 3a3714d2f..0650a3dec 100644
--- a/Main/Source/command.cpp
+++ b/Main/Source/command.cpp
@@ -10,24 +10,27 @@
*
*/
-#include "command.h"
+#include "actions.h"
+#include "bitmap.h"
#include "char.h"
-#include "message.h"
+#include "command.h"
+#include "database.h"
+#include "felist.h"
#include "game.h"
-#include "stack.h"
-#include "room.h"
#include "god.h"
-#include "felist.h"
+#include "graphics.h"
+#include "human.h"
#include "iconf.h"
-#include "bitmap.h"
-#include "actions.h"
+#include "materia.h"
+#include "message.h"
#include "miscitem.h"
+#include "room.h"
+#include "stack.h"
+#include "team.h"
+#include "whandler.h"
#include "worldmap.h"
#include "wsquare.h"
#include "wterras.h"
-#include "materia.h"
-#include "database.h"
-#include "team.h"
#ifdef WIZARD
#include "proto.h"
@@ -78,7 +81,8 @@ command* commandsystem::Command[] =
new command(&IssueCommand, "issue command(s) to team member(s)", 'I', 'I', 'I', false),
new command(&Kick, "kick", 'k', 'K', 'K', false),
new command(&Look, "look", 'l', 'L', 'L', true),
- new command(&AssignName, "name", 'n', 'n', 'N', false),
+ new command(&ShowMap, "show map", 'm', 'm', 'm', false),
+ new command(&AssignName , "name", 'n', 'n', 'N', false),
new command(&Offer, "offer", 'O', 'f', 'O', false),
new command(&Open, "open", 'o', 'O', 'o', false),
new command(&PickUp, "pick up", ',', ',', ',', false),
@@ -111,6 +115,7 @@ command* commandsystem::Command[] =
/* Sort according to key */
+ new command(&AutoPlay, "auto play the game (hold ESC to stop)", '~', '~', '~', true, true), //there is more AI than NPC's one to let it work better
new command(&RaiseStats, "raise stats", '1', '1', '1', true, true),
new command(&LowerStats, "lower stats", '2', '2', '2', true, true),
new command(&SeeWholeMap, "see whole map", '3', '3', '3', true, true),
@@ -132,6 +137,127 @@ command* commandsystem::Command[] =
0
};
+truth commandsystem::IsForRegionListItem(int iIndex){ //see code generator helper script prepareCmdsDescrCode.sh (use cygwin)
+ cchar* str = Command[iIndex]->GetDescription();
+ if(strcmp(str,"apply")==0)return true;
+// if(strcmp(str,"chat")==0)return true;
+// if(strcmp(str,"close")==0)return true;
+ if(strcmp(str,"dip")==0)return true;
+ if(strcmp(str,"drink")==0)return true;
+ if(strcmp(str,"drop")==0)return true;
+ if(strcmp(str,"eat")==0)return true;
+// if(strcmp(str,"engrave")==0)return true;
+ if(strcmp(str,"equipment menu")==0)return true;
+// if(strcmp(str,"go")==0)return true;
+// if(strcmp(str,"go down/enter area")==0)return true;
+// if(strcmp(str,"go up")==0)return true;
+// if(strcmp(str,"issue command(s) to team member(s)")==0)return true;
+// if(strcmp(str,"kick")==0)return true;
+// if(strcmp(str,"look")==0)return true;
+// if(strcmp(str,"name")==0)return true;
+ if(strcmp(str,"offer")==0)return true;
+ if(strcmp(str,"open")==0)return true;
+ if(strcmp(str,"pick up")==0)return true;
+ if(strcmp(str,"pray")==0)return true;
+// if(strcmp(str,"quit")==0)return true;
+ if(strcmp(str,"read")==0)return true;
+// if(strcmp(str,"rest/heal")==0)return true;
+// if(strcmp(str,"save game")==0)return true;
+// if(strcmp(str,"scroll messages down")==0)return true;
+// if(strcmp(str,"scroll messages up")==0)return true;
+// if(strcmp(str,"show config screen")==0)return true;
+// if(strcmp(str,"show inventory")==0)return true;
+// if(strcmp(str,"show key layout")==0)return true;
+// if(strcmp(str,"show message history")==0)return true;
+// if(strcmp(str,"show weapon skills")==0)return true;
+// if(strcmp(str,"search")==0)return true;
+// if(strcmp(str,"sit")==0)return true;
+ if(strcmp(str,"throw")==0)return true;
+// if(strcmp(str,"toggle running")==0)return true;
+// if(strcmp(str,"vomit")==0)return true;
+// if(strcmp(str,"wait")==0)return true;
+ if(strcmp(str,"wield in right arm")==0)return true;
+ if(strcmp(str,"wield in left arm")==0)return true;
+// if(strcmp(str,"wizard mode activation")==0)return true;
+ if(strcmp(str,"zap")==0)return true;
+// if(strcmp(str,"raise stats")==0)return true;
+// if(strcmp(str,"lower stats")==0)return true;
+// if(strcmp(str,"see whole map")==0)return true;
+// if(strcmp(str,"toggle walk through walls mode")==0)return true;
+// if(strcmp(str,"raise your relations to the gods")==0)return true;
+// if(strcmp(str,"lower your relations to the gods")==0)return true;
+// if(strcmp(str,"gain knowledge of all gods")==0)return true;
+// if(strcmp(str,"gain all items")==0)return true;
+// if(strcmp(str,"reveal secret knowledge")==0)return true;
+// if(strcmp(str,"detach a limb")==0)return true;
+// if(strcmp(str,"set fire to a limb")==0)return true;
+// if(strcmp(str,"summon monster")==0)return true;
+// if(strcmp(str,"level teleport")==0)return true;
+// if(strcmp(str,"possess creature")==0)return true;
+ if(strcmp(str,"polymorph")==0)return true;
+ return false;
+}
+truth commandsystem::IsForRegionSilhouette(int iIndex){ //see code generator helper script prepareCmdsDescrCode.sh (use cygwin)
+ cchar* str = Command[iIndex]->GetDescription();
+ if(strcmp(str,"apply")==0)return true;
+// if(strcmp(str,"chat")==0)return true;
+// if(strcmp(str,"close")==0)return true;
+ if(strcmp(str,"dip")==0)return true;
+ if(strcmp(str,"drink")==0)return true;
+ if(strcmp(str,"drop")==0)return true;
+ if(strcmp(str,"eat")==0)return true;
+// if(strcmp(str,"engrave")==0)return true;
+ if(strcmp(str,"equipment menu")==0)return true;
+// if(strcmp(str,"go")==0)return true;
+// if(strcmp(str,"go down/enter area")==0)return true;
+// if(strcmp(str,"go up")==0)return true;
+// if(strcmp(str,"issue command(s) to team member(s)")==0)return true;
+// if(strcmp(str,"kick")==0)return true;
+// if(strcmp(str,"look")==0)return true;
+// if(strcmp(str,"name")==0)return true;
+ if(strcmp(str,"offer")==0)return true;
+ if(strcmp(str,"open")==0)return true;
+ if(strcmp(str,"pick up")==0)return true;
+ if(strcmp(str,"pray")==0)return true;
+// if(strcmp(str,"quit")==0)return true;
+ if(strcmp(str,"read")==0)return true;
+// if(strcmp(str,"rest/heal")==0)return true;
+// if(strcmp(str,"save game")==0)return true;
+// if(strcmp(str,"scroll messages down")==0)return true;
+// if(strcmp(str,"scroll messages up")==0)return true;
+// if(strcmp(str,"show config screen")==0)return true;
+ if(strcmp(str,"show inventory")==0)return true;
+// if(strcmp(str,"show key layout")==0)return true;
+// if(strcmp(str,"show message history")==0)return true;
+// if(strcmp(str,"show weapon skills")==0)return true;
+// if(strcmp(str,"search")==0)return true;
+// if(strcmp(str,"sit")==0)return true;
+ if(strcmp(str,"throw")==0)return true;
+// if(strcmp(str,"toggle running")==0)return true;
+// if(strcmp(str,"vomit")==0)return true;
+// if(strcmp(str,"wait")==0)return true;
+ if(strcmp(str,"wield in right arm")==0)return true;
+ if(strcmp(str,"wield in left arm")==0)return true;
+// if(strcmp(str,"wizard mode activation")==0)return true;
+ if(strcmp(str,"zap")==0)return true;
+// if(strcmp(str,"raise stats")==0)return true;
+// if(strcmp(str,"lower stats")==0)return true;
+// if(strcmp(str,"see whole map")==0)return true;
+// if(strcmp(str,"toggle walk through walls mode")==0)return true;
+// if(strcmp(str,"raise your relations to the gods")==0)return true;
+// if(strcmp(str,"lower your relations to the gods")==0)return true;
+// if(strcmp(str,"gain knowledge of all gods")==0)return true;
+// if(strcmp(str,"gain all items")==0)return true;
+// if(strcmp(str,"reveal secret knowledge")==0)return true;
+// if(strcmp(str,"detach a limb")==0)return true;
+// if(strcmp(str,"set fire to a limb")==0)return true;
+// if(strcmp(str,"summon monster")==0)return true;
+// if(strcmp(str,"level teleport")==0)return true;
+// if(strcmp(str,"possess creature")==0)return true;
+ if(strcmp(str,"polymorph")==0)return true;
+ return false;
+}
+
truth commandsystem::GoUp(character* Char)
{
if(!Char->TryToUnStickTraps(ZERO_V2))
@@ -288,8 +414,9 @@ truth commandsystem::Open(character* Char)
v2 DirVect = game::GetDirectionVectorForKey(Key);
- if(DirVect != ERROR_V2 && Char->GetArea()->IsValidPos(Char->GetPos() + DirVect))
+ if(DirVect != ERROR_V2 && Char->GetArea()->IsValidPos(Char->GetPos() + DirVect)){
return Char->GetNearLSquare(Char->GetPos() + DirVect)->Open(Char);
+ }
}
else
ADD_MESSAGE("This monster type cannot open anything.");
@@ -420,34 +547,43 @@ truth commandsystem::Drop(character* Char)
truth commandsystem::Eat(character* Char)
{
- if(!Char->CheckConsume(CONST_S("eat")))
+ if(!Char->CheckConsume(CONST_S("eat"))){
return false;
+ }
lsquare* Square = Char->GetLSquareUnder();
if(!game::IsInWilderness() && Square->GetOLTerrain() && Square->GetOLTerrain()->HasEatEffect())
{
- if(Square->GetOLTerrain()->Eat(Char))
+ if(Square->GetOLTerrain()->Eat(Char)){
return true;
+ }
}
- return Consume(Char, "eat", "eating", &item::IsEatable);
+ bool b=Consume(Char, "eat", &item::IsEatable);
+
+ return b;
}
truth commandsystem::Drink(character* Char)
{
- if(!Char->CheckConsume(CONST_S("drink")))
+
+ if(!Char->CheckConsume(CONST_S("drink"))){
return false;
+ }
lsquare* Square = Char->GetLSquareUnder();
if(!game::IsInWilderness() && Square->GetOLTerrain() && Square->GetOLTerrain()->HasDrinkEffect())
{
- if(Square->GetOLTerrain()->Drink(Char))
+ if(Square->GetOLTerrain()->Drink(Char)){
return true;
+ }
}
- return Consume(Char, "drink", "drinking", &item::IsDrinkable);
+ bool b=Consume(Char, "drink", &item::IsDrinkable);
+
+ return b;
}
truth commandsystem::Taste(character* Char)
@@ -497,11 +633,13 @@ truth commandsystem::ShowInventory(character* Char)
Title << Char->GetStack()->GetWeight();
Title << "g)";
Char->GetStack()->DrawContents(Char, Title, NO_SELECT);
+
return false;
}
truth commandsystem::PickUp(character* Char)
{
+
if(!Char->GetStackUnder()->GetVisibleItems(Char))
{
ADD_MESSAGE("There is nothing here to pick up!");
@@ -529,8 +667,9 @@ truth commandsystem::PickUp(character* Char)
Amount = game::ScrollBarQuestion(CONST_S("How many ") + PileVector[0][0]->GetName(PLURAL) + '?',
Amount, 1, 0, Amount, 0, WHITE, LIGHT_GRAY, DARK_GRAY);
- if(!Amount)
+ if(!Amount){
return false;
+ }
if((!PileVector[0][0]->GetRoom()
|| PileVector[0][0]->GetRoom()->PickupItem(Char, PileVector[0][0], Amount))
@@ -544,7 +683,9 @@ truth commandsystem::PickUp(character* Char)
return true;
}
else
+ {
return false;
+ }
}
else
{
@@ -638,7 +779,7 @@ truth commandsystem::Talk(character* Char)
return ToTalk->ChatMenu();
else
{
- int Dir = game::DirectionQuestion(CONST_S("To whom do you wish to talk to? [press a direction key]"), false, true);
+ int Dir = game::DirectionQuestion(CONST_S("To whom do you wish to talk? [press a direction key]"), false, true);
if(Dir == DIR_ERROR || !Char->GetArea()->IsValidPos(Char->GetPos() + game::GetMoveVector(Dir)))
return false;
@@ -674,6 +815,7 @@ truth commandsystem::Save(character*)
if(game::TruthQuestion(CONST_S("Do you truly wish to save and flee? [y/N]")))
{
game::Save();
+ game::SRegionAroundDisable();
game::End("", false);
return true;
}
@@ -707,6 +849,7 @@ truth commandsystem::Read(character* Char)
truth commandsystem::Dip(character* Char)
{
+
if(!Char->GetStack()->SortedItems(Char, &item::IsDippable) && !Char->EquipsSomething(&item::IsDippable))
{
ADD_MESSAGE("You have nothing to dip!");
@@ -741,10 +884,13 @@ truth commandsystem::Dip(character* Char)
+ "? [press a direction key or '.']", false, true);
v2 Pos = Char->GetPos() + game::GetMoveVector(Dir);
- if(Dir == DIR_ERROR || !Char->GetArea()->IsValidPos(Pos) || !Char->GetNearLSquare(Pos)->IsDipDestination())
+ if(Dir == DIR_ERROR || !Char->GetArea()->IsValidPos(Pos) || !Char->GetNearLSquare(Pos)->IsDipDestination()){
return false;
+ }
- return Char->GetNearLSquare(Pos)->DipInto(Item, Char);
+ bool b = Char->GetNearLSquare(Pos)->DipInto(Item, Char);
+
+ return b;
}
else
{
@@ -804,18 +950,36 @@ truth commandsystem::ShowKeyLayout(character*)
return false;
}
+void commandsystem::PlayerDiedLookMode(bool bSeeWholeMapCheatMode){
+ //TODO why this does not work??? if(!PLAYER->IsDead())return;
+#ifdef WIZARD
+ if(bSeeWholeMapCheatMode && !game::GetSeeWholeMapCheatMode()){
+ game::SeeWholeMap(); //1
+ game::SeeWholeMap(); //2
+ }
+#endif
+ commandsystem::Look(PLAYER);
+}
+
truth commandsystem::Look(character* Char)
{
- festring Msg;
- if(!game::IsInWilderness())
- Char->GetLevel()->AddSpecialCursors();
+ festring Msg; //DBG1(Char->GetSquareUnder());
+ if(!game::IsInWilderness()){
+ if(Char->GetSquareUnder()==NULL){ //dead (removed) Char (actually PlayerDiedLookMode())
+ game::GetCurrentLevel()->AddSpecialCursors(); //TODO isnt, this alone, enough?
+ }else{
+ Char->GetLevel()->AddSpecialCursors();
+ }
+ }
if(!game::IsInWilderness())
Msg = CONST_S("Direction keys move cursor, ESC exits, 'i' examines items, 'c' examines a character.");
else
Msg = CONST_S("Direction keys move cursor, ESC exits, 'c' examines a character.");
- game::PositionQuestion(Msg, Char->GetPos(), &game::LookHandler, &game::LookKeyHandler, ivanconfig::GetLookZoom());
+ v2 pos = Char->GetPosSafely();
+ if(pos.Is0())pos = game::GetCamera()+v2(game::GetScreenXSize(),game::GetScreenYSize())/2; // gum: this may happen if player died, the probably position is around screen center, if it is not good enough just deny it and add a log message saying unable to.
+ game::PositionQuestion(Msg,pos,&game::LookHandler, &game::LookKeyHandler, ivanconfig::GetLookZoom());
game::RemoveSpecialCursors();
return false;
}
@@ -828,10 +992,50 @@ truth commandsystem::WhatToEngrave(character* Char)
return false;
}
- festring What;
+ int Key = 0;
+ while(!(Key == KEY_ESC || Key == ' '))
+ {
+ Key = game::AskForKeyPress(CONST_S("Where do you want to engrave? "
+ "'.' square, 'i' inventory, ESC exits"));
- if(game::StringQuestion(What, CONST_S("What do you want to engrave here?"), WHITE, 0, 80, true) == NORMAL_EXIT)
- Char->GetNearLSquare(Char->GetPos())->Engrave(What);
+ if(Key == '.')
+ {
+ festring What;
+
+ if(game::StringQuestion(What, CONST_S("What do you want to engrave here?"), WHITE, 0, 80, true) == NORMAL_EXIT)
+ Char->GetNearLSquare(Char->GetPos())->Engrave(What);
+
+ break;
+ }
+
+ if(Key == 'i')
+ {
+ if(!Char->GetStack()->GetItems())
+ {
+ ADD_MESSAGE("You have nothing to inscribe on!");
+ return false;
+ }
+
+ stack::SetSelected(0);
+
+ for(;;)
+ {
+ itemvector ToAddLabel;
+ game::DrawEverythingNoBlit();
+ Char->GetStack()->DrawContents(ToAddLabel, Char, CONST_S("What item do you want to inscribe on?"), REMEMBER_SELECTED);
+
+ if(ToAddLabel.empty())
+ break;
+
+ festring What = ToAddLabel[0]->GetLabel();
+ if(game::StringQuestion(What, CONST_S("What would you like to inscribe on this item?"), WHITE, 0, 20, true) == NORMAL_EXIT)
+ for(int i=0;iSetLabel(What);
+ }
+
+ break;
+ }
+ }
return false;
}
@@ -852,10 +1056,14 @@ truth commandsystem::Pray(character* Char)
if(!DivineMaster)
{
+ festring desc;
for(int c = 1; c <= GODS; ++c)
if(game::GetGod(c)->IsKnown())
{
- Panthenon.AddEntry(game::GetGod(c)->GetCompleteDescription(), LIGHT_GRAY, 20, c);
+ desc.Empty();
+ desc << game::GetGod(c)->GetCompleteDescription();
+ if(ivanconfig::IsShowGodInfo())desc << " ("<GetDescription()<<")";
+ Panthenon.AddEntry(desc, LIGHT_GRAY, 20, c);
Known[Index++] = c;
}
}
@@ -1018,8 +1226,10 @@ truth commandsystem::DrawMessageHistory(character*)
truth commandsystem::Throw(character* Char)
{
- if(!Char->CheckThrow())
+
+ if(!Char->CheckThrow()){
return false;
+ }
if(!Char->GetStack()->GetItems())
{
@@ -1034,8 +1244,9 @@ truth commandsystem::Throw(character* Char)
int Answer = game::DirectionQuestion(CONST_S("In what direction do you wish to throw? "
"[press a direction key]"), false);
- if(Answer == DIR_ERROR)
+ if(Answer == DIR_ERROR){
return false;
+ }
Char->ThrowItem(Answer, Item);
Char->EditExperience(ARM_STRENGTH, 75, 1 << 8);
@@ -1046,19 +1257,23 @@ truth commandsystem::Throw(character* Char)
return true;
}
else
+ {
return false;
+ }
}
truth commandsystem::Apply(character* Char)
{
+
if(!Char->CanApply())
{
ADD_MESSAGE("This monster type cannot apply.");
return false;
}
- if(!Char->CheckApply())
+ if(!Char->CheckApply()){
return false;
+ }
if(!Char->PossessesItem(&item::IsAppliable))
{
@@ -1067,7 +1282,9 @@ truth commandsystem::Apply(character* Char)
}
item* Item = Char->SelectFromPossessions(CONST_S("What do you want to apply?"), &item::IsAppliable);
- return Item && Item->Apply(Char);
+ bool b = Item && Item->Apply(Char);
+
+ return b;
}
truth commandsystem::ForceVomit(character* Char)
@@ -1105,8 +1322,10 @@ truth commandsystem::ForceVomit(character* Char)
truth commandsystem::Zap(character* Char)
{
- if(!Char->CheckZap())
+
+ if(!Char->CheckZap()){
return false;
+ }
if(!Char->PossessesItem(&item::IsZappable))
{
@@ -1121,8 +1340,9 @@ truth commandsystem::Zap(character* Char)
int Answer = game::DirectionQuestion(CONST_S("In what direction do you wish to zap? "
"[press a direction key or '.']"), false, true);
- if(Answer == DIR_ERROR)
+ if(Answer == DIR_ERROR){
return false;
+ }
if(Item->Zap(Char, Char->GetPos(), Answer))
{
@@ -1130,10 +1350,14 @@ truth commandsystem::Zap(character* Char)
return true;
}
else
+ {
return false;
+ }
}
else
+ {
return false;
+ }
}
truth commandsystem::Rest(character* Char)
@@ -1202,6 +1426,22 @@ truth commandsystem::Rest(character* Char)
return true;
}
+truth commandsystem::ShowMap(character* Char)
+{
+ static humanoid* h;h = dynamic_cast(PLAYER);
+
+ if( h && (h->GetLeftArm() || h->GetRightArm()) ){
+ if(game::ToggleDrawMapOverlay()){
+ while(!game::TruthQuestion(festring("Hit a key to close your map."), YES, 'm'));
+ game::ToggleDrawMapOverlay();
+ }
+ }else{
+ ADD_MESSAGE("I can't hold the map!");
+ }
+
+ return true;
+}
+
truth commandsystem::Sit(character* Char)
{
lsquare* Square = Char->GetLSquareUnder();
@@ -1335,6 +1575,7 @@ truth commandsystem::WieldInRightArm(character* Char)
truth commandsystem::WieldInLeftArm(character* Char)
{
+
if(!Char->CanUseEquipment())
ADD_MESSAGE("You cannot wield anything.");
else if(Char->TryToChangeEquipment(Char->GetStack(), 0, LEFT_WIELDED_INDEX))
@@ -1368,11 +1609,11 @@ truth commandsystem::WizardMode(character* Char)
v2 ElpuriCavePos = game::GetWorldMap()->GetEntryPos(0, ELPURI_CAVE);
game::GetWorldMap()->GetWSquare(ElpuriCavePos)->ChangeOWTerrain(elpuricave::Spawn());
game::GetWorldMap()->RevealEnvironment(ElpuriCavePos, 1);
-
+
v2 XinrochTombPos = game::GetWorldMap()->GetEntryPos(0, XINROCH_TOMB);
game::GetWorldMap()->GetWSquare(XinrochTombPos)->ChangeOWTerrain(locationAW::Spawn());
game::GetWorldMap()->RevealEnvironment(XinrochTombPos, 1);
-
+
game::GetWorldMap()->SendNewDrawRequest();
}
else
@@ -1381,11 +1622,11 @@ truth commandsystem::WizardMode(character* Char)
v2 ElpuriCavePos = game::GetWorldMap()->GetEntryPos(0, ELPURI_CAVE);
game::GetWorldMap()->GetWSquare(ElpuriCavePos)->ChangeOWTerrain(elpuricave::Spawn());
game::GetWorldMap()->RevealEnvironment(ElpuriCavePos, 1);
-
+
v2 XinrochTombPos = game::GetWorldMap()->GetEntryPos(0, XINROCH_TOMB);
game::GetWorldMap()->GetWSquare(XinrochTombPos)->ChangeOWTerrain(locationAW::Spawn());
game::GetWorldMap()->RevealEnvironment(XinrochTombPos, 1);
-
+
game::SaveWorldMap();
}
@@ -1404,6 +1645,12 @@ truth commandsystem::WizardMode(character* Char)
return false;
}
+truth commandsystem::AutoPlay(character* Char)
+{
+ game::IncAutoPlayMode();
+ return false;
+}
+
truth commandsystem::RaiseStats(character* Char)
{
Char->EditAllAttributes(1);
@@ -1621,7 +1868,7 @@ truth commandsystem::SecretKnowledge(character* Char)
std::vector Material;
protosystem::CreateEveryMaterial(Material);
List.SetPageLength(30);
- List.AddDescription(CONST_S(" Strength Flexibility Density"));
+ List.AddDescription(CONST_S(" Str. Flex. Dens. Int. God"));
for(c = 0; c < Material.size(); ++c)
{
@@ -1629,10 +1876,14 @@ truth commandsystem::SecretKnowledge(character* Char)
Material[c]->AddName(Entry, false, false);
Entry.Resize(40);
Entry << Material[c]->GetStrengthValue();
- Entry.Resize(55);
+ Entry.Resize(46);
Entry << Material[c]->GetFlexibility();
- Entry.Resize(70);
+ Entry.Resize(52);
Entry << Material[c]->GetDensity();
+ Entry.Resize(58);
+ Entry << Material[c]->GetIntelligenceRequirement();
+ Entry.Resize(64);
+ Entry << game::GetGod(Material[c]->GetAttachedGod())->GetName();
List.AddEntry(Entry, Material[c]->GetColor());
}
@@ -1721,8 +1972,9 @@ truth commandsystem::Polymorph(character* Char)
{
character* NewForm;
- if(!Char->GetNewFormForPolymorphWithControl(NewForm))
+ if(!Char->GetNewFormForPolymorphWithControl(NewForm)){
return true;
+ }
Char->Polymorph(NewForm, game::NumberQuestion(CONST_S("For how long?"), WHITE));
return true;
diff --git a/Main/Source/database.cpp b/Main/Source/database.cpp
index 6b92dc962..e60f1f27c 100644
--- a/Main/Source/database.cpp
+++ b/Main/Source/database.cpp
@@ -71,7 +71,7 @@ template void databasecreator::ReadFrom(inputfile& SaveFile)
//
std::stack infStack;
infStack.push(&SaveFile);
- while (!infStack.empty())
+ while (!infStack.empty())
{
inputfile *inFile = infStack.top();
infStack.pop();
@@ -151,7 +151,7 @@ template void databasecreator::ReadFrom(inputfile& SaveFile)
ConfigDataBase->InitDefaults(Proto, ConfigNumber);
TempConfig[Configs++] = ConfigDataBase;
if (inFile->ReadWord() != "{") ABORT("Bracket missing in %s datafile line %ld!", protocontainer::GetMainClassID(), inFile->TellLine());
- for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word))
+ for (inFile->ReadWord(Word); Word != "}"; inFile->ReadWord(Word))
{
if (!AnalyzeData(*inFile, Word, *ConfigDataBase)) ABORT("Illegal datavalue %s found while building up %s config #%d, line %ld!", Word.CStr(), Proto->GetClassID(), ConfigNumber, inFile->TellLine());
}
@@ -355,6 +355,7 @@ template<> void databasecreator::CreateDataBaseMemberMap()
ADD_MEMBER(PoisonResistance);
ADD_MEMBER(ElectricityResistance);
ADD_MEMBER(AcidResistance);
+ ADD_MEMBER(SoundResistance);
ADD_MEMBER(IsUnique);
ADD_MEMBER(ConsumeFlags);
ADD_MEMBER(TotalVolume);
@@ -395,6 +396,7 @@ template<> void databasecreator::CreateDataBaseMemberMap()
ADD_MEMBER(BaseUnarmedStrength);
ADD_MEMBER(BaseBiteStrength);
ADD_MEMBER(BaseKickStrength);
+ ADD_MEMBER(BonusBiteStrength);
ADD_MEMBER(AttackStyle);
ADD_MEMBER(CanUseEquipment);
ADD_MEMBER(CanKick);
@@ -518,10 +520,12 @@ template<> void databasecreator
- ::CreateDataBaseMemberMap()
ADD_MEMBER(IsPolymorphSpawnable);
ADD_MEMBER(IsAutoInitializable);
ADD_MEMBER(Category);
+ ADD_MEMBER(EnergyResistance);
ADD_MEMBER(FireResistance);
ADD_MEMBER(PoisonResistance);
ADD_MEMBER(ElectricityResistance);
ADD_MEMBER(AcidResistance);
+ ADD_MEMBER(SoundResistance);
ADD_MEMBER(StrengthModifier);
ADD_MEMBER(FormModifier);
ADD_MEMBER(DefaultSize);
@@ -741,10 +745,12 @@ template<> void databasecreator::CreateDataBaseMemberMap()
ADD_MEMBER(Acidicity);
ADD_MEMBER(NaturalForm);
ADD_MEMBER(HardenedMaterial);
+ ADD_MEMBER(SoftenedMaterial);
ADD_MEMBER(IntelligenceRequirement);
ADD_MEMBER(Stickiness);
ADD_MEMBER(DisablesPanicWhenConsumed);
ADD_MEMBER(FireResistance);
+ ADD_MEMBER(BlockESP);
}
#define ADD_BASE_VALUE(name)\
diff --git a/Main/Source/dungeon.cpp b/Main/Source/dungeon.cpp
index d06562a86..909a1d2dc 100644
--- a/Main/Source/dungeon.cpp
+++ b/Main/Source/dungeon.cpp
@@ -18,8 +18,8 @@
#include "save.h"
#include "femath.h"
#include "bitmap.h"
+#include "graphics.h"
#include "message.h"
-
#include "audio.h"
dungeon::dungeon(int Index) : Index(Index)
@@ -76,6 +76,8 @@ const levelscript* dungeon::GetLevelScript(int I)
truth dungeon::PrepareLevel(int Index, truth Visual)
{
+ graphics::SetDenyStretchedBlit();
+
if(Generated[Index])
{
level* NewLevel = LoadLevel(game::SaveName(), Index);
@@ -134,8 +136,7 @@ void dungeon::PrepareMusic(int Index)
{
const levelscript* LevelScript = GetLevelScript(Index);
bool hasCurrentTrack = false;
- char* CurrentTrack = audio::GetCurrentlyPlayedFile();
-
+ cchar* CurrentTrack = audio::GetCurrentlyPlayedFile();
for( int i = 0; i < LevelScript->GetAudioPlayList()->Size; ++i )
{
@@ -220,12 +221,26 @@ int dungeon::GetLevels() const
return *DungeonScript->GetLevels();
}
-festring dungeon::GetLevelDescription(int I)
+festring dungeon::GetLevelDescription(int I,bool bPretty)
{
- if(GetLevel(I)->GetLevelScript()->GetDescription())
+ if(GetLevel(I)->GetLevelScript()->GetDescription()){
return *GetLevel(I)->GetLevelScript()->GetDescription();
- else
- return *DungeonScript->GetDescription() + " level " + (I + 1);
+ }else{
+ festring fs = *DungeonScript->GetDescription();
+ int i = I+1;
+
+ if(bPretty){
+ festring fsRoman;
+ const char* X[] = {"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
+ fsRoman << X[(i%100)/10];
+ const char* I[] = {"","I","II","III","IV","V","VI","VII","VIII","IX"};
+ fsRoman << I[(i%10)];
+
+ return fs + " " + fsRoman;
+ }else{
+ return fs + " level " + i;
+ }
+ }
}
festring dungeon::GetShortLevelDescription(int I)
diff --git a/Main/Source/fluid.cpp b/Main/Source/fluid.cpp
index 5b12affcb..bec487267 100644
--- a/Main/Source/fluid.cpp
+++ b/Main/Source/fluid.cpp
@@ -336,7 +336,7 @@ void fluid::SetMotherItem(item* What)
}
/* Ensures the gear pictures are correct after this. ShadowPos is the armor's
- or weapon's BitmapPos in humanoid.pcx. SpecialFlags should include drawing
+ or weapon's BitmapPos in Humanoid.png. SpecialFlags should include drawing
information of the bodypart in question (ST_RIGHT_ARM etc). BodyArmor should
be true iff the picture is part of a body armor, for instance armor covering
one's shoulder. */
diff --git a/Main/Source/game.cpp b/Main/Source/game.cpp
index a9e854cd7..e5824e446 100644
--- a/Main/Source/game.cpp
+++ b/Main/Source/game.cpp
@@ -12,6 +12,11 @@
#include
#include
+#include
+#include
+#include
+#include
+#include
#if defined(UNIX) || defined(__DJGPP__)
#include
@@ -21,39 +26,45 @@
#include
#endif
-#include "whandler.h"
-#include "hscore.h"
-#include "rawbit.h"
-#include "message.h"
-#include "feio.h"
-#include "team.h"
-#include "iconf.h"
#include "allocate.h"
-#include "pool.h"
-#include "god.h"
-#include "proto.h"
-#include "stack.h"
+#include "action.h"
+#include "area.h"
+#include "audio.h"
+#include "balance.h"
+#include "bitmap.h"
+#include "confdef.h"
+#include "feio.h"
#include "felist.h"
-#include "human.h"
-#include "nonhuman.h"
-#include "wsquare.h"
+#include "fetime.h"
#include "game.h"
+#include "gear.h"
+#include "god.h"
#include "graphics.h"
-#include "bitmap.h"
-#include "save.h"
-#include "miscitem.h"
-#include "room.h"
+#include "hscore.h"
+#include "human.h"
+#include "iconf.h"
+#include "lterras.h"
#include "materias.h"
+#include "message.h"
+#include "miscitem.h"
+#include "nonhuman.h"
+#include "pool.h"
+#include "proto.h"
#include "rain.h"
-#include "gear.h"
-#include "fetime.h"
-#include "balance.h"
-#include "confdef.h"
+#include "rawbit.h"
+#include "room.h"
+#include "save.h"
+#include "stack.h"
+#include "team.h"
+#include "whandler.h"
+#include "wsquare.h"
+#include "namegen.h"
-#include "audio.h"
+#define DBGMSG_BLITDATA
+#include "dbgmsgproj.h"
-#define SAVE_FILE_VERSION 128 // Increment this if changes make savefiles incompatible
-#define BONE_FILE_VERSION 114 // Increment this if changes make bonefiles incompatible
+#define SAVE_FILE_VERSION 132 // Increment this if changes make savefiles incompatible
+#define BONE_FILE_VERSION 117 // Increment this if changes make bonefiles incompatible
#define LOADED 0
#define NEW_GAME 1
@@ -111,6 +122,7 @@ int game::LastAttributeChangeTick[ATTRIBUTES];
int game::NecroCounter;
int game::CursorData;
truth game::CausePanicFlag;
+//int game::iListWidth = 652;
truth game::Loading = false;
truth game::JumpToPlayerBe = false;
@@ -121,7 +133,6 @@ time_t game::LastLoad;
time_t game::GameBegan;
truth game::PlayerHasReceivedAllGodsKnownBonus;
-festring game::AutoSaveFileName = game::GetSaveDir() + "AutoSave";
cchar* const game::Alignment[] = { "L++", "L+", "L", "L-", "N+", "N=", "N-", "C+", "C", "C-", "C--" };
god** game::God;
@@ -167,6 +178,7 @@ festring game::DefaultWish;
festring game::DefaultChangeMaterial;
festring game::DefaultDetectMaterial;
truth game::WizardMode;
+int game::AutoPlayMode=0;
int game::SeeWholeMapCheatMode;
truth game::GoThroughWallsCheat;
int game::QuestMonstersFound;
@@ -179,6 +191,83 @@ std::vector game::SpecialCursorData;
cbitmap* game::EnterImage;
v2 game::EnterTextDisplacement;
+int iMaxXSize=0;
+int iMaxYSize=0;
+int iXSize=0;
+int iYSize=0;
+
+int iRegionAroundXBRZ = -1;
+int iRegionSilhouette = -1;
+int iRegionVanillaSilhouette = -1;
+int iRegionIndexDungeon = -1;
+int iRegionListItem = -1;
+int iRegionItemsUnder = -1;
+
+blitdata game::bldAroundOnScreenTMP = DEFAULT_BLITDATA;
+blitdata bldFullDungeonTMP = DEFAULT_BLITDATA;
+blitdata bldSilhouetteTMP = DEFAULT_BLITDATA;
+blitdata bldVanillaSilhouetteTMP = DEFAULT_BLITDATA;
+blitdata bldListItemTMP = DEFAULT_BLITDATA;
+
+int iItemsUnderStretch = 2;
+
+int iZoomFactor=6;
+v2 ZoomPos = v2(0,0);
+v2 silhouettePos = v2(0,0);
+
+bool bPositionQuestionMode=false;
+
+std::vector game::vDbgDrawOverlayFunctions;
+
+int game::iCurrentDungeonTurn=-1;
+
+int CurrentSavefileVersion=-1;
+
+int game::GetCurrentSavefileVersion(){
+ if(CurrentSavefileVersion==-1)
+ ABORT("no savegame loaded yet..."); //just means wrong usage of this method...
+
+ return CurrentSavefileVersion;
+}
+
+int game::GetSaveFileVersion(){return SAVE_FILE_VERSION;}
+
+void game::SetIsRunning(truth What) { Running = What; }
+
+int game::GetMaxScreenXSize() { //this generally should not be used when the campera position is part of the calculations
+ if(iMaxXSize==0){
+ // 800 provides 42. 800/16=50. 42=50-8. 8 magic number for whatever is drawn to the right of the dungeon.
+ iMaxXSize = ivanconfig::GetStartingWindowWidth()/TILE_SIZE;
+ iMaxXSize-=8;
+ }
+ return iMaxXSize;
+}
+
+int game::GetMaxScreenYSize() { //this generally should not be used when the campera position is part of the calculations
+ if(iMaxYSize==0){
+ // 600 provides 26. 600/16=37. 26=37-11. 11 magic number for whatever is drawn below of the dungeon.
+ iMaxYSize = ivanconfig::GetStartingWindowHeight()/TILE_SIZE;
+ iMaxYSize-=11;
+ }
+ return iMaxYSize;
+}
+
+int game::GetScreenXSize() { //actually dugeon visible width in tiles count
+ if(iXSize==0){
+ iXSize=GetMaxScreenXSize();
+ iXSize/=ivanconfig::GetStartingDungeonGfxScale();DBG2("VisibleDungeonColumns",iXSize); //yes, may lose some columns, no way to fit as scaler is integer and not float
+ }
+ return iXSize;
+}
+
+int game::GetScreenYSize() { //actually dugeon visible height in tiles count
+ if(iYSize==0){
+ iYSize=GetMaxScreenYSize();
+ iYSize/=ivanconfig::GetStartingDungeonGfxScale();DBG2("VisibleDungeonLines",iYSize); //yes, may lose some lines, no way to fit as scaler is integer and not float
+ }
+ return iYSize;
+}
+
void game::AddCharacterID(character* Char, ulong ID)
{
CharacterIDMap.insert(std::make_pair(ID, Char));
@@ -236,14 +325,329 @@ void game::InitScript()
GameScript->RandomizeLevels();
}
-truth game::Init(cfestring& Name)
+void game::PrepareToClearNonVisibleSquaresAround(v2 v2SqrPos) {
+ int i=ivanconfig::GetXBRZSquaresAroundPlayer();
+ if(i==0)return;
+ if(DoZoom())return; //TODO should be able to clear in zoom mode too? the result is still messy, but... is it cool to xBRZ non visible squares in look mode? if so, no need to clear them...
+
+ std::vector vv2ToBeCleared;
+ if(!IsInWilderness()){
+ /***
+ * this will check the squares around player for visibility/CanFeel
+ *
+ * the problem is the dungeon corners, ex.:
+ * 0 1 2
+ * ####### ######O ######O
+ * ####### ##P###O ##P###O
+ * WWW#### WWW###O WWW###O
+ * ##WP### ##W###O ##O
+ * ##W#### ##W###O #O
+ * ####### OOOOOOO OOOOOOO
+ * ####### OOOOOOO OOOOOOO
+ *
+ * Using xBRZ around player by 3 squares.
+ * P = player
+ * # = within user requested "around" distance.
+ * O = out of user requested "around" distance (are ignored/not considered)
+ * W = wall
+ *
+ * 0 - player is far from visible dungeon corners (no complexity)
+ *
+ * 1 - player is near top left corner:
+ * The drawn dungeon visible area will be copied just 2 to the left and 1 to the top away from player position,
+ * this means the cached bitmap will be smaller than at (*0).
+ *
+ * 2 - The player surroundings will be checked for visibility/CanFeel, if neither, these squares (that I deleted
+ * on the example above) will be cleared from pixel colors to the mask/transparent color.
+ * So, the vanilla (non xBRZ) non-visible squares' representation will be kept.
+ */
+
+ // lsquare* plsq = Player->GetLSquareUnder();
+ // v2 v2PlayerPos = plsq->GetPos(); DBG3("PlayerPos",v2PlayerPos.X,v2PlayerPos.Y);
+ v2 v2MaxSqrUpperLeft (v2SqrPos.X-i,v2SqrPos.Y-i); DBGSV2(v2MaxSqrUpperLeft);
+ v2 v2MaxSqrLowerRight(v2SqrPos.X+i,v2SqrPos.Y+i); DBGSV2(v2MaxSqrLowerRight);
+
+ level* plv = Player->GetLevel();
+ v2 v2ChkSqrPos;
+ lsquare* plsqChk;
+ v2 v2CamSqPos = GetCamera();
+ v2 v2DungeonSqSize = v2(GetScreenXSize(),GetScreenYSize());
+ int iSqLeftSkipX=0;
+ int iSqTopSkipY=0;
+ v2 v2Invalid(-1,-1),v2TopLeft(v2Invalid),v2BottomRight(v2Invalid);
+ // tips: OnScreen(v2Square)
+ for(int iY=v2MaxSqrUpperLeft.Y;iY<=v2MaxSqrLowerRight.Y;iY++){
+ if(iY<0 || iY< v2CamSqPos.Y ){iSqTopSkipY++;continue;}
+ if(iY>=plv->GetYSize() || iY>=(v2CamSqPos.Y+v2DungeonSqSize.Y))break;
+
+ iSqLeftSkipX=0; //must be reset here
+ for(int iX=v2MaxSqrUpperLeft.X;iX<=v2MaxSqrLowerRight.X;iX++){
+ if(iX<0 || iX< v2CamSqPos.X ){iSqLeftSkipX++;continue;}
+ if(iX>=plv->GetXSize() || iX>=(v2CamSqPos.X+v2DungeonSqSize.X))break;
+
+ v2ChkSqrPos=v2(iX,iY);
+ if(v2TopLeft==v2Invalid)v2TopLeft=v2ChkSqrPos; //first is top left
+ v2BottomRight=v2ChkSqrPos; //it will keep updating bottom right while it can
+ plsqChk = plv->GetLSquare(v2ChkSqrPos);
+
+ if(plsqChk->CanBeSeenByPlayer())continue;DBGLN;
+ if(!IsInWilderness() && plsqChk->CanBeFeltByPlayer())continue;DBGLN;
+
+ /********************************************************************************************
+ * Now the final thing is to setup the relative pixel position on the small blitdata->bitmap
+ * (that is a copy of the player surroundings at dungeon area),
+ * that will have the squares cleared after it is cached
+ * and before it is stretched with xBRZ,
+ * so that the non visible squares will be drawn equally to all other far away
+ * non vivible squares.
+ */
+ vv2ToBeCleared.push_back(v2( //TODO CalculateScreenCoordinates(v2Square)
+ (v2ChkSqrPos.X - v2MaxSqrUpperLeft.X - iSqLeftSkipX)*TILE_SIZE,
+ (v2ChkSqrPos.Y - v2MaxSqrUpperLeft.Y - iSqTopSkipY )*TILE_SIZE
+ )); DBGSV2(vv2ToBeCleared[vv2ToBeCleared.size()-1]);
+ }
+ }
+
+ DBGSV2(v2TopLeft);DBGSV2(v2BottomRight);
+ }
+
+ graphics::SetSRegionClearSquaresAt(iRegionAroundXBRZ,TILE_V2,vv2ToBeCleared);
+}
+
+void game::SRegionAroundDisable(){
+ if(iRegionAroundXBRZ==-1)return;
+
+ graphics::SetSRegionEnabled(iRegionAroundXBRZ,false);
+}
+
+bool bRegionAroundXBRZAllowed=true;
+void game::SRegionAroundAllow(){
+ bRegionAroundXBRZAllowed=true;
+}
+void game::SRegionAroundDeny(){
+ bRegionAroundXBRZAllowed=false;
+}
+
+void game::UpdatePosAroundForXBRZ(v2 v2SqrPos){ //TODO join this logic with PrepareToClearNonVisibleSquaresAroundPlayer() as they deal with the same thing.
+ if(iRegionAroundXBRZ==-1)return;
+
+ bool bOk=true;
+
+ if(bOk && !bRegionAroundXBRZAllowed)bOk=false;
+
+ int iSAP=ivanconfig::GetXBRZSquaresAroundPlayer();
+ if(bOk && iSAP==0)bOk=false;
+
+ if(bOk && Player->IsDead())bOk=false; // this may actually never happen...
+
+ if(bOk && !OnScreen(v2SqrPos))bOk=false;
+
+ if(bOk && bPositionQuestionMode){
+ if(!IsInWilderness()){ // always allowed in wilderness (as there is only fully dark squares, not partial as memories)
+ bOk=false;
+ /**
+ * TODO adapt the squares cleaners to work with bPositionQuestionMode too
+ * despite interesting, these are not good...:
+ if(bOk && IsDark(Player->GetLevel()->GetSunLightEmitation()))bOk=false;
+ if(bOk && IsDark(Player->GetLevel()->GetAmbientLuminance ()))bOk=false; //TODO explain: snow/rain?
+ */
+ }
+ }
+
+ if(!bOk){
+ SRegionAroundDisable();
+ return;
+ }
+
+ /////////////////// ok ///////////////////////
+
+ v2 v2ScreenPos = CalculateScreenCoordinates(v2SqrPos);//DBGSV2(v2ScreenPos);
+
+ graphics::SetSRegionEnabled(iRegionAroundXBRZ,true);
+
+ bldAroundOnScreenTMP.Src = v2ScreenPos;
+
+// v2 v2SqrPosPlayer = Player->GetPos();
+ v2 v2SqrPosCam = GetCamera();
+ v2 v2DeltaSqr = v2(v2SqrPos.X-v2SqrPosCam.X, v2SqrPos.Y-v2SqrPosCam.Y);
+
+ v2 deltaSquaresForUpperLeft=v2DeltaSqr;
+ deltaSquaresForUpperLeft.X-=iSAP;
+ deltaSquaresForUpperLeft.Y-=iSAP;
+
+ v2 v2SrcInSquares(iSAP,iSAP);
+
+ if(deltaSquaresForUpperLeft.X<0)v2SrcInSquares.X+=deltaSquaresForUpperLeft.X;
+ if(deltaSquaresForUpperLeft.Y<0)v2SrcInSquares.Y+=deltaSquaresForUpperLeft.Y;
+
+ bldAroundOnScreenTMP.Src.X-=TILE_SIZE*v2SrcInSquares.X;
+ bldAroundOnScreenTMP.Src.Y-=TILE_SIZE*v2SrcInSquares.Y;
+
+// bldPlayerOnScreen.Dest = bldPlayerOnScreen.Src;
+
+ v2 v2BorderInSquares(iSAP*2,iSAP*2);
+
+ if(deltaSquaresForUpperLeft.X<0)v2BorderInSquares.X+=deltaSquaresForUpperLeft.X;
+ if(deltaSquaresForUpperLeft.Y<0)v2BorderInSquares.Y+=deltaSquaresForUpperLeft.Y;
+
+ v2 deltaForLowerRight=v2DeltaSqr;
+ deltaForLowerRight.X=GetScreenXSize()-deltaForLowerRight.X-iSAP-1;
+ deltaForLowerRight.Y=GetScreenYSize()-deltaForLowerRight.Y-iSAP-1;
+
+ if(deltaForLowerRight.X<0)v2BorderInSquares.X+=deltaForLowerRight.X;
+ if(deltaForLowerRight.Y<0)v2BorderInSquares.Y+=deltaForLowerRight.Y;
+
+ bldAroundOnScreenTMP.Border.X=TILE_SIZE+(TILE_SIZE*v2BorderInSquares.X);
+ bldAroundOnScreenTMP.Border.Y=TILE_SIZE+(TILE_SIZE*v2BorderInSquares.Y);
+
+ // this grants positioninig on the upper left player's square corner
+
+ // relative to full dungeon in source image vanilla position
+ v2 deltaForFullDungeonSrc = v2(bldAroundOnScreenTMP.Src.X-bldFullDungeonTMP.Src.X, bldAroundOnScreenTMP.Src.Y-bldFullDungeonTMP.Src.Y);
+
+ // relative to full dungeon over it's stretched image position
+ bldAroundOnScreenTMP.Dest.X=bldFullDungeonTMP.Dest.X+(deltaForFullDungeonSrc.X*ivanconfig::GetStartingDungeonGfxScale());
+ bldAroundOnScreenTMP.Dest.Y=bldFullDungeonTMP.Dest.Y+(deltaForFullDungeonSrc.Y*ivanconfig::GetStartingDungeonGfxScale());
+
+ graphics::SetSRegionBlitdata(iRegionAroundXBRZ,bldAroundOnScreenTMP); DBGBLD(bldAroundOnScreenTMP);
+
+ PrepareToClearNonVisibleSquaresAround(v2SqrPos);
+}
+
+void game::RegionListItemEnable(bool b){
+ game::PrepareStretchRegionsLazy();
+ if(iRegionListItem==-1)return;
+
+ // src pos is set at felist
+ graphics::SetSRegionBlitdata(iRegionListItem, bldListItemTMP);
+ graphics::SetSRegionEnabled(iRegionListItem, b);
+}
+
+void game::RegionSilhouetteEnable(bool bEnable){
+ game::PrepareStretchRegionsLazy();
+ if(iRegionSilhouette==-1)return;
+
+ if(bEnable && ivanconfig::GetSilhouetteScale()==1)bEnable=false;
+
+ if(bEnable && !PLAYER->IsHumanoid())bEnable=false; //TODO isHuman() too?
+
+ if(bEnable){
+ bldSilhouetteTMP.Stretch = ivanconfig::GetSilhouetteScale();
+
+ bldSilhouetteTMP.Dest = {
+ silhouettePos.X -(bldSilhouetteTMP.Border.X*ivanconfig::GetSilhouetteScale()) -3,
+ silhouettePos.Y};
+
+ graphics::SetSRegionBlitdata(iRegionSilhouette, bldSilhouetteTMP);
+ graphics::SetSRegionEnabled(iRegionSilhouette, true);
+ }else{
+ graphics::SetSRegionEnabled(iRegionSilhouette, false);
+ }
+
+}
+
+void game::UpdateSRegionsXBRZ(){
+ for(int i=0;i0){
+ graphics::SetSRegionUseXBRZ(iRegionIndexDungeon,false);
+ continue;
+ }
+ }
+
+ graphics::SetSRegionUseXBRZ(i,ivanconfig::IsXBRZScale());
+ }
+}
+
+void game::PrepareStretchRegionsLazy(){ // the ADD order IS important IF they overlap
+ if(iRegionIndexDungeon==-1){
+ if(ivanconfig::GetStartingDungeonGfxScale()>1){
+ /**
+ * dungeon visible area (Bitmap must be NULL)
+ * workaround: only one line of the border will be stretched, hence src -1 and border +2
+ */
+ v2 topleft = area::getTopLeftCorner();
+ bldFullDungeonTMP.Src = {topleft.X-1,topleft.Y-1}; //the top left corner of the dungeon drawn area INSIDE the dungeon are grey ouline
+ bldFullDungeonTMP.Dest = {topleft.X - area::getOutlineThickness() -1, topleft.Y - area::getOutlineThickness() -1}; //the top left corner of the grey ouline to cover it TODO a new one should be drawn one day
+ bldFullDungeonTMP.Border = {GetScreenXSize()*TILE_SIZE+2, game::GetScreenYSize()*TILE_SIZE+2};
+ bldFullDungeonTMP.Stretch = ivanconfig::GetStartingDungeonGfxScale();
+ iRegionIndexDungeon = graphics::AddStretchRegion(bldFullDungeonTMP,"FullDungeon");
+
+ /***********************************
+ * AROUND: player or look zoom pos *
+ ***********************************/
+ // (will be above dungeon) around player on screen
+ bldAroundOnScreenTMP.Stretch = ivanconfig::GetStartingDungeonGfxScale();
+ iRegionAroundXBRZ = graphics::AddStretchRegion(bldAroundOnScreenTMP,"AroundXBRZ");
+ }
+ }
+
+ //TODO player stats etc, text log? at most x2?, set thru one user option bool for all (fast blit only?)
+
+ if(iRegionSilhouette==-1){ // equiped items and humanoid silhouette region
+ silhouettePos = humanoid::GetSilhouetteWhereDefault();
+ if(!silhouettePos.Is0()){
+ silhouettePos.X -= 15; silhouettePos.Y -= 23; //exact top left corner of all equipped items countour
+ silhouettePos-=v2(1,1); //1 dot b4
+ bldSilhouetteTMP.Src = {silhouettePos.X, silhouettePos.Y};
+ int iEqSize=23;
+ v2 v2EqSqr(iEqSize,iEqSize);
+ bldSilhouetteTMP.Border = SILHOUETTE_SIZE+(v2EqSqr*2); //SILHOUETTE_SIZE + equipped items all around
+ bldSilhouetteTMP.Border+=v2(2,2); //compensate for pos-1 and add +1 after border
+ bldSilhouetteTMP.Stretch = 2; // minimum to allow setup
+ iRegionSilhouette = graphics::AddStretchRegion(bldSilhouetteTMP,"Silhouette");
+ graphics::SetSRegionDrawAfterFelist(iRegionSilhouette,true);
+ graphics::SetSRegionDrawRectangleOutline(iRegionSilhouette,true);
+
+ // alt vanilla silhouette pos
+ bldVanillaSilhouetteTMP.Stretch = 2; // minimum to allow setup
+ bldVanillaSilhouetteTMP.Border = SILHOUETTE_SIZE + v2(TILE_SIZE,2);
+ iRegionVanillaSilhouette = graphics::AddStretchRegion(bldVanillaSilhouetteTMP,"AltPosForVanillaSilhouette");
+ graphics::SetSRegionDrawAlways(iRegionVanillaSilhouette,true);
+ graphics::SetSRegionDrawRectangleOutline(iRegionVanillaSilhouette,true);
+ }
+ }
+
+ if(iRegionListItem==-1){
+ bldListItemTMP.Dest = ZoomPos;
+ bldListItemTMP.Border = TILE_V2;
+ bldListItemTMP.Stretch = iZoomFactor;
+ iRegionListItem = graphics::AddStretchRegion(bldListItemTMP,"ListItem");
+ graphics::SetSRegionListItem(iRegionListItem);
+ graphics::SetSRegionDrawRectangleOutline(iRegionListItem,true);
+ }
+
+ if(iRegionItemsUnder==-1){
+ blitdata B = DEFAULT_BLITDATA;
+ B.Stretch=iItemsUnderStretch;
+ iRegionItemsUnder = graphics::AddStretchRegion(B,"ItemsUnderPosShowAboveHead");
+ }
+
+ UpdateSRegionsXBRZ();
+}
+
+void FantasyName(festring& rfsName){ DBG2(rfsName.CStr(),ivanconfig::GetFantasyNamePattern().CStr());
+ if(ivanconfig::GetFantasyNamePattern().IsEmpty())return;
+
+ NameGen::Generator gen(ivanconfig::GetFantasyNamePattern().CStr());
+ rfsName << gen.toString().c_str(); DBG1(rfsName.CStr());
+}
+
+truth game::Init(cfestring& loadBaseName)
{
- if(Name.IsEmpty())
- {
+ festring absLoadNameOk;
+
+ if(!loadBaseName.IsEmpty()){
+ absLoadNameOk = SaveName(loadBaseName); //will prepend the path
+ }else{
if(ivanconfig::GetDefaultName().IsEmpty())
{
PlayerName.Empty();
+ FantasyName(PlayerName); DBG1(PlayerName.CStr());
+
if(iosystem::StringQuestion(PlayerName, CONST_S("What is your name? (1-20 letters)"),
v2(30, 46), WHITE, 1, 20, true, true) == ABORTED
|| PlayerName.IsEmpty())
@@ -251,9 +655,9 @@ truth game::Init(cfestring& Name)
}
else
PlayerName = ivanconfig::GetDefaultName();
+
+ absLoadNameOk = SaveName(); //default is to use PlayerName
}
- else
- PlayerName = Name;
#ifdef WIN32
_mkdir("Save");
@@ -275,7 +679,8 @@ truth game::Init(cfestring& Name)
DangerFound = 0;
CausePanicFlag = false;
- switch(Load(SaveName(PlayerName)))
+ bool bSuccess=false; DBG3(PlayerName.CStr(),loadBaseName.CStr(),absLoadNameOk.CStr());
+ switch(Load(absLoadNameOk))
{
case LOADED:
{
@@ -285,10 +690,13 @@ truth game::Init(cfestring& Name)
GetCurrentArea()->SendNewDrawRequest();
SendLOSUpdateRequest();
ADD_MESSAGE("Game loaded successfully.");
- return true;
+ bSuccess=true;
+ break;
}
case NEW_GAME:
{
+ CurrentSavefileVersion = SAVE_FILE_VERSION;
+
/* New game music */
audio::SetPlaybackStatus(0);
audio::ClearMIDIPlaylist();
@@ -412,11 +820,22 @@ truth game::Init(cfestring& Name)
audio::LoadMIDIFile("world.mid", 0, 100);
audio::SetPlaybackStatus(audio::PLAYING);
- return true;
+ bSuccess=true;
+ break;
}
default:
- return false;
+ {
+ bSuccess=false;
+ break;
+ }
}
+
+ if(bSuccess){ // for loaded or new game
+ ZoomPos = {RES.X - 104, RES.Y - 112};
+ PrepareStretchRegionsLazy();
+ }
+
+ return bSuccess;
}
void game::DeInit()
@@ -447,6 +866,8 @@ void game::DeInit()
void game::Run()
{
+ PrepareStretchRegionsLazy();
+
for(;;)
{
if(!InWilderness)
@@ -595,8 +1016,6 @@ void game::Run()
else if(!RAND_N(5))
Char = billswill::Spawn();
else if(!RAND_N(5))
- Char = ghost::Spawn();
- else if(!RAND_N(5))
Char = dolphin::Spawn();
else if(!RAND_N(5))
Char = cossack::Spawn();
@@ -618,12 +1037,16 @@ void game::Run()
}
catch(quitrequest)
{
+ graphics::SetDenyStretchedBlit();
break;
}
catch(areachangerequest)
{
}
+
+// PrepareStretchRegions();
}
+
}
void game::InitLuxTable()
@@ -717,33 +1140,1336 @@ cchar* game::Insult()
/* DefaultAnswer = REQUIRES_ANSWER the question requires an answer */
-truth game::TruthQuestion(cfestring& String, int DefaultAnswer, int OtherKeyForTrue)
-{
- if(DefaultAnswer == NO)
- DefaultAnswer = 'n';
- else if(DefaultAnswer == YES)
- DefaultAnswer = 'y';
- else if(DefaultAnswer != REQUIRES_ANSWER)
- ABORT("Illegal TruthQuestion DefaultAnswer send!");
+truth game::TruthQuestion(cfestring& String, int DefaultAnswer, int OtherKeyForTrue)
+{
+ if(DefaultAnswer == NO)
+ DefaultAnswer = 'n';
+ else if(DefaultAnswer == YES)
+ DefaultAnswer = 'y';
+ else if(DefaultAnswer != REQUIRES_ANSWER)
+ ABORT("Illegal TruthQuestion DefaultAnswer send!");
+
+ int FromKeyQuestion = KeyQuestion(String, DefaultAnswer, 5, 'y', 'Y', 'n', 'N', OtherKeyForTrue);
+ return FromKeyQuestion == 'y' || FromKeyQuestion == 'Y' || FromKeyQuestion == OtherKeyForTrue;
+}
+
+void game::DrawEverything()
+{
+ DrawEverythingNoBlit();
+ graphics::BlitDBToScreen();
+}
+
+truth game::OnScreen(v2 Pos)
+{
+ return Pos.X >= 0 && Pos.Y >= 0 && Pos.X >= Camera.X && Pos.Y >= Camera.Y
+ && Pos.X < GetCamera().X + GetScreenXSize() && Pos.Y < GetCamera().Y + GetScreenYSize();
+}
+
+bool bDrawMapOverlayEnabled=false;
+int iMapOverlayDrawCount=0;
+bool game::ToggleDrawMapOverlay()
+{
+ SetDrawMapOverlay(!bDrawMapOverlayEnabled);
+ return bDrawMapOverlayEnabled;
+}
+
+void game::SetDrawMapOverlay(bool b)
+{
+ static bool bDummyInit = [](){graphics::AddDrawAboveAll(&DrawMapOverlay,1000,"Map");return true;}();
+
+ bDrawMapOverlayEnabled=b;
+
+ if(bDrawMapOverlayEnabled)iMapOverlayDrawCount=0;
+}
+
+bitmap* finalMapBmp(blitdata& bld, int iStretch, bitmap* bmpFrom, v2& v2TopLeftFinal, v2& v2MapScrSizeFinal, v2 v2Center){
+ bld.Stretch = iStretch;
+ bld.Border = bmpFrom->GetSize();
+
+ v2MapScrSizeFinal = bld.Border * bld.Stretch;
+ v2TopLeftFinal = v2Center -(v2MapScrSizeFinal/2);
+
+ if(bld.Bitmap==NULL || bld.Bitmap->GetSize()!=v2MapScrSizeFinal){
+ delete bld.Bitmap;
+ bld.Bitmap = new bitmap(v2MapScrSizeFinal);
+ }
+
+ graphics::Stretch(true,bmpFrom,bld,false);
+
+ return bld.Bitmap;
+};
+
+void game::DrawMapOverlay(bitmap* buffer)
+{ DBGLN;
+ if(!bDrawMapOverlayEnabled)return;
+
+ bool bUsexBRZ=false;
+ int iImersiveMap=0;
+
+ switch(ivanconfig::GetShowMap()){
+ case 0: //mmm... just not using xBRZ
+ break;
+ case 1:
+ bUsexBRZ=ivanconfig::IsXBRZScale();
+ break;
+ case 2:
+ iImersiveMap=1;
+ break;
+ case 3:
+ iImersiveMap=2;
+ break;
+ case 4:
+ iImersiveMap=3;
+ break;
+ }
+
+ if(ivanconfig::GetStartingDungeonGfxScale()==1){
+ ADD_MESSAGE("This map is as big as the world!");
+ }else{ //it actually work works (for now) if there is any dungeon stretching going on
+ if(buffer==NULL)return; //TODO can this happen?
+
+ static bitmap* bmpMapBuffer=NULL;
+
+ int iMapTileSizeMax=32; //TODO this starting is too big if known map is still tiny?
+ int iMapTileSize=iMapTileSizeMax;
+ static v2 v2TopLeft(0,0);
+ static v2 v2Center(0,0);
+ static v2 v2MapScrSize(0,0);
+ static v2 v2BmpSize(0,0);
+ static v2 v2TopLeftFinal(0,0);
+ static v2 v2MapScrSizeFinal(0,0);
+ static bitmap* bmpFinal;
+
+ if(iMapOverlayDrawCount==0){
+ // static level* lvlLast=NULL; //this is just a changed dungeon indicator
+ // if(lvlLast == game::GetCurrentLevel())return;
+ // lvlLast=game::GetCurrentLevel();
+
+// static int iR=0xFF, iG=0xFF*0.80, iB=0xFF*0.60; //old paper like
+// static col16 colorMapBkg=MakeRGB16(iR,iG,iB);
+ // static const int iLumTot=5;
+ // static col16 bkg[iLumTot];
+ // static col24 lum[iLumTot];static bool bDummyInit=[](){
+ // for(int i=0;iGetXSize(),game::GetCurrentLevel()->GetYSize());
+ v2 v2Max(0,0);
+ for(int iY=0;iYGetYSize();iY++){for(int iX=0;iXGetXSize();iX++){
+ static lsquare* lsqr;lsqr=CurrentLevel->GetLSquare(iX,iY);
+ if(lsqr->HasBeenSeen()){
+ if(v2Min.X > lsqr->GetPos().X) v2Min.X = lsqr->GetPos().X;
+ if(v2Min.Y > lsqr->GetPos().Y) v2Min.Y = lsqr->GetPos().Y;
+ if(v2Max.X < lsqr->GetPos().X) v2Max.X = lsqr->GetPos().X;
+ if(v2Max.Y < lsqr->GetPos().Y) v2Max.Y = lsqr->GetPos().Y;
+ }
+
+ v2KnownDungeonSize = (v2Max+v2(1,1)) -v2Min;
+ }} DBG3(DBGAV2(v2Min),DBGAV2(v2Max),DBGAV2(v2KnownDungeonSize));
+
+
+// v2 v2FullDungeonSize=v2(game::GetCurrentLevel()->GetXSize(),game::GetCurrentLevel()->GetYSize());
+ while(iMapTileSizeMax*v2KnownDungeonSize.X > RES.X*0.9)iMapTileSizeMax--;
+ while(iMapTileSizeMax*v2KnownDungeonSize.Y > RES.Y*0.9)iMapTileSizeMax--;
+ iMapTileSize=iMapTileSizeMax;
+ if(iImersiveMap>0 || bUsexBRZ){
+ iMapTileSize=1; //1 works best with xBRZ (2 makes it blocky again)
+
+ if(iImersiveMap>0)
+ iMapTileSizeMax = 3 + iImersiveMap; //forces x2 scale tiny map
+ }DBG2(iMapTileSizeMax,iMapTileSize);
+ /********** ONLY USE iMapTileSize BELOW HERE!!! *************/
+
+ v2 v2MapTileSize(iMapTileSize,iMapTileSize);
+
+ v2MapScrSize=v2KnownDungeonSize*iMapTileSize;
+
+ v2 v2DungeonScrSize(GetScreenXSize(),GetScreenYSize()); //the visible dungeon size b4 stretching
+ v2DungeonScrSize *= TILE_SIZE*ivanconfig::GetStartingDungeonGfxScale(); //the final size in pixels
+ DBG4(DBGAV2(v2KnownDungeonSize),DBGAV2(area::getTopLeftCorner()),DBGAV2(v2DungeonScrSize),DBGAV2(v2MapScrSize));
+// v2 v2VisibleDungeonScrSize=v2CL*TILE_SIZE;
+ v2Center = area::getTopLeftCorner() +v2DungeonScrSize/2;
+ v2TopLeft = v2Center -v2MapScrSize/2;
+ if(v2TopLeft.X<0)v2TopLeft.X=0;
+ if(v2TopLeft.Y<0)v2TopLeft.Y=0;
+// v2(
+// RES.X/2 -(v2CL.X * iMapTileSize)/2,
+// RES.Y/2 -(v2CL.Y * iMapTileSize)/2);
+
+ v2BmpSize=v2KnownDungeonSize*iMapTileSize;
+ if(bmpMapBuffer==NULL || bmpMapBuffer->GetSize()!=v2BmpSize){
+ delete bmpMapBuffer;
+ bmpMapBuffer=new bitmap(v2BmpSize);
+ }
+// bmpMapBuffer->ClearToColor(TRANSPARENT_COLOR);
+
+ v2 v2PlayerScrPos(0,0);
+ v2 v2Dest(0,0);
+ for(int iY=v2Min.Y;iY<=v2Max.Y;iY++){
+// B.Dest.Y = v2TopLeft.Y +iY*iMapTileSize;
+ v2Dest.Y = (iY-v2Min.Y)*iMapTileSize;
+
+ for(int iX=v2Min.X;iX<=v2Max.X;iX++){
+// B.Dest.X = v2TopLeft.X +iX*iMapTileSize;
+ v2Dest.X = (iX-v2Min.X)*iMapTileSize;
+
+ static v2 v2SqrPos;v2SqrPos.X=iX;v2SqrPos.Y=iY;
+
+ static lsquare* lsqr;lsqr=CurrentLevel->GetLSquare(v2SqrPos);
+
+// static float fStepDelay=3.0;
+// static int iAdd;iAdd = ((int)(clock()/(CLOCKS_PER_SEC*fStepDelay))) % ((iLumTot-1)*2); //moving waves
+// static int iLumIndex;iLumIndex = abs( ((iX+iY+iAdd)%((iLumTot-1)*2)) - (iLumTot-1)); //like a wave from 0 to iLumTot to 0 to iLumTot
+// B.Luminance=lum[iLumIndex]; DBG2(iLumIndex,B.Luminance);
+
+// static int iR=0xFF, iG=0xFF*0.80, iB=0xFF*0.60; //old paper like
+// static float fFrom=0.95;
+// static float fStep=0.10;
+//
+// static float fW=fFrom;
+// static col16 colorWall =MakeRGB16(iR*fW,iG*fW,iB*fW);
+//
+// static float fF=fFrom-fStep;
+// static col16 colorFloor =MakeRGB16(iR*fF,iG*fF,iB*fF);
+//
+// static float fB=fFrom-fStep; //always darker than everything else based on height
+// static col16 colorMapBkg=MakeRGB16(iR*fB,iG*fB,iB*fB);
+
+ static col16 colorNaturalWall,colorBuiltWall,colorFloor,colorMapBkg;
+ static bool bDummyInit = [](){
+ int iR=0xFF, iG=0xFF*0.80, iB=0xFF*0.60; //old paper like, well.. should be at least ;)
+ float fFrom=0.95;
+ float fStep=0.15;
+ int iTot=1.0/fStep;
+ col16 clMap[iTot];
+ for(int i=0;iHasBeenSeen()){
+ static col16 colorDoor =MakeRGB16(0xFF*0.66, 0xFF*0.33, 0); //brown
+ static col16 colorFountain=MakeRGB16( 0, 0,0xFF ); //blue
+ static col16 colorUp =MakeRGB16( 0, 0xFF , 0); //green
+ static col16 colorDown =MakeRGB16( 0, 0xFF*0.50, 0); //dark green
+ static col16 colorAltar =MakeRGB16(0xFF*0.50, 0,0xFF ); //purple
+// static col16 colorOnGround=MakeRGB16(0xFF*0.80, 0xFF*0.50,0xFF*0.20); //orange
+
+ static const int iTotRM=5 +1; //5 is max rest modifier from dat files
+ static col16 colorOnGroundRM[iTotRM];
+ static bool bDummyInit2 = [](){
+ int iR=0xFF, iG=0xFF*0.70, iB=0xFF*0.40; //light orange
+ float fFrom=1.00;
+ float fStep=0.05;
+ for(int i=0;iGetOLTerrain();
+ if(olt){
+ if(olt->IsDoor()){
+ colorO=colorDoor;
+ }else if(olt->IsWall()){
+ if(dynamic_cast(olt)!=NULL)
+ colorO=colorNaturalWall;
+ else
+ colorO=colorBuiltWall;
+ }else if(olt->IsFountainWithWater()){
+ colorO=colorFountain;
+// }else if(olt->IsUpLink()){
+ }else if(olt->GetConfig() == STAIRS_UP || olt->GetConfig() == SUMO_ARENA_EXIT ){
+ colorO=colorUp;
+ }else if(olt->GetConfig() == STAIRS_DOWN || olt->GetConfig() == SUMO_ARENA_ENTRY){
+ colorO=colorDown;
+ }else if(dynamic_cast(olt)!=NULL){
+ colorO=colorAltar;
+ }else if(olt->IsOnGround()){ //LAST ONE! as is generic thing
+// if(olt->GetRestModifier()>1)
+// colorO=colorOnGround;
+// else
+// colorO=colorOnGround;
+ colorO=colorOnGroundRM[olt->GetRestModifier()]; //TODO this may break if another RM level is configured at .dat files
+ }
+ }else{ //floor
+ colorO=colorFloor;
+ }
+
+ if(lsqr->IsMaterialDetected()) //color override
+ colorO=YELLOW;
+ }else{
+ colorO=colorMapBkg;
+ }
+
+ bmpMapBuffer->Fill(v2Dest, v2MapTileSize, colorO);
+
+ if(PLAYER->GetPos() == v2SqrPos)
+ v2PlayerScrPos=v2Dest;
+ }
+ }
+
+// graphics::DrawRectangleOutlineAround(
+// B.Bitmap, v2TopLeft, v2CL*iMapTileSize, LIGHT_GRAY, true);
+
+ if(iMapTileSize<3){
+ bmpMapBuffer->Fill(v2PlayerScrPos, v2MapTileSize, RED);
+ }else{
+ graphics::DrawRectangleOutlineAround(
+ bmpMapBuffer, v2PlayerScrPos, v2MapTileSize, RED, iMapTileSize>12);
+ }
+
+ bmpFinal = bmpMapBuffer;
+ v2TopLeftFinal = v2TopLeft;
+ v2MapScrSizeFinal = v2MapScrSize;
+ } DBG3(bmpMapBuffer,iMapOverlayDrawCount,DBGAV2(v2TopLeft));
+
+ if((bUsexBRZ || iImersiveMap>0) && iMapOverlayDrawCount==0){ //double stretch
+ /**
+ * these are "best fit" double stretch values
+ *
+ * max 'a' or 'b' is 6, min is 2
+ *
+ * 'b' may be ignored
+ *
+ * for best xBRZ results, 'a' should be as big as possible.
+ *
+ * TODO a smart formulae that allows above 32 too one day? :>
+ */
+ int a=-1,b=-1;
+// if(iMapTileSize==1){
+ if(iMapTileSizeMax>32)ABORT("not supported yet: iMapTileSizeMax=%d",iMapTileSizeMax);
+ switch(iMapTileSizeMax/iMapTileSize){
+ case 32:case 31:case 30:
+ a=6;b=5;break;
+ case 29:case 28:case 27:case 26:case 25:
+ a=5;b=5;break;
+ case 24:
+ a=6;b=4;break;
+ case 23:case 22:case 21:case 20:
+ a=5;b=4;break;
+ case 19:case 18:
+ a=6;b=3;break;
+ case 17:case 16:
+ a=4;b=4;break;
+ case 15:
+ a=5;b=3;break;
+ case 14:case 13:case 12:
+ a=6;b=2;break;
+ case 11:case 10:
+ a=5;b=2;break;
+ case 9:
+ a=3;b=3;break;
+ case 8:
+ a=4;b=2;break;
+ case 7:
+ a=6;break;
+ default: // <=6
+ a=iMapTileSizeMax;
+ }
+// }
+// else
+// if(iMapTileSize==2){ // the final result is a bit messy... kept in case we use it anyway
+// switch(iMapTileSizeVanillaBkp){ //
+// case 32:
+// a=4;b=4;break;
+// case 31:case 30:
+// a=3;b=5;break;
+// case 29:case 28:case 27:case 26:case 25:case 24:
+// a=3;b=4;break;
+// case 23:case 22:case 21:case 20:
+// a=2;b=5;break;
+// case 19:case 18:
+// a=3;b=3;break;
+// case 17:case 16:
+// a=2;b=4;break;
+// default: // <=15
+// a=iMapTileSizeVanillaBkp/2;
+// }
+// }
+ DBG4(a,b,iMapTileSize,iMapTileSizeMax);
+ if(a=2){
+ v2 v2BmpSizeIn=v2BmpSize;
+ static blitdata bldA=DEFAULT_BLITDATA;
+ bmpFinal=finalMapBmp(bldA,a,bmpFinal,v2TopLeftFinal,v2MapScrSizeFinal,v2Center);
+// /* a */
+// { // a block to prevent mistakes at 'b'
+// static blitdata bld=DEFAULT_BLITDATA;
+// v2MapScrSizeFinal = v2BmpSizeIn*a;
+// if(bld.Bitmap == NULL || bld.Bitmap->GetSize()!=v2MapScrSizeFinal){
+// delete bld.Bitmap;
+// bmpFinal = bld.Bitmap = new bitmap(v2MapScrSizeFinal);
+// }
+// bld.Stretch = a;
+// bld.Border = v2BmpSizeIn;
+// graphics::Stretch(true,bmpFinal,bld,false);
+// v2TopLeftFinal = v2Center -(bld.Border*bld.Stretch)/2;
+// }
+//
+// /* b */
+ if(b>=2){
+ static blitdata bldB=DEFAULT_BLITDATA;
+ bmpFinal=finalMapBmp(bldB,b,bmpFinal,v2TopLeftFinal,v2MapScrSizeFinal,v2Center);
+// v2MapScrSizeFinal = v2BmpSize*a;
+// if(bld.Bitmap == NULL || bld.Bitmap->GetSize()!=v2MapScrSizeFinal){
+// delete bld.Bitmap;
+// bmpFinal = bld.Bitmap = new bitmap(v2MapScrSizeFinal);
+// }
+// bld.Stretch = a;
+// bld.Border = v2BmpSize;
+// graphics::Stretch(true,bmpFinal,bld,false);
+// v2TopLeftFinal = v2Center -(bld.Border*bld.Stretch)/2;
+ }
+
+// graphics::DrawRectangleOutlineAround(
+// buffer, bld.Dest, bld.Border*bld.Stretch, LIGHT_GRAY, true);
+ }
+
+ }
+
+ if(iImersiveMap>0 && iMapOverlayDrawCount==0){ // at player hands!
+ v2TopLeftFinal = area::getTopLeftCorner()
+ + (CalculateScreenCoordinates(PLAYER->GetPos()) -area::getTopLeftCorner()) * ivanconfig::GetStartingDungeonGfxScale()
+ + (TILE_V2*ivanconfig::GetStartingDungeonGfxScale())/2 //find center at player tile
+ + v2(0,TILE_SIZE*ivanconfig::GetStartingDungeonGfxScale()*0.2) //player's hands a bit below center
+ - v2(bmpFinal->GetSize().X/2,0) //center map top's on player's hands
+ ;
+ }
+
+ if(iMapOverlayDrawCount==0){
+ if((v2TopLeftFinal.X+v2MapScrSizeFinal.X) > RES.X)v2TopLeftFinal.X=RES.X-v2MapScrSizeFinal.X;
+ if((v2TopLeftFinal.Y+v2MapScrSizeFinal.Y) > RES.Y)v2TopLeftFinal.Y=RES.Y-v2MapScrSizeFinal.Y;
+ if(v2TopLeftFinal.X<0)v2TopLeftFinal.X=0;
+ if(v2TopLeftFinal.Y<0)v2TopLeftFinal.Y=0;
+ }
+
+ bmpFinal->FastBlit(buffer, v2TopLeftFinal);
+ graphics::DrawRectangleOutlineAround(buffer, v2TopLeftFinal, v2MapScrSizeFinal, LIGHT_GRAY, true);
+
+ iMapOverlayDrawCount++;
+ }
+
+}
+/****************
+ * Fancy map code have some interesting calculations,
+ * kept as reference, may be useful to something later,
+ * if it breaks just comment or remove it...
+ */
+void DrawMapOverlayFancy(bitmap* buffer)
+{
+ if(!bDrawMapOverlayEnabled)return;
+
+ if(ivanconfig::GetStartingDungeonGfxScale()==1){
+ ADD_MESSAGE("This map is as big as the world!");
+ }else{ //it actually work works (for now) if there is any dungeon stretching going on
+ if(buffer!=NULL){
+ static float fRGB=0.3;
+ static int iR=0xFF*fRGB,iG=0xFF*fRGB,iB=0xFF*fRGB;
+
+ static const int iLumTot=5;
+ static col16 bkg[iLumTot];
+ static col24 lum[iLumTot];static bool bDummyInit=[](){
+ for(int i=0;iGetXSize(),game::GetCurrentLevel()->GetYSize());
+
+ static v2 v2MapVisibleSize;
+ v2MapVisibleSize.X = Min(v2MapMaxSize.X,v2CL.X);
+ v2MapVisibleSize.Y = Min(v2MapMaxSize.Y,v2CL.Y);
+
+ static v2 v2MapSkipSize;
+ v2MapSkipSize.X = v2CL.X - v2MapVisibleSize.X;
+ v2MapSkipSize.Y = v2CL.Y - v2MapVisibleSize.Y;
+
+ float fPercX = PLAYER->GetPos().X/(float)game::GetCurrentLevel()->GetXSize();
+ float fPercY = PLAYER->GetPos().Y/(float)game::GetCurrentLevel()->GetYSize();
+
+ v2MapSkipSize.X*=fPercX;
+ v2MapSkipSize.Y*=fPercY;
+
+ static blitdata B = [buffer](){B=DEFAULT_BLITDATA;
+ B.Bitmap=buffer;
+ B.Border=TILE_V2;return B;}();
+// B.Luminance=NORMAL_LUMINANCE; return B;}(); //TODO yellowish like an old map? this no good: MakeRGB24(150,150,0);
+// B.Luminance=MakeRGB24(iR,iG,iB); return B;}(); //TODO yellowish like an old map
+
+ v2 v2TopLeft(
+ RES.X/2 -(v2MapVisibleSize.X * TILE_SIZE)/2,
+ RES.Y/2 -(v2MapVisibleSize.Y * TILE_SIZE)/2);
+
+ /** arms not ready, still broken, TODO would be cool anyway?
+ static humanoid* h;h = dynamic_cast(PLAYER);
+ static blitdata bldArm = [](){bldArm=DEFAULT_BLITDATA;
+ bldArm.Bitmap=new bitmap(TILE_V2);
+ bldArm.Border=TILE_V2; return bldArm;}();
+ static blitdata bldArmBig = [buffer](){bldArmBig=DEFAULT_BLITDATA;
+ bldArmBig.Bitmap=buffer;
+ bldArmBig.Border=TILE_V2; return bldArmBig;}();
+ bldArmBig.Stretch=6;
+ if(h->GetLeftArm ())h->GetLeftArm ()->Draw(bldArm);
+ graphics::Stretch(ivanconfig::IsXBRZScale(), bldArm.Bitmap, bldArmBig, false);
+ //TODO fix right pos etc
+ if(h->GetRightArm())h->GetRightArm()->Draw(bldArm);
+ graphics::Stretch(ivanconfig::IsXBRZScale(), bldArm.Bitmap, bldArmBig, false);
+ */
+
+ /* the alpha just looks bad, mainly when above non visible areas, kept this comment as reminder...
+ static blitdata bldTmp = [](){bldTmp=DEFAULT_BLITDATA;
+ bldTmp.Bitmap=new bitmap(TILE_V2);
+ bldTmp.Bitmap->CreateAlphaMap(0xFF*0.75);
+ bldTmp.Border=TILE_V2; return bldTmp;}();
+ */
+
+ v2 PlayerScrPos(0,0);
+ for(int iY=0;iYGetLSquare(v2SqrPos);
+
+ static float fStepDelay=3.0;
+ static int iAdd;iAdd = ((int)(clock()/(CLOCKS_PER_SEC*fStepDelay))) % ((iLumTot-1)*2); //moving waves
+ static int iLumIndex;iLumIndex = abs( ((iX+iY+iAdd)%((iLumTot-1)*2)) - (iLumTot-1)); //like a wave from 0 to iLumTot to 0 to iLumTot
+ B.Luminance=lum[iLumIndex]; DBG2(iLumIndex,B.Luminance);
+// bldTmp.Luminance=lum[iLumIndex]; DBG2(iLumIndex,B.Luminance);
+
+ if(lsqr->HasBeenSeen()){
+ lsqr->GetGLTerrain()->Draw(B);
+// lsqr->GetGLTerrain()->Draw(bldTmp);
+// bldTmp.Bitmap->AlphaMaskedBlit(B);
+
+ static olterrain* olt;olt = lsqr->GetOLTerrain();
+ if(olt){
+ olt->Draw(B);
+// olt->Draw(bldTmp);
+// bldTmp.Bitmap->AlphaMaskedBlit(B);
+ }
+ }else{
+// static col16 bkg = MakeRGB16(iR,iG,iB);
+ B.Bitmap->Fill(B.Dest, B.Border, bkg[iLumIndex]); DBG2(iLumIndex,bkg[iLumIndex]);
+ }
+
+ if(PLAYER->GetPos() == v2SqrPos){
+ static float fP = 0.75;
+ static col24 colP = MakeRGB24(0xff*fP,0xff*fP,0xff*fP);
+ B.Luminance = clock()%2==0 ? colP : NORMAL_LUMINANCE; //to call attention like a highlight TODO not working...
+ PLAYER->Draw(B);
+// static int iHL=0;iHL++;
+// B.Bitmap->DrawRectangle(B.Dest-v2(1,1), B.Border+v2(2,2), iHL%2==0 ? RED : YELLOW, false);
+// graphics::DrawRectangleOutlineAround(
+// B.Bitmap, B.Dest-v2(2,2), B.Border+v2(4,4), RED, true);//iHL%2==0);
+// B.Bitmap, B.Dest-v2(2,2), B.Border+v2(4,4), RED, iHL%2==0);
+ PlayerScrPos=B.Dest;
+ }
+ }
+ }
+
+ graphics::DrawRectangleOutlineAround(
+ B.Bitmap, v2TopLeft, v2MapVisibleSize*TILE_SIZE, LIGHT_GRAY, true);
+
+ graphics::DrawRectangleOutlineAround(
+ B.Bitmap, PlayerScrPos, TILE_V2, RED, false);
+ }
+ }
+}
+
+/**
+ * TODO optimize it: there are some calculations that could be made once per turn and not per frame...
+ * TODO split this method in many, merely to easy it's understanding by sub-contexts..
+ */
+void game::UpdateAltSilhouette(bool AnimationDraw){
+ static const int iStep=2;
+ static const int iYDiff=TILE_SIZE/3; //has more +- 33% height, after stretching by x3 will be like 3x4 squares of 16x16 dots each
+ static const int iY4 = TILE_SIZE + iYDiff + 1; //+1 as the top line is to be kept empty
+ static const v2 v2OverSilhouette = v2(TILE_SIZE, iY4);
+ static int iAltSilBlitCount=0;
+ static const int iTotTallStates=3;
+ static const int iTallFrom=2;
+ static const int iBreathFrom=3;
+ static int iTallState=iTotTallStates-1;
+ static int iPreviousAltSilOpt=0;
+ static const v2 v2AltSilDispl = v2(8,-2);//v2(10,-2);//v2(24,24);
+ static v2 v2AltSilPos=v2(0,0);
+// static int iRandTorso=0;
+
+ bool bOk=true;
+
+ //if(bOk && !bAllowed)bOk=false;
+
+ //if(bOk && !graphics::IsSRegionEnabled(iRegionSilhouette))bOk=false; //depends on it
+
+ if(bOk && bPositionQuestionMode)bOk=false;
+
+ if(bOk && ivanconfig::GetAltSilhouette()==0)bOk=false;
+
+ if(bOk && !Player->IsEnabled())bOk=false;
+
+ if(bOk && Player->IsDead())bOk=false; //TODO this works?
+
+ humanoid* h=dynamic_cast(Player);
+ if(bOk && h==NULL)bOk=false; //TODO let it work with non humanoid forms
+// if(bOk && Player->IsPolymorphed())bOk=false;
+
+ if(humanoid::GetSilhouetteWhereDefault().Is0()){
+ bOk=false;
+ }else{
+ if(iRegionVanillaSilhouette==-1)game::PrepareStretchRegionsLazy();
+ }
+
+ if(!bOk){
+ iTallState=iTotTallStates-1;
+ iAltSilBlitCount=0;
+ humanoid::SetSilhouetteWhere(humanoid::GetSilhouetteWhereDefault());
+ if(iRegionVanillaSilhouette!=-1)
+ graphics::SetSRegionEnabled(iRegionVanillaSilhouette,false);
+ return;
+ }
+
+ /////////////////////////// ok ////////////////////////////
+
+ iPreviousAltSilOpt=ivanconfig::GetAltSilhouette();
+
+// humanoid::SetSilhouetteWhere(ZoomPos+v2(10,10));
+ bool bRolling=false;
+ bool bHopping=false; DBG1(iRegionVanillaSilhouette);
+ if(iRegionVanillaSilhouette!=-1){
+ bool bOk2=true;
+
+ if(bOk2 && ZoomPos.Is0())bOk2=false;
+
+ if(bOk2 && h==NULL)bOk2=false;
+
+ if(bOk2 && ivanconfig::GetAltListItemPos()==1 && graphics::IsSRegionEnabled(iRegionListItem))bOk2=false; //is same of zoom pos
+
+ if(bOk2){
+ bRolling = !h->GetRightLeg() && !h->GetLeftLeg();
+ bHopping = !bRolling && (!h->GetRightLeg() || !h->GetLeftLeg());
+
+ v2 v2Pos=ZoomPos;
+
+ humanoid::SetSilhouetteWhere(v2Pos);DBGSV2(v2Pos);
+
+ if(iAltSilBlitCount==0) //first time
+ if(h){
+ h->DrawSilhouette(false);DBGLN;
+ }
+
+ bldVanillaSilhouetteTMP.Src = v2Pos + v2(0,-1);
+
+ v2 v2Dest = v2Pos;
+ v2 v2Min = RES - (bldVanillaSilhouetteTMP.Border*bldVanillaSilhouetteTMP.Stretch) - v2(5,5);
+ if(v2Dest.X > v2Min.X)v2Dest.X=v2Min.X;
+ if(v2Dest.Y > v2Min.Y)v2Dest.Y=v2Min.Y;
+ bldVanillaSilhouetteTMP.Dest=v2Dest;
+
+ graphics::SetSRegionBlitdata(iRegionVanillaSilhouette,bldVanillaSilhouetteTMP);
+ //h->DrawSilhouette(AnimationDraw); //TODO necessary?
+ graphics::SetSRegionEnabled(iRegionVanillaSilhouette,true);
+ }else{
+ graphics::SetSRegionEnabled(iRegionVanillaSilhouette,false);
+ }
+ }
+
+// if(v2AltSilPos.Is0())v2AltSilPos = bldSilhouetteTMP.Src + v2AltSilDispl;
+// if(v2AltSilPos.Is0())v2AltSilPos = humanoid::GetSilhouetteWhere() + v2AltSilDispl;
+ if(v2AltSilPos.Is0())v2AltSilPos = humanoid::GetSilhouetteWhereDefault() + v2AltSilDispl;
+ static const v2 v2AltSilTopCenterPos = v2AltSilPos + v2(v2OverSilhouette.X/2,0);
+ static v2 v2AltSilMovingPos=v2AltSilPos;
+
+ static blitdata bldPlayerCopyTMP = [](){bldPlayerCopyTMP = DEFAULT_BLITDATA;
+ bldPlayerCopyTMP.Bitmap = new bitmap(TILE_V2);
+ bldPlayerCopyTMP.CustomData |= ALLOW_ANIMATE;
+ bldPlayerCopyTMP.Luminance = NORMAL_LUMINANCE; return bldPlayerCopyTMP; }(); DBGBLD(bldPlayerCopyTMP);
+ static int iDarkComp=50;
+ static col16 darkestThatWontGlitchWithAlpha = MakeRGB16(iDarkComp,iDarkComp,iDarkComp); //still glitches a bit...
+// static col24 darkestThatWontGlitchWithAlphaLum24 = MakeRGB24(iDarkComp,iDarkComp,iDarkComp);
+ col16 bkgAlignmentColor = TRANSPARENT_COLOR;
+ col24 bkgAlignmentLum24 = NORMAL_LUMINANCE;
+ int iPlayerAlignment = GetPlayerAlignment();
+ switch(ivanconfig::GetAltSilhouettePreventColorGlitch()){
+ case 0:
+ // keep default transparent
+ break;
+ case 1:
+ bkgAlignmentColor = darkestThatWontGlitchWithAlpha;
+ break;
+ case 2:{
+ /**
+ * depicts alignment with background colors
+ * tho, not more info than what is already written by the side of player's name
+ * TODO animations? fire chaotic, clouds lawful
+ */
+ const static int iColorCompBase=0xff/2; // should start where NORMAL_LUMINANCE does, in the middle of the range
+ const static int iColorCompMax=225;
+ const static int iColorStepMult=3;
+ const static int iMaxColorVariations = (iColorCompMax-iColorCompBase)/iColorStepMult;
+ static col16 reds[iMaxColorVariations];
+ static col24 reds24[iMaxColorVariations];
+ static col16 blues[iMaxColorVariations];
+ static col24 blues24[iMaxColorVariations];
+// static col16 greys[iMaxColorVariations];
+ static bool bDummy_Colors = [](){
+ int iColorVarFinal;
+ for(int i=0;i=iColorVariationChangeAt){
+ iColorVariationIndex+=iColorVariationDir;
+
+ if(iColorVariationIndex<0){
+ iColorVariationIndex=0;
+ iColorVariationDir=1;
+ }
+
+ if(iColorVariationIndex==totColorVariations){
+ iColorVariationIndex=totColorVariations-1;
+ iColorVariationDir=-1;
+ }
+ }
+ int iBaseColorVariation=0;
+ switch(abs(iPlayerAlignment)){
+ case 4: iBaseColorVariation+=totColorVariations;
+ case 3: iBaseColorVariation+=totColorVariations;
+ case 2: iBaseColorVariation+=totColorVariations;
+ case 1:
+ case 0:
+ iColorVariationIndex+=iBaseColorVariation;
+ if(iColorVariationIndex>=iMaxColorVariations)iColorVariationIndex=iMaxColorVariations-1; //fail safe...
+ }
+ DBG5(iColorVariationIndex,iBaseColorVariation,totColorVariations,iMaxColorVariations,iColorVariationDir);
+ switch(iPlayerAlignment){
+ case 4: case 3: case 2: case 1:
+ bkgAlignmentColor=blues[iColorVariationIndex];
+ bkgAlignmentLum24=blues24[iColorVariationIndex];
+ break;
+ case 0:
+ bkgAlignmentColor=darkestThatWontGlitchWithAlpha; //greys[iColorVariationIndex];
+ bkgAlignmentLum24=NORMAL_LUMINANCE;// to not darken it //darkestThatWontGlitchWithAlphaLum24;
+ break;
+ case -1: case -2: case -3: case -4:
+ bkgAlignmentColor=reds[iColorVariationIndex];
+ bkgAlignmentLum24=reds24[iColorVariationIndex];
+ break;
+ }
+// igraph::BlitBackGround(bldPlayerCopyTMP.Bitmap,v2(),TILE_V2); //not good...
+// bldPlayerCopyTMP.Bitmap->Fill(0,0,TILE_V2,bkgAlignmentColor);
+ }break;
+ default:
+ ABORT("invalid option GetAltSilhouettePreventColorGlitch %d",ivanconfig::GetAltSilhouettePreventColorGlitch());
+ break;
+ }
+
+ bool bFluctuating = Player->IsSwimming() || Player->IsFlying();
+
+ bool bSleeping = false;
+ if(Player->GetAction()!=NULL)bSleeping=Player->GetAction()->IsUnconsciousness();
+
+ bool bRotate=false;
+ static blitdata bldRotated = [](){bldRotated = DEFAULT_BLITDATA;
+ bldRotated.Border=TILE_V2;
+ bldRotated.Bitmap = new bitmap(TILE_V2); return bldRotated; }(); DBGBLD(bldRotated);
+
+ static int iLastSleepSide=0;
+// if(bSleeping && !bFluctuating){
+ if(bSleeping){ //TODO ? currently there is no space for breath animation if rotated +-90 degrees, some lines could be lost may be?
+ if(iLastSleepSide==0)iLastSleepSide=clock()%2==0?1:-1;
+ bitmap::ConfigureBlitdataRotation(bldRotated,1);
+// bldPlayerCopyTMP.CustomData |= SQUARE_INDEX_MASK;
+ bRotate=true;
+ }else{
+ iLastSleepSide=0;
+// bldPlayerCopyTMP.CustomData &= ~SQUARE_INDEX_MASK;
+ }
+
+ /**
+ * This is an attempt to workaround the alpha blit.
+ *
+ * The problem (glitch):
+ * To blit the player with transparent background we use TRANSPARENT_COLOR.
+ * But when the alpha blit from Player->Draw() writes to the bitmap, it will blend with the TRANSPARENT_COLOR.
+ *
+ * The workaround:
+ * Let it draw over TRANSPARENT_COLOR.
+ * Look for the first available (non used) color from darkest possible.
+ * Let it draw again over that not found color to prevent the glitch.
+ *
+ * TODO The correct solution (may be):
+ * Let Player->Draw(), when blitting alpha pixels, optionally use some requested color (like black) just to blend
+ * with thes alpha pixels, instead of the existing one (TRANSPARENT_COLOR that is pink).
+ */
+ static col16 aColorToClear[256];static bool bDummy_aColorToClear = [](){ //grey levels
+ for(int i=0;i<256;i++)aColorToClear[i]=MakeRGB16(i,i,i); return true;}();
+ bldPlayerCopyTMP.Bitmap->Fill(0,0,TILE_V2,TRANSPARENT_COLOR);
+ Player->Draw(bldPlayerCopyTMP);
+
+ col16 colorNotFound=TRANSPARENT_COLOR; //this may cause one frame glitch from time to time :/ by bleding other color that has alpha with that color
+
+ if(bkgAlignmentColor != TRANSPARENT_COLOR){ // prefers alignment color first for best blending
+ if(!bldPlayerCopyTMP.Bitmap->HasColor(bkgAlignmentColor))
+ colorNotFound=bkgAlignmentColor;
+ }
+
+ if(colorNotFound == TRANSPARENT_COLOR){
+ for(int i=0;i<256;i++){ //starting from black (0,0,0) gave better visual results than from white or gray.
+ if(!bldPlayerCopyTMP.Bitmap->HasColor(aColorToClear[i])){
+ colorNotFound=aColorToClear[i]; DBG2(colorNotFound,i);
+ break;
+ }
+ }
+ }
+
+ if(colorNotFound != TRANSPARENT_COLOR){
+ bldPlayerCopyTMP.Bitmap->Fill(0,0,TILE_V2,colorNotFound);
+ Player->Draw(bldPlayerCopyTMP); // draws again for best blending
+ bldPlayerCopyTMP.Bitmap->ReplaceColor(colorNotFound, TRANSPARENT_COLOR);
+ }
+ /*
+ static col16 ColorBlendWithAlphaAndToClear = MakeRGB16(255,254,253); //TODO expectedly unused, but just a wild bad guess...
+ bldPlayerCopyTMP.Bitmap->Fill(0,0,TILE_V2, ColorBlendWithAlphaAndToClear);
+ Player->Draw(bldPlayerCopyTMP);
+ bldPlayerCopyTMP.Bitmap->ReplaceColor(ColorBlendWithAlphaAndToClear,TRANSPARENT_COLOR); //TODO this may create holes in the image...
+ */
+ /*
+ static bool bBkgPlayerForceTransparent = true;
+ bldPlayerCopyTMP.Bitmap->Fill(0,0,TILE_V2, bBkgPlayerForceTransparent ? TRANSPARENT_COLOR : bkgAlignmentColor);
+ Player->Draw(bldPlayerCopyTMP);
+ * */
+
+ bitmap* bmpPlayerSrc=bldPlayerCopyTMP.Bitmap; //DBG1(bmpPlayerSrc);
+
+ bool bXbyYis3by4=ivanconfig::GetAltSilhouette()>=iTallFrom; // tall/breathing
+ if(bXbyYis3by4){
+ static blitdata bldPlayer3by4TMP = [](){
+// blitdata B = DEFAULT_BLITDATA;
+ bldPlayer3by4TMP=DEFAULT_BLITDATA;
+ bldPlayer3by4TMP.Bitmap = new bitmap(v2OverSilhouette);
+// return B;
+ return bldPlayer3by4TMP;
+ }();
+// if(bldPlayer3by4TMP.Bitmap==NULL){
+// bldPlayer3by4TMP.Bitmap = new bitmap(v2OverSilhouette);
+// }
+
+ bool bTired = Player->GetTirednessState()==EXHAUSTED || Player->GetTirednessState()==FAINTING;
+
+ static int iFullBreathCount=0;
+
+ static bool bKeepRolling=false;
+ static int iNextRollAtFullBreath=0;
+ if(bRolling && !bFluctuating && !bSleeping && iTallState==0){
+ if(Player->GetBurdenState()!=OVER_LOADED){
+ if(iFullBreathCount>=iNextRollAtFullBreath){
+ int iRollFPS = 3 * (PlayerIsRunning()?2:1); // 4 steps is one full roll 360 degrees
+ int iStepDelay = CLOCKS_PER_SEC/iRollFPS;
+
+ static clock_t nextRollTime=0;
+ static int iRollDirection=1;
+ static int iRollingCount=0;
+ if(clock() >= nextRollTime){
+ iRollingCount++;
+
+ bitmap::ConfigureBlitdataRotation(bldRotated,iRollingCount*iRollDirection);
+ DBG5("RollRotate90deg", iRollingCount*iRollDirection, bldRotated.Flags&ROTATE, bldRotated.Flags&FLIP, bldRotated.Flags&MIRROR );
+
+ if(iRollingCount >= 4){
+ bKeepRolling=false;
+ iRollDirection = clock()%2==0 ? 1 : -1; //prepare for next roll direction TODO use last if was left or right move (will ignore up/down tho)? would look good
+ iRollingCount=0;
+ iNextRollAtFullBreath = iFullBreathCount + 2 + clock()%4; DBG1(iNextRollAtFullBreath);
+ }else{
+ bKeepRolling=true;
+ } DBG2(bKeepRolling,DBGB(bKeepRolling));
+
+ nextRollTime = clock()+iStepDelay;
+ }
+
+ bRotate=true;
+ }
+ }else{
+ bKeepRolling=false;
+ }
+ }
+
+ if(bRotate){
+ bmpPlayerSrc->NormalBlit(bldRotated); //DBG1(bmpPlayerSrc);DBGLN;
+ bmpPlayerSrc = bldRotated.Bitmap; //DBG1(bmpPlayerSrc);DBGLN;
+ }
+
+ /********************************************
+ * set base position
+ */
+ if(bFluctuating){
+ float fStepsPerSecond=15; //fly turbulence move base speed
+ int iMoveStep=1;
+ if(PlayerIsRunning()){
+ static int iRunMultSPS=2;
+ fStepsPerSecond *= iRunMultSPS; //this will not work well if the machine is too slow
+ if(globalwindowhandler::GetFPS(true) < fStepsPerSecond) iMoveStep=iRunMultSPS; //this is like a frame skip
+ }
+ if(bTired){
+ fStepsPerSecond/=2;
+ iMoveStep=1;
+ }
+ long lFlyStepDelay = CLOCKS_PER_SEC/fStepsPerSecond;
+
+ static v2 v2PtoSAmoveTo;
+ long lTimeNow=clock(); //this is animation based on real time.
+ bool bDoStepNow=false;
+ static long lPreviousFlyStepTime=0;
+ if(lTimeNow-lPreviousFlyStepTime > lFlyStepDelay){
+ bDoStepNow=true;
+ lPreviousFlyStepTime=lTimeNow;
+ }else{DBGSI(lTimeNow);}
+
+ v2 v2Dist = v2PtoSAmoveTo - v2AltSilMovingPos; DBG2(DBGAV2(v2Dist),DBGB(v2Dist=iMoveStep || abs(v2Dist.Y)>=iMoveStep) ){ //slowly move to the new spot
+ if(bDoStepNow){
+ if(v2AltSilMovingPos.X < v2PtoSAmoveTo.X)v2AltSilMovingPos.X+=iMoveStep;
+ else
+ if(v2AltSilMovingPos.X > v2PtoSAmoveTo.X)v2AltSilMovingPos.X-=iMoveStep;
+
+ if(v2AltSilMovingPos.Y < v2PtoSAmoveTo.Y)v2AltSilMovingPos.Y+=iMoveStep;
+ else
+ if(v2AltSilMovingPos.Y > v2PtoSAmoveTo.Y)v2AltSilMovingPos.Y-=iMoveStep;
+ }
+ }else{ //prepare new target fly spot destination
+ // a bit more turbulence :)
+ v2 v2Displ;
+ int iMaxDisplacementFromCenterLess1=TILE_SIZE/4;//(PlayerIsRunning()?4:8);
+ v2Displ.X = clock()%iMaxDisplacementFromCenterLess1;
+ v2Displ.Y = clock()%iMaxDisplacementFromCenterLess1;
+ v2Displ.X *= clock()%2==0 ? 1 : -1;
+ v2Displ.Y *= clock()%2==0 ? 1 : -1;
+
+ v2PtoSAmoveTo = v2AltSilTopCenterPos - v2(v2OverSilhouette.X/2,0); //top left
+ v2PtoSAmoveTo += v2Displ; //variation from top center
+ }
+
+ }
+
+ if(!bKeepRolling && !bSleeping){
+ int iYDest=0;
+ int iBreathStepCount=0;
+ if(ivanconfig::GetAltSilhouette()>=iBreathFrom){ //breath animation
+ int nBreathDelay = 20 + 10*(ivanconfig::GetAltSilhouette()-iBreathFrom); //calm breathing
+ if(PlayerIsRunning())nBreathDelay/=2;
+ if(Player->GetTirednessState()==EXHAUSTED)nBreathDelay/=2; // OR faiting...
+ if(Player->GetTirednessState()==FAINTING )nBreathDelay/=4;
+ if(nBreathDelay<1)nBreathDelay=1;
+
+ iBreathStepCount = iAltSilBlitCount/nBreathDelay;
+ int iTotTallStatesCurrent=iTotTallStates;
+ if(bFluctuating)iTotTallStatesCurrent=2;
+ int iTallStateNew = iBreathStepCount % iTotTallStatesCurrent;
+ // if(bFluctuating)iTallStateNew=0;
+ if(iTallStateNew!=iTallState){
+ if(iTallStateNew==0)iFullBreathCount++;
+ }
+ iTallState=iTallStateNew;
+ }DBG1(iTallState);
+ if(TILE_SIZE==16){ // this is like a post processing gfx
+ //never glue the head on top to prevent (more) stretching distortions, so we have at least one empty line on top
+ bldPlayer3by4TMP.Bitmap->Fill(0, iYDest++, TILE_SIZE, 1, TRANSPARENT_COLOR);
+
+ bool bLower = (iTallState==0 && bTired) || bFluctuating;
+
+ int iTotBlankLines = iTotTallStates - (iTallState+1);
+ // 3-(2+1)=0 //nothing
+ // 3-(1+1)=1 //0
+ // 3-(0+1)=2 //0 1
+ if(bLower)iTotBlankLines++; //wont dup pants
+
+ bool bJump=false;
+ if(bFluctuating){
+ iTotBlankLines+=1; // for the shorter legs
+ iTotBlankLines+=2; // for the even smaller torso with -2 lines both at 0 and 1 tall states
+ // switch(iTallState){
+ // case 0: iTotBlankLines+=2; break; // for the even smaller torso
+ // case 1: iTotBlankLines+=1; break;
+ // }
+
+ // // random blank above head to make it oscillate while flying
+ // if(iFlyRandom%2==0){
+ // bldPlayer3by4TMP.Bitmap->Fill(0, iYDest++, TILE_SIZE, 1, TRANSPARENT_COLOR);
+ // iTotBlankLines--;
+ // }
+ }else{
+ if(iTallState==0 && bHopping && clock()%2==0)bJump=true;
+
+ //blank space above head
+ if(!bJump)
+ for(int i=0;iFill(0, iYDest++, TILE_SIZE, 1, TRANSPARENT_COLOR);
+ }
+
+ /*************************************
+ * full body
+ *************************************/
+ int iHeadLines=6;
+ for(int y=0;yCopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,y,TILE_SIZE,true);
+ }
+
+ // torso are lines 6 7 8 9 (lets keep it simple to read...)
+ switch(iTallState){
+ case 0:
+ if(bFluctuating){ // -2L (4 lines)
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,9,TILE_SIZE,true);
+ }else{ //lowest (6 lines) for non flying
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,9,TILE_SIZE,true);
+ }
+ break;
+ case 1:
+ if(bFluctuating){ // -2L (5 lines)
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,9,TILE_SIZE,true);
+ }else{ // (7 lines)
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,9,TILE_SIZE,true);
+ }
+ break;
+ case 2:
+ if(bFluctuating){ // -2L (6 lines)
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,9,TILE_SIZE,true);
+ }else{ //tallest (8 lines)
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,6,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,7,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,8,TILE_SIZE,true);
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,9,TILE_SIZE,true);
+ }
+ break;
+ default:
+ ABORT("not supported tall state %d",iTallState); //all the above is for 3 tall states, changing it probably will require updating them all
+ }
+
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,10,TILE_SIZE,true); //pants
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,11,TILE_SIZE,true); //weapon handle
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,12,TILE_SIZE,true); //pants
+ if(!bLower)bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,12,TILE_SIZE,true); //pants dup
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,13,TILE_SIZE,true);
+ if(!bFluctuating)bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,14,TILE_SIZE,true); //shorter legs if flying
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest++,bldPlayerCopyTMP.Bitmap,15,TILE_SIZE,true); //feet
+
+ ////////////////////////// end of body //////////////////////////
+
+ if(bFluctuating || bJump){
+ // blank lines below feet
+ for(int i=0;iFill(0, iYDest++, TILE_SIZE, 1, TRANSPARENT_COLOR);
+ }
+
+ if(iYDest!=iY4)ABORT("bad calc iYDest=%d != iY4=%d, jump=%s, fly=%s, swim=%s, lower=%s, TotBlank=%d",iYDest,iY4,
+ bJump?"T":"F", Player->IsFlying()?"T":"F", Player->IsSwimming()?"T":"F", bLower?"T":"F", iTotBlankLines); //Better never remove this, highly useful!
+
+ }else{
+ // fall back to simple blit for not supported tile sizes
+ bool bBreakLoop=false;
+ for(int y = 0; y < TILE_SIZE; ++y){
+ if(bBreakLoop)break;
+ bldPlayer3by4TMP.Bitmap->CopyLineFrom(iYDest,bldPlayerCopyTMP.Bitmap,y,TILE_SIZE,true);
+ if(++iYDest>=iY4){bBreakLoop=true;continue;}
+ }
+ }
+
+ bmpPlayerSrc=bldPlayer3by4TMP.Bitmap;
+ }
+
+ }
+
+ static blitdata bldPlayerToSilhouetteAreaAtDB = [](){
+ blitdata B = DEFAULT_BLITDATA;
+ B.Stretch = 3;
+ B.Bitmap = DOUBLE_BUFFER;
+ return B;
+ }();
+// if(bldPlayerToSilhouetteAreaAtDB.Bitmap==NULL){
+// bldPlayerToSilhouetteAreaAtDB.Stretch = 3;
+// bldPlayerToSilhouetteAreaAtDB.Bitmap = DOUBLE_BUFFER;
+// };
+ bldPlayerToSilhouetteAreaAtDB.Dest = v2AltSilPos;
+ if(bXbyYis3by4 && !bSleeping){
+ bldPlayerToSilhouetteAreaAtDB.Dest = v2AltSilMovingPos; DBGLN;
+ }else{
+// if(bSleeping && !bFluctuating){
+// bldPlayerToSilhouetteAreaAtDB.Dest.Y += iY4-TILE_SIZE;
+// }else{
+// bldPlayerToSilhouetteAreaAtDB.Dest.Y += TILE_SIZE/2 + (iY4-TILE_SIZE); //at bottom
+ bldPlayerToSilhouetteAreaAtDB.Dest.Y += (iY4-TILE_SIZE)*bldPlayerToSilhouetteAreaAtDB.Stretch; //at bottom
+ // bldPlayerToSilhouetteAreaAtDB.Dest.Y += TILE_SIZE/2; //to center on it TODO wrong?
+ }
+ bldPlayerToSilhouetteAreaAtDB.Border = bmpPlayerSrc->GetSize(); DBGBLD(bldPlayerToSilhouetteAreaAtDB);
+
+ /*************************************************
+ * blit the base background to DB
+ */
+ static const v2 v2StretchedPos = v2AltSilPos+v2(-2,0); DBG2(DBGAV2(v2AltSilPos),DBGAV2(v2StretchedPos));
+// v2 v2StretchedBorder = (v2OverSilhouette+v2(4,2))*bldPlayerToSilhouetteAreaAtDB.Stretch;
+ static const v2 v2StretchedBorder = (v2OverSilhouette*bldPlayerToSilhouetteAreaAtDB.Stretch)+v2(4,2);
+
+ switch(ivanconfig::GetAltSilhouettePreventColorGlitch()){
+ case 0:
+ igraph::BlitBackGround(DOUBLE_BUFFER, v2StretchedPos, v2StretchedBorder);
+ break;
+ case 1:
+ DOUBLE_BUFFER->Fill(v2StretchedPos, v2StretchedBorder, darkestThatWontGlitchWithAlpha);
+ break;
+ case 2:
+ static blitdata bldLum = [](){bldLum=DEFAULT_BLITDATA;
+ bldLum.Bitmap = DOUBLE_BUFFER;
+ bldLum.Dest = bldLum.Src = v2StretchedPos;
+ bldLum.Border = v2StretchedBorder; return bldLum;}();
+
+ static long iNextAlignBkgMove=0;
+ if(clock()>iNextAlignBkgMove){
+ static v2 v2DisplTargetNext=v2(0,0); DBGSV2(v2DisplTargetNext);
+ static v2 v2Displacement=v2(0,0); DBGSV2(v2Displacement);
+ v2 v2Diff = v2DisplTargetNext-v2Displacement; DBGSV2(v2Diff);
+ int iAbsPA=(abs(iPlayerAlignment)*2)+1; DBG1(iAbsPA);
+ if(v2Diff.Is0()){
+ v2DisplTargetNext=v2( clock()%iAbsPA, clock()%iAbsPA);
+ }else{
+ if(v2Diff.X!=0)v2Displacement.X += v2Diff.X>0 ? 1 : -1;
+ if(v2Diff.Y!=0)v2Displacement.Y += v2Diff.Y>0 ? 1 : -1;
+ }
+ bldLum.Src = v2StretchedPos+v2Displacement; DBGSV2(v2Displacement);
+ long iDisplDelay = CLOCKS_PER_SEC/iAbsPA;
+ iNextAlignBkgMove = clock()+iDisplDelay;
+ }
+
+ bldLum.Luminance = bkgAlignmentLum24;
+ igraph::GetBackGround()->LuminanceBlit(bldLum); DBGBLD(bldLum);
+ //DOUBLE_BUFFER->Fill(v2StretchedPos, v2StretchedBorder, bkgAlignmentColor);
+ break;
+ }
+
+ bool bAllowOtherLayers=!IsInWilderness(); //TODO let it work in wilderness too)
+ /*************************************************
+ * configure the final blit to DB
+ */
+ static blitdata bldToDB = [](){bldToDB=DEFAULT_BLITDATA;
+ bldToDB.Border=v2StretchedBorder;
+ bldToDB.Luminance=NORMAL_LUMINANCE;
+ bldToDB.Bitmap=DOUBLE_BUFFER; return bldToDB;}(); DBGBLD(bldToDB);
+
+ /*************************************************
+ * collect the graphics from the square
+ */
+ static blitdata bldFromSqr = [](){bldFromSqr = DEFAULT_BLITDATA;
+ bldFromSqr.Border=TILE_V2;
+ bldFromSqr.Bitmap=new bitmap(bldFromSqr.Border);
+ bldFromSqr.Luminance=NORMAL_LUMINANCE;
+ bldFromSqr.CustomData |= ALLOW_ANIMATE; return bldFromSqr; }(); DBGBLD(bldFromSqr);
+ if(bAllowOtherLayers){
+ // if(Player->IsSwimming()){
+ // // collect the liquid ground gfx
+ Player->GetLSquareUnder()->GetGLTerrain()->Draw(bldFromSqr); //only the terrain w/o other stuff dropped on it
+ // }else{
+ // // collect the whole ground gfx
+ // Player->GetLSquareUnder()->DrawStaticContents(bldFromSqr);
+ // }
+ }
+
+ /*************************************************
+ * prepare the multiplied ground copy for maximum details before stretching
+ */
+ static v2 v2CopyWH = [](){
+ v2CopyWH = v2(3,4); //the tall silhouette
+ v2CopyWH += v2(1,1); //+1,1 as there is tiny bits around the player allowing fly/swim shaking animations
+ v2CopyWH += v2(0,1); //+1 if the ground liquid oscilates too much
+ return v2CopyWH;
+ }();
+ static blitdata bldCopy = [](){bldCopy = DEFAULT_BLITDATA;
+ bldCopy.Border = v2CopyWH*TILE_SIZE;
+ bldCopy.Bitmap=new bitmap(bldCopy.Border);
+ bldCopy.Bitmap->CreateAlphaMap(0xFF*0.50); return bldCopy;}(); DBGBLD(bldCopy);
+ if(bAllowOtherLayers){
+ // static blitdata bldStretch = [](){bldStretch = DEFAULT_BLITDATA;
+ // bldStretch.Stretch=bldPlayerToSilhouetteAreaAtDB.Stretch+1; //+1 as there is tiny bits around the player allowing fly/swim animations
+ // bldStretch.Border = TILE_V2;
+ // bldStretch.Bitmap=new bitmap(bldStretch.Border * bldStretch.Stretch);
+ // bldStretch.Bitmap->CreateAlphaMap(0xFF*0.50); return bldStretch;}(); DBGBLD(bldStretch);
+ // stretch that gfx enough to prepare the final blit
+ // graphics::Stretch(ivanconfig::IsXBRZScale(),bldFromSqr.Bitmap,bldStretch,true);
+ for(int iY=0;iYNormalBlit(bldCopy); //to have maximum details before stretching later
+ }
+ }
+ }
+
+ if(bAllowOtherLayers){
+ /*************************************************
+ * the moving shrinked ground below player
+ */
+ if(!Player->IsSwimming()){ //TODO wilderness: earth below and treetop on top sides, in case walking in trees square
+ int iWalkFPS = 2 * (PlayerIsRunning()?3:1);
+ int iStepDelay = CLOCKS_PER_SEC/iWalkFPS;
+
+ static int iWalkStepPrevious=-1;
+ int iWalkStep = clock()/iStepDelay;
+ if(iWalkStepPrevious!=iWalkStep){
+ int iHeight = v2StretchedBorder.Y * (bRolling||bSleeping ? 0.66 : 0.33);
+ bldToDB.Dest = v2StretchedPos+(v2(0,v2StretchedBorder.Y-iHeight));
+ bldToDB.Border.Y=iHeight;
+
+ //walking ground effect
+ static int iGroundSrcY=0;
+ bool bIsMovingOnFloor = !bSleeping && Player->GetBurdenState()!=OVER_LOADED;
+ if(bIsMovingOnFloor)
+ iGroundSrcY++; //moving
+ if((iGroundSrcY+iHeight)>v2StretchedBorder.Y)
+ iGroundSrcY=0;
+ bldToDB.Src = v2(0,iGroundSrcY);
+
+ iWalkStepPrevious=iWalkStep;
+ }
+
+ // copy from stretched as much as needed, to DB
+ // bldStretch.Bitmap->NormalBlit(bldToDB);
+ bldCopy.Bitmap->NormalBlit(bldToDB);
+ }
+ }
+
+ /*************************************************
+ * this stretch draws the modified player at the tiny silhouette region at DB
+ **/
+ graphics::Stretch(ivanconfig::IsXBRZScale(),bmpPlayerSrc,bldPlayerToSilhouetteAreaAtDB,true); DBG1(bmpPlayerSrc);
+
+ if(bAllowOtherLayers){
+ /*************************************************
+ * draw transparent ground liquid above player
+ */
+ if(Player->IsSwimming()){
+ static bool bSimple=false;
+
+ static const int iMaxWaveLength=6;
+ static int iWaveLength=iMaxWaveLength;
+ static const int iHeight = v2StretchedBorder.Y*0.75;
+ static const int iLiquidFPS=5;
+ static const int iStepDelay = CLOCKS_PER_SEC/iLiquidFPS;
+
+ static int iWaveStepPrevious=-1;
+ int iWaveStep = clock()/iStepDelay;
+ static int iDegrees;
+ static int iHeightFinal;
+ static int iDestDisplY;
+ static v2 v2Dest;
+ static int iDegreesStep=30;
+ if(iWaveStepPrevious!=iWaveStep){
+ iDegrees+=iDegreesStep;
+ if(iDegrees>=360){
+ iDegrees=0;
+ iDegreesStep=30+clock()%60;
+ iWaveLength=iMaxWaveLength/(1 + clock()%3);
+ }
+ iHeightFinal = iHeight + iWaveLength*sin(iDegrees*3.14159/180);
+ iDestDisplY = v2StretchedBorder.Y - iHeightFinal;
+ v2Dest = v2StretchedPos+v2(0,iDestDisplY);
+ iWaveStepPrevious=iWaveStep;
+ }
- int FromKeyQuestion = KeyQuestion(String, DefaultAnswer, 5, 'y', 'Y', 'n', 'N', OtherKeyForTrue);
- return FromKeyQuestion == 'y' || FromKeyQuestion == 'Y' || FromKeyQuestion == OtherKeyForTrue;
-}
+ if(bSimple){
+ DOUBLE_BUFFER->Fill(v2Dest, v2(v2StretchedBorder.X,iHeightFinal), BLUE);
+ }else{
+ // copy from stretched as much as needed, to DB
+ bldToDB.Dest = v2Dest;
+ bldToDB.Border.Y=iHeightFinal;
+ /* TODO oscilating the alpha is being cumulative? leading to full transparency, and this alpha veriation is not working as intended:
+ float fAlpha = 0.85-(0.03*iWaveStep);
+ bldStretch.Bitmap->FillAlpha(0xFF*fAlpha);
+ */
+ bldCopy.Bitmap->AlphaMaskedBlit(bldToDB); //->AlphaLuminanceBlit(bldToDB);
+ }
+ }
+ }
-void game::DrawEverything()
-{
- DrawEverythingNoBlit();
- graphics::BlitDBToScreen();
-}
+ if(ivanconfig::GetAltSilhouettePreventColorGlitch()>0)
+ graphics::DrawRectangleOutlineAround(DOUBLE_BUFFER, v2StretchedPos, v2StretchedBorder, DARK_GRAY, false);
-truth game::OnScreen(v2 Pos)
-{
- return Pos.X >= 0 && Pos.Y >= 0 && Pos.X >= Camera.X && Pos.Y >= Camera.Y
- && Pos.X < GetCamera().X + GetScreenXSize() && Pos.Y < GetCamera().Y + GetScreenYSize();
+ iAltSilBlitCount++;
}
void game::DrawEverythingNoBlit(truth AnimationDraw)
{
+ bool bXBRZandFelist = ivanconfig::IsXBRZScale() && felist::isAnyFelistCurrentlyDrawn();
+
if(LOSUpdateRequested && Player->IsEnabled())
{
if(!IsInWilderness())
@@ -760,18 +2486,19 @@ void game::DrawEverythingNoBlit(truth AnimationDraw)
DOUBLE_BUFFER->Fill(CalculateScreenCoordinates(CursorPos), TILE_V2, 0);
}
- for(size_t c = 0; c < SpecialCursorPos.size(); ++c)
- if(OnScreen(SpecialCursorPos[c]))
- CurrentArea->GetSquare(SpecialCursorPos[c])->SendStrongNewDrawRequest();
+ if(!bXBRZandFelist)
+ for(size_t c = 0; c < SpecialCursorPos.size(); ++c)
+ if(OnScreen(SpecialCursorPos[c]))
+ CurrentArea->GetSquare(SpecialCursorPos[c])->SendStrongNewDrawRequest();
globalwindowhandler::UpdateTick();
- GetCurrentArea()->Draw(AnimationDraw);
+ if(!bXBRZandFelist)GetCurrentArea()->Draw(AnimationDraw);
Player->DrawPanel(AnimationDraw);
if(!AnimationDraw)
msgsystem::Draw();
- if(OnScreen(CursorPos))
+ if(!bXBRZandFelist && OnScreen(CursorPos))
{
v2 ScreenCoord = CalculateScreenCoordinates(CursorPos);
blitdata B = { DOUBLE_BUFFER,
@@ -791,18 +2518,18 @@ void game::DrawEverythingNoBlit(truth AnimationDraw)
}
if(DoZoom())
- {
+ { //TODO could this zoom feature simply be another stretchregion?
B.Src = B.Dest;
- B.Dest.X = RES.X - 96;
- B.Dest.Y = RES.Y - 96;
- B.Stretch = 5;
- DOUBLE_BUFFER->StretchBlit(B);
+ B.Dest = ZoomPos;
+ B.Stretch = iZoomFactor;
+ graphics::DrawRectangleOutlineAround(DOUBLE_BUFFER, ZoomPos, TILE_V2*iZoomFactor, DARK_GRAY, true);
+ graphics::Stretch(ivanconfig::IsXBRZScale(),DOUBLE_BUFFER,B,false);
}
igraph::DrawCursor(ScreenCoord, CursorData);
}
- if(Player->IsEnabled())
+ if(!bXBRZandFelist && Player->IsEnabled())
{
if(Player->IsSmall())
{
@@ -812,6 +2539,7 @@ void game::DrawEverythingNoBlit(truth AnimationDraw)
{
v2 ScreenCoord = CalculateScreenCoordinates(Pos);
igraph::DrawCursor(ScreenCoord, Player->GetCursorData());
+ if(!DoZoom())UpdatePosAroundForXBRZ(Pos);
}
}
else
@@ -824,18 +2552,401 @@ void game::DrawEverythingNoBlit(truth AnimationDraw)
{
v2 ScreenCoord = CalculateScreenCoordinates(Pos);
igraph::DrawCursor(ScreenCoord, Player->GetCursorData()|CURSOR_BIG, c);
+ if(!DoZoom())UpdatePosAroundForXBRZ(Pos);
}
}
}
}
- for(size_t c = 0; c < SpecialCursorPos.size(); ++c)
- if(OnScreen(SpecialCursorPos[c]))
- {
- v2 ScreenCoord = CalculateScreenCoordinates(SpecialCursorPos[c]);
- igraph::DrawCursor(ScreenCoord, SpecialCursorData[c]);
- GetCurrentArea()->GetSquare(SpecialCursorPos[c])->SendStrongNewDrawRequest();
+ if(!bXBRZandFelist){
+ for(size_t c = 0; c < SpecialCursorPos.size(); ++c){
+ if(OnScreen(SpecialCursorPos[c]))
+ {
+ v2 ScreenCoord = CalculateScreenCoordinates(SpecialCursorPos[c]);
+ igraph::DrawCursor(ScreenCoord, SpecialCursorData[c]);
+ GetCurrentArea()->GetSquare(SpecialCursorPos[c])->SendStrongNewDrawRequest();
+ }
+ }
+ }
+
+ UpdateAltSilhouette(AnimationDraw);
+
+ UpdateShowItemsAtPos(!bXBRZandFelist); //last thing as this is a temp overlay
+
+ #ifdef WIZARD
+ DBG1(vDbgDrawOverlayFunctions.size());
+ if(vDbgDrawOverlayFunctions.size()>0){DBGLN; // ULTRA last thing
+ for(int i=0;iGetItems();
+ if(iMax>-1)iTot = Min(iMax,iTot);
+ if(iTot==0)return NULL;
+
+ v2 v2Pos = v2PosIni; DBGSV2(v2PosIni);
+
+ blitdata B = DEFAULT_BLITDATA;
+ B.CustomData = ALLOW_ANIMATE;
+ B.Stretch = 1; //ignored? anyway this will work only from/to 16x16...
+ B.Border = { TILE_SIZE, TILE_SIZE };
+ B.Luminance = ivanconfig::GetContrastLuminance();
+
+ if(bUseDB){
+ bmpTgt = DOUBLE_BUFFER;
+ }else{
+ v2 v2Size = v2(TILE_SIZE*iTot,TILE_SIZE);
+ if(bmpTgt==NULL || bmpTgt->GetSize()!=v2Size){
+ // DO NOT DELETE the old bitmap here. See graphics::SetSRegionSrcBitmapOverride(); //NO NO NO: if(bmpTgt!=NULL)delete bmpTgt;
+ bmpTgt = new bitmap(v2Size);
+ }
+ }
+
+ B.Bitmap=bmpTgt;
+ B.CustomData |= ALLOW_ANIMATE|ALLOW_ALPHA;
+
+ static bool bLight=false; //TODO make this an user option?
+ col16 clOutline = bLight ? LIGHT_GRAY : BLACK;//DARK_GRAY;
+ if(!bLight){ //overall around if tiny
+ v2 v2BkgIni = v2(0,0);
+ v2 v2Border = bmpTgt->GetSize();
+ if(bUseDB){
+ v2BkgIni = v2PosIni+v2(1,1);
+ if(iDirX<0)v2BkgIni.X-=((iTot-1)*TILE_SIZE);
+ if(iDirY<0)v2BkgIni.Y-=((iTot-1)*TILE_SIZE);
+
+ v2Border = B.Border;
+ if(iDirX!=0)v2Border.X*=iTot;
+ if(iDirY!=0)v2Border.Y*=iTot;
+ v2Border-=v2(2,2);
+ }
+ igraph::BlitBackGround(bmpTgt, v2BkgIni, v2Border);
+ graphics::DrawRectangleOutlineAround(bmpTgt, v2BkgIni, v2Border, clOutline, false);
+ }
+// itemvector vit;su->FillItemVector(vit);
+ static itemvector vit;vit.clear();su->FillItemVector(vit);
+ for(int i=0;iCanBeSeenByPlayer())continue;
+
+ if(bLight){ // each square
+ bmpTgt->Fill(v2Pos, B.Border, DARK_GRAY);
+ graphics::DrawRectangleOutlineAround(bmpTgt, v2Pos+v2(1,1), B.Border-v2(2,2), clOutline, false);
+ }
+
+ B.Dest = v2Pos; DBGBLD(B);
+ it->Draw(B);
+
+ v2Pos.X+=(TILE_SIZE*iDirX);
+ v2Pos.Y+=(TILE_SIZE*iDirY);
+ }
+
+ return bmpTgt;
+}
+
+int iStretchedTileSize = -1;
+int getDungeonStretchedTileSize(){
+ if(iStretchedTileSize==-1)iStretchedTileSize = TILE_SIZE * ivanconfig::GetStartingDungeonGfxScale();
+ return iStretchedTileSize;
+}
+
+/**
+ * For Stretched buffer:
+ * The final screen coordinates are relative not to 0,0 but to the top left dungeon corner,
+ * because the full dungeon stretching happens from that spot,
+ * therefore when working on the stretched buffer, this does not work, ex.:
+ * CalculateScreenCoordinates(Player->GetPos())
+ */
+v2 game::CalculateStretchedBufferCoordinatesFromDungeonSquarePos(v2 v2SqrPos){
+ v2 v2SqrRelativePosFromCam = v2SqrPos - GetCamera();
+ v2 v2StretchedBufferDest=area::getTopLeftCorner();
+ v2StretchedBufferDest+=(v2SqrRelativePosFromCam*getDungeonStretchedTileSize());
+ return v2StretchedBufferDest;
+}
+
+void game::UpdateShowItemsAtPos(bool bAllowed,v2 v2AtPos){
+ if(v2AtPos.Is0() && bPositionQuestionMode) v2AtPos = CursorPos;
+
+ bool bOk=true;
+
+ if(bOk && !bAllowed)bOk=false;
+
+// if(bOk && !bAllowPosMode && bPositionQuestionMode)bOk=false;
+
+ if(bOk && !Player->IsEnabled())bOk=false;
+
+ if(bOk && Player->IsDead())bOk=false;
+
+ if(bOk && v2AtPos.Is0()){ //after validating player
+ v2AtPos = Player->GetPos();
+ }
+
+ if(bOk && !OnScreen(v2AtPos))bOk=false;
+
+ if(bOk && IsInWilderness())bOk=false;
+
+ if(bOk){
+ if(v2AtPos!=Player->GetPos())
+ if(!GetCurrentLevel()->GetLSquare(v2AtPos)->CanBeSeenByPlayer())
+ bOk=false;
+ }
+
+ bool bDynamic=false;
+ bool bDynamicItems=false;
+ if(ivanconfig::GetShowItemsAtPlayerSquare()>=10){
+ bDynamic=true;
+ if(ivanconfig::GetShowItemsAtPlayerSquare()==11)bDynamicItems=true;
+ }
+ int iCode = 1;
+ if(!bDynamic)iCode=ItemUnderCode(ivanconfig::GetShowItemsAtPlayerSquare());
+ bool bEnabled = iCode>0;
+ bool bAboveHead = iCode==1;
+
+ if(bOk && !bEnabled)bOk=false;
+
+ stack* su = NULL;
+ if(bOk){
+ // su=Player->GetStackUnder(); //try{su=Player->GetStackUnder();}catch(std::exception& e){bOk=false;} TODO is this catch too generic/permissive?
+ su=GetCurrentLevel()->GetLSquare(v2AtPos)->GetStack();
+ if(bOk && su==NULL)bOk=false; //TODO can this happen?
+ if(bOk && su->GetItems()==0)bOk=false;
+ if(bOk){
+// itemvector vit;su->FillItemVector(vit);
+ static itemvector vit;vit.clear();su->FillItemVector(vit);
+ for(int i=0;iCanBeSeenByPlayer())break;
+ if(i==(vit.size()-1))bOk=false; // nothing there can be seen
+ }
+ }
+ }
+
+ if(!bOk){ // reaching here is IMPORTANT as a disabler to the region!
+ graphics::SetSRegionEnabled(iRegionItemsUnder,false);
+ return;
+ }
+
+ /////////////////////// ok ////////////////////////
+ const v2 v2AbsLevelSqrPos = v2AtPos;
+
+ bool bNearEC=false;
+ int iNearEC=3; //near edges/corners to avoid hiding player/NPCs that can be in combat TODO use player view distance?
+ int iCycleCodeFallBack=4; //top right horiz if not near corners/edges
+ if(v2AbsLevelSqrPos.X<=iNearEC){ //left edge
+ bNearEC=true;iCycleCodeFallBack=8; //bottom right vert
+ }else if(v2AbsLevelSqrPos.Y<=iNearEC){ //top edge
+ bNearEC=true;iCycleCodeFallBack=6; //bottom left horiz
+ }else if(v2AbsLevelSqrPos.X >= (GetCurrentArea()->GetXSize() - iNearEC)){ //right edge
+ bNearEC=true;iCycleCodeFallBack=7; //bottom left vert
+ }else if(v2AbsLevelSqrPos.Y >= (GetCurrentArea()->GetYSize() - iNearEC)){ //bottom edge
+ bNearEC=true;iCycleCodeFallBack=4; //top right horiz
+ }
+ if(bNearEC)bAboveHead=true;
+
+ if(bDynamic && bAboveHead && !bPositionQuestionMode){ // will not be above head in bPositionQuestionMode
+ v2 v2Chk; //(v2AbsLevelSqrPos.X,v2AbsLevelSqrPos.Y-1);
+ bool bCharAboveNear=false;
+ bool bItemAboveNear=false;
+ for(int i=-1;i<=1;i++){
+ v2Chk = v2AbsLevelSqrPos+v2(0+i,-1);
+ if(GetCurrentLevel()->IsValidPos(v2Chk)){
+ if(GetCurrentLevel()->GetSquare(v2Chk)->GetCharacter()){
+ bCharAboveNear=true;
+ break;
+ }
+
+ if(bDynamicItems){
+ if(GetCurrentLevel()->GetLSquare(v2Chk)->GetStack()->GetItems()>0){
+ bItemAboveNear=true;
+ break;
+ }
+ }
+ }
+ }
+
+ if(bCharAboveNear || bItemAboveNear){
+ iCode = ItemUnderCode(iCycleCodeFallBack);
+ bAboveHead=false;
+ }
+ }
+
+ int iTot = su->GetItems();
+ if(iTot>game::GetScreenXSize())
+ iTot=game::GetScreenXSize();
+ if(iTot>GetCurrentArea()->GetXSize())
+ iTot=GetCurrentArea()->GetXSize();
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // above head with x1 dungeon scale will fall back to "Dungeon square overwrite mode"
+ if(bAboveHead && ivanconfig::GetStartingDungeonGfxScale()>=2){ //use xBRZ stretch region
+ // TODO ? Some possible tips if look mode is used later: GetCurrentArea()->, Player->GetArea()->get, game::GetCurrentDungeon()->
+ bitmap* bmp = PrepareItemsUnder(false, su, iTot, v2(0,0), 1, 0);
+
+ int iStretch=iItemsUnderStretch;
+ if(su->GetItems()==1)iStretch++;
+
+ v2 v2StretchedBufferDest = CalculateStretchedBufferCoordinatesFromDungeonSquarePos(v2AbsLevelSqrPos);
+ v2StretchedBufferDest.X+=getDungeonStretchedTileSize()/2; //center of player's head
+ v2StretchedBufferDest.X-=(bmp->GetSize().X*iStretch)/2;
+ v2StretchedBufferDest.Y-= bmp->GetSize().Y*iStretch; // above player's head
+ v2StretchedBufferDest.Y-=2; //just to look better
+
+ if(v2StretchedBufferDest.XGetLSquare(v2(0,0))->GetPos());DBGSV2(v2Sqr00ScrPos);
+// if(v2ScrPosIni.XGetXSize()),
+ Min(game::GetScreenYSize(), GetCurrentLevel()->GetYSize()) );
+ int iSqrMaxX=v2SqrSize.X-1;
+ int iSqrMaxY=v2SqrSize.Y-1;
+
+ switch(iCorner){
+ case 0: iDirX=bHorizontal? 1:0; iDirY=bHorizontal?0: 1;
+ break;
+ case 1: iDirX=bHorizontal?-1:0; iDirY=bHorizontal?0: 1;
+ v2SqrPosIni.X+=iSqrMaxX;
+// v2ScrPosIni.X+=iSqrMaxX*TILE_SIZE;
+ break;
+ case 2: iDirX=bHorizontal? 1:0; iDirY=bHorizontal?0:-1;
+ v2SqrPosIni.Y+=iSqrMaxY;
+// v2ScrPosIni.Y+=iSqrMaxY*TILE_SIZE;
+ break;
+ case 3: iDirX=bHorizontal?-1:0; iDirY=bHorizontal?0:-1;
+ v2SqrPosIni.X+=iSqrMaxX;
+// v2ScrPosIni.X+=iSqrMaxX*TILE_SIZE;
+ v2SqrPosIni.Y+=iSqrMaxY;
+// v2ScrPosIni.Y+=iSqrMaxY*TILE_SIZE;
+ break;
+ }
+
+ if(!bHorizontal){
+ if(iTot>game::GetScreenYSize())
+ iTot=game::GetScreenYSize();
+
+ if(iTot>GetCurrentArea()->GetYSize())
+ iTot=GetCurrentArea()->GetYSize();
}
+
+//
+// }break;
+//
+// case 2:
+// case 3:
+// case 4:
+// case 5:
+// case 6:
+// //TODO xBRZ ?
+// //TODO graphics::DrawRectangleOutlineAround(DOUBLE_BUFFER, area::getTopLeftCorner(), {TILE_SIZE*iTot,TILE_SIZE}, LIGHT_GRAY, false);
+// break;
+
+ }
+
+ v2 v2ScrPosIni=CalculateScreenCoordinates(v2SqrPosIni); DBG2(DBGAV2(v2SqrPosIni),DBGAV2(v2ScrPosIni));
+
+ PrepareItemsUnder(true,su,iTot,v2ScrPosIni,iDirX,iDirY);
+
+ /**
+ * this grants updating the squares used to show the items.
+ * this also provides a cleanup after player moves or gets things from the floor.
+ */
+ for(int i=0;iIsValidPos(v2SqrPosIni)){
+ GetCurrentArea()->GetSquare(v2SqrPosIni)->SendStrongNewDrawRequest();
+ }
+ v2SqrPosIni.X+=iDirX;
+ v2SqrPosIni.Y+=iDirY;
+ }
}
truth game::Save(cfestring& SaveName)
@@ -889,24 +3000,32 @@ truth game::Save(cfestring& SaveName)
return true;
}
-int game::Load(cfestring& SaveName)
-{
- inputfile SaveFile(SaveName + ".sav", 0, false);
+int game::Load(cfestring& saveName)
+{DBGLN;
+ inputfile SaveFile(saveName + ".sav", 0, false);
if(!SaveFile.IsOpen())
return NEW_GAME;
- int Version;
- SaveFile >> Version;
+ SaveFile >> CurrentSavefileVersion;
- if(Version != SAVE_FILE_VERSION)
- {
- if(!iosystem::Menu(0, v2(RES.X >> 1, RES.Y >> 1),
- CONST_S("Sorry, this save is incompatible with the new version.\rStart new game?\r"),
- CONST_S("Yes\rNo\r"), LIGHT_GRAY))
- return NEW_GAME;
- else
+ if(ivanconfig::IsAllowImportOldSavegame()){
+ if(CurrentSavefileVersion > SAVE_FILE_VERSION){
+ iosystem::Menu(0, v2(RES.X >> 1, RES.Y >> 1),
+ CONST_S("Sorry, this save can't be imported by this game version.\r"),
+ CONST_S("Hit a key to go back...\r"), LIGHT_GRAY);
return BACK;
+ }
+ }else{
+ if(CurrentSavefileVersion != SAVE_FILE_VERSION)
+ {
+ if(!iosystem::Menu(0, v2(RES.X >> 1, RES.Y >> 1),
+ CONST_S("Sorry, this save is incompatible with the new version.\rStart new game?\r"),
+ CONST_S("Yes\rNo\r"), LIGHT_GRAY))
+ return NEW_GAME;
+ else
+ return BACK;
+ }
}
SaveFile >> GameScript >> CurrentDungeonIndex >> CurrentLevelIndex >> Camera;
@@ -946,20 +3065,23 @@ int game::Load(cfestring& SaveName)
if(InWilderness)
{
- SetCurrentArea(LoadWorldMap(SaveName));
+ SetCurrentArea(LoadWorldMap(saveName));
CurrentWSquareMap = WorldMap->GetMap();
igraph::CreateBackGround(GRAY_FRACTAL);
}
else
{
- SetCurrentArea(CurrentLevel = GetCurrentDungeon()->LoadLevel(SaveName, CurrentLevelIndex));
+ SetCurrentArea(CurrentLevel = GetCurrentDungeon()->LoadLevel(saveName, CurrentLevelIndex));
CurrentLSquareMap = CurrentLevel->GetMap();
igraph::CreateBackGround(*CurrentLevel->GetLevelScript()->GetBackGroundType());
}
v2 Pos;
SaveFile >> Pos >> PlayerName;
- SetPlayer(GetCurrentArea()->GetSquare(Pos)->GetCharacter());
+ character* CharAtPos = GetCurrentArea()->GetSquare(Pos)->GetCharacter();
+ if(CharAtPos==NULL || !CharAtPos->IsPlayer())
+ ABORT("Player not found! If there are backup files, try the 'restore backup' option.");
+ SetPlayer(CharAtPos); DBG2(PLAYER,DBGAV2(Pos));
msgsystem::Load(SaveFile);
SaveFile >> DangerMap >> NextDangerIDType >> NextDangerIDConfigIndex;
SaveFile >> DefaultPolymorphTo >> DefaultSummonMonster;
@@ -968,6 +3090,9 @@ int game::Load(cfestring& SaveName)
SaveFile >> PlayerHasReceivedAllGodsKnownBonus;
LastLoad = time(0);
protosystem::LoadCharacterDataBaseFlags(SaveFile);
+
+ UpdateCamera();
+
return LOADED;
}
@@ -975,14 +3100,29 @@ festring game::SaveName(cfestring& Base)
{
festring SaveName = GetSaveDir();
- if(!Base.GetSize())
- SaveName << PlayerName;
- else
- SaveName << Base;
+ /**
+ * Base must come OK, will just prepend directory,
+ * the problem on modifying it is that as it is read from the filesystem
+ * it will not be found if it gets changed...
+ */
+ festring BaseOk;
+ BaseOk << Base; DBG2(PlayerName.CStr(),Base.CStr());
+
+ if(Base.GetSize()==0){
+ BaseOk.Empty();
+ BaseOk << PlayerName; //ATTENTION! festring reuses the internal festring data pointer of other festring when using operator= even to char* !
+
+ for(festring::sizetype c = 0; c < BaseOk.GetSize(); ++c){
+ // this prevents all possibly troublesome characters in all OSs
+ if(BaseOk[c]>=0x41 && BaseOk[c]<=0x5A)continue; //A-Z
+ if(BaseOk[c]>=0x61 && BaseOk[c]<=0x7A)continue; //a-z
+ if(BaseOk[c]>=0x30 && BaseOk[c]<=0x39)continue; //0-9
+
+ BaseOk[c] = '_';
+ }
+ }DBG3(PlayerName.CStr(),BaseOk.CStr(),Base.CStr());
- for(festring::sizetype c = 0; c < SaveName.GetSize(); ++c)
- if(SaveName[c] == ' ')
- SaveName[c] = '_';
+ SaveName << BaseOk;
#if defined(WIN32) || defined(__DJGPP__)
if(SaveName.GetSize() > 13)
@@ -1085,16 +3225,18 @@ int game::DirectionQuestion(cfestring& Topic, truth RequireAnswer, truth AcceptY
}
}
-void game::RemoveSaves(truth RealSavesAlso)
+void game::RemoveSaves(truth RealSavesAlso,truth onlyBackups)
{
+ festring bkp(".bkp");
+
if(RealSavesAlso)
{
- remove(festring(SaveName() + ".sav").CStr());
- remove(festring(SaveName() + ".wm").CStr());
+ remove(festring(SaveName() + ".sav" + (onlyBackups?bkp.CStr():"") ).CStr());
+ remove(festring(SaveName() + ".wm" + (onlyBackups?bkp.CStr():"") ).CStr());
}
- remove(festring(AutoSaveFileName + ".sav").CStr());
- remove(festring(AutoSaveFileName + ".wm").CStr());
+ remove(festring(GetAutoSaveFileName() + ".sav" + (onlyBackups?bkp.CStr():"") ).CStr());
+ remove(festring(GetAutoSaveFileName() + ".wm" + (onlyBackups?bkp.CStr():"") ).CStr());
festring File;
for(int i = 1; i < Dungeons; ++i)
@@ -1108,12 +3250,12 @@ void game::RemoveSaves(truth RealSavesAlso)
File << c;
if(RealSavesAlso)
- remove(File.CStr());
+ remove(festring(File + (onlyBackups?bkp.CStr():"")).CStr());
- File = AutoSaveFileName + '.' + i;
+ File = GetAutoSaveFileName() + '.' + i;
File << c;
- remove(File.CStr());
+ remove(festring(File + (onlyBackups?bkp.CStr():"")).CStr());
}
}
@@ -1247,18 +3389,22 @@ int game::StringQuestion(festring& Answer, cfestring& Topic, col16 Color,
truth AllowExit, stringkeyhandler KeyHandler)
{
DrawEverythingNoBlit();
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23)); // pos may be incorrect!
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23)); // pos may be incorrect!
+ SRegionAroundDeny();
int Return = iosystem::StringQuestion(Answer, Topic, v2(16, 6), Color, MinLetters, MaxLetters, false, AllowExit, KeyHandler);
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ SRegionAroundAllow();
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
return Return;
}
long game::NumberQuestion(cfestring& Topic, col16 Color, truth ReturnZeroOnEsc)
{
DrawEverythingNoBlit();
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
+ SRegionAroundDeny();
long Return = iosystem::NumberQuestion(Topic, v2(16, 6), Color, false, ReturnZeroOnEsc);
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ SRegionAroundAllow();
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
return Return;
}
@@ -1266,11 +3412,13 @@ long game::ScrollBarQuestion(cfestring& Topic, long BeginValue, long Step, long
col16 TopicColor, col16 Color1, col16 Color2, void (*Handler)(long))
{
DrawEverythingNoBlit();
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
+ SRegionAroundDeny();
long Return = iosystem::ScrollBarQuestion(Topic, v2(16, 6), BeginValue, Step, Min, Max, AbortValue,
TopicColor, Color1, Color2, GetMoveCommandKey(KEY_LEFT_INDEX),
GetMoveCommandKey(KEY_RIGHT_INDEX), false, Handler);
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ SRegionAroundAllow();
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
return Return;
}
@@ -1305,7 +3453,7 @@ truth game::HandleQuitMessage()
{
case 0:
Save();
- RemoveSaves(false);
+ RemoveSaves(false); //keep backups during autosaves
break;
case 2:
GetCurrentArea()->SendNewDrawRequest();
@@ -1321,8 +3469,10 @@ truth game::HandleQuitMessage()
else
if(!Menu(0, v2(RES.X >> 1, RES.Y >> 1),
CONST_S("You can't save at this point. Are you sure you still want to do this?\r"),
- CONST_S("Yes\rNo\r"), LIGHT_GRAY))
- RemoveSaves();
+ CONST_S("Yes\rNo\r"), LIGHT_GRAY)){
+ RemoveSaves(); //will remove the real saves too
+ RemoveSaves(true,true); //will remove only the backups now
+ }
else
{
GetCurrentArea()->SendNewDrawRequest();
@@ -1345,34 +3495,63 @@ int game::GetDirectionForVector(v2 Vector)
return DIR_ERROR;
}
-cchar* game::GetVerbalPlayerAlignment()
-{
+int GetPlayerAlignmentSum(){
long Sum = 0;
for(int c = 1; c <= GODS; ++c)
{
- if(GetGod(c)->GetRelation() > 0)
- Sum += GetGod(c)->GetRelation() * (5 - GetGod(c)->GetAlignment());
- }
-
- if(Sum > 15000)
- return "extremely lawful";
- if(Sum > 10000)
- return "very lawful";
- if(Sum > 5000)
- return "lawful";
- if(Sum > 1000)
- return "mildly lawful";
- if(Sum > -1000)
- return "neutral";
- if(Sum > -5000)
- return "mildly chaotic";
- if(Sum > -10000)
- return "chaotic";
- if(Sum > -15000)
- return "very chaotic";
+ if(game::GetGod(c)->GetRelation() > 0)
+ Sum += game::GetGod(c)->GetRelation() * (5 - game::GetGod(c)->GetAlignment());
+ }
+
+ return Sum;
+}
+
+int game::GetPlayerAlignment()
+{
+ long Sum = GetPlayerAlignmentSum();
+
+ if(Sum > 15000)return 4;
+ if(Sum > 10000)return 3;
+ if(Sum > 5000)return 2;
+ if(Sum > 1000)return 1;
+ if(Sum > -1000)return 0;
+ if(Sum > -5000)return -1;
+ if(Sum > -10000)return -2;
+ if(Sum > -15000)return -3;
+
+ return -4;
+}
+
+cchar* game::GetVerbalPlayerAlignment()
+{
+ switch(GetPlayerAlignment()){
+ case 4:return "extremely lawful";
+ case 3:return "very lawful";
+ case 2:return "lawful";
+ case 1:return "mildly lawful";
+ case 0:return "neutral";
+ case -1:return "mildly chaotic";
+ case -2:return "chaotic";
+ case -3:return "very chaotic";
+ case -4:return "extremely chaotic";
+ }
+ ABORT("unsupported alignment %d",GetPlayerAlignment());
+ return NULL; //return just to let it compile
+
+ /* //kept just in case something changes...
+ long Sum = GetPlayerAlignment();
+ if(Sum > 15000)return "extremely lawful";
+ if(Sum > 10000)return "very lawful";
+ if(Sum > 5000)return "lawful";
+ if(Sum > 1000)return "mildly lawful";
+ if(Sum > -1000)return "neutral";
+ if(Sum > -5000)return "mildly chaotic";
+ if(Sum > -10000)return "chaotic";
+ if(Sum > -15000)return "very chaotic";
return "extremely chaotic";
+ */
}
void game::CreateGods()
@@ -1479,8 +3658,14 @@ int game::AskForKeyPress(cfestring& Topic)
DrawEverythingNoBlit();
FONT->Printf(DOUBLE_BUFFER, v2(16, 8), WHITE, "%s", Topic.CapitalizeCopy().CStr());
graphics::BlitDBToScreen();
+
int Key = GET_KEY();
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ #ifdef FELIST_WAITKEYUP //not actually felist here but is the waitkeyup event
+ if(game::GetAutoPlayMode()==0)
+ for(;;){if(WAIT_FOR_KEY_UP())break;};
+ #endif
+
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
return Key;
}
@@ -1499,6 +3684,7 @@ v2 game::PositionQuestion(cfestring& Topic, v2 CursorPos, void (*Handler)(v2),
if(Handler)
Handler(CursorPos);
+ bPositionQuestionMode=true;
for(;;)
{
square* Square = GetCurrentArea()->GetSquare(CursorPos);
@@ -1555,14 +3741,29 @@ v2 game::PositionQuestion(cfestring& Topic, v2 CursorPos, void (*Handler)(v2),
FONT->Printf(DOUBLE_BUFFER, v2(16, 8), WHITE, "%s", Topic.CStr());
SetCursorPos(CursorPos);
+ UpdatePosAroundForXBRZ(CursorPos);
DrawEverything();
Key = GET_KEY();
}
+ bPositionQuestionMode=false;
+
+ // for text
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
- igraph::BlitBackGround(v2(RES.X - 96, RES.Y - 96), v2(80, 80));
+ // for zoom
+ igraph::BlitBackGround(ZoomPos, TILE_V2*iZoomFactor);
SetDoZoom(false);
+
SetCursorPos(v2(-1, -1));
+
+ if(ivanconfig::IsCenterOnPlayerAfterLook()){
+ v2 ppos = Player->GetPosSafely();
+ if(!ppos.Is0()){
+ UpdateCameraX(ppos.X);
+ UpdateCameraY(ppos.Y);
+ }
+ }
+
return Return;
}
@@ -1585,13 +3786,16 @@ void game::LookHandler(v2 CursorPos)
if(Square->HasBeenSeen() || GetSeeWholeMapCheatMode())
{
- if(!IsInWilderness()
- && !Square->CanBeSeenByPlayer()
- && GetCurrentLevel()->GetLSquare(CursorPos)->CanBeFeltByPlayer())
+ if(
+ !IsInWilderness()
+ && !Square->CanBeSeenByPlayer()
+ && Player->IsEnabled() && Player->GetSquareUnderSafely() // important to block this on death
+ && GetCurrentLevel()->GetLSquare(CursorPos)->CanBeFeltByPlayer()
+ ){
Msg = CONST_S("You feel here ");
- else if(Square->CanBeSeenByPlayer(true) || GetSeeWholeMapCheatMode())
+ }else if(Square->CanBeSeenByPlayer(true) || GetSeeWholeMapCheatMode()){
Msg = CONST_S("You see here ");
- else
+ }else
Msg = CONST_S("You remember here ");
Msg << Square->GetMemorizedDescription() << '.';
@@ -1633,6 +3837,89 @@ truth game::AnimationController()
return true;
}
+//static void DefinesValidatorAppend(std::string s);
+//static void DefinesValidatorTop();
+//static void DefinesValidatorAppendCode(std::string s);
+std::ofstream DefinesValidator;
+void DefinesValidatorAppend(std::string s)
+{
+ static std::stringstream ssValidateLine;ssValidateLine.str(std::string());ssValidateLine.clear(); //actually clear/empty it = ""
+
+ ssValidateLine << s << std::endl;
+
+ static bool bDummyInit = [](){
+ DefinesValidator.open(
+ festring(game::GetHomeDir() + "definesvalidator.h").CStr(),
+ std::ios::binary);
+ return true;}();
+
+ DefinesValidator.write(ssValidateLine.str().c_str(),ssValidateLine.str().length());
+}
+void DefinesValidatorTop()
+{
+ DefinesValidatorAppend("/****");
+ DefinesValidatorAppend(" * AUTO-GENERATED CODE FILE, DO NOT MODIFY as modifications will be overwritten !!!");
+ DefinesValidatorAppend(" *");
+ DefinesValidatorAppend(" * After it is generated, update the one at source code path with it and");
+ DefinesValidatorAppend(" * recompile so the results on the abort message (if happens) will be updated !!!");
+ DefinesValidatorAppend(" */");
+ DefinesValidatorAppend("");
+ DefinesValidatorAppend("#ifndef _DEFINESVALIDATOR_H_");
+ DefinesValidatorAppend("#define _DEFINESVALIDATOR_H_");
+ DefinesValidatorAppend("");
+ DefinesValidatorAppend("class definesvalidator{ public: static void Validate() {");
+ DefinesValidatorAppend("");
+ DefinesValidatorAppend(" std::stringstream ssErrors;");
+ DefinesValidatorAppend(" std::bitset<32> bsA, bsB;");
+ DefinesValidatorAppend("");
+}
+void DefinesValidatorAppendCode(std::string sDefineId, long valueReadFromDatFile)
+{
+ static std::stringstream ssMsg;ssMsg.str(std::string());ssMsg.clear(); //actually clear/empty it = ""
+
+ ssMsg << "\"Defined " << sDefineId << " with value " << valueReadFromDatFile << " from .dat file " <<
+ "mismatches hardcoded c++ define value of \" << " << sDefineId << " << \"!\"";
+
+
+ static std::stringstream ssCode;ssCode.str(std::string());ssCode.clear(); //actually clear/empty it = ""
+
+// " if( " << valueReadFromDatFile << " != ((ulong)" << sDefineId << ") ) // DO NOT MODIFY!" << std::endl <<
+ ssCode <<
+ " " << std::endl <<
+ "#ifdef " << sDefineId << " // DO NOT MODIFY!" << std::endl <<
+ " bsA = " << valueReadFromDatFile << ";" << std::endl <<
+ " bsB = " << sDefineId << ";" << std::endl <<
+ " if(bsA!=bsB)" << std::endl <<
+ " ssErrors << " << ssMsg.str() << " << std::endl;" << std::endl <<
+ "#endif " << std::endl;
+
+
+ DefinesValidatorAppend(ssCode.str());
+}
+void DefinesValidatorClose(){
+ DefinesValidatorAppend("");
+ DefinesValidatorAppend(" if(ssErrors.str().length() > 0) ABORT(ssErrors.str().c_str());");
+ DefinesValidatorAppend("");
+ DefinesValidatorAppend("}};");
+ DefinesValidatorAppend("");
+ DefinesValidatorAppend("#endif // _DEFINESVALIDATOR_H_");
+
+ DefinesValidator.close();
+}
+#include "definesvalidator.h" //tip: 1st run this was commented
+void game::GenerateDefinesValidator(bool bValidade)
+{
+ DefinesValidatorTop();
+
+ for(const valuemap::value_type& p : GlobalValueMap)
+ DefinesValidatorAppendCode(p.first.CStr(), p.second);
+
+ DefinesValidatorClose();
+
+ if(bValidade)
+ definesvalidator::Validate(); //tip: 1st run this was commented
+}
+
void game::InitGlobalValueMap()
{
inputfile SaveFile(GetDataDir() + "Script/define.dat", &GlobalValueMap);
@@ -1644,13 +3931,17 @@ void game::InitGlobalValueMap()
ABORT("Illegal datafile define on line %ld!", SaveFile.TellLine());
SaveFile.ReadWord(Word);
- GlobalValueMap.insert(std::make_pair(Word, SaveFile.ReadNumber()));
+
+ long value = SaveFile.ReadNumber();
+ GlobalValueMap.insert(std::make_pair(Word, value));
}
+
}
void game::TextScreen(cfestring& Text, v2 Displacement, col16 Color,
truth GKey, truth Fade, bitmapeditor BitmapEditor)
{
+ graphics::SetDenyStretchedBlit();
globalwindowhandler::DisableControlLoops();
iosystem::TextScreen(Text, Displacement, Color, GKey, Fade, BitmapEditor);
globalwindowhandler::EnableControlLoops();
@@ -1692,7 +3983,7 @@ int game::KeyQuestion(cfestring& Message, int DefaultAnswer, int KeyNumber, ...)
}
delete [] Key;
- igraph::BlitBackGround(v2(16, 6), v2(GetScreenXSize() << 4, 23));
+ igraph::BlitBackGround(v2(16, 6), v2(GetMaxScreenXSize() << 4, 23));
return Return;
}
@@ -1705,8 +3996,7 @@ v2 game::LookKeyHandler(v2 CursorPos, int Key)
case 'i':
if(!IsInWilderness())
{
- if(Square->CanBeSeenByPlayer() || CursorPos == Player->GetPos() || GetSeeWholeMapCheatMode())
- {
+ if(Square->CanBeSeenByPlayer() || CursorPos == Player->GetPosSafely() || GetSeeWholeMapCheatMode()){
lsquare* LSquare = GetCurrentLevel()->GetLSquare(CursorPos);
stack* Stack = LSquare->GetStack();
@@ -1759,6 +4049,11 @@ v2 game::NameKeyHandler(v2 CursorPos, int Key)
void game::End(festring DeathMessage, truth Permanently, truth AndGoToMenu)
{
+ if(!Permanently)
+ game::Save();
+
+ game::RemoveSaves(true,true); // ONLY THE BACKUPS: after fully saving successfully, is a safe moment to remove them.
+
globalwindowhandler::DeInstallControlLoop(AnimationController);
SetIsRunning(false);
@@ -1767,7 +4062,7 @@ void game::End(festring DeathMessage, truth Permanently, truth AndGoToMenu)
if(Permanently && !WizardModeIsReallyActive())
{
- highscore HScore;
+ highscore HScore(GetStateDir() + HIGH_SCORE_FILENAME);
if(HScore.LastAddFailed())
{
@@ -1867,10 +4162,10 @@ void game::InitDangerMap()
First = false;
}
- character* Char = Proto->Spawn(Config, NO_EQUIPMENT|NO_PIC_UPDATE|NO_EQUIPMENT_PIC_UPDATE);
+ character* Char = Proto->Spawn(Config, NO_EQUIPMENT|NO_PIC_UPDATE|NO_EQUIPMENT_PIC_UPDATE|NO_SEVERED_LIMBS);
double NakedDanger = Char->GetRelativeDanger(Player, true);
delete Char;
- Char = Proto->Spawn(Config, NO_PIC_UPDATE|NO_EQUIPMENT_PIC_UPDATE);
+ Char = Proto->Spawn(Config, NO_PIC_UPDATE|NO_EQUIPMENT_PIC_UPDATE|NO_SEVERED_LIMBS);
double EquippedDanger = Char->GetRelativeDanger(Player, true);
delete Char;
DangerMap[configid(c1, Config)] = dangerid(NakedDanger, EquippedDanger);
@@ -2078,6 +4373,8 @@ void game::EnterArea(charactervector& Group, int Area, int EntryIndex)
if(ivanconfig::GetAutoSaveInterval())
Save(GetAutoSaveFileName().CStr());
}
+
+ iCurrentDungeonTurn=-1; //-1 as it will be the turn index and be inc before checking
}
int game::CompareLightToInt(col24 L, col24 Int)
@@ -2090,10 +4387,61 @@ int game::CompareLightToInt(col24 L, col24 Int)
return -1;
}
+void prepareList(felist& rList, v2& v2TopLeft, int& iW){
+ bool bAltItemPos = ivanconfig::GetAltListItemPos()==2;
+ if(iRegionListItem==-1){ //not initialized
+ bAltItemPos=false;
+ }else{
+ if(ivanconfig::GetAltListItemPos()==0){
+ graphics::SetSRegionEnabled(iRegionListItem,false); //user option override
+ }
+
+ if(!graphics::IsSRegionEnabled(iRegionListItem)){ //can be by user option or dependent on what command the user is using like 'drop'
+ bAltItemPos=false;
+ }
+ }
+// bool bAltItemPos = graphics::IsSRegionEnabled(iRegionListItem) && ivanconfig::GetAltListItemPos()==2;
+
+ rList.SetOriginalPos(v2TopLeft);
+
+ int iX=v2TopLeft.X+10,iY=v2TopLeft.Y+10;
+ if(ivanconfig::GetStartingDungeonGfxScale()>=2){
+ //mainly to be drawn above the small dungeon (that gets scaled up)
+ iX=v2TopLeft.X-3;
+ iY=v2TopLeft.Y-3;
+ }
+
+ int iItemW=bldListItemTMP.Border.X*bldListItemTMP.Stretch;
+ if(bAltItemPos){
+ iX += area::getOutlineThickness()*2; //to leave some space to alt item outline
+ iX += iItemW;
+ }else{
+ bldListItemTMP.Dest = ZoomPos;
+ }
+
+ if(graphics::IsSRegionEnabled(iRegionSilhouette)){
+ iW=ivanconfig::GetAltListItemWidth();
+ //cant be so automatic... or user wants alt or default position... //if(bAltItemPos){iW+=iItemW;}
+ }
+
+ v2TopLeft=v2(iX,iY);
+
+ graphics::SetSpecialListItemAltPos(bAltItemPos);
+}
+
+int prepareListWidth(int iW){
+ return iW;
+}
+
void game::SetStandardListAttributes(felist& List)
{
- List.SetPos(v2(26, 42));
- List.SetWidth(652);
+ v2 v2TopLeft = area::getTopLeftCorner();
+ int iW = iListWidth;
+
+ prepareList(List, v2TopLeft, iW);
+
+ List.SetPos(v2TopLeft);
+ List.SetWidth(iW);
List.SetFlags(DRAW_BACKGROUND_AFTERWARDS);
List.SetUpKey(GetMoveCommandKey(KEY_UP_INDEX));
List.SetDownKey(GetMoveCommandKey(KEY_DOWN_INDEX));
@@ -2342,7 +4690,15 @@ festring game::GetHomeDir()
{
#ifdef UNIX
festring Dir;
- Dir << getenv("HOME") << "/.ivan/";
+ Dir << getenv("HOME");
+#ifdef MAC_APP
+ Dir << "/Library/Application Support/IVAN/";
+#else
+ Dir << "/.ivan/";
+#endif
+#ifdef DBGMSG
+ dbgmsg::SetDebugLogPath(Dir.CStr());
+#endif
return Dir;
#endif
@@ -2364,34 +4720,41 @@ festring game::GetScrshotDir()
festring game::GetDataDir()
{
#ifdef UNIX
+#ifdef MAC_APP
+ return "../Resources/ivan/";
+#else
return DATADIR "/ivan/";
#endif
+#endif
#if defined(WIN32) || defined(__DJGPP__)
- return "";
+ return GetHomeDir();
#endif
}
-festring game::GetBoneDir()
+festring game::GetStateDir()
{
#ifdef UNIX
- return LOCAL_STATE_DIR "/Bones/";
+#ifdef MAC_APP
+ return GetHomeDir();
+#else
+ return LOCAL_STATE_DIR "/";
+#endif
#endif
#if defined(WIN32) || defined(__DJGPP__)
- return "Bones/";
+ return GetHomeDir();
#endif
}
+festring game::GetBoneDir()
+{
+ return GetStateDir() + "Bones/";
+}
+
festring game::GetMusicDir()
{
-#ifdef UNIX
return GetDataDir() + "Music/";
-#endif
-
-#if defined(WIN32) || defined(__DJGPP__)
- return "Music/";
-#endif
}
level* game::GetLevel(int I)
@@ -2463,9 +4826,13 @@ void game::SignalDeath(ccharacter* Ghost, ccharacter* Murderer, festring DeathMs
void game::DisplayMassacreLists()
{
+ game::RegionListItemEnable(true);
+
DisplayMassacreList(PlayerMassacreMap, "directly by you.", PlayerMassacreAmount);
DisplayMassacreList(PetMassacreMap, "by your allies.", PetMassacreAmount);
DisplayMassacreList(MiscMassacreMap, "by some other reason.", MiscMassacreAmount);
+
+ game::RegionListItemEnable(false);
}
struct massacresetentry
@@ -2622,6 +4989,56 @@ truth game::MassacreListsEmpty()
#ifdef WIZARD
+void game::AutoPlayModeApply(){
+ int iTimeout=0;
+ bool bPlayInBackground=false;
+
+ const char* msg;
+ switch(game::AutoPlayMode){
+ case 0:
+ // disabled
+ msg="%s says \"I can rest now.\"";
+ break;
+ case 1:
+ // no timeout, user needs to hit '.' to it autoplay once, the behavior is controled by AutoPlayMode AND the timeout delay that if 0 will have no timeout but will still autoplay.
+ msg="%s says \"I won't rest!\"";
+ break;
+ case 2: // TIMEOUTs key press from here to below
+ msg="%s says \"I can't wait anymore!\"";
+ iTimeout=(1000);
+ bPlayInBackground=true;
+ break;
+ case 3:
+ msg="%s says \"I am in a hurry!!\"";
+ iTimeout=(1000/2);
+ bPlayInBackground=true;
+ break;
+ case 4:
+ msg="%s says \"I... *frenzy* yeah! try to follow me now! hahaha!\"";
+ iTimeout=(1000/10); // like 10 FPS, so user has 100ms change to disable it
+ bPlayInBackground=true;
+ break;
+ }
+ ADD_MESSAGE(msg, game::GetPlayer()->CHAR_NAME(DEFINITE));
+
+ globalwindowhandler::SetPlayInBackground(bPlayInBackground);
+ globalwindowhandler::SetKeyTimeout(iTimeout,'.');//,'~');
+}
+
+void game::IncAutoPlayMode() {
+// if(!globalwindowhandler::IsKeyTimeoutEnabled()){
+// if(AutoPlayMode>=2){
+// AutoPlayMode=0; // TIMEOUT was disabled there at window handler! so reset here.
+// AutoPlayModeApply();
+// }
+// }
+
+ ++AutoPlayMode;
+ if(AutoPlayMode>4)AutoPlayMode=0;
+
+ AutoPlayModeApply();
+}
+
void game::SeeWholeMap()
{
if(SeeWholeMapCheatMode < 2)
@@ -3185,6 +5602,8 @@ ulong game::IncreaseSquarePartEmitationTicks()
int game::Wish(character* Wisher, cchar* MsgSingle, cchar* MsgPair, truth AllowExit)
{
+ if(Wisher->IsPlayerAutoPlay())return ABORTED;
+
for(;;)
{
festring Temp;
@@ -3769,6 +6188,12 @@ void game::AdjustRelationsToAllGods(int Amount)
GetGod(c)->AdjustRelation(Amount);
}
+void game::SetRelationsToAllGods(int Amount)
+{
+ for(int c = 1; c <= GODS; ++c)
+ GetGod(c)->SetRelation(Amount);
+}
+
void game::ShowDeathSmiley(bitmap* Buffer, truth)
{
static blitdata B = { 0,
diff --git a/Main/Source/gear.cpp b/Main/Source/gear.cpp
index c85c5024e..bc1d0f7a1 100644
--- a/Main/Source/gear.cpp
+++ b/Main/Source/gear.cpp
@@ -28,6 +28,7 @@ v2 meleeweapon::GetWieldedBitmapPos(int I) const
{ return SecondaryMaterial->GetVolume() ? item::GetWieldedBitmapPos(I) : v2(160, 128); }
void meleeweapon::InitMaterials(const materialscript* M, const materialscript* S, truth CUP)
{ InitMaterials(M->Instantiate(), S->Instantiate(), CUP); }
+truth meleeweapon::IsRuneSword() const { return (GetConfig() == RUNE_SWORD); }
col16 justifier::GetOutlineColor(int) const { return MakeRGB16(0, 255, 0); }
@@ -51,11 +52,11 @@ int armor::GetCarryingBonus() const { return Enchantment << 1; }
double armor::GetTHVBonus() const { return Enchantment * .5; }
double armor::GetDamageBonus() const { return Enchantment; }
truth armor::IsDippable(ccharacter*) const { return !!IsBurning() && !Fluid; }
+cfestring& armor::GetNameSingular() const
+{ return GetMainMaterial()->GetFlexibility() >= 5 ? item::GetFlexibleNameSingular() : item::GetNameSingular(); }
long bodyarmor::GetPrice() const { return (armor::GetPrice() << 3) + GetEnchantedPrice(Enchantment); }
truth bodyarmor::IsInCorrectSlot(int I) const { return I == BODY_ARMOR_INDEX; }
-cfestring& bodyarmor::GetNameSingular() const
-{ return GetMainMaterial()->GetFlexibility() >= 5 ? item::GetFlexibleNameSingular() : item::GetNameSingular(); }
cchar* bodyarmor::GetBreakVerb() const
{ return GetMainMaterial()->GetFlexibility() >= 5 ? "is torn apart" : "breaks"; }
@@ -101,6 +102,10 @@ col16 helmet::GetMaterialColorC(int) const { return MakeRGB16(180, 200, 180); }
int wondersmellstaff::GetClassAnimationFrames() const { return !IsBroken() ? 128 : 1; }
+int taiaha::GetClassAnimationFrames() const { return !IsBroken() ? 128 : 1; }
+
+int filthytunic::GetClassAnimationFrames() const { return !IsBroken() ? 32 : 1; }
+
truth meleeweapon::HitEffect(character* Enemy, character* Hitter, v2,
int BodyPartIndex, int Direction, truth BlockedByArmour)
{
@@ -645,10 +650,8 @@ void shield::AddInventoryEntry(ccharacter* Viewer, festring& Entry,
if(ShowSpecialInfo)
{
- Entry << " [" << GetWeight() << "g, " << GetBaseBlockValueDescription();
-
- if(!IsBroken())
- Entry << ", " << GetStrengthValueDescription();
+ Entry << " [" << GetWeight() << "g, AV " << GetStrengthValue();
+ Entry << ", " << GetBaseBlockValueDescription();
int CWeaponSkillLevel = Viewer->GetCWeaponSkillLevel(this);
int SWeaponSkillLevel = Viewer->GetSWeaponSkillLevel(this);
@@ -748,7 +751,7 @@ truth chameleonwhip::HitEffect(character* Enemy, character* Hitter, v2 HitPos,
{
if(Enemy->IsPlayer() || Hitter->IsPlayer() || Enemy->CanBeSeenByPlayer() || Hitter->CanBeSeenByPlayer())
ADD_MESSAGE("%s whip asks for the help of Scabies as it polymorphs %s.",
- Hitter->CHAR_PERSONAL_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE));
+ Hitter->CHAR_POSSESSIVE_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE));
if(Hitter->IsPlayer())
{
@@ -1160,3 +1163,335 @@ void wondersmellstaff::Break(character* Who, int Much)
meleeweapon::Break(Who, Much);
}
+
+void darkaxe::Be()
+{
+ meleeweapon::Be();
+
+ if(Exists() && !IsBroken() && (*Slot)->IsGearSlot() && !RAND_N(10))
+ {
+ fluidvector FluidVector;
+ FillFluidVector(FluidVector);
+ uint Volume = 0;
+
+ for(uint c = 0; c < FluidVector.size(); ++c)
+ {
+ liquid* L = FluidVector[c]->GetLiquid();
+ Volume += L->GetVolume();
+ }
+
+ if(Volume < 90)
+ SpillFluid(0, liquid::Spawn(LIQUID_DARKNESS, 10));
+ }
+}
+
+truth slowaxe::HitEffect(character* Enemy, character* Hitter, v2 HitPos,
+ int BodyPartIndex, int Direction, truth BlockedByArmour)
+{
+ truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour);
+
+ if(!IsBroken() && Enemy->IsEnabled())
+ {
+ if(Hitter)
+ {
+ if(Enemy->IsPlayer() || Hitter->IsPlayer() || Enemy->CanBeSeenByPlayer() || Hitter->CanBeSeenByPlayer())
+ ADD_MESSAGE("%s axe chills %s.", Hitter->CHAR_POSSESSIVE_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE));
+ }
+ else
+ {
+ if(Enemy->IsPlayer() || Enemy->CanBeSeenByPlayer())
+ ADD_MESSAGE("The axe chills %s.", Enemy->CHAR_DESCRIPTION(DEFINITE));
+ }
+
+ Enemy->BeginTemporaryState(SLOW, 400 + RAND_N(200));
+ return BaseSuccess;
+ }
+ else
+ return BaseSuccess;
+}
+
+truth terrorscythe::HitEffect(character* Enemy, character* Hitter, v2 HitPos,
+ int BodyPartIndex, int Direction, truth BlockedByArmour)
+{
+ truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour);
+
+ if(!IsBroken() && Enemy->IsEnabled() && !(RAND() % 2))
+ {
+ if(Hitter)
+ {
+ if(Enemy->IsPlayer() || Hitter->IsPlayer() || Enemy->CanBeSeenByPlayer() || Hitter->CanBeSeenByPlayer())
+ ADD_MESSAGE("%s scythe terrifies %s.", Hitter->CHAR_POSSESSIVE_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE));
+ }
+ else
+ {
+ if(Enemy->IsPlayer() || Enemy->CanBeSeenByPlayer())
+ ADD_MESSAGE("The scythe terrifies %s.", Enemy->CHAR_DESCRIPTION(DEFINITE));
+ }
+
+ Enemy->BeginTemporaryState(PANIC, 200 + RAND_N(100));
+ return BaseSuccess;
+ }
+ else
+ return BaseSuccess;
+}
+
+truth bansheesickle::HitEffect(character* Enemy, character* Hitter, v2 HitPos,
+ int BodyPartIndex, int Direction, truth BlockedByArmour)
+{
+ truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour);
+
+ if(!IsBroken() && Enemy->IsEnabled() && RAND() & 1)
+ {
+ if(Hitter)
+ {
+ if(Enemy->IsPlayer() || Hitter->IsPlayer() || Enemy->CanBeSeenByPlayer() || Hitter->CanBeSeenByPlayer())
+ ADD_MESSAGE("%s sickle shrieks at %s.", Hitter->CHAR_POSSESSIVE_PRONOUN, Enemy->CHAR_DESCRIPTION(DEFINITE));
+ }
+ else
+ {
+ if(Enemy->IsPlayer() || Enemy->CanBeSeenByPlayer())
+ ADD_MESSAGE("The sickle shrieks at %s.", Enemy->CHAR_DESCRIPTION(DEFINITE));
+ }
+
+ return Enemy->ReceiveBodyPartDamage(Hitter, 4 + (RAND() & 4), SOUND, BodyPartIndex, Direction) || BaseSuccess;
+ }
+ else
+ return BaseSuccess;
+}
+
+truth rustscythe::HitEffect(character* Enemy, character* Hitter, v2 HitPos,
+ int BodyPartIndex, int Direction, truth BlockedByArmour)
+{
+ truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour);
+
+ if(!IsBroken() && Enemy->IsEnabled() && Enemy->IsHumanoid())
+ {
+ bodypart* BodyPartHit = Enemy->GetBodyPart(BodyPartIndex);
+ item* MainArmor = 0;
+
+ switch(BodyPartIndex)
+ {
+ case TORSO_INDEX:
+ MainArmor = Enemy->GetEquipment(BODY_ARMOR_INDEX);
+ break;
+ case HEAD_INDEX:
+ MainArmor = Enemy->GetEquipment(HELMET_INDEX);
+ break;
+ case RIGHT_ARM_INDEX:
+ MainArmor = Enemy->GetEquipment(RAND_2 ? RIGHT_WIELDED_INDEX : RIGHT_GAUNTLET_INDEX);
+ break;
+ case LEFT_ARM_INDEX:
+ MainArmor = Enemy->GetEquipment(RAND_2 ? LEFT_WIELDED_INDEX : LEFT_GAUNTLET_INDEX);
+ break;
+ case GROIN_INDEX:
+ MainArmor = Enemy->GetEquipment(BELT_INDEX);
+ break;
+ case RIGHT_LEG_INDEX:
+ MainArmor = Enemy->GetEquipment(RIGHT_BOOT_INDEX);
+ break;
+ case LEFT_LEG_INDEX:
+ MainArmor = Enemy->GetEquipment(LEFT_BOOT_INDEX);
+ break;
+ }
+
+ if(MainArmor/* && BlockedByArmor */)
+ {
+ MainArmor->TryToRust(10000000);
+ }
+ else if(BodyPartHit)
+ {
+ BodyPartHit->TryToRust(10000000);
+ }
+ }
+
+ return BaseSuccess;
+}
+
+void rustscythe::BlockEffect(character* Blocker, character* Attacker, item* Weapon, int Type)
+{
+ if(!IsBroken() && Weapon)
+ {
+ Weapon->TryToRust(10000000);
+ }
+}
+
+truth sharpaxe::HitEffect(character* Enemy, character* Hitter, v2 HitPos,
+ int BodyPartIndex, int Direction, truth BlockedByArmour)
+{
+ truth BaseSuccess = meleeweapon::HitEffect(Enemy, Hitter, HitPos, BodyPartIndex, Direction, BlockedByArmour);
+
+ if(!IsBroken() && Enemy->IsEnabled() && Enemy->IsHumanoid() && !(Enemy->IsUnique()))
+ {
+ bodypart* ToBeSevered = Enemy->GetBodyPart(BodyPartIndex);
+
+ if(ToBeSevered && Enemy->BodyPartCanBeSevered(BodyPartIndex))
+ {
+ if(Enemy->IsPlayer())
+ ADD_MESSAGE("Your %s is severed off!", ToBeSevered->GetBodyPartName().CStr());
+ else if(Enemy->CanBeSeenByPlayer())
+ ADD_MESSAGE("%s %s is severed off!", Enemy->GetPossessivePronoun().CStr(), ToBeSevered->GetBodyPartName().CStr());
+
+ item* Severed = Enemy->SevereBodyPart(BodyPartIndex);
+ Enemy->SendNewDrawRequest();
+
+ if(Severed)
+ {
+ Enemy->GetStack()->AddItem(Severed);
+ Severed->DropEquipment();
+ }
+ else if(Enemy->IsPlayer() || Enemy->CanBeSeenByPlayer())
+ {
+ ADD_MESSAGE("It vanishes.");
+ }
+
+ if(Enemy->IsPlayer())
+ game::AskForKeyPress(CONST_S("Bodypart severed! [press any key to continue]"));
+ }
+
+ return true;
+ }
+ else
+ return BaseSuccess;
+}
+
+truth taiaha::Zap(character* Zapper, v2, int Direction)
+{
+ if((Charges <= TimesUsed) || IsBroken())
+ {
+ ADD_MESSAGE("Nothing happens.");
+ return true;
+ }
+
+ Zapper->EditExperience(PERCEPTION, 150, 1 << 10);
+
+ beamdata Beam
+ (
+ Zapper,
+ CONST_S("killed by ") + GetName(INDEFINITE) + " zapped @bk",
+ Zapper->GetPos(),
+ GREEN,
+ BEAM_STRIKE,
+ Direction,
+ 15,
+ 0
+ );
+
+ (GetLevel()->*level::GetBeam(PARTICLE_BEAM))(Beam);
+ ++TimesUsed;
+ return true;
+}
+
+void taiaha::AddInventoryEntry(ccharacter* Viewer, festring& Entry, int, truth ShowSpecialInfo) const // never piled
+{
+ AddName(Entry, INDEFINITE);
+
+ if(ShowSpecialInfo)
+ {
+ Entry << " [" << GetWeight() << "g, DAM " << GetBaseMinDamage() << '-' << GetBaseMaxDamage();
+ Entry << ", " << GetBaseToHitValueDescription();
+
+ if(!IsBroken() && !IsWhip())
+ Entry << ", " << GetStrengthValueDescription();
+
+ int CWeaponSkillLevel = Viewer->GetCWeaponSkillLevel(this);
+ int SWeaponSkillLevel = Viewer->GetSWeaponSkillLevel(this);
+
+ if(CWeaponSkillLevel || SWeaponSkillLevel)
+ Entry << ", skill " << CWeaponSkillLevel << '/' << SWeaponSkillLevel;
+
+ if(TimesUsed == 1)
+ Entry << ", zapped 1 time]";
+ else if(TimesUsed)
+ Entry << ", zapped " << TimesUsed << " times]";
+ else
+ Entry << "]";
+ }
+}
+
+void taiaha::Save(outputfile& SaveFile) const
+{
+ item::Save(SaveFile);
+ SaveFile << TimesUsed << Charges;
+ SaveFile << Enchantment;
+ SaveFile << SecondaryMaterial;
+}
+
+void taiaha::Load(inputfile& SaveFile)
+{
+ item::Load(SaveFile);
+ SaveFile >> TimesUsed >> Charges;
+ SaveFile >> Enchantment;
+ LoadMaterial(SaveFile, SecondaryMaterial);
+}
+
+void taiaha::PostConstruct()
+{
+ Charges = GetMinCharges() + RAND() % (GetMaxCharges() - GetMinCharges() + 1);
+ TimesUsed = 0;
+ meleeweapon::PostConstruct();
+}
+
+alpha taiaha::GetOutlineAlpha(int Frame) const
+{
+ if(!IsBroken())
+ {
+ Frame &= 31;
+ return Frame * (31 - Frame) >> 1;
+ }
+ else
+ return 255;
+}
+
+col16 taiaha::GetOutlineColor(int Frame) const
+{
+ if(!IsBroken())
+ switch((Frame&127) >> 5)
+ {
+ case 0: return BLUE;
+ case 1: return GREEN;
+ case 2: return RED;
+ case 3: return YELLOW;
+ }
+
+ return TRANSPARENT_COLOR;
+}
+
+void filthytunic::Be()
+{
+ bodyarmor::Be();
+
+ if(Exists() && !IsBroken() && (*Slot)->IsGearSlot() && !RAND_N(10))
+ {
+ fluidvector FluidVector;
+ FillFluidVector(FluidVector);
+ uint Volume = 0;
+
+ for(uint c = 0; c < FluidVector.size(); ++c)
+ {
+ liquid* L = FluidVector[c]->GetLiquid();
+ Volume += L->GetVolume();
+ }
+
+ if(Volume < 90)
+ SpillFluid(0, liquid::Spawn(BLOOD, 10));
+ }
+}
+
+alpha filthytunic::GetOutlineAlpha(int Frame) const
+{
+ if(!IsBroken())
+ {
+ Frame &= 31;
+ return Frame * (31 - Frame) >> 1;
+ }
+ else
+ return 255;
+}
+
+col16 filthytunic::GetOutlineColor(int Frame) const
+{
+ if(!IsBroken())
+ return MakeRGB16(77, 254, 21);
+ else
+ return TRANSPARENT_COLOR;
+}
diff --git a/Main/Source/god.cpp b/Main/Source/god.cpp
index b17fe4b13..1187b3ec6 100644
--- a/Main/Source/god.cpp
+++ b/Main/Source/god.cpp
@@ -391,7 +391,7 @@ truth god::TryToAttachBodyPart(character* Char)
{
BodyPart = 0;
materialvector MaterialVector;
- protosystem::CreateEveryMaterial(MaterialVector, this, Char);
+ protosystem::CreateEveryGodlyMaterial(MaterialVector, this, Char);
std::sort(MaterialVector.begin(), MaterialVector.end(), materialsorter(0));
uint c;
@@ -459,7 +459,7 @@ truth god::TryToHardenBodyPart(character* Char)
material* OldMaterial = BodyPart->GetMainMaterial();
int OldModifier = OldMaterial->GetHardenModifier(BodyPart);
materialvector MaterialVector;
- protosystem::CreateEveryMaterial(MaterialVector, this, Char);
+ protosystem::CreateEveryGodlyMaterial(MaterialVector, this, Char);
std::sort(MaterialVector.begin(), MaterialVector.end(), materialsorter(BodyPart));
truth Changed = false;
diff --git a/Main/Source/gods.cpp b/Main/Source/gods.cpp
index edddf19f1..3bf94a566 100644
--- a/Main/Source/gods.cpp
+++ b/Main/Source/gods.cpp
@@ -128,9 +128,17 @@ col16 mortifer::GetEliteColor() const { return CHAOS_ELITE_COLOR; }
void sophos::PrayGoodEffect()
{
- ADD_MESSAGE("Suddenly, the fabric of space experiences an unnaturally "
- "powerful quantum displacement! You teleport away!");
- PLAYER->Move(game::GetCurrentLevel()->GetRandomSquare(PLAYER), true);
+ if(PLAYER->StateIsActivated(TELEPORT_LOCK))
+ {
+ ADD_MESSAGE("You hear a booming voice: \"Alas, I cannot help thee, mortal.\"");
+ return;
+ }
+ else
+ {
+ ADD_MESSAGE("Suddenly, the fabric of space experiences an unnaturally "
+ "powerful quantum displacement! You teleport away!");
+ PLAYER->Move(game::GetCurrentLevel()->GetRandomSquare(PLAYER), true);
+ }
}
void sophos::PrayBadEffect()
@@ -1191,7 +1199,7 @@ void cruentus::PrayGoodEffect()
character* Audience = game::GetCurrentLevel()->GetSquare(x, y)->GetCharacter();
if(Audience && Audience->CanBeSeenByPlayer() && !Audience->TemporaryStateIsActivated(PANIC)
- && PLAYER->GetRelation(Audience) == HOSTILE)
+ && !Audience->StateIsActivated(FEARLESS) && PLAYER->GetRelation(Audience) == HOSTILE)
{
AudiencePresent = true;
break;
diff --git a/Main/Source/hiteffect.cpp b/Main/Source/hiteffect.cpp
new file mode 100644
index 000000000..ffbad8540
--- /dev/null
+++ b/Main/Source/hiteffect.cpp
@@ -0,0 +1,450 @@
+/*
+ *
+ * Iter Vehemens ad Necem (IVAN)
+ * Copyright (C) Timo Kiviluoto
+ * Released under the GNU General
+ * Public License
+ *
+ * See LICENSING which should be included
+ * along with this file for more details
+ *
+ */
+
+/* Compiled through materset.cpp */
+
+#define DBGMSG_BLITDATA
+#include "dbgmsgproj.h"
+
+int iDrawTot=3;
+int iCleanTot=2; //min 1
+
+hiteffect::hiteffect() : entity(HAS_BE), Next(NULL), iState(-1), bBlitdataWasSet(false) {DBGSTK;} //iState -1 indicates this constructor
+
+square* hiteffect::GetSquareUnderEntity(int) const {
+ return setup.LSquareUnder;
+}
+
+#define ITGSTATE_INIT 1 //in order always
+#define ITGSTATE_SETBLD 2
+#define ITGSTATE_SENDTOHELL 2 //must be the state value before cleaup bypassing previous
+#define ITGSTATE_CLEANUP 3
+#define ITGSTATE_DESTROY 4
+
+#define DBGHITEFFINFO \
+ DBG1(iState); \
+ DBG6("pointers",this,setup.WhoHits,setup.WhoIsHit,bmpHitEffect,setup.itemEffectReference); \
+ DBG5(setup.Type,bWhoIsHitDied,iDrawCount,bBlitdataWasSet,DBGAV2(v2HitFromSqrPos)); \
+ DBGSV2(v2HitToSqrPos); \
+ DBGEXEC(if(setup.WhoHits ->Exists())DBG1(setup.WhoHits ->GetName(DEFINITE).CStr())); \
+ DBGEXEC(if(setup.WhoIsHit->Exists())DBG1(setup.WhoIsHit->GetName(DEFINITE).CStr())); \
+ DBGEXEC(if(setup.itemEffectReference->Exists())DBGSC(setup.itemEffectReference->GetName(DEFINITE).CStr())); \
+ DBGSV2(bmpHitEffect->GetSize()); \
+ DBGBLD(bldFinalDraw); \
+ DBGSTK;
+
+hiteffect::hiteffect(hiteffectSetup s)
+: entity(HAS_BE), Next(NULL), iDrawCount(0), iState(0), bBlitdataWasSet(false), lStartTime(clock())
+{
+ chkCleanupAlready();
+
+ static short int iHigh=0xFF*0.85;
+ static col24 lumHigh=MakeRGB24(iHigh,iHigh,iHigh);
+
+ static short int iL =0xFF*0.15; //dark works better with already light graphics like arcanite or bone stuff
+ static short int iIsh=0xFF*0.90;
+ static col24 lumReddish =MakeRGB24(iIsh,iL,iL);
+ static col24 lumGreenish=MakeRGB24(iL,iIsh,iL);
+ static col24 lumBluish =MakeRGB24(iL,iL,iIsh);
+ static col24 lumYellowish =MakeRGB24(iIsh,iIsh,iL);
+
+ static blitdata bldLum = [](){bldLum = DEFAULT_BLITDATA;
+ bldLum.Bitmap = new bitmap(TILE_V2);
+ bldLum.Border = TILE_V2; return bldLum;}();
+ bldLum.Src=v2(); //reset
+ bldLum.Bitmap->ClearToColor(TRANSPARENT_COLOR); //reset
+
+ setup=s; DBG4(this,s.WhoHits,s.WhoIsHit,"WhoHits");DBG2(s.WhoHits->GetName(DEFINITE).CStr(),s.WhoIsHit->GetName(DEFINITE).CStr());
+
+ bldFinalDraw=DEFAULT_BLITDATA; DBGLN;
+
+ v2CamPos = game::GetCamera();
+
+ v2HitFromSqrPos=s.WhoHits->GetPos(); DBGSV2(v2HitFromSqrPos);
+ v2HitToSqrPos=s.WhoIsHit->GetPos(); DBGSV2(v2HitToSqrPos);
+ v2HitFromToSqrDiff = v2HitFromSqrPos-v2HitToSqrPos; DBGSV2(v2HitFromToSqrDiff);
+ if(v2HitFromToSqrDiff.X!=0 && v2HitFromToSqrDiff.Y!=0){ DBGLN; //diagonal
+ v2 v2FromXY(Min(v2HitFromSqrPos.X,v2HitToSqrPos.X),Min(v2HitFromSqrPos.Y,v2HitToSqrPos.Y)); DBGSV2(v2FromXY);
+ v2 v2ToXY(Max(v2HitFromSqrPos.X,v2HitToSqrPos.X),Max(v2HitFromSqrPos.Y,v2HitToSqrPos.Y)); DBGSV2(v2ToXY);
+ for(int iY=v2FromXY.Y;iY<=v2ToXY.Y;iY++){
+ for(int iX=v2FromXY.X;iX<=v2ToXY.X;iX++){
+ vExtraSquares.push_back(s.WhoHits->GetLevel()->GetLSquare(iX,iY)); DBG3("vExtraSquares:add",iX,iY);
+ }
+ }
+ }
+
+ bWhoIsHitDied=s.WhoIsHit->IsDead(); DBGLN;
+
+ LSquareUnderOfWhoHits=s.WhoHits->GetLSquareUnder(); DBGLN;
+
+ switch(setup.iMode){
+ case 1: //immersive
+ bldLum.Luminance = NORMAL_LUMINANCE;
+ break;
+ case 2: //indicator
+ bldLum.Luminance = lumHigh;
+ break;
+ case 3: //colored indicators where possible
+ if(setup.WhoIsHit->IsPlayer() || setup.WhoIsHit->IsPet()){
+ bldLum.Luminance = lumReddish;
+ }else
+ if(setup.WhoHits->IsPlayer()){
+ bldLum.Luminance = lumBluish;
+ }else
+ if(setup.WhoHits->IsPet()){
+ bldLum.Luminance = lumGreenish;
+ }else{
+ bldLum.Luminance = lumHigh;
+ }
+ break;
+ case 4: //dynamic colored indicators or based on usefulness of the color indicator
+ if(setup.WhoIsHit->IsPlayer() || setup.WhoHits->IsPlayer()){ //player being hit or hitting is w/o doubts the origin of the attack
+ if(setup.Critical){
+ bldLum.Luminance = lumReddish;
+ }else{
+ bldLum.Luminance = NORMAL_LUMINANCE; // do not highlight non critical strikes
+ }
+ }else
+ if(setup.WhoIsHit->IsPet()){
+ if(setup.Critical){
+ bldLum.Luminance = lumReddish;
+ }else{
+ bldLum.Luminance = lumYellowish; // just to call player attention
+ }
+ }else
+ if(setup.WhoHits->IsPet()){
+ if(setup.itemEffectReference->IsWeapon(setup.WhoHits)){ //TODO why char as param?
+ bldLum.Luminance = lumBluish;
+ }else{
+ bldLum.Luminance = lumGreenish;
+ }
+ }else{
+ bldLum.Luminance = NORMAL_LUMINANCE; // unrelated to the player's team have no highlighting at all
+ }
+
+// if(bldLum.Luminance == NORMAL_LUMINANCE){
+// if(dynamic_cast(setup.itemEffectReference)!=NULL){
+// bldLum.Luminance = lumHigh;
+// }
+// }
+
+ break;
+ default: ABORT("unsupported hiteffect mode %d",setup.iMode);
+ }
+
+ int iDegrees=0;
+ int iTipAt=2; //2 is default of most items TODO a simple database specifying where is the tip of each item gfx: 0 2 7 or 5
+ bool bAllowDirRotate=true;
+ bool bTypePrepared=false;
+ switch(setup.Type) //TODO use arm, feet, head material colors
+ {
+ case WEAPON_ATTACK:
+ if(!bTypePrepared)bTypePrepared=true;
+
+ //TODO make it sure the item will be drawn pointing at the same direction found at it's graphics file
+ setup.itemEffectReference->Draw(bldLum); //the item* cant be stored as it may break and be sent to hell after here...
+ break;
+
+ /**
+ * These 3 specific graphics below are collected directly from the raw bitmap.
+ */
+
+ case UNARMED_ATTACK: // The punch used graphics looks messy if rotated at any direction as it has no direction (it points nowhere in the 2D, it is upwards in 3D).
+ if(!bTypePrepared){bTypePrepared=true;
+ bldLum.Src.X = 16;
+ }
+ /* no break */
+
+ case KICK_ATTACK: // the used graphics points at dir 6 (down)
+ if(!bTypePrepared){bTypePrepared=true;
+ bldLum.Src.X = 32;
+ switch(setup.GivenDir){
+ case 0:case 1:case 2: iDegrees=180; break;
+ case 3: iDegrees= 90; break;
+ case 4: iDegrees=270; break;
+ // ignored 5 (6) 7
+ }
+ }
+ /* no break */
+
+ case BITE_ATTACK: // the used graphics points at dir 4 (right)
+ if(!bTypePrepared){bTypePrepared=true;
+ switch(setup.GivenDir){
+ case 0:case 1:case 2: iDegrees=270; break;
+ case 3: iDegrees=180; break;
+ // ignored (4)
+ case 5:case 6:case 7: iDegrees= 90; break;
+ }
+ }
+
+ bldLum.Src.Y = 112;
+ igraph::GetSymbolGraphic()->LuminanceMaskedBlit(bldLum);
+
+ bAllowDirRotate=false;
+
+ break;
+
+ default: DBGABORT("unsupported type mode %d",setup.Type);
+ }
+
+ /**
+ * GivenDir, see doc MirrorFlipRotateToDegrees.jpg
+ * 012
+ * 3 4
+ * 567
+ */
+ static blitdata bldRotate = [](){bldRotate = DEFAULT_BLITDATA;bldRotate.Border = TILE_V2;return bldRotate;}();
+ bldRotate.Bitmap=NULL; //reset
+
+ // reset static blitdata dir, grant it is drawn pointing to default top right
+ bitmap::ResetBlitdataRotation(bldRotate);
+
+ DBGEXEC(if(setup.WhoHits->IsPlayer())DBG3(DBGI(setup.Type),DBGI(setup.GivenDir),DBGC(setup.itemEffectReference->GetName(DEFINITE).CStr())));
+ // there is no horizontal or vertical easy rotations implemented yet TODO but ex.: spears would not fit in 16x16 w/o shrinking it...
+ if(bAllowDirRotate){
+ int iDir = setup.GivenDir;
+
+ if(iDir==1)iDir = clock()%2==0 ? 0 : 2;
+ if(iDir==3)iDir = clock()%2==0 ? 0 : 5;
+ if(iDir==4)iDir = clock()%2==0 ? 2 : 7;
+ if(iDir==6)iDir = clock()%2==0 ? 5 : 7;
+
+ switch(iDir){
+ case 0: iDegrees=270; break;
+ case 2: iDegrees= 0; break; //default at top right
+ case 5: iDegrees=180; break;
+ case 7: iDegrees= 90; break;
+ default: DBGABORT("unsupported iDir %d",iDir);
+ }
+
+ // adjusts the requested rotation based on the tip default rotation
+ switch(iTipAt){
+ case 2:break; //default top right
+ case 7:iDegrees+=-90;break; //lower right
+ case 5:iDegrees+=180;break; //lower left
+ case 0:iDegrees+= 90;break; //upper left
+ default: DBGABORT("unsupported iTipAt %d",iTipAt); //should have been converted to one of these 4
+ }
+
+ // fix overlaps
+ while(iDegrees>=360)iDegrees-=360;
+ while(iDegrees< 0)iDegrees+=360;
+ }
+
+ switch(iDegrees){
+ case 270: bldRotate.Flags |= ROTATE|FLIP|MIRROR; break;
+ case 180: bldRotate.Flags |= FLIP|MIRROR; break;
+ case 90: bldRotate.Flags |= ROTATE; break;
+ case 0: break; //default
+ default: DBGABORT("unsupported iDegrees %d",iDegrees);
+ }
+
+ DBG7(iDegrees, bAllowDirRotate,setup.GivenDir, bTypePrepared,bldRotate.Flags&ROTATE,bldRotate.Flags&FLIP,bldRotate.Flags&MIRROR);
+ (bmpHitEffect = bldRotate.Bitmap = new bitmap(TILE_V2))->ClearToColor(TRANSPARENT_COLOR); DBGLN; //TODO is clear unnecessary?
+ bldLum.Bitmap->NormalBlit(bldRotate); DBGLN; //this "rotates"
+
+ SetIntegrityState(ITGSTATE_INIT);
+}
+
+void hiteffect::SetIntegrityState(int iNewState){ DBG1(iNewState);
+ chkCleanupAlready();
+
+ if(iState != iNewState-1){
+ DBGHITEFFINFO;
+ if(iNewState!=ITGSTATE_CLEANUP) // cleanup is the end of it, no problem.
+ DBGABORT("Wrong state usage(%d), must always be equal to current(%d)+1",iNewState,iState);
+ }
+
+ iState=iNewState;
+}
+
+hiteffect::~hiteffect()
+{
+ if(bmpHitEffect!=NULL)delete bmpHitEffect;
+ iState=ITGSTATE_DESTROY; //not safe to use this here: SetIntegrityState(ITGSTATE_DESTROY); as may have debug messages...
+}
+
+void hiteffect::Be()
+{
+ chkCleanupAlready();
+
+ bool bHell=false;
+ bool bClean=false;
+
+ if(iDrawCount==iDrawTot)
+ iCleanCount++;
+
+ if(iCleanCount>0)
+ bClean=true;
+
+ if(bClean){
+ //TODO is post clean (after drawing ends) unnecessary now that drawing is denied when camera changes pos?
+ //TODO is post clean working at all?
+ if(bBlitdataWasSet){
+ CheckIntegrity(ITGSTATE_SETBLD); //before hell
+ setup.LSquareUnder->SendStrongNewDrawRequest(); //too unbuffer all hit effects as soon as possible
+ }
+ }
+
+ if(iDrawCount==iDrawTot && iCleanCount==iCleanTot)
+ bHell=true;
+
+ if(bHell){
+ setup.LSquareUnder->RemoveHitEffect(this);
+ iState=ITGSTATE_SENDTOHELL;
+ cleanup();
+ SendToHell();
+ }
+
+}
+
+void hiteffect::chkCleanupAlready() const
+{
+ if(iState==ITGSTATE_CLEANUP)DBGABORT("hiteffect was cleanup already!");
+}
+
+void hiteffect::cleanup(){
+ chkCleanupAlready();
+
+ SetIntegrityState(ITGSTATE_CLEANUP); //before the actual cleanup as pointers are still set
+
+ // TODO necessary?
+ setup.LSquareUnder=NULL;
+ setup.WhoHits=NULL;
+ setup.WhoIsHit=NULL;
+ setup.itemEffectReference=NULL;
+
+ //not external reference, must be deleted at destructor: bmpHitEffect=NULL;
+
+ LSquareUnderOfWhoHits=NULL;
+ vExtraSquares.clear(); //TODO move to destructor? or is automatic?
+}
+
+void hiteffect::PrepareBlitdata(const blitdata& bld){
+ chkCleanupAlready();
+
+ bldFinalDraw=bld; DBG1(this);DBGBLD(bldFinalDraw); //copy
+ bitmap::ResetBlitdataRotation(bldFinalDraw); //prevent it from further rotating beyong the initial setup at constructor!!!
+ bldFinalDraw.Stretch=0; //TODO why so big numbers here? was it uninitialized?
+ bBlitdataWasSet=true;
+
+ if(iState!=ITGSTATE_SETBLD){ //can be set more than once
+ CheckIntegrity(ITGSTATE_INIT); //must be only this one here
+ SetIntegrityState(ITGSTATE_SETBLD);
+ }
+}
+
+void hiteffect::End(){
+ chkCleanupAlready();
+
+ iDrawCount=iDrawTot;
+}
+
+truth hiteffect::DrawStep()
+{
+ chkCleanupAlready();
+
+ if(iDrawCount==iDrawTot)return false;
+
+ bool bDraw = true;
+ bool bAnimate = true;
+
+ if(ivanconfig::IsHideWeirdHitAnimationsThatLookLikeMiss()){
+ //showing all animations helps on understanding there happened a hit, even if it looks like a miss or weird (kills before hitting) :(
+ if(bAnimate && bWhoIsHitDied)bAnimate=false;
+ if(bAnimate && !setup.WhoIsHit->Exists())bAnimate=false; //TODO is this crash safe?
+ if(bDraw && bAnimate && setup.WhoIsHit->GetPos()!=v2HitToSqrPos){
+ /*
+ * TODO if the hit target moves, the effect would play flying to it's last location (where it was actually)
+ * and will look like a miss (what is wrong), so I tried setting it to instantly draw there,
+ * but still looks like a miss, so I just disabled the effect when that happens to not look confusing :(.
+ */
+ End(); //this will end the drawing to prevent it looking like a missed hit :(
+ bDraw=false;
+
+ bAnimate=false;
+ }
+ }
+
+ static long lTimeoutDelay = CLOCKS_PER_SEC*3.0; //prevent effects older than 3 seconds from continue playing, the glitch is most visible during wizard autoplay mode
+ if( clock() > (lStartTime+lTimeoutDelay) ){
+ End();
+ bDraw=false;
+ }
+
+ //TODO use rotation?
+ if(bAnimate){ //just to not fly if it died already
+ //place at who hits to fly from it to who is hit
+ bldFinalDraw.Dest += v2HitFromToSqrDiff*TILE_SIZE;
+
+ //displacement, interpolate TODO could be at v2 class with To and fPercent!
+ bldFinalDraw.Dest += -(v2HitFromToSqrDiff*TILE_SIZE)*(iDrawCount/(float)iDrawTot);
+ }
+
+ if(game::GetCamera()!=v2CamPos){
+ /**
+ * As the hiteffect will draw LATER,
+ * this means, if the camera moves, the blitdata will command to still draw relatively to where the camera WAS
+ * and not where the camera IS!!
+ * TODO improve this by updating the blitdata to the new camPos?
+ */
+ End();
+ bDraw=false;
+ }
+
+ if(bDraw){
+ Draw();
+ iDrawCount++; // AFTER drawing!
+
+ //clear all hit effects as soon as possible
+ setup.LSquareUnder->SendStrongNewDrawRequest();
+ LSquareUnderOfWhoHits->SendStrongNewDrawRequest();
+ for(int i=0;iSendStrongNewDrawRequest(); DBGSV2(vExtraSquares[i]->GetPos());
+ }
+ }
+
+ return true; //did draw now
+}
+
+truth hiteffect::CheckIntegrity(int iItgState) const{
+ chkCleanupAlready();
+
+ if(
+ bldFinalDraw.Border.X==0 ||
+ bldFinalDraw.Border.Y==0
+ ){
+ DBGHITEFFINFO;
+
+ if(iState!=iItgState)DBGABORT("hiteffect not initialized or not setup properly %d!=%d",iState,iItgState);
+
+ DBGABORT("invalid hit effect setup"); //will force exit right here during development
+ return false;
+ }
+ return true;
+}
+
+void hiteffect::Draw() const //TODO is it being called other than thru DrawStep()?
+{
+ chkCleanupAlready();
+
+ if(!bBlitdataWasSet)return;
+
+ /**
+ * As this is just an effect, it's funtionally shall not break the game.
+ * So it will simply return if something is wrong.
+ */
+ if(!CheckIntegrity(ITGSTATE_SETBLD))return;
+
+ if(iDrawCountNormalMaskedBlit(bldFinalDraw); //TODO use alpha?
+}
diff --git a/Main/Source/human.cpp b/Main/Source/human.cpp
index 90476a61f..5c1740643 100644
--- a/Main/Source/human.cpp
+++ b/Main/Source/human.cpp
@@ -12,6 +12,8 @@
/* Compiled through charsset.cpp */
+#include "dbgmsgproj.h"
+
cint humanoid::DrawOrder[] =
{ TORSO_INDEX, GROIN_INDEX, RIGHT_LEG_INDEX, LEFT_LEG_INDEX, RIGHT_ARM_INDEX, LEFT_ARM_INDEX, HEAD_INDEX };
@@ -43,24 +45,26 @@ v2 housewife::GetHeadBitmapPos() const { return v2(112, (RAND() % 6) << 4); }
truth zombie::BodyPartIsVital(int I) const { return I == GROIN_INDEX || I == TORSO_INDEX; }
festring zombie::GetZombieDescription() const { return Description; }
-truth spirit::BodyPartIsVital(int I) const { return I == GROIN_INDEX || I == TORSO_INDEX || I == HEAD_INDEX; }
-festring spirit::GetSpiritDescription() const { return Description; }
-cchar* spirit::FirstPersonUnarmedHitVerb() const { return "touch"; }
-cchar* spirit::FirstPersonCriticalUnarmedHitVerb() const
+truth ghost::BodyPartIsVital(int I) const { return I == GROIN_INDEX || I == TORSO_INDEX; }
+festring ghost::GetGhostDescription() const { return Description; }
+cchar* ghost::FirstPersonUnarmedHitVerb() const { return "touch"; }
+cchar* ghost::FirstPersonCriticalUnarmedHitVerb() const
{ return "critically touch"; }
-cchar* spirit::ThirdPersonUnarmedHitVerb() const { return "touches"; }
-cchar* spirit::ThirdPersonCriticalUnarmedHitVerb() const
+cchar* ghost::ThirdPersonUnarmedHitVerb() const { return "touches"; }
+cchar* ghost::ThirdPersonCriticalUnarmedHitVerb() const
{ return "critically touches"; }
truth angel::BodyPartIsVital(int I) const { return I == TORSO_INDEX || I == HEAD_INDEX; }
+truth nihil::BodyPartIsVital(int I) const { return I == TORSO_INDEX || I == HEAD_INDEX; }
+
truth genie::BodyPartIsVital(int I) const { return I == TORSO_INDEX || I == HEAD_INDEX; }
material* golem::CreateBodyPartMaterial(int, long Volume) const { return MAKE_MATERIAL(GetConfig(), Volume); }
truth sumowrestler::EquipmentIsAllowed(int I) const { return I == BELT_INDEX; }
-truth spirit::SpecialEnemySightedReaction(character*) { return !(Active = true); }
+truth ghost::SpecialEnemySightedReaction(character*) { return !(Active = true); }
petrus::~petrus()
{
@@ -481,6 +485,16 @@ truth humanoid::Hit(character* Enemy, v2 HitPos, int Direction, int Flags)
break;
}
+ if(StateIsActivated(VAMPIRISM) && !(RAND() % 2))
+ {
+ if(Chosen == USE_ARMS && CanAttackWithAnArm())
+ if(!GetRightWielded() && !GetLeftWielded())
+ Chosen = USE_HEAD;
+
+ if(Chosen == USE_LEGS && HasTwoUsableLegs())
+ Chosen = USE_HEAD;
+ }
+
switch(Chosen)
{
case USE_ARMS:
@@ -754,7 +768,7 @@ void priest::BeTalkedTo()
{
if(GetRelation(PLAYER) == HOSTILE)
{
- ADD_MESSAGE("\"Sinner! My hands shall pour Divine Wrath upon thee!\"");
+ character::BeTalkedTo();
return;
}
@@ -774,7 +788,7 @@ void priest::BeTalkedTo()
return;
}
}
- else
+ else
ADD_MESSAGE("\"Good %s, you're on fire! Quick, go find %ld gold so that I can help!\"", GetMasterGod()->GetName(), Price);
}
@@ -930,7 +944,7 @@ void priest::BeTalkedTo()
if(PLAYER->GetMoney() >= Price)
{
ADD_MESSAGE("\"You seem to be turning into a werewolf quite frequently. Well, everyone has right to "
- "little secret habits, but if you wish to donate %ldgp to %s, maybe I could pray %s to "
+ "little secret habits, but if you wish to donate %ldgp to %s, maybe I could pray to %s to "
"remove the canine blood from your veins, just so you don't scare our blessed youth.\"",
Price, GetMasterGod()->GetName(), GetMasterGod()->GetObjectPronoun());
@@ -948,6 +962,79 @@ void priest::BeTalkedTo()
"for that but I need %ldgp for the ritual materials first.\"", Price);
}
+ if(PLAYER->TemporaryStateIsActivated(VAMPIRISM))
+ {
+ long Price = GetConfig() == VALPURUS ? 100 : 20;
+
+ if(PLAYER->GetMoney() >= Price)
+ {
+ ADD_MESSAGE("\"You seem to have an addiction to drinking blood. Well, everyone has right to "
+ "little secret habits, but if you wish to donate %ldgp to %s, maybe I could pray "
+ "%s to remove your vampiric urges, just so you don't victimize our besotted youth.\""
+ , Price, GetMasterGod()->GetName(), GetMasterGod()->GetObjectPronoun());
+
+ if(game::TruthQuestion(CONST_S("Do you agree? [y/N]")))
+ {
+ ADD_MESSAGE("You feel better.");
+ PLAYER->DeActivateTemporaryState(VAMPIRISM);
+ PLAYER->SetMoney(PLAYER->GetMoney() - Price);
+ SetMoney(GetMoney() + Price);
+ return;
+ }
+ }
+ else
+ ADD_MESSAGE("\"You seem to be vampiric. I might be able to do something for that but "
+ "I need %ldgp for the ritual materials first.\"", Price);
+ }
+
+ if(PLAYER->TemporaryStateIsActivated(PARASITE_TAPE_WORM))
+ {
+ long Price = GetConfig() == VALPURUS ? 100 : 20;
+
+ if(PLAYER->GetMoney() >= Price)
+ {
+ ADD_MESSAGE("\"Ugh, there seems to be some other creature living in your body. I could try "
+ "to purge the parasite, that is if you wish to donate %ldgp to %s, of course.\""
+ , Price, GetMasterGod()->GetName(), GetMasterGod()->GetObjectPronoun());
+
+ if(game::TruthQuestion(CONST_S("Do you agree? [y/N]")))
+ {
+ ADD_MESSAGE("You feel better.");
+ PLAYER->DeActivateTemporaryState(PARASITE_TAPE_WORM);
+ PLAYER->SetMoney(PLAYER->GetMoney() - Price);
+ SetMoney(GetMoney() + Price);
+ return;
+ }
+ }
+ else
+ ADD_MESSAGE("\"You seem to have an unwanted guest in your guts. I can help but "
+ "I need %ldgp for a ritual of cleansing.\"", Price);
+ }
+
+ if(PLAYER->TemporaryStateIsActivated(PARASITE_MIND_WORM))
+ {
+ long Price = GetConfig() == VALPURUS ? 100 : 20;
+
+ if(PLAYER->GetMoney() >= Price)
+ {
+ ADD_MESSAGE("\"Ugh, there seems to be some other creature living in your body. I could try "
+ "to purge the parasite, that is if you wish to donate %ldgp to %s, of course.\""
+ , Price, GetMasterGod()->GetName(), GetMasterGod()->GetObjectPronoun());
+
+ if(game::TruthQuestion(CONST_S("Do you agree? [y/N]")))
+ {
+ ADD_MESSAGE("You feel better.");
+ PLAYER->DeActivateTemporaryState(PARASITE_MIND_WORM);
+ PLAYER->SetMoney(PLAYER->GetMoney() - Price);
+ SetMoney(GetMoney() + Price);
+ return;
+ }
+ }
+ else
+ ADD_MESSAGE("\"You seem to have an unwanted guest in your head. I can help but "
+ "I need %ldgp for a ritual of cleansing.\"", Price);
+ }
+
static long Said;
if(GetConfig() != SILVA)
@@ -963,7 +1050,7 @@ void skeleton::BeTalkedTo()
if(GetHead())
humanoid::BeTalkedTo();
else
- ADD_MESSAGE("The headless %s remains silent.", PLAYER->CHAR_DESCRIPTION(UNARTICLED));
+ ADD_MESSAGE("The headless %s remains silent.", CHAR_DESCRIPTION(DEFINITE));
}
void communist::BeTalkedTo()
@@ -980,7 +1067,7 @@ void communist::BeTalkedTo()
{
if(Char != this)
Char->ChangeTeam(PLAYER->GetTeam());
-
+
if(GetTeam()->GetMembers() == 1) // Only Ivan left in Party
break;
}
@@ -1120,6 +1207,9 @@ void slave::GetAICommand()
{
SeekLeader(GetLeader());
+ if(CheckAIZapOpportunity())
+ return;
+
if(CheckForEnemies(true, true, true))
return;
@@ -1259,7 +1349,11 @@ truth communist::MoveRandomly()
void zombie::BeTalkedTo()
{
- if(GetRelation(PLAYER) == HOSTILE && PLAYER->GetAttribute(INTELLIGENCE) > 5)
+ if(!HasHead())
+ {
+ ADD_MESSAGE("The headless %s remains silent.", CHAR_DESCRIPTION(DEFINITE));
+ }
+ else if(GetRelation(PLAYER) == HOSTILE && PLAYER->GetAttribute(INTELLIGENCE) > 5)
{
if(RAND() % 5)
{
@@ -1272,7 +1366,7 @@ void zombie::BeTalkedTo()
ADD_MESSAGE("\"Redrum! Redrum! Redrum!\"");
}
else
- ADD_MESSAGE("\"Need brain but you too stoopid!\"");
+ character::BeTalkedTo();
}
void angel::Save(outputfile& SaveFile) const
@@ -1823,6 +1917,8 @@ v2 humanoid::GetEquipmentPanelPos(int I) const // convert to array
return v2(24, 12);
}
+v2 humanoid::SilhouetteWhere=v2(0,0); //zeroed because wont init properly here.. TODO explain why.
+v2 humanoid::SilhouetteWhereDefault=v2(0,0); //zeroed because wont init properly here.. TODO explain why.
void humanoid::DrawSilhouette(truth AnimationDraw) const
{
int c;
@@ -1834,14 +1930,16 @@ void humanoid::DrawSilhouette(truth AnimationDraw) const
TRANSPARENT_COLOR,
ALLOW_ANIMATE };
- v2 Where(RES.X - SILHOUETTE_SIZE.X - 39, 53);
cint Equipments = GetEquipments();
+ if(SilhouetteWhereDefault.Is0())SilhouetteWhereDefault={RES.X - SILHOUETTE_SIZE.X - 39, 53};
+ if(SilhouetteWhere.Is0())SilhouetteWhere=SilhouetteWhereDefault;
+
if(CanUseEquipment())
for(c = 0; c < Equipments; ++c)
if(GetBodyPartOfEquipment(c) && EquipmentIsAllowed(c))
{
- v2 Pos = Where + GetEquipmentPanelPos(c);
+ v2 Pos = SilhouetteWhereDefault + GetEquipmentPanelPos(c);
if(!AnimationDraw)
DOUBLE_BUFFER->DrawRectangle(Pos + v2(-1, -1), Pos + TILE_V2, DARK_GRAY);
@@ -1865,7 +1963,7 @@ void humanoid::DrawSilhouette(truth AnimationDraw) const
{
blitdata B2 = { DOUBLE_BUFFER,
{ 0, 0 },
- { Where.X + 8, Where.Y },
+ { SilhouetteWhere.X + 8, SilhouetteWhere.Y },
{ SILHOUETTE_SIZE.X, SILHOUETTE_SIZE.Y },
{ 0 },
0,
@@ -1893,6 +1991,18 @@ int humanoid::GetGlobalResistance(int Type) const
if(GetCloak())
Resistance += GetCloak()->GetResistance(Type);
+ if(GetRightWielded())
+ {
+ if(GetRightWielded()->IsShield(this))
+ Resistance += GetRightWielded()->GetResistance(Type);
+ }
+
+ if(GetLeftWielded())
+ {
+ if(GetLeftWielded()->IsShield(this))
+ Resistance += GetLeftWielded()->GetResistance(Type);
+ }
+
if(!(Type & PHYSICAL_DAMAGE))
{
if(GetAmulet())
@@ -2612,6 +2722,16 @@ int angel::GetAttribute(int Identifier, truth AllowBonus) const // temporary unt
return humanoid::GetAttribute(Identifier, AllowBonus);
}
+int nihil::GetAttribute(int Identifier, truth AllowBonus) const
+{
+ if(Identifier == LEG_STRENGTH)
+ return GetDefaultLegStrength();
+ else if(Identifier == AGILITY)
+ return GetDefaultAgility();
+ else
+ return humanoid::GetAttribute(Identifier, AllowBonus);
+}
+
int genie::GetAttribute(int Identifier, truth AllowBonus) const // temporary until someone invents a better way of doing this
{
if(Identifier == LEG_STRENGTH)
@@ -2714,7 +2834,7 @@ item* skeleton::SevereBodyPart(int BodyPartIndex, truth ForceDisappearance, stac
void zombie::CreateBodyParts(int SpecialFlags)
{
bool Anyway = false;
- if(GetConfig() == ZOMBIE_OF_KHAZ_ZADM)
+ if((GetConfig() == ZOMBIE_OF_KHAZ_ZADM) || !!(SpecialFlags & NO_SEVERED_LIMBS))
{
Anyway = true;
} // Khaz-Zadm needs his hands...
@@ -2727,7 +2847,7 @@ void zombie::CreateBodyParts(int SpecialFlags)
}
}
-void spirit::AddName(festring& String, int Case) const
+void ghost::AddName(festring& String, int Case) const
{
if(OwnerSoul.IsEmpty() || Case & PLURAL)
character::AddName(String, Case);
@@ -2738,13 +2858,13 @@ void spirit::AddName(festring& String, int Case) const
}
}
-void spirit::Save(outputfile& SaveFile) const
+void ghost::Save(outputfile& SaveFile) const
{
humanoid::Save(SaveFile);
SaveFile << OwnerSoul << Active << Description;
}
-void spirit::Load(inputfile& SaveFile)
+void ghost::Load(inputfile& SaveFile)
{
humanoid::Load(SaveFile);
SaveFile >> OwnerSoul >> Active >> Description;
@@ -2762,7 +2882,7 @@ void bonesghost::Load(inputfile& SaveFile)
SaveFile >> OwnerSoul >> Active >> Description >> EyeColor >> HairColor;
}
-truth spirit::RaiseTheDead(character* Summoner)
+truth ghost::RaiseTheDead(character* Summoner)
{
itemvector ItemVector;
GetStackUnder()->FillItemVector(ItemVector);
@@ -2779,7 +2899,7 @@ truth spirit::RaiseTheDead(character* Summoner)
return false;
}
-int spirit::ReceiveBodyPartDamage(character* Damager, int Damage, int Type, int BodyPartIndex,
+int ghost::ReceiveBodyPartDamage(character* Damager, int Damage, int Type, int BodyPartIndex,
int Direction, truth PenetrateResistance, truth Critical,
truth ShowNoDamageMsg, truth CaptureBodyPart)
{
@@ -2793,7 +2913,7 @@ int spirit::ReceiveBodyPartDamage(character* Damager, int Damage, int Type, int
return 0;
}
-void spirit::GetAICommand()
+void ghost::GetAICommand()
{
if(Active)
character::GetAICommand();
@@ -3251,6 +3371,11 @@ truth angel::CanCreateBodyPart(int I) const
return I == TORSO_INDEX || I == HEAD_INDEX || I == RIGHT_ARM_INDEX || I == LEFT_ARM_INDEX;
}
+truth nihil::CanCreateBodyPart(int I) const
+{
+ return I == TORSO_INDEX || I == HEAD_INDEX || I == RIGHT_ARM_INDEX || I == LEFT_ARM_INDEX;
+}
+
truth genie::CanCreateBodyPart(int I) const
{
return I == TORSO_INDEX || I == HEAD_INDEX || I == RIGHT_ARM_INDEX || I == LEFT_ARM_INDEX;
@@ -3346,6 +3471,152 @@ long skeleton::GetBodyPartVolume(int I) const
return 0;
}
+truth humanoid::AutoPlayAIequip()
+{
+ item* iL = GetEquipment(LEFT_WIELDED_INDEX);
+ item* iR = GetEquipment(RIGHT_WIELDED_INDEX);
+
+ //every X turns remove all equipments
+ bool bTryWieldNow=false;
+ static int iLastReEquipAllTurn=-1;
+ if(game::GetTurn()>(iLastReEquipAllTurn+150)){ DBG2(game::GetTurn(),iLastReEquipAllTurn);
+ iLastReEquipAllTurn=game::GetTurn();
+ for(int i=0;iMoveTo(GetStack());SetEquipment(i,NULL);} //eq is moved to end of stack!
+ if(iL==eq)iL=NULL;
+ if(iR==eq)iR=NULL;
+ }
+// if(iL!=NULL){iL->MoveTo(GetStack());iL=NULL;SetEquipment(LEFT_WIELDED_INDEX ,NULL);DBGLN;}
+// if(iR!=NULL){iR->MoveTo(GetStack());iR=NULL;SetEquipment(RIGHT_WIELDED_INDEX,NULL);DBGLN;}
+ bTryWieldNow=true;
+ }
+
+ //wield some weapon from the inventory as the NPC AI is not working for the player TODO why?
+ //every X turns try to wield
+ static int iLastTryToWieldTurn=-1;
+ if(bTryWieldNow || game::GetTurn()>(iLastTryToWieldTurn+10)){ DBG2(game::GetTurn(),iLastTryToWieldTurn);
+ iLastTryToWieldTurn=game::GetTurn();
+ bool bDoneLR=false;
+ bool bL2H = iL && iL->IsTwoHanded();
+ bool bR2H = iR && iR->IsTwoHanded();
+
+ //2handed
+ static int iTryWieldWhat=0; iTryWieldWhat++;
+ if(iTryWieldWhat%2==0){ //will try 2handed first, alternating. If player has only 2handeds, the 1handeds will not be wielded and it will use punches, what is good too for tests.
+ if( !bDoneLR &&
+ iL==NULL && GetBodyPartOfEquipment(LEFT_WIELDED_INDEX )!=NULL &&
+ iR==NULL && GetBodyPartOfEquipment(RIGHT_WIELDED_INDEX)!=NULL
+ ){
+ static itemvector vitEqW;vitEqW.clear();GetStack()->FillItemVector(vitEqW);
+ for(uint c = 0; c < vitEqW.size(); ++c){
+ if(vitEqW[c]->IsWeapon(this) && vitEqW[c]->IsTwoHanded()){
+ vitEqW[c]->RemoveFromSlot();
+ SetEquipment(clock()%2==0 ? LEFT_WIELDED_INDEX : RIGHT_WIELDED_INDEX, vitEqW[c]); //DBG3("Wield",iEqIndex,vitEqW[c]->GetName(DEFINITE).CStr());
+ bDoneLR=true;
+ break;
+ }
+ }
+ }
+ }
+
+ //dual 1handed (if not 2hd already)
+ if(!bDoneLR){
+ for(int i=0;i<2;i++){
+ int iChk=-1;
+ if(i==0)iChk=LEFT_WIELDED_INDEX;
+ if(i==1)iChk=RIGHT_WIELDED_INDEX;
+
+ if(
+ !bDoneLR &&
+ (
+ (iChk==LEFT_WIELDED_INDEX && iL==NULL && GetBodyPartOfEquipment(LEFT_WIELDED_INDEX ) && !bR2H)
+ ||
+ (iChk==RIGHT_WIELDED_INDEX && iR==NULL && GetBodyPartOfEquipment(RIGHT_WIELDED_INDEX) && !bL2H)
+ )
+ ){
+ static itemvector vitEqW;vitEqW.clear();GetStack()->FillItemVector(vitEqW);
+ for(uint c = 0; c < vitEqW.size(); ++c){
+ if(
+ (vitEqW[c]->IsWeapon(this) && !vitEqW[c]->IsTwoHanded())
+ ||
+ vitEqW[c]->IsShield(this)
+ ){
+ vitEqW[c]->RemoveFromSlot();
+ SetEquipment(iChk, vitEqW[c]);
+ bDoneLR=true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ static int iLastTryToUseInvTurn=-1;
+ if(game::GetTurn()>(iLastTryToUseInvTurn+5)){ //every X turns try to use stuff from inv
+ iLastTryToUseInvTurn=game::GetTurn();
+
+ //////////////////////////////// consume food/drink
+ {
+ static itemvector vitEqW;vitEqW.clear();GetStack()->FillItemVector(vitEqW);
+ for(uint c = 0; c < vitEqW.size(); ++c){
+ if(GetHungerState() >= BLOATED)break;
+ if(TryToConsume(vitEqW[c]))return true;
+ }
+ }
+
+ //////////////////////////////// equip
+ {
+ static itemvector vitEqW;vitEqW.clear();GetStack()->FillItemVector(vitEqW);
+ for(uint c = 0; c < vitEqW.size(); ++c){
+ if(TryToEquip(vitEqW[c],true)){
+ return true;
+ }else{
+ vitEqW[c]->MoveTo(GetStack()); //was dropped, get back, will be in the end of the stack! :)
+ }
+ }
+ }
+
+ //////////////////////////////// zap
+ static int iLastZapTurn=-1;
+ if(game::GetTurn()>(iLastZapTurn+100)){ //every X turns try to use stuff from inv
+ iLastZapTurn=game::GetTurn();
+
+ int iDir=clock()%(8+1); // index 8 is the macro YOURSELF already... if(iDir==8)iDir=YOURSELF;
+ static itemvector vitEqW;vitEqW.clear();GetStack()->FillItemVector(vitEqW);
+ for(uint c = 0; c < vitEqW.size(); ++c){
+ if(!vitEqW[c]->IsZappable(this))continue;
+
+ if(vitEqW[c]->Zap(this, GetPos(), iDir)) //TODO try to aim at NPCs
+ return true;
+
+ if(vitEqW[c]->Apply(this))
+ return true;
+ }
+ }
+
+ //////////////////////////////// read book
+ static int iLastReadTurn=-1;
+ if(game::GetTurn()>(iLastReadTurn+50)){ //every X turns try to use stuff from inv
+ iLastReadTurn=game::GetTurn();
+
+ static itemvector vitEqW;vitEqW.clear();GetStack()->FillItemVector(vitEqW);
+ for(uint c = 0; c < vitEqW.size(); ++c){
+ if(!vitEqW[c]->IsReadable(this))continue;
+ static holybook* hb;hb = dynamic_cast(vitEqW[c]);
+ if(hb==NULL)continue;
+
+ if(vitEqW[c]->Read(this)) //TODO try to aim at NPCs
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
truth humanoid::CheckIfEquipmentIsNotUsable(int I) const
{
return (I == RIGHT_WIELDED_INDEX && GetRightArm()->CheckIfWeaponTooHeavy("this item"))
@@ -3399,6 +3670,43 @@ truth housewife::SpecialEnemySightedReaction(character* Char)
return false;
}
+void housewife::CreateInitialEquipment(int SpecialFlags)
+{
+ humanoid::CreateInitialEquipment(SpecialFlags);
+ meleeweapon* Weapon;
+
+ if(GetConfig() == CULTIST)
+ {
+ Weapon = meleeweapon::Spawn(SCYTHE);
+ SetRightWielded(Weapon);
+ GetCWeaponSkill(POLE_ARMS)->AddHit(100);
+ GetCurrentRightSWeaponSkill()->AddHit(50);
+ return;
+ }
+ else switch(RAND() % 4)
+ {
+ case 0:
+ Weapon = meleeweapon::Spawn(ROLLING_PIN);
+ SetRightWielded(Weapon);
+ GetCWeaponSkill(BLUNT_WEAPONS)->AddHit(50);
+ GetCurrentRightSWeaponSkill()->AddHit(10);
+ break;
+ case 1:
+ Weapon = meleeweapon::Spawn(FRYING_PAN);
+ SetRightWielded(Weapon);
+ GetCWeaponSkill(BLUNT_WEAPONS)->AddHit(50);
+ GetCurrentRightSWeaponSkill()->AddHit(10);
+ break;
+ case 2:
+ Weapon = meleeweapon::Spawn(MEAT_CLEAVER);
+ SetRightWielded(Weapon);
+ GetCWeaponSkill(SMALL_SWORDS)->AddHit(50);
+ GetCurrentRightSWeaponSkill()->AddHit(10);
+ break;
+ default: break;
+ }
+}
+
void guard::Save(outputfile& SaveFile) const
{
humanoid::Save(SaveFile);
@@ -3807,6 +4115,31 @@ festring werewolfwolf::GetKillName() const
return humanoid::GetKillName();
}
+truth werewolfwolf::SpecialBiteEffect(character* Victim, v2 HitPos, int BodyPartIndex, int Direction, truth BlockedByArmour, truth Critical, int DoneDamage)
+{
+ if(!BlockedByArmour && Victim->IsWarmBlooded() && (!(RAND() % 2) || Critical) && !Victim->AllowSpoil())
+ {
+ // Werewolf wolf gives lycanthropy
+ if(Victim->IsHumanoid() && !Victim->StateIsActivated(VAMPIRISM) && !Victim->StateIsActivated(LYCANTHROPY) && !Victim->StateIsActivated(DISEASE_IMMUNITY))
+ Victim->BeginTemporaryState(LYCANTHROPY, 6000 + RAND_N(2000));
+
+ // Werewolves do double damage against vampires and this is a drain attack
+ if(Victim->StateIsActivated(VAMPIRISM) && (DoneDamage >= 1))
+ {
+ if(IsPlayer())
+ ADD_MESSAGE("You drain some life force from %s!", Victim->CHAR_DESCRIPTION(DEFINITE));
+ else if(Victim->IsPlayer() || Victim->CanBeSeenByPlayer() || CanBeSeenByPlayer())
+ ADD_MESSAGE("%s drains some life force from %s!", CHAR_DESCRIPTION(DEFINITE), Victim->CHAR_DESCRIPTION(DEFINITE));
+
+ return Victim->ReceiveBodyPartDamage(this, DoneDamage, DRAIN, BodyPartIndex, Direction);
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
int humanoid::GetRandomApplyBodyPart() const
{
if(RightArmIsUsable())
@@ -4383,7 +4716,7 @@ void necromancer::GetAICommand()
if(NearestEnemy && NearestEnemy->GetPos().IsAdjacent(Pos))
{
- if(GetConfig() == MASTER_NECROMANCER && !(RAND() & 3))
+ if(GetConfig() != APPRENTICE_NECROMANCER && !(RAND() & 3))
{
if(CanBeSeenByPlayer())
ADD_MESSAGE("%s invokes a spell and disappears.", CHAR_NAME(DEFINITE));
@@ -4427,7 +4760,7 @@ void necromancer::GetAICommand()
case APPRENTICE_NECROMANCER:
RaiseSkeleton();
break;
- case MASTER_NECROMANCER:
+ default:
if(RAND() % 5)
RaiseSkeleton();
else
@@ -4523,7 +4856,7 @@ void necromancer::RaiseSkeleton()
databasecreator::FindDataBase(WarLordDataBase, &skeleton::ProtoType, WAR_LORD);
skeleton* Skeleton;
- if(GetConfig() == MASTER_NECROMANCER && !(WarLordDataBase->Flags & HAS_BEEN_GENERATED) && !(RAND() % 250))
+ if(GetConfig() == MASTER_NECROMANCER && !(WarLordDataBase->Flags & HAS_BEEN_GENERATED) && !(game::GetCurrentDungeonIndex() == XINROCH_TOMB) && !(RAND() % 250))
{
Skeleton = skeleton::Spawn(WAR_LORD);
Skeleton->SetTeam(GetTeam());
@@ -4564,7 +4897,7 @@ void necromancer::BeTalkedTo()
/* From here we are talking to the necromancer in the attnamese catacombs */
if(GetRelation(PLAYER) == HOSTILE)
{
- ADD_MESSAGE("I will bury you in the catacombs with all the others!");
+ ADD_MESSAGE("\"I will bury you in the catacombs with all the others!\"");
return;
}
@@ -4634,9 +4967,11 @@ void necromancer::BeTalkedTo()
"from my minions. But alas, no more necromancy, that stupid floating eye hovers by here\n"
"every now and again to check up on me.\"\n"));
- game::TextScreen(CONST_S("\"I can relate the history of dark knighthood to you. Long ago, there lived a\n"
- "powerful warrior, Xinroch, who rose up the ranks of the fearsome order of the\n"
- "dark knights, to become the grand master dark knight. \n\n"
+ game::TextScreen(CONST_S("\"Wait, don't go yet! It gets lonely here, with no one to talk to but the punishers.\n"
+ "Keep me company a little longer, please... Maybe I can tell you a story? I can relate\n"
+ "the history of dark knighthood to you.\n\n"
+ "Long ago, there lived a powerful warrior, Xinroch, who rose up the ranks\n"
+ "of the fearsome order of the dark knights, to become the grand master dark knight. \n\n"
"His soul dwells within his mausoleum, not far from here. He doesn't stand a chance\n"
"of returning to us; not without a piece of his soul getting out. There is a cadre\n"
"of devoted dark knights, called the Templars. Being eager to protect the resting place\n"
@@ -4764,6 +5099,65 @@ void oree::Bite(character* Enemy, v2 HitPos, int, truth)
Vomit(HitPos, 500 + RAND() % 500, false);
}
+truth vampire::SpecialBiteEffect(character* Victim, v2 HitPos, int BodyPartIndex, int Direction, truth BlockedByArmour, truth Critical, int DoneDamage)
+{
+ if(!BlockedByArmour && Victim->IsWarmBlooded() && (!(RAND() % 2) || Critical) && !Victim->AllowSpoil())
+ {
+ if(IsPlayer())
+ ADD_MESSAGE("You drain some precious lifeblood from %s!", Victim->CHAR_DESCRIPTION(DEFINITE));
+ else if(Victim->IsPlayer() || Victim->CanBeSeenByPlayer() || CanBeSeenByPlayer())
+ ADD_MESSAGE("%s drains some precious lifeblood from %s!", CHAR_DESCRIPTION(DEFINITE), Victim->CHAR_DESCRIPTION(DEFINITE));
+
+ if(Victim->IsHumanoid() && !Victim->StateIsActivated(VAMPIRISM) && !Victim->StateIsActivated(LYCANTHROPY) && !Victim->StateIsActivated(DISEASE_IMMUNITY))
+ Victim->BeginTemporaryState(VAMPIRISM, 5000 + RAND_N(2500));
+
+ // HP recieved is about half the damage done; against werewolves this is full
+ int DrainDamage = (DoneDamage >> 1) + 1;
+ if(Victim->StateIsActivated(LYCANTHROPY))
+ DrainDamage = DoneDamage + 1;
+
+ if(IsPlayer())
+ game::DoEvilDeed(10);
+
+ return Victim->ReceiveBodyPartDamage(this, DrainDamage, DRAIN, BodyPartIndex, Direction);
+ }
+ else
+ return false;
+}
+
+truth humanoid::SpecialBiteEffect(character* Victim, v2 HitPos, int BodyPartIndex, int Direction, truth BlockedByArmour, truth Critical, int DoneDamage)
+{
+ if(StateIsActivated(VAMPIRISM))
+ {
+ if(!BlockedByArmour && Victim->IsWarmBlooded() && (!(RAND() % 2) || Critical) && !Victim->AllowSpoil())
+ {
+ if(IsPlayer())
+ ADD_MESSAGE("You drain some precious lifeblood from %s!", Victim->CHAR_DESCRIPTION(DEFINITE));
+ else if(Victim->IsPlayer() || Victim->CanBeSeenByPlayer() || CanBeSeenByPlayer())
+ ADD_MESSAGE("%s drains some precious lifeblood from %s!", CHAR_DESCRIPTION(DEFINITE), Victim->CHAR_DESCRIPTION(DEFINITE));
+
+ if(Victim->IsHumanoid() && !Victim->StateIsActivated(VAMPIRISM) && !Victim->StateIsActivated(LYCANTHROPY) && !Victim->StateIsActivated(DISEASE_IMMUNITY))
+ Victim->BeginTemporaryState(VAMPIRISM, 2000 + RAND_N(500));
+
+ // HP recieved is about half the damage done; against werewolves this is full
+ int DrainDamage = (DoneDamage >> 1) + 1;
+ if(Victim->StateIsActivated(LYCANTHROPY))
+ DrainDamage = DoneDamage + 1;
+
+ // To perpetuate vampirism, simply keep doing drain attacks
+ BeginTemporaryState(VAMPIRISM, 50*DrainDamage);
+ if(IsPlayer())
+ game::DoEvilDeed(10);
+
+ return Victim->ReceiveBodyPartDamage(this, DrainDamage, DRAIN, BodyPartIndex, Direction);
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
void sumowrestler::GetAICommand()
{
EditNP(-25);
@@ -4986,18 +5380,39 @@ void darkknight::SpecialBodyPartSeverReaction()
{
if(!IsPlayer())
{
- if(IsUsingHead())
- ADD_MESSAGE("%s screams: \"I'll do you for that! I'll bite your legs off!\"", CHAR_DESCRIPTION(DEFINITE));
- else if(!(RAND() % 5))
- switch(RAND() % 3)
+ if(!(GetConfig() == MASTER))
+ {
+ if(IsUsingHead())
+ ADD_MESSAGE("%s screams: \"I'll do you for that! I'll bite your legs off!\"", CHAR_DESCRIPTION(DEFINITE));
+ else if(!(RAND() % 5))
+ switch(RAND() % 3)
+ {
+ case 0:
+ ADD_MESSAGE("%s states calmly: \"'Tis but a scratch.\"", CHAR_DESCRIPTION(DEFINITE)); break;
+ case 1:
+ ADD_MESSAGE("%s states calmly: \"Just a flesh wound.\"", CHAR_DESCRIPTION(DEFINITE)); break;
+ case 2:
+ ADD_MESSAGE("%s shouts: \"I'm invincible!\"", CHAR_DESCRIPTION(DEFINITE)); break;
+ }
+ }
+ else if((GetConfig() == MASTER) && HasHead())
+ {
+ character* Called = 0;
+ Called = darkknight::Spawn(ELITE);
+ Called->SetTeam(GetTeam());
+ Called->PutNear(GetPos());
+ Called->SignalGeneration();
+
+ if(CanBeSeenByPlayer())
{
- case 0:
- ADD_MESSAGE("%s states calmly: \"'Tis but a scratch.\"", CHAR_DESCRIPTION(DEFINITE)); break;
- case 1:
- ADD_MESSAGE("%s states calmly: \"Just a flesh wound.\"", CHAR_DESCRIPTION(DEFINITE)); break;
- case 2:
- ADD_MESSAGE("%s shouts: \"I'm invincible!\"", CHAR_DESCRIPTION(DEFINITE)); break;
+ ADD_MESSAGE("%s screams a profane incantation to Infuscor before disappearing.", CHAR_NAME(DEFINITE));
+ TeleportRandomly(true);
}
+ if(Called->CanBeSeenByPlayer())
+ ADD_MESSAGE("The whole area trembles terribly as %s emerges from the shadows.", Called->CHAR_NAME(INDEFINITE));
+ }
+ else
+ ADD_MESSAGE("You feel the sudden presence of a violent enemy nearby.");
}
}
@@ -5109,43 +5524,17 @@ void archangel::CreateInitialEquipment(int SpecialFlags)
{
humanoid::CreateInitialEquipment(SpecialFlags);
GetStack()->AddItem(holybook::Spawn(GetConfig(), SpecialFlags));
- armor* Equipment;
- meleeweapon* Weapon;
switch(GetMasterGod()->GetBasicAlignment())
{
case GOOD:
- Weapon = flamingsword::Spawn(0, SpecialFlags|NO_MATERIALS);
- Weapon->InitMaterials(MAKE_MATERIAL(DIAMOND), MAKE_MATERIAL(ADAMANT), !(SpecialFlags & NO_PIC_UPDATE));
- Weapon->SetEnchantment(4);
- SetRightWielded(Weapon);
- Equipment = shield::Spawn(0, SpecialFlags|NO_MATERIALS);
- Equipment->InitMaterials(MAKE_MATERIAL(DIAMOND), !(SpecialFlags & NO_PIC_UPDATE));
- Equipment->SetEnchantment(4);
- SetLeftWielded(Equipment);
- GetCWeaponSkill(LARGE_SWORDS)->AddHit(200000);
- GetCWeaponSkill(SHIELDS)->AddHit(500000);
- GetCurrentRightSWeaponSkill()->AddHit(200000);
- GetCurrentLeftSWeaponSkill()->AddHit(200000);
GetRightArm()->SetDexterity(70);
GetLeftArm()->SetDexterity(70);
break;
case NEUTRAL:
- Weapon = meleeweapon::Spawn(WAR_HAMMER, SpecialFlags|NO_MATERIALS);
- Weapon->InitMaterials(MAKE_MATERIAL(SAPPHIRE), MAKE_MATERIAL(OCTIRON), !(SpecialFlags & NO_PIC_UPDATE));
- Weapon->SetEnchantment(4);
- SetRightWielded(Weapon);
- GetCWeaponSkill(BLUNT_WEAPONS)->AddHit(500000);
- GetCurrentRightSWeaponSkill()->AddHit(200000);
SetEndurance(70);
break;
case EVIL:
- Weapon = meleeweapon::Spawn(HALBERD, SpecialFlags|NO_MATERIALS);
- Weapon->InitMaterials(MAKE_MATERIAL(RUBY), MAKE_MATERIAL(OCTIRON), !(SpecialFlags & NO_PIC_UPDATE));
- Weapon->SetEnchantment(4);
- SetLeftWielded(Weapon);
- GetCWeaponSkill(POLE_ARMS)->AddHit(500000);
- GetCurrentLeftSWeaponSkill()->AddHit(500000);
GetRightArm()->SetStrength(70);
GetLeftArm()->SetStrength(70);
}
@@ -5157,6 +5546,18 @@ void zombie::PostConstruct()
GainIntrinsic(LEPROSY);
}
+truth orc::MoveRandomly()
+{
+ if(GetConfig() == REPRESENTATIVE)
+ {
+ return MoveRandomlyInRoom();
+ }
+ else
+ {
+ return humanoid::MoveRandomly();
+ }
+}
+
void orc::PostConstruct()
{
if(!RAND_N(25))
@@ -5394,6 +5795,65 @@ void oree::CallForMonsters()
delete ToBeCalled;
}
+void priest::GetAICommand()
+{
+ if(GetConfig() == INFUSCOR)
+ {
+ if(!RAND_N(50))
+ CallForMonsters();
+ }
+
+ StandIdleAI();
+}
+
+void priest::CallForMonsters()
+{
+ if(GetDungeon()->GetIndex() != XINROCH_TOMB || GetLevel()->GetIndex() != NECRO_CHAMBER_LEVEL)
+ return;
+
+ character* ToBeCalled = 0;
+
+ switch(RAND_N(6))
+ {
+ case 0:
+ ToBeCalled = skeleton::Spawn(RAND_2 ? 0 : WARRIOR);
+ break;
+ case 1:
+ ToBeCalled = zombie::Spawn();
+ break;
+ case 2:
+ ToBeCalled = frog::Spawn(DARK);
+ break;
+ case 3:
+ ToBeCalled = skeleton::Spawn(RAND_2 ? 0 : WARRIOR);
+ break;
+ case 4:
+ ToBeCalled = zombie::Spawn();
+ break;
+ case 5:
+ ToBeCalled = necromancer::Spawn(RAND_2 ? APPRENTICE_NECROMANCER : MASTER_NECROMANCER);
+ break;
+ }
+
+ v2 TryToCreate;
+
+ for(int c = 0; c < 100; ++c)
+ {
+ TryToCreate = game::GetMonsterPortal()->GetPos() + game::GetMoveVector(RAND() % DIRECTION_COMMAND_KEYS);
+
+ if(GetArea()->IsValidPos(TryToCreate)
+ && ToBeCalled->CanMoveOn(GetNearLSquare(TryToCreate))
+ && ToBeCalled->IsFreeForMe(GetNearLSquare(TryToCreate)))
+ {
+ ToBeCalled->SetTeam(game::GetTeam(MONSTER_TEAM));
+ ToBeCalled->PutTo(TryToCreate);
+ return;
+ }
+ }
+
+ delete ToBeCalled;
+}
+
int humanoid::RandomizeTryToUnStickBodyPart(ulong PossibleBodyParts) const
{
int Possible = 0, PossibleArray[3];
@@ -5498,6 +5958,12 @@ truth humanoid::BrainsHurt() const
return !Head || Head->IsBadlyHurt();
}
+truth humanoid::IsHeadless() const
+{
+ head* Head = GetHead();
+ return !Head;
+}
+
void playerkind::PostConstruct()
{
int R = 0, G = 0, B = 0;
@@ -5756,6 +6222,18 @@ void siren::GetAICommand()
humanoid::GetAICommand();
}
+truth siren::MoveRandomly()
+{
+ if(GetConfig() == AMBASSADOR_SIREN)
+ {
+ return MoveRandomlyInRoom();
+ }
+ else
+ {
+ return humanoid::MoveRandomly();
+ }
+}
+
truth siren::TryToSing()
{
truth Success = false;
@@ -5765,8 +6243,10 @@ truth siren::TryToSing()
if(Square && Square->GetCharacter())
{
- Success = true;
- Square->GetCharacter()->ReceiveSirenSong(this);
+ Success = Square->GetCharacter()->ReceiveSirenSong(this);
+
+ if(Success)
+ break;
}
}
if(Success)
@@ -5775,17 +6255,15 @@ truth siren::TryToSing()
return Success;
}
-truth humanoid::MindWormCanPenetrateSkull(mindworm* Worm) const
+truth humanoid::MindWormCanPenetrateSkull(mindworm*) const
{
if(GetHelmet())
{
- if(RAND_N(102) > GetHelmet()->GetCoverPercentile())
- {
- return RAND_2;
- }
+ if(RAND() % 100 < GetHelmet()->GetCoverPercentile())
+ return false;
}
- return RAND_2;
+ return true;
}
truth humanoid::HasSadistWeapon() const
@@ -5980,3 +6458,80 @@ void xinrochghost::CreateCorpse(lsquare* Square)
game::GetCurrentLevel()->GetLSquare(x, y)->ReceiveEarthQuakeDamage();
}
}
+
+truth darkknight::SpecialEnemySightedReaction(character*)
+{
+ if((GetConfig() == MASTER))
+ {
+ const database* WarLordDataBase;
+ databasecreator::FindDataBase(WarLordDataBase, &skeleton::ProtoType, WAR_LORD);
+ skeleton* Skeleton;
+
+ if(!(WarLordDataBase->Flags & HAS_BEEN_GENERATED) && !(RAND() % 5))
+ {
+ if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s invokes a spell!", CHAR_NAME(DEFINITE));
+
+ Skeleton = skeleton::Spawn(WAR_LORD);
+ Skeleton->SetTeam(GetTeam());
+ Skeleton->PutNear(GetPos());
+ Skeleton->SignalGeneration();
+
+ if(Skeleton->CanBeSeenByPlayer())
+ ADD_MESSAGE("The whole area trembles terribly as %s emerges from the ground.", Skeleton->CHAR_NAME(DEFINITE));
+ else if(CanBeSeenByPlayer())
+ ADD_MESSAGE("%s casts a powerful spell which makes the whole area tremble.", CHAR_NAME(DEFINITE));
+ else
+ ADD_MESSAGE("You feel the presence of an ancient evil being awakened from its long slumber. You shiver.");
+
+ Skeleton->SetGenerationDanger(GetGenerationDanger());
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+truth darkknight::CheckForUsefulItemsOnGround(truth CheckFood)
+{
+ if(GetConfig() == MASTER)
+ return false;
+ else
+ return character::CheckForUsefulItemsOnGround(CheckFood);
+}
+
+void goblin::GetAICommand()
+{
+ if(CheckAIZapOpportunity())
+ return;
+
+ humanoid::GetAICommand();
+}
+
+truth humanoid::CheckAIZapOpportunity()
+{
+ if(!HasAUsableArm() || !CanZap() || !(RAND() % 2) || StateIsActivated(CONFUSED))
+ return false;
+ else
+ return character::CheckAIZapOpportunity();
+}
+
+truth imp::SpecialBiteEffect(character* Victim, v2 HitPos, int BodyPartIndex, int Direction, truth BlockedByArmour, truth Critical, int DoneDamage)
+{
+ bodypart* BodyPart = Victim->GetBodyPart(BodyPartIndex);
+
+ if(BodyPart && BodyPart->IsDestroyable(Victim)
+ && BodyPart->GetMainMaterial() && BodyPart->CanBeBurned()
+ && (BodyPart->GetMainMaterial()->GetInteractionFlags() & CAN_BURN)
+ && !BodyPart->IsBurning())
+ {
+ if(BodyPart->TestActivationEnergy(150))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
diff --git a/Main/Source/iconf.cpp b/Main/Source/iconf.cpp
index 49f44a109..445ba9701 100644
--- a/Main/Source/iconf.cpp
+++ b/Main/Source/iconf.cpp
@@ -10,25 +10,40 @@
*
*/
-#include "iconf.h"
-#include "game.h"
-#include "feio.h"
#include "area.h"
-#include "graphics.h"
+#include "audio.h"
#include "bitmap.h"
+#include "feio.h"
+#include "felist.h"
+#include "game.h"
+#include "graphics.h"
+#include "iconf.h"
#include "igraph.h"
-#include "audio.h"
+#include "save.h"
+#include "stack.h"
+#include "whandler.h"
stringoption ivanconfig::DefaultName( "DefaultName",
"player's default name",
"",
&configsystem::NormalStringDisplayer,
&DefaultNameChangeInterface);
+stringoption ivanconfig::FantasyNamePattern("FantasyNamePattern",
+ "fantasy name generator pattern",
+ "!ss !sV",
+ &configsystem::NormalStringDisplayer,
+ &FantasyNameChangeInterface);
stringoption ivanconfig::DefaultPetName( "DefaultPetName",
"starting pet's default name",
CONST_S("Kenny"),
&configsystem::NormalStringDisplayer,
&DefaultPetNameChangeInterface);
+stringoption ivanconfig::SelectedBkgColor("SelectedBkgColor",
+ "selected list entry's highlight color",
+ "8,8,8",
+ &configsystem::NormalStringDisplayer,
+ &SelectedBkgColorChangeInterface,
+ &SelectedBkgColorChanger);
numberoption ivanconfig::AutoSaveInterval("AutoSaveInterval",
"autosave interval",
100,
@@ -42,6 +57,89 @@ scrollbaroption ivanconfig::Contrast( "Contrast",
&ContrastChangeInterface,
&ContrastChanger,
&ContrastHandler);
+cycleoption ivanconfig::HitIndicator( "HitIndicator",
+ "Show Hit",
+ 0, 5,
+ &HitIndicatorDisplayer);
+cycleoption ivanconfig::HoldPosMaxDist( "HoldPosMaxDist",
+ "Pet will wait near the last position", // if pet is set to not follow, will move away max the specified distance. if it loses the player, will stay near the last position it moves to trying to follow the player.
+ 0, 7,
+ &HoldPosMaxDistDisplayer);
+cycleoption ivanconfig::ShowItemsAtPlayerSquare("ShowItemsAtPlayerSquare",
+ "Show items at player square",
+ 0, 12,
+ &ShowItemsAtPlayerSquareDisplayer,
+ &configsystem::NormalCycleChangeInterface,
+ &ShowItemsAtPlayerSquareChanger);
+cycleoption ivanconfig::ShowMap( "ShowMap",
+ "Map preferences",
+ 0, 5,
+ &ShowMapDisplayer);
+cycleoption ivanconfig::RotateTimesPerSquare("RotateTimesPerSquare",
+ "Thrown weapons rotate times per square",
+ 0, 6,
+ &RotateTimesPerSquareDisplayer);
+numberoption ivanconfig::WindowWidth( "WindowWidth",
+ "* window width in pixels, min 800",
+ 800,
+ &WindowWidthDisplayer,
+ &WindowWidthChangeInterface,
+ &WindowWidthChanger);
+numberoption ivanconfig::WindowHeight( "WindowHeight",
+ "* window height in pixels, min 600",
+ 600,
+ &WindowHeightDisplayer,
+ &WindowHeightChangeInterface,
+ &WindowHeightChanger);
+numberoption ivanconfig::StackListPageLength("StackListPageLength",
+ "Page length in entries for non-selectable lists",
+ stack::GetDefaultPageLength(),
+ &StackListPageLengthDisplayer,
+ &StackListPageLengthChangeInterface,
+ &StackListPageLengthChanger);
+cycleoption ivanconfig::GoOnStopMode( "GoOnStopMode",
+ "Go stop mode",
+ 0, 4,
+ &GoOnStopModeDisplayer);
+numberoption ivanconfig::FrameSkip( "FrameSkip",
+ "FrameSkip to inc. input responsiveness",
+ 0,
+ &FrameSkipDisplayer,
+ &FrameSkipChangeInterface,
+ &FrameSkipChanger);
+truthoption ivanconfig::ShowMapAtDetectMaterial("ShowMapAtDetectMaterial",
+ "Show map while detecting material",
+ false);
+truthoption ivanconfig::AllowImportOldSavegame("AllowImportOldSavegame",
+ "Let old savegames (v131 up) be imported (experimental)",
+ false);
+truthoption ivanconfig::WaitNeutralsMoveAway("WaitNeutralsMoveAway",
+ "wait neutral NPCs move away from your path",
+ false);
+truthoption ivanconfig::SavegameSafely( "SavegameSafely",
+ "Safely save games",
+ false,
+ &configsystem::NormalTruthDisplayer,
+ &configsystem::NormalTruthChangeInterface,
+ &SavegameSafelyChanger);
+truthoption ivanconfig::GenerateDefinesValidator("GenerateDefinesValidator",
+ "generate validator and validate define.dat (may abort)",
+ false,
+ &configsystem::NormalTruthDisplayer,
+ &configsystem::NormalTruthChangeInterface,
+ &GenerateDefinesValidatorChanger);
+truthoption ivanconfig::HideWeirdHitAnimationsThatLookLikeMiss("HideWeirdHitAnimationsThatLookLikeMiss",
+ "Hide hit animations that look like miss",
+ true);
+truthoption ivanconfig::ShowFullDungeonName("ShowFullDungeonName",
+ "Show current dungeon's full name",
+ false);
+truthoption ivanconfig::ShowGodInfo( "ShowGodInfo",
+ "Shows info about each God when praying",
+ false);
+truthoption ivanconfig::CenterOnPlayerAfterLook("CenterOnPlayerAfterLook",
+ "Always center camera on player after look mode exits",
+ false);
truthoption ivanconfig::WarnAboutDanger( "WarnAboutVeryDangerousMonsters",
"Warn about very dangerous monsters",
true);
@@ -51,6 +149,51 @@ truthoption ivanconfig::AutoDropLeftOvers("AutoDropLeftOvers",
truthoption ivanconfig::LookZoom( "LookZoom",
"zoom feature in look mode",
false);
+truthoption ivanconfig::AltAdentureInfo( "AltAdentureInfo",
+ "on death, enhanced messages review mode",
+ false);
+cycleoption ivanconfig::MemorizeEquipmentMode("MemorizeEquipmentMode",
+ "NPCs restore equipped items after polymorph",
+ 0, 3,
+ &MemorizeEquipmentModeDisplayer);
+truthoption ivanconfig::XBRZScale( "XBRZScale",
+ "use xBRZScale to stretch graphics",
+ false,
+ &configsystem::NormalTruthDisplayer,
+ &configsystem::NormalTruthChangeInterface,
+ &XBRZScaleChanger);
+numberoption ivanconfig::XBRZSquaresAroundPlayer("XBRZSquaresAroundPlayer",
+ "Stretch squares around player with xBRZ (performance)",
+ 3,
+ &XBRZSquaresAroundPlayerDisplayer,
+ &XBRZSquaresAroundPlayerChangeInterface,
+ &XBRZSquaresAroundPlayerChanger);
+cycleoption ivanconfig::DungeonGfxScale( "DungeonGfxScale",
+ "* Select dungeon scale factor",
+ 1, 6, //from 1 to 6 (max xbrz) where 1 is no scale
+ &DungeonGfxScaleDisplayer,
+ &DungeonGfxScaleChangeInterface,
+ &DungeonGfxScaleChanger);
+cycleoption ivanconfig::SaveGameSortMode( "SaveGameSortMode",
+ "sort savegame files and show dungeon IDs progress",
+ 0, 4,
+ &SaveGameSortModeDisplayer,
+ &configsystem::NormalCycleChangeInterface,
+ &SaveGameSortModeChanger);
+cycleoption ivanconfig::SilhouetteScale( "SilhouetteScale",
+ "Silhouette scale factor (1 to disable)",
+ 1, 6, //from 1 to 6 (max xbrz) where 1 is no scale
+ &SilhouetteScaleDisplayer,
+ &SilhouetteScaleChangeInterface,
+ &SilhouetteScaleChanger);
+cycleoption ivanconfig::AltSilhouette( "AltSilhouette",
+ "Alternative silhouette mode",
+ 0, 7,
+ &AltSilhouetteDisplayer);
+cycleoption ivanconfig::AltSilhouettePreventColorGlitch("AltSilhouettePreventColorGlitch",
+ "Alternative silhouette background",
+ 2, 3,
+ &AltSilhouettePreventColorGlitchDisplayer);
cycleoption ivanconfig::DirectionKeyMap( "DirectionKeyMap",
"Movement control scheme",
DIR_NORM, 3, // {default value, number of options to cycle through}
@@ -61,7 +204,17 @@ truthoption ivanconfig::SmartOpenCloseApply("SmartOpenCloseApply",
truthoption ivanconfig::BeNice( "BeNice",
"be nice to pets",
true);
-scrollbaroption ivanconfig::Volume( "Volume",
+cycleoption ivanconfig::AltListItemPos( "AltListItemPos",
+ "Stretched list item alternative position",
+ 0, 3,
+ &AltListItemPosDisplayer);
+numberoption ivanconfig::AltListItemWidth("AltListItemWidth",
+ "List width for 'item alternative position'",
+ game::getDefaultItemsListWidth(),
+ &AltListItemWidthDisplayer,
+ &AltListItemWidthChangeInterface,
+ &AltListItemWidthChanger);
+scrollbaroption ivanconfig::Volume( "Volume",
"volume",
127,
&VolumeDisplayer,
@@ -73,18 +226,163 @@ cycleoption ivanconfig::MIDIOutputDevice( "MIDIOutputDevice",
0, 0, // {default value, number of options to cycle through}
&MIDIOutputDeviceDisplayer);
#ifndef __DJGPP__
+cycleoption ivanconfig::GraphicsScale( "GraphicsScale",
+ "select window scale factor",
+ 1, 2,
+ &GraphicsScaleDisplayer,
+ &GraphicsScaleChangeInterface,
+ &GraphicsScaleChanger);
truthoption ivanconfig::FullScreenMode( "FullScreenMode",
"run the game in full screen mode",
false,
&configsystem::NormalTruthDisplayer,
&configsystem::NormalTruthChangeInterface,
&FullScreenModeChanger);
+cycleoption ivanconfig::ScalingQuality( "ScalingQuality",
+ "* scaling quality",
+ 0, 2,
+ &ScalingQualityDisplayer);
#endif
col24 ivanconfig::ContrastLuminance = NORMAL_LUMINANCE;
+truthoption ivanconfig::PlaySounds( "PlaySounds",
+ "use sound effects",
+ true);
+truthoption ivanconfig::ShowTurn( "ShowTurn",
+ "show the turn on log messages",
+ false);
+truthoption ivanconfig::OutlinedGfx( "OutlinedGfx",
+ "* Outlined graphics",
+ false);
v2 ivanconfig::GetQuestionPos() { return game::IsRunning() ? v2(16, 6) : v2(30, 30); }
void ivanconfig::BackGroundDrawer() { game::DrawEverythingNoBlit(); }
+void ivanconfig::XBRZSquaresAroundPlayerDisplayer(const numberoption* O, festring& Entry)
+{
+ Entry << O->Value << " squares";
+}
+
+void ivanconfig::AltListItemWidthDisplayer(const numberoption* O, festring& Entry)
+{
+ Entry << O->Value << " pixels";
+}
+
+void ivanconfig::FrameSkipDisplayer(const numberoption* O, festring& Entry)
+{
+ Entry << O->Value;
+ if(O->Value==-2)Entry << " = wait" ;
+ if(O->Value==-1)Entry << " = auto" ;
+ if(O->Value>= 0)Entry << " frames";
+}
+
+void ivanconfig::StackListPageLengthDisplayer(const numberoption* O, festring& Entry)
+{
+ Entry << O->Value << " entries";
+}
+
+void ivanconfig::WindowHeightDisplayer(const numberoption* O, festring& Entry)
+{
+ Entry << O->Value << " pixels";
+}
+
+void ivanconfig::AltSilhouettePreventColorGlitchDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0: Entry << "transparent";break;
+ case 1: Entry << "dark";break;
+ case 2: Entry << "alignment";break;
+ }
+}
+
+void ivanconfig::RotateTimesPerSquareDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0: Entry << "disabled";break;
+ case 1: Entry << "x1";break;
+ case 2: Entry << "x2";break;
+ case 3: Entry << "x3";break;
+ case 4: Entry << "x4";break;
+ case 5: Entry << "dynamic";break;
+ }
+}
+
+void ivanconfig::HoldPosMaxDistDisplayer(const cycleoption* O, festring& Entry)
+{
+ if(O->Value>0)
+ Entry << O->Value << " squares";
+ else
+ Entry << "disabled";
+}
+
+void ivanconfig::HitIndicatorDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0: Entry << "disabled";break;
+ case 1: Entry << "immersive";break;
+ case 2: Entry << "indicator";break;
+ case 3: Entry << "ind+color";break;
+ case 4: Entry << "dynamic";break;
+ }
+}
+
+void ivanconfig::GoOnStopModeDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0:Entry << "everything";break;
+ case 1:Entry << "ignore useless";break;
+ case 2:Entry << "ignore cheap";break;
+ case 3:Entry << "ignore encumbering";break;
+ }
+}
+
+void ivanconfig::ShowMapDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0:Entry << "vanilla";break; //mmm... just not using xBRZ
+ case 1:Entry << "xBRZ";break;
+ case 2:Entry << "imersive";break;
+ case 3:Entry << "imersive2";break;
+ case 4:Entry << "imersive3";break;
+ }
+}
+
+void ivanconfig::ShowItemsAtPlayerSquareDisplayer(const cycleoption* O, festring& Entry)
+{
+ if(O->Value>=10){
+ Entry << "Use corners if NPC";
+ if(O->Value==11)Entry << "+Items";
+ Entry << " above";
+ return;
+ }
+
+ int iCode = game::ItemUnderCode(O->Value);
+
+ if(iCode==0){
+ Entry << "disabled";
+ }else
+ if(iCode==1){
+ Entry << "above head";
+ }else{
+ switch(game::ItemUnderCorner(iCode)){
+ case 0:Entry << "UL";break;
+ case 1:Entry << "UR";break;
+ case 2:Entry << "LL";break;
+ case 3:Entry << "LR";break;
+ }
+
+// Entry << ",";
+// Entry << "x" << game::ItemUnderZoom(O->Value);
+
+ Entry << ",";
+ Entry << (game::ItemUnderHV(iCode) ? "H" : "V");
+ }
+}
+
+void ivanconfig::WindowWidthDisplayer(const numberoption* O, festring& Entry)
+{
+ Entry << O->Value << " pixels";
+}
+
void ivanconfig::AutoSaveIntervalDisplayer(const numberoption* O, festring& Entry)
{
if(O->Value)
@@ -108,6 +406,19 @@ void ivanconfig::VolumeDisplayer(const numberoption* O, festring& Entry)
Entry << O->Value << "/127";
}
+void ivanconfig::AltSilhouetteDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0: Entry << "no" ; break;
+ case 1: Entry << "short" ; break;
+ case 2: Entry << "tall" ; break;
+ case 3: Entry << "breathing" ; break;
+ case 4: Entry << "breathSlower"; break;
+ case 5: Entry << "breathSlower+"; break;
+ case 6: Entry << "breathSlower++"; break;
+ }
+}
+
void ivanconfig::DirectionKeyMapDisplayer(const cycleoption* O, festring& Entry)
{
switch(O->Value)
@@ -130,7 +441,7 @@ void ivanconfig::MIDIOutputDeviceDisplayer(const cycleoption* O, festring& Entry
int NumDevices = audio::GetMIDIOutputDevices(devicenames);
MIDIOutputDevice.CycleCount = NumDevices+1;
- if( O->Value && devicenames.size() )
+ if(O->Value && O->Value <= devicenames.size())
{
const char *cstr = devicenames[O->Value - 1].c_str();
Entry << cstr;
@@ -145,6 +456,48 @@ void ivanconfig::MIDIOutputDeviceDisplayer(const cycleoption* O, festring& Entry
}
}
+void clearToBackgroundAfterChangeInterface(){
+ if(game::IsRunning())
+ igraph::BlitBackGround(
+ v2(16,6),
+ v2(game::GetMaxScreenXSize() << 4, 23)
+ );
+}
+
+truth ivanconfig::GraphicsScaleChangeInterface(cycleoption* O)
+{
+ O->ChangeValue(O->Value % O->CycleCount + 1);
+ clearToBackgroundAfterChangeInterface();
+ return true;
+}
+
+truth ivanconfig::SilhouetteScaleChangeInterface(cycleoption* O)
+{
+ O->ChangeValue(O->Value % O->CycleCount + 1);
+ clearToBackgroundAfterChangeInterface();
+ return true;
+}
+
+truth ivanconfig::DungeonGfxScaleChangeInterface(cycleoption* O)
+{
+ O->ChangeValue(O->Value % O->CycleCount + 1);
+ clearToBackgroundAfterChangeInterface();
+ return true;
+}
+
+truth ivanconfig::FantasyNameChangeInterface(stringoption* O)
+{
+ festring String;
+
+ if(iosystem::StringQuestion(String, CONST_S("Set name generator pattern (recommended \"!ss !sV\"):"),
+ GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
+ O->ChangeValue(String);
+
+ clearToBackgroundAfterChangeInterface();
+
+ return false;
+}
+
truth ivanconfig::DefaultNameChangeInterface(stringoption* O)
{
festring String;
@@ -153,8 +506,20 @@ truth ivanconfig::DefaultNameChangeInterface(stringoption* O)
GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
O->ChangeValue(String);
- if(game::IsRunning())
- igraph::BlitBackGround(v2(16, 6), v2(game::GetScreenXSize() << 4, 23));
+ clearToBackgroundAfterChangeInterface();
+
+ return false;
+}
+
+truth ivanconfig::SelectedBkgColorChangeInterface(stringoption* O)
+{
+ festring String;
+
+ if(iosystem::StringQuestion(String, CONST_S("Set new Red,Green,Blue color (8 to 200 each value) or empty to disable:"),
+ GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
+ O->ChangeValue(String);
+
+ clearToBackgroundAfterChangeInterface();
return false;
}
@@ -167,9 +532,56 @@ truth ivanconfig::DefaultPetNameChangeInterface(stringoption* O)
GetQuestionPos(), WHITE, 0, 20, !game::IsRunning(), true) == NORMAL_EXIT)
O->ChangeValue(String);
- if(game::IsRunning())
- igraph::BlitBackGround(v2(16, 6), v2(game::GetScreenXSize() << 4, 23));
+ clearToBackgroundAfterChangeInterface();
+
+ return false;
+}
+truth ivanconfig::XBRZSquaresAroundPlayerChangeInterface(numberoption* O)
+{
+ O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set how many squares around player to xBRZ (0=FullDungeon):"),
+ GetQuestionPos(), WHITE, !game::IsRunning()));
+ clearToBackgroundAfterChangeInterface();
+ return false;
+}
+
+truth ivanconfig::AltListItemWidthChangeInterface(numberoption* O)
+{
+ O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new item's list width to fit well with other elements:"),
+ GetQuestionPos(), WHITE, !game::IsRunning()));
+ clearToBackgroundAfterChangeInterface();
+ return false;
+}
+
+truth ivanconfig::FrameSkipChangeInterface(numberoption* O)
+{
+ O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set frame skip to let controls/input work better (-2=wait,-1=auto,0to100):"),
+ GetQuestionPos(), WHITE, !game::IsRunning()));
+ clearToBackgroundAfterChangeInterface();
+ return false;
+}
+
+truth ivanconfig::StackListPageLengthChangeInterface(numberoption* O)
+{
+ O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new stack list page's length in entries:"),
+ GetQuestionPos(), WHITE, !game::IsRunning()));
+ clearToBackgroundAfterChangeInterface();
+ return false;
+}
+
+truth ivanconfig::WindowHeightChangeInterface(numberoption* O)
+{
+ O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new window height (from 600 to your monitor screen max width):"),
+ GetQuestionPos(), WHITE, !game::IsRunning()));
+ clearToBackgroundAfterChangeInterface();
+ return false;
+}
+
+truth ivanconfig::WindowWidthChangeInterface(numberoption* O)
+{
+ O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new window width (from 800 to your monitor screen max width):"),
+ GetQuestionPos(), WHITE, !game::IsRunning()));
+ clearToBackgroundAfterChangeInterface();
return false;
}
@@ -178,8 +590,7 @@ truth ivanconfig::AutoSaveIntervalChangeInterface(numberoption* O)
O->ChangeValue(iosystem::NumberQuestion(CONST_S("Set new autosave interval (1-50000 turns, 0 for never):"),
GetQuestionPos(), WHITE, !game::IsRunning()));
- if(game::IsRunning())
- igraph::BlitBackGround(v2(16, 6), v2(game::GetScreenXSize() << 4, 23));
+ clearToBackgroundAfterChangeInterface();
return false;
}
@@ -191,8 +602,7 @@ truth ivanconfig::ContrastChangeInterface(numberoption* O)
game::GetMoveCommandKey(KEY_LEFT_INDEX), game::GetMoveCommandKey(KEY_RIGHT_INDEX),
!game::IsRunning(), static_cast(O)->BarHandler);
- if(game::IsRunning())
- igraph::BlitBackGround(v2(16, 6), v2(game::GetScreenXSize() << 4, 23));
+ clearToBackgroundAfterChangeInterface();
return false;
}
@@ -204,12 +614,99 @@ truth ivanconfig::VolumeChangeInterface(numberoption* O)
game::GetMoveCommandKey(KEY_LEFT_INDEX), game::GetMoveCommandKey(KEY_RIGHT_INDEX),
!game::IsRunning(), static_cast(O)->BarHandler);
- if(game::IsRunning())
- igraph::BlitBackGround(v2(16, 6), v2(game::GetScreenXSize() << 4, 23));
+ clearToBackgroundAfterChangeInterface();
return false;
}
+void ivanconfig::XBRZSquaresAroundPlayerChanger(numberoption* O, long What)
+{
+ if(What < 0) What = 0;
+ O->Value = What;
+}
+
+void ivanconfig::AltListItemWidthChanger(numberoption* O, long What)
+{
+ if(What < 400) What = 400; //TODO find the best quality minimum value
+ O->Value = What;
+}
+
+void ivanconfig::FrameSkipChanger(numberoption* O, long What)
+{
+ if(What < -2) What = -2;
+ if(What > 100) What = 100;
+
+ if(O!=NULL)O->Value = What;
+
+ globalwindowhandler::SetAddFrameSkip(What);
+}
+
+void ivanconfig::StackListPageLengthChanger(numberoption* O, long What)
+{
+ if(What < stack::GetDefaultPageLength()) What = stack::GetDefaultPageLength();
+ if(O!=NULL)O->Value = What;
+
+ stack::SetStandardPageLength(What);
+}
+
+void ivanconfig::WindowHeightChanger(numberoption* O, long What)
+{
+ if(What < 600) What = 600;
+ O->Value = What;
+}
+
+void ivanconfig::ShowItemsAtPlayerSquareChanger(cycleoption* O, long What)
+{
+// if(What==1 && GetStartingDungeonGfxScale()<3){ //above head asked
+// What=2; //upgrade to 1st corner
+// }
+
+ O->Value = What;
+}
+
+void ivanconfig::WindowWidthChanger(numberoption* O, long What)
+{
+ if(What < 800) What = 800;
+ O->Value = What;
+}
+
+void ivanconfig::SelectedBkgColorChanger(stringoption* O, cfestring& What)
+{
+ if(What.GetSize()>0){
+ int RGB[3]={1,1,1}, j=0;
+ std::string sC;
+ for(int i=0;i=0x30 && What[i]<=0x39) //0-9
+ sC+=What[i];
+ else{
+ if(What[i]!=',') //wrong usage detected
+ return;
+ }
+
+ if(What[i]==',' || i==What.GetSize()-1){
+ RGB[j]=std::stol(sC);
+ if(RGB[j]<8)return; //0,0,0 makes xBRZ not work well. 8,8,8 is min to have col16 not 0,0,0 (it is less bits than col24 per component)
+ if(RGB[j]>200)return; //if all too high will prevent reading white text
+ j++;
+ sC="";
+ }
+ }
+
+ if(j!=3)return; //wrong usage detected
+
+ felist::SetSelectedBkgColor(MakeRGB16(RGB[0],RGB[1],RGB[2]));
+ }else{
+ felist::SetSelectedBkgColor(TRANSPARENT_COLOR);
+ }
+
+ if(O!=NULL){
+ O->Value.Empty();
+ O->Value< 200) What = 200;
O->Value = What;
+
CalculateContrastLuminance();
}
@@ -236,16 +734,114 @@ void ivanconfig::VolumeChanger(numberoption* O, long What)
#ifndef __DJGPP__
+void ivanconfig::GraphicsScaleDisplayer(const cycleoption* O, festring& Entry)
+{
+ Entry << O->Value << 'x';
+}
+
+void ivanconfig::GraphicsScaleChanger(cycleoption* O, long What)
+{
+ O->Value = What;
+ graphics::SetScale(What);
+}
+
+void ivanconfig::SilhouetteScaleDisplayer(const cycleoption* O, festring& Entry)
+{
+ Entry << O->Value << 'x';
+}
+
+void ivanconfig::AltListItemPosDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0:Entry << "disabled";break; //do not show
+ case 1:Entry << "no";break; //default pos
+ case 2:Entry << "yes";break; //alt pos
+ }
+}
+
+void ivanconfig::SaveGameSortModeDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0: Entry << "newest first";break;
+ case 1: Entry << "newest first + progress";break;
+ case 2: Entry << "alphanumeric";break;
+ case 3: Entry << "alphanumeric + progress";break;
+ }
+}
+
+void ivanconfig::MemorizeEquipmentModeDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0:Entry << "disabled";break; //do not show
+ case 1:Entry << "only pet";break; //default pos
+ case 2:Entry << "everyone";break; //alt pos
+ }
+}
+
+void ivanconfig::DungeonGfxScaleDisplayer(const cycleoption* O, festring& Entry)
+{
+ Entry << O->Value << 'x';
+}
+
+void ivanconfig::SilhouetteScaleChanger(cycleoption* O, long What)
+{
+ O->Value = What;
+}
+
+void ivanconfig::SaveGameSortModeChanger(cycleoption* O, long What)
+{
+ if(O!=NULL)O->Value = What;
+
+ iosystem::SetSaveGameSortMode(What);
+}
+
+void ivanconfig::DungeonGfxScaleChanger(cycleoption* O, long What)
+{
+ O->Value = What;
+}
+
+void ivanconfig::GenerateDefinesValidatorChanger(truthoption* O, truth What)
+{
+ if(O!=NULL)O->Value = What;
+
+ if(What)
+ game::GenerateDefinesValidator(true); //TODO make validation (that aborts) optional using cycleoption
+}
+
+void ivanconfig::SavegameSafelyChanger(truthoption* O, truth What)
+{
+ if(O!=NULL)O->Value = What;
+
+ outputfile::SetSafeSaving(What);
+}
+
+void ivanconfig::XBRZScaleChanger(truthoption* O, truth What)
+{
+ O->Value = What;
+
+ game::UpdateSRegionsXBRZ();
+}
+
void ivanconfig::FullScreenModeChanger(truthoption*, truth)
{
graphics::SwitchMode();
}
+void ivanconfig::ScalingQualityDisplayer(const cycleoption* O, festring& Entry)
+{
+ switch(O->Value){
+ case 0: Entry << "pixelated"; break;
+ case 1: Entry << "smooth"; break;
+ }
+}
+
#endif
void ivanconfig::Show()
{
+ game::SRegionAroundDeny();
configsystem::Show(&BackGroundDrawer, &game::SetStandardListAttributes, game::IsRunning());
+ game::SRegionAroundAllow();
}
void ivanconfig::ContrastHandler(long Value)
@@ -286,19 +882,68 @@ void ivanconfig::CalculateContrastLuminance()
ContrastLuminance = MakeRGB24(Element, Element, Element);
}
+// TODO keep initializing with invalid values (where possible) so if they are used before cfg file loading it will show errors clearly?
+int ivanconfig::iStartingWindowWidth=-1;
+int ivanconfig::iStartingWindowHeight=-1;
+int ivanconfig::iStartingDungeonGfxScale=-1;
+bool ivanconfig::bStartingOutlinedGfx=false;
void ivanconfig::Initialize()
{
- configsystem::AddOption(&DefaultName);
- configsystem::AddOption(&DefaultPetName);
- configsystem::AddOption(&AutoSaveInterval);
- configsystem::AddOption(&Contrast);
- configsystem::AddOption(&WarnAboutDanger);
- configsystem::AddOption(&AutoDropLeftOvers);
- configsystem::AddOption(&LookZoom);
- configsystem::AddOption(&DirectionKeyMap);
- configsystem::AddOption(&SmartOpenCloseApply);
- configsystem::AddOption(&BeNice);
- configsystem::AddOption(&Volume);
+ festring fsCategory;
+
+ fsCategory="Core Game Setup";
+ configsystem::AddOption(fsCategory,&DefaultName);
+ configsystem::AddOption(fsCategory,&FantasyNamePattern);
+ configsystem::AddOption(fsCategory,&DefaultPetName);
+ configsystem::AddOption(fsCategory,&AutoSaveInterval);
+ configsystem::AddOption(fsCategory,&AltAdentureInfo);
+
+ fsCategory="Gameplay Changes";
+ configsystem::AddOption(fsCategory,&BeNice);
+ configsystem::AddOption(fsCategory,&HoldPosMaxDist);
+ configsystem::AddOption(fsCategory,&MemorizeEquipmentMode);
+ configsystem::AddOption(fsCategory,&WarnAboutDanger);
+ configsystem::AddOption(fsCategory,&AutoDropLeftOvers);
+ configsystem::AddOption(fsCategory,&SmartOpenCloseApply);
+ configsystem::AddOption(fsCategory,&CenterOnPlayerAfterLook);
+ configsystem::AddOption(fsCategory,&ShowGodInfo); //gameplay change in a sense that, to remember what each god is about may be a challenge on itself :)
+ configsystem::AddOption(fsCategory,&ShowMapAtDetectMaterial);
+ configsystem::AddOption(fsCategory,&GoOnStopMode);
+ configsystem::AddOption(fsCategory,&WaitNeutralsMoveAway);
+
+ fsCategory="Window";
+ configsystem::AddOption(fsCategory,&Contrast);
+ configsystem::AddOption(fsCategory,&WindowWidth);
+ configsystem::AddOption(fsCategory,&WindowHeight);
+#ifndef __DJGPP__
+ configsystem::AddOption(fsCategory,&GraphicsScale);
+ configsystem::AddOption(fsCategory,&FullScreenMode);
+#endif
+
+ fsCategory="Graphics";
+#ifndef __DJGPP__
+ configsystem::AddOption(fsCategory,&ScalingQuality);
+#endif
+ configsystem::AddOption(fsCategory,&LookZoom);
+ configsystem::AddOption(fsCategory,&XBRZScale);
+ configsystem::AddOption(fsCategory,&XBRZSquaresAroundPlayer);
+ configsystem::AddOption(fsCategory,&SilhouetteScale);
+ configsystem::AddOption(fsCategory,&AltSilhouette);
+ configsystem::AddOption(fsCategory,&AltSilhouettePreventColorGlitch);
+ configsystem::AddOption(fsCategory,&AltListItemPos);
+ configsystem::AddOption(fsCategory,&AltListItemWidth);
+ configsystem::AddOption(fsCategory,&StackListPageLength);
+ configsystem::AddOption(fsCategory,&DungeonGfxScale);
+ configsystem::AddOption(fsCategory,&OutlinedGfx);
+ configsystem::AddOption(fsCategory,&FrameSkip);
+ configsystem::AddOption(fsCategory,&ShowItemsAtPlayerSquare);
+ configsystem::AddOption(fsCategory,&RotateTimesPerSquare);
+ configsystem::AddOption(fsCategory,&HitIndicator);
+ configsystem::AddOption(fsCategory,&ShowMap);
+
+ fsCategory="Sounds";
+ configsystem::AddOption(fsCategory,&PlaySounds);
+ configsystem::AddOption(fsCategory,&Volume);
std::vector DeviceNames;
int NumDevices = audio::GetMIDIOutputDevices(DeviceNames);
@@ -309,18 +954,45 @@ void ivanconfig::Initialize()
}
MIDIOutputDevice.CycleCount = NumDevices+1;
- configsystem::AddOption(&MIDIOutputDevice);
-#ifndef __DJGPP__
- configsystem::AddOption(&FullScreenMode);
-#endif
+ configsystem::AddOption(fsCategory,&MIDIOutputDevice);
+
+ fsCategory="System and user interface/input";
+ configsystem::AddOption(fsCategory,&DirectionKeyMap);
+ configsystem::AddOption(fsCategory,&SaveGameSortMode);
+ configsystem::AddOption(fsCategory,&ShowTurn);
+ configsystem::AddOption(fsCategory,&ShowFullDungeonName);
+ configsystem::AddOption(fsCategory,&SelectedBkgColor);
+
+ fsCategory="Advanced/Developer options";
+ configsystem::AddOption(fsCategory,&AllowImportOldSavegame);
+ configsystem::AddOption(fsCategory,&SavegameSafely);
+ configsystem::AddOption(fsCategory,&HideWeirdHitAnimationsThatLookLikeMiss);
+ configsystem::AddOption(fsCategory,&GenerateDefinesValidator);
+
+ /********************************
+ * LOAD AND APPLY some SETTINGS *
+ ********************************/
#if defined(WIN32) || defined(__DJGPP__)
configsystem::SetConfigFileName(game::GetHomeDir() + "ivan.cfg");
#else
configsystem::SetConfigFileName(game::GetHomeDir() + "ivan.conf");
#endif
+
configsystem::Load();
+
+ iStartingWindowWidth = WindowWidth.Value;
+ iStartingWindowHeight = WindowHeight.Value;
+ iStartingDungeonGfxScale = DungeonGfxScale.Value;
+ bStartingOutlinedGfx = OutlinedGfx.Value;
+
CalculateContrastLuminance();
audio::ChangeMIDIOutputDevice(MIDIOutputDevice.Value);
audio::SetVolumeLevel(Volume.Value);
+ //TODO re-use changer methods for above configs too to avoid duplicating the algo?
+ FrameSkipChanger(NULL,FrameSkip.Value);
+ StackListPageLengthChanger(NULL, StackListPageLength.Value);
+ SaveGameSortModeChanger(NULL, SaveGameSortMode.Value);
+ SavegameSafelyChanger(NULL, SavegameSafely.Value);
+ SelectedBkgColorChanger(NULL, SelectedBkgColor.Value);
}
diff --git a/Main/Source/igraph.cpp b/Main/Source/igraph.cpp
index 479829a14..eaa5eb95c 100644
--- a/Main/Source/igraph.cpp
+++ b/Main/Source/igraph.cpp
@@ -28,20 +28,20 @@ bitmap* igraph::TileBuffer;
bitmap* igraph::FlagBuffer;
cchar* igraph::RawGraphicFileName[] =
{
- "Graphics/GLTerra.pcx",
- "Graphics/OLTerra.pcx",
- "Graphics/Item.pcx",
- "Graphics/Char.pcx",
- "Graphics/Humanoid.pcx",
- "Graphics/Effect.pcx",
- "Graphics/Cursor.pcx"
+ "Graphics/GLTerra.png",
+ "Graphics/OLTerra.png",
+ "Graphics/Item.png",
+ "Graphics/Char.png",
+ "Graphics/Humanoid.png",
+ "Graphics/Effect.png",
+ "Graphics/Cursor.png"
};
cchar* igraph::GraphicFileName[] =
{
- "Graphics/WTerra.pcx",
- "Graphics/FOW.pcx",
- "Graphics/Symbol.pcx",
- "Graphics/Smiley.pcx"
+ "Graphics/WTerra.png",
+ "Graphics/FOW.png",
+ "Graphics/Symbol.png",
+ "Graphics/Smiley.png"
};
tilemap igraph::TileMap;
uchar igraph::RollBuffer[256];
@@ -60,6 +60,12 @@ int igraph::CurrentColorType = -1;
void igraph::Init()
{
+ if(ivanconfig::IsStartingOutlinedGfx()){
+ RawGraphicFileName[GR_ITEM]="Graphics/Item-outlined.png";
+ RawGraphicFileName[GR_CHARACTER]="Graphics/Char-outlined.png";
+ RawGraphicFileName[GR_HUMANOID]="Graphics/Humanoid-outlined.png";
+ }
+
static truth AlreadyInstalled = false;
if(!AlreadyInstalled)
@@ -68,15 +74,21 @@ void igraph::Init()
graphics::Init();
graphics::SetMode("IVAN " IVAN_VERSION,
festring(game::GetDataDir() + "Graphics/Icon.bmp").CStr(),
- v2(800, 600), ivanconfig::GetFullScreenMode());
+ v2(ivanconfig::GetStartingWindowWidth(), ivanconfig::GetStartingWindowHeight()),
+#ifndef __DJGPP__
+ ivanconfig::GetGraphicsScale(),
+ ivanconfig::GetScalingQuality(),
+#endif
+ ivanconfig::GetFullScreenMode());
DOUBLE_BUFFER->ClearToColor(0);
graphics::BlitDBToScreen();
#ifndef __DJGPP__
graphics::SetSwitchModeHandler(ivanconfig::SwitchModeHandler);
#endif
- graphics::LoadDefaultFont(game::GetDataDir() + "Graphics/Font.pcx");
+ graphics::LoadDefaultFont(game::GetDataDir() + "Graphics/Font.png");
FONT->CreateFontCache(WHITE);
FONT->CreateFontCache(LIGHT_GRAY);
+ felist::SetDefaultEntryImageSize(TILE_V2);
felist::CreateQuickDrawFontCaches(FONT, WHITE, 8);
felist::CreateQuickDrawFontCaches(FONT, LIGHT_GRAY, 8);
object::InitSparkleValidityArrays();
@@ -464,7 +476,7 @@ void igraph::CreateBodyBitmapValidityMaps()
void igraph::LoadMenu()
{
- Menu = new bitmap(game::GetDataDir() + "Graphics/Menu.pcx");
+ Menu = new bitmap(game::GetDataDir() + "Graphics/Menu.png");
}
void igraph::UnLoadMenu()
@@ -472,6 +484,41 @@ void igraph::UnLoadMenu()
delete Menu;
}
+#ifdef IMPORT_EXPORT_GFX //INCOMPLETE WORK. for (one day) load each gfx from independent files.
+bool isFileExist(const char *fileName) //TODO this should be more global
+{
+ DBG2("chkIfFileExist:",fileName);
+ std::ifstream fl(fileName);
+ bool b=fl.good(); //ifstream destructor will close the file
+ DBG2("chkIfFileExist:",b);
+ return b;
+}
+bool importGfx(festring fsFile,bitmap** ppbmpSC){
+ DBG2("importing:",fsFile.CStr());
+ (*ppbmpSC) = new bitmap(SILHOUETTE_SIZE, 0);
+ inputfile flIn(fsFile);
+ (*ppbmpSC)->Load(flIn);
+ flIn.Close();
+ DBG2("imported:",fsFile.CStr());
+
+ return true; //TODO make it sure the file load woked, catching errors and so on...
+}
+bool bExportGfx=false; //if ran at a readonly location, true will fail.
+void chkExportGfx(){
+ //TODO inform this env var in some kind of developer documentation (preferable in an existing one)
+ char* env=std::getenv("IVAN_EXPORTGFX"); DBG2("bExportGfx",env);
+
+ if(env!=NULL){
+ bExportGfx = strcmp(env,"true")==0; DBG2("bExportGfx",bExportGfx);
+ }
+
+}
+festring prepareFileName(const char* strName){
+ festring fs="";
+ return fs<(abs(Map[1024 - x][1024 - (RES.Y - y)]) / 30, 0, 100);
+// BackGround->PutPixel(x, y, GetBackGroundColor(E));
+// }
+//
+// delete [] Map;
+//}
void igraph::CreateBackGround(int ColorType)
{
if(CurrentColorType == ColorType)
@@ -513,15 +582,17 @@ void igraph::CreateBackGround(int ColorType)
CurrentColorType = ColorType;
delete BackGround;
BackGround = new bitmap(RES);
- int Side = 1025;
+ int base=1024; //TODO explain this: fractals require multiple of 1024 to work/workBetter?
+ while(ivanconfig::GetStartingWindowWidth()>base)base+=1024;
+ int Side = base+1;
int** Map;
- Alloc2D(Map, Side, Side);
- femath::GenerateFractalMap(Map, Side, Side - 1, 800);
+ Alloc2D(Map, Side, Side); //TODO confirm and explain this: it seems fractals work better on a squared img right?
+ femath::GenerateFractalMap(Map, Side, Side - 1, ivanconfig::GetStartingWindowWidth());
for(int x = 0; x < RES.X; ++x)
for(int y = 0; y < RES.Y; ++y)
{
- int E = Limit(abs(Map[1024 - x][1024 - (RES.Y - y)]) / 30, 0, 100);
+ int E = Limit(abs(Map[base - x][base - (RES.Y - y)]) / 30, 0, 100);
BackGround->PutPixel(x, y, GetBackGroundColor(E));
}
@@ -544,7 +615,12 @@ col16 igraph::GetBackGroundColor(int Element)
void igraph::BlitBackGround(v2 Pos, v2 Border)
{
- blitdata B = { DOUBLE_BUFFER,
+ BlitBackGround(DOUBLE_BUFFER, Pos, Border);
+}
+
+void igraph::BlitBackGround(bitmap* bmpAt, v2 Pos, v2 Border)
+{
+ blitdata B = { bmpAt,
{ Pos.X, Pos.Y },
{ Pos.X, Pos.Y },
{ Border.X, Border.Y },
diff --git a/Main/Source/item.cpp b/Main/Source/item.cpp
index a0afe553e..9e9cda51d 100644
--- a/Main/Source/item.cpp
+++ b/Main/Source/item.cpp
@@ -39,10 +39,10 @@ itemprototype::itemprototype(const itemprototype* Base, itemspawner Spawner, ite
truth itemdatabase::AllowRandomInstantiation() const { return !(Config & S_LOCK_ID); }
-item::item() : Slot(0), CloneMotherID(0), Fluid(0), LifeExpectancy(0), ItemFlags(0) { }
+item::item() : Slot(0), CloneMotherID(0), Fluid(0), LifeExpectancy(0), ItemFlags(0), iRotateFlyingThrownStep(0) { }
truth item::IsOnGround() const { return Slot[0]->IsOnGround(); }
truth item::IsSimilarTo(item* Item) const { return Item->GetType() == GetType() && Item->GetConfig() == GetConfig(); }
-double item::GetBaseDamage() const { return sqrt(5e-5 * GetWeaponStrength()) + GetDamageBonus(); }
+double item::GetBaseDamage() const { return Max(0., sqrt(5e-5 * GetWeaponStrength()) + GetDamageBonus()); }
int item::GetBaseMinDamage() const { return int(GetBaseDamage() * 0.75); }
int item::GetBaseMaxDamage() const { return int(GetBaseDamage() * 1.25) + 1; }
int item::GetBaseToHitValue() const { return int(10000. / (1000 + GetWeight()) + GetTHVBonus()); }
@@ -119,13 +119,17 @@ item::~item()
}
}
-void item::Fly(character* Thrower, int Direction, int Force)
+void item::Fly(character* Thrower, int Direction, int Force, bool bTryStartThrownRotation)
{
+ iRotateFlyingThrownStep=0; //simple granted reset
+ lsquare* LandingSquare=NULL;
+
int Range = Force * 25 / Max(long(sqrt(GetWeight())), 1L);
lsquare* LSquareUnder = GetLSquareUnder();
RemoveFromSlot();
LSquareUnder->GetStack()->AddItem(this, false);
+ LandingSquare=LSquareUnder;
if(!Range || GetSquaresUnder() != 1)
{
@@ -145,6 +149,7 @@ void item::Fly(character* Thrower, int Direction, int Force)
double BaseDamage, BaseToHitValue;
/*** check ***/
+ int iRotateTimes = ivanconfig::GetRotateTimesPerSquare();
if(Thrower)
{
@@ -153,15 +158,25 @@ void item::Fly(character* Thrower, int Direction, int Force)
BaseToHitValue = 10 * Bonus * Thrower->GetMoveEase()
/ (500 + GetWeight()) * Thrower->GetAttribute(DEXTERITY)
* sqrt(2.5e-8 * Thrower->GetAttribute(PERCEPTION)) / Range;
+
+ if(bTryStartThrownRotation && ivanconfig::GetRotateTimesPerSquare()>0)
+ iRotateFlyingThrownStep = (clock()%2)==0 ? 1 : -1; //init rotation
+
+ if(!Thrower->IsPlayer() && iRotateTimes>1)
+ iRotateTimes=1; //disable "dramatic" rotations from NPCs but still keep minimum if enabled
}
else
{
BaseDamage = sqrt(5e-6 * GetWeaponStrength() * Force / Range);
BaseToHitValue = 10 * 100 / (500 + GetWeight()) / Range;
+ iRotateTimes=0;
}
int RangeLeft;
+ truth Draw=false;
+ float fFlyDelay = 0.03;
+ bool bLowerRotationsPerSqr = iRotateTimes==5;
for(RangeLeft = Range; RangeLeft; --RangeLeft)
{
if(!GetLevel()->IsValidPos(Pos + DirVector))
@@ -181,7 +196,8 @@ void item::Fly(character* Thrower, int Direction, int Force)
Pos += DirVector;
RemoveFromSlot();
JustHit->GetStack()->AddItem(this, false);
- truth Draw = game::OnScreen(JustHit->GetPos()) && JustHit->CanBeSeenByPlayer();
+ LandingSquare=JustHit;
+ Draw = game::OnScreen(JustHit->GetPos()) && JustHit->CanBeSeenByPlayer();
if(Draw)
game::DrawEverything();
@@ -200,8 +216,38 @@ void item::Fly(character* Thrower, int Direction, int Force)
}
if(Draw)
- while(clock() - StartTime < 0.03 * CLOCKS_PER_SEC);
+ while(clock() - StartTime < fFlyDelay * CLOCKS_PER_SEC);
+
+ if(iRotateFlyingThrownStep!=0){
+ if(iRotateTimes==1){
+ iRotateFlyingThrownStep += iRotateFlyingThrownStep>0 ? 1 : -1; //next rotation step on next square
+ }else{ //if rotation steps is >= 2 rotate at least one more time on the same square
+ for(int i=0;i<(iRotateTimes-1);i++){
+ iRotateFlyingThrownStep += iRotateFlyingThrownStep>0 ? 1 : -1;
+ if(Draw){
+ StartTime = clock();
+ RemoveFromSlot();JustHit->GetStack()->AddItem(this, false); //TODO find a better way then remove and re-add to same square to redraw...
+ game::DrawEverything();
+ if(bLowerRotationsPerSqr){
+ iRotateTimes--;
+ if(iRotateTimes<1)iRotateTimes=1;
+ }
+ //while(clock() - StartTime < fFlyDelay * CLOCKS_PER_SEC);
+ }
+ }
+ }
+ }
+
}
+
+ }
+
+ if(iRotateFlyingThrownStep!=0){ //must be disabled before exiting Fly()
+ iRotateFlyingThrownStep=4; //default rotation is w/o the rotation flags at the switch(){}
+ //force redraw at default rotation to avoid another spin when player moves TODO how to let it stay in the last rotation?
+ RemoveFromSlot();LandingSquare->GetStack()->AddItem(this, false); //TODO find a better way then remove and re-add to same square...
+ game::DrawEverything();
+ iRotateFlyingThrownStep=0; //disables rotation
}
if(Breaks)
@@ -283,6 +329,37 @@ truth item::Polymorph(character* Polymorpher, stack* CurrentStack)
}
}
+/* Returns truth that tells whether the alchemical conversion really happened. */
+
+truth item::Alchemize(character* Midas, stack* CurrentStack)
+{
+ if(IsQuestItem())
+ return false;
+ else
+ {
+ if(Midas && IsOnGround())
+ {
+ room* Room = GetRoom();
+
+ if(Room)
+ Room->HostileAction(Midas);
+ }
+
+ long Price = GetTruePrice();
+
+ if(Price)
+ {
+ Price /= 4; /* slightly lower than with 10 Cha */
+ ADD_MESSAGE("Gold pieces clatter on the floor.");
+ Midas->SetMoney(Midas->GetMoney() + Price);
+ }
+
+ RemoveFromSlot();
+ SendToHell();
+ return true;
+ }
+}
+
/* Returns whether the Eater must stop eating the item */
truth item::Consume(character* Eater, long Amount)
@@ -324,6 +401,23 @@ truth item::CanBeEatenByAI(ccharacter* Eater) const
&& ConsumeMaterial && ConsumeMaterial->CanBeEatenByAI(Eater);
}
+void item::SetLabel(cfestring& What)
+{
+ label.Empty();
+ if(What.GetSize()>0)
+ label << What;
+}
+
+void item::AddName(festring& Name, int Case) const
+{
+ if(label.GetSize())
+ Name << label << " "; //this way user can decide how it should look, with or w/o delimiters and which ones
+// Name << "{"<