1 | /* |
1 | /* |
2 | * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Crossfire TRT is free software: you can redistribute it and/or modify |
8 | * Deliantra is free software: you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation, either version 3 of the License, or |
10 | * the Free Software Foundation, either version 3 of the License, or |
11 | * (at your option) any later version. |
11 | * (at your option) any later version. |
12 | * |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
13 | * This program is distributed in the hope that it will be useful, |
… | |
… | |
16 | * GNU General Public License for more details. |
16 | * GNU General Public License for more details. |
17 | * |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | * |
20 | * |
21 | * The authors can be reached via e-mail to <crossfire@schmorp.de> |
21 | * The authors can be reached via e-mail to <support@deliantra.net> |
22 | */ |
22 | */ |
23 | |
23 | |
24 | /* This file contains all the code implementing diseases, |
24 | /* This file contains all the code implementing diseases, |
25 | * except for odds and ends in attack.c and in |
25 | * except for odds and ends in attack.c and in |
26 | * living.c |
26 | * living.c |
… | |
… | |
162 | } |
162 | } |
163 | |
163 | |
164 | int |
164 | int |
165 | move_disease (object *disease) |
165 | move_disease (object *disease) |
166 | { |
166 | { |
167 | /* first task is to determine if the disease is inside or outside of someone. |
167 | /* First task is to determine if the disease is inside or outside of someone. |
168 | * If outside, we decrement 'value' until we're gone. |
168 | * If outside, we decrement 'value' until we're gone. |
169 | */ |
169 | */ |
170 | |
170 | |
171 | if (!disease->env) |
171 | if (!disease->env) |
172 | { /* we're outside of someone */ |
172 | { /* we're outside of someone */ |
173 | if (disease->stats.maxhp > 0) |
173 | if (disease->stats.maxhp > 0) |
174 | disease->value--; |
174 | disease->value--; |
175 | |
175 | |
176 | if (!disease->value) |
176 | if (!disease->value) |
177 | { |
177 | { |
178 | disease->destroy (); |
178 | disease->destroy (true); |
179 | return 1; |
179 | return 1; |
180 | } |
180 | } |
181 | } |
181 | } |
182 | else |
182 | else |
183 | { |
183 | { |
… | |
… | |
189 | |
189 | |
190 | if (!disease->stats.food) |
190 | if (!disease->stats.food) |
191 | { |
191 | { |
192 | remove_symptoms (disease); /* remove the symptoms of this disease */ |
192 | remove_symptoms (disease); /* remove the symptoms of this disease */ |
193 | grant_immunity (disease); |
193 | grant_immunity (disease); |
194 | disease->destroy (); |
194 | disease->destroy (true); |
195 | return 1; |
195 | return 1; |
196 | } |
196 | } |
197 | } |
197 | } |
198 | } |
198 | } |
199 | |
199 | |
… | |
… | |
221 | while ((symptom = find_symptom (disease)) != NULL) |
221 | while ((symptom = find_symptom (disease)) != NULL) |
222 | { |
222 | { |
223 | if (!victim) |
223 | if (!victim) |
224 | victim = symptom->env; |
224 | victim = symptom->env; |
225 | |
225 | |
226 | symptom->destroy (); |
226 | symptom->destroy (true); |
227 | } |
227 | } |
228 | |
228 | |
229 | if (victim) |
229 | if (victim) |
230 | victim->update_stats (); |
230 | victim->update_stats (); |
231 | |
231 | |
… | |
… | |
535 | object *new_ob; |
535 | object *new_ob; |
536 | int sp_reduce; |
536 | int sp_reduce; |
537 | |
537 | |
538 | if (!victim || !victim->map) |
538 | if (!victim || !victim->map) |
539 | { /* outside a monster/player, die immediately */ |
539 | { /* outside a monster/player, die immediately */ |
540 | symptom->destroy (); |
540 | symptom->destroy (true); |
541 | return 0; |
541 | return 0; |
542 | } |
542 | } |
543 | |
543 | |
544 | if (symptom->stats.dam > 0) |
544 | if (symptom->stats.dam > 0) |
545 | hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1); |
545 | hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1); |
546 | else |
546 | else |
547 | hit_player (victim, max (1, -victim->stats.maxhp * symptom->stats.dam / 100.0), symptom, symptom->attacktype, 1); |
547 | hit_player (victim, max (1, -victim->stats.maxhp * symptom->stats.dam / 100), symptom, symptom->attacktype, 1); |
548 | |
548 | |
549 | if (symptom->stats.maxsp > 0) |
549 | if (symptom->stats.maxsp > 0) |
550 | sp_reduce = symptom->stats.maxsp; |
550 | sp_reduce = symptom->stats.maxsp; |
551 | else |
551 | else |
552 | sp_reduce = max (1, victim->stats.maxsp * symptom->stats.maxsp / 100.0); |
552 | sp_reduce = max (1, victim->stats.maxsp * symptom->stats.maxsp / 100); |
553 | |
553 | |
554 | victim->stats.sp = max (0, victim->stats.sp - sp_reduce); |
554 | victim->stats.sp = max (0, victim->stats.sp - sp_reduce); |
555 | |
555 | |
556 | /* create the symptom "other arch" object and drop it here |
556 | /* create the symptom "other arch" object and drop it here |
557 | * under every part of the monster |
557 | * under every part of the monster |
558 | * The victim may well have died. |
558 | * The victim may well have died. |
559 | */ |
559 | */ |
560 | if (symptom->other_arch && victim->map) |
560 | if (victim->map) |
|
|
561 | { |
|
|
562 | victim->play_sound (symptom->sound); |
|
|
563 | |
|
|
564 | if (symptom->other_arch) |
561 | for (object *tmp = victim->head_ (); tmp; tmp = tmp->more) |
565 | for (object *tmp = victim->head_ (); tmp; tmp = tmp->more) |
562 | { |
566 | { |
563 | new_ob = arch_to_object (symptom->other_arch); |
567 | new_ob = arch_to_object (symptom->other_arch); |
564 | new_ob->x = tmp->x; |
568 | new_ob->x = tmp->x; |
565 | new_ob->y = tmp->y; |
569 | new_ob->y = tmp->y; |
566 | new_ob->map = victim->map; |
570 | new_ob->map = victim->map; |
567 | insert_ob_in_map (new_ob, victim->map, victim, 0); |
571 | insert_ob_in_map (new_ob, victim->map, victim, 0); |
|
|
572 | } |
568 | } |
573 | } |
569 | |
574 | |
570 | new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); |
575 | new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); |
571 | |
576 | |
572 | return 1; |
577 | return 1; |
573 | } |
578 | } |
… | |
… | |
622 | cure = 1; |
627 | cure = 1; |
623 | |
628 | |
624 | if (caster && spell) |
629 | if (caster && spell) |
625 | change_exp (caster, disease->stats.exp, spell->skill, SK_EXP_SKILL_ONLY); |
630 | change_exp (caster, disease->stats.exp, spell->skill, SK_EXP_SKILL_ONLY); |
626 | |
631 | |
627 | disease->destroy (); |
632 | disease->destroy (true); |
628 | } |
633 | } |
629 | } |
634 | } |
630 | } |
635 | } |
631 | |
636 | |
632 | if (cure) |
637 | if (cure) |