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.5 by root, Thu Sep 14 22:34:04 2006 UTC vs.
Revision 1.18 by root, Sat Jan 20 22:09:54 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game for X-windows
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 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
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 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,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 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
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The authors can be reached via e-mail to <crossfire@schmorp.de> 22 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22*/ 23 */
23 24
24/* This file contains all the code implementing diseases, 25/* This file contains all the code implementing diseases,
25 except for odds and ends in attack.c and in 26 except for odds and ends in attack.c and in
26 living.c*/ 27 living.c*/
27 28
126 127
127 128
128#include <global.h> 129#include <global.h>
129#include <object.h> 130#include <object.h>
130#include <living.h> 131#include <living.h>
131#ifndef __CEXTRACT__
132# include <sproto.h> 132#include <sproto.h>
133#endif
134#include <spells.h> 133#include <spells.h>
135#include <sounds.h> 134#include <sounds.h>
136#include <skills.h> 135#include <skills.h>
137 136
138/* IMPLEMENTATION NOTES 137/* IMPLEMENTATION NOTES
170 169
171 if (disease->env == NULL) 170 if (disease->env == NULL)
172 { /* we're outside of someone */ 171 { /* we're outside of someone */
173 if (disease->stats.maxhp > 0) 172 if (disease->stats.maxhp > 0)
174 disease->value--; 173 disease->value--;
174
175 if (disease->value == 0) 175 if (disease->value == 0)
176 { 176 {
177 remove_ob (disease); 177 disease->destroy ();
178 free_object (disease);
179 return 1; 178 return 1;
180 } 179 }
181 } 180 }
182 else 181 else
183 { 182 {
184 /* if we're inside a person, have the disease run its course */ 183 /* if we're inside a person, have the disease run its course */
185 /* negative foods denote "perpetual" diseases. */ 184 /* negative foods denote "perpetual" diseases. */
186 if (disease->stats.food > 0) 185 if (disease->stats.food > 0)
187 { 186 {
188 disease->stats.food--; 187 disease->stats.food--;
188
189 if (disease->stats.food == 0) 189 if (disease->stats.food == 0)
190 { 190 {
191 remove_symptoms (disease); /* remove the symptoms of this disease */ 191 remove_symptoms (disease); /* remove the symptoms of this disease */
192 grant_immunity (disease); 192 grant_immunity (disease);
193 remove_ob (disease); 193 disease->destroy ();
194 free_object (disease);
195 return 1; 194 return 1;
196 } 195 }
197 } 196 }
198 } 197 }
198
199 /* check to see if we infect others */ 199 /* check to see if we infect others */
200 check_infection (disease); 200 check_infection (disease);
201 201
202 /* impose or modify the symptoms of the disease */ 202 /* impose or modify the symptoms of the disease */
203 if (disease->env && is_susceptible_to_disease (disease->env, disease)) 203 if (disease->env && is_susceptible_to_disease (disease->env, disease))
220 220
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 remove_ob (symptom); 225
226 free_object (symptom); 226 symptom->destroy ();
227 } 227 }
228
228 if (victim) 229 if (victim)
229 fix_player (victim); 230 victim->update_stats ();
230 return 0; 231 return 0;
231} 232}
232 233
233/* argument is a disease */ 234/* argument is a disease */
234object * 235object *
246/* searches around for more victims to infect */ 247/* searches around for more victims to infect */
247int 248int
248check_infection (object *disease) 249check_infection (object *disease)
249{ 250{
250 int x, y, range, mflags; 251 int x, y, range, mflags;
251 mapstruct *map, *map2; 252 maptile *map, *map2;
252 object *tmp; 253 object *tmp;
253 sint16 i, j, i2, j2;
254 254
255 range = abs (disease->magic); 255 range = abs (disease->magic);
256
256 if (disease->env) 257 if (disease->env)
257 { 258 {
258 x = disease->env->x; 259 x = disease->env->x;
259 y = disease->env->y; 260 y = disease->env->y;
260 map = disease->env->map; 261 map = disease->env->map;
261 } 262 }
262 else 263 else
263 { 264 {
264 x = disease->x; 265 x = disease->x;
265 y = disease->y; 266 y = disease->y;
266 map = disease->map; 267 map = disease->map;
267 } 268 }
268 269
269 if (map == NULL) 270 if (!map)
270 return 0; 271 return 0;
272
271 for (i = x - range; i <= x + range; i++) 273 for (int i = x - range; i <= x + range; i++)
272 {
273 for (j = y - range; j <= y + range; j++) 274 for (int j = y - range; j <= y + range; j++)
274 { 275 {
276 sint16 i2, j2;
275 mflags = get_map_flags (map, &map2, i, j, &i2, &j2); 277 mflags = get_map_flags (map, &map2, i, j, &i2, &j2);
278
276 if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE)) 279 if (!(mflags & P_OUT_OF_MAP) && (mflags & P_IS_ALIVE))
277 {
278 for (tmp = get_map_ob (map2, i2, j2); tmp; tmp = tmp->above) 280 for (tmp = GET_MAP_OB (map2, i2, j2); tmp; tmp = tmp->above)
279 {
280 infect_object (tmp, disease, 0); 281 infect_object (tmp, disease, 0);
281 }
282 }
283 } 282 }
284 } 283
285 return 1; 284 return 1;
286} 285}
287 286
288 287
289/* check to see if an object is infectable: 288/* check to see if an object is infectable:
324 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as 323 * (eg, level 1 cold, level 2 cold, level 3 cold, etc), as long as
325 * they were cast in that same order. Instead, change it so that 324 * they were cast in that same order. Instead, change it so that
326 * if you diseased, you can't get diseased more. 325 * if you diseased, you can't get diseased more.
327 */ 326 */
328 327
329 for ( /* tmp initialized in if, above */ ; tmp; tmp = tmp->below) 328 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
330 { 329 {
331 if (tmp->type == SIGN && !strcmp (tmp->name, disease->name) && tmp->level >= disease->level) 330 if (tmp->type == SIGN && !strcmp (tmp->name, disease->name) && tmp->level >= disease->level)
332 return 0; /*Immune! */ 331 return 0; /* Immune! */
333 else if (tmp->type == DISEASE && !strcmp (tmp->name, disease->name)) 332 else if (tmp->type == DISEASE && !strcmp (tmp->name, disease->name))
334 return 0; /* already diseased */ 333 return 0; /* already diseased */
335 } 334 }
336 335
337 /* If we've gotten this far, go ahead and infect the victim. */ 336 /* If we've gotten this far, go ahead and infect the victim. */
338 new_disease = get_object (); 337 new_disease = disease->clone ();
339 copy_object (disease, new_disease);
340 new_disease->stats.food = disease->stats.maxgrace; 338 new_disease->stats.food = disease->stats.maxgrace;
341 new_disease->value = disease->stats.maxhp; 339 new_disease->value = disease->stats.maxhp;
342 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */ 340 new_disease->stats.wc -= disease->last_grace; /* self-limiting factor */
343 341
344 /* Unfortunately, set_owner does the wrong thing to the skills pointers 342 /* Unfortunately, set_owner does the wrong thing to the skills pointers
345 * resulting in exp going into the owners *current* chosen skill. 343 * resulting in exp going into the owners *current* chosen skill.
346 */ 344 */
347 345
348 if (get_owner (disease)) 346 if (disease->owner)
349 { 347 {
350 set_owner (new_disease, disease->owner); 348 new_disease->set_owner (disease->owner);
351 349
352 /* Only need to update skill if different */ 350 /* Only need to update skill if different */
353 if (new_disease->skill != disease->skill) 351 if (new_disease->skill != disease->skill)
354 new_disease->skill = disease->skill; 352 new_disease->skill = disease->skill;
355 } 353 }
357 { /* for diseases which are passed by hitting, set owner and praying skill */ 355 { /* for diseases which are passed by hitting, set owner and praying skill */
358 if (disease->env && disease->env->type == PLAYER) 356 if (disease->env && disease->env->type == PLAYER)
359 { 357 {
360 object *player = disease->env; 358 object *player = disease->env;
361 359
362 set_owner (new_disease, player); 360 new_disease->set_owner (player);
363 361
364 /* the skill pointer for these diseases should already be set up - 362 /* the skill pointer for these diseases should already be set up -
365 * hardcoding in 'praying' is not the right approach. 363 * hardcoding in 'praying' is not the right approach.
366 */ 364 */
367 } 365 }
434 if (victim->head) 432 if (victim->head)
435 tmp = victim->head->inv; 433 tmp = victim->head->inv;
436 else 434 else
437 tmp = victim->inv; 435 tmp = victim->inv;
438 436
439 for ( /* tmp initialized in if, above */ ; tmp; tmp = tmp->below) 437 for ( /* tmp initialised in if, above */ ; tmp; tmp = tmp->below)
440 { 438 {
441 if (tmp->type == SIGN) /* possibly an immunity, or diseased */ 439 if (tmp->type == SIGN) /* possibly an immunity, or diseased */
442 if (!strcmp (tmp->name, disease->name) && tmp->level >= disease->level) 440 if (!strcmp (tmp->name, disease->name) && tmp->level >= disease->level)
443 return 0; /*Immune! */ 441 return 0; /*Immune! */
444 } 442 }
453 { 451 {
454 int dam = disease->stats.dam; 452 int dam = disease->stats.dam;
455 453
456 /* reduce the damage, on average, 50%, and making things random. */ 454 /* reduce the damage, on average, 50%, and making things random. */
457 455
458 dam = random_roll (1, FABS (dam), victim, PREFER_LOW); 456 dam = random_roll (1, abs (dam), victim, PREFER_LOW);
459 if (disease->stats.dam < 0) 457 if (disease->stats.dam < 0)
460 dam = -dam; 458 dam = -dam;
461 new_symptom->stats.dam = dam; 459 new_symptom->stats.dam = dam;
462 } 460 }
463 461
485 new_symptom->stats.hp = disease->stats.hp; 483 new_symptom->stats.hp = disease->stats.hp;
486 new_symptom->msg = disease->msg; 484 new_symptom->msg = disease->msg;
487 new_symptom->attacktype = disease->attacktype; 485 new_symptom->attacktype = disease->attacktype;
488 new_symptom->other_arch = disease->other_arch; 486 new_symptom->other_arch = disease->other_arch;
489 487
490 set_owner (new_symptom, disease->owner); 488 new_symptom->set_owner (disease->owner);
491 489
492 if (new_symptom->skill != disease->skill) 490 if (new_symptom->skill != disease->skill)
493 new_symptom->skill = disease->skill; 491 new_symptom->skill = disease->skill;
494 492
495 new_symptom->move_block = 0; 493 new_symptom->move_block = 0;
525 symptom->msg = disease->msg; 523 symptom->msg = disease->msg;
526 symptom->attacktype = disease->attacktype; 524 symptom->attacktype = disease->attacktype;
527 symptom->other_arch = disease->other_arch; 525 symptom->other_arch = disease->other_arch;
528 } 526 }
529 SET_FLAG (symptom, FLAG_APPLIED); 527 SET_FLAG (symptom, FLAG_APPLIED);
530 fix_player (victim); 528 victim->update_stats ();
531 return 1; 529 return 1;
532} 530}
533 531
534 532
535/* grants immunity to plagues we've seen before. */ 533/* grants immunity to plagues we've seen before. */
570 object *new_ob; 568 object *new_ob;
571 int sp_reduce; 569 int sp_reduce;
572 570
573 if (victim == NULL || victim->map == NULL) 571 if (victim == NULL || victim->map == NULL)
574 { /* outside a monster/player, die immediately */ 572 { /* outside a monster/player, die immediately */
575 remove_ob (symptom); 573 symptom->destroy ();
576 free_object (symptom);
577 return 0; 574 return 0;
578 } 575 }
579 576
580 if (symptom->stats.dam > 0) 577 if (symptom->stats.dam > 0)
581 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1); 578 hit_player (victim, symptom->stats.dam, symptom, symptom->attacktype, 1);
600 object *tmp; 597 object *tmp;
601 598
602 tmp = victim; 599 tmp = victim;
603 if (tmp->head != NULL) 600 if (tmp->head != NULL)
604 tmp = tmp->head; 601 tmp = tmp->head;
605 for ( /*tmp initialized above */ ; tmp != NULL; tmp = tmp->more) 602 for ( /*tmp initialised above */ ; tmp != NULL; tmp = tmp->more)
606 { 603 {
607 new_ob = arch_to_object (symptom->other_arch); 604 new_ob = arch_to_object (symptom->other_arch);
608 new_ob->x = tmp->x; 605 new_ob->x = tmp->x;
609 new_ob->y = tmp->y; 606 new_ob->y = tmp->y;
610 new_ob->map = victim->map; 607 new_ob->map = victim->map;
671 */ 668 */
672 if ((casting_level >= disease->level) || (!(random_roll (0, (disease->level - casting_level - 1), caster, PREFER_LOW)))) 669 if ((casting_level >= disease->level) || (!(random_roll (0, (disease->level - casting_level - 1), caster, PREFER_LOW))))
673 { 670 {
674 671
675 remove_symptoms (disease); 672 remove_symptoms (disease);
676 remove_ob (disease);
677 cure = 1; 673 cure = 1;
674
678 if (caster) 675 if (caster)
679 change_exp (caster, disease->stats.exp, caster->chosen_skill ? &caster->chosen_skill->skill : (const char *) 0, 0); 676 change_exp (caster, disease->stats.exp, caster->chosen_skill ? &caster->chosen_skill->skill : (const char *) 0, 0);
680 free_object (disease); 677
678 disease->destroy ();
681 } 679 }
682 } 680 }
683 } 681 }
684 if (cure) 682 if (cure)
685 { 683 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines