From fdf0605b2ebea447c0277fe2c171e70bd93ddfac Mon Sep 17 00:00:00 2001 From: jc_gargma Date: Sun, 5 Sep 2021 22:00:26 -0700 Subject: Merge custom and custom 2 patches --- custom-2.patch | 331 -------------------------------------------- custom.patch | 422 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 379 insertions(+), 374 deletions(-) delete mode 100644 custom-2.patch diff --git a/custom-2.patch b/custom-2.patch deleted file mode 100644 index a54377b..0000000 --- a/custom-2.patch +++ /dev/null @@ -1,331 +0,0 @@ ---- a/data/json/flags.json -+++ b/data/json/flags.json -@@ -1093,6 +1093,11 @@ - "context": [ "COMESTIBLE" ] - }, - { -+ "id": "ALLERGEN_HONEY", -+ "type": "json_flag", -+ "context": [ "COMESTIBLE" ] -+ }, -+ { - "id": "ALLERGEN_JUNK", - "type": "json_flag", - "context": [ "COMESTIBLE" ] -@@ -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" ); - -@@ -114,6 +114,7 @@ - static const std::string flag_HIDDEN_HALLU( "HIDDEN_HALLU" ); - static const std::string flag_ALLERGEN_EGG( "ALLERGEN_EGG" ); - static const std::string flag_ALLERGEN_FRUIT( "ALLERGEN_FRUIT" ); -+static const std::string flag_ALLERGEN_HONEY( "ALLERGEN_HONEY" ); - static const std::string flag_ALLERGEN_JUNK( "ALLERGEN_JUNK" ); - static const std::string flag_ALLERGEN_MEAT( "ALLERGEN_MEAT" ); - static const std::string flag_ALLERGEN_MILK( "ALLERGEN_MILK" ); -@@ -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 carnivore_blacklist {{ - flag_ALLERGEN_VEGGY, flag_ALLERGEN_FRUIT, flag_ALLERGEN_WHEAT, flag_ALLERGEN_NUT, - } - }; -+const std::vector vamp_blacklist {{ -+ flag_ALLERGEN_VEGGY, flag_ALLERGEN_FRUIT, flag_ALLERGEN_WHEAT, flag_ALLERGEN_NUT, flag_ALLERGEN_MEAT, flag_ALLERGEN_EGG, flag_ALLERGEN_JUNK, flag_ALLERGEN_MILK, flag_ALLERGEN_HONEY, -+ } -+}; - // This ugly temp array is here because otherwise it goes - // std::vector(char*, char*)->vector(InputIterator,InputIterator) or some such - const std::array 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::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 +1135,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 +1161,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 -@@ -2219,6 +2219,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" ), -@@ -2233,10 +2234,13 @@ - std::make_pair( material_id( "mushroom" ), "ALLERGEN_VEGGY" ), - std::make_pair( material_id( "milk" ), "ALLERGEN_MILK" ), - std::make_pair( material_id( "egg" ), "ALLERGEN_EGG" ), -+ std::make_pair( material_id( "honey" ), "ALLERGEN_HONEY" ), - std::make_pair( material_id( "junk" ), "ALLERGEN_JUNK" ), - // 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( "killer" ); - if( ch == g->u.getID() ) { - std::string name = e.get( "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 -@@ -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; diff --git a/custom.patch b/custom.patch index 25cc30d..6046066 100644 --- a/custom.patch +++ b/custom.patch @@ -1,3 +1,33 @@ +--- 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.cpp +++ b/src/character.cpp @@ -288,9 +288,11 @@ @@ -39,6 +69,181 @@ temp_conv.fill( BODYTEMP_NORM ); return; +--- 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" ); + +@@ -114,6 +114,7 @@ + static const std::string flag_HIDDEN_HALLU( "HIDDEN_HALLU" ); + static const std::string flag_ALLERGEN_EGG( "ALLERGEN_EGG" ); + static const std::string flag_ALLERGEN_FRUIT( "ALLERGEN_FRUIT" ); ++static const std::string flag_ALLERGEN_HONEY( "ALLERGEN_HONEY" ); + static const std::string flag_ALLERGEN_JUNK( "ALLERGEN_JUNK" ); + static const std::string flag_ALLERGEN_MEAT( "ALLERGEN_MEAT" ); + static const std::string flag_ALLERGEN_MILK( "ALLERGEN_MILK" ); +@@ -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 carnivore_blacklist {{ + flag_ALLERGEN_VEGGY, flag_ALLERGEN_FRUIT, flag_ALLERGEN_WHEAT, flag_ALLERGEN_NUT, + } + }; ++const std::vector vamp_blacklist {{ ++ flag_ALLERGEN_VEGGY, flag_ALLERGEN_FRUIT, flag_ALLERGEN_WHEAT, flag_ALLERGEN_NUT, flag_ALLERGEN_MEAT, flag_ALLERGEN_EGG, flag_ALLERGEN_JUNK, flag_ALLERGEN_MILK, flag_ALLERGEN_HONEY, ++ } ++}; + // This ugly temp array is here because otherwise it goes + // std::vector(char*, char*)->vector(InputIterator,InputIterator) or some such + const std::array 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::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 +1135,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 +1161,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 +@@ -2219,6 +2219,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" ), +@@ -2233,10 +2234,13 @@ + std::make_pair( material_id( "mushroom" ), "ALLERGEN_VEGGY" ), + std::make_pair( material_id( "milk" ), "ALLERGEN_MILK" ), + std::make_pair( material_id( "egg" ), "ALLERGEN_EGG" ), ++ std::make_pair( material_id( "honey" ), "ALLERGEN_HONEY" ), + std::make_pair( material_id( "junk" ), "ALLERGEN_JUNK" ), + // 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/map_field.cpp +++ b/src/map_field.cpp @@ -88,6 +88,7 @@ @@ -71,50 +276,37 @@ const int intensity = cur.get_field_intensity(); bool inhaled = u.add_env_effect( effect_poison, bp_mouth, 5, intensity * 1_minutes ); if( u.has_trait( trait_THRESH_MYCUS ) || u.has_trait( trait_THRESH_MARLOSS ) || ---- a/src/suffer.cpp -+++ b/src/suffer.cpp -@@ -143,10 +143,13 @@ - static const trait_id trait_SHOUT3( "SHOUT3" ); - static const trait_id trait_SORES( "SORES" ); - static const trait_id trait_SUNBURN( "SUNBURN" ); -+static const trait_id trait_THRESH_GYNOID( "THRESH_GYNOID" ); -+static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" ); - static const trait_id trait_TROGLO( "TROGLO" ); - static const trait_id trait_TROGLO2( "TROGLO2" ); - static const trait_id trait_TROGLO3( "TROGLO3" ); - static const trait_id trait_UNSTABLE( "UNSTABLE" ); -+static const trait_id trait_VAMP_CURSE( "VAMP_CURSE" ); - static const trait_id trait_VOMITOUS( "VOMITOUS" ); - static const trait_id trait_WEB_SPINNER( "WEB_SPINNER" ); - static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" ); -@@ -243,7 +246,8 @@ - - void Character::suffer_while_underwater() - { -- if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) ) { -+ if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) && -+ !has_trait( trait_THRESH_GYNOID ) && !has_trait( trait_THRESH_VAMP ) ) { - oxygen--; - } - if( oxygen < 12 && worn_with_flag( "REBREATHER" ) ) { -@@ -759,6 +763,17 @@ - } - } + +--- 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" ); -+ if( has_trait( trait_VAMP_CURSE ) && one_in( 10 ) ) { -+ if( !( weapon.has_flag( "RAIN_PROTECT" ) ) ) { -+ add_msg_if_player( m_bad, _( "The sunlight sears your skin!" ) ); -+ if( has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) { -+ wake_up(); -+ } -+ mod_pain( 5 ); -+ hurtall( 5, nullptr ); -+ } -+ } -+ - if( ( has_trait( trait_TROGLO ) || has_trait( trait_TROGLO2 ) ) && - g->weather.weather == WEATHER_SUNNY ) { - mod_str_bonus( -1 ); ++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( "killer" ); + if( ch == g->u.getID() ) { + std::string name = e.get( "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/monattack.cpp +++ b/src/monattack.cpp @@ -143,6 +143,7 @@ @@ -135,6 +327,56 @@ if( hit ) { //Add checks if previous NPC/player conditions are removed dynamic_cast( target )->mutate(); + +--- a/src/morale_types.cpp ++++ b/src/morale_types.cpp +@@ -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/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; + +--- 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/player_hardcoded_effects.cpp +++ b/src/player_hardcoded_effects.cpp @@ -114,7 +114,9 @@ @@ -159,6 +401,52 @@ strength = 4; // Post-human. } else if( highest >= 20 && highest < 35 ) { strength = 1; // Low strength + +--- a/src/suffer.cpp ++++ b/src/suffer.cpp +@@ -143,10 +143,13 @@ + static const trait_id trait_SHOUT3( "SHOUT3" ); + static const trait_id trait_SORES( "SORES" ); + static const trait_id trait_SUNBURN( "SUNBURN" ); ++static const trait_id trait_THRESH_GYNOID( "THRESH_GYNOID" ); ++static const trait_id trait_THRESH_VAMP( "THRESH_VAMP" ); + static const trait_id trait_TROGLO( "TROGLO" ); + static const trait_id trait_TROGLO2( "TROGLO2" ); + static const trait_id trait_TROGLO3( "TROGLO3" ); + static const trait_id trait_UNSTABLE( "UNSTABLE" ); ++static const trait_id trait_VAMP_CURSE( "VAMP_CURSE" ); + static const trait_id trait_VOMITOUS( "VOMITOUS" ); + static const trait_id trait_WEB_SPINNER( "WEB_SPINNER" ); + static const trait_id trait_WEB_WEAVER( "WEB_WEAVER" ); +@@ -243,7 +246,8 @@ + + void Character::suffer_while_underwater() + { +- if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) ) { ++ if( !has_trait( trait_GILLS ) && !has_trait( trait_GILLS_CEPH ) && ++ !has_trait( trait_THRESH_GYNOID ) && !has_trait( trait_THRESH_VAMP ) ) { + oxygen--; + } + if( oxygen < 12 && worn_with_flag( "REBREATHER" ) ) { +@@ -759,6 +763,17 @@ + } + } + ++ if( has_trait( trait_VAMP_CURSE ) && one_in( 10 ) ) { ++ if( !( weapon.has_flag( "RAIN_PROTECT" ) ) ) { ++ add_msg_if_player( m_bad, _( "The sunlight sears your skin!" ) ); ++ if( has_effect( effect_sleep ) && !has_effect( effect_narcosis ) ) { ++ wake_up(); ++ } ++ mod_pain( 5 ); ++ hurtall( 5, nullptr ); ++ } ++ } ++ + if( ( has_trait( trait_TROGLO ) || has_trait( trait_TROGLO2 ) ) && + g->weather.weather == WEATHER_SUNNY ) { + mod_str_bonus( -1 ); + --- a/data/json/field_type.json +++ b/data/json/field_type.json @@ -303,7 +303,7 @@ @@ -242,6 +530,54 @@ "priority": 8, "half_life": "30 minutes", "phase": "gas", + +--- a/data/json/flags.json ++++ b/data/json/flags.json +@@ -1093,6 +1093,11 @@ + "context": [ "COMESTIBLE" ] + }, + { ++ "id": "ALLERGEN_HONEY", ++ "type": "json_flag", ++ "context": [ "COMESTIBLE" ] ++ }, ++ { + "id": "ALLERGEN_JUNK", + "type": "json_flag", + "context": [ "COMESTIBLE" ] +@@ -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/data/json/mutations/mutation_ordering.json +++ b/data/json/mutations/mutation_ordering.json @@ -73,6 +73,7 @@ -- cgit v1.2.1