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

Comparing deliantra/server/server/disease.C (file contents):
Revision 1.51 by root, Thu Jan 1 15:43:34 2009 UTC vs.
Revision 1.68 by root, Sun May 1 16:58:17 2011 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your option) any later version. 11 * 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,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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 Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 23 */
23 24
24/* This file contains all the code implementing diseases, 25/* This file contains all the code implementing diseases,
150 if (disease->last_heal) 151 if (disease->last_heal)
151 return 0; 152 return 0;
152 153
153 /* first, search for an immunity of the same name */ 154 /* first, search for an immunity of the same name */
154 for (walk = disease->env->inv; walk; walk = walk->below) 155 for (walk = disease->env->inv; walk; walk = walk->below)
155 if (walk->type == 98 && disease->name == walk->name) 156 if (disease->name == walk->name && walk->is_immunity ())
156 { 157 {
157 walk->level = disease->level; 158 walk->level = disease->level;
158 return 1; /* just update the existing immunity. */ 159 return 1; /* just update the existing immunity. */
159 } 160 }
160 161
161 immunity = get_archetype ("immunity"); 162 immunity = archetype::get (shstr_immunity);
162 163
163 immunity->name = disease->name; 164 immunity->name = disease->name;
164 immunity->level = disease->level; 165 immunity->level = disease->level;
165 immunity->move_block = 0; 166 immunity->move_block = 0;
166 167
210static int 211static int
211check_infection (object *disease) 212check_infection (object *disease)
212{ 213{
213 int range = abs (disease->magic); 214 int range = abs (disease->magic);
214 215
215 object *op = disease->outer_env (); 216 object *op = disease->outer_env_or_self ();
216 217
217 if (!op->is_on_map ()) 218 if (!op->is_on_map ())
218 return 0; 219 return 0;
219 220
221 dynbuf buf;
220 unordered_mapwalk (op, -range, -range, range, range) 222 unordered_mapwalk (buf, op, -range, -range, range, range)
221 { 223 {
222 mapspace &ms = m->at (nx, ny); 224 mapspace &ms = m->at (nx, ny);
223 225
224 if (ms.flags () & P_IS_ALIVE) 226 if (ms.flags () & P_IS_ALIVE)
225 for (object *tmp = ms.bot; tmp; tmp = tmp->above) 227 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
231 233
232/* check if victim is susceptible to disease. */ 234/* check if victim is susceptible to disease. */
233static int 235static int
234is_susceptible_to_disease (object *victim, object *disease) 236is_susceptible_to_disease (object *victim, object *disease)
235{ 237{
236 if (!QUERY_FLAG (victim, FLAG_ALIVE)) 238 if (!victim->flag [FLAG_ALIVE])
237 return 0; 239 return 0;
238 240
239 if (victim->flag [FLAG_WIZ]) 241 if (victim->flag [FLAG_WIZ])
240 return 0; 242 return 0;
241 243
242 if (disease->race.contains ("*") && !QUERY_FLAG (victim, FLAG_UNDEAD)) 244 if (disease->race.contains ("*") && !victim->flag [FLAG_UNDEAD])
243 return 1; 245 return 1;
244 246
245 if ((disease->race == shstr_undead) && QUERY_FLAG (victim, FLAG_UNDEAD)) 247 if ((disease->race == shstr_undead) && victim->flag [FLAG_UNDEAD])
246 return 1; 248 return 1;
247 249
248 if ((victim->race && disease->race.contains (victim->race)) || disease->race.contains (victim->name)) 250 if ((victim->race && disease->race.contains (victim->race)) || disease->race.contains (victim->name))
249 return 1; 251 return 1;
250 252
287 return 0; 289 return 0;
288 290
289 /* check for an actual immunity */ 291 /* check for an actual immunity */
290 /* do an immunity check */ 292 /* do an immunity check */
291 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below) 293 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below)
292 if (tmp->type == SIGN) /* possibly an immunity, or diseased */ 294 if (tmp->name == disease->name && tmp->is_immunity ()) /* possibly an immunity, or diseased */
293 if (tmp->name == disease->name && tmp->level >= disease->level) 295 if (tmp->level >= disease->level)
294 return 0; /* Immune! */ 296 return 0; /* Immune! */
295 297
296 object *new_symptom = get_archetype ("symptom"); 298 object *new_symptom = archetype::get (shstr_symptom);
297 299
298 /* Something special done with dam. We want diseases to be more 300 /* Something special done with dam. We want diseases to be more
299 * random in what they'll kill, so we'll make the damage they 301 * random in what they'll kill, so we'll make the damage they
300 * do random, note, this has a weird effect with progressive diseases. 302 * do random, note, this has a weird effect with progressive diseases.
301 */ 303 */
316 new_symptom->stats.food = new_symptom->stats.maxgrace; 318 new_symptom->stats.food = new_symptom->stats.maxgrace;
317 319
318 new_symptom->name = new_symptom->name_pl = disease->name; 320 new_symptom->name = new_symptom->name_pl = disease->name;
319 321
320 new_symptom->level = disease->level; 322 new_symptom->level = disease->level;
321 new_symptom->speed = disease->speed;
322 new_symptom->value = 0; 323 new_symptom->value = 0;
324
325 new_symptom->set_speed (disease->speed);
323 326
324 for (int i = 0; i < NUM_STATS; ++i) 327 for (int i = 0; i < NUM_STATS; ++i)
325 new_symptom->stats.stat (i) = disease->stats.stat (i); 328 new_symptom->stats.stat (i) = disease->stats.stat (i);
326 329
327 new_symptom->stats.sp = disease->stats.sp; 330 new_symptom->stats.sp = disease->stats.sp;
368 symptom->msg = disease->msg; 371 symptom->msg = disease->msg;
369 symptom->attacktype = disease->attacktype; 372 symptom->attacktype = disease->attacktype;
370 symptom->other_arch = disease->other_arch; 373 symptom->other_arch = disease->other_arch;
371 } 374 }
372 375
373 SET_FLAG (symptom, FLAG_APPLIED); 376 symptom->set_flag (FLAG_APPLIED);
374 victim->update_stats (); 377 victim->update_stats ();
375 378
376 return 1; 379 return 1;
377} 380}
378 381
433{ 436{
434 object *tmp; 437 object *tmp;
435 object *new_disease; 438 object *new_disease;
436 439
437 /* don't infect inanimate objects */ 440 /* don't infect inanimate objects */
438 if (!QUERY_FLAG (victim, FLAG_MONSTER) && !(victim->type == PLAYER)) 441 if (!victim->flag [FLAG_MONSTER] && !(victim->type == PLAYER))
439 return 0; 442 return 0;
440 443
441 /* check and see if victim can catch disease: diseases 444 /* check and see if victim can catch disease: diseases
442 * are specific 445 * are specific
443 */ 446 */
457 * they were cast in that same order. Instead, change it so that 460 * they were cast in that same order. Instead, change it so that
458 * if you diseased, you can't get diseased more. 461 * if you diseased, you can't get diseased more.
459 */ 462 */
460 463
461 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below) 464 for (tmp = victim->head_ ()->inv; tmp; tmp = tmp->below)
462 if (tmp->type == SIGN && tmp->name == disease->name && tmp->level >= disease->level) 465 if (tmp->name == disease->name && tmp->is_immunity () && tmp->level >= disease->level)
463 return 0; /* Immune! */ 466 return 0; /* Immune! */
464 else if (tmp->type == DISEASE && tmp->name == disease->name) 467 else if (tmp->type == DISEASE && tmp->name == disease->name)
465 return 0; /* already diseased */ 468 return 0; /* already diseased */
466 469
467 /* If we've gotten this far, go ahead and infect the victim. */ 470 /* If we've gotten this far, go ahead and infect the victim. */
513/* make the symptom do the nasty things it does */ 516/* make the symptom do the nasty things it does */
514int 517int
515move_symptom (object *symptom) 518move_symptom (object *symptom)
516{ 519{
517 object *victim = symptom->env; 520 object *victim = symptom->env;
518 object *new_ob;
519 int sp_reduce;
520 521
521 if (!victim || !victim->map) 522 if (!victim || !victim->map)
522 { /* outside a monster/player, die immediately */ 523 { /* outside a monster/player, die immediately */
523 symptom->destroy (); 524 symptom->destroy ();
524 return 0; 525 return 0;
525 } 526 }
526
527 if (symptom->stats.dam > 0)
528 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
529 else
530 hit_player (victim, max (1, -victim->stats.maxhp * symptom->stats.dam / 100), symptom, symptom->attacktype, 1);
531
532 if (symptom->stats.maxsp > 0)
533 sp_reduce = symptom->stats.maxsp;
534 else
535 sp_reduce = max (1, victim->stats.maxsp * symptom->stats.maxsp / 100);
536
537 victim->stats.sp = max (0, victim->stats.sp - sp_reduce);
538 527
539 /* create the symptom "other arch" object and drop it here 528 /* create the symptom "other arch" object and drop it here
540 * under every part of the monster 529 * under every part of the monster
541 * The victim may well have died. 530 * The victim may well have died.
542 */ 531 */
545 victim->play_sound (symptom->sound); 534 victim->play_sound (symptom->sound);
546 535
547 if (symptom->other_arch) 536 if (symptom->other_arch)
548 for (object *tmp = victim->head_ (); tmp; tmp = tmp->more) 537 for (object *tmp = victim->head_ (); tmp; tmp = tmp->more)
549 { 538 {
550 new_ob = arch_to_object (symptom->other_arch); 539 object *new_ob = symptom->other_arch->instance ();
551 new_ob->x = tmp->x; 540 new_ob->x = tmp->x;
552 new_ob->y = tmp->y; 541 new_ob->y = tmp->y;
553 new_ob->map = victim->map; 542 new_ob->map = victim->map;
554 insert_ob_in_map (new_ob, victim->map, victim, 0); 543 insert_ob_in_map (new_ob, victim->map, victim, 0);
555 } 544 }
556 } 545 }
557 546
547 int damage =
548 symptom->stats.dam > 0
549 ? symptom->stats.dam
550 : max (1, victim->stats.maxhp * -symptom->stats.dam / 100);
551
552 hit_player (victim, damage, symptom, symptom->attacktype, 1);
553
554 int sp_reduce =
555 symptom->stats.maxsp > 0
556 ? symptom->stats.maxsp
557 : max (1, victim->stats.maxsp * -symptom->stats.maxsp / 100);
558
559 victim->stats.sp = max (0, victim->stats.sp - sp_reduce);
560
558 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg); 561 new_draw_info (NDI_UNIQUE | NDI_RED, 0, victim, symptom->msg);
559 562
560 return 1; 563 return 1;
561} 564}
562 565
569 for (object *disease = hitter->inv; disease; disease = disease->below) 572 for (object *disease = hitter->inv; disease; disease = disease->below)
570 if (disease->type == DISEASE) 573 if (disease->type == DISEASE)
571 infect_object (victim, disease, 0); 574 infect_object (victim, disease, 0);
572 575
573 return 1; 576 return 1;
574}
575
576// find a disease in someone
577object *
578find_disease (object *victim)
579{
580 for (object *disease = victim->inv; disease; disease = disease->below)
581 if (disease->type == DISEASE)
582 return disease;
583
584 return 0;
585} 577}
586 578
587/* do the cure disease stuff, from the spell "cure disease" */ 579/* do the cure disease stuff, from the spell "cure disease" */
588int 580int
589cure_disease (object *sufferer, object *caster, object *spell) 581cure_disease (object *sufferer, object *caster, object *spell)
627 } 619 }
628 620
629 return 1; 621 return 1;
630} 622}
631 623
624#if 0 // unused, but seems interesting
632/* reduces disease progression: reduce_symptoms 625/* reduces disease progression: reduce_symptoms
633 * return true if we actually reduce a disease. 626 * return true if we actually reduce a disease.
634 */ 627 */
635int 628static int
636reduce_symptoms (object *sufferer, int reduction) 629reduce_symptoms (object *sufferer, int reduction)
637{ 630{
638 object *walk; 631 object *walk;
639 int success = 0; 632 int success = 0;
640 633
656 if (success) 649 if (success)
657 new_draw_info (NDI_UNIQUE, 0, sufferer, "Your illness seems less severe."); 650 new_draw_info (NDI_UNIQUE, 0, sufferer, "Your illness seems less severe.");
658 651
659 return success; 652 return success;
660} 653}
654#endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines