Andreas Kirschbaum wrote: > Hello, > > I'd like to come back to alternate recipes for alchemy and related > skills. I think they can be (and currently on metalforge are) abused to > make money. (I found 1 million(!) potions of sunfire sold to a shop.) > > The common precondition for any valid recipe should be that at least one > ingredient is hard to get. This precondition is not valid for many > alternate recipes: after writing a small perl script, I recognized that > alternate recipes are *very* common, even when using only common > ingredients (for example coins or food). Without much effort, I found a > recipe that made items with a selling price of 40.000pp while using only > 400pp of coins as ingredients. > > To prevent this particular abuse, I'd like to propose the following fix > (see attached diff): do not allow *alternate* recipes with a result > value higher than that of the ingredients. > > I limited the check for increased value to alternate recipes only > because there are some normal recipes that also match. But this should > not be a problem because you have to get the uncommon items first. the patch looks good, with only a few minor nits: 1) It seems there is a debug new_draw_info_format left in that prints the results of value of the item - presumably that needs to be removed. 2) The block: @@ -168,8 +183,14 @@ success_chance, ability, rp->diff, item->level); #endif + value_item = query_cost(item, NULL, F_TRUE); + new_draw_info_format(NDI_UNIQUE, 0, caster, "result value=%llu", value_item); + if(attempt_shadow_alchemy && value_item > value_ingredients) +#ifdef ALCHEMY_DEBUG + LOG(llevDebug, "Forcing failure for shadow alchemy recipe.\n"); +#endif /* roll the dice */ - if ((float)(random_roll(0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) { + else if ((float)(random_roll(0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) { change_exp(caster, rp->exp, rp->skill, SK_EXP_NONE); return; } @@ -640,4 +661,84 @@ I'm not sure if it will actually compile of ALCHEMY_DEBUG is not defined, as there is then just an empty if () else statement. This can pretty easily be solved by just putting {} in the right places, as an empty block should be OK. Wonder if it might also be good to put some message as to why it failed. 3) use of any 'long' or 'unsigned long' variables is discouraged, as past experience has shown that there is no guarantee if these will be 64 or 32 bit values. Instead use the uint32 or uint64 types, depending on what you need (maybe this has been clarified in more recent versions of the C standard). But in any case, use of the uint/sint types is still preferred - I note that object.h defines nrof as a uint32. _______________________________________________ crossfire-devel mailing list crossfire-devel at lists.real-time.com https://mailman.real-time.com/mailman/listinfo/crossfire-devel