summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-29 09:30:00 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-12-29 09:30:00 +0000
commit1acc5c3b399b756f29c5f458e915052f890c266c (patch)
tree5e4f85867d4597ad13e062e2d6bf490f2388b2b4 /crawl-ref/source
parent07a0e09b11917bebd145b44d85cb6a44a79fd472 (diff)
downloadcrawl-ref-1acc5c3b399b756f29c5f458e915052f890c266c.tar.gz
crawl-ref-1acc5c3b399b756f29c5f458e915052f890c266c.zip
[1622133] Implemented incremental butchering as Haran suggested.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@722 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/delay.cc387
-rw-r--r--crawl-ref/source/food.cc145
2 files changed, 276 insertions, 256 deletions
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index eacddf56c1..c7aab68460 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -44,6 +44,7 @@ extern std::vector<SelItem> items_for_multidrop;
static void armour_wear_effects(const int item_inv_slot);
static void handle_run_delays(const delay_queue_item &delay);
static void handle_macro_delay();
+static void finish_delay(const delay_queue_item &delay);
// Returns true if this delay can act as a parent to other delays, i.e. if
// other delays can be spawned while this delay is running. If is_parent_delay
@@ -60,7 +61,7 @@ static bool is_parent_delay(int delay)
|| delay == DELAY_MULTIDROP);
}
-static void push_delay(const delay_queue_item &delay)
+static int push_delay(const delay_queue_item &delay)
{
for (delay_queue_type::iterator i = you.delay_queue.begin();
i != you.delay_queue.end();
@@ -69,10 +70,11 @@ static void push_delay(const delay_queue_item &delay)
if (is_parent_delay( i->type ))
{
you.delay_queue.insert(i, delay);
- return;
+ return (i - you.delay_queue.begin());
}
}
you.delay_queue.push_back( delay );
+ return (you.delay_queue.size() - 1);
}
static void pop_delay()
@@ -97,7 +99,17 @@ void start_delay( int type, int turns, int parm1, int parm2 )
delay.parm1 = parm1;
delay.parm2 = parm2;
- switch ( delay.type ) {
+ // Handle zero-turn delays (possible with butchering).
+ if (turns == 0)
+ {
+ // Don't issue startup message.
+ if (push_delay(delay) == 0)
+ finish_delay(delay);
+ return;
+ }
+
+ switch ( delay.type )
+ {
case DELAY_ARMOUR_ON:
mpr("You start putting on your armour.", MSGCH_MULTITURN_ACTION);
break;
@@ -364,223 +376,228 @@ void handle_delay( void )
}
else
{
- switch (delay.type)
- {
- case DELAY_AUTOPICKUP:
- {
- const int estop =
- you.running == RMODE_EXPLORE_GREEDY?
- ES_GREEDY_PICKUP : ES_PICKUP;
- if ((Options.explore_stop & estop) && prompt_stop_explore(estop))
- stop_delay();
- break;
- }
-
- case DELAY_WEAPON_SWAP:
- weapon_switch( delay.parm1 );
- break;
+ finish_delay(delay);
+ }
+}
- case DELAY_JEWELLERY_ON:
- puton_ring( delay.parm1, false );
- break;
+static void finish_delay(const delay_queue_item &delay)
+{
+ char str_pass[ ITEMNAME_SIZE ];
+ switch (delay.type)
+ {
+ case DELAY_AUTOPICKUP:
+ {
+ const int estop =
+ you.running == RMODE_EXPLORE_GREEDY?
+ ES_GREEDY_PICKUP : ES_PICKUP;
+ if ((Options.explore_stop & estop) && prompt_stop_explore(estop))
+ stop_delay();
+ break;
+ }
- case DELAY_ARMOUR_ON:
- armour_wear_effects( delay.parm1 );
- break;
+ case DELAY_WEAPON_SWAP:
+ weapon_switch( delay.parm1 );
+ break;
- case DELAY_ARMOUR_OFF:
- {
- in_name( delay.parm1, DESC_NOCAP_YOUR, str_pass );
- snprintf( info, INFO_SIZE, "You finish taking off %s.", str_pass );
- mpr(info);
+ case DELAY_JEWELLERY_ON:
+ puton_ring( delay.parm1, false );
+ break;
- const equipment_type slot =
- get_armour_slot( you.inv[delay.parm1] );
+ case DELAY_ARMOUR_ON:
+ armour_wear_effects( delay.parm1 );
+ break;
- if (slot == EQ_BODY_ARMOUR)
- {
- you.equip[EQ_BODY_ARMOUR] = -1;
- }
- else
- {
- switch (slot)
- {
- case EQ_SHIELD:
- if (delay.parm1 == you.equip[EQ_SHIELD])
- you.equip[EQ_SHIELD] = -1;
- break;
-
- case EQ_CLOAK:
- if (delay.parm1 == you.equip[EQ_CLOAK])
- you.equip[EQ_CLOAK] = -1;
- break;
-
- case EQ_HELMET:
- if (delay.parm1 == you.equip[EQ_HELMET])
- you.equip[EQ_HELMET] = -1;
- break;
-
-
- case EQ_GLOVES:
- if (delay.parm1 == you.equip[EQ_GLOVES])
- you.equip[EQ_GLOVES] = -1;
- break;
-
- case EQ_BOOTS:
- if (delay.parm1 == you.equip[EQ_BOOTS])
- you.equip[EQ_BOOTS] = -1;
- break;
-
- default:
- break;
- }
- }
+ case DELAY_ARMOUR_OFF:
+ {
+ in_name( delay.parm1, DESC_NOCAP_YOUR, str_pass );
+ snprintf( info, INFO_SIZE, "You finish taking off %s.", str_pass );
+ mpr(info);
- unwear_armour( delay.parm1 );
+ const equipment_type slot =
+ get_armour_slot( you.inv[delay.parm1] );
- you.redraw_armour_class = 1;
- you.redraw_evasion = 1;
- break;
+ if (slot == EQ_BODY_ARMOUR)
+ {
+ you.equip[EQ_BODY_ARMOUR] = -1;
}
- case DELAY_EAT:
- mpr( "You finish eating." );
- // For chunks, warn the player if they're not getting much
- // nutrition.
- if (delay.parm1)
- chunk_nutrition_message(delay.parm1);
- break;
+ else
+ {
+ switch (slot)
+ {
+ case EQ_SHIELD:
+ if (delay.parm1 == you.equip[EQ_SHIELD])
+ you.equip[EQ_SHIELD] = -1;
+ break;
- case DELAY_MEMORISE:
- mpr( "You finish memorising." );
- add_spell_to_memory( delay.parm1 );
- break;
+ case EQ_CLOAK:
+ if (delay.parm1 == you.equip[EQ_CLOAK])
+ you.equip[EQ_CLOAK] = -1;
+ break;
- case DELAY_PASSWALL:
- {
- mpr( "You finish merging with the rock." );
- more(); // or the above message won't be seen
+ case EQ_HELMET:
+ if (delay.parm1 == you.equip[EQ_HELMET])
+ you.equip[EQ_HELMET] = -1;
+ break;
- const int pass_x = delay.parm1;
- const int pass_y = delay.parm2;
+ case EQ_GLOVES:
+ if (delay.parm1 == you.equip[EQ_GLOVES])
+ you.equip[EQ_GLOVES] = -1;
+ break;
- if (pass_x != 0 && pass_y != 0)
- {
+ case EQ_BOOTS:
+ if (delay.parm1 == you.equip[EQ_BOOTS])
+ you.equip[EQ_BOOTS] = -1;
+ break;
- switch (grd[ pass_x ][ pass_y ])
- {
- case DNGN_ROCK_WALL:
- case DNGN_STONE_WALL:
- case DNGN_METAL_WALL:
- case DNGN_GREEN_CRYSTAL_WALL:
- case DNGN_WAX_WALL:
- case DNGN_SILVER_STATUE:
- case DNGN_ORANGE_CRYSTAL_STATUE:
- ouch(1 + you.hp, 0, KILLED_BY_PETRIFICATION);
- break;
-
- case DNGN_SECRET_DOOR: // oughtn't happen
- case DNGN_CLOSED_DOOR: // open the door
- grd[ pass_x ][ pass_y ] = DNGN_OPEN_DOOR;
- break;
-
- default:
- break;
- }
-
- // move any monsters out of the way:
- int mon = mgrd[ pass_x ][ pass_y ];
- if (mon != NON_MONSTER)
- {
- // one square, a few squares, anywhere...
- if (!shift_monster(&menv[mon])
- && !monster_blink(&menv[mon]))
- {
- monster_teleport( &menv[mon], true, true );
- }
- }
-
- move_player_to_grid(pass_x, pass_y, false, true, true);
- redraw_screen();
- }
+ default:
+ break;
}
- break;
+ }
- case DELAY_BUTCHER:
- snprintf(info, INFO_SIZE, "You finish %s the corpse into pieces.",
- (you.species == SP_TROLL ||
- you.species == SP_GHOUL) ? "ripping" : "chopping" );
- mpr(info);
+ unwear_armour( delay.parm1 );
- turn_corpse_into_chunks( mitm[ delay.parm1 ] );
+ you.redraw_armour_class = 1;
+ you.redraw_evasion = 1;
+ break;
+ }
+ case DELAY_EAT:
+ mpr( "You finish eating." );
+ // For chunks, warn the player if they're not getting much
+ // nutrition.
+ if (delay.parm1)
+ chunk_nutrition_message(delay.parm1);
+ break;
- if (you.berserker && you.berserk_penalty != NO_BERSERK_PENALTY)
- {
- mpr("You enjoyed that.");
- you.berserk_penalty = 0;
- }
- break;
+ case DELAY_MEMORISE:
+ mpr( "You finish memorising." );
+ add_spell_to_memory( delay.parm1 );
+ break;
+
+ case DELAY_PASSWALL:
+ {
+ mpr( "You finish merging with the rock." );
+ more(); // or the above message won't be seen
- case DELAY_DROP_ITEM:
- // Note: checking if item is droppable is assumed to
- // be done before setting up this delay... this includes
- // quantity (delay.parm2). -- bwr
+ const int pass_x = delay.parm1;
+ const int pass_y = delay.parm2;
- // Make sure item still exists.
- if (!is_valid_item( you.inv[ delay.parm1 ] ))
+ if (pass_x != 0 && pass_y != 0)
+ {
+
+ switch (grd[ pass_x ][ pass_y ])
+ {
+ case DNGN_ROCK_WALL:
+ case DNGN_STONE_WALL:
+ case DNGN_METAL_WALL:
+ case DNGN_GREEN_CRYSTAL_WALL:
+ case DNGN_WAX_WALL:
+ case DNGN_SILVER_STATUE:
+ case DNGN_ORANGE_CRYSTAL_STATUE:
+ ouch(1 + you.hp, 0, KILLED_BY_PETRIFICATION);
break;
- // Must handle unwield_item before we attempt to copy
- // so that temporary brands and such are cleared. -- bwr
- if (delay.parm1 == you.equip[EQ_WEAPON])
- {
- unwield_item( delay.parm1 );
- you.equip[EQ_WEAPON] = -1;
- canned_msg( MSG_EMPTY_HANDED );
+ case DNGN_SECRET_DOOR: // oughtn't happen
+ case DNGN_CLOSED_DOOR: // open the door
+ grd[ pass_x ][ pass_y ] = DNGN_OPEN_DOOR;
+ break;
+
+ default:
+ break;
}
- if (!copy_item_to_grid( you.inv[ delay.parm1 ],
- you.x_pos, you.y_pos, delay.parm2,
- true ))
+ // move any monsters out of the way:
+ int mon = mgrd[ pass_x ][ pass_y ];
+ if (mon != NON_MONSTER)
{
- mpr("Too many items on this level, not dropping the item.");
+ // one square, a few squares, anywhere...
+ if (!shift_monster(&menv[mon])
+ && !monster_blink(&menv[mon]))
+ {
+ monster_teleport( &menv[mon], true, true );
+ }
}
- else
- {
- quant_name( you.inv[ delay.parm1 ], delay.parm2,
- DESC_NOCAP_A, str_pass );
- snprintf( info, INFO_SIZE, "You drop %s.", str_pass );
- mpr(info);
+ move_player_to_grid(pass_x, pass_y, false, true, true);
+ redraw_screen();
+ }
+ break;
+ }
- dec_inv_item_quantity( delay.parm1, delay.parm2 );
- }
- break;
+ case DELAY_BUTCHER:
+ snprintf(info, INFO_SIZE, "You finish %s the corpse into pieces.",
+ (you.species == SP_TROLL ||
+ you.species == SP_GHOUL) ? "ripping" : "chopping" );
+ mpr(info);
- case DELAY_ASCENDING_STAIRS:
- up_stairs();
- untag_followers();
- break;
+ turn_corpse_into_chunks( mitm[ delay.parm1 ] );
- case DELAY_DESCENDING_STAIRS:
- down_stairs( false, delay.parm1 );
- untag_followers();
- break;
+ if (you.berserker && you.berserk_penalty != NO_BERSERK_PENALTY)
+ {
+ mpr("You enjoyed that.");
+ you.berserk_penalty = 0;
+ }
+ break;
+
+ case DELAY_DROP_ITEM:
+ // Note: checking if item is droppable is assumed to
+ // be done before setting up this delay... this includes
+ // quantity (delay.parm2). -- bwr
- case DELAY_INTERRUPTIBLE:
- case DELAY_UNINTERRUPTIBLE:
- // these are simple delays that have no effect when complete
+ // Make sure item still exists.
+ if (!is_valid_item( you.inv[ delay.parm1 ] ))
break;
- default:
- mpr( "You finish doing something." );
- break;
+ // Must handle unwield_item before we attempt to copy
+ // so that temporary brands and such are cleared. -- bwr
+ if (delay.parm1 == you.equip[EQ_WEAPON])
+ {
+ unwield_item( delay.parm1 );
+ you.equip[EQ_WEAPON] = -1;
+ canned_msg( MSG_EMPTY_HANDED );
}
- you.wield_change = true;
- print_stats(); // force redraw of the stats
- you.turn_is_over = true;
- pop_delay();
+ if (!copy_item_to_grid( you.inv[ delay.parm1 ],
+ you.x_pos, you.y_pos, delay.parm2,
+ true ))
+ {
+ mpr("Too many items on this level, not dropping the item.");
+ }
+ else
+ {
+ quant_name( you.inv[ delay.parm1 ], delay.parm2,
+ DESC_NOCAP_A, str_pass );
+
+ snprintf( info, INFO_SIZE, "You drop %s.", str_pass );
+ mpr(info);
+
+ dec_inv_item_quantity( delay.parm1, delay.parm2 );
+ }
+ break;
+
+ case DELAY_ASCENDING_STAIRS:
+ up_stairs();
+ untag_followers();
+ break;
+
+ case DELAY_DESCENDING_STAIRS:
+ down_stairs( false, delay.parm1 );
+ untag_followers();
+ break;
+
+ case DELAY_INTERRUPTIBLE:
+ case DELAY_UNINTERRUPTIBLE:
+ // these are simple delays that have no effect when complete
+ break;
+
+ default:
+ mpr( "You finish doing something." );
+ break;
}
+
+ you.wield_change = true;
+ print_stats(); // force redraw of the stats
+ you.turn_is_over = true;
+ pop_delay();
}
static void armour_wear_effects(const int item_slot)
diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc
index 5ec6b7bbfb..93af87ce84 100644
--- a/crawl-ref/source/food.cc
+++ b/crawl-ref/source/food.cc
@@ -232,87 +232,90 @@ bool butchery(void)
// to butcher, *then* decide to actually butcher it.
// The old code did it the other way.
if ( !can_butcher && you.berserker ) {
- mpr ("You are too berserk to search for a butchering knife!");
- return (false);
+ mpr ("You are too berserk to search for a butchering knife!");
+ return (false);
}
int objl;
for (objl = igrd[you.x_pos][you.y_pos]; objl != NON_ITEM;
- objl = mitm[objl].link) {
-
- if ( (mitm[objl].base_type != OBJ_CORPSES) ||
- (mitm[objl].sub_type != CORPSE_BODY) )
- continue;
-
- // offer the possibility of butchering
- it_name(objl, DESC_NOCAP_A, str_pass);
- snprintf(info, INFO_SIZE, "Butcher %s?", str_pass);
- int answer = yesnoquit( info, true, 'n', false );
- if ( answer == -1 )
- break;
- if ( answer == 0 )
- continue;
+ objl = mitm[objl].link)
+ {
+ if ( (mitm[objl].base_type != OBJ_CORPSES) ||
+ (mitm[objl].sub_type != CORPSE_BODY) )
+ continue;
+
+ // offer the possibility of butchering
+ it_name(objl, DESC_NOCAP_A, str_pass);
+ snprintf(info, INFO_SIZE, "Butcher %s?", str_pass);
+ int answer = yesnoquit( info, true, 'n', false );
+ if ( answer == -1 )
+ break;
+ if ( answer == 0 )
+ continue;
- if ( Options.easy_butcher && !can_butcher ) {
-
- // try to find a butchering implement
- wpn_switch = find_butchering_implement();
- const int wpn = you.equip[EQ_WEAPON];
- if ( wpn_switch ) {
- new_cursed =
- (wpn != -1) &&
- (you.inv[wpn].base_type == OBJ_WEAPONS) &&
- item_cursed( you.inv[wpn]);
- }
+ if ( Options.easy_butcher && !can_butcher )
+ {
+ // try to find a butchering implement
+ wpn_switch = find_butchering_implement();
+ const int wpn = you.equip[EQ_WEAPON];
+ if ( wpn_switch )
+ {
+ new_cursed =
+ (wpn != -1) &&
+ (you.inv[wpn].base_type == OBJ_WEAPONS) &&
+ item_cursed( you.inv[wpn]);
+ }
- // note that barehanded butchery would not reach this
- // stage, so if wpn == -1 the user selected '-' when
- // switching weapons
+ // note that barehanded butchery would not reach this
+ // stage, so if wpn == -1 the user selected '-' when
+ // switching weapons
- if (!wpn_switch || wpn == -1 || !can_cut_meat(you.inv[wpn])) {
-
- // still can't butcher. Early out
- if ( wpn == -1 ) {
- if (you.equip[EQ_GLOVES] == -1)
- mpr("What, with your bare hands?");
- else
- mpr("Your gloves aren't that sharp!");
- }
- else
- mpr("Maybe you should try using a sharper implement.");
+ if (!wpn_switch || wpn == -1 || !can_cut_meat(you.inv[wpn]))
+ {
+ // still can't butcher. Early out
+ if ( wpn == -1 ) {
+ if (you.equip[EQ_GLOVES] == -1)
+ mpr("What, with your bare hands?");
+ else
+ mpr("Your gloves aren't that sharp!");
+ }
+ else
+ mpr("Maybe you should try using a sharper implement.");
- if ( !new_cursed && wpn_switch )
- start_delay( DELAY_WEAPON_SWAP, 1, old_weapon );
+ if ( !new_cursed && wpn_switch )
+ start_delay( DELAY_WEAPON_SWAP, 1, old_weapon );
- return false;
- }
+ return false;
+ }
- // switched to a good butchering knife
- can_butcher = true;
- }
+ // switched to a good butchering knife
+ can_butcher = true;
+ }
- if ( can_butcher ) {
-
- // we actually butcher now
- 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(objl);
- destroy_item(objl);
- }
- else {
- int work_req = 3 - mitm[objl].plus2;
- if (work_req < 0)
- work_req = 0;
-
- start_delay(DELAY_BUTCHER, work_req, objl, mitm[objl].special);
- }
+ if ( can_butcher )
+ {
+ // we actually butcher now
+ 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(objl);
+ destroy_item(objl);
+ }
+ else
+ {
+ int work_req = 4 - (++mitm[objl].plus2);
+ if (work_req < 0)
+ work_req = 0;
+
+ start_delay(DELAY_BUTCHER, work_req, objl, mitm[objl].special);
+ }
}
// switch weapon back
@@ -320,10 +323,10 @@ bool butchery(void)
start_delay( DELAY_WEAPON_SWAP, 1, old_weapon );
you.turn_is_over = true;
-
+
return true;
}
-
+
mpr("There isn't anything to dissect here.");
if (!new_cursed && wpn_switch) { // should never happen