 |
Crossfire Server, Trunk
1.75.0
|
Go to the documentation of this file.
47 static void build_stringlist(
const char *str,
char ***result_list,
size_t *result_size);
102 while (fl && number > 1) {
103 if (!(fl = fl->
next))
127 if (strcmp(rp->
title,
"NONE")) {
167 char *
buf, *cp, *next;
177 if (*
buf ==
'#' || *
buf ==
'\0')
183 if (!strncmp(cp,
"Remove ", 7)) {
184 if (strcmp(cp + 7,
"*") == 0) {
192 if (!strncmp(cp,
"Object", 6)) {
195 }
else if (formula == NULL) {
196 LOG(
llevError,
"recipe.c: First key in formulae file %s is not \"Object\".\n", filename);
198 }
else if (!strncmp(cp,
"keycode", 7)) {
200 }
else if (sscanf(cp,
"trans %d", &value)) {
202 }
else if (sscanf(cp,
"yield %d", &value)) {
203 formula->
yield = value;
204 }
else if (sscanf(cp,
"chance %d", &value)) {
206 }
else if (sscanf(cp,
"exp %d", &value)) {
207 formula->
exp = value;
208 }
else if (sscanf(cp,
"diff %d", &value)) {
209 formula->
diff = value;
210 }
else if (!strncmp(cp,
"ingred", 6)) {
213 cp = strchr(cp,
' ')+1;
215 if ((next = strchr(cp,
',')) != NULL) {
223 while (*cp !=
'\0' && cp[strlen(cp) - 1] ==
' ')
224 cp[strlen(cp) - 1] =
'\0';
233 }
while ((cp = next) != NULL);
245 }
else if (!strncmp(cp,
"arch", 4)) {
247 }
else if (!strncmp(cp,
"skill", 5)) {
249 }
else if (!strncmp(cp,
"cauldron", 8)) {
251 }
else if (!strncmp(cp,
"failure_arch ", 13)) {
253 }
else if (!strncmp(cp,
"failure_message ", 16)) {
255 }
else if (sscanf(cp,
"min_level %d", &value)) {
257 }
else if (!strncmp(cp,
"tool ", 5)) {
259 }
else if (sscanf(cp,
"combination %d", &value)) {
270 for (formula = fl->
items; formula; formula = formula->
next) {
295 int numb = 1, tool_match;
296 size_t tool_i,tool_j;
302 for (formula = fl->
items; formula != NULL; formula = formula->
next) {
303 for (check = formula->
next; check != NULL; check = check->
next)
310 for (tool_i = 0; tool_i < formula->
tool_size; ++tool_i)
312 for (tool_j = 0; tool_j < check->
tool_size; ++tool_j)
313 if (strcmp(formula->
tool[tool_i], check->
tool[tool_j]) == 0) {
324 LOG(
llevError,
"Formulae [%s] of %s and [%s] of %s have matching index id (%d)\n",
329 for (
size_t idx = 0; idx < formula->
arch_names; idx++) {
331 LOG(
llevError,
"Formulae %s of %s (%d ingredients) references non existent archetype %s\n",
358 fprintf(
logfile,
"\n Formulae with %d ingredient%s %d Formulae with total_chance=%d\n", num_ingred, num_ingred > 1 ?
"s." :
".", fl->
number, fl->
total_chance);
359 for (formula = fl->
items; formula != NULL; formula = formula->
next) {
365 const char *
string = formula->
arch_name[i];
369 if (!art && strcmp(formula->
title,
"NONE"))
372 if (strcmp(formula->
title,
"NONE"))
373 snprintf(
buf,
sizeof(
buf),
"%s of %s",
string, formula->
title);
379 if (formula->
ingred != NULL) {
380 int nval = 0, tval = 0;
381 fprintf(
logfile,
"\tIngred: ");
382 for (next = formula->
ingred; next != NULL; next = next->
next) {
389 if (tval != formula->
index)
390 fprintf(
logfile,
"WARNING:ingredient list and formula values not equal.\n");
392 if (formula->
skill != NULL)
393 fprintf(
logfile,
"\tSkill Required: %s", formula->
skill);
396 fprintf(
logfile,
"\tDifficulty: %d\t Exp: %d\n", formula->
diff, formula->
exp);
399 LOG(
llevError,
"Can't find archetype:%s for formula %s\n",
string, formula->
title);
430 if (
t->name != NULL) {
439 if (
t->next_yes != NULL) {
444 if (
t->next_no != NULL) {
481 while (isdigit(*
name)) {
482 mult = 10*mult+(*
name-
'0');
500 snprintf(part1, sizeof(part1),
"%s %s", at->clone.name, at->clone.title);
501 if (!strcasecmp(part1, name)) {
502 value = at->clone.value;
508 value = at->clone.value;
518 cp = strstr(
name,
" of ");
521 part1[cp-
name] =
'\0';
530 for (auto al = first_artifactlist; al != NULL; al = al->next) {
531 if (al->type == at->clone.type) {
532 for (const auto art : al->items) {
533 if (!strcasecmp(art->item->name, part2)) {
534 value = at->clone.value * art->item->value;
549 cp = strstr(
name,
"'s ");
552 part1[cp-
name] =
'\0';
560 if (at->clone.randomitems != NULL) {
561 auto at2 = find_treasure_by_name(at->clone.randomitems->items, part2, 0);
563 value = at2->clone.value * isqrt(at->clone.level * 2);
599 fprintf(
logfile,
"\n Formulae with %d ingredient%s %d Formulae with total_chance=%d\n", num_ingred, num_ingred > 1 ?
"s." :
".", fl->
number, fl->
total_chance);
600 for (formula = fl->
items; formula != NULL; formula = formula->
next) {
607 const char *
string = formula->
arch_name[i];
611 if (!art && strcmp(formula->
title,
"NONE"))
614 if (!strcmp(formula->
title,
"NONE"))
617 snprintf(
buf,
sizeof(
buf),
"%s of %s",
string, formula->
title);
619 if (formula->
ingred != NULL) {
621 for (next = formula->
ingred; next != NULL; next = next->
next) {
625 fprintf(
logfile,
"\t%-33s%5ld\n", next->
name, cost);
626 if (cost < 0 || tcost < 0)
631 if (art != NULL && art->
item != NULL)
635 fprintf(
logfile,
"\t\tBuying result costs: %5ld", cost);
636 if (formula->
yield > 1) {
637 fprintf(
logfile,
" to %ld (max %d items)\n", cost*formula->
yield, formula->
yield);
638 cost = cost*(formula->
yield+1L)/2L;
641 fprintf(
logfile,
"\t\tIngredients cost: %5ld\n\t\tComment: ", tcost);
643 fprintf(
logfile,
"Could not find some ingredients. Check the formula!\n");
644 else if (tcost > cost)
645 fprintf(
logfile,
"Ingredients are much too expensive. Useless formula.\n");
646 else if (tcost*2L > cost)
647 fprintf(
logfile,
"Ingredients are too expensive.\n");
648 else if (tcost*10L < cost)
649 fprintf(
logfile,
"Ingredients are too cheap.\n");
655 LOG(
llevError,
"Can't find archetype:%s for formula %s\n",
string, formula->
title);
663 fprintf(
logfile,
"WARNING: %d objects required by the formulae do not exist in the game.\n", num_errors);
675 const char *cp =
name;
678 cp = strchr(cp,
' ')+1;
693 if ((numb = atoi(
buf)))
738 for (
auto art : at->items)
753 int number = 0, roll = 0;
772 LOG(
llevError,
"get_random_recipelist(): no recipelists found!\n");
799 for (rp = fl->
items; rp; rp = rp->
next) {
813 recipe *formula = NULL, *next;
820 for (formula = fl->
items; formula != NULL; formula = next) {
821 next = formula->
next;
835 for (lchar = formula->
ingred; lchar; lchar = charnext) {
836 charnext = lchar->
next;
841 free(formula->
tool[0]);
872 for (p = strtok(dup,
","); p != NULL; p = strtok(NULL,
","))
876 *result_list =
static_cast<char **
>(malloc(
sizeof(**result_list) * size));
877 if (*result_list == NULL)
881 for (i = 0; i < size; i++) {
882 (*result_list)[i] = dup;
883 dup = dup+strlen(dup)+1;
902 if (strcmp(test->
tool[
t], tool) == 0) {
933 if (strcmp(rp->
title,
"NONE") == 0) {
970 return "complicated";
974 return "challenging";
976 return "frustrating";
recipe * find_recipe_for_tool(const char *tool, recipe *from)
Find a recipe for a specified tool.
New face structure - this enforces the notion that data is face by face only - you can not change the...
Main Crossfire structure, one ingame object.
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
recipelist * get_formulalist(int i)
Gets a formula list by ingredients count.
size_t tool_size
Length of tool.
size_t bufferreader_current_line(BufferReader *br)
Return the index of the last line returned by bufferreader_next_line().
@ llevError
Error, serious thing.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
size_t arch_names
Size of the arch_name[] array.
treasure * items
Items in this list, linked.
void dump_alchemy_costs(void)
Dumps to output all costs of recipes.
static recipelist * init_recipelist(void)
Allocates a new recipelist.
int yield
Maximum number of items produced by the recipe.
static recipelist * get_random_recipelist(void)
Gets a random recipe list.
sstring failure_arch
Arch of the item to generate on failure, instead of blowing up stuff.
void give_artifact_abilities(object *op, const object *artifact)
Fixes the given object, giving it the abilities and titles it should have due to the second artifact-...
recipelist * next
Pointer to next recipe list.
treasurelist * find_treasurelist(const char *name)
Search for the given treasurelist by name.
object * item
Special values of the artifact.
recipe * items
Pointer to first recipe in this list.
static int check_recipe(const recipe *rp)
Makes sure we actually have the requested artifact and archetype.
#define tolower(C)
Simple macro to convert a letter to lowercase.
sstring failure_message
Specific failure message.
char ** arch_name
Possible archetypes of the final product made.
const Face * blank_face
Following can just as easily be pointers, but it is easier to keep them like this.
int transmute
If defined, one of the formula ingredients is used as the basis for the product object.
sstring title
Of foo, etc.
static long recipe_find_ingredient_cost(const char *name)
Try to find an ingredient with specified name.
int exp
How much exp to give for this formulae.
bool check_recipes()
Ensure that all recipes have a valid artifact, and that archetypes are correct.
AssetsManager * getManager()
int total_chance
Total chance of the recipes in this list.
static recipelist * formulalist
Pointer to first recipelist.
Plugin animator file specs[Config] name
int is_combination
Whather this is an alchemy recipe, or an item transformation description.
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects,...
List of recipes with a certain number of ingredients.
treasurelist represents one logical group of items to be generated together.
object clone
An object from which to do object_copy()
bool check_formulae(void)
Check if formula don't have the same index.
sstring add_string(const char *str)
This will add 'str' to the hash table.
const Face * face
Face with colors.
int32_t value
How much money it is worth (or contains)
int index
Index value derived from formula ingredients.
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn t
static int numb_ingred(const char *buf)
Extracts the number part of an ingredient.
struct linked_char * next
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects,...
This represents all archetypes for one particular object type.
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
FILE * logfile
Used by server/daemon.c.
void each(std::function< void(T *)> op)
Apply a function to each asset.
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
int ingred_count
Number of items in ingred.
Archetypes * archetypes()
Get archetypes.
#define MAX_BUF
Used for all kinds of things.
void free_all_recipes(void)
Frees all memory allocated to recipes and recipes lists.
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
object * create_archetype(const char *name)
Finds which archetype matches the given name, and returns a new object containing a copy of the arche...
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
char ** tool
Tool(s) for item transformation.
sstring name
The name of the object, obviously...
recipe * get_random_recipe(recipelist *rpl)
Gets a random recipe from a list, based on chance.
const artifact * locate_recipe_artifact(const recipe *rp, size_t idx)
Finds an artifact for a recipe.
static const char * ingred_name(const char *name)
Extracts the name from an ingredient.
archetype * find_treasure_by_name(const treasure *t, const char *name, int depth)
Find a treasure with a matching name.
int chance
Chance that recipe for this item will appear in an alchemical grimore.
void dump_alchemy(void)
Dumps alchemy recipes to output.
int strtoint(const char *buf)
Convert buf into an integer equal to the coadded sum of the (lowercase) character.
int diff
Alchemical dfficulty level.
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
void object_give_identified_properties(object *op)
Ensure op has all its "identified" properties set.
void init_formulae(BufferReader *reader, const char *filename)
Builds up the lists of formula from the file in the libdir.
int strcasecmp(const char *s1, const char *s2)
sstring keycode
Optional keycode needed to use the recipe.
int number
Number of recipes in this list.
int min_level
Minimum level to have in the skill to be able to use the formulae.
static recipe * get_empty_formula(void)
Allocates a new recipe.
archetype * try_find_archetype(const char *name)
linked_char * ingred
List of ingredients.
#define FREE_OBJ_FREE_INVENTORY
Free inventory objects; if not set, drop inventory.
recipe * next
Next recipe with the same number of ingredients.
sstring skill
Skill name used to make this recipe.
treasure is one element in a linked list, which together consist of a complete treasure-list.
How to Install a Crossfire Server on you must install a python script engine on your computer Python is the default script engine of Crossfire You can find the python engine you have only to install them The VisualC Crossfire settings are for but you habe then to change the pathes in the VC settings Go in Settings C and Settings Link and change the optional include and libs path to the new python installation path o except the maps ! You must download a map package and install them the share folder Its must look like doubleclick on crossfire32 dsw There are projects in your libcross lib and plugin_python You need to compile all Easiest way is to select the plugin_python ReleaseLog as active this will compile all others too Then in Visual C press< F7 > to compile If you don t have an appropriate compiler you can try to get the the VC copies the crossfire32 exe in the crossfire folder and the plugin_python dll in the crossfire share plugins folder we will remove it when we get time for it o Last showing lots of weird write to the Crossfire mailing list
This is one artifact, ie one special item.
static void build_stringlist(const char *str, char ***result_list, size_t *result_size)
Split a comma separated string list into words.
artifactlist * find_artifactlist(int type)
Finds the artifact list for a certain item type.
const Face * recipe_get_face(const recipe *rp)
Return the best face associated with a recipe.
const char * recipe_get_difficulty_string(int difficulty)
A method to produce a difficulty adjective to describe alchemy projects.
@ llevDebug
Only for debugging purposes.
in that case they will be relative to whatever the PWD of the crossfire server process is You probably shouldn though Notes on Specific and settings file datadir Usually usr share crossfire Contains data that the server does not need to modify while such as the etc A default install will pack the and treasurelist definitions into a single or trs file and the graphics into a face(metadata) and .tar(bitmaps) file
int legal_artifact_combination(const object *op, const artifact *art)
Checks if op can be combined with art.
sstring cauldron
Arch of the cauldron/workbench used to house the formulae.
char * bufferreader_next_line(BufferReader *br)
Return the next line in the buffer, as separated by a newline.
sstring title
Distinguishing name of product.