Crossfire Server, Trunk
|
#include "global.h"
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "object.h"
#include "shop.h"
#include "skills.h"
#include "spells.h"
#include "sproto.h"
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, const recipe *rp, int danger) |
static void | attempt_do_alchemy (object *caster, object *cauldron) |
static object * | attempt_recipe (object *caster, object *cauldron, int ability, const recipe *rp, int nbatches, int ignore_cauldron) |
static int | calc_alch_danger (object *caster, object *cauldron, const recipe *rp) |
static const char * | cauldron_sound (void) |
static float | chance_fn (int diff) |
static int | content_recipe_value (object *op) |
static const recipe * | find_recipe (const recipelist *fl, int formula, object *ingredients) |
static object * | find_transmution_ob (object *first_ingred, const recipe *rp, size_t *rp_arch_index, int create_item) |
static int | is_defined_recipe (const recipe *rp, const object *cauldron) |
static object * | make_item_from_recipe (object *cauldron, const recipe *rp) |
static int | numb_ob_inside (const object *op) |
static float | recipe_chance (const recipe *rp, const object *skill, const object *cauldron) |
static void | remove_contents (object *first_ob, object *save_item) |
int | use_alchemy (object *op) |
Variables | |
static const char *const | cauldron_effect [] |
This contains all alchemy-related functions.
Definition in file alchemy.c.
|
static |
We adjust the nrof of the final product, based on the item's default parameters, and the relevant caster skill level.
item | item to adjust. |
adjust | nrof adjustment parameter, the higher the better. |
yield | how many products the recipe returns at maximum. |
Definition at line 406 of file alchemy.c.
References rndm().
Referenced by attempt_recipe().
|
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.
op | who tried to do alchemy. |
cauldron | container that was used. |
rp | recipe that failed, can be NULL. |
danger | danger value, the higher the more evil the effect. |
Recipe specifies a special failure archetype, so use it instead of evil random things.
Definition at line 550 of file alchemy.c.
References add_string(), recipestruct::arch_name, recipestruct::arch_names, attempt_recipe(), cast_magic_storm(), cauldron_sound(), change_attr_value(), CLEAR_FLAG, create_archetype(), draw_ext_info(), draw_ext_info_format(), recipestruct::failure_arch, recipestruct::failure_message, fire_arch_from_position(), FLAG_CAN_ROLL, FLAG_CURSED, FLAG_IDENTIFIED, FLAG_KNOWN_CURSED, FLAG_NO_PICK, FOOD, FOR_INV_FINISH, FOR_INV_PREPARE, free_string(), generate_artifact(), get_formulalist(), get_random_mon(), get_random_recipe(), commongive::inv, obj::inv, llevDebug, llevError, LOG(), LOOSE_MANA, M_STONE, obj::magic, monster_npc_call_help(), MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, MSG_TYPE_SKILL_SUCCESS, obj::name, NDI_UNIQUE, numb_ob_inside(), object_free_drop_inventory(), object_insert_in_map_at(), object_insert_in_ob(), object_set_enemy(), give::op, PREFER_HIGH, PREFER_LOW, QUERY_FLAG, RANDOM, random_roll(), remove_contents(), rndm(), SET_FLAG, SP_MED_FIREBALL, summon_hostile_monsters(), recipestruct::title, Ice::tmp, nlohmann::detail::void(), obj::x, and obj::y.
Referenced by attempt_do_alchemy().
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.
caster | who is doing alchemy. |
cauldron | the cauldron in which alchemy should take place. |
Definition at line 159 of file alchemy.c.
References alchemy_failure_effect(), recipestruct::arch_name, attempt_recipe(), calc_alch_danger(), recipestruct::cauldron, change_exp(), content_recipe_value(), recipestruct::diff, draw_ext_info(), draw_ext_info_format(), recipestruct::exp, find_recipe(), find_skill_by_name(), FLAG_WIZ, FOR_INV_FINISH, FOR_INV_PREPARE, get_formulalist(), recipestruct::index, obj::inv, is_defined_recipe(), say::item, obj::level, llevDebug, LOG(), obj::magic, recipestruct::min_level, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, MSG_TYPE_SKILL_MISSING, obj::name, NDI_UNIQUE, numb_ob_inside(), PLAYER, PREFER_LOW, price_base(), QUERY_FLAG, random_roll(), recipe_chance(), SK_EXP_NONE, recipestruct::skill, recipestruct::title, Ice::tmp, and obj::type.
Referenced by use_alchemy().
|
static |
Essentially a wrapper for make_item_from_recipe() and object_insert_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)
caster | who is trying to do alchemy. |
cauldron | container used for alchemy. |
ability | ? |
rp | recipe attempted. |
nbatches | ? |
ignore_cauldron | if 0, checks the recipe uses the right cauldron type, else no check is done. |
Definition at line 340 of file alchemy.c.
References adjust_product(), obj::arch, recipestruct::cauldron, cauldron_sound(), draw_ext_info(), draw_ext_info_format(), find_skill_by_name(), FORCE, obj::inv, say::item, recipestruct::keycode, llevDebug, LOG(), make_item_from_recipe(), MAX, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, MSG_TYPE_SKILL_FAILURE, MSG_TYPE_SKILL_SUCCESS, obj::name, archt::name, NDI_UNIQUE, object_find_by_type_and_slaying(), object_insert_in_ob(), POTION, remove_contents(), recipestruct::skill, recipestruct::title, Ice::tmp, and recipestruct::yield.
Referenced by alchemy_failure_effect(), and attempt_do_alchemy().
"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 magical nature of ingredients, 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.
caster | who is trying alchemy. |
cauldron | container used. |
rp | recipe attempted. |
Definition at line 831 of file alchemy.c.
References obj::chosen_skill, recipestruct::diff, FLAG_CURSED, FLAG_DAMNED, FOR_INV_FINISH, FOR_INV_PREPARE, liv::Int, obj::level, llevDebug, LOG(), obj::magic, QUERY_FLAG, and obj::stats.
Referenced by attempt_do_alchemy().
|
static |
Returns a random selection from cauldron_effect[]
Definition at line 77 of file alchemy.c.
References cauldron_effect, and rndm().
Referenced by alchemy_failure_effect(), and attempt_recipe().
|
static |
Compute a success probability, between .01 and .95, based on the level difference.
diff | level difference. |
Definition at line 89 of file alchemy.c.
Referenced by recipe_chance().
|
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
op | contained for which to generate a hash. |
Definition at line 275 of file alchemy.c.
References FOR_INV_FINISH, FOR_INV_PREPARE, llevDebug, LOG(), MAX_BUF, give::name, NROF(), give::op, safe_strncpy, strtoint(), and Ice::tmp.
Referenced by attempt_do_alchemy().
|
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.
fl | list containing the potential formulae based on the number of ingredients. |
formula | hash of the ingredients. |
ingredients | ingredients, linked through the 'below' field. |
Definition at line 970 of file alchemy.c.
References recipestruct::arch_name, find_transmution_ob(), recipestruct::index, recipeliststruct::items, llevDebug, LOG(), recipestruct::next, rotate-tower::result, rndm(), recipestruct::title, and recipestruct::transmute.
Referenced by attempt_do_alchemy().
|
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.
first_ingred | pointer to first item to check |
rp | recipe the player is trying |
rp_arch_index | pointer to return value; set to arch index for recipe; set to zero if not using a transmution formula |
create_item | if set, will create a generic item if no suitable item is found. |
Definition at line 495 of file alchemy.c.
References recipestruct::arch_name, recipestruct::arch_names, create_archetype(), FOR_OB_AND_BELOW_FINISH, FOR_OB_AND_BELOW_PREPARE, say::item, llevDebug, LOG(), RANDOM, and recipestruct::transmute.
Referenced by find_recipe(), and make_item_from_recipe().
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
rp | recipe to check. |
cauldron | container that holds the ingredients. |
Definition at line 888 of file alchemy.c.
References FOR_INV_FINISH, FOR_INV_PREPARE, recipestruct::ingred, MAX_BUF, give::name, linked_char::name, linked_char::next, and guildjoin::ob.
Referenced by attempt_do_alchemy().
Using a list of items and a recipe to make an artifact.
cauldron | the cauldron (including the ingredients) used to make the item |
rp | the recipe to make the artifact from |
Definition at line 431 of file alchemy.c.
References recipestruct::arch_name, find_transmution_ob(), FLAG_CURSED, FLAG_DAMNED, give_artifact_abilities(), obj::inv, is_identified(), artifactstruct::item, say::item, llevDebug, llevError, locate_recipe_artifact(), LOG(), NROF(), object_add_weight(), object_give_identified_properties(), object_sub_weight(), QUERY_FLAG, SET_FLAG, recipestruct::title, recipestruct::transmute, and transmute_materialname().
Referenced by attempt_recipe().
|
static |
Returns the total number of items in op, excluding ones in item's items.
op | container. |
Definition at line 303 of file alchemy.c.
References FOR_INV_FINISH, FOR_INV_PREPARE, llevDebug, LOG(), give::op, and Ice::tmp.
Referenced by alchemy_failure_effect(), and attempt_do_alchemy().
|
static |
Compute the success probability of a recipe.
Probability of success is a function of the difference between the recipe difficulty and the player's skill level, adjusted by the cauldron bonus.
The shape is roughly 1-exp(-x): ---------—+----------— Difference | Probability ---------—+----------— 10 | 0.31 0 | 0.51 -10 | 0.71 -30 | 0.91 <= -35 | 0.95 ---------—+----------—
rp | recipe to attempt. |
skill | skill being used. |
cauldron | provides the magic of the used device. |
Definition at line 121 of file alchemy.c.
References chance_fn(), recipestruct::diff, obj::level, and obj::magic.
Referenced by attempt_do_alchemy().
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).
first_ob | container from which to remove. |
save_item | what item to not remove. Can be NULL. |
Definition at line 798 of file alchemy.c.
References FOR_OB_AND_BELOW_FINISH, FOR_OB_AND_BELOW_PREPARE, object_free_drop_inventory(), object_remove(), and Ice::tmp.
Referenced by alchemy_failure_effect(), and attempt_recipe().
int use_alchemy | ( | object * | op | ) |
Handle use_skill for alchemy-like items.
op | player trying to do alchemy. |
Definition at line 1047 of file alchemy.c.
References attempt_do_alchemy(), draw_ext_info(), draw_ext_info_format(), esrv_send_inventory(), FLAG_APPLIED, FLAG_IS_CAULDRON, FLAG_UNPAID, FLAG_WIZ, FOR_MAP_FINISH, FOR_MAP_PREPARE, MAX_BUF, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DM, MSG_TYPE_SKILL, MSG_TYPE_SKILL_ERROR, give::name, NDI_UNIQUE, object_find_by_flag(), give::op, query_base_name(), QUERY_FLAG, and Ice::tmp.
Referenced by do_skill(), and knowledge_alchemy_attempt().
|
static |
define this for some helpful debuging information define this for loads of (marginal) debuging information Random cauldrons effects
Definition at line 45 of file alchemy.c.
Referenced by cauldron_sound().