ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/alchemy.C
(Generate patch)

Comparing deliantra/server/server/alchemy.C (file contents):
Revision 1.3 by elmex, Tue Aug 15 17:35:51 2006 UTC vs.
Revision 1.4 by root, Tue Aug 29 08:01:37 2006 UTC

1/* 1/*
2 * static char *rcsid_alchemy_c = 2 * static char *rcsid_alchemy_c =
3 * "$Id: alchemy.C,v 1.3 2006/08/15 17:35:51 elmex Exp $"; 3 * "$Id: alchemy.C,v 1.4 2006/08/29 08:01:37 root Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
108 int formula=0; 108 int formula=0;
109 float ave_chance; 109 float ave_chance;
110 object *item, *skop; 110 object *item, *skop;
111 111
112 if (caster->type!=PLAYER) 112 if (caster->type!=PLAYER)
113 return; /* only players for now */ 113 return; /* only players for now */
114 114
115 if (get_map_flags(caster->map, NULL, caster->x, caster->y, NULL, NULL) & P_SAFE) 115 if (get_map_flags(caster->map, NULL, caster->x, caster->y, NULL, NULL) & P_SAFE)
116 { 116 {
117 new_draw_info (NDI_UNIQUE, 0, caster, 117 new_draw_info (NDI_UNIQUE, 0, caster,
118 "This is sacred ground, the gods prevent you from using this device." 118 "This is sacred ground, the gods prevent you from using this device."
124 if (!(formula=content_recipe_value(cauldron))) return; 124 if (!(formula=content_recipe_value(cauldron))) return;
125 125
126 numb=numb_ob_inside(cauldron); 126 numb=numb_ob_inside(cauldron);
127 if ((fl=get_formulalist(numb))) { 127 if ((fl=get_formulalist(numb))) {
128 if (QUERY_FLAG(caster, FLAG_WIZ)) { 128 if (QUERY_FLAG(caster, FLAG_WIZ)) {
129 rp = find_recipe(fl, formula, cauldron->inv);
130 if (rp != NULL) {
131#ifdef ALCHEMY_DEBUG
132 if(strcmp(rp->title, "NONE"))
133 LOG(llevDebug, "WIZ got formula: %s of %s\n",
134 rp->arch_name[0], rp->title);
135 else
136 LOG(llevDebug, "WIZ got formula: %s (nbatches:%d)\n",
137 rp->arch_name[0], formula/rp->index);
138#endif
139 attempt_recipe(caster, cauldron, ability, rp, formula/rp->index);
140 } else LOG(llevDebug, "WIZ couldn't find formula for ingredients.\n");
141 return;
142 } /* End of WIZ alchemy */
143
144 /* find the recipe */
129 rp = find_recipe(fl, formula, cauldron->inv); 145 rp = find_recipe(fl, formula, cauldron->inv);
130 if (rp != NULL) { 146 if (rp != NULL) {
131#ifdef ALCHEMY_DEBUG
132 if(strcmp(rp->title, "NONE"))
133 LOG(llevDebug, "WIZ got formula: %s of %s\n",
134 rp->arch_name[0], rp->title);
135 else
136 LOG(llevDebug, "WIZ got formula: %s (nbatches:%d)\n",
137 rp->arch_name[0], formula/rp->index);
138#endif
139 attempt_recipe(caster, cauldron, ability, rp, formula/rp->index);
140 } else LOG(llevDebug, "WIZ couldn't find formula for ingredients.\n");
141 return;
142 } /* End of WIZ alchemy */
143
144 /* find the recipe */
145 rp = find_recipe(fl, formula, cauldron->inv);
146 if (rp != NULL) {
147 uint64 value_ingredients; 147 uint64 value_ingredients;
148 uint64 value_item; 148 uint64 value_item;
149 object *tmp; 149 object *tmp;
150 int attempt_shadow_alchemy; 150 int attempt_shadow_alchemy;
151 151
152 ave_chance = fl->total_chance/(float)fl->number; 152 ave_chance = fl->total_chance/(float)fl->number;
153 /* the caster gets an increase in ability based on thier skill lvl */ 153 /* the caster gets an increase in ability based on thier skill lvl */
154 if (rp->skill != NULL) { 154 if (rp->skill != NULL) {
155 skop = find_skill_by_name(caster, rp->skill); 155 skop = find_skill_by_name(caster, rp->skill);
156 if (!skop) { 156 if (!skop) {
157 new_draw_info(NDI_UNIQUE, 0, caster, "You do not have the proper skill for this recipe"); 157 new_draw_info(NDI_UNIQUE, 0, caster, "You do not have the proper skill for this recipe");
158 } else { 158 } else {
159 ability+= (int) (skop->level*((4.0 + cauldron->magic)/4.0)); 159 ability+= (int) (skop->level*((4.0 + cauldron->magic)/4.0));
160 } 160 }
161 } else { 161 } else {
162 LOG(llevDebug, "Recipe %s has NULL skill!\n", rp->title); 162 LOG(llevDebug, "Recipe %s has NULL skill!\n", rp->title);
163 return; 163 return;
164 } 164 }
165 165
166 if (rp->cauldron == NULL) { 166 if (rp->cauldron == NULL) {
167 LOG(llevDebug, "Recipe %s has NULL cauldron!\n", rp->title); 167 LOG(llevDebug, "Recipe %s has NULL cauldron!\n", rp->title);
168 return; 168 return;
169 } 169 }
170 170
171 /* determine value of ingredients */ 171 /* determine value of ingredients */
172 value_ingredients = 0; 172 value_ingredients = 0;
173 for(tmp = cauldron->inv; tmp != NULL; tmp = tmp->below) 173 for(tmp = cauldron->inv; tmp != NULL; tmp = tmp->below)
174 value_ingredients += query_cost(tmp, NULL, F_TRUE); 174 value_ingredients += query_cost(tmp, NULL, F_TRUE);
175 175
176 attempt_shadow_alchemy = !is_defined_recipe(rp, cauldron, caster); 176 attempt_shadow_alchemy = !is_defined_recipe(rp, cauldron, caster);
177 177
178 /* create the object **FIRST**, then decide whether to keep it. */ 178 /* create the object **FIRST**, then decide whether to keep it. */
179 if ((item=attempt_recipe(caster, cauldron, ability, rp, formula/rp->index)) != NULL) { 179 if ((item=attempt_recipe(caster, cauldron, ability, rp, formula/rp->index)) != NULL) {
180 /* compute base chance of recipe success */ 180 /* compute base chance of recipe success */
181 success_chance = ((float)ability / 181 success_chance = ((float)ability /
182 (float)(rp->diff * (item->level+2))); 182 (float)(rp->diff * (item->level+2)));
183 if (ave_chance == 0) 183 if (ave_chance == 0)
184 ave_chance = 1; 184 ave_chance = 1;
185 185
186#ifdef ALCHEMY_DEBUG 186#ifdef ALCHEMY_DEBUG
187 LOG(llevDebug, "percent success chance = %f ab%d / diff%d*lev%d\n", 187 LOG(llevDebug, "percent success chance = %f ab%d / diff%d*lev%d\n",
188 success_chance, ability, rp->diff, item->level); 188 success_chance, ability, rp->diff, item->level);
189#endif 189#endif
190 190
191 value_item = query_cost(item, NULL, F_TRUE|F_IDENTIFIED|F_NOT_CURSED); 191 value_item = query_cost(item, NULL, F_TRUE|F_IDENTIFIED|F_NOT_CURSED);
192 if(attempt_shadow_alchemy && value_item > value_ingredients) { 192 if(attempt_shadow_alchemy && value_item > value_ingredients) {
193#ifdef ALCHEMY_DEBUG 193#ifdef ALCHEMY_DEBUG
194#ifndef WIN32 194#ifndef WIN32
195 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); 195 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);
196#else 196#else
197 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); 197 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);
198#endif 198#endif
199#endif 199#endif
200 } 200 }
201 /* roll the dice */ 201 /* roll the dice */
202 else if ((float)(random_roll(0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) { 202 else if ((float)(random_roll(0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) {
203 change_exp(caster, rp->exp, rp->skill, SK_EXP_NONE); 203 change_exp(caster, rp->exp, rp->skill, SK_EXP_NONE);
204 return; 204 return;
205 } 205 }
206 } 206 }
207 } 207 }
208 } 208 }
209 /* if we get here, we failed!! */ 209 /* if we get here, we failed!! */
210 alchemy_failure_effect(caster, cauldron, rp, 210 alchemy_failure_effect(caster, cauldron, rp,
211 calc_alch_danger(caster, cauldron, rp)); 211 calc_alch_danger(caster, cauldron, rp));
212} 212}
213 213
214/** 214/**
215 * Recipe value of the entire contents of a container. 215 * Recipe value of the entire contents of a container.
216 * This appears to just generate a hash value, which I guess for now works 216 * This appears to just generate a hash value, which I guess for now works
221 char name[MAX_BUF]; 221 char name[MAX_BUF];
222 object *tmp=op->inv; 222 object *tmp=op->inv;
223 int tval=0, formula=0; 223 int tval=0, formula=0;
224 224
225 while(tmp) { 225 while(tmp) {
226 tval=0; 226 tval=0;
227 strcpy(name, tmp->name); 227 strcpy(name, tmp->name);
228 if (tmp->title) 228 if (tmp->title)
229 sprintf(name, "%s %s", tmp->name, tmp->title); 229 sprintf(name, "%s %s", tmp->name, tmp->title);
230 tval = (strtoint(name) * (tmp->nrof?tmp->nrof:1)); 230 tval = (strtoint(name) * (tmp->nrof?tmp->nrof:1));
231#ifdef ALCHEMY_DEBUG 231#ifdef ALCHEMY_DEBUG
232 LOG(llevDebug,"Got ingredient %d %s(%d)\n", tmp->nrof?tmp->nrof:1, 232 LOG(llevDebug,"Got ingredient %d %s(%d)\n", tmp->nrof?tmp->nrof:1,
233 name, tval); 233 name, tval);
234#endif 234#endif
235 formula += tval; 235 formula += tval;
236 tmp=tmp->below; 236 tmp=tmp->below;
237 } 237 }
238#ifdef ALCHEMY_DEBUG 238#ifdef ALCHEMY_DEBUG
239 LOG(llevDebug, " Formula value=%d\n", formula); 239 LOG(llevDebug, " Formula value=%d\n", formula);
240#endif 240#endif
250 int number=0,o_number=0; 250 int number=0,o_number=0;
251 251
252 while(tmp) { 252 while(tmp) {
253 if(tmp->nrof) number += tmp->nrof; 253 if(tmp->nrof) number += tmp->nrof;
254 else number++; 254 else number++;
255 o_number++; 255 o_number++;
256 tmp=tmp->below; 256 tmp=tmp->below;
257 } 257 }
258#ifdef ALCHEMY_DEBUG 258#ifdef ALCHEMY_DEBUG
259 LOG(llevDebug,"numb_ob_inside(%s): found %d ingredients\n",op->name,o_number); 259 LOG(llevDebug,"numb_ob_inside(%s): found %d ingredients\n",op->name,o_number);
260#endif 260#endif
275 /* this should be passed to this fctn, not effiecent cpu use this way */ 275 /* this should be passed to this fctn, not effiecent cpu use this way */
276 int batches=abs(nbatches); 276 int batches=abs(nbatches);
277 277
278 /* is the cauldron the right type? */ 278 /* is the cauldron the right type? */
279 if (strcmp(rp->cauldron, cauldron->arch->name) != 0) { 279 if (strcmp(rp->cauldron, cauldron->arch->name) != 0) {
280 new_draw_info(NDI_UNIQUE, 0, caster, "You are not using the proper" 280 new_draw_info(NDI_UNIQUE, 0, caster, "You are not using the proper"
281 " facilities for this formula."); 281 " facilities for this formula.");
282 return 0; 282 return 0;
283 } 283 }
284 284
285 skop = find_skill_by_name(caster, rp->skill); 285 skop = find_skill_by_name(caster, rp->skill);
286 /* does the caster have the skill? */ 286 /* does the caster have the skill? */
287 if (!skop) 287 if (!skop)
288 return 0; 288 return 0;
289 289
290 /* code required for this recipe, search the caster */ 290 /* code required for this recipe, search the caster */
291 if(rp->keycode) { 291 if(rp->keycode) {
292 object *tmp; 292 object *tmp;
293 for(tmp=caster->inv; tmp != NULL; tmp=tmp->below) { 293 for(tmp=caster->inv; tmp != NULL; tmp=tmp->below) {
294 if(tmp->type==FORCE && tmp->slaying && 294 if(tmp->type==FORCE && tmp->slaying &&
295 !strcmp(rp->keycode, tmp->slaying)) 295 !strcmp(rp->keycode, tmp->slaying))
296 break; 296 break;
297 } 297 }
298 if(tmp==NULL) { /* failure--no code found */ 298 if(tmp==NULL) { /* failure--no code found */
299 new_draw_info(NDI_UNIQUE, 0, caster, "You know the ingredients," 299 new_draw_info(NDI_UNIQUE, 0, caster, "You know the ingredients,"
300 " but not the technique. Go learn how to do this recipe."); 300 " but not the technique. Go learn how to do this recipe.");
301 return 0; 301 return 0;
302 } 302 }
303 } 303 }
304 304
305#ifdef EXTREME_ALCHEMY_DEBUG 305#ifdef EXTREME_ALCHEMY_DEBUG
306 LOG(llevDebug,"attempt_recipe(): got %d nbatches\n",nbatches); 306 LOG(llevDebug,"attempt_recipe(): got %d nbatches\n",nbatches);
307 LOG(llevDebug,"attempt_recipe(): using recipe %s\n", 307 LOG(llevDebug,"attempt_recipe(): using recipe %s\n",
308 rp->title?rp->title:"unknown"); 308 rp->title?rp->title:"unknown");
309#endif 309#endif
310 310
311 if((item=make_item_from_recipe(cauldron, rp))!=NULL) { 311 if((item=make_item_from_recipe(cauldron, rp))!=NULL) {
312 remove_contents(cauldron->inv, item); 312 remove_contents(cauldron->inv, item);
313 /* Recalc carrying of the cauldron, in case recipe did not conserve mass */ 313 /* Recalc carrying of the cauldron, in case recipe did not conserve mass */
314 sum_weight(cauldron); 314 sum_weight(cauldron);
315 /* adj lvl, nrof on caster level */ 315 /* adj lvl, nrof on caster level */
316 adjust_product(item, ability, rp->yield?(rp->yield*batches):batches); 316 adjust_product(item, ability, rp->yield?(rp->yield*batches):batches);
317 if(!item->env && (item=insert_ob_in_ob(item,cauldron)) == NULL) { 317 if(!item->env && (item=insert_ob_in_ob(item,cauldron)) == NULL) {
318 new_draw_info(NDI_UNIQUE, 0,caster,"Nothing happened."); 318 new_draw_info(NDI_UNIQUE, 0,caster,"Nothing happened.");
319 /* new_draw_info_format(NDI_UNIQUE, 0,caster, 319 /* new_draw_info_format(NDI_UNIQUE, 0,caster,
320 "Your spell causes the %s to explode!",cauldron->name); */ 320 "Your spell causes the %s to explode!",cauldron->name); */
321 /* kaboom_cauldron(); */ 321 /* kaboom_cauldron(); */
322 } else { 322 } else {
323 new_draw_info_format(NDI_UNIQUE, 0,caster, 323 new_draw_info_format(NDI_UNIQUE, 0,caster,
324 "The %s %s.",cauldron->name,cauldron_sound()); 324 "The %s %s.",cauldron->name,cauldron_sound());
325 } 325 }
326 } 326 }
327 return item; 327 return item;
328} 328}
329 329
330 330
336 336
337void adjust_product(object *item, int lvl, int yield) { 337void adjust_product(object *item, int lvl, int yield) {
338 int nrof=1; 338 int nrof=1;
339 339
340 if (!yield) 340 if (!yield)
341 yield = 1; 341 yield = 1;
342 if (lvl<=0) 342 if (lvl<=0)
343 lvl = 1; /* lets avoid div by zero! */ 343 lvl = 1; /* lets avoid div by zero! */
344 if (item->nrof) { 344 if (item->nrof) {
345 nrof = (int) ( 345 nrof = (int) (
346 (1.0 - 1.0/(lvl/10.0 + 1.0)) * 346 (1.0 - 1.0/(lvl/10.0 + 1.0)) *
347 (rndm(0, yield-1) + rndm(0, yield-1) + rndm(0, yield-1)) + 1 347 (rndm(0, yield-1) + rndm(0, yield-1) + rndm(0, yield-1)) + 1
348 ); 348 );
349 if (nrof > yield) 349 if (nrof > yield)
350 nrof = yield; 350 nrof = yield;
351 item->nrof=nrof; 351 item->nrof=nrof;
352 } 352 }
353} 353}
354 354
355 355
356/** 356/**
380 if(strcmp(rp->title,"NONE")) { 380 if(strcmp(rp->title,"NONE")) {
381 if((art=locate_recipe_artifact(rp, rp_arch_index))==NULL) { 381 if((art=locate_recipe_artifact(rp, rp_arch_index))==NULL) {
382 LOG(llevError,"make_alchemy_item(): failed to locate recipe artifact.\n"); 382 LOG(llevError,"make_alchemy_item(): failed to locate recipe artifact.\n");
383 LOG(llevDebug," --requested recipe: %s of %s.\n",rp->arch_name[0],rp->title); 383 LOG(llevDebug," --requested recipe: %s of %s.\n",rp->arch_name[0],rp->title);
384 return (object *) NULL; 384 return (object *) NULL;
385 } 385 }
386 transmute_materialname(item, art->item); 386 transmute_materialname(item, art->item);
387 give_artifact_abilities(item, art->item); 387 give_artifact_abilities(item, art->item);
388 } 388 }
389 389
390 if(QUERY_FLAG(cauldron,FLAG_CURSED)) SET_FLAG(item,FLAG_CURSED); 390 if(QUERY_FLAG(cauldron,FLAG_CURSED)) SET_FLAG(item,FLAG_CURSED);
391 if(QUERY_FLAG(cauldron,FLAG_DAMNED)) SET_FLAG(item,FLAG_DAMNED); 391 if(QUERY_FLAG(cauldron,FLAG_DAMNED)) SET_FLAG(item,FLAG_DAMNED);
460 LOG(llevDebug,"Alchemy_failure_effect(): using level=%d\n",level); 460 LOG(llevDebug,"Alchemy_failure_effect(): using level=%d\n",level);
461#endif 461#endif
462 462
463 /* possible outcomes based on level */ 463 /* possible outcomes based on level */
464 if(level<25) { /* INGREDIENTS USED/SLAGGED */ 464 if(level<25) { /* INGREDIENTS USED/SLAGGED */
465 object *item=NULL; 465 object *item=NULL;
466 466
467 if(rndm(0, 2)) { /* slag created */ 467 if(rndm(0, 2)) { /* slag created */
468 object *tmp=cauldron->inv; 468 object *tmp=cauldron->inv;
469 int weight=0; 469 int weight=0;
470 uint16 material=M_STONE; 470 uint16 material=M_STONE;
471 471
472 while(tmp) { /* slag has coadded ingredient properties */ 472 while(tmp) { /* slag has coadded ingredient properties */
473 weight+=tmp->weight; 473 weight+=tmp->weight;
474 if(!(material&tmp->material)) 474 if(!(material&tmp->material))
475 material |= tmp->material; 475 material |= tmp->material;
476 tmp=tmp->below; 476 tmp=tmp->below;
477 } 477 }
478 tmp = get_archetype("rock"); 478 tmp = get_archetype("rock");
479 tmp->weight=weight; 479 tmp->weight=weight;
480 tmp->value=0; 480 tmp->value=0;
481 tmp->material=material; 481 tmp->material=material;
482 tmp->materialname = add_string("stone"); 482 tmp->materialname = add_string("stone");
483 free_string(tmp->name); 483 free_string(tmp->name);
484 tmp->name=add_string("slag"); 484 tmp->name=add_string("slag");
485 if (tmp->name_pl) free_string(tmp->name_pl); 485 if (tmp->name_pl) free_string(tmp->name_pl);
486 tmp->name_pl=add_string("slags"); 486 tmp->name_pl=add_string("slags");
487 item=insert_ob_in_ob(tmp,cauldron); 487 item=insert_ob_in_ob(tmp,cauldron);
488 CLEAR_FLAG(tmp,FLAG_CAN_ROLL); 488 CLEAR_FLAG(tmp,FLAG_CAN_ROLL);
489 CLEAR_FLAG(tmp,FLAG_NO_PICK); 489 CLEAR_FLAG(tmp,FLAG_NO_PICK);
490 tmp->move_block = 0; 490 tmp->move_block = 0;
491 } 491 }
492 remove_contents(cauldron->inv,item); 492 remove_contents(cauldron->inv,item);
493 new_draw_info_format(NDI_UNIQUE,0,op, 493 new_draw_info_format(NDI_UNIQUE,0,op,
494 "The %s %s.",cauldron->name,cauldron_sound()); 494 "The %s %s.",cauldron->name,cauldron_sound());
495 return; 495 return;
496 } else if (level< 40) { /* MAKE TAINTED ITEM */ 496 } else if (level< 40) { /* MAKE TAINTED ITEM */
497 object *tmp=NULL; 497 object *tmp=NULL;
498 498
499 if (!rp) 499 if (!rp)
500 if((rp=get_random_recipe((recipelist *) NULL))==NULL) 500 if((rp=get_random_recipe((recipelist *) NULL))==NULL)
501 return; 501 return;
502 502
503 if((tmp=attempt_recipe(op,cauldron,1,rp,-1))) { 503 if((tmp=attempt_recipe(op,cauldron,1,rp,-1))) {
504 if(!QUERY_FLAG(tmp,FLAG_CURSED)) /* curse it */ 504 if(!QUERY_FLAG(tmp,FLAG_CURSED)) /* curse it */
505 SET_FLAG(tmp,FLAG_CURSED); 505 SET_FLAG(tmp,FLAG_CURSED);
506 506
507 /* the apply code for potions already deals with cursed 507 /* the apply code for potions already deals with cursed
508 * potions, so any code here is basically ignored. 508 * potions, so any code here is basically ignored.
509 */ 509 */
510 if(tmp->type==FOOD) { 510 if(tmp->type==FOOD) {
511 tmp->stats.hp=random_roll(0, 149, op, PREFER_LOW); 511 tmp->stats.hp=random_roll(0, 149, op, PREFER_LOW);
512 } 512 }
513 tmp->value = 0; /* unsaleable item */ 513 tmp->value = 0; /* unsaleable item */
514 514
515 /* change stats downward */ 515 /* change stats downward */
516 do { 516 do {
517 change_attr_value(&tmp->stats,rndm(0, 6),-1*(rndm(1, 3))); 517 change_attr_value(&tmp->stats,rndm(0, 6),-1*(rndm(1, 3)));
518 } while (rndm(0, 2)); 518 } while (rndm(0, 2));
519 } 519 }
520 return; 520 return;
521 } if(level==40) { /* MAKE RANDOM RECIPE */ 521 } if(level==40) { /* MAKE RANDOM RECIPE */
522 recipelist *fl; 522 recipelist *fl;
523 int numb=numb_ob_inside(cauldron); 523 int numb=numb_ob_inside(cauldron);
524 524
525 fl=get_formulalist(numb-1); /* take a lower recipe list */ 525 fl=get_formulalist(numb-1); /* take a lower recipe list */
526 if(fl &&(rp=get_random_recipe(fl))) 526 if(fl &&(rp=get_random_recipe(fl)))
527 /* even though random, don't grant user any EXP for it */ 527 /* even though random, don't grant user any EXP for it */
528 (void) attempt_recipe(op,cauldron,1,rp,-1); 528 (void) attempt_recipe(op,cauldron,1,rp,-1);
529 else 529 else
530 alchemy_failure_effect(op,cauldron,rp,level-1); 530 alchemy_failure_effect(op,cauldron,rp,level-1);
531 return; 531 return;
532 532
533 } else if (level<45) { /* INFURIATE NPC's */ 533 } else if (level<45) { /* INFURIATE NPC's */
534 /* this is kind of kludgy I know...*/ 534 /* this is kind of kludgy I know...*/
535 cauldron->enemy=op; 535 cauldron->enemy=op;
536 npc_call_help(cauldron); 536 npc_call_help(cauldron);
537 cauldron->enemy=NULL; 537 cauldron->enemy=NULL;
538 538
539 alchemy_failure_effect(op,cauldron,rp,level-5); 539 alchemy_failure_effect(op,cauldron,rp,level-5);
540 return; 540 return;
541 } else if (level<50) { /* MINOR EXPLOSION/FIREBALL */ 541 } else if (level<50) { /* MINOR EXPLOSION/FIREBALL */
542 object *tmp; 542 object *tmp;
543 remove_contents(cauldron->inv,NULL); 543 remove_contents(cauldron->inv,NULL);
544 switch(rndm(0, 2)) { 544 switch(rndm(0, 2)) {
545 case 0: 545 case 0:
546 tmp=get_archetype("bomb"); 546 tmp=get_archetype("bomb");
547 tmp->stats.dam=random_roll(1, level, op, PREFER_LOW); 547 tmp->stats.dam=random_roll(1, level, op, PREFER_LOW);
548 tmp->stats.hp=random_roll(1, level, op, PREFER_LOW); 548 tmp->stats.hp=random_roll(1, level, op, PREFER_LOW);
549 new_draw_info_format(NDI_UNIQUE,0,op,"The %s creates a bomb!", 549 new_draw_info_format(NDI_UNIQUE,0,op,"The %s creates a bomb!",
550 cauldron->name); 550 cauldron->name);
551 break; 551 break;
552 552
553 default: 553 default:
554 tmp=get_archetype("fireball"); 554 tmp=get_archetype("fireball");
555 tmp->stats.dam=random_roll(1, level, op, PREFER_LOW)/5+1; 555 tmp->stats.dam=random_roll(1, level, op, PREFER_LOW)/5+1;
556 tmp->stats.hp=random_roll(1, level, op, PREFER_LOW)/10+2; 556 tmp->stats.hp=random_roll(1, level, op, PREFER_LOW)/10+2;
557 new_draw_info_format(NDI_UNIQUE,0,op,"The %s erupts in flame!", 557 new_draw_info_format(NDI_UNIQUE,0,op,"The %s erupts in flame!",
558 cauldron->name); 558 cauldron->name);
559 break; 559 break;
560 } 560 }
561 tmp->x=cauldron->x,tmp->y=cauldron->y; 561 tmp->x=cauldron->x,tmp->y=cauldron->y;
562 insert_ob_in_map(tmp,op->map,NULL,0); 562 insert_ob_in_map(tmp,op->map,NULL,0);
563 return; 563 return;
564 564
565 } else if (level<60) { /* CREATE MONSTER */ 565 } else if (level<60) { /* CREATE MONSTER */
566 new_draw_info_format(NDI_UNIQUE,0,op, 566 new_draw_info_format(NDI_UNIQUE,0,op,
567 "The %s %s.",cauldron->name,cauldron_sound()); 567 "The %s %s.",cauldron->name,cauldron_sound());
568 remove_contents(cauldron->inv,NULL); 568 remove_contents(cauldron->inv,NULL);
569 return; 569 return;
570 } else if (level<80) { /* MAJOR FIRE */ 570 } else if (level<80) { /* MAJOR FIRE */
571 object *fb = get_archetype(SP_MED_FIREBALL); 571 object *fb = get_archetype(SP_MED_FIREBALL);
572 remove_contents(cauldron->inv,NULL); 572 remove_contents(cauldron->inv,NULL);
573 fire_arch_from_position(cauldron, cauldron,cauldron->x, cauldron->y, 573 fire_arch_from_position(cauldron, cauldron,cauldron->x, cauldron->y,
574 0, fb); 574 0, fb);
575 free_object(fb); 575 free_object(fb);
576 new_draw_info_format(NDI_UNIQUE,0,op,"The %s erupts in flame!", 576 new_draw_info_format(NDI_UNIQUE,0,op,"The %s erupts in flame!",
577 cauldron->name); 577 cauldron->name);
578 return; 578 return;
579 579
580 } else if (level<100) { /* WHAMMY the CAULDRON */ 580 } else if (level<100) { /* WHAMMY the CAULDRON */
581 if(!QUERY_FLAG(cauldron,FLAG_CURSED)) 581 if(!QUERY_FLAG(cauldron,FLAG_CURSED))
582 SET_FLAG(cauldron,FLAG_CURSED); 582 SET_FLAG(cauldron,FLAG_CURSED);
583 else cauldron->magic--; 583 else cauldron->magic--;
584 cauldron->magic -= random_roll(0, 4, op, PREFER_LOW); 584 cauldron->magic -= random_roll(0, 4, op, PREFER_LOW);
585 if(rndm(0, 1)) { 585 if(rndm(0, 1)) {
586 remove_contents(cauldron->inv,NULL); 586 remove_contents(cauldron->inv,NULL);
587 new_draw_info_format(NDI_UNIQUE,0,op, 587 new_draw_info_format(NDI_UNIQUE,0,op,
588 "Your %s turns darker then makes a gulping sound!", 588 "Your %s turns darker then makes a gulping sound!",
589 cauldron->name); 589 cauldron->name);
590 } else 590 } else
591 new_draw_info_format(NDI_UNIQUE,0,op, 591 new_draw_info_format(NDI_UNIQUE,0,op,
592 "Your %s becomes darker.",cauldron->name); 592 "Your %s becomes darker.",cauldron->name);
593 return; 593 return;
594 594
595 } else if (level<110) { /* SUMMON EVIL MONSTERS */ 595 } else if (level<110) { /* SUMMON EVIL MONSTERS */
596 object *tmp=get_random_mon(level/5); 596 object *tmp=get_random_mon(level/5);
597 597
598 remove_contents(cauldron->inv,NULL); 598 remove_contents(cauldron->inv,NULL);
599 if(!tmp) 599 if(!tmp)
600 alchemy_failure_effect(op,cauldron,rp,level); 600 alchemy_failure_effect(op,cauldron,rp,level);
601 else if(summon_hostile_monsters(cauldron, random_roll(1, 10, op, PREFER_LOW), tmp->arch->name)) 601 else if(summon_hostile_monsters(cauldron, random_roll(1, 10, op, PREFER_LOW), tmp->arch->name))
602 new_draw_info_format(NDI_UNIQUE, 0,op, 602 new_draw_info_format(NDI_UNIQUE, 0,op,
603 "The %s %s and then pours forth monsters!", 603 "The %s %s and then pours forth monsters!",
604 cauldron->name,cauldron_sound()); 604 cauldron->name,cauldron_sound());
605 return; 605 return;
606 606
607 } else if (level<150) { /* COMBO EFFECT */ 607 } else if (level<150) { /* COMBO EFFECT */
608 int roll = rndm(1, 3); 608 int roll = rndm(1, 3);
609 while(roll) { 609 while(roll) {
610 alchemy_failure_effect(op,cauldron,rp,level-39); 610 alchemy_failure_effect(op,cauldron,rp,level-39);
611 roll--; 611 roll--;
612 } 612 }
613 return; 613 return;
614 } else if (level==151) { /* CREATE RANDOM ARTIFACT */ 614 } else if (level==151) { /* CREATE RANDOM ARTIFACT */
615 object *tmp; 615 object *tmp;
616 /* this is meant to be better than prior possiblity, 616 /* this is meant to be better than prior possiblity,
617 * in this one, we allow *any* valid alchemy artifact 617 * in this one, we allow *any* valid alchemy artifact
618 * to be made (rather than only those on the given 618 * to be made (rather than only those on the given
619 * formulalist) */ 619 * formulalist) */
620 if(!rp) rp=get_random_recipe((recipelist *) NULL); 620 if(!rp) rp=get_random_recipe((recipelist *) NULL);
621 if(rp && (tmp=get_archetype(rp->arch_name[RANDOM()%rp->arch_names]))) { 621 if(rp && (tmp=get_archetype(rp->arch_name[RANDOM()%rp->arch_names]))) {
622 generate_artifact(tmp,random_roll(1, op->level/2+1, op, PREFER_HIGH)+1); 622 generate_artifact(tmp,random_roll(1, op->level/2+1, op, PREFER_HIGH)+1);
623 if((tmp=insert_ob_in_ob(tmp,cauldron))) { 623 if((tmp=insert_ob_in_ob(tmp,cauldron))) {
624 remove_contents(cauldron->inv,tmp); 624 remove_contents(cauldron->inv,tmp);
625 new_draw_info_format(NDI_UNIQUE, 0,op, 625 new_draw_info_format(NDI_UNIQUE, 0,op,
626 "The %s %s.",cauldron->name,cauldron_sound()); 626 "The %s %s.",cauldron->name,cauldron_sound());
627 } 627 }
628 } 628 }
629 return; 629 return;
630 } else { /* MANA STORM - watch out!! */ 630 } else { /* MANA STORM - watch out!! */
631 object *tmp = get_archetype(LOOSE_MANA); 631 object *tmp = get_archetype(LOOSE_MANA);
632 new_draw_info(NDI_UNIQUE,0,op,"You unwisely release potent forces!"); 632 new_draw_info(NDI_UNIQUE,0,op,"You unwisely release potent forces!");
633 remove_contents (cauldron->inv,NULL); 633 remove_contents (cauldron->inv,NULL);
634 cast_magic_storm(op,tmp, level); 634 cast_magic_storm(op,tmp, level);
635 return; 635 return;
636 } 636 }
637} 637}
638 638
639 639
640/** 640/**
649 while(tmp) { 649 while(tmp) {
650 next = tmp->below; 650 next = tmp->below;
651 if(tmp==save_item) { 651 if(tmp==save_item) {
652 if(!(tmp=next)) break; 652 if(!(tmp=next)) break;
653 else next=next->below; 653 else next=next->below;
654 } 654 }
655 if(tmp->inv) remove_contents(tmp->inv,NULL); 655 if(tmp->inv) remove_contents(tmp->inv,NULL);
656 remove_ob(tmp); 656 remove_ob(tmp);
657 free_object(tmp); 657 free_object(tmp);
658 tmp=next; 658 tmp=next;
659 } 659 }
690 * and thus the backfire will be worse. */ 690 * and thus the backfire will be worse. */
691 for(item=cauldron->inv;item;item=item->below) { 691 for(item=cauldron->inv;item;item=item->below) {
692 strcpy(name,item->name); 692 strcpy(name,item->name);
693 if(item->title) sprintf(name,"%s %s",item->name,item->title); 693 if(item->title) sprintf(name,"%s %s",item->name,item->title);
694 danger += (strtoint(name)/1000) + 3; 694 danger += (strtoint(name)/1000) + 3;
695 nrofi++; 695 nrofi++;
696 } 696 }
697 if (rp == NULL) 697 if (rp == NULL)
698 danger += 110; 698 danger += 110;
699 else 699 else
700 danger += rp->diff*3; 700 danger += rp->diff*3;
732 const object *ob; 732 const object *ob;
733 733
734 /* check for matching number of ingredients */ 734 /* check for matching number of ingredients */
735 number = 0; 735 number = 0;
736 for(ingredient = rp->ingred; ingredient != NULL; ingredient = ingredient->next) 736 for(ingredient = rp->ingred; ingredient != NULL; ingredient = ingredient->next)
737 number++; 737 number++;
738 for(ob = cauldron->inv; ob != NULL; ob = ob->below) 738 for(ob = cauldron->inv; ob != NULL; ob = ob->below)
739 number--; 739 number--;
740 if(number != 0) 740 if(number != 0)
741 return 0; 741 return 0;
742 742
743 /* check for matching ingredients */ 743 /* check for matching ingredients */
744 batches_in_cauldron = 0; 744 batches_in_cauldron = 0;
745 for(ingredient = rp->ingred; ingredient != NULL; ingredient = ingredient->next) { 745 for(ingredient = rp->ingred; ingredient != NULL; ingredient = ingredient->next) {
746 uint32 nrof; 746 uint32 nrof;
747 const char *name; 747 const char *name;
748 int ok; 748 int ok;
749 749
750 /* determine and remove nrof from name */ 750 /* determine and remove nrof from name */
751 name = ingredient->name; 751 name = ingredient->name;
752 nrof = 0; 752 nrof = 0;
753 while(isdigit(*name)) { 753 while(isdigit(*name)) {
754 nrof = 10*nrof+(*name-'0'); 754 nrof = 10*nrof+(*name-'0');
755 name++; 755 name++;
756 } 756 }
757 if(nrof == 0) 757 if(nrof == 0)
758 nrof = 1; 758 nrof = 1;
759 while(*name == ' ') 759 while(*name == ' ')
760 name++; 760 name++;
761 761
762 /* find the current ingredient in the cauldron */ 762 /* find the current ingredient in the cauldron */
763 ok = 0; 763 ok = 0;
764 for(ob = cauldron->inv; ob != NULL; ob = ob->below) { 764 for(ob = cauldron->inv; ob != NULL; ob = ob->below) {
765 char name_ob[MAX_BUF]; 765 char name_ob[MAX_BUF];
766 const char *name2; 766 const char *name2;
767 767
768 if(ob->title == NULL) 768 if(ob->title == NULL)
769 name2 = ob->name; 769 name2 = ob->name;
770 else { 770 else {
771 snprintf(name_ob, sizeof(name_ob), "%s %s", ob->name, ob->title); 771 snprintf(name_ob, sizeof(name_ob), "%s %s", ob->name, ob->title);
772 name2 = name_ob; 772 name2 = name_ob;
773 } 773 }
774 774
775 if(strcmp(name2, name) == 0) { 775 if(strcmp(name2, name) == 0) {
776 if(ob->nrof%nrof == 0) { 776 if(ob->nrof%nrof == 0) {
777 uint32 batches; 777 uint32 batches;
778 778
779 batches = ob->nrof/nrof; 779 batches = ob->nrof/nrof;
780 if(batches_in_cauldron == 0) { 780 if(batches_in_cauldron == 0) {
781 batches_in_cauldron = batches; 781 batches_in_cauldron = batches;
782 ok = 1; 782 ok = 1;
783 } else if(batches_in_cauldron == batches) 783 } else if(batches_in_cauldron == batches)
784 ok = 1; 784 ok = 1;
785 } 785 }
786 break; 786 break;
787 } 787 }
788 } 788 }
789 if(!ok) 789 if(!ok)
790 return(0); 790 return(0);
791 } 791 }
792 792
793 return(1); 793 return(1);
794} 794}
795 795

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines