/* * Activate a wielded object. Wielded objects never stack. * And even if they did, activatable objects never stack. * * Note that it always takes a turn to activate an artifact, even if * the user hits "escape" at the "direction" prompt. */ void do_cmd_activate(void) { int item, lev, chance; bool ident; object_type *o_ptr; cptr q, s; /* Prepare the hook */ item_tester_hook = item_tester_hook_activate; /* Get an item */ q = "Activate which item? "; s = "You have nothing to activate."; if (!get_item(&item, q, s, (USE_EQUIP))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Take a turn */ p_ptr->energy_use = 100; /* Extract the item level */ lev = k_info[o_ptr->k_idx].level; /* Hack -- use artifact level instead */ if (artifact_p(o_ptr)) lev = a_info[o_ptr->name1].level; /* Base chance of success */ chance = p_ptr->skill_dev; /* Confusion hurts skill */ if (p_ptr->confused) chance = chance / 2; /* High level objects are harder */ chance = chance - ((lev > 50) ? 50 : lev); /* Give everyone a (slight) chance */ if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) { chance = USE_DEVICE; } /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { if (flush_failure) flush(); msg_print("You failed to activate it properly."); return; } /* Activate the object */ (void)use_object(o_ptr, &ident); }
/* * Eat some food (from the pack or floor) */ void do_cmd_eat_food(void) { int item, lev; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to food */ item_tester_tval = TV_FOOD; /* Get an item */ q = "Eat which item? "; s = "You have nothing to eat."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Sound */ sound(MSG_EAT); /* Take a turn */ p_ptr->energy_use = 100; /* Identity not known yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Eat the food */ use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* We have tried it */ object_tried(o_ptr); /* The player is now aware of the object */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* Destroy a food in the pack */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Destroy a food on the floor */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
/* * Activate (zap) a Rod * * Unstack fully charged rods as needed. * * Hack -- rods of perception/banishment can be "cancelled" * All rods can be cancelled at the "Direction?" prompt */ void do_cmd_zap_rod(void) { int item; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to rods */ item_tester_tval = TV_ROD; /* Get an item */ q = "Zap which rod? "; s = "You have no rod to zap."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Mega-Hack -- refuse to zap a pile from the ground */ if ((item < 0) && (o_ptr->number > 1)) { msg_print("You must first pick up the rods."); return; } /* Zap the rod */ if (!use_object(o_ptr, &ident)) return; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Tried the object */ object_tried(o_ptr); /* Successfully determined the object function */ if (ident && !object_aware_p(o_ptr)) { /* Object level */ int lev = k_info[o_ptr->k_idx].level; object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* XXX Hack -- unstack if necessary */ if ((item >= 0) && (o_ptr->number > 1) && (o_ptr->pval > 0)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Restore "charge" */ o_ptr->pval = 0; /* Unstack the used item */ o_ptr->number--; p_ptr->total_weight -= i_ptr->weight; item = inven_carry(i_ptr); /* Message */ msg_print("You unstack your rod."); } }
/* * Aim a wand (from the pack or floor). * * Use a single charge from a single item. * Handle "unstacking" in a logical manner. * * For simplicity, you cannot use a stack of items from the * ground. This would require too much nasty code. * * There are no wands which can "destroy" themselves, in the inventory * or on the ground, so we can ignore this possibility. Note that this * required giving "wand of wonder" the ability to ignore destruction * by electric balls. * * All wands can be "cancelled" at the "Direction?" prompt for free. * * Note that the basic "bolt" wands do slightly less damage than the * basic "bolt" rods, but the basic "ball" wands do the same damage * as the basic "ball" rods. */ void do_cmd_aim_wand(void) { int item, lev; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to wands */ item_tester_tval = TV_WAND; /* Get an item */ q = "Aim which wand? "; s = "You have no wand to aim."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Mega-Hack -- refuse to aim a pile from the ground */ if ((item < 0) && (o_ptr->number > 1)) { msg_print("You must first pick up the wands."); return; } /* Aim the wand */ if (!use_object(o_ptr, &ident)) return; /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Mark it as tried */ object_tried(o_ptr); /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Apply identification */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* Use a single charge */ o_ptr->pval--; /* Hack -- unstack if necessary */ if ((item >= 0) && (o_ptr->number > 1)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Restore the charges */ o_ptr->pval++; /* Unstack the used item */ o_ptr->number--; p_ptr->total_weight -= i_ptr->weight; item = inven_carry(i_ptr); /* Message */ msg_print("You unstack your wand."); } /* Describe the charges in the pack */ if (item >= 0) { inven_item_charges(item); } /* Describe the charges on the floor */ else { floor_item_charges(0 - item); } }
/* * Use a staff * * One charge of one staff disappears. * * Hack -- staffs of identify can be "cancelled". */ void do_cmd_use_staff(void) { int item, chance, lev; bool ident; object_type *o_ptr; bool use_charge; cptr q, s; /* Restrict choices to staves */ item_tester_tval = TV_STAFF; /* Get an item */ q = "Use which staff? "; s = "You have no staff to use."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Mega-Hack -- refuse to use a pile from the ground */ if ((item < 0) && (o_ptr->number > 1)) { msg_print("You must first pick up the staffs."); return; } /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ ident = FALSE; /* Extract the item level */ lev = k_info[o_ptr->k_idx].level; /* Base chance of success */ chance = p_ptr->skill_dev; /* Confusion hurts skill */ if (p_ptr->confused) chance = chance / 2; /* High level objects are harder */ chance = chance - ((lev > 50) ? 50 : lev); /* Give everyone a (slight) chance */ if ((chance < USE_DEVICE) && (rand_int(USE_DEVICE - chance + 1) == 0)) { chance = USE_DEVICE; } /* Roll for usage */ if ((chance < USE_DEVICE) || (randint(chance) < USE_DEVICE)) { if (flush_failure) flush(); msg_print("You failed to use the staff properly."); return; } /* Notice empty staffs */ if (o_ptr->pval <= 0) { if (flush_failure) flush(); msg_print("The staff has no charges left."); o_ptr->ident |= (IDENT_EMPTY); p_ptr->notice |= (PN_COMBINE | PN_REORDER); p_ptr->window |= (PW_INVEN); return; } /* Sound */ sound(MSG_ZAP); /* Use the staff */ use_charge = use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* Tried the item */ object_tried(o_ptr); /* An identification was made */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* Hack -- some uses are "free" */ if (!use_charge) return; /* Use a single charge */ o_ptr->pval--; /* XXX Hack -- unstack if necessary */ if ((item >= 0) && (o_ptr->number > 1)) { object_type *i_ptr; object_type object_type_body; /* Get local object */ i_ptr = &object_type_body; /* Obtain a local object */ object_copy(i_ptr, o_ptr); /* Modify quantity */ i_ptr->number = 1; /* Restore the charges */ o_ptr->pval++; /* Unstack the used item */ o_ptr->number--; p_ptr->total_weight -= i_ptr->weight; item = inven_carry(i_ptr); /* Message */ msg_print("You unstack your staff."); } /* Describe charges in the pack */ if (item >= 0) { inven_item_charges(item); } /* Describe charges on the floor */ else { floor_item_charges(0 - item); } }
/* * Read a scroll (from the pack or floor). * * Certain scrolls can be "aborted" without losing the scroll. These * include scrolls with no effects but recharge or identify, which are * cancelled before use. XXX Reading them still takes a turn, though. */ void do_cmd_read_scroll(void) { int item, used_up, lev; bool ident; object_type *o_ptr; cptr q, s; /* Check some conditions */ if (p_ptr->blind) { msg_print("You can't see anything."); return; } if (no_lite()) { msg_print("You have no light to read by."); return; } if (p_ptr->confused) { msg_print("You are too confused!"); return; } /* Restrict choices to scrolls */ item_tester_tval = TV_SCROLL; /* Get an item */ q = "Read which scroll? "; s = "You have no scrolls to read."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Read the scroll */ used_up = use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* The item was tried */ object_tried(o_ptr); /* An identification was made */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* Hack -- allow certain scrolls to be "preserved" */ if (!used_up) return; /* Destroy a scroll in the pack */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Destroy a scroll on the floor */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
/* * Quaff a potion (from the pack or the floor) */ void do_cmd_quaff_potion(void) { int item, lev; bool ident; object_type *o_ptr; cptr q, s; /* Restrict choices to potions */ item_tester_tval = TV_POTION; /* Get an item */ q = "Quaff which potion? "; s = "You have no potions to quaff."; if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return; /* Get the item (in the pack) */ if (item >= 0) { o_ptr = &inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Sound */ sound(MSG_QUAFF); /* Take a turn */ p_ptr->energy_use = 100; /* Not identified yet */ ident = FALSE; /* Object level */ lev = k_info[o_ptr->k_idx].level; /* Quaff the potion */ use_object(o_ptr, &ident); /* Combine / Reorder the pack (later) */ p_ptr->notice |= (PN_COMBINE | PN_REORDER); /* The item has been tried */ object_tried(o_ptr); /* An identification was made */ if (ident && !object_aware_p(o_ptr)) { object_aware(o_ptr); gain_exp((lev + (p_ptr->lev / 2)) / p_ptr->lev); } /* Window stuff */ p_ptr->window |= (PW_INVEN | PW_EQUIP); /* Destroy a potion in the pack */ if (item >= 0) { inven_item_increase(item, -1); inven_item_describe(item); inven_item_optimize(item); } /* Destroy a potion on the floor */ else { floor_item_increase(0 - item, -1); floor_item_describe(0 - item); floor_item_optimize(0 - item); } }
void start_game(playerType *player, roomBase *roomdb, objectBase *objectdb, enemyBase *enemydb) { player->quit = 0; player->n_object_ids = 0; player->health = 100; int test_coordinates[2] = { 0, 0 }; int input_size = 0; char input_command[INPUT_LENGTH] = { 0 }; char input_parameter[INPUT_LENGTH] = { 0 }; player->current_room = get_room_from_id(player->starting_room_id, roomdb); set_player_coordinates(player->current_room->coordinates, player); show_room_content(player->current_room, objectdb); while( ! player->quit ) { input_size = player_input(player, input_command, input_parameter); if( COMP_STR(input_command, "exit") || COMP_STR(input_command, "quit") || feof(stdin) ) { printf("Thanks for playing, have a nice day!\n"); player->quit = 1; } else if( COMP_STR(input_command, "look") ) { show_room_content(player->current_room, objectdb); } else if( COMP_STR(input_command, "health") ) { printf("Player HP: %d\n", player->health); } else if( COMP_STR(input_command, "inventory" ) ) { show_inventory(player, objectdb); } else if( COMP_STR(input_command, "examine" ) ) { examine_object(input_parameter, player, objectdb); } else if( COMP_STR(input_command, "take" ) ) { take_object(input_parameter, player, objectdb); } else if( COMP_STR(input_command, "use" ) ) { use_object(input_parameter, player, objectdb, roomdb, enemydb); } else if( COMP_STR(input_command, "north" ) ) { test_coordinates[0] = player->coordinates[0]; test_coordinates[1] = player->coordinates[1] + 1; go_to_room(player, roomdb, test_coordinates, objectdb, enemydb); } else if( COMP_STR(input_command, "south" ) ) { test_coordinates[0] = player->coordinates[0]; test_coordinates[1] = player->coordinates[1] - 1; go_to_room(player, roomdb, test_coordinates, objectdb, enemydb); } else if( COMP_STR(input_command, "east" ) ) { test_coordinates[0] = player->coordinates[0] + 1; test_coordinates[1] = player->coordinates[1]; go_to_room(player, roomdb, test_coordinates, objectdb, enemydb); } else if( COMP_STR(input_command, "west" ) ) { test_coordinates[0] = player->coordinates[0] - 1; test_coordinates[1] = player->coordinates[1]; go_to_room(player, roomdb, test_coordinates, objectdb, enemydb); } else if( COMP_STR(input_command, "help" ) ) { printf("Commands: %s\n", COMMANDS_LIST); } else { if( input_size > 0 ) /* check that the user hasn't simply just pressed enter */ printf("I don't understand that. Type \"help\" for a list of recognised commands\n"); } } }