/** * Returns information about objects that can be used for digging. * * `deciturns` will be filled in with the avg number of deciturns it will * take to dig through each type of diggable terrain, and must be at least * [DIGGING_MAX]. * * Returns FALSE if the object has no effect on digging, or if the specifics * are meaningless (i.e. the object is an ego template, not a real item). */ static bool obj_known_digging(struct object *obj, int deciturns[]) { player_state state; int i; int chances[DIGGING_MAX]; int slot = wield_slot(obj); struct object *current = slot_object(player, slot); if (!tval_is_wearable(obj) || (!tval_is_melee_weapon(obj) && (obj->modifiers[OBJ_MOD_TUNNEL] <= 0))) return FALSE; /* Pretend we're wielding the object */ player->body.slots[slot].obj = obj; /* Calculate the player's hypothetical state */ calc_bonuses(player->gear, &state, TRUE); /* Stop pretending */ player->body.slots[slot].obj = current; calc_digging_chances(&state, chances); /* Digging chance is out of 1600 */ for (i = DIGGING_RUBBLE; i < DIGGING_MAX; i++) { int chance = MIN(1600, chances[i]); deciturns[i] = chance ? (16000 / chance) : 0; } return TRUE; }
/** * Attempt to make an object * * \param c is the current dungeon level. * \param lev is the creation level of the object (not necessarily == depth). * \param good is whether the object is to be good * \param great is whether the object is to be great * \param extra_roll is whether we get an extra roll in apply_magic() * \param value is the value to be returned to the calling function * \param tval is the desired tval, or 0 if we allow any tval * * \return a pointer to the newly allocated object, or NULL on failure. */ struct object *make_object(struct chunk *c, int lev, bool good, bool great, bool extra_roll, s32b *value, int tval) { int base; struct object_kind *kind; struct object *new_obj; /* Try to make a special artifact */ if (one_in_(good ? 10 : 1000)) { new_obj = make_artifact_special(lev); if (new_obj) { if (value) *value = object_value_real(new_obj, 1, false); return new_obj; } /* If we failed to make an artifact, the player gets a good item */ good = true; } /* Base level for the object */ base = (good ? (lev + 10) : lev); /* Try to choose an object kind */ kind = get_obj_num(base, good || great, tval); if (!kind) return NULL; /* Make the object, prep it and apply magic */ new_obj = object_new(); object_prep(new_obj, kind, lev, RANDOMISE); if (one_in_(20) && tval_is_wearable(new_obj)) { apply_curse(new_obj, &lev); } apply_magic(new_obj, lev, true, good, great, extra_roll); apply_curse_knowledge(new_obj); /* Generate multiple items */ if (kind->gen_mult_prob >= randint1(100)) new_obj->number = randcalc(kind->stack_size, lev, RANDOMISE); if (new_obj->number > z_info->stack_size) new_obj->number = z_info->stack_size; /* Get the value */ if (value) *value = object_value_real(new_obj, new_obj->number, false); /* Boost of 20% per level OOD for uncursed objects */ if ((!new_obj->curses) && (kind->alloc_min > c->depth)) { if (value) *value += (kind->alloc_min - c->depth) * (*value / 5); } return new_obj; }
/** * Gives the known effects of using the given item. * * Fills in: * - the effect * - whether the effect can be aimed * - the minimum and maximum time in game turns for the item to recharge * (or zero if it does not recharge) * - the percentage chance of the effect failing when used * * Return false if the object has no effect. */ static bool obj_known_effect(const struct object *obj, struct effect **effect, bool *aimed, int *min_recharge, int *max_recharge, int *failure_chance) { random_value timeout = {0, 0, 0, 0}; bool store_consumable = object_is_in_store(obj) && tval_is_useable(obj); *effect = NULL; *min_recharge = 0; *max_recharge = 0; *failure_chance = 0; *aimed = false; if (object_effect_is_known(obj) || store_consumable) { *effect = object_effect(obj); timeout = obj->time; if (effect_aim(*effect)) *aimed = true;; } else if (object_effect(obj) && !tval_is_wearable(obj)) { /* Don't know much - be vague */ *effect = NULL; if (!obj->artifact && effect_aim(object_effect(obj))) { *aimed = true; } return true; } else { /* No effect - no info */ return false; } if (randcalc(timeout, 0, MAXIMISE) > 0) { *min_recharge = randcalc(timeout, 0, MINIMISE); *max_recharge = randcalc(timeout, 0, MAXIMISE); } if (tval_is_edible(obj) || tval_is_potion(obj) || tval_is_scroll(obj)) { *failure_chance = 0; } else { *failure_chance = get_use_device_chance(obj); } return true; }
/** * Returns information about objects that can be used for digging. * * `deciturns` will be filled in with the avg number of deciturns it will * take to dig through each type of diggable terrain, and must be at least * [DIGGING_MAX]. * * Returns false if the object has no effect on digging, or if the specifics * are meaningless (i.e. the object is an ego template, not a real item). */ static bool obj_known_digging(struct object *obj, int deciturns[]) { struct player_state state; int i; int chances[DIGGING_MAX]; int slot = wield_slot(obj); struct object *current = slot_object(player, slot); /* Doesn't remotely resemble a digger */ if (!tval_is_wearable(obj) || (!tval_is_melee_weapon(obj) && (obj->modifiers[OBJ_MOD_TUNNEL] <= 0))) return false; /* Player has no digging info */ if (!tval_is_melee_weapon(obj) && !obj->known->modifiers[OBJ_MOD_TUNNEL]) return false; /* Pretend we're wielding the object */ player->body.slots[slot].obj = obj; /* Calculate the player's hypothetical state */ memcpy(&state, &player->state, sizeof(state)); state.stat_ind[STAT_STR] = 0; //Hack - NRM state.stat_ind[STAT_DEX] = 0; //Hack - NRM calc_bonuses(player, &state, true, false); /* Stop pretending */ player->body.slots[slot].obj = current; calc_digging_chances(&state, chances); /* Digging chance is out of 1600 */ for (i = DIGGING_RUBBLE; i < DIGGING_MAX; i++) { int chance = MIN(1600, chances[i]); deciturns[i] = chance ? (16000 / chance) : 0; } return true; }