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)
591 if (!(material&
inv->material))
592 material |=
inv->material;
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 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)
Plugin animator file specs[Config] name
void cast_magic_storm(object *op, object *tmp, int lvl)
void transmute_materialname(object *op, const object *change)
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_)
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your and press< Return > You can also use say if you feel like typing a little extra Other NPCs may not speak to but display intelligence with their movement Some monsters can be and may attack the nearest of your enemies Others can be in that they follow you around and help you in your quest to kill enemies and find treasure SPECIAL ITEMS There are many special items which can be found in of these the most important may be the signs all a player must do is apply the handle In the case of the player must move items over the button to hold it down Some of the larger buttons may need very large items to be moved onto before they can be activated Gates and locked but be for you could fall down into a pit full of ghosts or dragons and not be able to get back out Break away sometimes it may be worth a player s time to test the walls of a map for secret doors Fire such as missile weapons and spells you will notice them going up in smoke ! So be careful not to destroy valuable items Spellbooks sometimes a player can learn the other times they cannot There are many different types of books and scrolls out there Improve item have lower weight
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
#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)
int random_roll(int min, int max, const object *op, int goodbad)
void object_give_identified_properties(object *op)
object * get_random_mon(int level)
void object_remove(object *op)
static float chance_fn(int diff)
No space after the left no space before the right paren Comma right after the formal space right after the comma Local variable names Just a rules of thumb These are ok
int rndm(int min, int max)
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_)