Crossfire Server, Branches 1.12  R18729
alchemy.c File Reference
#include <global.h>
#include <object.h>
#include <sproto.h>
#include <skills.h>
#include <spells.h>
+ Include dependency graph for alchemy.c:

Go to the source code of this file.

Functions

static void adjust_product (object *item, int lvl, int yield)
 
static void alchemy_failure_effect (object *op, object *cauldron, recipe *rp, int danger)
 
static void attempt_do_alchemy (object *caster, object *cauldron)
 
static objectattempt_recipe (object *caster, object *cauldron, int ability, recipe *rp, int nbatches, int ignore_cauldron)
 
static int calc_alch_danger (object *caster, object *cauldron, recipe *rp)
 
static const char * cauldron_sound (void)
 
static int content_recipe_value (object *op)
 
static recipefind_recipe (recipelist *fl, int formula, object *ingredients)
 
static objectfind_transmution_ob (object *first_ingred, recipe *rp, size_t *rp_arch_index, int create_item)
 
static int is_defined_recipe (const recipe *rp, const object *cauldron, object *caster)
 
static objectmake_item_from_recipe (object *cauldron, recipe *rp)
 
static int numb_ob_inside (object *op)
 
static void remove_contents (object *first_ob, object *save_item)
 
int use_alchemy (object *op)
 

Variables

static const char *const cauldron_effect []
 

Detailed Description

This contains all alchemy-related functions.

Definition in file alchemy.c.

Function Documentation

static void adjust_product ( object item,
int  lvl,
int  yield 
)
static

We adjust the nrof of the final product, based on the item's default parameters, and the relevant caster skill level.

Parameters
itemitem to adjust.
lvlalchemy skill level.
yieldhow many products the recipe returns at maximum.

Definition at line 373 of file alchemy.c.

References obj::nrof, and rndm().

Referenced by attempt_recipe().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void alchemy_failure_effect ( object op,
object cauldron,
recipe rp,
int  danger 
)
static

Ouch. We didnt get the formula we wanted. This fctn simulates the backfire effects–worse effects as the level increases. If SPELL_FAILURE_EFFECTS is defined some really evil things can happen to the would be alchemist. This table probably needs some adjustment for playbalance. -b.t.

Parameters
opwho tried to do alchemy.
cauldroncontainer that was used.
rprecipe that failed.
dangerdanger value, the higher the more evil the effect.

Definition at line 502 of file alchemy.c.

References add_string(), obj::arch, recipestruct::arch_name, recipestruct::arch_names, attempt_recipe(), obj::below, cast_magic_storm(), cauldron_sound(), change_attr_value(), CLEAR_FLAG, create_archetype(), liv::dam, draw_ext_info(), draw_ext_info_format(), obj::enemy, fire_arch_from_position(), FLAG_CAN_ROLL, FLAG_CURSED, FLAG_IDENTIFIED, FLAG_KNOWN_CURSED, FLAG_NO_PICK, FOOD, free_object(), free_string(), generate_artifact(), get_formulalist(), get_random_mon(), get_random_recipe(), liv::hp, insert_ob_in_map(), insert_ob_in_ob(), obj::inv, obj::level, llevDebug, LOG(), LOOSE_MANA, M_STONE, obj::magic, obj::map, obj::material, obj::materialname, obj::move_block, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, MSG_TYPE_SKILL_SUCCESS, obj::name, archt::name, obj::name_pl, NDI_UNIQUE, npc_call_help(), numb_ob_inside(), PREFER_HIGH, PREFER_LOW, QUERY_FLAG, random_roll(), remove_contents(), rndm(), SET_FLAG, SP_MED_FIREBALL, obj::stats, summon_hostile_monsters(), obj::type, obj::value, obj::weight, obj::x, and obj::y.

Referenced by attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void attempt_do_alchemy ( object caster,
object cauldron 
)
static

Main part of the ALCHEMY code. From this we call fctns that take a look at the contents of the 'cauldron' and, using these ingredients, we construct an integer formula value which is referenced (randomly) against a formula list (the formula list chosen is based on the # contents of the cauldron).

If we get a match between the recipe indicated in cauldron contents and a randomly chosen one, an item is created and experience awarded. Otherwise various failure effects are possible (getting worse and worse w/ # cauldron ingredients). Note that the 'item' to be made can be *anything *listed on the artifacts list in lib/artifacts which has a recipe listed in lib/formulae.

To those wondering why I am using the funky formula index method: 1) I want to match recipe to ingredients regardless of ordering. 2) I want a fast search for the 'right' recipe.

Note: it is just possible that a totally different combination of ingredients will result in a match with a given recipe. This is not a bug! There is no good reason (in my mind) why alchemical processes have to be unique – such a 'feature' is one reason why players might want to experiment around. :) -b.t.

