summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--0.F_backport-inhaler-mission-no-autofail.patch12
-rw-r--r--0007-oxyacetylene-from-oxygen.patch12
-rw-r--r--0025-fix-open-metal-doors.patch11
-rw-r--r--0026-fix-brioche-cooking-time.patch11
-rw-r--r--PKGBUILD39
-rw-r--r--custom-2.patch314
6 files changed, 358 insertions, 41 deletions
diff --git a/0.F_backport-inhaler-mission-no-autofail.patch b/0.F_backport-inhaler-mission-no-autofail.patch
deleted file mode 100644
index 32983d7..0000000
--- a/0.F_backport-inhaler-mission-no-autofail.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/src/mission.cpp
-+++ b/src/mission.cpp
-@@ -230,6 +230,9 @@
- } else if( type->goal == MGOAL_KILL_MONSTER_SPEC ) {
- kill_count_to_reach = kills.kill_count( monster_species ) + monster_kill_goal;
- }
-+ if( type->deadline_low != 0_turns || type->deadline_high != 0_turns ) {
-+ deadline = calendar::turn + rng( type->deadline_low, type->deadline_high );
-+ }
- type->start( this );
- status = mission_status::in_progress;
- }
diff --git a/0007-oxyacetylene-from-oxygen.patch b/0007-oxyacetylene-from-oxygen.patch
deleted file mode 100644
index 8da7688..0000000
--- a/0007-oxyacetylene-from-oxygen.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/data/json/recipes/ammo/weldgas.json
-+++ b/data/json/recipes/ammo/weldgas.json
-@@ -7,8 +8,9 @@
- "charges": 120,
- "book_learn": [ [ "textbook_chemistry", 4 ], [ "textbook_gaswarfare", 5 ], [ "atomic_survival", 3 ] ],
- "qualities": [ { "id": "PRESSURIZATION", "level": 1 } ],
-+ "tools": [ [ [ "oxygen_tank", 24 ], [ "oxygen_cylinder", 24 ], [ "smoxygen_tank", 24 ] ] ],
-- "components": [ [ [ "oxygen", 24 ] ], [ [ "acetylene", 96 ] ] ]
-+ "components": [ [ [ "acetylene", 96 ] ] ]
- },
- {
- "result": "acetylene",
diff --git a/0025-fix-open-metal-doors.patch b/0025-fix-open-metal-doors.patch
new file mode 100644
index 0000000..f0369ef
--- /dev/null
+++ b/0025-fix-open-metal-doors.patch
@@ -0,0 +1,11 @@
+--- a/data/json/furniture_and_terrain/terrain-doors.json
++++ b/data/json/furniture_and_terrain/terrain-doors.json
+@@ -2152,7 +2152,7 @@
+ "symbol": "+",
+ "looks_like": "t_door_metal_lab_o",
+ "color": "cyan",
+- "move_cost": 1,
++ "move_cost": 2,
+ "roof": "t_flat_roof",
+ "flags": [ "TRANSPARENT", "FLAT", "CONNECT_TO_WALL", "BURROWABLE" ],
+ "bash": {
diff --git a/0026-fix-brioche-cooking-time.patch b/0026-fix-brioche-cooking-time.patch
new file mode 100644
index 0000000..5e94204
--- /dev/null
+++ b/0026-fix-brioche-cooking-time.patch
@@ -0,0 +1,11 @@
+--- a/data/json/recipes/recipe_food.json
++++ b/data/json/recipes/recipe_food.json
+@@ -5008,6 +5008,8 @@
+ "subcategory": "CSC_FOOD_BREAD",
+ "skill_used": "cooking",
+ "difficulty": 3,
++ "time": "20 m",
++ "batch_time_factors": [ 50, 4 ],
+ "book_learn": [ [ "baking_book", 3 ], [ "cookbook_daintydishes", 5 ] ],
+ "qualities": [ { "id": "COOK", "level": 3 } ],
+ "tools": [ [ [ "surface_heat", 8, "LIST" ] ] ],
diff --git a/PKGBUILD b/PKGBUILD
index efb42a2..e96cdea 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -13,9 +13,9 @@ pkgbase=cataclysm-bn
pkgname=(cataclysm-bn cataclysm-bn-tiles)
pkgname=cataclysm-bn
_pkgname=Cataclysm-BN-cbn-experimental
-pkgver=202107310434
-_pkgver=2021-07-31-0434
-pkgrel=1
+pkgver=202108171012
+_pkgver=2021-08-17-1012
+pkgrel=2
pkgdesc="A post-apocalyptic roguelike."
#url="http://cataclysmrl.blogspot.com/"
#url="http://www.cataclysm.glyphgryph.com/"
@@ -32,7 +32,6 @@ source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-
"0.F_backport-tacoma-barn-door-position.patch"
"0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch"
- "0.F_backport-inhaler-mission-no-autofail.patch"
"0.F_backport-radio-can-use-ups.patch"
"0001-quiverfull-house-correct-stairs.patch"
@@ -41,7 +40,6 @@ source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-
"0004-tacoma-clinic-add-missing-floor.patch"
"0005-lumbermill-gasoline-not-spilled.patch"
"0006-community-garden-fertilizer-not-spilled.patch"
- "0007-oxyacetylene-from-oxygen.patch"
"0008-npc-can-use-more-bionics.patch"
"0009-22-casings-can-stack.patch"
"0010-4570-dragon-can-be-dismantled.patch"
@@ -59,6 +57,8 @@ source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-
"0022-fix-evac3-background-visible.patch"
"0023-fix-rubbersplosion.patch"
"0024-ammo-order-fix.patch"
+ "0025-fix-open-metal-doors.patch"
+ "0026-fix-brioche-cooking-time.patch"
"jc_ammo-loudness-ap-times-2.patch"
"jc_allow-bio-firestarter-on-smoker.patch"
@@ -70,19 +70,19 @@ source=("$pkgname-$_pkgver.tar.gz::https://github.com/cataclysmbnteam/Cataclysm-
"jc_restore-inf-immune.patch"
"custom.patch"
+ "custom-2.patch"
"cataclysm-dda-tileset_undeadpeople.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-tileset_undeadpeople.git/snapshot/cataclysm-dda-tileset_undeadpeople-master.tar.xz"
"cataclysm-dda-mod_battle-maid-redone-tileset.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-mod_battle-maid-redone-tileset.git/snapshot/cataclysm-dda-mod_battle-maid-redone-tileset-master.tar.xz"
"cataclysm-dda-soundpack_jcsoundpack.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-soundpack_jcsoundpack.git/snapshot/cataclysm-dda-soundpack_jcsoundpack-master.tar.xz"
"cataclysm-dda-musicpack_coag-musicpack.tar.xz::https://library.iserlohn-fortress.net/cataclysm-dda-musicpack_coag-musicpack.git/snapshot/cataclysm-dda-musicpack_coag-musicpack-master.tar.xz"
)
-b2sums=('ebb0aba2614372af488322cf9b445ea20c17e76699cd019ecb73b7dc07ecdd7d1ef98fc4bab3cb67d88dec6c45034323d80b8ed79ded32c32a04342d6cf8e3df'
+b2sums=('a382f7bbd31862cb4568d9510718d4586931294629f99cd753ae9f494532a854946d2dafbe3bf4700fe2577693d1a1c989d6cf902e8d52eb9f744106e5e5e479'
'069ecde58859b3d44cd687c4b6e718610cefb693ff86e66f199ebfb1b3072023ad2b6f0c28e27ef9c1ce4997f6a5b2ca0d45046996b3ff35a4aeaeb1a7cf9421'
'ad88bc6c1e3c8183a313b5eec42f98d6956afea349feff34a86e4536c9921fa99d2594282caf27de8ebb7ffb56376ed2e76d572227bfd6d8173c7bb1f01e23b8'
'6f70e90359a14e4839d9a2683debb88850e5dd387add911ad68fd87e5512cfcdd435da63e1e370358153673fd5a72a9b1e9c94f1979edb7948b4da8c82407bad'
'ce0dd5121e814e0fcd79d68362c80a83bfe70f970be9d5d6f6fe5f6a56ed3f041be4d560aaf02225c3ce7c457dc63bc3adf0709d4b89a81c18184ff5341eb5d3'
'2cdcf9ab03eb92f384caf1a2d90f82c75f880cb6286811e83217c883e421c116e7844ca193a010dc35e12eec46ede3663171a2f45f660ef5a8be95c474f61bfc'
- '9e2c26bf0e2bb4fd60de8cad1f9c05f329d99a56c64189bc2747915c48d208b63038d45a90f7a1c8e8bb0ac33461f217acf7e57f752f0acff117e2062459e9bb'
'51b1324506179f7fadd8bc187eb8db939494483597b0b7b63909cec66f4e94b27888ccfa926bbd2ff8b0e80108ecc373118c202a177fc2ebd4f5231f87f09a83'
'8232c6a10fd1f608304982ae7f03eb8afc663be76cdc00aee46ecb58de838e21fdc8673841266ccd00153263f7b15b59dcd1fc6ece86834509d7ccb2cacf08fa'
'025213998583972e7551bd7bd7376ab65857e28d4338fab60ae792a6b3bd48983aec77e5143baaa63d4f3feb7cd590c4bded529c410e4d18f2b8c5813f25daa3'
@@ -90,7 +90,6 @@ b2sums=('ebb0aba2614372af488322cf9b445ea20c17e76699cd019ecb73b7dc07ecdd7d1ef98fc
'b8a64accada87ee5be989c5307805610c9b5c0327bc107aab237ac3225dd9e4c51b6c79a2a7de15fe187d3c32d7cbe1c462f9b0e9fb5d5a55a74236c7061e96e'
'85aeb5920ee5879848be4057324153a077fe907bed527ed8f9b80a3c5ee1ef64786f63ee2999f5ba74e80a43e99ded3280ce27759c1f7b73259a6e2b5e584aa8'
'58a94409205f7b670ab5745b8cbc234a38efd6a6217cef4efb7e397f091092e3e0c7790706b0a42accaa83d7509b8e244a98b9f0ba78349ee85f3164745c3501'
- 'd34d673fe04d4317ef3c1ac3f088b6614f7c20414cfe44aa0ff71bdc932c517c4e6295492f158ced84232af8f54d1672ae56078b156593d58bf8fe7ffc3d475d'
'f3bdbaac5dbe9384571fe5ec14d2d25035f227a977c25349b8188e7343804e3973b898b44c34f9abe9318666294f4fdfe780fd516dcbdb29c4ac52f6d0ed6cad'
'67cdb7e097bbb46da5cf04708bc2858b080d1a85742afc4c088da3e4e3fdeb6e4c51240fc5a6b9a1c7d927b30b3d251236e025ee4e5496142a7716d4ba51b82c'
'9ad2986261e6613e80b4bb61b89e2d0c703d7c4d28fda98e58fbcc2623a05c05e253cd2045e64c140e5de99aa2278165948e717739eb803849ea17745e974620'
@@ -108,6 +107,8 @@ b2sums=('ebb0aba2614372af488322cf9b445ea20c17e76699cd019ecb73b7dc07ecdd7d1ef98fc
'ab35d6663b864449d46da4a9e1c51e11956ff4c38e16db58c831b71f7b964fc25b0283122dbc8aa0549f240f01c4a910fb5c6c82937258c6b736c05b54bcf768'
'e1d03f68918d03f980f4c2dd966e3788afe63f14e2d18dbd4dab2cdbfa1253e4823c0f5daa3a579e47319a3c2af35bc5af0a390e2ba91fe7621f6db8b1a60994'
'c47d002dc55af6c74a830205626eab57922f3f79143a5e1ddbc9ac8dc75c1ef4f2adf6a1816f8abe0b43e9a81a9021d1c9c7f62d76fdf67fa5fe00bbeca73962'
+ '067dc37b995fc75ee720a4738c9ba43774c57331d53da4d82edcd954c94baf4e40c101aa20bdba7fa5c5ae2fda836c5b7405f7837c19b41bb4b2e9e25c44d242'
+ 'c37cd997666836479a7a17a57c007ded373c03b10c59c68d594675a41a362cbff9d1b584581bff899d31221e8719cd51516904fa0f72ae343c6ea06ed4acc70d'
'92cde696eec00e6758b58e73e8bc60ad1a73bb2a18d4fdfd24a19b5be715305a047943a02d94a9703c101ca0c769dbeb816f1f28809345bae0fec42fbc27bb34'
'edfccb4ccb70e174648101d68432ea14ee1e7cc9304d4545dddb65184eeafb708a898cc90778e44cf7464c82c9d350209e5ad262c50a50fa0b8ae3a22fca9ff9'
'8e9bf6ff4bafc6397c6631392aaddd2866537943ae3bbdb95282945acba385d66f6d9879fd283eeafbb8df4e927f3ecc061fb36ecb5d38dbddecd2fd9c735e56'
@@ -117,9 +118,10 @@ b2sums=('ebb0aba2614372af488322cf9b445ea20c17e76699cd019ecb73b7dc07ecdd7d1ef98fc
'e9c8decf0ab74ac2dd02ddd537ca80ad2aa02d97faf6cfcb983965b4c3f400b47b2e0517f2927d1b2463c14370fd1a0bad5b4d00710b2b415b45d1a81724a9c9'
'0bc675f798113cc744337ac2864c54510af89fc59450a3bf250cc49c1a1b17ebeddc007e38491978d367555ed7f4895266d68f50f01d30f79a7cacdc01f0f207'
'0dc275d5e1aa79b2cf73f7e997ea2b602690787ae15e3abdd3b9195bb409d511c74d4f7dca4bf1753a9afb4618f04cb462769c24999357dea62593a379411f42'
- '59665e75f28e04a7c1da4dca3242626bab8298849fec5af099550fc3ee36cc6badd7794aaad7b8b3f1b85790df3b89b4d0bb91dcda809b109bf729bb40b0a972'
+ '431b1757432f1bf3c8d838b149f23be7778367bc8a8a906294e4313ff34f4819bef93e493f6c9ce99ee2cbbe023d2f24893e6fd5352056c208e386702416a907'
+ '0cf2d5cbf60c4c4a52cb7f2ecd4dd1757a811e3b0b6b5606f4417ba95901479bfc3fc9270377d5c4d855a94cd841e07229415dacce3475dcb7f03b01ebc3b949'
'ba0bd9be874e134914334a5baaef843162003adc0253dae32f1a052da6da59e108808852f51b05350ae6ae074f8d15d88cfcf93f49174c47b924f0f9d7fbd206'
- '2b506d69016b5eac7b72341d30900dded43b5c54471547db43968c7b8724d95aff622aa133afb161e200b1b8e470b47422966230458e7b41a112d47fdcdf27f0'
+ '83ea75e6c14667c134bf683f330235c40c7bb94c65e19a6fc4a09ba38da254d09264a86cba4cafcbcf9b79916bd8e16976cb1b49be2475fe315616a3cc857820'
'b9309da09b165fb57e83f84e3584d2479bd3336ed86e181e5df2d27daa92bd55d03d7f3fc226f03696af5f0f32d8e0e7ecd26ae7e50eed0200d0b0feaad07efb')
prepare() {
@@ -137,7 +139,7 @@ prepare() {
sed -i 's|cataclysm-dda|cataclysm-bn|' src/path_info.cpp
# Fix version
- sed -i 's|VERSION = unstable|VERSION = 2021-07-31-0434|' Makefile
+ sed -i 's|VERSION = unstable|VERSION = 2021-08-17-1012|' Makefile
# Backports from 0.F
@@ -147,9 +149,6 @@ prepare() {
# Fix npcs unable to drink from firestation and shelter basecamps wells
patch -Np1 -i "$srcdir"/0.F_backport-make-firestation-shelter-wells-npc-drinkable.patch
- # Fix npcs with the inhaler mission instantly dying upon mission acceptance
- patch -Np1 -i "$srcdir"/0.F_backport-inhaler-mission-no-autofail.patch
-
# Fix radio, e-ink reader music, tactical tonfa not working with UPS
patch -Np1 -i "$srcdir"/0.F_backport-radio-can-use-ups.patch
@@ -173,9 +172,6 @@ prepare() {
# Fix community garden liquid fertilizer being in a pit instead of in the storage tanks
patch -Np1 -i "$srcdir"/0006-community-garden-fertilizer-not-spilled.patch
- # Fix oxyacetylene to be craftable from oxygen tanks
- patch -Np1 -i "$srcdir"/0007-oxyacetylene-from-oxygen.patch
-
# Fix npc not being able to install some additional CBMs:
# ie, soporific inducer, gasoline fuel cell, enhanced hearing, surgical scalpels
patch -Np1 -i "$srcdir"/0008-npc-can-use-more-bionics.patch
@@ -228,6 +224,12 @@ prepare() {
# Fix ammo ordering so as to not prevent those items being modded
patch -Np1 -i "$srcdir"/0024-ammo-order-fix.patch
+ # Fix the t_door_metal_locked_o not allowing vehicles to pass
+ patch -Np1 -i "$srcdir"/0025-fix-open-metal-doors.patch
+
+ # Fix brioche bun missing a cooking time
+ patch -Np1 -i "$srcdir"/0026-fix-brioche-cooking-time.patch
+
# Various other fixes for bugs I came across that modify src
# Fix ammo loudness mulitplying by six instead of two
@@ -257,6 +259,9 @@ prepare() {
# Some personal quirks that simply lack a means short of patching the source
patch -Np1 -i "$srcdir"/custom.patch
+
+ # Expand the vampirism patchset to add an entirely new food category so vampires can only drink blood
+ patch -Np1 -i "$srcdir"/custom-2.patch
}
build() {
diff --git a/custom-2.patch b/custom-2.patch
new file mode 100644
index 0000000..08fa1c0
--- /dev/null
+++ b/custom-2.patch
@@ -0,0 +1,314 @@
+--- a/data/json/flags.json
++++ b/data/json/flags.json
+@@ -1173,6 +1173,16 @@
+ "context": [ ]
+ },
+ {
++ "id": "VAMPIRISM",
++ "type": "json_flag",
++ "context": [ ]
++ },
++ {
++ "id": "VAMPIRISM_OK",
++ "type": "json_flag",
++ "context": [ ]
++ },
++ {
+ "id": "CASING",
+ "type": "json_flag",
+ "context": [ ]
+
+--- a/data/json/morale_types.json
++++ b/data/json/morale_types.json
+@@ -125,6 +125,11 @@
+ "text": "Ate Human Flesh"
+ },
+ {
++ "id": "morale_vampire",
++ "type": "morale_type",
++ "text": "Drank Human Blood"
++ },
++ {
+ "id": "morale_vegetarian",
+ "type": "morale_type",
+ "text": "Ate Meat"
+
+--- a/src/activity_handlers.cpp
++++ b/src/activity_handlers.cpp
+@@ -220,6 +220,7 @@
+ static const species_id HUMAN( "HUMAN" );
+ static const species_id ZOMBIE( "ZOMBIE" );
+
++static const std::string trait_flag_VAMPIRE( "CANNIBAL" );
+ static const std::string trait_flag_CANNIBAL( "CANNIBAL" );
+ static const std::string trait_flag_PSYCHOPATH( "PSYCHOPATH" );
+ static const std::string trait_flag_SAPIOVORE( "SAPIOVORE" );
+@@ -259,6 +260,8 @@
+ static const std::string flag_SUPPORTS_ROOF( "SUPPORTS_ROOF" );
+ static const std::string flag_TREE( "TREE" );
+ static const std::string flag_USE_UPS( "USE_UPS" );
++static const std::string flag_VAMPIRISM( "VAMPIRE" );
++static const std::string flag_VAMPIRISM_OK( "VAMPIRISM_OK" );
+
+ using namespace activity_handlers;
+
+@@ -651,7 +654,8 @@
+ !corpse.in_species( ZOMBIE ) );
+ if( is_human && !( u.has_trait_flag( trait_flag_CANNIBAL ) ||
+ u.has_trait_flag( trait_flag_PSYCHOPATH ) ||
+- u.has_trait_flag( trait_flag_SAPIOVORE ) ) ) {
++ u.has_trait_flag( trait_flag_SAPIOVORE ) ||
++ u.has_trait_flag( trait_flag_VAMPIRE ) ) ) {
+ need_confirm( _( "Would you dare desecrate the mortal remains of a fellow human being?" ),
+ butcherable_rating::warn_cannibalism );
+ }
+
+
+--- a/src/character.h
++++ b/src/character.h
+@@ -163,6 +163,8 @@
+ allergy_weak,
+ // Cannibalism (unless psycho/cannibal)
+ cannibalism,
++ // Vampirism (unless psycho/cannibal)
++ vampirism,
+ // Rotten or not rotten enough (for saprophages)
+ rotten,
+ // Can provoke vomiting if you already feel nauseous.
+
+--- a/src/consumption.cpp
++++ b/src/consumption.cpp
+@@ -108,6 +108,7 @@
+ static const trait_id trait_THRESH_LUPINE( "THRESH_LUPINE" );
+ static const trait_id trait_THRESH_PLANT( "THRESH_PLANT" );
+ static const trait_id trait_THRESH_URSINE( "THRESH_URSINE" );
++static const trait_id trait_VAMP_HUNGER( "VAMP_HUNGER" );
+ static const trait_id trait_VEGETARIAN( "VEGETARIAN" );
+ static const trait_id trait_WATERSLEEP( "WATERSLEEP" );
+
+@@ -143,11 +144,17 @@
+ static const std::string flag_RAW( "RAW" );
+ static const std::string flag_URSINE_HONEY( "URSINE_HONEY" );
+ static const std::string flag_USE_EAT_VERB( "USE_EAT_VERB" );
++static const std::string flag_VAMPIRISM( "VAMPIRISM" );
++static const std::string flag_VAMPIRISM_OK( "VAMPIRISM_OK" );
+
+ const std::vector<std::string> carnivore_blacklist {{
+ flag_ALLERGEN_VEGGY, flag_ALLERGEN_FRUIT, flag_ALLERGEN_WHEAT, flag_ALLERGEN_NUT,
+ }
+ };
++const std::vector<std::string> vamp_blacklist {{
++ flag_ALLERGEN_VEGGY, flag_ALLERGEN_FRUIT, flag_ALLERGEN_WHEAT, flag_ALLERGEN_NUT, flag_ALLERGEN_MEAT, flag_ALLERGEN_EGG, flag_ALLERGEN_JUNK,
++ }
++};
+ // This ugly temp array is here because otherwise it goes
+ // std::vector(char*, char*)->vector(InputIterator,InputIterator) or some such
+ const std::array<std::string, 2> temparray {{flag_ALLERGEN_MEAT, flag_ALLERGEN_EGG}};
+@@ -719,6 +726,12 @@
+ _( "Eww. Inedible plant stuff!" ) );
+ }
+
++ if( has_trait( trait_VAMP_HUNGER ) && nutrition_for( food ) > 0 &&
++ food.has_any_flag( vamp_blacklist ) && !food.has_flag( flag_VAMPIRISM_OK ) ) {
++ return ret_val<edible_rating>::make_failure( edible_rating::inedible_mutation,
++ _( "Bleh. This isn't blood!" ) );
++ }
++
+ if( ( has_trait( trait_HERBIVORE ) || has_trait( trait_RUMINANT ) ) &&
+ food.has_any_flag( herbivore_blacklist ) ) {
+ // Like non-cannibal, but more strict!
+@@ -767,6 +780,12 @@
+ edible_rating::cannibalism );
+ }
+
++ if( food.has_flag( flag_VAMPIRISM ) && ( !has_trait_flag( "VAMPIRE" ) &&
++ !has_trait_flag( "CANNIBAL" ) ) ) {
++ add_consequence( _( "The thought of drinking human blood makes you feel sick." ),
++ edible_rating::vampirism );
++ }
++
+ const bool edible = comest->comesttype == comesttype_FOOD || food.has_flag( flag_USE_EAT_VERB );
+
+ int food_kcal = compute_effective_nutrients( food ).kcal;
+@@ -1116,6 +1136,25 @@
+ }
+ }
+
++ if( food.has_flag( flag_VAMPIRISM ) ) {
++ const bool cannibal = has_trait( trait_CANNIBAL );
++ const bool psycho = has_trait( trait_PSYCHOPATH );
++ const bool sapiovore = has_trait( trait_SAPIOVORE );
++ const bool vamp = has_trait( trait_VAMP_HUNGER );
++ if( cannibal ) {
++ add_msg_if_player( m_good, _( "You indulge your shameful hunger." ) );
++ add_morale( MORALE_CANNIBAL, 20, 200 );
++ } else if( vamp ) {
++ add_msg_if_player( m_good, _( "You relish drinking the human blood." ) );
++ add_morale( MORALE_VAMPIRE, 30, 300 );
++ } else if( psycho || sapiovore ) {
++ // Nothing - doesn't care enough to print a message
++ } else {
++ add_msg_if_player( m_bad, _( "You feel horrible for drinking the blood of a person." ) );
++ add_morale( MORALE_CANNIBAL, -60, -400, 60_minutes, 30_minutes );
++ }
++ }
++
+ // Allergy check for food that is ingested (not gum)
+ if( !food.has_flag( "NO_INGEST" ) ) {
+ const auto allergy = allergy_type( food );
+@@ -1123,6 +1162,11 @@
+ add_msg_if_player( m_bad, _( "Yuck! How can anybody eat this stuff?" ) );
+ add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
+ }
++ if( allergy != MORALE_NULL && has_trait( trait_VAMP_HUNGER ) ) {
++ add_msg_if_player( m_bad, _( "I can't stomach anything but blood!" ) );
++ add_morale( allergy, -75, -400, 30_minutes, 24_minutes );
++ vomit();
++ }
+ if( food.has_flag( flag_ALLERGEN_JUNK ) ) {
+ if( has_trait( trait_PROJUNK ) ) {
+ add_msg_if_player( m_good, _( "Mmm, junk food." ) );
+
+--- a/src/game.cpp
++++ b/src/game.cpp
+@@ -1008,8 +1008,9 @@
+ int iInfoLine = 0;
+
+ if( u.has_amount( "holybook_bible1", 1 ) || u.has_amount( "holybook_bible2", 1 ) ||
+- u.has_amount( "holybook_bible3", 1 ) ) {
+- if( !( u.has_trait( trait_id( "CANNIBAL" ) ) || u.has_trait( trait_id( "PSYCHOPATH" ) ) ) ) {
++ u.has_amount( "holybook_bible3", 1 ) || u.has_trait( trait_id( "THRESH_VAMP" ) ) ) {
++ if( !( u.has_trait( trait_id( "CANNIBAL" ) ) || u.has_trait( trait_id( "PSYCHOPATH" ) ) ||
++ u.has_trait( trait_id( "THRESH_VAMP" ) ) ) ) {
+ vRip.emplace_back( " _______ ___" );
+ vRip.emplace_back( " < `/ |" );
+ vRip.emplace_back( " > _ _ (" );
+
+--- a/src/item.cpp
++++ b/src/item.cpp
+@@ -3947,6 +3947,7 @@
+ case edible_rating::allergy:
+ case edible_rating::allergy_weak:
+ case edible_rating::cannibalism:
++ case edible_rating::vampirism:
+ ret = c_red;
+ break;
+ case edible_rating::rotten:
+
+--- a/src/item_factory.cpp
++++ b/src/item_factory.cpp
+@@ -2220,6 +2220,7 @@
+ // First allergens:
+ // An item is an allergen even if it has trace amounts of allergenic material
+ std::make_pair( material_id( "hflesh" ), "CANNIBALISM" ),
++ std::make_pair( material_id( "blood" ), "VAMPIRISM" ),
+
+ std::make_pair( material_id( "hflesh" ), "ALLERGEN_MEAT" ),
+ std::make_pair( material_id( "iflesh" ), "ALLERGEN_MEAT" ),
+@@ -2238,6 +2239,8 @@
+ // Not food, but we can keep it here
+ std::make_pair( material_id( "wool" ), "ALLERGEN_WOOL" ),
+ // Now "made of". Those flags should not be passed
++ std::make_pair( material_id( "blood" ), "VAMPIRISM_OK" ),
++ std::make_pair( material_id( "blood" ), "CARNIVORE_OK" ),
+ std::make_pair( material_id( "flesh" ), "CARNIVORE_OK" ),
+ std::make_pair( material_id( "hflesh" ), "CARNIVORE_OK" ),
+ std::make_pair( material_id( "iflesh" ), "CARNIVORE_OK" ),
+
+--- a/src/iteminfo_query.h
++++ b/src/iteminfo_query.h
+@@ -36,6 +36,7 @@
+ FOOD_VITAMINS,
+ FOOD_VIT_EFFECTS,
+ FOOD_CANNIBALISM,
++ FOOD_VAMPIRISM,
+ FOOD_TAINT,
+ FOOD_POISON,
+ FOOD_HALLUCINOGENIC,
+
+--- a/src/memorial_logger.cpp
++++ b/src/memorial_logger.cpp
+@@ -80,6 +80,7 @@
+ static const trap_str_id tr_snake( "tr_snake" );
+ static const trap_str_id tr_glass_pit( "tr_glass_pit" );
+
++static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
+ static const trait_id trait_CANNIBAL( "CANNIBAL" );
+ static const trait_id trait_PSYCHOPATH( "PSYCHOPATH" );
+ static const trait_id trait_SAPIOVORE( "SAPIOVORE" );
+@@ -486,6 +487,7 @@
+ character_id ch = e.get<character_id>( "killer" );
+ if( ch == g->u.getID() ) {
+ std::string name = e.get<cata_variant_type::string>( "victim_name" );
++ bool vampire = g->u.has_trait( trait_THRESH_VAMP );
+ bool cannibal = g->u.has_trait( trait_CANNIBAL );
+ bool psycho = g->u.has_trait( trait_PSYCHOPATH );
+ if( g->u.has_trait( trait_SAPIOVORE ) ) {
+@@ -509,6 +511,10 @@
+ add( pgettext( "memorial_male", "Killed an innocent, %s." ),
+ pgettext( "memorial_female", "Killed an innocent, %s." ),
+ name );
++ } else if( vampire ) {
++ add( pgettext( "memorial_male", "Killed an innocent human, %s." ),
++ pgettext( "memorial_female", "Killed an innocent human, %s." ),
++ name );
+ } else {
+ add( pgettext( "memorial_male",
+ "Killed an innocent person, %s, in cold blood and "
+
+--- a/src/morale_types.cpp
++++ b/src/morale_types.cpp
+@@ -40,6 +40,7 @@
+
+ morale_type( "morale_food_bad" ),
+ morale_type( "morale_cannibal" ),
++ morale_type( "morale_vampire" ),
+ morale_type( "morale_vegetarian" ),
+ morale_type( "morale_meatarian" ),
+ morale_type( "morale_antifruit" ),
+@@ -138,6 +139,7 @@
+ const morale_type MORALE_CRAVING_MARLOSS( "morale_craving_marloss" );
+ const morale_type MORALE_FOOD_BAD( "morale_food_bad" );
+ const morale_type MORALE_CANNIBAL( "morale_cannibal" );
++const morale_type MORALE_VAMPIRE( "morale_vampire" );
+ const morale_type MORALE_VEGETARIAN( "morale_vegetarian" );
+ const morale_type MORALE_MEATARIAN( "morale_meatarian" );
+ const morale_type MORALE_ANTIFRUIT( "morale_antifruit" );
+
+--- a/src/npc.cpp
++++ b/src/npc.cpp
+@@ -116,6 +116,7 @@
+ static const trait_id trait_SAPIOVORE( "SAPIOVORE" );
+ static const trait_id trait_SCHIZOPHRENIC( "SCHIZOPHRENIC" );
+ static const trait_id trait_TERRIFYING( "TERRIFYING" );
++static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" );
+
+ static const std::string flag_NPC_SAFE( "NPC_SAFE" );
+
+@@ -2486,12 +2487,15 @@
+ }
+
+ if( killer == &g->u && ( !guaranteed_hostile() || hit_by_player ) ) {
++ bool vampire = g->u.has_trait( trait_THRESH_VAMP );
+ bool cannibal = g->u.has_trait( trait_CANNIBAL );
+ bool psycho = g->u.has_trait( trait_PSYCHOPATH );
+ if( g->u.has_trait( trait_SAPIOVORE ) || psycho ) {
+ // No morale effect
+ } else if( cannibal ) {
+ g->u.add_morale( MORALE_KILLED_INNOCENT, -5, 0, 2_days, 3_hours );
++ } else if( vampire ) {
++ g->u.add_morale( MORALE_KILLED_INNOCENT, -5, 0, 2_days, 3_hours );
+ } else {
+ g->u.add_morale( MORALE_KILLED_INNOCENT, -100, 0, 2_days, 3_hours );
+ }
+
+--- a/src/morale_types.h
++++ b/src/morale_types.h
+@@ -62,6 +62,7 @@
+ extern const morale_type MORALE_CRAVING_MARLOSS;
+ extern const morale_type MORALE_FOOD_BAD;
+ extern const morale_type MORALE_CANNIBAL;
++extern const morale_type MORALE_VAMPIRE;
+ extern const morale_type MORALE_VEGETARIAN;
+ extern const morale_type MORALE_MEATARIAN;
+ extern const morale_type MORALE_ANTIFRUIT;