void item_list::handle_dropped() { int num_items = count_items_at(current_dungeon, player.pos.x, player.pos.y); if ((num_items + m_chosen_items.size()) >= 26) { append_msg_log("No room to drop all this stuff here!"); return; } bool did_drop = false; for (auto it = m_chosen_items.begin(); it != m_chosen_items.end(); ++it) { bool item_type = false; for (int i = 0; i < MAX_EQUIP; i++) { if (player.equipment[i] == *it) { append_msg_log("You can't drop an item you have equipped."); item_type = true; } } int index = get_index_for_item_in_inventory(*it); if (!item_type && index > -1) { tile_t* tile = get_tile_at(current_dungeon, player.pos.x, player.pos.y); ShopEnum sell_result = SHOP_NO_SHOPKEEPER; if ((tile->properties & TILE_PROP_SHOP)) { sell_result = sell_item(*it); } if (sell_result == SHOP_NO_SHOPKEEPER) { if ((*it)->stacksize > 1) { append_msg_log("Dropped all your %s.", (*it)->plural); } else { append_msg_log("Dropped a %s.", (*it)->get_item_name().c_str()); } } // If in a shop and you couldn't sell the item, do not drop it! if (sell_result != SHOP_NOT_ENOUGH_GOLD) { nullify_item_at(index); add_item_to_dungeon(current_dungeon, (*it), player.pos.x, player.pos.y); did_drop = true; } } } if (did_drop) { player.ap -= ITEM_DROP_COST; } }
/** * Withdraw money player previously stored in bank object. * @param op Player. * @param bank Bank object in player's inventory. * @param text What was said to trigger this. * @retval 1 Money withdrawn successfully. * @retval 0 Failed to withdraw money. * @retval -1 The text parameter was invalid. */ int bank_withdraw(object *op, object *bank, char *text) { int pos = 0; sint64 big_value; _money_block money; get_word_from_string(text, &pos); get_money_from_string(text + pos , &money); if (!money.mode) { new_draw_info(NDI_UNIQUE, op, "Withdraw what?\nUse 'withdraw all' or 'withdraw 30 gold, 20 silver...'"); return -1; } else if (money.mode == MONEYSTRING_ALL) { sell_item(NULL, op, bank->value); bank->value = 0; fix_player(op); } else { /* Just to set a border.... */ if (money.mithril > 100000 || money.gold > 100000 || money.silver > 1000000 || money.copper > 1000000) { new_draw_info(NDI_UNIQUE, op, "Withdraw values are too high."); return 1; } big_value = money.mithril * coins_arch[0]->clone.value + money.gold * coins_arch[1]->clone.value + money.silver * coins_arch[2]->clone.value + money.copper * coins_arch[3]->clone.value; if (big_value > bank->value) { return 0; } if (money.mithril) { insert_money_in_player(op, &coins_arch[0]->clone, money.mithril); } if (money.gold) { insert_money_in_player(op, &coins_arch[1]->clone, money.gold); } if (money.silver) { insert_money_in_player(op, &coins_arch[2]->clone, money.silver); } if (money.copper) { insert_money_in_player(op, &coins_arch[3]->clone, money.copper); } bank->value -= big_value; fix_player(op); } return 1; }
/** * Drop an object onto the floor. * @param op Player object. * @param tmp The object to drop. * @param nrof Number of items to drop (0 for all). */ void drop_object(object *op, object *tmp, long nrof) { object *floor; if (QUERY_FLAG(tmp, FLAG_NO_DROP) && !QUERY_FLAG(op, FLAG_WIZ)) { return; } if (op->type == PLAYER) { CONTR(op)->praying = 0; } if (QUERY_FLAG(tmp, FLAG_APPLIED)) { /* Can't unapply it */ if (apply_special(op, tmp, AP_UNAPPLY | AP_NO_MERGE)) { return; } } if (tmp->type == CONTAINER) { container_unlink(NULL, tmp); } /* Trigger the DROP event */ if (trigger_event(EVENT_DROP, op, tmp, NULL, NULL, nrof, 0, 0, SCRIPT_FIX_ACTIVATOR)) { return; } /* We are only dropping some of the items. We split the current * object off. */ if (nrof && tmp->nrof != (uint32) nrof) { object *tmp2 = tmp, *tmp2_cont = tmp->env; tag_t tmp2_tag = tmp2->count; char err[MAX_BUF]; tmp = get_split_ob(tmp, nrof, err, sizeof(err)); if (!tmp) { new_draw_info(NDI_UNIQUE, op, err); return; } /* Tell the client what happened to the rest of the objects. tmp2 * is now the original object */ if (op->type == PLAYER) { if (was_destroyed(tmp2, tmp2_tag)) { esrv_del_item(CONTR(op), tmp2_tag, tmp2_cont); } else { esrv_send_item(op, tmp2); } } } else { remove_ob(tmp); if (check_walk_off(tmp, NULL, MOVE_APPLY_DEFAULT) != CHECK_WALK_OK) { return; } } if (QUERY_FLAG(tmp, FLAG_STARTEQUIP) || QUERY_FLAG(tmp, FLAG_UNPAID)) { if (op->type == PLAYER) { new_draw_info_format(NDI_UNIQUE, op, "You drop the %s.", query_name(tmp, NULL)); esrv_del_item(CONTR(op), tmp->count, tmp->env); if (QUERY_FLAG(tmp, FLAG_UNPAID)) { new_draw_info(NDI_UNIQUE, op, "The shop magic put it back to the storage."); floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0); /* If the player is standing on a unique shop floor or unique randomitems shop floor, drop the object back to the floor */ if (floor && floor->type == SHOP_FLOOR && (QUERY_FLAG(floor, FLAG_IS_MAGICAL) || (floor->randomitems && QUERY_FLAG(floor, FLAG_CURSED)))) { tmp->x = op->x; tmp->y = op->y; insert_ob_in_map(tmp, op->map, op, 0); } } else { new_draw_info(NDI_UNIQUE, op, "The god-given item vanishes to nowhere as you drop it!"); } } fix_player(op); return; } /* If SAVE_INTERVAL is commented out, we never want to save * the player here. */ #ifdef SAVE_INTERVAL if (op->type == PLAYER && !QUERY_FLAG(tmp, FLAG_UNPAID) && (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000) && (CONTR(op)->last_save_time + SAVE_INTERVAL) <= time(NULL)) { save_player(op, 1); CONTR(op)->last_save_time = time(NULL); } #endif floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0); if (floor && floor->type == SHOP_FLOOR && !QUERY_FLAG(tmp, FLAG_UNPAID) && tmp->type != MONEY) { sell_item(tmp, op, -1); /* Ok, we have really sold it - not only dropped. Run this only * if the floor is not magical (i.e., unique shop) */ if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(floor, FLAG_IS_MAGICAL)) { if (op->type == PLAYER) { new_draw_info(NDI_UNIQUE, op, "The shop magic put it to the storage."); esrv_del_item(CONTR(op), tmp->count, tmp->env); } fix_player(op); if (op->type == PLAYER) { esrv_send_item(op, op); } return; } } tmp->x = op->x; tmp->y = op->y; if (op->type == PLAYER) { esrv_del_item(CONTR(op), tmp->count, tmp->env); } insert_ob_in_map(tmp, op->map, op, 0); SET_FLAG(op, FLAG_NO_APPLY); remove_ob(op); insert_ob_in_map(op, op->map, op, INS_NO_MERGE | INS_NO_WALK_ON); CLEAR_FLAG(op, FLAG_NO_APPLY); /* Need to update the weight for the player */ if (op->type == PLAYER) { fix_player(op); esrv_send_item(op, op); } }