Go to the documentation of this file.
41 #define EXTREME_ALCHEMY_DEBUG
47 "produces a cloud of steam",
48 "emits bright flames",
49 "pours forth heavy black smoke",
51 "shoots out small flames",
58 "makes chugging sounds",
59 "smokes heavily for a while"
68 static object *
attempt_recipe(
object *caster,
object *cauldron,
int ability,
const recipe *rp,
int nbatches,
int ignore_cauldron);
91 return MAX(.01, .3 - (diff - 10) * .03);
94 return .5 + .02 * (float)(-diff);
96 return MIN(.95, .70 + (-diff - 10) * .01);
126 const int cauldron_add_skill = (cauldron->
magic + 1) / 2;
127 const int eff_skill = skill->
level + cauldron_add_skill;
162 float success_chance;
163 int numb, ability = 1;
184 if (strcmp(rp->
title,
"NONE"))
191 LOG(
llevDebug,
"WIZ couldn't find formula for ingredients.\n");
198 uint64_t value_ingredients;
200 int attempt_shadow_alchemy;
203 if (rp->
skill != NULL) {
207 "You do not have the proper skill for this recipe");
209 ability += skop->
level*((4.0+cauldron->
magic)/4.0);
223 "You aren't skilled enough to try this recipe.");
228 value_ingredients = 0;
236 if ((
item =
attempt_recipe(caster, cauldron, ability, rp, formula/rp->
index, attempt_shadow_alchemy)) != NULL) {
241 LOG(
llevDebug,
"percent success chance = %f ab%d / diff%d*lev%d\n", success_chance, ability, rp->
diff,
item->level);
245 if (attempt_shadow_alchemy && value_item > value_ingredients) {
248 LOG(
llevDebug,
"Forcing failure for shadow alchemy recipe because price of ingredients (%llu) is less than price of result (%llu).\n", value_ingredients, value_item);
250 LOG(
llevDebug,
"Forcing failure for shadow alchemy recipe because price of ingredients (%I64d) is less than price of result (%I64d).\n", value_ingredients, value_item);
277 int tval = 0, formula = 0;
310 LOG(
llevDebug,
"numb_ob_inside(%s): found %d ingredients\n",
op->name, o_number);
340 static object *
attempt_recipe(
object *caster,
object *cauldron,
int ability,
const recipe *rp,
int nbatches,
int ignore_cauldron) {
341 object *
item = NULL, *skop;
343 int batches = abs(nbatches);
346 if (!ignore_cauldron && (strcmp(rp->
cauldron, cauldron->
arch->
name) != 0)) {
348 "You are not using the proper facilities for this formula.");
364 "You know the ingredients, but not the technique. Go learn how to do this recipe.");
369 #ifdef EXTREME_ALCHEMY_DEBUG
370 LOG(
llevDebug,
"attempt_recipe(): got %d nbatches\n", nbatches);
385 "Nothing happened.");
414 nrof = (1.0-1.0/(adjust/10.0+1.0))*(
rndm(0, yield-1)+
rndm(0, yield-1)+
rndm(0, yield-1))+1;
434 size_t rp_arch_index;
437 return (
object *)NULL;
441 LOG(
llevDebug,
"make_alchemy_item(): failed to create alchemical object.\n");
442 return (
object *)NULL;
446 if (
item->env != NULL)
450 if (strcmp(rp->
title,
"NONE")) {
451 int item_power_delta = 0;
453 LOG(
llevError,
"make_alchemy_item(): failed to locate recipe artifact.\n");
455 return (
object *)NULL;
462 item_power_delta =
item->item_power -
item->arch->clone.item_power;
465 item->item_power += item_power_delta;
471 if (
item->env != NULL)
512 if (i < rp->arch_names)
519 if (create_item && (!
item ||
item->nrof > 1)) {
527 LOG(
llevDebug,
" find_transmutable_ob(): returns arch %s(sp:%d)\n",
item->arch->name,
item->stats.sp);
553 if (!
op || !cauldron)
590 weight +=
inv->weight;
591 if (!(material&
inv->material))
592 material |=
inv->material;
595 tmp->weight = weight;
597 tmp->material = material;
614 }
else if (
level < 40) {
631 if ((
tmp = cauldron->
inv)) {
649 }
while (
rndm(0, 2));
683 }
else if (
level < 50) {
687 switch (
rndm(0, 2)) {
693 "The %s creates a bomb!",
702 "The %s erupts in flame!",
708 }
else if (
level < 60) {
713 }
else if (
level < 80) {
720 "The %s erupts in flame!",
723 }
else if (
level < 100) {
734 "Your %s turns darker then makes a gulping sound!",
738 "Your %s becomes darker.",
741 }
else if (
level < 110) {
749 "The %s %s and then pours forth monsters!",
752 }
else if (
level < 150) {
753 int roll =
rndm(1, 3);
759 }
else if (
level == 151) {
782 "You unwisely release potent forces!");
803 if (
tmp != save_item) {
840 danger -= cauldron->
magic;
858 danger += rp->
diff*3;
867 LOG(
llevDebug,
"calc_alch_danger() returned danger=%d\n", danger);
891 uint32_t batches_in_cauldron;
897 for (ingredient = rp->
ingred; ingredient != NULL; ingredient = ingredient->
next)
901 LOG(
llevDebug,
"cauldron %s, item %s, number %d->%d\n", cauldron->
name,
ob->name, number, number - 1);
909 batches_in_cauldron = 0;
910 for (ingredient = rp->
ingred; ingredient != NULL; ingredient = ingredient->
next) {
918 while (isdigit(*
name)) {
919 nrof = 10*nrof+(*
name-
'0');
933 if (
ob->title == NULL)
936 snprintf(name_ob,
sizeof(name_ob),
"%s %s",
ob->name,
ob->title);
940 if (strcmp(name2,
name) == 0) {
941 if (
ob->nrof%nrof == 0) {
945 batches = (
ob->nrof ?
ob->nrof : 1)/nrof;
947 LOG(
llevDebug,
"batches of ingred %s: %d; batches prior: %d\n",
name, batches, batches_in_cauldron);
949 if (batches_in_cauldron == 0) {
950 batches_in_cauldron = batches;
952 }
else if (batches_in_cauldron == batches)
982 int recipes_matching;
984 size_t rp_arch_index;
986 #ifdef EXTREME_ALCHEMY_DEBUG
990 recipes_matching = 0;
992 for (rp = fl->
items; rp != NULL; rp = rp->
next) {
995 #ifdef EXTREME_ALCHEMY_DEBUG
1001 object *ingredients = cauldron->
inv;
1003 #ifdef EXTREME_ALCHEMY_DEBUG
1007 if (!transmute_found) {
1008 transmute_found = 1;
1009 recipes_matching = 0;
1011 }
else if (transmute_found) {
1012 #ifdef EXTREME_ALCHEMY_DEBUG
1018 #ifdef EXTREME_ALCHEMY_DEBUG
1024 if (
rndm(0, recipes_matching) == 0)
1031 #ifdef ALCHEMY_DEBUG
1032 LOG(
llevDebug,
"couldn't find formula for ingredients.\n");
1037 #ifdef ALCHEMY_DEBUG
1038 if (strcmp(
result->title,
"NONE") != 0)
1058 object *unpaid_cauldron = NULL;
1059 object *unpaid_item = NULL;
1060 int did_alchemy = 0;
1069 unpaid_cauldron =
tmp;
1073 if (unpaid_item != NULL)
1082 if (unpaid_cauldron) {
1085 "You must pay for your %s first!",
1087 }
else if (unpaid_item) {
1090 "You must pay for your %s first!",
static int calc_alch_danger(object *caster, object *cauldron, const recipe *rp)
recipelist * get_formulalist(int i)
void LOG(LogLevel logLevel, const char *format,...)
static const char * cauldron_sound(void)
#define QUERY_FLAG(xyz, p)
uint64_t price_base(const object *obj)
void esrv_send_inventory(object *pl, object *op)
void object_set_enemy(object *op, object *enemy)
static const recipe * find_recipe(const recipelist *fl, int formula, object *cauldron)
void give_artifact_abilities(object *op, const object *artifact)
static void adjust_product(object *item, int lvl, int yield)
static const char *const cauldron_effect[]
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
static void alchemy_failure_effect(object *op, object *cauldron, const recipe *rp, int danger)
static object * attempt_recipe(object *caster, object *cauldron, int ability, const recipe *rp, int nbatches, int ignore_cauldron)
int rndm(int min, int max)
int fire_arch_from_position(object *op, object *caster, int16_t x, int16_t y, int dir, object *spell)
object * object_insert_in_ob(object *op, object *where)
void cast_magic_storm(object *op, object *tmp, int lvl)
void object_free_drop_inventory(object *ob)
static uint32_t NROF(const object *const ob)
static object * find_transmution_ob(object *first_ingred, const recipe *rp, size_t *rp_arch_index, int create_item)
#define FLAG_KNOWN_CURSED
#define MSG_TYPE_COMMAND_DM
sstring add_string(const char *str)
#define FOR_OB_AND_BELOW_FINISH()
int use_alchemy(object *op)
static int numb_ob_inside(const object *op)
int is_identified(const object *op)
static int content_recipe_value(object *op)
object * object_find_by_flag(const object *who, int flag)
struct linked_char * next
#define MSG_TYPE_SKILL_MISSING
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
static void remove_contents(object *first_ob, object *save_item)
#define FOR_OB_AND_BELOW_PREPARE(op_)
int random_roll(int min, int max, const object *op, int goodbad)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
object * find_skill_by_name(object *who, const char *name)
object * create_archetype(const char *name)
static void attempt_do_alchemy(object *caster, object *cauldron)
void free_string(sstring str)
static object * make_item_from_recipe(object *cauldron, const recipe *rp)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
void object_add_weight(object *op, signed long weight)
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
#define MSG_TYPE_SKILL_ERROR
void transmute_materialname(object *op, const object *change)
#define MSG_TYPE_SKILL_FAILURE
recipe * get_random_recipe(recipelist *rpl)
const artifact * locate_recipe_artifact(const recipe *rp, size_t idx)
void change_attr_value(living *stats, int attr, int8_t value)
void monster_npc_call_help(object *op)
int summon_hostile_monsters(object *op, int n, const char *monstername)
static int is_defined_recipe(const recipe *rp, const object *cauldron)
int strtoint(const char *buf)
#define CLEAR_FLAG(xyz, p)
void object_give_identified_properties(object *op)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
object * get_random_mon(int level)
void object_remove(object *op)
static float chance_fn(int diff)
void query_base_name(const object *op, int plural, char *buf, size_t size)
#define MSG_TYPE_SKILL_SUCCESS
void object_sub_weight(object *op, signed long weight)
static float recipe_chance(const recipe *rp, const object *skill, const object *cauldron)
void generate_artifact(object *op, int difficulty)
#define FOR_INV_PREPARE(op_, it_)