1 | |
|
|
2 | /* |
|
|
3 | * static char *rcsid_alchemy_c = |
|
|
4 | * "$Id: alchemy.C,v 1.7 2006/09/10 15:59:57 root Exp $"; |
|
|
5 | */ |
|
|
6 | |
|
|
7 | /* |
1 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
2 | CrossFire, A Multiplayer game for X-windows |
9 | |
3 | |
10 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
4 | Copyright (C) 2002 Mark Wedel & Crossfire Development Team |
11 | Copyright (C) 1992 Frank Tore Johansen |
5 | Copyright (C) 1992 Frank Tore Johansen |
… | |
… | |
22 | |
16 | |
23 | You should have received a copy of the GNU General Public License |
17 | You should have received a copy of the GNU General Public License |
24 | along with this program; if not, write to the Free Software |
18 | along with this program; if not, write to the Free Software |
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | |
20 | |
27 | The authors can be reached via e-mail at crossfire-devel@real-time.com |
21 | The authors can be reached via e-mail at <crossfire@schmorp.de> |
28 | */ |
22 | */ |
29 | |
23 | |
30 | /* March 96 - Laid down original code. -b.t. thomas@astro.psu.edu */ |
24 | /* March 96 - Laid down original code. -b.t. thomas@astro.psu.edu */ |
31 | |
25 | |
32 | #include <global.h> |
26 | #include <global.h> |
33 | #include <object.h> |
27 | #include <object.h> |
34 | #ifndef __CEXTRACT__ |
|
|
35 | # include <sproto.h> |
28 | #include <sproto.h> |
36 | #endif |
|
|
37 | #include <skills.h> |
29 | #include <skills.h> |
38 | #include <spells.h> |
30 | #include <spells.h> |
39 | |
31 | |
40 | /** define this for some helpful debuging information */ |
32 | /** define this for some helpful debuging information */ |
41 | #if 0 |
33 | #if 0 |
… | |
… | |
161 | /* 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 */ |
162 | if (rp->skill) |
154 | if (rp->skill) |
163 | { |
155 | { |
164 | skop = find_skill_by_name (caster, rp->skill); |
156 | skop = find_skill_by_name (caster, rp->skill); |
165 | if (!skop) |
157 | if (!skop) |
166 | { |
|
|
167 | new_draw_info (NDI_UNIQUE, 0, caster, "You do not have the proper skill for this recipe"); |
158 | new_draw_info (NDI_UNIQUE, 0, caster, "You do not have the proper skill for this recipe"); |
168 | } |
|
|
169 | else |
159 | else |
170 | { |
|
|
171 | ability += (int) (skop->level * ((4.0 + cauldron->magic) / 4.0)); |
160 | ability += (int) (skop->level * ((4.0 + cauldron->magic) / 4.0)); |
172 | } |
|
|
173 | } |
161 | } |
174 | else |
162 | else |
175 | { |
163 | { |
176 | LOG (llevDebug, "Recipe %s has NULL skill!\n", &rp->title); |
164 | LOG (llevDebug, "Recipe %s has NULL skill!\n", &rp->title); |
177 | return; |
165 | return; |
178 | } |
166 | } |
179 | |
167 | |
180 | if (rp->cauldron) |
168 | if (!rp->cauldron) |
181 | { |
169 | { |
182 | LOG (llevDebug, "Recipe %s has NULL cauldron!\n", &rp->title); |
170 | LOG (llevDebug, "Recipe %s has NULL cauldron!\n", &rp->title); |
183 | return; |
171 | return; |
184 | } |
172 | } |
185 | |
173 | |
… | |
… | |
204 | |
192 | |
205 | value_item = query_cost (item, NULL, F_TRUE | F_IDENTIFIED | F_NOT_CURSED); |
193 | value_item = query_cost (item, NULL, F_TRUE | F_IDENTIFIED | F_NOT_CURSED); |
206 | if (attempt_shadow_alchemy && value_item > value_ingredients) |
194 | if (attempt_shadow_alchemy && value_item > value_ingredients) |
207 | { |
195 | { |
208 | #ifdef ALCHEMY_DEBUG |
196 | #ifdef ALCHEMY_DEBUG |
209 | # ifndef WIN32 |
|
|
210 | LOG (llevDebug, |
197 | LOG (llevDebug, |
211 | "Forcing failure for shadow alchemy recipe because price of ingredients (%llu) is less than price of result (%llu).\n", |
198 | "Forcing failure for shadow alchemy recipe because price of ingredients (%llu) is less than price of result (%llu).\n", |
212 | value_ingredients, value_item); |
199 | value_ingredients, value_item); |
213 | # else |
|
|
214 | LOG (llevDebug, |
|
|
215 | "Forcing failure for shadow alchemy recipe because price of ingredients (%I64d) is less than price of result (%I64d).\n", |
|
|
216 | value_ingredients, value_item); |
|
|
217 | # endif |
|
|
218 | #endif |
200 | #endif |
219 | } |
201 | } |
220 | /* roll the dice */ |
202 | /* roll the dice */ |
221 | else if ((float) (random_roll (0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) |
203 | else if ((float) (random_roll (0, 101, caster, PREFER_LOW)) <= 100.0 * success_chance) |
222 | { |
204 | { |
223 | change_exp (caster, rp->exp, rp->skill, SK_EXP_NONE); |
205 | change_exp (caster, rp->exp, rp->skill, SK_EXP_NONE); |
|
|
206 | |
|
|
207 | // let alchemy consume some time, so that exploits are less easy |
|
|
208 | caster->speed_left -= 1.0; |
|
|
209 | |
224 | return; |
210 | return; |
225 | } |
211 | } |
226 | } |
212 | } |
227 | } |
213 | } |
228 | } |
214 | } |
|
|
215 | |
229 | /* if we get here, we failed!! */ |
216 | /* if we get here, we failed!! */ |
230 | alchemy_failure_effect (caster, cauldron, rp, calc_alch_danger (caster, cauldron, rp)); |
217 | alchemy_failure_effect (caster, cauldron, rp, calc_alch_danger (caster, cauldron, rp)); |
231 | } |
218 | } |
232 | |
219 | |
233 | /**
|
220 | /**
|
… | |
… | |
606 | object *tmp; |
593 | object *tmp; |
607 | |
594 | |
608 | remove_contents (cauldron->inv, NULL); |
595 | remove_contents (cauldron->inv, NULL); |
609 | switch (rndm (0, 2)) |
596 | switch (rndm (0, 2)) |
610 | { |
597 | { |
611 | case 0: |
598 | case 0: |
612 | tmp = get_archetype ("bomb"); |
599 | tmp = get_archetype ("bomb"); |
613 | tmp->stats.dam = random_roll (1, level, op, PREFER_LOW); |
600 | tmp->stats.dam = random_roll (1, level, op, PREFER_LOW); |
614 | tmp->stats.hp = random_roll (1, level, op, PREFER_LOW); |
601 | tmp->stats.hp = random_roll (1, level, op, PREFER_LOW); |
615 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s creates a bomb!", &cauldron->name); |
602 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s creates a bomb!", &cauldron->name); |
616 | break; |
603 | break; |
617 | |
604 | |
618 | default: |
605 | default: |
619 | tmp = get_archetype ("fireball"); |
606 | tmp = get_archetype ("fireball"); |
620 | tmp->stats.dam = random_roll (1, level, op, PREFER_LOW) / 5 + 1; |
607 | tmp->stats.dam = random_roll (1, level, op, PREFER_LOW) / 5 + 1; |
621 | tmp->stats.hp = random_roll (1, level, op, PREFER_LOW) / 10 + 2; |
608 | tmp->stats.hp = random_roll (1, level, op, PREFER_LOW) / 10 + 2; |
622 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s erupts in flame!", &cauldron->name); |
609 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s erupts in flame!", &cauldron->name); |
623 | break; |
610 | break; |
624 | } |
611 | } |
625 | tmp->x = cauldron->x, tmp->y = cauldron->y; |
612 | |
626 | insert_ob_in_map (tmp, op->map, NULL, 0); |
613 | op->insert_at (cauldron); |
627 | return; |
614 | return; |
628 | |
615 | |
629 | } |
616 | } |
630 | else if (level < 60) |
617 | else if (level < 60) |
631 | { /* CREATE MONSTER */ |
618 | { /* CREATE MONSTER */ |
… | |
… | |
637 | { /* MAJOR FIRE */ |
624 | { /* MAJOR FIRE */ |
638 | object *fb = get_archetype (SP_MED_FIREBALL); |
625 | object *fb = get_archetype (SP_MED_FIREBALL); |
639 | |
626 | |
640 | remove_contents (cauldron->inv, NULL); |
627 | remove_contents (cauldron->inv, NULL); |
641 | fire_arch_from_position (cauldron, cauldron, cauldron->x, cauldron->y, 0, fb); |
628 | fire_arch_from_position (cauldron, cauldron, cauldron->x, cauldron->y, 0, fb); |
642 | free_object (fb); |
629 | fb->destroy (); |
643 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s erupts in flame!", &cauldron->name); |
630 | new_draw_info_format (NDI_UNIQUE, 0, op, "The %s erupts in flame!", &cauldron->name); |
644 | return; |
631 | return; |
645 | |
632 | |
646 | } |
633 | } |
647 | else if (level < 100) |
634 | else if (level < 100) |
… | |
… | |
715 | return; |
702 | return; |
716 | } |
703 | } |
717 | } |
704 | } |
718 | |
705 | |
719 | |
706 | |
720 | /**
|
707 | /* |
721 | * All but object "save_item" are elimentated from |
708 | * All but object "save_item" are elimentated from |
722 | * the container list. Note we have to becareful to remove the inventories |
709 | * the container list. Note we have to becareful to remove the inventories |
723 | * of objects in the cauldron inventory (ex icecube has stuff in it). |
710 | * of objects in the cauldron inventory (ex icecube has stuff in it). |
724 | */ |
711 | */ |
725 | |
712 | |
… | |
… | |
729 | object *next, *tmp = first_ob; |
716 | object *next, *tmp = first_ob; |
730 | |
717 | |
731 | while (tmp) |
718 | while (tmp) |
732 | { |
719 | { |
733 | next = tmp->below; |
720 | next = tmp->below; |
|
|
721 | |
734 | if (tmp == save_item) |
722 | if (tmp == save_item) |
735 | { |
723 | { |
736 | if (!(tmp = next)) |
724 | if (!(tmp = next)) |
737 | break; |
725 | break; |
738 | else |
726 | else |
739 | next = next->below; |
727 | next = next->below; |
740 | } |
728 | } |
|
|
729 | |
741 | if (tmp->inv) |
730 | if (tmp->inv) |
742 | remove_contents (tmp->inv, NULL); |
731 | remove_contents (tmp->inv, NULL); |
743 | remove_ob (tmp); |
732 | |
744 | free_object (tmp); |
733 | tmp->destroy (); |
745 | tmp = next; |
734 | tmp = next; |
746 | } |
735 | } |
747 | } |
736 | } |
748 | |
737 | |
749 | /**
|
738 | /**
|