diff --git a/.clang-tidy b/.clang-tidy index 4662f94f442d1..ef41eda3bb7b5 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,6 +1,6 @@ -Checks: 'clang-diagnostic-*,-clang-analyzer-security.FloatLoopCounter,-clang-analyzer-core.UndefinedBinaryOperatorResult' +Checks: 'clang-diagnostic-*,modernize-use-using' WarningsAsErrors: '*' -HeaderFilterRegex: '.*' +HeaderFilterRegex: '(src|test).*' FormatStyle: none # vim:tw=0 diff --git a/.travis.yml b/.travis.yml index 24df1acd92081..5977deb0b9b6e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,71 +32,94 @@ branches: - master - development +# Overall strategy for what sorts of builds to include: +# We want a build for each compiler and each platform. +# For PRs, we lessen the "each compiler" requirement to just covering the newest +# and oldest relevant version of each compiler. +# We also want to ensure that each of the following tweaks are covered in at +# least one PR build: +# - TILES=1 +# - SOUND=1 +# - RELEASE=1 +# - CMAKE=1 +# - SANITIZE=address +# - LOCALIZE=0 +# - A clang-tidy run +# We try to minimize the number of builds subject to those constraints. + +# To see what toolchains are available, consult the following: +# https://github.com/travis-ci/apt-source-safelist/blob/master/ubuntu.json +# https://launchpad.net/%7Eubuntu-toolchain-r/+archive/ubuntu/test/+index + jobs: include: # Initial test stage, if this fails everything else is cancelled. - - stage: test - # GCC 5.4 is the pre-installed compiler on Xenial - env: COMPILER=g++ MODS=--mods=RL_Classes TEST_STAGE=1 + - stage: Test + # Clang is consistently the fastest to build, so use it for the initial test. + # Clang 3.8, oldest supported Clang, build with Makefile with extra tests and json style check. + env: CLANG=clang++-3.8 MODS=--mods=RL_Classes TEST_STAGE=1 CXXFLAGS='-Wno-error=unused-command-line-argument -D__extern_always_inline="extern __always_inline"' + compiler: clang + addons: &clang38 + apt: + packages: ["clang-3.8", "g++-multilib", "libc6-dbg", "libc6-dbg:i386", "g++-6"] + sources: *apt_sources # Then build different configurations and targets in parallel. - - stage: variants - # Linux Tiles - env: COMPILER=g++-8 CXXFLAGS='-Wno-implicit-fallthrough' TILES=1 SOUND=1 SANITIZE=address + - stage: "Main Compilers" + # GCC 5.3, oldest supported GCC, build with Makefile configured for Curses, disable LOCALIZE + env: COMPILER=g++ LOCALIZE=0 + compiler: gcc + addons: &gcc53 + apt: + packages: ["g++-5=5.3.1-14ubuntu2", "libstdc++-5-dev=5.3.1-14ubuntu2", "gcc-5=5.3.1-14ubuntu2", "gcc-5-base=5.3.1-14ubuntu2", "cpp-5=5.3.1-14ubuntu2", "libgcc-5-dev=5.3.1-14ubuntu2", "libasan2=5.3.1-14ubuntu2", "libmpx0=5.3.1-14ubuntu2"] + sources: [*apt_sources] + + # GCC 8, latest supported GCC, build with Makefile configured with TILES and SOUND and use address sanitization + - env: COMPILER=g++-8 CXXFLAGS='-Wno-implicit-fallthrough' TILES=1 SOUND=1 SANITIZE=address compiler: gcc addons: &gcc8 apt: packages: ["g++-8", "g++-8-multilib", "libc6-dbg", "libc6-dbg:i386", "libsdl2-dev", "libsdl2-ttf-dev", "libsdl2-image-dev", "libsdl2-mixer-dev"] sources: *apt_sources - # MXE variants using alternate repository http://mirror.mxe.cc/repos/apt - # GCC MinGW - - env: COMPILER='g++' LDFLAGS='-static-libgcc -static-libstdc++' MXE_TARGET='i686-w64-mingw32.static' WINE='wine' - addons: &gcc + # Clang 8, latest supported Clang, build with Makefile and address sanitization, but disable some very long-running tests + - env: CLANG=clang++-8 SANITIZE=address EXTRA_TEST_OPTS="~[.] ~vehicle_efficiency ~vehicle_drag ~starting_items" + compiler: clang + addons: &clang8 apt: - packages: ["wine"] + packages: ["clang-8", "libc6-dbg", "libc6-dbg:i386"] + sources: [*apt_sources, llvm-toolchain-xenial-8] - # Windows Tiles - - env: COMPILER='g++' LDFLAGS='-static-libgcc -static-libstdc++' MXE_TARGET='i686-w64-mingw32.static' WINE='wine' TILES=1 SOUND=1 + - stage: "Platforms and Tidy" + # MXE variant using alternate repository http://mirror.mxe.cc/repos/apt + # Mingw-w64 building with Tiles and Sound + env: COMPILER='g++' LDFLAGS='-static-libgcc -static-libstdc++' MXE_TARGET='i686-w64-mingw32.static' WINE='wine' TILES=1 SOUND=1 compiler: gcc addons: &gcc apt: packages: ["wine"] - # CMake Clang 6.0 Tiles with CMAKE - - env: CLANG=clang++-6.0 TILES=1 SOUND=1 CXXFLAGS=-Wno-error=unused-command-line-argument CMAKE=1 RELEASE=1 - dist: trusty - compiler: clang - addons: &clang60 - apt: - packages: ["clang-6.0", "g++-multilib", "libc6-dbg", "libc6-dbg:i386", "g++-6", "libsdl2-dev", "libsdl2-ttf-dev", "libsdl2-image-dev", "libsdl2-mixer-dev"] - sources: [*apt_sources, llvm-toolchain-trusty-6.0] - # macOS Tiles + # Xcode 10.1 building with Tiles and sound - env: CLANG=clang++ NATIVE=osx OSX_MIN=10.13 TILES=1 SOUND=1 os: osx osx_image: xcode10.1 compiler: clang - # CMake Clang 8.0 Tiles with CMAKE and clang-tidy + # Execute Clang-tidy with CMake, configured with Tiles and Sound # (analysis only; no build or tests) - env: CLANG=clang++-8 TILES=1 SOUND=1 CXXFLAGS=-Wno-unused-command-line-argument CMAKE=1 CATA_CLANG_TIDY=clang-tidy-8 compiler: clang - addons: &clang80 + addons: &clang8 apt: - packages: ["clang-8", "clang-tidy-8", "libc6-dbg", "libc6-dbg:i386", "g++-6", "libsdl2-dev", "libsdl2-ttf-dev", "libsdl2-image-dev", "libsdl2-mixer-dev"] + packages: ["clang-8", "clang-tidy-8", "libsdl2-dev", "libsdl2-ttf-dev", "libsdl2-image-dev", "libsdl2-mixer-dev"] sources: [*apt_sources, llvm-toolchain-xenial-8] - # Finally check the compiler variants - stage: compilers - env: COMPILER=g++ 5.3 + # GCC 5.4 is default on Xenial + env: COMPILER=g++ if: type != pull_request - compiler: gcc - addons: &gcc53 - apt: - packages: ["g++-5=5.3.1-14ubuntu2", "libstdc++-5-dev=5.3.1-14ubuntu2", "gcc-5=5.3.1-14ubuntu2", "gcc-5-base=5.3.1-14ubuntu2", "cpp-5=5.3.1-14ubuntu2", "libgcc-5-dev=5.3.1-14ubuntu2", "libasan2=5.3.1-14ubuntu2", "libmpx0=5.3.1-14ubuntu2"] - sources: [*apt_sources] # GCC 6 - env: COMPILER=g++-6 @@ -107,34 +130,21 @@ jobs: packages: ["g++-6", "g++-6-multilib", "libc6-dbg", "libc6-dbg:i386"] sources: *apt_sources - # GCC 7 - - env: COMPILER=g++-7 CXXFLAGS='-Wno-implicit-fallthrough' CODE_COVERAGE=true + # GCC 7, adding _GLIBCXX_DEBUG so that one build can test with that + - env: COMPILER=g++-7 CXXFLAGS='-Wno-implicit-fallthrough -D_GLIBCXX_DEBUG' CODE_COVERAGE=true if: type != pull_request compiler: gcc - dist: trusty addons: &gcc7 apt: packages: ["g++-7", "g++-7-multilib", "libc6-dbg", "libc6-dbg:i386", "lcov"] sources: *apt_sources - # GCC 8 - # Also, adding _GLIBCXX_DEBUG so that one build can test with that - - env: COMPILER=g++-8 CXXFLAGS='-Wno-implicit-fallthrough -D_GLIBCXX_DEBUG' - compiler: gcc - if: type != pull_request - addons: &gcc8 - apt: - packages: ["g++-8", "g++-8-multilib", "libc6-dbg", "libc6-dbg:i386"] - sources: *apt_sources - - # Clang 3.8 - - env: CLANG=clang++-3.8 CXXFLAGS='-Wno-error=unused-command-line-argument -D__extern_always_inline="extern __always_inline"' - compiler: clang + # GCC MinGW with only terminal support + - env: COMPILER='g++' LDFLAGS='-static-libgcc -static-libstdc++' MXE_TARGET='i686-w64-mingw32.static' WINE='wine' if: type != pull_request - addons: &clang38 + addons: &gcc apt: - packages: ["clang-3.8", "g++-multilib", "libc6-dbg", "libc6-dbg:i386", "g++-6"] - sources: *apt_sources + packages: ["wine"] # Clang 3.9 - env: CLANG=clang++-3.9 CXXFLAGS='-Wno-error=unused-command-line-argument -D__extern_always_inline="extern __always_inline"' @@ -152,9 +162,11 @@ jobs: addons: &clang40 apt: packages: ["clang-4.0", "g++-multilib", "libc6-dbg", "libc6-dbg:i386", "g++-6"] + # Luckily the Trusty install Just Works on Xenial sources: [*apt_sources, llvm-toolchain-trusty-4.0] - # Clang 5.0 + # Clang 5.0 (still on Trusty, because I could find no readily available + # source on Xenial at time of writing) - env: CLANG=clang++-5.0 CXXFLAGS=-Wno-error=unused-command-line-argument if: type != pull_request dist: trusty @@ -164,14 +176,23 @@ jobs: packages: ["clang-5.0", "g++-multilib", "libc6-dbg", "libc6-dbg:i386", "g++-6"] sources: [*apt_sources, llvm-toolchain-trusty-5.0] - # Clang 6.0 - - env: CLANG=clang++-6.0 CXXFLAGS=-Wno-error=unused-command-line-argument SANITIZE=address EXTRA_TEST_OPTS="~[.] ~vehicle_efficiency ~vehicle_drag ~starting_items" - dist: trusty + # CMake Clang 6.0 Tiles with CMAKE + - env: CLANG=clang++-6.0 TILES=1 SOUND=1 CXXFLAGS=-Wno-error=unused-command-line-argument CMAKE=1 RELEASE=1 + if: type != pull_request compiler: clang addons: &clang60 apt: - packages: ["clang-6.0", "g++-multilib", "libc6-dbg", "libc6-dbg:i386", "g++-6"] - sources: [*apt_sources, llvm-toolchain-trusty-6.0] + packages: ["clang-6.0", "g++-multilib", "libc6-dbg", "g++-6", "libsdl2-dev", "libsdl2-ttf-dev", "libsdl2-image-dev", "libsdl2-mixer-dev"] + sources: [*apt_sources, llvm-toolchain-xenial-6.0] + + # Clang 7 + - env: CLANG=clang++-7 + if: type != pull_request + compiler: clang + addons: &clang7 + apt: + packages: ["clang-7", "libc6-dbg", "libc6-dbg:i386"] + sources: [*apt_sources, llvm-toolchain-xenial-7] before_script: - if [ -n "${CLANG}" ]; then COMPILER="$CLANG"; fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e83018c401b3..2c1443daf5d5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,7 +212,9 @@ IF(MSVC) add_definitions(-D_X86_) endif() ELSE() - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall -Wextra -Woverloaded-virtual -Wpedantic -std=c++14") + SET(CATA_WARNINGS + "-Werror -Wall -Wextra -Woverloaded-virtual -Wpedantic -Wmissing-declarations") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CATA_WARNINGS} -std=c++14") SET(CMAKE_CXX_FLAGS_DEBUG "-Og -g") ENDIF() diff --git a/COMPILING.md b/COMPILING.md index 5da66db03922f..ed323cedf4251 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -10,10 +10,11 @@ * [Cross-compile to Windows from Linux](#cross-compile-to-windows-from-linux) * [Cross-compile to Mac OS X from Linux](#cross-compile-to-mac-os-x-from-linux) * [Cross-compile to Android from Linux](#cross-compile-to-android-from-linux) + * [Troubleshooting](#debian-troubleshooting) * [Mac OS X](#mac-os-x) * [Simple build using Homebrew](#simple-build-using-homebrew) * [Advanced info for Developers](#advanced-info-for-developers) - * [Troubleshooting](#troubleshooting) + * [Troubleshooting](#mac-troubleshooting) * [Windows](#windows) * [Visual Studio Guide](#visual-studio-guide) * [MinGW Guide](#mingw-guide) @@ -353,6 +354,10 @@ To build a signed release APK (ie. one that can be installed on a device), [buil The app stores data files on the device in `/sdcard/Android/data/com.cleverraven/cataclysmdda/files`. The data is backwards compatible with the desktop version. +## Linux Troubleshooting + +If you get an error stating `make: build-scripts/validate_pr_in_jenkins: Command not found` clone a separate copy of the upstream source to a new git repository as your git setup has become corrupted by the Blob. + # Mac OS X To build Cataclysm on Mac you'll need [Command Line Tools for Xcode](https://developer.apple.com/downloads/) and the [Homebrew](http://brew.sh) package manager. With Homebrew, you can easily install or build Cataclysm using the [Cataclysm](https://formulae.brew.sh/formula/cataclysm) forumla. diff --git a/Makefile b/Makefile index daf3e07e178c2..533710fc720ea 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ # PROFILE is for use with gprof or a similar program -- don't bother generally. # RELEASE_FLAGS is flags for release builds. RELEASE_FLAGS = -WARNINGS = -Werror -Wall -Wextra -Woverloaded-virtual -Wpedantic +WARNINGS = -Werror -Wall -Wextra -Woverloaded-virtual -Wpedantic -Wmissing-declarations # Uncomment below to disable warnings #WARNINGS = -w DEBUGSYMS = -g diff --git a/build-scripts/build.sh b/build-scripts/build.sh index b9fbcac025cbd..521abd96877e1 100755 --- a/build-scripts/build.sh +++ b/build-scripts/build.sh @@ -18,6 +18,10 @@ if [ -n "$TEST_STAGE" ] then build-scripts/lint-json.sh make -j "$num_jobs" style-json + + # Also build chkjson (even though we're not using it), to catch any + # compile errors there + make -j "$num_jobs" chkjson elif [ -n "$JUST_JSON" ] then echo "Early exit on just-json change" @@ -107,7 +111,7 @@ else run_tests ./tests/cata_test & if [ -n "$MODS" ] then - run_tests ./tests/cata_test $MODS & + run_tests ./tests/cata_test --user-dir=modded $MODS & wait -n fi wait -n diff --git a/build-scripts/requirements.sh b/build-scripts/requirements.sh index b99be52d9f83e..99ad8505ab89c 100644 --- a/build-scripts/requirements.sh +++ b/build-scripts/requirements.sh @@ -22,9 +22,9 @@ if just_json; then fi if [ -n "${CODE_COVERAGE}" ]; then - travis_retry pip install --user pyyaml cpp-coveralls; - export CXXFLAGS=--coverage; - export LDFLAGS=--coverage; + travis_retry pip install --user pyyaml cpp-coveralls + export CXXFLAGS="$CXXFLAGS --coverage" + export LDFLAGS="$LDFLAGS --coverage" fi if [ -n "$CATA_CLANG_TIDY" ]; then diff --git a/data/json/bionics.json b/data/json/bionics.json index fc57a2642187c..0555ec3a2e74f 100644 --- a/data/json/bionics.json +++ b/data/json/bionics.json @@ -53,7 +53,7 @@ "name": "Alloy Plating - Arms", "description": "The flesh on your arms has been surgically replaced by a strong armor, protecting you greatly.", "occupied_bodyparts": [ [ "ARM_L", 4 ], [ "ARM_R", 4 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_armor_eyes", @@ -61,7 +61,7 @@ "name": "Protective Lenses", "description": "Your eye sockets have been surgically sealed with highly protective mirrored lenses and your tear ducts have been re-routed to your mouth. When you cry, you must spit out or swallow your tears.", "occupied_bodyparts": [ [ "EYES", 1 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_armor_head", @@ -69,7 +69,7 @@ "name": "Alloy Plating - Head", "description": "The flesh on your head has been surgically replaced by a strong armor, protecting both your head and jaw regions.", "occupied_bodyparts": [ [ "HEAD", 5 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_armor_legs", @@ -77,7 +77,7 @@ "name": "Alloy Plating - Legs", "description": "The flesh on your legs has been surgically replaced by a strong armor, protecting you greatly.", "occupied_bodyparts": [ [ "LEG_L", 6 ], [ "LEG_R", 6 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_armor_torso", @@ -85,7 +85,7 @@ "name": "Alloy Plating - Torso", "description": "The flesh on your torso has been surgically replaced by a strong armor, protecting you greatly.", "occupied_bodyparts": [ [ "TORSO", 10 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_batteries", @@ -156,7 +156,7 @@ "capacity": 10, "description": "You have a complex port surgically mounted above your hip. While active, it will drain power through a jumper cable held on your person.", "occupied_bodyparts": [ [ "TORSO", 10 ] ], - "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_TOGGLED" ] + "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_SHOCKPROOF", "BIONIC_TOGGLED" ] }, { "id": "bio_carbon", @@ -175,7 +175,7 @@ [ "FOOT_L", 1 ], [ "FOOT_R", 1 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_chain_lightning", @@ -274,7 +274,7 @@ "name": "Expanded Digestive System", "description": "You have been outfitted with three synthetic stomachs and industrial-grade intestines. Not only can you extract much more nutrition from food, but you are highly resistant to foodborne illness, and can sometimes eat rotten food.", "occupied_bodyparts": [ [ "TORSO", 20 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_dis_acid", @@ -340,7 +340,7 @@ "name": "Ethanol Burner", "description": "You burn alcohol as fuel in an extremely efficient reaction. However, you will still suffer the inebriating effects of the substance.", "occupied_bodyparts": [ [ "TORSO", 26 ] ], - "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_NPC_USABLE", "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_POWER_SOURCE", "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_evap", @@ -390,7 +390,7 @@ [ "FOOT_L", 1 ], [ "FOOT_R", 1 ] ], - "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE" ], + "flags": [ "BIONIC_TOGGLED", "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ], "act_cost": 1, "react_cost": 1, "time": 2 @@ -954,7 +954,7 @@ "name": "Internal Storage", "description": "Space inside your chest cavity has been surgically converted into a storage area. You may carry an extra 2 liters of volume.", "occupied_bodyparts": [ [ "TORSO", 32 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_str_enhancer", @@ -1122,7 +1122,7 @@ "name": "Titanium Skeletal Bracing", "description": "Titanium bracing has been installed onto your elbows, knees, and spine, making them far better at handling strain. Your carrying capacity is increased by 20 kilograms, or about 44 pounds.", "occupied_bodyparts": [ [ "TORSO", 8 ], [ "ARM_L", 3 ], [ "ARM_R", 3 ], [ "LEG_L", 3 ], [ "LEG_R", 3 ] ], - "flags": [ "BIONIC_NPC_USABLE" ] + "flags": [ "BIONIC_NPC_USABLE", "BIONIC_SHOCKPROOF" ] }, { "id": "bio_shock_absorber", diff --git a/data/json/construction.json b/data/json/construction.json index fb9d82fe56861..b3b62e8621505 100644 --- a/data/json/construction.json +++ b/data/json/construction.json @@ -2515,5 +2515,60 @@ ], "pre_terrain": "t_fence_post", "post_terrain": "t_wall_rammed_earth" + }, + { + "type": "construction", + "description": "Build Counter Gate", + "category": "FURN", + "required_skills": [ [ "fabrication", 1 ] ], + "time": 30, + "qualities": [ [ { "id": "HAMMER", "level": 2 } ] ], + "components": [ [ [ "2x4", 6 ] ], [ [ "nail", 10 ] ] ], + "pre_special": "check_empty", + "post_terrain": "f_counter_gate_c" + }, + { + "type": "construction", + "description": "Build Split Rail Fence Gate", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ], [ "survival", 1 ] ], + "time": 30, + "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "DIG", "level": 2 } ] ], + "components": [ [ [ "pointy_stick", 2 ], [ "spear_wood", 2 ] ], [ [ "2x4", 5 ] ], [ [ "nail", 12 ] ] ], + "pre_flags": "DIGGABLE", + "post_terrain": "t_splitrail_fencegate_c" + }, + { + "type": "construction", + "description": "Build Privacy Fence Gate", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ], [ "survival", 1 ] ], + "time": 30, + "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "DIG", "level": 2 } ] ], + "components": [ [ [ "pointy_stick", 2 ], [ "spear_wood", 2 ] ], [ [ "2x4", 8 ] ], [ [ "nail", 20 ] ] ], + "pre_flags": "DIGGABLE", + "post_terrain": "t_privacy_fencegate_c" + }, + { + "type": "construction", + "description": "Build Split Rail Fence", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ], [ "survival", 1 ] ], + "time": 30, + "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "DIG", "level": 2 } ] ], + "components": [ [ [ "pointy_stick", 2 ], [ "spear_wood", 2 ] ], [ [ "2x4", 4 ] ], [ [ "nail", 20 ] ] ], + "pre_flags": "DIGGABLE", + "post_terrain": "t_splitrail_fence" + }, + { + "type": "construction", + "description": "Build Privacy Fence", + "category": "CONSTRUCT", + "required_skills": [ [ "fabrication", 2 ], [ "survival", 1 ] ], + "time": 30, + "qualities": [ [ { "id": "HAMMER", "level": 2 } ], [ { "id": "DIG", "level": 2 } ] ], + "components": [ [ [ "pointy_stick", 2 ], [ "spear_wood", 2 ] ], [ [ "2x4", 8 ] ], [ [ "nail", 20 ] ] ], + "pre_flags": "DIGGABLE", + "post_terrain": "t_privacy_fence" } ] diff --git a/data/json/furniture.json b/data/json/furniture.json index d81dda952ff78..e0c4980f7f140 100644 --- a/data/json/furniture.json +++ b/data/json/furniture.json @@ -72,7 +72,7 @@ "type": "furniture", "id": "f_rubble_rock", "name": "pile of rocky rubble", - "description": "Pile of rocks. Useless.", + "description": "Pile of rocks. Useless?", "symbol": "^", "color": "dark_gray", "move_cost_mod": 6, @@ -96,7 +96,7 @@ "type": "furniture", "id": "f_rubble_landfill", "name": "pile of trashy rubble", - "description": "Trash topped with dirt and grass, it smells gross and but another mans trash...", + "description": "Trash topped with dirt and grass, it smells gross, but another man's trash...", "symbol": "#", "color": "green", "move_cost_mod": 8, @@ -284,7 +284,7 @@ "type": "furniture", "id": "f_bulletin", "name": "bulletin board", - "description": "Pin some notes for other survivors to read.", + "description": "A big, cork bulletin board capable of sporting various notices. Pin some notes for other survivors to read.", "symbol": "6", "color": "blue", "move_cost_mod": -1, @@ -382,7 +382,7 @@ "id": "f_bed", "name": "bed", "symbol": "#", - "description": "Quite comfortable to sleep in.", + "description": "This is a bed. A luxury in these times. Quite comfortable to sleep in.", "color": "magenta", "move_cost_mod": 3, "coverage": 40, @@ -413,7 +413,7 @@ "name": "toilet", "symbol": "&", "color": "white", - "description": "Emergency water source, from the tank, and provider of relief.", + "description": "A porcelain throne. Emergency water source, from the tank, and provider of relief.", "move_cost_mod": 2, "coverage": 30, "required_str": -1, @@ -489,7 +489,7 @@ "id": "f_sink", "name": "sink", "symbol": "&", - "description": "Emergency relief provider. Water isn't running, so no water.", + "description": "Emergency relief provider. Water isn't running, so it's basically useless.", "color": "white", "move_cost_mod": 2, "coverage": 60, @@ -512,7 +512,7 @@ "id": "f_oven", "name": "oven", "symbol": "#", - "description": "Used for heating and cooking food with electricity. Doesn't look like it's working, although it still has parts.", + "description": "Used for heating and cooking food with electricity. Doesn't look like it's working, although it still has parts. It might be safe to light a fire inside of it, if you had to.", "color": "dark_gray", "move_cost_mod": 2, "coverage": 60, @@ -554,7 +554,7 @@ "name": "wood stove", "symbol": "#", "bgcolor": "red", - "description": "Wood stove for heating and cooking. Much more effective than an open flame.", + "description": "Wood stove for heating and cooking. Much more efficient than an open flame.", "move_cost_mod": 2, "coverage": 60, "required_str": 10, @@ -575,7 +575,7 @@ "id": "f_fireplace", "name": "fireplace", "symbol": "#", - "description": "Ah. The relaxation of sitting in front of a fire as the world around you crumbles.", + "description": "Ah. The relaxation of sitting in front of a fire as the world around you crumbles. Towards the End, you could also get this service on your television.", "bgcolor": "white", "move_cost_mod": 2, "coverage": 50, @@ -774,7 +774,7 @@ "id": "f_trashcan", "name": "trash can", "symbol": "&", - "description": "One man's trash is another mans dinner.", + "description": "One man's trash is another man's dinner.", "color": "light_cyan", "move_cost_mod": 1, "required_str": 5, @@ -813,7 +813,7 @@ "id": "f_desk", "name": "desk", "symbol": "#", - "description": "Sit down at it, and, if up to, work on it.", + "description": "Sit down at it or work on it.", "color": "light_red", "move_cost_mod": 1, "coverage": 45, @@ -840,7 +840,7 @@ "id": "f_exercise", "name": "exercise machine", "symbol": "T", - "description": "Typically used for, well, exercising. You're not up for it.", + "description": "Typically used for, well, exercising. You're getting quite enough of that; running for your life.", "color": "dark_gray", "move_cost_mod": 1, "coverage": 35, @@ -871,7 +871,7 @@ "type": "furniture", "id": "f_ball_mach", "name": "ball machine", - "description": "Remember when baseball was a thing?", + "description": "An unpowered machine that seems like it could've been used to launch various balls for different types of sports. It's only good for parts now if disassembled.", "symbol": "T", "color": "dark_gray", "move_cost_mod": 1, @@ -890,7 +890,7 @@ "id": "f_bench", "name": "bench", "symbol": "#", - "description": "Hobo bed. Use at your own risk.", + "description": "Hobo bed. Airy. Use at your own risk.", "color": "brown", "move_cost_mod": 1, "coverage": 35, @@ -1019,7 +1019,7 @@ "id": "f_mailbox", "name": "mailbox", "symbol": "P", - "description": "A metal box attached to the top of a wooden post. You've got mail.", + "description": "A metal box attached to the top of a wooden post. Mail delivery hasn't come for awhile. Doesn't look like it's coming again anytime soon.", "color": "light_gray", "move_cost_mod": 1, "required_str": -1, @@ -1091,12 +1091,57 @@ "examine_action": "workbench", "workbench": { "multiplier": 1.1, "mass": 200000, "volume": "75L" } }, + { + "type": "furniture", + "id": "f_counter_gate_c", + "name": "closed counter gate", + "description": "A commercial quality swining door made of wood that allows passage behind counters.", + "symbol": "+", + "color": "blue", + "move_cost": 3, + "move_cost_mod": 2, + "required_str": 4, + "coverage": 60, + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "DOOR", "ORGANIC" ], + "connects_to": "COUNTER", + "open": "f_counter_gate_o", + "deconstruct": { "ter_set": "t_floor", "items": [ { "item": "2x4", "count": 6 }, { "item": "nail", "charges": 10 } ] }, + "bash": { + "str_min": 12, + "str_max": 40, + "sound": "smash!", + "sound_fail": "whump.", + "items": [ { "item": "2x4", "count": [ 2, 6 ] }, { "item": "nail", "charges": [ 4, 8 ] }, { "item": "splinter", "count": 1 } ] + } + }, + { + "type": "furniture", + "id": "f_counter_gate_o", + "name": "open counter gate", + "description": "A commercial quality swinging door made of wood that allows passage behind counters.", + "symbol": ".", + "color": "blue", + "move_cost": 2, + "move_cost_mod": 2, + "required_str": 4, + "connects_to": "COUNTER", + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "FLAT", "ROAD", "ORGANIC" ], + "close": "f_counter_gate_c", + "deconstruct": { "ter_set": "t_floor", "items": [ { "item": "2x4", "count": 6 }, { "item": "nail", "charges": 10 } ] }, + "bash": { + "str_min": 12, + "str_max": 40, + "sound": "smash!", + "sound_fail": "whump.", + "items": [ { "item": "2x4", "count": [ 2, 6 ] }, { "item": "nail", "charges": [ 4, 8 ] }, { "item": "splinter", "count": 1 } ] + } + }, { "type": "furniture", "id": "f_fridge", "name": "refrigerator", "symbol": "{", - "description": "Freeze your food with the amazing science of electricity! Oh wait, none is flowing.", + "description": "Freeze your food with the amazing science of electricity! Oh wait, none is flowing. Well, as long as you don't open it, maybe it'll stay cool for awhile.", "color": "light_cyan", "move_cost_mod": -1, "coverage": 90, @@ -1143,7 +1188,7 @@ "name": "glass door fridge", "symbol": "{", "color": "light_cyan", - "description": "Wow! See INTO your fridge before you open it!", + "description": "Wow! See INTO your fridge before you open it and discover it's not working!", "move_cost_mod": -1, "coverage": 90, "required_str": 10, @@ -1188,7 +1233,7 @@ "id": "f_dresser", "name": "dresser", "symbol": "{", - "description": "Dress yourself for the prom, or other occasions.", + "description": "Dress yourself for the zombie prom, or other occasions.", "color": "brown", "move_cost_mod": -1, "coverage": 70, @@ -1272,9 +1317,9 @@ { "type": "furniture", "id": "f_bookcase", - "name": "book case", + "name": "bookcase", "symbol": "{", - "description": "Stores books. Y'know, Those things. Who reads books anymore?", + "description": "Stores books. Y'know, those things. Who reads books anymore?", "color": "brown", "move_cost_mod": -1, "coverage": 80, @@ -1336,7 +1381,7 @@ "type": "furniture", "id": "f_dryer", "name": "dryer", - "description": "Dry your clothes!", + "description": "'Dry your clothes!' would be what you'd do if electricity was running.", "symbol": "{", "bgcolor": "white", "move_cost_mod": -1, @@ -1376,7 +1421,7 @@ "id": "f_bigmirror", "name": "standing mirror", "symbol": "{", - "description": "Lookin' good- is that blood?", + "description": "Lookin' good - is that blood?", "color": "white", "move_cost_mod": 2, "coverage": 80, @@ -1438,7 +1483,7 @@ "type": "furniture", "id": "f_vending_o", "name": "broken vending machine", - "description": "Ponder if you could buy stuff, as it's broken.", + "description": "Ponder if you could buy stuff, as it's broken. Maybe if you broke it more, you wouldn't need to pay at all!", "symbol": "{", "color": "dark_gray", "move_cost_mod": -1, @@ -1463,7 +1508,7 @@ "type": "furniture", "id": "f_dumpster", "name": "dumpster", - "description": "Stores your trash.", + "description": "Stores trash. Doesn't get picked up anymore. Note the smell.", "symbol": "{", "color": "green", "move_cost_mod": 3, @@ -1504,7 +1549,7 @@ "type": "furniture", "id": "f_coffin_c", "name": "coffin", - "description": "Holds the bodies of the countless you kill.", + "description": "Holds the bodies of the countless killed in the Cataclysm.", "symbol": "0", "bgcolor": "brown", "move_cost_mod": -1, @@ -1543,7 +1588,7 @@ "type": "furniture", "id": "f_coffin_o", "name": "open coffin", - "description": "Look at the bodies of the countless you've killed.", + "description": "You can only hope you'll look good enough for one of these, when the time comes.", "symbol": "O", "bgcolor": "brown", "move_cost_mod": -1, @@ -1571,7 +1616,7 @@ "type": "furniture", "id": "f_crate_c", "name": "crate", - "description": "What's inside? Find out!", + "description": "What's inside? Pry it open to find out! Or just smash it, but you might break the contents.", "symbol": "X", "bgcolor": "brown", "move_cost_mod": -1, @@ -1663,6 +1708,7 @@ "type": "furniture", "id": "f_canvas_door", "name": "canvas flap", + "description": "This canvas flap door could be pulled aside.", "symbol": "+", "color": "blue", "move_cost_mod": -1, @@ -1683,6 +1729,7 @@ "type": "furniture", "id": "f_canvas_door_o", "name": "open canvas flap", + "description": "This canvas flap door has been pulled aside.", "symbol": ".", "color": "blue", "move_cost_mod": 0, @@ -1702,6 +1749,7 @@ "type": "furniture", "id": "f_large_canvas_door", "name": "canvas flap", + "description": "This heavy canvas flap door could be pulled aside.", "symbol": "+", "color": "blue", "move_cost_mod": -1, @@ -1723,6 +1771,7 @@ "type": "furniture", "id": "f_large_canvas_door_o", "name": "open canvas flap", + "description": "This heavy canvas flap door has been pulled aside.", "symbol": ".", "color": "blue", "move_cost_mod": 0, @@ -1743,6 +1792,7 @@ "type": "furniture", "id": "f_groundsheet", "name": "groundsheet", + "description": "This plastic groundsheet could keep you dry.", "symbol": ";", "color": "green", "move_cost_mod": 0, @@ -1764,6 +1814,7 @@ "type": "furniture", "id": "f_large_groundsheet", "name": "groundsheet", + "description": "This large plastic groundsheet could keep you dry.", "symbol": ";", "color": "green", "move_cost_mod": 0, @@ -1783,6 +1834,7 @@ "type": "furniture", "id": "f_center_groundsheet", "name": "groundsheet", + "description": "This plastic groundsheet could keep you dry.", "symbol": ";", "color": "green", "move_cost_mod": 0, @@ -1805,6 +1857,7 @@ "type": "furniture", "id": "f_fema_groundsheet", "name": "groundsheet", + "description": "This plastic government-issue groundsheet could keep you dry, but was made by the lowest bidder.", "symbol": ";", "color": "green", "move_cost_mod": 0, @@ -1843,6 +1896,7 @@ "type": "furniture", "id": "f_skin_door", "name": "animalskin flap", + "description": "This animal skin flap could be pulled aside.", "symbol": "+", "color": "white", "move_cost_mod": -1, @@ -1863,6 +1917,7 @@ "type": "furniture", "id": "f_skin_door_o", "name": "open animalskin flap", + "description": "This animal skin flap has been pulled aside.", "symbol": ".", "color": "white", "move_cost_mod": 0, @@ -1882,6 +1937,7 @@ "type": "furniture", "id": "f_skin_groundsheet", "name": "animalskin floor", + "description": "This animal skin groundsheet could keep you dry.", "symbol": ";", "color": "brown", "move_cost_mod": 0, @@ -2079,6 +2135,7 @@ "type": "furniture", "id": "f_plant_seed", "name": "seed", + "description": "A humble planted seed. Actions are the seed of fate deeds grow into destiny.", "symbol": "^", "color": "brown", "move_cost_mod": 0, @@ -2093,6 +2150,7 @@ "type": "furniture", "id": "f_plant_seedling", "name": "seedling", + "description": "This plant is just getting started.", "symbol": "^", "color": "green", "move_cost_mod": 0, @@ -2107,6 +2165,7 @@ "type": "furniture", "id": "f_plant_mature", "name": "mature plant", + "description": "This plant has matured.", "symbol": "#", "color": "green", "move_cost_mod": 0, @@ -2121,6 +2180,7 @@ "type": "furniture", "id": "f_plant_harvest", "name": "harvestable plant", + "description": "This plant is ready for harvest. Examine it more closely to identify how to harvest the plant appropriately.", "symbol": "#", "color": "light_green", "move_cost_mod": 0, @@ -2379,7 +2439,7 @@ "type": "furniture", "id": "f_wood_keg", "name": "wooden keg", - "description": "A keg made mostly of wood. Holds liquids, preferably beer.", + "description": "A keg made mostly of wood. Holds liquids, preferably alcoholic.", "symbol": "H", "color": "brown", "move_cost_mod": -1, @@ -2416,7 +2476,7 @@ "type": "furniture", "id": "f_statue", "name": "statue", - "description": "A carved statue made of stone..", + "description": "A carved statue made of stone.", "symbol": "S", "color": "dark_gray", "move_cost_mod": -1, @@ -2435,7 +2495,7 @@ "type": "furniture", "id": "f_mannequin", "name": "mannequin", - "description": "Put clothes on it and wish you looked as good.", + "description": "Put clothes on it, talk to it. Who's around to judge you? Wait... did it just move?", "symbol": "@", "color": "brown", "move_cost_mod": 2, @@ -2566,7 +2626,7 @@ "type": "furniture", "id": "f_TV_antenna", "name": "TV antenna", - "description": "The television antenna improves reception for televisions.", + "description": "The television antenna improved reception for televisions.", "symbol": "#", "color": "light_gray", "move_cost_mod": 2, @@ -2709,6 +2769,7 @@ "type": "furniture", "id": "f_datura", "name": "datura", + "description": "A pretty moonflower.", "symbol": "*", "color": "light_green", "move_cost_mod": 1, @@ -2748,6 +2809,7 @@ "type": "furniture", "id": "f_chamomile", "name": "chamomile", + "description": "Ahh, soothing chamomile tea. These particular plants doesn't seem very healthy, though.", "symbol": "f", "color": "white", "move_cost_mod": 0, @@ -2785,6 +2847,7 @@ "type": "furniture", "id": "f_cattails", "name": "cattails", + "description": "This useful plant is available all year round. Many parts of the plant are edible.", "symbol": "i", "color": "brown", "move_cost_mod": 1, @@ -2860,6 +2923,7 @@ "type": "furniture", "id": "f_lilypad", "name": "lilypad", + "description": "These lilypads don't look they'd support the weight of the things you've heard croaking in the swamp.", "symbol": "f", "color": "green", "move_cost_mod": 0, @@ -2923,6 +2987,7 @@ "type": "furniture", "id": "f_egg_sackbw", "name": "spider egg sack", + "description": "Much too large, off-white egg sack. Kind of icky. Something IS moving in there.", "symbol": "O", "color": "white", "move_cost_mod": 3, @@ -2935,6 +3000,7 @@ "type": "furniture", "id": "f_egg_sackcs", "name": "spider egg sack", + "description": "Bulbous mass of spider eggs. More than kind of icky. Something IS moving in there.", "symbol": "O", "color": "white", "move_cost_mod": 3, @@ -2947,6 +3013,7 @@ "type": "furniture", "id": "f_egg_sackws", "name": "spider egg sack", + "description": "A horrifyingly oversized egg sack. Something IS moving in there. If you're seeing this, you're already too close to it.", "symbol": "O", "color": "yellow", "move_cost_mod": 3, @@ -2959,6 +3026,7 @@ "type": "furniture", "id": "f_egg_sacke", "name": "ruptured egg sack", + "description": "Super icky. Spider stuff's spilling out.", "symbol": "X", "color": "white", "move_cost_mod": 3, @@ -2970,7 +3038,7 @@ "type": "furniture", "id": "f_vending_reinforced", "name": "reinforced vending machine", - "description": "A bit tougher to crack open than regular vending machines.", + "description": "A bit tougher to crack open than regular vending machines. That just makes it all the sweeter a target, doesn't it?", "symbol": "{", "color": "light_red", "move_cost_mod": -1, @@ -2995,7 +3063,7 @@ "type": "furniture", "id": "f_arcade_machine", "name": "arcade machine", - "description": "Play stupid games, win stupid prizes.", + "description": "Play stupid games, win stupid prizes. That was the idea, anyway. Now, without power, it's just stupid. Smarter to disassemble for all kinds of useful electronic parts.", "symbol": "6", "color": "red", "move_cost_mod": -1, @@ -3035,7 +3103,7 @@ "type": "furniture", "id": "f_pinball_machine", "name": "pinball machine", - "description": "Most underrated game of the 20th century. Press buttons so it doesn't go in the hole.", + "description": "Most underrated game of the 20th century. Press buttons so the ball doesn't go in the hole. It doesn't seem to be working without electricity. Could be disassembled for various electronic parts.", "symbol": "7", "color": "red", "move_cost_mod": -1, @@ -3126,7 +3194,7 @@ "type": "furniture", "id": "f_treadmill", "name": "treadmill", - "description": "Used for training leg muscles. It'll be hard without power.", + "description": "Used for training leg muscles. It'll be extra hard without power. Could be taken apart for its... parts.", "symbol": "L", "color": "dark_gray", "move_cost_mod": 1, @@ -3161,7 +3229,7 @@ "type": "furniture", "id": "f_displaycase", "name": "display case", - "description": "Display your stuff. Securely.", + "description": "Display your stuff fancily and securely.", "symbol": "#", "color": "light_cyan", "move_cost_mod": 2, @@ -3224,7 +3292,7 @@ "type": "furniture", "id": "f_floor_canvas", "name": "heavy punching bag", - "description": "Punch Punch! Exercise those arms!", + "description": "Punch Punch! Exercise those arms! Main selling point: it doesn't fight back!", "symbol": "0", "color": "dark_gray", "move_cost_mod": -1, @@ -3353,6 +3421,7 @@ "type": "furniture", "id": "f_robotic_arm", "name": "robotic arm", + "description": "Automation! Science! Industry! Make a better horse! This robot arm promises to do it all. Except it's currently unpowered. You could remove the casing and retrieve the electronics through disassembly.", "symbol": "&", "bgcolor": "yellow", "move_cost_mod": 3, @@ -3394,6 +3463,7 @@ "type": "furniture", "id": "f_aut_gas_console", "name": "automated gas console", + "description": "Automated gas flow control console.", "symbol": "9", "color": "blue", "move_cost_mod": -1, @@ -3407,6 +3477,7 @@ "type": "furniture", "id": "f_aut_gas_console_o", "name": "broken automated gas console", + "description": "Automated gas flow control console. Broken. This is not a good thing.", "symbol": "9", "color": "dark_gray", "move_cost_mod": -1, @@ -3665,6 +3736,7 @@ "type": "furniture", "id": "f_shackle", "name": "manacles", + "description": "Chain serfs in your dungeon. All you need now is an iron ball to chain to it.", "symbol": "8", "color": "light_gray", "move_cost_mod": 1, @@ -3740,6 +3812,7 @@ "type": "furniture", "id": "f_grave_monument", "name": "obelisk", + "description": "Monument to pride.", "symbol": "$", "color": "black_white", "move_cost_mod": -1, @@ -3758,6 +3831,7 @@ "type": "furniture", "id": "f_brazier", "name": "brazier", + "description": "A raised metal dish in which to safely burn things.", "symbol": "#", "color": "red", "move_cost_mod": 2, @@ -3779,10 +3853,61 @@ ] } }, + { + "type": "furniture", + "id": "f_55gal_firebarrel", + "name": "fire barrel (200L)", + "description": "A large metal barrel used to contain a fire. It has multiple holes punched in its walls for air supply. Fires set in a fire barrel will not spread to surrounding flammable objects.", + "symbol": "#", + "color": "red", + "looks_like": "55gal_drum", + "move_cost_mod": 2, + "coverage": 35, + "required_str": 8, + "flags": [ "PLACE_ITEM", "TRANSPARENT", "FIRE_CONTAINER", "EASY_DECONSTRUCT" ], + "deployed_item": "55gal_firebarrel", + "examine_action": "fireplace", + "max_volume": 4000, + "bash": { + "str_min": 8, + "str_max": 30, + "sound": "metal screeching!", + "sound_fail": "clang!", + "items": [ + { "item": "scrap", "count": [ 8, 20 ] }, + { "item": "sheet_metal_small", "count": [ 3, 10 ] }, + { "item": "sheet_metal", "count": [ 0, 1 ] } + ] + } + }, + { + "type": "furniture", + "id": "f_30gal_firebarrel", + "name": "fire barrel (100L)", + "description": "A large metal barrel used to contain a fire. It has multiple holes punched in its walls for air supply. Fires set in a fire barrel will not spread to surrounding flammable objects.", + "symbol": "#", + "color": "red", + "looks_like": "30gal_drum", + "move_cost_mod": 2, + "coverage": 35, + "required_str": 8, + "flags": [ "PLACE_ITEM", "TRANSPARENT", "FIRE_CONTAINER", "EASY_DECONSTRUCT" ], + "deployed_item": "30gal_firebarrel", + "examine_action": "fireplace", + "max_volume": 4000, + "bash": { + "str_min": 8, + "str_max": 30, + "sound": "metal screeching!", + "sound_fail": "clang!", + "items": [ { "item": "scrap", "count": [ 5, 15 ] }, { "item": "sheet_metal_small", "count": [ 1, 9 ] } ] + } + }, { "id": "f_firering", "type": "furniture", "name": "fire ring", + "description": "A ring of stones to safely contain a fire.", "symbol": "#", "bgcolor": [ "white" ], "move_cost_mod": 2, @@ -4125,7 +4250,7 @@ "id": "f_pillow_fort", "name": "pillow fort", "symbol": "^", - "description": "A comfy place to hide from the world.", + "description": "A comfy place to hide from the world. Not very defensible, though.", "color": "white", "move_cost_mod": 3, "coverage": 90, @@ -4158,6 +4283,7 @@ "type": "furniture", "id": "f_beaded_door", "name": "beaded curtain", + "description": "This beaded curtain could be pulled aside.", "symbol": "+", "color": "pink", "looks_like": "f_canvas_door", @@ -4186,6 +4312,7 @@ "type": "furniture", "id": "f_beaded_door_o", "name": "open beaded curtain", + "description": "This beaded curtain has been pulled aside.", "symbol": ".", "color": "pink", "looks_like": "f_canvas_door_o", @@ -4271,7 +4398,7 @@ "type": "furniture", "id": "f_piano", "name": "piano", - "description": "The ol' ebony and ivory.", + "description": "The ol' ebony and ivory. Really classes up the place. You could take it apart if you wanted... you monster.", "symbol": "P", "color": "i_black", "move_cost_mod": 6, @@ -6033,7 +6160,7 @@ "id": "f_dishwasher", "name": "dishwasher", "looks_like": "f_oven", - "description": "This metal box used to spray hot water and soap at dirty dishes to make them clean and to save people an unpleasant chore. Now, with the power off and it sitting for a while, it is starting to smell a bit off.", + "description": "This metal box used to spray hot water and soap at dirty dishes to make them clean and to save people an unpleasant chore. Now, with the power gone and it sitting for a while, it's starting to smell a bit off.", "symbol": "{", "bgcolor": "white", "move_cost_mod": -1, diff --git a/data/json/item_groups.json b/data/json/item_groups.json index 279cd8f8f8d92..1a69c175e342a 100644 --- a/data/json/item_groups.json +++ b/data/json/item_groups.json @@ -3901,6 +3901,7 @@ "type": "item_group", "id": "vault", "items": [ + { "group": "schematics", "prob": 5 }, [ "purifier", 12 ], [ "plut_cell", 10 ], [ "standard_template_construct", 5 ], @@ -8913,6 +8914,7 @@ "id": "recycle_paper", "type": "item_group", "items": [ + { "group": "schematics", "prob": 2 }, [ "mag_dude", 25 ], [ "mag_beauty", 25 ], [ "mag_glam", 25 ], @@ -9714,5 +9716,27 @@ "type": "item_group", "id": "meth_ingredients", "items": [ [ "dayquil", 2 ], [ "aspirin", 40 ], [ "adderall", 5 ], [ "energy_drink", 2 ], [ "caffeine", 20 ] ] + }, + { + "id": "schematics", + "type": "item_group", + "items": [ + [ "schematics_nursebot", 10 ], + [ "schematics_copbot", 50 ], + [ "schematics_eyebot", 50 ], + [ "schematics_secubot", 50 ], + [ "schematics_skitterbot", 50 ], + [ "schematics_chickenbot", 5 ], + [ "schematics_hazmatbot", 50 ], + [ "schematics_riotbot", 50 ], + [ "schematics_sciencebot", 10 ], + [ "schematics_tankbot", 5 ], + [ "schematics_tripod", 5 ], + [ "schematics_molebot", 20 ], + [ "schematics_dispatch", 25 ], + [ "schematics_dispatch_military", 20 ], + [ "schematics_antimateriel", 20 ], + [ "schematics_searchlight", 50 ] + ] } ] diff --git a/data/json/itemgroups/clothing.json b/data/json/itemgroups/clothing.json index 1cf4a5a40ae53..3e755147d653a 100644 --- a/data/json/itemgroups/clothing.json +++ b/data/json/itemgroups/clothing.json @@ -397,5 +397,27 @@ { "item": "socks" }, { "item": "boots" } ] + }, + { + "id": "underwear", + "type": "item_group", + "items": [ + [ "bra", 70 ], + [ "sports_bra", 50 ], + [ "bikini_top", 10 ], + [ "panties", 70 ], + [ "bikini_bottom", 10 ], + [ "panties", 70 ], + [ "boy_shorts", 50 ], + [ "boxer_shorts", 70 ], + [ "briefs", 50 ], + [ "undershirt", 50 ], + [ "long_undertop", 20 ], + [ "under_armor", 20 ], + [ "tank_top", 50 ], + [ "boxer_shorts", 70 ], + [ "long_underpants", 20 ], + [ "under_armor_shorts", 20 ] + ] } ] diff --git a/data/json/itemgroups/guns.json b/data/json/itemgroups/guns.json index 0dcef4a96a876..da0081c502762 100644 --- a/data/json/itemgroups/guns.json +++ b/data/json/itemgroups/guns.json @@ -332,6 +332,7 @@ [ "m202_flash", 100 ], [ "m235tpa", 150 ], [ "m3_carlgustav", 50 ], + [ "AT4", 50 ], [ "84x246mm_he", 100 ], [ "84x246mm_hedp", 80 ], [ "84x246mm_smoke", 100 ] diff --git a/data/json/itemgroups/locations.json b/data/json/itemgroups/locations.json index 5896cb5581786..2674ec266255d 100644 --- a/data/json/itemgroups/locations.json +++ b/data/json/itemgroups/locations.json @@ -508,5 +508,89 @@ { "item": "gasoline", "prob": 30, "charges-min": 450, "charges-max": 4000, "container-item": "jerrycan" }, { "item": "gasoline", "prob": 10, "charges-min": 2650, "charges-max": 10000, "container-item": "jerrycan_big" } ] + }, + { + "type": "item_group", + "id": "oa_ig_ts_tables", + "//": "for cs_tire_shop", + "items": [ + [ "radio", 30 ], + [ "rag", 30 ], + [ "cell_phone", 20 ], + [ "mag_mechanics", 20 ], + [ "manual_mechanics", 10 ], + [ "jack", 60 ], + [ "jack_small", 60 ], + [ "jack_makeshift", 30 ], + [ "wrench", 50 ], + [ "gloves_work", 30 ], + [ "glasses_safety", 20 ] + ] + }, + { + "type": "item_group", + "id": "oa_ig_ts_lockers", + "//": "for cs_tire_shop", + "items": [ + { "group": "ammo_pocket_batteries_full", "prob": 10 }, + [ "radio", 10 ], + [ "rag", 30 ], + [ "jack", 20 ], + [ "jack_small", 30 ], + [ "flashlight", 20 ], + [ "heavy_flashlight", 10 ], + [ "jumper_cable", 20 ], + [ "jumper_cable_heavy", 10 ], + [ "pliers", 10 ], + [ "battery_motorbike", 10 ], + [ "battery_car", 10 ], + [ "stereo", 10 ], + [ "wrench", 10 ], + [ "gloves_work", 10 ], + [ "glasses_safety", 10 ], + [ "solar_cell", 10 ], + [ "screwdriver", 15 ], + [ "superglue", 5 ], + [ "polisher", 15 ], + [ "solar_panel", 15 ], + [ "spare_tire_carrier", 10 ], + [ "mounted_spare_tire", 10 ] + ] + }, + { + "type": "item_group", + "id": "oa_ig_ts_crates", + "//": "for cs_tire_shop", + "items": [ + { "group": "ammo_any_batteries_full", "prob": 10 }, + [ "radio", 10 ], + [ "rag", 30 ], + [ "jack", 20 ], + [ "jack_small", 30 ], + [ "flashlight", 20 ], + [ "heavy_flashlight", 10 ], + [ "jumper_cable", 20 ], + [ "jumper_cable_heavy", 10 ], + [ "pliers", 10 ], + [ "battery_motorbike", 10 ], + [ "battery_car", 10 ], + [ "stereo", 10 ], + [ "wrench", 10 ], + [ "gloves_work", 10 ], + [ "glasses_safety", 10 ], + [ "solar_cell", 10 ], + [ "screwdriver", 15 ], + [ "superglue", 5 ], + [ "polisher", 15 ], + [ "solar_panel", 15 ], + [ "spare_tire_carrier", 10 ], + [ "mounted_spare_tire", 10 ] + ] + }, + { + "type": "item_group", + "id": "oa_ig_ts_tires", + "//": "for cs_tire_shop", + "items": [ [ "wheel_small", 30 ], [ "wheel", 30 ], [ "wheel_wide", 20 ] ] } ] diff --git a/data/json/itemgroups/mall_item_groups.json b/data/json/itemgroups/mall_item_groups.json index a1a1629e066c2..cf38fde60bc32 100644 --- a/data/json/itemgroups/mall_item_groups.json +++ b/data/json/itemgroups/mall_item_groups.json @@ -155,6 +155,56 @@ [ "knife_rambo", 5 ] ] }, + { + "id": "leather_shop", + "type": "item_group", + "items": [ + [ "hot_pants_leather", 20 ], + [ "cloak_leather", 20 ], + [ "duster_leather", 20 ], + [ "jacket_leather_red", 20 ], + [ "skirt_leather", 20 ], + [ "touring_suit", 20 ], + [ "chestwrap_leather", 20 ], + [ "chaps_leather", 35 ], + [ "trenchcoat_leather", 10 ], + [ "vest_leather", 50 ], + [ "apron_leather", 10 ], + [ "backpack_leather", 7 ], + [ "pants_leather", 20 ], + [ "bikini_top_leather", 20 ], + [ "jacket_leather", 5 ] + ] + }, + { + "id": "leather_shop_accessories", + "type": "item_group", + "items": [ + [ "leather_belt", 20 ], + [ "gloves_leather", 35 ], + [ "leather_harness_dog", 10 ], + [ "pockknife", 50 ], + [ "leather_tarp", 10 ], + [ "leather_cat_tail", 7 ], + [ "leather_cat_ears", 20 ], + [ "leather_collar", 20 ], + [ "bondage_mask", 5 ] + ] + }, + { + "id": "leather_shop_repair", + "type": "item_group", + "items": [ + [ "sewing_kit", 20 ], + [ "tailors_kit", 35 ], + [ "thread", 10 ], + [ "string_6", 50 ], + [ "leather", 10 ], + [ "fur", 7 ], + [ "tanned_hide", 20 ], + [ "tanned_pelt", 20 ] + ] + }, { "id": "key_shop", "type": "item_group", @@ -230,7 +280,97 @@ [ "candle", 50 ], [ "scissors", 30 ], [ "soap", 45 ], - [ "tailors_kit", 25 ] + [ "tailors_kit", 25 ], + [ "shavingkit", 20 ], + [ "elec_hairtrimmer", 20 ] + ] + }, + { + "id": "costume_clothes", + "type": "item_group", + "items": [ + [ "cloak", 40 ], + [ "cloak_leather", 30 ], + [ "cloak_wool", 40 ], + [ "jedi_cloak", 10 ], + [ "corset", 5 ], + [ "tux", 10 ], + [ "gown", 5 ], + [ "dress_wedding", 5 ], + [ "maid_dress", 35 ], + [ "postman_shirt", 50 ], + [ "postman_shorts", 30 ], + [ "robe", 45 ], + [ "kimono", 25 ], + [ "yukata", 20 ], + [ "coat_lab", 20 ], + [ "clown_suit", 20 ] + ] + }, + { + "id": "costume_accessories", + "type": "item_group", + "items": [ + [ "clownshoes", 20 ], + [ "bondage_mask", 30 ], + [ "long_glove_white", 20 ], + [ "porkpie", 10 ], + [ "postman_hat", 5 ], + [ "maid_hat", 10 ], + [ "fedora", 5 ], + [ "scarf_long", 5 ], + [ "mask_guy_fawkes", 35 ], + [ "mask_hockey", 20 ], + [ "cowboy_hat", 20 ], + [ "tophat", 25 ], + [ "hat_sombrero", 25 ], + [ "apron_leather", 20 ] + ] + }, + { + "id": "costume_weapons", + "type": "item_group", + "items": [ + [ "cutlass", 1 ], + [ "broadsword", 1 ], + [ "nodachi", 1 ], + [ "zweihander", 1 ], + [ "longsword", 1 ], + [ "katana", 1 ], + [ "kris", 1 ], + [ "rapier", 1 ], + [ "cavalry_sabre", 1 ], + [ "glaive", 1 ], + [ "naginata", 1 ], + [ "naginata_fake", 5 ], + [ "naginata_inferior", 3 ], + [ "estoc", 2 ], + [ "estoc_fake", 6 ], + [ "qiang", 3 ], + [ "halberd", 2 ], + [ "halberd_fake", 7 ], + [ "katana_fake", 4 ], + [ "katana_inferior", 8 ], + [ "zweihander_fake", 4 ], + [ "zweihander_inferior", 8 ], + [ "cutlass_fake", 4 ], + [ "cutlass_inferior", 8 ], + [ "jian", 2 ], + [ "jian_fake", 4 ], + [ "jian_inferior", 8 ], + [ "scimitar", 4 ], + [ "scimitar_fake", 8 ], + [ "arming_sword", 4 ], + [ "arming_sword_fake", 8 ], + [ "broadsword_fake", 4 ], + [ "broadsword_inferior", 8 ], + [ "longsword_fake", 4 ], + [ "longsword_inferior", 8 ], + [ "rapier_fake", 4 ], + [ "cavalry_sabre_fake", 4 ], + [ "wakizashi_fake", 4 ], + [ "wakizashi_inferior", 8 ], + [ "kris_fake", 8 ] ] } ] diff --git a/data/json/items/ammo/metal_rail.json b/data/json/items/ammo/metal_rail.json index 69fe4f6e3d3b2..6c04defe8ae57 100644 --- a/data/json/items/ammo/metal_rail.json +++ b/data/json/items/ammo/metal_rail.json @@ -4,8 +4,8 @@ "type": "AMMO", "name": "rebar rail", "description": "A short piece of ferromagnetic rebar which has been straightened and sharpened on one end. Could be used as a projectile by a sufficiently powerful electromagnetic weapon.", - "weight": 712, - "volume": 1, + "weight": 160, + "volume": "25ml", "price": 1000, "to_hit": -1, "bashing": 5, @@ -27,7 +27,7 @@ "type": "AMMO", "name": "steel rail", "description": "A short piece of steel which has been forged true and sharpened on one end. Could be used as a projectile by a sufficiently powerful electromagnetic weapon.", - "weight": 520, + "volume": "20ml", "price": 1500, "bashing": 4, "cutting": 2, diff --git a/data/json/items/book/electronics.json b/data/json/items/book/electronics.json index b1ebef166ff9d..0bbf73bfb7a10 100644 --- a/data/json/items/book/electronics.json +++ b/data/json/items/book/electronics.json @@ -207,5 +207,151 @@ "intelligence": 13, "time": 55, "fun": -1 + }, + { + "abstract": "schematics_generic", + "type": "BOOK", + "name": "schematics generic", + "description": "seeing this is a bug", + "weight": 30, + "volume": 1, + "price": 100000, + "to_hit": -1, + "material": "paper", + "skill": "electronics", + "required_level": 7, + "max_level": 7, + "intelligence": 8, + "time": 55, + "symbol": "รง", + "color": "blue" + }, + { + "id": "schematics_nursebot", + "type": "BOOK", + "name": "nurse bot schematics", + "name_plural": "nurse bot schematics", + "description": "Bearing the logo of Uncanny, those are assembly plans, design specs, and technical drawings for the nurse bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_copbot", + "type": "BOOK", + "name": "police bot schematics", + "name_plural": "police bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the police bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_eyebot", + "type": "BOOK", + "name": "eyebot schematics", + "name_plural": "eyebot schematics", + "description": "Assembly plans, design specs, and technical drawings for the eyebot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_secubot", + "type": "BOOK", + "name": "security bot schematics", + "name_plural": "security bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the security bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_skitterbot", + "type": "BOOK", + "name": "skitterbot schematics", + "name_plural": "security bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the skitterbot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_chickenbot", + "type": "BOOK", + "name": "chicken walker schematics", + "name_plural": "chicken walker schematics", + "description": "Bearing the logo of Northrop, those are assembly plans, design specs, and technical drawings for the chicken walker. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_hazmatbot", + "type": "BOOK", + "name": "cleaner bot schematics", + "name_plural": "cleaner bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the cleaner bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_molebot", + "type": "BOOK", + "name": "miner bot schematics", + "name_plural": "miner bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the miner bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_riotbot", + "type": "BOOK", + "name": "riot control bot schematics", + "name_plural": "riot control bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the riot control bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_sciencebot", + "type": "BOOK", + "name": "lab defense bot schematics", + "name_plural": "lab defense bot schematics", + "description": "Assembly plans, design specs, and technical drawings for the lab defense bot. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_tankbot", + "type": "BOOK", + "name": "tank drone schematics", + "name_plural": "tank drone schematics", + "description": "Bearing the logo of Northrop, those are assembly plans, design specs, and technical drawings for the tank drone. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_tripod", + "type": "BOOK", + "name": "tripod schematics", + "name_plural": "tripod schematics", + "description": "Bearing the logo of Honda, those are assembly plans, design specs, and technical drawings for the tripod. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_dispatch", + "type": "BOOK", + "name": "dispatch schematics", + "name_plural": "dispatch schematics", + "description": "Bearing the logo of Northrop, those are assembly plans, design specs, and technical drawings for the dispatch. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_dispatch_military", + "type": "BOOK", + "name": "military dispatch schematics", + "name_plural": "military dispatch schematics", + "description": "Bearing the logo of Northrop, those are assembly plans, design specs, and technical drawings for the military dispatch. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_antimateriel", + "type": "BOOK", + "name": "anti-materiel turret schematics", + "name_plural": "anti-materiel turret schematics", + "description": "Assembly plans, design specs, and technical drawings for the anti-materiel turret. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" + }, + { + "id": "schematics_searchlight", + "type": "BOOK", + "name": "milspec searchlight schematics", + "name_plural": "milspec searchlight schematics", + "description": "Assembly plans, design specs, and technical drawings for the milspec searchlight. Most of this is useless to you, but you could use the assembly plans to re-assemble the robot from salvaged parts.", + "copy-from": "schematics_generic" } ] diff --git a/data/json/items/comestibles/nuts.json b/data/json/items/comestibles/nuts.json index bb48ea83b13d4..c320ab1217a91 100644 --- a/data/json/items/comestibles/nuts.json +++ b/data/json/items/comestibles/nuts.json @@ -261,18 +261,6 @@ "flags": [ "EATEN_HOT", "EDIBLE_FROZEN" ], "fun": 1 }, - { - "type": "COMESTIBLE", - "id": "acorn_roasted", - "name": "handful of roasted acorns", - "name_plural": "handfuls of roasted acorns", - "copy-from": "acorns", - "healthy": 1, - "description": "A handful of roasted nuts from a oak tree.", - "price": 90, - "flags": [ "EATEN_HOT", "EDIBLE_FROZEN" ], - "fun": 1 - }, { "type": "COMESTIBLE", "id": "hazelnut_unshelled", diff --git a/data/json/items/generic.json b/data/json/items/generic.json index 10dc5794e7809..102f07d62b295 100644 --- a/data/json/items/generic.json +++ b/data/json/items/generic.json @@ -840,7 +840,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -857,7 +857,7 @@ "bashing": 4, "cutting": 4, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -874,7 +874,7 @@ "bashing": 4, "cutting": 4, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -892,7 +892,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -910,7 +910,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -934,7 +934,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -970,7 +970,7 @@ "bashing": 6, "cutting": 10, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -987,7 +987,7 @@ "bashing": 10, "cutting": 6, "to_hit": -2, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1004,7 +1004,7 @@ "bashing": 20, "cutting": 15, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1021,7 +1021,7 @@ "bashing": 4, "cutting": 4, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1038,7 +1038,7 @@ "bashing": 4, "cutting": 4, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1055,7 +1055,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1073,7 +1073,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1091,7 +1091,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1109,7 +1109,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1127,7 +1127,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1145,7 +1145,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", @@ -1163,7 +1163,7 @@ "bashing": 6, "cutting": 6, "to_hit": -3, - "flags": [ "TRADER_AVOID" ] + "flags": [ "TRADER_AVOID", "NO_REPAIR" ] }, { "type": "GENERIC", diff --git a/data/json/items/gun/223.json b/data/json/items/gun/223.json index 33e1d1ff9859b..30054193912e1 100644 --- a/data/json/items/gun/223.json +++ b/data/json/items/gun/223.json @@ -417,7 +417,7 @@ "type": "GUN", "name": "handmade carbine", "//": "It's smaller than an M4A1, plus it's a homemade firearm.", - "description": "A well-designed improvised carbine with a shortened barrel. Accepting crude detachable magazines, this is one of the better homemade weapons.", + "description": "A well-designed improvised carbine with a shortened barrel. Accepting crude detachable magazines or STANAG magazines, this is one of the better homemade weapons.", "weight": 1950, "volume": 6, "price": 10000, @@ -441,6 +441,6 @@ [ "stock", 1 ], [ "underbarrel", 1 ] ], - "magazines": [ [ "223", [ "survivor223mag" ] ] ] + "magazines": [ [ "223", [ "survivor223mag", "stanag30", "stanag50" ] ] ] } ] diff --git a/data/json/items/gun/84x246mm.json b/data/json/items/gun/84x246mm.json index 7ea521df072fb..e94c47f001439 100644 --- a/data/json/items/gun/84x246mm.json +++ b/data/json/items/gun/84x246mm.json @@ -21,6 +21,21 @@ "clip_size": 1, "reload": 300, "loudness": 200, - "valid_mod_locations": [ [ "accessories", 4 ], [ "grip", 1 ], [ "mechanism", 4 ], [ "sights", 1 ], [ "sling", 1 ] ] + "valid_mod_locations": [ [ "accessories", 4 ], [ "grip", 1 ], [ "mechanism", 4 ], [ "sights", 1 ] ] + }, + { + "id": "AT4", + "type": "GUN", + "copy-from": "LAW", + "name": "AT4", + "description": "Mil-Spec rocket launcher. An 84-mm unguided, portable, single-shot recoilless smoothbore weapon used primarily by the US military.", + "extend": { "flags": [ "FIRE_TWOHAND", "NO_REPAIR" ] }, + "ammo": "84x246mm", + "weight": 6803, + "volume": 14, + "bashing": 4, + "dispersion": 200, + "durability": 7, + "loudness": 200 } ] diff --git a/data/json/items/melee.json b/data/json/items/melee.json index 3aa046ae8d592..c798c4dd7bb2a 100644 --- a/data/json/items/melee.json +++ b/data/json/items/melee.json @@ -254,6 +254,7 @@ "color": "light_gray", "name": "rock", "description": "A rock the size of a baseball. Makes a decent melee weapon, and is also good for throwing at enemies.", + "category": "spare_parts", "material": "stone", "flags": "TRADER_AVOID", "weight": 657, diff --git a/data/json/items/robot_parts.json b/data/json/items/robot_parts.json new file mode 100644 index 0000000000000..fde4c5a7129fd --- /dev/null +++ b/data/json/items/robot_parts.json @@ -0,0 +1,281 @@ +[ + { + "type": "GENERIC", + "abstract": "robot_module_abstract", + "name": "module template", + "description": "This is a template for robot module. If found in a game it is a bug.", + "symbol": "%", + "color": "cyan", + "material": [ "plastic", "steel" ], + "weight": 250, + "volume": 2, + "price": 32000, + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "targeting_module", + "name": "targeting module", + "description": "This module integrate visual and proprioceptive information from peripheric sensors and outputs information necessary for accurate aiming.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "identification_module", + "name": "identification module", + "description": "This module continuously runs image recognition algorithms to identify friends from foe.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "pathfinding_module", + "name": "pathfinding module", + "description": "This module uses a combination of vector integration and egocentric mapping to find the best path available.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "memory_module", + "name": "memory banks module", + "description": "Allows for storage and recovery of information.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "sensor_module", + "name": "sensor array", + "description": "A wide range of sensors meant to give the ability to perceive the surrounding world.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "self_monitoring_module", + "name": "self monitoring sensors", + "description": "A array of sensors and diagnostic modules allowing the robot to perceive itself.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "ai_module", + "name": "AI core", + "description": "This module is responsible for decision making, it basically runs the AI of the robot.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "ai_module_basic", + "name": "basic AI core", + "description": "A very basic AI core with minimal cognitive abilities.", + "weight": 125, + "copy-from": "ai_module" + }, + { + "type": "GENERIC", + "id": "ai_module_advanced", + "name": "advanced AI core", + "description": "An advanced AI core with impressive cognitive abilities.", + "copy-from": "ai_module" + }, + { + "type": "GENERIC", + "id": "gun_module", + "name": "gun operating system", + "description": "This system can operate most conventional weapons.", + "copy-from": "robot_module_abstract" + }, + { + "type": "GENERIC", + "id": "spidery_legs_big", + "name": "set of spidery legs", + "name_plural": "sets of spidery legs", + "description": "A set of big pointy legs, like the ones found under a tripod.", + "symbol": "W", + "color": "light_gray", + "weight": 40000, + "volume": 80, + "price": 200000, + "material": "steel", + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "spidery_legs_small", + "name": "set of tiny spidery legs", + "name_plural": "sets of tiny spidery legs", + "description": "A set of tiny pointy legs, like the ones found under a skitterbot.", + "symbol": "w", + "color": "light_gray", + "weight": 200, + "volume": 2, + "price": 50000, + "material": "steel", + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "reverse_jointed_legs", + "name": "set of reverse-jointed legs", + "name_plural": "sets of reverse-jointed legs", + "description": "A set of reverse-jointed legs, like the ones found under a chicken walker.", + "symbol": "k", + "color": "light_gray", + "weight": 60000, + "volume": 80, + "price": 500000, + "material": "steel", + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "omni_wheel", + "name": "set of omni wheels", + "name_plural": "sets of omni wheels", + "description": "A set of omni wheels, like the ones found under a police bot.", + "symbol": "o", + "color": "light_gray", + "weight": 10000, + "volume": 40, + "price": 100000, + "material": "steel", + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "quad_rotors", + "name": "set of rotors", + "name_plural": "sets of rotors", + "description": "A set of rotors able to lift a small drone.", + "symbol": "#", + "color": "light_gray", + "weight": 130, + "volume": 2, + "price": 40000, + "material": [ "steel", "plastic" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "android_legs", + "name": "set of android legs", + "name_plural": "sets of android legs", + "description": "A set of human-like legs.", + "symbol": "M", + "color": "light_gray", + "weight": 10000, + "volume": 40, + "price": 100000, + "material": [ "steel", "plastic" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "android_arms", + "name": "set of android arms", + "name_plural": "sets of android arms", + "description": "A set of human-like arms.", + "symbol": "m", + "color": "light_gray", + "weight": 5000, + "volume": 20, + "price": 100000, + "material": [ "steel", "plastic" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "tank_tread", + "name": "set of small tank tread", + "name_plural": "sets of small tank tread", + "description": "A set of small tank tread, like the one used by the \"Beagle\" mini-tank.", + "symbol": "=", + "color": "light_gray", + "weight": 60000, + "volume": 120, + "price": 600000, + "material": [ "steel", "plastic" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "turret_chassis", + "name": "turret chassis", + "name_plural": "turret chassis", + "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of a turret.", + "symbol": "c", + "color": "light_gray", + "weight": 10000, + "volume": 40, + "price": 100000, + "material": [ "steel", "plastic" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "tripod_chassis", + "name": "tripod chassis", + "name_plural": "tripod chassis", + "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the tripod.", + "symbol": "c", + "color": "light_gray", + "weight": 40000, + "volume": "70000 ml", + "price": 200000, + "material": [ "steel" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "chickenbot_chassis", + "name": "chicken walker chassis", + "name_plural": "chicken walker chassis", + "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the chicken walker.", + "symbol": "c", + "color": "light_gray", + "weight": 60000, + "volume": "80000 ml", + "price": 300000, + "material": [ "steel" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "copbot_chassis", + "name": "police bot chassis", + "name_plural": "police bot chassis", + "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the police bot.", + "symbol": "c", + "color": "light_gray", + "weight": 20000, + "volume": "40000 ml", + "price": 100000, + "material": [ "steel" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "android_chassis", + "name": "android skeleton", + "description": "What's left when you strip an android body from its components.", + "symbol": "c", + "color": "light_gray", + "weight": 20000, + "volume": "40000 ml", + "price": 100000, + "material": [ "steel", "plastic" ], + "category": "spare_parts" + }, + { + "type": "GENERIC", + "id": "tankbot_chassis", + "name": "Beagle chassis", + "name_plural": "Beagle chassis", + "description": "What's left when you remove all moving parts and electronics. It's the skeleton and armor of the Beagle tank.", + "symbol": "c", + "color": "light_gray", + "weight": 150000, + "volume": "575000 ml", + "price": 1000000, + "material": [ "steel" ], + "category": "spare_parts" + } +] diff --git a/data/json/items/tool/deployable.json b/data/json/items/tool/deployable.json index 68f4edbe92ca3..8f40a75e1b7f4 100644 --- a/data/json/items/tool/deployable.json +++ b/data/json/items/tool/deployable.json @@ -15,6 +15,40 @@ "use_action": { "type": "deploy_furn", "furn_type": "f_brazier" }, "qualities": [ [ "COOK", 1 ], [ "BOIL", 2 ], [ "CONTAIN", 1 ] ] }, + { + "id": "55gal_firebarrel", + "type": "TOOL", + "name": "fire barrel (200L)", + "name_plural": "fire barrels (200L)", + "description": "A large metal barrel used to contain a fire. It has multiple holes punched in its walls for air supply. Fires set in a fire barrel will not spread to surrounding flammable objects.", + "weight": 20000, + "volume": 800, + "price": 10000, + "to_hit": -5, + "bashing": 8, + "looks_like": "55gal_drum", + "material": [ "steel" ], + "symbol": "0", + "color": "light_gray", + "use_action": { "type": "deploy_furn", "furn_type": "f_55gal_firebarrel" } + }, + { + "id": "30gal_firebarrel", + "type": "TOOL", + "name": "fire barrel (100L)", + "name_plural": "fire barrels (100L)", + "description": "A large metal barrel used to contain a fire. It has multiple holes punched in its walls for air supply. Fires set in a fire barrel will not spread to surrounding flammable objects.", + "weight": 12000, + "volume": 400, + "price": 5000, + "to_hit": -4, + "bashing": 7, + "looks_like": "30gal_drum", + "material": [ "steel" ], + "symbol": "0", + "color": "light_gray", + "use_action": { "type": "deploy_furn", "furn_type": "f_30gal_firebarrel" } + }, { "id": "camp_chair", "type": "TOOL", diff --git a/data/json/items/tools.json b/data/json/items/tools.json index 88e8f41842ff5..6bf53ae235653 100644 --- a/data/json/items/tools.json +++ b/data/json/items/tools.json @@ -1237,7 +1237,7 @@ "id": "bot_tripod", "looks_like": "broken_tripod", "type": "TOOL", - "name": "inactive tribot", + "name": "inactive tripod", "description": "This is an inactive Honda Regnal. Using this item involves placing it on the ground, wondering how it fuels its flamethrower and turning it on. If reprogrammed and rewired successfully the tribot will then identify you as an ally, roam around or follow you, and impale hostiles with its spiked cable weapons.", "weight": 120000, "volume": 370, @@ -1795,8 +1795,6 @@ "symbol": ";", "color": "light_gray", "ammo": "battery", - "//": "CAUTION: This is a special case where I put initial charges in and have magazines. Don't do this.", - "initial_charges": 150, "charges_per_use": 1, "use_action": { "target": "cell_phone_flashlight", @@ -2434,7 +2432,6 @@ "symbol": "|", "color": "pink", "ammo": "battery", - "initial_charges": 20, "charges_per_use": 1, "turns_per_charge": 20, "use_action": "DOLLCHAT", @@ -7360,7 +7357,6 @@ "symbol": "|", "color": "pink", "ammo": "battery", - "initial_charges": 20, "charges_per_use": 1, "turns_per_charge": 20, "use_action": "DOLLCHAT", diff --git a/data/json/mapgen/animalshelter.json b/data/json/mapgen/animalshelter.json index 9b09d064625f8..41f5d7bfeba79 100644 --- a/data/json/mapgen/animalshelter.json +++ b/data/json/mapgen/animalshelter.json @@ -155,7 +155,8 @@ "-": "t_wall", ".": "t_floor", ":": "t_door_glass_c", - "=": "t_chainfence_h", + "=": "t_privacy_fence", + "3": "t_privacy_fencegate_c", "O": "t_window", "^": "t_chaingate_c", "'": "t_dirt", diff --git a/data/json/mapgen/bar.json b/data/json/mapgen/bar.json index 85e2891883922..92e81bf8569e0 100644 --- a/data/json/mapgen/bar.json +++ b/data/json/mapgen/bar.json @@ -49,7 +49,6 @@ "D": "t_door_locked", "c": "t_linoleum_gray", "d": "t_pavement", - "f": "t_fencegate_c", "l": "t_linoleum_gray", "s": "t_linoleum_gray", "t": "t_linoleum_gray", @@ -69,6 +68,7 @@ "r": "f_trashcan", "c": "f_counter", "d": "f_dumpster", + "f": "f_counter_gate_c", "s": "f_sink", "x": "f_pool_table", "q": "f_stool", diff --git a/data/json/mapgen/cs_tire_shop.json b/data/json/mapgen/cs_tire_shop.json index 62f415699ca54..d43c267d81a9c 100644 --- a/data/json/mapgen/cs_tire_shop.json +++ b/data/json/mapgen/cs_tire_shop.json @@ -1,108 +1,11 @@ [ - { - "type": "vehicle_group", - "id": "oa_vg_ts_vehicles", - "vehicles": [ - [ "car", 2000 ], - [ "electric_car", 500 ], - [ "suv", 800 ], - [ "suv_electric", 200 ], - [ "car_mini", 800 ], - [ "beetle", 500 ], - [ "motorcycle", 200 ], - [ "motorcycle_sidecart", 100 ], - [ "scooter", 200 ], - [ "scooter_electric", 300 ], - [ "pickup", 800 ], - [ "hippie_van", 1000 ] - ] - }, - { - "type": "item_group", - "id": "oa_ig_ts_tables", - "items": [ - [ "radio", 30 ], - [ "rag", 30 ], - [ "cell_phone", 20 ], - [ "mag_mechanics", 20 ], - [ "manual_mechanics", 10 ], - [ "jack", 60 ], - [ "jack_small", 60 ], - [ "jack_makeshift", 30 ], - [ "wrench", 50 ], - [ "gloves_work", 30 ], - [ "glasses_safety", 20 ] - ] - }, - { - "type": "item_group", - "id": "oa_ig_ts_lockers", - "items": [ - { "group": "ammo_pocket_batteries_full", "prob": 10 }, - [ "radio", 10 ], - [ "rag", 30 ], - [ "jack", 20 ], - [ "jack_small", 30 ], - [ "flashlight", 20 ], - [ "heavy_flashlight", 10 ], - [ "jumper_cable", 20 ], - [ "jumper_cable_heavy", 10 ], - [ "pliers", 10 ], - [ "battery_motorbike", 10 ], - [ "battery_car", 10 ], - [ "stereo", 10 ], - [ "wrench", 10 ], - [ "gloves_work", 10 ], - [ "glasses_safety", 10 ], - [ "solar_cell", 10 ], - [ "screwdriver", 15 ], - [ "superglue", 5 ], - [ "polisher", 15 ], - [ "solar_panel", 15 ], - [ "spare_tire_carrier", 10 ], - [ "mounted_spare_tire", 10 ] - ] - }, - { - "type": "item_group", - "id": "oa_ig_ts_crates", - "items": [ - { "group": "ammo_any_batteries_full", "prob": 10 }, - [ "radio", 10 ], - [ "rag", 30 ], - [ "jack", 20 ], - [ "jack_small", 30 ], - [ "flashlight", 20 ], - [ "heavy_flashlight", 10 ], - [ "jumper_cable", 20 ], - [ "jumper_cable_heavy", 10 ], - [ "pliers", 10 ], - [ "battery_motorbike", 10 ], - [ "battery_car", 10 ], - [ "stereo", 10 ], - [ "wrench", 10 ], - [ "gloves_work", 10 ], - [ "glasses_safety", 10 ], - [ "solar_cell", 10 ], - [ "screwdriver", 15 ], - [ "superglue", 5 ], - [ "polisher", 15 ], - [ "solar_panel", 15 ], - [ "spare_tire_carrier", 10 ], - [ "mounted_spare_tire", 10 ] - ] - }, - { - "type": "item_group", - "id": "oa_ig_ts_tires", - "items": [ [ "wheel_small", 30 ], [ "wheel", 30 ], [ "wheel_wide", 20 ] ] - }, { "type": "mapgen", "om_terrain": [ "cs_tire_shop" ], "method": "json", "weight": 1000, "object": { + "fill_ter": "t_floor", "rows": [ ",..~~y''''y~~''''''~~.,,", ".,.~~y''''y~~''''''~~..,", @@ -124,37 +27,29 @@ ".,..| cc--l---- -- Sg..", "...,| ch|L C|Vv c| Sg,.", ".,..| |L C| c|-D-|..", - "..,.|rrr|L C|hhhh|T S|.,", + "..,.|rrr|L C|hhhh|T S|4,", "...,-ggg-----gggg-----..", - ".,..,..,...,..,....,...,", - "...,,....,.....,.....,.." + ".,..,..,.u## ", + " " + ], + "palettes": [ "roof_palette" ], + "terrain": { ">": "t_ladder_down" }, + "place_items": [ { "item": "roof_trash", "x": [ 7, 15 ], "y": [ 7, 18 ], "chance": 20, "repeat": [ 1, 3 ] } ], + "place_nested": [ + { + "chunks": [ + [ "null", 40 ], + [ "roof_2x2_utilities_b", 15 ], + [ "roof_2x2_utilities_c", 5 ], + [ "roof_2x2_utilities_d", 10 ], + [ "roof_2x2_utilities", 10 ], + [ "roof_2x2_golf", 5 ] + ], + "x": [ 7, 16 ], + "y": 17 + }, + { + "chunks": [ + [ "null", 50 ], + [ "roof_4x4_party", 5 ], + [ "roof_4x4_holdout", 5 ], + [ "roof_4x4_utility", 10 ], + [ "roof_4x4_utility_1", 10 ], + [ "roof_6x6_survivor", 10 ], + [ "roof_6x6_utility", 10 ] + ], + "x": [ 6, 15 ], + "y": [ 9, 12 ] + } + ] + } } ] diff --git a/data/json/mapgen/faction_buildings.json b/data/json/mapgen/faction_buildings.json index ef4ac1f7a2f64..95ff737c294d6 100644 --- a/data/json/mapgen/faction_buildings.json +++ b/data/json/mapgen/faction_buildings.json @@ -3,6 +3,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -39,6 +40,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -75,6 +77,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_2" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -111,6 +114,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_3" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -147,6 +151,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_4" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -183,6 +188,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_5" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -219,6 +225,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_6" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -255,6 +262,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_7" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -291,6 +299,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_8" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -327,6 +336,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_9" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -363,6 +373,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_10" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -399,6 +410,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_11" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -435,6 +447,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_12" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -471,6 +484,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_13" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -507,6 +521,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_14" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -543,6 +558,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_15" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -579,6 +595,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_16" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -615,6 +632,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_17" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -651,6 +669,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_18" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -687,6 +706,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_19" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -723,6 +743,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_camp_20" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -759,6 +780,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_farm_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -795,6 +817,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_farm_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -831,6 +854,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_farm_2" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -867,6 +891,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_farm_3" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -903,6 +928,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_farm_4" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -939,6 +965,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -975,6 +1002,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1011,6 +1039,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_2" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1047,6 +1076,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_3" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1083,6 +1113,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_4" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1119,6 +1150,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_5" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1155,6 +1187,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_garage_6" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1191,6 +1224,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1227,6 +1261,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1263,6 +1298,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_2" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1299,6 +1335,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_3" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1335,6 +1372,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_4" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1371,6 +1409,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_5" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1407,6 +1446,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_6" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1443,6 +1483,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_7" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1479,6 +1520,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_kitchen_8" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1515,6 +1557,7 @@ "type": "mapgen", "om_terrain": [ "faction_hide_site_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1551,6 +1594,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_N_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1587,6 +1631,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_E_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1623,6 +1668,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_S_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1659,6 +1705,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_W_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1695,6 +1742,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_N_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1731,6 +1779,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_E_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1767,6 +1816,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_S_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1803,6 +1853,7 @@ "type": "mapgen", "om_terrain": [ "faction_wall_level_W_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1839,6 +1890,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_0" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1875,6 +1927,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_1" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1911,6 +1964,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_2" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1947,6 +2001,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_3" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -1983,6 +2038,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_4" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -2019,6 +2075,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_5" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -2055,6 +2112,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_6" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -2091,6 +2149,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_7" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -2128,6 +2187,7 @@ "om_terrain": [ "faction_base_blacksmith_8" ], "method": "json", "weight": 250, + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "object": { "fill_ter": "t_floor", "rows": [ @@ -2164,6 +2224,7 @@ "om_terrain": [ "faction_base_blacksmith_9" ], "method": "json", "weight": 250, + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "object": { "fill_ter": "t_floor", "rows": [ @@ -2199,6 +2260,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_10" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -2235,6 +2297,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_11" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", @@ -2271,6 +2334,7 @@ "type": "mapgen", "om_terrain": [ "faction_base_blacksmith_12" ], "method": "json", + "faction_owner": { "id": "your_followers", "area": [ { "x": 0, "y": 0, "x2": 23, "y2": 23 } ] }, "weight": 250, "object": { "fill_ter": "t_floor", diff --git a/data/json/mapgen/farm_dairy.json b/data/json/mapgen/farm_dairy.json index 7d685c021a530..d7f8e4dd507b6 100644 --- a/data/json/mapgen/farm_dairy.json +++ b/data/json/mapgen/farm_dairy.json @@ -41,7 +41,7 @@ ".$......................", ".$......................" ], - "terrain": { "$": "t_chainfence_v", ".": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ] }, + "terrain": { "$": "t_splitrail_fence", ".": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ] }, "place_monsters": [ { "monster": "GROUP_COWS", "x": [ 1, 10 ], "y": [ 1, 9 ], "density": 0.5 }, { "monster": "GROUP_COWS", "x": [ 1, 12 ], "y": [ 1, 12 ], "density": 0.5 }, @@ -83,7 +83,7 @@ "......................$.", "......................$." ], - "terrain": { "$": "t_chainfence_v", ".": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ] }, + "terrain": { "$": "t_splitrail_fence", ".": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ] }, "place_monsters": [ { "monster": "GROUP_COWS", "x": [ 1, 10 ], "y": [ 1, 9 ], "density": 0.5 }, { "monster": "GROUP_COWS", "x": [ 1, 12 ], "y": [ 1, 12 ], "density": 0.5 }, @@ -127,7 +127,7 @@ "........................" ], "terrain": { - "$": "t_chainfence_v", + "$": "t_splitrail_fence", "%": "t_milking_machine", "*": "t_window_bars", "+": "t_door_o", @@ -182,7 +182,7 @@ "........................" ], "terrain": { - "$": "t_chainfence_v", + "$": "t_splitrail_fence", "'": "t_door_o", "*": "t_window_domestic", "+": "t_door_locked_interior", @@ -192,7 +192,7 @@ "Y": "t_floor", "_": "t_floor", "a": [ "t_grass", "t_grass", "t_dirt", "t_dirt", "t_dirt" ], - "f": "t_door_metal_c", + "f": "t_splitrail_fencegate_c", "|": "t_wall" }, "furniture": { diff --git a/data/json/mapgen/mall.json b/data/json/mapgen/mall.json index f36638b33935f..2f9e3e753c75b 100644 --- a/data/json/mapgen/mall.json +++ b/data/json/mapgen/mall.json @@ -125,6 +125,58 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_3", + "weight": 200, + "object": { + "fill_ter": "t_concrete", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " -------------------", + " |JJJJuuJ|zzzzz_zQQQ", + " |J______|zz___zz___", + " |J_FKF__|z____zz___", + " |__FKF__|__________", + " |Y_FKF__=__________", + " |Y_____y|--=--_____", + " |u_FKF_P|0+_F|_____", + " |u_FKF_P|--_F|_____", + " |_______|0+_F|_____", + " |-==-------_F|_____", + " |P___=__=___y|_____" + ], + "palettes": [ "mall_palette_2" ], + "furniture": { "0": "f_shower" } + }, + "items": { + "J": { "item": "elecsto_homapl", "chance": 10 }, + "0": { "item": "beauty", "chance": 10 }, + "P": [ + { "item": "jackets", "chance": 20 }, + { "item": "softdrugs", "chance": 20 }, + { "item": "bags", "chance": 20 }, + { "item": "winter", "chance": 20 } + ], + "u": [ + { "item": "vending_food_items", "chance": 20, "repeat": [ 4, 10 ] }, + { "item": "vending_drink_items", "chance": 30, "repeat": [ 6, 10 ] } + ], + "K": [ { "item": "vending_food_items", "chance": 20 }, { "item": "vending_drink_items", "chance": 20 } ] + } + }, { "type": "mapgen", "method": "json", @@ -145,21 +197,71 @@ " ", " ", " ", - " 2222222222222222222", - " |..................", - " |..................", - " |..................", - " |..................", - " |..................", - " |..................", - " |..................", - " |..................", - " |..................", - " |..................", - " |.................." + " 222222222222#######", + " !...........#______", + " !...........#zz_z__", + " !...........=_z_z__", + " !...........#____z_", + " !...........1__z_z_", + " !...........1___z__", + " !....*......1___z__", + " !...........1___zz_", + " !...........1____z_", + " !..........3#3___z_", + " !...........#______" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + ".": "t_flat_roof", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control", + "#": "t_wall_w", + "!": "t_gutter_west", + "2": "t_gutter_north" + }, + "items": { + "z": [ + { "item": "kitchen", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "allclothes", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "livingroom", "chance": 20, "repeat": [ 1, 2 ] } + ] + }, + "vehicles": { "*": { "vehicle": "forklift", "chance": 100, "rotation": 90 } } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_3", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " 2222222", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......" ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "|": "t_gutter_west" }, - "place_items": [ { "item": "roof_trash", "x": [ 7, 22 ], "y": [ 14, 22 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "palettes": [ "roof_palette" ] } }, { @@ -212,9 +314,102 @@ { "type": "mapgen", "method": "json", - "//": "has freight elevators on ground", + "//": "has freight elevators", + "om_terrain": "mall_b_4", + "weight": 200, + "object": { + "fill_ter": "t_concrete", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "---------|-----|--------", + "QQQ__QQQ_|EEEEE|____Y___", + "_________+EEEEE+___z__z_", + "QQQ______+EEEEE+___z_zz_", + "_________+EEEEE+__zz__z_", + "_________|EEEEE|________", + "_________|-----|________", + "___________zzz__________", + "____________z___________", + "________________________", + "________________---H=H--", + "_______________Y|Sy____WR" + ], + "palettes": [ "mall_palette_2" ], + "items": { + "Y": { "item": "trash", "chance": 100, "repeat": [ 1, 2 ] }, + "S": { "item": "trash", "chance": 30, "repeat": [ 4, 6 ] }, + "R": { "item": "magazines", "chance": 30, "repeat": [ 1, 2 ] }, + "z": [ + { "item": "hatstore_accessories", "chance": 40, "repeat": [ 1, 2 ] }, + { "item": "shoestore_shoes", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "coffee_display_2", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "coffee_condiments", "chance": 10, "repeat": [ 1, 2 ] } + ], + "Q": [ + { "item": "tools_construction", "chance": 40, "repeat": [ 1, 2 ] }, + { "item": "tools_entry", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "tools_mechanic", "chance": 30, "repeat": [ 1, 2 ] }, + { "item": "tools_carpentry", "chance": 10, "repeat": [ 1, 2 ] } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 13, 23 ], "y": [ 2, 23 ], "density": 0.3 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "//": "has freight elevators", "om_terrain": "mall_a_4_roof", "weight": 200, + "object": { + "fill_ter": "t_concrete", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "-|-------|-----|-------|", + "_|xx_____+EEEEE+_zzz_z_|", + "_|x__x___+EEEEE+_____z_1", + "_=_______+EEEEE+_______1", + "_|P______+EEEEE+__*____1", + "_|P______+EEEEE+_______1", + "_|-H+H-__|-----|______3|", + "_|K__S|_______________u|", + "_|@__BH_______________u|", + "_|@_II|_______3____xx__|", + "_|------=-1111---------|", + "______________3________|" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { ".": "t_flat_roof", "1": "t_door_metal_locked", "3": "t_gates_mech_control" }, + "vehicles": { "*": { "vehicle": "forklift", "chance": 100, "rotation": 90 } }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 13, 23 ], "y": [ 2, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_4", "object": { "fill_ter": "t_flat_roof", "rows": [ @@ -230,21 +425,20 @@ " ", " ", " ", - "222222222222222222222222", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" + "222222222222222222222223", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3" ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north" }, - "place_items": [ { "item": "roof_trash", "x": [ 2, 21 ], "y": [ 14, 22 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "palettes": [ "roof_palette" ] } }, { @@ -298,6 +492,49 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_5", + "weight": 200, + "object": { + "fill_ter": "t_concrete", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "---------------- ", + "_______________| ", + "_______________| ", + "____|-------|__| ", + "____|______z|__| ", + "____|__xx___|__| ", + "____+___xx__+__| ", + "____|____x__|__| ", + "____|_______|__| ", + "____|___z___|__| ", + "-___|zzzxxx_|__| ", + "--==---------==| " + ], + "palettes": [ "mall_palette_2" ], + "items": { + "z": [ + { "item": "tools_carpentry", "chance": 40, "repeat": [ 1, 2 ] }, + { "item": "tools_common", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "tools_mechanic", "chance": 10, "repeat": [ 1, 2 ] } + ] + } + } + }, { "type": "mapgen", "method": "json", @@ -324,15 +561,14 @@ "...............3 ", "...............3 ", "...............3 ", - "...............3 ", + "4..............3 ", "...............3 ", "...............3 ", "...............3 ", "...............3 ", "...............3 " ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "3": "t_gutter_east" }, - "place_items": [ { "item": "roof_trash", "x": [ 1, 13 ], "y": [ 14, 22 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "3": "t_gutter_east", "4": "t_gates_mech_control" } } }, { @@ -541,6 +777,47 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 15 ], "y": [ 2, 23 ], "density": 0.15 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_10", + "weight": 200, + "object": { + "fill_ter": "t_floor", + "rows": [ + " ", + " ", + " ", + " ", + " |-------", + " |^^^^^^^", + " |^^^^^^^", + " |==|----", + " |^^|y666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|Y666", + " |^^=6666", + " |^^|----", + " |^^=6666", + " |^^|Y666", + " |^^|y666" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "Y": "t_carpet_red", "y": "t_carpet_red" }, + "items": { + "y": { "item": "trash_cart", "chance": 10, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] } + } + } + }, { "type": "mapgen", "method": "json", @@ -574,8 +851,7 @@ " |.......", " |......." ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "|": "t_gutter_west" }, - "place_items": [ { "item": "roof_trash", "x": [ 18, 22 ], "y": [ 3, 14 ], "chance": 50, "repeat": [ 6, 23 ] } ] + "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "|": "t_gutter_west" } } }, { @@ -594,8 +870,8 @@ " ", " ", "----------------|---|-0-", - "3333333333333333|33K|u33", - "g3g3g3g3g3g3g333|-0-|u33", + "3333333333333333|<3<|u33", + "g3g3g3g3g3g3g333|333|u33", "g3g3g3g3g3g3g333033Q|-3-", "g3g3g3g3g3g3g3330333|33J", "g3g3g3g3g3g3g33G|333|333", @@ -623,6 +899,51 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 9, 23 ], "density": 0.15 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_11", + "weight": 200, + "object": { + "fill_ter": "t_floor", + "rows": [ + " ", + " ", + " ", + " ", + "------------------------", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "------------------=--=--", + "6666666666666666|>^>|^Y|", + "B6B6B6B6B6B6B666|^^^|^^|", + "B6B6B6B6B6B6B666=^^^|Q^7", + "B6B6B6B6B6B6B666=^^^|Q^7", + "B6B6B6B6B6B6B666|y^^|Q^7", + "6666666666666666|^^Y|b^7", + "6666666666666666|^^Y|y^7", + "B6B6B6B6B6B6B666|y^^|b^7", + "B6B6B6B6B6B6B666=^^^|Q^7", + "B6B6B6B6B6B6B666=^^^|Q^7", + "B6B6B6B6B6B6B666|y^^|Q^7", + "6666666666666666|^^^|^^^", + "----------------|y^Y|yby", + "6666666666666666|^^^|---", + "B6B6B6B6B6B6B666|y^^=^^P", + "B6B6B6B6B6B6B666=^^^|^^P" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "B": "t_carpet_red" }, + "items": { + "y": { "item": "trash_cart", "chance": 10, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] }, + "P": { "item": "cleaning", "chance": 30, "repeat": [ 1, 2 ] }, + "B": [ { "item": "bags", "chance": 5 }, { "item": "snacks", "chance": 20 }, { "item": "vending_food_items", "chance": 10 } ], + "Q": [ { "item": "bags", "chance": 20 }, { "item": "shoestore_shoes", "chance": 30 } ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 10, 23 ], "y": [ 2, 23 ], "density": 0.3 } ] + } + }, { "type": "mapgen", "method": "json", @@ -657,7 +978,7 @@ "........................" ], "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north" }, - "place_items": [ { "item": "roof_trash", "x": [ 2, 21 ], "y": [ 3, 14 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] } }, { @@ -706,24 +1027,98 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 8, 23 ], "density": 0.2 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_12", + "weight": 200, + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + " |P__P|jt|_--||_____", + " |P__P|--|_+0|______", + " |P___=__=_--|______", + " |P__P|jt|_+0|______", + "-------==-|---------==--", + "^^^^^^^^^^|P_=__________", + "^^^^^^^^^^|---=--------|", + "-----------MM|..yFFFy.Y|", + "^|^|^|^%|MM^^HH........|", + "=|=|=|=-|^^^^dH........|", + "77777777777^^dH...FF...+", + "KK7KK77KK77^^HH...FF...+", + "KK77777KK77^^+....FF...|", + "777JJJ77777^^+..........", + "KK77AJ7KK77^dHH.........", + "777JJJ77777^^+..........", + "KK77777KK77^^+....FF....", + "KK7KK77KK77^^HH...FF....", + "77777777777^^dH...FF....", + "^^^^^^^^^^^^^dH.........", + "^QQQdQQQdQQQ^HH.........", + "-------------|y.........", + "|UUUU|VVVyVVV|-H+H+H-|..", + "|U...|..............y|.." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "K": "t_carpet_green", + "J": "t_carpet_green", + "A": "t_carpet_green", + "d": "t_floor", + "M": "t_floor", + "Q": "t_floor", + "%": "t_floor", + "j": "t_concrete", + "t": "t_concrete" + }, + "furniture": { "%": "f_bench", "0": "f_shower" }, + "items": { + "y": { "item": "trash_cart", "chance": 10, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] }, + "M": { "item": "jewelry_front", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": { "item": "pants", "chance": 30 }, + "d": { "item": "dresses", "chance": 50 }, + "V": { "item": "consumer_electronics", "chance": 40 }, + "J": { "item": "hatstore_accessories", "chance": 20, "repeat": [ 1, 2 ] }, + "K": [ + { "item": "shoestore_accessories", "chance": 10 }, + { "item": "shirts", "chance": 10 }, + { "item": "winter", "chance": 10 } + ], + "U": [ + { "item": "consumer_electronics", "chance": 20 }, + { "item": "elecsto_books", "chance": 30 }, + { "item": "elecsto_lights", "chance": 10 } + ], + "P": [ + { "item": "jackets", "chance": 30 }, + { "item": "softdrugs", "chance": 30 }, + { "item": "bags", "chance": 30 }, + { "item": "winter", "chance": 30 } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", "om_terrain": "mall_a_12_roof", "weight": 200, "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_concrete", "rows": [ - " |..................", - " |..................", - " |..................", - " |..................", - "222222..................", - "........................", - "........................", - "........................", - "........................", - "........................", + " !...........#______", + " !...........#_____z", + " !...........#_____z", + " !...........#zzzz_z", + "******...........#_z___z", + ".................#_z____", + ".................#_zzz__", + ".................#______", + ".................#_PPP_#", + ".................#######", "........................", "........................", "........................", @@ -739,8 +1134,61 @@ "........................", "........................" ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "|": "t_gutter_west" }, - "place_items": [ { "item": "roof_trash", "x": [ 2, 21 ], "y": [ 5, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "palettes": [ "mall_palette_2" ], + "terrain": { + ".": "t_flat_roof", + " ": "t_open_air", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control", + "4": "t_chainfence", + "0": "t_chaingate_c", + "#": "t_wall_w", + "*": "t_gutter_north", + "!": "t_gutter_west" + }, + "items": { + "z": [ + { "item": "pasta", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "allclothes", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "child_items", "chance": 20, "repeat": [ 1, 2 ] } + ], + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ] + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_12", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |------", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] } }, { @@ -759,7 +1207,7 @@ " | z :2111111", " |zzz :2112222", "--| |---|--|2112|--", - "<<| |<<|2112|yq", + " <| | <|2112|yq", " |----||----| |2112|22", " |EEEE||EEEE| [2112V22", " |EEEE||EEEE| [2112V22", @@ -792,6 +1240,66 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 15, 23 ], "density": 0.6 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_13", + "weight": 200, + "object": { + "fill_ter": "t_linoleum_white", + "rows": [ + "____________z___=___I__S", + "__zzz____z______H_C_IB_w", + "___zz___zzz____P|-------", + "____z__________P|yFFYFFy", + "-------==-------|.......", + "________________=.......", + "__|----==----|__=.......", + "--|x________x|--|....|-H", + "<>|xxxPxxxPxx|<>|....|d%", + "..|----||----|..|....H%8", + ".Y|EEEE||EEEE|Y.+....+88", + "..|EEEE||EEEE|..+....+88", + "HH|H++H||H++H|HH|....H%8", + ".....................|d%", + ".....................|-H", + "........................", + "....###666###...........", + "...F# #606# #F.........#", + "...F# #666# #F........y#", + "...F# ##### #F........F#", + "...Y# #Y........F#", + "...F# #F........y#", + "...F# #F.........#", + "...F# #F.........." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "P": "t_concrete", + "z": "t_concrete", + "S": "t_concrete", + "C": "t_concrete", + "I": "t_concrete", + "B": "t_concrete", + "w": "t_concrete", + "0": "t_carpet_red", + "%": "t_carpet_purple", + "d": "t_carpet_purple" + }, + "furniture": { "0": "f_piano", "%": [ "f_indoor_plant_y", "f_indoor_plant" ] }, + "items": { + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 100 }, + { "item": "shoestore_shoes", "chance": 100 } + ], + "Y": { "item": "floor_trash", "chance": 100, "repeat": [ 1, 2 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -800,42 +1308,91 @@ "object": { "fill_ter": "t_flat_roof", "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - ">>............>>........", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "terrain": { ".": "t_flat_roof", ">": "t_stairs_down" }, - "place_items": [ { "item": "roof_trash", "x": [ 2, 22 ], "y": [ 2, 22 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "_______________________|", + "_______________zz_____3|", + "______zzz_______z__z___1", + "______________zz_______1", + "_zzz________________z__1", + "___z__zzz___________z__1", + "___________________zz__1", + "_______________________|", + ">>|__________|>>|_PP_PP|", + "--|++++--++++|--|---=---", + "..|EEEE--EEEE|..........", + "..|EEEE--EEEE|..........", + "..|----------|..........", + "........................", + "........................", + "........................", + "....ooooooooo...........", + "....ooooooooo..........o", + "....ooooooooo..........o", + "....ooooooooo..........o", + "....ooooooooo..........o", + "....ooooooooo..........o", + "....ooooooooo..........o", + "....ooooooooo..........." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + ".": "t_flat_roof", + "o": "t_glass_roof", + ">": "t_stairs_down", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control" + }, + "items": { + "z": [ + { "item": "cannedfood", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "allclothes", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "bed", "chance": 20, "repeat": [ 1, 2 ] } + ], + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ] + } } }, { "type": "mapgen", "method": "json", - "om_terrain": [ "mall_a_14" ], - "weight": 250, + "om_terrain": "mall_upper_roof_13", "object": { - "fill_ter": "t_floor", + "fill_ter": "t_flat_roof", + "rows": [ + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + "--|..........3----------", + " |..........3 ", + " |..........3 ", + " |----------3 ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": [ "mall_a_14" ], + "weight": 250, + "object": { + "fill_ter": "t_floor", "rows": [ "|2222|S + t| |...ss___", "|2112|S |--| |-|.ss___", @@ -879,6 +1436,80 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 16, 23 ], "density": 0.4 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_14", + "weight": 200, + "object": { + "fill_ter": "t_linoleum_white", + "rows": [ + "|....|^..+.t|__| ", + "|....|...|--|__|H| ", + "|....+^..+.t|__|dH ", + "F....|---|--|__|yH ", + ".....+^..+.t|__=dH ", + ".....|...|.-|__|H| ", + "..yuu|^..+.t|__| ", + "+H---------||==| ", + "88%TTT%8888|z__| ", + "88888888!A8|z__| ", + "KK8K8K88?88|z__| ", + "KK8K8K88!88=__z| ", + "88888888?8!|__z| ", + "KK%88%88!8!|zzz| ", + "HHH++HHHHH-|-H-| ", + "...........| ", + "yFFy......yH ", + "#####.....YH ", + " #y..JmmH ", + " #F..J.BH ", + " #F..J..H ", + " #y..JJ.H ", + "#####...Y..H ", + "yFFy......yH " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "%": "t_carpet_purple", + "T": "t_carpet_purple", + "K": "t_carpet_purple", + "!": "t_carpet_purple", + "A": "t_carpet_purple" + }, + "furniture": { "%": [ "f_indoor_plant_y", "f_indoor_plant" ], "^": "f_sink", "!": "f_counter" }, + "items": { + "u": [ + { "item": "vending_food_items", "chance": 20, "repeat": [ 4, 10 ] }, + { "item": "vending_drink_items", "chance": 30, "repeat": [ 6, 10 ] } + ], + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 100 }, + { "item": "shoestore_shoes", "chance": 100 } + ], + "K": { "item": "shoestore_shoes", "chance": 100, "repeat": [ 1, 2 ] }, + "Y": { "item": "floor_trash", "chance": 100, "repeat": [ 1, 2 ] }, + "T": { "item": "hatstore_accessories", "chance": 100, "repeat": [ 1, 2 ] }, + "!": [ + { "item": "hatstore_accessories", "chance": 30, "repeat": [ 1, 2 ] }, + { "item": "shoestore_shoes", "chance": 30, "repeat": [ 1, 2 ] } + ], + "z": [ + { "item": "hatstore_accessories", "chance": 40, "repeat": [ 1, 2 ] }, + { "item": "shoestore_shoes", "chance": 10, "repeat": [ 1, 2 ] } + ], + "m": { "item": "dessert", "chance": 50, "repeat": [ 1, 2 ] }, + "J": [ + { "item": "baked_goods", "chance": 40, "repeat": [ 1, 2 ] }, + { "item": "coffee_display_2", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "coffee_condiments", "chance": 10, "repeat": [ 1, 2 ] } + ] + } + } + }, { "type": "mapgen", "method": "json", @@ -888,7 +1519,7 @@ "fill_ter": "t_flat_roof", "rows": [ "...............3 ", - "...............323 ", + "4..............323 ", ".................3 ", ".................3 ", ".................3 ", @@ -904,16 +1535,23 @@ "...........3---3 ", "...........3 ", "...........3 ", - "...........3 ", - "...........3 ", - "...........3 ", - "...........3 ", - "...........3 ", - "...........3 ", + "ooooo......3 ", + "ooooo......3 ", + "ooooo......3 ", + "ooooo......3 ", + "ooooo......3 ", + "ooooo......3 ", "...........3 " ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "-": "t_gutter_south", "2": "t_gutter_north", "3": "t_gutter_east" }, - "place_items": [ { "item": "roof_trash", "x": [ 1, 13 ], "y": [ 1, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "terrain": { + ".": "t_flat_roof", + " ": "t_open_air", + "-": "t_gutter_south", + "2": "t_gutter_north", + "3": "t_gutter_east", + "o": "t_glass_roof", + "4": "t_gates_mech_control" + } } }, { @@ -1123,6 +1761,46 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 15 ], "y": [ 5, 11 ], "density": 0.15 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_19", + "object": { + "fill_ter": "t_floor", + "rows": [ + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|6666", + " |^^|yY66", + " |^^---==", + " |^^^^^^^", + " |^^^^^^^", + " |^^^^^^^", + " |-------", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "y": "t_carpet_red", "Y": "t_carpet_red" }, + "items": { + "y": { "item": "trash_cart", "chance": 10, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] } + } + } + }, { "type": "mapgen", "method": "json", @@ -1175,8 +1853,8 @@ "g3g3g3g3g3g3g33G|333|L +", "g3g3g3g3g3g3g3330333|-:|", "g3g3g3g3g3g3g333033Q| ", - "g3g3g3g3g3g3g333|-0-| ", - "3333333333333333|33K| ", + "g3g3g3g3g3g3g333|333| ", + "3333333333333333|<3<| ", "----------------|---| ", " ", " |--| |--| ", @@ -1210,6 +1888,49 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_20", + "object": { + "fill_ter": "t_floor", + "rows": [ + "B6B6B6B6B6B6B666=^^^|^zz", + "B6B6B6B6B6B6B666|y^^|---", + "6666666666666666|^^^|j.j", + "6666666666666666|^^^=...", + "B6B6B6B6B6B6B666|y^^|t|t", + "B6B6B6B6B6B6B666=^^Y|---", + "B6B6B6B6B6B6B666=^^Y|t|t", + "B6B6B6B6B6B6B666|y^^=...", + "6666666666666666|>^>|j.j", + "------------------------", + "^yyYyy^^^^yyYyy^^H..|777", + "^^^^^^^^^^^^^^^^^+.F|%99", + "^^^^^^^^^^^^^^^^^H.FHK99", + "HHH---HHH---HHH---.F|%99", + " |..H799", + " H..+799", + " H..+799", + " H..|777", + " |..|-HH", + " HF.....", + " HF.....", + " HF..###", + " H...# ", + " H...# " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "F": "t_linoleum_gray", "B": "t_carpet_red", "$": "t_ladder_up", "%": "t_carpet_green", "K": "t_carpet_green" }, + "furniture": { "%": "f_chair" }, + "items": { + "y": { "item": "trash_cart", "chance": 10, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] }, + "z": { "item": "vending_food_items", "chance": 70, "repeat": [ 4, 6 ] }, + "B": [ { "item": "bags", "chance": 5 }, { "item": "snacks", "chance": 10 }, { "item": "vending_food_items", "chance": 10 } ] + } + } + }, { "type": "mapgen", "method": "json", @@ -1239,12 +1960,11 @@ " |......", " |......", " |......", - " |......", - " |......", - " |......" + " |...ooo", + " |...ooo", + " |...ooo" ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "-": "t_gutter_south", "|": "t_gutter_west" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "terrain": { ".": "t_flat_roof", " ": "t_open_air", "-": "t_gutter_south", "|": "t_gutter_west", "o": "t_glass_roof" } } }, { @@ -1300,6 +2020,116 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 6, 23 ], "y": [ 13, 23 ], "density": 0.2 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_21", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "|z...|V..000.........|..", + "|....|V.......000....H..", + "|z...=...000.........+..", + "|zz..|V........MMMM?MH..", + "|zzz.|VVVyVVV....*...|..", + "------|------|-------|..", + "|U.U.U|QQQlll|%n^%%!%|y.", + "|U.U.U|Q.....=......%|..", + "|U...U|QQQQ.Y|$$$$$%%|Y.", + "|-=---|----=-|$HHH$--||F", + "777~jim~|YY.*%$...$%*.HF", + "9999999~|y..*%$.$$$%*.HF", + "JJJJJJJ?|...*%$.$%%%*.H.", + "9AAAAAA7|%*.*%$.$%*...+.", + "99999997|%*.*%$$$%*...H.", + "BKB9BKB7|%*.*%%%%%*...HF", + "BKB9BKB7|%*..*****...YHF", + "77777777|?...........?|F", + "-HH+HHH-|-HHHH++HHHH--|.", + "........................", + "........................", + "######################..", + " #..", + " #.." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "A": "t_carpet_yellow", + "B": "t_carpet_yellow", + "K": "t_carpet_yellow", + "J": "t_carpet_yellow", + "i": "t_carpet_green", + "%": "t_carpet_green", + "j": "t_carpet_green", + "m": "t_carpet_green", + "~": "t_carpet_green", + "Q": "t_linoleum_gray", + "$": "t_conveyor" + }, + "furniture": { "%": "f_counter", "^": "f_sink", "*": "f_stool", "!": "f_oven", "0": "f_table" }, + "items": { + "y": { "item": "trash_cart", "chance": 10, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] }, + "^": { "item": "restaur_sink", "chance": 50, "repeat": [ 1, 2 ] }, + "n": { "item": "restaur_sink", "chance": 50, "repeat": [ 1, 2 ] }, + "!": { "item": "oven", "chance": 50, "repeat": [ 1, 2 ] }, + "$": [ + { "item": "diner_food", "chance": 10 }, + { "item": "baked_goods", "chance": 10 }, + { "item": "groce_premade", "chance": 10 } + ], + "%": [ + { "item": "bar_food", "chance": 20 }, + { "item": "diner_food", "chance": 20 }, + { "item": "groce_premade", "chance": 20 } + ], + "Q": [ + { "item": "restaur_kitchen", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "groce_bread", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "groce_condiment", "chance": 20, "repeat": [ 1, 2 ] } + ], + "l": [ + { "item": "restaur_fridge", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "baked_goods", "chance": 20 }, + { "item": "fridge", "chance": 10, "repeat": [ 1, 2 ] } + ], + "K": [ + { "item": "baked_goods", "chance": 20 }, + { "item": "coffee_counter", "chance": 20 }, + { "item": "tea_dishes", "chance": 20 } + ], + "J": [ + { "item": "coffee_counter", "chance": 20 }, + { "item": "coffee_condiments", "chance": 20 }, + { "item": "tea_dishes", "chance": 20 } + ], + "~": [ + { "item": "coffee_display_2", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "coffee_prep", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "tea_dishes", "chance": 20, "repeat": [ 1, 2 ] } + ], + "U": [ + { "item": "baked_goods", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "groce_bread", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "groce_ingredient", "chance": 30, "repeat": [ 1, 2 ] } + ], + "m": { "item": "coffee_freezer", "chance": 30, "repeat": [ 1, 2 ] }, + "V": { "item": "consumer_electronics", "chance": 25, "repeat": [ 1, 2 ] }, + "0": [ { "item": "elecsto_lights", "chance": 20, "repeat": [ 1, 2 ] }, { "item": "elecsto_books", "chance": 30 } ], + "z": [ + { "item": "consumer_electronics", "chance": 20 }, + { "item": "elecsto_persele", "chance": 30 }, + { "item": "elecsto_pcs", "chance": 30 } + ], + "M": [ + { "item": "elecsto_pcs", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "elecsto_persele", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "elecsto_cameras", "chance": 10, "repeat": [ 1, 2 ] } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -1329,37 +2159,12 @@ "........................", "........................", "........................", - "........................", - "........................", - "........................" + "oooooooooooooooooooooo..", + "oooooooooooooooooooooo..", + "oooooooooooooooooooooo.." ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ], - "place_nested": [ - { - "chunks": [ - [ "null", 20 ], - [ "roof_2x2_utilities_b", 15 ], - [ "roof_2x2_utilities_c", 5 ], - [ "roof_2x2_utilities_d", 40 ], - [ "roof_2x2_utilities", 50 ], - [ "roof_4x4_utility_1", 30 ] - ], - "x": [ 3, 15 ], - "y": [ 3, 7 ] - }, - { - "chunks": [ - [ "null", 20 ], - [ "roof_4x4_party", 15 ], - [ "roof_4x4_utility", 40 ], - [ "roof_4x4_utility_1", 30 ], - [ "roof_6x6_utility", 20 ] - ], - "x": [ 3, 15 ], - "y": [ 3, 7 ] - } - ] + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, + "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, { @@ -1411,38 +2216,77 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_22_roof", - "weight": 200, + "om_terrain": "mall_b_22", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_linoleum_gray", "rows": [ + "....# #...........", + "....# #....M.M...|", + "....# #....MAM...H", + "....# #....MMM...H", + "....# #..........|", + "....# #..........|", + "...F# #F.........H", + "...F# #F.........+", + "...F# #F.........+", + "...Y# #Y.........H", + "...F# #F.........|", + "...F# #F.........|", + "...F# #F...KKK...H", + "....#########....KAK...H", + ".................K.K...|", "........................", "........................", "........................", + "......................##", + "........#####.........# ", + ".......## ##........# ", + "......## ##.......# ", + ".....## ##......##", + "....## ##......." + ], + "palettes": [ "mall_palette_2" ], + "items": { + "K": { "item": "cell_shop", "chance": 50 }, + "M": { "item": "jewelry_accessories", "chance": 50 }, + "Y": { "item": "floor_trash", "chance": 70, "repeat": [ 1, 2 ] } + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_22_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", + "....ooooooooo...........", "........................", "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" + "......................oo", + ".........ooo..........oo", + "........ooooo.........oo", + ".......ooooooo........oo", + "......ooooooooo.......oo", + ".....ooooooooooo........" ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" } } }, { @@ -1506,6 +2350,62 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 2, 21 ], "density": 0.15 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_23", + "object": { + "fill_ter": "t_floor", + "rows": [ + "...........| ", + "-HH--+H---|---|---------", + "yKK^^^K|PP|t.%|IB..Pzzzz", + "^^^^^^K|..|...|I......zz", + "^^^^^^K|=--=|=-------=--", + "^^^^^^^^^^^^|^^VVYVV^^^y", + "^^^^^^^^^^^^|^^^^^^^A^^^", + "^KK^KK^^J^^~|^^JJJJJJ?J^", + "^KK^KK^^J^^~|^^99999999^", + "^^^^^^^^?A^~|V^90099009^", + "^KK^KK^^J^^^|V^99999999^", + "^KK^KK^^JJJ^|V^90099009^", + "^^^^^^^^^^^^|^^99999999^", + "^KKy^^^^^KK^|yMM^^^^^^MM", + "-HH--+H--HH-|-HH--+H--HH", + "........................", + "........................", + "........................", + "####################....", + " #....", + " #....", + " #....", + "####################....", + "........................" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "0": "t_carpet_yellow", + "B": "t_linoleum_gray", + "I": "t_linoleum_gray", + "P": "t_linoleum_gray", + "z": "t_linoleum_gray", + "t": "t_linoleum_gray", + "%": "t_linoleum_gray" + }, + "furniture": { "%": "f_sink", "0": "f_table" }, + "items": { + "I": { "item": "cubical_office", "chance": 70, "repeat": [ 2, 4 ] }, + "M": { "item": "smoke_shop", "chance": 70, "repeat": [ 2, 4 ] }, + "J": { "item": "office_supplies", "chance": 10 }, + "P": { "item": "cleaning", "chance": 60, "repeat": [ 2, 4 ] }, + "K": { "item": "kitchen_counters", "chance": 50, "repeat": [ 1, 2 ] }, + "0": { "item": "smoke_shop", "chance": 50, "repeat": [ 1, 2 ] }, + "V": { "item": "misc_smoking", "chance": 50, "repeat": [ 1, 2 ] }, + "z": { "item": "smoke_shop", "chance": 50, "repeat": [ 4, 8 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -1531,14 +2431,14 @@ "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + "oooooooooooooooooooo....", + "oooooooooooooooooooo....", + "oooooooooooooooooooo....", + "oooooooooooooooooooo....", + "oooooooooooooooooooo....", "........................" ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north" }, + "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 1, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -1604,6 +2504,54 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.2 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_24", + "object": { + "fill_ter": "t_floor", + "rows": [ + " ", + "------------------------", + "z|t|t|t|t..|t|t|t|t..|RR", + "z|=|=|=|-=-|=|=|=|-=-|R^", + "-|.........|.........|R^", + "^|Y%%%%%..Y|Y%%%%%..Y|^^", + "V|------=---------=---^^", + "V|yFFF^^^^^^yFFF^^^^^^^^", + "y|^^^^777777777^^^^^^^^^", + "V|d^^^7K7K7K7K7^Q^^Q^^Q^", + "V|T^^^7K7K7K7K7^Q^^Q^^Q^", + "V|T^^^7K7K7K7K7^Q^^Q^^Q^", + "^|d^^^777777777^^^^^^^^^", + "^|T^^^7K7K7K7K7^Q^^Q^^Q^", + "-|T^^^7K7K7K7K7^Q^^Q^^Q^", + ".Hy^^^777777777^^^^^^^^^", + ".Hd^^^^^^^^^^^^^^^^^^^^^", + ".Hydy|^^^|d|^^^|^dyd^^^^", + ".|HHH|...|H|...|-HHH-|R^", + "....................Y|R^", + ".....................Hd^", + ".....................--^", + "......................^^", + "......................^^" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "%": "t_linoleum_gray", "t": "t_linoleum_gray", "Y": "t_linoleum_gray", "K": "t_carpet_green" }, + "furniture": { "%": "f_sink" }, + "items": { + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] }, + "V": { "item": "smoke_shop", "chance": 30, "repeat": [ 2, 4 ] }, + "z": { "item": "smoke_shop", "chance": 50, "repeat": [ 4, 8 ] }, + "R": { "item": "shoestore_shoes", "chance": 30, "repeat": [ 2, 4 ] }, + "K": { "item": "shirts", "chance": 30, "repeat": [ 1, 2 ] }, + "T": { "item": "hatstore_accessories", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": [ { "item": "pants", "chance": 30, "repeat": [ 2, 4 ] }, { "item": "suits", "chance": 30, "repeat": [ 2, 4 ] } ], + "d": [ { "item": "jackets", "chance": 40 }, { "item": "pants", "chance": 100 }, { "item": "shirts", "chance": 100 } ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -1657,9 +2605,9 @@ "Y ??? @@c@@ @c ", " ??? ", " HHHHH hnnh ccc cc ", - " | c@@ c ", + " <| c@@ c ", " HHHHH hh @@ ", - " | hnnh ", + " |< hnnh ", " HHHHH hnnh ", " VEEEV hh ", " VEEEV r", @@ -1697,6 +2645,54 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.2 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_25", + "object": { + "fill_ter": "t_floor", + "rows": [ + " ", + "------------------------", + "RRRRRRRRRRR|^|^|^F|SSSSS", + ".R..R..R..R|%|%|%-|..B..", + ".R..R..R..R|......|.III.", + "...........|--%---|.C.C.", + "...yFFFy..........|--=--", + "...HHHHH................", + "......>|.....MMMMMMM....", + "...HHHHH..............d.", + "J..|>.....J..MMMMMMM....", + "J.AHHHHH..J...........d.", + "?..HEEEHA.?..MMMMMMM....", + "J..HEEEH..J...........d.", + "JJ.H+++H.JJ..MMMMMMM....", + "...y...y................", + "........................", + ".9999999999.....9999999.", + ".9KK9KK9KK9..d..9K9K9K9.", + ".9KK9KK9KK9..y..9999999.", + ".9999999999..d..9K9K9K9.", + ".9KK9KK9KK9..y..9999999.", + ".9KK9KK9KK9..d..9K9K9K9.", + ".9999999999.....9999999." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { ".": "t_floor", "-": "t_wall_w", "K": "t_carpet_yellow", ">": "t_stairs_down" }, + "furniture": { "%": "f_beaded_door" }, + "items": { + "Y": { "item": "trash", "chance": 20, "repeat": [ 1, 2 ] }, + "M": { "item": "jewelry_front", "chance": 30, "repeat": [ 1, 2 ] }, + "J": { "item": "office", "chance": 10 }, + "R": { "item": "shoestore_shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "K": { "item": "shirts", "chance": 30, "repeat": [ 1, 2 ] }, + "S": { "item": "office_paper", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": [ { "item": "pants", "chance": 30, "repeat": [ 2, 4 ] }, { "item": "suits", "chance": 30, "repeat": [ 2, 4 ] } ], + "d": [ { "item": "jackets", "chance": 40 }, { "item": "pants", "chance": 100 }, { "item": "shirts", "chance": 100 } ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -1791,6 +2787,47 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_26", + "object": { + "fill_ter": "t_floor", + "rows": [ + " ", + "----------| ", + "|zzzzzz..z| ", + "=........z| ", + "|-----|...|-| ", + "|@@@Wy|z..|yH ", + "|@....=...|dH ", + "......|...=dH ", + "Q.Q.Q.|z..|dH ", + "Q.Q.Q.|z..|yH ", + "Q.Q.Q.|z..|-| ", + "Q.Q.Q.|..z| ", + "Q.Q.Q.|.zz| ", + "......|...| ", + "Q.Q.Q.|z..| ", + "Q.Q.Q.|..z| ", + "Q.Q.Q.|..z| ", + "Q.Q.Q.|...| ", + "Q.Q.Q.|...| ", + "......|z..| ", + "Q.Q.Q.|z..| ", + "Q.Q.Q.|z.z| ", + "Q.Q.Q.|..z| ", + "Q.Q.Q.|...| " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { ".": "t_floor" }, + "items": { + "Q": { "item": "allclothes", "chance": 20, "repeat": [ 1, 2 ] }, + "y": { "item": "trash", "chance": 10 }, + "z": { "item": "allclothes", "chance": 20, "repeat": [ 2, 4 ] } + } + } + }, { "type": "mapgen", "method": "json", @@ -1961,6 +2998,53 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 12 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_29", + "object": { + "fill_ter": "t_floor", + "rows": [ + " H...# ", + " H...# ", + " H...# ", + " H...# ", + " H...###", + " H......", + " |......", + " |-H++H-", + " H^6666^", + " H^!666F", + " |A!666F", + " |^?666F", + " |^6666^", + " |-HHHH---22^^22", + " |JJJJJJ^y^^^^^^", + " HJAAAA^^^^^^JJJ", + " HJA^^^^B^^^^J^V", + " HJA^^^^KKB^^J^V", + " HJA^^^BKK^^^J^V", + " |JJJ^^^^B^^^^^Y", + " |--2HHH222^^222", + " |JJJJJJ^^^JJJ", + " HJAA^A^^^^A^^", + " HJA^^^^^^^^AJ" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "!": "t_carpet_red" }, + "furniture": { "%": "f_pool_table", "!": "f_counter" }, + "items": { + "V": { "item": "alcohol", "chance": 50 }, + "!": { "item": "office", "chance": 40, "repeat": [ 2, 4 ] }, + "J": { "item": "bar_alcohol", "chance": 20 }, + "K": [ + { "item": "restaur_table", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "bar_alcohol", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "restaur_sink", "chance": 20, "repeat": [ 1, 2 ] } + ] + } + } + }, { "type": "mapgen", "method": "json", @@ -1969,11 +3053,11 @@ "object": { "fill_ter": "t_open_air", "rows": [ - " |......", - " |......", - " |......", - " |......", - " |......", + " |...ooo", + " |...ooo", + " |...ooo", + " |...ooo", + " |...ooo", " |......", " |......", " |......", @@ -1994,7 +3078,14 @@ " |............", " |............" ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "2": "t_gutter_north", "-": "t_gutter_south", "|": "t_gutter_west" }, + "terrain": { + ".": "t_flat_roof", + " ": "t_open_air", + "2": "t_gutter_north", + "-": "t_gutter_south", + "|": "t_gutter_west", + "o": "t_glass_roof" + }, "place_items": [ { "item": "roof_trash", "x": [ 19, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -2057,6 +3148,57 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 11 ], "density": 0.2 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_30", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + " #..", + " #..", + " #..", + " #..", + "######################..", + "...yFFFFy..Y..yFFFFy....", + "........................", + "--HHH-HHH-++-HHH-HHH-|p.", + "2.KKKyKKK....KKKyKKKY|..", + "2....................H..", + "2..K.K.K........K.K..|--", + "2..K.K.K........K.K..|Q^", + "2..K.K.K.JJ?JJJ.K.K..|Q^", + "2y.......J..A.J......|Q^", + "2.MMMM...J......MMMM.|Q^", + "2-----------=--------|--", + "2I...C|.Yz....zz.|Y.P|I.", + "2IB...=..........=..F|IB", + "2I...y|...UUUU..z|..P|S.", + "2R.SS--=----------------", + "2----|..................", + "2yj|t|.|----=-----|----=", + "=..|+|.|.%%..%|IIS|SII|.", + "2....|.|%....%|B..|..B|." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "Q": "t_floor" }, + "furniture": { "%": "f_crate_c" }, + "items": { + "K": { "item": "beauty", "chance": 30, "repeat": [ 1, 2 ] }, + "R": { "item": "dollar_books", "chance": 50 }, + "M": { "item": "beauty", "chance": 40, "repeat": [ 2, 4 ] }, + "J": { "item": "kitchen", "chance": 10 }, + "z": { "item": "beauty", "chance": 60, "repeat": [ 2, 4 ] }, + "I": { "item": "office", "chance": 20 }, + "Q": { "item": "camping", "chance": 20 }, + "S": { "item": "office_paper", "chance": 30, "repeat": [ 2, 4 ] }, + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ], + "U": { "item": "beauty", "chance": 60, "repeat": [ 2, 4 ] }, + "%": { "item": "candy_shop", "chance": 60, "repeat": [ 2, 4 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -2065,11 +3207,11 @@ "object": { "fill_ter": "t_flat_roof", "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", + "oooooooooooooooooooooo..", + "oooooooooooooooooooooo..", + "oooooooooooooooooooooo..", + "oooooooooooooooooooooo..", + "oooooooooooooooooooooo..", "........................", "........................", "........................", @@ -2090,28 +3232,8 @@ "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ], - "place_nested": [ - { - "chunks": [ - [ "null", 20 ], - [ "roof_2x2_utilities_b", 15 ], - [ "roof_2x2_utilities_c", 5 ], - [ "roof_2x2_utilities_d", 40 ], - [ "roof_2x2_utilities", 50 ], - [ "roof_2x2_golf", 20 ], - [ "roof_4x4_utility_1", 30 ] - ], - "x": [ 3, 15 ], - "y": [ 3, 7 ] - }, - { - "chunks": [ [ "null", 20 ], [ "roof_4x4_utility", 40 ], [ "roof_4x4_utility_1", 30 ], [ "roof_6x6_utility", 20 ] ], - "x": [ 3, 20 ], - "y": [ 3, 20 ] - } - ] + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, + "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, { @@ -2175,6 +3297,71 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_31", + "object": { + "fill_ter": "t_floor", + "rows": [ + "....# #.......", + "....# #.......", + "....## ##.......", + ".....## ##........", + "......## ##.........", + ".......## ##..........", + "........#####...........", + "........................", + "....................####", + "....................# #", + "--HHHH-++-HHHH-|....# #", + "^^MMMM^^^^MMMM^|...F# #", + "^^^^^^^^^^^^^^^|...F# #", + "^JJJ?JJ^^KK^KK^|...F# #", + "^^^^A^J^^KK^KK^H...y# #", + "-=--^^?^^^^^^^^+...F# #", + "..P|A^J^^KK^KK^H...F# #", + "..P|^^J^^KK^KK^|...F# #", + "..P|^^^^^^^^^^^|....# #", + "-=-|R^77777777^|...Y# #", + "...|R^7*]*7r%7^H....# #", + "---|R^7*'*7r%7^H...F# #", + "zzz|R^7***7777^H...F# #", + "..z|^^77777777^|...F# #" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "*": "t_carpet_green", + "'": "t_carpet_green", + "r": "t_carpet_green", + "b": "t_carpet_green", + "]": "t_carpet_green", + "%": "t_carpet_green", + "z": "t_linoleum_gray", + "F": "t_linoleum_gray", + "P": "t_linoleum_gray", + "Y": "t_linoleum_gray", + "y": "t_linoleum_gray" + }, + "furniture": { + "*": "f_canvas_wall", + "'": "f_groundsheet", + "]": "f_canvas_door", + "%": "f_camp_chair", + "b": "f_brazier", + "r": "f_tourist_table" + }, + "items": { + "K": { "item": "camping", "chance": 30, "repeat": [ 1, 4 ] }, + "R": { "item": "camping", "chance": 30, "repeat": [ 1, 4 ] }, + "J": { "item": "camping", "chance": 10 }, + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ], + "M": { "item": "knife_shop", "chance": 40, "repeat": [ 2, 4 ] }, + "z": { "item": "softdrugs", "chance": 40, "repeat": [ 2, 4 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -2183,32 +3370,32 @@ "object": { "fill_ter": "t_flat_roof", "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" - ], - "terrain": { ".": "t_flat_roof" }, + "....ooooooooooooo.......", + "....ooooooooooooo.......", + ".....ooooooooooo........", + "......ooooooooo.........", + ".......ooooooo..........", + "........ooooo...........", + ".........ooo............", + "........................", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo" + ], + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -2273,6 +3460,72 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 0, 14 ], "y": [ 1, 22 ], "density": 0.2 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_32", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "........................", + "........................", + "....|-HHHH-HH+H-HHH-|-HH", + "....|yQQQ...AA.A.A..|V66", + "....HQ....JJJJJJJ?J.|V66", + "....HQ...AJ...A.....|V6V", + "....+....AJ..~jll.n~|---", + "....+....AJ..~---=--|IIS", + "....HY...AJ..~|IB.=.=.B.", + "....|y...AJ..~|I.S|.|---", + "....--------------|.=...", + "F...|.MMMyMMM.|IIS|.|*.U", + "F...H.........|.B.|.|*.U", + "F...H..MM..%%%|...|.|..U", + "y...+..MM..?.A|-=-|.|*..", + "F...+..MM..%..=..z|.|***", + "F...H..MM..%..|z.z|.----", + "F...H......%%.|z..=.....", + "....|.MMMy....|zzz|.....", + "Y...--------------|-=---", + "....|TTT|^|^|^|^|ppp.S..", + "F..||^^^|!|!|!|!|pA...B.", + "F..Hd^^^^^^^^^^^|p..pppZ", + "F..Hd^^^@@^^^@@^|-=-HHH-" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "V": "t_carpet_red", "!": "t_floor", "T": "t_floor", "d": "t_floor", "@": "t_floor" }, + "furniture": { "%": "f_counter", "*": "f_crate_c", "!": "f_beaded_door", "p": "f_desk" }, + "items": { + "J": { "item": "coffee_counter", "chance": 20 }, + "j": { "item": "coffee_dishes", "chance": 20 }, + "l": { "item": "coffee_freezer", "chance": 20, "repeat": [ 2, 4 ] }, + "n": { "item": "coffee_dishes", "chance": 30, "repeat": [ 2, 4 ] }, + "~": [ + { "item": "coffee_condiments", "chance": 20, "repeat": [ 2, 4 ] }, + { "item": "coffee_prep", "chance": 20, "repeat": [ 2, 4 ] } + ], + "Y": { "item": "coffee_trash", "chance": 30, "repeat": [ 2, 4 ] }, + "Q": { "item": "coffee_display_2", "chance": 30, "repeat": [ 2, 4 ] }, + "S": { "item": "office_paper", "chance": 20 }, + "I": { "item": "office", "chance": 20 }, + "z": { "item": "glasses", "chance": 20 }, + "M": { "item": "glasses", "chance": 20 }, + "%": { "item": "office", "chance": 20 }, + "U": { "item": "cleaning", "chance": 20 }, + "p": { "item": "leather_shop_repair", "chance": 40, "repeat": [ 2, 4 ] }, + "T": { "item": "leather_shop", "chance": 30, "repeat": [ 2, 4 ] }, + "V": { "item": "bags", "chance": 30, "repeat": [ 2, 4 ] }, + "*": { "item": "bags", "chance": 30, "repeat": [ 2, 4 ] }, + "d": [ + { "item": "leather_shop", "chance": 100 }, + { "item": "pants", "chance": 50 }, + { "item": "shirts", "chance": 50 }, + { "item": "leather_shop_accessories", "chance": 100 } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.1 } ] + } + }, { "type": "mapgen", "method": "json", @@ -2365,10 +3618,70 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_33_roof", - "weight": 200, + "om_terrain": "mall_b_33", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_floor", + "rows": [ + ".....................--^", + ".........HHH.........H^^", + "H-HH++HH-HdH-|.......|--", + "6666666666666|.......|..", + "66%%%6%%%6666HH......H..", + "6666666666666dH......H.]", + "|V66666%6%6%6HH......|..", + "|V66666%6%6%6|.......H.]", + "=666J66%6%6%6H.......H..", + "|6A6?66666666+.......+..", + "|666J66666666+.......H..", + "|666J66%6%6%6H.......H.0", + "|6A6J66%6%6%6|.......|..", + "|666?66%6%6%6HH......H.0", + "=666J66666666dH......H..", + "|V66666VVV666HH......|FF", + "-------------|.......|--", + ".............=..........", + ".............=..........", + "--=----------|.......|--", + "|^^S|y^^^^^^^|.......|.|", + "|^B^=^^K^K^K^H.......|-|", + "|III|y^K^K^K^H.........H", + "|----^^K^K^K^H.........+" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "V": "t_carpet_red", + "J": "t_carpet_red", + "d": "t_carpet_red", + "A": "t_carpet_red", + "%": "t_carpet_red", + "0": "t_linoleum_gray", + "]": "t_linoleum_gray", + "F": "t_linoleum_gray" + }, + "furniture": { "%": "f_counter", "*": "f_crate_c", "!": "f_beaded_door", "p": "f_desk", "]": "f_ergometer", "0": "f_exercise" }, + "items": { + "K": { "item": "pottery", "chance": 30, "repeat": [ 2, 4 ] }, + "J": { "item": "office", "chance": 20 }, + "%": { "item": "bags", "chance": 30, "repeat": [ 1, 2 ] }, + "V": { "item": "bags", "chance": 30, "repeat": [ 2, 4 ] }, + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 100 }, + { "item": "bags", "chance": 100 } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_33_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", "rows": [ "........................", "........................", @@ -2377,10 +3690,10 @@ "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", + "..................o.....", + "..................o.....", + "..................o.....", + "..................o.....", "........................", "........................", "........................", @@ -2395,23 +3708,8 @@ "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ], - "place_nested": [ - { - "chunks": [ - [ "null", 20 ], - [ "roof_2x2_utilities_b", 15 ], - [ "roof_2x2_utilities_c", 5 ], - [ "roof_2x2_utilities_d", 40 ], - [ "roof_2x2_utilities", 50 ], - [ "roof_3x3_wine", 30 ], - [ "roof_4x4_utility_1", 30 ] - ], - "x": [ 3, 22 ], - "y": [ 3, 22 ] - } - ] + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, + "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, { @@ -2473,6 +3771,65 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_34", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "^^^^^^^^^^^^^^^^^^^^^^^^", + "^^^^C0C^^^^^C0C^^^^^C0C^", + "------------------------", + "..uuu...................", + "........------+------=--", + ".].].*..|t|FFY.PPP|@...S", + "........|.|F.....P|@...a", + ".].].*..=.|FF..PPP|P..BI", + "........|.|---+---|P...I", + ".....*..|j|%.=.=.%|W...S", + "........----------------", + ".!.!.*..|RRR7RRR|j.Y.=.t", + "........|.7A777.|J...---", + ".!.!.*..|.JJ?JJ.|j...=.t", + "........|.77777.|J...---", + ".FFF.FF.|y.....B|j......", + "-----------...-----=----", + ".........................", + "........................", + "-HH--HH------------=----", + "^^)^^^)^^^^^|IIS|j......", + "^77777777J7^|B..|J...---", + "^7K7K7K77?A^|-=-|j...=.t", + "^7K7K7K77J7^=..z|J...---" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "C": "t_floor", "0": "t_floor", ")": "t_floor", "A": "t_carpet_green", "J": "t_carpet_green", "K": "t_carpet_green" }, + "furniture": { + "*": "f_treadmill", + "]": "f_ergometer", + "!": "f_exercise", + "%": "f_shower", + "0": [ "f_indoor_plant_y", "f_indoor_plant" ] + }, + "items": { + "R": [ + { "item": "magazines", "chance": 40, "repeat": [ 2, 4 ] }, + { "item": "oa_discarded_news", "chance": 40, "repeat": [ 2, 4 ] } + ], + "Y": { "item": "trash", "chance": 50 }, + "F": { "item": "gym", "chance": 10 }, + "u": { "item": "default_vending_machine", "chance": 10 }, + "I": { "item": "office", "chance": 20 }, + "P": { "item": "gym", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + ")": { "item": "keg_wine_intact", "chance": 100 }, + "z": { "item": "crate_wine", "chance": 30 }, + "K": [ { "item": "table_wine", "chance": 30 }, { "item": "wines_worthy", "chance": 30 } ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -2483,15 +3840,15 @@ "rows": [ "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + ".................#######", + ".................#______", + ".................1______", + ".................1______", + ".................1______", + ".................1______", + ".................1______", + "................3#3_____", + ".................####=##", "........................", "........................", "........................", @@ -2506,8 +3863,49 @@ "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "terrain": { + ".": "t_flat_roof", + "#": "t_wall_w", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control", + "=": "t_door_c", + "_": "t_concrete" + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_34", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " 2222222", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " |......", + " -------", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] } }, { @@ -2552,6 +3950,51 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_35", + "object": { + "fill_ter": "t_floor", + "rows": [ + "^^^^^^|^^z| ", + "^^C^^y|z^^| ", + "|-----|-=-| ", + "|EEEEE|^^^| ", + "|EEEEE+^^^| ", + "|EEEEE+^^^| ", + "|EEEEE+^^^| ", + "|EEEEE|^^^| ", + "|-----|^^^| ", + "|<^^^^=^^^| ", + "------|^^^|| ", + "|t.=.Y|^^^yH ", + "|---..|^^^dH ", + "|t.=..|^^^yH ", + "|---..|^^^|| ", + ".....Y|^^^| ", + "|-----|^^^| ", + "=^^^^^^^^^| ", + "=^^^^^^^^^| ", + "|-----|^^^| ", + ".....Y|^^^| ", + "|---..|^^^| ", + "|t.=..|^^^| ", + "|---..|^^^| " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "Y": "t_linoleum_gray", "t": "t_linoleum_gray", "<": "t_stairs_up" }, + "items": { + "Y": { "item": "trash", "chance": 30, "repeat": [ 2, 4 ] }, + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 10 } + ] + } + } + }, { "type": "mapgen", "method": "json", @@ -2562,15 +4005,15 @@ "rows": [ "..........3 ", "..........3 ", - "..........3 ", - "..........3 ", - "..........3 ", - "..........3 ", - "..........3 ", - "..........3 ", - "..........3 ", - "..........3 ", - "..........33 ", + "|||||||...3 ", + "|EEEEE|...3 ", + "=EEEEE|...3 ", + "=EEEEE|...3 ", + "=EEEEE|...3 ", + "|EEEEE|...3 ", + "|||||||...3 ", + "_>|.......3 ", + "|||.......33 ", "...........3 ", "...........3 ", "...........3 ", @@ -2585,10 +4028,53 @@ "..........3 ", "..........3 " ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "3": "t_gutter_east" }, + "terrain": { + ".": "t_flat_roof", + " ": "t_open_air", + "3": "t_gutter_east", + ">": "t_stairs_down", + "|": "t_wall_w", + "E": "t_elevator", + "_": "t_concrete" + }, "place_items": [ { "item": "roof_trash", "x": [ 0, 8 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_35", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + "2222223 ", + "......3 ", + "......3 ", + "......3 ", + "......3 ", + "......3 ", + "..3---3 ", + "..3 ", + "--- ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] + } + }, { "type": "mapgen", "method": "json", @@ -2736,6 +4222,70 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_38", + "object": { + "fill_ter": "t_floor", + "rows": [ + " |J^^^^^^^^^^J", + " |J^^^%%^^%%^^", + " |-|JA^^%%^^%%^^", + " |JJJ^^^%%^^%%^^", + " HJA^^^^^^^^^^^^", + " |^^^^^^^^^^^^^^", + " H^^%%^^%%^^%%^^", + " H^^%%^^%%^^%%^^", + " H^^%%^^%%^^%%^^", + " |^^^^^^^^^^^^AJ", + " H^^^^^^^AAAAAAJ", + " |^^^^^^JJJJJJJJ", + " |-+-+----------", + " |.....|9wII|bbb", + " HF....=999B|b6b", + " HF....|SS99|666", + " |y...-|--=--999", + " HF...Hd99999999", + " HF...Hd999!@@!9", + " |....-|99999999", + " |-|...|V99MMMM9", + " |...|V9999999", + " |...|V99MMMM9", + " |...|V9999999", + " |...|99999999" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "F": "t_linoleum_gray", + "y": "t_linoleum_gray", + "b": "t_carpet_red", + "M": "t_carpet_yellow", + "V": "t_carpet_yellow", + "I": "t_carpet_yellow", + "B": "t_carpet_yellow", + "S": "t_carpet_yellow", + "@": "t_carpet_yellow", + "!": "t_carpet_yellow", + "w": "t_carpet_yellow", + "d": "t_carpet_yellow" + }, + "furniture": { "%": "f_pool_table", "!": [ "f_indoor_plant_y", "f_indoor_plant" ] }, + "items": { + "%": { "item": "pool_table", "chance": 20 }, + "J": [ + { "item": "restaur_table", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "bar_alcohol", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "restaur_sink", "chance": 20, "repeat": [ 1, 2 ] } + ], + "w": { "item": "mansion_safe", "chance": 20 }, + "S": { "item": "office_paper", "chance": 20 }, + "d": { "item": "fancyfurs", "chance": 20 }, + "V": { "item": "fancyfurs", "chance": 20 }, + "M": { "item": "fancyfurs", "chance": 20 } + } + } + }, { "type": "mapgen", "method": "json", @@ -2832,6 +4382,71 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_39", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "2----|.|z...zz|..Z|W..|.", + "2J..n|.|--=-----=-|-=---", + "2l..j|.|VV..VVV..V|.....", + "2l..J|.|V.888A88.V|Q....", + "2Y..J|.|..8%%%?%..|Q..*?", + "=...i|.|V.888888.V|Q....", + "2l..i|.|V.888888.V|Q..Q.", + "2l..J|.|V.8KKKK8.V|Q..Q.", + "2--=-|.|V.888888.V|Q..Q.", + "2U..U|.|V.8KKKK8.V|Q..Q.", + "2U...=.|..888888..|Q....", + "2UUUU|.|y........y|.....", + "-----|=--HH-++-HH---HH-+", + "|@99b|..................", + "|@99b|..................", + "--=--|H|................", + "999999dH......yFFFyFFF..", + "999999dH....y...........", + "!@@!99dH....F...........", + "99999|H|....F...........", + "MMMM99H.....F...|-HH-HH-", + "999999+.....y...|.B0BB0B", + "MMMM99H.....F...H.B0BB0B", + "99999|H|....F...H......." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "b": "t_carpet_yellow", + "M": "t_carpet_yellow", + "@": "t_carpet_yellow", + "!": "t_carpet_yellow", + "d": "t_carpet_yellow", + "K": "t_carpet_purple", + "%": "t_carpet_purple", + "A": "t_carpet_purple" + }, + "furniture": { "!": [ "f_indoor_plant_y", "f_indoor_plant" ], "%": "f_counter", "*": "f_counter", "0": "f_table" }, + "items": { + "n": { "item": "restaur_sink", "chance": 20, "repeat": [ 3, 5 ] }, + "l": { "item": "restaur_fridge", "chance": 20, "repeat": [ 3, 5 ] }, + "U": { "item": "restaur_kitchen", "chance": 20, "repeat": [ 3, 5 ] }, + "i": { "item": "oven", "chance": 20 }, + "j": { "item": "restaur_sink", "chance": 20 }, + "Y": { "item": "trash", "chance": 20 }, + "J": [ + { "item": "restaur_table", "chance": 30 }, + { "item": "restaur_kitchen", "chance": 30 }, + { "item": "restaur_sink", "chance": 20 } + ], + "d": { "item": "fancyfurs", "chance": 20 }, + "M": { "item": "fancyfurs", "chance": 20 }, + "V": { "item": "candy_shop", "chance": 20, "repeat": [ 3, 5 ] }, + "K": { "item": "candy_shop", "chance": 20, "repeat": [ 3, 5 ] }, + "Q": { "item": "softdrugs", "chance": 20, "repeat": [ 3, 5 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -2923,6 +4538,76 @@ "place_vehicles": [ { "vehicle": "golf_cart", "x": 12, "y": 12, "chance": 35, "rotation": 0 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_40", + "object": { + "fill_ter": "t_floor", + "rows": [ + "...|R^7***D77D^|...y# #", + "-=-|R^7*']77%7^H...F# #", + "...|R^7***L7D7^H...F# #", + "J.Q|R^77777777^H...F# #", + "J.Q|^!d^^^^^d!^|....# #", + "..Q|-HH-H+H-HH-|....####", + "Q.Q|....................", + "Q.Q|....................", + "Q.Q|....................", + "Q.Q|....########........", + "..Q|....# #........", + "..Y|....# #........", + "-H-|....# #........", + "........# #...#####", + "........# #...# ", + "........# #...# ", + "........########...# ", + "...................# ", + "...................# ", + "...................#####", + "HH-|....................", + "...|-H++H-H++H-|y.......", + "...............|-|Y.....", + ".................|Y...FK" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "*": "t_carpet_green", + "'": "t_carpet_green", + "L": "t_carpet_green", + "D": "t_carpet_green", + "]": "t_carpet_green", + "%": "t_carpet_green", + "Q": "t_linoleum_gray", + "Y": "t_linoleum_gray", + "J": "t_linoleum_gray", + "y": "t_linoleum_gray", + "F": "t_linoleum_gray", + "K": "t_linoleum_gray" + }, + "furniture": { + "*": "f_canvas_wall", + "'": "f_groundsheet", + "]": "f_canvas_door", + "D": "f_camp_chair", + "%": "f_brazier", + "L": "f_tourist_table", + "!": [ "f_indoor_plant_y", "f_indoor_plant" ] + }, + "items": { + "Q": { "item": "softdrugs", "chance": 30, "repeat": [ 2, 3 ] }, + "R": { "item": "book_survival", "chance": 30, "repeat": [ 2, 3 ] }, + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 100 }, + { "item": "shoestore_shoes", "chance": 100 } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -2931,32 +4616,32 @@ "object": { "fill_ter": "t_flat_roof", "rows": [ + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", + "....................oooo", "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + "........oooooooo........", + "........oooooooo........", + "........oooooooo........", + "........oooooooo........", + "........oooooooo...ooooo", + "........oooooooo...ooooo", + "........oooooooo...ooooo", + "........oooooooo...ooooo", + "...................ooooo", + "...................ooooo", + "...................ooooo", "........................", "........................", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -3012,16 +4697,61 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_41_roof", - "weight": 200, + "om_terrain": "mall_b_41", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_floor", "rows": [ + "Y..--^^^^^^^^^^^^^^^^^^^", + "F...|^^^KK^^KK^^J^^A^^^^", + "F...H^^^KK^^KK^^JJJJJJ^T", + "F...+^^^^^^^^^^^^^^^^^^T", + "....H^^^KK^^KK^^KK^^KK^T", + "....|^^^KK^^KK^^KK^^KK^y", + "...HH^^^^^^^^^^^^^^^^^^T", + "...Hd^^^^^d^C^d^C^d^^^^T", + "...HH^^^^^^^^^^^^^^^^^^T", + "....|yMMM^TT^^^^^TT^MMMy", + "....|-HHH----H+H----HHH-", "........................", "........................", + "########################", + " ", + " ", + " ", + " ", + " ", + "########################", "........................", "........................", "........................", + "F.F%F.F%F.F%F.F%F.F%F.F%" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "F": "t_linoleum_gray", "Y": "t_linoleum_gray", "%": "t_linoleum_gray" }, + "furniture": { "%": "f_table" }, + "items": { + "S": { "item": "office_paper", "chance": 20 }, + "J": { "item": "office", "chance": 20 }, + "M": { "item": "leather_shop_accessories", "chance": 30 }, + "K": { "item": "leather_shop", "chance": 40 }, + "T": { "item": "leather_shop", "chance": 30 }, + "d": [ + { "item": "leather_shop", "chance": 100 }, + { "item": "pants", "chance": 40 }, + { "item": "shirts", "chance": 40 }, + { "item": "leather_shop_accessories", "chance": 100 } + ] + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_41_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ "........................", "........................", "........................", @@ -3035,14 +4765,19 @@ "........................", "........................", "........................", - "........................", - "........................", + "oooooooooooooooooooooooo", + "oooooooooooooooooooooooo", + "oooooooooooooooooooooooo", + "oooooooooooooooooooooooo", + "oooooooooooooooooooooooo", + "oooooooooooooooooooooooo", + "oooooooooooooooooooooooo", "........................", "........................", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -3098,6 +4833,58 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 0, 23 ], "y": [ 0, 22 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_42", + "object": { + "fill_ter": "t_floor", + "rows": [ + "|^^^^^^^^^^^^|.........+", + "|^^^^^^^^^^^^|.........H", + "|^I^C^^K^K^K^+.......|-|", + "|BI^^^^K^K^K^+.......|.|", + "|^I^C^^K^K^K^|.......|-|", + "|^^^^^^^^^^^^|.......|..", + "|^^^^^^^^^^^^H.......H..", + "|^KKK^KKK^^^^H.......H..", + "|^^^^^^^^^^^KH.......|..", + "|^^^^^^^^KKKK|.......+..", + "--|H++H|-HHH-|.......+..", + ".....................|..", + ".....................H..", + "#####................H..", + " #................|..", + " #1...............|-H", + " #1..................", + " #1..................", + " #...................", + "#####...................", + "........................", + "........HHHHHH-++-HHHHH.", + "......HHHY...........YHH", + "F.....H................y" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "V": "t_carpet_red", "y": "t_linoleum_gray", "Y": "t_linoleum_gray", "F": "t_linoleum_gray" }, + "sealed_item": { "1": { "item": { "item": "seed_rose" }, "furniture": "f_planter_harvest" } }, + "furniture": { "%": "f_counter", "*": "f_crate_c", "!": "f_beaded_door", "p": "f_desk" }, + "items": { + "1": { "item": "ga_items_1", "chance": 100 }, + "K": { "item": "pottery", "chance": 30, "repeat": [ 2, 4 ] }, + "I": { "item": "office", "chance": 20 }, + "Y": { "item": "office", "chance": 20 }, + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 100 }, + { "item": "bags", "chance": 100 } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -3119,19 +4906,20 @@ "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + "ooooo...................", + "ooooo...................", + "ooooo...................", + "ooooo...................", + "ooooo...................", + "ooooo...................", + "ooooo...................", "........................", "........................", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, + "sealed_item": { "1": { "item": { "item": "seed_lettuce" }, "furniture": "f_planter_harvest" } }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -3191,6 +4979,58 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_43", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "^7K7K7K77J7)|z.z|j.Y.=.t", + "^7K7K7K77J7)|P.z|-------", + "^77777777J7^|...=^^^^^^^", + "^^^^))))^^^^|zzz|^^^^^^^", + "------------------------", + "..QQQQ.QQQQ.QQQQ.......|", + "...................%..Q|", + "..QQQQ.QQQQ.QQQQ...?.AQ|", + "...................%..Q|", + ".......................=", + "..!!!!.!!!!.!!!!...%..Y|", + "...................%.AQ|", + "..!!!!.!!!!.!!!!...?..Q|", + "...................%..Q|", + "....y...y..............|", + "-HHH-H+H-HHH------------", + ".............|...VVV..VV", + ".............HM.99999999", + ".............HM.9*9*99*9", + ".............HM.9*9*99*9", + ".............|..9*9*99*9", + "...........|-|..99999999", + "H..........|y...99999999", + "H..........|..9999999999" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "K": "t_carpet_green", "J": "t_carpet_green", ")": "t_floor", "*": "t_carpet_yellow" }, + "furniture": { "%": "f_counter", "!": "f_table", "*": "f_table" }, + "items": { + "Y": { "item": "trash", "chance": 50 }, + "I": { "item": "office", "chance": 20 }, + "P": { "item": "cleaning", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + ")": { "item": "keg_wine_intact", "chance": 100 }, + "z": { "item": "crate_wine", "chance": 60, "repeat": [ 1, 3 ] }, + "K": [ { "item": "table_wine", "chance": 30 }, { "item": "wines_worthy", "chance": 30 } ], + "!": { "item": "sports", "chance": 20, "repeat": [ 1, 3 ] }, + "Q": { "item": "sports", "chance": 20, "repeat": [ 1, 3 ] }, + "V": { "item": "mussto_stringinst", "chance": 20, "repeat": [ 1, 3 ] }, + "*": { "item": "musicstore_showpiece", "chance": 20, "repeat": [ 1, 3 ] }, + "M": { "item": "mussto_windinst", "chance": 20, "repeat": [ 1, 3 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 13, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -3284,6 +5124,59 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_44", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "|t.=.Y|^^^| ", + "------|^^^| ", + "^^^^^^^^^^| ", + "^^^^^^^^^^| ", + "------|^^^| ", + "S.YIIS|^^^| ", + "y...B.|^^^| ", + "---=--||^^|| ", + "UUU..zz|^^d| ", + ".......=^^d| ", + "U...zz.|^^d| ", + "U.Yz.zz|^^|| ", + "---=---|^^| ", + "P.....P|^^| ", + "P.FFF.P|^^| ", + "-------|^^| ", + "V..|YII|^^| ", + "99.|..B|^^| ", + "K9V|S..|^^| ", + "K9V|-=-|^^| ", + "K9.|Q.Q|^^| ", + "99.=...=^^| ", + "99.|Q..|^^| ", + "99.|.PP|^^| " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "d": "t_floor", "K": "t_carpet_yellow" }, + "items": { + "Y": { "item": "trash", "chance": 30, "repeat": [ 2, 4 ] }, + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 10 } + ], + "I": { "item": "office", "chance": 20 }, + "P": { "item": "jackets", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + "z": { "item": "sports", "chance": 60, "repeat": [ 1, 3 ] }, + "U": { "item": "sports", "chance": 20, "repeat": [ 1, 3 ] }, + "V": { "item": "mussto_stringinst", "chance": 20, "repeat": [ 1, 3 ] }, + "K": { "item": "musicstore_showpiece", "chance": 20, "repeat": [ 1, 3 ] }, + "Q": { "item": "musicstore_showpiece", "chance": 20, "repeat": [ 1, 3 ] } + } + } + }, { "type": "mapgen", "method": "json", @@ -3419,8 +5312,8 @@ "____ss...Vc| | + rr ", "____ss...Vc| |-| rr rr ", "____ss...|:| | rr ", - "___sss.|-| | ", - "ssssss.|.|--::-|--|cccc|", + "___sss.|-| | | ", + "ssssss.|< -::-|--|cccc|", "...sss.|-|2222yV22|HHHH|", "###.sssssZ21112Z22222222", "T###pssssZ21112Z21111111", @@ -3429,8 +5322,8 @@ "T###pssssZ21112Z21111111", "###.sssssZ21112Z21111111", "...sss.|-|2222yV22222222", - "ssssss.|.|--::-|HHH|-HHH", - "___sss.|-| :ccc|r hn", + "ssssss.|< -::-|HHH|-HHH", + "___sss.|-| | :ccc|r hn", "____ss...|:| |---|r ", "____ss...Vc| |rrrrr r", "____ss...Vc| ||r ", @@ -3461,6 +5354,64 @@ "place_vehicles": [ { "vehicle": "hippie_van", "x": 1, "y": 19, "chance": 35, "rotation": 0 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_47", + "object": { + "fill_ter": "t_floor", + "rows": [ + " |...|V99MMMM9", + " |-|...|V9999999", + " HdH...H999MMMM9", + " HdH...+99999999", + " HdH...H9999C999", + " |+|...|V99IIII9", + " |H|.|...|VV999999", + " H>..--+-|--|9999|", + " |H|.......Y|H++H|", + " H..............", + " H..............", + " H..............", + " H..............", + " H..............", + " H..............", + " |H|.....H........", + " H>..--=-|-HH--HH+", + " |H|.|...|^%%^^^^^", + " |+|...|^^^^^888", + " H.|...|TTTT^888", + " H.|..||----^8J8", + " H.|..|zzzz|^8?8", + " |-|..=....=^AJ8", + " |..|zz.z|^8J8" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "I": "t_carpet_yellow", + "M": "t_carpet_yellow", + "C": "t_carpet_yellow", + "!": "t_carpet_yellow", + "d": "t_carpet_yellow", + "A": "t_carpet_purple", + "J": "t_carpet_purple" + }, + "furniture": { "%": "f_mannequin", "0": "f_glass_cabinet", "!": [ "f_indoor_plant_y", "f_indoor_plant" ] }, + "items": { + "Y": { "item": "trash", "chance": 20 }, + "d": { "item": "fancyfurs", "chance": 20 }, + "V": { "item": "fancyfurs", "chance": 20 }, + "M": { "item": "fancyfurs", "chance": 20 }, + "3": { "item": "costume_accessories", "chance": 30 }, + "T": { "item": "costume_clothes", "chance": 30, "repeat": [ 1, 2 ] }, + "%": [ { "item": "costume_clothes", "chance": 100 }, { "item": "costume_accessories", "chance": 100 } ], + "z": [ + { "item": "costume_clothes", "chance": 30, "repeat": [ 1, 2 ] }, + { "item": "costume_accessories", "chance": 30, "repeat": [ 1, 2 ] } + ] + } + } + }, { "type": "mapgen", "method": "json", @@ -3475,18 +5426,18 @@ " |..............", " |..............", " |..............", + " |2|..............", + " |................", + " |-|..............", " |..............", " |..............", " |..............", " |..............", " |..............", " |..............", - " |..............", - " |..............", - " |..............", - " |..............", - " |..............", - " |..............", + " |2|..............", + " |................", + " |-|..............", " |..............", " |..............", " |..............", @@ -3553,55 +5504,146 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_48", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "MMMM99dH....F...|-------", + "999999dH........|QQQQY..", + "MMMM99dH........|Q......", + "99999|H|........|QQllllQ", + "C9!9V|..........|-------", + "99C9V|...####...=.......", + "V9d9V|...# #...|-|--|..", + "-HHH-|...# #...|EEEE|--", + ".........# #...HEEEE|66", + ".........# #...|H++H|66", + ".........# #........|HH", + ".........####........+66", + ".....................+66", + ".....................|HH", + "................|H++H|66", + "................HEEEE|66", + "HH-HHH-|........|EEEE||-", + "^^^333y|......|------|..", + "8888883H..FF..Hy^^^^^|..", + "8888883H..FF..H^^BKB^|--", + "8000883H..FF..H^^BKB^^^y", + "800088y|......|y^^^^^^^%", + "888888^H......H^^BKB^^^%", + "888888^+......+^^^^^^^^^" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "V": "t_carpet_yellow", + "M": "t_carpet_yellow", + "C": "t_carpet_yellow", + "!": "t_carpet_yellow", + "d": "t_carpet_yellow", + "%": "t_floor", + "y": "t_floor", + "K": "t_floor", + "B": "t_floor", + "0": "t_carpet_purple", + "3": "t_floor" + }, + "furniture": { "!": [ "f_indoor_plant_y", "f_indoor_plant" ], "%": "f_glass_cabinet", "0": "f_glass_cabinet", "3": "f_displaycase" }, + "items": { + "Y": { "item": "trash", "chance": 20 }, + "%": { "item": "baked_goods", "chance": 20, "repeat": [ 2, 4 ] }, + "K": { "item": "baked_goods", "chance": 20 }, + "d": { "item": "fancyfurs", "chance": 20 }, + "V": { "item": "fancyfurs", "chance": 20 }, + "M": { "item": "fancyfurs", "chance": 20 }, + "J": { "item": "fast_table", "chance": 10, "repeat": [ 2, 4 ] }, + "l": { "item": "fast_fridge", "chance": 20, "repeat": [ 2, 4 ] }, + "Q": { "item": "fast_kitchen", "chance": 20, "repeat": [ 2, 4 ] }, + "3": { "item": "costume_accessories", "chance": 30 }, + "0": { "item": "costume_weapons", "chance": 30 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", "om_terrain": "mall_a_48_roof", "weight": 200, "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_concrete", "rows": [ "........................", "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + "................|-------", + ".........oooo...|_______", + ".........oooo...|-----__", + ".........oooo...|EEEE|__", + ".........oooo...|EEEE|z_", + ".........oooo...|++++|__", + ".........oooo...|_______", + ".........oooo...|___z___", + "................|___zz__", + "................|_______", + "................|++++|__", + "................|EEEE|__", + "................|EEEE|__", + "................|-----__", + "................|___z___", + "................|-------", "........................", "........................", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ], - "place_nested": [ - { - "chunks": [ - [ "null", 20 ], - [ "roof_2x2_utilities_b", 15 ], - [ "roof_2x2_utilities_c", 5 ], - [ "roof_2x2_utilities_d", 40 ], - [ "roof_2x2_utilities", 50 ], - [ "roof_4x4_utility_1", 30 ] - ], - "x": [ 3, 15 ], - "y": [ 3, 7 ] - } - ] + "palettes": [ "mall_palette_2" ], + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, + "items": { + "z": [ + { "item": "winter", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "camping", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "alcohol", "chance": 20, "repeat": [ 1, 2 ] } + ] + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_48", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " |2222222", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |.......", + " |-------", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] } }, { @@ -3620,14 +5662,14 @@ " |-|", " |-------| |", "--:----| |3XuuuX3| ", - "2222222| |3333333| ", - "2222222| |---:---|-----", + "222222<| |3333333| ", + "222222<| |---:---|-----", "H222HHH| |Q333333|B33g3", "222222y| |3d3g3d3|B3ddd", "222222y| |3ddddd3|33333", "H222HHH| |3333333|HHH0H", - "2222222| |B33g333:33333", - "2222222| |B333333:33333", + "222222<| |B33g333:33333", + "222222<| |B333333:33333", "-------| |-------|-----", " ", " ", @@ -3660,18 +5702,120 @@ "place_vehicles": [ { "vehicle": "tricycle", "x": 20, "y": 23, "chance": 25, "status": 0 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_49", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "?JJJ?JJJ?JJJ?JJ.Y|-|..FK", + ".................|P|....", + "QQllJJJiiJJjnJJ..=.|..FK", + "---------------=-|-|..FK", + "-..................|-|..", + ".....................|-|", + "..........|-------|....|", + "--=----|..|t..|..t|.....", + "666666>|..|--.|.--|.....", + "666666>|..|j..|..j|-----", + "H666HHH|..|-=-|-=-|.uu.|", + "6666666|..|............|", + "6666666|..|..FFF..FFF..|", + "H666HHH|..|..KKK..KKK..=", + "666666>|..|..FFF..FFF..|", + "666666>|..|Y...........|", + "-------|..|-------------", + ".......................=", + ".......................=", + "---=----------------=--|", + "|U...U|y.....mmm.y|P..z|", + "|U.UUU|m.V.V.....Y|P.zz|", + "|U..AI|m.V.V...M..|z..z|", + "---=--|m.V.V...M..|-=--|" + ], + "palettes": [ "mall_palette_2" ], + "items": { + "Y": { "item": "trash_cart", "chance": 20 }, + "J": { "item": "fast_table", "chance": 20, "repeat": [ 2, 4 ] }, + "Q": { "item": "fast_kitchen", "chance": 20, "repeat": [ 2, 4 ] }, + "l": { "item": "fast_fridge", "chance": 20, "repeat": [ 2, 4 ] }, + "P": { "item": "cleaning", "chance": 20, "repeat": [ 2, 4 ] }, + "u": { "item": "default_vending_machine", "chance": 60, "repeat": [ 2, 4 ] }, + "M": { "item": "butcher_meat", "chance": 20, "repeat": [ 2, 4 ] }, + "V": { "item": "butcher_meat", "chance": 20, "repeat": [ 2, 4 ] }, + "z": { "item": "butcher_meat", "chance": 20, "repeat": [ 2, 4 ] }, + "m": { "item": "butcher_raw_meat", "chance": 20, "repeat": [ 2, 4 ] }, + "U": { "item": "groce_ingredient", "chance": 20, "repeat": [ 2, 4 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", "om_terrain": "mall_a_49_roof", "weight": 200, "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_concrete", "rows": [ "........................", "........................", "........................", + "......3.................", + "-11111--=--.............", + "____zz3___|.............", + "__zzz_____|.............", + "__________|-------------", + "________________________", + "_z_____________zzzzz____", + "____________z__zz_z_____", + "____z_______z__zzz______", + "________________________", + "____________________z___", + "____z___________________", + "__________________z_z___", + "__________|-------------", + "___z______|............4", + "___zz_3___|............0", + "-11111--=-|............4", + "......3...4............4", + "..........44444000044444", "........................", + "........................" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + ".": "t_flat_roof", + "4": "t_chainfence", + "0": "t_chaingate_c", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control" + }, + "items": { + "z": [ + { "item": "cannedfood", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "consumer_electronics", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "sports", "chance": 20, "repeat": [ 1, 2 ] } + ] + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_49", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + "22222222223 ", + "..........3 ", + "..........3 ", + "..........3-------------", "........................", "........................", "........................", @@ -3680,21 +5824,16 @@ "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................" + "..........3-------------", + "..........3 ", + "..........3 ", + "----------3 ", + " ", + " ", + " ", + " " ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "palettes": [ "roof_palette" ] } }, { @@ -3714,8 +5853,8 @@ ":|22222222222222222222|:", " |--------------------| ", " ", - "--|--------::|----|-++-|", - "3B|QgggJJJ333|EEEE|EEEE|", + "--|------::|-|----|-++-|", + "3B|QgggJJ33|<|EEEE|EEEE|", "3B|g333333333|EEEE|EEEE|", "33|g3nn333333|-55-|----|", "HH|33nn33333333333333335", @@ -3731,7 +5870,7 @@ " r|333V3JJJJ3333333333" ], "palettes": [ "mall_palette" ], - "terrain": { "B": "t_carpet_red", "d": "t_carpet_red", "n": "t_carpet_red" }, + "terrain": { "B": "t_carpet_red", "d": "t_carpet_red", "n": "t_carpet_red", "<": "t_stairs_up" }, "furniture": { "B": "f_bookcase", "d": "f_desk", "n": "f_table" }, "place_items": [ { "item": "museum_security", "x": [ 10, 13 ], "y": [ 23, 23 ], "chance": 60 }, @@ -3750,13 +5889,61 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_50_roof", - "weight": 200, + "om_terrain": "mall_b_50", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_linoleum_gray", "rows": [ + "F.FKF.FKF.FKF.FKF.FKF.FK", + "........................", + "F.FKF.FKF.FKF.FKF.FKF.FK", + "F.FKF.FKF.FKF.FKF.FKF.FK", "........................", + "=|y....uu..YY..uu....y|=", + ".|--------------------|.", "........................", + "---------==|-|----|-==-|", + "-66666666666>|EEEE|EEEE|", + "6@@@@@666666<|EEEE|EEEE|", + "6@66666666666|-==-|----|", + "6@6666666666C|66B6|6B66|", + "6@66C66666666|6III|6III|", + "666666666666C|666S|S666|", + "6666666666666-H+H---H+H|", + "666666666666666666666666", + "66C6C666666666666B666666", + "-H-+-H-|66666666III66666", + "666B666|6666666666666666", + "6BIIIB6H666BI6I66BI6I666", + "6BIIIB6H6666I6IB66I6IB6B", + "6BIIIB6H6666666666666666", + "6BIIIB6|666666I666I6IB6B" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + ">": "t_stairs_down", + "E": "t_elevator", + "<": "t_stairs_up", + "B": "t_carpet_red", + "I": "t_carpet_red", + "S": "t_carpet_red", + "C": "t_carpet_red", + "@": "t_carpet_red" + }, + "items": { + "u": { "item": "default_vending_machine", "chance": 50, "repeat": [ 2, 8 ] }, + "K": { "item": "pizza_table", "chance": 20 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_50_roof", + "weight": 200, + "object": { + "fill_ter": "t_concrete", + "rows": [ "........................", "........................", "........................", @@ -3764,12 +5951,51 @@ "........................", "........................", "........................", + "----------==------------", + "xxx__________|----|-==-|", + "__________z|_|EEEE|EEEE|", + "___________|>|EEEE|EEEE|", + "_____________|-==-|----|", + "________________________", + "________________________", + "___x______________z_z___", + "__xxxx__________zzz_z___", + "----------==------------", "........................", "........................", "........................", "........................", "........................", "........................", + "........................" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + ".": "t_flat_roof", + " ": "t_open_air", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control", + "4": "t_chainfence", + "0": "t_chaingate_c", + ">": "t_stairs_down" + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_50", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " ", + " ", + " ", + "222222222222222222222222", "........................", "........................", "........................", @@ -3778,10 +6004,16 @@ "........................", "........................", "........................", - "........................" + "------------------------", + " ", + " ", + " ", + " ", + " ", + " ", + " " ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] + "palettes": [ "roof_palette" ] } }, { @@ -3800,14 +6032,14 @@ "|-| : ", "| |rrr|----|", " |----:|---|EEEE|", - " |222222222|EEEEV", - "-----| |222222222|HZZH|", + " |<22222222|EEEEV", + "-----| |<22222222|HZZH|", "N11S$| |HHH222HHH|22222", "9111$| |y22222222Z21111", "N111l| |y22222222Z21111", "1111l| |HHH222HHH|22222", - "11111| |222222222|HZZH|", - "N99N1| |222222222|EEEEV", + "11111| |<22222222|HZZH|", + "N99N1| |<22222222|EEEEV", "N99N1| |---------|EEEE|", "-----| |----|", "3333B| ", @@ -3849,55 +6081,148 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.1 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_51", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "F..y|-|.AAA.AAAAAAA.....", + "...Y|JJJJJJJJJJJJJJJ?J..", + "F..Y|...................", + "F..y|QQiiJJnjJ.YJJJllQQ|", + "..|-|---------=---------", + "--|....................=", + "..................|----|", + "........|---------|EEEE|", + "........|>666666|P|EEEEH", + "-----|,.|>666666=.|H++H|", + "SSSSS|..|HHH666H|-|.....", + "66666|..|666666666+.....", + "SSSS6|..|666666666+.....", + "SSSS6|..|HHH666H|-|.....", + "66666|..|>666666=.|H++H|", + "--=--|..|>666666|<|EEEEH", + "66B66|..|---------|EEEE|", + "6III6|............|----|", + "66666=.................=", + "66666|--------=---------", + "I6IB6|I66S|zz...zz|3333|", + "I6I66|IB66=.....zz|3..33", + "66666|-------=----|3....", + "I6IB6|.................." + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "<": "t_stairs_up", "S": "t_carpet_red", "B": "t_carpet_red", "I": "t_carpet_red" }, + "furniture": { "3": "f_table" }, + "items": { + "Q": { "item": "pizza_kitchen", "chance": 50, "repeat": [ 2, 4 ] }, + "J": { "item": "pizza_display", "chance": 30 }, + "l": { "item": "pizza_fridge", "chance": 30, "repeat": [ 2, 4 ] }, + "j": { "item": "SUS_dishes", "chance": 10, "repeat": [ 2, 4 ] }, + "n": { "item": "SUS_dishes", "chance": 30, "repeat": [ 2, 4 ] }, + "i": { "item": "oven", "chance": 30, "repeat": [ 1, 2 ] }, + "z": { "item": "farming_seeds", "chance": 30, "repeat": [ 1, 2 ] }, + "3": { "item": "farming_seeds", "chance": 30, "repeat": [ 1, 2 ] }, + "I": { "item": "office", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", "om_terrain": "mall_a_51_roof", "weight": 200, "object": { - "fill_ter": "t_flat_roof", - "rows": [ - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + "fill_ter": "t_concrete", + "rows": [ + "........................", + "..........!.....*....*..", + "....!...................", + ".............3..........", + ".....---11111--=--------", + ".....|_______3_______zz|", + ".....|____________|----|", + "-----|____________|EEEE|", + "___z______________|EEEE|", + "___z______________|++++|", + "_________%_____________|", + "__z____________z_______|", + "z_z___________zz_______|", + "z______________________|", + "___z_____________-|++++|", + "_zzz_______%_____>|EEEE|", + "-----|___________-|EEEE|", + ".....|____________|----|", + ".....|_______3_______zz|", + ".....---11111--=--------", + ".............3..........", + "....................!...", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, - "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ], - "place_nested": [ - { - "chunks": [ - [ "null", 20 ], - [ "roof_2x2_utilities_b", 15 ], - [ "roof_2x2_utilities_c", 5 ], - [ "roof_2x2_utilities_d", 40 ], - [ "roof_2x2_utilities", 50 ], - [ "roof_4x4_utility_1", 30 ] - ], - "x": [ 15, 20 ], - "y": [ 15, 20 ] - } - ] + "palettes": [ "mall_palette_2" ], + "terrain": { + ".": "t_flat_roof", + "*": "t_flat_roof", + "!": "t_flat_roof", + " ": "t_open_air", + "1": "t_door_metal_locked", + "3": "t_gates_mech_control", + "4": "t_chainfence", + "0": "t_chaingate_c", + ">": "t_stairs_down" + }, + "items": { + "z": [ + { "item": "cannedfood", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "allclothes", "chance": 10, "repeat": [ 1, 2 ] }, + { "item": "livingroom", "chance": 20, "repeat": [ 1, 2 ] } + ] + }, + "vehicles": { + "!": { "vehicle": "golf_cart", "chance": 30, "rotation": 90 }, + "*": { "vehicle": "golf_cart_4seat", "chance": 30, "rotation": 180 }, + "%": { "vehicle": "forklift", "chance": 30, "rotation": 90 } + } + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_upper_roof_51", + "object": { + "fill_ter": "t_flat_roof", + "rows": [ + " ", + " ", + " ", + " ", + " |222222222222222222", + " |.................3", + " |.................3", + "22222|.................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + ".......................3", + "-----|.................3", + " |.................3", + " |.................3", + " ------------------3", + " ", + " ", + " ", + " " + ], + "palettes": [ "roof_palette" ] } }, { @@ -3934,7 +6259,7 @@ "|cV21111112 cc " ], "palettes": [ "mall_palette" ], - "terrain": { "8": "t_grass" }, + "terrain": { "8": "t_grass", "Q": "t_linoleum_gray", "G": "t_linoleum_gray", "g": "t_linoleum_gray", "J": "t_linoleum_gray" }, "furniture": { "8": "f_bluebell" }, "place_items": [ { "item": "knife_shop", "x": [ 14, 17 ], "y": [ 9, 9 ], "chance": 60 }, @@ -3953,37 +6278,85 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_52_roof", - "weight": 200, + "om_terrain": "mall_b_52", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_linoleum_gray", "rows": [ + "HHH........HV.9K9K9K99K9", + ".yH........H..9K9K9K99K9", + ".YH..####..+..9999999999", + "--|..# #..+..9K9K9K99K9", + "PP|..# #..H..9K9K9K99K9", + "..|..# #..H..9999999999", + "PP|..# #..|yMMMVMMM....", + "--|..####..|-HHH-HHH-H+H", "........................", "........................", + ".....####....###########", + ".....# #....# ", + ".....# #....# ", + ".....####....###########", "........................", "........................", + "--|..####..|-H--HHH--HHH", + "PP|..# #..|^A^^^^^^^444", + "..|..# #..HJJ?JJ^^^^^^^", + "PP|..# #..+^^9999999999", + "--|..# #..H^^9R9RR9RR9R", + "33|..####..|^^9R9RR9RR9R", + ".3H........H^^9R9RR9RR9R", + ".3H........+^^9R9RR9RR9R" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "K": "t_carpet_yellow", "4": "t_floor", "R": "t_carpet_yellow", "J": "t_floor", "A": "t_floor" }, + "furniture": { "3": "f_table", "4": "f_table" }, + "items": { + "J": { "item": "office", "chance": 5 }, + "K": { "item": "musicstore_showpiece", "chance": 50 }, + "M": { "item": "mussto_windinst", "chance": 50 }, + "V": { "item": "mussto_stringinst", "chance": 50 }, + "P": { "item": "cleaning", "chance": 50 }, + "3": { "item": "farming_seeds", "chance": 50 }, + "R": { "item": "novels", "chance": 50 }, + "4": { "item": "manuals", "chance": 50 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_52_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ "........................", "........................", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", "........................", "........................", + ".....oooo....ooooooooooo", + ".....oooo....ooooooooooo", + ".....oooo....ooooooooooo", + ".....oooo....ooooooooooo", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", + ".....oooo...............", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -4037,6 +6410,49 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_53", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "K9.----|^^| ", + "K9.....||^| ", + "99..J...|^| ", + "K9..J.A.|^| ", + "K9..?...|^| ", + "99..JJJ.|^| ", + "........|^|-| ", + "-HHH-HHH|=|.| ", + "........|.||| ", + "..........yH ", + "###.......FH ", + " #.......FH ", + " #.......FH ", + "###.......FH ", + "..........yH ", + "........|.||| ", + "-HHH-HH-|=|.| ", + "^444^44^|^|-| ", + "^^^^^^^^|^| ", + "99999^R||^| ", + "R9RR9^R|^^| ", + "R9RR9^R|^^| ", + "R9RR9^R|^^| ", + "R9RR9^R|^^| " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "K": "t_carpet_yellow", "4": "t_floor", "R": "t_carpet_yellow", "A": "t_floor" }, + "furniture": { "4": "f_table" }, + "items": { + "J": { "item": "office", "chance": 5 }, + "K": { "item": "light_reading", "chance": 50 }, + "R": { "item": "textbooks", "chance": 30 }, + "4": { "item": "exotic_books", "chance": 20 } + } + } + }, { "type": "mapgen", "method": "json", @@ -4051,18 +6467,18 @@ "..........3 ", "..........3 ", "..........3 ", - "..........3 ", - "..........3 ", - "..........33 ", - "...........3 ", - "...........3 ", - "...........3 ", + "..........333 ", + "............3 ", + "...........33 ", "...........3 ", + "ooo........3 ", + "ooo........3 ", + "ooo........3 ", + "ooo........3 ", "...........3 ", - "..........33 ", - "..........3 ", - "..........3 ", - "..........3 ", + "...........33 ", + "............3 ", + "..........333 ", "..........3 ", "..........3 ", "..........3 ", @@ -4223,6 +6639,74 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_56", + "object": { + "fill_ter": "t_floor", + "rows": [ + " |..|--=||8JJ8", + " |..|I..|^8888", + " |..|IB.|T88MM", + " |..|S..|T88MM", + " |-|..|-=-|T8888", + " Hd|..|t.j|^^TTT", + " Hd+..|---------", + " Hd|..=^^y^3333^", + " |----|^^^777777", + " Hy^^^^^^^7KK7KK", + " H@^777^^^7KK7KK", + " H@^7K7^^^777777", + " |^^7K7^^^^^^^^^", + " H@^7K7^^^^^^^^^", + " H@^777^77777^77", + " Hy^^^^^77777^77", + " |---^^^7K7K7^7K", + " |b^%^^^7K7K7^7K", + " |---^C^77777^77", + " |b^%^y^7K7K7^7K", + " |---^C^7K7K7^7K", + " |b^%^^^77777^77", + " |---^^^77777^77", + " |b^%^^^^^^^^^^^" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { + "S": "t_linoleum_gray", + "I": "t_linoleum_gray", + "B": "t_linoleum_gray", + "j": "t_linoleum_gray", + "d": "t_linoleum_gray", + "J": "t_carpet_purple", + "M": "t_carpet_purple", + "K": "t_carpet_green" + }, + "furniture": { "3": "f_wardrobe", "4": "f_table", "%": "f_beaded_door" }, + "items": { + "M": { "item": "costume_accessories", "chance": 20, "repeat": [ 1, 2 ] }, + "T": { "item": "costume_clothes", "chance": 20, "repeat": [ 1, 2 ] }, + "I": { "item": "office", "chance": 20 }, + "J": { "item": "office", "chance": 20 }, + "S": { "item": "office_paper", "chance": 100, "repeat": [ 1, 2 ] }, + "d": [ + { "item": "jackets", "chance": 40 }, + { "item": "pants", "chance": 100 }, + { "item": "shirts", "chance": 100 }, + { "item": "hatstore_accessories", "chance": 100 }, + { "item": "shoestore_shoes", "chance": 100 } + ], + "U": { "item": "allclothes", "chance": 30 }, + "z": { "item": "allclothes", "chance": 30, "repeat": [ 1, 2 ] }, + "R": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "K": { "item": "pants", "chance": 30, "repeat": [ 1, 2 ] }, + "3": { "item": "shirts", "chance": 30, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 2, 4 ] }, + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ] + } + } + }, { "type": "mapgen", "method": "json", @@ -4286,7 +6770,7 @@ " cccc cc c r|-", " rrrr r|t", " HHHH| r| ", - " >| rrrr r|-", + " <| rrrr r|-", " |HHH| |D", "cc rr |< | ", "c rr |HHHH rrrr r| ", @@ -4294,6 +6778,7 @@ " rr rrrr r|-" ], "palettes": [ "mall_palette" ], + "terrain": { "<": "t_stairs_up" }, "place_items": [ { "item": "floor_trash", "x": [ 23, 23 ], "y": [ 19, 19 ], "chance": 80 }, { "item": "allclothes", "x": [ 0, 1 ], "y": [ 20, 22 ], "chance": 60 }, @@ -4328,6 +6813,61 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_57", + "object": { + "fill_ter": "t_floor", + "rows": [ + "888888^+..11..+^^^B4B^^^", + "8MMM88^H..11..H^^^B4B^^^", + "888888^|..11..|^^^^^^^^^", + "8MMM88dH..11..H4^^B4B^^^", + "888888dH......H4^^B4B^^^", + "bTTTb^^|......|^^^^^^^^^", + "-------|-H++H-|---------", + "^3333^^^^^^^^^^^^3333^|.", + "77777777777777777777^^H.", + "K7KK7KK7KK7KK7KK7KK7^^H.", + "K7KK7KK7KK7KK7KK7KK7^^+.", + "77777777777777777777^^+.", + "^^^^^^^^^^^^^^^^^^^^^^H.", + "^^^^^^^^^^^^^^^^^^^^^^H.", + "777^JJJ?JJJ?JJJ^77777^|.", + "777^J^^^^A^^^^J^77777^|-", + "7K7^^^^^^^^^^^^^7K7K73|t", + "7K7^^^^HHHH|~^J^7K7K73|F", + "777^^^^^^^>|~A?^77777^|-", + "7K7^J^~|HHH|~^J^7K7K73|Y", + "7K7^?^~|>^^^^^^^7K7K73|.", + "777^JA~|HHHH^^^^77777^|.", + "777^^^^^^^^^^^^^77777^|J", + "^^^^^^^^^^^^^^^^^^^^^^|-" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "M": "t_carpet_purple", ">": "t_stairs_down", "Y": "t_linoleum_gray", "F": "t_linoleum_gray", "K": "t_carpet_green" }, + "furniture": { "3": "f_wardrobe", "4": "f_table" }, + "items": { + "4": { "item": "baked_goods", "chance": 20, "repeat": [ 1, 2 ] }, + "M": { "item": "costume_accessories", "chance": 20, "repeat": [ 1, 2 ] }, + "T": { "item": "costume_clothes", "chance": 20, "repeat": [ 1, 2 ] }, + "d": [ { "item": "costume_clothes", "chance": 100 }, { "item": "costume_accessories", "chance": 100 } ], + "I": { "item": "office", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + "U": { "item": "allclothes", "chance": 30 }, + "z": { "item": "allclothes", "chance": 30, "repeat": [ 1, 2 ] }, + "R": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "K": { "item": "pants", "chance": 30, "repeat": [ 1, 2 ] }, + "3": { "item": "shirts", "chance": 30, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 2, 4 ] }, + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ] + }, + "sealed_item": { "1": { "item": { "item": "seed_rose" }, "furniture": "f_planter_harvest" } }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -4427,15 +6967,63 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_58_roof", - "weight": 200, + "om_terrain": "mall_b_58", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_linoleum_gray", "rows": [ + "^^0^^Q|m.V.V...M..|S...|", + "^^0^^Q|m.V.V...M..=..B.|", + "^^?%^Q|m.V.V...MA.|IIIy|", + "^^0^^Q|m.V.V...M?M|----|", + "^^^^^Q|m.........y|EEEE|", + "000^^^|...KKK.KKK.|EEEE|", + "HHH+H-|-+-HHH-HHH-|H++H|", "........................", "........................", + ".........###############", + ".........# ", + ".........# ", + ".........###############", "........................", "........................", + "-----|....|-HHH--H+H-H+H", + ".|t|t|....|^444^^^^^^^^^^", + ".|.|.|....|^^^^^^^^^^^^^", + "=|=|=|....|^^^^^^3333^^^", + ".....|....|*^^3^^^^^^^^3", + ".....=....|*^^3^^3333^^3", + ".....|....|*^^3^^3333^^3", + "JjJjJ|....|^^^3^^^^^^^^3", + "-----|....|*^^^^^3333^^^" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "Q": "t_floor", "M": "t_floor", "0": "t_floor", "%": "t_floor", "3": "t_floor", "*": "t_floor", "4": "t_floor" }, + "furniture": { "0": "f_displaycase", "%": "f_stool", "4": "f_displaycase", "3": "f_table", "*": "f_glass_cabinet" }, + "items": { + "I": { "item": "office", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 2, 4 ] }, + "M": { "item": "butcher_meat", "chance": 20, "repeat": [ 1, 2 ] }, + "V": { "item": "butcher_meat", "chance": 20, "repeat": [ 1, 2 ] }, + "K": { "item": "butcher_meat", "chance": 20, "repeat": [ 1, 2 ] }, + "m": { "item": "butcher_raw_meat", "chance": 20, "repeat": [ 1, 2 ] }, + "0": { "item": "baked_goods", "chance": 20, "repeat": [ 1, 2 ] }, + "Q": { "item": "groce_bread", "chance": 20, "repeat": [ 1, 2 ] }, + "*": { "item": "glass_shop", "chance": 20, "repeat": [ 1, 2 ] }, + "3": { "item": "glass_shop", "chance": 20, "repeat": [ 1, 2 ] }, + "4": { "item": "glass_shop", "chance": 20, "repeat": [ 1, 2 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_58_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ "........................", "........................", "........................", @@ -4445,6 +7033,10 @@ "........................", "........................", "........................", + ".........ooooooooooooooo", + ".........ooooooooooooooo", + ".........ooooooooooooooo", + ".........ooooooooooooooo", "........................", "........................", "........................", @@ -4457,7 +7049,7 @@ "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -4516,15 +7108,56 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_59_roof", - "weight": 200, + "om_terrain": "mall_b_59", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_carpet_green", "rows": [ + "6BIIIB6H666666IB6BI6I666", + "6BIIIB6|6666666666666666", + "666B666||--==--|66666666", + "--------|......|--------", + "EEEE|-|..........|-|EEEE", + "EEEE|..............|EEEE", + "H++H|..............|H++H", "........................", "........................", + "#######..........#######", + " #..........# ", + " #..........# ", + "#######..........#######", "........................", "........................", + "--HHH--|..####..|---HHH-", + "^^444^^|..# #..|777MMM7", + "^^^^^^4H..# #..HM777777", + "^333^^4H..# #..HM77KKK7", + "^333^^4H..# #..HM777777", + "^^^^^^^|..# #..|7777777", + "^^^|H+H|..####..|H+H|777", + "^^^|................|VVV", + "^^4H................|---" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "B": "t_carpet_red", "I": "t_carpet_red", "S": "t_carpet_red", "4": "t_floor", "3": "t_floor" }, + "furniture": { "4": "f_displaycase", "3": "f_table" }, + "items": { + "V": { "item": "consumer_electronics", "chance": 30 }, + "M": { "item": "consumer_electronics", "chance": 30 }, + "K": { "item": "elecsto_diy", "chance": 30 }, + "4": { "item": "glass_shop", "chance": 30 }, + "3": { "item": "glass_shop", "chance": 30 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_59_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ "........................", "........................", "........................", @@ -4534,19 +7167,23 @@ "........................", "........................", "........................", + "ooooooo..........ooooooo", + "ooooooo..........ooooooo", + "ooooooo..........ooooooo", + "ooooooo..........ooooooo", "........................", "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + "..........oooo..........", + "..........oooo..........", + "..........oooo..........", + "..........oooo..........", + "..........oooo..........", + "..........oooo..........", + "..........oooo..........", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -4617,15 +7254,58 @@ { "type": "mapgen", "method": "json", - "om_terrain": "mall_a_60_roof", - "weight": 200, + "om_terrain": "mall_b_60", "object": { - "fill_ter": "t_flat_roof", + "fill_ter": "t_carpet_green", "rows": [ + "I6I66|Q....A............", + "66666|Q...JJJJ?JJJJJ....", + "66666|................Q.", + "|----|.QQQ..QQQ..QQQ..Q.", + "|EEEE|................Q.", + "|EEEE|.333..333..333....", + "|H++H|-HHH--HHH--HHH-+++", "........................", "........................", + "########...#############", + " #...# ", + " #...# ", + "########...#############", "........................", "........................", + "HHH-++-++-HHH-HHH-HHH-|.", + "MMM7777777MMM7MMM7MMM7|.", + "7777777777777777777777|.", + "KKK7777MMMM777KKK77K7V||", + "7777777777777777777K7V|^", + "KKK77444444477KKK77K77|^", + "7777747%7774777777777V|^", + "VVV7777VVV7777VVV77VVV|^", + "----------------------|^" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "I": "t_carpet_red", "3": "t_linoleum_gray", "J": "t_linoleum_gray", "Q": "t_linoleum_gray", "A": "t_linoleum_gray" }, + "furniture": { "3": "f_table", "4": "f_counter", "%": "f_stool" }, + "items": { + "I": { "item": "office", "chance": 30 }, + "Q": { "item": "farming_tools", "chance": 30 }, + "3": { "item": "farming_seeds", "chance": 20, "repeat": [ 2, 4 ] }, + "V": { "item": "consumer_electronics", "chance": 30 }, + "M": { "item": "consumer_electronics", "chance": 30 }, + "K": { "item": "elecsto_diy", "chance": 30 }, + "4": { "item": "office", "chance": 30 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_a_60_roof", + "weight": 200, + "object": { + "fill_ter": "t_flat_roof", + "rows": [ "........................", "........................", "........................", @@ -4635,19 +7315,23 @@ "........................", "........................", "........................", + "oooooooo...ooooooooooooo", + "oooooooo...ooooooooooooo", + "oooooooo...ooooooooooooo", + "oooooooo...ooooooooooooo", "........................", "........................", "........................", "........................", "........................", - "........................", + ".......................-", "........................", "........................", "........................", "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -4710,6 +7394,54 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 2, 23 ], "y": [ 1, 22 ], "density": 0.3 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_61", + "object": { + "fill_ter": "t_floor", + "rows": [ + ".3|........H^^9999999999", + ".3|........|^^9R9RR9RR9R", + "..H........H4^9R9RR9RR9R", + "..+........H4^9R9RR9RR9R", + "..H........H4^9999999999", + "..|........|^^^^^^^^^^^^", + "--|........|--|---------", + "..............|.QQQ.QQQ.", + "..............|.........", + "##............H.QQQ.QQQ.", + " #............+.........", + " #............H.QQQ.QQQ.", + "##............|.........", + "..............H.QQQ.QQQ.", + "..............+.........", + "..............H.QQQ.QQQ.", + "..............|.........", + "..............|.QQQ.QQQ.", + "HHH--H+H--HHH-|---------", + "@@@^^^^^^J^^^^^^^^^@@@@^", + "^^^^^^^^^J^A^^^^J^^^^^^^", + "C^C^^^^^^JJ?JJJJJ^^C^^C^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "^^^^^^^^^^^^^^^^^^^^^^^^" + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "3": "t_linoleum_gray", "R": "t_carpet_yellow", "Q": "t_linoleum_gray" }, + "furniture": { "3": "f_table", "4": "f_table" }, + "items": { + "4": { "item": "book_school", "chance": 30 }, + "3": { "item": "flower_pots", "chance": 30 }, + "R": { "item": "book_school", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": [ + { "item": "mil_surplus", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "mil_armor", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "mil_food_nodrugs", "chance": 20, "repeat": [ 1, 2 ] } + ] + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 8, 23 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -4727,10 +7459,10 @@ "........................", "........................", "........................", - "........................", - "........................", - "........................", - "........................", + "oo......................", + "oo......................", + "oo......................", + "oo......................", "........................", "........................", "........................", @@ -4743,7 +7475,7 @@ "........................", "........................" ], - "terrain": { ".": "t_flat_roof" }, + "terrain": { ".": "t_flat_roof", "o": "t_glass_roof" }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 23 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -4760,7 +7492,7 @@ "B nn BB B|...#T#.ss____", "B hh BB B|...###.ss____", " B|##.....ss____", - "BBBBBBB B|##.....ss____", + "BBBBBBB <|##.....ss____", "----|--+--|##.....ss,,,,", " P|z zz|##.....ss____", "c6 |zz zz|...###.ss____", @@ -4781,7 +7513,7 @@ "33333gJ33u|##.....ss____" ], "palettes": [ "mall_palette" ], - "terrain": { ")": "t_carpet_red" }, + "terrain": { ")": "t_carpet_red", "<": "t_stairs_up" }, "furniture": { ")": "f_table" }, "place_items": [ { "item": "homebooks", "x": [ 8, 9 ], "y": [ 7, 8 ], "chance": 60 }, @@ -4820,6 +7552,57 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_62", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "99999^^=^^| ", + "R9RR9^^|^^| ", + "R9RR9^R|^^| ", + "R9RR9^R|^^| ", + "99999^R|^^| ", + "^^^^^^>|^^| ", + "-------|^^| ", + "QQQ|III|^^| ", + "...|.B.|^^| ", + "...|..S|^^| ", + "JJ.|-=-|^^| ", + "J..|U.z|^^| ", + "?A.|U.z|^^| ", + "J..=...=^^| ", + "J..|U.z|^^| ", + "JJ.|Uzz|^^| ", + "...|-=-|^^| ", + "QQQ|t.j|^^| ", + "-------|==| ", + "|l.3nn3|^^| ", + "|l..A.j|^^| ", + "|I....j|^^| ", + "|IA.3.3|^^| ", + "|Y..3.i|^^| " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "R": "t_carpet_yellow", ">": "t_stairs_down" }, + "furniture": { "4": "f_table", "3": "f_counter" }, + "items": { + "R": { "item": "textbooks", "chance": 30 }, + "I": { "item": "office", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + "z": { "item": "mil_surplus", "chance": 30 }, + "U": { "item": "mil_food_nodrugs", "chance": 30 }, + "Q": { "item": "book_military", "chance": 30 }, + "J": { "item": "office", "chance": 30 }, + "3": { "item": "restaur_sink", "chance": 30 }, + "i": { "item": "oven", "chance": 30 }, + "n": { "item": "restaur_sink", "chance": 30 }, + "j": { "item": "restaur_sink", "chance": 30 }, + "l": { "item": "restaur_fridge", "chance": 30 } + } + } + }, { "type": "mapgen", "method": "json", @@ -5003,6 +7786,54 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_65", + "object": { + "fill_ter": "t_floor", + "rows": [ + " |----^^33^^RR^^", + " |tYj|T^33^^RR^^", + " |^^^=^^^^^^FF^^", + " |---|^^@^^^^^^^", + " |^^^=^^@^^^RR^^", + " |tYj|^^^^^^RR^^", + " |---|T^33^^RR^^", + " |t^j|T^33^^^^^^", + " |^^^|^^^^^^QQ^^", + " |-=-|--=-------", + " |^^^^FF^FF|yC^^", + " |^^^^^^^^^|^^^B", + " |PPP^PPP^y|S^II", + " |--------------", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "K": "t_carpet_green" }, + "furniture": { "3": "f_table" }, + "items": { + "I": { "item": "office", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + "R": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "K": { "item": "pants", "chance": 30, "repeat": [ 1, 2 ] }, + "T": { "item": "shirts", "chance": 30, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 2, 4 ] }, + "P": [ { "item": "jackets", "chance": 10 }, { "item": "bags", "chance": 10 } ], + "3": { "item": "underwear", "chance": 20, "repeat": [ 2, 4 ] } + } + } + }, { "type": "mapgen", "method": "json", @@ -5102,6 +7933,57 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_66", + "object": { + "fill_ter": "t_floor", + "rows": [ + "RR^^RR^^^^^^^^^^^^^^^T|j", + "RR^^RR^^^333^^^CyCyC^T|.", + "FF^^FF^^^333^^^^^^^^^^|.", + "^^^^^^^^^^^^^^^^^^^^^^|Y", + "RR^^RR^^^333^T|%|%|%|%|-", + "RR^^RR^^^333^T|^|^|^|^|.", + "RR^^RR^b^^^^^T|b|b|b|b|t", + "^^^^^^^---=---|---------", + "QQ^^QQy|U^^^zz|EEEE|^^^^", + "-------|U^z^zz|EEEE|^^^^", + "^S|PPzzzz^^^^z|-==-|^^^^", + "^^=^^^z^^^^^^^=^^^^^^^|-", + "IS|^^^^^^zzz^^=^^^^^^^| ", + "----------------------| ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "Y": "t_linoleum_gray", "t": "t_linoleum_gray", "j": "t_linoleum_gray", "K": "t_carpet_green" }, + "furniture": { "%": "f_beaded_door", "3": "f_table" }, + "items": { + "I": { "item": "office", "chance": 30 }, + "S": { "item": "office_paper", "chance": 30 }, + "U": { "item": "allclothes", "chance": 30 }, + "z": { "item": "allclothes", "chance": 30, "repeat": [ 1, 2 ] }, + "R": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "Q": { "item": "shoes", "chance": 30, "repeat": [ 1, 2 ] }, + "K": { "item": "pants", "chance": 30, "repeat": [ 1, 2 ] }, + "T": { "item": "shirts", "chance": 30, "repeat": [ 1, 2 ] }, + "Y": { "item": "trash", "chance": 20, "repeat": [ 2, 4 ] }, + "P": { "item": "cleaning", "chance": 20, "repeat": [ 2, 4 ] }, + "3": { "item": "underwear", "chance": 20, "repeat": [ 2, 4 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 3, 10 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -5195,6 +8077,48 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_67", + "object": { + "fill_ter": "t_floor", + "rows": [ + "JJjJJ|....|V^^^^^KKKK^^^", + ".....|....|V^^^^^^^^^^^^", + ".....=....|y^^^^^KKKK^^^", + ".....|....|V^^^^^KKKK^^^", + "=|=|=|....|V^^^^^^^^^^^^", + ".|.|.|....|V^^^JJJJJ?JJ^", + ".|t|t|....|^^^^^^^^A^^^^", + "-----|-==-|^V^^^VV^^^^VV", + "^^^^^^^^^^|---|----=----", + "^^^^^^^^^^^^^^|^z^^^^^^I", + "^^^^^^^^^^^^^^|zzz^^^^BI", + "----------|^^^|----=----", + " |^^^^^^^^^^^^^", + " |---------|FTF", + " HF^F", + " HFFF", + " |-HH", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "items": { + "I": { "item": "office", "chance": 5 }, + "S": { "item": "office_paper", "chance": 50 }, + "V": { "item": "glass_shop", "chance": 10, "repeat": [ 2, 4 ] }, + "K": { "item": "glass_shop", "chance": 10, "repeat": [ 2, 4 ] } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 3, 10 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -5272,6 +8196,50 @@ "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 4, 19 ], "y": [ 0, 23 ], "density": 0.7 } ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_68", + "object": { + "fill_ter": "t_floor", + "rows": [ + "^^^|................|^^^", + "^^y|.....######.....|^^^", + "^^MH.....# #.....HK^^", + "^^MH.....# #.....HK^^", + "^^^+.....# #.....+^^^", + "^^^+.....# #.....+^^^", + "^^MH.....# #.....HK^^", + "^^MH.....######.....HK^^", + "|^y|................|^^^", + "|M^|........A.......|^^^", + "---|................|---", + "^^^=................=^^^", + "^^^|....YFFFFFFY....|^^^", + "|----HH--HHHHHH--HH----|", + "H H", + "H H", + "| |", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "A": "t_linoleum_gray", "Y": "t_linoleum_gray", "F": "t_linoleum_gray" }, + "items": { + "K": [ + { "item": "dollar_clothes", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "dollar_books", "chance": 20, "repeat": [ 1, 2 ] } + ], + "M": { "item": "glass_shop", "chance": 20, "repeat": [ 1, 2 ] } + }, + "place_vehicles": [ { "vehicle": "food_cart", "x": 10, "y": 10, "chance": 100, "rotation": 90 } ] + } + }, { "type": "mapgen", "method": "json", @@ -5281,13 +8249,13 @@ "fill_ter": "t_flat_roof", "rows": [ "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", - "........................", + ".........oooooo.........", + ".........oooooo.........", + ".........oooooo.........", + ".........oooooo.........", + ".........oooooo.........", + ".........oooooo.........", + ".........oooooo.........", "........................", "........................", "........................", @@ -5305,7 +8273,14 @@ " ", " " ], - "terrain": { ".": "t_flat_roof", " ": "t_open_air", "-": "t_gutter_south", "3": "t_gutter_east", "|": "t_gutter_west" }, + "terrain": { + ".": "t_flat_roof", + " ": "t_open_air", + "-": "t_gutter_south", + "3": "t_gutter_east", + "|": "t_gutter_west", + "o": "t_glass_roof" + }, "place_items": [ { "item": "roof_trash", "x": [ 0, 23 ], "y": [ 0, 10 ], "chance": 50, "repeat": [ 1, 3 ] } ] } }, @@ -5369,6 +8344,61 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_69", + "object": { + "fill_ter": "t_floor", + "rows": [ + "^^KKKK^^^QQQ^QQQ^QQQ^Q|B", + "^^^^^^^^^^^^^^^^^^^^^Q|B", + "^^KKKK^^^QQQ^QQQ^QQQ^Q|^", + "^^^^^^^^^^^^^^^^^^^^^Q|^", + "^^KKKK^^^QQQ^QQQ^QQQ^Q|B", + "^^KKKK^^--------------|B", + "^^^^^^^^|zz^^z^^^z^^^^|^", + "JJJJ?JJJ|^^^^zz^z^^^^P|^", + "J^A^^^^^=^^^^^z^zzz^^P|B", + "^^^^^^^^|^^^^^^^z^^^^P|B", + "-----------=------=---|^", + "^^^^^^^^^^^^^^^|I^^|jt|^", + "^^^^^^^^^^^^^^^|IB^=^^|B", + "F^F|-------------------H", + "F^FH ", + "FFFH ", + "HHH| ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "items": { + "Q": [ + { "item": "dollar_food", "chance": 30, "repeat": [ 1, 2 ] }, + { "item": "dollar_kitchen", "chance": 30, "repeat": [ 1, 2 ] }, + { "item": "dollar_tools", "chance": 20, "repeat": [ 1, 2 ] } + ], + "K": [ + { "item": "dollar_clothes", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "dollar_books", "chance": 20, "repeat": [ 1, 2 ] } + ], + "z": [ + { "item": "dollar_food", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "dollar_kitchen", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "dollar_tools", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "dollar_books", "chance": 20, "repeat": [ 1, 2 ] }, + { "item": "dollar_clothes", "chance": 20, "repeat": [ 1, 2 ] } + ], + "I": { "item": "office", "chance": 30 } + }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 3, 10 ], "density": 0.15 } ] + } + }, { "type": "mapgen", "method": "json", @@ -5465,6 +8495,43 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_70", + "object": { + "fill_ter": "t_floor", + "rows": [ + "KB^^BKB^^BKB^^BKB^^BKB^^", + "KB^^BKB^^BKB^^BKB^^BKB^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "KB^^BKB^^BKB^^BKB^^BKB^^", + "KB^^BKB^^BKB^^BKB^^BKB^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "KB^^BKB^^BKB^^BKB^^BKB^^", + "KB^^BKB^^BKB^^BKB^^BKB^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "^^^^^^^^^^^^^^^^^^^^^^^^", + "KB^^BKB^^BKB^^BKB^^BKB^^", + "HH--HHH--HHH--HHH--HHH--", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "items": { "K": [ { "item": "restaur_table", "chance": 20 }, { "item": "table_wine", "chance": 10 } ] }, + "place_monsters": [ { "monster": "GROUP_MALL", "x": [ 3, 23 ], "y": [ 3, 10 ], "density": 0.3 } ] + } + }, { "type": "mapgen", "method": "json", @@ -5557,6 +8624,55 @@ ] } }, + { + "type": "mapgen", + "method": "json", + "om_terrain": "mall_b_71", + "object": { + "fill_ter": "t_linoleum_gray", + "rows": [ + "=...J.l|^^| ", + "|J..J.J|^^| ", + "|J..J.i|^^| ", + "|J..J.J|^^| ", + "=.....i|^^| ", + "|ll...l|^^|--| ", + "---=---|^^^^FH ", + "|UU.UU.=^^^^FH ", + "|.....z|^^|--| ", + "|UUUUUz|^^| ", + "-------|^^| ", + "|^^^^^^^^^| ", + "=^^^^^^^^^| ", + "----------| ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " ", + " " + ], + "palettes": [ "mall_palette_2" ], + "terrain": { "F": "t_floor" }, + "items": { + "U": [ + { "item": "groce_bread", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "groce_ingredient", "chance": 50, "repeat": [ 1, 2 ] }, + { "item": "groce_condiment", "chance": 20, "repeat": [ 1, 2 ] } + ], + "J": { "item": "diner_food", "chance": 20 }, + "i": { "item": "oven", "chance": 10, "repeat": [ 1, 2 ] }, + "l": [ + { "item": "groce_meat", "chance": 10, "repeat": [ 2, 4 ] }, + { "item": "restaur_fridge", "chance": 10, "repeat": [ 2, 4 ] } + ] + } + } + }, { "type": "mapgen", "method": "json", diff --git a/data/json/mapgen/park.json b/data/json/mapgen/park.json index a1e3ddaf2f7e4..a9412181a785b 100644 --- a/data/json/mapgen/park.json +++ b/data/json/mapgen/park.json @@ -272,7 +272,7 @@ "s": "t_sidewalk", "t": "t_tree", "z": "t_shrub", - "~": "t_water_sh" + "~": "t_water_pool_shallow" }, "furniture": { "A": "f_statue", "H": "f_bench", "R": "f_trashcan", "T": "f_table", "f": "f_dahlia" }, "place_items": [ { "item": "trash", "x": 4, "y": 5, "chance": 50 } ], @@ -839,7 +839,7 @@ "S": "t_grass", "_": "t_grass", "b": "t_grass", - "w": "t_water_sh", + "w": "t_water_pool_shallow", "|": "t_fence_h" } }, diff --git a/data/json/mapgen/refugee_center.json b/data/json/mapgen/refugee_center.json index c58c9d973b99d..ca2f7ce4ad7b8 100644 --- a/data/json/mapgen/refugee_center.json +++ b/data/json/mapgen/refugee_center.json @@ -5,6 +5,13 @@ "om_terrain": [ [ "evac_center_1", "evac_center_2", "evac_center_3", "evac_center_4", "evac_center_5" ] ], "weight": 100, "object": { + "faction_owner": [ + { "id": "free_merchants", "x": [ 0, 23 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 24, 47 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 48, 71 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 72, 95 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 96, 119 ], "y": [ 0, 23 ] } + ], "fill_ter": "t_floor", "rows": [ "........................................................................................................................", @@ -51,6 +58,13 @@ "om_terrain": [ [ "evac_center_6", "evac_center_7", "evac_center_8", "evac_center_9", "evac_center_10" ] ], "weight": 100, "object": { + "faction_owner": [ + { "id": "free_merchants", "x": [ 0, 23 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 24, 47 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 48, 71 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 72, 95 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 96, 119 ], "y": [ 0, 23 ] } + ], "fill_ter": "t_floor", "rows": [ "......_______,,_______ssss.......................sss________________sss.......................ssss_______,,_______......", @@ -143,6 +157,13 @@ "om_terrain": [ [ "evac_center_11", "evac_center_12", "evac_center_13", "evac_center_14", "evac_center_15" ] ], "weight": 100, "object": { + "faction_owner": [ + { "id": "free_merchants", "x": [ 0, 23 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 24, 47 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 48, 71 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 72, 95 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 96, 119 ], "y": [ 0, 23 ] } + ], "fill_ter": "t_floor", "rows": [ "......_______,,________sss.........##### c# ###########+#+###########LL#c #####..........sss________,,_______......", @@ -215,6 +236,13 @@ "om_terrain": [ [ "evac_center_16", "evac_center_17", "evac_center_18", "evac_center_19", "evac_center_20" ] ], "weight": 100, "object": { + "faction_owner": [ + { "id": "free_merchants", "x": [ 0, 23 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 24, 47 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 48, 71 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 72, 95 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 96, 119 ], "y": [ 0, 23 ] } + ], "fill_ter": "t_floor", "rows": [ "......_______,,_______sss....#########t+ c# #2hcV bbbb bbbb Vch2# #c +t#########....sss________,,_______......", @@ -303,6 +331,13 @@ "om_terrain": [ [ "evac_center_21", "evac_center_22", "evac_center_23", "evac_center_24", "evac_center_25" ] ], "weight": 100, "object": { + "faction_owner": [ + { "id": "free_merchants", "x": [ 0, 23 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 24, 47 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 48, 71 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 72, 95 ], "y": [ 0, 23 ] }, + { "id": "free_merchants", "x": [ 96, 119 ], "y": [ 0, 23 ] } + ], "fill_ter": "t_floor", "rows": [ "......_______,,_______ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss_______,,_______......", diff --git a/data/json/mapgen_palettes/mall_palette.json b/data/json/mapgen_palettes/mall_palette.json index 4f616a3944efc..cf8d02f0f190d 100644 --- a/data/json/mapgen_palettes/mall_palette.json +++ b/data/json/mapgen_palettes/mall_palette.json @@ -147,5 +147,83 @@ "|": "t_wall" }, "toilets": { "t": { } } + }, + { + "type": "palette", + "id": "mall_palette_2", + "furniture": { + "A": "f_stool", + "B": "f_chair", + "C": "f_armchair", + "D": "f_camp_chair", + "@": "f_sofa", + "F": "f_bench", + "G": "f_lab_bench", + "I": "f_desk", + "J": "f_counter", + "~": "f_cupboard", + "K": "f_table", + "L": "f_tourist_table", + "M": "f_displaycase", + "N": "f_workbench", + "O": "f_dresser", + "P": "f_locker", + "Q": "f_rack", + "R": "f_bookcase", + "S": "f_filing_cabinet", + "T": "f_wardrobe", + "U": "f_utility_shelf", + "V": "f_glass_cabinet", + "W": "f_rack_coat", + "X": "f_sign", + "Y": "f_trashcan", + "Z": "f_shredder", + "a": "f_floor_lamp", + "b": "f_bigmirror", + "c": "f_statue", + "d": "f_mannequin", + "e": "f_pool_table", + "g": "f_arcade_machine", + "h": "f_pinball_machine", + "i": "f_oven", + "j": "f_sink", + "k": "f_woodstove", + "l": "f_fridge", + "m": "f_glass_fridge", + "n": "f_dishwasher", + "r": "f_wood_keg", + "s": "f_metal_butcher_rack", + "u": [ "f_vending_c", "f_vending_reinforced" ], + "v": "f_gun_safe_el", + "w": "f_safe_l", + "y": [ "f_indoor_plant", "f_indoor_plant_y" ], + "z": "f_crate_c" + }, + "terrain": { + " ": "t_open_air", + ".": "t_linoleum_gray", + ",": "t_linoleum_white", + "_": "t_concrete", + "^": "t_floor", + "E": "t_elevator", + "<": "t_stairs_up", + ">": "t_stairs_down", + "-": "t_wall_w", + "|": "t_wall_w", + "H": "t_wall_glass", + "#": "t_glass_railing", + "+": "t_door_glass_c", + "=": [ "t_door_c", "t_door_locked" ], + "p": "t_column", + "x": [ "t_machinery_light", "t_machinery_heavy", "t_machinery_old", "t_machinery_electronic" ], + "2": "t_wall_g", + "5": "t_wall_wood", + "6": "t_carpet_red", + "7": "t_carpet_green", + "8": "t_carpet_purple", + "9": "t_carpet_yellow", + "?": "t_console_broken" + }, + "toilets": { "t": { } } } ] diff --git a/data/json/martialarts.json b/data/json/martialarts.json index 8ab0781ef86d0..4d9ed0c2ba0a7 100644 --- a/data/json/martialarts.json +++ b/data/json/martialarts.json @@ -24,6 +24,7 @@ "name": "Brawling", "description": "You're used to hand-to-creature fighting. Not stylish or sporting, but it gets the job done.", "initiate": [ "You grit your teeth and prepare for a good fight.", "%s gets ready to brawl." ], + "autolearn": [ [ "unarmed", "2" ] ], "arm_block": -1, "leg_block": 7, "techniques": [ "tec_brawl_feint", "tec_brawl_power", "tec_brawl_trip", "tec_brawl_counter" ] @@ -873,6 +874,41 @@ ] } ], + "oncrit_buffs": [ + { + "id": "debug_crit_buff", + "name": "Lightning Strike", + "description": "Lightning strikes twice. +Perception electric damage for 3 turns. Stacks 2 times.", + "unarmed_allowed": true, + "min_unarmed": 0, + "buff_duration": 3, + "max_stacks": 2, + "flat_bonuses": [ [ "damage", "electric", "per", 1.0 ] ] + } + ], + "onmiss_buffs": [ + { + "id": "debug_miss_buff", + "name": "Getting Angry", + "description": "When I get my hands on you... +2 bash damage for 2 turns. Stacks 5 times.", + "unarmed_allowed": true, + "min_unarmed": 0, + "buff_duration": 2, + "max_stacks": 5, + "flat_bonuses": [ [ "damage", "bash", 2.0 ] ] + } + ], + "onkill_buffs": [ + { + "id": "debug_kill_buff", + "name": "On Fire", + "description": "YOU ARE ON FIRE! +5 fire damage for 5 turns.", + "unarmed_allowed": true, + "min_unarmed": 0, + "buff_duration": 5, + "flat_bonuses": [ [ "damage", "heat", 5.0 ] ] + } + ], "techniques": [ "tec_debug_slow", "tec_debug_arpen" ] }, { diff --git a/data/json/monsters.json b/data/json/monsters.json index 2d3fdd7c01b76..a9243a13ff521 100644 --- a/data/json/monsters.json +++ b/data/json/monsters.json @@ -693,7 +693,7 @@ "id": "mon_chickenbot", "type": "MONSTER", "name": "chicken walker", - "description": "The Northrup ATSV, a massive, heavily-armed and armored robot walking on a pair of reverse-jointed legs. Armed with a 40mm anti-vehicle grenade launcher, 5.56 anti-personnel gun, and the ability to electrify itself against attackers, it is an effective automated sentry, though production was limited due to a legal dispute.", + "description": "The Northrop ATSV, a massive, heavily-armed and armored robot walking on a pair of reverse-jointed legs. Armed with a 40mm anti-vehicle grenade launcher, 5.56 anti-personnel gun, and the ability to electrify itself against attackers, it is an effective automated sentry, though production was limited due to a legal dispute.", "default_faction": "military", "species": [ "ROBOT" ], "diff": 20, @@ -2645,7 +2645,7 @@ "id": "mon_tankbot", "type": "MONSTER", "name": "Beagle Mini-Tank UGV", - "description": "The Northrup Beagle is a refrigerator-sized urban warfare UGV. Sporting an anti-tank missile launcher, 40mm grenade launcher, and numerous anti-infantry weapons, it's designed for high-risk urban fighting.", + "description": "The Northrop Beagle is a refrigerator-sized urban warfare UGV. Sporting an anti-tank missile launcher, 40mm grenade launcher, and numerous anti-infantry weapons, it's designed for high-risk urban fighting.", "default_faction": "military", "species": [ "ROBOT" ], "diff": 30, diff --git a/data/json/monsters/defense_bot.json b/data/json/monsters/defense_bot.json index 726bfa347a387..d920013722e8c 100644 --- a/data/json/monsters/defense_bot.json +++ b/data/json/monsters/defense_bot.json @@ -162,7 +162,7 @@ "id": "mon_dispatch", "type": "MONSTER", "name": "NR-031 Dispatch", - "description": "The Northrop Dispatch, designed for crowd control situations, carries and deployes kamikaze drones of various types, with a small onboard EMP emitter frying them in the event of its destruction. The bright green-and-yellow paint marks a low-force variant - *comparatively* low-force, anyways - typically deployed as guards after an area has been cleared.", + "description": "The Northrop Dispatch, designed for crowd control situations, carries and deploys kamikaze drones of various types, with a small onboard EMP emitter frying them in the event of its destruction. The bright green-and-yellow paint marks a low-force variant - *comparatively* low-force, anyways - typically deployed as guards after an area has been cleared.", "default_faction": "defense_bot", "species": [ "ROBOT" ], "diff": 20, diff --git a/data/json/npcs/TALK_COMMON_OTHER.json b/data/json/npcs/TALK_COMMON_OTHER.json index 4f44dbaddd292..2de46a56c0128 100644 --- a/data/json/npcs/TALK_COMMON_OTHER.json +++ b/data/json/npcs/TALK_COMMON_OTHER.json @@ -364,6 +364,64 @@ { "text": "Thanks, see you later!", "topic": "TALK_DONE" } ] }, + { + "id": "TALK_STOLE_ITEM", + "type": "talk_topic", + "dynamic_line": "You picked up something that does not belong to you...", + "responses": [ + { + "text": "Okay, okay, this is all a misunderstanding. Sorry, I'll drop it now.", + "topic": "TALK_DONE", + "effect": "drop_stolen_item", + "condition": "u_has_stolen_item" + }, + { + "text": "No, I'm keeping it. Try and take it off me, I dare you.", + "condition": "u_has_stolen_item", + "trial": { "type": "INTIMIDATE", "difficulty": 30, "mod": [ [ "FEAR", 8 ], [ "VALUE", 2 ], [ "TRUST", 2 ], [ "BRAVERY", -2 ] ] }, + "success": { "topic": "TALK_KEEPING_ITEM", "effect": { "u_faction_rep": -2 } }, + "failure": { "topic": "TALK_DONE", "effect": [ "hostile", { "u_faction_rep": -75 } ] } + }, + { + "text": "Look, I really need this. Please let me have it.", + "condition": "u_has_stolen_item", + "trial": { "type": "PERSUADE", "difficulty": 20, "mod": [ [ "TRUST", 3 ], [ "VALUE", 3 ], [ "ANGER", -3 ] ] }, + "success": { "topic": "TALK_ALLOW_KEEP_ITEM", "effect": { "u_faction_rep": -1 } }, + "failure": { "topic": "TALK_DISALLOW_KEEP_ITEM", "opinion": { "trust": -3, "anger": 2 }, "effect": { "u_faction_rep": -15 } } + }, + { + "text": "What, this? It's not the same one, you are mistaken.", + "condition": "u_has_stolen_item", + "trial": { "type": "LIE", "difficulty": 25, "mod": [ [ "TRUST", 3 ] ] }, + "success": { "topic": "TALK_DONE", "effect": "remove_stolen_status" }, + "failure": { "topic": "TALK_DISALLOW_KEEP_ITEM", "opinion": { "trust": -3, "value": -1, "anger": 2 } } + }, + { + "text": "I'm sorry. Look, I already dropped it, okay?", + "topic": "TALK_DONE", + "effect": [ "remove_stolen_status", { "u_faction_rep": -5 } ], + "condition": { "not": "u_has_stolen_item" } + } + ] + }, + { + "id": "TALK_DISALLOW_KEEP_ITEM", + "type": "talk_topic", + "dynamic_line": "Don't try and talk yourself out of this, drop it now.", + "responses": [ { "text": "Okay, I'm dropping it...", "effect": "drop_stolen_item", "topic": "TALK_DONE" } ] + }, + { + "id": "TALK_ALLOW_KEEP_ITEM", + "type": "talk_topic", + "dynamic_line": "Just this once, you can keep it. Don't tell anyone else.", + "responses": [ { "text": "Thanks.", "topic": "TALK_DONE", "effect": "remove_stolen_status" } ] + }, + { + "id": "TALK_KEEPING_ITEM", + "type": "talk_topic", + "dynamic_line": "Right... I don't want any trouble.", + "responses": [ { "text": "Smart choice.", "topic": "TALK_DONE", "effect": "remove_stolen_status" } ] + }, { "id": "TALK_DENY_EQUIPMENT", "type": "talk_topic", diff --git a/data/json/npcs/TALK_REFUGEE_BEGGAR_1.json b/data/json/npcs/TALK_REFUGEE_BEGGAR_1.json deleted file mode 100644 index e0be2d5afc0ff..0000000000000 --- a/data/json/npcs/TALK_REFUGEE_BEGGAR_1.json +++ /dev/null @@ -1,57 +0,0 @@ -[ - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_1", - "dynamic_line": { - "u_is_wearing": "badge_marshal", - "yes": "Please, help me. I need food. Aren't you their sheriff? Can't you help me?", - "no": "Please, help me. I need food." - }, - "responses": [ - { "text": "What are you doing here?", "topic": "TALK_REFUGEE_BEGGAR_1_INTRO" }, - { "text": "Get away from me.", "topic": "TALK_DONE" }, - { "text": "...", "topic": "TALK_DONE" } - ] - }, - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_1_INTRO", - "dynamic_line": "They won't let me in. They say they're too full. I'm allowed to camp out here as long as I keep it clean and don't make a fuss, but I'm so hungry.", - "responses": [ - { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, - { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, - { "text": "What did you do before the cataclysm?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, - { "text": "I'm sorry, I can't help you.", "topic": "TALK_DONE" } - ] - }, - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_1_LEAVE", - "dynamic_line": "Where else? I can't fight those things out there. I'm in terrible physical condition, don't have any useful skills, and I'm terrified of and violence. How am I supposed to find a safe place?", - "responses": [ - { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, - { "text": "What did you do before the cataclysm?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, - { "text": "I'm sorry, I can't help you.", "topic": "TALK_DONE" } - ] - }, - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_1_SCAVENGE", - "dynamic_line": "Out there? That's suicide! People that go out there don't come back, people who can hold their own... unlike me. I'd rather take my chances begging for scraps and waiting for someone in the center to die and make room for me, thanks.", - "responses": [ - { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, - { "text": "What did you do before the cataclysm?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, - { "text": "I'm sorry, I can't help you.", "topic": "TALK_DONE" } - ] - }, - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_1_EXPERTISE", - "dynamic_line": "I was a high school math teacher. It was a good job, I loved it. Funny enough, it's not super applicable after the end of the world. I mean, at some point people are going to need a teacher again, but right now they just want food, shelter, and clothing.", - "responses": [ - { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, - { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, - { "text": "I'm sorry, I can't help you.", "topic": "TALK_DONE" } - ] - } -] diff --git a/data/json/npcs/TALK_REFUGEE_BEGGAR_3.json b/data/json/npcs/TALK_REFUGEE_BEGGAR_3.json deleted file mode 100644 index 9984749be1e87..0000000000000 --- a/data/json/npcs/TALK_REFUGEE_BEGGAR_3.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_3", - "dynamic_line": "Don't bother with these assholes.", - "//": "STUB FILE: not all text implemented yet. TK: different greetings; topics FOOD, EXPERTISE, JOIN", - "responses": [ - { "text": "What's up?", "topic": "TALK_REFUGEE_BEGGAR_3_COMPLAIN" }, - { "text": "Ok... see ya.", "topic": "TALK_DONE" } - ] - }, - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_3_COMPLAIN", - "dynamic_line": "They're 'too full'. Won't share fuck-all.", - "responses": [ - { "text": "Why are you living here then?", "topic": "TALK_REFUGEE_BEGGAR_3_COMPLAIN2" }, - { "text": "I'd better get going.", "topic": "TALK_DONE" } - ] - }, - { - "type": "talk_topic", - "id": "TALK_REFUGEE_BEGGAR_3_COMPLAIN2", - "dynamic_line": "Even without them helping, it's the safest place to squat. As long as we keep it clean up here and don't cause sanitation problems, they don't mind us sitting around the entryway. So kind and generous of them, to let us sit here and slowly starve.", - "responses": [ { "text": "I'd better get going.", "topic": "TALK_DONE" } ] - } -] diff --git a/data/json/npcs/beggars/BEGGAR_1_Reena_Sandhu.json b/data/json/npcs/beggars/BEGGAR_1_Reena_Sandhu.json new file mode 100644 index 0000000000000..2b3dff5b3c4e5 --- /dev/null +++ b/data/json/npcs/beggars/BEGGAR_1_Reena_Sandhu.json @@ -0,0 +1,339 @@ +[ + { + "type": "effect_type", + "id": "beggar_has_eaten", + "name": [ "Full" ], + "desc": [ "This beggar in the refugee center has had something to eat recently." ] + }, + { + "type": "npc", + "id": "refugee_beggar1", + "//": "Hungry beggar in the refugee center.", + "name_unique": "Reena Sandhu", + "gender": "female", + "name_suffix": "beggar", + "class": "NC_BEGGAR_1", + "attitude": 0, + "mission": 7, + "chat": "TALK_REFUGEE_BEGGAR_1", + "faction": "lobby_beggars" + }, + { + "type": "npc_class", + "id": "NC_BEGGAR_1", + "name": "Beggar", + "job_description": "I'm just trying to survive.", + "common": false, + "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", + "bonus_str": { "rng": [ -6, -2 ] }, + "bonus_dex": { "rng": [ -4, -1 ] }, + "bonus_int": { "rng": [ 1, 2 ] }, + "bonus_per": { "rng": [ -3, -1 ] }, + "worn_override": "NC_BEGGAR_1_worn", + "carry_override": "EMPTY_GROUP", + "weapon_override": "EMPTY_GROUP", + "traits": [ + { "trait": "GLASSJAW" }, + { "trait": "VEGETARIAN" }, + { "trait": "SQUEAMISH" }, + { "trait": "MOODSWINGS" }, + { "trait": "SLOWHEALER" }, + { "trait": "SLOWRUNNER" }, + { "trait": "DISORGANIZED" }, + { "trait": "BADKNEES" }, + { "trait": "FLIMSY3" }, + { "trait": "MYOPIC" }, + { "trait": "PACIFIST" }, + { "trait": "Exp_Teaching2" }, + { "group": "Appearance_demographics" } + ], + "skills": [ { "skill": "speech", "bonus": { "rng": [ 0, 3 ] } }, { "skill": "cooking", "bonus": { "rng": [ 0, 3 ] } } ] + }, + { + "type": "item_group", + "id": "NC_BEGGAR_1_worn", + "subtype": "collection", + "entries": [ + { "item": "blanket" }, + { "item": "jeans" }, + { "item": "sweater" }, + { "item": "bra" }, + { "item": "panties" }, + { "item": "socks" }, + { "item": "sneakers" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1", + "dynamic_line": { + "u_has_var": "reena_recruited", + "type": "general", + "context": "recruit", + "value": "yes", + "yes": { + "npc_has_effect": "beggar_has_eaten", + "yes": "So, any luck with convincing the others to come on your crazy adventure yet?", + "no": "I'm sorry to say it after all you've done for me, but... I don't suppose you've got anything to eat?" + }, + "no": { + "npc_has_effect": "beggar_has_eaten", + "yes": "Thank you again. I really appreciate the food.", + "no": { + "u_is_wearing": "badge_marshal", + "yes": "Please, help me. I need food. Aren't you their sheriff? Can't you help me?", + "no": "Please, help me. I need food." + } + } + }, + "responses": [ + { "text": "What are you doing here?", "topic": "TALK_REFUGEE_BEGGAR_1_INTRO" }, + { + "text": "Hey, here, I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "text": "Get away from me.", "topic": "TALK_DONE", "opinion": { "trust": -1, "value": -1, "anger": 1 } }, + { "text": "...", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_INTRO", + "dynamic_line": { + "npc_has_effect": "beggar_has_eaten", + "yes": "They won't let me in. They say they're too full. I'm allowed to camp out here as long as I keep it clean and don't make a fuss, but I'm reduced to begging to survive.", + "no": "They won't let me in. They say they're too full. I'm allowed to camp out here as long as I keep it clean and don't make a fuss, but I'm so hungry." + }, + "responses": [ + { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, + { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { + "condition": { "npc_has_effect": "beggar_has_eaten" }, + "text": "I've got some more food, if you want it.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "condition": { "npc_has_effect": "beggar_has_eaten" }, "text": "I'd better get going.", "topic": "TALK_DONE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I'm sorry, I can't help you.", + "topic": "TALK_DONE" + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD", + "dynamic_line": "Thank you so much.", + "responses": [ + { + "text": "Can I ask you something else first?", + "topic": "TALK_NONE", + "opinion": { "trust": [ -1, 0 ], "value": [ -1, 0 ] } + }, + { + "text": "I'm sorry, I was wrong. I can't help you.", + "topic": "TALK_DONE", + "opinion": { "trust": [ -1, 0 ], "value": [ -1, 0 ] } + } + ], + "repeat_responses": [ + { + "for_category": [ "food" ], + "response": { + "text": "Here, you can have this .", + "topic": "TALK_REFUGEE_BEGGAR_1_GAVE_FOOD", + "opinion": { "trust": [ 0, 2 ], "value": [ 0, 2 ], "fear": [ -1, 0 ], "anger": [ -1, 0 ], "owed": 1 } + } + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_GAVE_FOOD", + "dynamic_line": "This is wonderful of you, I really appreciate it.", + "speaker_effect": [ { "effect": { "npc_add_effect": "beggar_has_eaten", "duration": 3600 } } ], + "responses": [ + { "text": "What are you doing here?", "topic": "TALK_REFUGEE_BEGGAR_1_INTRO", "effect": "u_bulk_trade_accept" }, + { "text": "No problem. See you around.", "topic": "TALK_DONE", "effect": "u_bulk_trade_accept" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_LEAVE", + "dynamic_line": "Where else? I can't fight those things out there. I'm in terrible physical condition, don't have any useful skills, and I'm terrified of and violence. How am I supposed to find a safe place?", + "responses": [ + { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, + { + "condition": { "not": "u_has_camp" }, + "text": "Come with me. Maybe you're not the greatest adventurer, but it's better than living here.", + "topic": "TALK_REFUGEE_BEGGAR_1_JOIN" + }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "reena_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "I have a camp of my own, away from here. You could come there. There aren't many people left, we could use anyone regardless of skills.", + "topic": "TALK_REFUGEE_BEGGAR_1_RECRUIT1" + }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "condition": { "npc_has_effect": "beggar_has_eaten" }, "text": "I'd better get going.", "topic": "TALK_DONE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I'm sorry, I can't help you.", + "topic": "TALK_DONE" + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_SCAVENGE", + "dynamic_line": "Out there? That's suicide! People that go out there don't come back, people who can hold their own... unlike me. I'd rather take my chances begging for scraps and waiting for someone in the center to die and make room for me, thanks.", + "responses": [ + { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, + { + "condition": { "not": "u_has_camp" }, + "text": "Come with me. Maybe you're not the greatest adventurer, but it's better than living here.", + "topic": "TALK_REFUGEE_BEGGAR_1_JOIN" + }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "reena_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "I have a camp of my own, away from here. Maybe you can't scavenge, but we can use any warm bodies that can lift a tool. You'd be safer and better fed there.", + "topic": "TALK_REFUGEE_BEGGAR_1_RECRUIT1" + }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "condition": { "npc_has_effect": "beggar_has_eaten" }, "text": "I'd better get going.", "topic": "TALK_DONE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I'm sorry, I can't help you.", + "topic": "TALK_DONE" + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_EXPERTISE", + "dynamic_line": "I was a high school math teacher. It was a good job, I loved it. Funny enough, it's not super applicable after the end of the world. I mean, at some point people are going to need a teacher again, but right now they just want food, shelter, and clothing.", + "responses": [ + { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, + { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, + { + "condition": { "not": "u_has_camp" }, + "text": "Come with me. Maybe you're not the greatest adventurer, but it's better than living here.", + "topic": "TALK_REFUGEE_BEGGAR_1_JOIN" + }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "reena_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "I have a camp of my own, away from here. Maybe they can't use your skills here, but I could.", + "topic": "TALK_REFUGEE_BEGGAR_1_RECRUIT1" + }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "condition": { "npc_has_effect": "beggar_has_eaten" }, "text": "I'd better get going.", "topic": "TALK_DONE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I'm sorry, I can't help you.", + "topic": "TALK_DONE" + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_JOIN", + "dynamic_line": "That's a kind offer of you, but I think I'd rather take my chances here than risking it out there again. I remember , I'm not in any hurry to face that again.", + "responses": [ + { "text": "Why don't you go somewhere else?", "topic": "TALK_REFUGEE_BEGGAR_1_LEAVE" }, + { "text": "Why don't you scavenge your own food?", "topic": "TALK_REFUGEE_BEGGAR_1_SCAVENGE" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_1_EXPERTISE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "condition": { "npc_has_effect": "beggar_has_eaten" }, "text": "I'd better get going.", "topic": "TALK_DONE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I'm sorry, I can't help you.", + "topic": "TALK_DONE" + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_RECRUIT1", + "dynamic_line": { + "npc_has_effect": "beggar_has_eaten", + "yes": "That's quite the offer, but I don't think I'd survive the trip. I don't think you realize how useless I am in this world.", + "no": "I'm sorry, I'm too hungry to make a big decision like that." + }, + "responses": [ + { + "text": "I can keep you safe. I'll take you there myself.", + "condition": { "npc_has_effect": "beggar_has_eaten" }, + "trial": { + "type": "PERSUADE", + "difficulty": 100, + "//": "This is a very difficult sell-job unless you've earned her trust with food", + "mod": [ [ "TRUST", 4 ], [ "VALUE", 2 ], [ "OWED", 3 ], [ "ANGER", -2 ], [ "FEAR", -6 ], [ "BRAVERY", 1 ] ] + }, + "success": { + "topic": "TALK_REFUGEE_BEGGAR_1_RECRUIT2", + "effect": { "u_add_var": "reena_recruited", "type": "general", "context": "recruit", "value": "yes" } + }, + "failure": { "topic": "TALK_REFUGEE_BEGGAR_1_RECRUIT_NO" } + }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Let me check.", + "topic": "TALK_REFUGEE_BEGGAR_1_GIVE_FOOD" + }, + { "text": "Let's talk about something else then.", "topic": "TALK_NONE" }, + { "condition": { "npc_has_effect": "beggar_has_eaten" }, "text": "I'd better get going.", "topic": "TALK_DONE" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I'm sorry, I can't help you.", + "topic": "TALK_DONE" + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_RECRUIT_NO", + "dynamic_line": "I really appreciate everything you've done for me, but I don't think you get it. I can't go out there. I will die. I know it's horrible camping out here, but I just can't face that nightmare again.", + "responses": [ + { "text": "Let's talk about something else then.", "topic": "TALK_NONE" }, + { "text": "I hope you'll reconsider eventually. Bye.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_1_RECRUIT2", + "dynamic_line": "Well... you have shown that you can survive out there, and you've been able to provide food, so I know you're thriving more than we are here. All right, I'll tell you what. I'm not going anywhere without my friends here, we've been through way too much together. If you can convince Luo, Brandon, and Yusuke to come along, then I'll go.", + "responses": [ + { "text": "OK. For now let's talk about something else.", "topic": "TALK_NONE" }, + { "text": "OK, I'll talk to them too.", "topic": "TALK_DONE" } + ] + } +] diff --git a/data/json/npcs/TALK_REFUGEE_BEGGAR_2.json b/data/json/npcs/beggars/BEGGAR_2_Dino_Dave.json similarity index 60% rename from data/json/npcs/TALK_REFUGEE_BEGGAR_2.json rename to data/json/npcs/beggars/BEGGAR_2_Dino_Dave.json index 36c7af142eb46..2bbfe6094fd26 100644 --- a/data/json/npcs/TALK_REFUGEE_BEGGAR_2.json +++ b/data/json/npcs/beggars/BEGGAR_2_Dino_Dave.json @@ -1,4 +1,58 @@ [ + { + "type": "npc", + "id": "refugee_beggar2", + "//": "Schizophrenic beggar in the refugee center.", + "name_unique": "Dino Dave", + "gender": "male", + "name_suffix": "beggar", + "class": "NC_BEGGAR_2", + "attitude": 0, + "mission": 7, + "chat": "TALK_REFUGEE_BEGGAR_2", + "faction": "lobby_beggars" + }, + { + "type": "npc_class", + "id": "NC_BEGGAR_2", + "name": "Beggar", + "job_description": "I'm just trying to survive.", + "common": false, + "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", + "bonus_str": { "rng": [ -3, -2 ] }, + "bonus_dex": { "rng": [ -5, -1 ] }, + "bonus_int": { "rng": [ -2, 0 ] }, + "bonus_per": { "rng": [ -6, -2 ] }, + "worn_override": "NC_BEGGAR_2_worn", + "carry_override": "EMPTY_GROUP", + "weapon_override": "EMPTY_GROUP", + "traits": [ + { "trait": "GLASSJAW" }, + { "trait": "ADDICTIVE" }, + { "trait": "HOARDER" }, + { "trait": "SLOWHEALER" }, + { "trait": "SLOWRUNNER" }, + { "trait": "CHEMIMBALANCE" }, + { "trait": "HEAVYSLEEPER" }, + { "trait": "FLIMSY2" }, + { "trait": "SCHIZOPHRENIC" }, + { "trait": "SLOWLEARNER" }, + { "trait": "PACIFIST" }, + { "group": "Appearance_demographics" } + ] + }, + { + "type": "item_group", + "id": "NC_BEGGAR_2_worn", + "subtype": "collection", + "entries": [ + { "item": "dinosuit" }, + { "item": "coat_winter" }, + { "item": "boxer_shorts" }, + { "item": "socks_wool" }, + { "item": "boots_winter" } + ] + }, { "type": "talk_topic", "id": "TALK_REFUGEE_BEGGAR_2", diff --git a/data/json/npcs/beggars/BEGGAR_3_Luo_Meizhen.json b/data/json/npcs/beggars/BEGGAR_3_Luo_Meizhen.json new file mode 100644 index 0000000000000..fdc11d44667da --- /dev/null +++ b/data/json/npcs/beggars/BEGGAR_3_Luo_Meizhen.json @@ -0,0 +1,511 @@ +[ + { + "type": "effect_type", + "id": "insulted_luo", + "name": [ "Insulted" ], + "desc": [ "Oh, you went there." ] + }, + { + "type": "npc", + "id": "refugee_beggar3", + "//": "Angry beggar in the refugee center.", + "name_unique": "Luo Meizhen", + "gender": "female", + "name_suffix": "beggar", + "class": "NC_BEGGAR_3", + "attitude": 0, + "mission": 7, + "chat": "TALK_REFUGEE_BEGGAR_3", + "faction": "lobby_beggars" + }, + { + "type": "npc_class", + "id": "NC_BEGGAR_3", + "name": "Beggar", + "job_description": "I'm just trying to survive.", + "common": false, + "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", + "bonus_str": { "rng": [ -4, -1 ] }, + "bonus_dex": { "rng": [ -4, -1 ] }, + "bonus_int": { "rng": [ 2, 5 ] }, + "bonus_per": { "rng": [ 0, 3 ] }, + "worn_override": "NC_BEGGAR_3_worn", + "carry_override": "EMPTY_GROUP", + "weapon_override": "EMPTY_GROUP", + "traits": [ + { "trait": "SLOWHEALER2" }, + { "trait": "SLOWRUNNER" }, + { "trait": "HEAVYSLEEPER" }, + { "trait": "FLIMSY2" }, + { "trait": "FASTLEARNER" }, + { "trait": "PACIFIST" }, + { "trait": "Exp_Mycology2" }, + { "group": "Appearance_demographics" } + ] + }, + { + "type": "item_group", + "id": "NC_BEGGAR_3_worn", + "subtype": "collection", + "items": [ + { "item": "hoodie" }, + { "item": "jacket_evac" }, + { "item": "jeans" }, + { "item": "panties" }, + { "item": "camisole" }, + { "item": "bra" }, + { "item": "socks" }, + { "item": "lowtops" }, + { "item": "gloves_light" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3", + "dynamic_line": { + "npc_has_effect": "insulted_luo", + "yes": "Fuck off, dickwaddle.", + "no": { + "u_has_var": "luo_recruited", + "type": "general", + "context": "recruit", + "value": "yes", + "yes": "Yo. Anyone else keen on moving from this bus stop to your tent city?", + "no": { + "npc_has_var": "dont_insult_luo", + "type": "general", + "context": "conversation", + "value": "yes", + "yes": { + "npc_has_var": "apology_luo", + "type": "general", + "context": "conversation", + "value": "yes", + "yes": { + "npc_has_effect": "beggar_has_eaten", + "yes": "Hey there. Good to see you again.", + "no": "Careful, I'm getting hangry again and am not totally responsible for my own actions." + }, + "no": "Look, I'm sorry for freaking out earlier. You might be an asshole but I'm sure you didn't mean it like that. My blood sugar is hella low, I get a bit cranky. We cool?" + }, + "no": { + "npc_has_effect": "beggar_has_eaten", + "yes": "Hey there, not-asshole. Good to see you again.", + "no": "Don't bother with these assholes." + } + } + } + }, + "responses": [ + { + "condition": { "and": [ { "not": { "npc_has_effect": "beggar_has_eaten" } }, { "not": { "npc_has_effect": "insulted_luo" } } ] }, + "text": "What's up?", + "topic": "TALK_REFUGEE_BEGGAR_3_COMPLAIN" + }, + { + "condition": { "and": [ { "npc_has_effect": "beggar_has_eaten" }, { "not": { "npc_has_effect": "insulted_luo" } } ] }, + "text": "What's up?", + "topic": "TALK_REFUGEE_BEGGAR_3_INTRO" + }, + { + "condition": { "and": [ { "not": { "npc_has_effect": "beggar_has_eaten" } }, { "not": { "npc_has_effect": "insulted_luo" } } ] }, + "text": "I might have some food for you. Are you hungry?", + "topic": "TALK_REFUGEE_BEGGAR_3_GIVE_FOOD" + }, + { + "condition": { + "and": [ + { "not": { "npc_has_effect": "apology_luo", "type": "general", "context": "conversation", "value": "yes" } }, + { "npc_has_var": "dont_insult_luo", "type": "general", "context": "conversation", "value": "yes" }, + { "not": { "npc_has_effect": "insulted_luo" } } + ] + }, + "text": "We're cool. Sorry for insulting you earlier.", + "effect": { "npc_add_var": "apology_luo", "type": "general", "context": "conversation", "value": "yes" }, + "topic": "TALK_REFUGEE_BEGGAR_3_APOLOGY" + }, + { + "condition": { + "and": [ + { "npc_has_var": "luo_mycus_mission", "type": "general", "context": "mission", "value": "yes" }, + { "u_has_item": "veggy_tainted" }, + { "not": { "npc_has_effect": "insulted_luo" } } + ] + }, + "text": "I found a sample of alien fungus for you.", + "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS4" + }, + { "text": "Ok... see ya.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_GIVE_FOOD", + "dynamic_line": "Actually yeah, I'm always hungry these days. I don't like taking handouts, but I wouldn't say no.", + "responses": [ + { + "text": "Actually can I ask you something else?", + "topic": "TALK_NONE", + "opinion": { "trust": [ -1, 0 ], "value": [ -1, 0 ] } + }, + { + "text": "I'm sorry, I was wrong. I can't help you.", + "topic": "TALK_DONE", + "opinion": { "trust": [ -1, 0 ], "value": [ -1, 0 ] } + } + ], + "repeat_responses": [ + { + "for_category": [ "food" ], + "response": { + "text": "Here, you can have this .", + "topic": "TALK_REFUGEE_BEGGAR_3_GAVE_FOOD", + "opinion": { "trust": [ 0, 1 ], "value": [ 0, 2 ], "fear": [ -1, 0 ], "anger": [ -1, 0 ], "owed": 1 } + } + } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_GAVE_FOOD", + "dynamic_line": "Thanks, I really appreciate this.", + "speaker_effect": [ { "effect": { "npc_add_effect": "beggar_has_eaten", "duration": 3600 } } ], + "responses": [ + { "text": "What are you doing here?", "topic": "TALK_REFUGEE_BEGGAR_3_INTRO", "effect": "u_bulk_trade_accept" }, + { "text": "No problem. See you around.", "topic": "TALK_DONE", "effect": "u_bulk_trade_accept" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_COMPLAIN", + "dynamic_line": "They're 'too full'. Won't share fuck-all.", + "responses": [ + { "text": "Why are you living here then?", "topic": "TALK_REFUGEE_BEGGAR_3_COMPLAIN2" }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "Well, they might not share, but I can. Are you hungry?", + "topic": "TALK_REFUGEE_BEGGAR_3_GIVE_FOOD" + }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_COMPLAIN2", + "dynamic_line": "Even without them helping, it's the safest place to squat. As long as we keep it clean up here and don't cause sanitation problems, they don't mind us sitting around the entryway. So kind and generous of them, to let us sit here and slowly starve.", + "responses": [ + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "Well, they might not share, but I can. Are you hungry?", + "topic": "TALK_REFUGEE_BEGGAR_3_GIVE_FOOD" + }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_INTRO", + "//": "The player shouldn't get to this dialogue without sharing some food first", + "dynamic_line": "Oh, same old story at first. I got evacuated on to the local concentration center, then picked up on a repurposed school bus and dragged out here. Then the chick processing me to get in saw my name and Chinese name and conveniently 'lost' my paperwork. I was sent out here to wait for further processing, while I watched busloads of people get processed and taken in. By the time they 'found' it, the place was full up, wouldn't ya know it. Now I'm stuck out here and they won't consider letting me in.", + "responses": [ + { "text": "You think you were treated like that because of your race?", "topic": "TALK_REFUGEE_BEGGAR_3_RACISM" }, + { "text": "Why stay out here then?", "topic": "TALK_REFUGEE_BEGGAR_3_WHYSTAY" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_3_EXPERTISE" }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "I have a camp of my own, away from here. No paperwork required. Want to come?", + "topic": "TALK_REFUGEE_BEGGAR_3_RECRUIT1" + }, + { + "condition": { + "and": [ + { "npc_has_var": "luo_mycus_mission", "type": "general", "context": "mission", "value": "yes" }, + { "u_has_item": "veggy_tainted" }, + { "not": { "npc_has_effect": "insulted_luo" } } + ] + }, + "text": "I found a sample of alien fungus for you.", + "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS4" + }, + { "text": "Ok... see ya.", "topic": "TALK_DONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_RACISM", + "dynamic_line": "Sure. My grandparents were from China. That means I'm obviously personally responsible for all this. Do you think there's some other reason they let hundreds of other educated people in and I'm sitting out here?", + "responses": [ + { + "condition": { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } }, + "text": "I don't care if you're Chinese. You can travel with me if you want.", + "topic": "TALK_REFUGEE_BEGGAR_3_JOIN" + }, + { + "condition": { + "and": [ + { "u_has_perception": 9 }, + { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } }, + { + "not": { "npc_has_var": "dont_insult_luo", "type": "general", "context": "conversation", "value": "yes" } + } + ] + }, + "text": "I mean, racism could definitely be a part of it... but you are visibly in poor shape. They need strong survivor material.", + "topic": "TALK_REFUGEE_BEGGAR_3_INSULTED" + }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_JOIN", + "dynamic_line": "That's awful kind of you, but look at me. I'm not travelling material, I've managed to stay fifty pounds overweight on a diet of pine nuts and wilted rhubarb, and I scream and shake uncontrollably at the sight of blood.", + "responses": [ + { "text": "Why stay out here then?", "topic": "TALK_REFUGEE_BEGGAR_3_WHYSTAY" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_3_EXPERTISE" }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "It'd be temporary. I have a base set up. There are only a few of us survivors left, we need to work together", + "topic": "TALK_REFUGEE_BEGGAR_3_RECRUIT1" + }, + { "text": "Okay, yeah, that's a bit of a problem. What were you saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_WHYSTAY", + "dynamic_line": "It may not be much, but we've got a little community. We can't live like this forever, but we're safer than out there, and we look out for each other. One way or another we'll shake things out to something better.", + "responses": [ + { "text": "You sound more optimistic than usual.", "topic": "TALK_REFUGEE_BEGGAR_3_WHYSTAY2" }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_3_EXPERTISE" }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "It'd be temporary. I have a base set up. There are only a few of us survivors left, we need to work together", + "topic": "TALK_REFUGEE_BEGGAR_3_RECRUIT1" + }, + { + "condition": { + "and": [ + { "u_has_var": "luo_doctorate", "type": "general", "context": "conversation", "value": "yes" }, + { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } + ] + }, + "text": "So, about that doctorate of yours...", + "topic": "TALK_REFUGEE_BEGGAR_3_DOCTORATE1" + }, + { "text": "What were you saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_WHYSTAY2", + "dynamic_line": "Don't get me wrong, I hate this place and this situation, and especially the selfish racist fucks that landed me here... but these other losers that landed out here with me? I like them. We might be miserable, but we're miserable together.", + "responses": [ + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_3_EXPERTISE" }, + { + "condition": { + "and": [ "u_has_camp", { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } ] + }, + "text": "It'd be temporary. I have a base set up. There are only a few of us survivors left, we need to work together", + "topic": "TALK_REFUGEE_BEGGAR_3_RECRUIT1" + }, + { "text": "What were you saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_INSULTED", + "dynamic_line": "Oooooh. Oh. You did not just fucking go there. Let's leave the fatties to die, hey? Wanna know how easy it is to find fucking *thyroid medication* after the apocalypse, asshat? Besides, there are more skills than heavy lifting needed now... no, you know what? Screw it. You're not worth my time.", + "speaker_effect": [ + { + "effect": [ + { "npc_add_effect": "insulted_luo", "duration": 28800 }, + { "npc_add_var": "dont_insult_luo", "type": "general", "context": "conversation", "value": "yes" } + ] + } + ], + "responses": [ { "text": "...", "topic": "TALK_DONE" } ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_APOLOGY", + "dynamic_line": "Thanks for saying it. So, what brings you around?", + "responses": [ + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "What's up?", + "topic": "TALK_REFUGEE_BEGGAR_3_COMPLAIN" + }, + { + "condition": { "npc_has_effect": "beggar_has_eaten" }, + "text": "What's up?", + "topic": "TALK_REFUGEE_BEGGAR_3_INTRO" + }, + { + "condition": { "not": { "npc_has_effect": "beggar_has_eaten" } }, + "text": "I might have some food for you. Are you hungry?", + "topic": "TALK_REFUGEE_BEGGAR_3_GIVE_FOOD" + }, + { "text": "Just wanted to get square. I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_RECRUIT1", + "dynamic_line": "Tempting offer, but I don't know how much I trust a random stranger offering me a place to live. Call me crazy.", + "responses": [ + { + "text": "What better choice do you have? It's not like it would be just you and me, the others out here can come too.", + "topic": "TALK_REFUGEE_BEGGAR_3_RECRUIT2" + }, + { + "condition": { + "and": [ + { "u_has_var": "luo_doctorate", "type": "general", "context": "conversation", "value": "yes" }, + { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } + ] + }, + "text": "So, about that doctorate of yours...", + "topic": "TALK_REFUGEE_BEGGAR_3_DOCTORATE1" + }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_3_EXPERTISE" }, + { "text": "Let's talk about something else then.", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_RECRUIT2", + "dynamic_line": "Like I said, sorry, it's just not happening. It's not that I don't trust you, it's just that I don't really trust you.", + "responses": [ + { + "condition": { + "and": [ + { "u_has_var": "luo_doctorate", "type": "general", "context": "conversation", "value": "yes" }, + { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } + ] + }, + "text": "So, about that doctorate of yours...", + "topic": "TALK_REFUGEE_BEGGAR_3_DOCTORATE1" + }, + { "text": "What did you do before ?", "topic": "TALK_REFUGEE_BEGGAR_3_EXPERTISE" }, + { "text": "Let's talk about something else then.", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_EXPERTISE", + "dynamic_line": "Well, before ended I was working at a university bookstore. I know a little bit about a lot of things, I guess you could say. I kinda loved the job, to be honest.", + "responses": [ + { + "condition": { + "and": [ + { "or": [ { "u_has_perception": 9 }, { "u_has_intelligence": 9 } ] }, + { "not": { "u_has_var": "luo_doctorate", "type": "general", "context": "conversation", "value": "yes" } }, + { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } + ] + }, + "text": "What had you working at the university bookstore in the first place? Are you an academic yourself?", + "effect": { "u_add_var": "luo_doctorate", "type": "general", "context": "conversation", "value": "yes" }, + "topic": "TALK_REFUGEE_BEGGAR_3_DOCTORATE" + }, + { + "condition": { + "and": [ + { "u_has_var": "luo_doctorate", "type": "general", "context": "conversation", "value": "yes" }, + { "not": { "u_has_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } + ] + }, + "text": "What's this I hear about you having a doctorate?", + "topic": "TALK_REFUGEE_BEGGAR_3_DOCTORATE1" + }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_DOCTORATE", + "dynamic_line": "Yeah, yeah, it's all very glamorous. Sure, I trained in the great ivory tower, got my PhD in mycology. Did my dissertation on signalling pathways in hyphae formation, and a postdoc in plant-fungus communication in rhyzomes. Then I got the job at the bookstore because there wasn't a ton of work for a doctor of mycology, although I'd had a few nibbles before things really got crazy. Now, people are just breaking down my door to get my sweet sweet knowledge of mold to help them fight the incoming zombie threat.", + "responses": [ + { "text": "Do you know about the fungal zombies though?", "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS1" }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_DOCTORATE1", + "dynamic_line": "Heh. Yeah, that was a great use of my time. As you can see it really helped my employment prospects. Yeah, I have a PhD in mycology. Did my dissertation on signalling pathways in hyphae formation, and a postdoc in plant-fungus communication in rhyzomes. Then I got the job at the bookstore because there wasn't a ton of work for a doctor of mycology, although I'd had a few nibbles before things really got crazy. Now, people are just breaking down my door to get my sweet sweet knowledge of mold to help them fight the incoming zombie threat.", + "responses": [ + { "text": "Do you know about the fungal zombies though?", "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS1" }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_MYCUS1", + "dynamic_line": "No, no I don't, and I'd appreciate you not leaving me hanging on that. There are fungal zombies?", + "responses": [ + { + "text": "Encroaching alien mushrooms, fungal towers, tough mycelium invading ground and trees, zombies taken over by aggressive mold... Yeah. It's ugly stuff.", + "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS2" + }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_MYCUS2", + "dynamic_line": "Okay, you've got my attention. Listen, do you think you could bring me some kind of sample of these things?", + "responses": [ + { "text": "It'd be dangerous, what's in it for me?", "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS3" }, + { "text": "Sure, easy enough. What do you need?", "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS3" }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "I'd better get going.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_MYCUS3", + "dynamic_line": "If you get me a sample, I'll join your crazy camp expedition. Hell, if you bring me a sample maybe I'll help you set up a lab to study this stuff. Almost anything could work, but if this stuff is as dangerous as you make it sound, maybe make sure it's not a sporulating body.", + "speaker_effect": [ { "effect": { "npc_add_var": "luo_mycus_mission", "type": "general", "context": "mission", "value": "yes" } } ], + "responses": [ + { + "condition": { "u_has_item": "veggy_tainted" }, + "text": "It just so happens I have a chunk of fungal matter on me right now.", + "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS4" + }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "Sure, I'd better get going. I'll see if I can find you something.", "topic": "TALK_DONE" } + ] + }, + { + "type": "talk_topic", + "id": "TALK_REFUGEE_BEGGAR_3_MYCUS4", + "dynamic_line": "Well. Well, well, well. This is really interesting. Look, you can see reticulations here, it looks sort of like an enlarged piece of a stipe from a basidiocarp... but look at this, these fibres are clearly unlike anything I've seen before. I wonder if they're motile?/n/nOkay, listen: you've got yourself a deal. I'll come to your base, but you've gotta get me hooked up with a microscope as soon as you can. This could be the beginning of something really cool. Oh, and it should go without saying that I'm not coming unless you can find a place for my friends here in your base. I'm sure you anticipated that. Talk them into going and I'm in. It should be easy, they're a bunch of sweet hearted saps.", + "speaker_effect": [ { "effect": { "u_add_var": "luo_recruited", "type": "general", "context": "recruit", "value": "yes" } } ], + "responses": [ + { + "condition": { "u_has_item": "veggy_tainted" }, + "text": "It just so happens I have a chunk of fungal matter on me right now.", + "topic": "TALK_REFUGEE_BEGGAR_3_MYCUS4" + }, + { "text": "What was it you were saying before?", "topic": "TALK_NONE" }, + { "text": "Sure, I'd better get going. I'll see if I can find you something.", "topic": "TALK_DONE" } + ] + } +] diff --git a/data/json/npcs/TALK_REFUGEE_BEGGAR_4.json b/data/json/npcs/beggars/BEGGAR_4_Brandon_Garder.json similarity index 69% rename from data/json/npcs/TALK_REFUGEE_BEGGAR_4.json rename to data/json/npcs/beggars/BEGGAR_4_Brandon_Garder.json index a2dc67431a6d6..7b3db525c538e 100644 --- a/data/json/npcs/TALK_REFUGEE_BEGGAR_4.json +++ b/data/json/npcs/beggars/BEGGAR_4_Brandon_Garder.json @@ -1,4 +1,64 @@ [ + { + "type": "npc", + "id": "refugee_beggar4", + "//": "Sickly beggar in the refugee center.", + "name_unique": "Brandon Garder", + "gender": "male", + "name_suffix": "beggar", + "class": "NC_BEGGAR_4", + "attitude": 0, + "mission": 7, + "chat": "TALK_REFUGEE_BEGGAR_4", + "faction": "lobby_beggars" + }, + { + "type": "npc_class", + "id": "NC_BEGGAR_4", + "name": "Beggar", + "job_description": "I'm just trying to survive.", + "common": false, + "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", + "bonus_str": { "rng": [ -4, -1 ] }, + "bonus_dex": { "rng": [ -4, -1 ] }, + "bonus_int": { "rng": [ -6, -2 ] }, + "bonus_per": { "rng": [ -3, -1 ] }, + "worn_override": "NC_BEGGAR_4_worn", + "carry_override": "EMPTY_GROUP", + "weapon_override": "EMPTY_GROUP", + "traits": [ + { "trait": "GLASSJAW" }, + { "trait": "ASTHMA" }, + { "trait": "SLOWHEALER3" }, + { "trait": "SLOWRUNNER" }, + { "trait": "HEAVYSLEEPER" }, + { "trait": "FLIMSY3" }, + { "trait": "WEAKSTOMACH" }, + { "trait": "MYOPIC" }, + { "trait": "HYPEROPIC" }, + { "trait": "JITTERY" }, + { "trait": "TRIGGERHAPPY" }, + { "trait": "SMELLY" }, + { "trait": "PROJUNK" }, + { "trait": "BADBACK" }, + { "trait": "BADKNEES" }, + { "trait": "BADCARDIO" }, + { "group": "Appearance_demographics" } + ] + }, + { + "type": "item_group", + "id": "NC_BEGGAR_4_worn", + "subtype": "collection", + "items": [ + { "item": "house_coat" }, + { "item": "briefs" }, + { "item": "tank_top" }, + { "item": "long_underpants" }, + { "item": "slippers" }, + { "item": "socks" } + ] + }, { "type": "talk_topic", "id": "TALK_REFUGEE_BEGGAR_4", diff --git a/data/json/npcs/TALK_REFUGEE_BEGGAR_5.json b/data/json/npcs/beggars/BEGGAR_5_Yusuke_Taylor.json similarity index 68% rename from data/json/npcs/TALK_REFUGEE_BEGGAR_5.json rename to data/json/npcs/beggars/BEGGAR_5_Yusuke_Taylor.json index 84cd5cddcae39..40bfa031fb0d8 100644 --- a/data/json/npcs/TALK_REFUGEE_BEGGAR_5.json +++ b/data/json/npcs/beggars/BEGGAR_5_Yusuke_Taylor.json @@ -1,4 +1,52 @@ [ + { + "type": "npc", + "id": "refugee_beggar5", + "//": "Mutant beggar in the refugee center.", + "name_unique": "Yusuke Taylor", + "gender": "male", + "name_suffix": "beggar", + "class": "NC_BEGGAR_5", + "attitude": 0, + "mission": 7, + "chat": "TALK_REFUGEE_BEGGAR_5", + "faction": "lobby_beggars" + }, + { + "type": "npc_class", + "id": "NC_BEGGAR_5", + "name": "Beggar", + "job_description": "I'm just trying to survive.", + "common": false, + "//": "This is the only beggar with some skills, sort of the leader.", + "bonus_str": { "rng": [ -2, 4 ] }, + "bonus_dex": { "rng": [ 0, 2 ] }, + "bonus_int": { "rng": [ -2, 2 ] }, + "bonus_per": { "rng": [ 0, 4 ] }, + "worn_override": "NC_BEGGAR_5_worn", + "carry_override": "EMPTY_GROUP", + "weapon_override": "EMPTY_GROUP", + "traits": [ { "trait": "FUR" }, { "trait": "OPTIMISTIC" }, { "trait": "LIGHTSTEP" }, { "trait": "CLAWS_RETRACT" } ], + "skills": [ + { "skill": "ALL", "level": { "sum": [ { "dice": [ 3, 2 ] }, { "constant": -3 } ] } }, + { "skill": "melee", "bonus": { "rng": [ 0, 5 ] } }, + { "skill": "unarmed", "bonus": { "rng": [ 0, 5 ] } } + ] + }, + { + "type": "item_group", + "id": "NC_BEGGAR_5_worn", + "subtype": "collection", + "items": [ + { "item": "jacket_jean" }, + { "item": "boxer_briefs" }, + { "item": "hoodie" }, + { "item": "pants_cargo" }, + { "item": "boots" }, + { "item": "socks" }, + { "item": "backpack" } + ] + }, { "type": "talk_topic", "id": "TALK_REFUGEE_BEGGAR_5", diff --git a/data/json/npcs/classes_uncommon.json b/data/json/npcs/classes_uncommon.json index 64339d167941c..79a551fb45d8a 100644 --- a/data/json/npcs/classes_uncommon.json +++ b/data/json/npcs/classes_uncommon.json @@ -1,213 +1,4 @@ [ - { - "type": "npc_class", - "id": "NC_BEGGAR_1", - "name": "Beggar", - "job_description": "I'm just trying to survive.", - "common": false, - "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", - "bonus_str": { "rng": [ -6, -2 ] }, - "bonus_dex": { "rng": [ -4, -1 ] }, - "bonus_int": { "rng": [ 1, 2 ] }, - "bonus_per": { "rng": [ -3, -1 ] }, - "worn_override": "NC_BEGGAR_1_worn", - "carry_override": "EMPTY_GROUP", - "weapon_override": "EMPTY_GROUP", - "traits": [ - { "trait": "GLASSJAW" }, - { "trait": "VEGETARIAN" }, - { "trait": "SQUEAMISH" }, - { "trait": "MOODSWINGS" }, - { "trait": "SLOWHEALER" }, - { "trait": "SLOWRUNNER" }, - { "trait": "DISORGANIZED" }, - { "trait": "BADKNEES" }, - { "trait": "FLIMSY3" }, - { "trait": "MYOPIC" }, - { "trait": "PACIFIST" }, - { "trait": "Exp_Teaching2" }, - { "group": "Appearance_demographics" } - ], - "skills": [ { "skill": "speech", "bonus": { "rng": [ 0, 3 ] } }, { "skill": "cooking", "bonus": { "rng": [ 0, 3 ] } } ] - }, - { - "type": "item_group", - "id": "NC_BEGGAR_1_worn", - "subtype": "collection", - "entries": [ - { "item": "blanket" }, - { "item": "jeans" }, - { "item": "sweater" }, - { "item": "bra" }, - { "item": "panties" }, - { "item": "socks" }, - { "item": "sneakers" } - ] - }, - { - "type": "npc_class", - "id": "NC_BEGGAR_2", - "name": "Beggar", - "job_description": "I'm just trying to survive.", - "common": false, - "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", - "bonus_str": { "rng": [ -3, -2 ] }, - "bonus_dex": { "rng": [ -5, -1 ] }, - "bonus_int": { "rng": [ -2, 0 ] }, - "bonus_per": { "rng": [ -6, -2 ] }, - "worn_override": "NC_BEGGAR_2_worn", - "carry_override": "EMPTY_GROUP", - "weapon_override": "EMPTY_GROUP", - "traits": [ - { "trait": "GLASSJAW" }, - { "trait": "ADDICTIVE" }, - { "trait": "HOARDER" }, - { "trait": "SLOWHEALER" }, - { "trait": "SLOWRUNNER" }, - { "trait": "CHEMIMBALANCE" }, - { "trait": "HEAVYSLEEPER" }, - { "trait": "FLIMSY2" }, - { "trait": "SCHIZOPHRENIC" }, - { "trait": "SLOWLEARNER" }, - { "trait": "PACIFIST" }, - { "group": "Appearance_demographics" } - ] - }, - { - "type": "item_group", - "id": "NC_BEGGAR_2_worn", - "subtype": "collection", - "entries": [ - { "item": "dinosuit" }, - { "item": "coat_winter" }, - { "item": "boxer_shorts" }, - { "item": "socks_wool" }, - { "item": "boots_winter" } - ] - }, - { - "type": "npc_class", - "id": "NC_BEGGAR_3", - "name": "Beggar", - "job_description": "I'm just trying to survive.", - "common": false, - "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", - "bonus_str": { "rng": [ -4, -1 ] }, - "bonus_dex": { "rng": [ -4, -1 ] }, - "bonus_int": { "rng": [ 2, 5 ] }, - "bonus_per": { "rng": [ 0, 3 ] }, - "worn_override": "NC_BEGGAR_3_worn", - "carry_override": "EMPTY_GROUP", - "weapon_override": "EMPTY_GROUP", - "traits": [ - { "trait": "SLOWHEALER2" }, - { "trait": "SLOWRUNNER" }, - { "trait": "HEAVYSLEEPER" }, - { "trait": "FLIMSY2" }, - { "trait": "FASTLEARNER" }, - { "trait": "PACIFIST" }, - { "trait": "Exp_Mycology2" }, - { "group": "Appearance_demographics" } - ] - }, - { - "type": "item_group", - "id": "NC_BEGGAR_3_worn", - "subtype": "collection", - "items": [ - { "item": "hoodie" }, - { "item": "jacket_evac" }, - { "item": "jeans" }, - { "item": "panties" }, - { "item": "camisole" }, - { "item": "bra" }, - { "item": "socks" }, - { "item": "lowtops" }, - { "item": "gloves_light" } - ] - }, - { - "type": "npc_class", - "id": "NC_BEGGAR_4", - "name": "Beggar", - "job_description": "I'm just trying to survive.", - "common": false, - "//": "All the beggars have been camping inside the evac shelter because they're too weak and unskilled to make it on their own.", - "bonus_str": { "rng": [ -4, -1 ] }, - "bonus_dex": { "rng": [ -4, -1 ] }, - "bonus_int": { "rng": [ -6, -2 ] }, - "bonus_per": { "rng": [ -3, -1 ] }, - "worn_override": "NC_BEGGAR_4_worn", - "carry_override": "EMPTY_GROUP", - "weapon_override": "EMPTY_GROUP", - "traits": [ - { "trait": "GLASSJAW" }, - { "trait": "ASTHMA" }, - { "trait": "SLOWHEALER3" }, - { "trait": "SLOWRUNNER" }, - { "trait": "HEAVYSLEEPER" }, - { "trait": "FLIMSY3" }, - { "trait": "WEAKSTOMACH" }, - { "trait": "MYOPIC" }, - { "trait": "HYPEROPIC" }, - { "trait": "JITTERY" }, - { "trait": "TRIGGERHAPPY" }, - { "trait": "SMELLY" }, - { "trait": "PROJUNK" }, - { "trait": "BADBACK" }, - { "trait": "BADKNEES" }, - { "trait": "BADCARDIO" }, - { "group": "Appearance_demographics" } - ] - }, - { - "type": "item_group", - "id": "NC_BEGGAR_4_worn", - "subtype": "collection", - "items": [ - { "item": "house_coat" }, - { "item": "briefs" }, - { "item": "tank_top" }, - { "item": "long_underpants" }, - { "item": "slippers" }, - { "item": "socks" } - ] - }, - { - "type": "npc_class", - "id": "NC_BEGGAR_5", - "name": "Beggar", - "job_description": "I'm just trying to survive.", - "common": false, - "//": "This is the only beggar with some skills, sort of the leader.", - "bonus_str": { "rng": [ -2, 4 ] }, - "bonus_dex": { "rng": [ 0, 2 ] }, - "bonus_int": { "rng": [ -2, 2 ] }, - "bonus_per": { "rng": [ 0, 4 ] }, - "worn_override": "NC_BEGGAR_5_worn", - "carry_override": "EMPTY_GROUP", - "weapon_override": "EMPTY_GROUP", - "traits": [ { "trait": "FUR" }, { "trait": "OPTIMISTIC" }, { "trait": "LIGHTSTEP" }, { "trait": "CLAWS_RETRACT" } ], - "skills": [ - { "skill": "ALL", "level": { "sum": [ { "dice": [ 3, 2 ] }, { "constant": -3 } ] } }, - { "skill": "melee", "bonus": { "rng": [ 0, 5 ] } }, - { "skill": "unarmed", "bonus": { "rng": [ 0, 5 ] } } - ] - }, - { - "type": "item_group", - "id": "NC_BEGGAR_5_worn", - "subtype": "collection", - "items": [ - { "item": "jacket_jean" }, - { "item": "boxer_briefs" }, - { "item": "hoodie" }, - { "item": "pants_cargo" }, - { "item": "boots" }, - { "item": "socks" }, - { "item": "backpack" } - ] - }, { "type": "npc_class", "id": "NC_SCAVENGER_MERC", diff --git a/data/json/npcs/npc.json b/data/json/npcs/npc.json index 8851834290fc4..4fac2a44d4d57 100644 --- a/data/json/npcs/npc.json +++ b/data/json/npcs/npc.json @@ -421,71 +421,6 @@ "chat": "TALK_DONE", "faction": "wasteland_scavengers" }, - { - "type": "npc", - "id": "refugee_beggar1", - "//": "Hungry beggar in the refugee center.", - "name_unique": "Reena Sandhu", - "gender": "female", - "name_suffix": "beggar", - "class": "NC_BEGGAR_1", - "attitude": 0, - "mission": 7, - "chat": "TALK_REFUGEE_BEGGAR_1", - "faction": "lobby_beggars" - }, - { - "type": "npc", - "id": "refugee_beggar2", - "//": "Schizophrenic beggar in the refugee center.", - "name_unique": "Dino Dave", - "gender": "male", - "name_suffix": "beggar", - "class": "NC_BEGGAR_2", - "attitude": 0, - "mission": 7, - "chat": "TALK_REFUGEE_BEGGAR_2", - "faction": "lobby_beggars" - }, - { - "type": "npc", - "id": "refugee_beggar3", - "//": "Angry beggar in the refugee center.", - "name_unique": "Luo Meizhen", - "gender": "female", - "name_suffix": "beggar", - "class": "NC_BEGGAR_3", - "attitude": 0, - "mission": 7, - "chat": "TALK_REFUGEE_BEGGAR_3", - "faction": "lobby_beggars" - }, - { - "type": "npc", - "id": "refugee_beggar4", - "//": "Sickly beggar in the refugee center.", - "name_unique": "Brandon Garder", - "gender": "male", - "name_suffix": "beggar", - "class": "NC_BEGGAR_4", - "attitude": 0, - "mission": 7, - "chat": "TALK_REFUGEE_BEGGAR_4", - "faction": "lobby_beggars" - }, - { - "type": "npc", - "id": "refugee_beggar5", - "//": "Mutant beggar in the refugee center.", - "name_unique": "Yusuke Taylor", - "gender": "male", - "name_suffix": "beggar", - "class": "NC_BEGGAR_5", - "attitude": 0, - "mission": 7, - "chat": "TALK_REFUGEE_BEGGAR_5", - "faction": "lobby_beggars" - }, { "type": "npc", "id": "survivor_chef", diff --git a/data/json/npcs/talk_tags.json b/data/json/npcs/talk_tags.json index 898042b3f31e7..9eccbe9bb7886 100644 --- a/data/json/npcs/talk_tags.json +++ b/data/json/npcs/talk_tags.json @@ -477,6 +477,21 @@ "Thanks, !" ] }, + { + "type": "snippet", + "category": "", + "text": [ + "Hey! I saw you take that ! Drop it. Now.", + "You best be dropping what you just picked up right now .", + "I've got eyes, you thief!", + "Hey! That belongs to us! Drop it.", + ", I've seen a thief!", + "I saw that! Drop what you just stole!", + "Thieves will not last long around me , please drop that.", + "Consider this a warning , thieves will not be tolerated, drop it.", + "You think I'm blind ? Don't touch our stuff." + ] + }, { "type": "snippet", "category": "", diff --git a/data/json/overmap/multitile_city_buildings.json b/data/json/overmap/multitile_city_buildings.json index 8dfb092e22b66..f0b25aaa9ce27 100644 --- a/data/json/overmap/multitile_city_buildings.json +++ b/data/json/overmap/multitile_city_buildings.json @@ -59,6 +59,15 @@ { "point": [ 0, 0, 3 ], "overmap": "church_roof_1_north" } ] }, + { + "type": "city_building", + "id": "cs_tire_shop", + "locations": [ "land" ], + "overmaps": [ + { "point": [ 0, 0, 0 ], "overmap": "cs_tire_shop_north" }, + { "point": [ 0, 0, 1 ], "overmap": "cs_tire_shop_roof_north" } + ] + }, { "type": "city_building", "id": "s_bookstore", @@ -605,125 +614,186 @@ { "point": [ 8, 9, 0 ], "overmap": "mall_a_1_south" }, { "point": [ 7, 9, 0 ], "overmap": "mall_a_2_south" }, { "point": [ 6, 9, 0 ], "overmap": "mall_a_3_south" }, - { "point": [ 6, 9, 1 ], "overmap": "mall_a_3_roof_south" }, + { "point": [ 6, 9, 1 ], "overmap": "mall_b_3_south" }, + { "point": [ 6, 9, 2 ], "overmap": "mall_a_3_roof_south" }, + { "point": [ 6, 9, 3 ], "overmap": "mall_upper_roof_3_south" }, { "point": [ 5, 9, 0 ], "overmap": "mall_a_4_south" }, - { "point": [ 5, 9, 1 ], "overmap": "mall_a_4_roof_south" }, + { "point": [ 5, 9, 1 ], "overmap": "mall_b_4_south" }, + { "point": [ 5, 9, 2 ], "overmap": "mall_a_4_roof_south" }, + { "point": [ 5, 9, 3 ], "overmap": "mall_upper_roof_4_south" }, { "point": [ 4, 9, 0 ], "overmap": "mall_a_5_south" }, - { "point": [ 4, 9, 1 ], "overmap": "mall_a_5_roof_south" }, + { "point": [ 4, 9, 1 ], "overmap": "mall_b_5_south" }, + { "point": [ 4, 9, 2 ], "overmap": "mall_a_5_roof_south" }, { "point": [ 3, 9, 0 ], "overmap": "mall_a_6_south" }, { "point": [ 2, 9, 0 ], "overmap": "mall_a_7_south" }, { "point": [ 1, 9, 0 ], "overmap": "mall_a_8_south" }, { "point": [ 0, 9, 0 ], "overmap": "mall_a_9_south" }, { "point": [ 8, 8, 0 ], "overmap": "mall_a_10_south" }, - { "point": [ 8, 8, 1 ], "overmap": "mall_a_10_roof_south" }, + { "point": [ 8, 8, 1 ], "overmap": "mall_b_10_south" }, + { "point": [ 8, 8, 2 ], "overmap": "mall_a_10_roof_south" }, { "point": [ 7, 8, 0 ], "overmap": "mall_a_11_south" }, - { "point": [ 7, 8, 1 ], "overmap": "mall_a_11_roof_south" }, + { "point": [ 7, 8, 1 ], "overmap": "mall_b_11_south" }, + { "point": [ 7, 8, 2 ], "overmap": "mall_a_11_roof_south" }, { "point": [ 6, 8, 0 ], "overmap": "mall_a_12_south" }, - { "point": [ 6, 8, 1 ], "overmap": "mall_a_12_roof_south" }, + { "point": [ 6, 8, 1 ], "overmap": "mall_b_12_south" }, + { "point": [ 6, 8, 2 ], "overmap": "mall_a_12_roof_south" }, + { "point": [ 6, 8, 3 ], "overmap": "mall_upper_roof_12_south" }, { "point": [ 5, 8, 0 ], "overmap": "mall_a_13_south" }, - { "point": [ 5, 8, 1 ], "overmap": "mall_a_13_roof_south" }, + { "point": [ 5, 8, 1 ], "overmap": "mall_b_13_south" }, + { "point": [ 5, 8, 2 ], "overmap": "mall_a_13_roof_south" }, + { "point": [ 5, 8, 3 ], "overmap": "mall_upper_roof_13_south" }, { "point": [ 4, 8, 0 ], "overmap": "mall_a_14_south" }, - { "point": [ 4, 8, 1 ], "overmap": "mall_a_14_roof_south" }, + { "point": [ 4, 8, 1 ], "overmap": "mall_b_14_south" }, + { "point": [ 4, 8, 2 ], "overmap": "mall_a_14_roof_south" }, { "point": [ 3, 8, 0 ], "overmap": "mall_a_15_south" }, { "point": [ 2, 8, 0 ], "overmap": "mall_a_16_south" }, { "point": [ 1, 8, 0 ], "overmap": "mall_a_17_south" }, { "point": [ 0, 8, 0 ], "overmap": "mall_a_18_south" }, { "point": [ 8, 7, 0 ], "overmap": "mall_a_19_south" }, - { "point": [ 8, 7, 1 ], "overmap": "mall_a_19_roof_south" }, + { "point": [ 8, 7, 1 ], "overmap": "mall_b_19_south" }, + { "point": [ 8, 7, 2 ], "overmap": "mall_a_19_roof_south" }, { "point": [ 7, 7, 0 ], "overmap": "mall_a_20_south" }, - { "point": [ 7, 7, 1 ], "overmap": "mall_a_20_roof_south" }, + { "point": [ 7, 7, 1 ], "overmap": "mall_b_20_south" }, + { "point": [ 7, 7, 2 ], "overmap": "mall_a_20_roof_south" }, { "point": [ 6, 7, 0 ], "overmap": "mall_a_21_south" }, - { "point": [ 6, 7, 1 ], "overmap": "mall_a_21_roof_south" }, + { "point": [ 6, 7, 1 ], "overmap": "mall_b_21_south" }, + { "point": [ 6, 7, 2 ], "overmap": "mall_a_21_roof_south" }, { "point": [ 5, 7, 0 ], "overmap": "mall_a_22_south" }, - { "point": [ 5, 7, 1 ], "overmap": "mall_a_22_roof_south" }, + { "point": [ 5, 7, 1 ], "overmap": "mall_b_22_south" }, + { "point": [ 5, 7, 2 ], "overmap": "mall_a_22_roof_south" }, { "point": [ 4, 7, 0 ], "overmap": "mall_a_23_south" }, - { "point": [ 4, 7, 1 ], "overmap": "mall_a_23_roof_south" }, + { "point": [ 4, 7, 1 ], "overmap": "mall_b_23_south" }, + { "point": [ 4, 7, 2 ], "overmap": "mall_a_23_roof_south" }, { "point": [ 3, 7, 0 ], "overmap": "mall_a_24_south" }, - { "point": [ 3, 7, 1 ], "overmap": "mall_a_24_roof_south" }, + { "point": [ 3, 7, 1 ], "overmap": "mall_b_24_south" }, + { "point": [ 3, 7, 2 ], "overmap": "mall_a_24_roof_south" }, { "point": [ 2, 7, 0 ], "overmap": "mall_a_25_south" }, - { "point": [ 2, 7, 1 ], "overmap": "mall_a_25_roof_south" }, + { "point": [ 2, 7, 1 ], "overmap": "mall_b_25_south" }, + { "point": [ 2, 7, 2 ], "overmap": "mall_a_25_roof_south" }, { "point": [ 1, 7, 0 ], "overmap": "mall_a_26_south" }, - { "point": [ 1, 7, 1 ], "overmap": "mall_a_26_roof_south" }, + { "point": [ 1, 7, 1 ], "overmap": "mall_b_26_south" }, + { "point": [ 1, 7, 2 ], "overmap": "mall_a_26_roof_south" }, { "point": [ 0, 7, 0 ], "overmap": "mall_a_27_south" }, { "point": [ 8, 6, 0 ], "overmap": "mall_a_28_south" }, { "point": [ 7, 6, 0 ], "overmap": "mall_a_29_south" }, - { "point": [ 7, 6, 1 ], "overmap": "mall_a_29_roof_south" }, + { "point": [ 7, 6, 1 ], "overmap": "mall_b_29_south" }, + { "point": [ 7, 6, 2 ], "overmap": "mall_a_29_roof_south" }, { "point": [ 6, 6, 0 ], "overmap": "mall_a_30_south" }, - { "point": [ 6, 6, 1 ], "overmap": "mall_a_30_roof_south" }, + { "point": [ 6, 6, 1 ], "overmap": "mall_b_30_south" }, + { "point": [ 6, 6, 2 ], "overmap": "mall_a_30_roof_south" }, { "point": [ 5, 6, 0 ], "overmap": "mall_a_31_south" }, - { "point": [ 5, 6, 1 ], "overmap": "mall_a_31_roof_south" }, + { "point": [ 5, 6, 1 ], "overmap": "mall_b_31_south" }, + { "point": [ 5, 6, 2 ], "overmap": "mall_a_31_roof_south" }, { "point": [ 4, 6, 0 ], "overmap": "mall_a_32_south" }, - { "point": [ 4, 6, 1 ], "overmap": "mall_a_32_roof_south" }, + { "point": [ 4, 6, 1 ], "overmap": "mall_b_32_south" }, + { "point": [ 4, 6, 2 ], "overmap": "mall_a_32_roof_south" }, { "point": [ 3, 6, 0 ], "overmap": "mall_a_33_south" }, - { "point": [ 3, 6, 1 ], "overmap": "mall_a_33_roof_south" }, + { "point": [ 3, 6, 1 ], "overmap": "mall_b_33_south" }, + { "point": [ 3, 6, 2 ], "overmap": "mall_a_33_roof_south" }, { "point": [ 2, 6, 0 ], "overmap": "mall_a_34_south" }, - { "point": [ 2, 6, 1 ], "overmap": "mall_a_34_roof_south" }, + { "point": [ 2, 6, 1 ], "overmap": "mall_b_34_south" }, + { "point": [ 2, 6, 2 ], "overmap": "mall_a_34_roof_south" }, + { "point": [ 2, 6, 3 ], "overmap": "mall_upper_roof_34_south" }, { "point": [ 1, 6, 0 ], "overmap": "mall_a_35_south" }, - { "point": [ 1, 6, 1 ], "overmap": "mall_a_35_roof_south" }, + { "point": [ 1, 6, 1 ], "overmap": "mall_b_35_south" }, + { "point": [ 1, 6, 2 ], "overmap": "mall_a_35_roof_south" }, + { "point": [ 1, 6, 3 ], "overmap": "mall_upper_roof_35_south" }, { "point": [ 0, 6, 0 ], "overmap": "mall_a_36_south" }, { "point": [ 8, 5, 0 ], "overmap": "mall_a_37_south" }, { "point": [ 7, 5, 0 ], "overmap": "mall_a_38_south" }, - { "point": [ 7, 5, 1 ], "overmap": "mall_a_38_roof_south" }, + { "point": [ 7, 5, 1 ], "overmap": "mall_b_38_south" }, + { "point": [ 7, 5, 2 ], "overmap": "mall_a_38_roof_south" }, { "point": [ 6, 5, 0 ], "overmap": "mall_a_39_south" }, - { "point": [ 6, 5, 1 ], "overmap": "mall_a_39_roof_south" }, + { "point": [ 6, 5, 1 ], "overmap": "mall_b_39_south" }, + { "point": [ 6, 5, 2 ], "overmap": "mall_a_39_roof_south" }, { "point": [ 5, 5, 0 ], "overmap": "mall_a_40_south" }, - { "point": [ 5, 5, 1 ], "overmap": "mall_a_40_roof_south" }, + { "point": [ 5, 5, 1 ], "overmap": "mall_b_40_south" }, + { "point": [ 5, 5, 2 ], "overmap": "mall_a_40_roof_south" }, { "point": [ 4, 5, 0 ], "overmap": "mall_a_41_south" }, - { "point": [ 4, 5, 1 ], "overmap": "mall_a_41_roof_south" }, + { "point": [ 4, 5, 1 ], "overmap": "mall_b_41_south" }, + { "point": [ 4, 5, 2 ], "overmap": "mall_a_41_roof_south" }, { "point": [ 3, 5, 0 ], "overmap": "mall_a_42_south" }, - { "point": [ 3, 5, 1 ], "overmap": "mall_a_42_roof_south" }, + { "point": [ 3, 5, 1 ], "overmap": "mall_b_42_south" }, + { "point": [ 3, 5, 2 ], "overmap": "mall_a_42_roof_south" }, { "point": [ 2, 5, 0 ], "overmap": "mall_a_43_south" }, - { "point": [ 2, 5, 1 ], "overmap": "mall_a_43_roof_south" }, + { "point": [ 2, 5, 1 ], "overmap": "mall_b_43_south" }, + { "point": [ 2, 5, 2 ], "overmap": "mall_a_43_roof_south" }, { "point": [ 1, 5, 0 ], "overmap": "mall_a_44_south" }, - { "point": [ 1, 5, 1 ], "overmap": "mall_a_44_roof_south" }, + { "point": [ 1, 5, 1 ], "overmap": "mall_b_44_south" }, + { "point": [ 1, 5, 2 ], "overmap": "mall_a_44_roof_south" }, { "point": [ 0, 5, 0 ], "overmap": "mall_a_45_south" }, { "point": [ 8, 4, 0 ], "overmap": "mall_a_46_south" }, { "point": [ 7, 4, 0 ], "overmap": "mall_a_47_south" }, - { "point": [ 7, 4, 1 ], "overmap": "mall_a_47_roof_south" }, + { "point": [ 7, 4, 1 ], "overmap": "mall_b_47_south" }, + { "point": [ 7, 4, 2 ], "overmap": "mall_a_47_roof_south" }, { "point": [ 6, 4, 0 ], "overmap": "mall_a_48_south" }, - { "point": [ 6, 4, 1 ], "overmap": "mall_a_48_roof_south" }, + { "point": [ 6, 4, 1 ], "overmap": "mall_b_48_south" }, + { "point": [ 6, 4, 2 ], "overmap": "mall_a_48_roof_south" }, + { "point": [ 6, 4, 3 ], "overmap": "mall_upper_roof_48_south" }, { "point": [ 5, 4, 0 ], "overmap": "mall_a_49_south" }, - { "point": [ 5, 4, 1 ], "overmap": "mall_a_49_roof_south" }, + { "point": [ 5, 4, 1 ], "overmap": "mall_b_49_south" }, + { "point": [ 5, 4, 2 ], "overmap": "mall_a_49_roof_south" }, + { "point": [ 5, 4, 3 ], "overmap": "mall_upper_roof_49_south" }, { "point": [ 4, 4, 0 ], "overmap": "mall_a_50_south" }, - { "point": [ 4, 4, 1 ], "overmap": "mall_a_50_roof_south" }, + { "point": [ 4, 4, 1 ], "overmap": "mall_b_50_south" }, + { "point": [ 4, 4, 2 ], "overmap": "mall_a_50_roof_south" }, + { "point": [ 4, 4, 3 ], "overmap": "mall_upper_roof_50_south" }, { "point": [ 3, 4, 0 ], "overmap": "mall_a_51_south" }, - { "point": [ 3, 4, 1 ], "overmap": "mall_a_51_roof_south" }, + { "point": [ 3, 4, 1 ], "overmap": "mall_b_51_south" }, + { "point": [ 3, 4, 2 ], "overmap": "mall_a_51_roof_south" }, + { "point": [ 3, 4, 3 ], "overmap": "mall_upper_roof_51_south" }, { "point": [ 2, 4, 0 ], "overmap": "mall_a_52_south" }, - { "point": [ 2, 4, 1 ], "overmap": "mall_a_52_roof_south" }, + { "point": [ 2, 4, 1 ], "overmap": "mall_b_52_south" }, + { "point": [ 2, 4, 2 ], "overmap": "mall_a_52_roof_south" }, { "point": [ 1, 4, 0 ], "overmap": "mall_a_53_south" }, - { "point": [ 1, 4, 1 ], "overmap": "mall_a_53_roof_south" }, + { "point": [ 1, 4, 1 ], "overmap": "mall_b_53_south" }, + { "point": [ 1, 4, 2 ], "overmap": "mall_a_53_roof_south" }, { "point": [ 0, 4, 0 ], "overmap": "mall_a_54_south" }, { "point": [ 8, 3, 0 ], "overmap": "mall_a_55_south" }, { "point": [ 7, 3, 0 ], "overmap": "mall_a_56_south" }, - { "point": [ 7, 3, 1 ], "overmap": "mall_a_56_roof_south" }, + { "point": [ 7, 3, 1 ], "overmap": "mall_b_56_south" }, + { "point": [ 7, 3, 2 ], "overmap": "mall_a_56_roof_south" }, { "point": [ 6, 3, 0 ], "overmap": "mall_a_57_south" }, - { "point": [ 6, 3, 1 ], "overmap": "mall_a_57_roof_south" }, + { "point": [ 6, 3, 1 ], "overmap": "mall_b_57_south" }, + { "point": [ 6, 3, 2 ], "overmap": "mall_a_57_roof_south" }, { "point": [ 5, 3, 0 ], "overmap": "mall_a_58_south" }, - { "point": [ 5, 3, 1 ], "overmap": "mall_a_58_roof_south" }, + { "point": [ 5, 3, 1 ], "overmap": "mall_b_58_south" }, + { "point": [ 5, 3, 2 ], "overmap": "mall_a_58_roof_south" }, { "point": [ 4, 3, 0 ], "overmap": "mall_a_59_south" }, - { "point": [ 4, 3, 1 ], "overmap": "mall_a_59_roof_south" }, + { "point": [ 4, 3, 1 ], "overmap": "mall_b_59_south" }, + { "point": [ 4, 3, 2 ], "overmap": "mall_a_59_roof_south" }, { "point": [ 3, 3, 0 ], "overmap": "mall_a_60_south" }, - { "point": [ 3, 3, 1 ], "overmap": "mall_a_60_roof_south" }, + { "point": [ 3, 3, 1 ], "overmap": "mall_b_60_south" }, + { "point": [ 3, 3, 2 ], "overmap": "mall_a_60_roof_south" }, { "point": [ 2, 3, 0 ], "overmap": "mall_a_61_south" }, - { "point": [ 2, 3, 1 ], "overmap": "mall_a_61_roof_south" }, + { "point": [ 2, 3, 1 ], "overmap": "mall_b_61_south" }, + { "point": [ 2, 3, 2 ], "overmap": "mall_a_61_roof_south" }, { "point": [ 1, 3, 0 ], "overmap": "mall_a_62_south" }, - { "point": [ 1, 3, 1 ], "overmap": "mall_a_62_roof_south" }, + { "point": [ 1, 3, 1 ], "overmap": "mall_b_62_south" }, + { "point": [ 1, 3, 2 ], "overmap": "mall_a_62_roof_south" }, { "point": [ 0, 3, 0 ], "overmap": "mall_a_63_south" }, { "point": [ 8, 2, 0 ], "overmap": "mall_a_64_south" }, { "point": [ 7, 2, 0 ], "overmap": "mall_a_65_south" }, - { "point": [ 7, 2, 1 ], "overmap": "mall_a_65_roof_south" }, + { "point": [ 7, 2, 1 ], "overmap": "mall_b_65_south" }, + { "point": [ 7, 2, 2 ], "overmap": "mall_a_65_roof_south" }, { "point": [ 6, 2, 0 ], "overmap": "mall_a_66_south" }, - { "point": [ 6, 2, 1 ], "overmap": "mall_a_66_roof_south" }, + { "point": [ 6, 2, 1 ], "overmap": "mall_b_66_south" }, + { "point": [ 6, 2, 2 ], "overmap": "mall_a_66_roof_south" }, { "point": [ 5, 2, 0 ], "overmap": "mall_a_67_south" }, - { "point": [ 5, 2, 1 ], "overmap": "mall_a_67_roof_south" }, + { "point": [ 5, 2, 1 ], "overmap": "mall_b_67_south" }, + { "point": [ 5, 2, 2 ], "overmap": "mall_a_67_roof_south" }, { "point": [ 4, 2, 0 ], "overmap": "mall_a_68_south" }, - { "point": [ 4, 2, 1 ], "overmap": "mall_a_68_roof_south" }, + { "point": [ 4, 2, 1 ], "overmap": "mall_b_68_south" }, + { "point": [ 4, 2, 2 ], "overmap": "mall_a_68_roof_south" }, { "point": [ 3, 2, 0 ], "overmap": "mall_a_69_south" }, - { "point": [ 3, 2, 1 ], "overmap": "mall_a_69_roof_south" }, + { "point": [ 3, 2, 1 ], "overmap": "mall_b_69_south" }, + { "point": [ 3, 2, 2 ], "overmap": "mall_a_69_roof_south" }, { "point": [ 2, 2, 0 ], "overmap": "mall_a_70_south" }, - { "point": [ 2, 2, 1 ], "overmap": "mall_a_70_roof_south" }, + { "point": [ 2, 2, 1 ], "overmap": "mall_b_70_south" }, + { "point": [ 2, 2, 2 ], "overmap": "mall_a_70_roof_south" }, { "point": [ 1, 2, 0 ], "overmap": "mall_a_71_south" }, - { "point": [ 1, 2, 1 ], "overmap": "mall_a_71_roof_south" }, + { "point": [ 1, 2, 1 ], "overmap": "mall_b_71_south" }, + { "point": [ 1, 2, 2 ], "overmap": "mall_a_71_roof_south" }, { "point": [ 0, 2, 0 ], "overmap": "mall_a_72_south" }, { "point": [ 8, 1, 0 ], "overmap": "mall_a_73_south" }, { "point": [ 7, 1, 0 ], "overmap": "mall_a_74_south" }, diff --git a/data/json/overmap_terrain_commercial.json b/data/json/overmap_terrain_commercial.json index 1fb1af176f79f..70073bb45ef6e 100644 --- a/data/json/overmap_terrain_commercial.json +++ b/data/json/overmap_terrain_commercial.json @@ -1733,6 +1733,14 @@ "sym": "O", "color": "white" }, + { + "type": "overmap_terrain", + "id": "cs_tire_shop_roof", + "copy-from": "generic_city_building", + "name": "tire shop roof", + "sym": "O", + "color": "white" + }, { "type": "overmap_terrain", "id": "headshop", diff --git a/data/json/overmap_terrain_mall.json b/data/json/overmap_terrain_mall.json index 329856da12c09..5f3653866d6eb 100644 --- a/data/json/overmap_terrain_mall.json +++ b/data/json/overmap_terrain_mall.json @@ -31,6 +31,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_3", + "name": "mall - loading bay", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_3_roof", @@ -39,6 +47,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_3", + "name": "mall - loading bay roof", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_4", @@ -47,6 +63,22 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_4", + "name": "mall - loading bay roof", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, + { + "type": "overmap_terrain", + "id": "mall_b_4", + "name": "mall - utilities", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_4_roof", @@ -63,6 +95,14 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_5", + "name": "mall - utilities", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_5_roof", @@ -111,6 +151,14 @@ "sym": "โ”‚", "color": "dark_gray" }, + { + "type": "overmap_terrain", + "id": "mall_b_10", + "name": "road", + "copy-from": "generic_mall", + "sym": "โ”‚", + "color": "dark_gray" + }, { "type": "overmap_terrain", "id": "mall_a_10_roof", @@ -126,6 +174,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_11", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_11_roof", @@ -140,6 +195,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_12", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_12_roof", @@ -147,6 +209,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_12", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_13", @@ -154,6 +223,20 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_13", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, + { + "type": "overmap_terrain", + "id": "mall_b_13", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_13_roof", @@ -169,6 +252,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_14", + "name": "mall - entrance", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_14_roof", @@ -217,6 +308,14 @@ "sym": "โ”‚", "color": "dark_gray" }, + { + "type": "overmap_terrain", + "id": "mall_b_19", + "name": "road", + "copy-from": "generic_mall", + "sym": "โ”‚", + "color": "dark_gray" + }, { "type": "overmap_terrain", "id": "mall_a_19_roof", @@ -233,6 +332,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_20", + "name": "mall - food court roof", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_20_roof", @@ -248,6 +355,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_21", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_21_roof", @@ -262,6 +376,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_22", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_22_roof", @@ -276,6 +397,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_23", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_23_roof", @@ -290,6 +418,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_24", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_24_roof", @@ -304,6 +439,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_25", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_25_roof", @@ -318,6 +460,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_26", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_26_roof", @@ -349,6 +498,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_29", + "name": "mall - food court", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_29_roof", @@ -364,6 +521,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_30", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_30_roof", @@ -378,6 +542,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_31", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_31_roof", @@ -392,6 +563,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_32", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_32_roof", @@ -406,6 +584,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_33", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_33_roof", @@ -420,6 +605,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_34", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_34_roof", @@ -427,6 +619,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_34", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_35", @@ -434,6 +633,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_35", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_35_roof", @@ -441,6 +647,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_35", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_36", @@ -464,6 +677,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_38", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_38_roof", @@ -478,6 +698,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_39", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_39_roof", @@ -492,6 +719,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_40", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_40_roof", @@ -506,6 +740,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_41", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_41_roof", @@ -520,6 +761,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_42", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_42_roof", @@ -534,6 +782,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_43", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_43_roof", @@ -548,6 +803,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_44", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_44_roof", @@ -579,6 +841,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_47", + "name": "mall - entrance", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_47_roof", @@ -594,6 +864,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_48", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_48_roof", @@ -601,6 +878,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_48", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_49", @@ -608,6 +892,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_49", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_49_roof", @@ -615,6 +906,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_49", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_50", @@ -622,6 +920,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_50", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_50_roof", @@ -629,6 +934,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_50", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_51", @@ -636,6 +948,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_51", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_51_roof", @@ -643,6 +962,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_upper_roof_51", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_52", @@ -650,6 +976,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_52", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_52_roof", @@ -665,6 +998,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_53", + "name": "mall - entrance", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_53_roof", @@ -696,6 +1037,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_56", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_56_roof", @@ -710,6 +1058,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_57", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_57_roof", @@ -724,6 +1079,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_58", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_58_roof", @@ -738,6 +1100,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_59", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_59_roof", @@ -752,6 +1121,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_60", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_60_roof", @@ -766,6 +1142,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_61", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_61_roof", @@ -780,6 +1163,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_62", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_62_roof", @@ -810,6 +1200,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_65", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_65_roof", @@ -824,6 +1221,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_66", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_66_roof", @@ -838,6 +1242,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_67", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_67_roof", @@ -853,6 +1264,14 @@ "sym": "M", "color": "i_light_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_68", + "name": "mall - entrance", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_light_red" + }, { "type": "overmap_terrain", "id": "mall_a_68_roof", @@ -868,6 +1287,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_69", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_69_roof", @@ -882,6 +1308,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_70", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_70_roof", @@ -896,6 +1329,13 @@ "sym": "M", "color": "i_red" }, + { + "type": "overmap_terrain", + "id": "mall_b_71", + "copy-from": "generic_mall", + "sym": "M", + "color": "i_red" + }, { "type": "overmap_terrain", "id": "mall_a_71_roof", diff --git a/data/json/player_activities.json b/data/json/player_activities.json index bb95649ded7ef..f0a26b2a8bfbd 100644 --- a/data/json/player_activities.json +++ b/data/json/player_activities.json @@ -582,6 +582,16 @@ "based_on": "neither", "no_resume": true }, + { + "id": "ACT_STUDY_SPELL", + "type": "activity_type", + "activity_level": "NO_EXERCISE", + "stop_phrase": "Stop studying?", + "suspendable": false, + "rooted": true, + "based_on": "time", + "no_resume": true + }, { "id": "ACT_CONSUME_DRINK_MENU", "type": "activity_type", diff --git a/data/json/professions.json b/data/json/professions.json index 4bda786f68693..559b35b990ad0 100644 --- a/data/json/professions.json +++ b/data/json/professions.json @@ -11,6 +11,14 @@ "id": "army_mags_mp5", "entries": [ { "item": "mp5mag", "ammo-item": "9mm", "charges": 30 }, { "item": "mp5mag", "ammo-item": "9mm", "charges": 30 } ] }, + { + "type": "item_group", + "subtype": "collection", + "id": "charged_cell_phone", + "ammo": 100, + "magazine": 100, + "entries": [ { "item": "cell_phone" } ] + }, { "type": "item_group", "subtype": "collection", @@ -176,26 +184,28 @@ { "level": 1, "name": "cooking" } ], "items": { - "both": [ - "jeans", - "tshirt", - "gloves_light", - "hat_ball", - "duffelbag", - "backpack", - "long_underpants", - "boots", - "socks_wool", - "socks", - "hoodie", - "folding_poncho_on", - "knit_scarf", - "jug_plastic", - "can_beans", - "pockknife", - "cell_phone", - "matches" - ], + "both": { + "items": [ + "jeans", + "tshirt", + "gloves_light", + "hat_ball", + "duffelbag", + "backpack", + "long_underpants", + "boots", + "socks_wool", + "socks", + "hoodie", + "folding_poncho_on", + "knit_scarf", + "jug_plastic", + "can_beans", + "pockknife", + "matches" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_briefs" ], "female": [ "bra", "panties" ] } @@ -261,19 +271,21 @@ "description": "Some would say that there's nothing particularly notable about you. But you've survived, and that's more than most could say right now.", "points": 0, "items": { - "both": [ - "jeans", - "longshirt", - "socks", - "coat_winter", - "boots_winter", - "knit_scarf", - "pockknife", - "water_clean", - "matches", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ + "jeans", + "longshirt", + "socks", + "coat_winter", + "boots_winter", + "knit_scarf", + "pockknife", + "water_clean", + "matches", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -294,7 +306,10 @@ { "level": 2, "name": "fabrication" } ], "items": { - "both": [ "pants", "tshirt", "socks", "sweater", "sneakers", "multitool", "water_clean", "matches", "cell_phone", "wristwatch" ], + "both": { + "items": [ "pants", "tshirt", "socks", "sweater", "sneakers", "multitool", "water_clean", "matches", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] }, @@ -344,19 +359,21 @@ "//": "Tailoring kit makes an already decent class for careful folks much more powerful.", "skills": [ { "level": 4, "name": "tailor" } ], "items": { - "both": [ - "polo_shirt", - "blazer", - "pants", - "socks", - "dress_shoes", - "knit_scarf", - "tailors_kit", - "thread", - "scissors", - "wristwatch", - "cell_phone" - ], + "both": { + "items": [ + "polo_shirt", + "blazer", + "pants", + "socks", + "dress_shoes", + "knit_scarf", + "tailors_kit", + "thread", + "scissors", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -370,8 +387,8 @@ "skills": [ { "name": "cooking", "level": 4 } ], "items": { "both": { - "items": [ "hat_chef", "jacket_chef", "pants_checkered", "socks", "dress_shoes", "cell_phone" ], - "entries": [ { "item": "knife_butcher", "container-item": "sheath" } ] + "items": [ "hat_chef", "jacket_chef", "pants_checkered", "socks", "dress_shoes" ], + "entries": [ { "group": "charged_cell_phone" }, { "item": "knife_butcher", "container-item": "sheath" } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] @@ -448,12 +465,11 @@ "wrench", "duct_tape", "screwdriver", - "cell_phone", "wristwatch", "mag_cars", "welder" ], - "entries": [ { "item": "goggles_welding", "custom-flags": [ "no_auto_equip" ] } ] + "entries": [ { "item": "goggles_welding", "custom-flags": [ "no_auto_equip" ] }, { "group": "charged_cell_phone" } ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "boy_shorts" ] @@ -484,11 +500,10 @@ "tobacco", "rolling_paper", "switchblade", - "cell_phone", "wristwatch", "picklocks" ], - "entries": [ { "item": "lighter", "charges": 100 } ] + "entries": [ { "group": "charged_cell_phone" }, { "item": "lighter", "charges": 100 } ] }, "male": [ "boxer_briefs" ], "female": [ "boxer_shorts" ] @@ -502,19 +517,21 @@ "points": 2, "skills": [ { "name": "survival", "level": 2 }, { "name": "fabrication", "level": 1 } ], "items": { - "both": [ - "honey_scraper", - "beekeeping_hood", - "beekeeping_suit", - "beekeeping_gloves", - "socks", - "boots", - "tank_top", - "cell_phone", - "honeycomb", - "honey_bottled", - "honey_bottled" - ], + "both": { + "items": [ + "honey_scraper", + "beekeeping_hood", + "beekeeping_suit", + "beekeeping_gloves", + "socks", + "boots", + "tank_top", + "honeycomb", + "honey_bottled", + "honey_bottled" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_briefs" ], "female": [ "bra", "panties" ] } @@ -527,7 +544,10 @@ "points": 1, "skills": [ { "level": 2, "name": "dodge" }, { "level": 3, "name": "throw" } ], "items": { - "both": [ "tank_top", "jersey", "b_shorts", "socks", "sneakers", "basketball", "cell_phone", "sports_drink" ], + "both": { + "items": [ "tank_top", "jersey", "b_shorts", "socks", "sneakers", "basketball", "sports_drink" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "sports_bra", "panties" ] } @@ -540,19 +560,21 @@ "points": 3, "skills": [ { "level": 3, "name": "driving" }, { "level": 2, "name": "dodge" } ], "items": { - "both": [ - "helmet_bike", - "folding_bicycle", - "under_armor_shorts", - "under_armor", - "socks", - "sneakers", - "sports_drink", - "cell_phone", - "wristwatch", - "fanny", - "fancy_sunglasses" - ], + "both": { + "items": [ + "helmet_bike", + "folding_bicycle", + "under_armor_shorts", + "under_armor", + "socks", + "sneakers", + "sports_drink", + "wristwatch", + "fanny", + "fancy_sunglasses" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "panties", "sports_bra" ] } @@ -653,7 +675,7 @@ "points": 1, "skills": [ { "level": 2, "name": "cooking" }, { "level": 1, "name": "driving" }, { "level": 2, "name": "tailor" } ], "items": { - "both": [ "pocketwatch", "knife_steak", "cell_phone" ], + "both": { "items": [ "pocketwatch", "knife_steak" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs", "socks", "dress_shoes", "tux" ], "female": [ "panties", "bra", "stockings", "dress_shoes", "maid_dress", "maid_hat" ] } @@ -667,21 +689,23 @@ "skills": [ { "level": 4, "name": "firstaid" } ], "traits": [ "PROF_MED" ], "items": { - "both": [ - "pants", - "dress_shirt", - "gloves_medical", - "socks", - "dress_shoes", - "coat_lab", - "wristwatch", - "cell_phone", - "water_clean", - "bandages", - "aspirin", - "1st_aid", - "stethoscope" - ], + "both": { + "items": [ + "pants", + "dress_shirt", + "gloves_medical", + "socks", + "dress_shoes", + "coat_lab", + "wristwatch", + "water_clean", + "bandages", + "aspirin", + "1st_aid", + "stethoscope" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -702,20 +726,9 @@ ], "items": { "both": { - "items": [ - "suit", - "bowhat", - "socks", - "dress_shoes", - "knit_scarf", - "cig", - "switchblade", - "mag_porn", - "sunglasses", - "cell_phone", - "wristwatch" - ], + "items": [ "suit", "bowhat", "socks", "dress_shoes", "knit_scarf", "cig", "switchblade", "mag_porn", "sunglasses", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "glock_19", "ammo-item": "9mm", "container-item": "sholster", "charges": 15 }, { "item": "9mm", "charges": 35 }, { "item": "lighter", "charges": 100 } @@ -743,10 +756,13 @@ "baton", "knife_folding", "hat_ball", - "cell_phone", "wristwatch" ], - "entries": [ { "item": "m9", "ammo-item": "9mm", "charges": 15, "container-item": "holster" }, { "item": "9mm", "charges": 35 } ] + "entries": [ + { "group": "charged_cell_phone" }, + { "item": "m9", "ammo-item": "9mm", "charges": 15, "container-item": "holster" }, + { "item": "9mm", "charges": 35 } + ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "boy_shorts" ] @@ -823,11 +839,14 @@ "backpack", "rope_30", "whistle", - "cell_phone", "wristwatch", "canteen" ], - "entries": [ { "item": "lighter", "charges": 100 }, { "item": "knife_rambo", "container-item": "scabbard" } ] + "entries": [ + { "group": "charged_cell_phone" }, + { "item": "lighter", "charges": 100 }, + { "item": "knife_rambo", "container-item": "scabbard" } + ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "boxer_shorts" ] @@ -841,8 +860,8 @@ "points": -1, "items": { "both": { - "items": [ "pants", "dress_shirt", "socks", "dress_shoes", "knit_scarf", "cig", "cell_phone", "wristwatch" ], - "entries": [ { "item": "lighter", "charges": 100 } ] + "items": [ "pants", "dress_shirt", "socks", "dress_shoes", "knit_scarf", "cig", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" }, { "item": "lighter", "charges": 100 } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] @@ -895,18 +914,9 @@ "pet": "mon_dog_gshepherd", "items": { "both": { - "items": [ - "pants_army", - "socks", - "badge_deputy", - "sheriffshirt", - "boots", - "dog_whistle", - "two_way_radio", - "cell_phone", - "wristwatch" - ], + "items": [ "pants_army", "socks", "badge_deputy", "sheriffshirt", "boots", "dog_whistle", "two_way_radio", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "usp_45", "ammo-item": "45_acp", "charges": 12, "container-item": "holster" }, { "item": "legpouch_large", "contents-group": "army_mags_usp45" } @@ -926,18 +936,9 @@ "traits": [ "PROF_POLICE" ], "items": { "both": { - "items": [ - "pants_army", - "socks", - "badge_deputy", - "sheriffshirt", - "boots", - "whistle", - "two_way_radio", - "cell_phone", - "wristwatch" - ], + "items": [ "pants_army", "socks", "badge_deputy", "sheriffshirt", "boots", "whistle", "two_way_radio", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "usp_45", "ammo-item": "45_acp", "charges": 12, "container-item": "holster" }, { "item": "legpouch_large", "contents-group": "army_mags_usp45" } @@ -970,11 +971,11 @@ "socks", "dress_shoes", "two_way_radio", - "cell_phone", "cig", "ref_lighter" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "l_enforcer_45", "ammo-item": "45_acp", "charges": 6, "container-item": "sholster" }, { "item": "45_acp", "charges": 24 } ] @@ -1140,7 +1141,10 @@ "points": 0, "skills": [ { "level": 4, "name": "barter" } ], "items": { - "both": [ "suit", "knit_scarf", "socks", "dress_shoes", "cell_phone", "wristwatch" ], + "both": { + "items": [ "suit", "knit_scarf", "socks", "dress_shoes", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -1163,10 +1167,10 @@ "jacket_flannel", "recurbow", "hat_hunting", - "wristwatch", - "cell_phone" + "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "quiver", "charges": 8, "contents-item": "arrow_cf" }, { "item": "sheath", "contents-item": "knife_hunting" } ] @@ -1184,18 +1188,9 @@ "skills": [ { "level": 2, "name": "rifle" } ], "items": { "both": { - "items": [ - "army_top", - "knit_scarf", - "socks", - "boots_steel", - "pants_cargo", - "jacket_flannel", - "hat_hunting", - "wristwatch", - "cell_phone" - ], + "items": [ "army_top", "knit_scarf", "socks", "boots_steel", "pants_cargo", "jacket_flannel", "hat_hunting", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "crossbow", "ammo-item": "bolt_metal", "charges": 1, "contents-item": "shoulder_strap" }, { "item": "bolt_metal", "charges": 9, "container-item": "quiver" }, { "item": "sheath", "contents-item": "knife_hunting" } @@ -1214,18 +1209,9 @@ "skills": [ { "level": 1, "name": "gun" }, { "level": 1, "name": "shotgun" } ], "items": { "both": { - "items": [ - "army_top", - "knit_scarf", - "socks", - "boots_steel", - "pants_cargo", - "jacket_flannel", - "hat_hunting", - "wristwatch", - "cell_phone" - ], + "items": [ "army_top", "knit_scarf", "socks", "boots_steel", "pants_cargo", "jacket_flannel", "hat_hunting", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "shotgun_d", "ammo-item": "shot_00", "charges": 2, "contents-item": "shoulder_strap" }, { "item": "shot_00", "charges": 12, "container-item": "bandolier_shotgun" }, @@ -1246,18 +1232,9 @@ "skills": [ { "level": 1, "name": "gun" }, { "level": 1, "name": "rifle" } ], "items": { "both": { - "items": [ - "army_top", - "knit_scarf", - "socks", - "boots_steel", - "pants_cargo", - "jacket_flannel", - "hat_hunting", - "wristwatch", - "cell_phone" - ], + "items": [ "army_top", "knit_scarf", "socks", "boots_steel", "pants_cargo", "jacket_flannel", "hat_hunting", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "ear_plugs", "custom-flags": [ "no_auto_equip" ] }, { "item": "remington_700", "ammo-item": "270", "charges": 4, "contents-item": "shoulder_strap" }, { "item": "270", "charges": 16, "container-item": "bandolier_rifle" }, @@ -1277,8 +1254,9 @@ "skills": [ { "level": 2, "name": "fabrication" } ], "items": { "both": { - "items": [ "tank_top", "socks", "boots_steel", "jeans", "multitool", "cell_phone", "wristwatch" ], + "items": [ "tank_top", "socks", "boots_steel", "jeans", "multitool", "wristwatch" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "nailgun", "ammo-item": "nail", "charges": 20 }, { "item": "nail", "charges": 180 }, { "item": "tool_belt", "contents-item": "hammer" } @@ -1295,7 +1273,10 @@ "description": "You're a lumberjack, and you're okay. You felled trees before the world ended, but suspect the undead aren't nearly as tough.", "points": 0, "items": { - "both": [ "jeans", "socks", "boots", "hat_hunting", "jacket_flannel", "knit_scarf", "vest", "ax", "cell_phone", "wristwatch" ], + "both": { + "items": [ "jeans", "socks", "boots", "hat_hunting", "jacket_flannel", "knit_scarf", "vest", "ax", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "boxer_shorts" ] } @@ -1307,7 +1288,10 @@ "description": "You've traveled for a living, sightseeing here and there, and living off your parents' trust fund. But now they're gone, and the only thing between you and death is the open road and your backpack.", "points": 0, "items": { - "both": [ "backpack_leather", "jeans", "sneakers", "tshirt", "knit_scarf", "socks", "cell_phone", "wristwatch", "fun_survival" ], + "both": { + "items": [ "backpack_leather", "jeans", "sneakers", "tshirt", "knit_scarf", "socks", "wristwatch", "fun_survival" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "boy_shorts" ] } @@ -1320,7 +1304,7 @@ "points": 0, "skills": [ { "level": 1, "name": "cooking" } ], "items": { - "both": [ "pants", "sneakers", "tshirt", "socks", "cell_phone", "knife_steak" ], + "both": { "items": [ "pants", "sneakers", "tshirt", "socks", "knife_steak" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -1342,10 +1326,10 @@ "boots", "tool_belt", "flashlight", - "cell_phone", "wristwatch", { "item": "light_battery_cell", "charges": 100 } - ] + ], + "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "boxer_briefs" ], "female": [ "bra", "panties" ] @@ -1381,20 +1365,22 @@ "description": "You were a high school student, but the tests you'll face now will have much higher stakes. There might even be something useful in one of these books you've been lugging around all year.", "points": 1, "items": { - "both": [ - "pants", - "tshirt", - "socks", - "sneakers", - "ZSG", - "backpack", - "cell_phone", - "wristwatch", - "textbook_speech", - "story_book", - "howto_computer", - "novel_coa" - ], + "both": { + "items": [ + "pants", + "tshirt", + "socks", + "sneakers", + "ZSG", + "backpack", + "wristwatch", + "textbook_speech", + "story_book", + "howto_computer", + "novel_coa" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "boy_shorts" ] } @@ -1416,8 +1402,8 @@ "skills": [ { "level": 4, "name": "driving" }, { "level": 1, "name": "mechanics" } ], "items": { "both": { - "items": [ "jeans", "tank_top", "chaps_leather", "socks", "boots", "bandana", "jacket_leather", "cell_phone", "wristwatch" ], - "entries": [ { "item": "sheath", "contents-item": "knife_trench" } ] + "items": [ "jeans", "tank_top", "chaps_leather", "socks", "boots", "bandana", "jacket_leather", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" }, { "item": "sheath", "contents-item": "knife_trench" } ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "boy_shorts" ] @@ -1431,7 +1417,7 @@ "points": 0, "skills": [ { "level": 2, "name": "dodge" } ], "items": { - "both": [ "socks", "knit_scarf", "dance_shoes", "cell_phone" ], + "both": { "items": [ "socks", "knit_scarf", "dance_shoes" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs", "tux" ], "female": [ "bra", "panties", "dress" ] } @@ -1461,7 +1447,7 @@ "points": 5, "CBMs": [ "bio_leukocyte", "bio_blood_anal", "bio_blood_filter", "bio_nanobots", "bio_metabolics", "bio_power_storage_mkII" ], "items": { - "both": [ "jeans", "tshirt", "socks", "sneakers", "cell_phone", "wristwatch" ], + "both": { "items": [ "jeans", "tshirt", "socks", "sneakers", "wristwatch" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -1473,7 +1459,7 @@ "description": "When the diagnosis came back positive, you were willing to fight to keep living. Now, you must renew your vow of tenacity in these new times.", "points": -2, "items": { - "both": [ "jeans", "tshirt", "socks", "sneakers", "cell_phone", "wristwatch" ], + "both": { "items": [ "jeans", "tshirt", "socks", "sneakers", "wristwatch" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] }, @@ -1938,12 +1924,11 @@ "knit_scarf", "beartrap", "wristwatch", - "cell_phone", "tobacco", "rolling_paper", "matches" ], - "entries": [ { "item": "knife_hunting", "container-item": "sheath" } ] + "entries": [ { "group": "charged_cell_phone" }, { "item": "knife_hunting", "container-item": "sheath" } ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "boxer_shorts" ] @@ -1957,7 +1942,10 @@ "points": 1, "skills": [ { "level": 4, "name": "fabrication" } ], "items": { - "both": [ "jeans", "socks", "boots", "tank_top", "apron_leather", "fire_gauntlets", "wristwatch", "cell_phone", "hammer" ], + "both": { + "items": [ "jeans", "socks", "boots", "tank_top", "apron_leather", "fire_gauntlets", "wristwatch", "hammer" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -1969,7 +1957,7 @@ "description": "All you ever wanted was to make people laugh. Dropping out of school and performing at kids' parties was a dream come true until the world ended. There's precious few balloon animals in your future now.", "points": -1, "items": { - "both": [ "clown_suit", "socks", "clownshoes", "cell_phone", "airhorn" ], + "both": { "items": [ "clown_suit", "socks", "clownshoes", "airhorn" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2002,21 +1990,23 @@ "points": 1, "skills": [ { "level": 1, "name": "tailor" } ], "items": { - "both": [ - "shorts", - "socks", - "sneakers", - "tank_top", - "sewing_kit", - "mbag", - "fur_cat_ears", - "fur_cat_tail", - "fur_collar", - "wristwatch", - "cell_phone", - "mag_animecon", - "cheeseburger" - ], + "both": { + "items": [ + "shorts", + "socks", + "sneakers", + "tank_top", + "sewing_kit", + "mbag", + "fur_cat_ears", + "fur_cat_tail", + "fur_collar", + "wristwatch", + "mag_animecon", + "cheeseburger" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2028,7 +2018,7 @@ "description": "The cataclysm struck on the big day and you escaped with nothing but your wedding attire. Cold feet? You'd just like to keep your feet attached!", "points": -1, "items": { - "both": [ "cell_phone" ], + "both": { "items": [ ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "tux", "socks", "dress_shoes", "briefs" ], "female": [ "veil_wedding", "dress_wedding", "stockings", "dress_shoes", "bra", "panties" ] } @@ -2040,19 +2030,21 @@ "description": "The apocalypse has been your psychotic dream come true. Now that the system is dead, it's time to party among the bones of the world!", "points": 0, "items": { - "both": [ - "trenchcoat", - "gloves_fingerless", - "socks", - "boots_combat", - "weed", - "tobacco", - "rolling_paper", - "mp3", - "ref_lighter", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ + "trenchcoat", + "gloves_fingerless", + "socks", + "boots_combat", + "weed", + "tobacco", + "rolling_paper", + "mp3", + "ref_lighter", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "pants_cargo", "tank_top", "boxer_shorts" ], "female": [ "skirt", "corset", "boxer_shorts" ] } @@ -2092,24 +2084,26 @@ "description": "Your ska band broke up after the drummer became a zombie, now you're alone in the cataclysm with some cigarettes and your mp3 player.", "points": 0, "items": { - "both": [ - "dress_shirt", - "skinny_tie", - "sunglasses", - "pants", - "socks", - "dress_shoes", - "rolling_paper", - "tobacco", - "cell_phone", - "wristwatch", - "mp3", - "ref_lighter" - ], - "male": [ "briefs" ], - "female": [ "bra", "panties" ] - } - }, + "both": { + "items": [ + "dress_shirt", + "skinny_tie", + "sunglasses", + "pants", + "socks", + "dress_shoes", + "rolling_paper", + "tobacco", + "wristwatch", + "mp3", + "ref_lighter" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, + "male": [ "briefs" ], + "female": [ "bra", "panties" ] + } + }, { "type": "profession", "ident": "postman", @@ -2118,19 +2112,21 @@ "points": 1, "skills": [ { "level": 1, "name": "driving" }, { "level": 1, "name": "dodge" } ], "items": { - "both": [ - "postman_hat", - "postman_shirt", - "mbag", - "dog_whistle", - "wristwatch", - "cell_phone", - "leather_belt", - "postman_shorts", - "knit_scarf", - "socks", - "sneakers" - ], + "both": { + "items": [ + "postman_hat", + "postman_shirt", + "mbag", + "dog_whistle", + "wristwatch", + "leather_belt", + "postman_shorts", + "knit_scarf", + "socks", + "sneakers" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2226,18 +2222,10 @@ ], "skills": [ { "level": 1, "name": "electronics" }, { "level": 1, "name": "firstaid" }, { "level": 1, "name": "computer" } ], "items": { - "both": [ - "tank_top", - "shorts", - "socks", - "lowtops", - "aspirin", - "anesthesia", - "pockknife", - "backpack", - "wristwatch", - "cell_phone" - ], + "both": { + "items": [ "tank_top", "shorts", "socks", "lowtops", "aspirin", "anesthesia", "pockknife", "backpack", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "camisole", "panties" ] } @@ -2321,7 +2309,10 @@ "points": 0, "skills": [ { "level": 3, "name": "speech" } ], "items": { - "both": [ "pants", "longshirt", "socks", "cassock", "dress_shoes", "holy_symbol", "holybook_bible1", "cell_phone" ], + "both": { + "items": [ "pants", "longshirt", "socks", "cassock", "dress_shoes", "holy_symbol", "holybook_bible1" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2334,7 +2325,10 @@ "points": 0, "skills": [ { "level": 1, "name": "fabrication" }, { "level": 1, "name": "tailor" } ], "items": { - "both": [ "kariginu", "eboshi", "pants", "tabi_dress", "geta", "holy_symbol", "holybook_kojiki", "cell_phone" ], + "both": { + "items": [ "kariginu", "eboshi", "pants", "tabi_dress", "geta", "holy_symbol", "holybook_kojiki" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2348,7 +2342,10 @@ "//": "No knife, fire, or decent storage/armor. Skill points are countered.", "skills": [ { "level": 2, "name": "speech" }, { "level": 1, "name": "barter" } ], "items": { - "both": [ "pants", "tshirt", "socks", "kufi", "thawb", "lowtops", "holybook_quran", "cell_phone" ], + "both": { + "items": [ "pants", "tshirt", "socks", "kufi", "thawb", "lowtops", "holybook_quran" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2361,19 +2358,21 @@ "points": 0, "skills": [ { "level": 2, "name": "speech" }, { "level": 1, "name": "firstaid" } ], "items": { - "both": [ - "pants", - "leather_belt", - "dress_shirt", - "socks", - "kittel", - "kippah", - "dress_shoes", - "cell_phone", - "holy_symbol", - "holybook_talmud", - "holybook_tanakh" - ], + "both": { + "items": [ + "pants", + "leather_belt", + "dress_shirt", + "socks", + "kittel", + "kippah", + "dress_shoes", + "holy_symbol", + "holybook_talmud", + "holybook_tanakh" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2387,20 +2386,22 @@ "//": "1.5 pts skills, cutting implement, and plenty of storage, so lack of fire only goes so far.", "skills": [ { "level": 2, "name": "speech" }, { "level": 1, "name": "survival" } ], "items": { - "both": [ - "jeans", - "tshirt", - "socks", - "robe", - "turban", - "waterskin", - "pockknife", - "mbag", - "leathersandals", - "holy_symbol", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ + "jeans", + "tshirt", + "socks", + "robe", + "turban", + "waterskin", + "pockknife", + "mbag", + "leathersandals", + "holy_symbol", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "panties" ] } @@ -2414,20 +2415,22 @@ "//": "Storage + 2 points in skills, - no knife or fire.", "skills": [ { "level": 2, "name": "speech" }, { "level": 1, "name": "driving" }, { "level": 1, "name": "computer" } ], "items": { - "both": [ - "dress_shirt", - "pants", - "socks", - "dress_shoes", - "wristwatch", - "cell_phone", - "backpack", - "laptop", - "flyer", - "flyer", - "flyer", - "holy_symbol" - ], + "both": { + "items": [ + "dress_shirt", + "pants", + "socks", + "dress_shoes", + "wristwatch", + "backpack", + "laptop", + "flyer", + "flyer", + "flyer", + "holy_symbol" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -2504,20 +2507,22 @@ "points": 1, "skills": [ { "level": 4, "name": "driving" }, { "level": 1, "name": "barter" }, { "level": 1, "name": "speech" } ], "items": { - "both": [ - "hat_ball", - "tshirt", - "jeans", - "jacket_light", - "socks", - "sneakers", - "pizza_veggy", - "pizza_meat", - "money_bundle", - "cell_phone", - "wristwatch", - "mbag" - ], + "both": { + "items": [ + "hat_ball", + "tshirt", + "jeans", + "jacket_light", + "socks", + "sneakers", + "pizza_veggy", + "pizza_meat", + "money_bundle", + "wristwatch", + "mbag" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "boy_shorts" ] } @@ -2531,7 +2536,6 @@ "skills": [ { "level": 2, "name": "melee" }, { "level": 2, "name": "gun" } ], "items": { "both": { - "ammo": 100, "items": [ "undershirt", "leather_belt", @@ -2543,11 +2547,11 @@ "bullwhip", "mbag", "fedora", - "cell_phone", "wristwatch", "spiral_stone" ], "entries": [ + { "group": "charged_cell_phone" }, { "item": "sw_619", "ammo-item": "38_special", "container-item": "holster" }, { "item": "38_special", "charges": 33 } ] @@ -2564,26 +2568,28 @@ "points": 3, "skills": [ { "level": 3, "name": "driving" }, { "level": 3, "name": "throw" }, { "level": 1, "name": "speech" } ], "items": { - "both": [ - "hat_newsboy", - "sweatshirt", - "pants", - "peacoat", - "socks", - "boots_winter", - "gloves_wool", - "knit_scarf", - "mbag", - "dog_whistle", - "cell_phone", - "wristwatch", - "newest_newspaper", - "newest_newspaper", - "newest_newspaper", - "newest_newspaper", - "newest_newspaper", - "folding_bicycle" - ], + "both": { + "items": [ + "hat_newsboy", + "sweatshirt", + "pants", + "peacoat", + "socks", + "boots_winter", + "gloves_wool", + "knit_scarf", + "mbag", + "dog_whistle", + "wristwatch", + "newest_newspaper", + "newest_newspaper", + "newest_newspaper", + "newest_newspaper", + "newest_newspaper", + "folding_bicycle" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "boy_shorts" ] } @@ -2597,19 +2603,21 @@ "skills": [ { "level": 1, "name": "melee" }, { "level": 1, "name": "unarmed" }, { "level": 1, "name": "dodge" } ], "traits": [ "PROF_SKATER" ], "items": { - "both": [ - "under_armor_shorts", - "under_armor", - "socks", - "elbow_pads", - "knee_pads", - "mouthpiece", - "gloves_fingerless", - "helmet_skid", - "cell_phone", - "wristwatch", - "rollerskates" - ], + "both": { + "items": [ + "under_armor_shorts", + "under_armor", + "socks", + "elbow_pads", + "knee_pads", + "mouthpiece", + "gloves_fingerless", + "helmet_skid", + "wristwatch", + "rollerskates" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "sports_bra", "panties" ] } @@ -2621,25 +2629,27 @@ "description": "You were making a living by raising crops, when the cataclysm struck. Now, with your trusty hoe and some seeds it's time to rebuild the Earth, one plant at a time.", "points": 1, "items": { - "both": [ - "jeans", - "tshirt", - "backpack", - "knit_scarf", - "multitool", - "hoe", - "socks", - "boots", - "cell_phone", - "wristwatch", - "seed_blueberries", - "seed_strawberries", - "seed_wheat", - "seed_hops", - "seed_barley", - "seed_sugar_beet", - "seed_tomato" - ], + "both": { + "items": [ + "jeans", + "tshirt", + "backpack", + "knit_scarf", + "multitool", + "hoe", + "socks", + "boots", + "wristwatch", + "seed_blueberries", + "seed_strawberries", + "seed_wheat", + "seed_hops", + "seed_barley", + "seed_sugar_beet", + "seed_tomato" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -2653,8 +2663,8 @@ "skills": [ { "level": 1, "name": "gun" }, { "level": 1, "name": "firstaid" } ], "items": { "both": { - "items": [ "shorts", "tshirt", "socks", "lowtops", "cell_phone", "wristwatch" ], - "entries": [ { "item": "gobag", "custom-flags": [ "FIT" ] } ] + "items": [ "shorts", "tshirt", "socks", "lowtops", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" }, { "item": "gobag", "custom-flags": [ "FIT" ] } ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] @@ -2930,20 +2940,22 @@ "description": "A mall security guard. You don't have any useful skills, other than some basic training for your job. You do however have your trusty tazer, baton, and pocket knife.", "points": 0, "items": { - "both": [ - "pants", - "socks", - "boots", - "flashlight", - "longshirt", - "jacket_light", - "baton", - "tazer", - "medium_battery_cell", - "pockknife", - "wristwatch", - "cell_phone" - ], + "both": { + "items": [ + "pants", + "socks", + "boots", + "flashlight", + "longshirt", + "jacket_light", + "baton", + "tazer", + "medium_battery_cell", + "pockknife", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "boy_shorts" ] } @@ -3015,11 +3027,14 @@ "fish_trap", "vest", "hat_boonie", - "cell_phone", "wristwatch", "jacket_flannel" ], - "entries": [ { "item": "lighter", "charges": 100 }, { "item": "knife_hunting", "container-item": "sheath" } ] + "entries": [ + { "group": "charged_cell_phone" }, + { "item": "lighter", "charges": 100 }, + { "item": "knife_hunting", "container-item": "sheath" } + ] }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] @@ -3038,7 +3053,10 @@ { "level": 1, "name": "cooking" } ], "items": { - "both": [ "stockings", "pockknife", "matches", "pipe_tobacco", "tobacco", "cell_phone" ], + "both": { + "items": [ "stockings", "pockknife", "matches", "pipe_tobacco", "tobacco" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "knee_high_boots", "breeches", @@ -3083,7 +3101,10 @@ { "level": 1, "name": "cooking" } ], "items": { - "both": [ "stockings", "pockknife", "matches", "pipe_tobacco", "tobacco", "cell_phone" ], + "both": { + "items": [ "stockings", "pockknife", "matches", "pipe_tobacco", "tobacco" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "dress", "apron_leather", @@ -3124,7 +3145,7 @@ "CBMs": [ "bio_batteries", "bio_power_storage", "bio_remote" ], "skills": [ { "level": 2, "name": "computer" } ], "items": { - "both": [ "jumpsuit", "socks", "boots", "cell_phone", "wristwatch" ], + "both": { "items": [ "jumpsuit", "socks", "boots", "wristwatch" ], "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -3138,20 +3159,22 @@ "skills": [ { "level": 1, "name": "dodge" } ], "traits": [ "PROF_SKATER" ], "items": { - "both": [ - "tshirt", - "hoodie", - "jeans", - "socks", - "elbow_pads", - "knee_pads", - "gloves_fingerless", - "helmet_skid", - "roller_blades", - "cell_phone", - "wristwatch", - "sports_drink" - ], + "both": { + "items": [ + "tshirt", + "hoodie", + "jeans", + "socks", + "elbow_pads", + "knee_pads", + "gloves_fingerless", + "helmet_skid", + "roller_blades", + "wristwatch", + "sports_drink" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "boy_shorts" ] } @@ -3164,24 +3187,26 @@ "points": 2, "skills": [ { "level": 1, "name": "gun" }, { "level": 1, "name": "dodge" }, { "level": 1, "name": "melee" } ], "items": { - "both": [ - "tshirt", - "hoodie", - "jeans", - "socks", - "sneakers", - "gloves_fingerless", - "slingpack", - "matches", - "hairpin", - "hairpin", - "mag_comic", - "cell_phone", - "wristwatch", - "marble", - "marble", - "slingshot" - ], + "both": { + "items": [ + "tshirt", + "hoodie", + "jeans", + "socks", + "sneakers", + "gloves_fingerless", + "slingpack", + "matches", + "hairpin", + "hairpin", + "mag_comic", + "wristwatch", + "marble", + "marble", + "slingshot" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "boy_shorts" ] } @@ -3194,24 +3219,26 @@ "points": 3, "skills": [ { "level": 1, "name": "survival" }, { "level": 1, "name": "fabrication" }, { "level": 1, "name": "firstaid" } ], "items": { - "both": [ - "tshirt", - "jacket_light", - "pants_cargo", - "socks", - "boots", - "knit_scarf", - "backpack", - "granola", - "water_clean", - "scissors", - "magnifying_glass", - "flashlight", - "1st_aid", - "cell_phone", - "wristwatch", - "whistle" - ], + "both": { + "items": [ + "tshirt", + "jacket_light", + "pants_cargo", + "socks", + "boots", + "knit_scarf", + "backpack", + "granola", + "water_clean", + "scissors", + "magnifying_glass", + "flashlight", + "1st_aid", + "wristwatch", + "whistle" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "boy_shorts" ] } @@ -3252,7 +3279,10 @@ "points": 1, "skills": [ { "level": 1, "name": "dodge" }, { "level": 1, "name": "throw" } ], "items": { - "both": [ "tshirt", "jacket_light", "jeans", "socks", "lowtops", "slingpack", "juice", "cell_phone" ], + "both": { + "items": [ "tshirt", "jacket_light", "jeans", "socks", "lowtops", "slingpack", "juice" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "boy_shorts" ] } @@ -3265,18 +3295,10 @@ "points": 1, "skills": [ { "level": 1, "name": "cooking" }, { "level": 1, "name": "mechanics" } ], "items": { - "both": [ - "tshirt", - "jacket_light", - "jeans", - "socks", - "sneakers", - "knit_scarf", - "backpack", - "textbook_chemistry", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ "tshirt", "jacket_light", "jeans", "socks", "sneakers", "knit_scarf", "backpack", "textbook_chemistry", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "panties" ] } @@ -3289,18 +3311,20 @@ "points": 1, "skills": [ { "level": 1, "name": "electronics" }, { "level": 1, "name": "computer" } ], "items": { - "both": [ - "linuxtshirt", - "jacket_light", - "jeans", - "socks", - "sneakers", - "knit_scarf", - "backpack", - "mag_electronics", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ + "linuxtshirt", + "jacket_light", + "jeans", + "socks", + "sneakers", + "knit_scarf", + "backpack", + "mag_electronics", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "panties" ] } @@ -3313,19 +3337,21 @@ "points": 0, "skills": [ { "level": 3, "name": "speech" } ], "items": { - "both": [ - "dress_shirt", - "blazer", - "pants", - "socks", - "dress_shoes", - "skinny_tie", - "tieclip", - "poetry_book", - "permanent_marker", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ + "dress_shirt", + "blazer", + "pants", + "socks", + "dress_shoes", + "skinny_tie", + "tieclip", + "poetry_book", + "permanent_marker", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -3337,7 +3363,10 @@ "description": "You were a freelance photojournalist before the end. You have a chance to be the first journalist to cover the apocalypse, though finding a publisher seems more difficult a prospect than usual. You managed to hold onto your camera, hopefully you can get some fantastic shots.", "points": 0, "items": { - "both": [ "pants", "dress_shirt", "blazer", "socks", "dress_shoes", "camera_pro", "cell_phone", "wristwatch" ], + "both": { + "items": [ "pants", "dress_shirt", "blazer", "socks", "dress_shoes", "camera_pro", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "boy_shorts", "bra" ] } @@ -3350,7 +3379,10 @@ "points": 3, "skills": [ { "level": 2, "name": "dodge" }, { "level": 2, "name": "speech" } ], "items": { - "both": [ "baseball", "bat", "whistle", "tank_top", "shorts", "socks", "sneakers", "runner_bag", "cell_phone", "wristwatch" ], + "both": { + "items": [ "baseball", "bat", "whistle", "tank_top", "shorts", "socks", "sneakers", "runner_bag", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "sports_bra", "boy_shorts" ] } @@ -3363,32 +3395,34 @@ "points": 6, "skills": [ { "level": 1, "name": "survival" }, { "level": 1, "name": "swimming" }, { "level": 1, "name": "firstaid" } ], "items": { - "both": [ - "tshirt", - "socks", - "jeans", - "jacket_windbreaker", - "boots_hiking", - "gloves_light", - "hat_cotton", - "knit_scarf", - "backpack", - "ref_lighter", - "hatchet", - "e_tool", - "tent_kit", - "rollmat", - "sleeping_bag_roll", - "knife_swissarmy", - "mess_kit", - "gasoline_lantern", - "canteen", - "granola", - "pur_tablets", - "cell_phone", - "wristwatch", - "1st_aid" - ], + "both": { + "items": [ + "tshirt", + "socks", + "jeans", + "jacket_windbreaker", + "boots_hiking", + "gloves_light", + "hat_cotton", + "knit_scarf", + "backpack", + "ref_lighter", + "hatchet", + "e_tool", + "tent_kit", + "rollmat", + "sleeping_bag_roll", + "knife_swissarmy", + "mess_kit", + "gasoline_lantern", + "canteen", + "granola", + "pur_tablets", + "wristwatch", + "1st_aid" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "sports_bra", "boy_shorts" ] } @@ -3437,7 +3471,10 @@ "traits": [ "PARKOUR" ], "skills": [ { "level": 4, "name": "dodge" } ], "items": { - "both": [ "tshirt", "hoodie", "pants_cargo", "socks", "sneakers", "runner_bag", "cell_phone", "wristwatch" ], + "both": { + "items": [ "tshirt", "hoodie", "pants_cargo", "socks", "sneakers", "runner_bag", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "sports_bra", "boy_shorts" ] } @@ -3449,22 +3486,24 @@ "description": "You came here to get a taste of New England; Now you hope New England won't get a taste of you!", "points": 1, "items": { - "both": [ - "hat_ball", - "knit_scarf", - "tshirt", - "jacket_light", - "gloves_light", - "pants", - "fanny", - "socks", - "sneakers", - "roadmap", - "touristmap", - "cell_phone", - "wristwatch", - "camera" - ], + "both": { + "items": [ + "hat_ball", + "knit_scarf", + "tshirt", + "jacket_light", + "gloves_light", + "pants", + "fanny", + "socks", + "sneakers", + "roadmap", + "touristmap", + "wristwatch", + "camera" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -3486,20 +3525,22 @@ "skills": [ { "level": 4, "name": "firstaid" }, { "level": 4, "name": "electronics" } ], "traits": [ "PROF_AUTODOC" ], "items": { - "both": [ - "pants", - "dress_shirt", - "gloves_medical", - "socks", - "dress_shoes", - "coat_lab", - "bandages", - "anesthesia", - "1st_aid", - "cell_phone", - "wristwatch", - "stethoscope" - ], + "both": { + "items": [ + "pants", + "dress_shirt", + "gloves_medical", + "socks", + "dress_shoes", + "coat_lab", + "bandages", + "anesthesia", + "1st_aid", + "wristwatch", + "stethoscope" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -3513,7 +3554,10 @@ "traits": [ "PROF_DICEMASTER" ], "skills": [ { "level": 2, "name": "speech" }, { "level": 1, "name": "survival" } ], "items": { - "both": [ "jeans", "tshirt", "socks", "sneakers", "mbag", "pizza_cheese", "cola", "dnd_handbook", "cell_phone", "wristwatch" ], + "both": { + "items": [ "jeans", "tshirt", "socks", "sneakers", "mbag", "pizza_cheese", "cola", "dnd_handbook", "wristwatch" ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "bra", "panties" ] } @@ -3551,18 +3595,20 @@ "traits": [ "ANIMALEMPATH" ], "skills": [ { "level": 1, "name": "firstaid" }, { "level": 1, "name": "survival" } ], "items": { - "both": [ - "shorts_cargo", - "technician_shirt_gray", - "socks", - "boots", - "hat_boonie", - "slingpack", - "bucket", - "shovel", - "cell_phone", - "wristwatch" - ], + "both": { + "items": [ + "shorts_cargo", + "technician_shirt_gray", + "socks", + "boots", + "hat_boonie", + "slingpack", + "bucket", + "shovel", + "wristwatch" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -3576,7 +3622,7 @@ "skills": [ { "level": 2, "name": "bashing" }, { "level": 1, "name": "melee" }, { "level": 1, "name": "driving" } ], "items": { "both": { - "items": [ "shorts", "polo_shirt", "socks", "golf_shoes", "hat_golf", "gloves_golf", "cell_phone", "wristwatch" ], + "items": [ "shorts", "polo_shirt", "socks", "golf_shoes", "hat_golf", "gloves_golf", "wristwatch" ], "entries": [ { "item": "golf_club", "container-item": "golf_bag" }, { "item": "golf_tee" }, @@ -3586,7 +3632,8 @@ { "item": "golf_tee" }, { "item": "golf_ball" }, { "item": "golf_ball" }, - { "item": "golf_ball" } + { "item": "golf_ball" }, + { "group": "charged_cell_phone" } ] }, "male": [ "boxer_shorts" ], diff --git a/data/json/recipes/recipe_deconstruction.json b/data/json/recipes/recipe_deconstruction.json index 1d6f05a77a388..026737b17727f 100644 --- a/data/json/recipes/recipe_deconstruction.json +++ b/data/json/recipes/recipe_deconstruction.json @@ -182,7 +182,15 @@ "time": 2000, "using": [ [ "soldering_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "RAM", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_c4_hack", @@ -192,7 +200,15 @@ "time": 2000, "using": [ [ "soldering_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "RAM", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_copbot", @@ -203,12 +219,17 @@ "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "omni_wheel", 1 ] ], + [ [ "copbot_chassis", 1 ] ], + [ [ "android_arms", 1 ] ], [ [ "power_supply", 4 ] ], [ [ "solar_cell", 2 ] ], - [ [ "motor", 1 ] ], - [ [ "tazer", 1 ] ], - [ [ "e_scrap", 3 ] ], - [ [ "steel_chunk", 12 ] ] + [ [ "tazer", 1 ] ] ] }, { @@ -236,7 +257,16 @@ "time": 30000, "using": [ [ "soldering_standard", 3 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "lens", 1 ] ], [ [ "e_scrap", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "lens", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_flashbang_hack", @@ -246,7 +276,15 @@ "time": 2000, "using": [ [ "soldering_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "RAM", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_gasbomb_hack", @@ -256,7 +294,15 @@ "time": 2000, "using": [ [ "soldering_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "RAM", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_grenade_hack", @@ -266,7 +312,15 @@ "time": 2000, "using": [ [ "soldering_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "RAM", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_manhack", @@ -276,7 +330,16 @@ "time": 2000, "using": [ [ "soldering_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "spike", 2 ] ], [ [ "processor", 1 ] ], [ [ "RAM", 1 ] ], [ [ "scrap", 1 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "spike", 2 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_mininuke_hack", @@ -286,7 +349,15 @@ "time": 4000, "using": [ [ "soldering_standard", 10 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 2 ] ], [ [ "RAM", 2 ] ], [ [ "scrap", 2 ] ] ] + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] }, { "result": "broken_molebot", @@ -296,7 +367,15 @@ "time": 180000, "using": [ [ "welding_standard", 6 ] ], "qualities": [ { "id": "SAW_M", "level": 1 } ], - "components": [ [ [ "power_supply", 4 ] ], [ [ "motor", 1 ] ], [ [ "steel_chunk", 20 ] ] ] + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "motor", 1 ] ], + [ [ "steel_chunk", 20 ] ] + ] }, { "result": "broken_riotbot", @@ -307,12 +386,17 @@ "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "omni_wheel", 1 ] ], + [ [ "copbot_chassis", 1 ] ], + [ [ "android_arms", 1 ] ], [ [ "power_supply", 4 ] ], [ [ "solar_cell", 2 ] ], - [ [ "motor", 1 ] ], - [ [ "canister_empty", 1 ] ], - [ [ "e_scrap", 3 ] ], - [ [ "steel_chunk", 12 ] ] + [ [ "canister_empty", 1 ] ] ] }, { @@ -323,7 +407,19 @@ "time": 60000, "using": [ [ "soldering_standard", 10 ] ], "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "power_supply", 1 ] ], [ [ "tazer", 2 ] ], [ [ "e_scrap", 2 ] ], [ [ "scrap", 4 ] ] ] + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "spidery_legs_small", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "tazer", 2 ] ], + [ [ "scrap", 4 ] ] + ] }, { "result": "broken_science_bot", @@ -334,14 +430,17 @@ "using": [ [ "soldering_standard", 20 ] ], "qualities": [ { "id": "WRENCH", "level": 1 }, { "id": "SCREW", "level": 1 } ], "components": [ + [ [ "ai_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "spidery_legs_small", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], [ [ "power_supply", 3 ] ], [ [ "geiger_off", 1 ] ], [ [ "tazer", 2 ] ], - [ [ "e_scrap", 4 ] ], - [ [ "solder_wire", 10 ] ], - [ [ "cable", 4 ] ], [ [ "scrap", 6 ] ], - [ [ "motor", 1 ] ], [ [ "plut_cell", 1 ] ], [ [ "steel_chunk", 6 ] ] ] @@ -355,16 +454,22 @@ "using": [ [ "soldering_standard", 30 ], [ "welding_standard", 20 ] ], "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "tank_tread", 1 ] ], + [ [ "tankbot_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "gun_module", 3 ] ], [ [ "flamethrower", 1 ] ], [ [ "tazer", 1 ] ], [ [ "m4a1", 1 ] ], - [ [ "motor_large", 1 ] ], [ [ "power_supply", 20 ] ], + [ [ "storage_battery", 1 ] ], [ [ "plut_cell", 4 ] ], - [ [ "RAM", 2 ] ], - [ [ "steel_chunk", 15 ] ], - [ [ "mil_plate", 2 ] ], - [ [ "robot_controls", 1 ] ] + [ [ "mil_plate", 2 ] ] ] }, { @@ -376,17 +481,22 @@ "using": [ [ "soldering_standard", 10 ], [ "welding_standard", 10 ] ], "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "spidery_legs_big", 1 ] ], + [ [ "tripod_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "gun_module", 1 ] ], [ [ "power_supply", 12 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "flamethrower", 1 ] ], - [ [ "wire", 4 ] ], - [ [ "motor", 2 ] ], - [ [ "steel_chunk", 60 ] ] + [ [ "storage_battery", 1 ] ], + [ [ "flamethrower", 1 ] ] ] }, { - "result": "bot_copbot", + "result": "broken_nursebot", "type": "uncraft", "skill_used": "electronics", "difficulty": 6, @@ -394,167 +504,332 @@ "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ - [ [ "power_supply", 4 ] ], - [ [ "solar_cell", 2 ] ], - [ [ "motor", 1 ] ], - [ [ "tazer", 1 ] ], - [ [ "e_scrap", 3 ] ], - [ [ "steel_chunk", 12 ] ] + [ [ "ai_module_advanced", 1 ] ], + [ [ "self_monitoring_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "android_legs", 1 ] ], + [ [ "android_chassis", 1 ] ], + [ [ "android_arms", 2 ] ], + [ [ "medium_storage_battery", 1 ] ] ] }, { - "result": "bot_eyebot", + "result": "broken_nursebot_defective", "type": "uncraft", "skill_used": "electronics", - "difficulty": 2, - "time": 37500, - "using": [ [ "soldering_standard", 3 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "processor", 1 ] ], [ [ "lens", 1 ] ], [ [ "e_scrap", 1 ] ], [ [ "scrap", 1 ] ] ] + "difficulty": 6, + "time": 150000, + "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "ai_module_advanced", 1 ] ], + [ [ "self_monitoring_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "android_legs", 1 ] ], + [ [ "android_chassis", 1 ] ], + [ [ "android_arms", 2 ] ], + [ [ "medium_storage_battery", 1 ] ] + ] }, { - "result": "bot_molebot", + "result": "broken_dispatch", "type": "uncraft", "skill_used": "electronics", - "difficulty": 3, - "time": 225000, - "using": [ [ "welding_standard", 6 ] ], - "qualities": [ { "id": "SAW_M", "level": 1 } ], - "components": [ [ [ "power_supply", 4 ] ], [ [ "motor", 1 ] ], [ [ "steel_chunk", 20 ] ] ] + "difficulty": 5, + "time": 60000, + "using": [ [ "soldering_standard", 20 ] ], + "qualities": [ { "id": "WRENCH", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "tank_tread", 1 ] ], + [ [ "tankbot_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "power_supply", 3 ] ], + [ [ "plut_cell", 1 ] ], + [ [ "broken_manhack", 4 ] ], + [ [ "omnicamera", 1 ] ], + [ [ "storage_battery", 1 ] ] + ] }, { - "result": "bot_riotbot", + "result": "broken_dispatch_military", "type": "uncraft", "skill_used": "electronics", - "difficulty": 6, - "time": 150000, - "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], - "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "difficulty": 5, + "time": 60000, + "using": [ [ "soldering_standard", 20 ] ], + "qualities": [ { "id": "WRENCH", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ - [ [ "power_supply", 4 ] ], - [ [ "solar_cell", 2 ] ], - [ [ "motor", 1 ] ], - [ [ "canister_empty", 1 ] ], - [ [ "e_scrap", 3 ] ], - [ [ "steel_chunk", 12 ] ] + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "tank_tread", 1 ] ], + [ [ "tankbot_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "power_supply", 3 ] ], + [ [ "plut_cell", 1 ] ], + [ [ "broken_manhack", 4 ] ], + [ [ "omnicamera", 1 ] ], + [ [ "storage_battery", 1 ] ] ] }, { - "result": "bot_skitterbot", + "result": "targeting_module", "type": "uncraft", "skill_used": "electronics", - "difficulty": 3, - "time": 75000, - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ [ [ "power_supply", 1 ] ], [ [ "tazer", 2 ] ], [ [ "e_scrap", 2 ] ], [ [ "scrap", 4 ] ] ] + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], + "components": [ [ [ "processor", 4 ] ], [ [ "power_supply", 1 ] ], [ [ "e_scrap", 6 ] ], [ [ "solder_wire", 1 ] ] ] }, { - "result": "bot_science_bot", + "result": "identification_module", "type": "uncraft", "skill_used": "electronics", "difficulty": 5, - "time": 150000, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], + "components": [ [ [ "processor", 4 ] ], [ [ "power_supply", 1 ] ], [ [ "e_scrap", 6 ] ], [ [ "solder_wire", 1 ] ] ] + }, + { + "result": "pathfinding_module", + "type": "uncraft", + "skill_used": "electronics", + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], + "components": [ [ [ "processor", 4 ] ], [ [ "power_supply", 1 ] ], [ [ "e_scrap", 6 ] ], [ [ "solder_wire", 1 ] ] ] + }, + { + "result": "memory_module", + "type": "uncraft", + "skill_used": "electronics", + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], + "components": [ [ [ "processor", 4 ] ], [ [ "RAM", 10 ] ], [ [ "power_supply", 1 ] ], [ [ "e_scrap", 6 ] ], [ [ "solder_wire", 1 ] ] ] + }, + { + "result": "sensor_module", + "type": "uncraft", + "skill_used": "electronics", + "difficulty": 5, + "time": 300000, "using": [ [ "soldering_standard", 20 ] ], - "qualities": [ { "id": "WRENCH", "level": 1 }, { "id": "SCREW", "level": 1 } ], "components": [ - [ [ "power_supply", 3 ] ], - [ [ "geiger_off", 1 ] ], - [ [ "tazer", 2 ] ], - [ [ "e_scrap", 4 ] ], - [ [ "solder_wire", 10 ] ], + [ [ "processor", 4 ] ], + [ [ "lens", 2 ] ], + [ [ "lens_small", 2 ] ], + [ [ "power_supply", 1 ] ], + [ [ "e_scrap", 6 ] ], + [ [ "solder_wire", 1 ] ] + ] + }, + { + "result": "self_monitoring_module", + "type": "uncraft", + "skill_used": "electronics", + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], + "components": [ + [ [ "processor", 4 ] ], + [ [ "power_supply", 1 ] ], [ [ "cable", 4 ] ], - [ [ "scrap", 6 ] ], - [ [ "motor", 1 ] ], - [ [ "plut_cell", 1 ] ], - [ [ "steel_chunk", 6 ] ] + [ [ "e_scrap", 6 ] ], + [ [ "solder_wire", 1 ] ] ] }, { - "result": "bot_tankbot", + "result": "ai_module", "type": "uncraft", "skill_used": "electronics", - "difficulty": 8, - "time": 750000, - "using": [ [ "soldering_standard", 30 ], [ "welding_standard", 20 ] ], - "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "WRENCH", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], "components": [ - [ [ "flamethrower", 1 ] ], - [ [ "tazer", 1 ] ], - [ [ "m4a1", 1 ] ], - [ [ "motor_large", 1 ] ], - [ [ "power_supply", 20 ] ], - [ [ "plut_cell", 4 ] ], + [ [ "processor", 10 ] ], [ [ "RAM", 2 ] ], - [ [ "steel_chunk", 15 ] ], - [ [ "mil_plate", 2 ] ], - [ [ "robot_controls", 1 ] ] + [ [ "power_supply", 1 ] ], + [ [ "cable", 4 ] ], + [ [ "e_scrap", 6 ] ], + [ [ "solder_wire", 1 ] ] ] }, { - "result": "bot_tripod", + "result": "ai_module_basic", "type": "uncraft", "skill_used": "electronics", - "difficulty": 8, - "time": 375000, - "using": [ [ "soldering_standard", 10 ], [ "welding_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 20 ] ], "components": [ - [ [ "power_supply", 12 ] ], - [ [ "processor", 1 ] ], + [ [ "processor", 5 ] ], [ [ "RAM", 1 ] ], - [ [ "flamethrower", 1 ] ], - [ [ "wire", 4 ] ], - [ [ "motor", 2 ] ], - [ [ "steel_chunk", 60 ] ] + [ [ "power_supply", 1 ] ], + [ [ "cable", 2 ] ], + [ [ "e_scrap", 3 ] ], + [ [ "solder_wire", 1 ] ] ] }, { - "result": "broken_dispatch", + "result": "ai_module_advanced", "type": "uncraft", "skill_used": "electronics", "difficulty": 5, - "time": 60000, + "time": 300000, "using": [ [ "soldering_standard", 20 ] ], - "qualities": [ { "id": "WRENCH", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], "components": [ - [ [ "power_supply", 3 ] ], + [ [ "processor", 15 ] ], + [ [ "RAM", 6 ] ], + [ [ "power_supply", 2 ] ], + [ [ "cable", 4 ] ], [ [ "e_scrap", 6 ] ], - [ [ "solder_wire", 50 ] ], - [ [ "cable", 20 ] ], + [ [ "solder_wire", 1 ] ] + ] + }, + { + "result": "gun_module", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 5, + "time": 300000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "motor_micro", 6 ] ], + [ [ "power_supply", 2 ] ], + [ [ "cable", 2 ] ], [ [ "scrap", 6 ] ], - [ [ "motor", 1 ] ], - [ [ "wire", 9 ] ], - [ [ "plut_cell", 1 ] ], - [ [ "steel_chunk", 6 ] ], - [ [ "broken_manhack", 4 ] ], - [ [ "omnicamera", 1 ] ], - [ [ "robot_controls", 1 ] ] + [ [ "steel_chunk", 1 ] ] ] }, { - "result": "broken_dispatch_military", + "result": "spidery_legs_big", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 4, + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "motor_small", 24 ] ], + [ [ "power_supply", 8 ] ], + [ [ "cable", 16 ] ], + [ [ "scrap", 6 ] ], + [ [ "steel_chunk", 8 ] ] + ] + }, + { + "result": "spidery_legs_small", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 4, + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW_FINE", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "motor_tiny", 24 ] ], [ [ "power_supply", 8 ] ], [ [ "cable", 16 ] ], [ [ "scrap", 14 ] ] ] + }, + { + "result": "reverse_jointed_legs", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 4, + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "motor_small", 6 ] ], [ [ "power_supply", 6 ] ], [ [ "cable", 12 ] ], [ [ "steel_chunk", 6 ] ] ] + }, + { + "result": "omni_wheel", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 4, + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "motor_small", 3 ] ], + [ [ "power_supply", 3 ] ], + [ [ "cable", 6 ] ], + [ [ "plastic_chunk", 6 ] ], + [ [ "steel_chunk", 2 ] ] + ] + }, + { + "result": "quad_rotors", "type": "uncraft", "skill_used": "electronics", + "difficulty": 4, + "time": 200000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW_FINE", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ + [ [ "motor_micro", 4 ] ], + [ [ "power_supply", 1 ] ], + [ [ "cable", 2 ] ], + [ [ "plastic_chunk", 4 ] ], + [ [ "scrap", 1 ] ] + ] + }, + { + "result": "android_legs", + "type": "uncraft", + "skill_used": "mechanics", "difficulty": 5, - "time": 60000, - "using": [ [ "soldering_standard", 20 ] ], - "qualities": [ { "id": "WRENCH", "level": 1 }, { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 }, { "id": "SCREW_FINE", "level": 1 } ], "components": [ - [ [ "power_supply", 3 ] ], - [ [ "e_scrap", 6 ] ], - [ [ "solder_wire", 60 ] ], - [ [ "cable", 35 ] ], - [ [ "scrap", 6 ] ], - [ [ "motor_large", 1 ] ], - [ [ "wire", 9 ] ], - [ [ "plut_cell", 2 ] ], - [ [ "steel_chunk", 6 ] ], - [ [ "broken_manhack", 7 ] ], - [ [ "omnicamera", 1 ] ], - [ [ "robot_controls", 1 ] ] + [ [ "motor_tiny", 4 ] ], + [ [ "motor_micro", 10 ] ], + [ [ "power_supply", 6 ] ], + [ [ "cable", 12 ] ], + [ [ "steel_chunk", 4 ] ], + [ [ "plastic_chunk", 4 ] ], + [ [ "scrap", 5 ] ] + ] + }, + { + "result": "android_arms", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 5, + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 }, { "id": "SCREW_FINE", "level": 1 } ], + "components": [ + [ [ "motor_tiny", 4 ] ], + [ [ "motor_micro", 10 ] ], + [ [ "power_supply", 6 ] ], + [ [ "cable", 12 ] ], + [ [ "steel_chunk", 2 ] ], + [ [ "plastic_chunk", 2 ] ], + [ [ "scrap", 5 ] ] ] }, + { + "result": "tank_tread", + "type": "uncraft", + "skill_used": "mechanics", + "difficulty": 4, + "time": 400000, + "using": [ [ "soldering_standard", 5 ] ], + "qualities": [ { "id": "SCREW", "level": 1 }, { "id": "SAW_M", "level": 1 } ], + "components": [ [ [ "motor", 2 ] ], [ [ "power_supply", 6 ] ], [ [ "cable", 4 ] ], [ [ "steel_lump", 6 ] ], [ [ "steel_chunk", 6 ] ] ] + }, { "result": "cable", "type": "uncraft", diff --git a/data/json/recipes/recipe_electronics.json b/data/json/recipes/recipe_electronics.json index 4d73173f46e7d..1f3254e754db8 100644 --- a/data/json/recipes/recipe_electronics.json +++ b/data/json/recipes/recipe_electronics.json @@ -1136,73 +1136,669 @@ "qualities": [ { "id": "SCREW", "level": 1 } ], "components": [ [ [ "small_storage_battery", 80 ] ], [ [ "e_scrap", 16 ] ], [ [ "scrap", 32 ] ], [ [ "cable", 20 ] ] ] }, + { + "type": "recipe", + "result": "bot_manhack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], + "difficulty": 6, + "time": 25000, + "reversible": true, + "decomp_learn": 7, + "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "spike", 2 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_grenade_hack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], + "difficulty": 6, + "time": 25000, + "reversible": true, + "decomp_learn": 7, + "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "grenade", 1 ] ], + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_mininuke_hack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 6 ], [ "computer", 5 ] ], + "difficulty": 7, + "time": 35000, + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "recipe_lab_elec", 7 ], [ "textbook_robots", 8 ] ], + "using": [ [ "soldering_standard", 20 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "mininuke", 1 ] ], + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_gasbomb_hack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], + "difficulty": 6, + "time": 25000, + "reversible": true, + "decomp_learn": 7, + "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "gasbomb", 1 ] ], + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_EMP_hack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], + "difficulty": 6, + "time": 25000, + "reversible": true, + "decomp_learn": 7, + "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "EMPbomb", 1 ] ], + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_flashbang_hack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], + "difficulty": 6, + "time": 25000, + "reversible": true, + "decomp_learn": 7, + "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "flashbang", 1 ] ], + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_c4_hack", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], + "difficulty": 6, + "time": 25000, + "reversible": true, + "decomp_learn": 7, + "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ { "id": "SCREW", "level": 1 } ], + "components": [ + [ [ "c4", 1 ] ], + [ [ "ai_module_basic", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, { "type": "recipe", "result": "bot_turret", "category": "CC_ELECTRONIC", - "subcategory": "CSC_ELECTRONIC_PARTS", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ], [ "gun", 3 ] ], + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 5 ] ], "difficulty": 7, - "time": 9000, + "time": 30000, "reversible": true, "decomp_learn": 8, "book_learn": [ [ "recipe_lab_elec", 7 ], [ "textbook_robots", 9 ] ], "using": [ [ "soldering_standard", 14 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], "components": [ - [ [ "uzi", 1 ], [ "tec9", 1 ], [ "calico", 1 ], [ "hk_mp5", 1 ] ], - [ [ "processor", 2 ] ], - [ [ "RAM", 2 ] ], - [ [ "power_supply", 1 ], [ "plut_cell", 1 ] ], - [ [ "scrap", 10 ] ] + [ [ "ai_module", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "gun_module", 2 ] ], + [ [ "hk_mp5", 2 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "turret_chassis", 1 ] ] ] }, { "type": "recipe", "result": "bot_laserturret", "category": "CC_ELECTRONIC", - "subcategory": "CSC_ELECTRONIC_PARTS", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 8 ], [ "computer", 5 ], [ "gun", 3 ] ], + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 8 ], [ "computer", 5 ] ], "difficulty": 8, - "time": 12000, + "time": 30000, "reversible": true, "decomp_learn": 9, "book_learn": [ [ "recipe_lab_elec", 8 ] ], "using": [ [ "soldering_standard", 14 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], "components": [ - [ [ "cerberus_laser", 3 ], [ "laser_rifle", 3 ], [ "v29_cheap", 3 ], [ "v29", 3 ] ], - [ [ "processor", 2 ] ], - [ [ "RAM", 2 ] ], - [ [ "motor", 1 ] ], + [ [ "ai_module", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "gun_module", 1 ] ], + [ [ "laser_cannon", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ], [ [ "solar_cell", 4 ] ], - [ [ "cable", 10 ] ], - [ [ "power_supply", 1 ], [ "plut_cell", 1 ] ], - [ [ "scrap", 10 ] ] + [ [ "power_supply", 1 ] ], + [ [ "turret_chassis", 1 ] ] ] }, { "type": "recipe", "result": "bot_rifleturret", "category": "CC_ELECTRONIC", - "subcategory": "CSC_ELECTRONIC_PARTS", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ], [ "gun", 3 ] ], + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 6 ], [ "computer", 5 ] ], "difficulty": 8, - "time": 9000, + "time": 30000, "reversible": true, "decomp_learn": 8, "book_learn": [ [ "recipe_lab_elec", 7 ], [ "textbook_robots", 9 ] ], "using": [ [ "soldering_standard", 14 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], "components": [ - [ [ "m4a1", 1 ], [ "sig552", 1 ], [ "h&k416a5", 1 ], [ "m27iar", 1 ], [ "acr", 1 ], [ "hk_g36", 1 ] ], - [ [ "processor", 2 ] ], - [ [ "RAM", 2 ] ], - [ [ "power_supply", 1 ], [ "plut_cell", 1 ] ], - [ [ "scrap", 15 ] ] + [ [ "ai_module", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "gun_module", 1 ] ], + [ [ "m4a1", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "turret_chassis", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_nursebot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 7 ], [ "computer", 6 ] ], + "difficulty": 8, + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_nursebot", 7 ] ], + "time": 60000, + "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module_advanced", 1 ] ], + [ [ "self_monitoring_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "android_legs", 1 ] ], + [ [ "android_chassis", 1 ] ], + [ [ "android_arms", 2 ] ], + [ [ "medium_storage_battery", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_hazmatbot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 6 ] ], + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_hazmatbot", 7 ] ], + "difficulty": 6, + "time": 50000, + "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "self_monitoring_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "omni_wheel", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "steel_chunk", 6 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_copbot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 5 ], [ "computer", 6 ] ], + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_copbot", 7 ] ], + "difficulty": 6, + "time": 50000, + "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "omni_wheel", 1 ] ], + [ [ "copbot_chassis", 1 ] ], + [ [ "android_arms", 1 ] ], + [ [ "power_supply", 4 ] ], + [ [ "solar_cell", 2 ] ], + [ [ "tazer", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_eyebot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 4 ], [ "computer", 4 ] ], + "reversible": true, + "decomp_learn": 5, + "book_learn": [ [ "schematics_eyebot", 7 ] ], + "difficulty": 4, + "time": 30000, + "using": [ [ "soldering_standard", 3 ], [ "welding_standard", 3 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "quad_rotors", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "lens", 1 ] ], + [ [ "identification_module", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_molebot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 6 ], [ "computer", 5 ] ], + "reversible": true, + "decomp_learn": 5, + "book_learn": [ [ "schematics_molebot", 7 ] ], + "difficulty": 3, + "time": 30000, + "using": [ [ "soldering_standard", 10 ], [ "welding_standard", 6 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "motor", 1 ] ], + [ [ "steel_chunk", 20 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_riotbot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 7 ], [ "computer", 6 ] ], + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_riotbot", 7 ] ], + "difficulty": 6, + "time": 40000, + "using": [ [ "soldering_standard", 20 ], [ "welding_standard", 5 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "omni_wheel", 1 ] ], + [ [ "copbot_chassis", 1 ] ], + [ [ "android_arms", 1 ] ], + [ [ "power_supply", 4 ] ], + [ [ "solar_cell", 2 ] ], + [ [ "canister_empty", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_skitterbot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 6 ], [ "computer", 5 ] ], + "reversible": true, + "decomp_learn": 5, + "book_learn": [ [ "schematics_skitterbot", 7 ] ], + "difficulty": 5, + "time": 30000, + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "scrap", 1 ] ], + [ [ "spidery_legs_small", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "tazer", 2 ] ], + [ [ "scrap", 4 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_science_bot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 6 ], [ "computer", 5 ] ], + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_sciencebot", 7 ] ], + "difficulty": 5, + "time": 60000, + "using": [ [ "soldering_standard", 20 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "medium_storage_battery", 1 ] ], + [ [ "spidery_legs_small", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "power_supply", 3 ] ], + [ [ "geiger_off", 1 ] ], + [ [ "tazer", 2 ] ], + [ [ "scrap", 6 ] ], + [ [ "plut_cell", 1 ] ], + [ [ "steel_chunk", 6 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_tankbot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 9 ], [ "computer", 8 ] ], + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_tankbot", 9 ] ], + "difficulty": 9, + "time": 75000, + "using": [ [ "soldering_standard", 30 ], [ "welding_standard", 20 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "tank_tread", 1 ] ], + [ [ "tankbot_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "gun_module", 3 ] ], + [ [ "flamethrower", 1 ] ], + [ [ "tazer", 1 ] ], + [ [ "m4a1", 1 ] ], + [ [ "power_supply", 20 ] ], + [ [ "storage_battery", 1 ] ], + [ [ "plut_cell", 4 ] ], + [ [ "mil_plate", 2 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_tripod", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 9 ], [ "computer", 8 ] ], + "reversible": true, + "decomp_learn": 8, + "book_learn": [ [ "schematics_tripod", 9 ] ], + "difficulty": 9, + "time": 60000, + "using": [ [ "soldering_standard", 10 ], [ "welding_standard", 10 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "spidery_legs_big", 1 ] ], + [ [ "tripod_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "gun_module", 1 ] ], + [ [ "power_supply", 12 ] ], + [ [ "storage_battery", 1 ] ], + [ [ "flamethrower", 1 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_chickenbot", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 10 ], [ "computer", 9 ] ], + "reversible": true, + "decomp_learn": 9, + "book_learn": [ [ "schematics_chickenbot", 10 ] ], + "difficulty": 10, + "time": 75000, + "using": [ [ "soldering_standard", 30 ], [ "welding_standard", 20 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "memory_module", 1 ] ], + [ [ "pathfinding_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "reverse_jointed_legs", 1 ] ], + [ [ "chickenbot_chassis", 1 ] ], + [ [ "targeting_module", 1 ] ], + [ [ "gun_module", 3 ] ], + [ [ "mark19", 1 ] ], + [ [ "tazer", 1 ] ], + [ [ "m249", 1 ] ], + [ [ "power_supply", 20 ] ], + [ [ "storage_battery", 1 ] ], + [ [ "plut_cell", 4 ] ], + [ [ "mil_plate", 2 ] ] + ] + }, + { + "type": "recipe", + "result": "bot_antimateriel", + "category": "CC_ELECTRONIC", + "subcategory": "CSC_ELECTRONIC_OTHER", + "skill_used": "electronics", + "skills_required": [ [ "mechanics", 6 ], [ "computer", 5 ] ], + "reversible": true, + "decomp_learn": 5, + "book_learn": [ [ "schematics_antimateriel", 7 ] ], + "difficulty": 5, + "time": 75000, + "using": [ [ "soldering_standard", 10 ] ], + "qualities": [ + { "id": "SCREW", "level": 1 }, + { "id": "SCREW_FINE", "level": 1 }, + { "id": "WRENCH", "level": 2 }, + { "id": "WRENCH_FINE", "level": 1 } + ], + "components": [ + [ [ "ai_module", 1 ] ], + [ [ "RAM", 1 ] ], + [ [ "gun_module", 1 ] ], + [ [ "m107a1", 1 ] ], + [ [ "small_storage_battery", 1 ] ], + [ [ "sensor_module", 1 ] ], + [ [ "identification_module", 1 ] ], + [ [ "power_supply", 1 ] ], + [ [ "turret_chassis", 1 ] ] ] }, { diff --git a/data/json/recipes/recipe_others.json b/data/json/recipes/recipe_others.json index 285ed91db9f5c..918bc4542a434 100644 --- a/data/json/recipes/recipe_others.json +++ b/data/json/recipes/recipe_others.json @@ -1728,6 +1728,32 @@ "qualities": [ { "id": "HAMMER", "level": 2 } ], "components": [ [ [ "sheet_metal", 1 ] ] ] }, + { + "type": "recipe", + "result": "55gal_firebarrel", + "category": "CC_OTHER", + "subcategory": "CSC_OTHER_TOOLS", + "skill_used": "survival", + "difficulty": 1, + "time": 2000, + "autolearn": true, + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "tools": [ [ [ "spike", -1 ], [ "sharp_rock", -1 ], [ "rebar", -1 ], [ "spear_rebar", -1 ] ] ], + "components": [ [ [ "55gal_drum", 1 ] ] ] + }, + { + "type": "recipe", + "result": "30gal_firebarrel", + "category": "CC_OTHER", + "subcategory": "CSC_OTHER_TOOLS", + "skill_used": "survival", + "difficulty": 1, + "time": 2000, + "autolearn": true, + "qualities": [ { "id": "HAMMER", "level": 1 } ], + "tools": [ [ [ "spike", -1 ], [ "sharp_rock", -1 ], [ "rebar", -1 ], [ "spear_rebar", -1 ] ] ], + "components": [ [ [ "30gal_drum", 1 ] ] ] + }, { "type": "recipe", "result": "metal_tank", @@ -1832,174 +1858,6 @@ [ [ "stick", 4 ], [ "broom", 4 ], [ "2x4", 4 ], [ "pool_cue", 4 ] ] ] }, - { - "type": "recipe", - "result": "bot_manhack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 6, - "time": 25000, - "reversible": true, - "decomp_learn": 7, - "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "spike", 2 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "small_storage_battery", 1 ] ], - [ [ "scrap", 2 ] ], - [ [ "motor_small", 1 ] ] - ] - }, - { - "type": "recipe", - "result": "bot_grenade_hack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 6, - "time": 25000, - "reversible": true, - "decomp_learn": 7, - "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "grenade", 1 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "small_storage_battery", 1 ] ], - [ [ "scrap", 2 ] ], - [ [ "motor_small", 1 ] ] - ] - }, - { - "type": "recipe", - "result": "bot_mininuke_hack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 7, - "time": 35000, - "reversible": true, - "decomp_learn": 8, - "book_learn": [ [ "recipe_lab_elec", 7 ], [ "textbook_robots", 8 ] ], - "using": [ [ "soldering_standard", 20 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "mininuke", 1 ] ], - [ [ "processor", 2 ] ], - [ [ "RAM", 2 ] ], - [ [ "power_supply", 2 ] ], - [ [ "small_storage_battery", 2 ] ], - [ [ "scrap", 4 ] ], - [ [ "motor_small", 2 ] ] - ] - }, - { - "type": "recipe", - "result": "bot_gasbomb_hack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 6, - "time": 25000, - "reversible": true, - "decomp_learn": 7, - "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "gasbomb", 1 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "small_storage_battery", 1 ] ], - [ [ "scrap", 2 ] ], - [ [ "motor_small", 1 ] ] - ] - }, - { - "type": "recipe", - "result": "bot_EMP_hack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 6, - "time": 25000, - "reversible": true, - "decomp_learn": 7, - "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "EMPbomb", 1 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "small_storage_battery", 1 ] ], - [ [ "scrap", 2 ] ], - [ [ "motor_small", 1 ] ] - ] - }, - { - "type": "recipe", - "result": "bot_flashbang_hack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 6, - "time": 25000, - "reversible": true, - "decomp_learn": 7, - "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "flashbang", 1 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "small_storage_battery", 1 ] ], - [ [ "scrap", 2 ] ], - [ [ "motor_small", 1 ] ] - ] - }, - { - "type": "recipe", - "result": "bot_c4_hack", - "category": "CC_OTHER", - "subcategory": "CSC_OTHER_OTHER", - "skill_used": "mechanics", - "skills_required": [ [ "electronics", 5 ], [ "computer", 5 ] ], - "difficulty": 6, - "time": 25000, - "reversible": true, - "decomp_learn": 7, - "book_learn": [ [ "recipe_lab_elec", 6 ], [ "textbook_robots", 7 ] ], - "using": [ [ "soldering_standard", 10 ] ], - "qualities": [ { "id": "SCREW", "level": 1 } ], - "components": [ - [ [ "c4", 1 ] ], - [ [ "processor", 1 ] ], - [ [ "RAM", 1 ] ], - [ [ "power_supply", 1 ] ], - [ [ "small_storage_battery", 1 ] ], - [ [ "scrap", 2 ] ], - [ [ "motor_small", 1 ] ] - ] - }, { "type": "recipe", "result": "scrap_copper", diff --git a/data/json/recipes/recipe_vehicle.json b/data/json/recipes/recipe_vehicle.json index e6de8010fe2f4..49f111c827c1b 100644 --- a/data/json/recipes/recipe_vehicle.json +++ b/data/json/recipes/recipe_vehicle.json @@ -23,7 +23,7 @@ [ [ "cable", 40 ] ], [ [ "frame", 1 ] ], [ [ "steel_plate", 8 ] ], - [ [ "water", 150 ] ] + [ [ "water", 150 ], [ "water_clean", 150 ] ] ] }, { diff --git a/data/json/terrain.json b/data/json/terrain.json index bbd7ea52d6371..ef55b5af85c55 100644 --- a/data/json/terrain.json +++ b/data/json/terrain.json @@ -6850,6 +6850,7 @@ "type": "terrain", "id": "t_gas_pump", "name": "gasoline pump", + "description": "Precious GASOLINE. The former world bowed to their petroleum god as it led them to their ruin. There's plenty left over to fuel your inner road warrior. If this gas dispenser doesn't give up the goods for free, you may have to pay at a nearby terminal.", "symbol": "&", "color": "red", "move_cost": 0, @@ -6932,6 +6933,7 @@ "type": "terrain", "id": "t_diesel_pump", "name": "diesel pump", + "description": "This is a diesel fuel pump. This roadside attraction provides all the thick, gloopy liquid POWER you need to move your sensibly oversized APOCOLYPTIC SUPERTRUCK from point A to points beyond. If it doesn't dispense fuel immediately, try banging on it or grunt your way over the nearby payment terminal.", "symbol": "&", "color": "green", "move_cost": 0, @@ -6974,6 +6976,7 @@ "type": "terrain", "id": "t_atm", "name": "ATM", + "description": "For your banking convenience, this Automated Teller Machine is fully capable of operating autonomously in the event of complete network failure. You can deposit funds from cash cards and migrate all of your inflation-adjusted earnings to a single card. These things have seen better days. There's been a run on the bank, and this machine has the dents and cracks to prove it.", "symbol": "&", "color": "magenta", "move_cost": 0, @@ -7016,6 +7019,7 @@ "type": "terrain", "id": "t_missile", "name": "missile", + "description": "This is a section of an ICBM, an Intercontinental Ballistic Missile. This isn't the kind of rocket that goes to the moon.", "symbol": "#", "color": "light_blue", "move_cost": 0, @@ -7034,6 +7038,7 @@ "type": "terrain", "id": "t_missile_exploded", "name": "blown-out missile", + "description": "This is a section of an ICBM, an Intercontiental Ballistic Missile. This isn't the kind of rocket that's going anywhere.", "symbol": "#", "color": "light_gray", "move_cost": 0, @@ -7055,6 +7060,7 @@ "type": "terrain", "id": "t_radio_tower", "name": "radio tower", + "description": "This is the structure of a radio transmission tower.", "symbol": "&", "color": "light_gray", "move_cost": 0, @@ -7076,6 +7082,7 @@ "type": "terrain", "id": "t_radio_controls", "name": "radio controls", + "description": "This console appears to control a nearby radio transmission tower. It doesn't seem to be fully operational.", "symbol": "6", "color": "green", "move_cost": 0, @@ -7120,6 +7127,7 @@ "type": "terrain", "id": "t_console_broken", "name": "broken console", + "description": "This is a standalone computer terminal. It doesn't seem to be working. It's the broken screen and shattered circuit boards that's telling you that.", "symbol": "6", "color": "light_gray", "move_cost": 0, @@ -7164,6 +7172,7 @@ "type": "terrain", "id": "t_console", "name": "computer console", + "description": "This is a standalone computer terminal. It can be used to view contents and perform any allowed functions. It might even be possible to hack it, given the skills.", "symbol": "6", "color": "blue", "move_cost": 0, @@ -7208,6 +7217,7 @@ "type": "terrain", "id": "t_gates_mech_control", "name": "mechanical winch", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate or door.", "symbol": "6", "color": "cyan_red", "move_cost": 0, @@ -7226,6 +7236,7 @@ "type": "terrain", "id": "t_gates_mech_control_lab", "name": "mechanical winch", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "cyan_red", "move_cost": 0, @@ -7244,6 +7255,7 @@ "type": "terrain", "id": "t_gates_control_concrete", "name": "mechanical winch", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "cyan_red", "move_cost": 0, @@ -7262,6 +7274,7 @@ "type": "terrain", "id": "t_gates_control_concrete_lab", "name": "mechanical winch", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "cyan_red", "move_cost": 0, @@ -7280,6 +7293,7 @@ "type": "terrain", "id": "t_gates_control_brick", "name": "mechanical winch", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "cyan_red", "move_cost": 0, @@ -7298,6 +7312,7 @@ "type": "terrain", "id": "t_gates_control_brick_lab", "name": "mechanical winch", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "cyan_red", "move_cost": 0, @@ -7316,6 +7331,7 @@ "type": "terrain", "id": "t_gates_control_metal", "name": "control lever", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "white", "move_cost": 0, @@ -7334,6 +7350,7 @@ "type": "terrain", "id": "t_gates_control_metal_lab", "name": "control lever", + "description": "This is a gate control winch. If it's functioning, it can be used to open or close a nearby gate.", "symbol": "6", "color": "white", "move_cost": 0, @@ -7399,7 +7416,8 @@ { "type": "terrain", "id": "t_sewage_pipe", - "name": "sewage pipe", + "name": "high gauge pipe", + "description": "This is a section of high gauge pipe.", "symbol": "1", "color": "light_gray", "move_cost": 0, @@ -7417,7 +7435,8 @@ { "type": "terrain", "id": "t_sewage_pump", - "name": "sewage pump", + "name": "high gauge pump", + "description": "This unpowered pump previously would have moved fluids around in a hurry.", "symbol": "&", "color": "light_gray", "move_cost": 0, @@ -7440,6 +7459,7 @@ "type": "terrain", "id": "t_centrifuge", "name": "centrifuge", + "description": "This is a centrifuge, a liquid separating device with an automated analyzer unit. It could be used to analyze a medical fluid sample, such as blood, if a test tube was placed in it.", "symbol": "{", "color": "magenta", "move_cost": 0, @@ -7465,6 +7485,7 @@ "type": "terrain", "id": "t_cvdbody", "name": "CVD machine", + "description": "The bulk of a highly technical-looking apparatus controlled by a nearby console.", "symbol": "%", "color": "dark_gray", "move_cost": 0, @@ -7487,6 +7508,7 @@ "type": "terrain", "id": "t_cvdmachine", "name": "CVD control panel", + "description": "This is a VERY expensive-looking apparatus that's labeled 'Chemical Vapor Deposition Machine'. With the input of certain exceptionally rare chemicals and elements, one could conceievably coat one's weapon with diamond. While the process is extremely complicated, a previous user has helpfully sketched: Hydrogen + charcoal = smiley face.", "symbol": "&", "color": "cyan", "move_cost": 0, @@ -7656,6 +7678,7 @@ "type": "terrain", "id": "t_manhole", "name": "manhole", + "description": "This is a manhole. The heavy iron cover lies over an entrance to the underworld of hidden tunnels beneath the streets where sewage and rain water frolic freely.", "symbol": ">", "color": "dark_gray", "move_cost": 2, @@ -7757,6 +7780,7 @@ "type": "terrain", "id": "t_card_science", "name": "card reader", + "description": "This is a smartcard reader. It sports the stylized symbol of an atom inside a flask that is universally known to indicate SCIENCE. The stark red LED blinks askance at your geek cred. You could swipe a scientific ID badge near it to unlock the gates to discovery.", "//": "Science", "symbol": "6", "color": "pink", @@ -7776,6 +7800,7 @@ "type": "terrain", "id": "t_card_military", "name": "card reader", + "description": "This is a smartcard reader. The universal symbol of an eagle driving a tank, biting a grenade pin stands rampant in front of an American flag. A small, red LED remains constant, as if watching you, waiting. You could swipe a military ID card in front of the reader if you dared.", "//": "Military", "symbol": "6", "color": "pink", @@ -7796,6 +7821,7 @@ "id": "t_card_industrial", "looks_like": "t_card_science", "name": "card reader", + "description": "This is a smartcard reader. The symbol of a gear in front of a bulging bicep is emblazoned on the matte black surface with an illegible heavy industrial company title. A red LED blinks on the card reader. Perhaps an industrial ID card could still open it.", "//": "Industrial", "symbol": "6", "color": "pink", @@ -7815,6 +7841,7 @@ "type": "terrain", "id": "t_card_reader_broken", "name": "broken card reader", + "description": "This is a smartcard reader, but it doesn't seem to be functioning. Probably because there's no more blinking red LED.", "symbol": "6", "color": "light_gray", "move_cost": 0, @@ -7841,6 +7868,7 @@ "type": "terrain", "id": "t_slot_machine", "name": "slot machine", + "description": "A machine with a bright screen flashing hypnotic promises of wealth. If gambling with your life on a daily basis isn't enough for you, you can also gamble with this.", "symbol": "6", "color": "green", "move_cost": 0, @@ -7871,6 +7899,7 @@ "type": "terrain", "id": "t_elevator_control", "name": "elevator controls", + "description": "This is the control face for an elevator. You could press the appropriate button to take you to your choice of floor.", "symbol": "6", "color": "light_blue", "move_cost": 0, @@ -7901,6 +7930,7 @@ "type": "terrain", "id": "t_elevator_control_off", "name": "powerless controls", + "description": "This is the control face for an elevator. It's currently unpowered.", "symbol": "6", "color": "light_gray", "move_cost": 0, @@ -8591,6 +8621,7 @@ "type": "terrain", "id": "t_plut_generator", "name": "plutonium generator", + "description": "This imposing apparatus harnesses the power of the atom. Refined nuclear fuel is 'burned' to provide nearly limitless electrical power. It's not doing much good here though. Perhaps it could be salvaged for other purposes.", "symbol": "0", "color": "light_green", "move_cost": 0, @@ -10372,5 +10403,160 @@ "ter_set": "t_fence_post", "items": [ { "item": "material_soil", "count": [ 100, 150 ] } ] } + }, + { + "type": "terrain", + "id": "t_splitrail_fence", + "aliases": [ "t_splitrail_fence_h", "t_splitrail_fence_v" ], + "name": "split rail fence", + "description": "A rather stout fence made of 2x4s and fence posts, suitable for containing livestock like horses, cows and pigs.", + "symbol": "LINE_OXOX", + "color": "brown", + "looks_like": "t_fence", + "move_cost": 0, + "examine_action": "chainfence", + "flags": [ "TRANSPARENT", "NOITEM", "THIN_OBSTACLE", "PERMEABLE", "FLAMMABLE_ASH", "CLIMBABLE", "AUTO_WALL_SYMBOL" ], + "connects_to": "WOODFENCE", + "deconstruct": { "ter_set": "t_fence_post", "items": [ { "item": "2x4", "count": 2 }, { "item": "nail", "count": 20 } ] }, + "bash": { + "str_min": 5, + "str_max": 12, + "sound": "whump!", + "sound_fail": "whack!", + "ter_set": "t_fence_post", + "items": [ { "item": "2x4", "count": [ 1, 2 ] } ] + } + }, + { + "type": "terrain", + "id": "t_splitrail_fencegate_c", + "name": "closed wooden split rail gate", + "description": "A commercial quality gate made of wood with a latch system.", + "symbol": "+", + "color": "brown", + "looks_like": "t_fencegate_c", + "move_cost": 0, + "coverage": 60, + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "DOOR" ], + "connects_to": "WOODFENCE", + "open": "t_splitrail_fencegate_o", + "deconstruct": { + "ter_set": "t_dirt", + "items": [ { "item": "2x4", "count": 5 }, { "item": "pointy_stick", "count": 2 }, { "item": "nail", "charges": 12 } ] + }, + "bash": { + "str_min": 4, + "str_max": 20, + "str_min_blocked": 6, + "str_max_blocked": 30, + "sound": "crack.", + "sound_fail": "wham.", + "ter_set": "t_null", + "items": [ + { "item": "2x4", "count": [ 1, 4 ] }, + { "item": "nail", "charges": [ 2, 8 ] }, + { "item": "splinter", "count": [ 1, 2 ] } + ] + } + }, + { + "type": "terrain", + "id": "t_splitrail_fencegate_o", + "name": "open wooden split rail gate", + "description": "A commercial quality gate made of wood with a latch system. The gate is wide open, allowing anything to travel through.", + "symbol": ".", + "color": "brown", + "looks_like": "t_fencegate_o", + "move_cost": 1, + "flags": [ "TRANSPARENT", "FLAMMABLE_ASH", "FLAT", "ROAD" ], + "connects_to": "WOODFENCE", + "close": "t_splitrail_fencegate_c", + "deconstruct": { + "ter_set": "t_dirt", + "items": [ { "item": "2x4", "count": 5 }, { "item": "pointy_stick", "count": 2 }, { "item": "nail", "charges": 12 } ] + } + }, + { + "type": "terrain", + "id": "t_privacy_fence", + "aliases": [ "t_privacy_fence_h", "t_privacy_fence_v" ], + "name": "wooden privacy fence", + "description": "A rather stout fence made of 2x4s and fence posts, it is tall and prevents people from seeing into your yard.", + "symbol": "LINE_OXOX", + "color": "brown", + "looks_like": "t_fence", + "move_cost": 0, + "examine_action": "chainfence", + "flags": [ "NOITEM", "CLIMBABLE", "PERMEABLE", "AUTO_WALL_SYMBOL", "FLAMMABLE_ASH", "THIN_OBSTACLE" ], + "connects_to": "WOODFENCE", + "deconstruct": { "ter_set": "t_fence_post", "items": [ { "item": "2x4", "count": 10 }, { "item": "nail", "count": 20 } ] }, + "bash": { + "str_min": 5, + "str_max": 12, + "sound": "whump!", + "sound_fail": "whack!", + "ter_set": "t_fence_post", + "items": [ { "item": "2x4", "count": [ 4, 10 ] } ] + } + }, + { + "type": "terrain", + "id": "t_privacy_fencegate_c", + "name": "closed wooden split rail gate", + "description": "A commercial quality gate made of wood with a latch system.", + "symbol": "+", + "color": "brown", + "looks_like": "t_fencegate_c", + "move_cost": 0, + "coverage": 60, + "flags": [ "FLAMMABLE_ASH", "DOOR" ], + "connects_to": "WOODFENCE", + "open": "t_privacy_fencegate_o", + "deconstruct": { + "ter_set": "t_dirt", + "items": [ { "item": "2x4", "count": 8 }, { "item": "pointy_stick", "count": 2 }, { "item": "nail", "charges": 20 } ] + }, + "bash": { + "str_min": 4, + "str_max": 20, + "str_min_blocked": 6, + "str_max_blocked": 30, + "sound": "crack.", + "sound_fail": "wham.", + "ter_set": "t_null", + "items": [ + { "item": "2x4", "count": [ 4, 8 ] }, + { "item": "nail", "charges": [ 10, 20 ] }, + { "item": "splinter", "count": [ 4, 6 ] } + ] + } + }, + { + "type": "terrain", + "id": "t_privacy_fencegate_o", + "name": "open wooden split rail gate", + "description": "A commercial quality gate made of wood with a latch system. The gate is wide open, allowing anything to travel through.", + "symbol": ".", + "color": "brown", + "looks_like": "t_fencegate_o", + "move_cost": 1, + "flags": [ "FLAMMABLE_ASH", "FLAT", "ROAD" ], + "connects_to": "WOODFENCE", + "close": "t_privacy_fencegate_c", + "deconstruct": { + "ter_set": "t_dirt", + "items": [ { "item": "2x4", "count": 8 }, { "item": "pointy_stick", "count": 2 }, { "item": "nail", "charges": 20 } ] + } + }, + { + "type": "terrain", + "id": "t_water_pool_shallow", + "name": "shallow pool water", + "description": "A shallow pool of water.", + "symbol": "~", + "color": "light_blue", + "move_cost": 5, + "flags": [ "TRANSPARENT", "LIQUID", "SWIMMABLE", "INDOORS" ], + "examine_action": "water_source" } ] diff --git a/data/json/vehicle_groups.json b/data/json/vehicle_groups.json index 6c21a32188c37..cea8a8ff3b919 100644 --- a/data/json/vehicle_groups.json +++ b/data/json/vehicle_groups.json @@ -499,5 +499,23 @@ "type": "vehicle_group", "id": "trains_draisine", "vehicles": [ [ "motorized_draisine_6seats", 500 ], [ "motorized_draisine_2seats", 2000 ] ] + }, + { + "type": "vehicle_group", + "id": "oa_vg_ts_vehicles", + "vehicles": [ + [ "car", 2000 ], + [ "electric_car", 500 ], + [ "suv", 800 ], + [ "suv_electric", 200 ], + [ "car_mini", 800 ], + [ "beetle", 500 ], + [ "motorcycle", 200 ], + [ "motorcycle_sidecart", 100 ], + [ "scooter", 200 ], + [ "scooter_electric", 300 ], + [ "pickup", 800 ], + [ "hippie_van", 1000 ] + ] } ] diff --git a/data/mods/DeadPeople_Xotto/modinfo.json b/data/mods/DeadPeople_Xotto/modinfo.json index 0af9f522bab89..915e4557ce42d 100644 --- a/data/mods/DeadPeople_Xotto/modinfo.json +++ b/data/mods/DeadPeople_Xotto/modinfo.json @@ -1,7 +1,7 @@ [ { "type": "MOD_INFO", - "ident": "DP__XOTTO_INDICATORS", + "ident": "DP_XOTTO_INDICATORS", "name": "[DP_MOD] Indicators: Xotto", "authors": [ "SomeDeadGuy" ], "description": "Changes interface indicators to Xotto version.", diff --git a/data/mods/Hydroponics/Hydroponics/construction.json b/data/mods/Hydroponics/construction.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/construction.json rename to data/mods/Hydroponics/construction.json diff --git a/data/mods/Hydroponics/Hydroponics/item_groups.json b/data/mods/Hydroponics/item_groups.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/item_groups.json rename to data/mods/Hydroponics/item_groups.json diff --git a/data/mods/Hydroponics/Hydroponics/mapgen/basement_hydrop.json b/data/mods/Hydroponics/mapgen/basement_hydrop.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/mapgen/basement_hydrop.json rename to data/mods/Hydroponics/mapgen/basement_hydrop.json diff --git a/data/mods/Hydroponics/Hydroponics/mapgen/lab_floorplans_1side.json b/data/mods/Hydroponics/mapgen/lab_floorplans_1side.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/mapgen/lab_floorplans_1side.json rename to data/mods/Hydroponics/mapgen/lab_floorplans_1side.json diff --git a/data/mods/Hydroponics/Hydroponics/mapgen/lab_rooms.json b/data/mods/Hydroponics/mapgen/lab_rooms.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/mapgen/lab_rooms.json rename to data/mods/Hydroponics/mapgen/lab_rooms.json diff --git a/data/mods/Hydroponics/Hydroponics/modinfo.json b/data/mods/Hydroponics/modinfo.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/modinfo.json rename to data/mods/Hydroponics/modinfo.json diff --git a/data/mods/Hydroponics/Hydroponics/requirements.json b/data/mods/Hydroponics/requirements.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/requirements.json rename to data/mods/Hydroponics/requirements.json diff --git a/data/mods/Hydroponics/Hydroponics/terrain.json b/data/mods/Hydroponics/terrain.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/terrain.json rename to data/mods/Hydroponics/terrain.json diff --git a/data/mods/Hydroponics/Hydroponics/tpalletes.json b/data/mods/Hydroponics/tpalletes.json similarity index 100% rename from data/mods/Hydroponics/Hydroponics/tpalletes.json rename to data/mods/Hydroponics/tpalletes.json diff --git a/data/mods/More_Locations/bandit_tower/bandit_tower_3blc_03.json b/data/mods/More_Locations/bandit_tower/bandit_tower_3blc_03.json index 41e709f6a5dba..487804d869ded 100644 --- a/data/mods/More_Locations/bandit_tower/bandit_tower_3blc_03.json +++ b/data/mods/More_Locations/bandit_tower/bandit_tower_3blc_03.json @@ -45,13 +45,12 @@ { "item": "broken_copbot", "chance": 4 }, { "item": "broken_riotbot", "chance": 4 }, { "item": "broken_skitterbot", "chance": 3 } - ], - "l": { "item": "battery", "amount": [ 0, 2 ] } + ] }, "items": { "$": { "item": "bots", "chance": 80 }, "b": { "item": "textbooks", "chance": 60 }, - "l": { "item": "electronics", "chance": 60 }, + "l": [ { "item": "electronics", "chance": 60 }, { "item": "ammo_pocket_batteries_full", "repeat": [ 0, 2 ] } ], "L": { "item": "tools_common", "chance": 60 }, "T": { "item": "tools_common", "chance": 30 }, "X": { "item": "consumer_electronics", "chance": 70 } diff --git a/data/mods/Salvaged_Robots/robot_additions/professions.json b/data/mods/Salvaged_Robots/robot_additions/professions.json index fb278c5a21946..f6e8978d144a1 100644 --- a/data/mods/Salvaged_Robots/robot_additions/professions.json +++ b/data/mods/Salvaged_Robots/robot_additions/professions.json @@ -19,9 +19,9 @@ "broken_skitterbot", "bot_manhack", "electrohack", - "cell_phone", "laptop" - ] + ], + "entries": [ { "group": "charged_cell_phone" } ] }, "male": [ "boxer_shorts" ], "female": [ "sports_bra", "boxer_shorts" ] diff --git a/data/mods/more_classes_scenarios/cs_classes.json b/data/mods/more_classes_scenarios/cs_classes.json index 254e6f90066cb..0efb4e91df78c 100644 --- a/data/mods/more_classes_scenarios/cs_classes.json +++ b/data/mods/more_classes_scenarios/cs_classes.json @@ -133,27 +133,29 @@ { "level": 1, "name": "firstaid" } ], "items": { - "both": [ - "knit_scarf", - "undershirt", - "dress_shirt", - "jacket_light", - "gloves_light", - "pants", - "fanny", - "socks", - "sneakers", - "roadmap", - "restaurantmap", - "shavingkit", - "mess_kit", - "aluminum_foil", - "cell_phone", - "can_chowder", - "apple_cider", - "fruit_leather", - "suitcase_m" - ], + "both": { + "items": [ + "knit_scarf", + "undershirt", + "dress_shirt", + "jacket_light", + "gloves_light", + "pants", + "fanny", + "socks", + "sneakers", + "roadmap", + "restaurantmap", + "shavingkit", + "mess_kit", + "aluminum_foil", + "can_chowder", + "apple_cider", + "fruit_leather", + "suitcase_m" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "boxer_shorts" ], "female": [ "bra", "panties" ] } @@ -291,24 +293,26 @@ "points": 1, "skills": [ { "level": 1, "name": "speech" } ], "items": { - "both": [ - "dress_shirt", - "jacket_light", - "pants", - "socks", - "dress_shoes", - "skinny_tie", - "tieclip", - "fancy_sunglasses", - "knit_scarf", - "wristwatch", - "mbag", - "water_mineral", - "cell_phone", - "money_bundle", - "adderall", - "manual_business" - ], + "both": { + "items": [ + "dress_shirt", + "jacket_light", + "pants", + "socks", + "dress_shoes", + "skinny_tie", + "tieclip", + "fancy_sunglasses", + "knit_scarf", + "wristwatch", + "mbag", + "water_mineral", + "money_bundle", + "adderall", + "manual_business" + ], + "entries": [ { "group": "charged_cell_phone" } ] + }, "male": [ "briefs" ], "female": [ "panties" ] } diff --git a/doc/JSON_FLAGS.md b/doc/JSON_FLAGS.md index 83e7bcb0f8247..578ae2c29ef6a 100644 --- a/doc/JSON_FLAGS.md +++ b/doc/JSON_FLAGS.md @@ -274,6 +274,7 @@ Some armor flags, such as `WATCH` and `ALARMCLOCK` are compatible with other ite - ```BIONIC_SLEEP_FRIENDLY``` This bionic won't prompt the user to turn it off if they try to sleep while it's active. - ```BIONIC_TOGGLED``` This bionic only has a function when activated, else it causes it's effect every turn. - ```BIONIC_WEAPON``` This bionic is a weapon bionic and activating it will create (or destroy) bionic's fake_item in user's hands. Prevents all other activation effects. +- ```BIONIC_SHOCKPROOF``` This bionic can't be incapacitated by electrical attacks. ## Books @@ -1039,8 +1040,6 @@ These branches are also the valid entries for the categories of `dreams` in `dre ### Overmap connections -#### Flags - - ```ORTHOGONAL``` The connection generally prefers straight lines, avoids turning wherever possible. ### Overmap specials diff --git a/doc/JSON_INFO.md b/doc/JSON_INFO.md index ffc8506a79643..a93d2a4829f95 100644 --- a/doc/JSON_INFO.md +++ b/doc/JSON_INFO.md @@ -587,6 +587,17 @@ Mods can modify this via `add:traits` and `remove:traits`. ] ``` +### Constructions +```C++ +"description": "Spike Pit", // Description string displayed in the construction menu +"category": "DIG", // Construction category +"required_skills": [ [ "survival", 1 ] ], // Skill levels required to undertake construction +"time": 30, // Time in minutes required to complete construction +"components": [ [ [ "spear_wood", 4 ], [ "pointy_stick", 4 ] ] ], // Items used in construction +"pre_terrain": "t_pit", // Required terrain to build on +"post_terrain": "t_pit_spiked" // Terrain type after construction is complete +``` + ## Skills ```C++ diff --git a/doc/MARTIALART_JSON.md b/doc/MARTIALART_JSON.md index a0eeb99f24dee..3c4ca11f050f4 100644 --- a/doc/MARTIALART_JSON.md +++ b/doc/MARTIALART_JSON.md @@ -9,6 +9,7 @@ "name" : "Debug Mastery", // In-game name displayed "description": "A secret martial art used only by developers and cheaters.", // In-game description "initiate": [ "You stand ready.", "%s stands ready." ], // Message shown when player or NPC chooses this art +"autolearn": [ [ "unarmed", "2" ] ], // A list of skill requirements that if met, automatically teach the player the martial art "arm_block" : 99, // Unarmed skill level at which arm blocking is unlocked "leg_block" : 99, // Unarmed skill level at which arm blocking is unlocked "static_buffs" : [ // List of buffs that are automatically applied every turn diff --git a/gfx/MSX++DeadPeopleEdition/14_tiles2_32x32_22365-27564.png b/gfx/MSX++DeadPeopleEdition/14_tiles2_32x32_22365-27564.png index 356c4ef7ce7a9..537640bfc5d20 100644 Binary files a/gfx/MSX++DeadPeopleEdition/14_tiles2_32x32_22365-27564.png and b/gfx/MSX++DeadPeopleEdition/14_tiles2_32x32_22365-27564.png differ diff --git a/gfx/MSX++DeadPeopleEdition/15_tiles-connected_variants_32x32_27565-32764.png b/gfx/MSX++DeadPeopleEdition/15_tiles-connected_variants_32x32_27565-32764.png index a2182f9825020..bfa813599812d 100644 Binary files a/gfx/MSX++DeadPeopleEdition/15_tiles-connected_variants_32x32_27565-32764.png and b/gfx/MSX++DeadPeopleEdition/15_tiles-connected_variants_32x32_27565-32764.png differ diff --git a/gfx/MSX++DeadPeopleEdition/18_big_things_64x80_35757.png b/gfx/MSX++DeadPeopleEdition/18_big_things_64x80_35757.png index c156f7c07bfe0..c947b7f8c117b 100644 Binary files a/gfx/MSX++DeadPeopleEdition/18_big_things_64x80_35757.png and b/gfx/MSX++DeadPeopleEdition/18_big_things_64x80_35757.png differ diff --git a/gfx/MSX++DeadPeopleEdition/1_tiles_32x32_0-5199.png b/gfx/MSX++DeadPeopleEdition/1_tiles_32x32_0-5199.png index 36113ab3a3f05..d8397b8e4d081 100644 Binary files a/gfx/MSX++DeadPeopleEdition/1_tiles_32x32_0-5199.png and b/gfx/MSX++DeadPeopleEdition/1_tiles_32x32_0-5199.png differ diff --git a/gfx/MSX++DeadPeopleEdition/3_tree_64x80_5392-5471.png b/gfx/MSX++DeadPeopleEdition/3_tree_64x80_5392-5471.png index e5d48915dfa32..38544beea5b0e 100644 Binary files a/gfx/MSX++DeadPeopleEdition/3_tree_64x80_5392-5471.png and b/gfx/MSX++DeadPeopleEdition/3_tree_64x80_5392-5471.png differ diff --git a/gfx/MSX++DeadPeopleEdition/8_tiles-monster-variants_32x32_11652-16851.png b/gfx/MSX++DeadPeopleEdition/8_tiles-monster-variants_32x32_11652-16851.png index 03423ac72cdd6..c11bb9b8c512a 100644 Binary files a/gfx/MSX++DeadPeopleEdition/8_tiles-monster-variants_32x32_11652-16851.png and b/gfx/MSX++DeadPeopleEdition/8_tiles-monster-variants_32x32_11652-16851.png differ diff --git a/gfx/MSX++DeadPeopleEdition/9_tiles-connected_32x32_16852-22051.png b/gfx/MSX++DeadPeopleEdition/9_tiles-connected_32x32_16852-22051.png index cd3116f25d79e..b7ba02a3a540c 100644 Binary files a/gfx/MSX++DeadPeopleEdition/9_tiles-connected_32x32_16852-22051.png and b/gfx/MSX++DeadPeopleEdition/9_tiles-connected_32x32_16852-22051.png differ diff --git a/gfx/MSX++DeadPeopleEdition/tile_config.json b/gfx/MSX++DeadPeopleEdition/tile_config.json index 7b18ce1741e56..68cabefd3064a 100644 --- a/gfx/MSX++DeadPeopleEdition/tile_config.json +++ b/gfx/MSX++DeadPeopleEdition/tile_config.json @@ -20,7 +20,11 @@ "toolset_extended", "f_fake_bench_hands", "f_fake_bench_ground", - "fake_milling_item" + "fake_milling_item", + "fake_burrowing", + "f_lilypad_season_winter", + "f_lotus_season_winter" + ], "fg": 0, "bg": 0, @@ -52939,10 +52943,6 @@ "fg": 837, "rotates": false }, - { - "id": "hakama_gi", - "fg": 837 - }, { "id": "pants_army", "fg": 838, @@ -53300,11 +53300,6 @@ "bg": 957, "rotates": false }, - { - "id": "sleeveless_trenchcoat", - "fg": 891, - "bg": 957 - }, { "id": "sleeveless_duster", "fg": 891, @@ -53320,11 +53315,6 @@ "fg": 892, "bg": 957 }, - { - "id": "sleeveless_trenchcoat_survivor", - "fg": 893, - "bg": 957 - }, { "id": "sleeveless_duster_survivor", "fg": 893, @@ -53627,58 +53617,30 @@ "id": "hsurvivor_suit", "fg": 931 }, - { - "id": "trenchcoat", - "fg": 932, - "rotates": false - }, { "id": "duster", "fg": 932, "bg": 957, "rotates": false }, - { - "id": "trenchcoat_fur", - "fg": 933, - "bg": 957, - "rotates": false - }, { "id": "duster_fur", "fg": 933, "bg": 957, "rotates": false }, - { - "id": "trenchcoat_leather", - "fg": 934, - "bg": 957, - "rotates": false - }, { "id": "duster_leather", "fg": 934, "bg": 957, "rotates": false }, - { - "id": "sleeveless_trenchcoat_leather", - "fg": 934, - "bg": 957, - "rotates": false - }, { "id": "sleeveless_duster_leather", "fg": 934, "bg": 957, "rotates": false }, - { - "id": "trenchcoat_survivor", - "fg": 935, - "bg": 957 - }, { "id": "duster_survivor", "fg": 935, @@ -54937,7 +54899,7 @@ "rotates": false }, { - "id": "hammer_sledge", + "id": ["hammer_sledge", "fake_drop_hammer"], "fg": 1757, "bg": 957, "rotates": false @@ -55123,7 +55085,7 @@ "rotates": false }, { - "id": "knife_butcher", + "id": "knife_meat_cleaver", "fg": 3586, "bg": 957, "rotates": false @@ -59383,7 +59345,7 @@ "rotates": false }, { - "id": "esbit_stove", + "id": ["esbit_stove", "fake_stove"], "fg": 3509, "bg": 957, "rotates": false @@ -61452,7 +61414,7 @@ { "id": "mon_blob", "fg": 2350, - "bg": 967, + "bg": 0, "rotates": false }, { @@ -69294,7 +69256,7 @@ "rotates": false }, { - "id": "coffee", + "id": ["coffee", "coffee_substitute"], "fg": 1148, "rotates": false }, @@ -71736,7 +71698,7 @@ "rotates": false }, { - "id": "f_fireplace", + "id": ["f_fireplace", "fake_fireplace"], "fg": 1512, "rotates": false }, @@ -72005,7 +71967,7 @@ "rotates": false }, { - "id": "f_sandbag_half", + "id": ["f_sandbag_half", "f_earthbag_half"], "fg": 1561, "rotates": true, "multitile": true, @@ -72037,7 +71999,7 @@ ] }, { - "id": "f_sandbag_wall", + "id": ["f_sandbag_wall", "f_earthbag_wall"], "fg": 1561, "rotates": true, "multitile": true, @@ -83702,7 +83664,7 @@ { "id": "mon_maggot", "fg": 2529, - "bg": 967, + "bg": 0, "rotates": false }, { @@ -84066,7 +84028,7 @@ { "id": "mon_trapdoor_egg", "fg": 2631, - "bg": 967, + "bg": 0, "rotates": false }, { @@ -84108,11 +84070,6 @@ "bg": 5239, "rotates": false }, - { - "id": "mon_vinebeast_pk", - "fg": 2651, - "rotates": false - }, { "id": "mon_vinebeast_terminal", "fg": 2651, @@ -86200,7 +86157,7 @@ "rotates": false }, { - "id": "char_smoker", + "id": ["char_smoker", "fake_char_smoker"], "fg": 3475, "rotates": false }, @@ -86832,7 +86789,7 @@ "rotates": false }, { - "id": "overlay_wielded_cavalry_sabre_fake", + "id": ["overlay_wielded_cavalry_sabre_fake", "overlay_wielded_cavalry_sabre"], "fg": 3652, "rotates": false }, @@ -87072,7 +87029,7 @@ "rotates": false }, { - "id": "overlay_wielded_knife_butcher", + "id": "overlay_wielded_knife_meat_cleaver", "fg": 3671, "rotates": false }, @@ -93012,7 +92969,7 @@ { "id": "mon_stemcell_nether", "fg": 4223, - "bg": 967, + "bg": 0, "rotates": false }, { @@ -95575,6 +95532,20 @@ ], "bg": 967, "rotates": false + }, + { + "id": "mon_furvivor", + "fg": [ + { "weight":111, "sprite":2480}, + { "weight":111, "sprite":12164}, + { "weight":111, "sprite":12165}, + { "weight":111, "sprite":12166}, + { "weight":111, "sprite":12167}, + { "weight":111, "sprite":12168}, + { "weight":111, "sprite":12169} + ], + "bg": 967, + "rotates": false } ] @@ -96149,7 +96120,11 @@ "multitile": true, "additional_tiles": [ { - "fg": 16996, + "fg": [{ "weight":1, "sprite":16996}, + { "weight":1, "sprite":27716}, + { "weight":1, "sprite":27717}, + { "weight":1, "sprite":27718}, + { "weight":1, "sprite":27719}], "bg": 985, "id": "center" }, @@ -98577,25 +98552,25 @@ "id": "corner", "fg": [ 17445, 17446, 17447, 17448 ], "bg": 5131 - }, - { - "id": "edge", + }, + { + "id": "t_connection", "fg": [ 17449, 17450, 17451, 17452 ], "bg": 5131 }, { - "id": "t_connection", - "fg": 17453, + "id": "edge", + "fg": [ 17453, 17454 ], "bg": 5131 }, - { + { "id": "end_piece", "fg": [ 17455, 17456, 17457, 17458 ], "bg": 5131 }, { "id": "unconnected", - "fg": 17444, + "fg": 17459, "bg": 5131 } ] @@ -98614,27 +98589,27 @@ }, { "id": "corner", - "fg": 17461, + "fg": [ 17461, 17462, 17463, 17464 ], + "bg": 5131 + }, + { + "id": "t_connection", + "fg": [ 17465, 17466, 17467, 17468 ], "bg": 5131 }, { "id": "edge", - "fg": 17465, + "fg": [ 17469, 17470 ], "bg": 5131 }, { "id": "end_piece", - "fg": 17465, - "bg": 5131 - }, - { - "id": "t_connection", - "fg": 17469, + "fg": [ 17471, 17472, 17473, 17474 ], "bg": 5131 }, { "id": "unconnected", - "fg": 0, + "fg": 17475, "bg": 5131 } ] @@ -98653,27 +98628,27 @@ }, { "id": "corner", - "fg": 17476, + "fg": [ 17477, 17478, 17479, 17480 ], "bg": 5131 - }, - { - "id": "edge", + }, + { + "id": "t_connection", "fg": [ 17481, 17482, 17483, 17484 ], "bg": 5131 }, { - "id": "t_connection", - "fg": 17485, + "id": "edge", + "fg": [ 17485, 17486 ], "bg": 5131 }, - { + { "id": "end_piece", "fg": [ 17487, 17488, 17489, 17490 ], "bg": 5131 }, { "id": "unconnected", - "fg": 17476, + "fg": 17491, "bg": 5131 } ] @@ -102164,7 +102139,7 @@ ] }, { - "id": "!t_door_metal_c", + "id": "t_wall_w", "fg": 18772, "bg": 0, "rotates": false, @@ -102201,54 +102176,823 @@ "bg": 0 } ] - } - ] - }, - { - "file": "10_xfiles_32x32_22052-22195.png", - "tiles": [ - { - "id": "mon_pink_mist", - "fg": 22052, - "rotates": false - }, - { - "id": "mon_entomber", - "fg": 22054, - "rotates": false - }, - { - "id": "mon_bloodbeast", - "fg": 22053, - "rotates": false - }, - { - "id": "mon_worm_mass", - "fg": 22061, - "rotates": false - }, - { - "id": "mon_bloodworm", - "fg": 22062, - "rotates": false - }, - { - "id": "mon_grey_grunt", - "fg": 22055, - "rotates": false - }, - { - "id": "mon_alien_turret", - "fg": 22056, - "rotates": false - }, + }, + { + "id": "t_rock_red", + "fg": 18788, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18788, + "bg": 0 + }, + { + "id": "corner", + "fg": [18789, 18790, 18791, 18792], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18793, 18794, 18795, 18796], + "bg": 0 + }, + { + "id": "edge", + "fg": [18797, 18798], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18799, 18800, 18801, 18802], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18803, + "bg": 0 + } + ] + }, + { + "id": "t_rock_green", + "fg": 18804, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18804, + "bg": 0 + }, + { + "id": "corner", + "fg": [18805, 18806, 18807, 18808], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18809, 18810, 18811, 18812], + "bg": 0 + }, + { + "id": "edge", + "fg": [18813, 18814], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18815, 18816, 18817, 18818], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18819, + "bg": 0 + } + ] + }, + { + "id": "t_rock_blue", + "fg": 18820, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18820, + "bg": 0 + }, + { + "id": "corner", + "fg": [18821, 18822, 18823, 18824], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18825, 18826, 18827, 18828], + "bg": 0 + }, + { + "id": "edge", + "fg": [18829, 18830], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18831, 18832, 18833, 18834], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18835, + "bg": 0 + } + ] + }, + { + "id": "t_wall_r", + "fg": 18836, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18836, + "bg": 0 + }, + { + "id": "corner", + "fg": [18837, 18838, 18839, 18840], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18841, 18842, 18843, 18844], + "bg": 0 + }, + { + "id": "edge", + "fg": [18845, 18846], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18847, 18848, 18849, 18850], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18851, + "bg": 0 + } + ] + }, + { + "id": "t_wall_b", + "fg": 18852, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18852, + "bg": 0 + }, + { + "id": "corner", + "fg": [18853, 18854, 18855, 18856], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18857, 18858, 18859, 18860], + "bg": 0 + }, + { + "id": "edge", + "fg": [18861, 18862], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18863, 18864, 18865, 18866], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18867, + "bg": 0 + } + ] + }, + { + "id": "t_wall_g", + "fg": 18868, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18868, + "bg": 0 + }, + { + "id": "corner", + "fg": [18869, 18870, 18871, 18872], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18873, 18874, 18875, 18876], + "bg": 0 + }, + { + "id": "edge", + "fg": [18877, 18878], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18879, 18880, 18881, 18882], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18883, + "bg": 0 + } + ] + }, + { + "id": "t_wall_p", + "fg": 18884, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18884, + "bg": 0 + }, + { + "id": "corner", + "fg": [18885, 18886, 18887, 18888], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18889, 18890, 18891, 18892], + "bg": 0 + }, + { + "id": "edge", + "fg": [18893, 18894], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18895, 18896, 18897, 18898], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18899, + "bg": 0 + } + ] + }, + { + "id": "t_wall_y", + "fg": 18900, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18900, + "bg": 0 + }, + { + "id": "corner", + "fg": [18901, 18902, 18903, 18904], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18905, 18906, 18907, 18908], + "bg": 0 + }, + { + "id": "edge", + "fg": [18909, 18910], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18911, 18912, 18913, 18914], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18915, + "bg": 0 + } + ] + }, + { + "id": "t_rock_wall", + "fg": 18916, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18916, + "bg": 0 + }, + { + "id": "corner", + "fg": [18917, 18918, 18919, 18920], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18921, 18922, 18923, 18924], + "bg": 0 + }, + { + "id": "edge", + "fg": [18925, 18926], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18927, 18928, 18929, 18930], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18931, + "bg": 0 + } + ] + }, + { + "id": "t_rock_wall_half", + "fg": 18932, + "bg": 985, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18932, + "bg": 985 + }, + { + "id": "corner", + "fg": [18933, 18934, 18935, 18936], + "bg": 985 + }, + { + "id": "t_connection", + "fg": [18937, 18938, 18939, 18940], + "bg": 985 + }, + { + "id": "edge", + "fg": [18941, 18942], + "bg": 985 + }, + { + "id": "end_piece", + "fg": [18943, 18944, 18945, 18946], + "bg": 985 + }, + { + "id": "unconnected", + "fg": 18947, + "bg": 985 + } + ] + }, + { + "id": "f_makeshift_bed", + "fg": 18948, + "bg": 0, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18948, + "bg": 0 + }, + { + "id": "corner", + "fg": [18949, 18950, 18951, 18952], + "bg": 0 + }, + { + "id": "t_connection", + "fg": [18953, 18954, 18955, 18956], + "bg": 0 + }, + { + "id": "edge", + "fg": [18957, 18958], + "bg": 0 + }, + { + "id": "end_piece", + "fg": [18959, 18960, 18961, 18962], + "bg": 0 + }, + { + "id": "unconnected", + "fg": 18963, + "bg": 0 + } + ] + }, { - "id": "mon_loch_ness_monster", - "fg": 22057, - "rotates": false - }, + "id": "t_sludge", + "fg": 18964, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18964, + "bg": 972 + }, + { + "id": "corner", + "fg": [18965, 18966, 18967, 18968], + "bg": 972 + }, + { + "id": "t_connection", + "fg": [18969, 18970, 18971, 18972], + "bg": 972 + }, + { + "id": "edge", + "fg": [18973, 18974], + "bg": 972 + }, + { + "id": "end_piece", + "fg": [18975, 18976, 18977, 18978], + "bg": 972 + }, + { + "id": "unconnected", + "fg": 18979, + "bg": 972 + } + ] + }, { - "id": "mon_jersey_devil", + "id": "t_tar", + "fg": 18980, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18980, + "bg": 972 + }, + { + "id": "corner", + "fg": [18981, 18982, 18983, 18984], + "bg": 972 + }, + { + "id": "t_connection", + "fg": [18985, 18986, 18987, 18988], + "bg": 972 + }, + { + "id": "edge", + "fg": [18989, 18990], + "bg": 972 + }, + { + "id": "end_piece", + "fg": [18991, 18992, 18993, 18994], + "bg": 972 + }, + { + "id": "unconnected", + "fg": 18995, + "bg": 972 + } + ] + }, { + "id": "t_rock_smooth", + "fg": 18996, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 18996, + "bg": 972 + }, + { + "id": "corner", + "fg": [18997, 18998, 18999, 19000], + "bg": 972 + }, + { + "id": "t_connection", + "fg": [19001, 19002, 19003, 19004], + "bg": 972 + }, + { + "id": "edge", + "fg": [19005, 19006], + "bg": 972 + }, + { + "id": "end_piece", + "fg": [19007, 19008, 19009, 19010], + "bg": 972 + }, + { + "id": "unconnected", + "fg": 19011, + "bg": 972 + } + ] + },{ + "id": "t_conveyor", + "fg": 19012, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 19012, + "bg": 972 + }, + { + "id": "corner", + "fg": [19013, 19014, 19015, 19016], + "bg": 972 + }, + { + "id": "t_connection", + "fg": [19017, 19018, 19019, 19020], + "bg": 972 + }, + { + "id": "edge", + "fg": [19021, 19022], + "bg": 972 + }, + { + "id": "end_piece", + "fg": [19023, 19024, 19025, 19026], + "bg": 972 + }, + { + "id": "unconnected", + "fg": 19027, + "bg": 972 + } + ] + },{ + "id": "t_machinery_heavy", + "fg": 19028, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 19028, + "bg": 972 + }, + { + "id": "corner", + "fg": [19029, 19030, 19031, 19032], + "bg": 972 + }, + { + "id": "t_connection", + "fg": [19033, 19034, 19035, 19036], + "bg": 972 + }, + { + "id": "edge", + "fg": [19037, 19038], + "bg": 972 + }, + { + "id": "end_piece", + "fg": [19039, 19040, 19041, 19042], + "bg": 972 + }, + { + "id": "unconnected", + "fg": 19043, + "bg": 972 + } + ] + }, + { + "id": "t_wall_rammed_earth", + "fg": 19044, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 19044, + "bg": 972 + }, + { + "id": "corner", + "fg": [19045, 19046, 19047, 19048], + "bg": 972 + }, + { + "id": "t_connection", + "fg": [19049, 19050, 19051, 19052], + "bg": 972 + }, + { + "id": "edge", + "fg": [19053, 19054], + "bg": 972 + }, + { + "id": "end_piece", + "fg": [19055, 19056, 19057, 19058], + "bg": 972 + }, + { + "id": "unconnected", + "fg": 19059, + "bg": 972 + } + ] + }, + { + "id": "t_concrete_railing", + "fg": 19060, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 19060, + "bg": 5010 + }, + { + "id": "corner", + "fg": [19061, 19062, 19063, 19064], + "bg": 5010 + }, + { + "id": "t_connection", + "fg": [19065, 19066, 19067, 19068], + "bg": 5010 + }, + { + "id": "edge", + "fg": [19069, 19070], + "bg": 5010 + }, + { + "id": "end_piece", + "fg": [19071, 19072, 19073, 19074], + "bg": 5010 + }, + { + "id": "unconnected", + "fg": 19075, + "bg": 5010 + } + ] + }, + { + "id": ["!t_railroad_tie", "!t_railroad_tie_d", "!t_railroad_tie_v", "!t_railroad_tie_h"], + "fg": 19076, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 19076, + "bg": 5131 + }, + { + "id": "corner", + "fg": [19077, 19078, 19079, 19080], + "bg": 5131 + }, + { + "id": "t_connection", + "fg": [19081, 19082, 19083, 19084], + "bg": 5131 + }, + { + "id": "edge", + "fg": [19085, 19086], + "bg": 5131 + }, + { + "id": "end_piece", + "fg": [19087, 19088, 19089, 19090], + "bg": 5131 + }, + { + "id": "unconnected", + "fg": 19091, + "bg": 5131 + } + ] + }, + { + "id": "!t_railroad_track_on_tie", + "fg": 19092, + "rotates": false, + "multitile": true, + "additional_tiles": [ + { + "id": "center", + "fg": 19092, + "bg": 5010 + }, + { + "id": "corner", + "fg": [19093, 19094, 19095, 19096], + "bg": 5010 + }, + { + "id": "t_connection", + "fg": [19097, 19098, 19099, 19100], + "bg": 5010 + }, + { + "id": "edge", + "fg": [19101, 19102], + "bg": 5010 + }, + { + "id": "end_piece", + "fg": [19103, 19104, 19105, 19106], + "bg": 5010 + }, + { + "id": "unconnected", + "fg": 19107, + "bg": 5010 + } + ] + } + + ] + }, + { + "file": "10_xfiles_32x32_22052-22195.png", + "tiles": [ + { + "id": "mon_pink_mist", + "fg": 22052, + "rotates": false + }, + { + "id": "mon_entomber", + "fg": 22054, + "rotates": false + }, + { + "id": "mon_bloodbeast", + "fg": 22053, + "rotates": false + }, + { + "id": "mon_worm_mass", + "fg": 22061, + "rotates": false + }, + { + "id": "mon_bloodworm", + "fg": 22062, + "rotates": false + }, + { + "id": "mon_grey_grunt", + "fg": 22055, + "rotates": false + }, + { + "id": "mon_alien_turret", + "fg": 22056, + "rotates": false + }, + { + "id": "mon_loch_ness_monster", + "fg": 22057, + "rotates": false + }, + { + "id": "mon_jersey_devil", "fg": 22059, "rotates": false }, @@ -120125,7 +120869,7 @@ "fg": 23994 }, { - "id": ["overlay_wielded_mag_archery", "overlay_wielded_book_archery", "overlay_wielded_manual_archery", "overlay_wielded_mag_barter", "overlay_wielded_manual_business", "overlay_wielded_textbook_business", "overlay_wielded_mag_bashing", "overlay_wielded_manual_bashing", "overlay_wielded_SICP", "overlay_wielded_computer_science", "overlay_wielded_howto_computer", "overlay_wielded_mag_computer", "overlay_wielded_manual_computers", "overlay_wielded_textbook_computer", "overlay_wielded_adv_chemistry", "overlay_wielded_brewing_cookbook", "overlay_wielded_cookbook", "overlay_wielded_cookbook_human", "overlay_wielded_cookbook_italian", "overlay_wielded_cookbook_sushi", "overlay_wielded_family_cookbook", "overlay_wielded_mag_cooking", "overlay_wielded_mag_glam", "overlay_wielded_modern_tanner", "overlay_wielded_recipe_alpha", "overlay_wielded_", "overlay_wielded_recipe_animal", "overlay_wielded_recipe_labchem", "overlay_wielded_recipe_chimera", "overlay_wielded_recipe_creepy", "overlay_wielded_recipe_elfa", "overlay_wielded_recipe_maiar", "overlay_wielded_recipe_medicalmut", "overlay_wielded_recipe_raptor", "overlay_wielded_recipe_serum", "overlay_wielded_scots_cookbook", "overlay_wielded_textbook_chemistry", "overlay_wielded_mag_cutting", "overlay_wielded_manual_cutting", "overlay_wielded_manual_knives", "overlay_wielded_mag_dodge", "overlay_wielded_manual_dodge", "overlay_wielded_manual_dodge_kid", "overlay_wielded_textbook_anarch", "overlay_wielded_advanced_electronics", "overlay_wielded_mag_electronics", "overlay_wielded_decoy_anarch", "overlay_wielded_mag_cars", "overlay_wielded_manual_driving", "overlay_wielded_manual_electronics", "overlay_wielded_radio_book", "overlay_wielded_recipe_atomic_battery", "overlay_wielded_recipe_augs", "overlay_wielded_recipe_lab_elec", "overlay_wielded_recipe_mil_augs", "overlay_wielded_repeater_mod_guide", "overlay_wielded_textbook_electronics", "overlay_wielded_textbook_robots", "overlay_wielded_glassblowing_book", "overlay_wielded_jewelry_book", "overlay_wielded_mag_fabrication", "overlay_wielded_manual_fabrication", "overlay_wielded_recipe_arrows", "overlay_wielded_recipe_bows", "overlay_wielded_recipe_bullets", "overlay_wielded_recipe_caseless", "overlay_wielded_recipe_lab_cvd", "overlay_wielded_recipe_melee", "overlay_wielded_recipe_mininuke_launch", "overlay_wielded_textbook_armeast", "overlay_wielded_textbook_armschina", "overlay_wielded_textbook_armwest", "overlay_wielded_textbook_fabrication", "overlay_wielded_textbook_fireman", "overlay_wielded_textbook_gaswarfare", "overlay_wielded_welding_book", "overlay_wielded_101_carpentry", "overlay_wielded_carpentry_book", "overlay_wielded_textbook_weapeast", "overlay_wielded_textbook_weapwest", "overlay_wielded_mag_guns", "overlay_wielded_mag_carpentry", "overlay_wielded_manual_carpentry", "overlay_wielded_textbook_carpentry", "overlay_wielded_emergency_book", "overlay_wielded_mag_firstaid", "overlay_wielded_manual_first_aid", "overlay_wielded_pocket_firstaid", "overlay_wielded_textbook_firstaid", "overlay_wielded_booklet_firstaid", "overlay_wielded_manual_gun", "overlay_wielded_pocket_firearms", "overlay_wielded_mag_launcher", "overlay_wielded_manual_launcher", "overlay_wielded_manual_aikido", "overlay_wielded_manual_boxing", "overlay_wielded_manual_capoeira", "overlay_wielded_manual_centipede", "overlay_wielded_manual_crane", "overlay_wielded_manual_dragon", "overlay_wielded_manual_eskrima", "overlay_wielded_manual_fencing", "overlay_wielded_manual_judo", "overlay_wielded_manual_karate", "overlay_wielded_manual_krav_maga", "overlay_wielded_manual_leopard", "overlay_wielded_manual_lizard", "overlay_wielded_manual_muay_thai", "overlay_wielded_manual_ninjutsu", "overlay_wielded_manual_niten", "overlay_wielded_manual_scorpion", "overlay_wielded_manual_silat", "overlay_wielded_manual_snake", "overlay_wielded_manual_taekwondo", "overlay_wielded_manual_tai_chi", "overlay_wielded_manual_tiger", "overlay_wielded_manual_toad", "overlay_wielded_manual_venom_snake", "overlay_wielded_manual_zui_quan", "overlay_wielded_manual_sojutsu", "overlay_wielded_book_icef", "overlay_wielded_mag_mechanics", "overlay_wielded_manual_mechanics", "overlay_wielded_mag_melee", "overlay_wielded_manual_melee", "overlay_wielded_mag_smg", "overlay_wielded_mag_fieldrepair", "overlay_wielded_textbook_biodiesel", "overlay_wielded_textbook_mechanics", "overlay_wielded_ZSG", "overlay_wielded_black_box_transcript", "overlay_wielded_child_book", "overlay_wielded_commune_prospectus", "overlay_wielded_decoy_elfa", "overlay_wielded_essay_book", "overlay_wielded_fairy_tales", "overlay_wielded_guidebook", "overlay_wielded_manual_smg", "overlay_wielded_mag_tv", "overlay_wielded_dnd_handbook", "overlay_wielded_textbook_speech", "overlay_wielded_holybook_bible1", "overlay_wielded_holybook_bible2", "overlay_wielded_manual_stabbing", "overlay_wielded_holybook_bible3", "overlay_wielded_manual_speech", "overlay_wielded_mag_stabbing", "overlay_wielded_atomic_survival", "overlay_wielded_holybook_hadith", "overlay_wielded_holybook_granth", "overlay_wielded_holybook_kojiki", "overlay_wielded_holybook_kallisti", "overlay_wielded_holybook_mormon", "overlay_wielded_holybook_pastafarian", "overlay_wielded_holybook_quran", "overlay_wielded_holybook_scientology", "overlay_wielded_holybook_slack", "overlay_wielded_holybook_sutras", "overlay_wielded_holybook_talmud", "overlay_wielded_holybook_tanakh", "overlay_wielded_holybook_tripitaka", "overlay_wielded_holybook_upanishads", "overlay_wielded_holybook_vedas", "overlay_wielded_mag_comic", "overlay_wielded_mag_gaming", "overlay_wielded_mag_porn", "overlay_wielded_necropolis_freq", "overlay_wielded_news_regional", "overlay_wielded_novel_adventure", "overlay_wielded_novel_buddy", "overlay_wielded_mag_news", "overlay_wielded_novel_crime", "overlay_wielded_novel_crime2", "overlay_wielded_novel_drama", "overlay_wielded_fun_survival", "overlay_wielded_novel_coa", "overlay_wielded_novel_coa2", "overlay_wielded_mag_dude", "overlay_wielded_novel_erotic", "overlay_wielded_novel_experimental", "overlay_wielded_novel_fantasy", "overlay_wielded_novel_horror", "overlay_wielded_novel_mystery", "overlay_wielded_novel_pulp", "overlay_wielded_mag_survival", "overlay_wielded_manual_survival", "overlay_wielded_pocket_survival", "overlay_wielded_survival_book", "overlay_wielded_novel_road", "overlay_wielded_novel_romance", "overlay_wielded_novel_samurai", "overlay_wielded_novel_satire", "overlay_wielded_novel_scifi", "overlay_wielded_textbook_survival", "overlay_wielded_mag_swimming", "overlay_wielded_novel_sports", "overlay_wielded_novel_spy", "overlay_wielded_novel_swash", "overlay_wielded_novel_thriller", "overlay_wielded_novel_tragedy", "overlay_wielded_novel_war", "overlay_wielded_novel_war2", "overlay_wielded_novel_western", "overlay_wielded_philosophy_book", "overlay_wielded_phonebook", "overlay_wielded_photo_album", "overlay_wielded_plays_book", "overlay_wielded_manual_swimming", "overlay_wielded_poetry_book", "overlay_wielded_priest_diary", "overlay_wielded_record_accounting", "overlay_wielded_record_patient", "overlay_wielded_record_weather", "overlay_wielded_story_book", "overlay_wielded_tall_tales", "overlay_wielded_visions_solitude", "overlay_wielded_holybook_havamal", "overlay_wielded_classic_literature", "overlay_wielded_collector_book", "overlay_wielded_mag_pistol", "overlay_wielded_manual_pistol", "overlay_wielded_mag_rifle", "overlay_wielded_manual_rifle", "overlay_wielded_mag_shotgun", "overlay_wielded_manual_shotgun", "overlay_wielded_manual_swimming", "overlay_wielded_mag_animecon", "overlay_wielded_mag_beauty", "overlay_wielded_mag_tailor", "overlay_wielded_manual_tailor", "overlay_wielded_tailor_portfolio", "overlay_wielded_recipe_fauxfur", "overlay_wielded_textbook_tailor", "overlay_wielded_mag_throwing", "overlay_wielded_manual_throw", "overlay_wielded_howto_traps", "overlay_wielded_mag_traps", "overlay_wielded_manual_traps", "overlay_wielded_textbook_traps", "overlay_wielded_trappers_companion", "overlay_wielded_mag_unarmed", "overlay_wielded_manual_brawl", "overlay_wielded_afs_librarian_book", "overlay_wielded_recipe_lab_cvd", "overlay_wielded_afs_textbook_shotguns", "overlay_wielded_afs_textbook_handguns", "overlay_wielded_afs_textbook_rifles", "overlay_wielded_afs_textbook_launchers", "overlay_wielded_manual_surv", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_encyclopedia_mechanics", "overlay_wielded_encyclopedia_fabrication", "overlay_wielded_encyclopedia_archery", "overlay_wielded_encyclopedia_barter", "overlay_wielded_encyclopedia_bashing", "overlay_wielded_encyclopedia_computer", "overlay_wielded_encyclopedia_cooking", "overlay_wielded_encyclopedia_cutting", "overlay_wielded_encyclopedia_dodge", "overlay_wielded_encyclopedia_driving", "overlay_wielded_encyclopedia_electronics", "overlay_wielded_encyclopedia_firstaid", "overlay_wielded_encyclopedia_gun", "overlay_wielded_encyclopedia_launcher", "overlay_wielded_encyclopedia_melee", "overlay_wielded_encyclopedia_pistol", "overlay_wielded_encyclopedia_rifle", "overlay_wielded_encyclopedia_shotgun", "overlay_wielded_encyclopedia_smg", "overlay_wielded_encyclopedia_speech", "overlay_wielded_encyclopedia_stabbing", "overlay_wielded_encyclopedia_survival", "overlay_wielded_encyclopedia_swimming", "overlay_wielded_encyclopedia_tailor", "overlay_wielded_encyclopedia_throw", "overlay_wielded_encyclopedia_traps", "overlay_wielded_encyclopedia_unarmed", "overlay_wielded_encyclopedia_mechanics_advance", "overlay_wielded_encyclopedia_fabrication_advance", "overlay_wielded_encyclopedia_archery_advance", "overlay_wielded_encyclopedia_barter_advance", "overlay_wielded_encyclopedia_bashing_advance", "overlay_wielded_encyclopedia_computer_advance", "overlay_wielded_encyclopedia_cooking_advance", "overlay_wielded_encyclopedia_cutting_advance", "overlay_wielded_encyclopedia_dodge_advance", "overlay_wielded_encyclopedia_driving_advance", "overlay_wielded_encyclopedia_electronics_advance", "overlay_wielded_encyclopedia_firstaid_advance", "overlay_wielded_encyclopedia_gun_advance", "overlay_wielded_encyclopedia_launcher_advance", "overlay_wielded_encyclopedia_melee_advance", "overlay_wielded_encyclopedia_pistol_advance", "overlay_wielded_encyclopedia_rifle_advance", "overlay_wielded_encyclopedia_shotgun_advance", "overlay_wielded_encyclopedia_smg_advance", "overlay_wielded_encyclopedia_speech_advance", "overlay_wielded_encyclopedia_stabbing_advance", "overlay_wielded_encyclopedia_survival_advance", "overlay_wielded_encyclopedia_swimming_advance", "overlay_wielded_encyclopedia_tailor_advance", "overlay_wielded_encyclopedia_throw_advance", "overlay_wielded_encyclopedia_traps_advance", "overlay_wielded_encyclopedia_unarmed_advance", "overlay_wielded_evil_invitation", "overlay_wielded_note_apophis", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_"], + "id": ["overlay_wielded_mag_archery", "overlay_wielded_book_archery", "overlay_wielded_manual_archery", "overlay_wielded_mag_barter", "overlay_wielded_manual_business", "overlay_wielded_textbook_business", "overlay_wielded_mag_bashing", "overlay_wielded_manual_bashing", "overlay_wielded_SICP", "overlay_wielded_computer_science", "overlay_wielded_howto_computer", "overlay_wielded_mag_computer", "overlay_wielded_manual_computers", "overlay_wielded_textbook_computer", "overlay_wielded_adv_chemistry", "overlay_wielded_brewing_cookbook", "overlay_wielded_cookbook", "overlay_wielded_cookbook_human", "overlay_wielded_cookbook_italian", "overlay_wielded_cookbook_sushi", "overlay_wielded_family_cookbook", "overlay_wielded_mag_cooking", "overlay_wielded_mag_glam", "overlay_wielded_modern_tanner", "overlay_wielded_recipe_alpha", "overlay_wielded_mycenacean_hymns", "overlay_wielded_recipe_animal", "overlay_wielded_recipe_labchem", "overlay_wielded_recipe_chimera", "overlay_wielded_recipe_creepy", "overlay_wielded_recipe_elfa", "overlay_wielded_recipe_maiar", "overlay_wielded_recipe_medicalmut", "overlay_wielded_recipe_raptor", "overlay_wielded_recipe_serum", "overlay_wielded_scots_cookbook", "overlay_wielded_textbook_chemistry", "overlay_wielded_mag_cutting", "overlay_wielded_manual_cutting", "overlay_wielded_manual_knives", "overlay_wielded_mag_dodge", "overlay_wielded_manual_dodge", "overlay_wielded_manual_dodge_kid", "overlay_wielded_textbook_anarch", "overlay_wielded_advanced_electronics", "overlay_wielded_mag_electronics", "overlay_wielded_decoy_anarch", "overlay_wielded_mag_cars", "overlay_wielded_manual_driving", "overlay_wielded_manual_electronics", "overlay_wielded_radio_book", "overlay_wielded_recipe_atomic_battery", "overlay_wielded_recipe_augs", "overlay_wielded_recipe_lab_elec", "overlay_wielded_recipe_mil_augs", "overlay_wielded_repeater_mod_guide", "overlay_wielded_textbook_electronics", "overlay_wielded_textbook_robots", "overlay_wielded_glassblowing_book", "overlay_wielded_jewelry_book", "overlay_wielded_mag_fabrication", "overlay_wielded_manual_fabrication", "overlay_wielded_recipe_arrows", "overlay_wielded_recipe_bows", "overlay_wielded_recipe_bullets", "overlay_wielded_recipe_caseless", "overlay_wielded_recipe_lab_cvd", "overlay_wielded_recipe_melee", "overlay_wielded_recipe_mininuke_launch", "overlay_wielded_textbook_armeast", "overlay_wielded_textbook_armschina", "overlay_wielded_textbook_armwest", "overlay_wielded_textbook_fabrication", "overlay_wielded_textbook_fireman", "overlay_wielded_textbook_gaswarfare", "overlay_wielded_welding_book", "overlay_wielded_101_carpentry", "overlay_wielded_carpentry_book", "overlay_wielded_textbook_weapeast", "overlay_wielded_textbook_weapwest", "overlay_wielded_mag_guns", "overlay_wielded_mag_carpentry", "overlay_wielded_manual_carpentry", "overlay_wielded_textbook_carpentry", "overlay_wielded_emergency_book", "overlay_wielded_mag_firstaid", "overlay_wielded_manual_first_aid", "overlay_wielded_pocket_firstaid", "overlay_wielded_textbook_firstaid", "overlay_wielded_booklet_firstaid", "overlay_wielded_manual_gun", "overlay_wielded_pocket_firearms", "overlay_wielded_mag_launcher", "overlay_wielded_manual_launcher", "overlay_wielded_manual_aikido", "overlay_wielded_manual_boxing", "overlay_wielded_manual_capoeira", "overlay_wielded_manual_centipede", "overlay_wielded_manual_crane", "overlay_wielded_manual_dragon", "overlay_wielded_manual_eskrima", "overlay_wielded_manual_fencing", "overlay_wielded_manual_judo", "overlay_wielded_manual_karate", "overlay_wielded_manual_krav_maga", "overlay_wielded_manual_leopard", "overlay_wielded_manual_lizard", "overlay_wielded_manual_muay_thai", "overlay_wielded_manual_ninjutsu", "overlay_wielded_manual_niten", "overlay_wielded_manual_scorpion", "overlay_wielded_manual_silat", "overlay_wielded_manual_snake", "overlay_wielded_manual_taekwondo", "overlay_wielded_manual_tai_chi", "overlay_wielded_manual_tiger", "overlay_wielded_manual_toad", "overlay_wielded_manual_venom_snake", "overlay_wielded_manual_zui_quan", "overlay_wielded_manual_sojutsu", "overlay_wielded_book_icef", "overlay_wielded_mag_mechanics", "overlay_wielded_manual_mechanics", "overlay_wielded_mag_melee", "overlay_wielded_manual_melee", "overlay_wielded_mag_smg", "overlay_wielded_mag_fieldrepair", "overlay_wielded_textbook_biodiesel", "overlay_wielded_textbook_mechanics", "overlay_wielded_ZSG", "overlay_wielded_black_box_transcript", "overlay_wielded_child_book", "overlay_wielded_commune_prospectus", "overlay_wielded_decoy_elfa", "overlay_wielded_essay_book", "overlay_wielded_fairy_tales", "overlay_wielded_guidebook", "overlay_wielded_manual_smg", "overlay_wielded_mag_tv", "overlay_wielded_dnd_handbook", "overlay_wielded_textbook_speech", "overlay_wielded_holybook_bible1", "overlay_wielded_holybook_bible2", "overlay_wielded_manual_stabbing", "overlay_wielded_holybook_bible3", "overlay_wielded_manual_speech", "overlay_wielded_mag_stabbing", "overlay_wielded_atomic_survival", "overlay_wielded_holybook_hadith", "overlay_wielded_holybook_granth", "overlay_wielded_holybook_kojiki", "overlay_wielded_holybook_kallisti", "overlay_wielded_holybook_mormon", "overlay_wielded_holybook_pastafarian", "overlay_wielded_holybook_quran", "overlay_wielded_holybook_scientology", "overlay_wielded_holybook_slack", "overlay_wielded_holybook_sutras", "overlay_wielded_holybook_talmud", "overlay_wielded_holybook_tanakh", "overlay_wielded_holybook_tripitaka", "overlay_wielded_holybook_upanishads", "overlay_wielded_holybook_vedas", "overlay_wielded_mag_comic", "overlay_wielded_mag_gaming", "overlay_wielded_mag_porn", "overlay_wielded_necropolis_freq", "overlay_wielded_news_regional", "overlay_wielded_novel_adventure", "overlay_wielded_novel_buddy", "overlay_wielded_mag_news", "overlay_wielded_novel_crime", "overlay_wielded_novel_crime2", "overlay_wielded_novel_drama", "overlay_wielded_fun_survival", "overlay_wielded_novel_coa", "overlay_wielded_novel_coa2", "overlay_wielded_mag_dude", "overlay_wielded_novel_erotic", "overlay_wielded_novel_experimental", "overlay_wielded_novel_fantasy", "overlay_wielded_novel_horror", "overlay_wielded_novel_mystery", "overlay_wielded_novel_pulp", "overlay_wielded_mag_survival", "overlay_wielded_manual_survival", "overlay_wielded_pocket_survival", "overlay_wielded_survival_book", "overlay_wielded_novel_road", "overlay_wielded_novel_romance", "overlay_wielded_novel_samurai", "overlay_wielded_novel_satire", "overlay_wielded_novel_scifi", "overlay_wielded_textbook_survival", "overlay_wielded_mag_swimming", "overlay_wielded_novel_sports", "overlay_wielded_novel_spy", "overlay_wielded_novel_swash", "overlay_wielded_novel_thriller", "overlay_wielded_novel_tragedy", "overlay_wielded_novel_war", "overlay_wielded_novel_war2", "overlay_wielded_novel_western", "overlay_wielded_philosophy_book", "overlay_wielded_phonebook", "overlay_wielded_photo_album", "overlay_wielded_plays_book", "overlay_wielded_manual_swimming", "overlay_wielded_poetry_book", "overlay_wielded_priest_diary", "overlay_wielded_record_accounting", "overlay_wielded_record_patient", "overlay_wielded_record_weather", "overlay_wielded_story_book", "overlay_wielded_tall_tales", "overlay_wielded_visions_solitude", "overlay_wielded_holybook_havamal", "overlay_wielded_classic_literature", "overlay_wielded_collector_book", "overlay_wielded_mag_pistol", "overlay_wielded_manual_pistol", "overlay_wielded_mag_rifle", "overlay_wielded_manual_rifle", "overlay_wielded_mag_shotgun", "overlay_wielded_manual_shotgun", "overlay_wielded_manual_swimming", "overlay_wielded_mag_animecon", "overlay_wielded_mag_beauty", "overlay_wielded_mag_tailor", "overlay_wielded_manual_tailor", "overlay_wielded_tailor_portfolio", "overlay_wielded_recipe_fauxfur", "overlay_wielded_textbook_tailor", "overlay_wielded_mag_throwing", "overlay_wielded_manual_throw", "overlay_wielded_howto_traps", "overlay_wielded_mag_traps", "overlay_wielded_manual_traps", "overlay_wielded_textbook_traps", "overlay_wielded_trappers_companion", "overlay_wielded_mag_unarmed", "overlay_wielded_manual_brawl", "overlay_wielded_afs_librarian_book", "overlay_wielded_recipe_lab_cvd", "overlay_wielded_afs_textbook_shotguns", "overlay_wielded_afs_textbook_handguns", "overlay_wielded_afs_textbook_rifles", "overlay_wielded_afs_textbook_launchers", "overlay_wielded_manual_surv", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_encyclopedia_mechanics", "overlay_wielded_encyclopedia_fabrication", "overlay_wielded_encyclopedia_archery", "overlay_wielded_encyclopedia_barter", "overlay_wielded_encyclopedia_bashing", "overlay_wielded_encyclopedia_computer", "overlay_wielded_encyclopedia_cooking", "overlay_wielded_encyclopedia_cutting", "overlay_wielded_encyclopedia_dodge", "overlay_wielded_encyclopedia_driving", "overlay_wielded_encyclopedia_electronics", "overlay_wielded_encyclopedia_firstaid", "overlay_wielded_encyclopedia_gun", "overlay_wielded_encyclopedia_launcher", "overlay_wielded_encyclopedia_melee", "overlay_wielded_encyclopedia_pistol", "overlay_wielded_encyclopedia_rifle", "overlay_wielded_encyclopedia_shotgun", "overlay_wielded_encyclopedia_smg", "overlay_wielded_encyclopedia_speech", "overlay_wielded_encyclopedia_stabbing", "overlay_wielded_encyclopedia_survival", "overlay_wielded_encyclopedia_swimming", "overlay_wielded_encyclopedia_tailor", "overlay_wielded_encyclopedia_throw", "overlay_wielded_encyclopedia_traps", "overlay_wielded_encyclopedia_unarmed", "overlay_wielded_encyclopedia_mechanics_advance", "overlay_wielded_encyclopedia_fabrication_advance", "overlay_wielded_encyclopedia_archery_advance", "overlay_wielded_encyclopedia_barter_advance", "overlay_wielded_encyclopedia_bashing_advance", "overlay_wielded_encyclopedia_computer_advance", "overlay_wielded_encyclopedia_cooking_advance", "overlay_wielded_encyclopedia_cutting_advance", "overlay_wielded_encyclopedia_dodge_advance", "overlay_wielded_encyclopedia_driving_advance", "overlay_wielded_encyclopedia_electronics_advance", "overlay_wielded_encyclopedia_firstaid_advance", "overlay_wielded_encyclopedia_gun_advance", "overlay_wielded_encyclopedia_launcher_advance", "overlay_wielded_encyclopedia_melee_advance", "overlay_wielded_encyclopedia_pistol_advance", "overlay_wielded_encyclopedia_rifle_advance", "overlay_wielded_encyclopedia_shotgun_advance", "overlay_wielded_encyclopedia_smg_advance", "overlay_wielded_encyclopedia_speech_advance", "overlay_wielded_encyclopedia_stabbing_advance", "overlay_wielded_encyclopedia_survival_advance", "overlay_wielded_encyclopedia_swimming_advance", "overlay_wielded_encyclopedia_tailor_advance", "overlay_wielded_encyclopedia_throw_advance", "overlay_wielded_encyclopedia_traps_advance", "overlay_wielded_encyclopedia_unarmed_advance", "overlay_wielded_evil_invitation", "overlay_wielded_note_apophis", "overlay_wielded_tailor_japanese", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_", "overlay_wielded_"], "fg": 23995 }, { @@ -120472,10 +121216,7 @@ "id": "overlay_wielded_mounted_spare_tire", "fg": 24059 }, - { - "id": "vp_mounted_spare_tire", - "fg": 24059 - }, + { "id": "mon_bear_mega_baby", "fg": 24060, @@ -120609,393 +121350,2070 @@ "fg": 24082 }, { - "id": "magazine_battery_heavy_mod", - "fg": 24083 + "id": "magazine_battery_heavy_mod", + "fg": 24083 + }, + { + "id": "overlay_wielded_magazine_battery_heavy_mod", + "fg": 24083 + }, + { + "id": "wire_stock", + "fg": 24084 + }, + { + "id": "overlay_wielded_wire_stock", + "fg": 24084 + }, + { + "id": "belt_clip", + "fg": 24085 + }, + { + "id": "overlay_wielded_belt_clip", + "fg": 24085 + }, + { + "id": "bholster", + "fg": 24086 + }, + { + "id": "overlay_wielded_bholster", + "fg": 24086 + }, + { + "id": "fn1910", + "fg": 24087 + }, + { + "id": "overlay_wielded_fn1910", + "fg": 24088 + }, + { + "id": "fn1910mag", + "fg": 24089 + }, + { + "id": "overlay_wielded_fn1910mag", + "fg": 24089 + }, + { + "id": "j22", + "fg": 24090 + }, + { + "id": "overlay_wielded_j22", + "fg": 24091 + }, + { + "id": "j22mag", + "fg": 24092 + }, + { + "id": "overlay_wielded_j22mag", + "fg": 24092 + }, + { + "id": "kp32", + "fg": 24093 + }, + { + "id": "overlay_wielded_kp32", + "fg": 24094 + }, + { + "id": "kp32mag", + "fg": 24095 + }, + { + "id": "overlay_wielded_kp32mag", + "fg": 24095 + }, + { + "id": "anesthetic_kit", + "fg": 24096 + }, + { + "id": "overlay_wielded_anesthetic_kit", + "fg": 24096 + }, + { + "id": "f_wind_mill", + "fg": 24097 + }, + { + "id": "f_wind_mill_active", + "fg": 24098 + }, + { + "id": "f_water_mill", + "fg": 24099 + }, + { + "id": "f_water_mill_active", + "fg": 24100 + }, + { + "id": "wind_mill", + "fg": 24101 + }, + { + "id": "overlay_wielded_wind_mill", + "fg": 24101 + }, + { + "id": "water_mill", + "fg": 24102 + }, + { + "id": "overlay_wielded_water_mill", + "fg": 24102 + }, + { + "id": "kp3at", + "fg": 24103 + }, + { + "id": "overlay_wielded_kp3at", + "fg": 24104 + }, + { + "id": "kp3atmag", + "fg": 24105 + }, + { + "id": "overlay_wielded_kp3atmag", + "fg": 24105 + }, + { + "id": "kpf9", + "fg": 24106 + }, + { + "id": "overlay_wielded_kpf9", + "fg": 24107 + }, + { + "id": "kpf9mag", + "fg": 24108 + }, + { + "id": "overlay_wielded_kpf9mag", + "fg": 24108 + }, + { + "id": "mac_11", + "fg": 24109 + }, + { + "id": "overlay_wielded_mac_11", + "fg": 24110 + }, + { + "id": "mac11mag", + "fg": 24111 + }, + { + "id": "overlay_wielded_mac11mag", + "fg": 24111 + }, + { + "id": "rugerlcp", + "fg": 24112 + }, + { + "id": "overlay_wielded_rugerlcp", + "fg": 24113 + }, + { + "id": "rugerlcpmag", + "fg": 24114 + }, + { + "id": "overlay_wielded_rugerlcpmag", + "fg": 24114 + }, + { + "id": "corpse_mon_lostsoul", + "fg": 24115 + }, + { + "id": "corpse_mon_lostsoul_mount", + "fg": 24116 + }, + { + "id": "corpse_mon_revenant", + "fg": 24117 + }, + { + "id": "corpse_mon_hell_knight", + "fg": 24118 + }, + { + "id": "corpse_mon_hell_knight_revive", + "fg": 24119 + }, + { + "id": "corpse_mon_hell_baron", + "fg": 24120 + }, + { + "id": "corpse_mon_mancubus", + "fg": 24121 + }, + { + "id": "corpse_mon_cacodemon", + "fg": 24122 + }, + { + "id": "corpse_mon_cacodemon_revive", + "fg": 24123 + }, + { + "id": "corpse_mon_doom_churl", + "fg": 24124 + }, + { + "id": "corpse_mon_doom_churl_revive", + "fg": 24125 + }, + { + "id": "corpse_mon_doom_slave", + "fg": 24126 + }, + { + "id": "corpse_mon_doom_cur", + "fg": 24127 + }, + { + "id": "corpse_mon_doom_sacrifice", + "fg": 24128 + }, + { + "id": ["corpse_mon_doom_archvile", "corpse_mon_doom_archvile_2", "corpse_mon_doom_archvile_3", "corpse_mon_doom_archvile_4", "corpse_mon_doom_archvile_5"], + "fg": 24129 + }, + { + "id": ["corpse_mon_doom_archvile_queen"], + "fg": 24130 + }, + { + "id": ["corpse_mon_fish_eel_large"], + "fg": 24131 + }, + { + "id": ["corpse_mon_fish_flying"], + "fg": 24132 + }, + { + "id": "overlay_wielded_arrow_metal_bodkin", + "fg": 24133, + "bg": 957, + "rotates": false + }, + { + "id": "arrow_metal_bodkin", + "fg": 24133, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_arrow_metal_sharpened_fletched", + "fg": 24134, + "bg": 957, + "rotates": false + }, + { + "id": "arrow_metal_sharpened_fletched", + "fg": 24134, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_arrow_field_point_fletched", + "fg": 24135, + "bg": 957, + "rotates": false + }, + { + "id": "arrow_field_point_fletched", + "fg": 24135, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_arrow_wood", + "fg": 24136, + "bg": 957, + "rotates": false + }, + { + "id": "arrow_wood", + "fg": 24136, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_arrow_flamming", + "fg": 24137, + "bg": 957, + "rotates": false + }, + { + "id": "arrow_flamming", + "fg": 24137, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_biodiesel", + "fg": 24138, + "bg": 957, + "rotates": false + }, + { + "id": "biodiesel", + "fg": 24138, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_cactus_pad", + "fg": 24139, + "bg": 957, + "rotates": false + }, + { + "id": "cactus_pad", + "fg": 24139, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_cargo_aisle", + "fg": 24140, + "bg": 957, + "rotates": false + }, + { + "id": "cargo_aisle", + "fg": 24140, + "bg": 957, + "rotates": false + }, + { + "id": "vp_cargo_aisle", + "fg": 24140, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_nopalitos", + "fg": 24141, + "bg": 957, + "rotates": false + }, + { + "id": "nopalitos", + "fg": 24141, + "bg": 957, + "rotates": false + }, { + "id": "overlay_wielded_welding_components", + "fg": 24142, + "bg": 957, + "rotates": false + }, + { + "id": "welding_components", + "fg": 24142, + "bg": 957, + "rotates": false + }, + { + "id": ["corpse_mon_fish_lobster_giant"], + "fg": 24143 + }, + { + "id": ["corpse_mon_fougar"], + "fg": 24144 + }, + { + "id": ["corpse_mon_feer"], + "fg": 24145 + }, + { + "id": ["corpse_mon_foose"], + "fg": 24146 + }, + { + "id": ["corpse_mon_folf"], + "fg": 24147 + }, + { + "id": ["corpse_mon_fant"], + "fg": 24148 + }, + { + "id": ["corpse_mon_fungaloid_pk"], + "fg": 24149 + }, + { + "id": ["corpse_mon_fardigrade"], + "fg": 24150 + }, + { + "id": ["corpse_mon_furvivor", "corpse_mon_furvivor_glock", "corpse_mon_furvivor_shotgun", "corpse_mon_furvivor_deagle", "corpse_mon_furvivor_smg", "corpse_mon_furvivor_pk"], + "fg": 24151 + }, + { + "id": ["corpse_mon_finebeast"], + "fg": 24152 + }, + { + "id": ["corpse_mon_fionaea"], + "fg": 24153 + }, + { + "id": ["corpse_mon_zombie_electric_fungal"], + "fg": 24154 + }, + { + "id": ["corpse_mon_fungus_pig"], + "fg": 24155 + }, + { + "id": ["corpse_mon_maggot"], + "fg": 24156 + }, + { + "id": ["corpse_mon_caterpillar"], + "fg": 24157 + }, + { + "id": ["corpse_mon_pupae"], + "fg": 24158 + }, + { + "id": ["corpse_mon_pupae_pk"], + "fg": 24159 + }, + { + "id": ["corpse_mon_butterfly"], + "fg": 24160 + }, + { + "id": ["corpse_mon_moth"], + "fg": 24161 + }, + { + "id": ["mon_zombeaver"], + "fg": 24162, + "bg": 967 + }, + { + "id": ["corpse_mon_zombeaver"], + "fg": 24163, + "bg": 967 + }, + { + "id": ["bag_zipper"], + "fg": 24164, + "bg": 0 + }, + { + "id": ["overlay_wielded_bag_zipper"], + "fg": 24164, + "bg": 0 + }, + { + "id": ["base_ceramic_dish"], + "fg": 24165, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_ceramic_dish"], + "fg": 24165, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_plastic_dish"], + "fg": 24166, + "bg": 0 + }, + { + "id": ["base_plastic_dish"], + "fg": 24166, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_tin_dish"], + "fg": 24167, + "bg": 0 + }, + { + "id": ["base_tin_dish"], + "fg": 24167, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_glass_dish"], + "fg": 24168, + "bg": 0 + }, + { + "id": ["base_glass_dish"], + "fg": 24168, + "bg": 0 + }, + { + "id": ["t_grave_new"], + "fg": 24169, + "bg": 0 + }, + { + "id": ["t_grave_new_season_winter"], + "fg": 24170, + "bg": 0 + }, + { + "id": ["f_metal_smoking_rack"], + "fg": 24171, + "bg": 0 + }, + { + "id": ["f_metal_smoking_rack_active"], + "fg": 24172, + "bg": 0 + }, + { + "id": ["overlay_wielded_bscabbard", "overlay_wielded_scabbard"], + "fg": 24173, + "bg": 0 + }, + { + "id": ["brush"], + "fg": 24174, + "bg": 0 + }, + { + "id": ["overlay_wielded_brush"], + "fg": 24174, + "bg": 0 + }, + { + "id": ["overlay_wielded_can_opener"], + "fg": 24175, + "bg": 0 + }, + { + "id": ["can_opener"], + "fg": 24175, + "bg": 0 + }, + { + "id": ["overlay_wielded_bottle_opener"], + "fg": 24176, + "bg": 0 + }, + { + "id": ["bottle_opener"], + "fg": 24176, + "bg": 0 + }, + { + "id": ["overlay_wielded_corkscrew"], + "fg": 24177, + "bg": 0 + }, + { + "id": ["corkscrew"], + "fg": 24177, + "bg": 0 + }, + { + "id": ["overlay_wielded_peeler"], + "fg": 24178, + "bg": 0 + }, + { + "id": ["peeler"], + "fg": 24178, + "bg": 0 + }, + { + "id": ["overlay_wielded_kettle"], + "fg": 24179, + "bg": 0 + }, + { + "id": ["kettle"], + "fg": 24179, + "bg": 0 + }, + { + "id": ["knife_bread"], + "fg": 24180, + "bg": 0 + }, + { + "id": ["overlay_wielded_knife_bread"], + "fg": 24181, + "bg": 0 + }, + { + "id": ["knife_carving"], + "fg": 24182, + "bg": 0 + }, + { + "id": ["overlay_wielded_knife_carving"], + "fg": 24183, + "bg": 0 + }, + { + "id": ["whisk"], + "fg": 24184, + "bg": 0 + }, + { + "id": ["overlay_wielded_whisk"], + "fg": 24184, + "bg": 0 + }, + { + "id": ["ladle"], + "fg": 24185, + "bg": 0 + }, + { + "id": ["overlay_wielded_ladle"], + "fg": 24185, + "bg": 0 + }, + { + "id": ["cutting_board"], + "fg": 24186, + "bg": 0 + }, + { + "id": ["overlay_wielded_cutting_board"], + "fg": 24186, + "bg": 0 + }, + { + "id": "vp_mounted_spare_tire", + "fg": 24187, + "rotates": true + }, + { + "id": ["base_utensil"], + "fg": 24188, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_utensil"], + "fg": 24188, + "bg": 0 + }, + { + "id": ["base_silverware"], + "fg": 24189, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_plastic_silverware"], + "fg": 24189, + "bg": 0 + }, + { + "id": ["base_plastic_silverware"], + "fg": 24190, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_silverware"], + "fg": 24190, + "bg": 0 + }, + { + "id": ["base_cookpot"], + "fg": 24191, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_cookpot"], + "fg": 24191, + "bg": 0 + }, + { + "id": ["carving_fork"], + "fg": 24192, + "bg": 0 + }, + { + "id": ["overlay_wielded_carving_fork"], + "fg": 24192, + "bg": 0 + }, + { + "id": ["plastic_fork"], + "fg": 24193, + "bg": 0 + }, + { + "id": ["overlay_wielded_plastic_fork"], + "fg": 24193, + "bg": 0 + }, + { + "id": ["casserole"], + "fg": 24194, + "bg": 0 + }, + { + "id": ["overlay_wielded_casserole"], + "fg": 24194, + "bg": 0 + }, + { + "id": ["base_kitchen_knife"], + "fg": 24195, + "bg": 0 + }, + { + "id": ["overlay_wielded_base_kitchen_knife"], + "fg": 24195, + "bg": 0 + }, + { + "id": ["ceramic_mug"], + "fg": 24196, + "bg": 0 + }, + { + "id": ["overlay_wielded_ceramic_mug"], + "fg": 24196, + "bg": 0 + }, + { + "id": ["chopsticks"], + "fg": 24197, + "bg": 0 + }, + { + "id": ["overlay_wielded_chopsticks"], + "fg": 24197, + "bg": 0 + }, + { + "id": ["copper_pan"], + "fg": 24198, + "bg": 0 + }, + { + "id": ["overlay_wielded_copper_pan"], + "fg": 24198, + "bg": 0 + }, + { + "id": ["steel_pan"], + "fg": 24199, + "bg": 0 + }, + { + "id": ["overlay_wielded_steel_pan"], + "fg": 24199, + "bg": 0 + }, + { + "id": ["spatula"], + "fg": 24200, + "bg": 0 + }, + { + "id": ["overlay_wielded_spatula"], + "fg": 24200, + "bg": 0 + }, + { + "id": ["rolling_pin"], + "fg": 24201, + "bg": 0 + }, + { + "id": ["overlay_wielded_rolling_pin"], + "fg": 24201, + "bg": 0 + }, + { + "id": ["potato_masher"], + "fg": 24202, + "bg": 0 + }, + { + "id": ["overlay_wielded_potato_masher"], + "fg": 24202, + "bg": 0 + }, + { + "id": ["tin_cup"], + "fg": 24203, + "bg": 0 + }, + { + "id": ["overlay_wielded_tin_cup"], + "fg": 24203, + "bg": 0 + }, + { + "id": "trenchcoat", + "fg": 24204, + "rotates": false + }, + { + "id": "trenchcoat_fur", + "fg": 24205, + "bg": 957, + "rotates": false + }, + { + "id": "trenchcoat_leather", + "fg": 24206, + "bg": 957, + "rotates": false + }, + { + "id": "trenchcoat_survivor", + "fg": 24207, + "bg": 957 + }, + { + "id": "sleeveless_trenchcoat", + "fg": 24208, + "bg": 957 + }, + { + "id": "sleeveless_trenchcoat_fur", + "fg": 24209, + "bg": 957 + }, + { + "id": "sleeveless_trenchcoat_leather", + "fg": 24210, + "bg": 957, + "rotates": false + }, + { + "id": "sleeveless_trenchcoat_survivor", + "fg": 24211, + "bg": 957 + }, + { + "id": "overlay_wielded_trenchcoat", + "fg": 24204, + "rotates": false + }, + { + "id": "overlay_wielded_trenchcoat_fur", + "fg": 24205, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_trenchcoat_leather", + "fg": 24206, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_trenchcoat_survivor", + "fg": 24207, + "bg": 957 + }, + { + "id": "overlay_wielded_sleeveless_trenchcoat", + "fg": 24208, + "bg": 957 + }, + { + "id": "overlay_wielded_sleeveless_trenchcoat_fur", + "fg": 24209, + "bg": 957 + }, + { + "id": "overlay_wielded_sleeveless_trenchcoat_leather", + "fg": 24210, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_sleeveless_trenchcoat_survivor", + "fg": 24211, + "bg": 957 + }, + { + "id": "coffee_raw_kentucky", + "fg": 24212, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_coffee_raw_kentucky", + "fg": 24212, + "bg": 957 + }, + { + "id": "garlic_press", + "fg": 24213, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_garlic_press", + "fg": 24213, + "bg": 957 + }, + { + "id": "hakama_gi", + "fg": 24214 + }, + { + "id": "overlay_wielded_hakama_gi", + "fg": 24214 + }, + { + "id": "hakama", + "fg": 24215 + }, + { + "id": "overlay_wielded_hakama", + "fg": 24215 + }, + { + "id": "hakama", + "fg": 24215 + }, + { + "id": "overlay_worn_hakama", + "fg": 24216 + }, + { + "id": "overlay_wielded_yukata", + "fg": 24217 + }, + { + "id": "yukata", + "fg": 24217 + }, + { + "id": "overlay_worn_yukata", + "fg": 24218 + }, + { + "id": "overlay_wielded_haori", + "fg": 24219 + }, + { + "id": "haori", + "fg": 24219 + }, + { + "id": "overlay_worn_haori", + "fg": 24220 + }, + { + "id": "naginata_fake", + "fg": 24221 + }, + { + "id": "overlay_wielded_naginata_fake", + "fg": 24222 + }, + { + "id": "naginata_inferior", + "fg": 24223 + }, + { + "id": "overlay_wielded_naginata_inferior", + "fg": 24224 + }, + { + "id": "spear_survivor", + "fg": 24225 + }, + { + "id": "overlay_wielded_spear_survivor", + "fg": 24226 + }, + { + "id": "overlay_wielded_naginata", + "fg": 24227 + }, + { + "id": "overlay_wielded_iron_pot", + "fg": 24228 + }, + { + "id": "iron_pot", + "fg": 24228 + }, + { + "id": "overlay_wielded_knife_chef", + "fg": 24229 + }, + { + "id": "knife_chef", + "fg": 24229 + }, + { + "id": "knife_butcher", + "fg": 24230, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_knife_butcher", + "fg": 24230, + "bg": 957, + "rotates": false + }, + { + "id": "knife_vegetable_cleaver", + "fg": 24231, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_knife_vegetable_cleaver", + "fg": 24231, + "bg": 957, + "rotates": false + }, + { + "id": "knife_paring", + "fg": 24232, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_knife_paring", + "fg": 24232, + "bg": 957, + "rotates": false + }, + { + "id": "plastic_knife", + "fg": 24233, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_plastic_knife", + "fg": 24233, + "bg": 957, + "rotates": false + }, + { + "id": "metal_smoking_rack", + "fg": 24234, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_metal_smoking_rack", + "fg": 24234, + "bg": 957, + "rotates": false + }, + { + "id": "hand_crank_charger", + "fg": 24235, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_hand_crank_charger", + "fg": 24235, + "bg": 957, + "rotates": false + }, + { + "id": "plastic_bowl_kids", + "fg": 24236, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_plastic_bowl_kids", + "fg": 24236, + "bg": 957, + "rotates": false + }, + { + "id": "plastic_plate", + "fg": 24237, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_plastic_plate", + "fg": 24237, + "bg": 957, + "rotates": false + }, + { + "id": "plastic_spoon", + "fg": 24238, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_plastic_spoon", + "fg": 24238, + "bg": 957, + "rotates": false + }, + { + "id": "plastic_spoon_kids", + "fg": 24239, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_plastic_spoon_kids", + "fg": 24239, + "bg": 957, + "rotates": false + }, + { + "id": "plastic_straw", + "fg": 24240, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_plastic_straw", + "fg": 24240, + "bg": 957, + "rotates": false + }, { + "id": "light_atomic_battery_cell", + "fg": 24241, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_light_atomic_battery_cell", + "fg": 24241, + "bg": 957, + "rotates": false + }, + { + "id": "medium_atomic_battery_cell", + "fg": 24242, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_medium_atomic_battery_cell", + "fg": 24242, + "bg": 957, + "rotates": false + }, { + "id": "heavy_atomic_battery_cell", + "fg": 24243, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_heavy_atomic_battery_cell", + "fg": 24243, + "bg": 957, + "rotates": false + }, + { + "id": "light_minus_atomic_battery_cell", + "fg": 24244, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_light_minus_atomic_battery_cell", + "fg": 24244, + "bg": 957, + "rotates": false + }, { + "id": "pressurized_tank_chem", + "fg": 24245, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_pressurized_tank_chem", + "fg": 24245, + "bg": 957, + "rotates": false + }, + { + "id": "tailor_japanese", + "fg": 24246, + "bg": 957, + "rotates": false + }, + { + "id": "small_turbine_engine", + "fg": 24247, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_small_turbine_engine", + "fg": 24247, + "bg": 957, + "rotates": false + }, + { + "id": "vp_engine_turbine_small", + "fg": 24247, + "bg": 957, + "rotates": false + }, { + "id": "medium_turbine_engine", + "fg": 24248, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_medium_turbine_engine", + "fg": 24248, + "bg": 957, + "rotates": false + }, + { + "id": "vp_engine_turbine_medium", + "fg": 24248, + "bg": 957, + "rotates": false + }, + { + "id": "large_turbine_engine", + "fg": 24249, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_large_turbine_engine", + "fg": 24249, + "bg": 957, + "rotates": false + }, + { + "id": "vp_engine_turbine_large", + "fg": 24249, + "bg": 957, + "rotates": false + }, + { + "id": "wine_glass", + "fg": 24250, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_wine_glass", + "fg": 24250, + "bg": 957, + "rotates": false + }, + { + "id": "stock_pot", + "fg": 24251, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_stock_pot", + "fg": 24251, + "bg": 957, + "rotates": false + }, + { + "id": "tumbler_plastic", + "fg": 24252, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_tumbler_plastic", + "fg": 24252, + "bg": 957, + "rotates": false + }, + { + "id": "wheel_rail", + "fg": 24253, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_wheel_rail", + "fg": 24253, + "bg": 957, + "rotates": false + }, + { + "id": "overlay_wielded_homewrecker", + "fg": 24254, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_tardigrade", + "fg": 24255, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_wolf_giant_pk", + "fg": 24256, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_trapdoor_giant_s", + "fg": 24257, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_trapdoor_giant_guardian", + "fg": 24258, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_trapdoor_giant_pk", + "fg": 24259, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_web_alpha", + "fg": 24260, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_web_mu", + "fg": 24261, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_web_omega", + "fg": 24262, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_spider_jumping_giant_acid", + "fg": 24263, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bee_scout", + "fg": 24264, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bee_soldier", + "fg": 24265, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bee_king", + "fg": 24266, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bee_queen", + "fg": 24267, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bee_larvae", + "fg": 24268, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_wasp_queen", + "fg": 24269, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_wasp_larvae", + "fg": 24270, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bear_pk", + "fg": 24271, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_bear_weak", + "fg": 24272, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_cougar_pk", + "fg": 24273, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_cougar_weak", + "fg": 24274, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_dog_large", + "fg": 24275, + "bg": 0, + "rotates": false + }, { + "id": "corpse_mon_moose_pk", + "fg": 24276, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_moose_weak", + "fg": 24277, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_skunk", + "fg": 24278, + "bg": 0, + "rotates": false + }, + { + "id": "mon_robofac_prototype", + "fg": 24279, + "bg": 967, + "rotates": false }, { - "id": "overlay_wielded_magazine_battery_heavy_mod", - "fg": 24083 + "id": "broken_robofac_prototype", + "fg": 24280, + "bg": 0, + "rotates": false }, { - "id": "wire_stock", - "fg": 24084 + "id": "overlay_wielded_broken_robofac_prototype", + "fg": 24280, + "bg": 0, + "rotates": false }, { - "id": "overlay_wielded_wire_stock", - "fg": 24084 + "id": "mon_nursebot", + "fg": 24281, + "bg": 967, + "rotates": false }, { - "id": "belt_clip", - "fg": 24085 + "id": "mon_nursebot_defective", + "fg": 24282, + "bg": 967, + "rotates": false }, { - "id": "overlay_wielded_belt_clip", - "fg": 24085 + "id": "mon_marloss_zealot_f", + "fg": 24283, + "bg": 967, + "rotates": false }, { - "id": "bholster", - "fg": 24086 + "id": "mon_marloss_zealot_m", + "fg": 24284, + "bg": 967, + "rotates": false + }, + { + "id": "f_sign_warning", + "fg": 24285, + "bg": 0, + "rotates": false }, { - "id": "overlay_wielded_bholster", - "fg": 24086 + "id": "t_water_dispenser", + "fg": 24286, + "bg": 5010, + "rotates": false + }, + { + "id": "t_card_robofac", + "fg": 24287, + "bg": 0, + "rotates": false }, { - "id": "fn1910", - "fg": 24087 + "id": "t_intercom", + "fg": 24288, + "bg": 0, + "rotates": false }, { - "id": "overlay_wielded_fn1910", - "fg": 24088 + "id": "t_thconc_y", + "fg": 24289, + "bg": 0, + "rotates": false }, { - "id": "fn1910mag", - "fg": 24089 + "id": "vp_rail_wheel", + "fg": 24290, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_fn1910mag", - "fg": 24089 - }, + "id": "vp_rail_wheel_steerable", + "fg": 24290, + "bg": 0, + "rotates": true + }, { - "id": "j22", - "fg": 24090 - }, + "id": "caltrops_glass", + "fg": 24291, + "bg": 0, + "rotates": true + }, { + "id": "overlay_wielded_caltrops_glass", + "fg": 24291, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_j22", - "fg": 24091 + "id": "tr_caltrops_glass", + "fg": 24292, + "bg": 0, + "rotates": true + }, + { + "id": "tr_glass", + "fg": 24293, + "bg": 0, + "rotates": true }, { - "id": "j22mag", - "fg": 24092 + "id": "sandbag", + "fg": 24294, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_j22mag", - "fg": 24092 - }, + "id": "overlay_wielded_sandbag", + "fg": 24294, + "bg": 0, + "rotates": true + }, { - "id": "kp32", - "fg": 24093 + "id": "earthbag", + "fg": 24295, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_kp32", - "fg": 24094 + "id": "overlay_wielded_earthbag", + "fg": 24295, + "bg": 0, + "rotates": true + }, { + "id": "flesh_golem_heart", + "fg": 24296, + "bg": 0, + "rotates": true }, { - "id": "kp32mag", - "fg": 24095 + "id": "overlay_wielded_flesh_golem_heart", + "fg": 24296, + "bg": 0, + "rotates": true + }, { + "id": "marloss_scarf", + "fg": 24297, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_kp32mag", - "fg": 24095 + "id": "overlay_wielded_marloss_scarf", + "fg": 24297, + "bg": 0, + "rotates": true }, { - "id": "anesthetic_kit", - "fg": 24096 - }, - { - "id": "overlay_wielded_anesthetic_kit", - "fg": 24096 + "id": "overlay_worn_marloss_scarf", + "fg": 24298, + "bg": 0, + "rotates": true }, { - "id": "f_wind_mill", - "fg": 24097 + "id": "broken_nursebot", + "fg": 24299, + "bg": 0, + "rotates": true }, { - "id": "f_wind_mill_active", - "fg": 24098 + "id": "overlay_wielded_broken_nursebot", + "fg": 24299, + "bg": 0, + "rotates": true }, { - "id": "f_water_mill", - "fg": 24099 + "id": "broken_nursebot_defective", + "fg": 24300, + "bg": 0, + "rotates": true }, { - "id": "f_water_mill_active", - "fg": 24100 - }, + "id": "overlay_wielded_broken_nursebot_defective", + "fg": 24300, + "bg": 0, + "rotates": true + }, { - "id": "wind_mill", - "fg": 24101 + "id": "bot_nursebot", + "fg": 24301, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_wind_mill", - "fg": 24101 + "id": "overlay_wielded_bot_nursebot", + "fg": 24301, + "bg": 0, + "rotates": true }, { - "id": "water_mill", - "fg": 24102 + "id": "badge_doctor", + "fg": 24302, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_water_mill", - "fg": 24102 + "id": "overlay_wielded_badge_doctor", + "fg": 24302, + "bg": 0, + "rotates": true + }, { + "id": "mycenacean_hymns", + "fg": 24303, + "bg": 0, + "rotates": true }, { - "id": "kp3at", - "fg": 24103 + "id": "phonebook", + "fg": 24304, + "bg": 0, + "rotates": true + }, + { + "id": "ar10", + "fg": 24305, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_kp3at", - "fg": 24104 + "id": "overlay_wielded_ar10", + "fg": 24306, + "bg": 0, + "rotates": true + }, + { + "id": "ar10mag_20rd", + "fg": 24307, + "bg": 0, + "rotates": true }, { - "id": "kp3atmag", - "fg": 24105 + "id": "overlay_wielded_ar10mag_20rd", + "fg": 24307, + "bg": 0, + "rotates": true }, + { + "id": "glock_18c", + "fg": 24308, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_kp3atmag", - "fg": 24105 + "id": "overlay_wielded_glock_18c", + "fg": 24309, + "bg": 0, + "rotates": true + }, { + "id": "m110a1", + "fg": 24310, + "bg": 0, + "rotates": true }, { - "id": "kpf9", - "fg": 24106 - }, + "id": "overlay_wielded_m110a1", + "fg": 24311, + "bg": 0, + "rotates": true + },{ + "id": "hk417_13", + "fg": 24312, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_kpf9", - "fg": 24107 - }, + "id": "overlay_wielded_hk417_13", + "fg": 24313, + "bg": 0, + "rotates": true + }, { - "id": "kpf9mag", - "fg": 24108 - }, + "id": "hk417mag_10rd", + "fg": 24314, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_kpf9mag", - "fg": 24108 - }, + "id": "overlay_wielded_hk417mag_10rd", + "fg": 24314, + "bg": 0, + "rotates": true + }, { + "id": "hk417mag_20rd", + "fg": 24315, + "bg": 0, + "rotates": true + }, { - "id": "mac_11", - "fg": 24109 - }, + "id": "overlay_wielded_hk417mag_20rd", + "fg": 24315, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_mac_11", - "fg": 24110 - }, + "id": "light_minus_disposable_cell", + "fg": 24316, + "bg": 0, + "rotates": true + }, { - "id": "mac11mag", - "fg": 24111 + "id": "overlay_wielded_light_minus_disposable_cell", + "fg": 24316, + "bg": 0, + "rotates": true }, { - "id": "overlay_wielded_mac11mag", - "fg": 24111 + "id": "light_disposable_cell", + "fg": 24317, + "bg": 0, + "rotates": true + }, + { + "id": "overlay_wielded_light_disposable_cell", + "fg": 24317, + "bg": 0, + "rotates": true }, { - "id": "rugerlcp", - "fg": 24112 - }, + "id": "medium_disposable_cell", + "fg": 24318, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_rugerlcp", - "fg": 24113 + "id": "overlay_wielded_medium_disposable_cell", + "fg": 24318, + "bg": 0, + "rotates": true }, { - "id": "rugerlcpmag", - "fg": 24114 - }, + "id": "heavy_disposable_cell", + "fg": 24319, + "bg": 0, + "rotates": true + }, { - "id": "overlay_wielded_rugerlcpmag", - "fg": 24114 + "id": "overlay_wielded_heavy_disposable_cell", + "fg": 24319, + "bg": 0, + "rotates": true }, { - "id": "corpse_mon_lostsoul", - "fg": 24115 - }, + "id": "robofac_enviro_suit", + "fg": 24320, + "bg": 0, + "rotates": true + }, { - "id": "corpse_mon_lostsoul_mount", - "fg": 24116 + "id": "overlay_wielded_robofac_enviro_suit", + "fg": 24320, + "bg": 0, + "rotates": true }, { - "id": "corpse_mon_revenant", - "fg": 24117 + "id": "overlay_worn_robofac_enviro_suit", + "fg": 24321, + "bg": 0, + "rotates": true }, { - "id": "corpse_mon_hell_knight", - "fg": 24118 - }, + "id": "robofac_test_data", + "fg": 24322, + "bg": 0, + "rotates": true + }, { - "id": "corpse_mon_hell_knight_revive", - "fg": 24119 - }, + "id": "overlay_wielded_robofac_test_data", + "fg": 24322, + "bg": 0, + "rotates": true + }, + { + "id": "f_planter", + "fg": 24323, + "bg": 24323, + "rotates": false + }, + { + "id": "f_planter_seed", + "fg": 1550, + "bg": 24323, + "rotates": false + }, + { + "id": "f_planter_seedling", + "fg": 1551, + "bg": 24323, + "rotates": false + }, { - "id": "corpse_mon_hell_baron", - "fg": 24120 - }, + "id": "f_planter_mature", + "fg": 1549, + "bg": 24323, + "rotates": false + }, { - "id": "corpse_mon_mancubus", - "fg": 24121 - }, + "id": "f_planter_harvest", + "fg": 1548, + "bg": 24323, + "rotates": false + }, { - "id": "corpse_mon_cacodemon", - "fg": 24122 + "id": "f_ground_crafting_spot", + "fg": 24324, + "rotates": false }, { - "id": "corpse_mon_cacodemon_revive", - "fg": 24123 + "id": "30gal_firebarrel", + "fg": 24325, + "rotates": false + }, + { + "id": "overlay_wielded_30gal_firebarrel", + "fg": 24325, + "rotates": false }, { - "id": "corpse_mon_doom_churl", - "fg": 24124 + "id": "f_30gal_firebarrel", + "fg": 24325, + "bg": 967, + "rotates": false }, { - "id": "corpse_mon_doom_churl_revive", - "fg": 24125 + "id": "55gal_firebarrel", + "fg": 24326, + "rotates": false }, - { - "id": "corpse_mon_doom_slave", - "fg": 24126 - }, { - "id": "corpse_mon_doom_cur", - "fg": 24127 + "id": "overlay_wielded_55gal_firebarrel", + "fg": 24326, + "rotates": false }, { - "id": "corpse_mon_doom_sacrifice", - "fg": 24128 + "id": "f_55gal_firebarrel", + "fg": 24326, + "bg": 967, + "rotates": false }, - { - "id": ["corpse_mon_doom_archvile", "corpse_mon_doom_archvile_2", "corpse_mon_doom_archvile_3", "corpse_mon_doom_archvile_4", "corpse_mon_doom_archvile_5"], - "fg": 24129 + { + "id": ["f_bluebell_season_winter", "f_dahlia_season_winter", "f_datura_season_winter", "f_flower_marloss_season_winter", "f_dandelion_season_winter", "f_chamomile_season_winter", "f_flower_tulip_season_winter", "f_flower_spurge_season_winter", "f_cattails_season_winter", "f_black_eyed_susan_season_winter", "f_lily_season_winter", "f_sunflower_season_winter", "f_mutpoppy_season_winter"], + "fg": 24327, + "bg": 0, + "rotates": false }, { - "id": ["corpse_mon_doom_archvile_queen"], - "fg": 24130 + "id": "f_cattails_season_winter", + "fg": 24328, + "bg": 0, + "rotates": false }, { - "id": ["corpse_mon_fish_eel_large"], - "fg": 24131 - }, - { - "id": ["corpse_mon_fish_flying"], - "fg": 24132 - }, + "id": "corpse_mon_goat", + "fg": 24329, + "bg": 0, + "rotates": false + }, { - "id": "overlay_wielded_arrow_metal_bodkin", - "fg": 24133, - "bg": 957, + "id": "corpse_mon_robin", + "fg": 24330, + "bg": 0, "rotates": false - }, + }, { - "id": "arrow_metal_bodkin", - "fg": 24133, - "bg": 957, + "id": "corpse_mon_pidgeon", + "fg": 24331, + "bg": 0, "rotates": false }, { - "id": "overlay_wielded_arrow_metal_sharpened_fletched", - "fg": 24134, - "bg": 957, + "id": "corpse_mon_bjay", + "fg": 24332, + "bg": 0, "rotates": false - }, + }, { - "id": "arrow_metal_sharpened_fletched", - "fg": 24134, - "bg": 957, + "id": "corpse_mon_gull", + "fg": 24333, + "bg": 0, "rotates": false }, { - "id": "overlay_wielded_arrow_field_point_fletched", - "fg": 24135, - "bg": 957, + "id": "corpse_mon_coyote_small", + "fg": 24334, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_mole_large", + "fg": 24335, + "bg": 0, "rotates": false }, + { + "id": ["corpse_mon_deer_small", "corpse_mon_deer_rutting"], + "fg": 24336, + "bg": 0, + "rotates": false + }, { - "id": "arrow_field_point_fletched", - "fg": 24135, - "bg": 957, + "id": "corpse_mon_pig_saber", + "fg": 24337, + "bg": 0, "rotates": false - }, + }, { - "id": "overlay_wielded_arrow_wood", - "fg": 24136, - "bg": 957, + "id": "corpse_mon_cyborg_guard", + "fg": 24338, + "bg": 0, "rotates": false }, { - "id": "arrow_wood", - "fg": 24136, - "bg": 957, + "id": "corpse_mon_cyborg_cop", + "fg": 24339, + "bg": 0, "rotates": false - }, + }, + { + "id": "corpse_mon_biollante_pk", + "fg": 24340, + "bg": 0, + "rotates": false + }, + { + "id": "mon_vinebeast_pk", + "fg": 24341, + "rotates": false + }, { - "id": "overlay_wielded_arrow_flamming", - "fg": 24137, - "bg": 957, + "id": "corpse_mon_vinebeast_pk", + "fg": 24342, "rotates": false - }, + }, { - "id": "arrow_flamming", - "fg": 24137, - "bg": 957, + "id": "corpse_mon_creeper_root", + "fg": 24343, "rotates": false - }, + }, { - "id": "overlay_wielded_biodiesel", - "fg": 24138, - "bg": 957, + "id": "corpse_mon_triffid_pk", + "fg": 24344, "rotates": false }, { - "id": "biodiesel", - "fg": 24138, - "bg": 957, + "id": "mon_vinebeast_terminal", + "fg": 24345, "rotates": false }, { - "id": "overlay_wielded_cactus_pad", - "fg": 24139, - "bg": 957, + "id": "corpse_mon_vinebeast_terminal", + "fg": 24346, + "rotates": false + }, { + "id": "corpse_mon_dionaea_sprout", + "fg": 24347, "rotates": false }, { - "id": "cactus_pad", - "fg": 24139, - "bg": 957, + "id": "corpse_mon_dionaea", + "fg": 24348, "rotates": false }, { - "id": "overlay_wielded_cargo_aisle", - "fg": 24140, - "bg": 957, + "id": "corpse_mon_dog_zombie_rot_worms", + "fg": 24349, "rotates": false }, { - "id": "cargo_aisle", - "fg": 24140, - "bg": 957, + "id": "corpse_mon_dog_zombie_rot_pain", + "fg": 24350, "rotates": false - }, + }, { - "id": "vp_cargo_aisle", - "fg": 24140, - "bg": 957, + "id": "corpse_mon_zolf_shady", + "fg": 24351, "rotates": false - }, + }, { - "id": "overlay_wielded_nopalitos", - "fg": 24141, - "bg": 957, + "id": "corpse_mon_horse_zombie", + "fg": 24352, "rotates": false - }, + }, { - "id": "nopalitos", - "fg": 24141, - "bg": 957, + "id": "corpse_mon_zombie_dog_pk", + "fg": 24353, "rotates": false - }, { - "id": "overlay_wielded_welding_components", - "fg": 24142, - "bg": 957, - "rotates": false - }, + }, { - "id": "welding_components", - "fg": 24142, - "bg": 957, + "id": "corpse_mon_dog_skeleton_pk", + "fg": 24354, "rotates": false - }, + }, { "id": "atlatl", "fg": 1986, "bg": 0, "rotates": false }, - { "id": "overlay_wielded_corpse", "fg": 1840, @@ -122658,6 +125076,65 @@ "fg": 35788, "bg": 0, "rotates": false + }, + { + "id": "mon_flesh_golem", + "fg": 35789, + "bg": 0, + "rotates": false + }, + { + "id": "mon_fleshy_shambler", + "fg": 35790, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_flesh_golem", + "fg": 35791, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_fleshy_shambler", + "fg": 35792, + "bg": 0, + "rotates": false + }, + { + "id": "mon_pig_saber", + "fg": 35793, + "bg": 0, + "rotates": false + }, { + "id": "mon_gelatin", + "fg": 35794, + "bg": 0, + "rotates": false + }, + { + "id": "mon_mi_go_terminal", + "fg": 35795, + "bg": 0, + "rotates": false + }, + { + "id": "mon_mi_go_fly", + "fg": 35796, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_mi_go_terminal", + "fg": 35797, + "bg": 0, + "rotates": false + }, + { + "id": "corpse_mon_mi_go_fly", + "fg": 35798, + "bg": 0, + "rotates": false } ] diff --git a/msvc-full-features/Cataclysm-App.vcxproj b/msvc-full-features/Cataclysm-App.vcxproj index 2ae5a01bcee2d..44caab15a041d 100644 --- a/msvc-full-features/Cataclysm-App.vcxproj +++ b/msvc-full-features/Cataclysm-App.vcxproj @@ -67,7 +67,7 @@ true false ProgramDatabase - 4819;4146 + 4819;4146;26495;26444;26451 stdafx.h /bigobj /utf-8 %(AdditionalOptions) _SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WINDOWS;%(PreprocessorDefinitions) diff --git a/msvc-full-features/Cataclysm-Lib.vcxproj b/msvc-full-features/Cataclysm-Lib.vcxproj index 6f6b6201c7b82..9cd58284a6076 100644 --- a/msvc-full-features/Cataclysm-Lib.vcxproj +++ b/msvc-full-features/Cataclysm-Lib.vcxproj @@ -67,7 +67,7 @@ true false ProgramDatabase - 4819;4146 + 4819;4146;26495;26444;26451 stdafx.h /bigobj /utf-8 %(AdditionalOptions) SDL_BUILDING_LIBRARY;_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WINDOWS;%(PreprocessorDefinitions) diff --git a/msvc-full-features/Cataclysm-vcpkg-static.vcxproj b/msvc-full-features/Cataclysm-vcpkg-static.vcxproj index bb47e468d896b..2b73f119efa58 100644 --- a/msvc-full-features/Cataclysm-vcpkg-static.vcxproj +++ b/msvc-full-features/Cataclysm-vcpkg-static.vcxproj @@ -68,7 +68,7 @@ true false ProgramDatabase - 4819;4146 + 4819;4146;26495;26444;26451 stdafx.h /bigobj /utf-8 %(AdditionalOptions) _SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions) diff --git a/msvc-full-features/Cataclysm-vcpkg.vcxproj b/msvc-full-features/Cataclysm-vcpkg.vcxproj index af1b3d82c5161..8f99373eddbf6 100644 --- a/msvc-full-features/Cataclysm-vcpkg.vcxproj +++ b/msvc-full-features/Cataclysm-vcpkg.vcxproj @@ -68,7 +68,7 @@ true false ProgramDatabase - 4819;4146 + 4819;4146;26495;26444;26451 stdafx.h /bigobj /utf-8 %(AdditionalOptions) _SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32_LEAN_AND_MEAN;_WINDOWS;SDL_SOUND;TILES;LOCALIZE;USE_VCPKG;USE_WINMAIN;%(PreprocessorDefinitions) diff --git a/src/action.cpp b/src/action.cpp index f7e6ec93cd38c..bb29046061f4c 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -600,7 +600,7 @@ bool can_examine_at( const tripoint &p ) return tr.can_see( p, g->u ); } -bool can_pickup_at( const tripoint &p ) +static bool can_pickup_at( const tripoint &p ) { bool veh_has_items = false; const optional_vpart_position vp = g->m.veh_at( p ); diff --git a/src/activity_handlers.cpp b/src/activity_handlers.cpp index 0a7ca0ebda9b9..81cde690c891e 100644 --- a/src/activity_handlers.cpp +++ b/src/activity_handlers.cpp @@ -31,6 +31,7 @@ #include "iexamine.h" #include "itype.h" #include "iuse_actor.h" +#include "magic.h" #include "map.h" #include "map_iterator.h" #include "mapdata.h" @@ -145,7 +146,8 @@ activity_handlers::do_turn_functions = { { activity_id( "ACT_FERTILIZE_PLOT" ), fertilize_plot_do_turn }, { activity_id( "ACT_TRY_SLEEP" ), try_sleep_do_turn }, { activity_id( "ACT_ROBOT_CONTROL" ), robot_control_do_turn }, - { activity_id( "ACT_TREE_COMMUNION" ), tree_communion_do_turn } + { activity_id( "ACT_TREE_COMMUNION" ), tree_communion_do_turn }, + { activity_id( "ACT_STUDY_SPELL" ), study_spell_do_turn} }; const std::map< activity_id, std::function > @@ -208,10 +210,11 @@ activity_handlers::finish_functions = { { activity_id( "ACT_UNLOAD_MAG" ), unload_mag_finish }, { activity_id( "ACT_ROBOT_CONTROL" ), robot_control_finish }, { activity_id( "ACT_HACK_DOOR" ), hack_door_finish }, - { activity_id( "ACT_HACK_SAFE" ), hack_safe_finish } + { activity_id( "ACT_HACK_SAFE" ), hack_safe_finish }, + { activity_id( "ACT_STUDY_SPELL" ), study_spell_finish } }; -void messages_in_process( const player_activity &act, const player &p ) +static void messages_in_process( const player_activity &act, const player &p ) { if( act.moves_left <= 91000 && act.moves_left > 89000 ) { p.add_msg_if_player( m_info, _( "You figure it'll take about an hour and a half at this rate." ) ); @@ -266,7 +269,7 @@ void activity_handlers::burrow_finish( player_activity *act, player *p ) act->set_to_null(); } -bool check_butcher_cbm( const int roll ) +static bool check_butcher_cbm( const int roll ) { // Failure rates for dissection rolls // 90% at roll 0, 72% at roll 1, 60% at roll 2, 51% @ 3, 45% @ 4, 40% @ 5, ... , 25% @ 10 @@ -278,8 +281,8 @@ bool check_butcher_cbm( const int roll ) return !failed; } -void butcher_cbm_item( const std::string &what, const tripoint &pos, - const time_point &age, const int roll ) +static void butcher_cbm_item( const std::string &what, const tripoint &pos, + const time_point &age, const int roll ) { if( roll < 0 ) { return; @@ -297,8 +300,8 @@ void butcher_cbm_item( const std::string &what, const tripoint &pos, } } -void butcher_cbm_group( const std::string &group, const tripoint &pos, - const time_point &age, const int roll ) +static void butcher_cbm_group( const std::string &group, const tripoint &pos, + const time_point &age, const int roll ) { if( roll < 0 ) { return; @@ -319,7 +322,7 @@ void butcher_cbm_group( const std::string &group, const tripoint &pos, } } -void set_up_butchery( player_activity &act, player &u, butcher_type action ) +static void set_up_butchery( player_activity &act, player &u, butcher_type action ) { if( !act.values.empty() ) { act.index = act.values.back(); @@ -583,7 +586,7 @@ int butcher_time_to_cut( const player &u, const item &corpse_item, const butcher return time_to_cut; } // The below function exists to allow mods to migrate their content fully to the new harvest system. This function should be removed eventually. -harvest_id butchery_flags_deprecate( const mtype &mt ) +static harvest_id butchery_flags_deprecate( const mtype &mt ) { std::string harvest_id_name = "null"; if( mt.has_flag( MF_CBM_CIV ) ) { @@ -671,7 +674,7 @@ harvest_id butchery_flags_deprecate( const mtype &mt ) } // this function modifies the input weight by its damage level, depending on the bodypart -int corpse_damage_effect( int weight, const std::string &entry_type, int damage_level ) +static int corpse_damage_effect( int weight, const std::string &entry_type, int damage_level ) { const float slight_damage = 0.9; const float damage = 0.75; @@ -724,9 +727,9 @@ int corpse_damage_effect( int weight, const std::string &entry_type, int damage_ return weight; } -void butchery_drops_harvest( item *corpse_item, const mtype &mt, player &p, - const std::function &roll_butchery, butcher_type action, - const std::function &roll_drops ) +static void butchery_drops_harvest( item *corpse_item, const mtype &mt, player &p, + const std::function &roll_butchery, butcher_type action, + const std::function &roll_drops ) { p.add_msg_if_player( m_neutral, _( mt.harvest->message() ) ); int monster_weight = to_gram( mt.weight ); @@ -983,7 +986,7 @@ void butchery_drops_harvest( item *corpse_item, const mtype &mt, player &p, } } -void butchery_quarter( item *corpse_item, player &p ) +static void butchery_quarter( item *corpse_item, player &p ) { corpse_item->set_flag( "QUARTERED" ); p.add_msg_if_player( m_good, @@ -2185,7 +2188,7 @@ enum repeat_type : int { REPEAT_CANCEL, // Stop repeating }; -repeat_type repeat_menu( const std::string &title, repeat_type last_selection ) +static repeat_type repeat_menu( const std::string &title, repeat_type last_selection ) { uilist rmenu; rmenu.text = title; @@ -3488,7 +3491,7 @@ void activity_handlers::tree_communion_do_turn( player_activity *act, player *p act->set_to_null(); } -hack_result try_hack( player &p ) +static hack_result try_hack( player &p ) { if( p.has_trait( trait_id( "ILLITERATE" ) ) ) { add_msg( _( "You can't read anything on the screen." ) ); @@ -3587,3 +3590,43 @@ void activity_handlers::hack_safe_finish( player_activity *act, player *p ) p->practice( skill_id( "computer" ), 20 ); act->set_to_null(); } + +void activity_handlers::study_spell_do_turn( player_activity *act, player *p ) +{ + if( p->fine_detail_vision_mod() > 4 ) { + act->values[2] = -1; + act->moves_left = 0; + return; + } + if( act->get_str_value( 1 ) == "study" ) { + spell &studying = p->magic.get_spell( spell_id( act->name ) ); + if( act->get_str_value( 0 ) == "gain_level" ) { + if( studying.get_level() < act->get_value( 1 ) ) { + act->moves_left = 1000000; + } else { + act->moves_left = 0; + } + } + const int xp = roll_remainder( studying.exp_modifier( *p ) ); + act->values[0] += xp; + studying.gain_exp( xp ); + } + act->moves_left -= 100; +} + +void activity_handlers::study_spell_finish( player_activity *act, player *p ) +{ + act->set_to_null(); + + if( act->get_str_value( 1 ) == "study" ) { + p->add_msg_if_player( m_good, _( "You gained %i experience from your study session." ), + act->get_value( 0 ) ); + p->practice( skill_id( "spellcraft" ), act->get_value( 0 ) / 5, + p->magic.get_spell( spell_id( act->name ) ).get_difficulty() ); + } else if( act->get_str_value( 1 ) == "learn" && act->values[2] == 0 ) { + p->magic.learn_spell( act->name, *p ); + } + if( act->values[2] == -1 ) { + p->add_msg_if_player( m_bad, _( "It's too dark to read." ) ); + } +} diff --git a/src/activity_handlers.h b/src/activity_handlers.h index c0a058686ce10..e9b6a1dc7f9e2 100644 --- a/src/activity_handlers.h +++ b/src/activity_handlers.h @@ -95,6 +95,7 @@ void harvest_plot_do_turn( player_activity *act, player *p ); void try_sleep_do_turn( player_activity *act, player *p ); void robot_control_do_turn( player_activity *act, player *p ); void tree_communion_do_turn( player_activity *act, player *p ); +void study_spell_do_turn( player_activity *act, player *p ); // defined in activity_handlers.cpp extern const std::map< activity_id, std::function > @@ -152,6 +153,7 @@ void unload_mag_finish( player_activity *act, player *p ); void robot_control_finish( player_activity *act, player *p ); void hack_door_finish( player_activity *act, player *p ); void hack_safe_finish( player_activity *act, player *p ); +void study_spell_finish( player_activity *act, player *p ); // defined in activity_handlers.cpp extern const std::map< activity_id, std::function > diff --git a/src/activity_item_handling.cpp b/src/activity_item_handling.cpp index ede3190155076..29ab109e8376b 100644 --- a/src/activity_item_handling.cpp +++ b/src/activity_item_handling.cpp @@ -68,17 +68,17 @@ struct act_item { }; // TODO: Deliberately unified with multidrop. Unify further. -typedef std::list> drop_indexes; +using drop_indexes = std::list>; -bool same_type( const std::list &items ) +static bool same_type( const std::list &items ) { return std::all_of( items.begin(), items.end(), [ &items ]( const item & it ) { return it.type == items.begin()->type; } ); } -void put_into_vehicle( Character &c, item_drop_reason reason, const std::list &items, - vehicle &veh, int part ) +static void put_into_vehicle( Character &c, item_drop_reason reason, const std::list &items, + vehicle &veh, int part ) { if( items.empty() ) { return; @@ -105,6 +105,7 @@ void put_into_vehicle( Character &c, item_drop_reason reason, const std::listm.add_item_or_charges( where, it ); fallen_count += it.count(); } + it.handle_pickup_ownership( c ); } const std::string part_name = veh.part_info( part ).name(); @@ -188,7 +189,17 @@ void put_into_vehicle( Character &c, item_drop_reason reason, const std::list &items, monster &pet ) +static void pass_to_ownership_handling( item obj, Character &c ) +{ + obj.handle_pickup_ownership( c ); +} + +static void pass_to_ownership_handling( item obj, player *p ) +{ + obj.handle_pickup_ownership( *p ); +} + +static void stash_on_pet( const std::list &items, monster &pet, player *p ) { units::volume remaining_volume = pet.inv.empty() ? 0_ml : pet.inv.front().get_storage(); units::mass remaining_weight = pet.weight_capacity(); @@ -213,11 +224,13 @@ void stash_on_pet( const std::list &items, monster &pet ) remaining_volume -= it.volume(); remaining_weight -= it.weight(); } + // TODO: if NPCs can have pets or move items onto pets + pass_to_ownership_handling( it, p ); } } -void drop_on_map( const Character &c, item_drop_reason reason, const std::list &items, - const tripoint &where ) +static void drop_on_map( Character &c, item_drop_reason reason, const std::list &items, + const tripoint &where ) { if( items.empty() ) { return; @@ -297,8 +310,9 @@ void drop_on_map( const Character &c, item_drop_reason reason, const std::listm.add_item_or_charges( where, it ); + pass_to_ownership_handling( it, c ); } } @@ -318,7 +332,7 @@ void put_into_vehicle_or_drop( Character &c, item_drop_reason reason, const std: drop_on_map( c, reason, items, where ); } -drop_indexes convert_to_indexes( const player_activity &act ) +static drop_indexes convert_to_indexes( const player_activity &act ) { drop_indexes res; @@ -332,7 +346,7 @@ drop_indexes convert_to_indexes( const player_activity &act ) return res; } -drop_indexes convert_to_indexes( const player &p, const std::list &items ) +static drop_indexes convert_to_indexes( const player &p, const std::list &items ) { drop_indexes res; @@ -350,8 +364,8 @@ drop_indexes convert_to_indexes( const player &p, const std::list &ite return res; } -std::list convert_to_items( const player &p, const drop_indexes &drop, - int min_pos, int max_pos ) +static std::list convert_to_items( const player &p, const drop_indexes &drop, + int min_pos, int max_pos ) { std::list res; @@ -382,7 +396,7 @@ std::list convert_to_items( const player &p, const drop_indexes &drop, // Prepares items for dropping by reordering them so that the drop // cost is minimal and "dependent" items get taken off first. // Implements the "backpack" logic. -std::list reorder_for_dropping( const player &p, const drop_indexes &drop ) +static std::list reorder_for_dropping( const player &p, const drop_indexes &drop ) { auto res = convert_to_items( p, drop, -1, -1 ); auto inv = convert_to_items( p, drop, 0, INT_MAX ); @@ -443,7 +457,7 @@ std::list reorder_for_dropping( const player &p, const drop_indexes &d } // TODO: Display costs in the multidrop menu -void debug_drop_list( const std::list &list ) +static void debug_drop_list( const std::list &list ) { if( !debug_mode ) { return; @@ -457,7 +471,7 @@ void debug_drop_list( const std::list &list ) popup( res, PF_GET_KEY ); } -std::list obtain_activity_items( player_activity &act, player &p ) +static std::list obtain_activity_items( player_activity &act, player &p ) { std::list res; @@ -663,7 +677,7 @@ void activity_handlers::stash_do_turn( player_activity *act, player *p ) monster *pet = g->critter_at( pos ); if( pet != nullptr && pet->has_effect( effect_pet ) ) { - stash_on_pet( obtain_activity_items( *act, *p ), *pet ); + stash_on_pet( obtain_activity_items( *act, *p ), *pet, p ); } else { p->add_msg_if_player( _( "The pet has moved somewhere else." ) ); p->cancel_activity(); @@ -1191,7 +1205,8 @@ void activity_on_turn_move_loot( player_activity &, player &p ) mgr.end_sort(); } -cata::optional find_best_fire( const std::vector &from, const tripoint ¢er ) +static cata::optional find_best_fire( + const std::vector &from, const tripoint ¢er ) { cata::optional best_fire; time_duration best_fire_age = 1_days; diff --git a/src/advanced_inv.cpp b/src/advanced_inv.cpp index 474ed59e0d9e8..465d8231a81be 100644 --- a/src/advanced_inv.cpp +++ b/src/advanced_inv.cpp @@ -342,6 +342,15 @@ void advanced_inventory::print_items( advanced_inventory_pane &pane, bool active } std::string item_name; + std::string stolen_string; + bool stolen = false; + if( it.has_owner() ) { + const faction *item_fac = it.get_owner(); + if( item_fac != g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ) { + stolen_string = string_format( "!" ); + stolen = true; + } + } if( it.ammo_type() == "money" ) { //Count charges // TODO: transition to the item_location system used for the normal inventory @@ -349,9 +358,18 @@ void advanced_inventory::print_items( advanced_inventory_pane &pane, bool active for( const auto item : sitem.items ) { charges_total += item->charges; } - item_name = it.display_money( sitem.items.size(), charges_total ); + if( stolen ) { + item_name = string_format( "%s %s", stolen_string, it.display_money( sitem.items.size(), + charges_total ) ); + } else { + item_name = it.display_money( sitem.items.size(), charges_total ); + } } else { - item_name = it.display_name(); + if( stolen ) { + item_name = string_format( "%s %s", stolen_string, it.display_name() ); + } else { + item_name = it.display_name(); + } } if( get_option( "ITEM_SYMBOLS" ) ) { item_name = string_format( "%s %s", it.symbol(), item_name ); @@ -776,11 +794,6 @@ void advanced_inv_area::init() } } -std::string center_text( const char *str, int width ) -{ - return std::string( ( ( width - strlen( str ) ) / 2 ), ' ' ) + str; -} - void advanced_inventory::init() { for( auto &square : squares ) { @@ -904,7 +917,7 @@ bool advanced_inventory_pane::is_filtered( const item &it ) const } // roll our own, to handle moving stacks better -typedef std::vector> itemstack; +using itemstack = std::vector >; template static itemstack i_stacked( T items ) diff --git a/src/advanced_inv.h b/src/advanced_inv.h index 5e5390ce9773f..ccc6d76d982ce 100644 --- a/src/advanced_inv.h +++ b/src/advanced_inv.h @@ -140,7 +140,7 @@ class item_category; * Most members are used only for sorting. */ struct advanced_inv_listitem { - typedef std::string itype_id; + using itype_id = std::string; /** * Index of the item in the itemstack. */ diff --git a/src/animation.cpp b/src/animation.cpp index 22b2758c175d3..1c38aefd63c3c 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -44,6 +44,7 @@ class basic_animation void draw() const { wrefresh( g->w_terrain ); + g->draw_panels(); query_popup() .wait_message( "%s", _( "Hang on a bit..." ) ) diff --git a/src/armor_layers.cpp b/src/armor_layers.cpp index ac637b2e4cc37..4c5e3eb14ffd3 100644 --- a/src/armor_layers.cpp +++ b/src/armor_layers.cpp @@ -365,7 +365,7 @@ static std::vector items_cover_bp( const Character &c, int b return s; } -void draw_grid( const catacurses::window &w, int left_pane_w, int mid_pane_w ) +static void draw_grid( const catacurses::window &w, int left_pane_w, int mid_pane_w ) { const int win_w = getmaxx( w ); const int win_h = getmaxy( w ); diff --git a/src/avatar.cpp b/src/avatar.cpp new file mode 100644 index 0000000000000..73a5e5fd7eb17 --- /dev/null +++ b/src/avatar.cpp @@ -0,0 +1,238 @@ +#include "avatar.h" + +#include "bionics.h" +#include "character.h" +#include "filesystem.h" +#include "game.h" +#include "inventory.h" +#include "item.h" +#include "messages.h" +#include "monstergenerator.h" +#include "mutation.h" +#include "overmapbuffer.h" +#include "player.h" +#include "profession.h" +#include "skill.h" +#include "type_id.h" +#include "get_version.h" + +void avatar::memorial( std::ostream &memorial_file, const std::string &epitaph ) +{ + static const char *eol = cata_files::eol(); + + //Size of indents in the memorial file + const std::string indent = " "; + + const std::string pronoun = male ? _( "He" ) : _( "She" ); + + //Avoid saying "a male unemployed" or similar + std::string profession_name; + if( prof == prof->generic( ) ) { + if( male ) { + profession_name = _( "an unemployed male" ); + } else { + profession_name = _( "an unemployed female" ); + } + } else { + profession_name = string_format( _( "a %s" ), prof->gender_appropriate_name( male ) ); + } + + const std::string locdesc = overmap_buffer.get_description_at( global_sm_location() ); + //~ First parameter is a pronoun ("He"/"She"), second parameter is a description + // that designates the location relative to its surroundings. + const std::string kill_place = string_format( _( "%1$s was killed in a %2$s." ), + pronoun, locdesc ); + + //Header + memorial_file << string_format( _( "Cataclysm - Dark Days Ahead version %s memorial file" ), + getVersionString() ) << eol; + memorial_file << eol; + memorial_file << string_format( _( "In memory of: %s" ), name ) << eol; + if( epitaph.length() > 0 ) { //Don't record empty epitaphs + //~ The "%s" will be replaced by an epitaph as displayed in the memorial files. Replace the quotation marks as appropriate for your language. + memorial_file << string_format( pgettext( "epitaph", "\"%s\"" ), epitaph ) << eol << eol; + } + //~ First parameter: Pronoun, second parameter: a profession name (with article) + memorial_file << string_format( _( "%1$s was %2$s when the apocalypse began." ), + pronoun, profession_name ) << eol; + memorial_file << string_format( _( "%1$s died on %2$s." ), pronoun, + to_string( time_point( calendar::turn ) ) ) << eol; + memorial_file << kill_place << eol; + memorial_file << eol; + + //Misc + memorial_file << string_format( _( "Cash on hand: %s" ), format_money( cash ) ) << eol; + memorial_file << eol; + + //HP + + const auto limb_hp = + [this, &memorial_file, &indent]( const std::string & desc, const hp_part bp ) { + memorial_file << indent << string_format( desc, get_hp( bp ), get_hp_max( bp ) ) << eol; + }; + + memorial_file << _( "Final HP:" ) << eol; + limb_hp( _( " Head: %d/%d" ), hp_head ); + limb_hp( _( "Torso: %d/%d" ), hp_torso ); + limb_hp( _( "L Arm: %d/%d" ), hp_arm_l ); + limb_hp( _( "R Arm: %d/%d" ), hp_arm_r ); + limb_hp( _( "L Leg: %d/%d" ), hp_leg_l ); + limb_hp( _( "R Leg: %d/%d" ), hp_leg_r ); + memorial_file << eol; + + //Stats + memorial_file << _( "Final Stats:" ) << eol; + memorial_file << indent << string_format( _( "Str %d" ), str_cur ) + << indent << string_format( _( "Dex %d" ), dex_cur ) + << indent << string_format( _( "Int %d" ), int_cur ) + << indent << string_format( _( "Per %d" ), per_cur ) << eol; + memorial_file << _( "Base Stats:" ) << eol; + memorial_file << indent << string_format( _( "Str %d" ), str_max ) + << indent << string_format( _( "Dex %d" ), dex_max ) + << indent << string_format( _( "Int %d" ), int_max ) + << indent << string_format( _( "Per %d" ), per_max ) << eol; + memorial_file << eol; + + //Last 20 messages + memorial_file << _( "Final Messages:" ) << eol; + std::vector > recent_messages = Messages::recent_messages( 20 ); + for( const std::pair &recent_message : recent_messages ) { + memorial_file << indent << recent_message.first << " " << recent_message.second; + memorial_file << eol; + } + memorial_file << eol; + + //Kill list + memorial_file << _( "Kills:" ) << eol; + + int total_kills = 0; + + std::map, int> kill_counts; + + // map to kill count + for( const mtype &type : MonsterGenerator::generator().get_all_mtypes() ) { + if( g->kill_count( type.id ) > 0 ) { + kill_counts[std::tuple( + type.nname(), + type.sym + )] += g->kill_count( type.id ); + total_kills += g->kill_count( type.id ); + } + } + + for( const std::pair, int> &entry : kill_counts ) { + memorial_file << " " << std::get<1>( entry.first ) << " - " + << string_format( "%4d", entry.second ) << " " + << std::get<0>( entry.first ) << eol; + } + + if( total_kills == 0 ) { + memorial_file << indent << _( "No monsters were killed." ) << eol; + } else { + memorial_file << string_format( _( "Total kills: %d" ), total_kills ) << eol; + } + memorial_file << eol; + + //Skills + memorial_file << _( "Skills:" ) << eol; + for( const std::pair &pair : *_skills ) { + const SkillLevel &lobj = pair.second; + //~ 1. skill name, 2. skill level, 3. exercise percentage to next level + memorial_file << indent << string_format( _( "%s: %d (%d %%)" ), pair.first->name(), lobj.level(), + lobj.exercise() ) << eol; + } + memorial_file << eol; + + //Traits + memorial_file << _( "Traits:" ) << eol; + for( const std::pair &iter : my_mutations ) { + memorial_file << indent << mutation_branch::get_name( iter.first ) << eol; + } + if( !my_mutations.empty() ) { + memorial_file << indent << _( "(None)" ) << eol; + } + memorial_file << eol; + + //Effects (illnesses) + memorial_file << _( "Ongoing Effects:" ) << eol; + bool had_effect = false; + if( get_perceived_pain() > 0 ) { + had_effect = true; + memorial_file << indent << _( "Pain" ) << " (" << get_perceived_pain() << ")"; + } + if( !had_effect ) { + memorial_file << indent << _( "(None)" ) << eol; + } + memorial_file << eol; + + //Bionics + memorial_file << _( "Bionics:" ) << eol; + int total_bionics = 0; + for( size_t i = 0; i < my_bionics->size(); ++i ) { + memorial_file << indent << ( i + 1 ) << ": " << ( *my_bionics )[i].id->name << eol; + total_bionics++; + } + if( total_bionics == 0 ) { + memorial_file << indent << _( "No bionics were installed." ) << eol; + } else { + memorial_file << string_format( _( "Total bionics: %d" ), total_bionics ) << eol; + } + memorial_file << string_format( + _( "Bionic Power: %d/%d" ), power_level, + max_power_level ) << eol; + memorial_file << eol; + + //Equipment + memorial_file << _( "Weapon:" ) << eol; + memorial_file << indent << weapon.invlet << " - " << weapon.tname( 1, false ) << eol; + memorial_file << eol; + + memorial_file << _( "Equipment:" ) << eol; + for( const item &elem : worn ) { + item next_item = elem; + memorial_file << indent << next_item.invlet << " - " << next_item.tname( 1, false ); + if( next_item.charges > 0 ) { + memorial_file << " (" << next_item.charges << ")"; + } else if( next_item.contents.size() == 1 && next_item.contents.front().charges > 0 ) { + memorial_file << " (" << next_item.contents.front().charges << ")"; + } + memorial_file << eol; + } + memorial_file << eol; + + //Inventory + memorial_file << _( "Inventory:" ) << eol; + inv.restack( *this ); + invslice slice = inv.slice(); + for( const std::list *elem : slice ) { + const item &next_item = elem->front(); + memorial_file << indent << next_item.invlet << " - " << + next_item.tname( static_cast( elem->size() ), false ); + if( elem->size() > 1 ) { + memorial_file << " [" << elem->size() << "]"; + } + if( next_item.charges > 0 ) { + memorial_file << " (" << next_item.charges << ")"; + } else if( next_item.contents.size() == 1 && next_item.contents.front().charges > 0 ) { + memorial_file << " (" << next_item.contents.front().charges << ")"; + } + memorial_file << eol; + } + memorial_file << eol; + + //Lifetime stats + memorial_file << _( "Lifetime Stats" ) << eol; + memorial_file << indent << string_format( _( "Distance walked: %d squares" ), + lifetime_stats.squares_walked ) << eol; + memorial_file << indent << string_format( _( "Damage taken: %d damage" ), + lifetime_stats.damage_taken ) << eol; + memorial_file << indent << string_format( _( "Damage healed: %d damage" ), + lifetime_stats.damage_healed ) << eol; + memorial_file << indent << string_format( _( "Headshots: %d" ), + lifetime_stats.headshots ) << eol; + memorial_file << eol; + + //History + memorial_file << _( "Game History" ) << eol; + memorial_file << dump_memorial(); +} diff --git a/src/avatar.h b/src/avatar.h index 4cf797f101c9b..c794824e6ee7f 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -13,6 +13,14 @@ class avatar : public player void load( JsonObject &data ); void serialize( JsonOut &josn ) const; void deserialize( JsonIn &json ); + + /** Prints out the player's memorial file */ + void memorial( std::ostream &memorial_file, const std::string &epitaph ); + + // newcharacter.cpp + bool create( character_type type, const std::string &tempname = "" ); + void randomize( bool random_scenario, points_left &points, bool play_now = false ); + bool load_template( const std::string &template_name, points_left &points ); }; #endif diff --git a/src/bionics.cpp b/src/bionics.cpp index 91914e36d819c..05f4261bf276c 100644 --- a/src/bionics.cpp +++ b/src/bionics.cpp @@ -145,7 +145,7 @@ bionic_data::bionic_data() description = "This bionic was not set up correctly, this is a bug"; } -void force_comedown( effect &eff ) +static void force_comedown( effect &eff ) { if( eff.is_null() || eff.get_effect_type() == nullptr || eff.get_duration() <= 1_turns ) { return; @@ -238,6 +238,12 @@ bool player::activate_bionic( int b, bool eff_only ) { bionic &bio = ( *my_bionics )[b]; + if( bio.incapacitated_time > 0_turns ) { + add_msg( m_info, _( "Your %s is shorting out and can't be activated." ), + bionics[bio.id].name.c_str() ); + return false; + } + // Preserve the fake weapon used to initiate bionic gun firing static item bio_gun( weapon ); @@ -694,6 +700,12 @@ bool player::deactivate_bionic( int b, bool eff_only ) { bionic &bio = ( *my_bionics )[b]; + if( bio.incapacitated_time > 0_turns ) { + add_msg( m_info, _( "Your %s is shorting out and can't be deactivated." ), + bionics[bio.id].name.c_str() ); + return false; + } + // Just do the effect, no stat changing or messages if( !eff_only ) { if( !bio.powered ) { @@ -777,7 +789,7 @@ bool player::deactivate_bionic( int b, bool eff_only ) * @param rate divides the number of turns we may charge (rate of 2 discharges in half the time). * @return indicates whether we successfully charged the bionic. */ -bool attempt_recharge( player &p, bionic &bio, int &amount, int factor = 1, int rate = 1 ) +static bool attempt_recharge( player &p, bionic &bio, int &amount, int factor = 1, int rate = 1 ) { const bionic_data &info = bio.info(); const int armor_power_cost = 1; @@ -1023,7 +1035,7 @@ void player::bionics_uninstall_failure( monster &installer, player &patient, int add_msg( m_mixed, _( "The %s messes up the operation." ), installer.name() ); break; case 3: - add_msg( m_mixed, _( "The The operation fails." ) ); + add_msg( m_mixed, _( "The operation fails." ) ); break; case 4: add_msg( m_mixed, _( "The operation is a failure." ) ); @@ -1265,7 +1277,9 @@ bool player::uninstall_bionic( const bionic &target_cbm, monster &installer, pla patient.add_effect( effect_narcosis, duration ); patient.add_effect( effect_sleep, duration ); - if( g->u.sees( patient ) ) { + if( patient.is_player() ) { + add_msg( "You fall asleep and %1$s starts operating.", installer.disp_name() ); + } else if( g->u.sees( patient ) ) { add_msg( "%1$s falls asleep and %2$s starts operating.", patient.disp_name(), installer.disp_name() ); } @@ -1751,6 +1765,7 @@ void load_bionic( JsonObject &jsobj ) false ); new_bionic.sleep_friendly = get_bool_or_flag( jsobj, "sleep_friendly", "BIONIC_SLEEP_FRIENDLY", false ); + new_bionic.shockproof = get_bool_or_flag( jsobj, "shockproof", "BIONIC_SHOCKPROOF", false ); if( new_bionic.gun_bionic && new_bionic.weapon_bionic ) { debugmsg( "Bionic %s specified as both gun and weapon bionic", id.c_str() ); @@ -1847,6 +1862,9 @@ void bionic::serialize( JsonOut &json ) const json.member( "charge", charge ); json.member( "ammo_loaded", ammo_loaded ); json.member( "ammo_count", ammo_count ); + if( incapacitated_time > 0 ) { + json.member( "incapacitated_time", incapacitated_time ); + } json.end_object(); } @@ -1863,6 +1881,9 @@ void bionic::deserialize( JsonIn &jsin ) if( jo.has_int( "ammo_count" ) ) { ammo_count = jo.get_int( "ammo_count" ); } + if( jo.has_int( "incapacitated_time" ) ) { + incapacitated_time = 1_turns * jo.get_int( "incapacitated_time" ); + } } void player::introduce_into_anesthesia( const time_duration &duration, player &installer, diff --git a/src/bionics.h b/src/bionics.h index fc8799e557800..f48e031e75ffe 100644 --- a/src/bionics.h +++ b/src/bionics.h @@ -10,6 +10,7 @@ #include #include "bodypart.h" +#include "calendar.h" #include "string_id.h" #include "type_id.h" @@ -65,6 +66,10 @@ struct bionic_data { * If true, this bionic won't provide a warning if the player tries to sleep while it's active. */ bool sleep_friendly = false; + /** + * If true, this bionic can't be incapacitated by electrical attacks. + */ + bool shockproof = false; /** * Body part slots used to install this bionic, mapped to the amount of space required. */ @@ -108,11 +113,14 @@ struct bionic { itype_id ammo_loaded = "null"; /* Ammount of ammo actually held inside by this bionic gun in deactivated state */ unsigned int ammo_count = 0; + /* An amount of time during which this bionic has been rendered inoperative. */ + time_duration incapacitated_time; bionic() - : id( "bio_batteries" ) { } + : id( "bio_batteries" ), incapacitated_time( 0_turns ) { + } bionic( bionic_id pid, char pinvlet ) - : id( std::move( pid ) ), invlet( pinvlet ) { } + : id( std::move( pid ) ), invlet( pinvlet ), incapacitated_time( 0_turns ) { } const bionic_data &info() const { return *id; diff --git a/src/bionics_ui.cpp b/src/bionics_ui.cpp index 06096e1084bbd..e67add9d2bad8 100644 --- a/src/bionics_ui.cpp +++ b/src/bionics_ui.cpp @@ -54,7 +54,8 @@ char get_free_invlet( player &p ) return ' '; } -void draw_bionics_titlebar( const catacurses::window &window, player *p, bionic_menu_mode mode ) +static void draw_bionics_titlebar( const catacurses::window &window, player *p, + bionic_menu_mode mode ) { werase( window ); @@ -75,7 +76,7 @@ void draw_bionics_titlebar( const catacurses::window &window, player *p, bionic_ } //builds the power usage string of a given bionic -std::string build_bionic_poweronly_string( const bionic &bio ) +static std::string build_bionic_poweronly_string( const bionic &bio ) { const bionic_data &bio_data = bio.id.obj(); std::vector properties; @@ -95,12 +96,15 @@ std::string build_bionic_poweronly_string( const bionic &bio ) if( bio_data.toggled ) { properties.push_back( bio.powered ? _( "ON" ) : _( "OFF" ) ); } + if( bio.incapacitated_time > 0_turns ) { + properties.push_back( _( "(incapacitated)" ) ); + } return enumerate_as_string( properties, enumeration_conjunction::none ); } //generates the string that show how much power a bionic uses -std::string build_bionic_powerdesc_string( const bionic &bio ) +static std::string build_bionic_powerdesc_string( const bionic &bio ) { std::ostringstream power_desc; const std::string power_string = build_bionic_poweronly_string( bio ); @@ -111,8 +115,8 @@ std::string build_bionic_powerdesc_string( const bionic &bio ) return power_desc.str(); } -void draw_bionics_tabs( const catacurses::window &win, const size_t active_num, - const size_t passive_num, const bionic_tab_mode current_mode ) +static void draw_bionics_tabs( const catacurses::window &win, const size_t active_num, + const size_t passive_num, const bionic_tab_mode current_mode ) { werase( win ); @@ -130,7 +134,7 @@ void draw_bionics_tabs( const catacurses::window &win, const size_t active_num, wrefresh( win ); } -void draw_description( const catacurses::window &win, const bionic &bio ) +static void draw_description( const catacurses::window &win, const bionic &bio ) { werase( win ); const int width = getmaxx( win ); @@ -153,8 +157,8 @@ void draw_description( const catacurses::window &win, const bionic &bio ) wrefresh( win ); } -void draw_connectors( const catacurses::window &win, const int start_y, const int start_x, - const int last_x, const bionic_id &bio_id ) +static void draw_connectors( const catacurses::window &win, const int start_y, const int start_x, + const int last_x, const bionic_id &bio_id ) { const int LIST_START_Y = 6; // first: pos_y, second: occupied slots @@ -234,7 +238,7 @@ void draw_connectors( const catacurses::window &win, const int start_y, const in } //get a text color depending on the power/powering state of the bionic -nc_color get_bionic_text_color( const bionic &bio, const bool isHighlightedBionic ) +static nc_color get_bionic_text_color( const bionic &bio, const bool isHighlightedBionic ) { nc_color type = c_white; if( bio.id->activated ) { @@ -277,7 +281,8 @@ nc_color get_bionic_text_color( const bionic &bio, const bool isHighlightedBioni return type; } -std::vector< bionic *>filtered_bionics( bionic_collection &all_bionics, bionic_tab_mode mode ) +static std::vector filtered_bionics( bionic_collection &all_bionics, + bionic_tab_mode mode ) { std::vector< bionic *>filtered_entries; for( auto &elem : all_bionics ) { diff --git a/src/bodypart.cpp b/src/bodypart.cpp index 0ff423f37e29f..35736f16d92f2 100644 --- a/src/bodypart.cpp +++ b/src/bodypart.cpp @@ -51,7 +51,7 @@ generic_factory body_part_factory( "body part" ); } // namespace -body_part legacy_id_to_enum( const std::string &legacy_id ) +static body_part legacy_id_to_enum( const std::string &legacy_id ) { static const std::unordered_map body_parts = { { "TORSO", bp_torso }, @@ -143,7 +143,7 @@ const bodypart_ids &convert_bp( body_part bp ) return body_parts[static_cast( bp )]; } -const body_part_struct &get_bp( body_part bp ) +static const body_part_struct &get_bp( body_part bp ) { return convert_bp( bp ).obj(); } diff --git a/src/bonuses.cpp b/src/bonuses.cpp index 9250dde018669..3d89cc6359076 100644 --- a/src/bonuses.cpp +++ b/src/bonuses.cpp @@ -12,7 +12,7 @@ #include "translations.h" #include "string_formatter.h" -bool needs_damage_type( affected_stat as ) +static bool needs_damage_type( affected_stat as ) { return as == AFFECTED_DAMAGE || as == AFFECTED_ARMOR || as == AFFECTED_ARMOR_PENETRATION; @@ -39,7 +39,7 @@ static const std::map scaling_stat_map = {{ } }; -scaling_stat scaling_stat_from_string( const std::string &s ) +static scaling_stat scaling_stat_from_string( const std::string &s ) { const auto &iter = scaling_stat_map.find( s ); if( iter == scaling_stat_map.end() ) { @@ -49,7 +49,7 @@ scaling_stat scaling_stat_from_string( const std::string &s ) return iter->second; } -affected_stat affected_stat_from_string( const std::string &s ) +static affected_stat affected_stat_from_string( const std::string &s ) { const auto &iter = affected_stat_map.find( s ); if( iter != affected_stat_map.end() ) { @@ -72,7 +72,7 @@ static const std::map affected_stat_map_translation } }; -std::string string_from_affected_stat( const affected_stat &s ) +static std::string string_from_affected_stat( const affected_stat &s ) { const auto &iter = affected_stat_map_translation.find( s ); return iter != affected_stat_map_translation.end() ? _( iter->second ) : ""; @@ -86,7 +86,7 @@ static const std::map scaling_stat_map_translation = } }; -std::string string_from_scaling_stat( const scaling_stat &s ) +static std::string string_from_scaling_stat( const scaling_stat &s ) { const auto &iter = scaling_stat_map_translation.find( s ); return iter != scaling_stat_map_translation.end() ? _( iter->second ) : ""; diff --git a/src/character.cpp b/src/character.cpp index c9d5abe3387ad..023766f6453a4 100644 --- a/src/character.cpp +++ b/src/character.cpp @@ -127,6 +127,7 @@ Character::Character() : // 45 days to starve to death healthy_calories = 55000; stored_calories = healthy_calories; + initialize_stomach_contents(); name.clear(); @@ -189,6 +190,27 @@ void Character::mod_stat( const std::string &stat, float modifier ) } } +std::string Character::disp_name( bool possessive ) const +{ + if( !possessive ) { + if( is_player() ) { + return pgettext( "not possessive", "you" ); + } + return name; + } else { + if( is_player() ) { + return _( "your" ); + } + return string_format( _( "%s's" ), name ); + } +} + +std::string Character::skin_name() const +{ + // TODO: Return actual deflecting layer name + return _( "armor" ); +} + int Character::effective_dispersion( int dispersion ) const { /** @EFFECT_PER penalizes sight dispersion when low. */ @@ -484,6 +506,15 @@ void Character::add_effect( const efftype_id &eff_id, const time_duration dur, b void Character::process_turn() { + for( auto &i : *my_bionics ) { + if( i.incapacitated_time > 0_turns ) { + i.incapacitated_time -= 1_turns; + if( i.incapacitated_time == 0_turns ) { + add_msg_if_player( m_bad, _( "Your %s bionic comes back online." ), i.info().name ); + } + } + } + Creature::process_turn(); } @@ -672,7 +703,7 @@ bool Character::has_active_bionic( const bionic_id &b ) const { for( auto &i : *my_bionics ) { if( i.id == b ) { - return ( i.powered ); + return ( i.powered && i.incapacitated_time == 0_turns ); } } return false; @@ -747,6 +778,7 @@ long int Character::i_add_to_container( const item &it, const bool unloading ) visit_items( [ & ]( item * item ) { if( charges > 0 && item->is_ammo_container() && item_type == item->contents.front().typeId() ) { charges = add_to_container( *item ); + item->handle_pickup_ownership( *this ); } return VisitResponse::NEXT; } ); @@ -774,7 +806,6 @@ item &Character::i_add( item it, bool should_stack ) break; } } - auto &item_in_inv = inv.add_item( it, keep_invlet, true, should_stack ); item_in_inv.on_pickup( *this ); return item_in_inv; @@ -1554,10 +1585,10 @@ int Character::extraEncumbrance( const layer_level level, const int bp ) const return encumbrance_cache[bp].layer_penalty_details[static_cast( level )].total; } -void layer_item( std::array &vals, - const item &it, - std::array &highest_layer_so_far, - bool power_armor, const Character &c ) +static void layer_item( std::array &vals, + const item &it, + std::array &highest_layer_so_far, + bool power_armor, const Character &c ) { const auto item_layer = it.get_layer(); int encumber_val = it.get_encumber( c ); @@ -1697,9 +1728,9 @@ int Character::encumb( body_part bp ) const return encumbrance_cache[bp].encumbrance; } -void apply_mut_encumbrance( std::array &vals, - const mutation_branch &mut, - const body_part_set &oversize ) +static void apply_mut_encumbrance( std::array &vals, + const mutation_branch &mut, + const body_part_set &oversize ) { for( const auto &enc : mut.encumbrance_always ) { vals[enc.first].encumbrance += enc.second; @@ -2147,6 +2178,35 @@ int Character::get_sleep_deprivation() const return sleep_deprivation; } +void Character::on_damage_of_type( int adjusted_damage, damage_type type, body_part bp ) +{ + // Electrical damage has a chance to temporarily incapacitate bionics in the damaged body_part. + if( type == DT_ELECTRIC ) { + const time_duration min_disable_time = 10_turns * adjusted_damage; + for( auto &i : *my_bionics ) { + if( !i.powered ) { + // Unpowered bionics are protected from power surges. + continue; + } + const auto &info = i.info(); + if( info.shockproof || info.faulty ) { + continue; + } + const auto &bodyparts = info.occupied_bodyparts; + if( bodyparts.find( bp ) != bodyparts.end() ) { + const int bp_hp = hp_cur[bp_to_hp( bp )]; + // The chance to incapacitate is as high as 50% if the attack deals damage equal to one third of the body part's current health. + if( x_in_y( adjusted_damage * 3, bp_hp ) && one_in( 2 ) ) { + if( i.incapacitated_time == 0_turns ) { + add_msg_if_player( m_bad, _( "Your %s bionic shorts out!" ), info.name ); + } + i.incapacitated_time += rng( min_disable_time, 10 * min_disable_time ); + } + } + } + } +} + void Character::reset_bonuses() { // Reset all bonuses to 0 and multipliers to 1.0 @@ -3100,3 +3160,63 @@ float Character::healing_rate_medicine( float at_rest_quality, const body_part b } return rate_medicine; } + +float Character::get_bmi() const +{ + return 12 * get_kcal_percent() + 13; +} + +units::mass Character::bodyweight() const +{ + return units::from_gram( round( get_bmi() * pow( height() / 100, 2 ) ) ); +} + +int Character::height() const +{ + // TODO: Make this a player creation option + return 175; +} + +int Character::get_bmr() const +{ + /** + Values are for males, and average! + */ + const int age = 25; + const int equation_constant = 5; + return ceil( metabolic_rate_base() * activity_level * ( units::to_gram( 10 * bodyweight() ) + + ( 6.25 * height() ) - ( 5 * age ) + equation_constant ) ); +} + +void Character::increase_activity_level( float new_level ) +{ + if( activity_level < new_level ) { + activity_level = new_level; + } +} + +void Character::decrease_activity_level( float new_level ) +{ + if( activity_level > new_level ) { + activity_level = new_level; + } +} +void Character::reset_activity_level() +{ + activity_level = NO_EXERCISE; +} + +std::string Character::activity_level_str() const +{ + if( activity_level <= NO_EXERCISE ) { + return _( "NO_EXERCISE" ); + } else if( activity_level <= LIGHT_EXERCISE ) { + return _( "LIGHT_EXERCISE" ); + } else if( activity_level <= MODERATE_EXERCISE ) { + return _( "MODERATE_EXERCISE" ); + } else if( activity_level <= ACTIVE_EXERCISE ) { + return _( "ACTIVE_EXERCISE" ); + } else { + return _( "EXTRA_EXERCISE" ); + } +} diff --git a/src/character.h b/src/character.h index 7a2fdb482144a..f6f5851f57c9a 100644 --- a/src/character.h +++ b/src/character.h @@ -19,6 +19,7 @@ #include "bodypart.h" #include "calendar.h" #include "creature.h" +#include "game_constants.h" #include "inventory.h" #include "pimpl.h" #include "pldata.h" @@ -28,6 +29,7 @@ #include "enums.h" #include "item.h" #include "optional.h" +#include "stomach.h" #include "string_formatter.h" #include "string_id.h" #include "type_id.h" @@ -255,6 +257,11 @@ class Character : public Creature, public visitable void mod_stat( const std::string &stat, float modifier ) override; + /** Returns either "you" or the player's name */ + std::string disp_name( bool possessive = false ) const override; + /** Returns the name of the player's outer layer, e.g. "armor plates" */ + std::string skin_name() const override; + /* Adjusts provided sight dispersion to account for player stats */ int effective_dispersion( int dispersion ) const; @@ -766,8 +773,35 @@ class Character : public Creature, public visitable pimpl my_bionics; + stomach_contents stomach; + stomach_contents guts; + + void initialize_stomach_contents(); + + /** Stable base metabolic rate due to traits */ + float metabolic_rate_base() const; + // calculates the BMI + float get_bmi() const; + // returns amount of calories burned in a day given various metabolic factors + int get_bmr() const; + // returns the height of the player character in cm + int height() const; + // returns bodyweight of the Character + units::mass bodyweight() const; + // increases the activity level to the next level + // does not decrease activity level + void increase_activity_level( float new_level ); + // decreases the activity level to the previous level + // does not increase activity level + void decrease_activity_level( float new_level ); + // sets activity level to NO_EXERCISE + void reset_activity_level(); + // outputs player activity level to a printable string + std::string activity_level_str() const; + protected: void on_stat_change( const std::string &, int ) override {} + void on_damage_of_type( int adjusted_damage, damage_type type, body_part bp ) override; virtual void on_mutation_gain( const trait_id & ) {} virtual void on_mutation_loss( const trait_id & ) {} public: @@ -805,6 +839,8 @@ class Character : public Creature, public visitable /** How healthy the character is. */ int healthy; int healthy_mod; + // the player's activity level for metabolism calculations + float activity_level = NO_EXERCISE; std::array encumbrance_cache; diff --git a/src/chkjson/chkjson.cpp b/src/chkjson/chkjson.cpp index 543e0a596c5b8..e9b6839eacf53 100644 --- a/src/chkjson/chkjson.cpp +++ b/src/chkjson/chkjson.cpp @@ -20,7 +20,7 @@ #include "json.h" // copypasta: file_finder.cpp -std::vector get_files_from_path(std::string extension, std::string root_path, bool recursive_search, bool match_extension) +static std::vector get_files_from_path(std::string extension, std::string root_path, bool recursive_search, bool match_extension) { std::vector files; const size_t extsz = extension.size(); @@ -90,7 +90,7 @@ std::vector get_files_from_path(std::string extension, std::string } // copypasta: init.cpp -void load_object(JsonObject &jo) +static void load_object(JsonObject &jo) { std::string type = jo.get_string("type"); if ( ! jo.has_string("type") ) @@ -98,7 +98,7 @@ void load_object(JsonObject &jo) jo.throw_error( "JSON object has no type" ); } } -void load_all_from_json(JsonIn &jsin) +static void load_all_from_json(JsonIn &jsin) { char ch; jsin.eat_whitespace(); @@ -141,7 +141,7 @@ void load_all_from_json(JsonIn &jsin) } } -void load_json_dir(const std::string &dirname) +static void load_json_dir(const std::string &dirname) { // get a list of all files in the directory std::vector dir = diff --git a/src/color.cpp b/src/color.cpp index 59353e32ecd55..c368b75dcf3e1 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -675,7 +675,7 @@ void color_manager::clear() } } -void draw_header( const catacurses::window &w ) +static void draw_header( const catacurses::window &w ) { int tmpx = 0; tmpx += shortcut_print( w, 0, tmpx, c_white, c_light_green, diff --git a/src/construction.cpp b/src/construction.cpp index 503483b1ed672..9eabb139eabe8 100644 --- a/src/construction.cpp +++ b/src/construction.cpp @@ -65,7 +65,7 @@ const trap_str_id tr_practice_target( "tr_practice_target" ); namespace construct { // Checks for whether terrain mod can proceed -bool check_nothing( const tripoint & ) +static bool check_nothing( const tripoint & ) { return true; } @@ -77,7 +77,7 @@ bool check_down_OK( const tripoint & ); // tile is empty and you're not on z-10 bool check_no_trap( const tripoint & ); // Special actions to be run post-terrain-mod -void done_nothing( const tripoint & ) {} +static void done_nothing( const tripoint & ) {} void done_trunk_plank( const tripoint & ); void done_grave( const tripoint & ); void done_vehicle( const tripoint & ); @@ -115,7 +115,7 @@ void standardize_construction_times( const int time ) } } -std::vector constructions_by_desc( const std::string &description ) +static std::vector constructions_by_desc( const std::string &description ) { std::vector result; for( auto &constructions_a : constructions ) { @@ -126,9 +126,9 @@ std::vector constructions_by_desc( const std::string &descriptio return result; } -void load_available_constructions( std::vector &available, - std::map> &cat_available, - bool hide_unconstructable ) +static void load_available_constructions( std::vector &available, + std::map> &cat_available, + bool hide_unconstructable ) { cat_available.clear(); available.clear(); @@ -149,7 +149,7 @@ void load_available_constructions( std::vector &available, } } -void draw_grid( const catacurses::window &w, const int list_width ) +static void draw_grid( const catacurses::window &w, const int list_width ) { draw_border( w ); mvwprintz( w, 0, 2, c_light_red, _( " Construction " ) ); @@ -165,7 +165,7 @@ void draw_grid( const catacurses::window &w, const int list_width ) wrefresh( w ); } -nc_color construction_color( const std::string &con_name, bool highlight ) +static nc_color construction_color( const std::string &con_name, bool highlight ) { nc_color col = c_dark_gray; if( g->u.has_trait( trait_id( "DEBUG_HS" ) ) ) { @@ -713,7 +713,7 @@ bool player_can_build( player &p, const inventory &inv, const std::string &desc return false; } -bool character_has_skill_for( const Character &c, const construction &con ) +static bool character_has_skill_for( const Character &c, const construction &con ) { return std::all_of( con.required_skills.begin(), con.required_skills.end(), [&]( const std::pair &pr ) { @@ -745,7 +745,7 @@ bool can_construct( const std::string &desc ) return false; } -bool can_construct( const construction &con, const tripoint &p ) +static bool can_construct( const construction &con, const tripoint &p ) { // see if the special pre-function checks out bool place_okay = con.pre_special( p ); @@ -808,6 +808,7 @@ void place_construction( const std::string &desc ) g->u.pos() + g->u.view_offset ); } wrefresh( g->w_terrain ); + g->draw_panels(); const cata::optional pnt_ = choose_adjacent( _( "Construct where?" ) ); if( !pnt_ ) { @@ -996,7 +997,7 @@ void construct::done_grave( const tripoint &p ) g->m.destroy_furn( p, true ); } -vpart_id vpart_from_item( const std::string &item_id ) +static vpart_id vpart_from_item( const std::string &item_id ) { for( const auto &e : vpart_info::all() ) { const vpart_info &vp = e.second; @@ -1086,7 +1087,7 @@ void construct::done_deconstruct( const tripoint &p ) } } -void unroll_digging( const int numer_of_2x4s ) +static void unroll_digging( const int numer_of_2x4s ) { // refund components! item rope( "rope_30" ); @@ -1276,7 +1277,7 @@ void load_construction( JsonObject &jo ) con.category = jo.get_string( "category", "OTHER" ); // constructions use different time units in json, this makes it compatible // with recipes/requirements, TODO: should be changed in json - con.time = jo.get_int( "time" ) * 1000; + con.time = to_moves( time_duration::from_minutes( jo.get_int( "time" ) ) ); if( jo.has_string( "using" ) ) { con.requirements = requirement_id( jo.get_string( "using" ) ); diff --git a/src/construction.h b/src/construction.h index b123679dff452..6139e3b2049fe 100644 --- a/src/construction.h +++ b/src/construction.h @@ -45,6 +45,8 @@ struct construction { // Index in construction vector size_t id; + + // Time in moves int time; // If true, the requirements are generated during finalization diff --git a/src/consumption.cpp b/src/consumption.cpp index 25fead934996f..3016a822f8cd3 100644 --- a/src/consumption.cpp +++ b/src/consumption.cpp @@ -252,7 +252,7 @@ std::map player::vitamins_from( const itype_id &id ) const } // list of traits the player has that modifies vitamin absorption -std::list mut_vitamin_absorb_modify( const player &p ) +static std::list mut_vitamin_absorb_modify( const player &p ) { std::list traits; for( auto &m : p.get_mutations() ) { @@ -265,7 +265,7 @@ std::list mut_vitamin_absorb_modify( const player &p ) } // is the material associated with this item? -bool material_exists( const material_id &material, const item &item ) +static bool material_exists( const material_id &material, const item &item ) { for( const material_id &mat : item.type->materials ) { if( mat == material ) { @@ -390,7 +390,7 @@ bool player::vitamin_set( const vitamin_id &vit, int qty ) return true; } -float player::metabolic_rate_base() const +float Character::metabolic_rate_base() const { float hunger_rate = get_option< float >( "PLAYER_HUNGER_RATE" ); return hunger_rate * ( 1.0f + mutation_value( "metabolism_modifier" ) ); diff --git a/src/crafting.cpp b/src/crafting.cpp index 26547a5925395..faa6a15974a69 100644 --- a/src/crafting.cpp +++ b/src/crafting.cpp @@ -406,7 +406,7 @@ bool player::check_eligible_containers_for_crafting( const recipe &rec, int batc return true; } -bool is_container_eligible_for_crafting( const item &cont, bool allow_bucket ) +static bool is_container_eligible_for_crafting( const item &cont, bool allow_bucket ) { if( cont.is_watertight_container() || ( allow_bucket && cont.is_bucket() ) ) { return !cont.is_container_full( allow_bucket ); @@ -534,8 +534,8 @@ void player::make_craft_with_command( const recipe_id &id_to_make, int batch_siz // @param offset is the index of the created item in the range [0, batch_size-1], // it makes sure that the used items are distributed equally among the new items. -void set_components( std::list &components, const std::list &used, - const int batch_size, const size_t offset ) +static void set_components( std::list &components, const std::list &used, + const int batch_size, const size_t offset ) { if( batch_size <= 1 ) { components.insert( components.begin(), used.begin(), used.end() ); @@ -1377,7 +1377,7 @@ comp_selection player::select_item_component( const std::vector> &related_recipes, const recipe_subset &available ); -std::string get_cat_name( const std::string &prefixed_name ) +static std::string get_cat_name( const std::string &prefixed_name ) { return prefixed_name.substr( 3, prefixed_name.size() - 3 ); } @@ -95,7 +95,7 @@ void load_recipe_category( JsonObject &jsobj ) } } -std::string get_subcat_name( const std::string &cat, const std::string &prefixed_name ) +static std::string get_subcat_name( const std::string &cat, const std::string &prefixed_name ) { std::string prefix = "CSC_" + get_cat_name( cat ) + "_"; @@ -106,7 +106,7 @@ std::string get_subcat_name( const std::string &cat, const std::string &prefixed return ( prefixed_name == "CSC_ALL" ? _( "ALL" ) : _( "NONCRAFT" ) ); } -void translate_all() +static void translate_all() { for( const auto &cat : craft_cat_list ) { normalized_names[cat] = _( get_cat_name( cat ) ); @@ -123,8 +123,8 @@ void reset_recipe_categories() craft_subcat_list.clear(); } -int print_items( const recipe &r, const catacurses::window &w, int ypos, int xpos, nc_color col, - int batch ) +static int print_items( const recipe &r, const catacurses::window &w, int ypos, int xpos, + nc_color col, int batch ) { if( !r.has_byproducts() ) { return 0; diff --git a/src/creature.cpp b/src/creature.cpp index 37e601a8479c6..3f12c81b72b0e 100644 --- a/src/creature.cpp +++ b/src/creature.cpp @@ -276,7 +276,8 @@ bool Creature::sees( const tripoint &t, bool is_player, int range_mod ) const // Helper function to check if potential area of effect of a weapon overlaps vehicle // Maybe TODO: If this is too slow, precalculate a bounding box and clip the tested area to it -bool overlaps_vehicle( const std::set &veh_area, const tripoint &pos, const int area ) +static bool overlaps_vehicle( const std::set &veh_area, const tripoint &pos, + const int area ) { tripoint tmp = pos; int &x = tmp.x; @@ -435,7 +436,7 @@ Creature *Creature::auto_find_hostile_target( int range, int &boo_hoo, int area * Damage-related functions */ -int size_melee_penalty( m_size target_size ) +static int size_melee_penalty( m_size target_size ) { switch( target_size ) { case MS_TINY: @@ -822,6 +823,8 @@ void Creature::deal_damage_handle_type( const damage_unit &du, body_part bp, int break; } + on_damage_of_type( adjusted_damage, du.type, bp ); + damage += adjusted_damage; pain += roll_remainder( adjusted_damage / div ); } diff --git a/src/creature.h b/src/creature.h index 87ccde3411c49..58c4b71489bf4 100644 --- a/src/creature.h +++ b/src/creature.h @@ -667,6 +667,7 @@ class Creature protected: virtual void on_stat_change( const std::string &, int ) {} virtual void on_effect_int_change( const efftype_id &, int, body_part ) {} + virtual void on_damage_of_type( int, damage_type, body_part ) {} public: body_part select_body_part( Creature *source, int hit_roll ) const; diff --git a/src/cursesport.h b/src/cursesport.h index b168f5e3105c4..5d4ca571bca96 100644 --- a/src/cursesport.h +++ b/src/cursesport.h @@ -26,10 +26,10 @@ namespace cata_cursesport using base_color = catacurses::base_color; //a pair of colors[] indexes, foreground and background -typedef struct { +struct pairs { base_color FG; base_color BG; -} pairs; +}; //Individual lines, so that we can track changed lines struct cursecell { diff --git a/src/damage.cpp b/src/damage.cpp index 17b8b1a3c7e02..74e2eda4da19c 100644 --- a/src/damage.cpp +++ b/src/damage.cpp @@ -274,7 +274,7 @@ const skill_id &skill_by_dt( damage_type dt ) } } -damage_unit load_damage_unit( JsonObject &curr ) +static damage_unit load_damage_unit( JsonObject &curr ) { damage_type dt = dt_by_name( curr.get_string( "damage_type" ) ); if( dt == DT_NULL ) { diff --git a/src/debug.cpp b/src/debug.cpp index 600e5541ae6e7..04a744f51b51c 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,8 @@ #include #include #include +#include +#include #include "cursesdef.h" #include "filesystem.h" @@ -59,6 +62,11 @@ # endif #endif // TILES +#if defined(__ANDROID__) +// used by android_version() function for __system_property_get(). +#include +#endif + // Static defines {{{1 // --------------------------------------------------------------------- @@ -263,7 +271,7 @@ struct time_info { }; #if defined(_MSC_VER) -time_info get_time() noexcept +static time_info get_time() noexcept { SYSTEMTIME time {}; @@ -274,7 +282,7 @@ time_info get_time() noexcept }; } #else -time_info get_time() noexcept +static time_info get_time() noexcept { timeval tv; gettimeofday( &tv, nullptr ); @@ -419,7 +427,7 @@ void deinitDebug() // OStream Operators {{{2 // --------------------------------------------------------------------- -std::ostream &operator<<( std::ostream &out, DebugLevel lev ) +static std::ostream &operator<<( std::ostream &out, DebugLevel lev ) { if( lev != DL_ALL ) { if( lev & D_INFO ) { @@ -438,7 +446,7 @@ std::ostream &operator<<( std::ostream &out, DebugLevel lev ) return out; } -std::ostream &operator<<( std::ostream &out, DebugClass cl ) +static std::ostream &operator<<( std::ostream &out, DebugClass cl ) { if( cl != DC_ALL ) { if( cl & D_MAIN ) { @@ -464,9 +472,10 @@ std::ostream &operator<<( std::ostream &out, DebugClass cl ) } #if defined(BACKTRACE) +#if !defined(_WIN32) // Verify that a string is safe for passing as an argument to addr2line. // In particular, we want to avoid any characters of significance to the shell. -bool debug_is_safe_string( const char *start, const char *finish ) +static bool debug_is_safe_string( const char *start, const char *finish ) { static constexpr char safe_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" @@ -481,8 +490,7 @@ bool debug_is_safe_string( const char *start, const char *finish ) return std::all_of( start, finish, is_safe_char ); } -#if !defined(_WIN32) -std::string debug_resolve_binary( const std::string &binary, std::ostream &out ) +static std::string debug_resolve_binary( const std::string &binary, std::ostream &out ) { if( binary.find( '/' ) != std::string::npos ) { // The easy case, where we have a path to the binary @@ -515,7 +523,7 @@ std::string debug_resolve_binary( const std::string &binary, std::ostream &out ) return binary; } -cata::optional debug_compute_load_offset( +static cata::optional debug_compute_load_offset( const std::string &binary, const std::string &symbol, const std::string &offset_within_symbol_s, void *address, std::ostream &out ) { @@ -788,7 +796,7 @@ std::string game_info::operating_system() return "Windows"; #elif defined(__linux__) return "Linux"; -#elif defined(unix) || defined(__unix__) || defined(__unix) || defined(__APPLE__) && defined(__MACH__) // unix; BSD; MacOs +#elif defined(unix) || defined(__unix__) || defined(__unix) || ( defined(__APPLE__) && defined(__MACH__) ) // unix; BSD; MacOs #if defined(__APPLE__) && defined(__MACH__) // The following include is **only** needed for the TARGET_xxx defines below and is only included if both of the above defines are true. // The whole function only relying on compiler defines, it is probably more meaningful to include it here and not mingle with the @@ -804,7 +812,7 @@ std::string game_info::operating_system() /* OSX */ return "MacOs"; #endif // TARGET_IPHONE_SIMULATOR -#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +#elif defined(BSD) // defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) return "BSD"; #else return "Unix"; @@ -814,6 +822,236 @@ std::string game_info::operating_system() #endif } +#if defined (__linux__) || defined(unix) || defined(__unix__) || defined(__unix) || ( defined(__APPLE__) && defined(__MACH__) ) || defined(BSD) // linux; unix; MacOs; BSD +/** Execute a command with the shell by using `popen()`. + * @param command The full command to execute. + * @note The output buffer is limited to 512 characters. + * @returns The result of the command (only stdout) or an empty string if there was a problem. + */ +static std::string shell_exec( const std::string &command ) +{ + std::vector buffer( 512 ); + std::string output; + try { + std::unique_ptr pipe( popen( command.c_str(), "r" ), pclose ); + if( pipe ) { + while( fgets( buffer.data(), buffer.size(), pipe.get() ) != nullptr ) { + output += buffer.data(); + } + } + } catch( ... ) { + output = ""; + } + return output; +} +#endif + +#if defined (__ANDROID__) +/** Get a precise version number for Android systems. + * @note see: + * - https://stackoverflow.com/a/19777977/507028 + * - https://github.com/pytorch/cpuinfo/blob/master/test/build.prop/galaxy-s7-us.log + * @returns If successful, a string containing the Android system version, otherwise an empty string. + */ +static std::string android_version() +{ + std::string output; + + // buffer used for the __system_property_get() function. + // note: according to android sources, it can't be greater than 92 chars (see 'PROP_VALUE_MAX' define in system_properties.h) + std::vector buffer( 255 ); + + static const std::vector> system_properties = { + // The manufacturer of the product/hardware; e.g. "Samsung", this is different than the carrier. + { "ro.product.manufacturer", "Manufacturer" }, + // The end-user-visible name for the end product; .e.g. "SAMSUNG-SM-G930A" for a Samsung S7. + { "ro.product.model", "Model" }, + // The Android system version; e.g. "6.0.1" + { "ro.build.version.release", "Release" }, + // The internal value used by the underlying source control to represent this build; e.g "G930AUCS4APK1" for a Samsung S7 on 6.0.1. + { "ro.build.version.incremental", "Incremental" }, + }; + + for( const auto &entry : system_properties ) { + int len = __system_property_get( entry.first.c_str(), &buffer[0] ); + std::string value; + if( len <= 0 ) { + // failed to get the property + value = ""; + } else { + value = std::string( buffer.begin(), buffer.end() ); + } + output.append( string_format( "%s: %s; ", entry.second, value ) ); + } + return output; +} + +#elif defined(BSD) + +/** Get a precise version number for BSD systems. + * @note The code shells-out to call `uname -a`. + * @returns If successful, a string containing the Linux system version, otherwise an empty string. + */ +static std::string bsd_version() +{ + std::string output; + output = shell_exec( "uname -a" ); + if( !output.empty() ) { + // remove trailing '\n', if any. + output.erase( std::remove( output.begin(), output.end(), '\n' ), + output.end() ); + } + return output; +} + +#elif defined(__linux__) + +/** Get a precise version number for Linux systems. + * @note The code shells-out to call `lsb_release -a`. + * @returns If successful, a string containing the Linux system version, otherwise an empty string. + */ +static std::string linux_version() +{ + std::string output; + output = shell_exec( "lsb_release -a" ); + if( !output.empty() ) { + // replace '\n' and '\t' in output. + static const std::vector> to_replace = { + {"\n", "; "}, + {"\t", " "}, + }; + for( const auto &e : to_replace ) { + std::string::size_type pos; + while( ( pos = output.find( e.first ) ) != std::string::npos ) { + output.replace( pos, e.first.length(), e.second ); + } + } + } + return output; +} + +#elif defined(__APPLE__) && defined(__MACH__) && !defined(BSD) + +/** Get a precise version number for MacOs systems. + * @note The code shells-out to call `sw_vers` with various options. + * @returns If successful, a string containing the MacOS system version, otherwise an empty string. + */ +static std::string mac_os_version() +{ + std::string output; + static const std::vector> commands = { + { "sw_vers -productName", "Name" }, + { "sw_vers -productVersion", "Version" }, + { "sw_vers -buildVersion", "Build" }, + }; + + for( const auto &entry : commands ) { + std::string command_result = shell_exec( entry.first ); + if( command_result.empty() ) { + command_result = ""; + } else { + // remove trailing '\n', if any. + command_result.erase( std::remove( command_result.begin(), command_result.end(), '\n' ), + command_result.end() ); + } + output.append( string_format( "%s: %s; ", entry.second, command_result ) ); + } + return output; +} + +#elif defined (_WIN32) + +/** Get a precise version number for Windows systems. + * @note Since Windows 10 all version-related APIs lie about the underlying system if the application is not Manifested (see VerifyVersionInfoA + * or GetVersionEx documentation for further explanation). In this function we use the registry or the native RtlGetVersion which both + * report correct versions and are compatible down to XP. + * @returns If successful, a string containing the Windows system version number, otherwise an empty string. + */ +static std::string windows_version() +{ + std::string output; + HKEY handle_key; + bool success = RegOpenKeyExA( HKEY_LOCAL_MACHINE, R"(SOFTWARE\Microsoft\Windows NT\CurrentVersion)", + 0, + KEY_QUERY_VALUE, &handle_key ) == ERROR_SUCCESS; + if( success ) { + DWORD value_type; + constexpr DWORD c_buffer_size = 512; + std::vector byte_buffer( c_buffer_size ); + DWORD buffer_size = c_buffer_size; + DWORD major_version = 0; + success = RegQueryValueExA( handle_key, "CurrentMajorVersionNumber", nullptr, &value_type, + &byte_buffer[0], &buffer_size ) == ERROR_SUCCESS && value_type == REG_DWORD; + if( success ) { + major_version = *reinterpret_cast( &byte_buffer[0] ); + output.append( std::to_string( major_version ) ); + } + if( success ) { + buffer_size = c_buffer_size; + success = RegQueryValueExA( handle_key, "CurrentMinorVersionNumber", nullptr, &value_type, + &byte_buffer[0], &buffer_size ) == ERROR_SUCCESS && value_type == REG_DWORD; + if( success ) { + const DWORD minor_version = *reinterpret_cast( &byte_buffer[0] ); + output.append( "." ); + output.append( std::to_string( minor_version ) ); + } + } + if( success && major_version == 10 ) { + buffer_size = c_buffer_size; + success = RegQueryValueExA( handle_key, "ReleaseId", nullptr, &value_type, &byte_buffer[0], + &buffer_size ) == ERROR_SUCCESS && value_type == REG_SZ; + if( success ) { + output.append( " " ); + output.append( std::string( byte_buffer.begin(), byte_buffer.end() ) ); + } + } + + RegCloseKey( handle_key ); + } + + if( !success ) { + output = ""; + using RtlGetVersion = LONG( WINAPI * )( PRTL_OSVERSIONINFOW ); + const HMODULE handle_ntdll = GetModuleHandleA( "ntdll" ); + if( handle_ntdll != nullptr ) { + // Use union-based type-punning to convert function pointer + // type without gcc warnings. + union { + RtlGetVersion p; + FARPROC q; + } rtl_get_version_func; + rtl_get_version_func.q = GetProcAddress( handle_ntdll, "RtlGetVersion" ); + if( rtl_get_version_func.p != nullptr ) { + RTL_OSVERSIONINFOW os_version_info = RTL_OSVERSIONINFOW(); + os_version_info.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW ); + if( rtl_get_version_func.p( &os_version_info ) == 0 ) { // NT_STATUS_SUCCESS = 0 + output.append( string_format( "%i.%i %i", os_version_info.dwMajorVersion, + os_version_info.dwMinorVersion, os_version_info.dwBuildNumber ) ); + } + } + } + } + return output; +} +#endif // Various OS define tests + +std::string game_info::operating_system_version() +{ +#if defined(__ANDROID__) + return android_version(); +#elif defined(BSD) + return bsd_version(); +#elif defined(__linux__) + return linux_version(); +#elif defined(__APPLE__) && defined(__MACH__) && !defined(BSD) + return mac_os_version(); +#elif defined(_WIN32) + return windows_version(); +#else + return ""; +#endif +} + std::string game_info::bitness() { if( sizeof( void * ) == 8 ) { @@ -865,9 +1103,14 @@ std::string game_info::mods_loaded() std::string game_info::game_report() { + std::string os_version = operating_system_version(); + if( os_version.empty() ) { + os_version = ""; + } std::stringstream report; report << "- OS: " << operating_system() << " [" << bitness() << "]\n" << + " - OS Version: " << os_version << "\n" << "- Game Version: " << game_version() << "\n" << "- Graphics Version: " << graphics_version() << "\n" << "- Mods loaded: [\n " << mods_loaded() << "\n]\n"; diff --git a/src/debug.h b/src/debug.h index 2df1a85b77c90..2da05a4520fd6 100644 --- a/src/debug.h +++ b/src/debug.h @@ -87,6 +87,9 @@ namespace game_info /** Return the name of the current operating system. */ std::string operating_system(); +/** Return a detailed version of the operating system; e.g. "Ubuntu 18.04" or "(Windows) 10 1809". + */ +std::string operating_system_version(); /** Return the "bitness" of the game (not necessarily of the operating system); either: 64-bit, 32-bit or Unknown. */ std::string bitness(); diff --git a/src/debug_menu.cpp b/src/debug_menu.cpp index 7f63db8b89c2b..e2507d00762f6 100644 --- a/src/debug_menu.cpp +++ b/src/debug_menu.cpp @@ -716,7 +716,7 @@ void character_edit_menu() } } -const std::string &mission_status_string( mission::mission_status status ) +static const std::string &mission_status_string( mission::mission_status status ) { static const std::map desc{ { { mission::mission_status::yet_to_start, _( "Yet to start" ) }, @@ -748,7 +748,7 @@ std::string mission_debug::describe( const mission &m ) return data.str(); } -void add_header( uilist &mmenu, const std::string &str ) +static void add_header( uilist &mmenu, const std::string &str ) { if( !mmenu.entries.empty() ) { mmenu.addentry( -1, false, -1, "" ); @@ -828,7 +828,7 @@ void mission_debug::edit_player() edit_mission( *all_missions[mmenu.ret] ); } -bool remove_from_vec( std::vector &vec, mission *m ) +static bool remove_from_vec( std::vector &vec, mission *m ) { auto iter = std::remove( vec.begin(), vec.end(), m ); bool ret = iter != vec.end(); @@ -968,6 +968,7 @@ void debug() temp->mission = NPC_MISSION_NULL; temp->add_new_mission( mission::reserve_random( ORIGIN_ANY_NPC, temp->global_omt_location(), temp->getID() ) ); + temp->set_fac( faction_id( "wasteland_scavengers" ) ); g->load_npcs(); } break; diff --git a/src/descriptions.cpp b/src/descriptions.cpp index 1157695779927..2cdb0dfe90425 100644 --- a/src/descriptions.cpp +++ b/src/descriptions.cpp @@ -27,7 +27,7 @@ enum class description_target : int { terrain }; -const Creature *seen_critter( const game &g, const tripoint &p ) +static const Creature *seen_critter( const game &g, const tripoint &p ) { const Creature *critter = g.critter_at( p, true ); if( critter != nullptr && g.u.sees( *critter ) ) { diff --git a/src/dialogue.h b/src/dialogue.h index b2e7022fefea3..11ceaeb105d0f 100644 --- a/src/dialogue.h +++ b/src/dialogue.h @@ -434,6 +434,7 @@ struct conditional_t { void set_has_weapon( bool is_npc = false ); void set_is_driving( bool is_npc = false ); void set_is_day(); + void set_has_stolen_item( bool is_npc = false ); void set_is_outside(); void set_is_by_radio(); void set_u_has_camp(); diff --git a/src/editmap.cpp b/src/editmap.cpp index b9ee808c31203..d43f0322995d0 100644 --- a/src/editmap.cpp +++ b/src/editmap.cpp @@ -68,7 +68,7 @@ static const ter_id undefined_ter_id( -1 ); static const furn_id undefined_furn_id( -1 ); static const trap_id undefined_trap_id( -1 ); -std::vector fld_string( const std::string &str, int width ) +static std::vector fld_string( const std::string &str, int width ) { std::vector lines; if( width < 1 ) { @@ -697,7 +697,7 @@ void editmap::update_view( bool update_info ) } -ter_id get_alt_ter( bool isvert, ter_id sel_ter ) +static ter_id get_alt_ter( bool isvert, ter_id sel_ter ) { std::map alts; alts["_v"] = "_h"; @@ -1483,7 +1483,7 @@ tripoint editmap::recalc_target( shapetype shape ) * If the result is not >= min and < 'max', constrain the result and adjust 'shift', * so it can adjust subsequent points of a set consistently. */ -int limited_shift( int var, int &shift, int min, int max ) +static int limited_shift( int var, int &shift, int min, int max ) { if( var + shift < min ) { shift = min - var; diff --git a/src/faction_camp.cpp b/src/faction_camp.cpp index 79d9647d53d93..0cb0f20fdf26d 100644 --- a/src/faction_camp.cpp +++ b/src/faction_camp.cpp @@ -300,6 +300,7 @@ int om_harvest_ter_break( npc &comp, const tripoint &omt_tgt, const ter_id &t, i /// @ref take, whether you take the item or count it mass_volume om_harvest_itm( npc_ptr comp, const tripoint &omt_tgt, int chance = 100, bool take = true ); +void apply_camp_ownership( const tripoint camp_pos, int radius ); /* * Counts or cuts trees into trunks and trunks into logs * @param omt_tgt the targeted OM tile @@ -1346,7 +1347,7 @@ bool basecamp::handle_mission( const std::string &miss_id, const std::string &mi g->draw_ter(); wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); return true; } @@ -3520,6 +3521,7 @@ void basecamp::place_results( item result, bool by_radio ) target_bay.load( omt_pos.x * 2, omt_pos.y * 2, omt_pos.z, false ); const tripoint &new_spot = target_bay.getlocal( get_dumping_spot() ); target_bay.add_item_or_charges( new_spot, result, true ); + apply_camp_ownership( new_spot, 10 ); target_bay.save(); } else { auto &mgr = zone_manager::get_manager(); @@ -3534,11 +3536,25 @@ void basecamp::place_results( item result, bool by_radio ) for( auto &src : src_sorted ) { const auto &src_loc = g->m.getlocal( src ); g->m.add_item_or_charges( src_loc, result, true ); + apply_camp_ownership( src_loc, 10 ); break; } //or dump them at players feet } else { g->m.add_item_or_charges( g->u.pos(), result, true ); + apply_camp_ownership( g->u.pos(), 0 ); + } + } +} + +void apply_camp_ownership( const tripoint camp_pos, int radius ) +{ + for( const tripoint &p : g->m.points_in_rectangle( tripoint( camp_pos.x - radius, + camp_pos.y - radius, camp_pos.z ), tripoint( camp_pos.x + radius, camp_pos.y + radius, + camp_pos.z ) ) ) { + auto items = g->m.i_at( p.x, p.y ); + for( item &elem : items ) { + elem.set_owner( g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ); } } } diff --git a/src/field.cpp b/src/field.cpp index 776a893d0f78f..25f59fa3f7f43 100644 --- a/src/field.cpp +++ b/src/field.cpp @@ -566,7 +566,7 @@ bool ter_furn_has_flag( const ter_t &ter, const furn_t &furn, const ter_bitflags return ter.has_flag( flag ) || furn.has_flag( flag ); } -int ter_furn_movecost( const ter_t &ter, const furn_t &furn ) +static int ter_furn_movecost( const ter_t &ter, const furn_t &furn ) { if( ter.movecost == 0 ) { return 0; @@ -591,11 +591,6 @@ static const std::array eight_horizontal_neighbors = { { } }; -bool at_edge( const size_t x, const size_t y ) -{ - return x == 0 || x == SEEX || y == 0 || y == SEEY; -} - /* Function: process_fields_in_submap Iterates over every field on every tile of the given submap given as parameter. diff --git a/src/game.cpp b/src/game.cpp index cae01567cacce..afd1593d8defc 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -802,7 +802,9 @@ bool game::start_game() } } } - + for( auto &e : u.inv_dump() ) { + e->set_owner( g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ); + } // Now that we're done handling coordinates, ensure the player's submap is in the center of the map update_map( u ); // Profession pets @@ -1599,7 +1601,7 @@ void game::cancel_activity() u.cancel_activity(); } -bool cancel_auto_move( player &p, const std::string &text ) +static bool cancel_auto_move( player &p, const std::string &text ) { if( p.has_destination() ) { add_msg( m_warning, _( "%s. Auto-move canceled" ), text ); @@ -1800,7 +1802,7 @@ void game::remove_npc_follower( const int &id ) u.follower_ids.erase( id ); } -void update_faction_api( npc *guy ) +static void update_faction_api( npc *guy ) { if( guy->get_faction_ver() < 2 ) { guy->set_fac( your_followers ); @@ -2604,7 +2606,9 @@ void game::load( const save_t &name ) validate_npc_followers(); validate_camps(); update_map( u ); - + for( auto &e : u.inv_dump() ) { + e->set_owner( g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ); + } // legacy, needs to be here as we access the map. if( u.getID() == 0 || u.getID() == -1 ) { // player does not have a real id, so assign a new one, @@ -3135,16 +3139,19 @@ void game::draw() draw_ter(); wrefresh( w_terrain ); - draw_panels(); + draw_panels( true ); } -void game::draw_panels() +void game::draw_panels( bool force_draw ) { - draw_panels( 0, 1 ); + draw_panels( 0, 1, force_draw ); } -void game::draw_panels( size_t column, size_t index ) +void game::draw_panels( size_t column, size_t index, bool force_draw ) { + static int previous_turn = -1; + const int current_turn = calendar::turn; + const bool draw_this_turn = current_turn > previous_turn || force_draw; auto &mgr = panel_manager::get_manager(); int y = 0; const bool sidebar_right = get_option( "SIDEBAR_POSITION" ) == "right"; @@ -3164,8 +3171,10 @@ void game::draw_panels( size_t column, size_t index ) } h += spacer; if( panel.toggle && h > 0 ) { - panel.draw( u, catacurses::newwin( h, panel.get_width(), y, - sidebar_right ? TERMX - panel.get_width() : 0 ) ); + if( panel.always_draw || draw_this_turn ) { + panel.draw( u, catacurses::newwin( h, panel.get_width(), y, + sidebar_right ? TERMX - panel.get_width() : 0 ) ); + } if( show_panel_adm ) { auto label = catacurses::newwin( 1, panel.get_name().length(), y, sidebar_right ? TERMX - panel.get_width() - panel.get_name().length() - 1 : panel.get_width() + 1 ); @@ -3192,6 +3201,7 @@ void game::draw_panels( size_t column, size_t index ) if( show_panel_adm ) { mgr.draw_adm( w_panel_adm, column, index ); } + previous_turn = current_turn; } void game::draw_pixel_minimap( const catacurses::window &w ) @@ -5315,12 +5325,12 @@ void game::examine() // redraw terrain to erase 'examine' window draw_ter(); wrefresh( w_terrain ); - draw_panels(); + draw_panels( true ); examine( *examp_ ); u.manual_examine = false; } -const std::string get_fire_fuel_string( const tripoint &examp ) +static const std::string get_fire_fuel_string( const tripoint &examp ) { if( g->m.has_flag( TFLAG_FIRE_CONTAINER, examp ) ) { field_entry *fire = g->m.get_field( examp, fd_fire ); @@ -5429,7 +5439,7 @@ void game::examine( const tripoint &examp ) iexamine::trap( u, examp ); draw_ter(); wrefresh( w_terrain ); - draw_panels(); + draw_panels( true ); } // In case of teleport trap or somesuch @@ -5537,6 +5547,7 @@ void game::peek() draw_ter(); } wrefresh( w_terrain ); + draw_panels(); return; } @@ -6160,7 +6171,7 @@ void game::zones_manager() draw_ter(); wrefresh( w_terrain ); - draw_panels(); + draw_panels( true ); } blink = false; stuff_changed = true; @@ -6371,6 +6382,7 @@ void game::zones_manager() wrefresh( w_terrain ); zones_manager_draw_borders( w_zones_border, w_zones_info_border, zone_ui_height, width ); zones_manager_shortcuts( w_zones_info ); + draw_panels(); wrefresh( w_zones ); wrefresh( w_zones_border ); @@ -6556,8 +6568,9 @@ look_around_result game::look_around( catacurses::window w_info, tripoint ¢e //Draw select cursor g->draw_cursor( lp ); - // redraw order: terrain, look_around panel + // redraw order: terrain, panels, look_around panel wrefresh( w_terrain ); + draw_panels(); wrefresh( w_info ); } @@ -6778,7 +6791,7 @@ void game::draw_trail_to_square( const tripoint &t, bool bDrawX ) wrefresh( w_terrain ); } -void centerlistview( const tripoint &active_item_position ) +static void centerlistview( const tripoint &active_item_position ) { player &u = g->u; if( get_option( "SHIFT_LIST_ITEM_VIEW" ) != "false" ) { @@ -7203,7 +7216,6 @@ game::vmenu_ret game::list_items( const std::vector &item_list ) if( action == "HELP_KEYBINDINGS" ) { draw_ter(); wrefresh( w_terrain ); - draw_panels(); } else if( action == "UP" ) { do { iActive--; @@ -7436,7 +7448,6 @@ game::vmenu_ret game::list_monsters( const std::vector &monster_list if( action == "HELP_KEYBINDINGS" ) { draw_ter(); wrefresh( w_terrain ); - draw_panels(); } else if( action == "UP" ) { iActive--; if( iActive < 0 ) { @@ -7650,23 +7661,6 @@ game::vmenu_ret game::list_monsters( const std::vector &monster_list return game::vmenu_ret::QUIT; } -std::vector nearby_vehicles_for( const itype_id &ft ) -{ - std::vector result; - for( auto &&p : g->m.points_in_radius( g->u.pos(), 1 ) ) { // *NOPAD* - vehicle *const veh = veh_pointer_or_null( g->m.veh_at( p ) ); - // TODO: constify fuel_left and fuel_capacity - // TODO: add a fuel_capacity_left function - if( std::find( result.begin(), result.end(), veh ) != result.end() ) { - continue; - } - if( veh != nullptr && veh->fuel_left( ft ) < veh->fuel_capacity( ft ) ) { - result.push_back( veh ); - } - } - return result; -} - void game::drop() { u.drop( game_menus::inv::multidrop( u ), u.pos() ); @@ -7942,6 +7936,7 @@ bool game::plfire() } draw_ter(); // Recenter our view wrefresh( w_terrain ); + draw_panels(); int shots = 0; @@ -7983,7 +7978,7 @@ bool game::plfire( item &weapon, int bp_cost ) } // Used to set up the first Hotkey in the display set -int get_initial_hotkey( const size_t menu_index ) +static int get_initial_hotkey( const size_t menu_index ) { int hotkey = -1; if( menu_index == 0 ) { @@ -8000,8 +7995,8 @@ int get_initial_hotkey( const size_t menu_index ) // Pair.second is the number of equivalent items per unique tname // There are options for optimization here, but the function is hit infrequently // enough that optimizing now is not a useful time expenditure. -const std::vector> generate_butcher_stack_display( - map_stack &items, const std::vector &indices ) +static const std::vector> generate_butcher_stack_display( + map_stack &items, const std::vector &indices ) { std::vector> result; std::vector result_strings; @@ -8037,8 +8032,8 @@ const std::vector> generate_butcher_stack_display( // Corpses are always individual items // Just add them individually to the menu -void add_corpses( uilist &menu, map_stack &items, - const std::vector &indices, size_t &menu_index ) +static void add_corpses( uilist &menu, map_stack &items, + const std::vector &indices, size_t &menu_index ) { int hotkey = get_initial_hotkey( menu_index ); @@ -8050,9 +8045,9 @@ void add_corpses( uilist &menu, map_stack &items, } // Salvagables stack so we need to pass in a stack vector rather than an item index vector -void add_salvagables( uilist &menu, map_stack &items, - const std::vector> &stacks, size_t &menu_index, - const salvage_actor &salvage_iuse ) +static void add_salvagables( uilist &menu, map_stack &items, + const std::vector> &stacks, size_t &menu_index, + const salvage_actor &salvage_iuse ) { if( !stacks.empty() ) { int hotkey = get_initial_hotkey( menu_index ); @@ -8071,8 +8066,8 @@ void add_salvagables( uilist &menu, map_stack &items, } // Disassemblables stack so we need to pass in a stack vector rather than an item index vector -void add_disassemblables( uilist &menu, map_stack &items, - const std::vector> &stacks, size_t &menu_index ) +static void add_disassemblables( uilist &menu, map_stack &items, + const std::vector> &stacks, size_t &menu_index ) { if( !stacks.empty() ) { int hotkey = get_initial_hotkey( menu_index ); @@ -8092,7 +8087,7 @@ void add_disassemblables( uilist &menu, map_stack &items, } // Butchery sub-menu and time calculation -void butcher_submenu( map_stack &items, const std::vector &corpses, int corpse = -1 ) +static void butcher_submenu( map_stack &items, const std::vector &corpses, int corpse = -1 ) { auto cut_time = [&]( enum butcher_type bt ) { int time_to_cut = 0; @@ -8390,7 +8385,7 @@ void game::butcher() butcher_submenu( items, corpses, indexer_index ); draw_ter(); wrefresh( w_terrain ); - draw_panels(); + draw_panels( true ); u.activity.values.push_back( corpses[indexer_index] ); } break; @@ -10207,7 +10202,7 @@ void game::plswim( const tripoint &p ) u.drench( 100, drenchFlags, true ); } -float rate_critter( const Creature &c ) +static float rate_critter( const Creature &c ) { const npc *np = dynamic_cast( &c ); if( np != nullptr ) { @@ -10383,7 +10378,7 @@ void game::fling_creature( Creature *c, const int &dir, float flvel, bool contro } } -cata::optional point_selection_menu( const std::vector &pts ) +static cata::optional point_selection_menu( const std::vector &pts ) { if( pts.empty() ) { debugmsg( "point_selection_menu called with empty point set" ); @@ -11442,6 +11437,7 @@ void game::display_scent() draw_ter(); scent.draw( w_terrain, div * 2, u.pos() + u.view_offset ); wrefresh( w_terrain ); + draw_panels(); inp_mngr.wait_for_any_key(); } } diff --git a/src/game.h b/src/game.h index 7efd2b488ca4d..1ebe28198fdf9 100644 --- a/src/game.h +++ b/src/game.h @@ -97,7 +97,7 @@ class map_item_stack; struct WORLD; class save_t; -typedef WORLD *WORLDPTR; +using WORLDPTR = WORLD *; class overmap; class event_manager; @@ -111,7 +111,7 @@ struct visibility_variables; class scent_map; class loading_ui; -typedef std::function item_filter; +using item_filter = std::function; enum peek_act : int { PA_BLIND_THROW @@ -215,8 +215,13 @@ class game void draw(); void draw_ter( bool draw_sounds = true ); void draw_ter( const tripoint ¢er, bool looking = false, bool draw_sounds = true ); - void draw_panels(); - void draw_panels( size_t column, size_t index ); + + // when force_redraw is true, redraw all panel instead of just animated panels + // mostly used after UI updates + void draw_panels( bool force_draw = false ); + // when force_redraw is true, redraw all panel instead of just animated panels + // mostly used after UI updates + void draw_panels( size_t column, size_t index, bool force_draw = false ); /** * Returns the location where the indicator should go relative to the reality bubble, * or nothing to indicate no indicator should be drawn. diff --git a/src/game_inventory.cpp b/src/game_inventory.cpp index e6c08d74b53ce..0eace79f72557 100644 --- a/src/game_inventory.cpp +++ b/src/game_inventory.cpp @@ -52,8 +52,8 @@ static const trait_id trait_NOPAIN( "NOPAIN" ); class Character; -typedef std::function item_filter; -typedef std::function item_location_filter; +using item_filter = std::function; +using item_location_filter = std::function; namespace { @@ -89,7 +89,7 @@ bool inventory_filter_preset::is_shown( const item_location &location ) const return filter( location ); } -item_location_filter convert_filter( const item_filter &filter ) +static item_location_filter convert_filter( const item_filter &filter ) { return [ &filter ]( const item_location & loc ) { return filter( *loc ); diff --git a/src/game_inventory.h b/src/game_inventory.h index bd1f61bf3b37d..8e5174a3d8042 100644 --- a/src/game_inventory.h +++ b/src/game_inventory.h @@ -21,7 +21,7 @@ class player; class salvage_actor; class repair_item_actor; -typedef std::function item_location_filter; +using item_location_filter = std::function; class inventory_filter_preset : public inventory_selector_preset { diff --git a/src/handle_action.cpp b/src/handle_action.cpp index 739ceb0cfa6fd..d6f167e1a98f7 100644 --- a/src/handle_action.cpp +++ b/src/handle_action.cpp @@ -301,6 +301,7 @@ input_context game::get_player_input( std::string &action ) } wrefresh( w_terrain ); + g->draw_panels(); if( uquit == QUIT_WATCH ) { @@ -687,7 +688,7 @@ static void smash() } } -bool try_set_alarm() +static bool try_set_alarm() { uilist as_m; const bool already_set = g->u.has_effect( effect_alarm_clock ); @@ -1090,6 +1091,7 @@ static void reach_attack( int range, player &u ) } g->draw_ter(); wrefresh( g->w_terrain ); + g->draw_panels(); g->reenter_fullscreen(); } diff --git a/src/harvest.h b/src/harvest.h index 9c568d1e0d667..3e4cf12c94972 100644 --- a/src/harvest.h +++ b/src/harvest.h @@ -11,7 +11,7 @@ #include "string_id.h" #include "type_id.h" -typedef std::string itype_id; +using itype_id = std::string; class JsonObject; // Could be reused for butchery diff --git a/src/iexamine.cpp b/src/iexamine.cpp index ebe22251b6b6b..508731b9835b6 100644 --- a/src/iexamine.cpp +++ b/src/iexamine.cpp @@ -1406,7 +1406,7 @@ void iexamine::fswitch( player &p, const tripoint &examp ) /** * If it's winter: show msg and return true. Otherwise return false */ -bool dead_plant( bool flower, player &p, const tripoint &examp ) +static bool dead_plant( bool flower, player &p, const tripoint &examp ) { if( season_of_year( calendar::turn ) == WINTER ) { if( flower ) { @@ -1425,7 +1425,7 @@ bool dead_plant( bool flower, player &p, const tripoint &examp ) /** * Helper method to see if player has traits, hunger and mouthwear for drinking nectar. */ -bool can_drink_nectar( const player &p ) +static bool can_drink_nectar( const player &p ) { return ( p.has_active_mutation( trait_id( "PROBOSCIS" ) ) || p.has_active_mutation( trait_id( "BEAK_HUM" ) ) ) && @@ -1435,7 +1435,7 @@ bool can_drink_nectar( const player &p ) /** * Consume Nectar. -15 hunger. */ -bool drink_nectar( player &p ) +static bool drink_nectar( player &p ) { if( can_drink_nectar( p ) ) { p.moves -= 50; // Takes 30 seconds @@ -2853,7 +2853,7 @@ void iexamine::tree_hickory( player &p, const tripoint &examp ) p.moves -= 2000 / ( p.get_skill_level( skill_survival ) + 1 ) + 100; } -item_location maple_tree_sap_container() +static item_location maple_tree_sap_container() { const item maple_sap = item( "maple_sap", 0 ); return g->inv_map_splice( [&]( const item & it ) { @@ -3884,8 +3884,8 @@ void iexamine::ledge( player &p, const tripoint &examp ) } } -player &player_on_couch( player &p, const tripoint &autodoc_loc, player &null_patient, - bool &adjacent_couch, tripoint &couch_pos ) +static player &player_on_couch( player &p, const tripoint &autodoc_loc, player &null_patient, + bool &adjacent_couch, tripoint &couch_pos ) { for( const auto &couch_loc : g->m.points_in_radius( autodoc_loc, 1, 0 ) ) { const furn_str_id couch( "f_autodoc_couch" ); @@ -3905,7 +3905,7 @@ player &player_on_couch( player &p, const tripoint &autodoc_loc, player &null_pa return null_patient; } -item &cyborg_on_couch( const tripoint &couch_pos, item &null_cyborg ) +static item &cyborg_on_couch( const tripoint &couch_pos, item &null_cyborg ) { for( item &it : g->m.i_at( couch_pos ) ) { if( it.typeId() == "bot_broken_cyborg" || it.typeId() == "bot_prototype_cyborg" ) { @@ -3920,7 +3920,7 @@ item &cyborg_on_couch( const tripoint &couch_pos, item &null_cyborg ) return null_cyborg; } -player &best_installer( player &p, player &null_player, int difficulty ) +static player &best_installer( player &p, player &null_player, int difficulty ) { float player_skill = p.bionics_adjusted_skill( skill_firstaid, skill_computer, @@ -4219,7 +4219,7 @@ static bool is_non_rotten_crafting_component( const item &it ) return is_crafting_component( it ) && !it.rotten(); } -void mill_activate( player &p, const tripoint &examp ) +static void mill_activate( player &p, const tripoint &examp ) { const furn_id cur_mill_type = g->m.furn( examp ); furn_id next_mill_type = f_null; @@ -4285,7 +4285,7 @@ void mill_activate( player &p, const tripoint &examp ) add_msg( _( "You remove the brake on the millstone and it slowly starts to turn." ) ); } -void smoker_activate( player &p, const tripoint &examp ) +static void smoker_activate( player &p, const tripoint &examp ) { furn_id cur_smoker_type = g->m.furn( examp ); furn_id next_smoker_type = f_null; @@ -4430,7 +4430,7 @@ void iexamine::mill_finalize( player &, const tripoint &examp, const time_point g->m.furn_set( examp, next_mill_type ); } -void smoker_finalize( player &, const tripoint &examp, const time_point &start_time ) +static void smoker_finalize( player &, const tripoint &examp, const time_point &start_time ) { furn_id cur_smoker_type = g->m.furn( examp ); furn_id next_smoker_type = f_null; @@ -4475,7 +4475,8 @@ void smoker_finalize( player &, const tripoint &examp, const time_point &start_t g->m.furn_set( examp, next_smoker_type ); } -void smoker_load_food( player &p, const tripoint &examp, const units::volume &remaining_capacity ) +static void smoker_load_food( player &p, const tripoint &examp, + const units::volume &remaining_capacity ) { std::vector comps; @@ -4582,7 +4583,8 @@ void smoker_load_food( player &p, const tripoint &examp, const units::volume &re p.invalidate_crafting_inventory(); } -void mill_load_food( player &p, const tripoint &examp, const units::volume &remaining_capacity ) +static void mill_load_food( player &p, const tripoint &examp, + const units::volume &remaining_capacity ) { std::vector comps; diff --git a/src/init.cpp b/src/init.cpp index 6f8485f73dbc2..aff010edbf171 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -130,7 +130,7 @@ void DynamicDataLoader::load_deferred( deferred_json &data ) } } -void load_ignored_type( JsonObject &jo ) +static void load_ignored_type( JsonObject &jo ) { // This does nothing! // This function is used for types that are to be ignored diff --git a/src/init.h b/src/init.h index ce4d7bd97fede..7b0789aaf639b 100644 --- a/src/init.h +++ b/src/init.h @@ -52,16 +52,16 @@ class JsonIn; class DynamicDataLoader { public: - typedef std::string type_string; - typedef std::map> - t_type_function_map; - typedef std::vector str_vec; + using type_string = std::string; + using t_type_function_map = + std::map>; + using str_vec = std::vector; /** * JSON data dependent upon as-yet unparsed definitions * first: JSON data, second: source identifier */ - typedef std::list> deferred_json; + using deferred_json = std::list>; private: bool finalized = false; diff --git a/src/input.h b/src/input.h index 6ff00359fc83b..bb6668aebaf37 100644 --- a/src/input.h +++ b/src/input.h @@ -286,16 +286,16 @@ class input_manager private: friend class input_context; - typedef std::vector t_input_event_list; - typedef std::map t_actions; - typedef std::map t_action_contexts; + using t_input_event_list = std::vector; + using t_actions = std::map; + using t_action_contexts = std::map; t_action_contexts action_contexts; - typedef std::map t_string_string_map; + using t_string_string_map = std::map; - typedef std::map t_key_to_name_map; + using t_key_to_name_map = std::map; t_key_to_name_map keycode_to_keyname; t_key_to_name_map gamepad_keycode_to_keyname; - typedef std::map t_name_to_key_map; + using t_name_to_key_map = std::map; t_name_to_key_map keyname_to_keycode; // See @ref get_previously_pressed_key diff --git a/src/int_id.h b/src/int_id.h index 7f5c078ab0aaa..5d9b07dc3c2b0 100644 --- a/src/int_id.h +++ b/src/int_id.h @@ -19,7 +19,7 @@ template class int_id { public: - typedef int_id This; + using This = int_id; /** * Explicit constructor to make it stand out in the code, so one can easily search for all diff --git a/src/inventory.cpp b/src/inventory.cpp index 412172109193f..324ec2bbf9cd9 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -200,7 +200,7 @@ void inventory::unsort() binned = false; } -bool stack_compare( const std::list &lhs, const std::list &rhs ) +static bool stack_compare( const std::list &lhs, const std::list &rhs ) { return lhs.front() < rhs.front(); } diff --git a/src/inventory.h b/src/inventory.h index 8cc43442e4861..8b480d72dd850 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -27,12 +27,12 @@ class JsonOut; class player; struct tripoint; -typedef std::list< std::list > invstack; -typedef std::vector< std::list* > invslice; -typedef std::vector< const std::list* > const_invslice; -typedef std::vector< std::pair*, int> > indexed_invslice; -typedef std::unordered_map< itype_id, std::list > itype_bin; -typedef std::bitset::max()> invlets_bitset; +using invstack = std::list >; +using invslice = std::vector *>; +using const_invslice = std::vector *>; +using indexed_invslice = std::vector< std::pair*, int> >; +using itype_bin = std::unordered_map< itype_id, std::list >; +using invlets_bitset = std::bitset::max()>; /** * Wrapper to handled a set of valid "inventory" letters. "inventory" can be any set of diff --git a/src/inventory_ui.cpp b/src/inventory_ui.cpp index db6a6dc0d8c91..4d51492fb8194 100644 --- a/src/inventory_ui.cpp +++ b/src/inventory_ui.cpp @@ -982,8 +982,8 @@ void selection_column::on_change( const inventory_entry &entry ) } // TODO: Move it into some 'item_stack' class. -std::vector> restack_items( const std::list::const_iterator &from, - const std::list::const_iterator &to, bool check_components = false ) +static std::vector> restack_items( const std::list::const_iterator &from, + const std::list::const_iterator &to, bool check_components = false ) { std::vector> res; @@ -1778,7 +1778,7 @@ item_location inventory_pick_selector::execute() if( input.action == "HELP_KEYBINDINGS" || input.action == "INVENTORY_FILTER" ) { g->draw_ter(); wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); } } } diff --git a/src/io.h b/src/io.h index 131493bc58798..b1ecc38dd6370 100644 --- a/src/io.h +++ b/src/io.h @@ -121,7 +121,7 @@ namespace detail template struct enable_if_type { - typedef R type; + using type = R; }; /** diff --git a/src/item.cpp b/src/item.cpp index 40b1050f1abca..dcebd62efdc16 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -111,9 +111,9 @@ const material_id mat_kevlar( "kevlar" ); const trait_id trait_small2( "SMALL2" ); const trait_id trait_small_ok( "SMALL_OK" ); - const trait_id trait_huge( "HUGE" ); const trait_id trait_huge_ok( "HUGE_OK" ); +using npc_class_id = string_id; const std::string &rad_badge_color( const int rad ) { @@ -838,7 +838,7 @@ std::string item::info( bool showtext, std::vector &iteminfo, int batc // Generates a long-form description of the freshness of the given rottable food item. // NB: Doesn't check for non-rottable! -std::string get_freshness_description( const item &food_item ) +static std::string get_freshness_description( const item &food_item ) { // So, skilled characters looking at food that is neither super-fresh nor about to rot // can guess its age as one of {quite fresh,midlife,past midlife,old soon}, and also @@ -950,7 +950,7 @@ item::sizing item::get_sizing( const Character &p, bool wearable ) const } -int get_base_env_resist( const item &it ) +static int get_base_env_resist( const item &it ) { const auto t = it.find_armor_data(); if( t == nullptr ) { @@ -1093,6 +1093,9 @@ std::string item::info( std::vector &info, const iteminfo_query *parts }, enumeration_conjunction::none ); info.push_back( iteminfo( "BASE", string_format( _( "Material: %s" ), material_list ) ) ); } + if( has_owner() ) { + info.push_back( iteminfo( "BASE", string_format( _( "Owner: %s" ), get_owner()->name ) ) ); + } if( has_var( "contained_name" ) && parts->test( iteminfo_parts::BASE_CONTENTS ) ) { info.push_back( iteminfo( "BASE", string_format( _( "Contains: %s" ), get_var( "contained_name" ) ) ) ); @@ -2930,7 +2933,10 @@ void item::on_wear( Character &p ) if( &p == &g->u && type->artifact ) { g->add_artifact_messages( type->artifact->effects_worn ); } - + // if game is loaded - dont want ownership assigned during char creation + if( g->u.getID() != -1 ) { + handle_pickup_ownership( p ); + } p.on_item_wear( *this ); } @@ -2990,22 +2996,70 @@ void item::on_wield( player &p, int mv ) } else { msg = _( "You wield your %s." ); } - + // if game is loaded - dont want ownership assigned during char creation + if( g->u.getID() != -1 ) { + handle_pickup_ownership( p ); + } p.add_msg_if_player( m_neutral, msg, tname() ); } +void item::handle_pickup_ownership( Character &c ) +{ + faction *yours; + if( &c == &g->u ) { + yours = g->faction_manager_ptr->get( faction_id( "your_followers" ) ); + } else { + npc *guy = dynamic_cast( &c ); + yours = guy->my_fac; + } + // Add ownership to item if unowned + if( !has_owner() ) { + set_owner( yours ); + } else { + if( get_owner() != yours && &c == &g->u ) { + std::vector witnesses; + for( npc &elem : g->all_npcs() ) { + if( rl_dist( elem.pos(), g->u.pos() ) < MAX_VIEW_DISTANCE && elem.my_fac == get_owner() && + elem.sees( g->u.pos() ) ) { + elem.say( "", 7 ); + npc *npc_to_add = &elem; + witnesses.push_back( npc_to_add ); + } + } + if( !witnesses.empty() ) { + set_old_owner( get_owner() ); + bool guard_chosen = false; + for( auto &elem : witnesses ) { + if( elem->myclass == npc_class_id( "NC_BOUNTY_HUNTER" ) ) { + guard_chosen = true; + elem->witness_thievery( &*this ); + break; + } + } + if( !guard_chosen ) { + int random_index = rand() % witnesses.size(); + witnesses[random_index]->witness_thievery( &*this ); + } + } + set_owner( yours ); + } + } +} + void item::on_pickup( Character &p ) { // Fake characters are used to determine pickup weight and volume if( p.is_fake() ) { return; } - // TODO: artifacts currently only work with the player character if( &p == &g->u && type->artifact ) { g->add_artifact_messages( type->artifact->effects_carried ); } - + // if game is loaded - dont want ownership assigned during char creation + if( g->u.getID() != -1 ) { + handle_pickup_ownership( p ); + } if( is_bucket_nonempty() ) { for( const auto &it : contents ) { g->m.add_item_or_charges( p.pos(), it ); @@ -3927,7 +3981,7 @@ int item::spoilage_sort_order() * @see calc_rot_array * @see rot_chart */ -int calc_hourly_rotpoints_at_temp( const int temp ) +static int calc_hourly_rotpoints_at_temp( const int temp ) { // default temp = 65, so generic->rotten() assumes 600 decay points per hour const int dropoff = 38; // ditch our fancy equation and do a linear approach to 0 rot at 31f @@ -3952,7 +4006,7 @@ int calc_hourly_rotpoints_at_temp( const int temp ) * Initialize the rot table. * @see rot_chart */ -std::vector calc_rot_array( const size_t cap ) +static std::vector calc_rot_array( const size_t cap ) { std::vector ret; ret.reserve( cap ); @@ -7123,7 +7177,7 @@ bool item::can_holster( const item &obj, bool ignore ) const std::string item::components_to_string() const { - typedef std::map t_count_map; + using t_count_map = std::map; t_count_map counts; for( const auto &elem : components ) { if( !elem.has_flag( "BYPRODUCT" ) ) { diff --git a/src/item.h b/src/item.h index e3871b20181cb..e0f3184f86637 100644 --- a/src/item.h +++ b/src/item.h @@ -17,6 +17,7 @@ #include "cata_utility.h" #include "debug.h" #include "enums.h" +#include "faction.h" #include "flat_set.h" #include "io_tags.h" #include "item_location.h" @@ -1836,9 +1837,35 @@ class item : public visitable void set_age( const time_duration &age ); time_point birthday() const; void set_birthday( const time_point &bday ); - + void handle_pickup_ownership( Character &p ); int get_gun_ups_drain() const; - + inline void set_old_owner( const faction *temp_owner ) { + old_owner = temp_owner; + } + inline void remove_old_owner() { + old_owner = nullptr; + } + inline void set_owner( faction *new_owner ) { + owner = new_owner; + } + inline void remove_owner() { + owner = nullptr; + } + inline const faction *get_owner() const { + if( owner ) { + return owner; + } + return nullptr; + } + inline const faction *get_old_owner() const { + if( old_owner ) { + return old_owner; + } + return nullptr; + } + inline bool has_owner() const { + return owner; + } int get_min_str() const; const cata::optional &get_comestible() const; @@ -1987,7 +2014,10 @@ class item : public visitable * PNULL. */ phase_id current_phase = static_cast( 0 ); - + // The faction that owns this item. + const faction *owner = nullptr; + // The faction that previously owned this item + const faction *old_owner = nullptr; int damage_ = 0; light_emission light = nolight; diff --git a/src/item_action.cpp b/src/item_action.cpp index a6b8601393e4d..a932967b1adaf 100644 --- a/src/item_action.cpp +++ b/src/item_action.cpp @@ -35,12 +35,7 @@ struct tripoint; static item_action nullaction; static const std::string errstring( "ERROR" ); -int clamp( int value, int low, int high ) -{ - return ( value < low ) ? low : ( ( value > high ) ? high : value ); -} - -char key_bound_to( const input_context &ctxt, const item_action_id &act ) +static char key_bound_to( const input_context &ctxt, const item_action_id &act ) { auto keys = ctxt.keys_bound_to( act ); return keys.empty() ? '\0' : keys[0]; @@ -73,7 +68,7 @@ item_action_generator::item_action_generator() = default; item_action_generator::~item_action_generator() = default; // Get use methods of this item and its contents -bool item_has_uses_recursive( const item &it ) +static bool item_has_uses_recursive( const item &it ) { if( !it.type->use_methods.empty() ) { return true; @@ -250,7 +245,7 @@ void game::item_action_menu() std::vector> menu_items; // Sorts menu items by action. - typedef decltype( menu_items )::iterator Iter; + using Iter = decltype( menu_items )::iterator; const auto sort_menu = []( Iter from, Iter to ) { std::sort( from, to, []( const std::tuple &lhs, const std::tuple &rhs ) { @@ -312,7 +307,7 @@ void game::item_action_menu() draw_ter(); wrefresh( w_terrain ); - draw_panels(); + draw_panels( true ); const item_action_id action = std::get<0>( menu_items[kmenu.ret] ); item *it = iactions[action]; diff --git a/src/item_action.h b/src/item_action.h index 16dbe86088244..2a660a51e0929 100644 --- a/src/item_action.h +++ b/src/item_action.h @@ -13,9 +13,9 @@ class player; class item; class JsonObject; -typedef std::string item_action_id; -typedef std::map< item_action_id, item * > item_action_map; -typedef std::map< item_action_id, item_action > action_map; +using item_action_id = std::string; +using item_action_map = std::map< item_action_id, item * >; +using action_map = std::map< item_action_id, item_action >; class item_action { diff --git a/src/item_factory.cpp b/src/item_factory.cpp index 64dc00267d95c..62d06954c5e9e 100644 --- a/src/item_factory.cpp +++ b/src/item_factory.cpp @@ -46,7 +46,7 @@ class player; -typedef std::set t_string_set; +using t_string_set = std::set; static t_string_set item_blacklist; static std::set repair_actions; @@ -2233,7 +2233,7 @@ void Item_factory::clear() frozen = false; } -std::string to_string( Item_group::Type t ) +static std::string to_string( Item_group::Type t ) { switch( t ) { case Item_group::Type::G_COLLECTION: @@ -2245,8 +2245,9 @@ std::string to_string( Item_group::Type t ) return "BUGGED"; } -Item_group *make_group_or_throw( const Group_tag &group_id, std::unique_ptr &isd, - Item_group::Type t, int ammo_chance, int magazine_chance ) +static Item_group *make_group_or_throw( const Group_tag &group_id, + std::unique_ptr &isd, + Item_group::Type t, int ammo_chance, int magazine_chance ) { Item_group *ig = dynamic_cast( isd.get() ); if( ig == nullptr ) { diff --git a/src/item_factory.h b/src/item_factory.h index 1035085bc1520..895abee6786e4 100644 --- a/src/item_factory.h +++ b/src/item_factory.h @@ -27,9 +27,9 @@ template class optional; bool item_is_blacklisted( const std::string &id ); -typedef std::string Item_tag; -typedef std::string Group_tag; -typedef std::vector Item_list; +using Item_tag = std::string; +using Group_tag = std::string; +using Item_list = std::vector; class Item_factory; class JsonObject; @@ -247,7 +247,7 @@ class Item_factory mutable std::map> m_runtimes; - typedef std::map> GroupMap; + using GroupMap = std::map>; GroupMap m_template_groups; /** Checks that ammo is listed in ammunition_type::name(). diff --git a/src/item_group.cpp b/src/item_group.cpp index a25357c5ca6ac..377bbb71fe74d 100644 --- a/src/item_group.cpp +++ b/src/item_group.cpp @@ -526,7 +526,7 @@ void item_group::load_item_group( JsonObject &jsobj, const Group_tag &group_id, item_controller->load_item_group( jsobj, group_id, subtype ); } -Group_tag get_unique_group_id() +static Group_tag get_unique_group_id() { // This is just a hint what id to use next. Overflow of it is defined and if the group // name is already used, we simply go the next id. diff --git a/src/item_group.h b/src/item_group.h index e19533c6f6ada..67ecc5b055194 100644 --- a/src/item_group.h +++ b/src/item_group.h @@ -10,8 +10,8 @@ #include "optional.h" #include "item.h" -typedef std::string Item_tag; -typedef std::string Group_tag; +using Item_tag = std::string; +using Group_tag = std::string; class JsonObject; class JsonIn; class time_point; @@ -30,7 +30,7 @@ item item_from( const Group_tag &group_id, const time_point &birthday ); */ item item_from( const Group_tag &group_id ); -typedef std::vector ItemList; +using ItemList = std::vector; /** * Create items from the given group. It creates as many items as the group definition requests. * For example if the group is a distribution that only contains item ids it will create @@ -101,8 +101,8 @@ Group_tag load_item_group( JsonIn &stream, const std::string &default_subtype ); class Item_spawn_data { public: - typedef std::vector ItemList; - typedef std::vector RecursionList; + using ItemList = std::vector; + using RecursionList = std::vector; Item_spawn_data( int _probability ) : probability( _probability ) { } virtual ~Item_spawn_data() = default; @@ -209,11 +209,11 @@ class Item_modifier class Single_item_creator : public Item_spawn_data { public: - typedef enum { + enum Type { S_ITEM_GROUP, S_ITEM, S_NONE, - } Type; + }; Single_item_creator( const std::string &id, Type type, int probability ); ~Single_item_creator() override = default; @@ -242,11 +242,11 @@ class Single_item_creator : public Item_spawn_data class Item_group : public Item_spawn_data { public: - typedef std::vector ItemList; - typedef enum { + using ItemList = std::vector; + enum Type { G_COLLECTION, G_DISTRIBUTION - } Type; + }; Item_group( Type type, int probability, int ammo_chance, int magazine_chance ); ~Item_group() override = default; @@ -260,7 +260,7 @@ class Item_group : public Item_spawn_data * If type is G_DISTRIBUTION, probability is relative, * the sum probability is sum_prob. */ - typedef std::vector> prop_list; + using prop_list = std::vector >; void add_item_entry( const Item_tag &itemid, int probability ); void add_group_entry( const Group_tag &groupid, int probability ); diff --git a/src/itype.h b/src/itype.h index bf868f255de97..fb400bafd910f 100644 --- a/src/itype.h +++ b/src/itype.h @@ -32,7 +32,7 @@ enum art_effect_active : int; enum art_charge : int; enum art_charge_req : int; enum art_effect_passive : int; -typedef std::string itype_id; +using itype_id = std::string; enum field_id : int; @@ -345,7 +345,7 @@ struct islot_book { return hidden; } }; - typedef std::set recipe_list_t; + using recipe_list_t = std::set; recipe_list_t recipes; }; diff --git a/src/iuse.cpp b/src/iuse.cpp index 1f5f7c0e8e517..641be32128c15 100644 --- a/src/iuse.cpp +++ b/src/iuse.cpp @@ -237,7 +237,7 @@ void remove_radio_mod( item &it, player &p ) } // Checks that the player does not have an active item with LITCIG flag. -bool check_litcig( player &u ) +static bool check_litcig( player &u ) { auto cigs = u.items_with( []( const item & it ) { return it.active && it.has_flag( "LITCIG" ); @@ -309,7 +309,7 @@ static constexpr time_duration alc_strength( const int strength, const time_dura return strength == 0 ? weak : strength == 1 ? medium : strong; } -int alcohol( player &p, const item &it, const int strength ) +static int alcohol( player &p, const item &it, const int strength ) { // Weaker characters are cheap drunks /** @EFFECT_STR_MAX reduces drunkenness duration */ @@ -1068,7 +1068,7 @@ int iuse::purify_smart( player *p, item *it, bool, const tripoint & ) return it->type->charges_to_use(); } -void spawn_spores( const player &p ) +static void spawn_spores( const player &p ) { int spores_spawned = 0; fungal_effects fe( *g, g->m ); @@ -1380,7 +1380,7 @@ enum Petfood { BIRDFOOD }; -int feedpet( player &p, monster &mon, item &it, m_flag food_flag, const char *message ) +static int feedpet( player &p, monster &mon, item &it, m_flag food_flag, const char *message ) { if( mon.has_flag( food_flag ) ) { p.add_msg_if_player( m_good, message, mon.get_name() ); @@ -1394,7 +1394,7 @@ int feedpet( player &p, monster &mon, item &it, m_flag food_flag, const char *me } } -int petfood( player &p, item &it, Petfood animal_food_type ) +static int petfood( player &p, item &it, Petfood animal_food_type ) { const cata::optional pnt_ = choose_adjacent( string_format( _( "Put the %s where?" ), it.tname() ) ); @@ -2899,9 +2899,9 @@ int iuse::siphon( player *p, item *it, bool, const tripoint & ) return it->type->charges_to_use(); } -int toolweapon_off( player &p, item &it, const bool fast_startup, - const bool condition, const int volume, - const std::string &msg_success, const std::string &msg_failure ) +static int toolweapon_off( player &p, item &it, const bool fast_startup, + const bool condition, const int volume, + const std::string &msg_success, const std::string &msg_failure ) { p.moves -= fast_startup ? 60 : 80; if( condition && it.ammo_remaining() > 0 ) { @@ -2997,10 +2997,10 @@ int iuse::trimmer_off( player *p, item *it, bool, const tripoint & ) _( "You yank the cord, but nothing happens." ) ); } -int toolweapon_on( player &p, item &it, const bool t, - const std::string &tname, const bool works_underwater, - const int sound_chance, const int volume, - const std::string &sound, const bool double_charge_cost = false ) +static int toolweapon_on( player &p, item &it, const bool t, + const std::string &tname, const bool works_underwater, + const int sound_chance, const int volume, + const std::string &sound, const bool double_charge_cost = false ) { std::string off_type = it.typeId().substr( 0, it.typeId().size() - 3 ) + @@ -3944,7 +3944,7 @@ int iuse::mp3( player *p, item *it, bool, const tripoint & ) return it->type->charges_to_use(); } -std::string get_music_description() +static std::string get_music_description() { static const std::string no_description = _( "a sweet guitar solo!" ); static const std::string rare = _( "some bass-heavy post-glam speed polka." ); @@ -5836,7 +5836,7 @@ int iuse::robotcontrol( player *p, item *it, bool, const tripoint & ) return 0; } -void init_memory_card_with_random_stuff( item &it ) +static void init_memory_card_with_random_stuff( item &it ) { if( it.has_flag( "MC_MOBILE" ) && ( it.has_flag( "MC_RANDOM_STUFF" ) || it.has_flag( "MC_SCIENCE_STUFF" ) ) && !( it.has_flag( "MC_USED" ) || @@ -5911,7 +5911,7 @@ void init_memory_card_with_random_stuff( item &it ) } } -bool einkpc_download_memory_card( player &p, item &eink, item &mc ) +static bool einkpc_download_memory_card( player &p, item &eink, item &mc ) { bool something_downloaded = false; if( mc.get_var( "MC_PHOTOS", 0 ) > 0 ) { @@ -6941,7 +6941,7 @@ int iuse::radiocaron( player *p, item *it, bool t, const tripoint &pos ) return it->type->charges_to_use(); } -void sendRadioSignal( player &p, const std::string &signal ) +static void sendRadioSignal( player &p, const std::string &signal ) { for( size_t i = 0; i < p.inv.size(); i++ ) { item &it = p.inv.find_item( i ); @@ -7099,7 +7099,7 @@ static bool hackveh( player &p, item &it, vehicle &veh ) return success; } -vehicle *pickveh( const tripoint ¢er, bool advanced ) +static vehicle *pickveh( const tripoint ¢er, bool advanced ) { static const std::string ctrl = "CTRL_ELECTRONIC"; static const std::string advctrl = "REMOTE_CONTROLS"; @@ -7214,7 +7214,7 @@ int iuse::remoteveh( player *p, item *it, bool t, const tripoint &pos ) return it->type->charges_to_use(); } -bool multicooker_hallu( player &p ) +static bool multicooker_hallu( player &p ) { p.moves -= 200; const int random_hallu = rng( 1, 7 ); diff --git a/src/iuse.h b/src/iuse.h index df08695e9cbe4..77d82b33dca4c 100644 --- a/src/iuse.h +++ b/src/iuse.h @@ -15,7 +15,7 @@ class monster; template class ret_val; struct iteminfo; -typedef std::string itype_id; +using itype_id = std::string; struct tripoint; // iuse methods returning a bool indicating whether to consume a charge of the item being used. @@ -237,7 +237,7 @@ struct washing_requirements { }; washing_requirements washing_requirements_for_volume( units::volume ); -typedef int ( iuse::*use_function_pointer )( player *, item *, bool, const tripoint & ); +using use_function_pointer = int ( iuse::* )( player *, item *, bool, const tripoint & ); class iuse_actor { diff --git a/src/iuse_actor.cpp b/src/iuse_actor.cpp index 491b0251c143a..1e2dbf266116c 100644 --- a/src/iuse_actor.cpp +++ b/src/iuse_actor.cpp @@ -23,6 +23,7 @@ #include "cata_utility.h" #include "coordinate_conversions.h" #include "crafting.h" +#include "creature.h" #include "debug.h" #include "vpart_position.h" #include "effect.h" @@ -34,6 +35,7 @@ #include "item.h" #include "item_factory.h" #include "itype.h" +#include "magic.h" #include "map.h" #include "map_iterator.h" #include "map_selector.h" @@ -855,7 +857,7 @@ void ups_based_armor_actor::load( JsonObject &obj ) obj.read( "out_of_power_msg", out_of_power_msg ); } -bool has_powersource( const item &i, const player &p ) +static bool has_powersource( const item &i, const player &p ) { if( i.is_power_armor() && p.can_interface_armor() && p.power_level > 0 ) { return true; @@ -2148,6 +2150,107 @@ ret_val musical_instrument_actor::can_use( const player &p, const item &, return ret_val::make_success(); } +iuse_actor *learn_spell_actor::clone() const +{ + return new learn_spell_actor( *this ); +} + +void learn_spell_actor::load( JsonObject &obj ) +{ + spells = obj.get_string_array( "spells" ); +} + +void learn_spell_actor::info( const item &, std::vector &dump ) const +{ + std::string message; + if( spells.size() == 1 ) { + message = _( "This can teach you a spell." ); + } else { + message = _( "This can teach you a number of spells." ); + } + dump.emplace_back( "DESCRIPTION", message ); + dump.emplace_back( "DESCRIPTION", _( "Spells Contained:" ) ); + for( const std::string sp : spells ) { + dump.emplace_back( "SPELL", spell_id( sp ).obj().name ); + } +} + +int learn_spell_actor::use( player &p, item &, bool, const tripoint & ) const +{ + if( p.fine_detail_vision_mod() > 4 ) { + p.add_msg_if_player( _( "It's too dark to read." ) ); + return 0; + } + std::vector uilist_initializer; + bool know_it_all = true; + for( const std::string sp_id_str : spells ) { + const spell_id sp_id( sp_id_str ); + const std::string sp_nm = sp_id.obj().name; + uilist_entry entry( sp_nm ); + if( p.magic.knows_spell( sp_id ) ) { + const spell sp = p.magic.get_spell( sp_id ); + entry.ctxt = string_format( "Level %u", sp.get_level() ); + if( sp.is_max_level() ) { + entry.ctxt += _( " (Max)" ); + entry.enabled = false; + } else { + know_it_all = false; + } + } else { + if( p.magic.can_learn_spell( p, sp_id ) ) { + entry.ctxt = _( "Study to Learn" ); + know_it_all = false; + } else { + entry.ctxt = _( "Can't learn!" ); + entry.enabled = false; + } + } + uilist_initializer.emplace_back( entry ); + } + + if( know_it_all ) { + add_msg( m_info, _( "You already know everything this could teach you." ) ); + return 0; + } + + const int action = uilist( _( "Study a spell:" ), uilist_initializer ); + if( action < 0 ) { + return 0; + } + const bool knows_spell = p.magic.knows_spell( spells[action] ); + player_activity study_spell( activity_id( "ACT_STUDY_SPELL" ), + p.magic.time_to_learn_spell( p, spells[action] ) ); + study_spell.str_values = { + "", // reserved for "until you gain a spell level" option [0] + "learn" + }; // [1] + study_spell.values = { 0, 0, 0 }; + if( knows_spell ) { + study_spell.str_values[1] = "study"; + const int study_time = uilist( _( "Spend how long studying?" ), { + { 30000, true, -1, _( "30 minutes" ) }, + { 60000, true, -1, _( "1 hour" ) }, + { 120000, true, -1, _( "2 hours" ) }, + { 240000, true, -1, _( "4 hours" ) }, + { 480000, true, -1, _( "8 hours" ) }, + { 10100, true, -1, _( "Until you gain a spell level" ) } + } ); + if( study_time <= 0 ) { + return 0; + } + study_spell.moves_total = study_time; + } + study_spell.moves_left = study_spell.moves_total; + if( study_spell.moves_total == 10100 ) { + study_spell.str_values[0] = "gain_level"; + study_spell.values[0]; // reserved for xp + study_spell.values[1] = p.magic.get_spell( spell_id( spells[action] ) ).get_level() + 1; + } + study_spell.name = spells[action]; + p.assign_activity( study_spell, false ); + return 0; +} + iuse_actor *holster_actor::clone() const { return new holster_actor( *this ); @@ -2883,7 +2986,7 @@ repair_item_actor::repair_type repair_item_actor::default_action( const item &fi return RT_NOTHING; } -bool damage_item( player &pl, item_location &fix ) +static bool damage_item( player &pl, item_location &fix ) { const std::string startdurability = fix->durability_indicator( true ); const auto destroyed = fix->inc_damage(); @@ -3102,7 +3205,7 @@ void heal_actor::load( JsonObject &obj ) } } -player &get_patient( player &healer, const tripoint &pos ) +static player &get_patient( player &healer, const tripoint &pos ) { if( healer.pos() == pos ) { return healer; @@ -3320,7 +3423,7 @@ int heal_actor::finish_using( player &healer, player &patient, item &it, hp_part return it.type->charges_to_use(); } -hp_part pick_part_to_heal( +static hp_part pick_part_to_heal( const player &healer, const player &patient, const std::string &menu_header, int limb_power, int head_bonus, int torso_bonus, @@ -3522,14 +3625,14 @@ iuse_actor *place_trap_actor::clone() const return new place_trap_actor( *this ); } -bool is_solid_neighbor( const tripoint &pos, const int offset_x, const int offset_y ) +static bool is_solid_neighbor( const tripoint &pos, const int offset_x, const int offset_y ) { const tripoint a = pos + tripoint( offset_x, offset_y, 0 ); const tripoint b = pos - tripoint( offset_x, offset_y, 0 ); return g->m.move_cost( a ) != 2 && g->m.move_cost( b ) != 2; } -bool has_neighbor( const tripoint &pos, const ter_id &terrain_id ) +static bool has_neighbor( const tripoint &pos, const ter_id &terrain_id ) { for( const tripoint &t : g->m.points_in_radius( pos, 1, 0 ) ) { if( g->m.ter( t ) == terrain_id ) { @@ -3576,7 +3679,7 @@ bool place_trap_actor::is_allowed( player &p, const tripoint &pos, const std::st return true; } -void place_and_add_as_known( player &p, const tripoint &pos, const trap_str_id &id ) +static void place_and_add_as_known( player &p, const tripoint &pos, const trap_str_id &id ) { g->m.trap_set( pos, id ); const trap &tr = g->m.tr_at( pos ); diff --git a/src/iuse_actor.h b/src/iuse_actor.h index 092700a33eecd..caf8a35c7bfb5 100644 --- a/src/iuse_actor.h +++ b/src/iuse_actor.h @@ -659,6 +659,24 @@ class musical_instrument_actor : public iuse_actor iuse_actor *clone() const override; }; +/** + * Learn a spell + */ +class learn_spell_actor : public iuse_actor +{ + public: + // list of spell ids that can be learned from this item + std::vector spells; + + learn_spell_actor( const std::string &type = "learn_spell" ) : iuse_actor( type ) {} + + ~learn_spell_actor() override = default; + void load( JsonObject &jo ) override; + int use( player &p, item &, bool, const tripoint & ) const override; + iuse_actor *clone() const override; + void info( const item &, std::vector & ) const override; +}; + /** * Holster a weapon */ diff --git a/src/json.cpp b/src/json.cpp index 2fc7b99fa1d5c..f620c21514e0a 100644 --- a/src/json.cpp +++ b/src/json.cpp @@ -19,14 +19,14 @@ // JSON parsing and serialization tools for Cataclysm-DDA. // For documentation, see the included header, json.h. -bool is_whitespace( char ch ) +static bool is_whitespace( char ch ) { // These are all the valid whitespace characters allowed by RFC 4627. return ( ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r' ); } // for parsing \uxxxx escapes -std::string utf16_to_utf8( uint32_t ch ) +static std::string utf16_to_utf8( uint32_t ch ) { char out[5]; char *buf = out; diff --git a/src/lightmap.cpp b/src/lightmap.cpp index 98a3224e7ecab..d9431f9afcbaf 100644 --- a/src/lightmap.cpp +++ b/src/lightmap.cpp @@ -1444,6 +1444,7 @@ void map::apply_light_arc( const tripoint &p, int angle, float luminance, int wi // attempt to determine beam density required to cover all squares const double wstep = ( wangle / ( wdist * SQRT_2 ) ); + // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter) for( double ao = wstep; ao <= wangle; ao += wstep ) { if( trigdist ) { double fdist = ( ao * HALFPI ) / wangle; diff --git a/src/line.cpp b/src/line.cpp index 3628f094c9780..75dc6cb941940 100644 --- a/src/line.cpp +++ b/src/line.cpp @@ -322,7 +322,7 @@ unsigned make_xyz( const int x, const int y, const int z ) } // returns the normalized dx, dy, dz for the current line vector. -std::tuple slope_of( const std::vector &line ) +static std::tuple slope_of( const std::vector &line ) { assert( !line.empty() && line.front() != line.back() ); const double len = trig_dist( line.front(), line.back() ); diff --git a/src/magic.cpp b/src/magic.cpp index 5cd7445f49df0..e5dc9de9eefd8 100644 --- a/src/magic.cpp +++ b/src/magic.cpp @@ -64,7 +64,7 @@ void spell_type::load_spell( JsonObject &jo, const std::string &src ) spell_factory.load( jo, src ); } -energy_type energy_source_from_string( const std::string &str ) +static energy_type energy_source_from_string( const std::string &str ) { if( str == "MANA" ) { return mana_energy; @@ -82,7 +82,7 @@ energy_type energy_source_from_string( const std::string &str ) } } -damage_type damage_type_from_string( const std::string &str ) +static damage_type damage_type_from_string( const std::string &str ) { if( str == "fire" ) { return DT_HEAT; @@ -399,7 +399,7 @@ std::string spell::energy_cost_string( const player &p ) const auto pair = get_hp_bar( energy_cost(), p.get_stamina_max() ); return colorize( pair.first, pair.second ); } - debugmsg( _( "ERROR: Spell %s has invalid energy source." ), id().c_str() ); + debugmsg( "ERROR: Spell %s has invalid energy source.", id().c_str() ); return _( "error: energy_type" ); } @@ -421,7 +421,7 @@ std::string spell::energy_cur_string( const player &p ) const if( energy_source() == hp_energy ) { return ""; } - debugmsg( _( "ERROR: Spell %s has invalid energy source." ), id().c_str() ); + debugmsg( "ERROR: Spell %s has invalid energy source.", id().c_str() ); return _( "error: energy_type" ); } @@ -513,7 +513,7 @@ int spell::get_max_level() const // helper function to calculate xp needed to be at a certain level // pulled out as a helper function to make it easier to either be used in the future // or easier to tweak the formula -int exp_for_level( int level ) +static int exp_for_level( int level ) { // level 0 never needs xp if( level == 0 ) { @@ -802,3 +802,330 @@ int known_magic::time_to_learn_spell( const player &p, spell_id sp ) const return base_time * ( 1.0 + sp.obj().difficulty / ( 1.0 + ( p.get_int() - 8.0 ) / 8.0 ) + ( p.get_skill_level( skill_id( "SPELLCRAFT" ) ) / 10.0 ) ); } + +// spell_effect + +namespace spell_effect +{ + +static tripoint random_point( int min_distance, int max_distance, const tripoint &player_pos ) +{ + const int angle = rng( 0, 360 ); + const int dist = rng( min_distance, max_distance ); + const int x = round( dist * cos( angle ) ); + const int y = round( dist * sin( angle ) ); + return tripoint( x + player_pos.x, y + player_pos.y, player_pos.z ); +} + +void teleport( int min_distance, int max_distance ) +{ + if( min_distance > max_distance || min_distance < 0 || max_distance < 0 ) { + debugmsg( "ERROR: Teleport argument(s) invalid" ); + return; + } + const tripoint player_pos = g->u.pos(); + tripoint target; + // limit the loop just in case it's impossble to find a valid point in the range + int tries = 0; + do { + target = random_point( min_distance, max_distance, player_pos ); + tries++; + } while( g->m.impassable( target ) && tries < 20 ); + if( tries == 20 ) { + add_msg( m_bad, _( "Unable to find a valid target for teleport." ) ); + return; + } + g->place_player( target ); +} + +void pain_split() +{ + player &p = g->u; + add_msg( m_info, _( "Your injuries even out." ) ); + int num_limbs = 0; // number of limbs effected (broken don't count) + int total_hp = 0; // total hp among limbs + + for( const int &part : p.hp_cur ) { + if( part != 0 ) { + num_limbs++; + total_hp += part; + } + } + for( int &part : p.hp_cur ) { + const int hp_each = total_hp / num_limbs; + if( part != 0 ) { + part = hp_each; + } + } +} + +void move_earth( const tripoint &target ) +{ + ter_id ter_here = g->m.ter( target ); + + std::set empty_air = { t_hole }; + std::set deep_pit = { t_pit, t_slope_down }; + std::set shallow_pit = { t_pit_corpsed, t_pit_covered, t_pit_glass, t_pit_glass_covered, t_pit_shallow, t_pit_spiked, t_pit_spiked, t_pit_spiked_covered, t_rootcellar }; + std::set soft_dirt = { t_grave, t_dirt, t_sand, t_clay, t_dirtmound, t_grass, t_grass_long, t_grass_tall, t_grass_golf, t_grass_dead, t_grass_white, t_dirtfloor, t_fungus_floor_in, t_fungus_floor_sup, t_fungus_floor_out, t_sandbox }; + // rock: can still be dug through with patience, converts to sand upon completion + std::set hard_dirt = { t_pavement, t_pavement_y, t_sidewalk, t_concrete, t_thconc_floor, t_thconc_floor_olight, t_strconc_floor, t_floor, t_floor_waxed, t_carpet_red, t_carpet_yellow, t_carpet_purple, t_carpet_green, t_linoleum_white, t_linoleum_gray, t_slope_up, t_rock_red, t_rock_green, t_rock_blue, t_floor_red, t_floor_green, t_floor_blue, t_pavement_bg_dp, t_pavement_y_bg_dp, t_sidewalk_bg_dp }; + + if( empty_air.count( ter_here ) == 1 ) { + add_msg( m_bad, _( "All the dust in the air here falls to the ground." ) ); + } else if( deep_pit.count( ter_here ) == 1 ) { + g->m.ter_set( target, t_hole ); + add_msg( _( "The pit has deepened further." ) ); + } else if( shallow_pit.count( ter_here ) == 1 ) { + g->m.ter_set( target, t_pit ); + add_msg( _( "More debris shifts out of the pit." ) ); + } else if( soft_dirt.count( ter_here ) == 1 ) { + g->m.ter_set( target, t_pit_shallow ); + add_msg( _( "The earth moves out of the way for you" ) ); + } else if( hard_dirt.count( ter_here ) == 1 ) { + g->m.ter_set( target, t_sand ); + add_msg( _( "The rocks here are ground into sand." ) ); + } else { + add_msg( m_bad, _( "The earth here does not listen to your command to move." ) ); + } +} + +static bool in_spell_aoe( const tripoint &target, const tripoint &epicenter, const int &radius, + const bool ignore_walls ) +{ + if( ignore_walls ) { + return rl_dist( epicenter, target ) <= radius; + } + std::vector trajectory = line_to( epicenter, target ); + for( const tripoint &pt : trajectory ) { + if( g->m.impassable( pt ) ) { + return false; + } + } + return rl_dist( epicenter, target ) <= radius; +} + +static std::set spell_effect_blast( spell &, const tripoint &, const tripoint &target, + const int aoe_radius, const bool ignore_walls ) +{ + std::set targets; + // TODO: Make this breadth-first + for( int x = target.x - aoe_radius; x < target.x + aoe_radius; x++ ) { + for( int y = target.y - aoe_radius; y < target.y + aoe_radius; y++ ) { + for( int z = target.z - aoe_radius; z < target.z + aoe_radius; z++ ) { + const tripoint potential_target( x, y, z ); + if( in_spell_aoe( potential_target, target, aoe_radius, ignore_walls ) ) { + targets.emplace( potential_target ); + } + } + } + } + return targets; +} + +static std::set spell_effect_cone( spell &sp, const tripoint &source, + const tripoint &target, + const int aoe_radius, const bool ignore_walls ) +{ + std::set targets; + // cones go all the way to end (if they don't hit an obstacle) + const int range = sp.range(); + const int initial_angle = coord_to_angle( source, target ); + std::set end_points; + for( int angle = initial_angle - floor( aoe_radius / 2.0 ); + angle <= initial_angle + ceil( aoe_radius / 2.0 ); angle++ ) { + tripoint potential; + calc_ray_end( angle, range, source, potential ); + end_points.emplace( potential ); + } + for( const tripoint &ep : end_points ) { + std::vector trajectory = line_to( ep, source ); + for( const tripoint &tp : trajectory ) { + if( ignore_walls || g->m.passable( tp ) ) { + targets.emplace( tp ); + } else { + break; + } + } + } + // we don't want to hit ourselves in the blast! + targets.erase( source ); + return targets; +} + +static std::set spell_effect_line( spell &, const tripoint &source, + const tripoint &target, + const int aoe_radius, const bool ignore_walls ) +{ + std::set targets; + const int initial_angle = coord_to_angle( source, target ); + tripoint clockwise_starting_point; + calc_ray_end( initial_angle - 90, floor( aoe_radius / 2.0 ), source, clockwise_starting_point ); + tripoint cclockwise_starting_point; + calc_ray_end( initial_angle + 90, ceil( aoe_radius / 2.0 ), source, cclockwise_starting_point ); + tripoint clockwise_end_point; + calc_ray_end( initial_angle - 90, floor( aoe_radius / 2.0 ), target, clockwise_end_point ); + tripoint cclockwise_end_point; + calc_ray_end( initial_angle + 90, ceil( aoe_radius / 2.0 ), target, cclockwise_end_point ); + + std::vector start_width_lh = line_to( source, cclockwise_starting_point ); + std::vector start_width_rh = line_to( source, clockwise_starting_point ); + + int start_width_lh_blocked = start_width_lh.size(); + int start_width_rh_blocked = start_width_rh.size() + 1; + for( const tripoint &p : start_width_lh ) { + if( ignore_walls || g->m.passable( p ) ) { + start_width_lh_blocked--; + } else { + break; + } + } + for( const tripoint &p : start_width_rh ) { + if( ignore_walls || g->m.passable( p ) ) { + start_width_rh_blocked--; + } else { + break; + } + } + + std::reverse( start_width_rh.begin(), start_width_rh.end() ); + std::vector start_width; + start_width.reserve( start_width_lh.size() + start_width_rh.size() + 2 ); + start_width.insert( start_width.end(), start_width_rh.begin(), start_width_rh.end() ); + start_width.emplace_back( source ); + start_width.insert( start_width.end(), start_width_lh.begin(), start_width_lh.end() ); + std::vector end_width = line_to( cclockwise_end_point, clockwise_end_point ); + // line_to omits the starting point. we want it back. + end_width.insert( end_width.begin(), cclockwise_end_point ); + + // we're going from right to left (clockwise to counterclockwise) + for( int i = start_width_rh_blocked; + i <= static_cast( start_width.size() ) - start_width_lh_blocked; i++ ) { + for( tripoint &ep : end_width ) { + for( tripoint &p : line_to( start_width[i], ep ) ) { + if( ignore_walls || g->m.passable( p ) ) { + targets.emplace( p ); + } else { + break; + } + } + } + } + + targets.erase( source ); + + return targets; +} + +// spells do not reduce in damage the further away from the epicenter the targets are +// rather they do their full damage in the entire area of effect +static std::set spell_effect_area( spell &sp, const tripoint &source, + const tripoint &target, + std::function( spell &, const tripoint &, const tripoint &, const int, const bool )> + aoe_func, bool ignore_walls = false ) +{ + std::set targets = { target }; // initialize with epicenter + if( sp.aoe() <= 1 ) { + return targets; + } + + const int aoe_radius = sp.aoe(); + targets = aoe_func( sp, source, target, aoe_radius, ignore_walls ); + + for( const tripoint &p : targets ) { + if( !sp.is_valid_target( p ) ) { + targets.erase( p ); + } + } + + // Draw the explosion + std::map explosion_colors; + for( auto &pt : targets ) { + explosion_colors[pt] = sp.damage_type_color(); + } + + explosion_handler::draw_custom_explosion( g->u.pos(), explosion_colors ); + return targets; +} + +static void damage_targets( spell &sp, std::set targets ) +{ + for( const tripoint target : targets ) { + Creature *const cr = g->critter_at( target ); + if( !cr ) { + continue; + } + + projectile bolt; + bolt.impact = sp.get_damage_instance(); + bolt.proj_effects.emplace( "magic" ); + + dealt_projectile_attack atk; + atk.end_point = target; + atk.hit_critter = cr; + atk.proj = bolt; + if( sp.damage() > 0 ) { + cr->deal_projectile_attack( &g->u, atk, true ); + } else { + sp.heal( target ); + add_msg( m_good, _( "%s wounds are closing up!" ), cr->disp_name( true ) ); + } + if( !sp.effect_data().empty() ) { + const int dur_moves = sp.duration(); + const time_duration dur_td = 1_turns * dur_moves / 100; + const std::vector all_bp = { bp_head, bp_torso, bp_arm_l, bp_arm_r, bp_leg_l, bp_leg_r, }; + for( const body_part bp : all_bp ) { + cr->add_effect( efftype_id( sp.effect_data() ), dur_td, bp ); + } + } + } +} + +void projectile_attack( spell &sp, const tripoint &source, const tripoint &target ) +{ + std::vector trajectory = line_to( source, target ); + for( const tripoint &pt : trajectory ) { + if( g->m.impassable( pt ) || pt == trajectory.back() ) { + target_attack( sp, source, target ); + } + } +} + +void target_attack( spell &sp, const tripoint &source, const tripoint &epicenter ) +{ + damage_targets( sp, spell_effect_area( sp, source, epicenter, spell_effect_blast ) ); +} + +void cone_attack( spell &sp, const tripoint &source, const tripoint &target ) +{ + damage_targets( sp, spell_effect_area( sp, source, target, spell_effect_cone ) ); +} + +void line_attack( spell &sp, const tripoint &source, const tripoint &target ) +{ + damage_targets( sp, spell_effect_area( sp, source, target, spell_effect_line ) ); +} + +void spawn_ethereal_item( spell &sp ) +{ + item granted( sp.effect_data(), calendar::turn ); + if( !granted.is_comestible() ) { + granted.set_rot( -sp.duration_turns() ); + granted.set_flag( "ETHEREAL_ITEM" ); + } + if( granted.count_by_charges() && sp.damage() > 0 ) { + granted.charges = sp.damage(); + } + if( g->u.can_wear( granted ).success() ) { + granted.set_flag( "FIT" ); + g->u.wear_item( granted, false ); + } else { + g->u.weapon = granted; + } + if( !granted.count_by_charges() ) { + for( int i = 1; i < sp.damage(); i++ ) { + g->u.i_add( granted ); + } + } +} + +} diff --git a/src/magic.h b/src/magic.h index 433691769f7f0..03d4cc8c4404b 100644 --- a/src/magic.h +++ b/src/magic.h @@ -288,7 +288,7 @@ namespace spell_effect { void teleport( int min_distance, int max_distance ); void pain_split(); // only does g->u -void shallow_pit( const tripoint &target ); +void move_earth( const tripoint &target ); void target_attack( spell &sp, const tripoint &source, const tripoint &target ); void projectile_attack( spell &sp, const tripoint &source, const tripoint &target ); void cone_attack( spell &sp, const tripoint &source, const tripoint &target ); diff --git a/src/main.cpp b/src/main.cpp index 3d302b029580b..e15322dd85c56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -110,7 +110,7 @@ struct arg_handler { //! called with the number of parameters after the flag was encountered, along with the array //! of following parameters. It must return an integer indicating how many parameters were //! consumed by the call or -1 to indicate that a required argument was missing. - typedef std::function handler_method; + using handler_method = std::function; const char *flag; //!< The commandline parameter to handle (e.g., "--seed"). const char *param_documentation; //!< Human readable description of this arguments parameter. diff --git a/src/map.cpp b/src/map.cpp index 6d09c8909fa50..f042b8c17447b 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -4831,33 +4831,8 @@ std::list use_charges_from_stack( Stack stack, const itype_id type, int &q return ret; } -int remove_charges_in_list( const itype *type, map_stack stack, int quantity ) -{ - auto target = stack.begin(); - for( ; target != stack.end(); ++target ) { - if( target->type == type ) { - break; - } - } - - if( target != stack.end() ) { - if( target->charges > quantity ) { - target->charges -= quantity; - return quantity; - } else { - const int charges = target->charges; - target->charges = 0; - if( target->destroyed_at_zero_charges() ) { - stack.erase( target ); - } - return charges; - } - } - return 0; -} - -void use_charges_from_furn( const furn_t &f, const itype_id &type, int &quantity, - map *m, const tripoint &p, std::list &ret, const std::function &filter ) +static void use_charges_from_furn( const furn_t &f, const itype_id &type, int &quantity, + map *m, const tripoint &p, std::list &ret, const std::function &filter ) { if( m->has_flag( "LIQUIDCONT", p ) ) { auto item_list = m->i_at( p ); diff --git a/src/map.h b/src/map.h index 2deceae8bf69d..4306b98d51dac 100644 --- a/src/map.h +++ b/src/map.h @@ -79,8 +79,8 @@ struct wrapped_vehicle { vehicle *v; }; -typedef std::vector VehicleList; -typedef std::string items_location; +using VehicleList = std::vector; +using items_location = std::string; class map; enum ter_bitflags : int; @@ -1220,7 +1220,8 @@ class map void place_vending( int x, int y, const std::string &type, bool reinforced = false ); // places an NPC, if static NPCs are enabled or if force is true int place_npc( int x, int y, const string_id &type, const bool force = false ); - + void apply_faction_ownership( const int x1, const int y1, const int x2, const int y2, + const faction_id id ); void add_spawn( const mtype_id &type, const int count, const int x, const int y, bool friendly = false, const int faction_id = -1, const int mission_id = -1, @@ -1588,8 +1589,8 @@ class map * It's a really heinous function pointer so a typedef is the best * solution in this instance. */ - typedef bool ( *map_process_func )( item_stack &, std::list::iterator &, const tripoint &, - const std::string &, float, temperature_flag ); + using map_process_func = bool ( * )( item_stack &, std::list::iterator &, const tripoint &, + const std::string &, float, temperature_flag ); private: // Iterates over every item on the map, passing each item to the provided function. diff --git a/src/map_extras.cpp b/src/map_extras.cpp index f1770503afd68..87b9fe70769fe 100644 --- a/src/map_extras.cpp +++ b/src/map_extras.cpp @@ -72,12 +72,12 @@ static const mtype_id mon_spider_cellar_giant( "mon_spider_cellar_giant" ); static const mtype_id mon_wasp( "mon_wasp" ); static const mtype_id mon_jabberwock( "mon_jabberwock" ); -void mx_null( map &, const tripoint & ) +static void mx_null( map &, const tripoint & ) { debugmsg( "Tried to generate null map extra." ); } -void mx_house_wasp( map &m, const tripoint & ) +static void mx_house_wasp( map &m, const tripoint & ) { for( int i = 0; i < SEEX * 2; i++ ) { for( int j = 0; j < SEEY * 2; j++ ) { @@ -114,7 +114,7 @@ void mx_house_wasp( map &m, const tripoint & ) m.place_items( "rare", 70, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, false, 0 ); } -void mx_house_spider( map &m, const tripoint & ) +static void mx_house_spider( map &m, const tripoint & ) { auto spider_type = mon_spider_widow_giant; auto egg_type = f_egg_sackbw; @@ -148,7 +148,7 @@ void mx_house_spider( map &m, const tripoint & ) } -void mx_helicopter( map &m, const tripoint &abs_sub ) +static void mx_helicopter( map &m, const tripoint &abs_sub ) { int cx = rng( 6, SEEX * 2 - 7 ); int cy = rng( 6, SEEY * 2 - 7 ); @@ -312,7 +312,7 @@ void mx_helicopter( map &m, const tripoint &abs_sub ) } } -void mx_military( map &m, const tripoint & ) +static void mx_military( map &m, const tripoint & ) { int num_bodies = dice( 2, 6 ); for( int i = 0; i < num_bodies; i++ ) { @@ -343,7 +343,7 @@ void mx_military( map &m, const tripoint & ) m.place_items( "rare", 25, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0 ); } -void mx_science( map &m, const tripoint & ) +static void mx_science( map &m, const tripoint & ) { int num_bodies = dice( 2, 5 ); for( int i = 0; i < num_bodies; i++ ) { @@ -365,7 +365,7 @@ void mx_science( map &m, const tripoint & ) m.place_items( "rare", 45, 0, 0, SEEX * 2 - 1, SEEY * 2 - 1, true, 0 ); } -void mx_collegekids( map &m, const tripoint & ) +static void mx_collegekids( map &m, const tripoint & ) { //college kids that got into trouble int num_bodies = dice( 2, 6 ); @@ -395,7 +395,7 @@ void mx_collegekids( map &m, const tripoint & ) } } -void mx_roadblock( map &m, const tripoint &abs_sub ) +static void mx_roadblock( map &m, const tripoint &abs_sub ) { std::string north = overmap_buffer.ter( abs_sub.x / 2, abs_sub.y / 2 - 1, abs_sub.z ).id().c_str(); std::string south = overmap_buffer.ter( abs_sub.x / 2, abs_sub.y / 2 + 1, abs_sub.z ).id().c_str(); @@ -528,7 +528,7 @@ void mx_roadblock( map &m, const tripoint &abs_sub ) } } -void mx_marloss_pilgrimage( map &m, const tripoint &abs_sub ) +static void mx_marloss_pilgrimage( map &m, const tripoint &abs_sub ) { const tripoint leader_pos( rng( 4, 19 ), rng( 4, 19 ), abs_sub.z ); const int max_followers = rng( 3, 12 ); @@ -546,7 +546,7 @@ void mx_marloss_pilgrimage( map &m, const tripoint &abs_sub ) } -void mx_bandits_block( map &m, const tripoint &abs_sub ) +static void mx_bandits_block( map &m, const tripoint &abs_sub ) { const oter_id &north = overmap_buffer.ter( abs_sub.x, abs_sub.y - 1, abs_sub.z ); const oter_id &south = overmap_buffer.ter( abs_sub.x, abs_sub.y + 1, abs_sub.z ); @@ -584,7 +584,7 @@ void mx_bandits_block( map &m, const tripoint &abs_sub ) } } -void mx_drugdeal( map &m, const tripoint &abs_sub ) +static void mx_drugdeal( map &m, const tripoint &abs_sub ) { // Decide on a drug type int num_drugs = 0; @@ -709,7 +709,7 @@ void mx_drugdeal( map &m, const tripoint &abs_sub ) } } -void mx_supplydrop( map &m, const tripoint &/*abs_sub*/ ) +static void mx_supplydrop( map &m, const tripoint &/*abs_sub*/ ) { int num_crates = rng( 1, 5 ); for( int i = 0; i < num_crates; i++ ) { @@ -751,7 +751,7 @@ void mx_supplydrop( map &m, const tripoint &/*abs_sub*/ ) } } -void mx_portal( map &m, const tripoint &abs_sub ) +static void mx_portal( map &m, const tripoint &abs_sub ) { int x = rng( 1, SEEX * 2 - 2 ), y = rng( 1, SEEY * 2 - 2 ); for( int i = x - 1; i <= x + 1; i++ ) { @@ -768,7 +768,7 @@ void mx_portal( map &m, const tripoint &abs_sub ) } } -void mx_minefield( map &m, const tripoint &abs_sub ) +static void mx_minefield( map &m, const tripoint &abs_sub ) { const int num_mines = rng( 6, 20 ); @@ -798,7 +798,7 @@ void mx_minefield( map &m, const tripoint &abs_sub ) m.set_signage( tripoint( x, y2, abs_sub.z ), text ); } -void mx_crater( map &m, const tripoint &abs_sub ) +static void mx_crater( map &m, const tripoint &abs_sub ) { int size = rng( 2, 6 ); int size_squared = size * size; @@ -815,7 +815,7 @@ void mx_crater( map &m, const tripoint &abs_sub ) } } -void place_fumarole( map &m, int x1, int y1, int x2, int y2, std::set &ignited ) +static void place_fumarole( map &m, int x1, int y1, int x2, int y2, std::set &ignited ) { // Tracks points nearby for ignition after the lava is placed //std::set ignited; @@ -842,7 +842,7 @@ void place_fumarole( map &m, int x1, int y1, int x2, int y2, std::set &ig } -void mx_fumarole( map &m, const tripoint &abs_sub ) +static void mx_fumarole( map &m, const tripoint &abs_sub ) { if( abs_sub.z <= 0 ) { int x1 = rng( 0, SEEX - 1 ), y1 = rng( 0, SEEY - 1 ), @@ -891,7 +891,7 @@ void mx_fumarole( map &m, const tripoint &abs_sub ) } } -void mx_portal_in( map &m, const tripoint &abs_sub ) +static void mx_portal_in( map &m, const tripoint &abs_sub ) { int x = rng( 5, SEEX * 2 - 6 ), y = rng( 5, SEEY * 2 - 6 ); m.add_field( {x, y, abs_sub.z}, fd_fatigue, 3, 0_turns ); @@ -908,7 +908,7 @@ void mx_portal_in( map &m, const tripoint &abs_sub ) } } -void mx_anomaly( map &m, const tripoint &abs_sub ) +static void mx_anomaly( map &m, const tripoint &abs_sub ) { tripoint center( rng( 6, SEEX * 2 - 7 ), rng( 6, SEEY * 2 - 7 ), abs_sub.z ); artifact_natural_property prop = @@ -917,7 +917,7 @@ void mx_anomaly( map &m, const tripoint &abs_sub ) m.spawn_natural_artifact( center, prop ); } -void mx_shia( map &m, const tripoint & ) +static void mx_shia( map &m, const tripoint & ) { // A rare chance to spawn Shia. This was extracted from the hardcoded forest mapgen // and moved into a map extra, but it still has a one_in chance of spawning because @@ -928,7 +928,7 @@ void mx_shia( map &m, const tripoint & ) } } -void mx_spider( map &m, const tripoint &abs_sub ) +static void mx_spider( map &m, const tripoint &abs_sub ) { // This was extracted from the hardcoded forest mapgen and slightly altered so // that it used flags rather than specific terrain types in determining where to @@ -953,7 +953,7 @@ void mx_spider( map &m, const tripoint &abs_sub ) m.add_spawn( mon_spider_web, rng( 1, 2 ), SEEX, SEEY ); } -void mx_jabberwock( map &m, const tripoint & ) +static void mx_jabberwock( map &m, const tripoint & ) { // A rare chance to spawn a jabberwock. This was extracted from the harcoded forest mapgen // and moved into a map extra. It still has a one_in chance of spawning because otherwise @@ -965,7 +965,7 @@ void mx_jabberwock( map &m, const tripoint & ) } } -void mx_grove( map &m, const tripoint &abs_sub ) +static void mx_grove( map &m, const tripoint &abs_sub ) { // From wikipedia - The main meaning of "grove" is a group of trees that grow close together, // generally without many bushes or other plants underneath. @@ -1000,7 +1000,7 @@ void mx_grove( map &m, const tripoint &abs_sub ) } } -void mx_shrubbery( map &m, const tripoint &abs_sub ) +static void mx_shrubbery( map &m, const tripoint &abs_sub ) { // This map extra finds the first shrub in the area, and then converts all trees, young trees, // and shrubs in the area into that type of shrub. @@ -1032,7 +1032,7 @@ void mx_shrubbery( map &m, const tripoint &abs_sub ) } } -void mx_clearcut( map &m, const tripoint &abs_sub ) +static void mx_clearcut( map &m, const tripoint &abs_sub ) { // From wikipedia - Clearcutting, clearfelling or clearcut logging is a forestry/logging // practice in which most or all trees in an area are uniformly cut down. @@ -1051,7 +1051,7 @@ void mx_clearcut( map &m, const tripoint &abs_sub ) } } -void mx_pond( map &m, const tripoint &abs_sub ) +static void mx_pond( map &m, const tripoint &abs_sub ) { // This map extra creates small ponds using a simple cellular automaton. @@ -1097,7 +1097,7 @@ void mx_pond( map &m, const tripoint &abs_sub ) m.place_spawns( GROUP_FISH, 1, 0, 0, width, height, 0.15f ); } -void mx_clay_deposit( map &m, const tripoint &abs_sub ) +static void mx_clay_deposit( map &m, const tripoint &abs_sub ) { // This map extra creates small clay deposits using a simple cellular automaton. @@ -1140,7 +1140,7 @@ void mx_clay_deposit( map &m, const tripoint &abs_sub ) } } -typedef std::unordered_map FunctionMap; +using FunctionMap = std::unordered_map; FunctionMap builtin_functions = { { "mx_null", mx_null }, { "mx_house_wasp", mx_house_wasp }, diff --git a/src/map_iterator.h b/src/map_iterator.h index aa0a32219dafa..f8649cf6fb66a 100644 --- a/src/map_iterator.h +++ b/src/map_iterator.h @@ -19,11 +19,11 @@ class tripoint_range tripoint p; const tripoint_range ⦥ public: - typedef tripoint value_type; - typedef std::ptrdiff_t difference_type; - typedef tripoint *pointer; - typedef tripoint &reference; - typedef std::forward_iterator_tag iterator_category; + using value_type = tripoint; + using difference_type = std::ptrdiff_t; + using pointer = tripoint *; + using reference = tripoint &; + using iterator_category = std::forward_iterator_tag; point_generator( const tripoint &_p, const tripoint_range &_range ) : p( _p ), range( _range ) { @@ -67,11 +67,11 @@ class tripoint_range tripoint minp; tripoint maxp; public: - typedef point_generator::value_type value_type; - typedef point_generator::difference_type difference_type; - typedef point_generator::pointer pointer; - typedef point_generator::reference reference; - typedef point_generator::iterator_category iterator_category; + using value_type = point_generator::value_type; + using difference_type = point_generator::difference_type; + using pointer = point_generator::pointer; + using reference = point_generator::reference; + using iterator_category = point_generator::iterator_category; tripoint_range( const tripoint &_minp, const tripoint &_maxp ) : minp( _minp ), maxp( _maxp ) { diff --git a/src/map_selector.h b/src/map_selector.h index 1ff45322216e1..354931536e07f 100644 --- a/src/map_selector.h +++ b/src/map_selector.h @@ -18,12 +18,12 @@ class map_selector : public visitable friend visitable; public: - typedef map_cursor value_type; - typedef std::vector::size_type size_type; - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; - typedef std::vector::reference reference; - typedef std::vector::const_reference const_reference; + using value_type = map_cursor; + using size_type = std::vector::size_type; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + using reference = std::vector::reference; + using const_reference = std::vector::const_reference; /** * Constructs map_selector used for querying items located on map tiles diff --git a/src/mapbuffer.h b/src/mapbuffer.h index e671d64368788..3eb4b4b65ba18 100644 --- a/src/mapbuffer.h +++ b/src/mapbuffer.h @@ -58,7 +58,7 @@ class mapbuffer submap *lookup_submap( const tripoint &p ); private: - typedef std::map submap_map_t; + using submap_map_t = std::map; public: inline submap_map_t::iterator begin() { diff --git a/src/mapdata.cpp b/src/mapdata.cpp index aea73c3100cd4..fe5eb02d32ac2 100644 --- a/src/mapdata.cpp +++ b/src/mapdata.cpp @@ -180,7 +180,7 @@ static const std::unordered_map ter_connects_map = { } }; -void load_map_bash_tent_centers( JsonArray ja, std::vector ¢ers ) +static void load_map_bash_tent_centers( JsonArray ja, std::vector ¢ers ) { while( ja.has_more() ) { centers.emplace_back( ja.next_string() ); @@ -1138,7 +1138,7 @@ void ter_t::load( JsonObject &jo, const std::string &src ) deconstruct.load( jo, "deconstruct", false ); } -void check_bash_items( const map_bash_info &mbi, const std::string &id, bool is_terrain ) +static void check_bash_items( const map_bash_info &mbi, const std::string &id, bool is_terrain ) { if( !item_group::group_is_defined( mbi.drop_group ) ) { debugmsg( "%s: bash result item group %s does not exist", id.c_str(), mbi.drop_group.c_str() ); @@ -1156,7 +1156,8 @@ void check_bash_items( const map_bash_info &mbi, const std::string &id, bool is_ } } -void check_decon_items( const map_deconstruct_info &mbi, const std::string &id, bool is_terrain ) +static void check_decon_items( const map_deconstruct_info &mbi, const std::string &id, + bool is_terrain ) { if( !mbi.can_do ) { return; diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 4a0c1eb4b603d..2e5faa1ed38bf 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -33,6 +33,7 @@ #include "mapdata.h" #include "mapgen_functions.h" #include "mapgenformat.h" +#include "messages.h" #include "mission.h" #include "mongroup.h" #include "mtype.h" @@ -309,8 +310,8 @@ bool defer; JsonObject jsi; } -void set_mapgen_defer( const JsonObject &jsi, const std::string &member, - const std::string &message ) +static void set_mapgen_defer( const JsonObject &jsi, const std::string &member, + const std::string &message ) { mapgen_defer::defer = true; mapgen_defer::jsi = jsi; @@ -372,7 +373,7 @@ load_mapgen_function( JsonObject &jio, const std::string &id_base, return ret; } -void load_nested_mapgen( JsonObject &jio, const std::string &id_base ) +static void load_nested_mapgen( JsonObject &jio, const std::string &id_base ) { const std::string mgtype = jio.get_string( "method" ); if( mgtype == "json" ) { @@ -390,7 +391,7 @@ void load_nested_mapgen( JsonObject &jio, const std::string &id_base ) } } -void load_update_mapgen( JsonObject &jio, const std::string &id_base ) +static void load_update_mapgen( JsonObject &jio, const std::string &id_base ) { const std::string mgtype = jio.get_string( "method" ); if( mgtype == "json" ) { @@ -481,8 +482,9 @@ size_t mapgen_function_json_base::calc_index( const size_t x, const size_t y ) c return y * mapgensize_y + x; } -bool common_check_bounds( const jmapgen_int &x, const jmapgen_int &y, const int mapgensize_x, - const int mapgensize_y, JsonObject &jso ) +static bool common_check_bounds( const jmapgen_int &x, const jmapgen_int &y, + const int mapgensize_x, const int mapgensize_y, + JsonObject &jso ) { if( x.val < 0 || x.val > mapgensize_x - 1 || y.val < 0 || y.val > mapgensize_y - 1 ) { return false; @@ -551,6 +553,8 @@ jmapgen_int::jmapgen_int( JsonObject &jo, const std::string &tag ) val = sparray.get_int( 0 ); if( sparray.size() == 2 ) { valmax = sparray.get_int( 1 ); + } else { + valmax = val; } } else { val = valmax = jo.get_int( tag ); @@ -801,6 +805,24 @@ class jmapgen_npc : public jmapgen_piece } } }; +/** +* Place ownership area +*/ +class jmapgen_faction : public jmapgen_piece +{ + public: + faction_id id; + jmapgen_faction( JsonObject &jsi ) : jmapgen_piece() { + if( jsi.has_string( "id" ) ) { + id = faction_id( jsi.get_string( "id" ) ); + std::string facid = jsi.get_string( "id" ); + } + } + void apply( const mapgendata &dat, const jmapgen_int &x, const jmapgen_int &y, + const float /*mdensity*/, mission * ) const override { + dat.m.apply_faction_ownership( x.val, y.val, x.valmax, y.valmax, id ); + } +}; /** * Place a sign with some text. * "signage": the text on the sign. @@ -2132,7 +2154,7 @@ mapgen_palette mapgen_palette::load_internal( JsonObject &jo, const std::string new_pal.load_place_mapings( jo, "graffiti", format_placings ); new_pal.load_place_mapings( jo, "translate", format_placings ); new_pal.load_place_mapings( jo, "zones", format_placings ); - + new_pal.load_place_mapings( jo, "faction_owner_character", format_placings ); return new_pal; } @@ -2317,7 +2339,8 @@ bool mapgen_function_json_base::setup_common( JsonObject jo ) objects.load_objects( jo, "place_graffiti" ); objects.load_objects( jo, "translate_ter" ); objects.load_objects( jo, "place_zones" ); - + // Needs to be last as it affects other placed items + objects.load_objects( jo, "faction_owner" ); if( !mapgen_defer::defer ) { is_ready = true; // skip setup attempts from any additional pointers } @@ -6914,6 +6937,19 @@ int map::place_npc( int x, int y, const string_id &type, bool forc return temp->getID(); } +void map::apply_faction_ownership( const int x1, const int y1, const int x2, const int y2, + const faction_id id ) +{ + faction *fac = g->faction_manager_ptr->get( id ); + for( const tripoint &p : points_in_rectangle( tripoint( x1, y1, abs_sub.z ), tripoint( x2, y2, + abs_sub.z ) ) ) { + auto items = i_at( p.x, p.y ); + for( item &elem : items ) { + elem.set_owner( fac ); + } + } +} + std::vector map::place_items( const items_location &loc, const int chance, const tripoint &f, const tripoint &t, const bool ongrass, const time_point &turn, @@ -8246,10 +8282,6 @@ void fill_background( map *m, ter_id( *f )() ) { m->draw_fill_background( f ); } -void fill_background( map *m, const weighted_int_list &f ) -{ - m->draw_fill_background( f ); -} void square( map *m, ter_id type, int x1, int y1, int x2, int y2 ) { m->draw_square_ter( type, x1, y1, x2, y2 ); @@ -8262,10 +8294,6 @@ void square( map *m, ter_id( *f )(), int x1, int y1, int x2, int y2 ) { m->draw_square_ter( f, x1, y1, x2, y2 ); } -void square( map *m, const weighted_int_list &f, int x1, int y1, int x2, int y2 ) -{ - m->draw_square_ter( f, x1, y1, x2, y2 ); -} void rough_circle( map *m, ter_id type, int x, int y, int rad ) { m->draw_rough_circle_ter( type, x, y, rad ); diff --git a/src/mapgen.h b/src/mapgen.h index 39f9bd4d24af7..f59ae56434149 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -9,6 +9,8 @@ #include #include +#include "faction.h" +#include "int_id.h" #include "mapgen_functions.h" #include "regional_settings.h" #include "type_id.h" @@ -21,7 +23,7 @@ class mission; struct tripoint; class map; -typedef void ( *building_gen_pointer )( map *, oter_id, mapgendata, const time_point &, float ); +using building_gen_pointer = void ( * )( map *, oter_id, mapgendata, const time_point &, float ); ////////////////////////////////////////////////////////////////////////// ///// function pointer class; provides abstract referencing of @@ -294,6 +296,7 @@ class mapgen_function_json_base void setup_common(); bool setup_common( JsonObject jo ); void setup_setmap( JsonArray &parray ); + void set_faction_owner( JsonObject jo ); // Returns true if the mapgen qualifies at this point already virtual bool setup_internal( JsonObject &jo ) = 0; virtual void setup_setmap_internal() { } @@ -440,6 +443,6 @@ void circle( map *m, ter_id type, int x, int y, int rad ); void circle_furn( map *m, furn_id type, int x, int y, int rad ); void add_corpse( map *m, int x, int y ); -typedef void ( *map_special_pointer )( map &m, const tripoint &abs_sub ); +using map_special_pointer = void ( * )( map &, const tripoint & ); #endif diff --git a/src/mapgen_functions.cpp b/src/mapgen_functions.cpp index 83af5ae38c53b..2cc38257eaa59 100644 --- a/src/mapgen_functions.cpp +++ b/src/mapgen_functions.cpp @@ -375,7 +375,7 @@ void mapgen_crater( map *m, oter_id, mapgendata dat, const time_point &turn, flo } // TODO: make void map::ter_or_furn_set(const int x, const int y, const ter_furn_id & tfid); -void ter_or_furn_set( map *m, const int x, const int y, const ter_furn_id &tfid ) +static void ter_or_furn_set( map *m, const int x, const int y, const ter_furn_id &tfid ) { if( tfid.ter != t_null ) { m->ter_set( x, y, tfid.ter ); @@ -786,7 +786,7 @@ void nesw_array_rotate( T *array, size_t len, size_t dist ) } // take x/y coordinates in a map and rotate them counterclockwise around the center -void coord_rotate_cw( int &x, int &y, int rot ) +static void coord_rotate_cw( int &x, int &y, int rot ) { for( ; rot--; ) { int temp = y; @@ -795,7 +795,7 @@ void coord_rotate_cw( int &x, int &y, int rot ) } } -bool compare_neswx( bool *a1, std::initializer_list a2 ) +static bool compare_neswx( bool *a1, std::initializer_list a2 ) { return std::equal( std::begin( a2 ), std::end( a2 ), a1, []( int a, bool b ) { @@ -2841,7 +2841,7 @@ void mapgen_basement_generic_layout( map *m, oter_id, mapgendata, const time_poi namespace furn_space { -bool clear( const map &m, const tripoint &from, const tripoint &to ) +static bool clear( const map &m, const tripoint &from, const tripoint &to ) { for( const auto &p : m.points_in_rectangle( from, to ) ) { if( m.ter( p ).obj().movecost == 0 ) { @@ -2852,7 +2852,7 @@ bool clear( const map &m, const tripoint &from, const tripoint &to ) return true; } -point best_expand( const map &m, const tripoint &from, int maxx, int maxy ) +static point best_expand( const map &m, const tripoint &from, int maxx, int maxy ) { if( clear( m, from, from + point( maxx, maxy ) ) ) { // Common case @@ -3596,8 +3596,8 @@ void mapgen_ants_tee( map *m, oter_id terrain_type, mapgendata dat, const time_p } -void mapgen_ants_generic( map *m, oter_id terrain_type, mapgendata dat, const time_point &turn, - float ) +static void mapgen_ants_generic( map *m, oter_id terrain_type, mapgendata dat, + const time_point &turn, float ) { for( int i = 0; i < SEEX * 2; i++ ) { @@ -4582,7 +4582,7 @@ void madd_field( map *m, int x, int y, field_id type, int density ) m->add_field( actual_location, type, density, 0_turns ); } -bool is_suitable_for_stairs( const map *const m, const tripoint &p ) +static bool is_suitable_for_stairs( const map *const m, const tripoint &p ) { const ter_t &p_ter = m->ter( p ).obj(); @@ -4592,8 +4592,8 @@ bool is_suitable_for_stairs( const map *const m, const tripoint &p ) m->furn( p ) == f_null; } -void stairs_debug_log( const map *const m, const std::string &msg, const tripoint &p, - DebugLevel level = D_INFO ) +static void stairs_debug_log( const map *const m, const std::string &msg, const tripoint &p, + DebugLevel level = D_INFO ) { const ter_t &p_ter = m->ter( p ).obj(); diff --git a/src/mapgen_functions.h b/src/mapgen_functions.h index b9ba5d264f29a..cd870ff12a4f1 100644 --- a/src/mapgen_functions.h +++ b/src/mapgen_functions.h @@ -94,7 +94,7 @@ tripoint rotate_point( const tripoint &p, int turn ); int terrain_type_to_nesw_array( oter_id terrain_type, bool array[4] ); // TODO: pass mapgendata by reference. -typedef void ( *building_gen_pointer )( map *, oter_id, mapgendata, const time_point &, float ); +using building_gen_pointer = void ( * )( map *, oter_id, mapgendata, const time_point &, float ); building_gen_pointer get_mapgen_cfunction( const std::string &ident ); ter_id grass_or_dirt(); ter_id clay_or_sand(); diff --git a/src/martialarts.cpp b/src/martialarts.cpp index 979d73b5b8b4a..1575ec4394383 100644 --- a/src/martialarts.cpp +++ b/src/martialarts.cpp @@ -199,6 +199,7 @@ void martialart::load( JsonObject &jo, const std::string & ) mandatory( jo, was_loaded, "name", name ); mandatory( jo, was_loaded, "description", description ); mandatory( jo, was_loaded, "initiate", initiate ); + optional( jo, was_loaded, "autolearn", autolearn_skills ); optional( jo, was_loaded, "static_buffs", static_buffs, ma_buff_reader{} ); optional( jo, was_loaded, "onmove_buffs", onmove_buffs, ma_buff_reader{} ); @@ -207,6 +208,9 @@ void martialart::load( JsonObject &jo, const std::string & ) optional( jo, was_loaded, "ondodge_buffs", ondodge_buffs, ma_buff_reader{} ); optional( jo, was_loaded, "onblock_buffs", onblock_buffs, ma_buff_reader{} ); optional( jo, was_loaded, "ongethit_buffs", ongethit_buffs, ma_buff_reader{} ); + optional( jo, was_loaded, "onmiss_buffs", onmiss_buffs, ma_buff_reader{} ); + optional( jo, was_loaded, "oncrit_buffs", oncrit_buffs, ma_buff_reader{} ); + optional( jo, was_loaded, "onkill_buffs", onkill_buffs, ma_buff_reader{} ); optional( jo, was_loaded, "techniques", techniques, auto_flags_reader {} ); optional( jo, was_loaded, "weapons", weapons, auto_flags_reader {} ); @@ -247,7 +251,7 @@ std::vector all_martialart_types() return result; } -void check( const ma_requirements &req, const std::string &display_text ) +static void check( const ma_requirements &req, const std::string &display_text ) { for( auto &r : req.req_buffs ) { if( !r.is_valid() ) { @@ -583,7 +587,7 @@ martialart::martialart() // simultaneously check and add all buffs. this is so that buffs that have // buff dependencies added by the same event trigger correctly -void simultaneous_add( player &u, const std::vector &buffs ) +static void simultaneous_add( player &u, const std::vector &buffs ) { std::vector buffer; // hey get it because it's for buffs???? for( auto &buffid : buffs ) { @@ -632,6 +636,21 @@ void martialart::apply_ongethit_buffs( player &u ) const simultaneous_add( u, ongethit_buffs ); } +void martialart::apply_onmiss_buffs( player &u ) const +{ + simultaneous_add( u, onmiss_buffs ); +} + +void martialart::apply_oncrit_buffs( player &u ) const +{ + simultaneous_add( u, oncrit_buffs ); +} + +void martialart::apply_onkill_buffs( player &u ) const +{ + simultaneous_add( u, onkill_buffs ); +} + bool martialart::has_technique( const player &u, const matec_id &tec_id ) const { for( const auto &elem : techniques ) { @@ -780,6 +799,18 @@ void player::ma_ongethit_effects() { style_selected.obj().apply_ongethit_buffs( *this ); } +void player::ma_onmiss_effects() +{ + style_selected.obj().apply_onmiss_buffs( *this ); +} +void player::ma_oncrit_effects() +{ + style_selected.obj().apply_oncrit_buffs( *this ); +} +void player::ma_onkill_effects() +{ + style_selected.obj().apply_onkill_buffs( *this ); +} template static void accumulate_ma_buff_effects( const C &container, F f ) @@ -926,6 +957,25 @@ void player::add_martialart( const matype_id &ma_id ) ma_styles.push_back( ma_id ); } +bool player::can_autolearn( const matype_id &ma_id ) const +{ + if( ma_id.obj().autolearn_skills.empty() ) { + return false; + } + + const std::vector> skills = ma_id.obj().autolearn_skills; + for( auto &elem : skills ) { + const skill_id skill_req( elem[0] ); + const int required_level = std::stoi( elem[1] ); + + if( required_level > get_skill_level( skill_req ) ) { + return false; + } + } + + return true; +} + float ma_technique::damage_bonus( const player &u, damage_type type ) const { return bonuses.get_flat( u, AFFECTED_DAMAGE, type ); @@ -1054,7 +1104,10 @@ bool ma_style_callback::key( const input_context &ctxt, const input_event &event buff_desc( _( "Passive" ), ma.static_buffs, true ); buff_desc( _( "Move" ), ma.onmove_buffs ); buff_desc( _( "Hit" ), ma.onhit_buffs ); + buff_desc( _( "Miss" ), ma.onmiss_buffs ); buff_desc( _( "Attack" ), ma.onattack_buffs ); + buff_desc( _( "Crit" ), ma.oncrit_buffs ); + buff_desc( _( "Kill" ), ma.onkill_buffs ); buff_desc( _( "Dodge" ), ma.ondodge_buffs ); buff_desc( _( "Block" ), ma.onblock_buffs ); buff_desc( _( "Get hit" ), ma.ongethit_buffs ); diff --git a/src/martialarts.h b/src/martialarts.h index 93a733c397193..dc9f1fc90f3d5 100644 --- a/src/martialarts.h +++ b/src/martialarts.h @@ -203,6 +203,12 @@ class martialart void apply_ongethit_buffs( player &u ) const; + void apply_onmiss_buffs( player &u ) const; + + void apply_oncrit_buffs( player &u ) const; + + void apply_onkill_buffs( player &u ) const; + // determines if a technique is valid or not for this style bool has_technique( const player &u, const matec_id &tech ) const; // determines if a weapon is valid for this style @@ -219,6 +225,7 @@ class martialart std::string name; std::string description; std::vector initiate; + std::vector> autolearn_skills; int arm_block; int leg_block; bool arm_block_with_bio_armor_arms; @@ -234,6 +241,9 @@ class martialart std::vector ondodge_buffs; std::vector onblock_buffs; std::vector ongethit_buffs; + std::vector onmiss_buffs; + std::vector oncrit_buffs; + std::vector onkill_buffs; }; class ma_style_callback : public uilist_callback diff --git a/src/material.cpp b/src/material.cpp index 3aac239c4c988..23384a3f47dc1 100644 --- a/src/material.cpp +++ b/src/material.cpp @@ -44,7 +44,7 @@ material_type::material_type() : _dmg_adj = { translate_marker( "lightly damaged" ), translate_marker( "damaged" ), translate_marker( "very damaged" ), translate_marker( "thoroughly damaged" ) }; } -mat_burn_data load_mat_burn_data( JsonObject &jsobj ) +static mat_burn_data load_mat_burn_data( JsonObject &jsobj ) { mat_burn_data bd; assign( jsobj, "immune", bd.immune ); diff --git a/src/mattack_actors.cpp b/src/mattack_actors.cpp index da84e11e45c55..a624f7aa2b091 100644 --- a/src/mattack_actors.cpp +++ b/src/mattack_actors.cpp @@ -35,7 +35,7 @@ const efftype_id effect_poison( "poison" ); const efftype_id effect_badpoison( "badpoison" ); // Simplified version of the function in monattack.cpp -bool is_adjacent( const monster &z, const Creature &target ) +static bool is_adjacent( const monster &z, const Creature &target ) { if( rl_dist( z.pos(), target.pos() ) != 1 ) { return false; @@ -44,14 +44,6 @@ bool is_adjacent( const monster &z, const Creature &target ) return z.posz() == target.posz(); } -// Modified version of the function on monattack.cpp -bool dodge_check( float max_accuracy, Creature &target ) -{ - ///\EFFECT_DODGE increases chance of dodging special attacks of monsters - float dodge = std::max( target.get_dodge() - rng( 0, max_accuracy ), 0.0f ); - return rng( 0, 10000 ) < 10000 / ( 1 + 99 * exp( -0.6f * dodge ) ); -} - void leap_actor::load_internal( JsonObject &obj, const std::string & ) { // Mandatory: diff --git a/src/melee.cpp b/src/melee.cpp index c4325e0e061af..7646f05399700 100644 --- a/src/melee.cpp +++ b/src/melee.cpp @@ -431,6 +431,8 @@ void player::melee_attack( Creature &t, bool allow_special, const matec_id &forc if( has_miss_recovery_tec( cur_weapon ) ) { move_cost /= 2; } + + ma_onmiss_effects(); // trigger martial arts on-miss effects } else { // Remember if we see the monster at start - it may change const bool seen = g->u.sees( t ); @@ -503,9 +505,18 @@ void player::melee_attack( Creature &t, bool allow_special, const matec_id &forc if( !specialmsg.empty() ) { add_msg_if_player( m_neutral, specialmsg ); } + + if( critical_hit ) { + ma_oncrit_effects(); // trigger martial arts on-crit effects + } + } t.check_dead_state(); + + if( t.is_dead_state() ) { + ma_onkill_effects(); // trigger martial arts on-kill effects + } } const int melee = get_skill_level( skill_melee ); @@ -1163,7 +1174,7 @@ bool player::has_technique( const matec_id &id, const item &weap ) const style_selected.obj().has_technique( *this, id ); } -damage_unit &get_damage_unit( std::vector &di, const damage_type dt ) +static damage_unit &get_damage_unit( std::vector &di, const damage_type dt ) { static damage_unit nullunit( DT_NULL, 0, 0, 0, 0 ); for( auto &du : di ) { @@ -1175,7 +1186,7 @@ damage_unit &get_damage_unit( std::vector &di, const damage_type dt return nullunit; } -void print_damage_info( const damage_instance &di ) +static void print_damage_info( const damage_instance &di ) { if( !debug_mode ) { return; @@ -1294,7 +1305,7 @@ void player::perform_technique( const ma_technique &technique, Creature &t, dama } } -int blocking_ability( const item &shield ) +static int blocking_ability( const item &shield ) { int block_bonus = 0; if( shield.has_technique( WBLOCK_3 ) ) { @@ -1630,7 +1641,7 @@ std::string player::melee_special_effects( Creature &t, damage_instance &d, item return dump.str(); } -damage_instance hardcoded_mutation_attack( const player &u, const trait_id &id ) +static damage_instance hardcoded_mutation_attack( const player &u, const trait_id &id ) { if( id == "BEAK_PECK" ) { // method open to improvement, please feel free to suggest diff --git a/src/mingw.thread.h b/src/mingw.thread.h index a37f664de01e8..c49ce2a981010 100644 --- a/src/mingw.thread.h +++ b/src/mingw.thread.h @@ -46,7 +46,7 @@ class thread HANDLE mHandle; id mThreadId; public: - typedef HANDLE native_handle_type; + using native_handle_type = HANDLE; id get_id() const noexcept { return mThreadId; } @@ -61,7 +61,7 @@ class thread } template explicit thread( Function &&f, Args &&... args ) { - typedef decltype( std::bind( f, args... ) ) Call; + using Call = decltype( std::bind( f, args... ) ); Call *call = new Call( std::bind( f, args... ) ); mHandle = ( HANDLE )_beginthreadex( NULL, 0, threadfunc, ( LPVOID )call, 0, ( unsigned * ) & ( mThreadId.mId ) ); diff --git a/src/mission_companion.cpp b/src/mission_companion.cpp index c37022cb08b2f..0cbdac1710d71 100644 --- a/src/mission_companion.cpp +++ b/src/mission_companion.cpp @@ -574,7 +574,7 @@ bool talk_function::display_and_choose_opts( mission_data &mission_key, const tr } else if( action == "HELP_KEYBINDINGS" ) { g->draw_ter(); wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); redraw = true; } } @@ -639,7 +639,7 @@ bool talk_function::handle_outpost_mission( const mission_entry &cur_key, npc &p g->draw_ter(); wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); return true; } @@ -1144,7 +1144,7 @@ void talk_function::field_harvest( npc &p, const std::string &place ) } -int scavenging_combat_skill( npc &p, int bonus, bool guns ) +static int scavenging_combat_skill( npc &p, int bonus, bool guns ) { // the following doxygen aliases do not yet exist. this is marked for future reference ///\EFFECT_MELEE_NPC affects scavenging_patrol results @@ -1768,7 +1768,7 @@ std::vector talk_function::companion_list( const npc &p, const std::str return available; } -int companion_combat_rank( const npc &p ) +static int companion_combat_rank( const npc &p ) { int combat = 2 * p.get_dex() + 3 * p.get_str() + 2 * p.get_per() + p.get_int(); combat += p.get_skill_level( skill_archery ) + p.get_skill_level( skill_bashing ) + @@ -1777,7 +1777,7 @@ int companion_combat_rank( const npc &p ) return combat * std::min( p.get_dex(), 32 ) * std::min( p.get_str(), 32 ) / 64; } -int companion_survival_rank( const npc &p ) +static int companion_survival_rank( const npc &p ) { int survival = 2 * p.get_dex() + p.get_str() + 2 * p.get_per() + 1.5 * p.get_int(); survival += p.get_skill_level( skill_archery ) + p.get_skill_level( skill_firstaid ) + @@ -1786,7 +1786,7 @@ int companion_survival_rank( const npc &p ) return survival * std::min( p.get_dex(), 32 ) * std::min( p.get_per(), 32 ) / 64; } -int companion_industry_rank( const npc &p ) +static int companion_industry_rank( const npc &p ) { int industry = p.get_dex() + p.get_str() + p.get_per() + 3 * p.get_int(); industry += p.get_skill_level( skill_cooking ) + p.get_skill_level( skill_electronics ) + @@ -1795,7 +1795,7 @@ int companion_industry_rank( const npc &p ) return industry * std::min( p.get_int(), 32 ) / 8 ; } -bool companion_sort_compare( const npc_ptr &first, const npc_ptr &second ) +static bool companion_sort_compare( const npc_ptr &first, const npc_ptr &second ) { return companion_combat_rank( *first ) > companion_combat_rank( *second ); } diff --git a/src/mission_util.cpp b/src/mission_util.cpp index 5cc9ffafec6d2..d92b07d58d3bb 100644 --- a/src/mission_util.cpp +++ b/src/mission_util.cpp @@ -25,7 +25,7 @@ #include "translations.h" #include "type_id.h" -const tripoint reveal_destination( const std::string &type ) +static const tripoint reveal_destination( const std::string &type ) { const tripoint your_pos = g->u.global_omt_location(); const tripoint center_pos = overmap_buffer.find_random( your_pos, type, rng( 40, 80 ), false ); @@ -38,7 +38,7 @@ const tripoint reveal_destination( const std::string &type ) return overmap::invalid_tripoint; } -void reveal_route( mission *miss, const tripoint &destination ) +static void reveal_route( mission *miss, const tripoint &destination ) { const npc *p = g->find_npc( miss->get_npc_id() ); if( p == nullptr ) { @@ -56,7 +56,7 @@ void reveal_route( mission *miss, const tripoint &destination ) } } -void reveal_target( mission *miss, const std::string &omter_id ) +static void reveal_target( mission *miss, const std::string &omter_id ) { const npc *p = g->find_npc( miss->get_npc_id() ); if( p == nullptr ) { @@ -76,7 +76,7 @@ void reveal_target( mission *miss, const std::string &omter_id ) } } -void reveal_any_target( mission *miss, const std::vector &omter_ids ) +static void reveal_any_target( mission *miss, const std::vector &omter_ids ) { reveal_target( miss, random_entry( omter_ids ) ); } @@ -108,7 +108,7 @@ tripoint mission_util::reveal_om_ter( const std::string &omter, int reveal_rad, * Given a (valid!) city reference, select a random house within the city borders. * @return global overmap terrain coordinates of the house. */ -tripoint random_house_in_city( const city_reference &cref ) +static tripoint random_house_in_city( const city_reference &cref ) { const auto city_center_omt = sm_to_omt_copy( cref.abs_sm_pos ); const auto size = cref.city->size; @@ -167,7 +167,7 @@ tripoint mission_util::target_closest_lab_entrance( const tripoint &origin, int return closest; } -cata::optional find_or_create_om_terrain( const tripoint &origin_pos, +static cata::optional find_or_create_om_terrain( const tripoint &origin_pos, const mission_target_params ¶ms ) { tripoint target_pos = overmap::invalid_tripoint; @@ -232,7 +232,7 @@ cata::optional find_or_create_om_terrain( const tripoint &origin_pos, return target_pos; } -tripoint get_mission_om_origin( const mission_target_params ¶ms ) +static tripoint get_mission_om_origin( const mission_target_params ¶ms ) { // use the player or NPC's current position, adjust for the z value if any tripoint origin_pos = g->u.global_omt_location(); diff --git a/src/mod_manager.h b/src/mod_manager.h index 634ca1912370a..c485ae008d001 100644 --- a/src/mod_manager.h +++ b/src/mod_manager.h @@ -15,7 +15,7 @@ struct WORLD; -typedef WORLD *WORLDPTR; +using WORLDPTR = WORLD *; class dependency_tree; class JsonObject; class mod_manager; @@ -67,7 +67,7 @@ struct MOD_INFORMATION { class mod_manager { public: - typedef std::vector t_mod_list; + using t_mod_list = std::vector; mod_manager(); ~mod_manager(); diff --git a/src/monattack.cpp b/src/monattack.cpp index a5a763ee518b2..ce56731b345c6 100644 --- a/src/monattack.cpp +++ b/src/monattack.cpp @@ -147,12 +147,12 @@ static const trait_id trait_THRESH_MARLOSS( "THRESH_MARLOSS" ); static const trait_id trait_THRESH_MYCUS( "THRESH_MYCUS" ); // shared utility functions -bool within_visual_range( monster *z, int max_range ) +static bool within_visual_range( monster *z, int max_range ) { return !( rl_dist( z->pos(), g->u.pos() ) > max_range || !z->sees( g->u ) ); } -bool within_target_range( const monster *const z, const Creature *const target, int range ) +static bool within_target_range( const monster *const z, const Creature *const target, int range ) { if( target == nullptr || rl_dist( z->pos(), target->pos() ) > range || @@ -162,7 +162,7 @@ bool within_target_range( const monster *const z, const Creature *const target, return true; } -Creature *sting_get_target( monster *z, float range = 5.0f ) +static Creature *sting_get_target( monster *z, float range = 5.0f ) { Creature *target = z->attack_target(); @@ -173,7 +173,7 @@ Creature *sting_get_target( monster *z, float range = 5.0f ) return rl_dist( z->pos(), target->pos() ) <= range ? target : nullptr; } -bool sting_shoot( monster *z, Creature *target, damage_instance &dam ) +static bool sting_shoot( monster *z, Creature *target, damage_instance &dam ) { if( target->uncanny_dodge() ) { target->add_msg_if_player( m_bad, _( "The %s shoots a dart but you dodge it." ), @@ -197,7 +197,7 @@ bool sting_shoot( monster *z, Creature *target, damage_instance &dam ) // If allow_zlev is false, don't allow attacking up/down at all. // If allow_zlev is true, also allow distance == 1 and on different z-level // as long as floor/ceiling doesn't exist. -bool is_adjacent( const monster *z, const Creature *target, const bool allow_zlev ) +static bool is_adjacent( const monster *z, const Creature *target, const bool allow_zlev ) { if( target == nullptr ) { return false; @@ -223,7 +223,7 @@ bool is_adjacent( const monster *z, const Creature *target, const bool allow_zle return g->m.ter( up ) == t_open_air && g->m.is_outside( down ); } -npc make_fake_npc( monster *z, int str, int dex, int inte, int per ) +static npc make_fake_npc( monster *z, int str, int dex, int inte, int per ) { npc tmp; tmp.name = _( "The " ) + z->name(); @@ -1051,7 +1051,7 @@ find_empty_neighbors( const Creature &c ) /** * Get a size_t value in the closed interval [0, size]; a convenience to avoid messy casting. */ -size_t get_random_index( const size_t size ) +static size_t get_random_index( const size_t size ) { return static_cast( rng( 0, static_cast( size - 1 ) ) ); } @@ -1267,7 +1267,7 @@ bool mattack::science( monster *const z ) // I said SCIENCE again! return true; } -body_part body_part_hit_by_plant() +static body_part body_part_hit_by_plant() { body_part hit = num_bp; if( one_in( 2 ) ) { @@ -4832,8 +4832,8 @@ struct grenade_helper_struct { }; // Returns 0 if this should be retired, 1 if it was successful, and -1 if something went horribly wrong -int grenade_helper( monster *const z, Creature *const target, const int dist, - const int moves, std::map data ) +static int grenade_helper( monster *const z, Creature *const target, const int dist, + const int moves, std::map data ) { // Can't do anything if we can't act if( !z->can_act() ) { diff --git a/src/mondeath.cpp b/src/mondeath.cpp index a7cf3fd6b88c6..f8bc7f4ef909c 100644 --- a/src/mondeath.cpp +++ b/src/mondeath.cpp @@ -116,8 +116,8 @@ void mdeath::normal( monster &z ) } } -void scatter_chunks( const std::string &chunk_name, int chunk_amt, monster &z, int distance, - int pile_size = 1 ) +static void scatter_chunks( const std::string &chunk_name, int chunk_amt, monster &z, int distance, + int pile_size = 1 ) { // can't have less than one item in a pile or it would cause an infinite loop pile_size = std::max( pile_size, 1 ); @@ -644,8 +644,19 @@ void mdeath::broken( monster &z ) } // make "broken_manhack", or "broken_eyebot", ... item_id.insert( 0, "broken_" ); - g->m.spawn_item( z.pos(), item_id, 1, 0, calendar::turn ); - if( g->u.sees( z.pos() ) ) { + + item broken_mon( item_id, calendar::turn ); + const int max_hp = std::max( z.get_hp_max(), 1 ); + const float overflow_damage = std::max( -z.get_hp(), 0 ); + const float corpse_damage = 2.5 * overflow_damage / max_hp; + broken_mon.set_damage( static_cast( std::floor( corpse_damage * itype::damage_scale ) ) ); + + g->m.add_item_or_charges( z.pos(), broken_mon ); + + //TODO: make mdeath::splatter work for robots + if( ( broken_mon.damage() >= broken_mon.max_damage() ) && g->u.sees( z.pos() ) ) { + add_msg( m_good, _( "The %s is destroyed!" ), z.name() ); + } else if( g->u.sees( z.pos() ) ) { add_msg( m_good, _( "The %s collapses!" ), z.name() ); } } diff --git a/src/monfaction.cpp b/src/monfaction.cpp index bff1b5e7e747c..27aa7ac5158cc 100644 --- a/src/monfaction.cpp +++ b/src/monfaction.cpp @@ -91,7 +91,7 @@ mfaction_id monfactions::get_or_add_faction( const mfaction_str_id &id ) return found->second; } -void apply_base_faction( mfaction_id base, mfaction_id faction_id ) +static void apply_base_faction( mfaction_id base, mfaction_id faction_id ) { for( const auto &pair : base.obj().attitude_map ) { // Fill in values set in base faction, but not in derived one @@ -203,14 +203,8 @@ void monfactions::finalize() faction_list.shrink_to_fit(); // Save a couple of bytes } -// Non-const monfaction reference -monfaction &get_faction( const mfaction_str_id &id ) -{ - return faction_list[id.id()]; -} - // Ensures all those factions exist -void prealloc( const std::set< std::string > &facs ) +static void prealloc( const std::set< std::string > &facs ) { for( const auto &f : facs ) { monfactions::get_or_add_faction( mfaction_str_id( f ) ); diff --git a/src/monfaction.h b/src/monfaction.h index c2f9971a14f4d..97328cf53265f 100644 --- a/src/monfaction.h +++ b/src/monfaction.h @@ -15,7 +15,7 @@ enum mf_attitude { MFA_FRIENDLY // Friendly }; -typedef std::unordered_map< mfaction_id, mf_attitude > mfaction_att_map; +using mfaction_att_map = std::unordered_map< mfaction_id, mf_attitude >; namespace monfactions { diff --git a/src/mongroup.h b/src/mongroup.h index 890dbea6bd8ca..f1a5ae5d756f0 100644 --- a/src/mongroup.h +++ b/src/mongroup.h @@ -22,8 +22,8 @@ class JsonOut; struct MonsterGroupEntry; -typedef std::vector FreqDef; -typedef FreqDef::iterator FreqDef_iter; +using FreqDef = std::vector; +using FreqDef_iter = FreqDef::iterator; struct MonsterGroupEntry { mtype_id name; @@ -185,7 +185,7 @@ class MonsterGroupManager private: static std::map monsterGroupMap; - typedef std::set t_string_set; + using t_string_set = std::set; static t_string_set monster_blacklist; static t_string_set monster_whitelist; static t_string_set monster_categories_blacklist; diff --git a/src/monmove.cpp b/src/monmove.cpp index 0721b810a33d7..230ebd264f028 100644 --- a/src/monmove.cpp +++ b/src/monmove.cpp @@ -1042,8 +1042,8 @@ int monster::calc_climb_cost( const tripoint &f, const tripoint &t ) const * Return points of an area extending 1 tile to either side and * (maxdepth) tiles behind basher. */ -std::vector get_bashing_zone( const tripoint &bashee, const tripoint &basher, - int maxdepth ) +static std::vector get_bashing_zone( const tripoint &bashee, const tripoint &basher, + int maxdepth ) { std::vector direction; direction.push_back( bashee ); diff --git a/src/monster.cpp b/src/monster.cpp index c563cf8a157fc..48e513a2760af 100644 --- a/src/monster.cpp +++ b/src/monster.cpp @@ -537,7 +537,7 @@ std::pair monster::get_attitude() const }; } -std::pair hp_description( int cur_hp, int max_hp ) +static std::pair hp_description( int cur_hp, int max_hp ) { std::string damage_info; nc_color col; diff --git a/src/monster.h b/src/monster.h index 82aa23cb8c881..9f406187049e6 100644 --- a/src/monster.h +++ b/src/monster.h @@ -41,7 +41,7 @@ enum field_id : int; class monster; -typedef std::map< mfaction_id, std::set< monster * > > mfactions; +using mfactions = std::map< mfaction_id, std::set< monster * > >; class mon_special_attack { diff --git a/src/monstergenerator.cpp b/src/monstergenerator.cpp index 3bd913500278e..7356439aba18d 100644 --- a/src/monstergenerator.cpp +++ b/src/monstergenerator.cpp @@ -237,7 +237,7 @@ static int calc_bash_skill( const mtype &t ) return ret; } -m_size volume_to_size( const units::volume vol ) +static m_size volume_to_size( const units::volume vol ) { if( vol <= 7500_ml ) { return MS_TINY; diff --git a/src/morale.h b/src/morale.h index 9a9ac18ae1353..b3dcef27f337e 100644 --- a/src/morale.h +++ b/src/morale.h @@ -159,7 +159,7 @@ class player_morale std::array body_parts; body_part_data no_body_part; - typedef std::function mutation_handler; + using mutation_handler = std::function; struct mutation_data { public: mutation_data() = default; diff --git a/src/mtype.h b/src/mtype.h index ec460bd81be61..a706c16c0cb1b 100644 --- a/src/mtype.h +++ b/src/mtype.h @@ -33,7 +33,7 @@ using bodytype_id = std::string; class JsonArray; class JsonObject; -typedef std::string itype_id; +using itype_id = std::string; // These are triggers which may affect the monster's anger or morale. // They are handled in monster::check_triggers(), in monster.cpp diff --git a/src/mutation_data.cpp b/src/mutation_data.cpp index 60793ea501962..aa7060d7b5afe 100644 --- a/src/mutation_data.cpp +++ b/src/mutation_data.cpp @@ -16,8 +16,8 @@ #include "translations.h" #include "generic_factory.h" -typedef std::map> TraitGroupMap; -typedef std::set TraitSet; +using TraitGroupMap = std::map>; +using TraitSet = std::set; TraitSet trait_blacklist; TraitGroupMap trait_groups; @@ -594,7 +594,8 @@ void mutation_branch::load_trait_group( JsonObject &jsobj ) load_trait_group( jsobj, group_id, subtype ); } -Trait_group &make_group_or_throw( const trait_group::Trait_group_tag &gid, bool is_collection ) +static Trait_group &make_group_or_throw( const trait_group::Trait_group_tag &gid, + bool is_collection ) { // NOTE: If the gid is already in the map, emplace will just return an iterator to it auto found = ( is_collection diff --git a/src/mutation_type.cpp b/src/mutation_type.cpp index e8a1a83b7d942..e8df5630d9ad3 100644 --- a/src/mutation_type.cpp +++ b/src/mutation_type.cpp @@ -21,7 +21,7 @@ bool mutation_type_exists( const std::string &id ) return mutation_types.find( id ) != mutation_types.end(); } -std::vector get_mutations_in_type( const std::string &id ) +static std::vector get_mutations_in_type( const std::string &id ) { std::vector ret; for( auto it : mutation_branch::get_all() ) { diff --git a/src/mutation_ui.cpp b/src/mutation_ui.cpp index fda5bacbc0992..e7ac3d05e259a 100644 --- a/src/mutation_ui.cpp +++ b/src/mutation_ui.cpp @@ -15,7 +15,7 @@ const invlet_wrapper mutation_chars( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"#&()*+./:;@[\\]^_{|}" ); -void draw_exam_window( const catacurses::window &win, const int border_y ) +static void draw_exam_window( const catacurses::window &win, const int border_y ) { const int width = getmaxx( win ); mvwputch( win, border_y, 0, BORDER_COLOR, LINE_XXXO ); @@ -28,8 +28,8 @@ const auto shortcut_desc = []( const std::string &comment, const std::string &ke return string_format( comment, string_format( "%s", keys ) ); }; -void show_mutations_titlebar( const catacurses::window &window, const std::string &menu_mode, - const input_context &ctxt ) +static void show_mutations_titlebar( const catacurses::window &window, + const std::string &menu_mode, const input_context &ctxt ) { werase( window ); std::ostringstream desc; diff --git a/src/newcharacter.cpp b/src/newcharacter.cpp index 4569567aa3dba..c45728ae420c8 100644 --- a/src/newcharacter.cpp +++ b/src/newcharacter.cpp @@ -179,7 +179,7 @@ tab_direction set_scenario( const catacurses::window &w, player &u, points_left tab_direction set_profession( const catacurses::window &w, player &u, points_left &points, const tab_direction direction ); tab_direction set_skills( const catacurses::window &w, player &u, points_left &points ); -tab_direction set_description( const catacurses::window &w, player &u, bool allow_reroll, +tab_direction set_description( const catacurses::window &w, avatar &you, bool allow_reroll, points_left &points ); static cata::optional query_for_template_name(); @@ -195,7 +195,7 @@ void Character::pick_name( bool bUseDefault ) } } -matype_id choose_ma_style( const character_type type, const std::vector &styles ) +static matype_id choose_ma_style( const character_type type, const std::vector &styles ) { if( type == PLTYPE_NOW || type == PLTYPE_FULL_RANDOM ) { return random_entry( styles ); @@ -230,12 +230,12 @@ matype_id choose_ma_style( const character_type type, const std::vector( "MAX_TRAIT_POINTS" ); // Reset everything to the defaults to have a clean state. - *this = player(); + *this = avatar(); male = ( rng( 1, 100 ) > 50 ); if( !MAP_SHARING::isSharing() ) { @@ -424,7 +424,7 @@ void player::randomize( const bool random_scenario, points_left &points, bool pl } } -bool player::create( character_type type, const std::string &tempname ) +bool avatar::create( character_type type, const std::string &tempname ) { weapon = item( "null", 0 ); @@ -2135,7 +2135,7 @@ tab_direction set_scenario( const catacurses::window &w, player &u, points_left return retval; } -tab_direction set_description( const catacurses::window &w, player &u, const bool allow_reroll, +tab_direction set_description( const catacurses::window &w, avatar &you, const bool allow_reroll, points_left &points ) { draw_tabs( w, _( "DESCRIPTION" ) ); @@ -2177,7 +2177,7 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo for( const auto &loc : start_location::get_all() ) { if( g->scen->allowed_start( loc.ident() ) ) { select_location.entries.emplace_back( loc.name() ); - if( loc.ident() == u.start_location ) { + if( loc.ident() == you.start_location ) { select_location.selected = offset; } offset++; @@ -2185,9 +2185,9 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo } select_location.setup(); if( MAP_SHARING::isSharing() ) { - u.name = MAP_SHARING::getUsername(); // set the current username as default character name + you.name = MAP_SHARING::getUsername(); // set the current username as default character name } else if( !get_option( "DEF_CHAR_NAME" ).empty() ) { - u.name = get_option( "DEF_CHAR_NAME" ); + you.name = get_option( "DEF_CHAR_NAME" ); } do { if( redraw ) { @@ -2220,14 +2220,14 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo utf8_width( vStatNames[i] ) : pos ); mvwprintz( w_stats, i + 1, 0, c_light_gray, vStatNames[i] ); } - mvwprintz( w_stats, 1, pos + 1, c_light_gray, "%2d", u.str_max ); - mvwprintz( w_stats, 2, pos + 1, c_light_gray, "%2d", u.dex_max ); - mvwprintz( w_stats, 3, pos + 1, c_light_gray, "%2d", u.int_max ); - mvwprintz( w_stats, 4, pos + 1, c_light_gray, "%2d", u.per_max ); + mvwprintz( w_stats, 1, pos + 1, c_light_gray, "%2d", you.str_max ); + mvwprintz( w_stats, 2, pos + 1, c_light_gray, "%2d", you.dex_max ); + mvwprintz( w_stats, 3, pos + 1, c_light_gray, "%2d", you.int_max ); + mvwprintz( w_stats, 4, pos + 1, c_light_gray, "%2d", you.per_max ); wrefresh( w_stats ); mvwprintz( w_traits, 0, 0, COL_HEADER, _( "Traits: " ) ); - std::vector current_traits = u.get_base_traits(); + std::vector current_traits = you.get_base_traits(); if( current_traits.empty() ) { wprintz( w_traits, c_light_red, _( "None!" ) ); } else { @@ -2241,16 +2241,16 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo mvwprintz( w_skills, 0, 0, COL_HEADER, _( "Skills:" ) ); auto skillslist = Skill::get_skills_sorted_by( [&]( const Skill & a, const Skill & b ) { - const int level_a = u.get_skill_level_object( a.ident() ).exercised_level(); - const int level_b = u.get_skill_level_object( b.ident() ).exercised_level(); + const int level_a = you.get_skill_level_object( a.ident() ).exercised_level(); + const int level_b = you.get_skill_level_object( b.ident() ).exercised_level(); return level_a > level_b || ( level_a == level_b && a.name() < b.name() ); } ); int line = 1; bool has_skills = false; - profession::StartingSkillList list_skills = u.prof->skills(); + profession::StartingSkillList list_skills = you.prof->skills(); for( auto &elem : skillslist ) { - int level = u.get_skill_level( elem->ident() ); + int level = you.get_skill_level( elem->ident() ); profession::StartingSkillList::iterator i = list_skills.begin(); while( i != list_skills.end() ) { if( i->first == ( elem )->ident() ) { @@ -2298,7 +2298,7 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo //We draw this stuff every loop because this is user-editable mvwprintz( w_name, 0, 0, c_light_gray, _( "Name:" ) ); mvwprintz( w_name, 0, namebar_pos, c_light_gray, "_______________________________" ); - mvwprintz( w_name, 0, namebar_pos, c_white, u.name ); + mvwprintz( w_name, 0, namebar_pos, c_white, you.name ); wprintz( w_name, h_light_gray, "_" ); if( !MAP_SHARING::isSharing() ) { // no random names when sharing maps @@ -2308,8 +2308,8 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo wrefresh( w_name ); mvwprintz( w_gender, 0, 0, c_light_gray, _( "Gender:" ) ); - mvwprintz( w_gender, 0, male_pos, ( u.male ? c_light_red : c_light_gray ), _( "Male" ) ); - mvwprintz( w_gender, 0, female_pos, ( u.male ? c_light_gray : c_light_red ), _( "Female" ) ); + mvwprintz( w_gender, 0, male_pos, ( you.male ? c_light_red : c_light_gray ), _( "Male" ) ); + mvwprintz( w_gender, 0, female_pos, ( you.male ? c_light_gray : c_light_red ), _( "Female" ) ); mvwprintz( w_gender, 1, 0, c_light_gray, _( "Press %s to switch gender" ), ctxt.get_desc( "CHANGE_GENDER" ) ); wrefresh( w_gender ); @@ -2322,17 +2322,17 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo mvwprintz( w_location, 0, prompt_offset + 1, c_light_gray, _( "Starting location:" ) ); // ::find will return empty location if id was not found. Debug msg will be printed too. mvwprintz( w_location, 0, prompt_offset + utf8_width( _( "Starting location:" ) ) + 2, - c_light_gray, u.start_location.obj().name() ); + c_light_gray, you.start_location.obj().name() ); wrefresh( w_location ); werase( w_scenario ); mvwprintz( w_scenario, 0, 0, COL_HEADER, _( "Scenario: " ) ); - wprintz( w_scenario, c_light_gray, g->scen->gender_appropriate_name( u.male ) ); + wprintz( w_scenario, c_light_gray, g->scen->gender_appropriate_name( you.male ) ); wrefresh( w_scenario ); werase( w_profession ); mvwprintz( w_profession, 0, 0, COL_HEADER, _( "Profession: " ) ); - wprintz( w_profession, c_light_gray, u.prof->gender_appropriate_name( u.male ) ); + wprintz( w_profession, c_light_gray, you.prof->gender_appropriate_name( you.male ) ); wrefresh( w_profession ); const std::string action = ctxt.handle_input(); @@ -2354,14 +2354,14 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo !query_yn( _( "Remaining points will be discarded, are you sure you want to proceed?" ) ) ) { redraw = true; continue; - } else if( u.name.empty() ) { + } else if( you.name.empty() ) { mvwprintz( w_name, 0, namebar_pos, h_light_gray, _( "_______NO NAME ENTERED!_______" ) ); wrefresh( w_name ); if( !query_yn( _( "Are you SURE you're finished? Your name will be randomly generated." ) ) ) { redraw = true; continue; } else { - u.pick_name(); + you.pick_name(); return tab_direction::FORWARD; } } else if( query_yn( _( "Are you SURE you're finished?" ) ) ) { @@ -2374,32 +2374,32 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo return tab_direction::BACKWARD; } else if( action == "REROLL_CHARACTER" && allow_reroll ) { points.init_from_options(); - u.randomize( false, points ); + you.randomize( false, points ); // Return tab_direction::NONE so we re-enter this tab again, but it forces a complete redrawing of it. return tab_direction::NONE; } else if( action == "REROLL_CHARACTER_WITH_SCENARIO" && allow_reroll ) { points.init_from_options(); - u.randomize( true, points ); + you.randomize( true, points ); // Return tab_direction::NONE so we re-enter this tab again, but it forces a complete redrawing of it. return tab_direction::NONE; } else if( action == "SAVE_TEMPLATE" ) { if( const auto name = query_for_template_name() ) { - ::save_template( u, *name, points ); + ::save_template( you, *name, points ); } redraw = true; } else if( action == "PICK_RANDOM_NAME" ) { if( !MAP_SHARING::isSharing() ) { // Don't allow random names when sharing maps. We don't need to check at the top as you won't be able to edit the name - u.pick_name(); + you.pick_name(); } } else if( action == "CHANGE_GENDER" ) { - u.male = !u.male; + you.male = !you.male; } else if( action == "CHOOSE_LOCATION" ) { select_location.redraw(); select_location.query(); if( select_location.ret >= 0 ) { for( const auto &loc : start_location::get_all() ) { if( loc.name() == select_location.entries[ select_location.ret ].txt ) { - u.start_location = loc.ident(); + you.start_location = loc.ident(); } } } @@ -2414,22 +2414,22 @@ tab_direction set_description( const catacurses::window &w, player &u, const boo } else if( action == "ANY_INPUT" && !MAP_SHARING::isSharing() ) { // Don't edit names when sharing maps const long ch = ctxt.get_raw_input().get_first_input(); - utf8_wrapper wrap( u.name ); + utf8_wrapper wrap( you.name ); if( ch == KEY_BACKSPACE ) { if( !wrap.empty() ) { wrap.erase( wrap.length() - 1, 1 ); - u.name = wrap.str(); + you.name = wrap.str(); } } else if( ch == KEY_F( 2 ) ) { utf8_wrapper tmp( get_input_string_from_file() ); if( !tmp.empty() && tmp.length() + wrap.length() < 30 ) { - u.name.append( tmp.str() ); + you.name.append( tmp.str() ); } } else if( ch == '\n' ) { // nope, we ignore this newline, don't want it in char names } else { wrap.append( ctxt.get_raw_input().text ); - u.name = wrap.str(); + you.name = wrap.str(); } } else if( action == "QUIT" && query_yn( _( "Return to main menu?" ) ) ) { return tab_direction::QUIT; @@ -2578,7 +2578,7 @@ void save_template( const player &u, const std::string &name, const points_left }, _( "player template" ) ); } -bool player::load_template( const std::string &template_name, points_left &points ) +bool avatar::load_template( const std::string &template_name, points_left &points ) { return read_from_file_json( FILENAMES["templatedir"] + utf8_to_native( template_name ) + ".template", [&]( JsonIn & jsin ) { diff --git a/src/npc.cpp b/src/npc.cpp index 29ad36bd56d31..53ce39c376c8a 100644 --- a/src/npc.cpp +++ b/src/npc.cpp @@ -462,6 +462,9 @@ void npc::set_fac( const string_id &id ) { my_fac = g->faction_manager_ptr->get( id ); fac_id = my_fac->id; + for( auto &e : inv_dump() ) { + e->set_owner( my_fac ); + } } void npc::clear_fac() @@ -471,8 +474,8 @@ void npc::clear_fac() } // item id from group "_" or from fallback group // may still be a null item! -item random_item_from( const npc_class_id &type, const std::string &what, - const std::string &fallback ) +static item random_item_from( const npc_class_id &type, const std::string &what, + const std::string &fallback ) { auto result = item_group::item_from( type.str() + "_" + what ); if( result.is_null() ) { @@ -482,13 +485,13 @@ item random_item_from( const npc_class_id &type, const std::string &what, } // item id from "_" or from "npc_" -item random_item_from( const npc_class_id &type, const std::string &what ) +static item random_item_from( const npc_class_id &type, const std::string &what ) { return random_item_from( type, what, "npc_" + what ); } // item id from "__" or from "npc__" -item get_clothing_item( const npc_class_id &type, const std::string &what, bool male ) +static item get_clothing_item( const npc_class_id &type, const std::string &what, bool male ) { item result; //Check if class has gendered clothing @@ -543,9 +546,9 @@ void starting_clothes( npc &who, const npc_class_id &type, bool male ) if( it.has_flag( "VARSIZE" ) ) { it.item_tags.insert( "FIT" ); } - if( who.can_wear( it ).success() ) { who.worn.push_back( it ); + it.set_owner( who.my_fac ); } } } @@ -605,7 +608,9 @@ void starting_inv( npc &who, const npc_class_id &type ) res.erase( std::remove_if( res.begin(), res.end(), [&]( const item & e ) { return e.has_flag( "TRADER_AVOID" ); } ), res.end() ); - + for( auto &it : res ) { + it.set_owner( who.my_fac ); + } who.inv += res; } @@ -765,6 +770,7 @@ void npc::starting_weapon( const npc_class_id &type ) if( weapon.is_gun() ) { weapon.ammo_set( weapon.type->gun->ammo->default_ammotype() ); } + weapon.set_owner( my_fac ); } bool npc::wear_if_wanted( const item &it ) @@ -1872,7 +1878,7 @@ std::string npc::opinion_text() const return ret.str(); } -void maybe_shift( cata::optional &pos, int dx, int dy ) +static void maybe_shift( cata::optional &pos, int dx, int dy ) { if( pos ) { pos->x += dx; @@ -1880,7 +1886,7 @@ void maybe_shift( cata::optional &pos, int dx, int dy ) } } -void maybe_shift( tripoint &pos, int dx, int dy ) +static void maybe_shift( tripoint &pos, int dx, int dy ) { if( pos != tripoint_min ) { pos.x += dx; @@ -2005,6 +2011,8 @@ std::string npc_attitude_name( npc_attitude att ) return _( "Healing you" ); case NPCATT_ACTIVITY: return _( "Performing a task" ); + case NPCATT_RECOVER_GOODS: + return _( "Trying to recover stolen goods" ); case NPCATT_LEGACY_1: case NPCATT_LEGACY_2: case NPCATT_LEGACY_3: diff --git a/src/npc.h b/src/npc.h index 2bcf1d8aa3ce4..ae83d5f0a9f88 100644 --- a/src/npc.h +++ b/src/npc.h @@ -85,6 +85,7 @@ enum npc_attitude : int { NPCATT_LEGACY_5, NPCATT_ACTIVITY, // Perform a mission activity NPCATT_FLEE_TEMP, // Get away from the player for a while + NPCATT_RECOVER_GOODS, // Chase the player to demand stolen goods back NPCATT_END }; @@ -689,7 +690,7 @@ struct npc_chatbin { class npc_template; struct epilogue; -typedef std::map epilogue_map; +using epilogue_map = std::map; class npc : public player { @@ -934,6 +935,8 @@ class npc : public player void handle_sound( int priority, const std::string &description, int heard_volume, const tripoint &spos ); + void witness_thievery( item *it ); + /* shift() works much like monster::shift(), and is called when the player moves * from one submap to an adjacent submap. It updates our position (shifting by * 12 tiles), as well as our plans. @@ -1169,7 +1172,9 @@ class npc : public player */ tripoint goal; std::vector omt_path; - + tripoint wander_pos; // Not actually used (should be: wander there when you hear a sound) + int wander_time; + item *known_stolen_item = nullptr; // the item that the NPC wants the player to drop or barter for. /** * Location and index of the corpse we'd like to pulp (if any). */ diff --git a/src/npc_class.cpp b/src/npc_class.cpp index 176ba0851a196..be636e56ef111 100644 --- a/src/npc_class.cpp +++ b/src/npc_class.cpp @@ -164,7 +164,7 @@ void npc_class::check_consistency() } } -distribution load_distribution( JsonObject &jo ) +static distribution load_distribution( JsonObject &jo ) { if( jo.has_float( "constant" ) ) { return distribution::constant( jo.get_float( "constant" ) ); @@ -212,7 +212,7 @@ distribution load_distribution( JsonObject &jo ) return distribution(); } -distribution load_distribution( JsonObject &jo, const std::string &name ) +static distribution load_distribution( JsonObject &jo, const std::string &name ) { if( !jo.has_member( name ) ) { return distribution(); diff --git a/src/npc_class.h b/src/npc_class.h index 5ebc614dc6dfa..e731d2717c0be 100644 --- a/src/npc_class.h +++ b/src/npc_class.h @@ -13,15 +13,15 @@ class JsonObject; -typedef std::string Group_tag; -typedef std::string Mutation_category_tag; +using Group_tag = std::string; +using Mutation_category_tag = std::string; class Trait_group; namespace trait_group { -typedef string_id Trait_group_tag; +using Trait_group_tag = string_id; } diff --git a/src/npcmove.cpp b/src/npcmove.cpp index ce54ad91bb65f..2db43e56cf798 100644 --- a/src/npcmove.cpp +++ b/src/npcmove.cpp @@ -209,7 +209,7 @@ bool compare_sound_alert( const dangerous_sound &sound_a, const dangerous_sound return sound_a.volume < sound_b.volume; } -bool clear_shot_reach( const tripoint &from, const tripoint &to ) +static bool clear_shot_reach( const tripoint &from, const tripoint &to ) { std::vector path = line_to( from, to ); path.pop_back(); @@ -354,7 +354,7 @@ float npc::evaluate_enemy( const Creature &target ) const } static constexpr int def_radius = 6; -bool too_close( const tripoint &critter_pos, const tripoint &ally_pos ) +static bool too_close( const tripoint &critter_pos, const tripoint &ally_pos ) { return rl_dist( critter_pos, ally_pos ) <= def_radius; } @@ -569,6 +569,14 @@ void npc::regen_ai_cache() auto i = std::begin( ai_cache.sound_alerts ); while( i != std::end( ai_cache.sound_alerts ) ) { if( sees( g->m.getlocal( i->abs_pos ) ) ) { + // if they were responding to a call for guards because of thievery + npc *const sound_source = g->critter_at( g->m.getlocal( i->abs_pos ) ); + if( sound_source ) { + if( my_fac == sound_source->my_fac && sound_source->known_stolen_item ) { + sound_source->known_stolen_item = nullptr; + set_attitude( NPCATT_RECOVER_GOODS ); + } + } i = ai_cache.sound_alerts.erase( i ); if( ai_cache.sound_alerts.size() == 1 ) { path.clear(); @@ -1148,6 +1156,21 @@ void npc::execute_action( npc_action action ) } } +void npc::witness_thievery( item *it ) +{ + // Shopkeep is behind glass + if( myclass == npc_class_id( "NC_EVAC_SHOPKEEP" ) ) { + known_stolen_item = it; + return; + } + set_attitude( NPCATT_RECOVER_GOODS ); + known_stolen_item = it; + for( auto &elem : g->u.inv_dump() ) { + if( elem->get_old_owner() ) { + } + } +} + npc_action npc::method_of_fleeing() { if( in_vehicle ) { @@ -1346,7 +1369,7 @@ npc_action npc::address_needs() return address_needs( ai_cache.danger ); } -bool wants_to_reload( const npc &who, const item &it ) +static bool wants_to_reload( const npc &who, const item &it ) { if( !who.can_reload( it ) ) { return false; @@ -1362,7 +1385,7 @@ bool wants_to_reload( const npc &who, const item &it ) return remaining < required || remaining < it.ammo_capacity(); } -bool wants_to_reload_with( const item &weap, const item &ammo ) +static bool wants_to_reload_with( const item &weap, const item &ammo ) { return !ammo.is_magazine() || ammo.ammo_remaining() > weap.ammo_remaining(); } @@ -1713,7 +1736,7 @@ npc_action npc::address_needs( float danger ) npc_action npc::address_player() { - if( attitude == NPCATT_TALK && sees( g->u ) ) { + if( ( attitude == NPCATT_TALK || attitude == NPCATT_RECOVER_GOODS ) && sees( g->u ) ) { if( g->u.in_sleep_state() ) { // Leave sleeping characters alone. return npc_undecided; @@ -2447,7 +2470,25 @@ void npc::find_item() // Don't even consider liquids. return; } - + std::vector followers; + for( auto &elem : g->get_follower_list() ) { + std::shared_ptr npc_to_get = overmap_buffer.find_npc( elem ); + if( !npc_to_get ) { + continue; + } + npc *npc_to_add = npc_to_get.get(); + followers.push_back( npc_to_add ); + } + for( auto &elem : followers ) { + if( it.has_owner() && it.get_owner() != my_fac && ( elem->sees( this->pos() ) || + elem->sees( wanted_item_pos ) ) ) { + return; + } + } + if( it.has_owner() && it.get_owner() != my_fac && ( g->u.sees( this->pos() ) || + g->u.sees( wanted_item_pos ) ) ) { + return; + } if( whitelisting && !item_whitelisted( it ) ) { return; } @@ -2634,7 +2675,6 @@ void npc::pick_up_item() if( itval < worst_item_value ) { worst_item_value = itval; } - i_add( it ); } @@ -3013,7 +3053,7 @@ bool npc::scan_new_items() // TODO: Armor? } -void npc_throw( npc &np, item &it, int index, const tripoint &pos ) +static void npc_throw( npc &np, item &it, int index, const tripoint &pos ) { if( g->u.sees( np ) ) { add_msg( _( "%1$s throws a %2$s." ), np.name, it.tname() ); @@ -3279,7 +3319,7 @@ void npc::use_painkiller() // Not be unhealthy // Not have side effects // Be eaten before it rots (favor soon-to-rot perishables) -float rate_food( const item &it, int want_nutr, int want_quench ) +static float rate_food( const item &it, int want_nutr, int want_quench ) { const auto &food = it.get_comestible(); if( !food ) { @@ -3795,7 +3835,7 @@ Creature *npc::current_ally() } // Maybe TODO: Move to Character method and use map methods -body_part bp_affected( npc &who, const efftype_id &effect_type ) +static body_part bp_affected( npc &who, const efftype_id &effect_type ) { body_part ret = num_bp; int highest_intensity = INT_MIN; diff --git a/src/npctalk.cpp b/src/npctalk.cpp index 4bd0bf7a124bc..c1940d16df64f 100644 --- a/src/npctalk.cpp +++ b/src/npctalk.cpp @@ -25,6 +25,7 @@ #include "game.h" #include "help.h" #include "input.h" +#include "item.h" #include "item_category.h" #include "itype.h" #include "json.h" @@ -186,8 +187,8 @@ enum npc_chat_menu { // given a vector of NPCs, presents a menu to allow a player to pick one. // everyone == true adds another entry at the end to allow selecting all listed NPCs // this implies a return value of npc_list.size() means "everyone" -int npc_select_menu( const std::vector &npc_list, const std::string &prompt, - const bool everyone = true ) +static int npc_select_menu( const std::vector &npc_list, const std::string &prompt, + const bool everyone = true ) { if( npc_list.empty() ) { return -1; @@ -210,14 +211,15 @@ int npc_select_menu( const std::vector &npc_list, const std::string &prom } -void npc_batch_override_toggle( const std::vector &npc_list, ally_rule rule, bool state ) +static void npc_batch_override_toggle( + const std::vector &npc_list, ally_rule rule, bool state ) { for( npc *p : npc_list ) { p->rules.toggle_specific_override_state( rule, state ); } } -void npc_temp_orders_menu( const std::vector &npc_list ) +static void npc_temp_orders_menu( const std::vector &npc_list ) { if( npc_list.empty() ) { return; @@ -605,8 +607,9 @@ void npc::talk_to_u( bool text_only, bool radio_contact ) d.add_topic( "TALK_LEADER" ); } else if( is_player_ally() && is_walking_with() ) { d.add_topic( "TALK_FRIEND" ); + } else if( get_attitude() == NPCATT_RECOVER_GOODS ) { + d.add_topic( "TALK_STOLE_ITEM" ); } - int most_difficult_mission = 0; for( auto &mission : chatbin.missions ) { const auto &type = mission->get_type(); @@ -1106,7 +1109,7 @@ void dialogue::gen_responses( const talk_topic &the_topic ) } } -int parse_mod( const dialogue &d, const std::string &attribute, const int factor ) +static int parse_mod( const dialogue &d, const std::string &attribute, const int factor ) { player &u = *d.alpha; npc &p = *d.beta; @@ -1602,7 +1605,7 @@ talk_trial::talk_trial( JsonObject jo ) } } -talk_topic load_inline_topic( JsonObject jo ) +static talk_topic load_inline_topic( JsonObject jo ) { const std::string id = jo.get_string( "id" ); json_talk_topics[id].load( jo ); @@ -1633,7 +1636,8 @@ talk_effect_fun_t::talk_effect_fun_t( std::function f } // throws an error on failure, so no need to return -std::string get_talk_varname( JsonObject jo, const std::string &member, bool check_value = true ) +static std::string get_talk_varname( JsonObject jo, const std::string &member, + bool check_value = true ) { if( !jo.has_string( "type" ) || !jo.has_string( "context" ) || ( check_value && !jo.has_string( "value" ) ) ) { @@ -2261,6 +2265,8 @@ void talk_effect_t::parse_string_effect( const std::string &effect_id, JsonObjec WRAP( start_mugging ), WRAP( player_leaving ), WRAP( drop_weapon ), + WRAP( drop_stolen_item ), + WRAP( remove_stolen_status ), WRAP( player_weapon_away ), WRAP( player_weapon_drop ), WRAP( lead_to_safety ), @@ -3027,6 +3033,24 @@ void conditional_t::set_is_driving( bool is_npc ) }; } +void conditional_t::set_has_stolen_item( bool is_npc ) +{ + ( void )is_npc; + condition = []( const dialogue & d ) { + player *actor = d.alpha; + npc &p = *d.beta; + bool found_in_inv = false; + for( auto &elem : actor->inv_dump() ) { + if( elem->get_old_owner() ) { + if( elem->get_old_owner()->id.str() == p.my_fac->id.str() ) { + found_in_inv = true; + } + } + } + return found_in_inv; + }; +} + void conditional_t::set_is_day() { condition = []( const dialogue & ) { @@ -3300,6 +3324,8 @@ conditional_t::conditional_t( const std::string &type ) set_is_driving( is_npc ); } else if( type == "is_day" ) { set_is_day(); + } else if( type == "u_has_stolen_item" ) { + set_has_stolen_item( is_npc ); } else if( type == "is_outside" ) { set_is_outside(); } else if( type == "u_has_camp" ) { @@ -3686,7 +3712,7 @@ enum consumption_result { }; // Returns true if we destroyed the item through consumption -consumption_result try_consume( npc &p, item &it, std::string &reason ) +static consumption_result try_consume( npc &p, item &it, std::string &reason ) { // TODO: Unify this with 'player::consume_item()' bool consuming_contents = it.is_container() && !it.contents.empty(); diff --git a/src/npctalk.h b/src/npctalk.h index 35118363afe6f..08838ad81d52d 100644 --- a/src/npctalk.h +++ b/src/npctalk.h @@ -55,9 +55,12 @@ void stranger_neutral( npc & ); // p is now neutral towards you void start_mugging( npc & ); void player_leaving( npc & ); +void remove_stolen_status( npc & ); + void drop_weapon( npc & ); void player_weapon_away( npc & ); void player_weapon_drop( npc & ); +void drop_stolen_item( npc & ); void lead_to_safety( npc & ); void start_training( npc & ); diff --git a/src/npctalk_funcs.cpp b/src/npctalk_funcs.cpp index afa34a2e74520..b5beaf9dfd408 100644 --- a/src/npctalk_funcs.cpp +++ b/src/npctalk_funcs.cpp @@ -663,6 +663,35 @@ void talk_function::stranger_neutral( npc &p ) p.chatbin.first_topic = "TALK_STRANGER_NEUTRAL"; } +void talk_function::drop_stolen_item( npc &p ) +{ + for( auto &elem : g->u.inv_dump() ) { + if( elem->get_old_owner() ) { + if( elem->get_old_owner()->id.str() == p.my_fac->id.str() ) { + item to_drop = g->u.i_rem( elem ); + to_drop.remove_old_owner(); + to_drop.set_owner( p.my_fac ); + g->m.add_item_or_charges( g->u.pos(), to_drop ); + } + } + } + if( p.known_stolen_item ) { + p.known_stolen_item = nullptr; + } + if( g->u.is_hauling() ) { + g->u.stop_hauling(); + } + p.set_attitude( NPCATT_NULL ); +} + +void talk_function::remove_stolen_status( npc &p ) +{ + if( p.known_stolen_item ) { + p.known_stolen_item = nullptr; + } + p.set_attitude( NPCATT_NULL ); +} + void talk_function::start_mugging( npc &p ) { p.set_attitude( NPCATT_MUG ); @@ -703,7 +732,7 @@ void talk_function::lead_to_safety( npc &p ) p.set_attitude( NPCATT_LEAD ); } -bool pay_npc( npc &np, int cost ) +static bool pay_npc( npc &np, int cost ) { if( np.op_of_u.owed >= cost ) { np.op_of_u.owed -= cost; diff --git a/src/npctrade.cpp b/src/npctrade.cpp index 339f75cf0e537..5429732385f77 100644 --- a/src/npctrade.cpp +++ b/src/npctrade.cpp @@ -458,6 +458,12 @@ TAB key to switch lists, letters to pick items, Enter to finalize, Esc to quit,\ g->u.practice( skill_barter, practice / 2 ); } } + for( auto &elem : g->u.inv_dump() ) { + elem->set_owner( g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ); + } + for( auto &elem : p.inv_dump() ) { + elem->set_owner( p.my_fac ); + } g->refresh_all(); return traded; } diff --git a/src/omdata.h b/src/omdata.h index 4cecba85f81df..db845aad643b7 100644 --- a/src/omdata.h +++ b/src/omdata.h @@ -427,6 +427,9 @@ class overmap_special void load( JsonObject &jo, const std::string &src ); void finalize(); void check() const; + private: + // These locations are the default values if ones are not specified for the individual OMTs. + std::set> default_locations; }; namespace overmap_terrains diff --git a/src/options.cpp b/src/options.cpp index f02a86984c7bb..69bab2285a3f9 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -2283,8 +2283,9 @@ static void refresh_tiles( bool, bool, bool ) } #endif // TILES -void draw_borders_external( const catacurses::window &w, int horizontal_level, - const std::map &mapLines, const bool world_options_only ) +static void draw_borders_external( + const catacurses::window &w, int horizontal_level, const std::map &mapLines, + const bool world_options_only ) { if( !world_options_only ) { draw_border( w, BORDER_COLOR, _( " OPTIONS " ) ); @@ -2298,7 +2299,7 @@ void draw_borders_external( const catacurses::window &w, int horizontal_level, wrefresh( w ); } -void draw_borders_internal( const catacurses::window &w, std::map &mapLines ) +static void draw_borders_internal( const catacurses::window &w, std::map &mapLines ) { for( int i = 0; i < getmaxx( w ); ++i ) { if( mapLines[i] ) { diff --git a/src/options.h b/src/options.h index 8a0a1d8234dc5..2e68b4e90f4d5 100644 --- a/src/options.h +++ b/src/options.h @@ -183,7 +183,7 @@ class options_manager float fStep; }; - typedef std::unordered_map options_container; + using options_container = std::unordered_map; void init(); void add_options_general(); diff --git a/src/output.cpp b/src/output.cpp index 79f3756f3b058..983e8560e116d 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -1025,7 +1025,7 @@ std::string trim_punctuation_marks( const std::string &s ) } ); } -typedef std::string::value_type char_t; +using char_t = std::string::value_type; std::string to_upper_case( const std::string &s ) { std::string res; diff --git a/src/output.h b/src/output.h index 344d0e9c45883..cf52efe3f0d5c 100644 --- a/src/output.h +++ b/src/output.h @@ -416,14 +416,14 @@ std::vector get_hotkeys( const std::string &s ); * */ /*@{*/ -typedef enum { +enum PopupFlags { PF_NONE = 0, PF_GET_KEY = 1 << 0, PF_NO_WAIT = 1 << 1, PF_ON_TOP = 1 << 2, PF_FULLSCREEN = 1 << 3, PF_NO_WAIT_ON_TOP = PF_NO_WAIT | PF_ON_TOP, -} PopupFlags; +}; template inline long popup_getkey( const char *const mes, Args &&... args ) diff --git a/src/overmap.cpp b/src/overmap.cpp index 97285ca47cccf..d6ab4a8c12a4b 100644 --- a/src/overmap.cpp +++ b/src/overmap.cpp @@ -127,6 +127,9 @@ constexpr size_t set_segment( size_t line, om_direction::type dir ) constexpr bool has_segment( size_t line, om_direction::type dir ) { + if( dir == om_direction::type::invalid ) { + return false; + } return static_cast( line & 1 << static_cast( dir ) ); } @@ -140,7 +143,7 @@ constexpr bool is_straight( size_t line ) || line == 10; } -size_t from_dir( om_direction::type dir ) +static size_t from_dir( om_direction::type dir ) { switch( dir ) { case om_direction::type::north: @@ -316,7 +319,7 @@ bool operator!=( const int_id &lhs, const char *rhs ) return !( lhs == rhs ); } -void set_oter_ids() // FIXME: constify +static void set_oter_ids() // FIXME: constify { ot_null = oter_str_id::NULL_ID(); // NOT required. @@ -506,8 +509,8 @@ bool is_ot_subtype( const char *otype, const oter_id &oter ) * load mapgen functions from an overmap_terrain json entry * suffix is for roads/subways/etc which have "_straight", "_curved", "_tee", "_four_way" function mappings */ -void load_overmap_terrain_mapgens( JsonObject &jo, const std::string &id_base, - const std::string &suffix = "" ) +static void load_overmap_terrain_mapgens( JsonObject &jo, const std::string &id_base, + const std::string &suffix = "" ) { const std::string fmapkey( id_base + suffix ); const std::string jsonkey( "mapgen" + suffix ); @@ -877,19 +880,7 @@ void overmap_special::load( JsonObject &jo, const std::string &src ) const bool is_special = jo.get_string( "type", "" ) == "overmap_special"; mandatory( jo, was_loaded, "overmaps", terrains ); - - // If the special has locations, then add those to the locations - // of each of the terrains IF the terrain has no locations already. - std::set> locations; - optional( jo, was_loaded, "locations", locations ); - if( !locations.empty() ) { - for( auto &t : terrains ) { - if( t.locations.empty() ) { - t.locations.insert( locations.begin(), locations.end() ); - } - } - } - + optional( jo, was_loaded, "locations", default_locations ); if( is_special ) { mandatory( jo, was_loaded, "occurrences", occurrences ); @@ -908,6 +899,16 @@ void overmap_special::load( JsonObject &jo, const std::string &src ) void overmap_special::finalize() { + // If the special has default locations, then add those to the locations + // of each of the terrains IF the terrain has no locations already. + if( !default_locations.empty() ) { + for( auto &t : terrains ) { + if( t.locations.empty() ) { + t.locations.insert( default_locations.begin(), default_locations.end() ); + } + } + } + for( auto &elem : connections ) { const auto &oter = get_terrain_at( elem.p ); if( !elem.terrain && oter.terrain ) { diff --git a/src/overmapbuffer.cpp b/src/overmapbuffer.cpp index e245a33a4e2d8..3680f8c862643 100644 --- a/src/overmapbuffer.cpp +++ b/src/overmapbuffer.cpp @@ -852,9 +852,9 @@ bool overmapbuffer::check_overmap_special_type( const overmap_special_id &id, co return om.overmap_pointer->check_overmap_special_type( id, om.coordinates ); } -omt_find_params assign_params( const std::string &type, int const radius, bool must_be_seen, - bool allow_subtype_matches, bool existing_overmaps_only, - const cata::optional &om_special ) +static omt_find_params assign_params( const std::string &type, int const radius, bool must_be_seen, + bool allow_subtype_matches, bool existing_overmaps_only, + const cata::optional &om_special ) { omt_find_params params; params.type = type; @@ -1157,7 +1157,7 @@ std::vector> overmapbuffer::get_npcs_near_omt( int x, int y return result; } -radio_tower_reference create_radio_tower_reference( const overmap &om, radio_tower &t, +static radio_tower_reference create_radio_tower_reference( const overmap &om, radio_tower &t, const tripoint ¢er ) { // global submap coordinates, same as center is diff --git a/src/overmapbuffer.h b/src/overmapbuffer.h index c3be993f4cb51..0f845fbb14994 100644 --- a/src/overmapbuffer.h +++ b/src/overmapbuffer.h @@ -365,8 +365,8 @@ class overmapbuffer */ bool is_omt_generated( const tripoint &loc ); - typedef std::pair t_point_with_note; - typedef std::vector t_notes_vector; + using t_point_with_note = std::pair; + using t_notes_vector = std::vector; t_notes_vector get_all_notes( int z ) { return get_notes( z, nullptr ); // NULL => don't filter notes } diff --git a/src/panels.cpp b/src/panels.cpp index 13806d6fdfd08..b8c8e28538cd9 100644 --- a/src/panels.cpp +++ b/src/panels.cpp @@ -59,7 +59,7 @@ const efftype_id effect_got_checked( "got_checked" ); // constructor window_panel::window_panel( std::function - draw_func, const std::string &nm, int ht, int wd, bool def_toggle ) + draw_func, const std::string &nm, int ht, int wd, bool def_toggle, bool force_draw ) { draw = draw_func; name = nm; @@ -67,13 +67,14 @@ window_panel::window_panel( std::function static_cast( trunc ) ) { return utf8_truncate( input, trunc - 1 ) + "โ€ฆ"; @@ -81,8 +82,8 @@ std::string trunc_ellipse( const std::string &input, unsigned int trunc ) return input; } -void draw_rectangle( const catacurses::window &w, nc_color, point top_left, - point bottom_right ) +static void draw_rectangle( const catacurses::window &w, nc_color, point top_left, + point bottom_right ) { // corners mvwaddch( w, top_left.y, top_left.x, LINE_OXXO ); @@ -101,7 +102,7 @@ void draw_rectangle( const catacurses::window &w, nc_color, point top_left, } } -std::pair str_string( const player &p ) +static std::pair str_string( const player &p ) { nc_color clr; @@ -115,7 +116,7 @@ std::pair str_string( const player &p ) return std::make_pair( clr, _( "Str " ) + ( p.get_str() < 100 ? to_string( p.get_str() ) : "++" ) ); } -std::pair dex_string( const player &p ) +static std::pair dex_string( const player &p ) { nc_color clr; @@ -129,7 +130,7 @@ std::pair dex_string( const player &p ) return std::make_pair( clr, _( "Dex " ) + ( p.get_dex() < 100 ? to_string( p.get_dex() ) : "++" ) ); } -std::pair int_string( const player &p ) +static std::pair int_string( const player &p ) { nc_color clr; @@ -143,7 +144,7 @@ std::pair int_string( const player &p ) return std::make_pair( clr, _( "Int " ) + ( p.get_int() < 100 ? to_string( p.get_int() ) : "++" ) ); } -std::pair per_string( const player &p ) +static std::pair per_string( const player &p ) { nc_color clr; @@ -157,7 +158,7 @@ std::pair per_string( const player &p ) return std::make_pair( clr, _( "Per " ) + ( p.get_per() < 100 ? to_string( p.get_per() ) : "++" ) ); } -nc_color focus_color( int focus ) +static nc_color focus_color( int focus ) { if( focus < 25 ) { return c_red; @@ -198,7 +199,7 @@ std::string window_panel::get_name() const return name; } -void draw_minimap( const player &u, const catacurses::window &w_minimap ) +static void draw_minimap( const player &u, const catacurses::window &w_minimap ) { const tripoint curs = u.global_omt_location(); const int cursx = curs.x; @@ -400,7 +401,7 @@ void draw_minimap( const player &u, const catacurses::window &w_minimap ) } } -void decorate_panel( const std::string &name, const catacurses::window &w ) +static void decorate_panel( const std::string &name, const catacurses::window &w ) { werase( w ); draw_border( w ); @@ -416,7 +417,7 @@ void decorate_panel( const std::string &name, const catacurses::window &w ) wprintz( w, c_white, title_suffix ); } -std::string get_temp( const player &u ) +static std::string get_temp( const player &u ) { std::string temp; if( u.has_item_with_flag( "THERMOMETER" ) || @@ -429,7 +430,7 @@ std::string get_temp( const player &u ) return temp; } -std::string get_moon_graphic() +static std::string get_moon_graphic() { //moon phase display static std::vector vMoonPhase = { "( )", "( ))", "( | )", "(( )" }; @@ -445,7 +446,7 @@ std::string get_moon_graphic() return sPhase; } -std::string get_moon() +static std::string get_moon() { const int iPhase = static_cast( get_moon_phase( calendar::turn ) ); switch( iPhase ) { @@ -472,7 +473,7 @@ std::string get_moon() } } -std::string time_approx() +static std::string time_approx() { const int iHour = hour_of_day( calendar::turn ); if( iHour >= 23 || iHour <= 1 ) { @@ -497,7 +498,7 @@ std::string time_approx() return _( "Night" ); } -nc_color value_color( int stat ) +static nc_color value_color( int stat ) { nc_color valuecolor = c_light_gray; @@ -513,24 +514,7 @@ nc_color value_color( int stat ) return valuecolor; } -nc_color stat_color( int stat ) -{ - nc_color statcolor = c_light_gray; - - if( stat >= 7 ) { - statcolor = c_green; - } else if( stat >= 5 ) { - statcolor = c_yellow; - } else if( stat >= 2 ) { - statcolor = c_red; - } else { - statcolor = c_magenta; - } - - return statcolor; -} - -std::pair morale_stat( const player &u ) +static std::pair morale_stat( const player &u ) { const int morale_int = u.get_morale_level(); nc_color morale_color = c_white; @@ -542,7 +526,7 @@ std::pair morale_stat( const player &u ) return std::make_pair( morale_color, morale_int ); } -std::pair temp_delta( const player &u ) +static std::pair temp_delta( const player &u ) { int current_bp_extreme = 0; int conv_bp_extreme = 0; @@ -557,7 +541,7 @@ std::pair temp_delta( const player &u ) return std::make_pair( current_bp_extreme, conv_bp_extreme ); } -int define_temp_level( const int lvl ) +static int define_temp_level( const int lvl ) { if( lvl > BODYTEMP_SCORCHING ) { return 7; @@ -575,7 +559,7 @@ int define_temp_level( const int lvl ) return 1; } -std::string temp_delta_string( const player &u ) +static std::string temp_delta_string( const player &u ) { std::string temp_message; std::pair temp_pair = temp_delta( u ); @@ -604,7 +588,7 @@ std::string temp_delta_string( const player &u ) return temp_message; } -std::pair temp_delta_arrows( const player &u ) +static std::pair temp_delta_arrows( const player &u ) { std::string temp_message; nc_color temp_color = c_white; @@ -641,7 +625,7 @@ std::pair temp_delta_arrows( const player &u ) return std::make_pair( temp_color, temp_message ); } -std::pair temp_stat( const player &u ) +static std::pair temp_stat( const player &u ) { /// Find hottest/coldest bodypart // Calculate the most extreme body temperatures @@ -675,7 +659,7 @@ std::pair temp_stat( const player &u ) return std::make_pair( temp_color, temp_string ); } -std::pair pain_stat( const player &u ) +static std::pair pain_stat( const player &u ) { nc_color pain_color = c_yellow; std::string pain_string; @@ -695,7 +679,7 @@ std::pair pain_stat( const player &u ) return std::make_pair( pain_color, pain_string ); } -std::string get_armor( const player &u, body_part bp, unsigned int truncate = 0 ) +static std::string get_armor( const player &u, body_part bp, unsigned int truncate = 0 ) { for( std::list::const_iterator it = u.worn.end(); it != u.worn.begin(); ) { --it; @@ -706,7 +690,7 @@ std::string get_armor( const player &u, body_part bp, unsigned int truncate = 0 return "-"; } -face_type get_face_type( const player &u ) +static face_type get_face_type( const player &u ) { face_type fc = face_human; if( u.has_trait( trait_THRESH_FELINE ) ) { @@ -719,8 +703,8 @@ face_type get_face_type( const player &u ) return fc; } -std::string morale_emotion( const int morale_cur, const face_type face, - const bool horizontal_style ) +static std::string morale_emotion( const int morale_cur, const face_type face, + const bool horizontal_style ) { if( horizontal_style ) { if( face == face_bear || face == face_cat ) { @@ -801,7 +785,7 @@ std::string morale_emotion( const int morale_cur, const face_type face, } } -std::pair power_stat( const player &u ) +static std::pair power_stat( const player &u ) { nc_color c_pwr = c_red; std::string s_pwr; @@ -821,7 +805,7 @@ std::pair power_stat( const player &u ) return std::make_pair( c_pwr, s_pwr ); } -nc_color safe_color() +static nc_color safe_color() { nc_color s_color = g->safe_mode ? c_green : c_red; if( g->safe_mode == SAFE_MODE_OFF && get_option( "AUTOSAFEMODE" ) ) { @@ -840,7 +824,7 @@ nc_color safe_color() return s_color; } -int get_int_digits( const int &digits ) +static int get_int_digits( const int &digits ) { int temp = abs( digits ); if( digits > 0 ) { @@ -855,7 +839,7 @@ int get_int_digits( const int &digits ) // panels code // =============================== -void draw_limb_health( player &u, const catacurses::window &w, int limb_index ) +static void draw_limb_health( player &u, const catacurses::window &w, int limb_index ) { const bool is_self_aware = u.has_trait( trait_SELFAWARE ); static auto print_symbol_num = []( const catacurses::window & w, int num, const std::string & sym, @@ -902,7 +886,7 @@ void draw_limb_health( player &u, const catacurses::window &w, int limb_index ) } } -void draw_limb2( player &u, const catacurses::window &w ) +static void draw_limb2( player &u, const catacurses::window &w ) { static std::array part = { { bp_head, bp_torso, bp_arm_l, bp_arm_r, bp_leg_l, bp_leg_r @@ -952,7 +936,7 @@ void draw_limb2( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_stats( player &u, const catacurses::window &w ) +static void draw_stats( player &u, const catacurses::window &w ) { werase( w ); nc_color stat_clr = str_string( u ).first; @@ -974,7 +958,7 @@ void draw_stats( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_stealth( player &u, const catacurses::window &w ) +static void draw_stealth( player &u, const catacurses::window &w ) { werase( w ); mvwprintz( w, 0, 0, c_light_gray, _( "Speed" ) ); @@ -995,7 +979,7 @@ void draw_stealth( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_time_graphic( const catacurses::window &w ) +static void draw_time_graphic( const catacurses::window &w ) { std::vector > vGlyphs; vGlyphs.push_back( std::make_pair( '_', c_red ) ); @@ -1039,7 +1023,7 @@ void draw_time_graphic( const catacurses::window &w ) wprintz( w, c_white, "]" ); } -void draw_time( const player &u, const catacurses::window &w ) +static void draw_time( const player &u, const catacurses::window &w ) { werase( w ); // display date @@ -1063,7 +1047,7 @@ void draw_time( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_needs( const player &u, const catacurses::window &w ) +static void draw_needs( const player &u, const catacurses::window &w ) { werase( w ); @@ -1087,7 +1071,7 @@ void draw_needs( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_limb( player &u, const catacurses::window &w ) +static void draw_limb( player &u, const catacurses::window &w ) { werase( w ); int ny2 = 0; @@ -1133,7 +1117,7 @@ void draw_limb( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_char( player &u, const catacurses::window &w ) +static void draw_char( player &u, const catacurses::window &w ) { werase( w ); std::pair morale_pair = morale_stat( u ); @@ -1170,7 +1154,7 @@ void draw_char( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_stat( player &u, const catacurses::window &w ) +static void draw_stat( player &u, const catacurses::window &w ) { werase( w ); @@ -1196,7 +1180,7 @@ void draw_stat( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_env1( const player &u, const catacurses::window &w ) +static void draw_env1( const player &u, const catacurses::window &w ) { werase( w ); // display location @@ -1233,7 +1217,7 @@ void draw_env1( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_env2( const player &u, const catacurses::window &w ) +static void draw_env2( const player &u, const catacurses::window &w ) { werase( w ); mvwprintz( w, 0, 1, c_light_gray, _( "Moon : %s" ), get_moon() ); @@ -1241,7 +1225,7 @@ void draw_env2( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_weapon_labels( const player &u, const catacurses::window &w ) +static void draw_weapon_labels( const player &u, const catacurses::window &w ) { werase( w ); nc_color color = c_light_gray; @@ -1252,7 +1236,7 @@ void draw_weapon_labels( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_mod1( const player &u, const catacurses::window &w ) +static void draw_mod1( const player &u, const catacurses::window &w ) { werase( w ); std::pair hunger_pair = u.get_hunger_description(); @@ -1273,7 +1257,7 @@ void draw_mod1( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_env_compact( player &u, const catacurses::window &w ) +static void draw_env_compact( player &u, const catacurses::window &w ) { werase( w ); @@ -1311,7 +1295,7 @@ void draw_env_compact( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_health_classic( player &u, const catacurses::window &w ) +static void draw_health_classic( player &u, const catacurses::window &w ) { static std::array part = { { bp_head, bp_torso, bp_arm_l, bp_arm_r, bp_leg_l, bp_leg_r @@ -1426,7 +1410,7 @@ void draw_health_classic( player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_mod2( const player &u, const catacurses::window &w ) +static void draw_mod2( const player &u, const catacurses::window &w ) { werase( w ); nc_color color = c_light_gray; @@ -1445,7 +1429,7 @@ void draw_mod2( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_armor( const player &u, const catacurses::window &w ) +static void draw_armor( const player &u, const catacurses::window &w ) { werase( w ); nc_color color = c_light_gray; @@ -1464,7 +1448,7 @@ void draw_armor( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_messages( player &, const catacurses::window &w ) +static void draw_messages( player &, const catacurses::window &w ) { werase( w ); int line = getmaxy( w ) - 2; @@ -1473,7 +1457,7 @@ void draw_messages( player &, const catacurses::window &w ) wrefresh( w ); } -void draw_messages_classic( player &, const catacurses::window &w ) +static void draw_messages_classic( player &, const catacurses::window &w ) { werase( w ); int line = getmaxy( w ) - 2; @@ -1482,28 +1466,30 @@ void draw_messages_classic( player &, const catacurses::window &w ) wrefresh( w ); } -void draw_mminimap( player &, const catacurses::window &w ) +#if defined(TILES) +static void draw_mminimap( player &, const catacurses::window &w ) { werase( w ); g->draw_pixel_minimap( w ); wrefresh( w ); } +#endif -void draw_compass( player &, const catacurses::window &w ) +static void draw_compass( player &, const catacurses::window &w ) { werase( w ); g->mon_info( w ); wrefresh( w ); } -void draw_compass_padding( player &, const catacurses::window &w ) +static void draw_compass_padding( player &, const catacurses::window &w ) { werase( w ); g->mon_info( w, 1 ); wrefresh( w ); } -void draw_veh_compact( const player &u, const catacurses::window &w ) +static void draw_veh_compact( const player &u, const catacurses::window &w ) { werase( w ); @@ -1536,7 +1522,7 @@ void draw_veh_compact( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_veh_padding( const player &u, const catacurses::window &w ) +static void draw_veh_padding( const player &u, const catacurses::window &w ) { werase( w ); @@ -1568,7 +1554,7 @@ void draw_veh_padding( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_ai_goal( const player &u, const catacurses::window &w ) +static void draw_ai_goal( const player &u, const catacurses::window &w ) { werase( w ); behavior::tree needs; @@ -1579,7 +1565,7 @@ void draw_ai_goal( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_location_classic( const player &u, const catacurses::window &w ) +static void draw_location_classic( const player &u, const catacurses::window &w ) { werase( w ); @@ -1590,7 +1576,7 @@ void draw_location_classic( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_weather_classic( player &, const catacurses::window &w ) +static void draw_weather_classic( player &, const catacurses::window &w ) { werase( w ); @@ -1608,7 +1594,7 @@ void draw_weather_classic( player &, const catacurses::window &w ) wrefresh( w ); } -void draw_lighting_classic( const player &u, const catacurses::window &w ) +static void draw_lighting_classic( const player &u, const catacurses::window &w ) { werase( w ); @@ -1626,7 +1612,7 @@ void draw_lighting_classic( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_weapon_classic( const player &u, const catacurses::window &w ) +static void draw_weapon_classic( const player &u, const catacurses::window &w ) { werase( w ); @@ -1655,7 +1641,7 @@ void draw_weapon_classic( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_time_classic( const player &u, const catacurses::window &w ) +static void draw_time_classic( const player &u, const catacurses::window &w ) { werase( w ); @@ -1681,7 +1667,7 @@ void draw_time_classic( const player &u, const catacurses::window &w ) wrefresh( w ); } -void draw_hint( const player &, const catacurses::window &w ) +static void draw_hint( const player &, const catacurses::window &w ) { werase( w ); std::string press = press_x( ACTION_TOGGLE_PANEL_ADM ); @@ -1695,7 +1681,7 @@ void draw_hint( const player &, const catacurses::window &w ) // INITIALIZERS // ============ -std::vector initialize_default_classic_panels() +static std::vector initialize_default_classic_panels() { std::vector ret; @@ -1713,13 +1699,13 @@ std::vector initialize_default_classic_panels() true ) ); ret.emplace_back( window_panel( draw_messages_classic, translate_marker( "Log" ), -2, 44, true ) ); #if defined(TILES) - ret.emplace_back( window_panel( draw_mminimap, translate_marker( "Map" ), -1, 44, true ) ); + ret.emplace_back( window_panel( draw_mminimap, translate_marker( "Map" ), -1, 44, true, true ) ); #endif // TILES ret.emplace_back( window_panel( draw_ai_goal, "AI Needs", 1, 44, false ) ); return ret; } -std::vector initialize_default_compact_panels() +static std::vector initialize_default_compact_panels() { std::vector ret; @@ -1734,14 +1720,14 @@ std::vector initialize_default_compact_panels() ret.emplace_back( window_panel( draw_messages_classic, translate_marker( "Log" ), -2, 32, true ) ); ret.emplace_back( window_panel( draw_compass, translate_marker( "Compass" ), 8, 32, true ) ); #if defined(TILES) - ret.emplace_back( window_panel( draw_mminimap, translate_marker( "Map" ), -1, 32, true ) ); + ret.emplace_back( window_panel( draw_mminimap, translate_marker( "Map" ), -1, 32, true, true ) ); #endif // TILES ret.emplace_back( window_panel( draw_ai_goal, "AI Needs", 1, 32, false ) ); return ret; } -std::vector initialize_default_label_panels() +static std::vector initialize_default_label_panels() { std::vector ret; @@ -1759,14 +1745,14 @@ std::vector initialize_default_label_panels() ret.emplace_back( window_panel( draw_compass_padding, translate_marker( "Compass" ), 8, 32, true ) ); #if defined(TILES) - ret.emplace_back( window_panel( draw_mminimap, translate_marker( "Map" ), -1, 32, true ) ); + ret.emplace_back( window_panel( draw_mminimap, translate_marker( "Map" ), -1, 32, true, true ) ); #endif // TILES ret.emplace_back( window_panel( draw_ai_goal, "AI Needs", 1, 32, false ) ); return ret; } -std::map> initialize_default_panel_layouts() +static std::map> initialize_default_panel_layouts() { std::map> ret; @@ -2012,7 +1998,7 @@ void panel_manager::draw_adm( const catacurses::window &w, size_t column, size_t } werase( w ); wrefresh( g->w_terrain ); - g->draw_panels( column, index ); + g->draw_panels( column, index, true ); return; } redraw = true; @@ -2028,7 +2014,7 @@ void panel_manager::draw_adm( const catacurses::window &w, size_t column, size_t to_map_font_dimension( width, h ); werase( w ); wrefresh( g->w_terrain ); - g->draw_panels( column, index ); + g->draw_panels( column, index, true ); // tell the game that the main screen might have a different size now. g->init_ui( true ); return; @@ -2050,7 +2036,7 @@ void panel_manager::draw_adm( const catacurses::window &w, size_t column, size_t if( action == "TOGGLE_PANEL" && column == 0 ) { panels[index - 1].toggle = !panels[index - 1].toggle; wrefresh( g->w_terrain ); - g->draw_panels( column, index ); + g->draw_panels( column, index, true ); return; } else if( action == "QUIT" ) { exit = true; diff --git a/src/panels.h b/src/panels.h index a60c12819ed92..cf10dadcfc4ad 100644 --- a/src/panels.h +++ b/src/panels.h @@ -28,13 +28,14 @@ class window_panel { public: window_panel( std::function draw_func, - const std::string &nm, int ht, int wd, bool default_toggle ); + const std::string &nm, int ht, int wd, bool default_toggle, bool force_draw = false ); std::function draw; int get_height() const; int get_width() const; std::string get_name() const; bool toggle; + bool always_draw; private: int height; diff --git a/src/pickup.cpp b/src/pickup.cpp index ba682ab6cfdf5..aa22da0312ff3 100644 --- a/src/pickup.cpp +++ b/src/pickup.cpp @@ -44,8 +44,8 @@ #include "units.h" #include "type_id.h" -typedef std::pair ItemCount; -typedef std::map PickupMap; +using ItemCount = std::pair; +using PickupMap = std::map; // Pickup helper functions static bool pick_one_up( const tripoint &pickup_target, item &newit, @@ -130,7 +130,7 @@ enum pickup_answer : int { NUM_ANSWERS }; -pickup_answer handle_problematic_pickup( const item &it, bool &offered_swap, +static pickup_answer handle_problematic_pickup( const item &it, bool &offered_swap, const std::string &explain ) { if( offered_swap ) { @@ -181,7 +181,12 @@ bool pick_one_up( const tripoint &pickup_target, item &newit, vehicle *veh, pickup_answer option = CANCEL; item leftovers = newit; const auto wield_check = u.can_wield( newit ); - + if( newit.has_owner() && + newit.get_owner() != g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ) { + if( !query_yn( "Picking up this item will be considered stealing, continue?" ) ) { + return false; + } + } if( newit.invlet != '\0' && u.invlet_to_position( newit.invlet ) != INT_MIN ) { // Existing invlet is not re-usable, remove it and let the code in player.cpp/inventory.cpp @@ -639,7 +644,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) filter_changed = true; } else { wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); } } else if( action == "ANY_INPUT" && raw_input_char == '`' ) { std::string ext = string_input_popup() @@ -697,7 +702,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) if( matches.empty() ) { popup( _( "Your filter returned no results" ) ); wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); // The filter must have results, or simply be emptied or canceled, // as this screen can't be reached without there being // items available @@ -720,7 +725,7 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) iScrollPos = 0; } wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); } item &selected_item = stacked_here[matches[selected]].begin()->_item; @@ -788,6 +793,15 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) wprintw( w_pickup, " - " ); } std::string item_name; + std::string stolen; + bool stealing = false; + if( this_item.has_owner() ) { + const faction *item_fac = this_item.get_owner(); + if( item_fac != g->faction_manager_ptr->get( faction_id( "your_followers" ) ) ) { + stolen = string_format( "!" ); + stealing = true; + } + } if( stacked_here[true_it].begin()->_item.ammo_type() == "money" ) { //Count charges // TODO: transition to the item_location system used for the inventory @@ -806,18 +820,40 @@ void Pickup::pick_up( const tripoint &p, int min, from_where get_items_from ) c > 0; ++it, --c ) { charges += it->_item.charges; } - item_name = string_format( _( "%s of %s" ), - stacked_here[true_it].begin()->_item.display_money( getitem[true_it].count, charges ), - format_money( charges_total ) ); + if( stealing ) { + //~ %s %s of %s ""!20 Cash Cards of $200" - ! added if stealing. + item_name = string_format( _( "%s %s of %s" ), stolen, + stacked_here[true_it].begin()->_item.display_money( getitem[true_it].count, charges ), + format_money( charges_total ) ); + } else { + item_name = string_format( _( "%s of %s" ), + stacked_here[true_it].begin()->_item.display_money( getitem[true_it].count, charges ), + format_money( charges_total ) ); + } } } else { - item_name = this_item.display_name( stacked_here[true_it].size() ); + if( stealing ) { + item_name = string_format( "%s %s", stolen, + this_item.display_name( stacked_here[true_it].size() ) ); + } else { + item_name = this_item.display_name( stacked_here[true_it].size() ); + } } if( stacked_here[true_it].size() > 1 ) { - item_name = string_format( "%d %s", stacked_here[true_it].size(), item_name ); + if( stealing ) { + item_name = string_format( "%s %d %s", stolen, stacked_here[true_it].size(), item_name ); + } else { + item_name = string_format( "%d %s", stacked_here[true_it].size(), item_name ); + } } if( get_option( "ITEM_SYMBOLS" ) ) { - item_name = string_format( "%s %s", this_item.symbol(), item_name ); + if( stealing ) { + item_name = string_format( "%s %s %s", stolen, this_item.symbol().c_str(), + item_name.c_str() ); + } else { + item_name = string_format( "%s %s", this_item.symbol().c_str(), + item_name ); + } } trim_and_print( w_pickup, 1 + ( cur_it % maxitems ), 6, pickupW - 4, icolor, item_name ); diff --git a/src/player.cpp b/src/player.cpp index e10cb4162beda..bf51bfc285cb9 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -560,7 +560,6 @@ player::player() : Character() style_none, style_kicks } }; - initialize_stomach_contents(); } player::~player() = default; @@ -579,27 +578,6 @@ void player::normalize() stamina = get_stamina_max(); } -std::string player::disp_name( bool possessive ) const -{ - if( !possessive ) { - if( is_player() ) { - return pgettext( "not possessive", "you" ); - } - return name; - } else { - if( is_player() ) { - return _( "your" ); - } - return string_format( _( "%s's" ), name ); - } -} - -std::string player::skin_name() const -{ - // TODO: Return actual deflecting layer name - return _( "armor" ); -} - void player::reset_stats() { // Trait / mutation buffs @@ -840,12 +818,13 @@ void player::process_turn() // auto-learning. This is here because skill-increases happens all over the place: // SkillLevel::readBook (has no connection to the skill or the player), // player::read, player::practice, ... - /** @EFFECT_UNARMED >1 allows spontaneous discovery of brawling martial art style */ - if( get_skill_level( skill_unarmed ) >= 2 ) { - const matype_id brawling( "style_brawling" ); - if( !has_martialart( brawling ) ) { - add_martialart( brawling ); - add_msg_if_player( m_info, _( "You learned a new style." ) ); + // Check for spontaneous discovery of martial art styles + for( auto &style : all_martialart_types() ) { + const matype_id ma( style ); + + if( can_autolearn( ma ) && !has_martialart( ma ) ) { + add_martialart( ma ); + add_msg_if_player( m_info, _( "You have learned a new style: %s!" ), ma.obj().name ); } } @@ -2183,228 +2162,6 @@ std::string player::save_info() const return ::serialize( *this ) + "\n" + dump_memorial(); } -void player::memorial( std::ostream &memorial_file, const std::string &epitaph ) -{ - static const char *eol = cata_files::eol(); - - //Size of indents in the memorial file - const std::string indent = " "; - - const std::string pronoun = male ? _( "He" ) : _( "She" ); - - //Avoid saying "a male unemployed" or similar - std::string profession_name; - if( prof == prof->generic() ) { - if( male ) { - profession_name = _( "an unemployed male" ); - } else { - profession_name = _( "an unemployed female" ); - } - } else { - profession_name = string_format( _( "a %s" ), prof->gender_appropriate_name( male ) ); - } - - const std::string locdesc = overmap_buffer.get_description_at( global_sm_location() ); - //~ First parameter is a pronoun ("He"/"She"), second parameter is a description - // that designates the location relative to its surroundings. - const std::string kill_place = string_format( _( "%1$s was killed in a %2$s." ), - pronoun, locdesc ); - - //Header - memorial_file << string_format( _( "Cataclysm - Dark Days Ahead version %s memorial file" ), - getVersionString() ) << eol; - memorial_file << eol; - memorial_file << string_format( _( "In memory of: %s" ), name ) << eol; - if( epitaph.length() > 0 ) { //Don't record empty epitaphs - //~ The "%s" will be replaced by an epitaph as displayed in the memorial files. Replace the quotation marks as appropriate for your language. - memorial_file << string_format( pgettext( "epitaph", "\"%s\"" ), epitaph ) << eol << eol; - } - //~ First parameter: Pronoun, second parameter: a profession name (with article) - memorial_file << string_format( _( "%1$s was %2$s when the apocalypse began." ), - pronoun, profession_name ) << eol; - memorial_file << string_format( _( "%1$s died on %2$s." ), pronoun, - to_string( time_point( calendar::turn ) ) ) << eol; - memorial_file << kill_place << eol; - memorial_file << eol; - - //Misc - memorial_file << string_format( _( "Cash on hand: %s" ), format_money( cash ) ) << eol; - memorial_file << eol; - - //HP - - const auto limb_hp = - [this, &memorial_file, &indent]( const std::string & desc, const hp_part bp ) { - memorial_file << indent << string_format( desc, get_hp( bp ), get_hp_max( bp ) ) << eol; - }; - - memorial_file << _( "Final HP:" ) << eol; - limb_hp( _( " Head: %d/%d" ), hp_head ); - limb_hp( _( "Torso: %d/%d" ), hp_torso ); - limb_hp( _( "L Arm: %d/%d" ), hp_arm_l ); - limb_hp( _( "R Arm: %d/%d" ), hp_arm_r ); - limb_hp( _( "L Leg: %d/%d" ), hp_leg_l ); - limb_hp( _( "R Leg: %d/%d" ), hp_leg_r ); - memorial_file << eol; - - //Stats - memorial_file << _( "Final Stats:" ) << eol; - memorial_file << indent << string_format( _( "Str %d" ), str_cur ) - << indent << string_format( _( "Dex %d" ), dex_cur ) - << indent << string_format( _( "Int %d" ), int_cur ) - << indent << string_format( _( "Per %d" ), per_cur ) << eol; - memorial_file << _( "Base Stats:" ) << eol; - memorial_file << indent << string_format( _( "Str %d" ), str_max ) - << indent << string_format( _( "Dex %d" ), dex_max ) - << indent << string_format( _( "Int %d" ), int_max ) - << indent << string_format( _( "Per %d" ), per_max ) << eol; - memorial_file << eol; - - //Last 20 messages - memorial_file << _( "Final Messages:" ) << eol; - std::vector > recent_messages = Messages::recent_messages( 20 ); - for( auto &recent_message : recent_messages ) { - memorial_file << indent << recent_message.first << " " << recent_message.second; - memorial_file << eol; - } - memorial_file << eol; - - //Kill list - memorial_file << _( "Kills:" ) << eol; - - int total_kills = 0; - - std::map, int> kill_counts; - - // map to kill count - for( const auto &type : MonsterGenerator::generator().get_all_mtypes() ) { - if( g->kill_count( type.id ) > 0 ) { - kill_counts[std::tuple( - type.nname(), - type.sym - )] += g->kill_count( type.id ); - total_kills += g->kill_count( type.id ); - } - } - - for( const auto &entry : kill_counts ) { - memorial_file << " " << std::get<1>( entry.first ) << " - " - << string_format( "%4d", entry.second ) << " " - << std::get<0>( entry.first ) << eol; - } - - if( total_kills == 0 ) { - memorial_file << indent << _( "No monsters were killed." ) << eol; - } else { - memorial_file << string_format( _( "Total kills: %d" ), total_kills ) << eol; - } - memorial_file << eol; - - //Skills - memorial_file << _( "Skills:" ) << eol; - for( auto &pair : *_skills ) { - const SkillLevel &lobj = pair.second; - //~ 1. skill name, 2. skill level, 3. exercise percentage to next level - memorial_file << indent << string_format( _( "%s: %d (%d %%)" ), pair.first->name(), lobj.level(), - lobj.exercise() ) << eol; - } - memorial_file << eol; - - //Traits - memorial_file << _( "Traits:" ) << eol; - for( auto &iter : my_mutations ) { - memorial_file << indent << mutation_branch::get_name( iter.first ) << eol; - } - if( !my_mutations.empty() ) { - memorial_file << indent << _( "(None)" ) << eol; - } - memorial_file << eol; - - //Effects (illnesses) - memorial_file << _( "Ongoing Effects:" ) << eol; - bool had_effect = false; - if( get_perceived_pain() > 0 ) { - had_effect = true; - memorial_file << indent << _( "Pain" ) << " (" << get_perceived_pain() << ")"; - } - if( !had_effect ) { - memorial_file << indent << _( "(None)" ) << eol; - } - memorial_file << eol; - - //Bionics - memorial_file << _( "Bionics:" ) << eol; - int total_bionics = 0; - for( size_t i = 0; i < my_bionics->size(); ++i ) { - memorial_file << indent << ( i + 1 ) << ": " << ( *my_bionics )[i].id->name << eol; - total_bionics++; - } - if( total_bionics == 0 ) { - memorial_file << indent << _( "No bionics were installed." ) << eol; - } else { - memorial_file << string_format( _( "Total bionics: %d" ), total_bionics ) << eol; - } - memorial_file << string_format( - _( "Bionic Power: %d/%d" ), power_level, - max_power_level ) << eol; - memorial_file << eol; - - //Equipment - memorial_file << _( "Weapon:" ) << eol; - memorial_file << indent << weapon.invlet << " - " << weapon.tname( 1, false ) << eol; - memorial_file << eol; - - memorial_file << _( "Equipment:" ) << eol; - for( auto &elem : worn ) { - item next_item = elem; - memorial_file << indent << next_item.invlet << " - " << next_item.tname( 1, false ); - if( next_item.charges > 0 ) { - memorial_file << " (" << next_item.charges << ")"; - } else if( next_item.contents.size() == 1 && next_item.contents.front().charges > 0 ) { - memorial_file << " (" << next_item.contents.front().charges << ")"; - } - memorial_file << eol; - } - memorial_file << eol; - - //Inventory - memorial_file << _( "Inventory:" ) << eol; - inv.restack( *this ); - invslice slice = inv.slice(); - for( auto &elem : slice ) { - item &next_item = elem->front(); - memorial_file << indent << next_item.invlet << " - " << - next_item.tname( static_cast( elem->size() ), false ); - if( elem->size() > 1 ) { - memorial_file << " [" << elem->size() << "]"; - } - if( next_item.charges > 0 ) { - memorial_file << " (" << next_item.charges << ")"; - } else if( next_item.contents.size() == 1 && next_item.contents.front().charges > 0 ) { - memorial_file << " (" << next_item.contents.front().charges << ")"; - } - memorial_file << eol; - } - memorial_file << eol; - - //Lifetime stats - memorial_file << _( "Lifetime Stats" ) << eol; - memorial_file << indent << string_format( _( "Distance walked: %d squares" ), - lifetime_stats.squares_walked ) << eol; - memorial_file << indent << string_format( _( "Damage taken: %d damage" ), - lifetime_stats.damage_taken ) << eol; - memorial_file << indent << string_format( _( "Damage healed: %d damage" ), - lifetime_stats.damage_healed ) << eol; - memorial_file << indent << string_format( _( "Headshots: %d" ), - lifetime_stats.headshots ) << eol; - memorial_file << eol; - - //History - memorial_file << _( "Game History" ) << eol; - memorial_file << dump_memorial(); - -} - /** * Adds an event to the memorial log, to be written to the memorial file when * the character dies. The message should contain only the informational string, @@ -2440,6 +2197,10 @@ void player::load_memorial_file( std::istream &fin ) memorial_log.clear(); while( fin.peek() == '|' ) { getline( fin, entry ); + // strip all \r from end of string + while( *entry.rbegin() == '\r' ) { + entry.pop_back(); + } memorial_log.push_back( entry ); } } @@ -6658,7 +6419,7 @@ bool player::irradiate( float rads, bool bypass ) } // At minimum level, return at_min, at maximum at_max -float addiction_scaling( float at_min, float at_max, float add_lvl ) +static float addiction_scaling( float at_min, float at_max, float add_lvl ) { // Not addicted if( add_lvl < MIN_ADDICTION_LEVEL ) { @@ -6780,16 +6541,6 @@ void player::mend( int rate_multiplier ) } } -// sets default stomach contents when starting the game -void player::initialize_stomach_contents() -{ - stomach = stomach_contents( 2500_ml ); - guts = stomach_contents( 24000_ml ); - guts.set_calories( 300 ); - stomach.set_calories( 800 ); - stomach.mod_contents( 475_ml ); -} - void player::vomit() { add_memorial_log( pgettext( "memorial_male", "Threw up." ), @@ -10952,7 +10703,7 @@ int player::warmth( body_part bp ) const return ret; } -int bestwarmth( const std::list< item > &its, const std::string &flag ) +static int bestwarmth( const std::list< item > &its, const std::string &flag ) { int best = 0; for( auto &w : its ) { @@ -11100,7 +10851,7 @@ int player::get_armor_fire( body_part bp ) const return get_armor_type( DT_HEAT, bp ); } -void destroyed_armor_msg( Character &who, const std::string &pre_damage_name ) +static void destroyed_armor_msg( Character &who, const std::string &pre_damage_name ) { //~ %s is armor name who.add_memorial_log( pgettext( "memorial_male", "Worn %s was completely destroyed." ), @@ -13054,62 +12805,3 @@ std::pair player::get_hunger_description() const return std::make_pair( hunger_string, hunger_color ); } - -float player::get_bmi() const -{ - return 12 * get_kcal_percent() + 13; -} - -units::mass player::bodyweight() const -{ - return units::from_gram( round( get_bmi() * pow( height() / 100, 2 ) ) ); -} - -int player::height() const -{ - return 175; -} - -int player::get_bmr() const -{ - /** - Values are for males, and average! - */ - const int age = 25; - const int equation_constant = 5; - return ceil( metabolic_rate_base() * activity_level * ( units::to_gram( 10 * bodyweight() ) + - ( 6.25 * height() ) - ( 5 * age ) + equation_constant ) ); -} - -void player::increase_activity_level( float new_level ) -{ - if( activity_level < new_level ) { - activity_level = new_level; - } -} - -void player::decrease_activity_level( float new_level ) -{ - if( activity_level > new_level ) { - activity_level = new_level; - } -} -void player::reset_activity_level() -{ - activity_level = NO_EXERCISE; -} - -std::string player::activity_level_str() const -{ - if( activity_level <= NO_EXERCISE ) { - return _( "NO_EXERCISE" ); - } else if( activity_level <= LIGHT_EXERCISE ) { - return _( "LIGHT_EXERCISE" ); - } else if( activity_level <= MODERATE_EXERCISE ) { - return _( "MODERATE_EXERCISE" ); - } else if( activity_level <= ACTIVE_EXERCISE ) { - return _( "ACTIVE_EXERCISE" ); - } else { - return _( "EXTRA_EXERCISE" ); - } -} diff --git a/src/player.h b/src/player.h index 9dadc71764bfe..0d5d5688e2fed 100644 --- a/src/player.h +++ b/src/player.h @@ -30,7 +30,6 @@ #include "player_activity.h" #include "ret_val.h" #include "weighted_list.h" -#include "stomach.h" #include "bodypart.h" #include "color.h" #include "creature.h" @@ -186,21 +185,12 @@ class player : public Character player &operator=( const player & ) = delete; player &operator=( player && ); - // newcharacter.cpp - bool create( character_type type, const std::string &tempname = "" ); - void randomize( bool random_scenario, points_left &points, bool play_now = false ); - bool load_template( const std::string &template_name, points_left &points ); - /** Calls Character::normalize() * normalizes HP and body temperature */ void normalize() override; - /** Returns either "you" or the player's name */ - std::string disp_name( bool possessive = false ) const override; - /** Returns the name of the player's outer layer, e.g. "armor plates" */ - std::string skin_name() const override; bool is_player() const override { return true; @@ -243,8 +233,6 @@ class player : public Character void serialize_map_memory( JsonOut &jsout ) const; void deserialize_map_memory( JsonIn &jsin ); - /** Prints out the player's memorial file */ - void memorial( std::ostream &memorial_file, const std::string &epitaph ); /** Handles and displays detailed character info for the '@' screen */ void disp_info(); /** Provides the window and detailed morale data */ @@ -509,6 +497,12 @@ class player : public Character void ma_onblock_effects(); /** Fires all get hit-triggered martial arts events */ void ma_ongethit_effects(); + /** Fires all miss-triggered martial arts events */ + void ma_onmiss_effects(); + /** Fires all crit-triggered martial arts events */ + void ma_oncrit_effects(); + /** Fires all kill-triggered martial arts events */ + void ma_onkill_effects(); /** Returns true if the player has any martial arts buffs attached */ bool has_mabuff( const mabuff_id &buff_id ) const; @@ -516,6 +510,8 @@ class player : public Character bool has_martialart( const matype_id &ma_id ) const; /** Adds the entered martial art to the player's list */ void add_martialart( const matype_id &ma_id ); + /** Returns true if the player can learn the entered martial art */ + bool can_autolearn( const matype_id &ma_id ) const; /** Returns the to hit bonus from martial arts buffs */ float mabuff_tohit_bonus() const; @@ -902,11 +898,7 @@ class player : public Character */ item &get_consumable_from( item &it ) const; - stomach_contents stomach; - stomach_contents guts; - std::pair get_hunger_description() const override; - void initialize_stomach_contents(); /** Get vitamin contents for a comestible */ std::map vitamins_from( const item &it ) const; @@ -948,8 +940,6 @@ class player : public Character */ bool vitamin_set( const vitamin_id &vit, int qty ); - /** Stable base metabolic rate due to traits */ - float metabolic_rate_base() const; /** Current metabolic rate due to traits, hunger, speed, etc. */ float metabolic_rate() const; /** Handles the effects of consuming an item */ @@ -1276,13 +1266,6 @@ class player : public Character int get_wind_resistance( body_part bp ) const; /** Returns the effect of pain on stats */ stat_mod get_pain_penalty() const; - float get_bmi() const; - // returns the height of the player character in cm - int height() const; - // returns bodyweight of the player - units::mass bodyweight() const; - // returns amount of calories burned in a day given various metabolic factors - int get_bmr() const; int kcal_speed_penalty(); /** Returns the penalty to speed from thirst */ static int thirst_speed_penalty( int thirst ); @@ -1328,7 +1311,6 @@ class player : public Character * All items that have the given flag (@ref item::has_flag). */ std::vector all_items_with_flag( const std::string &flag ) const; - void process_active_items(); /** * Remove charges from a specific item (given by its item position). @@ -1539,16 +1521,6 @@ class player : public Character const player_activity &destination_activity = player_activity() ); void clear_destination(); bool has_destination() const; - // increases the activity level to the next level - // does not decrease activity level - void increase_activity_level( float new_level ); - // decreases the activity level to the previous level - // does not increase activity level - void decrease_activity_level( float new_level ); - // sets activity level to NO_EXERCISE - void reset_activity_level(); - // outputs player activity level to a printable string - std::string activity_level_str() const; // true if player has destination activity AND is standing on destination tile bool has_destination_activity() const; // starts destination activity and cleans up to ensure it is called only once @@ -1739,7 +1711,7 @@ class player : public Character void add_msg_player_or_say( game_message_type type, const std::string &player_msg, const std::string &npc_speech ) const override; - typedef std::map trap_map; + using trap_map = std::map; bool knows_trap( const tripoint &pos ) const; void add_known_trap( const tripoint &pos, const trap &t ); /** Search surrounding squares for traps (and maybe other things in the future). */ @@ -1865,9 +1837,6 @@ class player : public Character known_magic magic; protected: - // the player's activity level for metabolism calculations - float activity_level = NO_EXERCISE; - // The player's position on the local map. tripoint position; @@ -1882,8 +1851,12 @@ class player : public Character private: friend class debug_menu::mission_debug; + protected: + // TODO: move this to avatar // Items the player has identified. std::unordered_set items_identified; + private: + /** Check if an area-of-effect technique has valid targets */ bool valid_aoe_technique( Creature &t, const ma_technique &technique ); bool valid_aoe_technique( Creature &t, const ma_technique &technique, @@ -1949,7 +1922,10 @@ class player : public Character int pkill; + protected: + // TODO: move this to avatar std::string move_mode; + private: std::vector auto_move_route; player_activity destination_activity; @@ -1962,14 +1938,23 @@ class player : public Character time_point cached_time; tripoint cached_position; + protected: + // TODO: move this to avatar object_type grab_type; + private: struct weighted_int_list melee_miss_reasons; + protected: + // TODO: move this to avatar pimpl morale; + private: int id; // A unique ID number, assigned by the game class private so it cannot be overwritten and cause save game corruptions. //NPCs also use this ID value. Values should never be reused. + + protected: + // TODO: move these to avatar /** * Missions that the player has accepted and that are not finished (one * way or the other). @@ -1987,10 +1972,13 @@ class player : public Character * The currently active mission, or null if no mission is currently in progress. */ mission *active_mission; + private: /** smart pointer to targeting data stored for aiming the player's weapon across turns. */ std::shared_ptr tdata; + protected: + // TODO: move these to avatar /** Current deficiency/excess quantity for each vitamin */ std::map vitamin_levels; @@ -1999,10 +1987,13 @@ class player : public Character /** Stamp of skills. @ref learned_recipes are valid only with this set of skills. */ mutable decltype( _skills ) valid_autolearn_skills; + private: /** Amount of time the player has spent in each overmap tile. */ std::unordered_map overmap_time; + protected: + // TODO: move these to avatar map_memory player_map_memory; bool show_map_memory; }; diff --git a/src/player_display.cpp b/src/player_display.cpp index 1edd8794e708f..c4b408f259a7e 100644 --- a/src/player_display.cpp +++ b/src/player_display.cpp @@ -27,12 +27,12 @@ const skill_id skill_swimming( "swimming" ); static const std::string header_spaces( 26, ' ' ); // Rescale temperature value to one that the player sees -int temperature_print_rescaling( int temp ) +static int temperature_print_rescaling( int temp ) { return ( temp / 100.0 ) * 2 - 100; } -bool should_combine_bps( const player &p, size_t l, size_t r ) +static bool should_combine_bps( const player &p, size_t l, size_t r ) { const auto enc_data = p.get_encumbrance(); return enc_data[l] == enc_data[r] && @@ -121,7 +121,7 @@ void player::print_encumbrance( const catacurses::window &win, int line, } -std::string swim_cost_text( int moves ) +static std::string swim_cost_text( int moves ) { return string_format( ngettext( "Swimming costs %+d movement point. ", "Swimming costs %+d movement points. ", @@ -129,7 +129,7 @@ std::string swim_cost_text( int moves ) moves ); } -std::string run_cost_text( int moves ) +static std::string run_cost_text( int moves ) { return string_format( ngettext( "Running costs %+d movement point. ", "Running costs %+d movement points. ", @@ -137,7 +137,7 @@ std::string run_cost_text( int moves ) moves ); } -std::string reload_cost_text( int moves ) +static std::string reload_cost_text( int moves ) { return string_format( ngettext( "Reloading costs %+d movement point. ", "Reloading costs %+d movement points. ", @@ -145,7 +145,7 @@ std::string reload_cost_text( int moves ) moves ); } -std::string melee_cost_text( int moves ) +static std::string melee_cost_text( int moves ) { return string_format( ngettext( "Melee and thrown attacks cost %+d movement point. ", "Melee and thrown attacks cost %+d movement points. ", @@ -153,12 +153,12 @@ std::string melee_cost_text( int moves ) moves ); } -std::string dodge_skill_text( double mod ) +static std::string dodge_skill_text( double mod ) { return string_format( _( "Dodge skill %+.1f. " ), mod ); } -int get_encumbrance( const player &p, body_part bp, bool combine ) +static int get_encumbrance( const player &p, body_part bp, bool combine ) { // Body parts that can't combine with anything shouldn't print double values on combine // This shouldn't happen, but handle this, just in case @@ -166,7 +166,7 @@ int get_encumbrance( const player &p, body_part bp, bool combine ) return p.encumb( bp ) * ( ( combine && combines_with_other ) ? 2 : 1 ); } -std::string get_encumbrance_description( const player &p, body_part bp, bool combine ) +static std::string get_encumbrance_description( const player &p, body_part bp, bool combine ) { std::string s; diff --git a/src/pldata.h b/src/pldata.h index c3be993a0d3b7..2babe38ae07b9 100644 --- a/src/pldata.h +++ b/src/pldata.h @@ -9,7 +9,7 @@ class JsonIn; class JsonOut; -typedef std::string dis_type; +using dis_type = std::string; enum character_type : int { PLTYPE_CUSTOM, diff --git a/src/profession.h b/src/profession.h index b3dc6138964cd..a7d7e4a1f8f74 100644 --- a/src/profession.h +++ b/src/profession.h @@ -27,8 +27,8 @@ enum add_type : int; class profession { public: - typedef std::pair StartingSkill; - typedef std::vector StartingSkillList; + using StartingSkill = std::pair; + using StartingSkillList = std::vector; struct itypedec { std::string type_id; /** Snippet id, @see snippet_library. */ @@ -39,7 +39,7 @@ class profession itypedec( const std::string &t, const std::string &d ) : type_id( t ), snippet_id( d ) { } }; - typedef std::vector itypedecvec; + using itypedecvec = std::vector; friend class string_id; friend class generic_factory; diff --git a/src/ranged.cpp b/src/ranged.cpp index 6b75c2d7d7cbe..7bfb3deb92d31 100644 --- a/src/ranged.cpp +++ b/src/ranged.cpp @@ -404,7 +404,7 @@ int player::fire_gun( const tripoint &target, int shots, item &gun ) } // TODO: Method -int throw_cost( const player &c, const item &to_throw ) +static int throw_cost( const player &c, const item &to_throw ) { // Very similar to player::attack_speed // TODO: Extract into a function? @@ -810,9 +810,9 @@ static std::vector get_default_aim_type() return aim_types; } -typedef std::vector> RatingVector; -std::string get_colored_bar( const double val, const int width, const std::string &label, - RatingVector::iterator begin, RatingVector::iterator end ) +using RatingVector = std::vector>; +static std::string get_colored_bar( const double val, const int width, const std::string &label, + RatingVector::iterator begin, RatingVector::iterator end ) { std::string result; @@ -1402,6 +1402,7 @@ std::vector target_handler::target_ui( player &pc, target_mode mode, } wrefresh( g->w_terrain ); + g->draw_panels(); draw_targeting_window( w_target, relevant->tname(), mode, ctxt, aim_types, tiny ); wrefresh( w_target ); diff --git a/src/recipe.cpp b/src/recipe.cpp index e880c95deaa52..e6ec87986e7e8 100644 --- a/src/recipe.cpp +++ b/src/recipe.cpp @@ -48,7 +48,7 @@ int recipe::batch_time( int batch, float multiplier, size_t assistants ) const // recipe benefits from batching, so batching scale factor needs to be calculated // At batch_rsize, incremental time increase is 99.5% of batch_rscale const double scale = batch_rsize / 6.0; - for( double x = 0; x < batch; x++ ) { + for( int x = 0; x < batch; x++ ) { // scaled logistic function output const double logf = ( 2.0 / ( 1.0 + exp( -( x / scale ) ) ) ) - 1.0; total_time += local_time * ( 1.0 - ( batch_rscale * logf ) ); diff --git a/src/recipe_dictionary.h b/src/recipe_dictionary.h index b6fb93fc9847a..70ff2f6595dc0 100644 --- a/src/recipe_dictionary.h +++ b/src/recipe_dictionary.h @@ -17,7 +17,7 @@ class JsonIn; class JsonOut; class JsonObject; -typedef std::string itype_id; +using itype_id = std::string; class recipe_dictionary { diff --git a/src/regional_settings.cpp b/src/regional_settings.cpp index 54e15df891116..9d0e16f351101 100644 --- a/src/regional_settings.cpp +++ b/src/regional_settings.cpp @@ -30,8 +30,8 @@ void read_and_set_or_throw( JsonObject &jo, const std::string &member, T &target } } -void load_forest_biome_component( JsonObject &jo, forest_biome_component &forest_biome_component, - const bool overlay ) +static void load_forest_biome_component( + JsonObject &jo, forest_biome_component &forest_biome_component, const bool overlay ) { read_and_set_or_throw( jo, "chance", forest_biome_component.chance, !overlay ); read_and_set_or_throw( jo, "sequence", forest_biome_component.sequence, !overlay ); @@ -59,7 +59,7 @@ void load_forest_biome_component( JsonObject &jo, forest_biome_component &forest } } -void load_forest_biome_terrain_dependent_furniture( JsonObject &jo, +static void load_forest_biome_terrain_dependent_furniture( JsonObject &jo, forest_biome_terrain_dependent_furniture &forest_biome_terrain_dependent_furniture, const bool overlay ) { @@ -90,7 +90,7 @@ void load_forest_biome_terrain_dependent_furniture( JsonObject &jo, } } -void load_forest_biome( JsonObject &jo, forest_biome &forest_biome, const bool overlay ) +static void load_forest_biome( JsonObject &jo, forest_biome &forest_biome, const bool overlay ) { read_and_set_or_throw( jo, "sparseness_adjacency_factor", forest_biome.sparseness_adjacency_factor, !overlay ); @@ -162,9 +162,10 @@ void load_forest_biome( JsonObject &jo, forest_biome &forest_biome, const bool o } } -void load_forest_mapgen_settings( JsonObject &jo, forest_mapgen_settings &forest_mapgen_settings, - const bool strict, - const bool overlay ) +static void load_forest_mapgen_settings( JsonObject &jo, + forest_mapgen_settings &forest_mapgen_settings, + const bool strict, + const bool overlay ) { if( !jo.has_object( "forest_mapgen_settings" ) ) { if( strict ) { @@ -183,8 +184,9 @@ void load_forest_mapgen_settings( JsonObject &jo, forest_mapgen_settings &forest } } -void load_forest_trail_settings( JsonObject &jo, forest_trail_settings &forest_trail_settings, - const bool strict, const bool overlay ) +static void load_forest_trail_settings( JsonObject &jo, + forest_trail_settings &forest_trail_settings, + const bool strict, const bool overlay ) { if( !jo.has_object( "forest_trail_settings" ) ) { if( strict ) { @@ -240,7 +242,7 @@ void load_forest_trail_settings( JsonObject &jo, forest_trail_settings &forest_t } } -void load_overmap_feature_flag_settings( JsonObject &jo, +static void load_overmap_feature_flag_settings( JsonObject &jo, overmap_feature_flag_settings &overmap_feature_flag_settings, const bool strict, const bool overlay ) { @@ -287,8 +289,9 @@ void load_overmap_feature_flag_settings( JsonObject &jo, } } -void load_overmap_forest_settings( JsonObject &jo, overmap_forest_settings &overmap_forest_settings, - const bool strict, const bool overlay ) +static void load_overmap_forest_settings( + JsonObject &jo, overmap_forest_settings &overmap_forest_settings, const bool strict, + const bool overlay ) { if( !jo.has_object( "overmap_forest_settings" ) ) { if( strict ) { @@ -311,8 +314,9 @@ void load_overmap_forest_settings( JsonObject &jo, overmap_forest_settings &over } } -void load_overmap_lake_settings( JsonObject &jo, overmap_lake_settings &overmap_lake_settings, - const bool strict, const bool overlay ) +static void load_overmap_lake_settings( JsonObject &jo, + overmap_lake_settings &overmap_lake_settings, + const bool strict, const bool overlay ) { if( !jo.has_object( "overmap_lake_settings" ) ) { if( strict ) { diff --git a/src/regional_settings.h b/src/regional_settings.h index 9b57ea775187d..482537f8b23a0 100644 --- a/src/regional_settings.h +++ b/src/regional_settings.h @@ -234,8 +234,8 @@ struct regional_settings { void finalize(); }; -typedef std::unordered_map t_regional_settings_map; -typedef t_regional_settings_map::const_iterator t_regional_settings_map_citr; +using t_regional_settings_map = std::unordered_map; +using t_regional_settings_map_citr = t_regional_settings_map::const_iterator; extern t_regional_settings_map region_settings_map; void load_region_settings( JsonObject &jo ); diff --git a/src/requirements.h b/src/requirements.h index f411e546902ab..78157af4e8dcf 100644 --- a/src/requirements.h +++ b/src/requirements.h @@ -18,7 +18,7 @@ class inventory; class item; // Denotes the id of an item type -typedef std::string itype_id; +using itype_id = std::string; enum available_status { a_true = +1, // yes, it's available @@ -158,9 +158,9 @@ struct requirement_data { // TODO: remove once all parts specify installation requirements directly friend class vpart_info; - typedef std::vector< std::vector > alter_tool_comp_vector; - typedef std::vector< std::vector > alter_quali_req_vector; - typedef std::vector< std::vector > alter_item_comp_vector; + using alter_tool_comp_vector = std::vector >; + using alter_quali_req_vector = std::vector >; + using alter_item_comp_vector = std::vector >; private: alter_tool_comp_vector tools; diff --git a/src/savegame.cpp b/src/savegame.cpp index d7b9927d1d8bd..b063bc4496d4d 100644 --- a/src/savegame.cpp +++ b/src/savegame.cpp @@ -137,7 +137,7 @@ std::string scent_map::serialize() const return rle_out.str(); } -void chkversion( std::istream &fin ) +static void chkversion( std::istream &fin ) { if( fin.peek() == '#' ) { std::string vline; diff --git a/src/savegame_json.cpp b/src/savegame_json.cpp index 64fec5b411aef..cd69da5a21f18 100644 --- a/src/savegame_json.cpp +++ b/src/savegame_json.cpp @@ -97,7 +97,7 @@ static const std::array obj_type_name = { { "OBJECT_NO }; // TODO: investigate serializing other members of the Creature class hierarchy -void serialize( const std::weak_ptr &obj, JsonOut &jsout ) +static void serialize( const std::weak_ptr &obj, JsonOut &jsout ) { if( const auto monster_ptr = obj.lock() ) { jsout.start_object(); @@ -113,7 +113,7 @@ void serialize( const std::weak_ptr &obj, JsonOut &jsout ) } } -void deserialize( std::weak_ptr &obj, JsonIn &jsin ) +static void deserialize( std::weak_ptr &obj, JsonIn &jsin ) { JsonObject data = jsin.get_object(); tripoint temp_pos; @@ -330,6 +330,9 @@ void SkillLevel::deserialize( JsonIn &jsin ) } } +//////////////////////////////////////////////////////////////////////////////////////////////////// +///// Character.h, avatar + npc + void Character::trait_data::serialize( JsonOut &json ) const { json.start_object(); @@ -347,10 +350,8 @@ void Character::trait_data::deserialize( JsonIn &jsin ) data.read( "powered", powered ); } -//////////////////////////////////////////////////////////////////////////////////////////////////// -///// Character.h, player + npc -/* - * Gather variables for saving. These variables are common to both the player and NPCs. +/** + * Gather variables for saving. These variables are common to both the avatar and NPCs. */ void Character::load( JsonObject &data ) { @@ -478,6 +479,9 @@ void Character::load( JsonObject &data ) on_stat_change( "sleep_deprivation", sleep_deprivation ); } +/** + * Load variables from json into object. These variables are common to both the avatar and NPCs. + */ void Character::store( JsonOut &json ) const { Creature::store( json ); @@ -527,17 +531,146 @@ void Character::store( JsonOut &json ) const json.end_object(); } -void avatar::load( JsonObject &data ) +//////////////////////////////////////////////////////////////////////////////////////////////////// +///// player.h, avatar + npc + +/* + * Prepare a json object for player, including player specific data, and data common to + * players and npcs. + * TODO: Make player abstract and delete this + */ +void player::serialize( JsonOut &json ) const { - player::load( data ); + json.start_object(); + // This must be after the json object has been started, so any super class + // puts their data into the same json object. + store( json ); + + json.end_object(); +} + +/** + * Gather variables for saving. These variables are common to both the avatar and npcs. + */ +void player::store( JsonOut &json ) const +{ + Character::store( json ); + + // assumes already in player object + // positional data + json.member( "posx", position.x ); + json.member( "posy", position.y ); + json.member( "posz", position.z ); + + // energy + json.member( "stim", stim ); + json.member( "last_sleep_check", last_sleep_check ); + // pain + json.member( "pkill", pkill ); + // misc levels + json.member( "radiation", radiation ); + json.member( "tank_plut", tank_plut ); + json.member( "reactor_plut", reactor_plut ); + json.member( "slow_rad", slow_rad ); + json.member( "scent", static_cast( scent ) ); + json.member( "body_wetness", body_wetness ); + + // breathing + json.member( "oxygen", oxygen ); + + // gender + json.member( "male", male ); + + json.member( "cash", cash ); + json.member( "recoil", recoil ); + json.member( "in_vehicle", in_vehicle ); + json.member( "id", getID() ); + + // potential incompatibility with future expansion + // TODO: consider ["parts"]["head"]["hp_cur"] instead of ["hp_cur"][head_enum_value] + json.member( "hp_cur", hp_cur ); + json.member( "hp_max", hp_max ); + json.member( "damage_bandaged", damage_bandaged ); + json.member( "damage_disinfected", damage_disinfected ); + + // npc; unimplemented + json.member( "power_level", power_level ); + json.member( "max_power_level", max_power_level ); + + json.member( "ma_styles", ma_styles ); + // "Looks like I picked the wrong week to quit smoking." - Steve McCroskey + json.member( "addictions", addictions ); + json.member( "followers", follower_ids ); + json.member( "known_traps" ); + json.start_array(); + for( const auto &elem : known_traps ) { + json.start_object(); + json.member( "x", elem.first.x ); + json.member( "y", elem.first.y ); + json.member( "z", elem.first.z ); + json.member( "trap", elem.second ); + json.end_object(); + } + json.end_array(); + + json.member( "worn", worn ); // also saves contents + + json.member( "inv" ); + inv.json_save_items( json ); + + if( !weapon.is_null() ) { + json.member( "weapon", weapon ); // also saves contents + } + + if( const auto lt_ptr = last_target.lock() ) { + if( const npc *const guy = dynamic_cast( lt_ptr.get() ) ) { + json.member( "last_target", guy->getID() ); + json.member( "last_target_type", +1 ); + } else if( const monster *const mon = dynamic_cast( lt_ptr.get() ) ) { + // monsters don't have IDs, so get its index in the Creature_tracker instead + json.member( "last_target", g->critter_tracker->temporary_id( *mon ) ); + json.member( "last_target_type", -1 ); + } + } else { + json.member( "last_target_pos", last_target_pos ); + } + + json.member( "ammo_location", ammo_location ); + + json.member( "camps" ); + json.start_array(); + for( const tripoint &bcpt : camps ) { + json.start_object(); + json.member( "pos", bcpt ); + json.end_object(); + } + json.end_array(); + + if( !overmap_time.empty() ) { + json.member( "overmap_time" ); + json.start_array(); + for( const std::pair &pr : overmap_time ) { + json.write( pr.first ); + json.write( pr.second ); + } + json.end_array(); + } } -//////////////////////////////////////////////////////////////////////////////////////////////////// -///// player.h, player (+ npc for now, should eventually only be the player) /* - * Gather variables for saving. + * Load player (soon to be renamed to survivor) from ginormous json blob. + * Used for avatars and npcs. + * TODO: Make player abstract and delete this */ +void player::deserialize( JsonIn &jsin ) +{ + JsonObject data = jsin.get_object(); + load( data ); +} +/** + * Load variables from json into object. These variables are common to both the avatar and NPCs. + */ void player::load( JsonObject &data ) { Character::load( data ); @@ -668,122 +801,8 @@ void player::load( JsonObject &data ) } } -void avatar::store( JsonOut &json ) const -{ - player::store( json ); -} - -/* - * Variables common to player (and npc's, should eventually just be players) - */ -void player::store( JsonOut &json ) const -{ - Character::store( json ); - - // assumes already in player object - // positional data - json.member( "posx", position.x ); - json.member( "posy", position.y ); - json.member( "posz", position.z ); - - // energy - json.member( "stim", stim ); - json.member( "last_sleep_check", last_sleep_check ); - // pain - json.member( "pkill", pkill ); - // misc levels - json.member( "radiation", radiation ); - json.member( "tank_plut", tank_plut ); - json.member( "reactor_plut", reactor_plut ); - json.member( "slow_rad", slow_rad ); - json.member( "scent", static_cast( scent ) ); - json.member( "body_wetness", body_wetness ); - - // breathing - json.member( "oxygen", oxygen ); - - // gender - json.member( "male", male ); - - json.member( "cash", cash ); - json.member( "recoil", recoil ); - json.member( "in_vehicle", in_vehicle ); - json.member( "id", getID() ); - - // potential incompatibility with future expansion - // TODO: consider ["parts"]["head"]["hp_cur"] instead of ["hp_cur"][head_enum_value] - json.member( "hp_cur", hp_cur ); - json.member( "hp_max", hp_max ); - json.member( "damage_bandaged", damage_bandaged ); - json.member( "damage_disinfected", damage_disinfected ); - - // npc; unimplemented - json.member( "power_level", power_level ); - json.member( "max_power_level", max_power_level ); - - // martial arts - /*for (int i = 0; i < ma_styles.size(); i++) { - ptmpvect.push_back( pv( ma_styles[i] ) ); - }*/ - json.member( "ma_styles", ma_styles ); - // "Looks like I picked the wrong week to quit smoking." - Steve McCroskey - json.member( "addictions", addictions ); - json.member( "followers", follower_ids ); - json.member( "known_traps" ); - json.start_array(); - for( const auto &elem : known_traps ) { - json.start_object(); - json.member( "x", elem.first.x ); - json.member( "y", elem.first.y ); - json.member( "z", elem.first.z ); - json.member( "trap", elem.second ); - json.end_object(); - } - json.end_array(); - - json.member( "worn", worn ); // also saves contents - - json.member( "inv" ); - inv.json_save_items( json ); - - if( !weapon.is_null() ) { - json.member( "weapon", weapon ); // also saves contents - } - - if( const auto lt_ptr = last_target.lock() ) { - if( const npc *const guy = dynamic_cast( lt_ptr.get() ) ) { - json.member( "last_target", guy->getID() ); - json.member( "last_target_type", +1 ); - } else if( const monster *const mon = dynamic_cast( lt_ptr.get() ) ) { - // monsters don't have IDs, so get its index in the Creature_tracker instead - json.member( "last_target", g->critter_tracker->temporary_id( *mon ) ); - json.member( "last_target_type", -1 ); - } - } else { - json.member( "last_target_pos", last_target_pos ); - } - - json.member( "ammo_location", ammo_location ); - - json.member( "camps" ); - json.start_array(); - for( const tripoint &bcpt : camps ) { - json.start_object(); - json.member( "pos", bcpt ); - json.end_object(); - } - json.end_array(); - - if( !overmap_time.empty() ) { - json.member( "overmap_time" ); - json.start_array(); - for( const std::pair &pr : overmap_time ) { - json.write( pr.first ); - json.write( pr.second ); - } - json.end_array(); - } -} +//////////////////////////////////////////////////////////////////////////////////////////////////// +///// avatar.h void avatar::serialize( JsonOut &json ) const { @@ -794,22 +813,9 @@ void avatar::serialize( JsonOut &json ) const json.end_object(); } -//////////////////////////////////////////////////////////////////////////////////////////////////// -///// player.h, player -/* - * Prepare a json object for player, including player specific data, and data common to - players and npcs ( which json_save_actor_data() handles ). - */ -void player::serialize( JsonOut &json ) const +void avatar::store( JsonOut &json ) const { - json.start_object(); - // This must be after the json object has been started, so any super class - // puts their data into the same json object. - store( json ); - - // TODO: once npcs are separated from the player class, - // this code should go into player::store, serialize will then only - // contain start_object(), store(), end_object(). + player::store( json ); // player-specific specifics if( prof != nullptr ) { @@ -878,15 +884,6 @@ void player::serialize( JsonOut &json ) const json.member( "invcache" ); inv.json_save_invcache( json ); - - // FIXME: separate function, better still another file - /* for( size_t i = 0; i < memorial_log.size(); ++i ) { - ptmpvect.push_back(pv(memorial_log[i])); - } - json.member("memorial",ptmpvect); - */ - - json.end_object(); } void avatar::deserialize( JsonIn &jsin ) @@ -895,18 +892,9 @@ void avatar::deserialize( JsonIn &jsin ) load( data ); } -/* - * load player from ginormous json blob - */ -void player::deserialize( JsonIn &jsin ) +void avatar::load( JsonObject &data ) { - JsonObject data = jsin.get_object(); - - load( data ); - - // TODO: once npcs are separated from the player class, - // this code should go into player::load, deserialize will then only - // contain get_object(), load() + player::load( data ); std::string prof_ident = "(null)"; if( data.read( "profession", prof_ident ) && string_id( prof_ident ).is_valid() ) { @@ -1302,8 +1290,6 @@ void npc::deserialize( JsonIn &jsin ) void npc::load( JsonObject &data ) { - // TODO: once npcs are separated from the player class, - // this should call load on the parent class of npc (probably Character). player::load( data ); int misstmp = 0; @@ -1505,8 +1491,6 @@ void npc::serialize( JsonOut &json ) const void npc::store( JsonOut &json ) const { - // TODO: once npcs are separated from the player class, - // this should call store on the parent class of npc (probably Character). player::store( json ); json.member( "name", name ); @@ -1950,6 +1934,9 @@ void item::io( Archive &archive ) const auto load_making = [this]( const std::string & id ) { making = &recipe_id( id ).obj(); }; + const auto load_owner = [this]( const std::string & id ) { + owner = g->faction_manager_ptr->get( faction_id( id ) ); + }; archive.template io( "typeid", type, load_type, []( const itype & i ) { return i.get_id(); @@ -1999,6 +1986,10 @@ void item::io( Archive &archive ) []( const recipe & i ) { return i.ident().str(); } ); + archive.template io( "owner", owner, load_owner, + []( const faction & i ) { + return i.id.str(); + } ); archive.io( "light", light.luminance, nolight.luminance ); archive.io( "light_width", light.width, nolight.width ); archive.io( "light_dir", light.direction, nolight.direction ); @@ -2344,7 +2335,7 @@ void vehicle_part::serialize( JsonOut &json ) const /* * label */ -void deserialize( label &val, JsonIn &jsin ) +static void deserialize( label &val, JsonIn &jsin ) { JsonObject data = jsin.get_object(); data.read( "x", val.x ); @@ -2352,7 +2343,7 @@ void deserialize( label &val, JsonIn &jsin ) data.read( "text", val.text ); } -void serialize( const label &val, JsonOut &json ) +static void serialize( const label &val, JsonOut &json ) { json.start_object(); json.member( "x", val.x ); diff --git a/src/scenario.cpp b/src/scenario.cpp index 6b8343c614f48..6876ab0b3b118 100644 --- a/src/scenario.cpp +++ b/src/scenario.cpp @@ -126,7 +126,7 @@ void scenario::check_definitions() } } -void check_traits( const std::set &traits, const string_id &ident ) +static void check_traits( const std::set &traits, const string_id &ident ) { for( auto &t : traits ) { if( !t.is_valid() ) { diff --git a/src/scent_map.cpp b/src/scent_map.cpp index 50287d0ec34b0..47351a095a462 100644 --- a/src/scent_map.cpp +++ b/src/scent_map.cpp @@ -13,7 +13,7 @@ static constexpr int SCENT_RADIUS = 40; -nc_color sev( const size_t level ) +static nc_color sev( const size_t level ) { static const std::array colors = { { c_cyan, diff --git a/src/sdlsound.cpp b/src/sdlsound.cpp index 0880360ee613f..9bb56920dc7b3 100644 --- a/src/sdlsound.cpp +++ b/src/sdlsound.cpp @@ -129,7 +129,7 @@ void shutdown_sound() void musicFinished(); -void play_music_file( const std::string &filename, int volume ) +static void play_music_file( const std::string &filename, int volume ) { if( !check_sound( volume ) ) { return; @@ -338,7 +338,7 @@ void sfx::load_playlist( JsonObject &jsobj ) // Returns a random sound effect matching given id and variant or `nullptr` if there is no // matching sound effect. -const sound_effect *find_random_effect( const id_and_variant &id_variants_pair ) +static const sound_effect *find_random_effect( const id_and_variant &id_variants_pair ) { const auto iter = sfx_resources.sound_effects.find( id_variants_pair ); if( iter == sfx_resources.sound_effects.end() ) { @@ -348,7 +348,7 @@ const sound_effect *find_random_effect( const id_and_variant &id_variants_pair ) } // Same as above, but with fallback to "default" variant. May still return `nullptr` -const sound_effect *find_random_effect( const std::string &id, const std::string &variant ) +static const sound_effect *find_random_effect( const std::string &id, const std::string &variant ) { const auto eff = find_random_effect( id_and_variant( id, variant ) ); if( eff != nullptr ) { @@ -363,7 +363,7 @@ bool sfx::has_variant_sound( const std::string &id, const std::string &variant ) } // Deletes the dynamically created chunk (if such a chunk had been played). -void cleanup_when_channel_finished( int /* channel */, void *udata ) +static void cleanup_when_channel_finished( int /* channel */, void *udata ) { Mix_Chunk *chunk = static_cast( udata ); free( chunk->abuf ); @@ -372,11 +372,11 @@ void cleanup_when_channel_finished( int /* channel */, void *udata ) // empty effect, as we cannot change the size of the output buffer, // therefore we cannot do the math from do_pitch_shift here -void empty_effect( int /* chan */, void * /* stream */, int /* len */, void * /* udata */ ) +static void empty_effect( int /* chan */, void * /* stream */, int /* len */, void * /* udata */ ) { } -Mix_Chunk *do_pitch_shift( Mix_Chunk *s, float pitch ) +static Mix_Chunk *do_pitch_shift( Mix_Chunk *s, float pitch ) { Uint32 s_in = s->alen / 4; Uint32 s_out = static_cast( static_cast( s_in ) * pitch ); diff --git a/src/sdltiles.cpp b/src/sdltiles.cpp index 9c68122d9d679..37be6f4ae6c94 100644 --- a/src/sdltiles.cpp +++ b/src/sdltiles.cpp @@ -229,7 +229,7 @@ extern catacurses::window w_hit_animation; //this window overlays w_terrain whic //*********************************** //Non-curses, Window functions * //*********************************** -void generate_alt_rect_texture() +static void generate_alt_rect_texture() { #if SDL_BYTEORDER == SDL_BIG_ENDIAN static const Uint32 rmask = 0xff000000; @@ -262,13 +262,6 @@ void generate_alt_rect_texture() } } -void draw_alt_rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect, unsigned char color ) -{ - SetTextureColorMod( alt_rect_tex, windowsPalette[color].r, windowsPalette[color].g, - windowsPalette[color].b ); - RenderCopy( renderer, alt_rect_tex, NULL, &rect ); -} - void draw_alt_rect( const SDL_Renderer_Ptr &renderer, const SDL_Rect &rect, Uint32 r, Uint32 g, Uint32 b ) { @@ -281,13 +274,13 @@ static bool operator==( const cata_cursesport::WINDOW *const lhs, const catacurs return lhs == rhs.get(); } -void ClearScreen() +static void ClearScreen() { SetRenderDrawColor( renderer, 0, 0, 0, 255 ); RenderClear( renderer ); } -void InitSDL() +static void InitSDL() { int init_flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER; int ret; @@ -327,7 +320,7 @@ void InitSDL() atexit( SDL_Quit ); } -bool SetupRenderTarget() +static bool SetupRenderTarget() { SetRenderDrawBlendMode( renderer, SDL_BLENDMODE_NONE ); display_buffer.reset( SDL_CreateTexture( renderer.get(), SDL_PIXELFORMAT_ARGB8888, @@ -345,7 +338,7 @@ bool SetupRenderTarget() } //Registers, creates, and shows the Window!! -void WinCreate() +static void WinCreate() { std::string version = string_format( "Cataclysm: Dark Days Ahead - %s", getVersionString() ); @@ -526,7 +519,7 @@ void WinCreate() } -void WinDestroy() +static void WinDestroy() { #if defined(__ANDROID__) touch_joystick.reset(); @@ -827,7 +820,7 @@ void set_displaybuffer_rendertarget() } // Populate a map with the available video displays and their name -void find_videodisplays() +static void find_videodisplays() { std::vector< std::tuple > displays; @@ -906,27 +899,21 @@ void Font::draw_ascii_lines( unsigned char line_id, int drawx, int drawy, int FG } } -void invalidate_framebuffer( std::vector &framebuffer, int x, int y, int width, - int height ) +static void invalidate_framebuffer( std::vector &framebuffer, int x, int y, int width, + int height ) { for( int j = 0, fby = y; j < height; j++, fby++ ) { std::fill_n( framebuffer[fby].chars.begin() + x, width, cursecell( "" ) ); } } -void invalidate_framebuffer( std::vector &framebuffer ) +static void invalidate_framebuffer( std::vector &framebuffer ) { for( auto &i : framebuffer ) { std::fill_n( i.chars.begin(), i.chars.size(), cursecell( "" ) ); } } -void invalidate_all_framebuffers() -{ - invalidate_framebuffer( terminal_framebuffer ); - invalidate_framebuffer( oversized_framebuffer ); -} - void reinitialize_framebuffer() { //Re-initialize the framebuffer with new values. @@ -942,7 +929,7 @@ void reinitialize_framebuffer() } } -void invalidate_framebuffer_proportion( cata_cursesport::WINDOW *win ) +static void invalidate_framebuffer_proportion( cata_cursesport::WINDOW *win ) { const int oversized_width = std::max( TERMX, std::max( OVERMAP_WINDOW_WIDTH, TERRAIN_WINDOW_WIDTH ) ); @@ -1350,7 +1337,7 @@ static long end_alt_code() return alt_buffer; } -int HandleDPad() +static int HandleDPad() { // Check if we have a gamepad d-pad event. if( SDL_JoystickGetHat( joystick, 0 ) != SDL_HAT_CENTERED ) { @@ -1422,7 +1409,7 @@ int HandleDPad() return 0; } -SDL_Keycode sdl_keycode_opposite_arrow( SDL_Keycode key ) +static SDL_Keycode sdl_keycode_opposite_arrow( SDL_Keycode key ) { switch( key ) { case SDLK_UP: @@ -1437,12 +1424,12 @@ SDL_Keycode sdl_keycode_opposite_arrow( SDL_Keycode key ) return 0; } -bool sdl_keycode_is_arrow( SDL_Keycode key ) +static bool sdl_keycode_is_arrow( SDL_Keycode key ) { return static_cast( sdl_keycode_opposite_arrow( key ) ); } -long arrow_combo_to_numpad( SDL_Keycode mod, SDL_Keycode key ) +static long arrow_combo_to_numpad( SDL_Keycode mod, SDL_Keycode key ) { if( ( mod == SDLK_UP && key == SDLK_RIGHT ) || ( mod == SDLK_RIGHT && key == SDLK_UP ) ) { @@ -1502,7 +1489,7 @@ static void end_arrow_combo() * -1 when a ALT+number sequence has been started, * or something that a call to ncurses getch would return. */ -long sdl_keysym_to_curses( const SDL_Keysym &keysym ) +static long sdl_keysym_to_curses( const SDL_Keysym &keysym ) { #if !defined(__ANDROID__) @@ -1718,7 +1705,7 @@ unsigned long finger_repeat_delay = 500; static bool needs_sdl_surface_visibility_refresh = true; // Quick shortcuts container: maps the touch input context category (std::string) to a std::list of input_events. -typedef std::list quick_shortcuts_t; +using quick_shortcuts_t = std::list; std::map quick_shortcuts_map; // A copy of the last known input_context from the input manager. It's important this is a copy, as there are times @@ -2423,7 +2410,7 @@ void android_vibrate() #endif //Check for any window messages (keypress, paint, mousemove, etc) -void CheckMessages() +static void CheckMessages() { SDL_Event ev; bool quit = false; @@ -3270,7 +3257,7 @@ int projected_window_height() return get_option( "TERMINAL_Y" ) * fontheight; } -void init_term_size_and_scaling_factor() +static void init_term_size_and_scaling_factor() { scaling_factor = 1; int terminal_x = get_option( "TERMINAL_X" ); @@ -3787,7 +3774,7 @@ CachedTTFFont::CachedTTFFont( const int w, const int h, std::string typeface, in TTF_SetFontStyle( font.get(), TTF_STYLE_NORMAL ); } -int map_font_width() +static int map_font_width() { if( use_tiles && tilecontext ) { return tilecontext->get_tile_width(); @@ -3795,7 +3782,7 @@ int map_font_width() return ( map_font ? map_font : font )->fontwidth; } -int map_font_height() +static int map_font_height() { if( use_tiles && tilecontext ) { return tilecontext->get_tile_height(); @@ -3803,12 +3790,12 @@ int map_font_height() return ( map_font ? map_font : font )->fontheight; } -int overmap_font_width() +static int overmap_font_width() { return ( overmap_font ? overmap_font : font )->fontwidth; } -int overmap_font_height() +static int overmap_font_height() { return ( overmap_font ? overmap_font : font )->fontheight; } diff --git a/src/sounds.cpp b/src/sounds.cpp index c6467a311a661..72ad0372ffb85 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -207,7 +207,7 @@ static std::vector cluster_sounds( std::vector &vec ) +static void add_boardable( const map &m, const tripoint &p, std::vector &vec ) { if( m.has_furn( p ) ) { // Don't need to board this up, is already occupied @@ -118,7 +118,7 @@ void add_boardable( const map &m, const tripoint &p, std::vector &vec vec.push_back( p ); } -void board_up( map &m, const tripoint &start, const tripoint &end ) +static void board_up( map &m, const tripoint &start, const tripoint &end ) { std::vector furnitures1; std::vector furnitures2; @@ -244,9 +244,9 @@ void start_location::prepare_map( const tripoint &omtstart ) const * Maybe TODO: Allow "picking up" items or parts of bashable furniture * and using them to help with bash attempts. */ -int rate_location( map &m, const tripoint &p, const bool must_be_inside, - const int bash_str, const int attempt, - int ( &checked )[MAPSIZE_X][MAPSIZE_Y] ) +static int rate_location( map &m, const tripoint &p, const bool must_be_inside, + const int bash_str, const int attempt, + int ( &checked )[MAPSIZE_X][MAPSIZE_Y] ) { if( ( must_be_inside && m.is_outside( p ) ) || m.impassable( p ) || diff --git a/src/stomach.cpp b/src/stomach.cpp index d4c41a54f8f09..bcb88423b3220 100644 --- a/src/stomach.cpp +++ b/src/stomach.cpp @@ -25,7 +25,7 @@ stomach_contents::stomach_contents( units::volume max_vol ) last_ate = calendar::before_time_starts; } -std::string ml_to_string( units::volume vol ) +static std::string ml_to_string( units::volume vol ) { return to_string( units::to_milliliter( vol ) ) + "_ml"; } @@ -43,7 +43,7 @@ void stomach_contents::serialize( JsonOut &json ) const json.end_object(); } -units::volume string_to_ml( const std::string &str ) +static units::volume string_to_ml( const std::string &str ) { return units::from_milliliter( std::stoi( str.substr( 0, str.size() - 3 ) ) ); } @@ -427,3 +427,13 @@ time_duration stomach_contents::time_since_ate() const { return calendar::turn - last_ate; } + +// sets default stomach contents when starting the game +void Character::initialize_stomach_contents() +{ + stomach = stomach_contents( 2500_ml ); + guts = stomach_contents( 24000_ml ); + guts.set_calories( 300 ); + stomach.set_calories( 800 ); + stomach.mod_contents( 475_ml ); +} diff --git a/src/string_id.h b/src/string_id.h index 45db3fd3cfd73..f528fc93725e9 100644 --- a/src/string_id.h +++ b/src/string_id.h @@ -44,7 +44,7 @@ template class string_id { public: - typedef string_id This; + using This = string_id; /** * Forwarding constructor, forwards any parameter to the std::string diff --git a/src/trait_group.cpp b/src/trait_group.cpp index 2e204804bdbc4..5e0499506365d 100644 --- a/src/trait_group.cpp +++ b/src/trait_group.cpp @@ -35,7 +35,7 @@ void trait_group::load_trait_group( JsonObject &jsobj, const Trait_group_tag &gi } // NOTE: This function is largely based on item_group::get_unique_group_id() -Trait_group_tag get_unique_trait_group_id() +static Trait_group_tag get_unique_trait_group_id() { // This is just a hint what id to use next. Overflow of it is defined and if the group // name is already used, we simply go the next id. diff --git a/src/trait_group.h b/src/trait_group.h index 6c7a1232f4d64..c949328cabd65 100644 --- a/src/trait_group.h +++ b/src/trait_group.h @@ -17,8 +17,8 @@ class Trait_group; namespace trait_group { -typedef string_id Trait_group_tag; -typedef std::vector Trait_list; +using Trait_group_tag = string_id; +using Trait_list = std::vector; /** * Returns a randomized list of traits from the given trait group. @@ -70,7 +70,7 @@ void debug_spawn(); class Trait_creation_data { public: - typedef std::vector RecursionList; + using RecursionList = std::vector; Trait_creation_data( int _probability ) : probability( _probability ) {} virtual ~Trait_creation_data() = default; @@ -146,7 +146,7 @@ class Trait_group_creator : public Trait_creation_data class Trait_group : public Trait_creation_data { public: - typedef std::vector> CreatorList; + using CreatorList = std::vector >; Trait_group( int probability ); ~Trait_group() override = default; diff --git a/src/trapfunc.cpp b/src/trapfunc.cpp index 18271115a563d..943f4e1fc9215 100644 --- a/src/trapfunc.cpp +++ b/src/trapfunc.cpp @@ -52,7 +52,7 @@ static const trait_id trait_WINGS_BIRD( "WINGS_BIRD" ); static const trait_id trait_WINGS_BUTTERFLY( "WINGS_BUTTERFLY" ); // A pit becomes less effective as it fills with corpses. -float pit_effectiveness( const tripoint &p ) +static float pit_effectiveness( const tripoint &p ) { units::volume corpse_volume = 0_ml; for( auto &pit_content : g->m.i_at( p ) ) { @@ -971,7 +971,7 @@ void trapfunc::portal( Creature *c, const tripoint &p ) } // Don't ask NPCs - they always want to do the first thing that comes to their minds -bool query_for_item( const player *pl, const std::string &itemname, const char *que ) +static bool query_for_item( const player *pl, const std::string &itemname, const char *que ) { return pl->has_amount( itemname, 1 ) && ( !pl->is_player() || query_yn( que ) ); } diff --git a/src/ui.cpp b/src/ui.cpp index 4a6c9bef803da..ea03caae644c0 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -28,19 +28,6 @@ * @{ */ -//////////////////////////////////// -int getfoldedwidth( const std::vector &foldedstring ) -{ - int ret = 0; - for( auto &i : foldedstring ) { - int width = utf8_width( i ); - if( width > ret ) { - ret = width; - } - } - return ret; -} - uilist::uilist() { init(); @@ -961,6 +948,7 @@ void pointmenu_cb::refresh( uilist *menu ) g->u.view_offset = tripoint_zero; g->draw_ter(); wrefresh( g->w_terrain ); + g->draw_panels(); menu->redraw( false ); // show() won't redraw borders menu->show(); return; diff --git a/src/uistate.h b/src/uistate.h index d9044e46d8fd4..31b2f2cfe8034 100644 --- a/src/uistate.h +++ b/src/uistate.h @@ -22,7 +22,7 @@ class uistatedata /**** this will set a default value on startup, however to save, see below ****/ private: // not needed for compilation, but keeps syntax plugins happy - typedef std::string itype_id; + using itype_id = std::string; enum side { left = 0, right = 1, NUM_PANES = 2 }; public: /**** declare your variable here. It can be anything, really *****/ diff --git a/src/veh_interact.cpp b/src/veh_interact.cpp index 16b456a6a4d55..ea0703c2e3808 100644 --- a/src/veh_interact.cpp +++ b/src/veh_interact.cpp @@ -2629,7 +2629,7 @@ void veh_interact::count_durability() * @param vpid The id of the vpart type to look for. * @return The item that was consumed. */ -item consume_vpart_item( const vpart_id &vpid ) +static item consume_vpart_item( const vpart_id &vpid ) { std::vector candidates; const itype_id itid = vpid.obj().item; diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 8ca79d295e009..d91139e27b06d 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -3086,7 +3086,7 @@ int vehicle::water_acceleration( const bool fueled, int at_vel_in_vmi ) const // cubic equation solution // don't use complex numbers unless necessary and it's usually not // see https://math.vanderbilt.edu/schectex/courses/cubic/ for the gory details -double simple_cubic_solution( double a, double b, double c, double d ) +static double simple_cubic_solution( double a, double b, double c, double d ) { double p = -b / ( 3 * a ); double q = p * p * p + ( b * c - 3 * a * d ) / ( 6 * a * a ); @@ -5424,7 +5424,7 @@ inline int modulo( int v, int m ) return r >= 0 ? r : r + m; } -bool is_sm_tile_over_water( const tripoint &real_global_pos ) +static bool is_sm_tile_over_water( const tripoint &real_global_pos ) { const tripoint smp = ms_to_sm_copy( real_global_pos ); @@ -5445,7 +5445,7 @@ bool is_sm_tile_over_water( const tripoint &real_global_pos ) sm->get_furn( { px, py } ).obj().has_flag( TFLAG_CURRENT ) ); } -bool is_sm_tile_outside( const tripoint &real_global_pos ) +static bool is_sm_tile_outside( const tripoint &real_global_pos ) { const tripoint smp = ms_to_sm_copy( real_global_pos ); diff --git a/src/vehicle_group.cpp b/src/vehicle_group.cpp index e86b1702d521f..b83e156ba969f 100644 --- a/src/vehicle_group.cpp +++ b/src/vehicle_group.cpp @@ -202,10 +202,10 @@ void VehicleSpawn::apply( const vspawn_id &id, map &m, const std::string &terrai namespace VehicleSpawnFunction { -void builtin_no_vehicles( map &, const std::string & ) +static void builtin_no_vehicles( map &, const std::string & ) {} -void builtin_jackknifed_semi( map &m, const std::string &terrainid ) +static void builtin_jackknifed_semi( map &m, const std::string &terrainid ) { const VehicleLocation *loc = vplacement_id( terrainid + "_semi" ).obj().pick(); if( ! loc ) { @@ -236,7 +236,7 @@ void builtin_jackknifed_semi( map &m, const std::string &terrainid ) m.add_vehicle( vgroup_id( "truck_trailer" ), trailer_p, ( facing + 90 ) % 360, -1, 1 ); } -void builtin_pileup( map &m, const std::string &, const std::string &vg ) +static void builtin_pileup( map &m, const std::string &, const std::string &vg ) { vehicle *last_added_car = nullptr; const int num_cars = rng( 5, 12 ); @@ -258,17 +258,17 @@ void builtin_pileup( map &m, const std::string &, const std::string &vg ) } } -void builtin_citypileup( map &m, const std::string &t ) +static void builtin_citypileup( map &m, const std::string &t ) { builtin_pileup( m, t, "city_pileup" ); } -void builtin_policepileup( map &m, const std::string &t ) +static void builtin_policepileup( map &m, const std::string &t ) { builtin_pileup( m, t, "police_pileup" ); } -void builtin_parkinglot( map &m, const std::string & ) +static void builtin_parkinglot( map &m, const std::string & ) { for( int v = 0; v < rng( 1, 4 ); v++ ) { tripoint pos_p; diff --git a/src/vehicle_group.h b/src/vehicle_group.h index 341120b91898e..c94e8445b00ba 100644 --- a/src/vehicle_group.h +++ b/src/vehicle_group.h @@ -88,7 +88,7 @@ struct VehiclePlacement { const VehicleLocation *pick() const; static void load( JsonObject &jo ); - typedef std::vector LocationMap; + using LocationMap = std::vector; LocationMap locations; }; @@ -105,7 +105,7 @@ class VehicleFunction virtual void apply( map &m, const std::string &terrainid ) const = 0; }; -typedef void ( *vehicle_gen_pointer )( map &m, const std::string &terrainid ); +using vehicle_gen_pointer = void ( * )( map &, const std::string & ); class VehicleFunction_builtin : public VehicleFunction { @@ -182,7 +182,7 @@ class VehicleSpawn private: weighted_float_list> types; - typedef std::unordered_map FunctionMap; + using FunctionMap = std::unordered_map; static FunctionMap builtin_functions; }; diff --git a/src/vehicle_move.cpp b/src/vehicle_move.cpp index 7813ae7745d24..080451ce3cf84 100644 --- a/src/vehicle_move.cpp +++ b/src/vehicle_move.cpp @@ -392,8 +392,8 @@ bool vehicle::collision( std::vector &colls, } // A helper to make sure mass and density is always calculated the same way -void terrain_collision_data( const tripoint &p, bool bash_floor, - float &mass, float &density, float &elastic ) +static void terrain_collision_data( const tripoint &p, bool bash_floor, + float &mass, float &density, float &elastic ) { elastic = 0.30; // Just a rough rescale for now to obtain approximately equal numbers @@ -1142,7 +1142,7 @@ void vehicle::precalculate_vehicle_turning( int new_turn_dir, bool check_rail_di } // rounds turn_dir to 45*X degree, respecting face_dir -int get_corrected_turn_dir( int turn_dir, int face_dir ) +static int get_corrected_turn_dir( int turn_dir, int face_dir ) { int corrected_turn_dir = 0; diff --git a/src/vehicle_selector.h b/src/vehicle_selector.h index ed13b3cad3f4e..620cedfbe7a2a 100644 --- a/src/vehicle_selector.h +++ b/src/vehicle_selector.h @@ -23,12 +23,12 @@ class vehicle_selector : public visitable friend visitable; public: - typedef vehicle_cursor value_type; - typedef std::vector::size_type size_type; - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; - typedef std::vector::reference reference; - typedef std::vector::const_reference const_reference; + using value_type = vehicle_cursor; + using size_type = std::vector::size_type; + using iterator = std::vector::iterator; + using const_iterator = std::vector::const_iterator; + using reference = std::vector::reference; + using const_reference = std::vector::const_reference; /** * Constructs vehicle_selector used for querying items located on vehicle tiles diff --git a/src/wdirent.h b/src/wdirent.h index b32e0866d4fe6..3974c10a0e9ee 100644 --- a/src/wdirent.h +++ b/src/wdirent.h @@ -232,7 +232,6 @@ struct _wdirent { int d_type; /* File type */ wchar_t d_name[PATH_MAX + 1]; /* File name */ }; -typedef struct _wdirent _wdirent; struct _WDIR { struct _wdirent ent; /* Current directory entry */ @@ -241,7 +240,6 @@ struct _WDIR { HANDLE handle; /* Win32 search handle */ wchar_t *patt; /* Initial directory name */ }; -typedef struct _WDIR _WDIR; static _WDIR *_wopendir( const wchar_t *dirname ); static struct _wdirent *_wreaddir( _WDIR *dirp ); @@ -264,13 +262,11 @@ struct dirent { int d_type; /* File type */ char d_name[PATH_MAX + 1]; /* File name */ }; -typedef struct dirent dirent; struct DIR { struct dirent ent; struct _WDIR *wdirp; }; -typedef struct DIR DIR; static DIR *opendir( const char *dirname ); static struct dirent *readdir( DIR *dirp ); diff --git a/src/weather.cpp b/src/weather.cpp index dc6c67c1ebf8c..ed4f26a1f47d3 100644 --- a/src/weather.cpp +++ b/src/weather.cpp @@ -104,34 +104,6 @@ void weather_effect::glare( bool snowglare ) ////// food vs weather -time_duration get_rot_since( const time_point &start, const time_point &end, - const tripoint &pos ) -{ - time_duration ret = 0_turns; - const auto &wgen = g->weather.get_cur_weather_gen(); - /* Hoisting loop invariants */ - const auto location_temp = g->weather.get_temperature( pos ); - const auto local = g->m.getlocal( pos ); - const auto local_mod = g->new_game ? 0 : g->m.get_temperature( local ); - const auto seed = g->get_seed(); - - const auto temp_modify = ( !g->new_game ) && ( g->m.ter( local ) == t_rootcellar ); - - for( time_point i = start; i < end; i += 1_hours ) { - w_point w = wgen.get_weather( pos, i, seed ); - - // Use weather if above ground, use map temp if below - double temperature = ( pos.z >= 0 ? w.temperature : location_temp ) + local_mod; - // If in a root celler: use AVERAGE_ANNUAL_TEMPERATURE - // If not: use calculated temperature - temperature = ( temp_modify * AVERAGE_ANNUAL_TEMPERATURE ) + ( !temp_modify * temperature ); - - ret += std::min( 1_hours, end - i ) / 1_hours * get_hourly_rotpoints_at_temp( - temperature ) * 1_turns; - } - return ret; -} - inline void proc_weather_sum( const weather_type wtype, weather_sum &data, const time_point &t, const time_duration &tick_size ) { @@ -330,7 +302,7 @@ double trap::funnel_turns_per_charge( double rain_depth_mm_per_hour ) const /** * Main routine for filling funnels from weather effects. */ -void fill_funnels( int rain_depth_mm_per_hour, bool acid, const trap &tr ) +static void fill_funnels( int rain_depth_mm_per_hour, bool acid, const trap &tr ) { const double turns_per_charge = tr.funnel_turns_per_charge( rain_depth_mm_per_hour ); // Give each funnel on the map a chance to collect the rain. @@ -363,7 +335,7 @@ void fill_funnels( int rain_depth_mm_per_hour, bool acid, const trap &tr ) * Fill funnels and makeshift funnels from weather effects. * @see fill_funnels */ -void fill_water_collectors( int mmPerHour, bool acid ) +static void fill_water_collectors( int mmPerHour, bool acid ) { for( auto &e : trap::get_funnels() ) { fill_funnels( mmPerHour, acid, *e ); @@ -382,7 +354,7 @@ void fill_water_collectors( int mmPerHour, bool acid ) * @see map::decay_fields_and_scent * @see player::drench */ -void wet_player( int amount ) +static void wet_player( int amount ) { if( !is_player_outside() || g->u.has_trait( trait_FEATHERS ) || @@ -410,7 +382,7 @@ void wet_player( int amount ) /** * Main routine for wet effects caused by weather. */ -void generic_wet( bool acid ) +static void generic_wet( bool acid ) { fill_water_collectors( 4, acid ); g->m.decay_fields_and_scent( 15_turns ); @@ -421,7 +393,7 @@ void generic_wet( bool acid ) * Main routine for very wet effects caused by weather. * Similar to generic_wet() but with more aggressive numbers. */ -void generic_very_wet( bool acid ) +static void generic_very_wet( bool acid ) { fill_water_collectors( 8, acid ); g->m.decay_fields_and_scent( 45_turns ); @@ -760,25 +732,6 @@ int get_local_windchill( double temperature, double humidity, double windpower ) return windchill; } -std::string get_wind_strength_bars( double windpower ) -{ - std::string wind_bars; - if( windpower < 3 ) { - wind_bars.clear(); - } else if( windpower < 12 ) { - wind_bars = "+"; - } else if( windpower < 24 ) { - wind_bars = "++"; - } else if( windpower < 38 ) { - wind_bars = "+++"; - } else if( windpower < 54 ) { - wind_bars = "++++"; - } else if( windpower >= 54 ) { - wind_bars = "+++++"; - } - return wind_bars; -} - nc_color get_wind_color( double windpower ) { nc_color windcolor; diff --git a/src/wincurse.cpp b/src/wincurse.cpp index 02f39bd313209..fd8fbfa19e53b 100644 --- a/src/wincurse.cpp +++ b/src/wincurse.cpp @@ -62,7 +62,7 @@ static int TERMINAL_HEIGHT; // Declare this locally, because it's not generally cross-compatible in cursesport.h LRESULT CALLBACK ProcessMessages( HWND__ *hWnd, std::uint32_t Msg, WPARAM wParam, LPARAM lParam ); -std::wstring widen( const std::string &s ) +static std::wstring widen( const std::string &s ) { if( s.empty() ) { // MultiByteToWideChar can not handle this case @@ -76,7 +76,7 @@ std::wstring widen( const std::string &s ) } // Registers, creates, and shows the Window!! -bool WinCreate() +static bool WinCreate() { // Get current process handle WindowINST = GetModuleHandle( 0 ); @@ -128,7 +128,7 @@ bool WinCreate() } // Unregisters, releases the DC if needed, and destroys the window. -void WinDestroy() +static void WinDestroy() { if( ( WindowDC != NULL ) && ( ReleaseDC( WindowHandle, WindowDC ) == 0 ) ) { WindowDC = 0; @@ -142,7 +142,7 @@ void WinDestroy() } // Creates a backbuffer to prevent flickering -void create_backbuffer() +static void create_backbuffer() { if( WindowDC != NULL ) { ReleaseDC( WindowHandle, WindowDC ); @@ -207,7 +207,7 @@ static void begin_alt_code() alt_buffer_len = 0; } -void add_alt_code( char c ) +static void add_alt_code( char c ) { // Not exactly how it works, but acceptable if( c >= '0' && c <= '9' ) { @@ -534,7 +534,7 @@ void cata_cursesport::curses_drawwindow( const catacurses::window &w ) } // Check for any window messages (keypress, paint, mousemove, etc) -void CheckMessages() +static void CheckMessages() { MSG msg; while( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) { @@ -636,7 +636,7 @@ void catacurses::init_interface() } // A very accurate and responsive timer (NEVER use GetTickCount) -uint64_t GetPerfCount() +static uint64_t GetPerfCount() { uint64_t Count; QueryPerformanceCounter( ( PLARGE_INTEGER )&Count ); diff --git a/src/wish.cpp b/src/wish.cpp index eca9e56bae1ce..6ad9967426004 100644 --- a/src/wish.cpp +++ b/src/wish.cpp @@ -13,6 +13,7 @@ #include "input.h" #include "item_factory.h" #include "map.h" +#include "npc.h" #include "monster.h" #include "monstergenerator.h" #include "mtype.h" @@ -616,7 +617,7 @@ void debug_menu::wishskill( player *p ) sksetmenu.query(); g->draw_ter(); wrefresh( g->w_terrain ); - g->draw_panels(); + g->draw_panels( true ); skset = sksetmenu.ret; } diff --git a/src/worldfactory.cpp b/src/worldfactory.cpp index 35e11b0525833..9ecd26389486a 100644 --- a/src/worldfactory.cpp +++ b/src/worldfactory.cpp @@ -63,7 +63,7 @@ save_t save_t::from_base_path( const std::string &base_path ) return save_t( base64_decode( base_path ) ); } -std::string get_next_valid_worldname() +static std::string get_next_valid_worldname() { std::string worldname = Name::get( nameIsWorldName ); diff --git a/src/worldfactory.h b/src/worldfactory.h index e7b6c53e97d69..8cff8dda178a6 100644 --- a/src/worldfactory.h +++ b/src/worldfactory.h @@ -81,7 +81,7 @@ class mod_manager; class mod_ui; class input_context; -typedef WORLD *WORLDPTR; +using WORLDPTR = WORLD *; class worldfactory { @@ -148,7 +148,7 @@ class worldfactory pimpl mman; pimpl mman_ui; - typedef std::function worldgen_display; + using worldgen_display = std::function; std::vector tabs; }; diff --git a/tests/behavior_test.cpp b/tests/behavior_test.cpp index ed66f3ad2f488..4846cc4040e0a 100644 --- a/tests/behavior_test.cpp +++ b/tests/behavior_test.cpp @@ -14,7 +14,7 @@ extern fallback_t default_fallback; extern sequential_until_done_t default_until_done; } -behavior::node_t make_test_node( std::string goal, behavior::status_t *status ) +static behavior::node_t make_test_node( std::string goal, behavior::status_t *status ) { behavior::node_t node; if( !goal.empty() ) { diff --git a/tests/bionics_test.cpp b/tests/bionics_test.cpp index 4605a8f1f4c8c..60965fb37c83e 100644 --- a/tests/bionics_test.cpp +++ b/tests/bionics_test.cpp @@ -17,14 +17,14 @@ #include "string_id.h" #include "type_id.h" -void clear_bionics( player &p ) +static void clear_bionics( player &p ) { p.my_bionics->clear(); p.power_level = 0; p.max_power_level = 0; } -void give_and_activate( player &p, bionic_id const &bioid ) +static void give_and_activate( player &p, bionic_id const &bioid ) { INFO( "bionic " + bioid.str() + " is valid" ); REQUIRE( bioid.is_valid() ); @@ -54,7 +54,8 @@ void give_and_activate( player &p, bionic_id const &bioid ) } } -void test_consumable_charges( player &p, std::string &itemname, bool when_none, bool when_max ) +static void test_consumable_charges( player &p, std::string &itemname, bool when_none, + bool when_max ) { item it = item( itemname, 0, 0 ) ; @@ -70,7 +71,8 @@ void test_consumable_charges( player &p, std::string &itemname, bool when_none, REQUIRE( p.can_consume( it ) == when_max ); } -void test_consumable_ammo( player &p, std::string &itemname, bool when_empty, bool when_full ) +static void test_consumable_ammo( player &p, std::string &itemname, bool when_empty, + bool when_full ) { item it = item( itemname, 0, 0 ) ; diff --git a/tests/comestible_tests.cpp b/tests/comestible_tests.cpp index 04f12bec0ed70..8d440f1583b7e 100644 --- a/tests/comestible_tests.cpp +++ b/tests/comestible_tests.cpp @@ -22,7 +22,7 @@ struct all_stats { }; // given a list of components, adds all the calories together -int comp_calories( std::vector components ) +static int comp_calories( std::vector components ) { int calories = 0; for( item_comp it : components ) { @@ -37,8 +37,8 @@ int comp_calories( std::vector components ) } // puts one permutation of item components into a vector -std::vector item_comp_vector_create( const std::vector> &vv, - const std::vector &ndx ) +static std::vector item_comp_vector_create( + const std::vector> &vv, const std::vector &ndx ) { std::vector list; for( int i = 0, sz = vv.size(); i < sz; ++i ) { @@ -47,8 +47,8 @@ std::vector item_comp_vector_create( const std::vector> recipe_permutations( const - std::vector< std::vector< item_comp > > &vv ) +static std::vector> recipe_permutations( + const std::vector< std::vector< item_comp > > &vv ) { std::vector muls; std::vector szs; @@ -80,7 +80,7 @@ std::vector> recipe_permutations( const return output; } -int byproduct_calories( const recipe &recipe_obj ) +static int byproduct_calories( const recipe &recipe_obj ) { std::vector byproducts = recipe_obj.create_byproducts(); @@ -93,16 +93,8 @@ int byproduct_calories( const recipe &recipe_obj ) return kcal; } -void print_itemcomp( const std::vector &list ) -{ - printf( "error in permutation. list of components:\n" ); - for( const item_comp &itc : list ) { - printf( "%s, %d\n", itc.to_string().c_str(), itc.count ); - } - printf( "\n" ); -} - -all_stats run_stats( std::vector> permutations, int byproduct_calories ) +static all_stats run_stats( std::vector> permutations, + int byproduct_calories ) { all_stats mystats; for( const std::vector &permut : permutations ) { @@ -111,7 +103,7 @@ all_stats run_stats( std::vector> permutations, int bypro return mystats; } -item food_or_food_container( item it ) +static item food_or_food_container( item it ) { return it.is_food_container() ? it.contents.front() : it; } diff --git a/tests/creature_test.cpp b/tests/creature_test.cpp index 0ceaea4d5be75..257066ac1af26 100644 --- a/tests/creature_test.cpp +++ b/tests/creature_test.cpp @@ -19,8 +19,8 @@ float expected_weights_max[][12] = { { 2000, 0, 0, 0, 1191.49, 1191.49, 0, 0 { 3657, 2861.78, 113.73, 0, 1815.83, 1815.83, 0, 0, 508.904, 508.904, 0, 0 } }; -void calculate_bodypart_distribution( const enum m_size asize, const enum m_size dsize, - const int hit_roll, float ( &expected )[12] ) +static void calculate_bodypart_distribution( const enum m_size asize, const enum m_size dsize, + const int hit_roll, float ( &expected )[12] ) { INFO( "hit roll = " << hit_roll ); std::map selected_part_histogram = { diff --git a/tests/encumbrance_test.cpp b/tests/encumbrance_test.cpp index f7e52f591e6e5..4a377f909fc78 100644 --- a/tests/encumbrance_test.cpp +++ b/tests/encumbrance_test.cpp @@ -16,7 +16,7 @@ #include "material.h" #include "type_id.h" -void test_encumbrance_on( +static void test_encumbrance_on( player &p, const std::vector &clothing, const std::string &body_part, @@ -38,7 +38,7 @@ void test_encumbrance_on( CHECK( enc.encumbrance == expected_encumbrance ); } -void test_encumbrance_items( +static void test_encumbrance_items( const std::vector &clothing, const std::string &body_part, const int expected_encumbrance, @@ -56,7 +56,7 @@ void test_encumbrance_items( } } -void test_encumbrance( +static void test_encumbrance( const std::vector &clothing_types, const std::string &body_part, const int expected_encumbrance diff --git a/tests/explosion_balance.cpp b/tests/explosion_balance.cpp index 682c42af320fa..cc91d03ef87f9 100644 --- a/tests/explosion_balance.cpp +++ b/tests/explosion_balance.cpp @@ -21,8 +21,8 @@ #include "string_id.h" #include "type_id.h" -void check_lethality( const std::string &explosive_id, const int range, float lethality, - float margin ) +static void check_lethality( const std::string &explosive_id, const int range, float lethality, + float margin ) { const epsilon_threshold target_lethality{ lethality, margin }; int num_survivors = 0; @@ -78,7 +78,7 @@ void check_lethality( const std::string &explosive_id, const int range, float le CHECK( deaths.avg() == Approx( lethality ).margin( margin ) ); } -std::vector get_part_hp( vehicle *veh ) +static std::vector get_part_hp( vehicle *veh ) { std::vector part_hp; part_hp.reserve( veh->parts.size() ); @@ -88,8 +88,8 @@ std::vector get_part_hp( vehicle *veh ) return part_hp; } -void check_vehicle_damage( const std::string &explosive_id, const std::string &vehicle_id, - const int range ) +static void check_vehicle_damage( const std::string &explosive_id, const std::string &vehicle_id, + const int range ) { // Clear map clear_map_and_put_player_underground(); diff --git a/tests/hash_test.cpp b/tests/hash_test.cpp index c5f1ebe6da265..7b0327badcdda 100644 --- a/tests/hash_test.cpp +++ b/tests/hash_test.cpp @@ -25,7 +25,7 @@ constexpr int MAX_COORDINATE = 300; constexpr int NUM_ENTRIES_2D = ( ( MAX_COORDINATE * 2 ) + 1 ) * ( ( MAX_COORDINATE * 2 ) + 1 ); constexpr int NUM_ENTRIES_3D = NUM_ENTRIES_2D * ( 21 ); -size_t count_unique_elements( std::vector &found_elements ) +static size_t count_unique_elements( std::vector &found_elements ) { std::sort( found_elements.begin(), found_elements.end() ); const auto range_end = std::unique( found_elements.begin(), found_elements.end() ); @@ -74,54 +74,6 @@ void put_coordinate( std::unordered_set &c, int x, int y ) c.emplace( x, y, 0 ); } -// These are the old versions of the hash functions for point and tripoint. -struct legacy_point_hash { - std::size_t operator()( const point &k ) const { - // Circular shift y by half its width so hash(5,6) != hash(6,5). - return std::hash()( k.x ) ^ std::hash()( ( k.y << 16 ) | ( k.y >> 16 ) ); - } -}; - -struct legacy_tripoint_hash { - std::size_t operator()( const tripoint &k ) const { - // Circular shift y and z so hash(5,6,7) != hash(7,6,5). - return std::hash()( k.x ) ^ - std::hash()( ( k.y << 10 ) | ( k.y >> 10 ) ) ^ - std::hash()( ( k.z << 20 ) | ( k.z >> 20 ) ); - } -}; - -// These legacy checks are expected to fail. -TEST_CASE( "legacy_point_hash_distribution", "[.]" ) -{ - std::vector found_hashes; - found_hashes.reserve( NUM_ENTRIES_2D ); - size_t element_count = 0; - for( int x = -MAX_COORDINATE; x <= MAX_COORDINATE; ++x ) { - for( int y = -MAX_COORDINATE; y <= MAX_COORDINATE; ++y ) { - element_count++; - found_hashes.push_back( legacy_point_hash{}( { x, y } ) ); - } - } - CHECK( count_unique_elements( found_hashes ) > element_count * 0.9 ); -} - -TEST_CASE( "legacy_tripoint_hash_distribution", "[.]" ) -{ - std::vector found_hashes; - found_hashes.reserve( NUM_ENTRIES_3D ); - size_t element_count = 0; - for( int x = -MAX_COORDINATE; x <= MAX_COORDINATE; ++x ) { - for( int y = -MAX_COORDINATE; y <= MAX_COORDINATE; ++y ) { - for( int z = -10; z <= 10; ++z ) { - element_count++; - found_hashes.push_back( legacy_tripoint_hash{}( { x, y, z } ) ); - } - } - } - CHECK( count_unique_elements( found_hashes ) > element_count * 0.9 ); -} - #ifdef RELEASE // These tests are slow and probably pointless for non-release builds @@ -142,18 +94,4 @@ long get_set_runtime() auto end1 = std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast( end1 - start1 ).count(); } - -TEST_CASE( "legacy_point_hash_runoff", "[hash]" ) -{ - long legacy_runtime = get_set_runtime(); - long new_runtime = get_set_runtime>(); - CHECK( new_runtime < legacy_runtime ); -} - -TEST_CASE( "legacy_tripoint_hash_runoff", "[hash]" ) -{ - long legacy_runtime = get_set_runtime(); - long new_runtime = get_set_runtime>(); - CHECK( new_runtime < legacy_runtime ); -} #endif // RELEASE diff --git a/tests/invlet_test.cpp b/tests/invlet_test.cpp index ba9d56a76af03..e088f40b59fa0 100644 --- a/tests/invlet_test.cpp +++ b/tests/invlet_test.cpp @@ -46,7 +46,7 @@ enum test_action { TEST_ACTION_NUM, }; -std::string location_desc( const inventory_location loc ) +static std::string location_desc( const inventory_location loc ) { switch( loc ) { case GROUND: @@ -63,8 +63,8 @@ std::string location_desc( const inventory_location loc ) return "unknown location"; } -std::string move_action_desc( const int pos, const inventory_location from, - const inventory_location to ) +static std::string move_action_desc( const int pos, const inventory_location from, + const inventory_location to ) { std::stringstream ss; ss << "move "; @@ -115,7 +115,7 @@ std::string move_action_desc( const int pos, const inventory_location from, return ss.str(); } -std::string invlet_state_desc( const invlet_state invstate ) +static std::string invlet_state_desc( const invlet_state invstate ) { switch( invstate ) { case NONE: @@ -130,11 +130,12 @@ std::string invlet_state_desc( const invlet_state invstate ) return "unexpected"; } -std::string test_action_desc( const test_action action, const inventory_location from, - const inventory_location to, - const invlet_state first_invlet_state, const invlet_state second_invlet_state, - const invlet_state expected_first_invlet_state, const invlet_state expected_second_invlet_state, - const invlet_state final_first_invlet_state, const invlet_state final_second_invlet_state ) +static std::string test_action_desc( + const test_action action, const inventory_location from, const inventory_location to, + const invlet_state first_invlet_state, const invlet_state second_invlet_state, + const invlet_state expected_first_invlet_state, + const invlet_state expected_second_invlet_state, + const invlet_state final_first_invlet_state, const invlet_state final_second_invlet_state ) { std::stringstream ss; ss << "1. add 1st item to " << location_desc( to ) << std::endl; @@ -171,7 +172,7 @@ std::string test_action_desc( const test_action action, const inventory_location return ss.str(); } -void assign_invlet( player &p, item &it, const char invlet, const invlet_state invstate ) +static void assign_invlet( player &p, item &it, const char invlet, const invlet_state invstate ) { p.reassign_item( it, '\0' ); switch( invstate ) { @@ -190,7 +191,7 @@ void assign_invlet( player &p, item &it, const char invlet, const invlet_state i } } -invlet_state check_invlet( player &p, item &it, const char invlet ) +static invlet_state check_invlet( player &p, item &it, const char invlet ) { if( it.invlet == '\0' ) { return NONE; @@ -205,7 +206,7 @@ invlet_state check_invlet( player &p, item &it, const char invlet ) return UNEXPECTED; } -void drop_at_feet( player &p, const int pos ) +static void drop_at_feet( player &p, const int pos ) { auto size_before = g->m.i_at( p.pos() ).size(); p.moves = 100; @@ -214,7 +215,7 @@ void drop_at_feet( player &p, const int pos ) REQUIRE( g->m.i_at( p.pos() ).size() == size_before + 1 ); } -void pick_up_from_feet( player &p, int pos ) +static void pick_up_from_feet( player &p, int pos ) { auto size_before = g->m.i_at( p.pos() ).size(); REQUIRE( size_before > pos ); @@ -228,7 +229,7 @@ void pick_up_from_feet( player &p, int pos ) REQUIRE( g->m.i_at( p.pos() ).size() == size_before - 1 ); } -void wear_from_feet( player &p, int pos ) +static void wear_from_feet( player &p, int pos ) { auto size_before = g->m.i_at( p.pos() ).size(); REQUIRE( size_before > pos ); @@ -236,7 +237,7 @@ void wear_from_feet( player &p, int pos ) g->m.i_rem( p.pos(), pos ); } -void wield_from_feet( player &p, int pos ) +static void wield_from_feet( player &p, int pos ) { auto size_before = g->m.i_at( p.pos() ).size(); REQUIRE( size_before > pos ); @@ -244,7 +245,7 @@ void wield_from_feet( player &p, int pos ) g->m.i_rem( p.pos(), pos ); } -void add_item( player &p, item &it, const inventory_location loc ) +static void add_item( player &p, item &it, const inventory_location loc ) { switch( loc ) { case GROUND: @@ -270,7 +271,7 @@ void add_item( player &p, item &it, const inventory_location loc ) } } -item &item_at( player &p, const int pos, const inventory_location loc ) +static item &item_at( player &p, const int pos, const inventory_location loc ) { switch( loc ) { case GROUND: @@ -288,8 +289,8 @@ item &item_at( player &p, const int pos, const inventory_location loc ) return null_item_reference(); } -void move_item( player &p, const int pos, const inventory_location from, - const inventory_location to ) +static void move_item( player &p, const int pos, const inventory_location from, + const inventory_location to ) { switch( from ) { case GROUND: @@ -384,7 +385,7 @@ void move_item( player &p, const int pos, const inventory_location from, } } -void invlet_test( player &dummy, const inventory_location from, const inventory_location to ) +static void invlet_test( player &dummy, const inventory_location from, const inventory_location to ) { // invlet to assign constexpr char invlet = '|'; @@ -469,7 +470,7 @@ void invlet_test( player &dummy, const inventory_location from, const inventory_ } } -void stack_invlet_test( player &dummy, inventory_location from, inventory_location to ) +static void stack_invlet_test( player &dummy, inventory_location from, inventory_location to ) { // invlet to assign constexpr char invlet = '|'; @@ -518,7 +519,7 @@ void stack_invlet_test( player &dummy, inventory_location from, inventory_locati assign_invlet( dummy, item_at( dummy, 0, to ), invlet, NONE ); } -void swap_invlet_test( player &dummy, inventory_location loc ) +static void swap_invlet_test( player &dummy, inventory_location loc ) { // invlet to assign constexpr char invlet_1 = '{'; @@ -586,7 +587,7 @@ void swap_invlet_test( player &dummy, inventory_location loc ) assign_invlet( dummy, item_at( dummy, 1, loc ), invlet_1, NONE ); } -void merge_invlet_test( player &dummy, inventory_location from ) +static void merge_invlet_test( player &dummy, inventory_location from ) { // invlet to assign constexpr char invlet_1 = '{'; @@ -705,7 +706,7 @@ TEST_CASE( "Inventory letter test", "[invlet]" ) merge_invlet_test_autoletter_off( "Merging worn item into an inventory stack", dummy, WORN ); } -void verify_invlet_consistency( const invlet_favorites &fav ) +static void verify_invlet_consistency( const invlet_favorites &fav ) { for( const auto &p : fav.get_invlets_by_id() ) { for( const char invlet : p.second ) { diff --git a/tests/iteminfo_test.cpp b/tests/iteminfo_test.cpp index 363360aedc917..0ce54574c9700 100644 --- a/tests/iteminfo_test.cpp +++ b/tests/iteminfo_test.cpp @@ -9,7 +9,7 @@ #include "iteminfo_query.h" #include "player.h" -void iteminfo_test( const item &i, const iteminfo_query &q, const std::string &reference ) +static void iteminfo_test( const item &i, const iteminfo_query &q, const std::string &reference ) { g->u.empty_traits(); std::vector info_v; diff --git a/tests/iuse_test.cpp b/tests/iuse_test.cpp index 2dcc0d41eefe3..1041203bd88d8 100644 --- a/tests/iuse_test.cpp +++ b/tests/iuse_test.cpp @@ -16,7 +16,7 @@ #include "string_id.h" #include "type_id.h" -player &get_sanitized_player( ) +static player &get_sanitized_player( ) { player &dummy = g->u; @@ -58,7 +58,7 @@ TEST_CASE( "use_eyedrops" ) REQUIRE( test_item_pos == INT_MIN ); } -monster *find_adjacent_monster( const tripoint &pos ) +static monster *find_adjacent_monster( const tripoint &pos ) { tripoint target = pos; for( target.x = pos.x - 1; target.x <= pos.x + 1; target.x++ ) { diff --git a/tests/line_test.cpp b/tests/line_test.cpp index 9709b4536fa50..ab3fbc4bb3b4c 100644 --- a/tests/line_test.cpp +++ b/tests/line_test.cpp @@ -14,8 +14,8 @@ #define SGN(a) (((a)<0) ? -1 : 1) // Compare all future line_to implementations to the canonical one. -std::vector canonical_line_to( const int x1, const int y1, const int x2, const int y2, - int t ) +static std::vector canonical_line_to( + const int x1, const int y1, const int x2, const int y2, int t ) { std::vector ret; const int dx = x2 - x1; @@ -291,7 +291,7 @@ TEST_CASE( "squares_closer_to_test" ) #define RANDOM_TEST_NUM 1000 #define COORDINATE_RANGE 99 -void line_to_comparison( const int iterations ) +static void line_to_comparison( const int iterations ) { REQUIRE( trig_dist( 0, 0, 0, 0 ) == 0 ); REQUIRE( trig_dist( 0, 0, 1, 0 ) == 1 ); diff --git a/tests/map_helpers.cpp b/tests/map_helpers.cpp index 3a1aa29e98e21..284dbf83dbf0d 100644 --- a/tests/map_helpers.cpp +++ b/tests/map_helpers.cpp @@ -1,3 +1,5 @@ +#include "map_helpers.h" + #include #include #include diff --git a/tests/map_memory.cpp b/tests/map_memory.cpp index da7054258601f..171fa31165d15 100644 --- a/tests/map_memory.cpp +++ b/tests/map_memory.cpp @@ -125,9 +125,9 @@ TEST_CASE( "lru_cache_perf", "[.]" ) // 3 | 4 // The partitions are defined by x_partition and y_partition // Each partition has an expected value, and should be homogenous. -void check_quadrants( std::bitset &test_cache, - size_t x_partition, size_t y_partition, - bool first_val, bool second_val, bool third_val, bool fourth_val ) +static void check_quadrants( std::bitset &test_cache, + size_t x_partition, size_t y_partition, + bool first_val, bool second_val, bool third_val, bool fourth_val ) { size_t y = 0; for( ; y < y_partition; ++y ) { diff --git a/tests/melee_test.cpp b/tests/melee_test.cpp index 8415928af8f16..09bc0ca573648 100644 --- a/tests/melee_test.cpp +++ b/tests/melee_test.cpp @@ -56,7 +56,7 @@ inline std::string percent_string( const float f ) return ss.str(); } -void check_near( float prob, const float expected, const float tolerance ) +static void check_near( float prob, const float expected, const float tolerance ) { const float low = expected - tolerance; const float high = expected + tolerance; diff --git a/tests/mondefense_test.cpp b/tests/mondefense_test.cpp index bac2d1b530d23..bf9c00a29cd93 100644 --- a/tests/mondefense_test.cpp +++ b/tests/mondefense_test.cpp @@ -7,8 +7,8 @@ #include "creature.h" #include "type_id.h" -void test_zapback( Creature &attacker, const bool expect_damage, - const dealt_projectile_attack *proj = nullptr ) +static void test_zapback( Creature &attacker, const bool expect_damage, + const dealt_projectile_attack *proj = nullptr ) { monster defender( mtype_id( "mon_zombie_electric" ) ); int prev_hp = attacker.get_hp(); diff --git a/tests/monster_test.cpp b/tests/monster_test.cpp index e9b1505828ede..e030f1d22e97b 100644 --- a/tests/monster_test.cpp +++ b/tests/monster_test.cpp @@ -22,7 +22,7 @@ #include "item.h" #include "line.h" -typedef statistics move_statistics; +using move_statistics = statistics; static int moves_to_destination( const std::string &monster_type, const tripoint &start, const tripoint &end ) @@ -62,7 +62,7 @@ struct track { tripoint location; }; -std::ostream &operator << ( std::ostream &os, track const &value ) +static std::ostream &operator<<( std::ostream &os, track const &value ) { os << value.participant << " l:" << value.location << @@ -71,7 +71,7 @@ std::ostream &operator << ( std::ostream &os, track const &value ) return os; } -std::ostream &operator << ( std::ostream &os, const std::vector &vec ) +static std::ostream &operator<<( std::ostream &os, const std::vector &vec ) { for( auto &track_instance : vec ) { os << track_instance << " "; diff --git a/tests/mutation_test.cpp b/tests/mutation_test.cpp index a915388541643..654dae132bfd1 100644 --- a/tests/mutation_test.cpp +++ b/tests/mutation_test.cpp @@ -15,8 +15,8 @@ std::string get_mutations_as_string( const player &p ); // Note: If a category has two mutually-exclusive mutations (like pretty/ugly for Lupine), the // one they ultimately end up with depends on the order they were loaded from JSON -void give_all_mutations( player &p, const mutation_category_trait &category, - const bool include_postthresh ) +static void give_all_mutations( player &p, const mutation_category_trait &category, + const bool include_postthresh ) { const std::vector category_mutations = mutations_category[category.id]; @@ -41,7 +41,7 @@ void give_all_mutations( player &p, const mutation_category_trait &category, } } -int get_total_category_strength( const player &p ) +static int get_total_category_strength( const player &p ) { int total = 0; for( auto &i : p.mutation_category_level ) { diff --git a/tests/new_character_test.cpp b/tests/new_character_test.cpp index ea60113441ac4..baa9cfba59493 100644 --- a/tests/new_character_test.cpp +++ b/tests/new_character_test.cpp @@ -23,7 +23,7 @@ #include "ret_val.h" #include "type_id.h" -std::ostream &operator<<( std::ostream &s, const std::vector &v ) +static std::ostream &operator<<( std::ostream &s, const std::vector &v ) { for( const auto &e : v ) { s << e.c_str() << " "; diff --git a/tests/npc_talk_test.cpp b/tests/npc_talk_test.cpp index 3e263eb683708..806faf655f885 100644 --- a/tests/npc_talk_test.cpp +++ b/tests/npc_talk_test.cpp @@ -36,7 +36,7 @@ const efftype_id effect_infected( "infected" ); static const trait_id trait_PROF_FED( "PROF_FED" ); static const trait_id trait_PROF_SWAT( "PROF_SWAT" ); -npc &create_test_talker() +static npc &create_test_talker() { const string_id test_talker( "test_talker" ); const int model_id = g->m.place_npc( 25, 25, test_talker, true ); @@ -58,7 +58,7 @@ npc &create_test_talker() return *model_npc; } -void gen_response_lines( dialogue &d, size_t expected_count ) +static void gen_response_lines( dialogue &d, size_t expected_count ) { d.gen_responses( d.topic_stack.back() ); for( talk_response &response : d.responses ) { @@ -73,7 +73,7 @@ void gen_response_lines( dialogue &d, size_t expected_count ) REQUIRE( d.responses.size() == expected_count ); } -void change_om_type( const std::string &new_type ) +static void change_om_type( const std::string &new_type ) { const point omt_pos = ms_to_omt_copy( g->m.getabs( g->u.posx(), g->u.posy() ) ); oter_id &omt_ref = overmap_buffer.ter( omt_pos.x, omt_pos.y, g->u.posz() ); diff --git a/tests/npc_test.cpp b/tests/npc_test.cpp index 4d98ab9fd4eae..74a77137139f3 100644 --- a/tests/npc_test.cpp +++ b/tests/npc_test.cpp @@ -32,7 +32,7 @@ #include "string_id.h" #include "type_id.h" -void on_load_test( npc &who, const time_duration &from, const time_duration &to ) +static void on_load_test( npc &who, const time_duration &from, const time_duration &to ) { calendar::turn = to_turn( calendar::time_of_cataclysm + from ); who.on_unload(); @@ -40,9 +40,9 @@ void on_load_test( npc &who, const time_duration &from, const time_duration &to who.on_load(); } -void test_needs( const npc &who, const numeric_interval &hunger, - const numeric_interval &thirst, - const numeric_interval &fatigue ) +static void test_needs( const npc &who, const numeric_interval &hunger, + const numeric_interval &thirst, + const numeric_interval &fatigue ) { CHECK( who.get_hunger() <= hunger.max ); CHECK( who.get_hunger() >= hunger.min ); @@ -52,7 +52,7 @@ void test_needs( const npc &who, const numeric_interval &hunger, CHECK( who.get_fatigue() >= fatigue.min ); } -npc create_model() +static npc create_model() { npc model_npc; model_npc.normalize(); @@ -70,7 +70,7 @@ npc create_model() return model_npc; } -std::string get_list_of_npcs( const std::string &title ) +static std::string get_list_of_npcs( const std::string &title ) { std::ostringstream npc_list; diff --git a/tests/overmap_noise_test.cpp b/tests/overmap_noise_test.cpp index ebaae8eac5659..a32bcced22226 100644 --- a/tests/overmap_noise_test.cpp +++ b/tests/overmap_noise_test.cpp @@ -5,8 +5,8 @@ #include "game_constants.h" #include "overmap_noise.h" -void export_raw_noise( const std::string &filename, const om_noise::om_noise_layer &noise, - int width, int height ) +static void export_raw_noise( const std::string &filename, const om_noise::om_noise_layer &noise, + int width, int height ) { std::ofstream testfile; testfile.open( filename, std::ofstream::trunc ); @@ -24,8 +24,9 @@ void export_raw_noise( const std::string &filename, const om_noise::om_noise_lay testfile.close(); } -void export_interpreted_noise( const std::string &filename, const om_noise::om_noise_layer &noise, - int width, int height, float threshold ) +static void export_interpreted_noise( + const std::string &filename, const om_noise::om_noise_layer &noise, int width, int height, + float threshold ) { std::ofstream testfile; testfile.open( filename, std::ofstream::trunc ); @@ -65,4 +66,4 @@ TEST_CASE( "om_noise_layer_lake_export", "[.]" ) const om_noise::om_noise_layer_lake f( {0, 0}, 1920237457 ); export_raw_noise( "lake-map-raw.pgm", f, OMAPX * 5, OMAPY * 5 ); export_interpreted_noise( "lake-map-interp.pgm", f, OMAPX * 5, OMAPY * 5, 0.25 ); -} \ No newline at end of file +} diff --git a/tests/player_test.cpp b/tests/player_test.cpp index 45b8fdb76815c..5f519f8690f25 100644 --- a/tests/player_test.cpp +++ b/tests/player_test.cpp @@ -14,7 +14,7 @@ // Set the stage for a particular ambient and target temperature and run update_bodytemp() until // core body temperature settles. -void temperature_check( player *p, const int ambient_temp, const int target_temp ) +static void temperature_check( player *p, const int ambient_temp, const int target_temp ) { g->weather.temperature = ambient_temp; for( int i = 0 ; i < num_bp; i++ ) { @@ -41,7 +41,7 @@ void temperature_check( player *p, const int ambient_temp, const int target_temp CHECK( high > p->temp_cur[0] ); } -void equip_clothing( player *p, const std::string &clothing ) +static void equip_clothing( player *p, const std::string &clothing ) { const item article( clothing, 0 ); p->wear_item( article ); @@ -49,7 +49,7 @@ void equip_clothing( player *p, const std::string &clothing ) // Run the tests for each of the temperature setpoints. // ambient_temps MUST have 7 values or we'll segfault. -void test_temperature_spread( player *p, const std::array &ambient_temps ) +static void test_temperature_spread( player *p, const std::array &ambient_temps ) { temperature_check( p, ambient_temps[0], BODYTEMP_FREEZING ); temperature_check( p, ambient_temps[1], BODYTEMP_VERY_COLD ); diff --git a/tests/ranged_balance.cpp b/tests/ranged_balance.cpp index 5991ba27b1ff4..4fdca73724399 100644 --- a/tests/ranged_balance.cpp +++ b/tests/ranged_balance.cpp @@ -22,7 +22,7 @@ #include "material.h" #include "type_id.h" -typedef statistics firing_statistics; +using firing_statistics = statistics; template < class T > std::ostream &operator <<( std::ostream &os, const std::vector &v ) @@ -208,7 +208,7 @@ static void test_fast_shooting( npc &shooter, const int moves, float hit_rate ) CHECK( fast_stats_upper[1].avg() < hit_rate_cap ); } -void assert_encumbrance( npc &shooter, int encumbrance ) +static void assert_encumbrance( npc &shooter, int encumbrance ) { for( const body_part bp : all_body_parts ) { INFO( "Body Part: " << body_part_name( bp ) ); diff --git a/tests/reloading_test.cpp b/tests/reloading_test.cpp index a351a68dc2e11..cb4237ead387b 100644 --- a/tests/reloading_test.cpp +++ b/tests/reloading_test.cpp @@ -122,7 +122,7 @@ TEST_CASE( "reload_gun_with_swappable_magazine", "[reload],[gun]" ) REQUIRE( gun.ammo_remaining() == gun.ammo_capacity() ); } -void reload_a_revolver( player &dummy, item &gun, item &ammo ) +static void reload_a_revolver( player &dummy, item &gun, item &ammo ) { while( gun.ammo_remaining() < gun.ammo_capacity() ) { g->reload_weapon( false ); diff --git a/tests/rng_test.cpp b/tests/rng_test.cpp index b38dec3e6ce09..b2638e3691c3d 100644 --- a/tests/rng_test.cpp +++ b/tests/rng_test.cpp @@ -55,6 +55,7 @@ TEST_CASE( "x_in_y_distribution" ) for( float y = 0.1; y < 500.0; y += y_increment ) { y_increment *= 1.1; float x_increment = 0.1; + // NOLINTNEXTLINE(clang-analyzer-security.FloatLoopCounter) for( float x = 0.1; x < y; x += x_increment ) { check_x_in_y( x, y ); x_increment *= 1.1; diff --git a/tests/savegame_test.cpp b/tests/savegame_test.cpp index 96f61ca61a3a7..589e8d5a0ba26 100644 --- a/tests/savegame_test.cpp +++ b/tests/savegame_test.cpp @@ -16,17 +16,17 @@ #include "type_id.h" // Intentionally ignoring the name member. -bool operator==( const city &a, const city &b ) +static bool operator==( const city &a, const city &b ) { return a.pos == b.pos && a.size == b.size; } -bool operator==( const radio_tower &a, const radio_tower &b ) +static bool operator==( const radio_tower &a, const radio_tower &b ) { return a.x == b.x && a.y == b.y && a.strength == b.strength && a.type == b.type && a.message == b.message; } -void check_test_overmap_data( const overmap &test_map ) +static void check_test_overmap_data( const overmap &test_map ) { // Spot-check a bunch of terrain values. // Bottom level, "L 0" in the save diff --git a/tests/shadowcasting_test.cpp b/tests/shadowcasting_test.cpp index aa6cdfdb430c3..50210a9d72cd3 100644 --- a/tests/shadowcasting_test.cpp +++ b/tests/shadowcasting_test.cpp @@ -20,11 +20,11 @@ constexpr unsigned int NUMERATOR = 1; constexpr unsigned int DENOMINATOR = 10; -void oldCastLight( float ( &output_cache )[MAPSIZE * SEEX][MAPSIZE * SEEY], - const float ( &input_array )[MAPSIZE * SEEX][MAPSIZE * SEEY], - const int xx, const int xy, const int yx, const int yy, - const int offsetX, const int offsetY, const int offsetDistance, - const int row = 1, float start = 1.0f, const float end = 0.0f ) +static void oldCastLight( float ( &output_cache )[MAPSIZE * SEEX][MAPSIZE * SEEY], + const float ( &input_array )[MAPSIZE * SEEX][MAPSIZE * SEEY], + const int xx, const int xy, const int yx, const int yy, + const int offsetX, const int offsetY, const int offsetDistance, + const int row = 1, float start = 1.0f, const float end = 0.0f ) { float newStart = 0.0f; @@ -80,8 +80,9 @@ void oldCastLight( float ( &output_cache )[MAPSIZE * SEEX][MAPSIZE * SEEY], /* * This is checking whether bresenham visibility checks match shadowcasting (they don't). */ -bool bresenham_visibility_check( const int offsetX, const int offsetY, const int x, const int y, - const float ( &transparency_cache )[MAPSIZE * SEEX][MAPSIZE * SEEY] ) +static bool bresenham_visibility_check( + const int offsetX, const int offsetY, const int x, const int y, + const float ( &transparency_cache )[MAPSIZE * SEEX][MAPSIZE * SEEY] ) { if( offsetX == x && offsetY == y ) { return true; @@ -100,7 +101,7 @@ bool bresenham_visibility_check( const int offsetX, const int offsetY, const int return visible; } -void randomly_fill_transparency( +static void randomly_fill_transparency( float ( &transparency_cache )[MAPSIZE * SEEX][MAPSIZE * SEEY], const unsigned int numerator = NUMERATOR, const unsigned int denominator = DENOMINATOR ) { @@ -122,12 +123,12 @@ void randomly_fill_transparency( } } -bool is_nonzero( const float x ) +static bool is_nonzero( const float x ) { return x != 0; } -bool is_nonzero( four_quadrants x ) +static bool is_nonzero( four_quadrants x ) { return is_nonzero( x.max() ); } @@ -216,7 +217,7 @@ void print_grid_comparison( const int offsetX, const int offsetY, } } -void shadowcasting_runoff( const int iterations, const bool test_bresenham = false ) +static void shadowcasting_runoff( const int iterations, const bool test_bresenham = false ) { float seen_squares_control[MAPSIZE * SEEX][MAPSIZE * SEEY] = {{0}}; float seen_squares_experiment[MAPSIZE * SEEX][MAPSIZE * SEEY] = {{0}}; @@ -283,7 +284,8 @@ void shadowcasting_runoff( const int iterations, const bool test_bresenham = fal REQUIRE( passed ); } -void shadowcasting_float_quad( const int iterations, const unsigned int denominator = DENOMINATOR ) +static void shadowcasting_float_quad( + const int iterations, const unsigned int denominator = DENOMINATOR ) { float lit_squares_float[MAPSIZE * SEEX][MAPSIZE * SEEY] = {{0}}; four_quadrants lit_squares_quad[MAPSIZE * SEEX][MAPSIZE * SEEY] = {{}}; @@ -334,7 +336,7 @@ void shadowcasting_float_quad( const int iterations, const unsigned int denomina REQUIRE( passed ); } -void shadowcasting_3d_2d( const int iterations ) +static void shadowcasting_3d_2d( const int iterations ) { float seen_squares_control[MAPSIZE * SEEX][MAPSIZE * SEEY] = {{0}}; float seen_squares_experiment[MAPSIZE * SEEX][MAPSIZE * SEEY] = {{0}}; diff --git a/tests/stomach_contents_tests.cpp b/tests/stomach_contents_tests.cpp index 5fd7cf7a392c7..48cf548c4db1f 100644 --- a/tests/stomach_contents_tests.cpp +++ b/tests/stomach_contents_tests.cpp @@ -12,7 +12,7 @@ #include "units.h" #include "type_id.h" -void reset_time() +static void reset_time() { calendar::turn = calendar( 0 ); player &p = g->u; @@ -21,7 +21,7 @@ void reset_time() clear_player(); } -void pass_time( player &p, time_duration amt ) +static void pass_time( player &p, time_duration amt ) { for( auto turns = 1_turns; turns < amt; turns += 1_turns ) { calendar::turn.increment(); @@ -29,7 +29,7 @@ void pass_time( player &p, time_duration amt ) } } -void clear_stomach( player &p ) +static void clear_stomach( player &p ) { p.guts.set_calories( 0 ); p.stomach.set_calories( 0 ); @@ -37,7 +37,7 @@ void clear_stomach( player &p ) p.guts.bowel_movement(); } -void set_all_vitamins( int target, player &p ) +static void set_all_vitamins( int target, player &p ) { p.vitamin_set( vitamin_id( "vitA" ), target ); p.vitamin_set( vitamin_id( "vitB" ), target ); @@ -48,7 +48,7 @@ void set_all_vitamins( int target, player &p ) // time (in minutes) it takes for the player to feel hungry // passes time on the calendar -time_duration time_until_hungry( player &p ) +static time_duration time_until_hungry( player &p ) { unsigned int thirty_minutes = 0; do { @@ -58,7 +58,7 @@ time_duration time_until_hungry( player &p ) return thirty_minutes * 30_minutes; } -void print_stomach_contents( player &p, const bool print ) +static void print_stomach_contents( player &p, const bool print ) { if( !print ) { return; @@ -76,7 +76,7 @@ void print_stomach_contents( player &p, const bool print ) // this represents an amount of food you can eat to keep you fed for an entire day // accounting for appropriate vitamins -void eat_all_nutrients( player &p ) +static void eat_all_nutrients( player &p ) { item f( "pizza_veggy" ); p.eat( f ); diff --git a/tests/temperature_test.cpp b/tests/temperature_test.cpp index c8b4354eb6b5a..b2a70047f1581 100644 --- a/tests/temperature_test.cpp +++ b/tests/temperature_test.cpp @@ -11,7 +11,7 @@ #include "game.h" -bool is_nearly( float value, float expected ) +static bool is_nearly( float value, float expected ) { // Rounding errors make the values change around a bit // Inside reality bubble and outside reality bubble also get slightly different results @@ -21,7 +21,7 @@ bool is_nearly( float value, float expected ) return ret_val; } -void set_map_temperature( int new_temperature ) +static void set_map_temperature( int new_temperature ) { g->weather.temperature = new_temperature; g->weather.clear_temp_cache(); diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 5eb7566ec14c6..2f563f5a24a2e 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -46,13 +46,13 @@ #include "rng.h" #include "type_id.h" -typedef std::pair name_value_pair_t; -typedef std::vector option_overrides_t; +using name_value_pair_t = std::pair; +using option_overrides_t = std::vector; // If tag is found as a prefix of any argument in arg_vec, the argument is // removed from arg_vec and the argument suffix after tag is returned. // Otherwise, an empty string is returned and arg_vec is unchanged. -std::string extract_argument( std::vector &arg_vec, const std::string &tag ) +static std::string extract_argument( std::vector &arg_vec, const std::string &tag ) { std::string arg_rest; for( auto iter = arg_vec.begin(); iter != arg_vec.end(); iter++ ) { @@ -65,7 +65,7 @@ std::string extract_argument( std::vector &arg_vec, const std::str return arg_rest; } -std::vector extract_mod_selection( std::vector &arg_vec ) +static std::vector extract_mod_selection( std::vector &arg_vec ) { std::vector ret; std::string mod_string = extract_argument( arg_vec, "--mods=" ); @@ -90,11 +90,16 @@ std::vector extract_mod_selection( std::vector &arg_vec ) return ret; } -void init_global_game_state( const std::vector &mods, - option_overrides_t &option_overrides ) +static void init_global_game_state( const std::vector &mods, + option_overrides_t &option_overrides, + const std::string &user_dir ) { + if( !assure_dir_exist( user_dir ) ) { + assert( !"Unable to make user_dir directory. Check permissions." ); + } + PATH_INFO::init_base_path( "" ); - PATH_INFO::init_user_dir( "./" ); + PATH_INFO::init_user_dir( user_dir.c_str() ); PATH_INFO::set_standard_filenames(); if( !assure_dir_exist( FILENAMES["config_dir"] ) ) { @@ -151,7 +156,8 @@ void init_global_game_state( const std::vector &mods, } // Checks if any of the flags are in container, removes them all -bool check_remove_flags( std::vector &cont, const std::vector &flags ) +static bool check_remove_flags( std::vector &cont, + const std::vector &flags ) { bool has_any = false; auto iter = flags.begin(); @@ -173,7 +179,7 @@ bool check_remove_flags( std::vector &cont, const std::vector &arg_vec ) +static option_overrides_t extract_option_overrides( std::vector &arg_vec ) { option_overrides_t ret; std::string option_overrides_string = extract_argument( arg_vec, "--option_overrides=" ); @@ -206,6 +212,18 @@ option_overrides_t extract_option_overrides( std::vector &arg_vec return ret; } +static std::string extract_user_dir( std::vector &arg_vec ) +{ + std::string option_user_dir = extract_argument( arg_vec, "--user-dir=" ); + if( option_user_dir.empty() ) { + return "./"; + } + if( !string_ends_with( option_user_dir, "/" ) ) { + option_user_dir += "/"; + } + return option_user_dir; +} + struct CataListener : Catch::TestEventListenerBase { using TestEventListenerBase::TestEventListenerBase; @@ -248,11 +266,14 @@ int main( int argc, const char *argv[] ) const bool dont_save = check_remove_flags( arg_vec, { "-D", "--drop-world" } ); + std::string user_dir = extract_user_dir( arg_vec ); + // Note: this must not be invoked before all DDA-specific flags are stripped from arg_vec! int result = session.applyCommandLine( arg_vec.size(), &arg_vec[0] ); if( result != 0 || session.configData().showHelp ) { printf( "CataclysmDDA specific options:\n" ); printf( " --mods= Loads the list of mods before executing tests.\n" ); + printf( " --user-dir= Set user dir (where test world will be created).\n" ); printf( " -D, --drop-world Don't save the world on test failure.\n" ); printf( " --option_overrides=n:v[,...] Name-value pairs of game options for tests.\n" ); printf( " (overrides config/options.json values)\n" ); @@ -272,7 +293,7 @@ int main( int argc, const char *argv[] ) try { // TODO: Only init game if we're running tests that need it. - init_global_game_state( mods, option_overrides_for_test_suite ); + init_global_game_state( mods, option_overrides_for_test_suite, user_dir ); } catch( const std::exception &err ) { fprintf( stderr, "Terminated: %s\n", err.what() ); fprintf( stderr, diff --git a/tests/throwing_test.cpp b/tests/throwing_test.cpp index 17a72f9ef1629..18cfab45ce45e 100644 --- a/tests/throwing_test.cpp +++ b/tests/throwing_test.cpp @@ -45,7 +45,7 @@ struct throw_test_pstats { int per; }; -std::ostream &operator<<( std::ostream &stream, const throw_test_pstats &pstats ) +static std::ostream &operator<<( std::ostream &stream, const throw_test_pstats &pstats ) { return( stream << "STR: " << pstats.str << " DEX: " << pstats.dex << " PER: " << pstats.per << " SKL: " << pstats.skill_lvl ); @@ -83,11 +83,12 @@ constexpr int max_throw_test_iterations = 10000; // tighter thresholds here will increase accuracy but also increase average test // time since more samples are required to get a more accurate test -void test_throwing_player_versus( player &p, const std::string &mon_id, const std::string &throw_id, - const int range, const throw_test_pstats &pstats, - const epsilon_threshold &hit_thresh, const epsilon_threshold &dmg_thresh, - const int min_throws = min_throw_test_iterations, - int max_throws = max_throw_test_iterations ) +static void test_throwing_player_versus( + player &p, const std::string &mon_id, const std::string &throw_id, + const int range, const throw_test_pstats &pstats, + const epsilon_threshold &hit_thresh, const epsilon_threshold &dmg_thresh, + const int min_throws = min_throw_test_iterations, + int max_throws = max_throw_test_iterations ) { const tripoint monster_start = { 30 + range, 30, 0 }; const tripoint player_start = { 30, 30, 0 }; @@ -152,11 +153,14 @@ void test_throwing_player_versus( player &p, const std::string &mon_id, const st // dump an extremely accurate population sample that can be used to tune a // broken test. // WARNING: these will take a long time likely -void test_throwing_player_versus( player &p, const std::string &mon_id, const std::string &throw_id, - const int range, const throw_test_pstats &pstats ) +/* +static void test_throwing_player_versus( + player &p, const std::string &mon_id, const std::string &throw_id, const int range, + const throw_test_pstats &pstats ) { test_throwing_player_versus( p, mon_id, throw_id, range, pstats, { 0, 0 }, { 0, 0 }, 5000, 5000 ); } +*/ constexpr throw_test_pstats lo_skill_base_stats = { 0, 8, 8, 8 }; constexpr throw_test_pstats mid_skill_base_stats = { MAX_SKILL / 2, 8, 8, 8 }; @@ -229,9 +233,9 @@ TEST_CASE( "throwing_skill_impact_test", "[throwing],[balance]" ) } } -void test_player_kills_monster( player &p, const std::string &mon_id, const std::string &item_id, - const int range, const int dist_thresh, const throw_test_pstats &pstats, - const int iterations ) +static void test_player_kills_monster( + player &p, const std::string &mon_id, const std::string &item_id, const int range, + const int dist_thresh, const throw_test_pstats &pstats, const int iterations ) { const tripoint monster_start = { 30 + range, 30, 0 }; const tripoint player_start = { 30, 30, 0 }; diff --git a/tests/time_duration_test.cpp b/tests/time_duration_test.cpp index 501c31feff4de..d340d5a321cdd 100644 --- a/tests/time_duration_test.cpp +++ b/tests/time_duration_test.cpp @@ -5,7 +5,7 @@ #include "calendar.h" #include "json.h" -time_duration parse_time_duration( const std::string &json ) +static time_duration parse_time_duration( const std::string &json ) { std::istringstream buffer( json ); JsonIn jsin( buffer ); diff --git a/tests/vehicle_drag.cpp b/tests/vehicle_drag.cpp index c9a355c374cf6..20227b81497a4 100644 --- a/tests/vehicle_drag.cpp +++ b/tests/vehicle_drag.cpp @@ -22,11 +22,11 @@ class monster; -typedef statistics efficiency_stat; +using efficiency_stat = statistics; const efftype_id effect_blind( "blind" ); -void clear_game_drag( const ter_id &terrain ) +static void clear_game_drag( const ter_id &terrain ) { // Set to turn 0 to prevent solars from producing power calendar::turn = 0; @@ -62,7 +62,7 @@ void clear_game_drag( const ter_id &terrain ) } -vehicle *setup_drag_test( const vproto_id &veh_id ) +static vehicle *setup_drag_test( const vproto_id &veh_id ) { clear_game_drag( ter_id( "t_pavement" ) ); @@ -96,11 +96,12 @@ vehicle *setup_drag_test( const vproto_id &veh_id ) // Spawn a vehicle // calculate c_air_drag and c_rolling_resistance // return whether they're within 5% of expected values -bool test_drag( const vproto_id &veh_id, - const double expected_c_air = 0, const double expected_c_rr = 0, - const double expected_c_water = 0, - const int expected_safe = 0, const int expected_max = 0, - const bool test_results = false ) +static bool test_drag( + const vproto_id &veh_id, + const double expected_c_air = 0, const double expected_c_rr = 0, + const double expected_c_water = 0, + const int expected_safe = 0, const int expected_max = 0, + const bool test_results = false ) { vehicle *veh_ptr = setup_drag_test( veh_id ); if( veh_ptr == nullptr ) { @@ -143,16 +144,15 @@ bool test_drag( const vproto_id &veh_id, return valid; } -void print_drag_test_strings( const std::string &type ) +static void print_drag_test_strings( const std::string &type ) { test_drag( vproto_id( type ) ); fflush( stdout ); } -void test_vehicle_drag( std::string type, - const double expected_c_air, const double expected_c_rr, - const double expected_c_water, - const int expected_safe, const int expected_max ) +static void test_vehicle_drag( + std::string type, const double expected_c_air, const double expected_c_rr, + const double expected_c_water, const int expected_safe, const int expected_max ) { SECTION( type ) { test_drag( vproto_id( type ), expected_c_air, expected_c_rr, expected_c_water, diff --git a/tests/vehicle_efficiency.cpp b/tests/vehicle_efficiency.cpp index fd5df46f69983..c3f5922172a51 100644 --- a/tests/vehicle_efficiency.cpp +++ b/tests/vehicle_efficiency.cpp @@ -35,11 +35,11 @@ class monster; -typedef statistics efficiency_stat; +using efficiency_stat = statistics; const efftype_id effect_blind( "blind" ); -void clear_game( const ter_id &terrain ) +static void clear_game( const ter_id &terrain ) { // Set to turn 0 to prevent solars from producing power calendar::turn = 0; @@ -71,7 +71,7 @@ void clear_game( const ter_id &terrain ) // Returns how much fuel did it provide // But contains only fuels actually used by engines -std::map set_vehicle_fuel( vehicle &v, const float veh_fuel_mult ) +static std::map set_vehicle_fuel( vehicle &v, const float veh_fuel_mult ) { // First we need to find the fuels to set // That is, fuels actually used by some engine @@ -134,7 +134,7 @@ std::map set_vehicle_fuel( vehicle &v, const float veh_fuel_mult // Returns the lowest percentage of fuel left // ie. 1 means no fuel was used, 0 means at least one dry tank -float fuel_percentage_left( vehicle &v, const std::map &started_with ) +static float fuel_percentage_left( vehicle &v, const std::map &started_with ) { std::map fuel_amount; std::set consumed_fuels; @@ -177,10 +177,10 @@ const int cycle_limit = 100; // Rescale the recorded number of tiles based on fuel percentage left // (ie. 0% fuel left means no scaling, 50% fuel left means double the effective distance) // Return the rescaled number -long test_efficiency( const vproto_id &veh_id, int &expected_mass, - const ter_id &terrain, - const int reset_velocity_turn, const long target_distance, - const bool smooth_stops = false, const bool test_mass = true ) +static long test_efficiency( const vproto_id &veh_id, int &expected_mass, + const ter_id &terrain, + const int reset_velocity_turn, const long target_distance, + const bool smooth_stops = false, const bool test_mass = true ) { long min_dist = target_distance * 0.99; long max_dist = target_distance * 1.01; @@ -280,9 +280,9 @@ long test_efficiency( const vproto_id &veh_id, int &expected_mass, return adjusted_tiles_travelled; } -efficiency_stat find_inner( const std::string &type, int &expected_mass, const std::string &terrain, - const int delay, - const bool smooth, const bool test_mass = false ) +static efficiency_stat find_inner( + const std::string &type, int &expected_mass, const std::string &terrain, const int delay, + const bool smooth, const bool test_mass = false ) { efficiency_stat efficiency; for( int i = 0; i < 10; i++ ) { @@ -292,7 +292,7 @@ efficiency_stat find_inner( const std::string &type, int &expected_mass, const s return efficiency; } -void print_stats( const efficiency_stat &st ) +static void print_stats( const efficiency_stat &st ) { if( st.min() == st.max() ) { printf( "All results %ld.\n", st.min() ); @@ -302,15 +302,16 @@ void print_stats( const efficiency_stat &st ) } } -void print_efficiency( const std::string &type, int expected_mass, const std::string &terrain, - const int delay, const bool smooth ) +static void print_efficiency( + const std::string &type, int expected_mass, const std::string &terrain, const int delay, + const bool smooth ) { printf( "Testing %s on %s with %s: ", type.c_str(), terrain.c_str(), ( delay < 0 ) ? "no resets" : "resets every 5 turns" ); print_stats( find_inner( type, expected_mass, terrain, delay, smooth ) ); } -void find_efficiency( const std::string &type ) +static void find_efficiency( const std::string &type ) { SECTION( "finding efficiency of " + type ) { print_efficiency( type, 0, "t_pavement", -1, false ); @@ -320,7 +321,7 @@ void find_efficiency( const std::string &type ) } } -int average_from_stat( const efficiency_stat &st ) +static int average_from_stat( const efficiency_stat &st ) { const int ugly_integer = ( st.min() + st.max() ) / 2.0; // Round to 4 most significant places @@ -330,7 +331,7 @@ int average_from_stat( const efficiency_stat &st ) } // Behold: power of laziness -void print_test_strings( const std::string &type ) +static void print_test_strings( const std::string &type ) { std::ostringstream ss; int expected_mass = 0; @@ -350,10 +351,11 @@ void print_test_strings( const std::string &type ) fflush( stdout ); } -void test_vehicle( std::string type, int expected_mass, - const long pavement_target, const long dirt_target, - const long pavement_target_w_stops, const long dirt_target_w_stops, - const long pavement_target_smooth_stops = 0, const long dirt_target_smooth_stops = 0 ) +static void test_vehicle( + std::string type, int expected_mass, + const long pavement_target, const long dirt_target, + const long pavement_target_w_stops, const long dirt_target_w_stops, + const long pavement_target_smooth_stops = 0, const long dirt_target_smooth_stops = 0 ) { SECTION( type + " on pavement" ) { test_efficiency( vproto_id( type ), expected_mass, ter_id( "t_pavement" ), -1, diff --git a/tests/vehicle_turrets.cpp b/tests/vehicle_turrets.cpp index fc3738f6d438a..1e21b164ec47e 100644 --- a/tests/vehicle_turrets.cpp +++ b/tests/vehicle_turrets.cpp @@ -35,7 +35,7 @@ static std::vector turret_types() return res; } -const vpart_info *biggest_tank( const ammotype &ammo ) +static const vpart_info *biggest_tank( const ammotype &ammo ) { std::vector res; diff --git a/tests/vision_test.cpp b/tests/vision_test.cpp index 951d61dc43181..5c7c017761cd1 100644 --- a/tests/vision_test.cpp +++ b/tests/vision_test.cpp @@ -23,9 +23,9 @@ #include "shadowcasting.h" #include "type_id.h" -void full_map_test( const std::vector &setup, - const std::vector &expected_results, - const calendar time ) +static void full_map_test( const std::vector &setup, + const std::vector &expected_results, + const calendar time ) { const ter_id t_brick_wall( "t_brick_wall" ); const ter_id t_window_frame( "t_window_frame" ); diff --git a/tests/wield_times_test.cpp b/tests/wield_times_test.cpp index 604ab18653fb8..db9e8a2cdc836 100644 --- a/tests/wield_times_test.cpp +++ b/tests/wield_times_test.cpp @@ -13,8 +13,8 @@ #include "enums.h" #include "item.h" -void wield_check_internal( player &dummy, item &the_item, const char *section_text, - const std::string &var_name, const int expected_cost ) +static void wield_check_internal( player &dummy, item &the_item, const char *section_text, + const std::string &var_name, const int expected_cost ) { dummy.weapon = item(); dummy.set_moves( 1000 ); @@ -39,7 +39,7 @@ void wield_check_internal( player &dummy, item &the_item, const char *section_te } -void do_test( const bool generating_cases ) +static void do_test( const bool generating_cases ) { player &dummy = g->u; const tripoint spot = dummy.pos(); diff --git a/tools/format/getpost.h b/tools/format/getpost.h index 87365fb4708e4..3e584cb837db8 100644 --- a/tools/format/getpost.h +++ b/tools/format/getpost.h @@ -31,7 +31,7 @@ THE SOFTWARE. #include #include -std::string urlDecode( std::string str ) +inline std::string urlDecode( std::string str ) { std::string temp; int i; @@ -60,7 +60,7 @@ std::string urlDecode( std::string str ) return temp; } -void initializeGet( std::map &Get ) +inline void initializeGet( std::map &Get ) { std::string tmpkey, tmpvalue; std::string *tmpstr = &tmpkey; @@ -92,7 +92,7 @@ void initializeGet( std::map &Get ) } } -void initializePost( std::map &Post ) +inline void initializePost( std::map &Post ) { std::string tmpkey, tmpvalue; std::string *tmpstr = &tmpkey; diff --git a/tools/generate_changelog.py b/tools/generate_changelog.py index 811f07e2ea1b4..1885d98dbc96a 100644 --- a/tools/generate_changelog.py +++ b/tools/generate_changelog.py @@ -14,6 +14,7 @@ import sys import argparse import pathlib +import contextlib import xml.etree.ElementTree from datetime import date, datetime, timedelta @@ -354,13 +355,16 @@ def add_multiple(self, builds): def get_build_by_number(self, build_number): return self.ref_by_build_number[build_number] if build_number in self.ref_by_build_number else None - def get_previous_successful_build(self, build_number): + def get_previous_build(self, build_number, condition=lambda x: True): for x in range(build_number - 1, 0, -1): prev_build = self.get_build_by_number(x) - if prev_build is not None and prev_build.was_successful(): + if prev_build is not None and condition(prev_build): return prev_build return None + def get_previous_successful_build(self, build_number): + return self.get_previous_build(build_number, lambda x: x.was_successful()) + def get_all_builds(self, filter_by=None, sort_by=None): """Return all Builds in Repository. No order is guaranteed.""" build_list = self.ref_by_build_number.values() @@ -403,9 +407,10 @@ def get_build_list(self): """Return the builds from Jenkins. API limits the result to last 999 builds.""" request_url = self.JENKINS_BUILD_LIST_API + '?' + urllib.parse.urlencode(self.JENKINS_BUILD_LONG_LIST_PARAMS) api_request = urllib.request.Request(request_url) + log.debug(f'Processing Request {api_request.full_url}') with urllib.request.urlopen(api_request) as api_response: - log.debug(f'Request DONE {api_request.full_url}') api_data = xml.etree.ElementTree.fromstring(api_response.read()) + log.debug('Jenkins Request DONE!') for build_data in api_data: yield self._create_build_from_api_data(build_data) @@ -428,7 +433,7 @@ def _create_build_from_api_data(self, build_data): jb_last_hash = None jb_branch = None - if jb_build_result == 'SUCCESS': + if build_data.find(r'.//action/lastBuiltRevision/branch/SHA1') is not None: jb_last_hash = build_data.find(r'.//action/lastBuiltRevision/branch/SHA1').text jb_branch = build_data.find(r'.//action/lastBuiltRevision/branch/name').text @@ -605,7 +610,7 @@ def process_api_requests(self, request_generator, callback, max_threads=15): ### start threads threads = [] for x in range(1, max_threads + 1): - t = threading.Thread(target=self._exit_on_exception(self._process_api_requests_on_threads), + t = threading.Thread(target=exit_on_exception(self._process_api_requests_on_threads), args=(request_generator, callback)) t.name = f'WORKER_{x:03}' threads.append(t) @@ -628,17 +633,6 @@ def _process_api_requests_on_threads(request_generator, callback): api_request = request_generator.generate() log.debug(f'No more requests left, killing Thread.') - @staticmethod - def _exit_on_exception(func): - """Decorator to terminate the main script and all threads if a thread generates an Exception""" - def _exit_on_exception_closure(*args, **kwargs): - try: - func(*args, **kwargs) - except Exception as err: - log.exception(f'Unhandled Exception: {err}') - os._exit(-5) - return _exit_on_exception_closure - class GitHubApiRequestBuilder: @@ -670,7 +664,8 @@ class CommitApiGenerator(GitHubApiRequestBuilder): GITHUB_API_LIST_COMMITS = r'https://api.github.com/repos/CleverRaven/Cataclysm-DDA/commits' - def __init__(self, api_token, since_dttm=None, until_dttm=None, sha='master', initial_page=1, step=1, timezone='Etc/UTC'): + def __init__(self, api_token, since_dttm=None, until_dttm=None, sha='master', + initial_page=1, step=1, timezone='Etc/UTC'): super().__init__(api_token, timezone) self.sha = sha self.since_dttm = since_dttm @@ -770,12 +765,23 @@ def create_request(self, state='all', page=1): return super().create_request(self.GITHUB_API_LIST_PR, params) +def exit_on_exception(func): + """Decorator to terminate the main script and all threads if a thread generates an Exception""" + def exit_on_exception_closure(*args, **kwargs): + try: + func(*args, **kwargs) + except Exception as err: + log.exception(f'Unhandled Exception: {err}') + os._exit(-10) + return exit_on_exception_closure + + def do_github_request(api_request, retry_on_limit=3): """Do an HTTP request to GitHub and retries in case of hitting API limits""" for retry in range(1, retry_on_limit + 2): try: + log.debug(f'Processing Request {api_request.full_url}') with urllib.request.urlopen(api_request) as api_response: - log.debug(f'Request DONE {api_request.full_url}') return json.load(api_response) except urllib.error.HTTPError as err: ### hit rate limit, wait and retry @@ -815,30 +821,54 @@ def read_personal_token(filename): return None +@contextlib.contextmanager +def smart_open(filename=None, *args, **kwargs): + if filename and (filename == '-' or filename == sys.stdout): + fh = sys.stdout + else: + fh = open(filename, *args, **kwargs) + + try: + yield fh + finally: + if fh is not sys.stdout: + fh.close() + + +def validate_file_for_writing(filepath): + if (filepath is not None and + filepath != sys.stdout and + (not filepath.parent.exists() + or not filepath.parent.is_dir())): + return False + + def main_entry(argv): parser = argparse.ArgumentParser(description='Generates Changelog from now until the specified date') - output_style_group = parser.add_mutually_exclusive_group(required=True) - output_style_group.add_argument( - '-D', '--group-by-date', - action='store_true', - help='Indicates changes should be grouped by Date.' + parser.add_argument( + 'target_date', + help='Specify when should stop generating. Accepts "YYYY-MM-DD" ISO 8601 Date format.', + type=lambda d: datetime.combine(date.fromisoformat(d), datetime.min.time()) ) - output_style_group.add_argument( - '-B', '--group-by-build', - action='store_true', - help='Indicates changes should be grouped by Build.' + + parser.add_argument( + '-D', '--by-date', + help='Indicates changes should be presented grouped by Date. Requires a filename parameter, "-" for STDOUT', + type=lambda x: sys.stdout if x == '-' else pathlib.Path(x).expanduser().resolve(), + default=None ) parser.add_argument( - 'target_date', - help='Specify when should stop generating . Accepts "YYYY-MM-DD" ISO 8601 Date format.', - type=lambda d: datetime.combine(date.fromisoformat(d), datetime.min.time()) + '-B', '--by-build', + help='Indicates changes should be presented grouped by Build. Requires a filename parameter, "-" for STDOUT', + type=lambda x: sys.stdout if x == '-' else pathlib.Path(x).expanduser().resolve(), + default=None ) parser.add_argument( '-e', '--end-date', - help='Specify when should start generating . Accepts "YYYY-MM-DD" ISO 8601 Date format.', + help='Specify when should start generating. Accepts "YYYY-MM-DD" ISO 8601 Date format.', type=lambda d: datetime.combine(date.fromisoformat(d), datetime.min.time()), default=None ) @@ -850,13 +880,6 @@ def main_entry(argv): default='~/.generate_changelog.token' ) - parser.add_argument( - '-o', '--output-file', - help='Specify where to write extracted information. Default to standard output.', - type=lambda x: pathlib.Path(x).expanduser().resolve(), - default=None - ) - parser.add_argument( '-N', '--include-summary-none', action='store_true', @@ -888,41 +911,76 @@ def main_entry(argv): log.debug(f'Commandline Arguments (+defaults): {arguments}') - if (arguments.output_file is not None and - (not arguments.output_file.parent.exists() - or not arguments.output_file.parent.is_dir())): - raise ValueError(f"Specified directory for Output File doesn't exist: {arguments.output_file.parent}") - - if arguments.group_by_date: - main_by_date(arguments.target_date, arguments.end_date, arguments.token_file, - arguments.output_file,arguments.include_summary_none, arguments.flatten_output) - elif arguments.group_by_build: - main_by_build(arguments.target_date, arguments.end_date, arguments.token_file, - arguments.output_file,arguments.include_summary_none) + if validate_file_for_writing(arguments.by_date): + raise ValueError(f"Specified directory in --by-date doesn't exist: {arguments.by_date.parent}") + if validate_file_for_writing(arguments.by_build): + raise ValueError(f"Specified directory in --by-build doesn't exist: {arguments.by_build.parent}") -def main_by_date(target_dttm, end_dttm, token_file, output_file, include_summary_none, flatten): - personal_token = read_personal_token(token_file) + personal_token = read_personal_token(arguments.token_file) if personal_token is None: log.warning("GitHub Token was not provided, API calls will have severely limited rates.") - ### get data from GitHub API - commit_api = CommitApi(CommitFactory(), personal_token) - commit_repo = CommitRepository() - commit_repo.add_multiple(commit_api.get_commit_list(target_dttm, end_dttm)) + if arguments.by_date is None and arguments.by_build is None: + raise ValueError("Script should be called with either --by-date or --by-build arguments or both.") + + main_output(arguments.by_date, arguments.by_build, arguments.target_date, arguments.end_date, + personal_token, arguments.include_summary_none, arguments.flatten_output) + + +def get_github_api_data(pr_repo, commit_repo, target_dttm, end_dttm, personal_token): + + def load_github_repos(): + commit_api = CommitApi(CommitFactory(), personal_token) + commit_repo.add_multiple(commit_api.get_commit_list(target_dttm, end_dttm)) + + pr_api = PullRequestApi(CDDAPullRequestFactory(), personal_token) + pr_repo.add_multiple(pr_api.get_pr_list(target_dttm, end_dttm, merged_only=True)) + + github_thread = threading.Thread(target=exit_on_exception(load_github_repos)) + github_thread.name = 'WORKER_GIT' + github_thread.daemon = True + github_thread.start() + + return github_thread + + +def get_jenkins_api_data(build_repo): + + def load_jenkins_repo(): + jenkins_api = JenkinsApi(JenkinsBuildFactory()) + build_repo.add_multiple(jenkins_api.get_build_list()) + + jenkins_thread = threading.Thread(target=exit_on_exception(load_jenkins_repo)) + jenkins_thread.name = 'WORKER_JEN' + jenkins_thread.daemon = True + jenkins_thread.start() + + return jenkins_thread + + +def main_output(by_date, by_build, target_dttm, end_dttm, personal_token, include_summary_none, flatten): + threads = [] + + if by_build is not None: + build_repo = JenkinsBuildRepository() + threads.append(get_jenkins_api_data(build_repo)) - pr_api = PullRequestApi(CDDAPullRequestFactory(), personal_token) pr_repo = CDDAPullRequestRepository() - pr_repo.add_multiple(pr_api.get_pr_list(target_dttm, end_dttm, merged_only=True)) + commit_repo = CommitRepository() + threads.append(get_github_api_data(pr_repo, commit_repo, target_dttm, end_dttm, personal_token)) - ### build script output - if output_file is None: - build_output_by_date(pr_repo, commit_repo, target_dttm, end_dttm, sys.stdout, - include_summary_none, flatten) - else: - with open(output_file, 'w', encoding='utf8') as opened_output_file: - build_output_by_date(pr_repo, commit_repo, target_dttm, end_dttm, opened_output_file, - include_summary_none, flatten) + for thread in threads: + thread.join() + + if by_date is not None: + with smart_open(by_date, 'w', encoding='utf8') as output_file: + build_output_by_date(pr_repo, commit_repo, target_dttm, end_dttm, + output_file, include_summary_none, flatten) + + if by_build is not None: + with smart_open(by_build, 'w', encoding='utf8') as output_file: + build_output_by_build(build_repo, pr_repo, commit_repo, output_file, include_summary_none) def build_output_by_date(pr_repo, commit_repo, target_dttm, end_dttm, output_file, @@ -969,53 +1027,40 @@ def build_output_by_date(pr_repo, commit_repo, target_dttm, end_dttm, output_fil if not flatten: print(f" MISC. COMMITS", file=output_file) for commit in commits_with_no_pr[curr_date]: - print(f" * {commit.message} (by {commit.author} in Commit {commit.hash[:7]})", file=output_file) + if not flatten: + print(f" * {commit.message} (by {commit.author} in Commit {commit.hash[:7]})", + file=output_file) + else: + print(f"COMMIT {commit.message})", file=output_file) print(file=output_file) if curr_date in pr_with_invalid_summary or (include_summary_none and curr_date in pr_with_summary_none): if not flatten: print(f" MISC. PULL REQUESTS", file=output_file) for pr in pr_with_invalid_summary[curr_date]: - print(f" * {pr.title} (by {pr.author} in PR {pr.id})", file=output_file) + if not flatten: + print(f" * {pr.title} (by {pr.author} in PR {pr.id})", file=output_file) + else: + print(f"INVALID_SUMMARY {pr.title})", file=output_file) if include_summary_none: for pr in pr_with_summary_none[curr_date]: - print(f" * [MINOR] {pr.title} (by {pr.author} in PR {pr.id})", file=output_file) + if not flatten: + print(f" * [MINOR] {pr.title} (by {pr.author} in PR {pr.id})", file=output_file) + else: + print(f"MINOR {pr.title})", file=output_file) print(file=output_file) print(file=output_file) -def main_by_build(target_dttm, end_dttm, token_file, output_file, include_summary_none): - personal_token = read_personal_token(token_file) - if personal_token is None: - log.warning("GitHub Token was not provided, API calls will have severely limited rates.") - - ### get data from GitHub API - commit_api = CommitApi(CommitFactory(), personal_token) - commit_repo = CommitRepository() - commit_repo.add_multiple(commit_api.get_commit_list(target_dttm, end_dttm)) - - pr_api = PullRequestApi(CDDAPullRequestFactory(), personal_token) - pr_repo = CDDAPullRequestRepository() - pr_repo.add_multiple(pr_api.get_pr_list(target_dttm, end_dttm, merged_only=True)) - - jenkins_api = JenkinsApi(JenkinsBuildFactory()) - build_repo = JenkinsBuildRepository() - build_repo.add_multiple((build for build in jenkins_api.get_build_list() if build.was_successful())) - - ### build script output - if output_file is None: - build_output_by_build(build_repo, pr_repo, commit_repo, sys.stdout, include_summary_none) - else: - with open(output_file, 'w', encoding='utf8') as opened_output_file: - build_output_by_build(build_repo, pr_repo, commit_repo, opened_output_file, include_summary_none) - - def build_output_by_build(build_repo, pr_repo, commit_repo, output_file, include_summary_none): - for build in build_repo.get_all_builds(sort_by=lambda x: -x.build_dttm.timestamp()): + ### "ABORTED" builds have no "hash" and fucks up the logic here... but just to be sure, ignore builds without hash + ### and changes will be atributed to next build availiable that does have a hash + for build in build_repo.get_all_builds(filter_by=lambda x: x.last_hash is not None, + sort_by=lambda x: -x.build_dttm.timestamp()): ### we need the previous build a hash/date hash ### to find commits / pull requests that got into the build - prev_build = build_repo.get_previous_successful_build(build.number) + prev_build = build_repo.get_previous_build(build.number, lambda x: x.last_hash is not None) if prev_build is None: break