diff --git a/.clang-tidy b/.clang-tidy
index ef0f6fde7..0b57ab8ea 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,282 +1,18 @@
---
-Checks: 'clang-diagnostic-*,clang-analyzer-*,misc-static-assert,modernize-use-auto,modernize-use-default,modernize-usenullptr,modernize-use-override,performance-*,readability-non-const-parameter,readability-redundant-*,readability-simplify-*,bugprone-*'
+Checks: 'clang-diagnostic-*,clang-analyzer-*,readability-non-const-parameter'
+WarningsAsErrors: ''
+HeaderFileExtensions:
+ - ''
+ - h
+ - hh
+ - hpp
+ - hxx
+ImplementationFileExtensions:
+ - c
+ - cc
+ - cpp
+ - cxx
HeaderFilterRegex: 'forms/.*|framework/.*|game/.*|library/.*|tests/.*|tools/.*'
-AnalyzeTemporaryDtors: false
-User: jonny
-CheckOptions:
- - key: google-readability-braces-around-statements.ShortStatementLines
- value: '1'
- - key: google-readability-function-size.StatementThreshold
- value: '800'
- - key: google-readability-namespace-comments.ShortNamespaceLines
- value: '10'
- - key: google-readability-namespace-comments.SpacesBeforeComments
- value: '2'
- - key: modernize-loop-convert.MaxCopySize
- value: '16'
- - key: modernize-loop-convert.MinConfidence
- value: reasonable
- - key: modernize-loop-convert.NamingStyle
- value: CamelCase
- - key: modernize-pass-by-value.IncludeStyle
- value: llvm
- - key: modernize-replace-auto-ptr.IncludeStyle
- value: llvm
- - key: modernize-use-nullptr.NullMacros
- value: 'NULL'
- - key: readability-identifier-naming.AbstractClassCase
- value: CamelCase
- - key: readability-identifier-naming.AbstractClassPrefix
- value: ''
- - key: readability-identifier-naming.AbstractClassSuffix
- value: ''
- - key: readability-identifier-naming.ClassCase
- value: CamelCase
- - key: readability-identifier-naming.ClassConstantCase
- value: aNy_CasE
- - key: readability-identifier-naming.ClassConstantPrefix
- value: ''
- - key: readability-identifier-naming.ClassConstantSuffix
- value: ''
- - key: readability-identifier-naming.ClassMemberCase
- value: aNy_CasE
- - key: readability-identifier-naming.ClassMemberPrefix
- value: ''
- - key: readability-identifier-naming.ClassMemberSuffix
- value: ''
- - key: readability-identifier-naming.ClassMethodCase
- value: camelBack
- - key: readability-identifier-naming.ClassMethodPrefix
- value: ''
- - key: readability-identifier-naming.ClassMethodSuffix
- value: ''
- - key: readability-identifier-naming.ClassPrefix
- value: ''
- - key: readability-identifier-naming.ClassSuffix
- value: ''
- - key: readability-identifier-naming.ConstantCase
- value: aNy_CasE
- - key: readability-identifier-naming.ConstantMemberCase
- value: aNy_CasE
- - key: readability-identifier-naming.ConstantMemberPrefix
- value: ''
- - key: readability-identifier-naming.ConstantMemberSuffix
- value: ''
- - key: readability-identifier-naming.ConstantParameterCase
- value: aNy_CasE
- - key: readability-identifier-naming.ConstantParameterPrefix
- value: ''
- - key: readability-identifier-naming.ConstantParameterSuffix
- value: ''
- - key: readability-identifier-naming.ConstantPrefix
- value: ''
- - key: readability-identifier-naming.ConstantSuffix
- value: ''
- - key: readability-identifier-naming.ConstexprFunctionCase
- value: aNy_CasE
- - key: readability-identifier-naming.ConstexprFunctionPrefix
- value: ''
- - key: readability-identifier-naming.ConstexprFunctionSuffix
- value: ''
- - key: readability-identifier-naming.ConstexprMethodCase
- value: camelBack
- - key: readability-identifier-naming.ConstexprMethodPrefix
- value: ''
- - key: readability-identifier-naming.ConstexprMethodSuffix
- value: ''
- - key: readability-identifier-naming.ConstexprVariableCase
- value: aNy_CasE
- - key: readability-identifier-naming.ConstexprVariablePrefix
- value: ''
- - key: readability-identifier-naming.ConstexprVariableSuffix
- value: ''
- - key: readability-identifier-naming.EnumCase
- value: CamelCase
- - key: readability-identifier-naming.EnumConstantCase
- value: aNy_CasE
- - key: readability-identifier-naming.EnumConstantPrefix
- value: ''
- - key: readability-identifier-naming.EnumConstantSuffix
- value: ''
- - key: readability-identifier-naming.EnumPrefix
- value: ''
- - key: readability-identifier-naming.EnumSuffix
- value: ''
- - key: readability-identifier-naming.FunctionCase
- value: aNy_CasE
- - key: readability-identifier-naming.FunctionPrefix
- value: ''
- - key: readability-identifier-naming.FunctionSuffix
- value: ''
- - key: readability-identifier-naming.GlobalConstantCase
- value: aNy_CasE
- - key: readability-identifier-naming.GlobalConstantPrefix
- value: ''
- - key: readability-identifier-naming.GlobalConstantSuffix
- value: ''
- - key: readability-identifier-naming.GlobalFunctionCase
- value: aNy_CasE
- - key: readability-identifier-naming.GlobalFunctionPrefix
- value: ''
- - key: readability-identifier-naming.GlobalFunctionSuffix
- value: ''
- - key: readability-identifier-naming.GlobalVariableCase
- value: aNy_CasE
- - key: readability-identifier-naming.GlobalVariablePrefix
- value: ''
- - key: readability-identifier-naming.GlobalVariableSuffix
- value: ''
- - key: readability-identifier-naming.IgnoreFailedSplit
- value: '0'
- - key: readability-identifier-naming.InlineNamespaceCase
- value: aNy_CasE
- - key: readability-identifier-naming.InlineNamespacePrefix
- value: ''
- - key: readability-identifier-naming.InlineNamespaceSuffix
- value: ''
- - key: readability-identifier-naming.LocalConstantCase
- value: aNy_CasE
- - key: readability-identifier-naming.LocalConstantPrefix
- value: ''
- - key: readability-identifier-naming.LocalConstantSuffix
- value: ''
- - key: readability-identifier-naming.LocalVariableCase
- value: aNy_CasE
- - key: readability-identifier-naming.LocalVariablePrefix
- value: ''
- - key: readability-identifier-naming.LocalVariableSuffix
- value: ''
- - key: readability-identifier-naming.MemberCase
- value: aNy_CasE
- - key: readability-identifier-naming.MemberPrefix
- value: ''
- - key: readability-identifier-naming.MemberSuffix
- value: ''
- - key: readability-identifier-naming.MethodCase
- value: camelBack
- - key: readability-identifier-naming.MethodPrefix
- value: ''
- - key: readability-identifier-naming.MethodSuffix
- value: ''
- - key: readability-identifier-naming.NamespaceCase
- value: aNy_CasE
- - key: readability-identifier-naming.NamespacePrefix
- value: ''
- - key: readability-identifier-naming.NamespaceSuffix
- value: ''
- - key: readability-identifier-naming.ParameterCase
- value: aNy_CasE
- - key: readability-identifier-naming.ParameterPackCase
- value: aNy_CasE
- - key: readability-identifier-naming.ParameterPackPrefix
- value: ''
- - key: readability-identifier-naming.ParameterPackSuffix
- value: ''
- - key: readability-identifier-naming.ParameterPrefix
- value: ''
- - key: readability-identifier-naming.ParameterSuffix
- value: ''
- - key: readability-identifier-naming.PrivateMemberCase
- value: aNy_CasE
- - key: readability-identifier-naming.PrivateMemberPrefix
- value: ''
- - key: readability-identifier-naming.PrivateMemberSuffix
- value: ''
- - key: readability-identifier-naming.PrivateMethodCase
- value: camelBack
- - key: readability-identifier-naming.PrivateMethodPrefix
- value: ''
- - key: readability-identifier-naming.PrivateMethodSuffix
- value: ''
- - key: readability-identifier-naming.ProtectedMemberCase
- value: aNy_CasE
- - key: readability-identifier-naming.ProtectedMemberPrefix
- value: ''
- - key: readability-identifier-naming.ProtectedMemberSuffix
- value: ''
- - key: readability-identifier-naming.ProtectedMethodCase
- value: camelBack
- - key: readability-identifier-naming.ProtectedMethodPrefix
- value: ''
- - key: readability-identifier-naming.ProtectedMethodSuffix
- value: ''
- - key: readability-identifier-naming.PublicMemberCase
- value: aNy_CasE
- - key: readability-identifier-naming.PublicMemberPrefix
- value: ''
- - key: readability-identifier-naming.PublicMemberSuffix
- value: ''
- - key: readability-identifier-naming.PublicMethodCase
- value: camelBack
- - key: readability-identifier-naming.PublicMethodPrefix
- value: ''
- - key: readability-identifier-naming.PublicMethodSuffix
- value: ''
- - key: readability-identifier-naming.StaticConstantCase
- value: aNy_CasE
- - key: readability-identifier-naming.StaticConstantPrefix
- value: ''
- - key: readability-identifier-naming.StaticConstantSuffix
- value: ''
- - key: readability-identifier-naming.StaticVariableCase
- value: aNy_CasE
- - key: readability-identifier-naming.StaticVariablePrefix
- value: ''
- - key: readability-identifier-naming.StaticVariableSuffix
- value: ''
- - key: readability-identifier-naming.StructCase
- value: CamelCase
- - key: readability-identifier-naming.StructPrefix
- value: ''
- - key: readability-identifier-naming.StructSuffix
- value: ''
- - key: readability-identifier-naming.TemplateParameterCase
- value: aNy_CasE
- - key: readability-identifier-naming.TemplateParameterPrefix
- value: ''
- - key: readability-identifier-naming.TemplateParameterSuffix
- value: ''
- - key: readability-identifier-naming.TemplateTemplateParameterCase
- value: aNy_CasE
- - key: readability-identifier-naming.TemplateTemplateParameterPrefix
- value: ''
- - key: readability-identifier-naming.TemplateTemplateParameterSuffix
- value: ''
- - key: readability-identifier-naming.TypeTemplateParameterCase
- value: aNy_CasE
- - key: readability-identifier-naming.TypeTemplateParameterPrefix
- value: ''
- - key: readability-identifier-naming.TypeTemplateParameterSuffix
- value: ''
- - key: readability-identifier-naming.TypedefCase
- value: aNy_CasE
- - key: readability-identifier-naming.TypedefPrefix
- value: ''
- - key: readability-identifier-naming.TypedefSuffix
- value: ''
- - key: readability-identifier-naming.UnionCase
- value: CamelCase
- - key: readability-identifier-naming.UnionPrefix
- value: ''
- - key: readability-identifier-naming.UnionSuffix
- value: ''
- - key: readability-identifier-naming.ValueTemplateParameterCase
- value: aNy_CasE
- - key: readability-identifier-naming.ValueTemplateParameterPrefix
- value: ''
- - key: readability-identifier-naming.ValueTemplateParameterSuffix
- value: ''
- - key: readability-identifier-naming.VariableCase
- value: aNy_CasE
- - key: readability-identifier-naming.VariablePrefix
- value: ''
- - key: readability-identifier-naming.VariableSuffix
- value: ''
- - key: readability-identifier-naming.VirtualMethodCase
- value: camelBack
- - key: readability-identifier-naming.VirtualMethodPrefix
- value: ''
- - key: readability-identifier-naming.VirtualMethodSuffix
- value: ''
+SystemHeaders: false
...
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
index e6fd7b204..a63846350 100644
--- a/.github/workflows/cmake.yml
+++ b/.github/workflows/cmake.yml
@@ -12,7 +12,7 @@ jobs:
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
@@ -34,7 +34,13 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
- run: sudo apt-get install libsdl2-dev cmake build-essential git libunwind8-dev libboost-locale-dev libboost-filesystem-dev libboost-program-options-dev qtbase5-dev libvorbis-dev ninja-build g++-13
+ run: sudo apt-get install libsdl2-dev cmake build-essential git libunwind8-dev libboost-locale-dev libboost-filesystem-dev libboost-program-options-dev qtbase5-dev libvorbis-dev ninja-build
+
+ - name: Install gcc-14
+ run: sudo apt install gcc-14 g++-14
+
+ - name: GCC 14 version check
+ run: echo "GCC-14:"; which gcc-14;gcc-14 --version;
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
@@ -44,7 +50,7 @@ jobs:
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
- run: CC=gcc-13 CXX=g++-13 cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -GNinja
+ run: CC=gcc-14 CXX=g++-14 cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -GNinja -DUSE_PCH=ON
- name: Build
working-directory: ${{runner.workspace}}/build
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 3041d03a5..c5c817577 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -5,6 +5,8 @@ on: [push, pull_request]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
+ CLANG_FORMAT: clang-format-18
+ CLANG_TIDY: clang-tidy-18
jobs:
build:
@@ -35,7 +37,7 @@ jobs:
run: sudo apt-get update
- name: Install dependencies
- run: sudo apt-get install libsdl2-dev cmake build-essential git libunwind8-dev libboost-locale-dev libboost-filesystem-dev libboost-program-options-dev qtbase5-dev libvorbis-dev ninja-build clang-format-15 clang-tidy-15
+ run: sudo apt-get install libsdl2-dev cmake build-essential git libunwind8-dev libboost-locale-dev libboost-filesystem-dev libboost-program-options-dev qtbase5-dev libvorbis-dev ninja-build ${CLANG_FORMAT} ${CLANG_TIDY}
- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
@@ -45,7 +47,7 @@ jobs:
# Note the current convention is to use the -S and -B options here to specify source
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
- run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -GNinja -DCLANG_FORMAT=clang-format-15 -DCLANG_TIDY=clang-tidy-15
+ run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -GNinja -DCLANG_FORMAT=${CLANG_FORMAT} -DCLANG_TIDY=${CLANG_TIDY}
- name: Setup Environment (PR)
if: ${{ github.event_name == 'pull_request' }}
@@ -65,14 +67,11 @@ jobs:
working-directory: ${{runner.workspace}}
shell: bash
run: |
- cd $GITHUB_WORKSPACE
- if [ "${{env.BEFORE_COMMIT_SHA}}" == "0000000000000000000000000000000000000000" ]
- then
- echo '$GITHUB_WORKSPACE/tools/lint.sh ${{env.AFTER_COMMIT_SHA}}'
- $GITHUB_WORKSPACE/tools/lint.sh ${{env.AFTER_COMMIT_SHA}}
- else
- echo '$GITHUB_WORKSPACE/tools/lint.sh ${{env.BEFORE_COMMIT_SHA}}..${{env.AFTER_COMMIT_SHA}}'
- $GITHUB_WORKSPACE/tools/lint.sh ${{env.BEFORE_COMMIT_SHA}}..${{env.AFTER_COMMIT_SHA}}
+ cmake --build ${{runner.workspace}}/build -t format-sources
+ if [[ `git -C $GITHUB_WORKSPACE status --porcelain` ]]; then
+ echo "Format mismatch:";
+ git -C $GITHUB_WORKSPACE diff;
+ exit 1;
fi
@@ -83,10 +82,10 @@ jobs:
cd $GITHUB_WORKSPACE
if [ "${{env.BEFORE_COMMIT_SHA}}" == "0000000000000000000000000000000000000000" ]
then
- echo 'CLANG_TIDY=clang-tidy-15 BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.AFTER_COMMIT_SHA}} || true;'
- CLANG_TIDY=clang-tidy-15 BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.AFTER_COMMIT_SHA}} || true;
+ echo 'BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.AFTER_COMMIT_SHA}} || true;'
+ BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.AFTER_COMMIT_SHA}} || true;
else
- echo 'CLANG_TIDY=clang-tidy-15 BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.BEFORE_COMMIT_SHA}}..${{env.AFTER_COMMIT_SHA}} || true;'
- CLANG_TIDY=clang-tidy-15 BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.BEFORE_COMMIT_SHA}}..${{env.AFTER_COMMIT_SHA}} || true;
+ echo 'BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.BEFORE_COMMIT_SHA}}..${{env.AFTER_COMMIT_SHA}} || true;'
+ BUILD_DIR=${{runner.workspace}}/build $GITHUB_WORKSPACE/tools/lint-tidy.sh ${{env.BEFORE_COMMIT_SHA}}..${{env.AFTER_COMMIT_SHA}} || true;
fi
diff --git a/.gitmodules b/.gitmodules
index cdae4ef5a..73205b622 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -23,3 +23,6 @@
[submodule "dependencies/fmt"]
path = dependencies/fmt
url = https://github.com/fmtlib/fmt.git
+[submodule "dependencies/magic_enum"]
+ path = dependencies/magic_enum
+ url = https://github.com/Neargye/magic_enum.git
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee6b7d33a..222234ba6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ string(TOLOWER "${CMAKE_BUILD_TYPE}" lower_build_type)
option(LTO "Build using link-time-optimisations" OFF)
option(MSVC_PDB "Always generate PDB files" OFF)
option(ENABLE_TESTS "Build some unit tests" ON)
+option(USE_PCH "Enable precompiled header use during build" OFF)
option(EXTRACT_DATA "Run the data extractor as part of the default target" ON)
set(CD_PATH ${CMAKE_SOURCE_DIR}/data/cd.iso CACHE STRING "Path to cd.iso (used
@@ -76,6 +77,8 @@ endif(LTO)
# MSVC has default flags that CMake doesn't set
if (MSVC)
add_definitions(-DUNICODE -D_UNICODE)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8")
if (MSVC_VERSION GREATER_EQUAL 1910)
if (MSVC_VERSION EQUAL 1928)
diff --git a/CODE_STYLE.md b/CODE_STYLE.md
index ac62d02ab..bfac4af08 100644
--- a/CODE_STYLE.md
+++ b/CODE_STYLE.md
@@ -15,7 +15,7 @@ GCCIsntMuchBetter
C++11 features are heavily encouraged - patterns from 'older' c++ versions that have been superceded should be avoided.
-The formatting sections of this document are enforced by the [clang-format tool](http://llvm.org/releases/15.0.0/tools/clang/docs/ClangFormat.html). Currently, version '15.0' of ``clang-format`` is to be used. The configuration file ``.clang-format`` in the root of the OpenApoc source repository should match the formatting guidelines specified below.
+The formatting sections of this document are enforced by the [clang-format tool](https://releases.llvm.org/18.1.1/tools/clang/docs/ClangFormat.html). Currently, version '18.0' of ``clang-format`` is to be used. The configuration file ``.clang-format`` in the root of the OpenApoc source repository should match the formatting guidelines specified below.
With this, it is highly recommended to run ``clang-format`` on all modified files before check-in. This can be run on source files with the following command:
diff --git a/README.md b/README.md
index 1aead7d8f..545f3273f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# OpenApocalypse [](https://twitter.com/intent/tweet?text=Are%20you%20a%20fan%20of%20X-Com%20Apocalypse?%20OpenApoc%20is%20a%20clone%20of%20this%20great%20game%20-%20contribute!%20https://github.com/OpenApoc/OpenApoc&hashtags=games,openapoc,xcom)
-> OpenApoc is an open-source re-implementation of the original [X-COM: Apocalypse](https://www.ufopaedia.org/index.php/Apocalypse), that requires the original files to run, licensed under the GPL3 and written in C++ / SDL2. It was originally founded by PmProg in July 2014, and has since grown in [community](https://www.ufopaedia.org/index.php/Credits_(OpenApoc)).
+> OpenApoc is an open-source re-implementation of the original [X-COM: Apocalypse](https://www.ufopaedia.org/index.php/Apocalypse), that requires the original files to run, licensed under the GPL3 and written in C++ / SDL2. It was originally founded by PmProg in July 2014, and has since grown a significant [community](https://www.ufopaedia.org/index.php/Credits_(OpenApoc)).
[](https://travis-ci.com/github/OpenApoc/OpenApoc)
[](https://ci.appveyor.com/project/openapoc/openapoc/branch/master)
@@ -33,44 +33,46 @@
## Copyright
-All rights for the original game and its resources belong to their respective owners. We do not encourage and do not support any form of illegal usage of the original game. We strongly advise to purchase the original game on GOG or other platforms. Pirated ISOs are not supported and will cause issues such as crashes and map problems with OpenApoc.
+All rights for the original game and its resources belong to their respective owners.
+We do not encourage and do not support any form of illegal usage of the original game.
+We strongly advise to purchase the original game on STEAM or another platform of your choosing.
+Pirated disc images and archives are not supported and will cause issues such as crashes and map problems with OpenApoc.
## Key Features
-* Unlimited modding capabilities, which was not possible in the original
-* Port the game to any platform you like (windows, linux, android etc)
-* Support for modern screen resolutions
-* Added a full debug system ([hot keys](https://github.com/OpenApoc/OpenApoc/blob/master/README_HOTKEYS.txt), etc.)
-* Added 'more options' menu (with more than 40 improvements)
-* Added skirmish module (fast fight)
-* The new engine has ample opportunities for expansion and changes:
- * High FPS, smooth sound during the game without bugs from original
- * No limitations which were in vanilla
- * Modern formats
-* After release, we can add Julian Gollop's cut ideas to the game through mods. Many have already been added but they need functionality and balance.
* [](https://www.reddit.com/user/JulianGollop/) "Yes, I am aware of the openApoc project and I very much do support it."
-* Fans creating Big Apoc Concept, for modders, thats should make OpenApoc more balanced, to provide:
- * A variety of interesting gameplay solutions
- * Make the game more complex and diverse
- * L.O.R.E more fulfilling, deep and mysterious, intertwined with real history and other games
- * Ending the game can be more interesting and less predictable
+* Full modding capability - You can add or change almost anything!
+* Options for modding that allow opportunity to make OpenApoc:
+ * More balanced
+ * More diverse
+ * More immersive
+* Human-Readable Savegame editing - It's all XML in a ZIP archvive so you can edit/tweak in progress games to your liking!
+* Support for modern screen resolutions and display scaling at a silky smooth 60fps
+* Added a 'More Options' menu that allows players to select dozens of new optional improvements and enhancements
+* Added a full debug system ([Hot Keys](https://github.com/OpenApoc/OpenApoc/blob/master/README_HOTKEYS.txt), etc.)
+* Port the game to any platform you like (Windows, Linux, Etc.)
+* Added a Skirmish Mode for quick fights and custom battles (Experimental)
+* The new engine has ample opportunities for expansion and refinements including:
+ * High FPS
+ * Smooth sound playback with none of the pop/clicks/stutters of the original game
+* The potential to add cut and missing features from the Original Game - some of these are already included even at current Alpha state or with the handful of mods already available!
## What's left?
-1. [TO HAVE A TRULY PLAYABLE ALPHA STATE (DONE)](https://github.com/OpenApoc/OpenApoc/issues/263)
-2. [TO REACH A BETA STATE (When All features implemented)](https://github.com/OpenApoc/OpenApoc/issues/264)
-3. [TO REACH OPENAPOC RELEASE 1.0](https://github.com/OpenApoc/OpenApoc/issues/265)
+1. [TO HAVE A TRULY PLAYABLE ALPHA STATE](https://github.com/OpenApoc/OpenApoc/issues/263)
+2. [TO REACH A BETA STATE (All core Original Game features implemented)](https://github.com/OpenApoc/OpenApoc/issues/264)
+3. [TO REACH OPENAPOC RELEASE 1.0 (Final polishing and testing to match or exceed Original Game state)](https://github.com/OpenApoc/OpenApoc/issues/265)
4. [Modding Functions, Extra Features, Enhancements and Quality of Life Updates](https://github.com/OpenApoc/OpenApoc/issues/941)
## Contribute and FAQ
-http://openapoc.org/#contribute
+http://openapoc.org/#contribute - Currently Offline, please use [Discord](https://discord.gg/f8Rayre)
>Here you find news, detailing how you can participate in project.
You can support the project by testing, translating, modding, drawing, modeling, concepting etc..
-http://openapoc.org/#faq
->Here you find the detailed FAQ (frequently asked questions)
+http://openapoc.org/#faq - Currently Offline, please use [Discord](https://discord.gg/f8Rayre)
+>Here you find the detailed FAQ (Frequently Asked Questions)
## Building
@@ -94,6 +96,7 @@ The following libraries are also used, but are shipped as submodules in the repo
* [physfs](https://icculus.org/physfs/) - Library for reading data from .iso files or directory trees (Note: We use a patched version, available on [GitHub](https://github.com/JonnyH/physfs-hg-import/tree/fix-iso) - required to read the .iso files we use).
* [pugixml](https://pugixml.org) - XML library used for reading/writing the game data files.
* [fmtlib](https://github.com/fmtlib/fmt) - A c++ string formatting library - proposed for c++20 standard.
+* [magic_enum](https://github.com/Neargye/magic_enum) - Header-only C++17 library provides static reflection for enums, work with any enum type without any macro or boilerplate code.
### Building on Windows
@@ -146,12 +149,12 @@ vcpkg --triplet x86-windows install sdl2 boost-locale boost-program-options boos
### Building on Linux
-(Tested on Ubuntu 22.04)
+(Tested on Ubuntu 22.04 and 24.04)
* On Ubuntu, install the following packages:
```sh
-sudo apt-get install sdl2-dev cmake build-essential git libunwind8-dev libboost-locale-dev libboost-program-options-dev qtbase5-dev libvorbis-dev
+sudo apt-get install libsdl2-dev cmake build-essential git libunwind8-dev libboost-locale-dev libboost-program-options-dev qtbase5-dev libvorbis-dev
```
* On Mageia, install the following packages as root:
@@ -276,13 +279,13 @@ OPENGL 2.0 SUPPORTIVE VIDEO CARDS ARE REQUIRED
WINDOWS USERS: You will require the LATEST Visual C++ Libraries obtained from windows update to run OpenApoc
https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
-(Keep in mind that OpenApoc is ALPHA STATE - this means bugs, crushes and not all features implemented, use our bug-tracker at https://github.com/OpenApoc/OpenApoc/issues to report bugs and navigate known ones)
+Simple steps to play OpenApoc on Windows right now
+(Keep in mind that it is ALPHA - this means bugs, crushes and not all features implemented, use our bug-tracker at https://github.com/OpenApoc/OpenApoc/issues to report bugs and navigate known ones)
-1) Download the OpenApoc core files: [](https://ci.appveyor.com/project/openapoc/openapoc/branch/master) (Latest master build)
-- If the build link above doesn't work, visit https://ci.appveyor.com/project/OpenApoc/openapoc/history
+1) Download the OpenApoc core files from https://github.com/OpenApoc/OpenApoc/releases
+- For experimental builds visit https://ci.appveyor.com/project/OpenApoc/openapoc/history
- If you see a green bar next to the latest build then you can download it, click a build that is green, or use "Show More" to list all builds
- Click ARTIFACTS (Currently only Windows x64)
-- If there are no artifacts use https://github.com/OpenApoc/OpenApoc/releases for the latest Winx64 compile
- Download the option that ends with a ".exe" (and without "debug" in it)
- Run the downloaded exe installer, this will guide you through the installation
- Use "portable install" if you want saves and settings to remain in the install directory
@@ -293,7 +296,7 @@ https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msv
- If the disc image is in .iso format, rename it to "cd.iso"
- We also support the GOG .cue / .bin files!
-3) Put cd.iso (image or folder) into the data folder under the specified OpenApoc install folder
+3) Put cd.iso (image or folder) into the "data" folder under the specified OpenApoc install folder
- If you have already specified the "cd.iso" location in the installer, you don't need to do this step
- To use GOG .cue/.bin you rename the XCOM.cue file to "cd.iso", put that in the OpenApoc data folder, then put the XCOM.BIN, without renaming it, into the data folder too
@@ -302,11 +305,13 @@ https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msv
## Contact us
-If you're interested, please visit our [website](http://openapoc.org).
-* We have [forums](http://openapoc.org/forum/) - please pop by and introduce yourself!
-* We have an [Discord](https://discord.gg/f8Rayre) channel
-* We have an IRC channel on [Freenode](http://webchat.freenode.net/?channels=openapoc) - [#openapoc](irc://irc.freenode.net/#openapoc).
+If you're interested, please visit our [website](http://openapoc.org) (Currently Offline, please use [Discord](https://discord.gg/f8Rayre)).
+* We have a [Discord](https://discord.gg/f8Rayre) - MOST ACTIVE PLACE FOR ALL THINGS OPENAPOC!
* We have a [Youtube](https://www.youtube.com/c/OpenApoc) channel.
+* We have a [forum](http://openapoc.org/forum/) (Currently Offline, please use [Discord](https://discord.gg/f8Rayre))
+
+## Unnofficial and Community Contacts
+
* We have a [Facebook](https://www.facebook.com/openapoc) page.
-* We have a [Vkontakte](https://vk.com/openapoc) page.
* We have a [Reddit](https://reddit.com/r/openapoc) page.
+* All VK Presence is currently unofficial
diff --git a/appveyor-dev.yml b/appveyor-dev.yml
index 794473c1c..38f7af6cc 100644
--- a/appveyor-dev.yml
+++ b/appveyor-dev.yml
@@ -25,7 +25,7 @@ cache: C:\Users\appveyor\AppData\Local\vcpkg\archives -> appveyor-dev.yml
before_build:
- cd c:\tools\vcpkg
- git pull
- - git checkout 2023.08.09
+ - git checkout 2024.10.21
- .\bootstrap-vcpkg.bat
- cd %APPVEYOR_BUILD_FOLDER%
- vcpkg install
@@ -34,7 +34,7 @@ before_build:
- 7z e temp\cd.iso.xz -odata\
- call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" %VCVARS_ARCH%
build_script:
- - cmake -DMSVC_PDB=ON . -GNinja -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE="%CONFIGURATION%" -DCMAKE_PREFIX_PATH=%QTPATH% -DUSE_SYSTEM_QT=ON
+ - cmake -DMSVC_PDB=ON -DUSE_PCH=ON . -GNinja -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE="%CONFIGURATION%" -DCMAKE_PREFIX_PATH=%QTPATH% -DUSE_SYSTEM_QT=ON
- cmake --build .
after_build:
- git describe --tags > build-id
diff --git a/appveyor.yml b/appveyor.yml
index ecb2f42a3..d00c922a0 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -25,7 +25,7 @@ cache: C:\Users\appveyor\AppData\Local\vcpkg\archives -> appveyor.yml
before_build:
- cd c:\tools\vcpkg
- git pull
- - git checkout 2023.08.09
+ - git checkout 2024.10.21
- .\bootstrap-vcpkg.bat
- cd %APPVEYOR_BUILD_FOLDER%
- vcpkg install
@@ -35,7 +35,7 @@ before_build:
- choco install nsis -pre
- call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" %VCVARS_ARCH%
build_script:
- - cmake -DMSVC_PDB=ON . -GNinja -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE="%CONFIGURATION%" -DCMAKE_PREFIX_PATH=%QTPATH% -DUSE_SYSTEM_QT=ON
+ - cmake -DMSVC_PDB=ON -DUSE_PCH=ON . -GNinja -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_BUILD_TYPE="%CONFIGURATION%" -DCMAKE_PREFIX_PATH=%QTPATH% -DUSE_SYSTEM_QT=ON
- cmake --build .
after_build:
- git describe --tags > build-id
diff --git a/data/forms/city/debugoverlay_city.form b/data/forms/city/debugoverlay_city.form
index 601b6d2ea..a787f8657 100644
--- a/data/forms/city/debugoverlay_city.form
+++ b/data/forms/city/debugoverlay_city.form
@@ -47,7 +47,7 @@
smalfont
-
+
@@ -143,7 +143,7 @@
smalfont
-
+
@@ -155,14 +155,20 @@
smalfont
-
+
+
+
+ smalfont
+
+
+
smalfont
-
+
smalfont
diff --git a/data/forms/city/infiltration.form b/data/forms/city/infiltration.form
index 893d7f0e5..233178abc 100644
--- a/data/forms/city/infiltration.form
+++ b/data/forms/city/infiltration.form
@@ -38,6 +38,30 @@
BUTTON_OK_DEPRESSED
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ BUTTON_SCROLL_UP_DEPRESSED
+
+
+
+
+
+
+ BUTTON_SCROLL_DOWN_DEPRESSED
+
diff --git a/data/forms/researchscreen.form b/data/forms/researchscreen.form
index 349f0778c..2e3cce5ba 100644
--- a/data/forms/researchscreen.form
+++ b/data/forms/researchscreen.form
@@ -82,8 +82,8 @@
smalfont
-
-
+
+
smalfont
diff --git a/data/forms/ufopaedia.form b/data/forms/ufopaedia.form
index db32120d4..a1e488ecd 100644
--- a/data/forms/ufopaedia.form
+++ b/data/forms/ufopaedia.form
@@ -85,6 +85,12 @@
smalfont
+
+
+
+
+ smalfont
+
@@ -139,6 +145,12 @@
smalfont
+
+
+
+
+ smalfont
+
diff --git a/data/languages/ufo_string.pot b/data/languages/ufo_string.pot
index 5295cf704..563a8b8a6 100644
--- a/data/languages/ufo_string.pot
+++ b/data/languages/ufo_string.pot
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_string_cs.po b/data/languages/ufo_string_cs.po
index 6c3b47d54..71864e7d9 100644
--- a/data/languages/ufo_string_cs.po
+++ b/data/languages/ufo_string_cs.po
@@ -4450,7 +4450,7 @@ msgstr "Zásoba munice"
msgid "Cargo"
msgstr "Náklad"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Cizác. náklad"
msgid "Jamming"
diff --git a/data/languages/ufo_string_de_DE.po b/data/languages/ufo_string_de_DE.po
index fa57cf1f1..46405c45b 100644
--- a/data/languages/ufo_string_de_DE.po
+++ b/data/languages/ufo_string_de_DE.po
@@ -4449,7 +4449,7 @@ msgstr "Munitionskapazität"
msgid "Cargo"
msgstr "Fracht"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Fstglt. Aliens"
msgid "Jamming"
diff --git a/data/languages/ufo_string_en_GB.po b/data/languages/ufo_string_en_GB.po
index 5295cf704..563a8b8a6 100644
--- a/data/languages/ufo_string_en_GB.po
+++ b/data/languages/ufo_string_en_GB.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_string_es.po b/data/languages/ufo_string_es.po
index e81082f8a..d6b7ba2a6 100644
--- a/data/languages/ufo_string_es.po
+++ b/data/languages/ufo_string_es.po
@@ -4449,7 +4449,7 @@ msgstr "Capacidad de Munición"
msgid "Cargo"
msgstr "Carga"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Alienígenas"
msgid "Jamming"
diff --git a/data/languages/ufo_string_fr_FR.po b/data/languages/ufo_string_fr_FR.po
index e65e0bc42..788caf0d7 100644
--- a/data/languages/ufo_string_fr_FR.po
+++ b/data/languages/ufo_string_fr_FR.po
@@ -4450,7 +4450,7 @@ msgstr "Capacité de munitions"
msgid "Cargo"
msgstr "Cargaison"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Aliens pris"
msgid "Jamming"
diff --git a/data/languages/ufo_string_it.po b/data/languages/ufo_string_it.po
index 8b53d5d20..137097278 100644
--- a/data/languages/ufo_string_it.po
+++ b/data/languages/ufo_string_it.po
@@ -4450,7 +4450,7 @@ msgstr "Munizioni"
msgid "Cargo"
msgstr "Cargo"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Alieni cont."
msgid "Jamming"
diff --git a/data/languages/ufo_string_pl.po b/data/languages/ufo_string_pl.po
index 61424cdab..6df7443e2 100644
--- a/data/languages/ufo_string_pl.po
+++ b/data/languages/ufo_string_pl.po
@@ -4450,7 +4450,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_string_pt_BR.po b/data/languages/ufo_string_pt_BR.po
index 91330229c..5d14acca2 100644
--- a/data/languages/ufo_string_pt_BR.po
+++ b/data/languages/ufo_string_pt_BR.po
@@ -4450,7 +4450,7 @@ msgstr "Capacidade p/ munição"
msgid "Cargo"
msgstr "Carga"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Alienígenas Aprisionados"
msgid "Jamming"
diff --git a/data/languages/ufo_string_ru_RU.po b/data/languages/ufo_string_ru_RU.po
index 71f752955..838629822 100644
--- a/data/languages/ufo_string_ru_RU.po
+++ b/data/languages/ufo_string_ru_RU.po
@@ -4455,7 +4455,7 @@ msgstr "Боезапас"
msgid "Cargo"
msgstr "Груз"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Пришельцев удерживается"
msgid "Jamming"
diff --git a/data/languages/ufo_string_uk.po b/data/languages/ufo_string_uk.po
index 72926769b..463affb3b 100644
--- a/data/languages/ufo_string_uk.po
+++ b/data/languages/ufo_string_uk.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_cs.po b/data/languages/ufo_stringpo_cs.po
index 35609116b..fd9621fe1 100644
--- a/data/languages/ufo_stringpo_cs.po
+++ b/data/languages/ufo_stringpo_cs.po
@@ -4452,7 +4452,7 @@ msgstr "Zásoba munice"
msgid "Cargo"
msgstr "Náklad"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Cizác. náklad"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_de_DE.po b/data/languages/ufo_stringpo_de_DE.po
index 00479ca34..02a3c2439 100644
--- a/data/languages/ufo_stringpo_de_DE.po
+++ b/data/languages/ufo_stringpo_de_DE.po
@@ -4449,7 +4449,7 @@ msgstr "Munitionskapazität"
msgid "Cargo"
msgstr "Fracht"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Fstglt. Aliens"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_en.po b/data/languages/ufo_stringpo_en.po
index 639414b80..ee3e872d8 100644
--- a/data/languages/ufo_stringpo_en.po
+++ b/data/languages/ufo_stringpo_en.po
@@ -4448,8 +4448,8 @@ msgstr "Ammo capacity"
msgid "Cargo"
msgstr "Cargo"
-msgid "Aliens Held"
-msgstr "Aliens Held"
+msgid "Max Samples"
+msgstr "Max Samples"
msgid "Jamming"
msgstr "Jamming"
diff --git a/data/languages/ufo_stringpo_en_GB.po b/data/languages/ufo_stringpo_en_GB.po
index 0b3b375c0..98d00d97c 100644
--- a/data/languages/ufo_stringpo_en_GB.po
+++ b/data/languages/ufo_stringpo_en_GB.po
@@ -4450,7 +4450,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_es.po b/data/languages/ufo_stringpo_es.po
index 72bfe14b4..0386849c6 100644
--- a/data/languages/ufo_stringpo_es.po
+++ b/data/languages/ufo_stringpo_es.po
@@ -4450,7 +4450,7 @@ msgstr "Capacidad de Munición"
msgid "Cargo"
msgstr "Carga"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Alienígenas"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_et_EE.po b/data/languages/ufo_stringpo_et_EE.po
index 42cbc5343..00c0b7d3b 100644
--- a/data/languages/ufo_stringpo_et_EE.po
+++ b/data/languages/ufo_stringpo_et_EE.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_fi.po b/data/languages/ufo_stringpo_fi.po
index 54a0b942b..2c9513d6a 100644
--- a/data/languages/ufo_stringpo_fi.po
+++ b/data/languages/ufo_stringpo_fi.po
@@ -4450,7 +4450,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_fil_PH.po b/data/languages/ufo_stringpo_fil_PH.po
index b1d6e2e08..a3a57b14d 100644
--- a/data/languages/ufo_stringpo_fil_PH.po
+++ b/data/languages/ufo_stringpo_fil_PH.po
@@ -4449,7 +4449,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_fr_FR.po b/data/languages/ufo_stringpo_fr_FR.po
index 64c32fab1..8623da97e 100644
--- a/data/languages/ufo_stringpo_fr_FR.po
+++ b/data/languages/ufo_stringpo_fr_FR.po
@@ -4450,7 +4450,7 @@ msgstr "Capacité de munitions"
msgid "Cargo"
msgstr "Cargaison"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Aliens pris"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_hu_HU.po b/data/languages/ufo_stringpo_hu_HU.po
index 23772a79f..d1998bfa2 100644
--- a/data/languages/ufo_stringpo_hu_HU.po
+++ b/data/languages/ufo_stringpo_hu_HU.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_it.po b/data/languages/ufo_stringpo_it.po
index f78dc92aa..8955cd340 100644
--- a/data/languages/ufo_stringpo_it.po
+++ b/data/languages/ufo_stringpo_it.po
@@ -4450,7 +4450,7 @@ msgstr "Munizioni"
msgid "Cargo"
msgstr "Cargo"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Alieni cont."
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_ja.po b/data/languages/ufo_stringpo_ja.po
index 7980a6f1a..e3de7c65b 100644
--- a/data/languages/ufo_stringpo_ja.po
+++ b/data/languages/ufo_stringpo_ja.po
@@ -4448,7 +4448,7 @@ msgstr "装弾数"
msgid "Cargo"
msgstr "貨物"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "捕獲中のエイリアン"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_ja_JP.po b/data/languages/ufo_stringpo_ja_JP.po
index cc4d7af60..803897b8d 100644
--- a/data/languages/ufo_stringpo_ja_JP.po
+++ b/data/languages/ufo_stringpo_ja_JP.po
@@ -4449,7 +4449,7 @@ msgstr "装弾数"
msgid "Cargo"
msgstr "貨物"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "捕獲中のエイリアン"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_lt.po b/data/languages/ufo_stringpo_lt.po
index 960f1beee..29ad5bfe3 100644
--- a/data/languages/ufo_stringpo_lt.po
+++ b/data/languages/ufo_stringpo_lt.po
@@ -4449,7 +4449,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_nb_NO.po b/data/languages/ufo_stringpo_nb_NO.po
index 5f8ad78ae..3cb845123 100644
--- a/data/languages/ufo_stringpo_nb_NO.po
+++ b/data/languages/ufo_stringpo_nb_NO.po
@@ -4449,7 +4449,7 @@ msgstr "Ammunisjonskapasitet"
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_pl.po b/data/languages/ufo_stringpo_pl.po
index c9f273162..3e19d9ce5 100644
--- a/data/languages/ufo_stringpo_pl.po
+++ b/data/languages/ufo_stringpo_pl.po
@@ -4454,7 +4454,7 @@ msgstr "Pojemność amunicji"
msgid "Cargo"
msgstr "Ładunek"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Pod kontrolą obcych"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_pt_BR.po b/data/languages/ufo_stringpo_pt_BR.po
index 84da87de0..33d759328 100644
--- a/data/languages/ufo_stringpo_pt_BR.po
+++ b/data/languages/ufo_stringpo_pt_BR.po
@@ -4450,7 +4450,7 @@ msgstr "Capacidade p/ munição"
msgid "Cargo"
msgstr "Carga"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Alienígenas Aprisionados"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_pt_PT.po b/data/languages/ufo_stringpo_pt_PT.po
index 845f0bcf1..aab4c6b42 100644
--- a/data/languages/ufo_stringpo_pt_PT.po
+++ b/data/languages/ufo_stringpo_pt_PT.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_ro_RO.po b/data/languages/ufo_stringpo_ro_RO.po
index 6ad5ab3e2..7275a2d26 100644
--- a/data/languages/ufo_stringpo_ro_RO.po
+++ b/data/languages/ufo_stringpo_ro_RO.po
@@ -4449,7 +4449,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_ru_RU.po b/data/languages/ufo_stringpo_ru_RU.po
index 8efd52727..9d4b639a1 100644
--- a/data/languages/ufo_stringpo_ru_RU.po
+++ b/data/languages/ufo_stringpo_ru_RU.po
@@ -4453,7 +4453,7 @@ msgstr "Боезапас"
msgid "Cargo"
msgstr "Груз"
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr "Пришельцев удерживается"
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_sk.po b/data/languages/ufo_stringpo_sk.po
index 10ed82394..426016804 100644
--- a/data/languages/ufo_stringpo_sk.po
+++ b/data/languages/ufo_stringpo_sk.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_sl_SI.po b/data/languages/ufo_stringpo_sl_SI.po
index 6c07733fd..455504de5 100644
--- a/data/languages/ufo_stringpo_sl_SI.po
+++ b/data/languages/ufo_stringpo_sl_SI.po
@@ -4450,7 +4450,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_tr_TR.po b/data/languages/ufo_stringpo_tr_TR.po
index d83887fc8..fc515af56 100644
--- a/data/languages/ufo_stringpo_tr_TR.po
+++ b/data/languages/ufo_stringpo_tr_TR.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_uk.po b/data/languages/ufo_stringpo_uk.po
index e95edba5c..3b6cfa59f 100644
--- a/data/languages/ufo_stringpo_uk.po
+++ b/data/languages/ufo_stringpo_uk.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/data/languages/ufo_stringpo_zh_TW.po b/data/languages/ufo_stringpo_zh_TW.po
index 2cb6e5825..b45b09069 100644
--- a/data/languages/ufo_stringpo_zh_TW.po
+++ b/data/languages/ufo_stringpo_zh_TW.po
@@ -4448,7 +4448,7 @@ msgstr ""
msgid "Cargo"
msgstr ""
-msgid "Aliens Held"
+msgid "Max Samples"
msgstr ""
msgid "Jamming"
diff --git a/dependencies/magic_enum b/dependencies/magic_enum
new file mode 160000
index 000000000..adc7d2ba5
--- /dev/null
+++ b/dependencies/magic_enum
@@ -0,0 +1 @@
+Subproject commit adc7d2ba57e142b6ad018e01057233478a74c1e8
diff --git a/forms/CMakeLists.txt b/forms/CMakeLists.txt
index dcf9492fe..35e3a536b 100644
--- a/forms/CMakeLists.txt
+++ b/forms/CMakeLists.txt
@@ -56,3 +56,7 @@ target_link_libraries(OpenApoc_Forms PUBLIC OpenApoc_Framework
OpenApoc_LibPugixml)
target_include_directories(OpenApoc_Forms PUBLIC ${CMAKE_SOURCE_DIR})
+
+if (USE_PCH)
+ target_precompile_headers(OpenApoc_Forms PUBLIC forms_pch.h)
+endif()
\ No newline at end of file
diff --git a/forms/control.cpp b/forms/control.cpp
index 07835eb1a..f2ba76080 100644
--- a/forms/control.cpp
+++ b/forms/control.cpp
@@ -10,7 +10,6 @@
#include "framework/image.h"
#include "framework/options.h"
#include "framework/renderer.h"
-#include "framework/sound.h"
#include "library/sp.h"
#include
@@ -23,8 +22,8 @@ Control::Control(bool takesFocus)
Size(0, 0), SelectionSize(0, 0), BackgroundColour(0, 0, 0, 0), takesFocus(takesFocus),
showBounds(false), Enabled(true), canCopy(true),
// Tooltip defaults
- ToolTipBackground{128, 128, 128}, ToolTipBorders{
- {1, {0, 0, 0}}, {1, {255, 255, 255}}, {1, {0, 0, 0, 0}}}
+ ToolTipBackground{128, 128, 128},
+ ToolTipBorders{{1, {0, 0, 0}}, {1, {255, 255, 255}}, {1, {0, 0, 0, 0}}}
{
this->ToolTipFont = ui().getFont(Options::defaultTooltipFont.get());
}
diff --git a/forms/forms_pch.h b/forms/forms_pch.h
index aa9734f1c..a402e3b2f 100644
--- a/forms/forms_pch.h
+++ b/forms/forms_pch.h
@@ -2,25 +2,10 @@
#include "dependencies/pugixml/src/pugixml.hpp"
#include "forms/control.h"
-#include "framework/apocresources/apocfont.h"
-#include "framework/configfile.h"
+#include "forms/forms_enums.h"
#include "framework/data.h"
#include "framework/event.h"
-#include "framework/font.h"
#include "framework/framework.h"
#include "framework/image.h"
-#include "framework/keycodes.h"
-#include "framework/logger.h"
#include "framework/renderer.h"
-#include "framework/sound.h"
-#include "framework/trace.h"
-#include "library/colour.h"
-#include "library/sp.h"
-#include "library/strings.h"
-#include "library/strings_format.h"
-#include "library/vec.h"
-#include
-#include
-#include
-#include
-#include
+#include "library/sp.h"
\ No newline at end of file
diff --git a/forms/graphic.cpp b/forms/graphic.cpp
index 40cf60739..82b81903b 100644
--- a/forms/graphic.cpp
+++ b/forms/graphic.cpp
@@ -1,7 +1,6 @@
#include "forms/graphic.h"
#include "dependencies/pugixml/src/pugixml.hpp"
#include "framework/data.h"
-#include "framework/event.h"
#include "framework/framework.h"
#include "framework/image.h"
#include "framework/renderer.h"
diff --git a/forms/label.cpp b/forms/label.cpp
index d637e2e16..7b5eb6a0b 100644
--- a/forms/label.cpp
+++ b/forms/label.cpp
@@ -85,11 +85,12 @@ void Label::setText(const UString &Text)
{
if (text == Text)
return;
+
text = Text;
+
if (scroller)
- {
scroller->setValue(0);
- }
+
this->setDirty();
}
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt
index f4a090ac8..0352e90dc 100644
--- a/framework/CMakeLists.txt
+++ b/framework/CMakeLists.txt
@@ -55,20 +55,13 @@ set (FRAMEWORK_HEADER_FILES
renderer_interface.h
sampleloader_interface.h
serialization/serialize.h
- serialization/providers/filedataprovider.h
- serialization/providers/providerwithchecksum.h
- serialization/providers/zipdataprovider.h
- serialization/providers/serializationdataprovider.h
sound.h
sound_interface.h
stage.h
stagestack.h
- ThreadPool/ThreadPool.h
video.h
- logger_sdldialog.h
- logger_file.h
options.h
- modinfo.h translation.h)
+ modinfo.h)
source_group(framework\\headers FILES ${FRAMEWORK_HEADER_FILES})
list(APPEND ALL_HEADER_FILES ${FRAMEWORK_HEADER_FILES})
@@ -293,3 +286,7 @@ endif()
target_include_directories(OpenApoc_Framework PRIVATE
${CMAKE_SOURCE_DIR}/dependencies/physfs/src)
target_include_directories(OpenApoc_Framework PUBLIC ${CMAKE_SOURCE_DIR})
+
+if (USE_PCH)
+ target_precompile_headers(OpenApoc_Framework PUBLIC framework_pch.h)
+endif()
\ No newline at end of file
diff --git a/framework/configfile.cpp b/framework/configfile.cpp
index ebfba7eb7..e77f09ec4 100644
--- a/framework/configfile.cpp
+++ b/framework/configfile.cpp
@@ -5,7 +5,6 @@
#include "framework/configfile.h"
#include "framework/filesystem.h"
#include "framework/logger.h"
-#include "framework/options.h"
#include
#include
#include
@@ -20,6 +19,11 @@ namespace po = boost::program_options;
namespace OpenApoc
{
+// validate overload required by boost::program_options for UString
+// boost should find this through ADL.
+// this is required for string values with spaces
+void validate(boost::any &v, const std::vector &values, UString *, int);
+
static ConfigFile *configInstance = nullptr;
ConfigFile &ConfigFile::getInstance()
diff --git a/framework/configfile.h b/framework/configfile.h
index 6a7b66ab3..5e07a7484 100644
--- a/framework/configfile.h
+++ b/framework/configfile.h
@@ -2,7 +2,6 @@
#include "library/sp.h"
#include "library/strings.h"
-#include
#include
#include
@@ -112,9 +111,4 @@ class ConfigOptionFloat : public ConfigOption
};
static inline ConfigFile &config() { return ConfigFile::getInstance(); }
-// validate overload required by boost::program_options for UString
-// boost should find this through ADL.
-// this is required for string values with spaces
-void validate(boost::any &v, const std::vector &values, UString *, int);
-
}; // namespace OpenApoc
diff --git a/framework/font.h b/framework/font.h
index b669600d1..784bb7f4f 100644
--- a/framework/font.h
+++ b/framework/font.h
@@ -2,6 +2,8 @@
#include "library/sp.h"
#include "library/strings.h"
+
+#include
#include
namespace OpenApoc
diff --git a/framework/framework.cpp b/framework/framework.cpp
index 4a26b653e..ec69e482c 100644
--- a/framework/framework.cpp
+++ b/framework/framework.cpp
@@ -5,7 +5,6 @@
#include "framework/data.h"
#include "framework/event.h"
#include "framework/filesystem.h"
-#include "framework/font.h"
#include "framework/image.h"
#include "framework/jukebox.h"
#include "framework/logger_file.h"
@@ -891,6 +890,10 @@ void Framework::displayInitialise()
SDL_GetWindowSize(p->window, &width, &height);
p->windowSize = {width, height};
+ auto mouseCapture = Options::mouseCaptureOption.get();
+ SDL_SetWindowMouseGrab(p->window, mouseCapture ? SDL_TRUE : SDL_FALSE);
+ SDL_SetRelativeMouseMode(mouseCapture ? SDL_TRUE : SDL_FALSE);
+
// FIXME: Scale is currently stored as an integer in 1/100 units (ie 100 is 1.0 == same
// size)
int scaleX = Options::screenScaleXOption.get();
diff --git a/framework/framework_pch.h b/framework/framework_pch.h
index 1f767229e..a7e91bf2c 100644
--- a/framework/framework_pch.h
+++ b/framework/framework_pch.h
@@ -1,56 +1,12 @@
#pragma once
-#define WIN32_MEAN_AND_LEAN
-#include "framework/filesystem.h"
+#include "framework/data.h"
#include "framework/framework.h"
-#include "library/colour.h"
-#include "library/line.h"
-#include "library/rect.h"
-#include "library/resource.h"
+#include "framework/image.h"
+#include "framework/logger.h"
+#include "library/sp.h"
#include "library/strings.h"
-#include "library/strings_format.h"
#include "library/vec.h"
-#include "library/voxel.h"
-#include "library/xorshift.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
-
-#undef max
-#undef min
diff --git a/framework/fs.h b/framework/fs.h
index 7060e44b2..682ae1f2e 100644
--- a/framework/fs.h
+++ b/framework/fs.h
@@ -4,6 +4,7 @@
#include "library/strings.h"
#include
#include
+#include
#define PROGRAM_NAME "OpenApoc"
#define PROGRAM_ORGANISATION "OpenApoc"
diff --git a/framework/image.cpp b/framework/image.cpp
index 10939fed1..68983a208 100644
--- a/framework/image.cpp
+++ b/framework/image.cpp
@@ -68,7 +68,7 @@ void PaletteImage::blit(sp src, sp dst, Vec2 size, Colour initialColour)
: Image(size),
- pixels(reinterpret_cast(operator new[](size.x *size.y * sizeof(Colour))))
+ pixels(reinterpret_cast(operator new[](size.x * size.y * sizeof(Colour))))
{
if (initialColour.r == initialColour.g && initialColour.r == initialColour.b &&
initialColour.r == initialColour.a)
diff --git a/framework/jukebox.cpp b/framework/jukebox.cpp
index 46e6163fc..08c53a61a 100644
--- a/framework/jukebox.cpp
+++ b/framework/jukebox.cpp
@@ -6,6 +6,7 @@
#include "framework/sound.h"
#include "library/xorshift.h"
#include
+#include
namespace OpenApoc
{
diff --git a/framework/logger.cpp b/framework/logger.cpp
index a590919aa..92fb15b47 100644
--- a/framework/logger.cpp
+++ b/framework/logger.cpp
@@ -1,8 +1,6 @@
#include "framework/logger.h"
#include "framework/configfile.h"
-#include "framework/framework.h"
#include "library/backtrace.h"
-#include "library/sp.h"
#include
#include
diff --git a/framework/logger.h b/framework/logger.h
index 809eaf419..c889996e0 100644
--- a/framework/logger.h
+++ b/framework/logger.h
@@ -4,7 +4,6 @@
#include "library/strings_format.h"
#include
-#include
#if defined(_MSC_VER) && _MSC_VER > 1400
#include
diff --git a/framework/modinfo.h b/framework/modinfo.h
index d5dcc5a3b..ab578934d 100644
--- a/framework/modinfo.h
+++ b/framework/modinfo.h
@@ -1,6 +1,8 @@
#pragma once
#include "library/strings.h"
+
+#include
#include
namespace OpenApoc
diff --git a/framework/options.cpp b/framework/options.cpp
index 1be7cb332..c9ff3c441 100644
--- a/framework/options.cpp
+++ b/framework/options.cpp
@@ -45,6 +45,7 @@ void dumpOptionsToLog()
dumpOption(screenScaleYOption);
dumpOption(screenAutoScale);
dumpOption(languageOption);
+ dumpOption(mouseCaptureOption);
dumpOption(targetFPS);
dumpOption(frameLimit);
@@ -141,6 +142,7 @@ void dumpOptionsToLog()
dumpOption(optionLoadSameAmmo);
dumpOption(optionShowCurrentDimensionVehicles);
dumpOption(optionShowNonXCOMVehiclesPrefix);
+ dumpOption(isoOnlyFollow);
dumpOption(optionStunHostileAction);
dumpOption(optionRaidHostileAction);
@@ -247,6 +249,9 @@ ConfigOptionBool screenAutoScale(
ConfigOptionString languageOption("Framework", "Language",
"The language used ingame (empty for system default)", "");
+ConfigOptionBool mouseCaptureOption("Framework", "MouseCapture",
+ "Enable mouse capture for the window", false);
+
ConfigOptionInt targetFPS("Framework", "TargetFPS", "The target FPS count - affects game speed!",
60);
ConfigOptionInt frameLimit("Framework", "FrameLimit", "Quit after this many frames - 0 = unlimited",
@@ -347,7 +352,7 @@ ConfigOptionBool optionDebugCommandsVisible("OpenApoc.NewFeature", "DebugCommand
ConfigOptionBool optionUFODamageModel("OpenApoc.NewFeature", "UFODamageModel",
"X-Com 1 Damage model (0-200%)", false);
ConfigOptionBool optionInstantExplosionDamage("OpenApoc.NewFeature", "InstantExplosionDamage",
- "Explosions damage instantly", false);
+ "Explosions damage instantly", true);
ConfigOptionBool optionGravliftSounds("OpenApoc.NewFeature", "GravliftSounds", "Gravlift sounds",
true);
ConfigOptionBool optionNoScrollSounds("OpenApoc.NewFeature", "NoScrollSounds",
@@ -376,7 +381,7 @@ ConfigOptionBool optionAdditionalUnitIcons("OpenApoc.NewFeature", "AdditionalUni
ConfigOptionBool optionAllowForceFiringParallel("OpenApoc.NewFeature", "AllowForceFiringParallel",
"Allow force-firing parallel to the ground", true);
ConfigOptionBool optionRequireLOSToMaintainPsi("OpenApoc.NewFeature", "RequireLOSToMaintainPsi",
- "Require LOS to maintain psi attack", true);
+ "Require LOS to maintain psi attack", false);
ConfigOptionBool optionAllowAttackingOwnedVehicles("OpenApoc.NewFeature",
"AllowAttackingOwnedVehicles",
"Allow attacking owned vehicles", true);
@@ -405,7 +410,7 @@ ConfigOptionBool optionArmoredRoads("OpenApoc.NewFeature", "ArmoredRoads", "Armo
ConfigOptionBool optionVanillaCityControls("OpenApoc.NewFeature", "OpenApocCityControls",
"Improved city control scheme", true);
ConfigOptionBool optionCollapseRaidedBuilding("OpenApoc.NewFeature", "CollapseRaidedBuilding",
- "Successful raid collapses building", true);
+ "Successful raid collapses building", false);
ConfigOptionBool
optionScrambleOnUnintentionalHit("OpenApoc.NewFeature", "ScrambleOnUnintentionalHit",
"Any hit on hostile building provokes retaliation", false);
@@ -421,7 +426,7 @@ ConfigOptionBool optionFuelCrashingVehicles(
ConfigOptionBool optionSkipTurbo("OpenApoc.NewFeature", "SkipTurboMovement",
"Skip turbo movement calculations", false);
ConfigOptionBool optionRunAndKneel("OpenApoc.NewFeature", "RunAndKneel",
- "All units run and kneel by default", false);
+ "All units run and kneel by default", true);
ConfigOptionBool optionSeedRng("OpenApoc.NewFeature", "SeedRng", "Seed RNG on game start", true);
ConfigOptionBool optionAutoReload("OpenApoc.NewFeature", "AutoReload",
"Automatically reload weapons when empty", true);
@@ -435,7 +440,7 @@ ConfigOptionBool optionSingleSquadSelect("OpenApoc.NewFeature", "SingleSquadSele
ConfigOptionBool
optionATVUFOMission("OpenApoc.NewFeature", "ATVUFOMission",
tr("Allow All Terrain Vehicles (ATV) to initiate UFO recovery missions"),
- false);
+ true);
ConfigOptionInt
optionMaxTileRepair("OpenApoc.Mod", "MaxTileRepair",
"Construction Vehicles will repair a maximum of X Tiles per night", 5);
@@ -445,14 +450,15 @@ ConfigOptionFloat
"pay for a Scenery Tile to be repaired",
10.0f);
ConfigOptionBool optionLoadSameAmmo("OpenApoc.NewFeature", "LoadSameAmmo",
- "Weapons autoreload only same ammo type", false);
+ "Weapons autoreload only same ammo type", true);
ConfigOptionBool
optionShowCurrentDimensionVehicles("OpenApoc.NewFeature", "ShowCurrentDimensionVehicles",
"Show vehicles in current dimension (or entering / leaving)",
true);
ConfigOptionBool optionShowNonXCOMVehiclesPrefix("OpenApoc.NewFeature", "ShowNonXCOMVehiclesPrefix",
tr("Add prefix to non-X-COM vehicles"), true);
-
+ConfigOptionBool isoOnlyFollow("OpenApoc.NewFeature", "IsoOnlyFollow",
+ tr("Don't follow vehicles in strategy view"), false);
ConfigOptionBool optionStunHostileAction("OpenApoc.Mod", "StunHostileAction",
"Stunning hurts relationships", false);
ConfigOptionBool optionRaidHostileAction("OpenApoc.Mod", "RaidHostileAction",
diff --git a/framework/options.h b/framework/options.h
index c7b6afe0b..cf1748f45 100644
--- a/framework/options.h
+++ b/framework/options.h
@@ -1,3 +1,5 @@
+#pragma once
+
#include "framework/configfile.h"
namespace OpenApoc::Options
@@ -23,6 +25,7 @@ extern ConfigOptionInt screenScaleXOption;
extern ConfigOptionInt screenScaleYOption;
extern ConfigOptionBool screenAutoScale;
extern ConfigOptionString languageOption;
+extern ConfigOptionBool mouseCaptureOption;
extern ConfigOptionInt frameLimit;
extern ConfigOptionInt targetFPS;
@@ -119,6 +122,7 @@ extern ConfigOptionFloat optionSceneryRepairCostFactor;
extern ConfigOptionBool optionLoadSameAmmo;
extern ConfigOptionBool optionShowCurrentDimensionVehicles;
extern ConfigOptionBool optionShowNonXCOMVehiclesPrefix;
+extern ConfigOptionBool isoOnlyFollow;
extern ConfigOptionBool optionStunHostileAction;
extern ConfigOptionBool optionRaidHostileAction;
diff --git a/framework/renderer.h b/framework/renderer.h
index 28e708fe8..a84ef0074 100644
--- a/framework/renderer.h
+++ b/framework/renderer.h
@@ -52,7 +52,7 @@ class Renderer
virtual void flush() = 0;
virtual UString getName() = 0;
- virtual void newFrame(){};
+ virtual void newFrame() {};
virtual sp getDefaultSurface() = 0;
};
diff --git a/framework/serialization/providers/providerwithchecksum.cpp b/framework/serialization/providers/providerwithchecksum.cpp
index 7e71f4f75..c850e7c59 100644
--- a/framework/serialization/providers/providerwithchecksum.cpp
+++ b/framework/serialization/providers/providerwithchecksum.cpp
@@ -27,11 +27,17 @@ static UString calculateSHA1Checksum(const std::string &str)
boost::uuids::detail::sha1 sha;
sha.process_bytes(str.c_str(), str.size());
+#if BOOST_VERSION >= 108600
+ boost::uuids::detail::sha1::digest_type hash;
+#else
unsigned int hash[5];
+#endif
sha.get_digest(hash);
+ std::array hashu32;
+ memcpy(hashu32.data(), hash, sizeof(hashu32));
for (int i = 0; i < 5; i++)
{
- unsigned int v = hash[i];
+ unsigned int v = hashu32[i];
for (int j = 0; j < 4; j++)
{
// FIXME: Probably need to do the reverse for big endian?
diff --git a/framework/sound.h b/framework/sound.h
index 79b443dff..d07d70f7b 100644
--- a/framework/sound.h
+++ b/framework/sound.h
@@ -5,7 +5,6 @@
#include "library/strings.h"
#include "library/vec.h"
#include
-#include
namespace OpenApoc
{
diff --git a/framework/translation.h b/framework/translation.h
deleted file mode 100644
index abca950e3..000000000
--- a/framework/translation.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include "library/framework.h"
-#include "library/strings.h"
-
-namespace OpenApoc
-{
-
-class LocalizedString
-{
- public:
- UStringView _id;
- UStringView _pleural;
- UStringView _context;
- int _n;
-
- LocalizedString(UStringView id) : _id(id){};
- LocalizedString(UStringView context, UStringView id) : _id(id), _context(context){};
- LocalizedString(UStringView id, UStringView pleural, int n)
- : _id(id), _pleural(pleural), _n(n){};
- LocalizedString(UStringView context, UStringView id, UStringView pleural, int n)
- : _id(id), _pleural(pleural), _context(context), _n(n){};
-};
-
-} // namespace OpenApoc
\ No newline at end of file
diff --git a/game/state/CMakeLists.txt b/game/state/CMakeLists.txt
index b8f343a25..125d482f6 100644
--- a/game/state/CMakeLists.txt
+++ b/game/state/CMakeLists.txt
@@ -257,3 +257,7 @@ add_custom_target(generated-source
DEPENDS
gamestate_serialize_generated.h gamestate_serialize_generated.cpp
luagamestate_support_generated.h luagamestate_support_generated.cpp)
+
+if (USE_PCH)
+ target_precompile_headers(OpenApoc_GameState PUBLIC gamestate_pch.h)
+endif()
\ No newline at end of file
diff --git a/game/state/battle/ai/tacticalai.h b/game/state/battle/ai/tacticalai.h
index e22bdbcd9..b29f203d0 100644
--- a/game/state/battle/ai/tacticalai.h
+++ b/game/state/battle/ai/tacticalai.h
@@ -1,12 +1,10 @@
#pragma once
-#include "float.h"
#include "game/state/battle/ai/aidecision.h"
#include "game/state/gametime.h"
#include "game/state/stateobject.h"
#include "library/sp.h"
#include "library/strings.h"
-#include "library/vec.h"
#include
namespace OpenApoc
@@ -27,8 +25,8 @@ class TacticalAI
virtual ~TacticalAI() = default;
const UString getName();
- virtual void reset(GameState &, StateRef){};
- virtual void beginTurnRoutine(GameState &, StateRef){};
+ virtual void reset(GameState &, StateRef) {};
+ virtual void beginTurnRoutine(GameState &, StateRef) {};
virtual std::list>, AIDecision>>
think(GameState &, StateRef)
{
diff --git a/game/state/battle/ai/tacticalaivanilla.cpp b/game/state/battle/ai/tacticalaivanilla.cpp
index c2097992e..558672c64 100644
--- a/game/state/battle/ai/tacticalaivanilla.cpp
+++ b/game/state/battle/ai/tacticalaivanilla.cpp
@@ -1,4 +1,6 @@
#include "game/state/battle/ai/tacticalaivanilla.h"
+
+#include "game/state/battle/ai/aitype.h"
#include "game/state/battle/ai/unitaihelper.h"
#include "game/state/battle/battle.h"
#include "game/state/battle/battleunit.h"
diff --git a/game/state/battle/ai/tacticalaivanilla.h b/game/state/battle/ai/tacticalaivanilla.h
index 8cf35fceb..377bdb470 100644
--- a/game/state/battle/ai/tacticalaivanilla.h
+++ b/game/state/battle/ai/tacticalaivanilla.h
@@ -1,4 +1,5 @@
#pragma once
+
#include "game/state/battle/ai/tacticalai.h"
namespace OpenApoc
diff --git a/game/state/battle/ai/unitai.h b/game/state/battle/ai/unitai.h
index 7b01c5af4..72774d7e2 100644
--- a/game/state/battle/ai/unitai.h
+++ b/game/state/battle/ai/unitai.h
@@ -29,13 +29,13 @@ class UnitAI
// Whether AI is currently active
bool active = false;
- virtual void reset(GameState &, BattleUnit &){};
+ virtual void reset(GameState &, BattleUnit &) {};
// Returns decision that was made, and whether we should stop going forward on the AI chain
virtual std::tuple think(GameState &, BattleUnit &, bool) { return {}; };
- virtual void routine(GameState &, BattleUnit &){};
+ virtual void routine(GameState &, BattleUnit &) {};
// virtual void reportExecuted(AIAction &action) {};
- virtual void reportExecuted(AIMovement &){};
+ virtual void reportExecuted(AIMovement &) {};
virtual void notifyUnderFire(Vec3){};
virtual void notifyHit(Vec3){};
diff --git a/game/state/battle/ai/unitaihelper.cpp b/game/state/battle/ai/unitaihelper.cpp
index 39eded034..737fd5b16 100644
--- a/game/state/battle/ai/unitaihelper.cpp
+++ b/game/state/battle/ai/unitaihelper.cpp
@@ -3,7 +3,7 @@
#include "game/state/battle/battleunit.h"
#include "game/state/gamestate.h"
#include "game/state/shared/aequipment.h"
-#include
+#include
#include
namespace OpenApoc
diff --git a/game/state/battle/ai/unitaivanilla.cpp b/game/state/battle/ai/unitaivanilla.cpp
index 1ab240868..2746a09a4 100644
--- a/game/state/battle/ai/unitaivanilla.cpp
+++ b/game/state/battle/ai/unitaivanilla.cpp
@@ -1,5 +1,6 @@
#include "game/state/battle/ai/unitaivanilla.h"
#include "game/state/battle/ai/aidecision.h"
+#include "game/state/battle/ai/aitype.h"
#include "game/state/battle/ai/unitaihelper.h"
#include "game/state/battle/battleunit.h"
#include "game/state/gamestate.h"
@@ -8,6 +9,7 @@
#include "game/state/rules/battle/damage.h"
#include "game/state/shared/aequipment.h"
#include "game/state/tilemap/tileobject_battleunit.h"
+#include
namespace OpenApoc
{
diff --git a/game/state/battle/battle.cpp b/game/state/battle/battle.cpp
index 08ac2d620..85e577be8 100644
--- a/game/state/battle/battle.cpp
+++ b/game/state/battle/battle.cpp
@@ -37,7 +37,6 @@
#include "game/state/tilemap/tileobject_battleitem.h"
#include "game/state/tilemap/tileobject_battlemappart.h"
#include "game/state/tilemap/tileobject_battleunit.h"
-#include "game/state/tilemap/tileobject_doodad.h"
#include "game/state/tilemap/tileobject_projectile.h"
#include "game/state/tilemap/tileobject_shadow.h"
#include "library/strings_format.h"
@@ -1023,7 +1022,7 @@ void Battle::initialUnitSpawn(GameState &state)
break;
offset++;
} // end of spawning within a block cycle
- } // end of if we have a position in a set
+ } // end of if we have a position in a set
// If failed to spawn anything, then this block is no longer appropriate
if (numSpawned == 0)
@@ -2567,15 +2566,9 @@ void Battle::finishBattle(GameState &state)
// Recharge all equipment
auto payload = e->getPayloadType();
- if (payload)
+ if (payload && payload->recharge && e->ammo < payload->max_ammo)
{
- if (payload->recharge)
- {
- if (e->ammo < payload->max_ammo)
- {
- e->ammo = payload->max_ammo;
- }
- }
+ e->ammo = payload->max_ammo;
}
}
}
@@ -2689,27 +2682,32 @@ void Battle::finishBattle(GameState &state)
// - give him alien remains
if (state.current_battle->playerWon && !state.current_battle->winnerHasRetreated)
{
- bool playerHasBioStorage = state.current_battle->player_craft &&
- state.current_battle->player_craft->getMaxBio() > 0;
+ const auto baseDefenseWithAlienStorage =
+ isBaseDefenseWithStorage(state, FacilityType::Capacity::Aliens);
+
+ const auto playerVehicles = Battle::getPlayerVehicles(state);
+ const auto playerHasCraftBioStorage = Battle::isBioCarrierPresent(playerVehicles);
+
+ const auto playerHasAlienStorage = playerHasCraftBioStorage || baseDefenseWithAlienStorage;
+
// Live alien loot
for (auto &u : liveAliens)
{
if (u->agent->type->liveSpeciesItem)
{
- if (playerHasBioStorage)
+ if (playerHasAlienStorage)
{
state.current_battle->score.liveAlienCaptured +=
u->agent->type->liveSpeciesItem->score;
}
+
if (u->agent->type->liveSpeciesItem->bioStorage)
{
- state.current_battle->bioLoot[u->agent->type->liveSpeciesItem] =
- state.current_battle->bioLoot[u->agent->type->liveSpeciesItem] + 1;
+ state.current_battle->bioLoot[u->agent->type->liveSpeciesItem] += 1;
}
else
{
- state.current_battle->cargoLoot[u->agent->type->liveSpeciesItem] =
- state.current_battle->cargoLoot[u->agent->type->liveSpeciesItem] + 1;
+ state.current_battle->cargoLoot[u->agent->type->liveSpeciesItem] += 1;
}
}
else
@@ -2725,13 +2723,11 @@ void Battle::finishBattle(GameState &state)
{
if (u->agent->type->deadSpeciesItem->bioStorage)
{
- state.current_battle->bioLoot[u->agent->type->deadSpeciesItem] =
- state.current_battle->bioLoot[u->agent->type->deadSpeciesItem] + 1;
+ state.current_battle->bioLoot[u->agent->type->deadSpeciesItem] += 1;
}
else
{
- state.current_battle->cargoLoot[u->agent->type->deadSpeciesItem] =
- state.current_battle->cargoLoot[u->agent->type->deadSpeciesItem] + 1;
+ state.current_battle->cargoLoot[u->agent->type->deadSpeciesItem] += 1;
}
}
}
@@ -2774,8 +2770,7 @@ void Battle::finishBattle(GameState &state)
{
for (auto &a : liveAliens)
{
- location->current_crew[a->agent->type] =
- location->current_crew[a->agent->type] + 1;
+ location->current_crew[a->agent->type] += 1;
}
}
else
@@ -2793,15 +2788,15 @@ void Battle::finishBattle(GameState &state)
{
state.current_battle->score.equipmentCaptured += e->type->score;
}
+
int mult = e->type->type == AEquipmentType::Type::Ammo ? e->ammo : 1;
if (e->type->bioStorage)
{
- state.current_battle->bioLoot[e->type] = state.current_battle->bioLoot[e->type] + mult;
+ state.current_battle->bioLoot[e->type] += mult;
}
else
{
- state.current_battle->cargoLoot[e->type] =
- state.current_battle->cargoLoot[e->type] + mult;
+ state.current_battle->cargoLoot[e->type] += mult;
}
}
// Regardless of what happened, retreated aliens go to a nearby building
@@ -2843,8 +2838,7 @@ void Battle::finishBattle(GameState &state)
}
for (auto &a : retreatedAliens)
{
- closestBuilding->current_crew[a->agent->type] =
- closestBuilding->current_crew[a->agent->type] + 1;
+ closestBuilding->current_crew[a->agent->type] += 1;
}
}
// Remove dead player agents and all enemy agents from the game and from vehicles
@@ -3031,50 +3025,13 @@ void Battle::exitBattle(GameState &state)
// LOOT!
// Compile list of player vehicles
- std::list> playerVehicles;
+ auto playerVehicles = Battle::getPlayerVehicles(state);
std::set> returningVehicles;
+
if (state.current_battle->player_craft)
{
- playerVehicles.push_back(state.current_battle->player_craft);
returningVehicles.insert(state.current_battle->player_craft);
}
- if (config().getBool("OpenApoc.NewFeature.AllowNearbyVehicleLootPickup"))
- {
- if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery)
- {
- StateRef city;
- StateRef location = {&state, state.current_battle->mission_location_id};
- city = location->city;
-
- for (auto &v : state.vehicles)
- {
- // Check every player owned vehicle located in city
- if (v.second->owner != player || v.second->city != city ||
- v.second->currentBuilding
- // Player's vehicle was already added and has priority
- || v.first == state.current_battle->player_craft.id)
- {
- continue;
- }
- if (glm::length(location->position - v.second->position) < VEHICLE_NEARBY_THRESHOLD)
- {
- playerVehicles.emplace_back(&state, v.first);
- }
- }
- }
- else
- {
- StateRef location = {&state, state.current_battle->mission_location_id};
- for (auto &v : location->currentVehicles)
- {
- // Player's vehicle was already added and has priority
- if (v->owner == player && v != state.current_battle->player_craft)
- {
- playerVehicles.push_back(v);
- }
- }
- }
- }
// List of vehicle loot
std::map, int> vehicleLoot;
@@ -3110,20 +3067,14 @@ void Battle::exitBattle(GameState &state)
// If player has vehicle with bio capacity then all bio loot goes to leftover loot
// This is regardless of "enforce limits" which only makes us enforce it
// on vehicles that have capacity in the first place
- bool bioCarrierPresent = false;
- bool cargoCarrierPresent = false;
- for (auto &v : playerVehicles)
- {
- if (v->getMaxCargo() > 0)
- {
- cargoCarrierPresent = true;
- }
- if (v->getMaxBio() > 0)
- {
- bioCarrierPresent = true;
- }
- }
- if (!cargoCarrierPresent)
+ const auto cargoCarrierPresent = Battle::isCargoCarrierPresent(playerVehicles);
+ const auto bioCarrierPresent = Battle::isBioCarrierPresent(playerVehicles);
+ const auto baseDefenseWithItemStorage =
+ isBaseDefenseWithStorage(state, FacilityType::Capacity::Stores);
+ const auto baseDefenseWithAlienStorage =
+ isBaseDefenseWithStorage(state, FacilityType::Capacity::Aliens);
+
+ if (!cargoCarrierPresent && !baseDefenseWithItemStorage)
{
for (auto &e : state.current_battle->cargoLoot)
{
@@ -3135,7 +3086,7 @@ void Battle::exitBattle(GameState &state)
}
state.current_battle->cargoLoot.clear();
}
- if (!bioCarrierPresent)
+ if (!bioCarrierPresent && !baseDefenseWithAlienStorage)
{
for (auto &e : state.current_battle->bioLoot)
{
@@ -3148,39 +3099,81 @@ void Battle::exitBattle(GameState &state)
if (!leftoverBioLoot.empty())
{
// Bio loot is wasted if can't be loaded on player craft
+ LogWarning("Bio loot remaining");
}
// Cargo loot remaining?
- if (leftoverCargoLoot.empty())
+ if (leftoverCargoLoot.empty() &&
+ config().getBool("OpenApoc.NewFeature.AllowBuildingLootDeposit"))
{
- if (config().getBool("OpenApoc.NewFeature.AllowBuildingLootDeposit"))
+ if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery)
{
- if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery)
+ // Still can't do anything if we're recovering UFO
+ LogWarning("AllowBuildingLootDeposit and UfoRecovery mission type");
+ }
+ else
+ {
+ // Deposit loot into building, call for pickup
+ StateRef location = {&state, state.current_battle->mission_location_id};
+ auto homeBuilding =
+ playerVehicles.empty() ? nullptr : playerVehicles.front()->homeBuilding;
+ if (!homeBuilding)
{
- // Still can't do anything if we're recovering UFO
+ homeBuilding = state.player_bases.begin()->second->building;
}
- else
+
+ // Main loop only starts with leftoverCargoLoot.empty()
+ // This means that the following inner loop will NEVER be executed!
+ // TODO: check if this can be removed
+ for (auto &e : leftoverCargoLoot)
{
- // Deposit loot into building, call for pickup
- StateRef location = {&state, state.current_battle->mission_location_id};
- auto homeBuilding =
- playerVehicles.empty() ? nullptr : playerVehicles.front()->homeBuilding;
- if (!homeBuilding)
- {
- homeBuilding = state.player_bases.begin()->second->building;
- }
- for (auto &e : leftoverCargoLoot)
- {
- int price = 0;
- location->cargo.emplace_back(state, e.first, e.second, price, nullptr,
- homeBuilding);
- }
- for (auto &e : leftoverVehicleLoot)
- {
- int price = 0;
- location->cargo.emplace_back(state, e.first, e.second, price, nullptr,
- homeBuilding);
- }
+ int price = 0;
+ location->cargo.emplace_back(state, e.first, e.second, price, nullptr,
+ homeBuilding);
+ }
+ for (auto &e : leftoverVehicleLoot)
+ {
+ int price = 0;
+ location->cargo.emplace_back(state, e.first, e.second, price, nullptr,
+ homeBuilding);
+ }
+ }
+ }
+
+ // Base defense missions only check for vehicles if no storage is available
+ // Items saved in this condition must NOT be saved again into vehicles!
+ if (state.current_battle->mission_type == Battle::MissionType::BaseDefense)
+ {
+ const auto defendedBase = getCurrentDefendedBase(state);
+
+ const auto lootTypeList = {
+ std::tuple(FacilityType::Capacity::Stores, &state.current_battle->cargoLoot,
+ &defendedBase->inventoryAgentEquipment),
+ std::tuple(FacilityType::Capacity::Aliens, &state.current_battle->bioLoot,
+ &defendedBase->inventoryBioEquipment)};
+
+ for (const auto &lootType : lootTypeList)
+ {
+ const auto facilityTypeEnum = std::get<0>(lootType);
+ auto &lootList = *std::get<1>(lootType);
+ auto &inventoryEquipment = *std::get<2>(lootType);
+
+ if (!isBaseDefenseWithStorage(state, facilityTypeEnum))
+ continue;
+
+ std::list> lootToRemove = {};
+
+ for (const auto &loot : lootList)
+ {
+ if (loot.second > 0)
+ inventoryEquipment[loot.first.id] += loot.second;
+
+ lootToRemove.push_back(loot.first);
+ }
+
+ for (const auto &loot : lootToRemove)
+ {
+ lootList.erase(loot);
}
}
}
@@ -3366,12 +3359,9 @@ void Battle::exitBattle(GameState &state)
}
}
- // Give player vehicle a null cargo just so it comes back to base once
- for (auto v : playerVehicles)
+ // Sending vehicles back to base
+ for (auto &v : playerVehicles)
{
- v->cargo.emplace_front(
- state, StateRef(&state, state.agent_equipment.begin()->first), 0, 0,
- nullptr, v->homeBuilding);
if (v->city.id == "CITYMAP_HUMAN")
{
v->setMission(state, VehicleMission::gotoBuilding(state, *v));
@@ -3481,6 +3471,38 @@ void Battle::exitBattle(GameState &state)
state.cleanUpDeathNote();
}
+sp Battle::getCurrentDefendedBase(GameState &state)
+{
+ if (state.current_battle->mission_type != Battle::MissionType::BaseDefense)
+ return {};
+
+ for (const auto &base : state.player_bases)
+ {
+ if (base.first == state.current_base.id)
+ return base.second;
+ }
+
+ return {};
+}
+
+bool Battle::isBaseDefenseWithStorage(GameState &state, const FacilityType::Capacity capacityType)
+{
+ // Check if mission is base defense, and defended base has alien containment facility to store
+ // live aliens from battle
+ if (state.current_battle->mission_type != Battle::MissionType::BaseDefense)
+ return false;
+
+ const auto defendedBase = getCurrentDefendedBase(state);
+
+ // If base not found
+ if (!defendedBase)
+ return false;
+
+ const auto availableStorageAtBase = defendedBase->getCapacityTotal(capacityType) > 0;
+
+ return availableStorageAtBase;
+}
+
void Battle::loadResources(GameState &state)
{
battle_map->loadTilesets(state);
@@ -3766,6 +3788,88 @@ void Battle::loadMessages(GameState &state)
}
}
+const std::list> Battle::getPlayerVehicles(GameState &state)
+{
+ std::list> playerVehicles;
+ const auto playerCraft = state.current_battle->player_craft;
+
+ if (playerCraft)
+ {
+ playerVehicles.push_back(playerCraft);
+ }
+
+ if (config().getBool("OpenApoc.NewFeature.AllowNearbyVehicleLootPickup"))
+ {
+ if (state.current_battle->mission_type == Battle::MissionType::UfoRecovery)
+ {
+ StateRef city;
+ StateRef location = {&state, state.current_battle->mission_location_id};
+ city = location->city;
+
+ for (const auto &v : state.vehicles)
+ {
+ // Check every player owned vehicle located in city
+ const auto isVehiclePlayerOwned = v.second->owner == state.player;
+ const auto isVehicleInTheCity =
+ v.second->city == city && !v.second->currentBuilding;
+
+ // Player's vehicle was already added and has priority
+ const auto isVehiclePlayerCraft = v.first == playerCraft.id;
+
+ if (!isVehiclePlayerOwned || !isVehicleInTheCity || isVehiclePlayerCraft)
+ {
+ continue;
+ }
+
+ if (glm::length(location->position - v.second->position) < VEHICLE_NEARBY_THRESHOLD)
+ {
+ playerVehicles.emplace_back(&state, v.first);
+ }
+ }
+ }
+ else
+ {
+ StateRef location = {&state, state.current_battle->mission_location_id};
+ for (const auto &v : location->currentVehicles)
+ {
+ // Player's vehicle was already added and has priority
+ if (v->owner == state.player && v != playerCraft)
+ {
+ playerVehicles.push_back(v);
+ }
+ }
+ }
+ }
+
+ return playerVehicles;
+}
+
+const bool Battle::isCargoCarrierPresent(const std::list> &playerVehicles)
+{
+ for (const auto &v : playerVehicles)
+ {
+ if (v->getMaxCargo() > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+const bool Battle::isBioCarrierPresent(const std::list> &playerVehicles)
+{
+ for (const auto &v : playerVehicles)
+ {
+ if (v->getMaxBio() > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
int BattleScore::getLeadershipBonus()
{
return (100 + 3 * casualtyPenalty) * (combatRating + friendlyFire + liveAlienCaptured) / 100;
diff --git a/game/state/battle/battle.h b/game/state/battle/battle.h
index 447d49663..d73c62b06 100644
--- a/game/state/battle/battle.h
+++ b/game/state/battle/battle.h
@@ -1,8 +1,8 @@
#pragma once
-#include "game/state/battle/ai/aitype.h"
#include "game/state/battle/ai/tacticalai.h"
#include "game/state/battle/battleforces.h"
+#include "game/state/city/base.h"
#include "game/state/gametime.h"
#include "game/state/rules/agenttype.h"
#include "game/state/rules/battle/battlemapsector.h"
@@ -328,6 +328,15 @@ class Battle : public std::enable_shared_from_this
// To be called after battle was finished and before returning to cityscape
static void exitBattle(GameState &state);
+ // Get list of player vehicles in battle
+ static const std::list> getPlayerVehicles(GameState &state);
+
+ // Check if cargo carrier is present at player vehicles list
+ static const bool isCargoCarrierPresent(const std::list> &playerVehicles);
+
+ // Check if bio carrier is present at player vehicles list
+ static const bool isBioCarrierPresent(const std::list> &playerVehicles);
+
// Pathfinding functions
public:
@@ -351,6 +360,13 @@ class Battle : public std::enable_shared_from_this
bool approachOnly = false, bool ignoreStaticUnits = false, bool ignoreMovingUnits = true,
bool ignoreAllUnits = false, float *cost = nullptr, float maxCost = 0.0f);
+ // Returns defended base if mission is base defense, returns null otherwise
+ static sp getCurrentDefendedBase(GameState &state);
+
+ // Check if mission is base defense and has storage for specified capacity type
+ static bool isBaseDefenseWithStorage(GameState &state,
+ const FacilityType::Capacity capacityType);
+
private:
void loadResources(GameState &state);
void unloadResources(GameState &state);
diff --git a/game/state/battle/battledoor.cpp b/game/state/battle/battledoor.cpp
index c73bec795..39e89d17b 100644
--- a/game/state/battle/battledoor.cpp
+++ b/game/state/battle/battledoor.cpp
@@ -9,7 +9,6 @@
#include "game/state/rules/battle/battlemapparttype.h"
#include "game/state/tilemap/tilemap.h"
#include "game/state/tilemap/tileobject_battlemappart.h"
-#include "game/state/tilemap/tileobject_battleunit.h"
namespace OpenApoc
{
diff --git a/game/state/battle/battleexplosion.cpp b/game/state/battle/battleexplosion.cpp
index 51de4c224..6ba5feb92 100644
--- a/game/state/battle/battleexplosion.cpp
+++ b/game/state/battle/battleexplosion.cpp
@@ -1,8 +1,6 @@
#include "game/state/battle/battleexplosion.h"
#include "framework/configfile.h"
#include "framework/framework.h"
-#include "framework/logger.h"
-#include "framework/sound.h"
#include "game/state/battle/battle.h"
#include "game/state/battle/battlehazard.h"
#include "game/state/battle/battleitem.h"
diff --git a/game/state/battle/battlehazard.cpp b/game/state/battle/battlehazard.cpp
index 84f600043..af0d1a606 100644
--- a/game/state/battle/battlehazard.cpp
+++ b/game/state/battle/battlehazard.cpp
@@ -1,7 +1,6 @@
#include "game/state/battle/battlehazard.h"
#include "framework/framework.h"
#include "framework/logger.h"
-#include "framework/sound.h"
#include "game/state/battle/battle.h"
#include "game/state/battle/battleitem.h"
#include "game/state/battle/battlemappart.h"
@@ -10,7 +9,6 @@
#include "game/state/rules/battle/battlemapparttype.h"
#include "game/state/rules/battle/damage.h"
#include "game/state/rules/doodadtype.h"
-#include "game/state/shared/aequipment.h"
#include "game/state/tilemap/tilemap.h"
#include "game/state/tilemap/tileobject_battlehazard.h"
#include "game/state/tilemap/tileobject_battleitem.h"
diff --git a/game/state/battle/battleitem.cpp b/game/state/battle/battleitem.cpp
index d688668d2..9c9c9ed8e 100644
--- a/game/state/battle/battleitem.cpp
+++ b/game/state/battle/battleitem.cpp
@@ -7,7 +7,6 @@
#include "game/state/battle/battleunit.h"
#include "game/state/gamestate.h"
#include "game/state/rules/aequipmenttype.h"
-#include "game/state/rules/battle/battlecommonsamplelist.h"
#include "game/state/rules/battle/damage.h"
#include "game/state/shared/aequipment.h"
#include "game/state/tilemap/collision.h"
diff --git a/game/state/battle/battlescanner.h b/game/state/battle/battlescanner.h
index cd3a0ebbf..245ec746c 100644
--- a/game/state/battle/battlescanner.h
+++ b/game/state/battle/battlescanner.h
@@ -3,7 +3,6 @@
#include "game/state/battle/battle.h"
#include "game/state/gametime.h"
#include "game/state/stateobject.h"
-#include "library/sp.h"
#include "library/vec.h"
#include
diff --git a/game/state/battle/battleunit.cpp b/game/state/battle/battleunit.cpp
index d9dc5caf9..6f01f23a8 100644
--- a/game/state/battle/battleunit.cpp
+++ b/game/state/battle/battleunit.cpp
@@ -5,6 +5,7 @@
#include "framework/configfile.h"
#include "framework/framework.h"
#include "framework/sound.h"
+#include "game/state/battle/ai/aitype.h"
#include "game/state/battle/ai/unitaihelper.h"
#include "game/state/battle/battle.h"
#include "game/state/battle/battleitem.h"
@@ -13,13 +14,11 @@
#include "game/state/rules/battle/battlecommonsamplelist.h"
#include "game/state/rules/battle/battleunitanimationpack.h"
#include "game/state/rules/battle/damage.h"
-#include "game/state/rules/city/facilitytype.h"
#include "game/state/shared/aequipment.h"
#include "game/state/shared/projectile.h"
#include "game/state/tilemap/collision.h"
#include "game/state/tilemap/tileobject_battleunit.h"
#include "game/state/tilemap/tileobject_shadow.h"
-#include "library/line.h"
#include "library/strings_format.h"
#include
#include
@@ -3839,6 +3838,7 @@ void BattleUnit::triggerBrainsuckers(GameState &state)
state.current_battle->spawnUnit(state, aliens, {&state, "AGENTTYPE_BRAINSUCKER"},
i->position, {0, 1}, BodyState::Throwing);
i->die(state, false);
+ state.current_battle->checkMissionEnd(state, false, true);
}
}
}
diff --git a/game/state/battle/battleunitmission.cpp b/game/state/battle/battleunitmission.cpp
index 49629d15a..02cd94487 100644
--- a/game/state/battle/battleunitmission.cpp
+++ b/game/state/battle/battleunitmission.cpp
@@ -3,7 +3,6 @@
#include "framework/sound.h"
#include "game/state/battle/battleitem.h"
#include "game/state/battle/battleunit.h"
-#include "game/state/gameevent.h"
#include "game/state/gamestate.h"
#include "game/state/rules/aequipmenttype.h"
#include "game/state/rules/battle/battlecommonsamplelist.h"
@@ -2054,7 +2053,7 @@ void BattleUnitMission::setPathTo(GameState &state, BattleUnit &u, Vec3 tar
auto path = state.current_battle->findShortestPath(
u.goalPosition, target, BattleUnitTileHelper{map, u}, approachOnly, demandGiveWay,
- !blockedByMovingUnit);
+ !blockedByMovingUnit, TileMap::MAX_ITERATION_LIMIT_DIRECT_FOR_BATTLE);
// Cancel movement if the closest path ends at the current position
if (path.size() == 1 && path.back() == Vec3{u.position})
diff --git a/game/state/city/agentmission.cpp b/game/state/city/agentmission.cpp
index 4aa52a54d..b0986a9f0 100644
--- a/game/state/city/agentmission.cpp
+++ b/game/state/city/agentmission.cpp
@@ -10,12 +10,7 @@
#include "game/state/rules/battle/battlecommonsamplelist.h"
#include "game/state/rules/city/scenerytiletype.h"
#include "game/state/shared/agent.h"
-#include "game/state/shared/doodad.h"
-#include "game/state/shared/organisation.h"
#include "game/state/tilemap/tilemap.h"
-#include "game/state/tilemap/tileobject_doodad.h"
-#include "game/state/tilemap/tileobject_scenery.h"
-#include "game/state/tilemap/tileobject_shadow.h"
#include "library/strings_format.h"
#include
diff --git a/game/state/city/agentmission.h b/game/state/city/agentmission.h
index 705c4f8d2..93f987adf 100644
--- a/game/state/city/agentmission.h
+++ b/game/state/city/agentmission.h
@@ -5,7 +5,6 @@
#include "library/strings.h"
#include "library/vec.h"
#include
-#include
namespace OpenApoc
{
diff --git a/game/state/city/base.cpp b/game/state/city/base.cpp
index dbf557568..85cdab918 100644
--- a/game/state/city/base.cpp
+++ b/game/state/city/base.cpp
@@ -1,4 +1,5 @@
#include "game/state/city/base.h"
+#include "dependencies/magic_enum/include/magic_enum/magic_enum.hpp"
#include "framework/framework.h"
#include "game/state/city/building.h"
#include "game/state/city/city.h"
@@ -282,86 +283,97 @@ Base::BuildError Base::canBuildFacility(StateRef type, Vec2 p
void Base::buildFacility(GameState &state, StateRef type, Vec2 pos, bool free)
{
- if (canBuildFacility(type, pos, free) == BuildError::NoError)
+ const auto canBuildFacilityResult = canBuildFacility(type, pos, free);
+
+ if (canBuildFacilityResult != BuildError::NoError)
+ {
+ const auto canBuildFacilityEnum = magic_enum::enum_name(canBuildFacilityResult);
+ const auto logMessage =
+ format("Error when trying to build facility: %s", canBuildFacilityEnum);
+ LogWarning(logMessage);
+ return;
+ }
+
+ auto facility = mksp(type);
+ facilities.push_back(facility);
+ facility->pos = pos;
+ if (!free)
{
- auto facility = mksp(type);
- facilities.push_back(facility);
- facility->pos = pos;
- if (!free)
+ if (!building)
{
- if (!building)
- {
- LogError("Building disappeared");
- }
- else
- {
- building->owner->balance -= type->buildCost;
- }
- facility->buildTime = type->buildTime;
+ LogError("Building disappeared");
}
- if (type->capacityAmount > 0)
+ else
{
- ResearchTopic::LabSize size;
- // FIXME: Make LabSize set-able outside of the facility size?
- if (type->size > 1)
+ building->owner->balance -= type->buildCost;
+ }
+ facility->buildTime = type->buildTime;
+ }
+ if (type->capacityAmount > 0)
+ {
+ ResearchTopic::LabSize size;
+ // FIXME: Make LabSize set-able outside of the facility size?
+ if (type->size > 1)
+ {
+ size = ResearchTopic::LabSize::Large;
+ }
+ else
+ {
+ size = ResearchTopic::LabSize::Small;
+ }
+ switch (type->capacityType)
+ {
+ case FacilityType::Capacity::Chemistry:
{
- size = ResearchTopic::LabSize::Large;
+ auto lab = mksp();
+ lab->size = size;
+ lab->type = ResearchTopic::Type::BioChem;
+ auto id = Lab::generateObjectID(state);
+ state.research.labs[id] = lab;
+ facility->lab = {&state, id};
+ break;
}
- else
+ case FacilityType::Capacity::Physics:
{
- size = ResearchTopic::LabSize::Small;
+ auto lab = mksp();
+ lab->size = size;
+ lab->type = ResearchTopic::Type::Physics;
+ auto id = Lab::generateObjectID(state);
+ state.research.labs[id] = lab;
+ facility->lab = {&state, id};
+ break;
}
- switch (type->capacityType)
+ case FacilityType::Capacity::Workshop:
{
- case FacilityType::Capacity::Chemistry:
- {
- auto lab = mksp();
- lab->size = size;
- lab->type = ResearchTopic::Type::BioChem;
- auto id = Lab::generateObjectID(state);
- state.research.labs[id] = lab;
- facility->lab = {&state, id};
- break;
- }
- case FacilityType::Capacity::Physics:
- {
- auto lab = mksp();
- lab->size = size;
- lab->type = ResearchTopic::Type::Physics;
- auto id = Lab::generateObjectID(state);
- state.research.labs[id] = lab;
- facility->lab = {&state, id};
- break;
- }
- case FacilityType::Capacity::Workshop:
- {
- auto lab = mksp();
- lab->size = size;
- lab->type = ResearchTopic::Type::Engineering;
- auto id = Lab::generateObjectID(state);
- state.research.labs[id] = lab;
- facility->lab = {&state, id};
- break;
- }
- default:
- // Non-lab modules don't need special handling
- break;
+ auto lab = mksp();
+ lab->size = size;
+ lab->type = ResearchTopic::Type::Engineering;
+ auto id = Lab::generateObjectID(state);
+ state.research.labs[id] = lab;
+ facility->lab = {&state, id};
+ break;
}
+ default:
+ // Non-lab modules don't need special handling
+ break;
}
}
}
Base::BuildError Base::canDestroyFacility(GameState &state, Vec2 pos) const
{
- auto facility = getFacility(pos);
+ const auto facility = getFacility(pos);
+
if (facility == nullptr)
{
return BuildError::OutOfBounds;
}
+
if (facility->type->fixed)
{
return BuildError::Indestructible;
}
+
if (facility->buildTime > 0)
{
return BuildError::NoError;
@@ -372,21 +384,23 @@ Base::BuildError Base::canDestroyFacility(GameState &state, Vec2 pos) const
case FacilityType::Capacity::Quarters:
case FacilityType::Capacity::Stores:
case FacilityType::Capacity::Aliens:
- if (getCapacityUsed(state, facility->type->capacityType) >
- getCapacityTotal(facility->type->capacityType) - facility->type->capacityAmount)
+ {
+ const auto capacityUsed = getCapacityUsed(state, facility->type->capacityType);
+ const auto capacityTotal = getCapacityTotal(facility->type->capacityType);
+ const auto capacityAmount = facility->type->capacityAmount;
+
+ if (capacityUsed > capacityTotal - capacityAmount)
{
return BuildError::Occupied;
}
break;
+ }
case FacilityType::Capacity::Physics:
case FacilityType::Capacity::Chemistry:
case FacilityType::Capacity::Workshop:
- if (facility->lab)
+ if (facility->lab && facility->lab->current_project)
{
- if (facility->lab->current_project)
- {
- return BuildError::Occupied;
- }
+ return BuildError::Occupied;
}
break;
default:
@@ -397,46 +411,63 @@ Base::BuildError Base::canDestroyFacility(GameState &state, Vec2 pos) const
void Base::destroyFacility(GameState &state, Vec2 pos)
{
- if (canDestroyFacility(state, pos) == BuildError::NoError)
+ const auto canDestroyFacilityResult = canDestroyFacility(state, pos);
+
+ if (canDestroyFacilityResult != BuildError::NoError)
+ {
+ const auto canDestroyFacilityEnum = magic_enum::enum_name(canDestroyFacilityResult);
+ const auto logMessage =
+ format("Error when trying to destroy facility: %s", canDestroyFacilityEnum);
+ LogWarning(logMessage);
+ return;
+ }
+
+ const auto facility = getFacility(pos);
+
+ for (auto f = facilities.begin(); f != facilities.end(); ++f)
{
- auto facility = getFacility(pos);
- for (auto f = facilities.begin(); f != facilities.end(); ++f)
+ if (*f != facility)
+ continue;
+
+ if (facility->lab)
{
- if (*f == facility)
+ for (auto &a : facility->lab->assigned_agents)
{
- if (facility->lab)
- {
- auto id = facility->lab.id;
- if (facility->lab->current_project)
- {
- facility->lab->current_project->current_lab = "";
- facility->lab->current_project = "";
- }
- facility->lab = "";
- state.research.labs.erase(id);
- }
- if (facility->type->buildTime > 0)
- {
- building->owner->balance +=
- facility->type->buildCost * facility->buildTime / facility->type->buildTime;
- }
- facilities.erase(f);
- break;
+ a->assigned_to_lab = false;
+ }
+ if (facility->lab->current_project)
+ {
+ facility->lab->current_project->current_lab = "";
+ facility->lab->current_project = "";
}
+ facility->lab = "";
+ state.research.labs.erase(facility->lab.id);
}
+
+ if (facility->type->buildTime > 0)
+ {
+ building->owner->balance +=
+ facility->type->buildCost * facility->buildTime / facility->type->buildTime;
+ }
+
+ facilities.erase(f);
+ break;
}
}
-bool Base::containmentEmpty(GameState &state)
+bool Base::alienContainmentExists() const
{
- for (auto &f : facilities)
+ return getCapacityTotal(FacilityType::Capacity::Aliens) > 0;
+}
+
+bool Base::alienContainmentIsEmpty(GameState &state)
+{
+ for (const auto &f : facilities)
{
- if (f->type->capacityType == FacilityType::Capacity::Aliens)
+ if (f->type->capacityType == FacilityType::Capacity::Aliens &&
+ getCapacityUsed(state, f->type->capacityType) != 0)
{
- if (getCapacityUsed(state, f->type->capacityType) != 0)
- {
- return false;
- }
+ return false;
}
}
return true;
@@ -448,35 +479,35 @@ int Base::getCapacityUsed(GameState &state, FacilityType::Capacity type) const
switch (type)
{
case FacilityType::Capacity::Repair:
- for (auto &v : state.vehicles)
+ for (const auto &v : state.vehicles)
{
- if (v.second->homeBuilding == building &&
- v.second->getMaxHealth() > v.second->getHealth())
+ const auto maxHealth = v.second->getMaxHealth();
+ const auto health = v.second->getHealth();
+
+ if (v.second->homeBuilding == building && maxHealth > health)
{
- total += v.second->getMaxHealth() - v.second->getHealth();
+ total += maxHealth - health;
}
}
// Show percentage of repair bay used if it can repair in one hour, or 100% if can't
if (total > 0)
{
- int max = getCapacityTotal(type);
+ const auto max = getCapacityTotal(type);
return std::min(total, max);
}
break;
case FacilityType::Capacity::Medical:
- for (auto &a : state.agents)
+ for (const auto &a : state.agents)
{
- if (a.second->homeBuilding == building)
+ if (a.second->homeBuilding == building &&
+ a.second->modified_stats.health < a.second->current_stats.health)
{
- if (a.second->modified_stats.health < a.second->current_stats.health)
- {
- total++;
- }
+ total++;
}
}
break;
case FacilityType::Capacity::Training:
- for (auto &a : state.agents)
+ for (const auto &a : state.agents)
{
if (a.second->homeBuilding == building &&
a.second->trainingAssignment == TrainingAssignment::Physical)
@@ -486,7 +517,7 @@ int Base::getCapacityUsed(GameState &state, FacilityType::Capacity type) const
}
break;
case FacilityType::Capacity::Psi:
- for (auto &a : state.agents)
+ for (const auto &a : state.agents)
{
if (a.second->homeBuilding == building &&
a.second->trainingAssignment == TrainingAssignment::Psi)
@@ -500,16 +531,16 @@ int Base::getCapacityUsed(GameState &state, FacilityType::Capacity type) const
case FacilityType::Capacity::Physics:
[[fallthrough]];
case FacilityType::Capacity::Workshop:
- for (auto f = facilities.begin(); f != facilities.end(); ++f)
+ for (const auto &f : facilities)
{
- if ((*f)->type->capacityType == type && (*f)->lab)
+ if (f->type->capacityType == type && f->lab)
{
- total += (int)(*f)->lab->assigned_agents.size();
+ total += (int)f->lab->assigned_agents.size();
}
}
break;
case FacilityType::Capacity::Quarters:
- for (auto &a : state.agents)
+ for (const auto &a : state.agents)
{
if (a.second->homeBuilding == building)
{
@@ -518,19 +549,19 @@ int Base::getCapacityUsed(GameState &state, FacilityType::Capacity type) const
}
break;
case FacilityType::Capacity::Stores:
- for (auto &e : inventoryAgentEquipment)
+ for (const auto &e : inventoryAgentEquipment)
{
StateRef ae = {&state, e.first};
total += ae->type == AEquipmentType::Type::Ammo
? ae->store_space * ((e.second + ae->max_ammo - 1) / ae->max_ammo)
: ae->store_space * e.second;
}
- for (auto &e : inventoryVehicleEquipment)
+ for (const auto &e : inventoryVehicleEquipment)
{
StateRef ve = {&state, e.first};
total += ve->store_space * e.second;
}
- for (auto &e : inventoryVehicleAmmo)
+ for (const auto &e : inventoryVehicleAmmo)
{
StateRef va = {&state, e.first};
total += va->store_space * e.second;
@@ -538,7 +569,7 @@ int Base::getCapacityUsed(GameState &state, FacilityType::Capacity type) const
break;
case FacilityType::Capacity::Aliens:
{
- for (auto &e : inventoryBioEquipment)
+ for (const auto &e : inventoryBioEquipment)
{
if (e.second == 0)
continue;
@@ -559,11 +590,11 @@ int Base::getCapacityUsed(GameState &state, FacilityType::Capacity type) const
int Base::getCapacityTotal(FacilityType::Capacity type) const
{
int total = 0;
- for (auto f = facilities.begin(); f != facilities.end(); ++f)
+ for (const auto &f : facilities)
{
- if ((*f)->type->capacityType == type && (*f)->buildTime == 0)
+ if (f->type->capacityType == type && f->buildTime == 0)
{
- total += (*f)->type->capacityAmount;
+ total += f->type->capacityAmount;
}
}
return total;
diff --git a/game/state/city/base.h b/game/state/city/base.h
index 3cbe23f95..05c15b2d8 100644
--- a/game/state/city/base.h
+++ b/game/state/city/base.h
@@ -55,7 +55,12 @@ class Base : public StateObject , public std::enable_shared_from_this
bool free = false);
BuildError canDestroyFacility(GameState &state, Vec2 pos) const;
void destroyFacility(GameState &state, Vec2 pos);
- bool containmentEmpty(GameState &state);
+
+ // Returns if an Alien Containment module exists at base
+ bool alienContainmentExists() const;
+
+ // Returns if Alien Containment capacity is empty at base
+ bool alienContainmentIsEmpty(GameState &state);
int getCapacityUsed(GameState &state, FacilityType::Capacity type) const;
int getCapacityTotal(FacilityType::Capacity type) const;
float getUsage(GameState &state, const sp facility, const int delta = 0) const;
diff --git a/game/state/city/building.cpp b/game/state/city/building.cpp
index 1fc68a388..2844a7bb7 100644
--- a/game/state/city/building.cpp
+++ b/game/state/city/building.cpp
@@ -354,7 +354,6 @@ void Building::updateCargo(GameState &state)
}
}
} while (spawnedFerry);
- return;
}
// Step 03.02: Compile list of carrying capacity required
diff --git a/game/state/city/building.h b/game/state/city/building.h
index e127caaf5..1edc36ca1 100644
--- a/game/state/city/building.h
+++ b/game/state/city/building.h
@@ -4,8 +4,8 @@
#include "game/state/stateobject.h"
#include "library/rect.h"
#include "library/vec.h"
+#include
#include
-#include
namespace OpenApoc
{
diff --git a/game/state/city/city.cpp b/game/state/city/city.cpp
index 3bbe37940..f9fb3727c 100644
--- a/game/state/city/city.cpp
+++ b/game/state/city/city.cpp
@@ -6,8 +6,6 @@
#include "game/state/city/building.h"
#include "game/state/city/scenery.h"
#include "game/state/city/vehicle.h"
-#include "game/state/city/vehiclemission.h"
-#include "game/state/city/vequipment.h"
#include "game/state/gamestate.h"
#include "game/state/rules/city/citycommonimagelist.h"
#include "game/state/rules/city/scenerytiletype.h"
@@ -323,11 +321,43 @@ void City::dailyLoop(GameState &state)
b.second->updateWorkforce();
}
}
- generatePortals(state);
+}
+
+void City::weeklyLoop(GameState &state) { generatePortals(state); }
+
+bool City::canPlacePortal(Vec3 position)
+{
+ if (!(map->tileIsValid(position) && map->getTile(position)->ownedObjects.empty()))
+ {
+ return false;
+ }
+
+ for (int i = 1; i < 5; i++)
+ {
+ for (int x = -1; x <= 1; x++)
+ {
+ for (int y = -1; y <= 1; y++)
+ {
+ for (int z = -2; z <= 2; z++)
+ {
+ const auto newTile = position + Vec3(x * i, y * i, z);
+
+ if (!(map->tileIsValid(newTile) && map->getTile(newTile)->ownedObjects.empty()))
+ {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
}
void City::generatePortals(GameState &state)
{
+ const static auto zWeight = {1, 1, 3, 4, 6};
+ const static double portalDev = 25.0;
+
if (portals.empty())
{
if (!initial_portals.empty())
@@ -345,12 +375,8 @@ void City::generatePortals(GameState &state)
}
else
{
- // FIXME: Implement proper portals
- // According to skin36, portals must have empty 4x4x4 around them
- // and spawn within 100x100 around city center
-
// FIXME: Implement portals in alien city staying where they are
- // and starting where they should
+ // and starting where they should (Need to be linked to portals in human city)
static const int iterLimit = 1000;
for (auto &p : portals)
@@ -359,15 +385,17 @@ void City::generatePortals(GameState &state)
}
this->portals.clear();
- std::uniform_int_distribution xyPos(20, 120);
- std::uniform_int_distribution zPos(2, 8);
+ std::normal_distribution xyPos(70.0, portalDev);
+ std::discrete_distribution zPos(zWeight.begin(), zWeight.end());
+
for (int p = 0; p < 3; p++)
{
for (int i = 0; i < iterLimit; i++)
{
- Vec3 pos(xyPos(state.rng), xyPos(state.rng), zPos(state.rng));
-
- if (map->tileIsValid(pos) && map->getTile(pos)->ownedObjects.empty())
+ Vec3 pos(std::clamp(static_cast(xyPos(state.rng)), 20, 120),
+ std::clamp(static_cast(xyPos(state.rng)), 20, 120),
+ zPos(state.rng) + 4);
+ if (canPlacePortal(pos))
{
auto doodad =
mksp(pos + Vec3{0.5f, 0.5f, 0.5f},
@@ -383,9 +411,63 @@ void City::generatePortals(GameState &state)
}
else
{
- // FIXME: Implement moving portals
- // According to skin36, portal is moved by +-(2*week + 15) on each coordinate
- // and must stay within -5..105 which means within 15 from map border in our coords
+ if (this->id == "CITYMAP_HUMAN")
+ {
+ curPortalPosList.clear();
+
+ static const int iterLimit = 1000;
+ for (auto &p : portals)
+ {
+ curPortalPosList.push_back(p->position);
+ p->remove(state);
+ }
+ this->portals.clear();
+
+ int week = state.gameTime.getWeek();
+ int offset = (2 * week) + 15;
+ std::uniform_int_distribution newxyOffset(-offset, offset);
+ std::discrete_distribution newzPos(zWeight.begin(), zWeight.end());
+
+ for (int p = 0; p < 3; p++)
+ {
+ bool portalPlaced = false;
+ for (int i = 0; i < iterLimit; i++)
+ {
+ Vec3 newPos(std::clamp(newxyOffset(state.rng) +
+ static_cast(curPortalPosList.back().x),
+ 20, 120),
+ std::clamp(newxyOffset(state.rng) +
+ static_cast(curPortalPosList.back().y),
+ 20, 120),
+ newzPos(state.rng) + 4);
+
+ if (canPlacePortal(newPos))
+ {
+ auto doodad =
+ mksp(newPos + Vec3{0.5f, 0.5f, 0.5f},
+ StateRef{&state, "DOODAD_6_DIMENSION_GATE"});
+ doodad->voxelMap = state.city_common_image_list->portalVoxelMap;
+ map->addObjectToMap(doodad);
+ this->portals.push_back(doodad);
+ curPortalPosList.pop_back();
+ portalPlaced = true;
+ break;
+ }
+ }
+ if (!portalPlaced)
+ {
+ auto currentPos = curPortalPosList.back();
+ auto doodad =
+ mksp(currentPos + Vec3{0.5f, 0.5f, 0.5f},
+ StateRef{&state, "DOODAD_6_DIMENSION_GATE"});
+ doodad->voxelMap = state.city_common_image_list->portalVoxelMap;
+ map->addObjectToMap(doodad);
+ this->portals.push_back(doodad);
+ curPortalPosList.pop_back();
+ // break;
+ }
+ }
+ }
}
}
diff --git a/game/state/city/city.h b/game/state/city/city.h
index 699f9fb33..a99d33b8e 100644
--- a/game/state/city/city.h
+++ b/game/state/city/city.h
@@ -91,6 +91,7 @@ class City : public StateObject, public std::enable_shared_from_this
std::vector> scenery;
std::list> doodads;
std::vector> portals;
+ std::list> curPortalPosList;
std::set> projectiles;
@@ -131,8 +132,10 @@ class City : public StateObject, public std::enable_shared_from_this
void update(GameState &state, unsigned int ticks);
void hourlyLoop(GameState &state);
void dailyLoop(GameState &state);
+ void weeklyLoop(GameState &state);
void generatePortals(GameState &state);
+ bool canPlacePortal(Vec3 position);
void updateInfiltration(GameState &state);
void repairVehicles(GameState &state);
void repairScenery(GameState &state, bool debugRepair = false);
diff --git a/game/state/city/research.cpp b/game/state/city/research.cpp
index 1a8cf3599..d15e8f560 100644
--- a/game/state/city/research.cpp
+++ b/game/state/city/research.cpp
@@ -9,7 +9,6 @@
#include "game/state/gameevent.h"
#include "game/state/gamestate.h"
#include "game/state/rules/aequipmenttype.h"
-#include "game/state/rules/city/citycommonimagelist.h"
#include "game/state/rules/city/vehicletype.h"
#include "game/state/shared/organisation.h"
#include "library/strings_format.h"
diff --git a/game/state/city/scenery.cpp b/game/state/city/scenery.cpp
index 526c23b26..abec9c22c 100644
--- a/game/state/city/scenery.cpp
+++ b/game/state/city/scenery.cpp
@@ -3,7 +3,6 @@
#include "framework/framework.h"
#include "framework/logger.h"
#include "framework/sound.h"
-#include "game/state/city/agentmission.h"
#include "game/state/city/building.h"
#include "game/state/city/city.h"
#include "game/state/city/vehicle.h"
@@ -961,8 +960,8 @@ bool Scenery::findSupport(bool allowClinging)
} // for every connected way
return true;
} // if connected to more than one way
- } // if more than 2 ways to connect to
- } // If road or tube
+ } // if more than 2 ways to connect to
+ } // If road or tube
// Step 04.02: With generals, we can shoot in x or in y, but connect only to hard support
// We also do not re-try support when lost
@@ -1092,7 +1091,7 @@ bool Scenery::findSupport(bool allowClinging)
} // for every connected way
return true;
} // for every list of increments (vertical and horizontal)
- } // If general
+ } // If general
// If we didn't succeed, don't clear supportedBy!
// supportedBy = lastSupportedBy;
diff --git a/game/state/city/scenery.h b/game/state/city/scenery.h
index dca1d85bf..f35a53878 100644
--- a/game/state/city/scenery.h
+++ b/game/state/city/scenery.h
@@ -4,6 +4,7 @@
#include "game/state/stateobject.h"
#include "library/sp.h"
#include "library/vec.h"
+#include
#include
#define FALLING_ACCELERATION_MAP_PART 0.16666667f // 1/6th
diff --git a/game/state/city/vehicle.cpp b/game/state/city/vehicle.cpp
index 28b3b79a5..b7917c5c0 100644
--- a/game/state/city/vehicle.cpp
+++ b/game/state/city/vehicle.cpp
@@ -1,6 +1,7 @@
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
+
#include "game/state/city/vehicle.h"
#include "framework/configfile.h"
#include "framework/framework.h"
@@ -15,6 +16,7 @@
#include "game/state/city/vequipment.h"
#include "game/state/gameevent.h"
#include "game/state/gamestate.h"
+#include "game/state/gametime.h"
#include "game/state/rules/aequipmenttype.h"
#include "game/state/rules/city/citycommonsamplelist.h"
#include "game/state/rules/city/scenerytiletype.h"
@@ -30,10 +32,12 @@
#include "game/state/tilemap/tileobject_shadow.h"
#include "game/state/tilemap/tileobject_vehicle.h"
#include "library/sp.h"
+#include
+#include
#include
#include
+#include
#include
-#include
#include
namespace OpenApoc
@@ -380,11 +384,14 @@ class FlyingVehicleMover : public VehicleMover
}
if (vehicle.carriedByVehicle)
{
- auto newPos = vehicle.carriedByVehicle->position;
- newPos.z = std::max(0.0f, newPos.z - 0.5f);
- vehicle.setPosition(newPos);
- vehicle.facing = vehicle.carriedByVehicle->facing;
- vehicle.updateSprite(state);
+ if (vehicle.tileObject)
+ {
+ auto newPos = vehicle.carriedByVehicle->position;
+ newPos.z = std::max(0.0f, newPos.z - 0.5f);
+ vehicle.setPosition(newPos);
+ vehicle.facing = vehicle.carriedByVehicle->facing;
+ vehicle.updateSprite(state);
+ }
return;
}
if (vehicle.crashed)
@@ -557,7 +564,6 @@ class FlyingVehicleMover : public VehicleMover
// d += 0.12f * (float)M_PI;
vehicle.ticksToTurn = floorf(d / vehicle.angularVelocity);
- // FIXME: Introduce proper turning speed
// Here we just slow down velocity if we're moving too quickly
if (vehicle.position != vehicle.goalPosition)
{
@@ -567,10 +573,11 @@ class FlyingVehicleMover : public VehicleMover
std::max(floorf(glm::length(vectorToGoal) /
glm::length(vehicle.velocity) * (float)TICK_SCALE) -
5.0f,
- 1.0f);
+ 2.0f);
if (ticksToMove < vehicle.ticksToTurn)
{
- vehicle.velocity *= (float)ticksToMove / (float)vehicle.ticksToTurn;
+ vehicle.velocity *=
+ std::abs(vehicle.angularVelocity) * TURNING_SLOW_DOWN_CORRECTION;
}
}
}
@@ -1127,12 +1134,8 @@ void VehicleMover::updateCrashed(GameState &state, unsigned int ticks [[maybe_un
if (vehicle.tileObject && vehicle.tileObject->getOwningTile() &&
vehicle.tileObject->getOwningTile()->presentScenery)
{
- auto presentScenery = vehicle.tileObject->getOwningTile()->presentScenery;
- if (!presentScenery)
- {
- vehicle.setCrashed(state, false);
- vehicle.startFalling(state);
- }
+ vehicle.setCrashed(state, false);
+ vehicle.startFalling(state);
}
}
@@ -1366,13 +1369,14 @@ void Vehicle::enterBuilding(GameState &state, StateRef b)
{
carriedByVehicle.clear();
crashed = false;
- if (this->currentBuilding)
+ if (b->currentVehicles.find(&state) != b->currentVehicles.end())
{
LogError("Vehicle already in a building?");
return;
}
this->currentBuilding = b;
b->currentVehicles.insert({&state, shared_from_this()});
+
if (carriedVehicle)
{
carriedVehicle->enterBuilding(state, b);
@@ -1736,6 +1740,29 @@ StateRef Vehicle::getServiceDestination(GameState &state)
{
if (it->destination == currentBuilding)
{
+ // Only add aliens if alien containment is available at base
+ const auto vehicleContainsAlienLoot = cargoContainsAlienLoot();
+ const auto alienContainmentExists =
+ currentBuilding->base ? currentBuilding->base->alienContainmentExists() : false;
+
+ // Vehicle must be stopped from unloading alien cargo when vehicle has alien loot but
+ // base has no alien containment
+ const auto isVehicleAllowedToUnloadAlienCargo =
+ !(vehicleContainsAlienLoot && !alienContainmentExists);
+
+ if (!isVehicleAllowedToUnloadAlienCargo)
+ {
+ fw().pushEvent(
+ new GameVehicleEvent(GameEventType::VehicleWithAlienLootInBaseWithNoContainment,
+ {&state, shared_from_this()}));
+ }
+ // Only unload alien cargo when base has alien containment
+ if (it->type == Cargo::Type::Bio && !isVehicleAllowedToUnloadAlienCargo)
+ {
+ it++;
+ continue;
+ }
+
it->arrive(state, cargoArrived, bioArrived, recoveryArrived, transferArrived,
suppliers);
it = cargo.erase(it);
@@ -3865,6 +3892,19 @@ const UString Vehicle::getFormattedVehicleNameForEventMessage(GameState &state)
return name;
}
+const bool Vehicle::cargoContainsAlienLoot() const
+{
+ for (const auto &cargoItem : cargo)
+ {
+ if (cargoItem.type == Cargo::Type::Bio)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
Cargo::Cargo(GameState &state, StateRef equipment, int count, int price,
StateRef originalOwner, StateRef destination)
: Cargo(state, equipment->bioStorage ? Type::Bio : Type::Agent, equipment.id, count,
diff --git a/game/state/city/vehicle.h b/game/state/city/vehicle.h
index afb9bf0f4..7adebd611 100644
--- a/game/state/city/vehicle.h
+++ b/game/state/city/vehicle.h
@@ -9,7 +9,6 @@
#include "library/strings.h"
#include "library/vec.h"
#include
-#include
// Uncomment to allow projectiles to shoot down friendly projectiles
// #define DEBUG_ALLOW_PROJECTILE_ON_PROJECTILE_FRIENDLY_FIRE
@@ -57,6 +56,9 @@ static const int FV_SCRAPPED_COST_PERCENT = 25;
static const int FUEL_TICKS_PER_SECOND = 144;
// How much ticks is required to spend one unit of fuel
static const int FUEL_TICKS_PER_UNIT = 40000;
+// Correction factor for turning slowdown mechanic, purely found by data analysis, could not
+// establish any logical conclusion
+static const float TURNING_SLOW_DOWN_CORRECTION = 38.893f;
class Image;
class TileObjectVehicle;
@@ -386,6 +388,8 @@ class Vehicle : public StateObject,
const UString getFormattedVehicleNameForEventMessage(GameState &state) const;
+ const bool cargoContainsAlienLoot() const;
+
// Following members are not serialized, but rather setup during game
up mover;
diff --git a/game/state/city/vehiclemission.cpp b/game/state/city/vehiclemission.cpp
index ae9558d1c..3020fb0df 100644
--- a/game/state/city/vehiclemission.cpp
+++ b/game/state/city/vehiclemission.cpp
@@ -22,7 +22,6 @@
#include "game/state/tilemap/tilemap.h"
#include "game/state/tilemap/tileobject_doodad.h"
#include "game/state/tilemap/tileobject_scenery.h"
-#include "game/state/tilemap/tileobject_shadow.h"
#include "game/state/tilemap/tileobject_vehicle.h"
#include "library/strings_format.h"
#include
@@ -1037,19 +1036,11 @@ Reachability VehicleTargetHelper::isReachableTargetGround(const Vehicle &v, Vec3
bool VehicleMission::takeOffCheck(GameState &state, Vehicle &v)
{
- if (!v.tileObject)
- {
- if (v.currentBuilding)
- {
- v.addMission(state, VehicleMission::takeOff(v));
- return true;
- }
- else
- {
- return false;
- }
- }
- return false;
+ if (v.tileObject || !v.currentBuilding)
+ return false;
+
+ v.addMission(state, VehicleMission::takeOff(v));
+ return true;
}
bool VehicleMission::teleportCheck(GameState &state, Vehicle &v)
@@ -1277,6 +1268,9 @@ bool VehicleMission::getNextDestination(GameState &state, Vehicle &v, Vec3targetBuilding)
@@ -1992,30 +1986,27 @@ void VehicleMission::start(GameState &state, Vehicle &v)
}
case MissionType::AttackBuilding:
{
- if (!targetBuilding)
+ if (!targetBuilding && !acquireTargetBuilding(state, v))
{
- if (!acquireTargetBuilding(state, v))
- {
- cancelled = true;
- return;
- }
+ cancelled = true;
+ return;
}
+
if (takeOffCheck(state, v))
{
return;
}
- else
+
+ if (this->currentPlannedPath.empty())
{
- if (this->currentPlannedPath.empty())
- {
- std::uniform_int_distribution xPos(targetBuilding->bounds.p0.x - 5,
- targetBuilding->bounds.p1.x + 5);
- std::uniform_int_distribution yPos(targetBuilding->bounds.p0.y - 5,
- targetBuilding->bounds.p1.y + 5);
- setPathTo(state, v, v.getPreferredPosition(xPos(state.rng), yPos(state.rng)),
- getDefaultIterationCount(v));
- }
+ std::uniform_int_distribution xPos(targetBuilding->bounds.p0.x - 5,
+ targetBuilding->bounds.p1.x + 5);
+ std::uniform_int_distribution yPos(targetBuilding->bounds.p0.y - 5,
+ targetBuilding->bounds.p1.y + 5);
+ setPathTo(state, v, v.getPreferredPosition(xPos(state.rng), yPos(state.rng)),
+ getDefaultIterationCount(v));
}
+
return;
}
case MissionType::Crash:
diff --git a/game/state/city/vehiclemission.h b/game/state/city/vehiclemission.h
index 2a2764955..998a4cfb4 100644
--- a/game/state/city/vehiclemission.h
+++ b/game/state/city/vehiclemission.h
@@ -7,8 +7,6 @@
#include "library/strings.h"
#include "library/vec.h"
#include
-#include
-#include
namespace OpenApoc
{
diff --git a/game/state/city/vequipment.h b/game/state/city/vequipment.h
index 3494bdbbe..e776b164a 100644
--- a/game/state/city/vequipment.h
+++ b/game/state/city/vequipment.h
@@ -3,9 +3,7 @@
#include "game/state/shared/equipment.h"
#include "game/state/stateobject.h"
#include "library/sp.h"
-#include "library/strings.h"
#include "library/vec.h"
-#include
namespace OpenApoc
{
diff --git a/game/state/gameevent.cpp b/game/state/gameevent.cpp
index 64d838d77..45d0f7c5d 100644
--- a/game/state/gameevent.cpp
+++ b/game/state/gameevent.cpp
@@ -129,6 +129,10 @@ UString GameVehicleEvent::message()
return format("%s %s", tr("Not enough ammo to rearm vehicle:"), vehicle->name);
case GameEventType::NotEnoughFuel:
return format("%s %s", tr("Not enough fuel to refuel vehicle"), vehicle->name);
+ case GameEventType::VehicleWithAlienLootInBaseWithNoContainment:
+ return format("%s %s",
+ tr("Vehicle landed with alien loot in base with no alien containment"),
+ vehicle->name);
default:
LogError("Invalid vehicle event type");
break;
diff --git a/game/state/gameeventtypes.h b/game/state/gameeventtypes.h
index 25a794972..541fc94c0 100644
--- a/game/state/gameeventtypes.h
+++ b/game/state/gameeventtypes.h
@@ -25,6 +25,7 @@ enum class GameEventType
UnauthorizedVehicle,
NotEnoughAmmo,
NotEnoughFuel,
+ VehicleWithAlienLootInBaseWithNoContainment,
// Vehicle event that starts recovery mission
UfoRecoveryBegin,
diff --git a/game/state/gamestate.cpp b/game/state/gamestate.cpp
index 503bf6cce..b03bae0c5 100644
--- a/game/state/gamestate.cpp
+++ b/game/state/gamestate.cpp
@@ -4,7 +4,6 @@
#include "framework/framework.h"
#include "framework/modinfo.h"
#include "framework/options.h"
-#include "framework/sound.h"
#include "game/state/battle/battle.h"
#include "game/state/city/base.h"
#include "game/state/city/building.h"
@@ -23,10 +22,8 @@
#include "game/state/rules/battle/battlemapparttype.h"
#include "game/state/rules/battle/battleunitanimationpack.h"
#include "game/state/rules/battle/battleunitimagepack.h"
-#include "game/state/rules/battle/damage.h"
#include "game/state/rules/city/baselayout.h"
#include "game/state/rules/city/citycommonimagelist.h"
-#include "game/state/rules/city/citycommonsamplelist.h"
#include "game/state/rules/city/scenerytiletype.h"
#include "game/state/rules/city/ufogrowth.h"
#include "game/state/rules/city/ufoincursion.h"
@@ -35,8 +32,6 @@
#include "game/state/rules/city/vammotype.h"
#include "game/state/rules/city/vehicletype.h"
#include "game/state/rules/doodadtype.h"
-#include "game/state/shared/aequipment.h"
-#include "game/state/shared/doodad.h"
#include "game/state/shared/organisation.h"
#include "game/state/shared/projectile.h"
#include "game/state/tilemap/tilemap.h"
@@ -114,9 +109,14 @@ GameState::~GameState()
}
// Just a handy shortcut since it's shown on every single screen
-UString GameState::getPlayerBalance() const
+UString GameState::getPlayerBalance(const bool formatAsCurrency) const
{
- return Strings::fromInteger(this->getPlayer()->balance);
+ auto playerBalance = Strings::fromInteger(this->getPlayer()->balance);
+
+ if (formatAsCurrency)
+ playerBalance = Strings::formatTextAsCurrency(playerBalance);
+
+ return playerBalance;
}
StateRef GameState::getOrganisation(const UString &orgID)
@@ -639,7 +639,7 @@ void GameState::startGame()
gameTime = GameTime::midday();
- updateEndOfWeek();
+ updateEndOfWeek(true);
newGame = true;
firstDetection = true;
@@ -796,8 +796,6 @@ void GameState::invasion()
nextInvasion = gameTime.getTicks() + 24 * TICKS_PER_HOUR +
randBoundsInclusive(rng, 0, (int)(72 * TICKS_PER_HOUR));
- invadedCity->generatePortals(*this);
-
auto invadingCity = StateRef{this, "CITYMAP_ALIEN"};
auto invadingOrg = StateRef{this, "ORG_ALIEN"};
@@ -1096,6 +1094,16 @@ void GameState::update(unsigned int ticks)
{
if (v.second->city == current_city)
{
+ auto vehicleMission = v.second->missions;
+ if (!vehicleMission.empty() &&
+ vehicleMission.back().type == VehicleMission::MissionType::AttackVehicle &&
+ (vehicleMission.back().targetVehicle == nullptr ||
+ vehicleMission.back().targetVehicle->city != current_city))
+ {
+ v.second->clearMissions(*this);
+ v.second->addMission(*this, VehicleMission::gotoBuilding(
+ *this, *v.second, v.second->homeBuilding));
+ }
v.second->update(*this, ticks);
}
}
@@ -1134,7 +1142,7 @@ void GameState::update(unsigned int ticks)
}
if (gameTime.weekPassed())
{
- this->updateEndOfWeek();
+ this->updateEndOfWeek(false);
}
gameTime.clearFlags();
@@ -1188,9 +1196,19 @@ void GameState::updateEndOfFiveMinutes()
{
continue;
}
+
auto base = b.second->base;
- for (auto v : b.second->currentVehicles)
+ for (auto it = b.second->currentVehicles.begin(); it != b.second->currentVehicles.end();)
{
+ auto v = *it;
+ if (this->vehicles.find(v.id) == this->vehicles.end())
+ {
+ LogWarning("%s not found, but removal was successful..", v.id);
+ v.clear();
+ it = b.second->currentVehicles.erase(it);
+ continue;
+ }
+
for (auto &e : v->equipment)
{
// We only can reload VehicleWeapon and VehicleEngine(?)
@@ -1222,6 +1240,8 @@ void GameState::updateEndOfFiveMinutes()
}
}
}
+
+ ++it;
}
}
@@ -1311,7 +1331,7 @@ void GameState::updateEndOfDay()
fw().pushEvent(new GameEvent(GameEventType::DailyReport));
}
-void GameState::updateEndOfWeek()
+void GameState::updateEndOfWeek(bool gameStart)
{
updateHumanEconomy();
@@ -1319,6 +1339,14 @@ void GameState::updateEndOfWeek()
fw().pushEvent(new GameEvent(GameEventType::WeeklyReport));
weeklyPlayerUpdate();
+
+ if (!gameStart)
+ {
+ for (auto &c : this->cities)
+ {
+ c.second->weeklyLoop(*this);
+ }
+ }
}
void GameState::weeklyPlayerUpdate()
diff --git a/game/state/gamestate.h b/game/state/gamestate.h
index b15dddee4..1a816144d 100644
--- a/game/state/gamestate.h
+++ b/game/state/gamestate.h
@@ -170,7 +170,7 @@ class GameState : public std::enable_shared_from_this
Xorshift128Plus rng;
- UString getPlayerBalance() const;
+ UString getPlayerBalance(const bool formatAsCurrency = true) const;
StateRef getOrganisation(const UString &orgID);
const StateRef &getPlayer() const;
StateRef getPlayer();
@@ -252,7 +252,7 @@ class GameState : public std::enable_shared_from_this
void updateEndOfFiveMinutes();
void updateEndOfHour();
void updateEndOfDay();
- void updateEndOfWeek();
+ void updateEndOfWeek(bool gameStart);
void updateHumanEconomy();
void weeklyPlayerUpdate();
diff --git a/game/state/gamestate_pch.h b/game/state/gamestate_pch.h
index 59bcad934..516d99896 100644
--- a/game/state/gamestate_pch.h
+++ b/game/state/gamestate_pch.h
@@ -1,46 +1,19 @@
#pragma once
-
#include "framework/configfile.h"
-#include "framework/data.h"
-#include "framework/event.h"
#include "framework/framework.h"
-#include "framework/image.h"
#include "framework/logger.h"
#include "framework/renderer.h"
-#include "framework/serialization/serialize.h"
#include "framework/sound.h"
-#include "framework/trace.h"
-#include "game/state/gamestate.h"
-#include "library/colour.h"
-#include "library/line.h"
-#include "library/rect.h"
+#include "game/state/stateobject.h"
+#include "game/state/tilemap/tilemap.h"
#include "library/sp.h"
#include "library/strings.h"
#include "library/strings_format.h"
#include "library/vec.h"
-#include "library/voxel.h"
-#include "library/xorshift.h"
#include
-#include
-#include
-#include
-#include
-#include
-#include
#include
-#include
#include
-#include
-#include
-#include
#include
-#include
#include
-#include
-#include
-#include
#include
-#include
-#include
-#include
-#include
+#include
\ No newline at end of file
diff --git a/game/state/gamestate_serialize.cpp b/game/state/gamestate_serialize.cpp
index 27a1d105b..0a1a24875 100644
--- a/game/state/gamestate_serialize.cpp
+++ b/game/state/gamestate_serialize.cpp
@@ -3,24 +3,9 @@
#include "framework/framework.h"
#include "framework/image.h"
#include "framework/serialization/serialize.h"
-#include "game/state/battle/battlemappart.h"
-#include "game/state/city/building.h"
-#include "game/state/city/city.h"
-#include "game/state/city/facility.h"
-#include "game/state/city/scenery.h"
-#include "game/state/city/vehicle.h"
-#include "game/state/city/vehiclemission.h"
-#include "game/state/city/vequipment.h"
#include "game/state/gamestate.h"
#include "game/state/gamestate_serialize_generated.h"
-#include "game/state/rules/aequipmenttype.h"
-#include "game/state/rules/battle/battlemapparttype.h"
-#include "game/state/rules/city/baselayout.h"
#include "game/state/rules/city/scenerytiletype.h"
-#include "game/state/rules/city/vammotype.h"
-#include "game/state/rules/city/vequipmenttype.h"
-#include "game/state/shared/doodad.h"
-#include "game/state/shared/projectile.h"
#include "library/voxel.h"
namespace OpenApoc
diff --git a/game/state/gamestate_serialize.xml b/game/state/gamestate_serialize.xml
index 4556d7690..621c0e388 100644
--- a/game/state/gamestate_serialize.xml
+++ b/game/state/gamestate_serialize.xml
@@ -1,2111 +1,2112 @@
-
- GameState
- vehicle_types
- organisations
- facility_types
- doodad_types
- vehicle_equipment
- vehicle_ammo
- cities
- ufo_growth_lists
- ufo_mission_preference
- ufo_incursions
- base_layouts
- player_bases
- vehicles
- ufopaedia
- research
- agents
- agent_types
- agent_body_types
- agent_equipment_layouts
- agent_generator
- organisation_raid_rules
- weekly_rating_rules
- agent_salary
- agent_fired_penalty
- initial_agents
- initial_facilities
- initial_agent_equipment
- initial_vehicles
- initial_vehicle_equipment
- initial_vehicle_ammo
- initial_base_agent_equipment
- initial_aliens
- current_city
- current_base
- agentEquipmentTemplates
- totalScore
- weekScore
- micronoidRainChance
- objectIdCount
- city_common_image_list
- city_common_sample_list
- battle_common_image_list
- battle_common_sample_list
- economy
- player
- aliens
- civilian
- government
- rng
- gameTime
- gameTimeBeforeBattle
- missionLocationBattle
- eventFromBattleText
- eventFromBattle
- battle_maps
- current_battle
- hazard_types
- damage_modifiers
- damage_types
- agent_equipment
- equipment_sets_by_score
- equipment_sets_by_level
- building_functions
- messages
- baseIndex
- difficulty
- fundingTerminated
- firstDetection
- nextInvasion
-
-
- BattleMapTileset
- map_part_types
-
-
- EventMessage
- time
- text
- location
-
-
- GameTime
- ticks
-
-
- ResearchState
- topics
- labs
-
-
- AgentGenerator
- first_names
- second_names
-
-
- AgentBodyType
- allowed_body_states
- allowed_movement_states
- allowed_fire_movement_states
- allowed_facing
- large
- maxHeight
- height
- muzzleZPosition
- size
- voxelMaps
-
-
- AgentEquipmentLayout
- slots
-
-
- AgentType
- id
- name
- role
- possible_genders
- gender_chance
- portraits
- min_stats
- max_stats
- bodyType
- shadow_pack
- appearance_count
- image_packs
- animation_packs
- armor
- damage_modifier
- inventory
- built_in_weapon_left
- built_in_weapon_right
- equipment_layout
- improvementPercentagePhysical
- improvementPercentagePsi
- canTrain
- playable
- availableAtTheGameStart
- allowsDirectControl
- aiType
- immuneToFatalWounds
- infiltrationSpeed
- growthChance
- growthOptions
- growthInfiltration
- detectionWeight
- movementPercent
- spreadHazardDamageType
- spreadHazardMinPower
- spreadHazardMaxPower
- spreadHazardTTLDivizor
- inventoryBackground
- displayRank
- missionObjective
- liveSpeciesItem
- deadSpeciesItem
- score
- walkSfx
- crySfx
- damageSfx
- fatalWoundSfx
- dieSfx
-
-
- EquipmentLayoutSlot
- type
- align_x
- align_y
- bounds
-
-
- AEquipment
- type
- payloadType
- lastLoadedAmmoType
- equippedPosition
- equippedSlotType
- ownerAgent
- ownerOrganisation
- ownerUnit
- ammo
- armor
- primed
- activated
- triggerDelay
- triggerRange
- triggerType
- recharge_ticks_accumulated
- readyToFire
- weapon_fire_ticks_remaining
- aimingMode
- inUse
- battleScanner
-
-
- EquipmentSet
- id
- min_score
- max_score
- weapons
- grenades
- equipment
-
-
- EquipmentTemplate
- equipment
-
-
- EquipmentTemplate::EquipmentTemplateEntry
- pos
- type
- payloadType
-
-
- EquipmentSet::WeaponData
- weapon
- clip
- clip_amount
-
-
- EquipmentSet::GrenadeData
- grenade
- grenade_amount
-
-
- EquipmentSet::EquipmentData
- equipment
-
-
- Agent
- type
- name
- portrait
- appearance
- gender
- initial_stats
- current_stats
- modified_stats
- overEncumbred
- rank
- trainingPhysicalTicksAccumulated
- trainingPsiTicksAccumulated
- trainingAssignment
- recentlyHired
- recentlyTransferred
- recentlyFought
- healingProgress
- owner
- city
- homeBuilding
- currentBuilding
- currentVehicle
- position
- goalPosition
- lab_assigned
- assigned_to_lab
- unit
- isBrainsucker
- missions
- teleportTicksAccumulated
- equipment
- destroyAfterBattle
- hiredOn
- killCount
- missionCount
-
-
- AgentPortrait
- photo
- icon
-
-
- AgentStats
- health
- accuracy
- reactions
- speed
- time_units
- stamina
- bravery
- strength
- morale
- psi_energy
- psi_attack
- psi_defence
- physics_skill
- biochem_skill
- engineering_skill
-
-
- ResearchTopic
- name
- order
- description
- man_hours
- type
- required_lab_size
- dependencies
- ufopaedia_entry
- man_hours_progress
- current_lab
- score
- started
- cost
- item_type
- itemId
- hidden
- picture
-
-
- ProjectDependencies
- research
- items
-
-
- ItemDependency
- agentItemsRequired
- vehicleItemsRequired
- agentItemsConsumed
- vehicleItemsConsumed
-
-
- UfopaediaCategory
- title
- description
- background
- entries
-
-
- GameEventType
- UfoSpotted
- UfoCrashed
- UfoRecoveryUnmanned
- VehicleLightDamage
- VehicleModerateDamage
- VehicleHeavyDamage
- VehicleEscaping
- VehicleNoAmmo
- VehicleLowFuel
- VehicleNoFuel
- VehicleRepaired
- VehicleRearmed
- VehicleRefuelled
- VehicleNoEngine
- VehicleRecovered
- UnauthorizedVehicle
- NotEnoughAmmo
- NotEnoughFuel
- UfoRecoveryBegin
- DefendTheBase
- AgentRearmed
- CargoArrived
- TransferArrived
- RecoveryArrived
- CargoExpired
- CargoSeized
- MissionCompletedBase
- BaseDestroyed
- AgentDiedCity
- VehicleDestroyed
- AlienSpotted
- CommenceInvestigation
- BuildingAttacked
- CargoExpiresSoon
- MissionCompletedBuildingRaid
- MissionCompletedBuildingNormal
- OrganisationAttackBuilding
- OrganisationRaidBuilding
- OrganisationStormBuilding
- OrganisationTreatySigned
- AlienTakeover
- OrganisationRequestBribe
- OrganisationRequestAlliance
- AgentArrived
- AgentUnableToReach
- HostileSpotted
- AgentBrainsucked
- AgentDiedBattle
- HostileDied
- UnknownDied
- AgentCriticallyWounded
- AgentBadlyInjured
- AgentInjured
- AgentUnderFire
- AgentUnconscious
- AgentLeftCombat
- AgentFrozen
- AgentBerserk
- AgentPanicked
- AgentPanicOver
- AgentPsiAttacked
- AgentPsiProbed
- AgentPsiControlled
- AgentPsiOver
- NoLOF
- NewTurn
- ResearchCompleted
- ManufactureCompleted
- ManufactureHalted
- FacilityCompleted
- ZoomView
- MarketUpdate
- WeeklyReport
- EnterAlienDimension
- LeaveAlienDimension
- MissionStarted
- BuildingDisabled
- MissionCompletedVehicle
- MissionCompletedBuildingAlien
- None
-
-
- Cargo::Type
- Agent
- Bio
- VehicleAmmo
- VehicleEquipment
-
-
- Cargo
- type
- id
- count
- divisor
- space
- cost
- originalOwner
- destination
- expirationDate
- warned
- suppressEvents
-
-
- Vehicle
- type
- owner
- name
- attackMode
- altitude
- missions
- equipment
- city
- position
- goalPosition
- goalWaypoints
- loot
- velocity
- facing
- goalFacing
- angularVelocity
- ticksToTurn
- banking
- direction
- shadowDirection
- health
- shield
- shieldRecharge
- stunTicksRemaining
- falling
- crashed
- sliding
- fuelSpentTicks
- cloakTicksAccumulated
- teleportTicksAccumulated
- ticksAutoActionAvailable
- homeBuilding
- currentBuilding
- currentAgents
- cargo
- carriedVehicle
- carriedByVehicle
- betweenDimensions
-
-
- VEquipment
- type
- equippedPosition
- weaponState
- owner
- ammo
- reloadTime
-
-
- VehicleMission
- type
- targetLocation
- allowTeleporter
- reRouteAttempts
- pickNearest
- patrolHome
- pickedNearest
- targetBuilding
- targetVehicle
- targets
- timeToSnooze
- missionCounter
- currentPlannedPath
- subvert
- attackCrashed
- cancelled
-
-
- AgentMission
- type
- allowTeleporter
- allowTaxi
- targetBuilding
- timeToSnooze
- currentPlannedPath
- cancelled
-
-
- BattleUnitMission
- type
- targetLocation
- facingDelta
- giveWayAttemptsRemaining
- demandGiveWay
- blockedByMovingUnit
- costPaidUpFront
- allowSkipNodes
- targetFacing
- requireGoal
- freeTurn
- item
- velocityXY
- velocityZ
- timeToSnooze
- allowContinue
- targetBodyState
- currentPlannedPath
- allowRunningAway
- jumpTarget
- jumped
- targetUnit
- brainsuckTicksAccumulated
- brainsuckSoundsPlayed
- cancelled
-
-
- Base
- corridors
- facilities
- inventoryBioEquipment
- inventoryAgentEquipment
- inventoryVehicleEquipment
- inventoryVehicleAmmo
- name
- building
-
-
- Facility
- type
- pos
- buildTime
- lab
-
-
- Lab
- size
- type
- current_project
- assigned_agents
- ticks_since_last_progress
- manufacture_goal
- manufacture_done
- manufacture_man_hours_invested
-
-
- BattleMapPartType
- type
- autoConvert
- sprite
- strategySprite
- voxelMapLOF
- voxelMapLOS
- imageOffset
- constitution
- explosion_power
- explosion_depletion_rate
- explosion_type
- fire_resist
- fire_burn_time
- block
- size
- damaged_map_part
- alternative_map_part
- animation_frames
- transparent
- sfxIndex
- door
- blocksLOS
- floor
- gravlift
- movement_cost
- height
- floating
- provides_support
- supportedByAbove
- supportedByDirections
- supportedByTypes
- vanillaSupportedById
- independent_structure
- exit
- missionObjective
- reinforcementSpawner
-
-
- BattleScore
- combatRating
- casualtyPenalty
- friendlyFire
- liveAlienCaptured
- equipmentCaptured
- equipmentLost
-
-
- Battle
- size
- battle_map
- losBlocks
- visibleTiles
- visibleBlocks
- visibleUnits
- visibleEnemies
- blockAvailable
- blockCenterPos
- linkAvailable
- linkCost
- blockNeedsUpdate
- linkNeedsUpdate
- tilesChangedForVision
- mission_type
- mission_location_id
- mode
- score
- missionEndTimer
- buildingCanBeDisabled
- buildingDisabled
- playerWon
- locationOwner
- loserHasRetreated
- winnerHasRetreated
- player_craft
- map_parts
- units
- scanners
- items
- doodads
- projectiles
- doors
- explosions
- hazards
- participants
- leadershipBonus
- aiBlock
- currentPlayer
- currentActiveOrganisation
- hotseat
- currentTurn
- ticksWithoutAction
- ticksWithoutSeenAction
- lastSeenActionLocation
- turnEndAllowed
- interruptQueue
- interruptUnits
- skirmish
- relationshipsBeforeSkirmish
- scoreBeforeSkirmish
- reinforcementsInterval
- ticksUntilNextReinforcement
- battleViewZLevel
- battleViewScreenCenter
- battleViewGroupMove
- battleViewSquadIndex
- battleViewSelectedUnits
-
-
- BattleMap
- id
- chunk_size
- max_battle_size
- allow_entrance
- allow_exit
- entrance_level_min
- entrance_level_max
- exit_level_min
- exit_level_max
- exitsX
- exitsY
- reinforcementsInterval
- tilesets
- destroyed_ground_tile
- rubble_left_wall
- rubble_right_wall
- rubble_feature
- exit_grounds
- sectors
-
-
- BattleMapSector
- size
- occurrence_min
- occurrence_max
- sectorTilesName
- tiles
- spawnLocations
-
-
- BattleMapSectorTiles
- losBlocks
- loot_locations
- guardianLocations
- initial_grounds
- initial_left_walls
- initial_right_walls
- initial_features
-
-
- BattleMapSector::LineOfSightBlock
- start
- end
- ai_patrol_priority
- ai_target_priority
- spawn_type
- spawn_priority
- also_allow_civilians
- low_priority
- spawn_large_units
- spawn_walking_units
-
-
- BattleUnitImagePack
- image_offset
- images
-
-
- BattleCommonImageList
- strategyImages
- loadingImage
- focusArrows
- burningDoodad
-
-
- CityCommonImageList
- strategyImages
- projectileVoxelMap
- portalVoxelMap
- agentIsometric
- agentStrategic
- portalStrategic
-
-
- BattleCommonSampleList
- gravlift
- door
- brainsuckerHatch
- brainsuckerSuck
- teleport
- burn
- genericHitSounds
- walkSounds
- objectDropSounds
- throwSounds
- psiFailSounds
- psiSuccessSounds
-
-
- CityCommonSampleList
- teleport
- vehicleExplosion
- sceneryExplosion
- shieldHit
- dimensionShiftIn
- dimensionShiftOut
- alertSounds
-
-
- BattleUnitAnimationPack
- standart_animations
- hand_state_animations
- body_state_animations
- hasAlternativeFiringAnimations
- useFiringAnimationForPsi
- alt_fire_animations
-
-
- BattleUnitAnimationPack::AnimationEntry
- frames
- is_overlay
- frame_count
- units_per_100_frames
-
-
- BattleUnitAnimationPack::AnimationEntry::Frame
- unit_image_parts
- unit_image_draw_order
-
-
- BattleUnitAnimationPack::AnimationEntry::Frame::InfoBlock
- index
- offset
-
-
- BattleUnit
- id
- agent
- owner
- squadNumber
- squadPosition
- weaponStatus
- targetingMode
- targetTile
- timesTargetMIA
- targetUnit
- focusUnit
- focusedByUnits
- ticksUntillNextTargetCheck
- psiStatus
- psiTarget
- psiItem
- ticksAccumulatedToNextPsiCheck
- psiAttackers
- brainSucker
- experiencePoints
- combatRating
- fatalWounds
- healingBodyPart
- isHealing
- woundTicksAccumulated
- regenTicksAccumulated
- stunDamage
- enzymeDebuffTicksAccumulated
- fireDebuffTicksAccumulated
- enzymeDebuffIntensity
- fireDebuffTicksRemaining
- moraleState
- moraleStateTicksRemaining
- moraleTicksAccumulated
- initialTU
- reserveShotCost
- cloakTicksAccumulated
- ticksUntillNextCry
- behavior_mode
- fire_aiming_mode
- fire_permission_mode
- movement_mode
- kneeling_mode
- reserve_shot_mode
- reserve_kneel_mode
- body_animation_ticks_remaining
- body_animation_ticks_total
- body_animation_ticks_static
- current_body_state
- target_body_state
- hand_animation_ticks_remaining
- residual_aiming_ticks_remaining
- firing_animation_ticks_remaining
- current_hand_state
- target_hand_state
- movement_ticks_passed
- movement_sounds_played
- current_movement_state
- turning_animation_ticks_remaining
- missions
- position
- goalPosition
- atGoal
- usingLift
- facing
- goalFacing
- flyingSpeedModifier
- retreated
- destroyed
- falling
- launched
- launchGoal
- bounced
- collisionIgnoredTicks
- velocity
- tilesMoved
- giveWayRequestData
- displayedItem
- visibleUnits
- visibleEnemies
- aiList
-
-
- BattleItem
- item
- position
- velocity
- bounced
- falling
- ownerInvulnerableTicks
- collisionIgnoredTicks
- ticksUntilCollapse
- owner
-
-
- BattleHazard
- position
- damageType
- hazardType
- power
- lifetime
- age
- frame
- ticksUntilVisible
- frameChangeTicksAccumulated
- nextUpdateTicksAccumulated
- ownerOrganisation
- ownerUnit
-
-
- BattleExplosion
- position
- power
- ticksUntilExpansion
- locationsToExpand
- locationsVisited
- damageInTheEnd
- locationsToDamage
- damageType
- depletionRate
- ownerUnit
- ownerOrganisation
- affectedUnits
-
-
- BattleMapPart
- type
- alternative_type
- position
- ticksUntilCollapse
- burnTicksAccumulated
- damaged
- falling
- fallingSpeed
- destroyed
- providesHardSupport
- door
- supportedItems
- supportedParts
- owner
-
-
- BattleDoor
- id
- operational
- right
- open
- animationFrameCount
- openTicksRemaining
- animationTicksRemaining
- doorSound
-
-
- City
- id
- size
- tile_types
- initial_tiles
- buildings
- scenery
- doodads
- portals
- projectiles
- initial_portals
- tileToRoadSegmentMap
- roadSegments
- civilianSalary
- researchUnlock
- cityViewScreenCenter
- cityViewPageIndex
- cityViewSelectedOwnedVehicles
- cityViewSelectedOtherVehicles
- cityViewSelectedSoldiers
- cityViewSelectedBios
- cityViewSelectedPhysics
- cityViewSelectedEngineers
- cityViewSelectedOrganisation
- cityViewOrgButtonIndex
-
-
- RoadSegment
- connections
- tilePosition
- intact
- tileIntact
- middle
- length
-
-
- Projectile
- type
- position
- velocity
- turnRate
- age
- damage
- delay_ticks_remaining
- depletionRate
- lifetime
- firerVehicle
- firerUnit
- trackedVehicle
- trackedUnit
- targetPosition
- previousPosition
- stunTicks
- splitIntoTypesCity
- splitIntoTypesBattle
- spritePositions
- tail_length
- projectile_sprites
- sprite_distance
- manualFire
- voxelMapLof
- voxelMapLos
- impactSfx
- doodadType
- damageType
- ownerInvulnerableTicks
- velocityScale
-
-
- Doodad
- position
- imageOffset
- temporary
- age
- lifetime
- sprite
- type
- voxelMap
-
-
- DoodadType
- lifetime
- repeatable
- imageOffset
- frames
-
-
- Scenery
- type
- initialPosition
- currentPosition
- ticksUntilCollapse
- supportedParts
- supportedBy
- damaged
- falling
- fallingSpeed
- destroyed
- supportHardness
-
-
- BuildingFunction
- name
- baseCost
- baseIncome
- workersPerTile
- agentSpawnType
- investmentValue
- prestige
- infiltrationSpeed
- detectionWeight
- ufopaedia_entry
-
-
- Building
- name
- city
- function
- owner
- bounds
- base_layout
- base
- battle_map
- preset_crew
- current_crew
- crewQuarters
- currentVehicles
- currentAgents
- cargo
- isPurchesable
- purchasePrice
- maintenanceCosts
- maximumWorkforce
- currentWorkforce
- incomePerCapita
- currentWage
- investment
- prestige
- ticksDetectionTimeOut
- ticksDetectionAttemptAccumulated
- detected
- timeOfLastAttackEvent
- researchUnlock
- accessTopic
- victory
- pendingInvestigatorCount
-
-
- UFOIncursion
- primaryMission
- primaryList
- escortList
- attackList
- priority
-
-
- UFOGrowth
- week
- vehicleTypeList
-
-
- UFOMissionPreference
- week
- missionList
-
-
- BaseLayout
- baseCorridors
- baseLift
-
-
- SceneryTileType
- tile_type
- road_type
- walk_mode
- connection
- hill
- tube
- sprite
- strategySprite
- overlaySprite
- voxelMap
- damagedTile
- imageOffset
- isLandingPad
- minimap_colour
- constitution
- value
- mass
- strength
- height
- overlayHeight
- basement
- isBuildingPart
- commonProperty
- isHill
-
-
- VAmmoType
- id
- name
- weight
- ammo_id
- manufacturer
- store_space
-
-
- DamageModifier
-
-
- HazardType
- doodadType
- sound
- minLifetime
- maxLifetime
- fire
-
-
- DamageType::BlockType
- Physical
- Psionic
- Gas
- Fire
-
-
- DamageType::EffectType
- None
- Stun
- Smoke
- Fire
- Enzyme
- Brainsucker
- Psionic
-
-
- DamageType
- name
- icon_sprite
- ignore_shield
- non_violent
- modifiers
- explosive
- explosionDoodad
- blockType
- effectType
- hazardType
- explosionSounds
-
-
- AEquipmentType
- type
- id
- name
- weight
- held_image_pack
- dropped_sprite
- dropped_offset
- dropped_shadow_sprite
- shadow_offset
- equipscreen_sprite
- equipscreen_size
- manufacturer
- store_space
- armor
- score
- research_dependency
- two_handed
- bioStorage
- bioRemains
- launcher
- artifact
- body_sprite
- damage_modifier
- body_part
- body_image_pack
- provides_flight
- weapon_types
- max_ammo
- burst
- recharge
- rechargeTB
- speed
- projectile_sprites
- damage
- accuracy
- fire_delay
- projectile_delay
- tail_size
- guided
- turn_rate
- range
- ttl
- explosion_graphic
- shield_graphic
- fire_sfx
- impact_sfx
- damage_type
- trigger_type
- explosion_depletion_rate
- spawnList
-
-
- VEquipmentType
- type
- id
- name
- weight
- max_ammo
- burst
- ammo_type
- equipscreen_sprite
- equipscreen_size
- manufacturer
- store_space
- users
- speed
- projectile_sprites
- damage
- accuracy
- fire_delay
- tail_size
- guided
- turn_rate
- range
- ttl
- firing_arc_1
- firing_arc_2
- point_defence
- fire_sfx
- impact_sfx
- explosion_graphic
- icon
- stunTicks
- splitIntoTypes
- power
- top_speed
- accuracy_modifier
- cargo_space
- passengers
- alien_space
- missile_jamming
- shielding
- cloaking
- teleporting
- dimensionShifting
- scoreRequirement
- research_dependency
-
-
- DoodadFrame
- image
- time
-
-
- FacilityType
- name
- fixed
- buildCost
- buildTime
- weeklyCost
- capacityType
- capacityAmount
- size
- sprite
- dependency
- ufopaedia_entry
- sector
-
-
- OrganisationRaid::Type
- None
- Attack
- Raid
- Storm
- UnauthorizedVehicle
- Treaty
-
-
- OrganisationRaid
- nextRaidTimer
- attack_vehicle_types
- neutral_low_manpower
- neutral_normal
- neutral_high_manpower
- military_low_manpower
- military_normal
- military_high_manpower
-
-
- Organisation::MissionPattern::Target
- Owned
- OwnedOrOther
- Other
- ArriveFromSpace
- DepartToSpace
-
-
- Organisation::Relation
- Allied
- Friendly
- Neutral
- Unfriendly
- Hostile
-
-
- Organisation::RecurringMission
- time
- pattern
-
-
- Organisation::RaidMission
- time
- type
- target
-
-
- Organisation::MissionPattern
- minIntervalRepeat
- maxIntervalRepeat
- minAmount
- maxAmount
- allowedTypes
- target
- relation
-
-
- Organisation
- id
- name
- balance
- income
- rebuildingRate
- infiltrationValue
- infiltrationHistory
- infiltrationSpeed
- ticksTakeOverAttemptAccumulated
- takenOver
- militarized
- initiatesDiplomacy
- providesTransportationServices
- tech_level
- average_guards
- guard_types_reinforcements
- guard_types_human
- guard_types_alien
- loot
- icon
- current_relations
- long_term_relations
- ufopaedia_entry
- raid_missions
- recurring_missions
- vehiclePark
- hirableAgentTypes
-
-
- VehicleType
- numCreated
- type
- name
- manufacturer
- image_offset
- acceleration
- top_speed
- health
- crash_health
- weight
- armour
- passengers
- aggressiveness
- score
- icon
- battle_map
- crew_downed
- crew_deposit
- equipment_screen
- equip_icon_big
- equip_icon_small
- mapIconType
- directional_sprites
- shadow_offset
- directional_shadow_sprites
- animation_sprites
- crashed_sprite
- height
- size
- voxelMaps
- voxelMapsLOS
- equipment_layout_slots
- initial_equipment_list
- ufopaedia_entry
- provideFreightAgent
- provideFreightCargo
- provideFreightBio
- canRescueCrashed
- canEnterDimensionGate
- researchUnlock
-
-
- UfopaediaEntry
- title
- description
- background
- data_id
- data_type
- dependency
-
-
- ResearchDependency
- type
- topics
-
-
- BattleUnitAnimationPack::AnimationKey
- itemWieldMode
- handState
- movementState
- bodyState
-
-
- BattleUnitAnimationPack::ChangingHandAnimationKey
- itemWieldMode
- currentHand
- targetHand
- movementState
- bodyState
-
-
- BattleUnitAnimationPack::ChangingBodyStateAnimationKey
- itemWieldMode
- handState
- movementState
- currentBodyState
- targetBodyState
-
-
- BattleUnitAnimationPack::AltFireAnimationKey
- itemWieldMode
- handState
- angle
- movementState
- bodyState
-
-
- VEquipmentType::User
- Ground
- Air
- Ammo
-
-
- VehicleType::Type
- Flying
- UFO
- Road
- ATV
-
-
- VehicleType::Direction
- N
- NNE
- NE
- NEE
- E
- SEE
- SE
- SSE
- S
- SSW
- SW
- SWW
- W
- NWW
- NW
- NNW
-
-
- VehicleType::Banking
- Flat
- Left
- Right
- Ascending
- Descending
-
-
- VehicleType::ArmourDirection
- Top
- Bottom
- Front
- Rear
- Left
- Right
-
-
- VehicleType::MapIconType
- Arrow
- SmallCircle
- LargeCircle
-
-
- ResearchTopic::Type
- BioChem
- Physics
- Engineering
-
-
- ResearchTopic::LabSize
- Small
- Large
-
-
- ResearchTopic::ItemType
- VehicleEquipment
- AgentEquipment
- VehicleEquipmentAmmo
- Craft
-
-
- Vehicle::AttackMode
- Aggressive
- Standard
- Defensive
- Evasive
-
-
- Vehicle::Altitude
- Highest
- High
- Standard
- Low
-
-
- VehicleMission::MissionType
- GotoLocation
- GotoBuilding
- FollowVehicle
- RecoverVehicle
- AttackVehicle
- AttackBuilding
- RestartNextMission
- Snooze
- TakeOff
- Land
- Crash
- Patrol
- GotoPortal
- InfiltrateSubvert
- OfferService
- Teleport
- SelfDestruct
- DepartToSpace
- ArriveFromDimensionGate
- InvestigateBuilding
-
-
- AgentMission::MissionType
- GotoBuilding
- AwaitPickup
- RestartNextMission
- Snooze
- Teleport
-
-
- BattleUnitMission::Type
- GotoLocation
- Snooze
- RestartNextMission
- AcquireTU
- ChangeBodyState
- ThrowItem
- DropItem
- Turn
- ReachGoal
- Teleport
- Brainsuck
- Jump
-
-
- VEquipment::WeaponState
- Ready
- Disabled
- Reloading
- OutOfAmmo
-
-
- Battle::MissionType
- AlienExtermination
- RaidAliens
- BaseDefense
- RaidHumans
- UfoRecovery
-
-
- MapDirection
- North
- East
- South
- West
- Up
- Down
-
-
- Battle::Mode
- RealTime
- TurnBased
-
-
- SpawnType
- Player
- Enemy
- Civilian
-
-
- ItemWieldMode
- None
- OneHanded
- TwoHanded
-
-
- BattleUnitAnimationPack::AnimationEntry::Frame::UnitImagePart
- Shadow
- Body
- Legs
- Helmet
- LeftArm
- RightArm
- Weapon
-
-
- BattleUnit::BehaviorMode
- Aggressive
- Normal
- Evasive
-
-
- WeaponAimingMode
- Aimed
- Snap
- Auto
-
-
- ReserveShotMode
- Aimed
- Snap
- Auto
- None
-
-
- BattleUnit::FirePermissionMode
- AtWill
- CeaseFire
-
-
- MovementMode
- Prone
- Walking
- Running
-
-
- KneelingMode
- None
- Kneeling
-
-
- WeaponStatus
- NotFiring
- FiringLeftHand
- FiringRightHand
- FiringBothHands
-
-
- PsiStatus
- NotEngaged
- Control
- Panic
- Stun
- Probe
-
-
- BattleUnit::TargetingMode
- NoTarget
- Unit
- TileCenter
- TileGround
-
-
- BattleUnitType
- SmallWalker
- SmallFlyer
- LargeWalker
- LargeFlyer
-
-
- Organisation::LootPriority
- A
- B
- C
-
-
- BattleMapPartType::Type
- Ground
- LeftWall
- RightWall
- Feature
-
-
- BattleMapPartType::AutoConvert
- None
- Fire
- Smoke
-
-
- Projectile::Type
- Beam
- Missile
-
-
- UFOIncursion::PrimaryMission
- Infiltration
- Subversion
- Attack
- Overspawn
-
-
- SceneryTileType::TileType
- General
- Road
- PeopleTubeJunction
- PeopleTube
- CityWall
-
-
- SceneryTileType::RoadType
- StraightBend
- Junction
- Terminal
-
-
- SceneryTileType::WalkMode
- None
- Into
- Onto
-
-
- FacilityType::Capacity
- Nothing
- Quarters
- Stores
- Medical
- Training
- Psi
- Repair
- Chemistry
- Physics
- Workshop
- Aliens
-
-
- ResearchDependency::Type
- Any
- All
-
-
- UfopaediaEntry::Data
- Nothing
- Organisation
- Vehicle
- VehicleEquipment
- Equipment
- Facility
- Building
-
-
- AEquipmentType::Type
- Armor
- Weapon
- Grenade
- Ammo
- MotionScanner
- StructureProbe
- VortexAnalyzer
- MultiTracker
- MindShield
- MindBender
- AlienDetector
- DisruptorShield
- Teleporter
- CloakingField
- DimensionForceField
- MediKit
- Brainsucker
- Popper
- Spawner
- Loot
-
-
- AgentType::Role
- Soldier
- Physicist
- BioChemist
- Engineer
-
-
- AgentType::Gender
- Male
- Female
-
-
- EquipmentSlotType
- General
- ArmorBody
- ArmorLegs
- ArmorHelmet
- ArmorLeftHand
- ArmorRightHand
- LeftHand
- RightHand
- VehicleGeneral
- VehicleWeapon
- VehicleEngine
-
-
- TriggerType
- None
- Timed
- Contact
- Proximity
- Boomeroid
-
-
- AlignmentX
- Left
- Right
- Centre
-
-
- AlignmentY
- Top
- Bottom
- Centre
-
-
- BodyPart
- Body
- Legs
- Helmet
- LeftArm
- RightArm
-
-
- BodyState
- Standing
- Flying
- Kneeling
- Prone
- Jumping
- Throwing
- Downed
- Dead
-
-
- HandState
- AtEase
- Aiming
- Firing
-
-
- MovementState
- None
- Normal
- Running
- Strafing
- Reverse
- Brainsuck
-
-
- AIType
- None
- Civilian
- Loner
- Group
- PanicFreeze
- PanicRun
- Berserk
-
-
- AIAction::Type
- AttackWeaponTile
- AttackWeaponUnit
- AttackGrenade
- AttackPsiPanic
- AttackPsiStun
- AttackPsiMC
- AttackBrainsucker
- AttackSuicide
-
-
- AIMovement::Type
- Stop
- ChangeStance
- Patrol
- Advance
- Pursue
- GetInRange
- TakeCover
- Retreat
-
-
- UnitAI::Type
- LowMorale
- Default
- Behavior
- Vanilla
- Hardcore
-
-
- TacticalAI::Type
- Vanilla
-
-
- Rank
- Rookie
- Squaddie
- SquadLeader
- Sergeant
- Captain
- Colonel
- Commander
-
-
- TrainingAssignment
- None
- Physical
- Psi
-
-
- MoraleState
- Normal
- PanicFreeze
- PanicRun
- Berserk
-
-
- AIAction
- type
- targetUnit
- item
- weaponStatus
- psiEnergySnapshot
- preventOutOfTurnReThink
- executed
-
-
- AIMovement
- type
- targetLocation
- movementMode
- kneelingMode
- executed
- subordinate
-
-
- AIDecision
- action
- movement
-
-
- AIBlockUnit
- aiList
- ticksLastThink
- ticksLastOutOfOrderThink
- ticksUntilReThink
-
-
- UnitAILowMorale
- type
- active
- ticksActionAvailable
-
-
- UnitAIDefault
- type
- active
- ticksAutoTurnAvailable
- ticksAutoTargetAvailable
- attackerPosition
-
-
- UnitAIBehavior
- type
- active
-
-
- UnitAIVanilla
- type
- active
- ticksLastThink
- ticksUntilReThink
- lastDecision
- enemySpotted
- enemySpottedPrevious
- attackerPosition
- lastSeenEnemyPosition
- flagEnemySpotted
- flagLastSeenPosition
- flagLastAttackerPosition
-
-
- UnitAIHardcore
- type
- active
-
-
- AIBlockTactical
- aiList
- ticksLastThink
- ticksUntilReThink
-
-
- TacticalAIVanilla
- type
-
-
- BattleScanner
- movementTicks
- version
- updateTicksAccumulated
- lastPosition
- holder
-
-
- EconomyInfo
- weekAvailable
- basePrice
- minStock
- maxStock
- currentPrice
- currentStock
- lastStock
-
-
- GameScore
- tacticalMissions
- researchCompleted
- alienIncidents
- craftShotDownUFO
- craftShotDownXCom
- incursions
- cityDamage
-
+
+ GameState
+ vehicle_types
+ organisations
+ facility_types
+ doodad_types
+ vehicle_equipment
+ vehicle_ammo
+ cities
+ ufo_growth_lists
+ ufo_mission_preference
+ ufo_incursions
+ base_layouts
+ player_bases
+ vehicles
+ ufopaedia
+ research
+ agents
+ agent_types
+ agent_body_types
+ agent_equipment_layouts
+ agent_generator
+ organisation_raid_rules
+ weekly_rating_rules
+ agent_salary
+ agent_fired_penalty
+ initial_agents
+ initial_facilities
+ initial_agent_equipment
+ initial_vehicles
+ initial_vehicle_equipment
+ initial_vehicle_ammo
+ initial_base_agent_equipment
+ initial_aliens
+ current_city
+ current_base
+ agentEquipmentTemplates
+ totalScore
+ weekScore
+ micronoidRainChance
+ objectIdCount
+ city_common_image_list
+ city_common_sample_list
+ battle_common_image_list
+ battle_common_sample_list
+ economy
+ player
+ aliens
+ civilian
+ government
+ rng
+ gameTime
+ gameTimeBeforeBattle
+ missionLocationBattle
+ eventFromBattleText
+ eventFromBattle
+ battle_maps
+ current_battle
+ hazard_types
+ damage_modifiers
+ damage_types
+ agent_equipment
+ equipment_sets_by_score
+ equipment_sets_by_level
+ building_functions
+ messages
+ baseIndex
+ difficulty
+ fundingTerminated
+ firstDetection
+ nextInvasion
+
+
+ BattleMapTileset
+ map_part_types
+
+
+ EventMessage
+ time
+ text
+ location
+
+
+ GameTime
+ ticks
+
+
+ ResearchState
+ topics
+ labs
+
+
+ AgentGenerator
+ first_names
+ second_names
+
+
+ AgentBodyType
+ allowed_body_states
+ allowed_movement_states
+ allowed_fire_movement_states
+ allowed_facing
+ large
+ maxHeight
+ height
+ muzzleZPosition
+ size
+ voxelMaps
+
+
+ AgentEquipmentLayout
+ slots
+
+
+ AgentType
+ id
+ name
+ role
+ possible_genders
+ gender_chance
+ portraits
+ min_stats
+ max_stats
+ bodyType
+ shadow_pack
+ appearance_count
+ image_packs
+ animation_packs
+ armor
+ damage_modifier
+ inventory
+ built_in_weapon_left
+ built_in_weapon_right
+ equipment_layout
+ improvementPercentagePhysical
+ improvementPercentagePsi
+ canTrain
+ playable
+ availableAtTheGameStart
+ allowsDirectControl
+ aiType
+ immuneToFatalWounds
+ infiltrationSpeed
+ growthChance
+ growthOptions
+ growthInfiltration
+ detectionWeight
+ movementPercent
+ spreadHazardDamageType
+ spreadHazardMinPower
+ spreadHazardMaxPower
+ spreadHazardTTLDivizor
+ inventoryBackground
+ displayRank
+ missionObjective
+ liveSpeciesItem
+ deadSpeciesItem
+ score
+ walkSfx
+ crySfx
+ damageSfx
+ fatalWoundSfx
+ dieSfx
+
+
+ EquipmentLayoutSlot
+ type
+ align_x
+ align_y
+ bounds
+
+
+ AEquipment
+ type
+ payloadType
+ lastLoadedAmmoType
+ equippedPosition
+ equippedSlotType
+ ownerAgent
+ ownerOrganisation
+ ownerUnit
+ ammo
+ armor
+ primed
+ activated
+ triggerDelay
+ triggerRange
+ triggerType
+ recharge_ticks_accumulated
+ readyToFire
+ weapon_fire_ticks_remaining
+ aimingMode
+ inUse
+ battleScanner
+
+
+ EquipmentSet
+ id
+ min_score
+ max_score
+ weapons
+ grenades
+ equipment
+
+
+ EquipmentTemplate
+ equipment
+
+
+ EquipmentTemplate::EquipmentTemplateEntry
+ pos
+ type
+ payloadType
+
+
+ EquipmentSet::WeaponData
+ weapon
+ clip
+ clip_amount
+
+
+ EquipmentSet::GrenadeData
+ grenade
+ grenade_amount
+
+
+ EquipmentSet::EquipmentData
+ equipment
+
+
+ Agent
+ type
+ name
+ portrait
+ appearance
+ gender
+ initial_stats
+ current_stats
+ modified_stats
+ overEncumbred
+ rank
+ trainingPhysicalTicksAccumulated
+ trainingPsiTicksAccumulated
+ trainingAssignment
+ recentlyHired
+ recentlyTransferred
+ recentlyFought
+ healingProgress
+ owner
+ city
+ homeBuilding
+ currentBuilding
+ currentVehicle
+ position
+ goalPosition
+ lab_assigned
+ assigned_to_lab
+ unit
+ isBrainsucker
+ missions
+ teleportTicksAccumulated
+ equipment
+ destroyAfterBattle
+ hiredOn
+ killCount
+ missionCount
+
+
+ AgentPortrait
+ photo
+ icon
+
+
+ AgentStats
+ health
+ accuracy
+ reactions
+ speed
+ time_units
+ stamina
+ bravery
+ strength
+ morale
+ psi_energy
+ psi_attack
+ psi_defence
+ physics_skill
+ biochem_skill
+ engineering_skill
+
+
+ ResearchTopic
+ name
+ order
+ description
+ man_hours
+ type
+ required_lab_size
+ dependencies
+ ufopaedia_entry
+ man_hours_progress
+ current_lab
+ score
+ started
+ cost
+ item_type
+ itemId
+ hidden
+ picture
+
+
+ ProjectDependencies
+ research
+ items
+
+
+ ItemDependency
+ agentItemsRequired
+ vehicleItemsRequired
+ agentItemsConsumed
+ vehicleItemsConsumed
+
+
+ UfopaediaCategory
+ title
+ description
+ background
+ entries
+
+
+ GameEventType
+ UfoSpotted
+ UfoCrashed
+ UfoRecoveryUnmanned
+ VehicleLightDamage
+ VehicleModerateDamage
+ VehicleHeavyDamage
+ VehicleEscaping
+ VehicleNoAmmo
+ VehicleLowFuel
+ VehicleNoFuel
+ VehicleRepaired
+ VehicleRearmed
+ VehicleRefuelled
+ VehicleNoEngine
+ VehicleRecovered
+ UnauthorizedVehicle
+ NotEnoughAmmo
+ NotEnoughFuel
+ VehicleWithAlienLootInBaseWithNoContainment
+ UfoRecoveryBegin
+ DefendTheBase
+ AgentRearmed
+ CargoArrived
+ TransferArrived
+ RecoveryArrived
+ CargoExpired
+ CargoSeized
+ MissionCompletedBase
+ BaseDestroyed
+ AgentDiedCity
+ VehicleDestroyed
+ AlienSpotted
+ CommenceInvestigation
+ BuildingAttacked
+ CargoExpiresSoon
+ MissionCompletedBuildingRaid
+ MissionCompletedBuildingNormal
+ OrganisationAttackBuilding
+ OrganisationRaidBuilding
+ OrganisationStormBuilding
+ OrganisationTreatySigned
+ AlienTakeover
+ OrganisationRequestBribe
+ OrganisationRequestAlliance
+ AgentArrived
+ AgentUnableToReach
+ HostileSpotted
+ AgentBrainsucked
+ AgentDiedBattle
+ HostileDied
+ UnknownDied
+ AgentCriticallyWounded
+ AgentBadlyInjured
+ AgentInjured
+ AgentUnderFire
+ AgentUnconscious
+ AgentLeftCombat
+ AgentFrozen
+ AgentBerserk
+ AgentPanicked
+ AgentPanicOver
+ AgentPsiAttacked
+ AgentPsiProbed
+ AgentPsiControlled
+ AgentPsiOver
+ NoLOF
+ NewTurn
+ ResearchCompleted
+ ManufactureCompleted
+ ManufactureHalted
+ FacilityCompleted
+ ZoomView
+ MarketUpdate
+ WeeklyReport
+ EnterAlienDimension
+ LeaveAlienDimension
+ MissionStarted
+ BuildingDisabled
+ MissionCompletedVehicle
+ MissionCompletedBuildingAlien
+ None
+
+
+ Cargo::Type
+ Agent
+ Bio
+ VehicleAmmo
+ VehicleEquipment
+
+
+ Cargo
+ type
+ id
+ count
+ divisor
+ space
+ cost
+ originalOwner
+ destination
+ expirationDate
+ warned
+ suppressEvents
+
+
+ Vehicle
+ type
+ owner
+ name
+ attackMode
+ altitude
+ missions
+ equipment
+ city
+ position
+ goalPosition
+ goalWaypoints
+ loot
+ velocity
+ facing
+ goalFacing
+ angularVelocity
+ ticksToTurn
+ banking
+ direction
+ shadowDirection
+ health
+ shield
+ shieldRecharge
+ stunTicksRemaining
+ falling
+ crashed
+ sliding
+ fuelSpentTicks
+ cloakTicksAccumulated
+ teleportTicksAccumulated
+ ticksAutoActionAvailable
+ homeBuilding
+ currentBuilding
+ currentAgents
+ cargo
+ carriedVehicle
+ carriedByVehicle
+ betweenDimensions
+
+
+ VEquipment
+ type
+ equippedPosition
+ weaponState
+ owner
+ ammo
+ reloadTime
+
+
+ VehicleMission
+ type
+ targetLocation
+ allowTeleporter
+ reRouteAttempts
+ pickNearest
+ patrolHome
+ pickedNearest
+ targetBuilding
+ targetVehicle
+ targets
+ timeToSnooze
+ missionCounter
+ currentPlannedPath
+ subvert
+ attackCrashed
+ cancelled
+
+
+ AgentMission
+ type
+ allowTeleporter
+ allowTaxi
+ targetBuilding
+ timeToSnooze
+ currentPlannedPath
+ cancelled
+
+
+ BattleUnitMission
+ type
+ targetLocation
+ facingDelta
+ giveWayAttemptsRemaining
+ demandGiveWay
+ blockedByMovingUnit
+ costPaidUpFront
+ allowSkipNodes
+ targetFacing
+ requireGoal
+ freeTurn
+ item
+ velocityXY
+ velocityZ
+ timeToSnooze
+ allowContinue
+ targetBodyState
+ currentPlannedPath
+ allowRunningAway
+ jumpTarget
+ jumped
+ targetUnit
+ brainsuckTicksAccumulated
+ brainsuckSoundsPlayed
+ cancelled
+
+
+ Base
+ corridors
+ facilities
+ inventoryBioEquipment
+ inventoryAgentEquipment
+ inventoryVehicleEquipment
+ inventoryVehicleAmmo
+ name
+ building
+
+
+ Facility
+ type
+ pos
+ buildTime
+ lab
+
+
+ Lab
+ size
+ type
+ current_project
+ assigned_agents
+ ticks_since_last_progress
+ manufacture_goal
+ manufacture_done
+ manufacture_man_hours_invested
+
+
+ BattleMapPartType
+ type
+ autoConvert
+ sprite
+ strategySprite
+ voxelMapLOF
+ voxelMapLOS
+ imageOffset
+ constitution
+ explosion_power
+ explosion_depletion_rate
+ explosion_type
+ fire_resist
+ fire_burn_time
+ block
+ size
+ damaged_map_part
+ alternative_map_part
+ animation_frames
+ transparent
+ sfxIndex
+ door
+ blocksLOS
+ floor
+ gravlift
+ movement_cost
+ height
+ floating
+ provides_support
+ supportedByAbove
+ supportedByDirections
+ supportedByTypes
+ vanillaSupportedById
+ independent_structure
+ exit
+ missionObjective
+ reinforcementSpawner
+
+
+ BattleScore
+ combatRating
+ casualtyPenalty
+ friendlyFire
+ liveAlienCaptured
+ equipmentCaptured
+ equipmentLost
+
+
+ Battle
+ size
+ battle_map
+ losBlocks
+ visibleTiles
+ visibleBlocks
+ visibleUnits
+ visibleEnemies
+ blockAvailable
+ blockCenterPos
+ linkAvailable
+ linkCost
+ blockNeedsUpdate
+ linkNeedsUpdate
+ tilesChangedForVision
+ mission_type
+ mission_location_id
+ mode
+ score
+ missionEndTimer
+ buildingCanBeDisabled
+ buildingDisabled
+ playerWon
+ locationOwner
+ loserHasRetreated
+ winnerHasRetreated
+ player_craft
+ map_parts
+ units
+ scanners
+ items
+ doodads
+ projectiles
+ doors
+ explosions
+ hazards
+ participants
+ leadershipBonus
+ aiBlock
+ currentPlayer
+ currentActiveOrganisation
+ hotseat
+ currentTurn
+ ticksWithoutAction
+ ticksWithoutSeenAction
+ lastSeenActionLocation
+ turnEndAllowed
+ interruptQueue
+ interruptUnits
+ skirmish
+ relationshipsBeforeSkirmish
+ scoreBeforeSkirmish
+ reinforcementsInterval
+ ticksUntilNextReinforcement
+ battleViewZLevel
+ battleViewScreenCenter
+ battleViewGroupMove
+ battleViewSquadIndex
+ battleViewSelectedUnits
+
+
+ BattleMap
+ id
+ chunk_size
+ max_battle_size
+ allow_entrance
+ allow_exit
+ entrance_level_min
+ entrance_level_max
+ exit_level_min
+ exit_level_max
+ exitsX
+ exitsY
+ reinforcementsInterval
+ tilesets
+ destroyed_ground_tile
+ rubble_left_wall
+ rubble_right_wall
+ rubble_feature
+ exit_grounds
+ sectors
+
+
+ BattleMapSector
+ size
+ occurrence_min
+ occurrence_max
+ sectorTilesName
+ tiles
+ spawnLocations
+
+
+ BattleMapSectorTiles
+ losBlocks
+ loot_locations
+ guardianLocations
+ initial_grounds
+ initial_left_walls
+ initial_right_walls
+ initial_features
+
+
+ BattleMapSector::LineOfSightBlock
+ start
+ end
+ ai_patrol_priority
+ ai_target_priority
+ spawn_type
+ spawn_priority
+ also_allow_civilians
+ low_priority
+ spawn_large_units
+ spawn_walking_units
+
+
+ BattleUnitImagePack
+ image_offset
+ images
+
+
+ BattleCommonImageList
+ strategyImages
+ loadingImage
+ focusArrows
+ burningDoodad
+
+
+ CityCommonImageList
+ strategyImages
+ projectileVoxelMap
+ portalVoxelMap
+ agentIsometric
+ agentStrategic
+ portalStrategic
+
+
+ BattleCommonSampleList
+ gravlift
+ door
+ brainsuckerHatch
+ brainsuckerSuck
+ teleport
+ burn
+ genericHitSounds
+ walkSounds
+ objectDropSounds
+ throwSounds
+ psiFailSounds
+ psiSuccessSounds
+
+
+ CityCommonSampleList
+ teleport
+ vehicleExplosion
+ sceneryExplosion
+ shieldHit
+ dimensionShiftIn
+ dimensionShiftOut
+ alertSounds
+
+
+ BattleUnitAnimationPack
+ standart_animations
+ hand_state_animations
+ body_state_animations
+ hasAlternativeFiringAnimations
+ useFiringAnimationForPsi
+ alt_fire_animations
+
+
+ BattleUnitAnimationPack::AnimationEntry
+ frames
+ is_overlay
+ frame_count
+ units_per_100_frames
+
+
+ BattleUnitAnimationPack::AnimationEntry::Frame
+ unit_image_parts
+ unit_image_draw_order
+
+
+ BattleUnitAnimationPack::AnimationEntry::Frame::InfoBlock
+ index
+ offset
+
+
+ BattleUnit
+ id
+ agent
+ owner
+ squadNumber
+ squadPosition
+ weaponStatus
+ targetingMode
+ targetTile
+ timesTargetMIA
+ targetUnit
+ focusUnit
+ focusedByUnits
+ ticksUntillNextTargetCheck
+ psiStatus
+ psiTarget
+ psiItem
+ ticksAccumulatedToNextPsiCheck
+ psiAttackers
+ brainSucker
+ experiencePoints
+ combatRating
+ fatalWounds
+ healingBodyPart
+ isHealing
+ woundTicksAccumulated
+ regenTicksAccumulated
+ stunDamage
+ enzymeDebuffTicksAccumulated
+ fireDebuffTicksAccumulated
+ enzymeDebuffIntensity
+ fireDebuffTicksRemaining
+ moraleState
+ moraleStateTicksRemaining
+ moraleTicksAccumulated
+ initialTU
+ reserveShotCost
+ cloakTicksAccumulated
+ ticksUntillNextCry
+ behavior_mode
+ fire_aiming_mode
+ fire_permission_mode
+ movement_mode
+ kneeling_mode
+ reserve_shot_mode
+ reserve_kneel_mode
+ body_animation_ticks_remaining
+ body_animation_ticks_total
+ body_animation_ticks_static
+ current_body_state
+ target_body_state
+ hand_animation_ticks_remaining
+ residual_aiming_ticks_remaining
+ firing_animation_ticks_remaining
+ current_hand_state
+ target_hand_state
+ movement_ticks_passed
+ movement_sounds_played
+ current_movement_state
+ turning_animation_ticks_remaining
+ missions
+ position
+ goalPosition
+ atGoal
+ usingLift
+ facing
+ goalFacing
+ flyingSpeedModifier
+ retreated
+ destroyed
+ falling
+ launched
+ launchGoal
+ bounced
+ collisionIgnoredTicks
+ velocity
+ tilesMoved
+ giveWayRequestData
+ displayedItem
+ visibleUnits
+ visibleEnemies
+ aiList
+
+
+ BattleItem
+ item
+ position
+ velocity
+ bounced
+ falling
+ ownerInvulnerableTicks
+ collisionIgnoredTicks
+ ticksUntilCollapse
+ owner
+
+
+ BattleHazard
+ position
+ damageType
+ hazardType
+ power
+ lifetime
+ age
+ frame
+ ticksUntilVisible
+ frameChangeTicksAccumulated
+ nextUpdateTicksAccumulated
+ ownerOrganisation
+ ownerUnit
+
+
+ BattleExplosion
+ position
+ power
+ ticksUntilExpansion
+ locationsToExpand
+ locationsVisited
+ damageInTheEnd
+ locationsToDamage
+ damageType
+ depletionRate
+ ownerUnit
+ ownerOrganisation
+ affectedUnits
+
+
+ BattleMapPart
+ type
+ alternative_type
+ position
+ ticksUntilCollapse
+ burnTicksAccumulated
+ damaged
+ falling
+ fallingSpeed
+ destroyed
+ providesHardSupport
+ door
+ supportedItems
+ supportedParts
+ owner
+
+
+ BattleDoor
+ id
+ operational
+ right
+ open
+ animationFrameCount
+ openTicksRemaining
+ animationTicksRemaining
+ doorSound
+
+
+ City
+ id
+ size
+ tile_types
+ initial_tiles
+ buildings
+ scenery
+ doodads
+ portals
+ projectiles
+ initial_portals
+ tileToRoadSegmentMap
+ roadSegments
+ civilianSalary
+ researchUnlock
+ cityViewScreenCenter
+ cityViewPageIndex
+ cityViewSelectedOwnedVehicles
+ cityViewSelectedOtherVehicles
+ cityViewSelectedSoldiers
+ cityViewSelectedBios
+ cityViewSelectedPhysics
+ cityViewSelectedEngineers
+ cityViewSelectedOrganisation
+ cityViewOrgButtonIndex
+
+
+ RoadSegment
+ connections
+ tilePosition
+ intact
+ tileIntact
+ middle
+ length
+
+
+ Projectile
+ type
+ position
+ velocity
+ turnRate
+ age
+ damage
+ delay_ticks_remaining
+ depletionRate
+ lifetime
+ firerVehicle
+ firerUnit
+ trackedVehicle
+ trackedUnit
+ targetPosition
+ previousPosition
+ stunTicks
+ splitIntoTypesCity
+ splitIntoTypesBattle
+ spritePositions
+ tail_length
+ projectile_sprites
+ sprite_distance
+ manualFire
+ voxelMapLof
+ voxelMapLos
+ impactSfx
+ doodadType
+ damageType
+ ownerInvulnerableTicks
+ velocityScale
+
+
+ Doodad
+ position
+ imageOffset
+ temporary
+ age
+ lifetime
+ sprite
+ type
+ voxelMap
+
+
+ DoodadType
+ lifetime
+ repeatable
+ imageOffset
+ frames
+
+
+ Scenery
+ type
+ initialPosition
+ currentPosition
+ ticksUntilCollapse
+ supportedParts
+ supportedBy
+ damaged
+ falling
+ fallingSpeed
+ destroyed
+ supportHardness
+
+
+ BuildingFunction
+ name
+ baseCost
+ baseIncome
+ workersPerTile
+ agentSpawnType
+ investmentValue
+ prestige
+ infiltrationSpeed
+ detectionWeight
+ ufopaedia_entry
+
+
+ Building
+ name
+ city
+ function
+ owner
+ bounds
+ base_layout
+ base
+ battle_map
+ preset_crew
+ current_crew
+ crewQuarters
+ currentVehicles
+ currentAgents
+ cargo
+ isPurchesable
+ purchasePrice
+ maintenanceCosts
+ maximumWorkforce
+ currentWorkforce
+ incomePerCapita
+ currentWage
+ investment
+ prestige
+ ticksDetectionTimeOut
+ ticksDetectionAttemptAccumulated
+ detected
+ timeOfLastAttackEvent
+ researchUnlock
+ accessTopic
+ victory
+ pendingInvestigatorCount
+
+
+ UFOIncursion
+ primaryMission
+ primaryList
+ escortList
+ attackList
+ priority
+
+
+ UFOGrowth
+ week
+ vehicleTypeList
+
+
+ UFOMissionPreference
+ week
+ missionList
+
+
+ BaseLayout
+ baseCorridors
+ baseLift
+
+
+ SceneryTileType
+ tile_type
+ road_type
+ walk_mode
+ connection
+ hill
+ tube
+ sprite
+ strategySprite
+ overlaySprite
+ voxelMap
+ damagedTile
+ imageOffset
+ isLandingPad
+ minimap_colour
+ constitution
+ value
+ mass
+ strength
+ height
+ overlayHeight
+ basement
+ isBuildingPart
+ commonProperty
+ isHill
+
+
+ VAmmoType
+ id
+ name
+ weight
+ ammo_id
+ manufacturer
+ store_space
+
+
+ DamageModifier
+
+
+ HazardType
+ doodadType
+ sound
+ minLifetime
+ maxLifetime
+ fire
+
+
+ DamageType::BlockType
+ Physical
+ Psionic
+ Gas
+ Fire
+
+
+ DamageType::EffectType
+ None
+ Stun
+ Smoke
+ Fire
+ Enzyme
+ Brainsucker
+ Psionic
+
+
+ DamageType
+ name
+ icon_sprite
+ ignore_shield
+ non_violent
+ modifiers
+ explosive
+ explosionDoodad
+ blockType
+ effectType
+ hazardType
+ explosionSounds
+
+
+ AEquipmentType
+ type
+ id
+ name
+ weight
+ held_image_pack
+ dropped_sprite
+ dropped_offset
+ dropped_shadow_sprite
+ shadow_offset
+ equipscreen_sprite
+ equipscreen_size
+ manufacturer
+ store_space
+ armor
+ score
+ research_dependency
+ two_handed
+ bioStorage
+ bioRemains
+ launcher
+ artifact
+ body_sprite
+ damage_modifier
+ body_part
+ body_image_pack
+ provides_flight
+ weapon_types
+ max_ammo
+ burst
+ recharge
+ rechargeTB
+ speed
+ projectile_sprites
+ damage
+ accuracy
+ fire_delay
+ projectile_delay
+ tail_size
+ guided
+ turn_rate
+ range
+ ttl
+ explosion_graphic
+ shield_graphic
+ fire_sfx
+ impact_sfx
+ damage_type
+ trigger_type
+ explosion_depletion_rate
+ spawnList
+
+
+ VEquipmentType
+ type
+ id
+ name
+ weight
+ max_ammo
+ burst
+ ammo_type
+ equipscreen_sprite
+ equipscreen_size
+ manufacturer
+ store_space
+ users
+ speed
+ projectile_sprites
+ damage
+ accuracy
+ fire_delay
+ tail_size
+ guided
+ turn_rate
+ range
+ ttl
+ firing_arc_1
+ firing_arc_2
+ point_defence
+ fire_sfx
+ impact_sfx
+ explosion_graphic
+ icon
+ stunTicks
+ splitIntoTypes
+ power
+ top_speed
+ accuracy_modifier
+ cargo_space
+ passengers
+ alien_space
+ missile_jamming
+ shielding
+ cloaking
+ teleporting
+ dimensionShifting
+ scoreRequirement
+ research_dependency
+
+
+ DoodadFrame
+ image
+ time
+
+
+ FacilityType
+ name
+ fixed
+ buildCost
+ buildTime
+ weeklyCost
+ capacityType
+ capacityAmount
+ size
+ sprite
+ dependency
+ ufopaedia_entry
+ sector
+
+
+ OrganisationRaid::Type
+ None
+ Attack
+ Raid
+ Storm
+ UnauthorizedVehicle
+ Treaty
+
+
+ OrganisationRaid
+ nextRaidTimer
+ attack_vehicle_types
+ neutral_low_manpower
+ neutral_normal
+ neutral_high_manpower
+ military_low_manpower
+ military_normal
+ military_high_manpower
+
+
+ Organisation::MissionPattern::Target
+ Owned
+ OwnedOrOther
+ Other
+ ArriveFromSpace
+ DepartToSpace
+
+
+ Organisation::Relation
+ Allied
+ Friendly
+ Neutral
+ Unfriendly
+ Hostile
+
+
+ Organisation::RecurringMission
+ time
+ pattern
+
+
+ Organisation::RaidMission
+ time
+ type
+ target
+
+
+ Organisation::MissionPattern
+ minIntervalRepeat
+ maxIntervalRepeat
+ minAmount
+ maxAmount
+ allowedTypes
+ target
+ relation
+
+
+ Organisation
+ id
+ name
+ balance
+ income
+ rebuildingRate
+ infiltrationValue
+ infiltrationHistory
+ infiltrationSpeed
+ ticksTakeOverAttemptAccumulated
+ takenOver
+ militarized
+ initiatesDiplomacy
+ providesTransportationServices
+ tech_level
+ average_guards
+ guard_types_reinforcements
+ guard_types_human
+ guard_types_alien
+ loot
+ icon
+ current_relations
+ long_term_relations
+ ufopaedia_entry
+ raid_missions
+ recurring_missions
+ vehiclePark
+ hirableAgentTypes
+
+
+ VehicleType
+ numCreated
+ type
+ name
+ manufacturer
+ image_offset
+ acceleration
+ top_speed
+ health
+ crash_health
+ weight
+ armour
+ passengers
+ aggressiveness
+ score
+ icon
+ battle_map
+ crew_downed
+ crew_deposit
+ equipment_screen
+ equip_icon_big
+ equip_icon_small
+ mapIconType
+ directional_sprites
+ shadow_offset
+ directional_shadow_sprites
+ animation_sprites
+ crashed_sprite
+ height
+ size
+ voxelMaps
+ voxelMapsLOS
+ equipment_layout_slots
+ initial_equipment_list
+ ufopaedia_entry
+ provideFreightAgent
+ provideFreightCargo
+ provideFreightBio
+ canRescueCrashed
+ canEnterDimensionGate
+ researchUnlock
+
+
+ UfopaediaEntry
+ title
+ description
+ background
+ data_id
+ data_type
+ dependency
+
+
+ ResearchDependency
+ type
+ topics
+
+
+ BattleUnitAnimationPack::AnimationKey
+ itemWieldMode
+ handState
+ movementState
+ bodyState
+
+
+ BattleUnitAnimationPack::ChangingHandAnimationKey
+ itemWieldMode
+ currentHand
+ targetHand
+ movementState
+ bodyState
+
+
+ BattleUnitAnimationPack::ChangingBodyStateAnimationKey
+ itemWieldMode
+ handState
+ movementState
+ currentBodyState
+ targetBodyState
+
+
+ BattleUnitAnimationPack::AltFireAnimationKey
+ itemWieldMode
+ handState
+ angle
+ movementState
+ bodyState
+
+
+ VEquipmentType::User
+ Ground
+ Air
+ Ammo
+
+
+ VehicleType::Type
+ Flying
+ UFO
+ Road
+ ATV
+
+
+ VehicleType::Direction
+ N
+ NNE
+ NE
+ NEE
+ E
+ SEE
+ SE
+ SSE
+ S
+ SSW
+ SW
+ SWW
+ W
+ NWW
+ NW
+ NNW
+
+
+ VehicleType::Banking
+ Flat
+ Left
+ Right
+ Ascending
+ Descending
+
+
+ VehicleType::ArmourDirection
+ Top
+ Bottom
+ Front
+ Rear
+ Left
+ Right
+
+
+ VehicleType::MapIconType
+ Arrow
+ SmallCircle
+ LargeCircle
+
+
+ ResearchTopic::Type
+ BioChem
+ Physics
+ Engineering
+
+
+ ResearchTopic::LabSize
+ Small
+ Large
+
+
+ ResearchTopic::ItemType
+ VehicleEquipment
+ AgentEquipment
+ VehicleEquipmentAmmo
+ Craft
+
+
+ Vehicle::AttackMode
+ Aggressive
+ Standard
+ Defensive
+ Evasive
+
+
+ Vehicle::Altitude
+ Highest
+ High
+ Standard
+ Low
+
+
+ VehicleMission::MissionType
+ GotoLocation
+ GotoBuilding
+ FollowVehicle
+ RecoverVehicle
+ AttackVehicle
+ AttackBuilding
+ RestartNextMission
+ Snooze
+ TakeOff
+ Land
+ Crash
+ Patrol
+ GotoPortal
+ InfiltrateSubvert
+ OfferService
+ Teleport
+ SelfDestruct
+ DepartToSpace
+ ArriveFromDimensionGate
+ InvestigateBuilding
+
+
+ AgentMission::MissionType
+ GotoBuilding
+ AwaitPickup
+ RestartNextMission
+ Snooze
+ Teleport
+
+
+ BattleUnitMission::Type
+ GotoLocation
+ Snooze
+ RestartNextMission
+ AcquireTU
+ ChangeBodyState
+ ThrowItem
+ DropItem
+ Turn
+ ReachGoal
+ Teleport
+ Brainsuck
+ Jump
+
+
+ VEquipment::WeaponState
+ Ready
+ Disabled
+ Reloading
+ OutOfAmmo
+
+
+ Battle::MissionType
+ AlienExtermination
+ RaidAliens
+ BaseDefense
+ RaidHumans
+ UfoRecovery
+
+
+ MapDirection
+ North
+ East
+ South
+ West
+ Up
+ Down
+
+
+ Battle::Mode
+ RealTime
+ TurnBased
+
+
+ SpawnType
+ Player
+ Enemy
+ Civilian
+
+
+ ItemWieldMode
+ None
+ OneHanded
+ TwoHanded
+
+
+ BattleUnitAnimationPack::AnimationEntry::Frame::UnitImagePart
+ Shadow
+ Body
+ Legs
+ Helmet
+ LeftArm
+ RightArm
+ Weapon
+
+
+ BattleUnit::BehaviorMode
+ Aggressive
+ Normal
+ Evasive
+
+
+ WeaponAimingMode
+ Aimed
+ Snap
+ Auto
+
+
+ ReserveShotMode
+ Aimed
+ Snap
+ Auto
+ None
+
+
+ BattleUnit::FirePermissionMode
+ AtWill
+ CeaseFire
+
+
+ MovementMode
+ Prone
+ Walking
+ Running
+
+
+ KneelingMode
+ None
+ Kneeling
+
+
+ WeaponStatus
+ NotFiring
+ FiringLeftHand
+ FiringRightHand
+ FiringBothHands
+
+
+ PsiStatus
+ NotEngaged
+ Control
+ Panic
+ Stun
+ Probe
+
+
+ BattleUnit::TargetingMode
+ NoTarget
+ Unit
+ TileCenter
+ TileGround
+
+
+ BattleUnitType
+ SmallWalker
+ SmallFlyer
+ LargeWalker
+ LargeFlyer
+
+
+ Organisation::LootPriority
+ A
+ B
+ C
+
+
+ BattleMapPartType::Type
+ Ground
+ LeftWall
+ RightWall
+ Feature
+
+
+ BattleMapPartType::AutoConvert
+ None
+ Fire
+ Smoke
+
+
+ Projectile::Type
+ Beam
+ Missile
+
+
+ UFOIncursion::PrimaryMission
+ Infiltration
+ Subversion
+ Attack
+ Overspawn
+
+
+ SceneryTileType::TileType
+ General
+ Road
+ PeopleTubeJunction
+ PeopleTube
+ CityWall
+
+
+ SceneryTileType::RoadType
+ StraightBend
+ Junction
+ Terminal
+
+
+ SceneryTileType::WalkMode
+ None
+ Into
+ Onto
+
+
+ FacilityType::Capacity
+ Nothing
+ Quarters
+ Stores
+ Medical
+ Training
+ Psi
+ Repair
+ Chemistry
+ Physics
+ Workshop
+ Aliens
+
+
+ ResearchDependency::Type
+ Any
+ All
+
+
+ UfopaediaEntry::Data
+ Nothing
+ Organisation
+ Vehicle
+ VehicleEquipment
+ Equipment
+ Facility
+ Building
+
+
+ AEquipmentType::Type
+ Armor
+ Weapon
+ Grenade
+ Ammo
+ MotionScanner
+ StructureProbe
+ VortexAnalyzer
+ MultiTracker
+ MindShield
+ MindBender
+ AlienDetector
+ DisruptorShield
+ Teleporter
+ CloakingField
+ DimensionForceField
+ MediKit
+ Brainsucker
+ Popper
+ Spawner
+ Loot
+
+
+ AgentType::Role
+ Soldier
+ Physicist
+ BioChemist
+ Engineer
+
+
+ AgentType::Gender
+ Male
+ Female
+
+
+ EquipmentSlotType
+ General
+ ArmorBody
+ ArmorLegs
+ ArmorHelmet
+ ArmorLeftHand
+ ArmorRightHand
+ LeftHand
+ RightHand
+ VehicleGeneral
+ VehicleWeapon
+ VehicleEngine
+
+
+ TriggerType
+ None
+ Timed
+ Contact
+ Proximity
+ Boomeroid
+
+
+ AlignmentX
+ Left
+ Right
+ Centre
+
+
+ AlignmentY
+ Top
+ Bottom
+ Centre
+
+
+ BodyPart
+ Body
+ Legs
+ Helmet
+ LeftArm
+ RightArm
+
+
+ BodyState
+ Standing
+ Flying
+ Kneeling
+ Prone
+ Jumping
+ Throwing
+ Downed
+ Dead
+
+
+ HandState
+ AtEase
+ Aiming
+ Firing
+
+
+ MovementState
+ None
+ Normal
+ Running
+ Strafing
+ Reverse
+ Brainsuck
+
+
+ AIType
+ None
+ Civilian
+ Loner
+ Group
+ PanicFreeze
+ PanicRun
+ Berserk
+
+
+ AIAction::Type
+ AttackWeaponTile
+ AttackWeaponUnit
+ AttackGrenade
+ AttackPsiPanic
+ AttackPsiStun
+ AttackPsiMC
+ AttackBrainsucker
+ AttackSuicide
+
+
+ AIMovement::Type
+ Stop
+ ChangeStance
+ Patrol
+ Advance
+ Pursue
+ GetInRange
+ TakeCover
+ Retreat
+
+
+ UnitAI::Type
+ LowMorale
+ Default
+ Behavior
+ Vanilla
+ Hardcore
+
+
+ TacticalAI::Type
+ Vanilla
+
+
+ Rank
+ Rookie
+ Squaddie
+ SquadLeader
+ Sergeant
+ Captain
+ Colonel
+ Commander
+
+
+ TrainingAssignment
+ None
+ Physical
+ Psi
+
+
+ MoraleState
+ Normal
+ PanicFreeze
+ PanicRun
+ Berserk
+
+
+ AIAction
+ type
+ targetUnit
+ item
+ weaponStatus
+ psiEnergySnapshot
+ preventOutOfTurnReThink
+ executed
+
+
+ AIMovement
+ type
+ targetLocation
+ movementMode
+ kneelingMode
+ executed
+ subordinate
+
+
+ AIDecision
+ action
+ movement
+
+
+ AIBlockUnit
+ aiList
+ ticksLastThink
+ ticksLastOutOfOrderThink
+ ticksUntilReThink
+
+
+ UnitAILowMorale
+ type
+ active
+ ticksActionAvailable
+
+
+ UnitAIDefault
+ type
+ active
+ ticksAutoTurnAvailable
+ ticksAutoTargetAvailable
+ attackerPosition
+
+
+ UnitAIBehavior
+ type
+ active
+
+
+ UnitAIVanilla
+ type
+ active
+ ticksLastThink
+ ticksUntilReThink
+ lastDecision
+ enemySpotted
+ enemySpottedPrevious
+ attackerPosition
+ lastSeenEnemyPosition
+ flagEnemySpotted
+ flagLastSeenPosition
+ flagLastAttackerPosition
+
+
+ UnitAIHardcore
+ type
+ active
+
+
+ AIBlockTactical
+ aiList
+ ticksLastThink
+ ticksUntilReThink
+
+
+ TacticalAIVanilla
+ type
+
+
+ BattleScanner
+ movementTicks
+ version
+ updateTicksAccumulated
+ lastPosition
+ holder
+
+
+ EconomyInfo
+ weekAvailable
+ basePrice
+ minStock
+ maxStock
+ currentPrice
+ currentStock
+ lastStock
+
+
+ GameScore
+ tacticalMissions
+ researchCompleted
+ alienIncidents
+ craftShotDownUFO
+ craftShotDownXCom
+ incursions
+ cityDamage
+
diff --git a/game/state/message.cpp b/game/state/message.cpp
index da181d92f..5d540bf81 100644
--- a/game/state/message.cpp
+++ b/game/state/message.cpp
@@ -1,8 +1,5 @@
#include "game/state/message.h"
#include "battle/battle.h"
-#include "battle/battleunit.h"
-#include "city/building.h"
-#include "city/vehicle.h"
#include "game/state/gamestate.h"
namespace OpenApoc
diff --git a/game/state/rules/aequipmenttype.cpp b/game/state/rules/aequipmenttype.cpp
index 7549adfd9..f97b284e2 100644
--- a/game/state/rules/aequipmenttype.cpp
+++ b/game/state/rules/aequipmenttype.cpp
@@ -2,7 +2,6 @@
#include "game/state/gamestate.h"
#include "game/state/shared/aequipment.h"
#include "game/state/tilemap/tilemap.h"
-#include
namespace OpenApoc
{
@@ -127,6 +126,26 @@ bool AEquipmentType::canBeUsed(GameState &state, StateRef owner) c
return true;
}
+bool AEquipmentType::isResearched() const
+{
+ StateRef equipmentTopic;
+
+ for (auto &dependencyTopic : research_dependency.topics)
+ {
+ if (dependencyTopic->name == name)
+ {
+ equipmentTopic = dependencyTopic;
+ break;
+ }
+ }
+
+ // If no research topic is found with same name as type, then we use "satisfied()" instead
+ // This is not the prefered method since it will consider not only specific topic but all
+ // children topics as well
+
+ return equipmentTopic ? equipmentTopic->isComplete() : research_dependency.satisfied();
+}
+
float AEquipmentType::getRoundsPerSecond() const
{
return (float)TICKS_PER_SECOND / (float)fire_delay;
diff --git a/game/state/rules/aequipmenttype.h b/game/state/rules/aequipmenttype.h
index 8d2357536..889fd9157 100644
--- a/game/state/rules/aequipmenttype.h
+++ b/game/state/rules/aequipmenttype.h
@@ -176,6 +176,17 @@ class AEquipmentType : public StateObject
std::map, int> spawnList;
bool canBeUsed(GameState &state, StateRef user) const;
+
+ ///
+ /// Get if type is researched.
+ ///
+ /// By default it will search through dependency topics via topic name.
+ /// If no topic with same name is found, then method will call "research_dependency.satisfied()"
+ /// instead, which unfortunately considers not only topic research, but children research status
+ /// as well.
+ ///
+ /// Returns if type is already researched.
+ bool isResearched() const;
};
class EquipmentSet : public StateObject
diff --git a/game/state/rules/agenttype.cpp b/game/state/rules/agenttype.cpp
index a36e8a1cf..8a4822734 100644
--- a/game/state/rules/agenttype.cpp
+++ b/game/state/rules/agenttype.cpp
@@ -1,23 +1,10 @@
#include "game/state/rules/agenttype.h"
#include "framework/framework.h"
#include "game/state/battle/ai/aitype.h"
-#include "game/state/battle/battleunit.h"
#include "game/state/city/agentmission.h"
-#include "game/state/city/base.h"
-#include "game/state/city/building.h"
-#include "game/state/city/city.h"
-#include "game/state/city/facility.h"
-#include "game/state/city/scenery.h"
#include "game/state/city/vehicle.h"
-#include "game/state/gameevent.h"
#include "game/state/gamestate.h"
-#include "game/state/rules/aequipmenttype.h"
-#include "game/state/rules/city/scenerytiletype.h"
-#include "game/state/shared/aequipment.h"
-#include "game/state/shared/organisation.h"
-#include "game/state/tilemap/tileobject_scenery.h"
#include "library/strings_format.h"
-#include
namespace OpenApoc
{
diff --git a/game/state/rules/battle/battlecommonsamplelist.h b/game/state/rules/battle/battlecommonsamplelist.h
index b0f0952f3..81058ba80 100644
--- a/game/state/rules/battle/battlecommonsamplelist.h
+++ b/game/state/rules/battle/battlecommonsamplelist.h
@@ -1,9 +1,7 @@
#pragma once
-#include "game/state/stateobject.h"
#include "library/sp.h"
#include
-#include