Parameters
casterwho is doing alchemy.
cauldronthe cauldron in which alchemy should take place.

Definition at line 121 of file alchemy.c.

References alchemy_failure_effect(), recipestruct::arch_name, attempt_recipe(), obj::below, calc_alch_danger(), recipestruct::cauldron, change_exp(), content_recipe_value(), recipestruct::diff, draw_ext_info(), draw_ext_info_format(), recipestruct::exp, F_IDENTIFIED, F_NOT_CURSED, F_TRUE, find_recipe(), find_skill_by_name(), FLAG_WIZ, get_formulalist(), recipestruct::index, obj::inv, is_defined_recipe(), obj::level, llevDebug, LOG(), obj::magic, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, MSG_TYPE_SKILL_MISSING, obj::name, NDI_UNIQUE, numb_ob_inside(), recipeliststruct::number, PLAYER, PREFER_LOW, query_cost(), QUERY_FLAG, random_roll(), SK_EXP_NONE, recipestruct::skill, recipestruct::title, recipeliststruct::total_chance, and obj::type.

Referenced by use_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static object * attempt_recipe ( object caster,
object cauldron,
int  ability,
recipe rp,
int  nbatches,
int  ignore_cauldron 
)
static

Essentially a wrapper for make_item_from_recipe() and insert_ob_in_ob(). If the caster has some alchemy skill, then they might gain some exp from (successfull) fabrication of the product. If nbatches==-1, don't give exp for this creation (random generation/ failed recipe) If ignore_cauldron, don't check if we are using the matching cauldron type (shadow alchemy)

Parameters
casterwho is trying to do alchemy.
cauldroncontainer used for alchemy.
ability?
rprecipe attempted.
nbatches?
ignore_cauldronif 0, checks the recipe uses the right cauldron type, else no check is done.
Returns
generated item, can be NULL if contents were destroyed.
Todo:
check meaning of ability/nbatches.

Definition at line 305 of file alchemy.c.

References adjust_product(), obj::arch, obj::below, recipestruct::cauldron, cauldron_sound(), draw_ext_info(), draw_ext_info_format(), obj::env, find_skill_by_name(), FORCE, insert_ob_in_ob(), obj::inv, recipestruct::keycode, llevDebug, LOG(), make_item_from_recipe(), MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_FAILURE, MSG_TYPE_SKILL_SUCCESS, obj::name, archt::name, NDI_UNIQUE, remove_contents(), recipestruct::skill, obj::slaying, recipestruct::title, obj::type, and recipestruct::yield.

Referenced by alchemy_failure_effect(), and attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int calc_alch_danger ( object caster,
object cauldron,
recipe rp 
)
static

"Danger" level, will determine how bad the backfire could be if the user fails to concoct a recipe properly. Factors include the number of ingredients, the length of the name of each ingredient, the user's effective level, the user's Int and the enchantment on the mixing device (aka "cauldron"). Higher values of 'danger' indicate more danger. Note that we assume that we have had the caster ready the alchemy skill *before *this routine is called. (no longer auto-readies that skill) -b.t.

Parameters
casterwho is trying alchemy.
cauldroncontainer used.
rprecipe attempted.
Returns
danger value.

Definition at line 783 of file alchemy.c.

References obj::below, obj::chosen_skill, recipestruct::diff, FLAG_CURSED, FLAG_DAMNED, liv::Int, obj::inv, obj::level, llevDebug, LOG(), obj::magic, MAX_BUF, obj::name, QUERY_FLAG, snprintf(), obj::stats, strtoint(), and obj::title.

Referenced by attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static const char* cauldron_sound ( void  )
static

Returns a random selection from cauldron_effect[]

Definition at line 87 of file alchemy.c.

References cauldron_effect, and rndm().

Referenced by alchemy_failure_effect(), and attempt_recipe().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int content_recipe_value ( object op)
static

Recipe value of the entire contents of a container. This appears to just generate a hash value, which I guess for now works ok, but the possibility of duplicate hashes is certainly possible - msw

Parameters
opcontained for which to generate a hash.
Returns
hash value.

Definition at line 236 of file alchemy.c.

References obj::below, obj::inv, llevDebug, LOG(), MAX_BUF, obj::name, obj::nrof, snprintf(), strtoint(), and obj::title.

Referenced by attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static recipe * find_recipe ( recipelist fl,
int  formula,
object ingredients 
)
static

Find a recipe from a recipe list that matches the given formula. If there is more than one matching recipe, it selects a random one. If at least one transmuting recipe matches, it only considers matching transmuting recipes.

Parameters
fl?
formula?
ingredients?
Returns
one matching recipe, or NULL if no recipe matches
Todo:
document parameters.

Definition at line 929 of file alchemy.c.

References recipestruct::arch_name, find_transmution_ob(), recipestruct::index, recipeliststruct::items, llevDebug, LOG(), recipestruct::next, rndm(), recipestruct::title, and recipestruct::transmute.

