diff options
Diffstat (limited to 'stone_soup/crawl-ref/source/food.cc')
-rw-r--r-- | stone_soup/crawl-ref/source/food.cc | 1379 |
1 files changed, 0 insertions, 1379 deletions
diff --git a/stone_soup/crawl-ref/source/food.cc b/stone_soup/crawl-ref/source/food.cc deleted file mode 100644 index eee0cd6a78..0000000000 --- a/stone_soup/crawl-ref/source/food.cc +++ /dev/null @@ -1,1379 +0,0 @@ -/* - * File: food.cc - * Summary: Functions for eating and butchering. - * Written by: Linley Henzell - * - * Change History (most recent first): - * - * <2> 5/20/99 BWR Added CRAWL_PIZZA. - * <1> -/--/-- LRH Created - */ - -#include "AppHdr.h" -#include "food.h" - -#include <string.h> -// required for abs() {dlb}: -#include <stdlib.h> -#include <stdio.h> -#include <ctype.h> - -#ifdef DOS -#include <conio.h> -#endif - -#include "externs.h" - -#include "clua.h" -#include "debug.h" -#include "delay.h" -#include "invent.h" -#include "items.h" -#include "itemname.h" -#include "itemprop.h" -#include "item_use.h" -#include "it_use2.h" -#include "macro.h" -#include "misc.h" -#include "mon-util.h" -#include "mutation.h" -#include "player.h" -#include "religion.h" -#include "skills2.h" -#include "spells2.h" -#include "stuff.h" -#include "wpn-misc.h" - -static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk); -static void eat_chunk( int chunk_effect ); -static void eating(unsigned char item_class, int item_type); -static void ghoul_eat_flesh( int chunk_effect ); -static void describe_food_change(int hunger_increment); -static bool food_change(bool suppress_message); - -/* - ************************************************** - * * - * BEGIN PUBLIC FUNCTIONS * - * * - ************************************************** -*/ - -void make_hungry( int hunger_amount, bool suppress_msg ) -{ - if (you.is_undead == US_UNDEAD) - return; - -#if DEBUG_DIAGNOSTICS - set_redraw_status( REDRAW_HUNGER ); -#endif - - you.hunger -= hunger_amount; - - if (you.hunger < 0) - you.hunger = 0; - - // so we don't get two messages, ever. - bool state_message = food_change(false); - - if (!suppress_msg && !state_message) - describe_food_change( -hunger_amount ); -} // end make_hungry() - -void lessen_hunger( int satiated_amount, bool suppress_msg ) -{ - if (you.is_undead == US_UNDEAD) - return; - - you.hunger += satiated_amount; - - if (you.hunger > 12000) - you.hunger = 12000; - - // so we don't get two messages, ever - bool state_message = food_change(false); - - if (!suppress_msg && !state_message) - describe_food_change(satiated_amount); -} // end lessen_hunger() - -void set_hunger( int new_hunger_level, bool suppress_msg ) -{ - if (you.is_undead == US_UNDEAD) - return; - - int hunger_difference = (new_hunger_level - you.hunger); - - if (hunger_difference < 0) - make_hungry( abs(hunger_difference), suppress_msg ); - else if (hunger_difference > 0) - lessen_hunger( hunger_difference, suppress_msg ); -} // end set_hunger() - -// more of a "weapon_switch back from butchering" function, switching -// to a weapon is done using the wield_weapon code. -// special cases like staves of power or other special weps are taken -// care of by calling wield_effects() {gdl} - -void weapon_switch( int targ ) -{ - if (targ == -1) - { - mpr( "You switch back to your bare hands." ); - } - else - { - char buff[80]; - in_name( targ, DESC_NOCAP_A, buff ); - - char let = index_to_letter( targ ); - - snprintf( info, INFO_SIZE, "Switching back to %c - %s.", let, buff ); - mpr( info ); - } - - // unwield the old weapon and wield the new. - // XXX This is a pretty dangerous hack; I don't like it.--GDL - // - // Well yeah, but that's because interacting with the wielding - // code is a mess... this whole function's purpose was to - // isolate this hack until there's a proper way to do things. -- bwr - if (you.equip[EQ_WEAPON] != -1) - unwield_item(you.equip[EQ_WEAPON]); - - you.equip[EQ_WEAPON] = targ; - - // special checks: staves of power, etc - if (targ != -1) - wield_effects( targ, false ); -} - -bool butchery(void) -{ - char str_pass[ ITEMNAME_SIZE ]; - int items_here = 0; - int o = igrd[you.x_pos][you.y_pos]; - int k = 0; - int item_got; - unsigned char keyin; - - bool can_butcher = false; - bool wpn_switch = false; - bool new_cursed = false; - int old_weapon = you.equip[EQ_WEAPON]; - - bool barehand_butcher = (you.equip[ EQ_GLOVES ] == -1) - && (you.species == SP_TROLL - || you.species == SP_GHOUL - || you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS - || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON - || you.mutation[MUT_CLAWS]); - - - if (igrd[you.x_pos][you.y_pos] == NON_ITEM) - { - mpr("There isn't anything here!"); - return (false); - } - - if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT)) - { - mpr("You can't reach the floor from up here."); - return (false); - } - - if (barehand_butcher) - can_butcher = true; - else - { - if (you.equip[EQ_WEAPON] != -1) - { - can_butcher = can_cut_meat( you.inv[you.equip[EQ_WEAPON]].base_type, - you.inv[you.equip[EQ_WEAPON]].sub_type ); - } - - // Should probably check for cursed-weapons, bare hands and - // non-weapons in hand here, but wield_weapon will be used for - // this swap and it will do all that (although the player might - // be annoyed with the excess prompt). - if (Options.easy_butcher && !can_butcher) - { - //mv: check for berserk first - if (you.berserker) - { - mpr ("You are too berserk to search for a butchering knife!"); - return (false); - } - - // We'll now proceed to look through the entire inventory for - // choppers/slicers. We'll skip special weapons because - // wielding/unwielding a foo of distortion would be disastrous. - for (int i = 0; i < ENDOFPACK; ++i) - { - if (is_valid_item( you.inv[i] ) - && can_cut_meat( you.inv[i].base_type, - you.inv[i].sub_type ) - && you.inv[i].base_type == OBJ_WEAPONS - && item_known_uncursed(you.inv[i]) - && item_ident( you.inv[i], ISFLAG_KNOW_TYPE ) - && get_weapon_brand(you.inv[i]) - != SPWPN_DISTORTION - && can_wield( you.inv[i] )) - { - mpr("Switching to a butchering implement."); - wpn_switch = true; - wield_weapon( true, i, false ); - break; - } - } - - // if we didn't swap above, then we still can't cut... let's - // call wield_weapon() in the "prompt the user" way... - if (!wpn_switch) - { - // prompt for new weapon - mpr( "What would you like to use?", MSGCH_PROMPT ); - wield_weapon( false ); - - // let's see if the user did something... - if (you.equip[EQ_WEAPON] != old_weapon) - wpn_switch = true; - } - } - - // weapon might have changed (to bare hands as well), we'll - // update the can_butcher status accordingly (note: if we could - // butcher with our bare hands we wouldn't be here) -- bwr - if (wpn_switch && you.equip[EQ_WEAPON] != -1) - { - can_butcher = can_cut_meat( you.inv[you.equip[EQ_WEAPON]].base_type, - you.inv[you.equip[EQ_WEAPON]].sub_type ); - } - } - - // Account for the weapon switch above if it happened... we're - // doing this here since the above switch may reveal information - // about the weapon (curse status, ego type). So even if the - // character fails to or decides not to butcher past this point, - // they have achieved something and there should be a cost. - if (wpn_switch) - start_delay( DELAY_UNINTERUPTABLE, 1, old_weapon ); - - // check to see if the new implement is cursed - if so, set a - // flag indicating this. If a player actually butchers anything, - // this flag can be checked before switching back. - int wpn = you.equip[EQ_WEAPON]; - - if (wpn != -1 - && you.inv[wpn].base_type == OBJ_WEAPONS - && item_cursed( you.inv[wpn] )) - { - new_cursed = true; - } - - // Final checks and clue-giving... - if (!barehand_butcher && you.equip[EQ_WEAPON] == -1) - { - if (you.equip[ EQ_GLOVES ] == -1) - mpr("What, with your bare hands?"); - else - mpr("You can't use your claws with your gloves on!"); - - // Switching back to avoid possible bug where player can use - // this to switch weapons in zero time. - if (wpn_switch) - weapon_switch( old_weapon ); - - return (false); - } - else if (!can_butcher) - { - mpr("Maybe you should try using a sharper implement."); - - // Switching back to avoid possible bug where player can use - // this to switch weapons in zero time. - if (wpn_switch && !new_cursed) - weapon_switch( old_weapon ); - - return (false); - } - - // No turning back at this point, we better be qualified. - ASSERT( can_butcher ); - - int last_item = NON_ITEM; - - int objl = igrd[you.x_pos][you.y_pos]; - int hrg = 0; - int counter = 0; - - while (objl != NON_ITEM) - { - counter++; - - last_item = objl; - - hrg = mitm[objl].link; - objl = hrg; - items_here++; - - if (counter > 1000) - { - error_message_to_player(); - - if (wpn_switch && !new_cursed) - weapon_switch( old_weapon ); - - return (false); - } - } - - if (items_here == 1 - && (mitm[igrd[you.x_pos][you.y_pos]].base_type == OBJ_CORPSES && - mitm[igrd[you.x_pos][you.y_pos]].sub_type == CORPSE_BODY)) - { - strcpy(info, "Butcher "); - it_name(igrd[you.x_pos][you.y_pos], DESC_NOCAP_A, str_pass); - strcat(info, str_pass); - strcat(info, "\?"); - mpr(info, MSGCH_PROMPT); - - unsigned char keyin = getch(); - - if (keyin == 0) - { - getch(); - keyin = 0; - } - - if (keyin != 'y' && keyin != 'Y') - { - if (wpn_switch && !new_cursed) - weapon_switch( old_weapon ); - - return (false); - } - - int item_got = igrd[you.x_pos][you.y_pos]; - - last_item = NON_ITEM; - - if (barehand_butcher) - mpr("You start tearing the corpse apart."); - else - mpr("You start hacking away."); - - if (you.duration[DUR_PRAYER] - && (you.religion == GOD_OKAWARU - || you.religion == GOD_MAKHLEB || you.religion == GOD_TROG)) - { - offer_corpse(item_got); - destroy_item(item_got); - // XXX: need an extra turn here for weapon swapping? - } - else - { - int work_req = 3 - mitm[item_got].plus2; - if (work_req < 0) - work_req = 0; - - start_delay( DELAY_BUTCHER, work_req, item_got ); - } - - // cue up switching weapon back - if (wpn_switch && !new_cursed) - start_delay( DELAY_WEAPON_SWAP, 1, old_weapon ); - - you.turn_is_over = 1; - - return (true); - - } // end "if items_here == 1" - else if (items_here > 1) - { - last_item = NON_ITEM; - o = igrd[you.x_pos][you.y_pos]; - - for (k = 0; k < items_here; k++) - { - if (mitm[o].base_type != OBJ_CORPSES - || mitm[o].sub_type != CORPSE_BODY) - { - goto out_of_eating; - } - - strcpy(info, "Butcher "); - it_name(o, DESC_NOCAP_A, str_pass); - strcat(info, str_pass); - strcat(info, "\?"); - mpr(info, MSGCH_PROMPT); - - keyin = getch(); - if (keyin == 0) - { - getch(); - keyin = 0; - } - - if (keyin == 'q') - { - if (wpn_switch && !new_cursed) - weapon_switch( old_weapon ); - - return (false); - } - - if (keyin == 'y') - { - item_got = o; - - if (barehand_butcher) - mpr("You start tearing the corpse apart."); - else - mpr("You start hacking away."); - - if (you.duration[DUR_PRAYER] - && (you.religion == GOD_OKAWARU - || you.religion == GOD_MAKHLEB - || you.religion == GOD_TROG)) - { - offer_corpse(item_got); - destroy_item(item_got); - // XXX: need an extra turn here for weapon swapping? - } - else - { - int work_req = 3 - mitm[item_got].plus2; - if (work_req < 0) - work_req = 0; - - start_delay( DELAY_BUTCHER, work_req, item_got ); - } - - if (wpn_switch && !new_cursed) - { - // weapon_switch( old_weapon ); - // need to count the swap delay in this case - start_delay( DELAY_WEAPON_SWAP, 1, old_weapon ); - } - - you.turn_is_over = 1; - return (true); - } - - out_of_eating: - - if (is_valid_item( mitm[o] )) - last_item = o; - - hrg = mitm[o].link; - o = hrg; - - if (o == NON_ITEM) - break; - - if (items_here == 0) - break; - } // end "for k" loop - } - - mpr("There isn't anything to dissect here."); - - if (wpn_switch && !new_cursed) - weapon_switch( old_weapon ); - - return (false); -} // end butchery() - -#ifdef CLUA_BINDINGS -void lua_push_items(lua_State *ls, int link) -{ - lua_newtable(ls); - int index = 0; - for ( ; link != NON_ITEM; link = mitm[link].link) - { - lua_pushlightuserdata(ls, &mitm[link]); - lua_rawseti(ls, -2, ++index); - } -} - -void lua_push_floor_items(lua_State *ls) -{ - lua_push_items(ls, igrd[you.x_pos][you.y_pos]); -} - -void lua_push_inv_items(lua_State *ls = NULL) -{ - if (!ls) - ls = clua.state(); - lua_newtable(ls); - int index = 0; - for (unsigned slot = 0; slot < ENDOFPACK; ++slot) - { - if (is_valid_item(you.inv[slot])) - { - lua_pushlightuserdata(ls, &you.inv[slot]); - lua_rawseti(ls, -2, ++index); - } - } -} -#endif - -static bool userdef_eat_food() -{ -#ifdef CLUA_BINDINGS - lua_push_floor_items(clua.state()); - lua_push_inv_items(); - bool ret = clua.callfn("c_eat", 2, 0); - if (!ret && clua.error.length()) - mpr(clua.error.c_str()); - return ret; -#else - return false; -#endif -} - -bool prompt_eat_from_inventory(void) -{ - if (inv_count() < 1) - { - canned_msg(MSG_NOTHING_CARRIED); - return (false); - } - - int which_inventory_slot = - prompt_invent_item( "Eat which item?", OBJ_FOOD ); - if (which_inventory_slot == PROMPT_ABORT) - { - canned_msg( MSG_OK ); - return (false); - } - - // this conditional can later be merged into food::can_ingest() when - // expanded to handle more than just OBJ_FOOD 16mar200 {dlb} - if (you.inv[which_inventory_slot].base_type != OBJ_FOOD) - { - mpr("You can't eat that!"); - return (false); - } - - if (!can_ingest( you.inv[which_inventory_slot].base_type, - you.inv[which_inventory_slot].sub_type, false )) - { - return (false); - } - - eat_from_inventory(which_inventory_slot); - - burden_change(); - you.turn_is_over = 1; - - return (true); -} - -// [ds] Returns true if something was eaten -bool eat_food(bool run_hook) -{ - if (you.is_undead == US_UNDEAD) - { - mpr("You can't eat."); - return (false); - } - - if (you.hunger >= 11000) - { - mpr("You're too full to eat anything."); - return (false); - } - - // If user hook ran, we don't know whether something - // was eaten or not... - if (run_hook && userdef_eat_food()) - return (false); - - if (igrd[you.x_pos][you.y_pos] != NON_ITEM) - { - if (eat_from_floor()) - { - burden_change(); // ghouls regain strength from rotten food - return (true); - } - } - - return (prompt_eat_from_inventory()); -} // end eat_food() - -/* - ************************************************** - * * - * END PUBLIC FUNCTIONS * - * * - ************************************************** -*/ - -static bool food_change(bool suppress_message) -{ - char newstate = HS_ENGORGED; - bool state_changed = false; - - // this case shouldn't actually happen: - if (you.is_undead == US_UNDEAD) - you.hunger = 6000; - - // take care of ghouls - they can never be 'full' - if (you.species == SP_GHOUL && you.hunger > 6999) - you.hunger = 6999; - - // get new hunger state - if (you.hunger <= 1000) - newstate = HS_STARVING; - else if (you.hunger <= 2600) - newstate = HS_HUNGRY; - else if (you.hunger < 7000) - newstate = HS_SATIATED; - else if (you.hunger < 11000) - newstate = HS_FULL; - - if (newstate != you.hunger_state) - { - state_changed = true; - you.hunger_state = newstate; - set_redraw_status( REDRAW_HUNGER ); - - // Stop the travel command, if it's in progress and we just got hungry - if (newstate < HS_SATIATED) - interrupt_activity( AI_HUNGRY ); - - if (suppress_message == false) - { - switch (you.hunger_state) - { - case HS_STARVING: - mpr("You are starving!", MSGCH_FOOD); - break; - case HS_HUNGRY: - mpr("You are feeling hungry.", MSGCH_FOOD); - break; - default: - break; - } - } - } - - return (state_changed); -} // end food_change() - - -// food_increment is positive for eating, negative for hungering -static void describe_food_change(int food_increment) -{ - int magnitude = (food_increment > 0)?food_increment:(-food_increment); - - if (magnitude == 0) - return; - - strcpy(info, (magnitude <= 100) ? "You feel slightly " : - (magnitude <= 350) ? "You feel somewhat " : - (magnitude <= 800) ? "You feel a quite a bit " - : "You feel a lot "); - - if ((you.hunger_state > HS_SATIATED) ^ (food_increment < 0)) - strcat(info, "more "); - else - strcat(info, "less "); - - strcat(info, (you.hunger_state > HS_SATIATED) ? "full." - : "hungry."); - mpr(info); -} // end describe_food_change() - -void eat_from_inventory(int which_inventory_slot) -{ - if (you.inv[which_inventory_slot].sub_type == FOOD_CHUNK) - { - // this is a bit easier to read... most compilers should - // handle this the same -- bwr - const int mons_type = you.inv[ which_inventory_slot ].plus; - const int chunk_type = mons_corpse_effect( mons_type ); - const bool rotten = (you.inv[which_inventory_slot].special < 100); - - eat_chunk( determine_chunk_effect( chunk_type, rotten ) ); - } - else - { - eating( you.inv[which_inventory_slot].base_type, - you.inv[which_inventory_slot].sub_type ); - } - - dec_inv_item_quantity( which_inventory_slot, 1 ); -} // end eat_from_inventory() - -void eat_floor_item(int item_link) -{ - if (mitm[item_link].sub_type == FOOD_CHUNK) - { - const int chunk_type = mons_corpse_effect( mitm[item_link].plus ); - const bool rotten = (mitm[item_link].special < 100); - - eat_chunk( determine_chunk_effect( chunk_type, rotten ) ); - } - else - { - eating( mitm[item_link].base_type, mitm[item_link].sub_type ); - } - - you.turn_is_over = 1; - - dec_mitm_item_quantity( item_link, 1 ); -} - -bool eat_from_floor(void) -{ - char str_pass[ ITEMNAME_SIZE ]; - - if (player_is_levitating() && !wearing_amulet(AMU_CONTROLLED_FLIGHT)) - return (false); - - for (int o = igrd[you.x_pos][you.y_pos]; o != NON_ITEM; o = mitm[o].link) - { - if (mitm[o].base_type != OBJ_FOOD) - continue; - - it_name( o, DESC_NOCAP_A, str_pass ); - snprintf( info, INFO_SIZE, "Eat %s%s?", (mitm[o].quantity > 1) ? "one of " : "", - str_pass ); - mpr( info, MSGCH_PROMPT ); - - unsigned char keyin = tolower( getch() ); - - if (keyin == 0) - { - getch(); - keyin = 0; - } - - if (keyin == 'q') - return (false); - - if (keyin == 'y') - { - if (!can_ingest( mitm[o].base_type, mitm[o].sub_type, false )) - return (false); - - eat_floor_item(o); - return (true); - } - } - - return (false); -} - - -// never called directly - chunk_effect values must pass -// through food::determine_chunk_effect() first {dlb}: -static void eat_chunk( int chunk_effect ) -{ - - bool likes_chunks = (you.species == SP_KOBOLD || you.species == SP_OGRE - || you.species == SP_TROLL - || you.mutation[MUT_CARNIVOROUS] > 0); - - if (you.species == SP_GHOUL) - { - ghoul_eat_flesh( chunk_effect ); - start_delay( DELAY_EAT, 2 ); - lessen_hunger( 1000, true ); - } - else - { - switch (chunk_effect) - { - case CE_MUTAGEN_RANDOM: - mpr("This meat tastes really weird."); - mutate(100); - break; - - case CE_MUTAGEN_BAD: - mpr("This meat tastes *really* weird."); - give_bad_mutation(); - break; - - case CE_HCL: - rot_player( 10 + random2(10) ); - disease_player( 50 + random2(100) ); - break; - - case CE_POISONOUS: - mpr("Yeeuch - this meat is poisonous!"); - poison_player( 3 + random2(4) ); - break; - - case CE_ROTTEN: - case CE_CONTAMINATED: - mpr("There is something wrong with this meat."); - disease_player( 50 + random2(100) ); - break; - - // note that this is the only case that takes time and forces redraw - case CE_CLEAN: - strcpy(info, "This raw flesh "); - - strcat(info, (likes_chunks) ? "tastes good." - : "is not very appetising."); - mpr(info); - - start_delay( DELAY_EAT, 2 ); - lessen_hunger( 1000, true ); - break; - } - } - - return; -} // end eat_chunk() - -static void ghoul_eat_flesh( int chunk_effect ) -{ - bool healed = false; - - if (chunk_effect != CE_ROTTEN && chunk_effect != CE_CONTAMINATED) - { - mpr("This raw flesh tastes good."); - - if (!one_chance_in(5)) - healed = true; - - if (player_rotted() && !one_chance_in(3)) - { - mpr("You feel more resilient."); - unrot_hp(1); - } - } - else - { - if (chunk_effect == CE_ROTTEN) - mpr( "This rotting flesh tastes delicious!" ); - else // CE_CONTAMINATED - mpr( "This flesh tastes delicious!" ); - - healed = true; - - if (player_rotted() && !one_chance_in(4)) - { - mpr("You feel more resilient."); - unrot_hp(1); - } - } - - if (you.strength < you.max_strength && one_chance_in(5)) - { - mpr("You feel your strength returning."); - you.strength++; - you.redraw_strength = 1; - } - - if (healed && you.hp < you.hp_max) - inc_hp(1 + random2(5) + random2(1 + you.experience_level), false); - - calc_hp(); - - return; -} // end ghoul_eat_flesh() - -static void eating(unsigned char item_class, int item_type) -{ - int temp_rand; // probability determination {dlb} - int food_value = 0; - int how_herbivorous = you.mutation[MUT_HERBIVOROUS]; - int how_carnivorous = you.mutation[MUT_CARNIVOROUS]; - int carnivore_modifier = 0; - int herbivore_modifier = 0; - - switch (item_class) - { - case OBJ_FOOD: - // apply base sustenance {dlb}: - switch (item_type) - { - case FOOD_MEAT_RATION: - case FOOD_ROYAL_JELLY: - food_value = 5000; - break; - case FOOD_BREAD_RATION: - food_value = 4400; - break; - case FOOD_HONEYCOMB: - food_value = 2000; - break; - case FOOD_SNOZZCUMBER: // maybe a nasty side-effect from RD's book? - case FOOD_PIZZA: - case FOOD_BEEF_JERKY: - food_value = 1500; - break; - case FOOD_CHEESE: - case FOOD_SAUSAGE: - food_value = 1200; - break; - case FOOD_ORANGE: - case FOOD_BANANA: - case FOOD_LEMON: - food_value = 1000; - break; - case FOOD_PEAR: - case FOOD_APPLE: - case FOOD_APRICOT: - food_value = 700; - break; - case FOOD_CHOKO: - case FOOD_RAMBUTAN: - case FOOD_LYCHEE: - food_value = 600; - break; - case FOOD_STRAWBERRY: - food_value = 200; - break; - case FOOD_GRAPE: - food_value = 100; - break; - case FOOD_SULTANA: - food_value = 70; // will not save you from starvation - break; - default: - break; - } // end base sustenance listing {dlb} - - // next, sustenance modifier for carnivores/herbivores {dlb}: - // for some reason, sausages do not penalize herbivores {dlb}: - switch (item_type) - { - case FOOD_MEAT_RATION: - carnivore_modifier = 500; - herbivore_modifier = -1500; - break; - case FOOD_BEEF_JERKY: - carnivore_modifier = 200; - herbivore_modifier = -200; - break; - case FOOD_BREAD_RATION: - carnivore_modifier = -1000; - herbivore_modifier = 500; - break; - case FOOD_BANANA: - case FOOD_ORANGE: - case FOOD_LEMON: - carnivore_modifier = -300; - herbivore_modifier = 300; - break; - case FOOD_PEAR: - case FOOD_APPLE: - case FOOD_APRICOT: - case FOOD_CHOKO: - case FOOD_SNOZZCUMBER: - case FOOD_RAMBUTAN: - case FOOD_LYCHEE: - carnivore_modifier = -200; - herbivore_modifier = 200; - break; - case FOOD_STRAWBERRY: - carnivore_modifier = -50; - herbivore_modifier = 50; - break; - case FOOD_GRAPE: - case FOOD_SULTANA: - carnivore_modifier = -20; - herbivore_modifier = 20; - break; - default: - carnivore_modifier = 0; - herbivore_modifier = 0; - break; - } // end carnivore/herbivore modifier listing {dlb} - - // next, let's take care of messaging {dlb}: - if (how_carnivorous > 0 && carnivore_modifier < 0) - mpr("Blech - you need meat!"); - else if (how_herbivorous > 0 && herbivore_modifier < 0) - mpr("Blech - you need greens!"); - - if (how_herbivorous < 1) - { - switch (item_type) - { - case FOOD_MEAT_RATION: - mpr("That meat ration really hit the spot!"); - break; - case FOOD_BEEF_JERKY: - strcpy(info, "That beef jerky was "); - strcat(info, (one_chance_in(4)) ? "jerk-a-riffic" - : "delicious"); - strcat(info, "!"); - mpr(info); - break; - default: - break; - } - } - - if (how_carnivorous < 1) - { - switch (item_type) - { - case FOOD_BREAD_RATION: - mpr("That bread ration really hit the spot!"); - break; - case FOOD_PEAR: - case FOOD_APPLE: - case FOOD_APRICOT: - strcpy(info, "Mmmm... Yummy "); - strcat(info, (item_type == FOOD_APPLE) ? "apple." : - (item_type == FOOD_PEAR) ? "pear." : - (item_type == FOOD_APRICOT) ? "apricot." - : "fruit."); - mpr(info); - break; - case FOOD_CHOKO: - mpr("That choko was very bland."); - break; - case FOOD_SNOZZCUMBER: - mpr("That snozzcumber tasted truly putrid!"); - break; - case FOOD_ORANGE: - strcpy(info, "That orange was delicious!"); - if (one_chance_in(8)) - strcat(info, " Even the peel tasted good!"); - mpr(info); - break; - case FOOD_BANANA: - strcpy(info, "That banana was delicious!"); - if (one_chance_in(8)) - strcat(info, " Even the peel tasted good!"); - mpr(info); - break; - case FOOD_STRAWBERRY: - mpr("That strawberry was delicious!"); - break; - case FOOD_RAMBUTAN: - mpr("That rambutan was delicious!"); - break; - case FOOD_LEMON: - mpr("That lemon was rather sour... But delicious nonetheless!"); - break; - case FOOD_GRAPE: - mpr("That grape was delicious!"); - break; - case FOOD_SULTANA: - mpr("That sultana was delicious! (but very small)"); - break; - case FOOD_LYCHEE: - mpr("That lychee was delicious!"); - break; - default: - break; - } - } - - switch (item_type) - { - case FOOD_HONEYCOMB: - mpr("That honeycomb was delicious."); - break; - case FOOD_ROYAL_JELLY: - mpr("That royal jelly was delicious!"); - restore_stat(STAT_ALL, false); - break; - case FOOD_PIZZA: - if (SysEnv.crawl_pizza && !one_chance_in(3)) - snprintf(info, INFO_SIZE, "Mmm... %s", SysEnv.crawl_pizza); - else - { - temp_rand = random2(9); - - snprintf(info, INFO_SIZE, "Mmm... %s", - (temp_rand == 0) ? "Ham and pineapple." : - (temp_rand == 2) ? "Vegetable." : - (temp_rand == 3) ? "Pepperoni." : - (temp_rand == 4) ? "Yeuchh - Anchovies!" : - (temp_rand == 5) ? "Cheesy." : - (temp_rand == 6) ? "Supreme." : - (temp_rand == 7) ? "Super Supreme!" - : "Chicken."); - } - mpr(info); - break; - case FOOD_CHEESE: - strcpy(info, "Mmm... "); - temp_rand = random2(9); - - strcat(info, (temp_rand == 0) ? "Cheddar" : - (temp_rand == 1) ? "Edam" : - (temp_rand == 2) ? "Wensleydale" : - (temp_rand == 3) ? "Camembert" : - (temp_rand == 4) ? "Goat cheese" : - (temp_rand == 5) ? "Fruit cheese" : - (temp_rand == 6) ? "Mozzarella" : - (temp_rand == 7) ? "Sheep cheese" - : "Yak cheese"); - - strcat(info, "."); - mpr(info); - break; - case FOOD_SAUSAGE: - mpr("That sausage was delicious!"); - break; - default: - break; - } - - // finally, modify player's hunger level {dlb}: - if (carnivore_modifier && how_carnivorous > 0) - food_value += (carnivore_modifier * how_carnivorous); - - if (herbivore_modifier && how_herbivorous > 0) - food_value += (herbivore_modifier * how_herbivorous); - - if (food_value > 0) - { - if (item_type == FOOD_MEAT_RATION || item_type == FOOD_BREAD_RATION) - start_delay( DELAY_EAT, 3 ); - else - start_delay( DELAY_EAT, 1 ); - - lessen_hunger( food_value, true ); - } - break; - - default: - break; - } - - return; -} // end eating() - -bool can_ingest(int what_isit, int kindof_thing, bool suppress_msg, bool reqid, - bool check_hunger) -{ - bool survey_says = false; - - // [ds] These redundant checks are now necessary - Lua might be calling us. - if (you.is_undead == US_UNDEAD) - { - if (!suppress_msg) - mpr("You can't eat."); - return (false); - } - - if (check_hunger && you.hunger >= 11000) - { - if (!suppress_msg) - mpr("You're too full to eat anything."); - return (false); - } - - - bool ur_carnivorous = (you.species == SP_GHOUL - || you.species == SP_KOBOLD - || you.mutation[MUT_CARNIVOROUS] == 3); - - bool ur_herbivorous = (you.mutation[MUT_HERBIVOROUS] > 1); - - // ur_chunkslover not defined in terms of ur_carnivorous because - // a player could be one and not the other IMHO - 13mar2000 {dlb} - bool ur_chunkslover = ( - (check_hunger? you.hunger_state <= HS_HUNGRY : true) - || wearing_amulet(AMU_THE_GOURMAND, !reqid) - || you.species == SP_KOBOLD - || you.species == SP_OGRE - || you.species == SP_TROLL - || you.species == SP_GHOUL - || you.mutation[MUT_CARNIVOROUS]); - - switch (what_isit) - { - case OBJ_FOOD: - switch (kindof_thing) - { - case FOOD_BREAD_RATION: - case FOOD_PEAR: - case FOOD_APPLE: - case FOOD_CHOKO: - case FOOD_SNOZZCUMBER: - case FOOD_PIZZA: - case FOOD_APRICOT: - case FOOD_ORANGE: - case FOOD_BANANA: - case FOOD_STRAWBERRY: - case FOOD_RAMBUTAN: - case FOOD_LEMON: - case FOOD_GRAPE: - case FOOD_SULTANA: - case FOOD_LYCHEE: - if (ur_carnivorous) - { - survey_says = false; - if (!suppress_msg) - mpr("Sorry, you're a carnivore."); - } - else - survey_says = true; - break; - - case FOOD_CHUNK: - if (ur_herbivorous) - { - survey_says = false; - if (!suppress_msg) - mpr("You can't eat raw meat!"); - } - else if (!ur_chunkslover) - { - survey_says = false; - if (!suppress_msg) - mpr("You aren't quite hungry enough to eat that!"); - } - else - survey_says = true; - break; - - default: - return (true); - } - break; - - // other object types are set to return false for now until - // someone wants to recode the eating code to permit consumption - // of things other than just food -- corpses first, then more - // exotic stuff later would be good to explore - 13mar2000 {dlb} - case OBJ_CORPSES: - default: - return (false); - } - - return (survey_says); -} // end can_ingest() - -// see if you can follow along here -- except for the Amulet of the Gourmand -// addition (long missing and requested), what follows is an expansion of how -// chunks were handled in the codebase up to this date -- I have never really -// understood why liches are hungry and not true undead beings ... {dlb}: -static int determine_chunk_effect(int which_chunk_type, bool rotten_chunk) -{ - int poison_resistance_level = player_res_poison(); - int this_chunk_effect = which_chunk_type; - - // determine the initial effect of eating a particular chunk {dlb}: - switch (this_chunk_effect) - { - case CE_HCL: - case CE_MUTAGEN_RANDOM: - if (you.species == SP_GHOUL - || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH) - { - this_chunk_effect = CE_CLEAN; - } - break; - - case CE_POISONOUS: - if (you.species == SP_GHOUL - || you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH - || poison_resistance_level > 0) - { - this_chunk_effect = CE_CLEAN; - } - break; - - case CE_CONTAMINATED: - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH) - this_chunk_effect = CE_CLEAN; - else - { - switch (you.species) - { - case SP_GHOUL: - // Doing this here causes a odd message later. -- bwr - // this_chunk_effect = CE_ROTTEN; - break; - - case SP_KOBOLD: - case SP_TROLL: - if (!one_chance_in(45)) - this_chunk_effect = CE_CLEAN; - break; - - case SP_HILL_ORC: - case SP_OGRE: - if (!one_chance_in(15)) - this_chunk_effect = CE_CLEAN; - break; - - default: - if (!one_chance_in(3)) - this_chunk_effect = CE_CLEAN; - break; - } - } - break; - - default: - break; - } - - // determine effects of rotting on base chunk effect {dlb}: - if (rotten_chunk) - { - switch (this_chunk_effect) - { - case CE_CLEAN: - case CE_CONTAMINATED: - this_chunk_effect = CE_ROTTEN; - break; - case CE_MUTAGEN_RANDOM: - this_chunk_effect = CE_MUTAGEN_BAD; - break; - default: - break; - } - } - - // one last chance for some species to safely eat rotten food {dlb}: - if (this_chunk_effect == CE_ROTTEN) - { - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_LICH) - this_chunk_effect = CE_CLEAN; - else - { - switch (you.species) - { - case SP_KOBOLD: - case SP_TROLL: - if (!one_chance_in(15)) - this_chunk_effect = CE_CLEAN; - break; - case SP_HILL_ORC: - case SP_OGRE: - if (!one_chance_in(5)) - this_chunk_effect = CE_CLEAN; - break; - default: - break; - } - } - } - - // the amulet of the gourmad will permit consumption of rotting meat as - // though it were "clean" meat - ghouls can expect the reverse, as they - // prize rotten meat ... yum! {dlb}: - if (wearing_amulet(AMU_THE_GOURMAND)) - { - if (you.species == SP_GHOUL) - { - if (this_chunk_effect == CE_CLEAN) - this_chunk_effect = CE_ROTTEN; - } - else - { - if (this_chunk_effect == CE_ROTTEN) - this_chunk_effect = CE_CLEAN; - } - } - - return (this_chunk_effect); -} // end determine_chunk_effect() |