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");
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;
283 snprintf(name,
sizeof(name),
"%s %s", tmp->name, tmp->title);
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")) {
452 LOG(
llevError,
"make_alchemy_item(): failed to locate recipe artifact.\n");
454 return (
object *)NULL;
463 if (item->
env != NULL)
504 if (i < rp->arch_names)
511 if (create_item && (!item || item->
nrof > 1)) {
545 if (!op || !cauldron)
569 LOG(
llevDebug,
"Alchemy_failure_effect(): using level=%d\n", level);
606 }
else if (level < 40) {
623 if ((tmp = cauldron->
inv)) {
641 }
while (
rndm(0, 2));
675 }
else if (level < 50) {
679 switch (
rndm(0, 2)) {
685 "The %s creates a bomb!",
694 "The %s erupts in flame!",
700 }
else if (level < 60) {
705 }
else if (level < 80) {
712 "The %s erupts in flame!",
715 }
else if (level < 100) {
726 "Your %s turns darker then makes a gulping sound!",
730 "Your %s becomes darker.",
733 }
else if (level < 110) {
741 "The %s %s and then pours forth monsters!",
744 }
else if (level < 150) {
745 int roll =
rndm(1, 3);
751 }
else if (level == 151) {
774 "You unwisely release potent forces!");
795 if (tmp != save_item) {
830 danger -= cauldron->
magic;
848 danger += rp->
diff*3;
857 LOG(
llevDebug,
"calc_alch_danger() returned danger=%d\n", danger);
889 for (ingredient = rp->
ingred; ingredient != NULL; ingredient = ingredient->
next)
898 batches_in_cauldron = 0;
899 for (ingredient = rp->
ingred; ingredient != NULL; ingredient = ingredient->
next) {
905 name = ingredient->
name;
907 while (isdigit(*name)) {
908 nrof = 10*nrof+(*name-
'0');
929 if (strcmp(name2, name) == 0) {
934 if (batches_in_cauldron == 0) {
935 batches_in_cauldron = batches;
937 }
else if (batches_in_cauldron == batches)
967 int recipes_matching;
969 size_t rp_arch_index;
971 #ifdef EXTREME_ALCHEMY_DEBUG 975 recipes_matching = 0;
977 for (rp = fl->
items; rp != NULL; rp = rp->
next) {
979 if (formula%rp->
index != 0) {
980 #ifdef EXTREME_ALCHEMY_DEBUG 986 if (rp->
transmute && find_transmution_ob(ingredients, rp, &rp_arch_index, 0) != NULL) {
987 #ifdef EXTREME_ALCHEMY_DEBUG 991 if (!transmute_found) {
993 recipes_matching = 0;
995 }
else if (transmute_found) {
996 #ifdef EXTREME_ALCHEMY_DEBUG 1002 #ifdef EXTREME_ALCHEMY_DEBUG 1008 if (
rndm(0, recipes_matching) == 0)
1014 if (result == NULL) {
1015 #ifdef ALCHEMY_DEBUG 1016 LOG(
llevDebug,
"couldn't find formula for ingredients.\n");
1021 #ifdef ALCHEMY_DEBUG 1022 if (strcmp(result->
title,
"NONE") != 0)
1042 object *unpaid_cauldron = NULL;
1043 object *unpaid_item = NULL;
1044 int did_alchemy = 0;
1053 unpaid_cauldron = tmp;
1057 if (unpaid_item != NULL)
1066 if (unpaid_cauldron) {
1069 "You must pay for your %s first!",
1071 }
else if (unpaid_item) {
1074 "You must pay for your %s first!",
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
static void alchemy_failure_effect(object *op, object *cauldron, const recipe *rp, int danger)
static void attempt_do_alchemy(object *caster, object *cauldron)
void object_give_identified_properties(object *op)
void object_sub_weight(object *op, signed long weight)
recipe * get_random_recipe(recipelist *rpl)
static void adjust_product(object *item, int lvl, int yield)
object * get_random_mon(int level)
static int numb_ob_inside(const object *op)
void free_string(sstring str)
static uint32_t NROF(const object *const ob)
void query_base_name(const object *op, int plural, char *buf, size_t size)
void esrv_send_inventory(object *pl, object *op)
object * object_find_by_flag(const object *who, int flag)
#define MSG_TYPE_SKILL_MISSING
object * object_find_by_type_and_slaying(const object *who, int type, const char *slaying)
#define MSG_TYPE_SKILL_ERROR
static const char *const cauldron_effect[]
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
void transmute_materialname(object *op, const object *change)
#define FOR_OB_AND_BELOW_FINISH()
int rndm(int min, int max)
struct obj * chosen_skill
void object_free_drop_inventory(object *ob)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
static float chance_fn(int diff)
int is_identified(const object *op)
object * create_archetype(const char *name)
object * object_insert_in_ob(object *op, object *where)
static const recipe * find_recipe(const recipelist *fl, int formula, object *ingredients)
static int content_recipe_value(object *op)
const char * materialname
void monster_npc_call_help(object *op)
const artifact * locate_recipe_artifact(const recipe *rp, size_t idx)
static object * attempt_recipe(object *caster, object *cauldron, int ability, const recipe *rp, int nbatches, int ignore_cauldron)
int summon_hostile_monsters(object *op, int n, const char *monstername)
struct linked_char * next
int strtoint(const char *buf)
void change_attr_value(living *stats, int attr, int8_t value)
uint64_t price_base(const object *obj)
#define MSG_TYPE_SKILL_FAILURE
void cast_magic_storm(object *op, object *tmp, int lvl)
static int calc_alch_danger(object *caster, object *cauldron, const recipe *rp)
unsigned __int64 uint64_t
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
void generate_artifact(object *op, int difficulty)
void give_artifact_abilities(object *op, const object *artifact)
#define FLAG_KNOWN_CURSED
static int is_defined_recipe(const recipe *rp, const object *cauldron, object *caster)
static object * make_item_from_recipe(object *cauldron, const recipe *rp)
void object_set_enemy(object *op, object *enemy)
struct recipestruct * next
static float recipe_chance(const recipe *rp, const object *skill, const object *cauldron)
int fire_arch_from_position(object *op, object *caster, int16_t x, int16_t y, int dir, object *spell)
#define FOR_OB_AND_BELOW_PREPARE(op_)
sstring add_string(const char *str)
void object_add_weight(object *op, signed long weight)
void LOG(LogLevel logLevel, const char *format,...)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
static object * find_transmution_ob(object *first_ingred, const recipe *rp, size_t *rp_arch_index, int create_item)
#define MSG_TYPE_SKILL_SUCCESS
static const char * cauldron_sound(void)
int random_roll(int min, int max, const object *op, int goodbad)
int use_alchemy(object *op)
object * find_skill_by_name(object *who, const char *name)
static void remove_contents(object *first_ob, object *save_item)
struct recipestruct * items
recipelist * get_formulalist(int i)
#define FOR_INV_PREPARE(op_, it_)
void object_remove(object *op)
#define MSG_TYPE_COMMAND_DM