Referenced by attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static object * find_transmution_ob ( object first_ingred,
recipe rp,
size_t *  rp_arch_index,
int  create_item 
)
static

Looks through the ingredient list. If we find a suitable object in it - we will use that to make the requested artifact. Otherwise the code returns a 'generic' item if create_item is set. -b.t.

Parameters
first_ingredpointer to first item to check
rprecipe the player is trying
rp_arch_indexpointer to return value; set to arch index for recipe; set to zero if not using a transmution formula
create_itemif set, will create a generic item if no suitable item is found.
Returns
NULL if no suitable item was found and create_item is 0, existing or new item else.

Definition at line 450 of file alchemy.c.

References obj::arch, recipestruct::arch_name, recipestruct::arch_names, obj::below, create_archetype(), llevDebug, LOG(), archt::name, obj::nrof, liv::sp, obj::stats, and recipestruct::transmute.

Referenced by find_recipe(), and make_item_from_recipe().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int is_defined_recipe ( const recipe rp,
const object cauldron,
object caster 
)
static

Determines if ingredients in a container match the proper ingredients for a recipe.

This functions tries to find each defined ingredient in the container. It is the defined recipe iff

  • the number of ingredients of the recipe and in the container is equal
  • all ingredients of the recipe are found in the container
  • the number of batches is the same for all ingredients
Parameters
rprecipe to check.
cauldroncontainer that holds the ingredients.
casterwho is trying to cast.
Returns
1 if the ingredients match the recipe, 0 if not.

Definition at line 845 of file alchemy.c.

References obj::below, recipestruct::ingred, obj::inv, MAX_BUF, linked_char::name, obj::name, linked_char::next, obj::nrof, snprintf(), and obj::title.

Referenced by attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static object * make_item_from_recipe ( object cauldron,
recipe rp 
)
static

Using a list of items and a recipe to make an artifact.

Parameters
cauldronthe cauldron (including the ingredients) used to make the item
rpthe recipe to make the artifact from
Returns
the newly created object, NULL if something failed

Definition at line 398 of file alchemy.c.

References add_weight(), recipestruct::arch_name, obj::env, find_transmution_ob(), FLAG_CURSED, FLAG_DAMNED, give_artifact_abilities(), obj::inv, artifactstruct::item, llevDebug, llevError, locate_recipe_artifact(), LOG(), obj::nrof, QUERY_FLAG, SET_FLAG, sub_weight(), recipestruct::title, transmute_materialname(), and obj::weight.

Referenced by attempt_recipe().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int numb_ob_inside ( object op)
static

Returns the total number of items in op, excluding ones in item's items.

Parameters
opcontainer.
Returns
total item count.

Definition at line 266 of file alchemy.c.

References obj::below, obj::inv, llevDebug, LOG(), and obj::name.

Referenced by alchemy_failure_effect(), and attempt_do_alchemy().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void remove_contents ( object first_ob,
object save_item 
)
static

All but object "save_item" are elimentated from the container list. Note we have to becareful to remove the inventories of objects in the cauldron inventory (ex icecube has stuff in it).

Parameters
first_obcontainer from which to remove.
save_itemwhat item to not remove. Can be NULL.

Definition at line 745 of file alchemy.c.

References obj::below, free_object(), obj::inv, and remove_ob().

Referenced by alchemy_failure_effect(), and attempt_recipe().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int use_alchemy ( object op)

Handle use_skill for alchemy-like items.

Parameters
opplayer trying to do alchemy.
Returns
1 if any recipe was attempted, 0 else.
Note
Will inform player if attempting to use unpaid cauldron or ingredient.
Todo:
check if no superflous message when 2 cauldrons on same spot, one unpaid? (shouldn't happen, but well).

Definition at line 1006 of file alchemy.c.

References obj::above, attempt_do_alchemy(), obj::below, draw_ext_info_format(), esrv_send_inventory(), FLAG_APPLIED, FLAG_IS_CAULDRON, FLAG_UNPAID, GET_MAP_OB, obj::inv, obj::map, MAX_BUF, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, NDI_UNIQUE, query_base_name(), QUERY_FLAG, obj::x, and obj::y.

Referenced by do_skill().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

const char* const cauldron_effect[]
static
Initial value:
= {
"vibrates briefly",
"produces a cloud of steam",
"emits bright flames",
"pours forth heavy black smoke",
"emits sparks",
"shoots out small flames",
"whines painfully",
"hiccups loudly",
"wheezes",
"burps",
"shakes",
"rattles",
"makes chugging sounds",
"smokes heavily for a while"
}

define this for some helpful debuging information define this for loads of (marginal) debuging information Random cauldrons effects

Definition at line 55 of file alchemy.c.

Referenced by cauldron_sound().