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

Comparing deliantra/server/common/living.C (file contents):
Revision 1.2 by root, Sat Aug 26 23:36:28 2006 UTC vs.
Revision 1.5 by root, Sun Sep 3 00:18:40 2006 UTC

1/* 1/*
2 * static char *rcsid_living_c = 2 * static char *rcsid_living_c =
3 * "$Id: living.C,v 1.2 2006/08/26 23:36:28 root Exp $"; 3 * "$Id: living.C,v 1.5 2006/09/03 00:18:40 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
213 "You feel your charisma return.", 213 "You feel your charisma return.",
214 "You feel your memory return.", 214 "You feel your memory return.",
215 "You feel your spirits return." 215 "You feel your spirits return."
216}; 216};
217const char *const gain_msg[NUM_STATS] = { 217const char *const gain_msg[NUM_STATS] = {
218 "You feel stronger.", 218 "You feel stronger.",
219 "You feel more agile.", 219 "You feel more agile.",
220 "You feel healthy.", 220 "You feel healthy.",
221 "You feel wiser.", 221 "You feel wiser.",
222 "You seem to look better.", 222 "You seem to look better.",
223 "You feel smarter.", 223 "You feel smarter.",
224 "You feel more potent." 224 "You feel more potent."
225}; 225};
226const char *const lose_msg[NUM_STATS] = { 226const char *const lose_msg[NUM_STATS] = {
227 "You feel weaker!", 227 "You feel weaker!",
228 "You feel clumsy!", 228 "You feel clumsy!",
229 "You feel less healthy!", 229 "You feel less healthy!",
230 "You lose some of your memory!", 230 "You lose some of your memory!",
231 "You look ugly!", 231 "You look ugly!",
232 "You feel stupid!", 232 "You feel stupid!",
233 "You feel less potent!" 233 "You feel less potent!"
234}; 234};
235 235
236const char *const statname[NUM_STATS] = { 236const char *const statname[NUM_STATS] = {
237 "strength", "dexterity", "constitution", "wisdom", "charisma", "intelligence","power" 237 "strength", "dexterity", "constitution", "wisdom", "charisma", "intelligence","power"
238}; 238};
302 break; 302 break;
303 case INT: 303 case INT:
304 stats->Int+=value; 304 stats->Int+=value;
305 break; 305 break;
306 default: 306 default:
307 LOG(llevError,"Invalid attribute in change_attr_value: %d\n", attr); 307 LOG(llevError,"Invalid attribute in change_attr_value: %d\n", attr);
308 } 308 }
309} 309}
310 310
311/* 311/*
312 * returns the specified stat. See also set_attr_value(). 312 * returns the specified stat. See also set_attr_value().
379 * found by fix_player. refop is not a real object 379 * found by fix_player. refop is not a real object
380 */ 380 */
381 memcpy(&refop, op, sizeof(object)); 381 memcpy(&refop, op, sizeof(object));
382 382
383 if(op->type==PLAYER) { 383 if(op->type==PLAYER) {
384 if (tmp->type==POTION) { 384 if (tmp->type==POTION) {
385 potion_max=1; 385 potion_max=1;
386 for(j=0;j<NUM_STATS;j++) { 386 for(j=0;j<NUM_STATS;j++) {
387 int nstat, ostat; 387 int nstat, ostat;
388 388
389 ostat = get_attr_value(&(op->contr->orig_stats),j); 389 ostat = get_attr_value(&(op->contr->orig_stats),j);
390 i = get_attr_value(&(tmp->stats),j); 390 i = get_attr_value(&(tmp->stats),j);
391 391
392 /* nstat is what the stat will be after use of the potion */ 392 /* nstat is what the stat will be after use of the potion */
393 nstat = flag*i + ostat; 393 nstat = flag*i + ostat;
394 394
395 /* Do some bounds checking. While I don't think any 395 /* Do some bounds checking. While I don't think any
396 * potions do so right now, there is the potential for potions 396 * potions do so right now, there is the potential for potions
397 * that adjust that stat by more than one point, so we need 397 * that adjust that stat by more than one point, so we need
398 * to allow for that. 398 * to allow for that.
399 */ 399 */
400 if (nstat < 1 && i*flag < 0 ) nstat = 1; 400 if (nstat < 1 && i*flag < 0 ) nstat = 1;
401 else if (nstat > 20 + get_attr_value(&(op->arch->clone.stats),j)) { 401 else if (nstat > 20 + get_attr_value(&(op->arch->clone.stats),j)) {
402 nstat = 20 + get_attr_value(&(op->arch->clone.stats),j); 402 nstat = 20 + get_attr_value(&(op->arch->clone.stats),j);
403 } 403 }
404 if (nstat != ostat) { 404 if (nstat != ostat) {
405 set_attr_value(&(op->contr->orig_stats), j, nstat); 405 set_attr_value(&(op->contr->orig_stats), j, nstat);
406 potion_max=0; 406 potion_max=0;
407 } 407 }
408 else if (i) { 408 else if (i) {
409 /* potion is useless - player has already hit the natural maximum */ 409 /* potion is useless - player has already hit the natural maximum */
410 potion_max = 1; 410 potion_max = 1;
411 } 411 }
412 } 412 }
413 /* This section of code ups the characters normal stats also. I am not 413 /* This section of code ups the characters normal stats also. I am not
414 * sure if this is strictly necessary, being that fix_player probably 414 * sure if this is strictly necessary, being that fix_player probably
415 * recalculates this anyway. 415 * recalculates this anyway.
416 */ 416 */
417 for(j=0;j<NUM_STATS;j++) 417 for(j=0;j<NUM_STATS;j++)
418 change_attr_value(&(op->stats),j,flag*get_attr_value(&(tmp->stats),j)); 418 change_attr_value(&(op->stats),j,flag*get_attr_value(&(tmp->stats),j));
419 check_stat_bounds(&(op->stats)); 419 check_stat_bounds(&(op->stats));
420 } /* end of potion handling code */ 420 } /* end of potion handling code */
421 } 421 }
422 422
423 /* reset attributes that fix_player doesn't reset since it doesn't search 423 /* reset attributes that fix_player doesn't reset since it doesn't search
424 * everything to set 424 * everything to set
425 */ 425 */
426 if(flag == -1) { 426 if(flag == -1) {
427 op->attacktype&=~tmp->attacktype; 427 op->attacktype&=~tmp->attacktype;
428 op->path_attuned&=~tmp->path_attuned; 428 op->path_attuned&=~tmp->path_attuned;
429 op->path_repelled&=~tmp->path_repelled; 429 op->path_repelled&=~tmp->path_repelled;
430 op->path_denied&=~tmp->path_denied; 430 op->path_denied&=~tmp->path_denied;
431 /* Presuming here that creatures only have move_type, 431 /* Presuming here that creatures only have move_type,
432 * and not the other move_ fields. 432 * and not the other move_ fields.
433 */ 433 */
434 op->move_type &= ~tmp->move_type; 434 op->move_type &= ~tmp->move_type;
435 } 435 }
436 436
437 /* call fix_player since op object could have whatever attribute due 437 /* call fix_player since op object could have whatever attribute due
438 * to multiple items. if fix_player always has to be called after 438 * to multiple items. if fix_player always has to be called after
439 * change_ability then might as well call it from here 439 * change_ability then might as well call it from here
442 442
443 /* Fix player won't add the bows ability to the player, so don't 443 /* Fix player won't add the bows ability to the player, so don't
444 * print out message if this is a bow. 444 * print out message if this is a bow.
445 */ 445 */
446 if(tmp->attacktype & AT_CONFUSION && tmp->type != BOW) { 446 if(tmp->attacktype & AT_CONFUSION && tmp->type != BOW) {
447 success=1; 447 success=1;
448 DIFF_MSG(flag, "Your hands begin to glow red.", 448 DIFF_MSG(flag, "Your hands begin to glow red.",
449 "Your hands stop glowing red."); 449 "Your hands stop glowing red.");
450 } 450 }
451 if ( QUERY_FLAG(op,FLAG_LIFESAVE) != QUERY_FLAG(&refop,FLAG_LIFESAVE)){ 451 if ( QUERY_FLAG(op,FLAG_LIFESAVE) != QUERY_FLAG(&refop,FLAG_LIFESAVE)){
452 success=1; 452 success=1;
453 DIFF_MSG(flag, "You feel very protected.", 453 DIFF_MSG(flag, "You feel very protected.",
454 "You don't feel protected anymore."); 454 "You don't feel protected anymore.");
455 } 455 }
456 if ( QUERY_FLAG(op,FLAG_REFL_MISSILE) != QUERY_FLAG(&refop,FLAG_REFL_MISSILE)){ 456 if ( QUERY_FLAG(op,FLAG_REFL_MISSILE) != QUERY_FLAG(&refop,FLAG_REFL_MISSILE)){
457 success=1; 457 success=1;
458 DIFF_MSG(flag, "A magic force shimmers around you.", 458 DIFF_MSG(flag, "A magic force shimmers around you.",
459 "The magic force fades away."); 459 "The magic force fades away.");
460 } 460 }
461 if ( QUERY_FLAG(op,FLAG_REFL_SPELL) != QUERY_FLAG(&refop,FLAG_REFL_SPELL)){ 461 if ( QUERY_FLAG(op,FLAG_REFL_SPELL) != QUERY_FLAG(&refop,FLAG_REFL_SPELL)){
462 success=1; 462 success=1;
463 DIFF_MSG(flag, "You feel more safe now, somehow.", 463 DIFF_MSG(flag, "You feel more safe now, somehow.",
464 "Suddenly you feel less safe, somehow."); 464 "Suddenly you feel less safe, somehow.");
465 } 465 }
466 /* movement type has changed. We don't care about cases where 466 /* movement type has changed. We don't care about cases where
467 * user has multiple items giving the same type appled like we 467 * user has multiple items giving the same type appled like we
468 * used to - that is more work than what we gain, plus messages 468 * used to - that is more work than what we gain, plus messages
469 * can be misleading (a little higher could be miscontrued from 469 * can be misleading (a little higher could be miscontrued from
470 * from fly high) 470 * from fly high)
471 */ 471 */
472 if (tmp->move_type && op->move_type != refop.move_type) { 472 if (tmp->move_type && op->move_type != refop.move_type) {
473 success=1; 473 success=1;
474 474
475 /* MOVE_FLY_HIGH trumps MOVE_FLY_LOW - changing your move_fly_low 475 /* MOVE_FLY_HIGH trumps MOVE_FLY_LOW - changing your move_fly_low
476 * status doesn't make a difference if you are flying high 476 * status doesn't make a difference if you are flying high
477 */ 477 */
478 if (tmp->move_type & MOVE_FLY_LOW && !(op->move_type & MOVE_FLY_HIGH)) { 478 if (tmp->move_type & MOVE_FLY_LOW && !(op->move_type & MOVE_FLY_HIGH)) {
479 DIFF_MSG(flag, "You start to float in the air!.", "You float down to the ground."); 479 DIFF_MSG(flag, "You start to float in the air!.", "You float down to the ground.");
480 } 480 }
481 481
482 if (tmp->move_type & MOVE_FLY_HIGH) { 482 if (tmp->move_type & MOVE_FLY_HIGH) {
483 /* double conditional - second case covers if you have move_fly_low - 483 /* double conditional - second case covers if you have move_fly_low -
484 * in that case, you don't actually land 484 * in that case, you don't actually land
485 */ 485 */
486 DIFF_MSG(flag, "You soar into the air air!.", 486 DIFF_MSG(flag, "You soar into the air air!.",
487 (op->move_type&MOVE_FLY_LOW ? "You fly lower in the air": 487 (op->move_type&MOVE_FLY_LOW ? "You fly lower in the air":
488 "You float down to the ground.")); 488 "You float down to the ground."));
489 } 489 }
490 if (tmp->move_type & MOVE_SWIM) 490 if (tmp->move_type & MOVE_SWIM)
491 DIFF_MSG(flag,"You feel ready for a swim", "You no longer feel like swimming"); 491 DIFF_MSG(flag,"You feel ready for a swim", "You no longer feel like swimming");
492 492
493 /* Changing move status may mean you are affected by things you weren't before */ 493 /* Changing move status may mean you are affected by things you weren't before */
494 check_move_on(op, op); 494 check_move_on(op, op);
495 } 495 }
496 496
497 /* becoming UNDEAD... a special treatment for this flag. Only those not 497 /* becoming UNDEAD... a special treatment for this flag. Only those not
498 * originally undead may change their status 498 * originally undead may change their status
499 */ 499 */
500 if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) 500 if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD))
501 if ( QUERY_FLAG(op,FLAG_UNDEAD) != QUERY_FLAG(&refop,FLAG_UNDEAD)) { 501 if ( QUERY_FLAG(op,FLAG_UNDEAD) != QUERY_FLAG(&refop,FLAG_UNDEAD)) {
502 success=1; 502 success=1;
503 if(flag>0) { 503 if(flag>0) {
504 if(op->race) free_string(op->race); 504 op->race = "undead";
505 op->race=add_string("undead");
506 new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce drains away!"); 505 new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce drains away!");
507 } else { 506 } else {
508 if(op->race) free_string(op->race); 507 op->race = op->arch->clone.race;
509 if(op->arch->clone.race)
510 op->race=add_string(op->arch->clone.race);
511 else
512 op->race = NULL;
513 new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce returns!"); 508 new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce returns!");
514 } 509 }
515 } 510 }
516 511
517 if ( QUERY_FLAG(op,FLAG_STEALTH) != QUERY_FLAG(&refop,FLAG_STEALTH)){ 512 if ( QUERY_FLAG(op,FLAG_STEALTH) != QUERY_FLAG(&refop,FLAG_STEALTH)){
518 success=1; 513 success=1;
519 DIFF_MSG(flag, "You walk more quietly.", "You walk more noisily."); 514 DIFF_MSG(flag, "You walk more quietly.", "You walk more noisily.");
520 } 515 }
521 if ( QUERY_FLAG(op,FLAG_MAKE_INVIS) != QUERY_FLAG(&refop,FLAG_MAKE_INVIS)){ 516 if ( QUERY_FLAG(op,FLAG_MAKE_INVIS) != QUERY_FLAG(&refop,FLAG_MAKE_INVIS)){
522 success=1; 517 success=1;
523 DIFF_MSG(flag, "You become transparent.", "You can see yourself."); 518 DIFF_MSG(flag, "You become transparent.", "You can see yourself.");
524 } 519 }
525 /* blinded you can tell if more blinded since blinded player has minimal 520 /* blinded you can tell if more blinded since blinded player has minimal
526 * vision 521 * vision
527 */ 522 */
528 if(QUERY_FLAG(tmp,FLAG_BLIND)) { 523 if(QUERY_FLAG(tmp,FLAG_BLIND)) {
529 success=1; 524 success=1;
530 if(flag>0) { 525 if(flag>0) {
531 if(QUERY_FLAG(op,FLAG_WIZ)) 526 if(QUERY_FLAG(op,FLAG_WIZ))
532 new_draw_info(NDI_UNIQUE, 0, op,"Your mortal self is blinded."); 527 new_draw_info(NDI_UNIQUE, 0, op,"Your mortal self is blinded.");
533 else { 528 else {
534 new_draw_info(NDI_UNIQUE, 0, op,"You are blinded."); 529 new_draw_info(NDI_UNIQUE, 0, op,"You are blinded.");
535 SET_FLAG(op,FLAG_BLIND); 530 SET_FLAG(op,FLAG_BLIND);
536 if(op->type==PLAYER) 531 if(op->type==PLAYER)
537 op->contr->do_los=1; 532 op->contr->do_los=1;
538 } 533 }
539 } else { 534 } else {
540 if(QUERY_FLAG(op,FLAG_WIZ)) 535 if(QUERY_FLAG(op,FLAG_WIZ))
541 new_draw_info(NDI_UNIQUE, 0, op,"Your mortal self can now see again."); 536 new_draw_info(NDI_UNIQUE, 0, op,"Your mortal self can now see again.");
542 else { 537 else {
543 new_draw_info(NDI_UNIQUE, 0, op,"Your vision returns."); 538 new_draw_info(NDI_UNIQUE, 0, op,"Your vision returns.");
544 CLEAR_FLAG(op,FLAG_BLIND); 539 CLEAR_FLAG(op,FLAG_BLIND);
545 if(op->type==PLAYER) 540 if(op->type==PLAYER)
546 op->contr->do_los=1; 541 op->contr->do_los=1;
547 } 542 }
548 } 543 }
549 } 544 }
550 545
551 if ( QUERY_FLAG(op,FLAG_SEE_IN_DARK) != QUERY_FLAG(&refop,FLAG_SEE_IN_DARK)){ 546 if ( QUERY_FLAG(op,FLAG_SEE_IN_DARK) != QUERY_FLAG(&refop,FLAG_SEE_IN_DARK)){
552 success=1; 547 success=1;
553 if(op->type==PLAYER) 548 if(op->type==PLAYER)
554 op->contr->do_los=1; 549 op->contr->do_los=1;
555 DIFF_MSG(flag, "Your vision is better in the dark.", "You see less well in the dark."); 550 DIFF_MSG(flag, "Your vision is better in the dark.", "You see less well in the dark.");
556 } 551 }
557 552
558 if ( QUERY_FLAG(op,FLAG_XRAYS) != QUERY_FLAG(&refop,FLAG_XRAYS)){ 553 if ( QUERY_FLAG(op,FLAG_XRAYS) != QUERY_FLAG(&refop,FLAG_XRAYS)){
559 success=1; 554 success=1;
560 if(flag>0) { 555 if(flag>0) {
561 if(QUERY_FLAG(op,FLAG_WIZ)) 556 if(QUERY_FLAG(op,FLAG_WIZ))
562 new_draw_info(NDI_UNIQUE, 0, op,"Your vision becomes a little clearer."); 557 new_draw_info(NDI_UNIQUE, 0, op,"Your vision becomes a little clearer.");
563 else { 558 else {
564 new_draw_info(NDI_UNIQUE, 0, op,"Everything becomes transparent."); 559 new_draw_info(NDI_UNIQUE, 0, op,"Everything becomes transparent.");
565 if(op->type==PLAYER) 560 if(op->type==PLAYER)
566 op->contr->do_los=1; 561 op->contr->do_los=1;
567 } 562 }
568 } else { 563 } else {
569 if(QUERY_FLAG(op,FLAG_WIZ)) 564 if(QUERY_FLAG(op,FLAG_WIZ))
570 new_draw_info(NDI_UNIQUE, 0, op,"Your vision becomes a bit out of focus."); 565 new_draw_info(NDI_UNIQUE, 0, op,"Your vision becomes a bit out of focus.");
571 else { 566 else {
572 new_draw_info(NDI_UNIQUE, 0, op,"Everything suddenly looks very solid."); 567 new_draw_info(NDI_UNIQUE, 0, op,"Everything suddenly looks very solid.");
573 if(op->type==PLAYER) 568 if(op->type==PLAYER)
574 op->contr->do_los=1; 569 op->contr->do_los=1;
575 } 570 }
576 } 571 }
577 } 572 }
578 573
579 if(tmp->stats.luck) { 574 if(tmp->stats.luck) {
580 success=1; 575 success=1;
581 DIFF_MSG(flag*tmp->stats.luck, "You feel more lucky.", "You feel less lucky."); 576 DIFF_MSG(flag*tmp->stats.luck, "You feel more lucky.", "You feel less lucky.");
582 } 577 }
583 578
584 if(tmp->stats.hp && op->type==PLAYER) { 579 if(tmp->stats.hp && op->type==PLAYER) {
585 success=1; 580 success=1;
586 DIFF_MSG(flag*tmp->stats.hp, "You feel much more healthy!", 581 DIFF_MSG(flag*tmp->stats.hp, "You feel much more healthy!",
587 "You feel much less healthy!"); 582 "You feel much less healthy!");
588 } 583 }
589 584
590 if(tmp->stats.sp && op->type==PLAYER && tmp->type!=SKILL) { 585 if(tmp->stats.sp && op->type==PLAYER && tmp->type!=SKILL) {
591 success=1; 586 success=1;
592 DIFF_MSG(flag*tmp->stats.sp, "You feel one with the powers of magic!", 587 DIFF_MSG(flag*tmp->stats.sp, "You feel one with the powers of magic!",
593 "You suddenly feel very mundane."); 588 "You suddenly feel very mundane.");
594 } 589 }
595 590
596 /* for the future when artifacts set this -b.t. */ 591 /* for the future when artifacts set this -b.t. */
597 if(tmp->stats.grace && op->type==PLAYER) { 592 if(tmp->stats.grace && op->type==PLAYER) {
598 success=1; 593 success=1;
599 DIFF_MSG(flag*tmp->stats.grace, "You feel closer to your god!", 594 DIFF_MSG(flag*tmp->stats.grace, "You feel closer to your god!",
600 "You suddenly feel less holy."); 595 "You suddenly feel less holy.");
601 } 596 }
602 597
603 if(tmp->stats.food && op->type==PLAYER) { 598 if(tmp->stats.food && op->type==PLAYER) {
604 success=1; 599 success=1;
605 DIFF_MSG(flag*tmp->stats.food, "You feel your digestion slowing down.", 600 DIFF_MSG(flag*tmp->stats.food, "You feel your digestion slowing down.",
606 "You feel your digestion speeding up."); 601 "You feel your digestion speeding up.");
607 } 602 }
608 603
609 /* Messages for changed resistance */ 604 /* Messages for changed resistance */
610 for (i=0; i<NROFATTACKS; i++) { 605 for (i=0; i<NROFATTACKS; i++) {
611 if (i==ATNR_PHYSICAL) continue; /* Don't display about armour */ 606 if (i==ATNR_PHYSICAL) continue; /* Don't display about armour */
612 607
613 if (op->resist[i] != refop.resist[i]) { 608 if (op->resist[i] != refop.resist[i]) {
614 success=1; 609 success=1;
615 if (op->resist[i] > refop.resist[i]) 610 if (op->resist[i] > refop.resist[i])
616 sprintf(message, "Your resistance to %s rises to %d%%.", 611 sprintf(message, "Your resistance to %s rises to %d%%.",
617 change_resist_msg[i], op->resist[i]); 612 change_resist_msg[i], op->resist[i]);
618 else 613 else
619 sprintf(message, "Your resistance to %s drops to %d%%.", 614 sprintf(message, "Your resistance to %s drops to %d%%.",
620 change_resist_msg[i], op->resist[i]); 615 change_resist_msg[i], op->resist[i]);
621 616
622 new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, op, message); 617 new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, op, message);
623 } 618 }
624 } 619 }
625 620
626 if(tmp->type!=EXPERIENCE && !potion_max) { 621 if(tmp->type!=EXPERIENCE && !potion_max) {
627 for (j=0; j<NUM_STATS; j++) { 622 for (j=0; j<NUM_STATS; j++) {
628 if ((i=get_attr_value(&(tmp->stats),j))!=0) { 623 if ((i=get_attr_value(&(tmp->stats),j))!=0) {
629 success=1; 624 success=1;
630 DIFF_MSG(i * flag, gain_msg[j], lose_msg[j]); 625 DIFF_MSG(i * flag, gain_msg[j], lose_msg[j]);
631 } 626 }
632 } 627 }
633 } 628 }
634 return success; 629 return success;
635} 630}
636 631
637/* 632/*
693 * in op itself). 688 * in op itself).
694 */ 689 */
695 new_luck = tmp->stats.luck+value; 690 new_luck = tmp->stats.luck+value;
696 if (new_luck >= -100 && new_luck <= 100) { 691 if (new_luck >= -100 && new_luck <= 100) {
697 op->stats.luck+=value; 692 op->stats.luck+=value;
698 tmp->stats.luck = new_luck; 693 tmp->stats.luck = new_luck;
699 } 694 }
700 } else { 695 } else {
701 if (!tmp->stats.luck) { 696 if (!tmp->stats.luck) {
702 return; 697 return;
703 } 698 }
766 spell system split, grace points now added to system --peterm 761 spell system split, grace points now added to system --peterm
767 */ 762 */
768 763
769void fix_player(object *op) { 764void fix_player(object *op) {
770 int i,j; 765 int i,j;
771 event *evt;
772 float f,max=9,added_speed=0,bonus_speed=0, sp_tmp,speed_reduce_from_disease=1; 766 float f,max=9,added_speed=0,bonus_speed=0, sp_tmp,speed_reduce_from_disease=1;
773 int weapon_weight=0,weapon_speed=0; 767 int weapon_weight=0,weapon_speed=0;
774 int best_wc=0, best_ac=0, wc=0, ac=0; 768 int best_wc=0, best_ac=0, wc=0, ac=0;
775 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; 769 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS];
776 object *grace_obj=NULL,*mana_obj=NULL,*wc_obj=NULL,*tmp; 770 object *grace_obj=NULL,*mana_obj=NULL,*wc_obj=NULL,*tmp;
777 771
778 /* First task is to clear all the values back to their original values */ 772 /* First task is to clear all the values back to their original values */
779 if(op->type==PLAYER) { 773 if(op->type==PLAYER) {
780 for(i=0;i<NUM_STATS;i++) { 774 for(i=0;i<NUM_STATS;i++) {
781 set_attr_value(&(op->stats),i,get_attr_value(&(op->contr->orig_stats),i)); 775 set_attr_value(&(op->stats),i,get_attr_value(&(op->contr->orig_stats),i));
782 } 776 }
783 if (settings.spell_encumbrance == TRUE) 777 if (settings.spell_encumbrance == TRUE)
784 op->contr->encumbrance=0; 778 op->contr->encumbrance=0;
785 779
786 op->attacktype=0; 780 op->attacktype=0;
787 op->contr->digestion = 0; 781 op->contr->digestion = 0;
788 op->contr->gen_hp = 0; 782 op->contr->gen_hp = 0;
789 op->contr->gen_sp = 0; 783 op->contr->gen_sp = 0;
790 op->contr->gen_grace = 0; 784 op->contr->gen_grace = 0;
791 op->contr->gen_sp_armour = 10; 785 op->contr->gen_sp_armour = 10;
792 op->contr->item_power = 0; 786 op->contr->item_power = 0;
793 787
794 /* Don't clobber all the range_ values. range_golem otherwise 788 /* Don't clobber all the range_ values. range_golem otherwise
795 * gets reset for no good reason, and we don't want to reset 789 * gets reset for no good reason, and we don't want to reset
796 * range_magic (what spell is readied). These three below 790 * range_magic (what spell is readied). These three below
797 * well get filled in based on what the player has equipped. 791 * well get filled in based on what the player has equipped.
798 */ 792 */
799 op->contr->ranges[range_bow] = NULL; 793 op->contr->ranges[range_bow] = NULL;
800 op->contr->ranges[range_misc] = NULL; 794 op->contr->ranges[range_misc] = NULL;
801 op->contr->ranges[range_skill] = NULL; 795 op->contr->ranges[range_skill] = NULL;
802 } 796 }
803 memcpy(op->body_used, op->body_info, sizeof(op->body_info)); 797 memcpy(op->body_used, op->body_info, sizeof(op->body_info));
804 798
805 if(op->slaying!=NULL) { 799 op->slaying = 0;
806 free_string(op->slaying); 800
807 op->slaying=NULL;
808 }
809 if(!QUERY_FLAG(op,FLAG_WIZ)) { 801 if(!QUERY_FLAG(op,FLAG_WIZ)) {
810 CLEAR_FLAG(op, FLAG_XRAYS); 802 CLEAR_FLAG(op, FLAG_XRAYS);
811 CLEAR_FLAG(op, FLAG_MAKE_INVIS); 803 CLEAR_FLAG(op, FLAG_MAKE_INVIS);
812 } 804 }
813 805
814 CLEAR_FLAG(op,FLAG_LIFESAVE); 806 CLEAR_FLAG(op,FLAG_LIFESAVE);
815 CLEAR_FLAG(op,FLAG_STEALTH); 807 CLEAR_FLAG(op,FLAG_STEALTH);
816 CLEAR_FLAG(op,FLAG_BLIND); 808 CLEAR_FLAG(op,FLAG_BLIND);
817 if ( ! QUERY_FLAG (&op->arch->clone, FLAG_REFL_SPELL)) 809 if ( ! QUERY_FLAG (&op->arch->clone, FLAG_REFL_SPELL))
818 CLEAR_FLAG(op,FLAG_REFL_SPELL); 810 CLEAR_FLAG(op,FLAG_REFL_SPELL);
819 if ( ! QUERY_FLAG (&op->arch->clone, FLAG_REFL_MISSILE)) 811 if ( ! QUERY_FLAG (&op->arch->clone, FLAG_REFL_MISSILE))
820 CLEAR_FLAG(op,FLAG_REFL_MISSILE); 812 CLEAR_FLAG(op,FLAG_REFL_MISSILE);
821 if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) 813 if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD))
822 CLEAR_FLAG(op,FLAG_UNDEAD); 814 CLEAR_FLAG(op,FLAG_UNDEAD);
823 if ( ! QUERY_FLAG (&op->arch->clone, FLAG_SEE_IN_DARK)) 815 if ( ! QUERY_FLAG (&op->arch->clone, FLAG_SEE_IN_DARK))
824 CLEAR_FLAG(op,FLAG_SEE_IN_DARK); 816 CLEAR_FLAG(op,FLAG_SEE_IN_DARK);
825 817
826 op->path_attuned=op->arch->clone.path_attuned; 818 op->path_attuned=op->arch->clone.path_attuned;
827 op->path_repelled=op->arch->clone.path_repelled; 819 op->path_repelled=op->arch->clone.path_repelled;
828 op->path_denied=op->arch->clone.path_denied; 820 op->path_denied=op->arch->clone.path_denied;
829 op->glow_radius=op->arch->clone.glow_radius; 821 op->glow_radius=op->arch->clone.glow_radius;
834 * archetype clone 826 * archetype clone
835 */ 827 */
836 memcpy(&op->resist, &op->arch->clone.resist, sizeof(op->resist)); 828 memcpy(&op->resist, &op->arch->clone.resist, sizeof(op->resist));
837 829
838 for (i=0;i<NROFATTACKS;i++) { 830 for (i=0;i<NROFATTACKS;i++) {
839 if (op->resist[i] > 0) 831 if (op->resist[i] > 0)
840 prot[i]= op->resist[i], vuln[i]=0; 832 prot[i]= op->resist[i], vuln[i]=0;
841 else 833 else
842 vuln[i]= -(op->resist[i]), prot[i]=0; 834 vuln[i]= -(op->resist[i]), prot[i]=0;
843 potion_resist[i]=0; 835 potion_resist[i]=0;
844 } 836 }
845 837
846 wc=op->arch->clone.stats.wc; 838 wc=op->arch->clone.stats.wc;
847 op->stats.dam=op->arch->clone.stats.dam; 839 op->stats.dam=op->arch->clone.stats.dam;
848 840
852 * we should probably give them some bonus and cap it off - otherwise, 844 * we should probably give them some bonus and cap it off - otherwise,
853 * basically, if a server updates its max level, these playes may find 845 * basically, if a server updates its max level, these playes may find
854 * that their protection from physical goes down 846 * that their protection from physical goes down
855 */ 847 */
856 if(!QUERY_FLAG(op,FLAG_USE_ARMOUR) && op->type==PLAYER) { 848 if(!QUERY_FLAG(op,FLAG_USE_ARMOUR) && op->type==PLAYER) {
857 ac=MAX(-10,op->arch->clone.stats.ac - op->level/3); 849 ac=MAX(-10,op->arch->clone.stats.ac - op->level/3);
858 prot[ATNR_PHYSICAL] += ((100-prot[AT_PHYSICAL])*(80*op->level/settings.max_level))/100; 850 prot[ATNR_PHYSICAL] += ((100-prot[AT_PHYSICAL])*(80*op->level/settings.max_level))/100;
859 } 851 }
860 else 852 else
861 ac=op->arch->clone.stats.ac; 853 ac=op->arch->clone.stats.ac;
862 854
863 op->stats.luck=op->arch->clone.stats.luck; 855 op->stats.luck=op->arch->clone.stats.luck;
864 op->speed = op->arch->clone.speed; 856 op->speed = op->arch->clone.speed;
865 857
866 /* OK - we've reset most all the objects attributes to sane values. 858 /* OK - we've reset most all the objects attributes to sane values.
867 * now go through and make adjustments for what the player has equipped. 859 * now go through and make adjustments for what the player has equipped.
868 */ 860 */
869 861
870 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) { 862 for(tmp=op->inv;tmp!=NULL;tmp=tmp->below) {
871 /* See note in map.c:update_position about making this additive 863 /* See note in map.c:update_position about making this additive
872 * since light sources are never applied, need to put check here. 864 * since light sources are never applied, need to put check here.
873 */ 865 */
874 if (tmp->glow_radius > op->glow_radius) op->glow_radius=tmp->glow_radius; 866 if (tmp->glow_radius > op->glow_radius) op->glow_radius=tmp->glow_radius;
875 867
876 /* This happens because apply_potion calls change_abil with the potion 868 /* This happens because apply_potion calls change_abil with the potion
877 * applied so we can tell the player what chagned. But change_abil 869 * applied so we can tell the player what chagned. But change_abil
878 * then calls this function. 870 * then calls this function.
879 */ 871 */
880 if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == POTION) { 872 if (QUERY_FLAG(tmp, FLAG_APPLIED) && tmp->type == POTION) {
881 continue; 873 continue;
882 } 874 }
883 875
884 /* For some things, we don't care what is equipped */ 876 /* For some things, we don't care what is equipped */
885 if (tmp->type == SKILL) { 877 if (tmp->type == SKILL) {
886 /* Want to take the highest skill here. */ 878 /* Want to take the highest skill here. */
887 if (IS_MANA_SKILL(tmp->subtype)) { 879 if (IS_MANA_SKILL(tmp->subtype)) {
888 if (!mana_obj) mana_obj=tmp; 880 if (!mana_obj) mana_obj=tmp;
889 else if (tmp->level > mana_obj->level) mana_obj = tmp; 881 else if (tmp->level > mana_obj->level) mana_obj = tmp;
890 } 882 }
891 if (IS_GRACE_SKILL(tmp->subtype)) { 883 if (IS_GRACE_SKILL(tmp->subtype)) {
892 if (!grace_obj) grace_obj=tmp; 884 if (!grace_obj) grace_obj=tmp;
893 else if (tmp->level > grace_obj->level) grace_obj = tmp; 885 else if (tmp->level > grace_obj->level) grace_obj = tmp;
894 } 886 }
895 } 887 }
896 888
897 /* Container objects are not meant to adjust a players, but other applied 889 /* Container objects are not meant to adjust a players, but other applied
898 * objects need to make adjustments. 890 * objects need to make adjustments.
899 * This block should handle all player specific changes 891 * This block should handle all player specific changes
900 * The check for Praying is a bit of a hack - god given bonuses are put 892 * The check for Praying is a bit of a hack - god given bonuses are put
901 * in the praying skill, and the player should always get those. 893 * in the praying skill, and the player should always get those.
902 * It also means we need to put in additional checks for applied below, 894 * It also means we need to put in additional checks for applied below,
903 * because the skill shouldn't count against body positions being used 895 * because the skill shouldn't count against body positions being used
904 * up, etc. 896 * up, etc.
905 */ 897 */
906 if ((QUERY_FLAG(tmp,FLAG_APPLIED) && tmp->type!=CONTAINER && tmp->type!=CLOSE_CON) || 898 if ((QUERY_FLAG(tmp,FLAG_APPLIED) && tmp->type!=CONTAINER && tmp->type!=CLOSE_CON) ||
907 (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) { 899 (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) {
908 if(op->type==PLAYER) { 900 if(op->type==PLAYER) {
909 if (tmp->type == BOW) 901 if (tmp->type == BOW)
910 op->contr->ranges[range_bow] = tmp; 902 op->contr->ranges[range_bow] = tmp;
911 903
912 if (tmp->type == WAND || tmp->type == ROD || tmp->type==HORN) 904 if (tmp->type == WAND || tmp->type == ROD || tmp->type==HORN)
913 op->contr->ranges[range_misc] = tmp; 905 op->contr->ranges[range_misc] = tmp;
914 906
915 for(i=0;i<NUM_STATS;i++) 907 for(i=0;i<NUM_STATS;i++)
916 change_attr_value(&(op->stats),i,get_attr_value(&(tmp->stats),i)); 908 change_attr_value(&(op->stats),i,get_attr_value(&(tmp->stats),i));
917 909
918 /* these are the items that currently can change digestion, regeneration, 910 /* these are the items that currently can change digestion, regeneration,
919 * spell point recovery and mana point recovery. Seems sort of an arbitary 911 * spell point recovery and mana point recovery. Seems sort of an arbitary
920 * list, but other items store other info into stats array. 912 * list, but other items store other info into stats array.
921 */ 913 */
922 if ((tmp->type == EXPERIENCE) || (tmp->type == WEAPON) || 914 if ((tmp->type == EXPERIENCE) || (tmp->type == WEAPON) ||
923 (tmp->type == ARMOUR) || (tmp->type == HELMET) || 915 (tmp->type == ARMOUR) || (tmp->type == HELMET) ||
924 (tmp->type == SHIELD) || (tmp->type == RING) || 916 (tmp->type == SHIELD) || (tmp->type == RING) ||
925 (tmp->type == BOOTS) || (tmp->type == GLOVES) || 917 (tmp->type == BOOTS) || (tmp->type == GLOVES) ||
926 (tmp->type == AMULET ) || (tmp->type == GIRDLE) || 918 (tmp->type == AMULET ) || (tmp->type == GIRDLE) ||
927 (tmp->type == BRACERS ) || (tmp->type == CLOAK) || 919 (tmp->type == BRACERS ) || (tmp->type == CLOAK) ||
928 (tmp->type == DISEASE) || (tmp->type == FORCE) || 920 (tmp->type == DISEASE) || (tmp->type == FORCE) ||
929 (tmp->type == SKILL)) { 921 (tmp->type == SKILL)) {
930 op->contr->digestion += tmp->stats.food; 922 op->contr->digestion += tmp->stats.food;
931 op->contr->gen_hp += tmp->stats.hp; 923 op->contr->gen_hp += tmp->stats.hp;
932 op->contr->gen_sp += tmp->stats.sp; 924 op->contr->gen_sp += tmp->stats.sp;
933 op->contr->gen_grace += tmp->stats.grace; 925 op->contr->gen_grace += tmp->stats.grace;
934 op->contr->gen_sp_armour+= tmp->gen_sp_armour; 926 op->contr->gen_sp_armour+= tmp->gen_sp_armour;
935 op->contr->item_power += tmp->item_power; 927 op->contr->item_power += tmp->item_power;
936 } 928 }
937 } /* if this is a player */ 929 } /* if this is a player */
938 930
939 /* Update slots used for items */ 931 /* Update slots used for items */
940 if (QUERY_FLAG(tmp,FLAG_APPLIED)) { 932 if (QUERY_FLAG(tmp,FLAG_APPLIED)) {
941 for (i=0; i<NUM_BODY_LOCATIONS; i++) 933 for (i=0; i<NUM_BODY_LOCATIONS; i++)
942 op->body_used[i] += tmp->body_info[i]; 934 op->body_used[i] += tmp->body_info[i];
943 } 935 }
944 936
945 if(tmp->type==SYMPTOM) { 937 if(tmp->type==SYMPTOM) {
946 speed_reduce_from_disease = tmp->last_sp / 100.0; 938 speed_reduce_from_disease = tmp->last_sp / 100.0;
947 if(speed_reduce_from_disease ==0) speed_reduce_from_disease = 1; 939 if(speed_reduce_from_disease ==0) speed_reduce_from_disease = 1;
948 } 940 }
949 941
950 /* Pos. and neg. protections are counted seperate (-> pro/vuln). 942 /* Pos. and neg. protections are counted seperate (-> pro/vuln).
951 * (Negative protections are calculated extactly like positive.) 943 * (Negative protections are calculated extactly like positive.)
952 * Resistance from potions are treated special as well. If there's 944 * Resistance from potions are treated special as well. If there's
953 * more than one potion-effect, the bigger prot.-value is taken. 945 * more than one potion-effect, the bigger prot.-value is taken.
954 */ 946 */
955 if (tmp->type != POTION) { 947 if (tmp->type != POTION) {
956 for (i=0; i<NROFATTACKS; i++) { 948 for (i=0; i<NROFATTACKS; i++) {
957 /* Potential for cursed potions, in which case we just can use 949 /* Potential for cursed potions, in which case we just can use
958 * a straight MAX, as potion_resist is initialized to zero. 950 * a straight MAX, as potion_resist is initialized to zero.
959 */ 951 */
960 if (tmp->type==POTION_EFFECT) { 952 if (tmp->type==POTION_EFFECT) {
961 if (potion_resist[i]) 953 if (potion_resist[i])
962 potion_resist[i] = MAX(potion_resist[i], tmp->resist[i]); 954 potion_resist[i] = MAX(potion_resist[i], tmp->resist[i]);
963 else 955 else
964 potion_resist[i] = tmp->resist[i]; 956 potion_resist[i] = tmp->resist[i];
965 } 957 }
966 else if (tmp->resist[i] > 0) 958 else if (tmp->resist[i] > 0)
967 prot[i] += ((100-prot[i])*tmp->resist[i])/100; 959 prot[i] += ((100-prot[i])*tmp->resist[i])/100;
968 else if (tmp->resist[i] < 0) 960 else if (tmp->resist[i] < 0)
969 vuln[i] += ((100-vuln[i])*(-tmp->resist[i]))/100; 961 vuln[i] += ((100-vuln[i])*(-tmp->resist[i]))/100;
970 } 962 }
971 } 963 }
972 964
973 /* There may be other things that should not adjust the attacktype */ 965 /* There may be other things that should not adjust the attacktype */
974 if (tmp->type!=BOW && tmp->type != SYMPTOM) 966 if (tmp->type!=BOW && tmp->type != SYMPTOM)
975 op->attacktype|=tmp->attacktype; 967 op->attacktype|=tmp->attacktype;
976 968
977 op->path_attuned|=tmp->path_attuned; 969 op->path_attuned|=tmp->path_attuned;
978 op->path_repelled|=tmp->path_repelled; 970 op->path_repelled|=tmp->path_repelled;
979 op->path_denied|=tmp->path_denied; 971 op->path_denied|=tmp->path_denied;
980 op->stats.luck+=tmp->stats.luck; 972 op->stats.luck+=tmp->stats.luck;
981 op->move_type |= tmp->move_type; 973 op->move_type |= tmp->move_type;
982 974
983 if(QUERY_FLAG(tmp,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE); 975 if(QUERY_FLAG(tmp,FLAG_LIFESAVE)) SET_FLAG(op,FLAG_LIFESAVE);
984 if(QUERY_FLAG(tmp,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL); 976 if(QUERY_FLAG(tmp,FLAG_REFL_SPELL)) SET_FLAG(op,FLAG_REFL_SPELL);
985 if(QUERY_FLAG(tmp,FLAG_REFL_MISSILE)) SET_FLAG(op,FLAG_REFL_MISSILE); 977 if(QUERY_FLAG(tmp,FLAG_REFL_MISSILE)) SET_FLAG(op,FLAG_REFL_MISSILE);
986 if(QUERY_FLAG(tmp,FLAG_STEALTH)) SET_FLAG(op,FLAG_STEALTH); 978 if(QUERY_FLAG(tmp,FLAG_STEALTH)) SET_FLAG(op,FLAG_STEALTH);
987 if(QUERY_FLAG(tmp,FLAG_XRAYS)) SET_FLAG(op,FLAG_XRAYS); 979 if(QUERY_FLAG(tmp,FLAG_XRAYS)) SET_FLAG(op,FLAG_XRAYS);
988 if(QUERY_FLAG(tmp,FLAG_BLIND)) SET_FLAG(op,FLAG_BLIND); 980 if(QUERY_FLAG(tmp,FLAG_BLIND)) SET_FLAG(op,FLAG_BLIND);
989 if(QUERY_FLAG(tmp,FLAG_SEE_IN_DARK)) SET_FLAG(op,FLAG_SEE_IN_DARK); 981 if(QUERY_FLAG(tmp,FLAG_SEE_IN_DARK)) SET_FLAG(op,FLAG_SEE_IN_DARK);
990 982
991 if(QUERY_FLAG(tmp,FLAG_UNDEAD)&&!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) 983 if(QUERY_FLAG(tmp,FLAG_UNDEAD)&&!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD))
992 SET_FLAG(op,FLAG_UNDEAD); 984 SET_FLAG(op,FLAG_UNDEAD);
993 985
994 if(QUERY_FLAG(tmp,FLAG_MAKE_INVIS)) { 986 if(QUERY_FLAG(tmp,FLAG_MAKE_INVIS)) {
995 SET_FLAG(op,FLAG_MAKE_INVIS); 987 SET_FLAG(op,FLAG_MAKE_INVIS);
996 op->invisible=1; 988 op->invisible=1;
997 } 989 }
998 990
999 if(tmp->stats.exp && tmp->type!=SKILL) { 991 if(tmp->stats.exp && tmp->type!=SKILL) {
1000 if(tmp->stats.exp > 0) { 992 if(tmp->stats.exp > 0) {
1001 added_speed+=(float)tmp->stats.exp/3.0; 993 added_speed+=(float)tmp->stats.exp/3.0;
1002 bonus_speed+=1.0+(float)tmp->stats.exp/3.0; 994 bonus_speed+=1.0+(float)tmp->stats.exp/3.0;
1003 } else 995 } else
1004 added_speed+=(float)tmp->stats.exp; 996 added_speed+=(float)tmp->stats.exp;
1005 } 997 }
1006 998
1007 switch(tmp->type) { 999 switch(tmp->type) {
1008 /* skills modifying the character -b.t. */ 1000 /* skills modifying the character -b.t. */
1009 /* for all skills and skill granting objects */ 1001 /* for all skills and skill granting objects */
1010 case SKILL: 1002 case SKILL:
1011 if (!QUERY_FLAG(tmp,FLAG_APPLIED)) break; 1003 if (!QUERY_FLAG(tmp,FLAG_APPLIED)) break;
1012 1004
1013 if (IS_COMBAT_SKILL(tmp->subtype)) wc_obj=tmp; 1005 if (IS_COMBAT_SKILL(tmp->subtype)) wc_obj=tmp;
1014 1006
1015 if (op->chosen_skill) { 1007 if (op->chosen_skill) {
1016 LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", op->name); 1008 LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name);
1017 } 1009 }
1018 op->chosen_skill = tmp; 1010 op->chosen_skill = tmp;
1019 if(tmp->stats.dam>0) { /* skill is a 'weapon' */ 1011 if(tmp->stats.dam>0) { /* skill is a 'weapon' */
1020 if(!QUERY_FLAG(op,FLAG_READY_WEAPON)) 1012 if(!QUERY_FLAG(op,FLAG_READY_WEAPON))
1021 weapon_speed = (int) WEAPON_SPEED(tmp); 1013 weapon_speed = (int) WEAPON_SPEED(tmp);
1022 if(weapon_speed<0) weapon_speed = 0; 1014 if(weapon_speed<0) weapon_speed = 0;
1023 weapon_weight=tmp->weight; 1015 weapon_weight=tmp->weight;
1024 op->stats.dam+=tmp->stats.dam*(1 + (op->chosen_skill->level/9)); 1016 op->stats.dam+=tmp->stats.dam*(1 + (op->chosen_skill->level/9));
1025 if(tmp->magic) op->stats.dam += tmp->magic; 1017 if(tmp->magic) op->stats.dam += tmp->magic;
1026 } 1018 }
1027 if(tmp->stats.wc) 1019 if(tmp->stats.wc)
1028 wc-=(tmp->stats.wc+tmp->magic); 1020 wc-=(tmp->stats.wc+tmp->magic);
1029 1021
1030 if(tmp->slaying!=NULL) { 1022 if (tmp->slaying!=NULL)
1031 if (op->slaying != NULL) 1023 op->slaying = tmp->slaying;
1032 free_string (op->slaying);
1033 add_refcount(op->slaying = tmp->slaying);
1034 }
1035 1024
1036 if(tmp->stats.ac) 1025 if(tmp->stats.ac)
1037 ac-=(tmp->stats.ac+tmp->magic); 1026 ac-=(tmp->stats.ac+tmp->magic);
1038 if(settings.spell_encumbrance == TRUE && op->type==PLAYER) 1027 if(settings.spell_encumbrance == TRUE && op->type==PLAYER)
1039 op->contr->encumbrance+=(int)3*tmp->weight/1000; 1028 op->contr->encumbrance+=(int)3*tmp->weight/1000;
1040 if (op->type == PLAYER) 1029 if (op->type == PLAYER)
1041 op->contr->ranges[range_skill] = op; 1030 op->contr->ranges[range_skill] = op;
1042 break; 1031 break;
1043 1032
1044 case SKILL_TOOL: 1033 case SKILL_TOOL:
1045 if (op->chosen_skill) { 1034 if (op->chosen_skill) {
1046 LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", op->name); 1035 LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name);
1047 } 1036 }
1048 op->chosen_skill = tmp; 1037 op->chosen_skill = tmp;
1049 if (op->type == PLAYER) 1038 if (op->type == PLAYER)
1050 op->contr->ranges[range_skill] = op; 1039 op->contr->ranges[range_skill] = op;
1051 break; 1040 break;
1052 1041
1053 case SHIELD: 1042 case SHIELD:
1054 if(settings.spell_encumbrance == TRUE && op->type==PLAYER) 1043 if(settings.spell_encumbrance == TRUE && op->type==PLAYER)
1055 op->contr->encumbrance+=(int)tmp->weight/2000; 1044 op->contr->encumbrance+=(int)tmp->weight/2000;
1056 case RING: 1045 case RING:
1057 case AMULET: 1046 case AMULET:
1058 case GIRDLE: 1047 case GIRDLE:
1059 case HELMET: 1048 case HELMET:
1060 case BOOTS: 1049 case BOOTS:
1061 case GLOVES: 1050 case GLOVES:
1062 case CLOAK: 1051 case CLOAK:
1063 if(tmp->stats.wc) 1052 if(tmp->stats.wc)
1064 wc-=(tmp->stats.wc+tmp->magic); 1053 wc-=(tmp->stats.wc+tmp->magic);
1065 if(tmp->stats.dam) 1054 if(tmp->stats.dam)
1066 op->stats.dam+=(tmp->stats.dam+tmp->magic); 1055 op->stats.dam+=(tmp->stats.dam+tmp->magic);
1067 if(tmp->stats.ac) 1056 if(tmp->stats.ac)
1068 ac-=(tmp->stats.ac+tmp->magic); 1057 ac-=(tmp->stats.ac+tmp->magic);
1069 break; 1058 break;
1070 1059
1071 case WEAPON: 1060 case WEAPON:
1072 wc-=(tmp->stats.wc+tmp->magic); 1061 wc-=(tmp->stats.wc+tmp->magic);
1073 if(tmp->stats.ac&&tmp->stats.ac+tmp->magic>0) 1062 if(tmp->stats.ac&&tmp->stats.ac+tmp->magic>0)
1074 ac-=tmp->stats.ac+tmp->magic; 1063 ac-=tmp->stats.ac+tmp->magic;
1075 op->stats.dam+=(tmp->stats.dam+tmp->magic); 1064 op->stats.dam+=(tmp->stats.dam+tmp->magic);
1076 weapon_weight=tmp->weight; 1065 weapon_weight=tmp->weight;
1077 weapon_speed=((int)WEAPON_SPEED(tmp)*2-tmp->magic)/2; 1066 weapon_speed=((int)WEAPON_SPEED(tmp)*2-tmp->magic)/2;
1078 if(weapon_speed<0) weapon_speed=0; 1067 if(weapon_speed<0) weapon_speed=0;
1079 if(tmp->slaying!=NULL) { 1068 op->slaying = tmp->slaying;
1080 if (op->slaying != NULL)
1081 free_string (op->slaying);
1082 add_refcount(op->slaying = tmp->slaying);
1083 }
1084 /* If there is desire that two handed weapons should do 1069 /* If there is desire that two handed weapons should do
1085 * extra strength damage, this is where the code should 1070 * extra strength damage, this is where the code should
1086 * go. 1071 * go.
1087 */ 1072 */
1088 op->current_weapon = tmp; 1073 op->current_weapon = tmp;
1089 if(settings.spell_encumbrance == TRUE && op->type==PLAYER) 1074 if(settings.spell_encumbrance == TRUE && op->type==PLAYER)
1090 op->contr->encumbrance+=(int)3*tmp->weight/1000; 1075 op->contr->encumbrance+=(int)3*tmp->weight/1000;
1091 break; 1076 break;
1092 1077
1093 case ARMOUR: /* Only the best of these three are used: */ 1078 case ARMOUR: /* Only the best of these three are used: */
1094 if(settings.spell_encumbrance == TRUE && op->type==PLAYER) 1079 if(settings.spell_encumbrance == TRUE && op->type==PLAYER)
1095 op->contr->encumbrance+=(int)tmp->weight/1000; 1080 op->contr->encumbrance+=(int)tmp->weight/1000;
1096 1081
1097 case BRACERS: 1082 case BRACERS:
1098 case FORCE: 1083 case FORCE:
1099 if(tmp->stats.wc) { 1084 if(tmp->stats.wc) {
1100 if(best_wc<tmp->stats.wc+tmp->magic) { 1085 if(best_wc<tmp->stats.wc+tmp->magic) {
1101 wc+=best_wc; 1086 wc+=best_wc;
1102 best_wc=tmp->stats.wc+tmp->magic; 1087 best_wc=tmp->stats.wc+tmp->magic;
1103 } else 1088 } else
1104 wc+=tmp->stats.wc+tmp->magic; 1089 wc+=tmp->stats.wc+tmp->magic;
1105 } 1090 }
1106 if(tmp->stats.ac) { 1091 if(tmp->stats.ac) {
1107 if(best_ac<tmp->stats.ac+tmp->magic) { 1092 if(best_ac<tmp->stats.ac+tmp->magic) {
1108 ac+=best_ac; /* Remove last bonus */ 1093 ac+=best_ac; /* Remove last bonus */
1109 best_ac=tmp->stats.ac+tmp->magic; 1094 best_ac=tmp->stats.ac+tmp->magic;
1110 } 1095 }
1111 else /* To nullify the below effect */ 1096 else /* To nullify the below effect */
1112 ac+=tmp->stats.ac+tmp->magic; 1097 ac+=tmp->stats.ac+tmp->magic;
1113 } 1098 }
1114 if(tmp->stats.wc) wc-=(tmp->stats.wc+tmp->magic); 1099 if(tmp->stats.wc) wc-=(tmp->stats.wc+tmp->magic);
1115 if(tmp->stats.ac) ac-=(tmp->stats.ac+tmp->magic); 1100 if(tmp->stats.ac) ac-=(tmp->stats.ac+tmp->magic);
1116 if(ARMOUR_SPEED(tmp)&&ARMOUR_SPEED(tmp)/10.0<max) 1101 if(ARMOUR_SPEED(tmp)&&ARMOUR_SPEED(tmp)/10.0<max)
1117 max=ARMOUR_SPEED(tmp)/10.0; 1102 max=ARMOUR_SPEED(tmp)/10.0;
1118 break; 1103 break;
1119 } /* switch tmp->type */ 1104 } /* switch tmp->type */
1120 } /* item is equipped */ 1105 } /* item is equipped */
1121 } /* for loop of items */ 1106 } /* for loop of items */
1122 1107
1123 /* We've gone through all the objects the player has equipped. For many things, we 1108 /* We've gone through all the objects the player has equipped. For many things, we
1124 * have generated intermediate values which we now need to assign. 1109 * have generated intermediate values which we now need to assign.
1125 */ 1110 */
1129 * than that, we take: 'total resistance = resistance from potion'. 1114 * than that, we take: 'total resistance = resistance from potion'.
1130 * If there is a cursed (and no uncursed) potion in effect, we take 1115 * If there is a cursed (and no uncursed) potion in effect, we take
1131 * 'total resistance = vulnerability from cursed potion'. 1116 * 'total resistance = vulnerability from cursed potion'.
1132 */ 1117 */
1133 for (i=0; i<NROFATTACKS; i++) { 1118 for (i=0; i<NROFATTACKS; i++) {
1134 op->resist[i] = prot[i] - vuln[i]; 1119 op->resist[i] = prot[i] - vuln[i];
1135 if (potion_resist[i] && ((potion_resist[i] > op->resist[i]) || 1120 if (potion_resist[i] && ((potion_resist[i] > op->resist[i]) ||
1136 (potion_resist[i] < 0))) 1121 (potion_resist[i] < 0)))
1137 op->resist[i] = potion_resist[i]; 1122 op->resist[i] = potion_resist[i];
1138 } 1123 }
1139 1124
1140 /* Figure out the players sp/mana/hp totals. */ 1125 /* Figure out the players sp/mana/hp totals. */
1141 if(op->type==PLAYER) { 1126 if(op->type==PLAYER) {
1142 int pl_level; 1127 int pl_level;
1143 1128
1144 check_stat_bounds(&(op->stats)); 1129 check_stat_bounds(&(op->stats));
1145 pl_level=op->level; 1130 pl_level=op->level;
1146 1131
1147 if(pl_level<1) pl_level=1; /* safety, we should always get 1 levels worth of hp! */ 1132 if(pl_level<1) pl_level=1; /* safety, we should always get 1 levels worth of hp! */
1148 1133
1149 /* You basically get half a con bonus/level. But we do take into account rounding, 1134 /* You basically get half a con bonus/level. But we do take into account rounding,
1150 * so if your bonus is 7, you still get 7 worth of bonus every 2 levels. 1135 * so if your bonus is 7, you still get 7 worth of bonus every 2 levels.
1151 */ 1136 */
1152 for(i=1,op->stats.maxhp=0;i<=pl_level&&i<=10;i++) { 1137 for(i=1,op->stats.maxhp=0;i<=pl_level&&i<=10;i++) {
1153 j=op->contr->levhp[i]+con_bonus[op->stats.Con]/2; 1138 j=op->contr->levhp[i]+con_bonus[op->stats.Con]/2;
1154 if(i%2 && con_bonus[op->stats.Con]%2) { 1139 if(i%2 && con_bonus[op->stats.Con]%2) {
1155 if (con_bonus[op->stats.Con]>0) 1140 if (con_bonus[op->stats.Con]>0)
1156 j++; 1141 j++;
1157 else 1142 else
1158 j--; 1143 j--;
1159 } 1144 }
1160 op->stats.maxhp+=j>1?j:1; /* always get at least 1 hp/level */ 1145 op->stats.maxhp+=j>1?j:1; /* always get at least 1 hp/level */
1161 } 1146 }
1162 1147
1163 for(i=11;i<=op->level;i++) 1148 for(i=11;i<=op->level;i++)
1164 op->stats.maxhp+=2; 1149 op->stats.maxhp+=2;
1165 1150
1166 if(op->stats.hp>op->stats.maxhp) 1151 if(op->stats.hp>op->stats.maxhp)
1167 op->stats.hp=op->stats.maxhp; 1152 op->stats.hp=op->stats.maxhp;
1168 1153
1169 /* Sp gain is controlled by the level of the player's 1154 /* Sp gain is controlled by the level of the player's
1170 * relevant experience object (mana_obj, see above) 1155 * relevant experience object (mana_obj, see above)
1171 */ 1156 */
1172 /* following happen when skills system is not used */ 1157 /* following happen when skills system is not used */
1173 if(!mana_obj) mana_obj = op; 1158 if(!mana_obj) mana_obj = op;
1174 if(!grace_obj) grace_obj = op; 1159 if(!grace_obj) grace_obj = op;
1175 /* set maxsp */ 1160 /* set maxsp */
1176 if(!mana_obj || !mana_obj->level || op->type!=PLAYER) mana_obj = op; 1161 if(!mana_obj || !mana_obj->level || op->type!=PLAYER) mana_obj = op;
1177 1162
1178 if (mana_obj == op && op->type == PLAYER) { 1163 if (mana_obj == op && op->type == PLAYER) {
1179 op->stats.maxsp = 1; 1164 op->stats.maxsp = 1;
1180 } else { 1165 } else {
1181 sp_tmp=0.0; 1166 sp_tmp=0.0;
1182 for(i=1;i<=mana_obj->level&&i<=10;i++) { 1167 for(i=1;i<=mana_obj->level&&i<=10;i++) {
1183 float stmp; 1168 float stmp;
1184 1169
1185 /* Got some extra bonus at first level */ 1170 /* Got some extra bonus at first level */
1186 if(i<2) { 1171 if(i<2) {
1187 stmp = op->contr->levsp[i] +((2.0 * (float)sp_bonus[op->stats.Pow] + 1172 stmp = op->contr->levsp[i] +((2.0 * (float)sp_bonus[op->stats.Pow] +
1188 (float)sp_bonus[op->stats.Int])/6.0); 1173 (float)sp_bonus[op->stats.Int])/6.0);
1189 } else { 1174 } else {
1190 stmp=(float)op->contr->levsp[i] 1175 stmp=(float)op->contr->levsp[i]
1191 +(2.0 * (float)sp_bonus[op->stats.Pow] + 1176 +(2.0 * (float)sp_bonus[op->stats.Pow] +
1192 (float)sp_bonus[op->stats.Int])/12.0; 1177 (float)sp_bonus[op->stats.Int])/12.0;
1193 } 1178 }
1194 if (stmp<1.0) stmp=1.0; 1179 if (stmp<1.0) stmp=1.0;
1195 sp_tmp+=stmp; 1180 sp_tmp+=stmp;
1196 } 1181 }
1197 op->stats.maxsp=(int)sp_tmp; 1182 op->stats.maxsp=(int)sp_tmp;
1198 1183
1199 for(i=11;i<=mana_obj->level;i++) 1184 for(i=11;i<=mana_obj->level;i++)
1200 op->stats.maxsp+=2; 1185 op->stats.maxsp+=2;
1201 } 1186 }
1202 /* Characters can get their sp supercharged via rune of transferrance */ 1187 /* Characters can get their sp supercharged via rune of transferrance */
1203 if(op->stats.sp>op->stats.maxsp*2) 1188 if(op->stats.sp>op->stats.maxsp*2)
1204 op->stats.sp=op->stats.maxsp*2; 1189 op->stats.sp=op->stats.maxsp*2;
1205 1190
1206 /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */ 1191 /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */
1207 if(!grace_obj || !grace_obj->level || op->type!=PLAYER) grace_obj = op; 1192 if(!grace_obj || !grace_obj->level || op->type!=PLAYER) grace_obj = op;
1208 1193
1209 if (grace_obj == op && op->type == PLAYER) { 1194 if (grace_obj == op && op->type == PLAYER) {
1210 op->stats.maxgrace = 1; 1195 op->stats.maxgrace = 1;
1211 } else { 1196 } else {
1212 /* store grace in a float - this way, the divisions below don't create 1197 /* store grace in a float - this way, the divisions below don't create
1213 * big jumps when you go from level to level - with int's, it then 1198 * big jumps when you go from level to level - with int's, it then
1214 * becomes big jumps when the sums of the bonuses jump to the next 1199 * becomes big jumps when the sums of the bonuses jump to the next
1215 * step of 8 - with floats, even fractional ones are useful. 1200 * step of 8 - with floats, even fractional ones are useful.
1216 */ 1201 */
1217 sp_tmp=0.0; 1202 sp_tmp=0.0;
1218 for(i=1,op->stats.maxgrace=0;i<=grace_obj->level&&i<=10;i++) { 1203 for(i=1,op->stats.maxgrace=0;i<=grace_obj->level&&i<=10;i++) {
1219 float grace_tmp=0.0; 1204 float grace_tmp=0.0;
1220 1205
1221 /* Got some extra bonus at first level */ 1206 /* Got some extra bonus at first level */
1222 if(i<2) { 1207 if(i<2) {
1223 grace_tmp = op->contr->levgrace[i]+(((float)grace_bonus[op->stats.Pow] + 1208 grace_tmp = op->contr->levgrace[i]+(((float)grace_bonus[op->stats.Pow] +
1224 2.0 * (float)grace_bonus[op->stats.Wis])/6.0); 1209 2.0 * (float)grace_bonus[op->stats.Wis])/6.0);
1225 } else { 1210 } else {
1226 grace_tmp=(float)op->contr->levgrace[i] 1211 grace_tmp=(float)op->contr->levgrace[i]
1227 +((float)grace_bonus[op->stats.Pow] + 1212 +((float)grace_bonus[op->stats.Pow] +
1228 2.0 * (float)grace_bonus[op->stats.Wis])/12.0; 1213 2.0 * (float)grace_bonus[op->stats.Wis])/12.0;
1229 } 1214 }
1230 if (grace_tmp<1.0) grace_tmp=1.0; 1215 if (grace_tmp<1.0) grace_tmp=1.0;
1231 sp_tmp+=grace_tmp; 1216 sp_tmp+=grace_tmp;
1232 } 1217 }
1233 op->stats.maxgrace=(int)sp_tmp; 1218 op->stats.maxgrace=(int)sp_tmp;
1234 1219
1235 /* two grace points per level after 11 */ 1220 /* two grace points per level after 11 */
1236 for(i=11;i<=grace_obj->level;i++) 1221 for(i=11;i<=grace_obj->level;i++)
1237 op->stats.maxgrace+=2; 1222 op->stats.maxgrace+=2;
1238 } 1223 }
1239 /* No limit on grace vs maxgrace */ 1224 /* No limit on grace vs maxgrace */
1240 1225
1241 if(op->contr->braced) { 1226 if(op->contr->braced) {
1242 ac+=2; 1227 ac+=2;
1243 wc+=4; 1228 wc+=4;
1244 } 1229 }
1245 else 1230 else
1246 ac-=dex_bonus[op->stats.Dex]; 1231 ac-=dex_bonus[op->stats.Dex];
1247 1232
1248 /* In new exp/skills system, wc bonuses are related to 1233 /* In new exp/skills system, wc bonuses are related to
1249 * the players level in a relevant exp object (wc_obj) 1234 * the players level in a relevant exp object (wc_obj)
1250 * not the general player level -b.t. 1235 * not the general player level -b.t.
1251 * I changed this slightly so that wc bonuses are better 1236 * I changed this slightly so that wc bonuses are better
1252 * than before. This is to balance out the fact that 1237 * than before. This is to balance out the fact that
1253 * the player no longer gets a personal weapon w/ 1 1238 * the player no longer gets a personal weapon w/ 1
1254 * improvement every level, now its fighterlevel/5. So 1239 * improvement every level, now its fighterlevel/5. So
1255 * we give the player a bonus here in wc and dam 1240 * we give the player a bonus here in wc and dam
1256 * to make up for the change. Note that I left the 1241 * to make up for the change. Note that I left the
1257 * monster bonus the same as before. -b.t. 1242 * monster bonus the same as before. -b.t.
1258 */ 1243 */
1259 1244
1260 if(op->type==PLAYER && wc_obj && wc_obj->level>1) { 1245 if(op->type==PLAYER && wc_obj && wc_obj->level>1) {
1261 wc-=(wc_obj->level+thaco_bonus[op->stats.Str]); 1246 wc-=(wc_obj->level+thaco_bonus[op->stats.Str]);
1262 for(i=1;i<wc_obj->level;i++) { 1247 for(i=1;i<wc_obj->level;i++) {
1263 /* addtional wc every 6 levels */ 1248 /* addtional wc every 6 levels */
1264 if(!(i%6)) wc--; 1249 if(!(i%6)) wc--;
1265 /* addtional dam every 4 levels. */ 1250 /* addtional dam every 4 levels. */
1266 if(!(i%4) && (dam_bonus[op->stats.Str]>=0)) 1251 if(!(i%4) && (dam_bonus[op->stats.Str]>=0))
1267 op->stats.dam+=(1+(dam_bonus[op->stats.Str]/5)); 1252 op->stats.dam+=(1+(dam_bonus[op->stats.Str]/5));
1268 } 1253 }
1269 } else 1254 } else
1270 wc-=(op->level+thaco_bonus[op->stats.Str]); 1255 wc-=(op->level+thaco_bonus[op->stats.Str]);
1271 1256
1272 op->stats.dam+=dam_bonus[op->stats.Str]; 1257 op->stats.dam+=dam_bonus[op->stats.Str];
1273 1258
1274 if(op->stats.dam<1) 1259 if(op->stats.dam<1)
1275 op->stats.dam=1; 1260 op->stats.dam=1;
1276 1261
1277 op->speed=1.0+speed_bonus[op->stats.Dex]; 1262 op->speed=1.0+speed_bonus[op->stats.Dex];
1278 if (settings.search_items && op->contr->search_str[0]) 1263 if (settings.search_items && op->contr->search_str[0])
1279 op->speed -= 1; 1264 op->speed -= 1;
1280 if (op->attacktype==0) 1265 if (op->attacktype==0)
1281 op->attacktype=op->arch->clone.attacktype; 1266 op->attacktype=op->arch->clone.attacktype;
1282 1267
1283 } /* End if player */ 1268 } /* End if player */
1284 1269
1285 if(added_speed>=0) 1270 if(added_speed>=0)
1286 op->speed+=added_speed/10.0; 1271 op->speed+=added_speed/10.0;
1287 else /* Something wrong here...: */ 1272 else /* Something wrong here...: */
1288 op->speed /= (float)(1.0-added_speed); 1273 op->speed /= (float)(1.0-added_speed);
1289 1274
1290 /* Max is determined by armour */ 1275 /* Max is determined by armour */
1291 if(op->speed>max) 1276 if(op->speed>max)
1292 op->speed=max; 1277 op->speed=max;
1293 1278
1294 if(op->type == PLAYER) { 1279 if(op->type == PLAYER) {
1295 /* f is a number the represents the number of kg above (positive num) 1280 /* f is a number the represents the number of kg above (positive num)
1296 * or below (negative number) that the player is carrying. If above 1281 * or below (negative number) that the player is carrying. If above
1297 * weight limit, then player suffers a speed reduction based on how 1282 * weight limit, then player suffers a speed reduction based on how
1298 * much above he is, and what is max carry is 1283 * much above he is, and what is max carry is
1299 */ 1284 */
1300 f=(op->carrying/1000)-max_carry[op->stats.Str]; 1285 f=(op->carrying/1000)-max_carry[op->stats.Str];
1301 if(f>0) op->speed=op->speed/(1.0+f/max_carry[op->stats.Str]); 1286 if(f>0) op->speed=op->speed/(1.0+f/max_carry[op->stats.Str]);
1302 } 1287 }
1303 1288
1304 op->speed+=bonus_speed/10.0; /* Not affected by limits */ 1289 op->speed+=bonus_speed/10.0; /* Not affected by limits */
1305 1290
1306 /* Put a lower limit on speed. Note with this speed, you move once every 1291 /* Put a lower limit on speed. Note with this speed, you move once every
1309 op->speed = op->speed * speed_reduce_from_disease; 1294 op->speed = op->speed * speed_reduce_from_disease;
1310 1295
1311 if (op->speed<0.01 && op->type==PLAYER) op->speed=0.01; 1296 if (op->speed<0.01 && op->type==PLAYER) op->speed=0.01;
1312 1297
1313 if(op->type == PLAYER) { 1298 if(op->type == PLAYER) {
1314 float M,W,s,D,K,S,M2; 1299 float M,W,s,D,K,S,M2;
1315 1300
1316 /* (This formula was made by vidarl@ifi.uio.no) 1301 /* (This formula was made by vidarl@ifi.uio.no)
1317 * Note that we never used these values again - basically 1302 * Note that we never used these values again - basically
1318 * all of these could be subbed into one big equation, but 1303 * all of these could be subbed into one big equation, but
1319 * that would just be a real pain to read. 1304 * that would just be a real pain to read.
1320 */ 1305 */
1321 M=(max_carry[op->stats.Str]-121)/121.0; 1306 M=(max_carry[op->stats.Str]-121)/121.0;
1322 M2=max_carry[op->stats.Str]/100.0; 1307 M2=max_carry[op->stats.Str]/100.0;
1323 W=weapon_weight/20000.0; 1308 W=weapon_weight/20000.0;
1324 s=2-weapon_speed/10.0; 1309 s=2-weapon_speed/10.0;
1325 D=(op->stats.Dex-14)/14.0; 1310 D=(op->stats.Dex-14)/14.0;
1326 K=1 + M/3.0 - W/(3*M2) + op->speed/5.0 + D/2.0; 1311 K=1 + M/3.0 - W/(3*M2) + op->speed/5.0 + D/2.0;
1327 K*=(4+op->level)/(float)(6+op->level)*1.2; 1312 K*=(4+op->level)/(float)(6+op->level)*1.2;
1328 if(K<=0) K=0.01; 1313 if(K<=0) K=0.01;
1329 S=op->speed/(K*s); 1314 S=op->speed/(K*s);
1330 op->contr->weapon_sp=S; 1315 op->contr->weapon_sp=S;
1331 } 1316 }
1332 /* I want to limit the power of small monsters with big weapons: */ 1317 /* I want to limit the power of small monsters with big weapons: */
1333 if(op->type!=PLAYER&&op->arch!=NULL&& 1318 if(op->type!=PLAYER&&op->arch!=NULL&&
1334 op->stats.dam>op->arch->clone.stats.dam*3) 1319 op->stats.dam>op->arch->clone.stats.dam*3)
1335 op->stats.dam=op->arch->clone.stats.dam*3; 1320 op->stats.dam=op->arch->clone.stats.dam*3;
1336 1321
1337 /* Prevent overflows of wc - best you can get is ABS(120) - this 1322 /* Prevent overflows of wc - best you can get is ABS(120) - this
1338 * should be more than enough - remember, AC is also in 8 bits, 1323 * should be more than enough - remember, AC is also in 8 bits,
1339 * so its value is the same. 1324 * so its value is the same.
1340 */ 1325 */
1372 */ 1357 */
1373 1358
1374int allowed_class(const object *op) { 1359int allowed_class(const object *op) {
1375 return op->stats.Dex>0&&op->stats.Str>0&&op->stats.Con>0&& 1360 return op->stats.Dex>0&&op->stats.Str>0&&op->stats.Con>0&&
1376 op->stats.Int>0&&op->stats.Wis>0&&op->stats.Pow>0&& 1361 op->stats.Int>0&&op->stats.Wis>0&&op->stats.Pow>0&&
1377 op->stats.Cha>0; 1362 op->stats.Cha>0;
1378} 1363}
1379 1364
1380/* 1365/*
1381 * set the new dragon name after gaining levels or 1366 * set the new dragon name after gaining levels or
1382 * changing ability focus (later this can be extended to 1367 * changing ability focus (later this can be extended to
1396 if (!abil || !skin) return; 1381 if (!abil || !skin) return;
1397 1382
1398 /* first, look for the highest level */ 1383 /* first, look for the highest level */
1399 for(i=0; i<NROFATTACKS; i++) { 1384 for(i=0; i<NROFATTACKS; i++) {
1400 if (atnr_is_dragon_enabled(i) && 1385 if (atnr_is_dragon_enabled(i) &&
1401 (atnr==-1 || abil->resist[i] > abil->resist[atnr])) { 1386 (atnr==-1 || abil->resist[i] > abil->resist[atnr])) {
1402 level = abil->resist[i]; 1387 level = abil->resist[i];
1403 atnr = i; 1388 atnr = i;
1404 } 1389 }
1405 } 1390 }
1406 1391
1423 else if (level == 3) 1408 else if (level == 3)
1424 sprintf(pl->contr->title, "%s dragon", attacks[atnr]); 1409 sprintf(pl->contr->title, "%s dragon", attacks[atnr]);
1425 else { 1410 else {
1426 /* special titles for extra high resistance! */ 1411 /* special titles for extra high resistance! */
1427 if (skin->resist[atnr] > 80) 1412 if (skin->resist[atnr] > 80)
1428 sprintf(pl->contr->title, "legendary %s dragon", attacks[atnr]); 1413 sprintf(pl->contr->title, "legendary %s dragon", attacks[atnr]);
1429 else if (skin->resist[atnr] > 50) 1414 else if (skin->resist[atnr] > 50)
1430 sprintf(pl->contr->title, "ancient %s dragon", attacks[atnr]); 1415 sprintf(pl->contr->title, "ancient %s dragon", attacks[atnr]);
1431 else 1416 else
1432 sprintf(pl->contr->title, "big %s dragon", attacks[atnr]); 1417 sprintf(pl->contr->title, "big %s dragon", attacks[atnr]);
1433 } 1418 }
1434 } 1419 }
1435 1420
1436 strcpy(pl->contr->own_title, ""); 1421 strcpy(pl->contr->own_title, "");
1437} 1422}
1447 object *tmp = NULL; /* tmp. object */ 1432 object *tmp = NULL; /* tmp. object */
1448 char buf[MAX_BUF]; /* tmp. string buffer */ 1433 char buf[MAX_BUF]; /* tmp. string buffer */
1449 1434
1450 /* now grab the 'dragon_ability'-forces from the player's inventory */ 1435 /* now grab the 'dragon_ability'-forces from the player's inventory */
1451 for (tmp=who->inv; tmp!=NULL; tmp=tmp->below) { 1436 for (tmp=who->inv; tmp!=NULL; tmp=tmp->below) {
1452 if (tmp->type == FORCE) { 1437 if (tmp->type == FORCE) {
1453 if (strcmp(tmp->arch->name, "dragon_ability_force")==0) 1438 if (strcmp(tmp->arch->name, "dragon_ability_force")==0)
1454 abil = tmp; 1439 abil = tmp;
1455 if (strcmp(tmp->arch->name, "dragon_skin_force")==0) 1440 if (strcmp(tmp->arch->name, "dragon_skin_force")==0)
1456 skin = tmp; 1441 skin = tmp;
1457 } 1442 }
1458 } 1443 }
1459 /* if the force is missing -> bail out */ 1444 /* if the force is missing -> bail out */
1460 if (abil == NULL) return; 1445 if (abil == NULL) return;
1461 1446
1462 /* The ability_force keeps track of maximum level ever achieved. 1447 /* The ability_force keeps track of maximum level ever achieved.
1463 * New abilties can only be gained by surpassing this max level 1448 * New abilties can only be gained by surpassing this max level
1464 */ 1449 */
1465 if (who->level > abil->level) { 1450 if (who->level > abil->level) {
1466 /* increase our focused ability */ 1451 /* increase our focused ability */
1467 abil->resist[abil->stats.exp]++; 1452 abil->resist[abil->stats.exp]++;
1468 1453
1469 1454
1470 if (abil->resist[abil->stats.exp]>0 && abil->resist[abil->stats.exp]%5 == 0) { 1455 if (abil->resist[abil->stats.exp]>0 && abil->resist[abil->stats.exp]%5 == 0) {
1471 /* time to hand out a new ability-gift */ 1456 /* time to hand out a new ability-gift */
1472 dragon_ability_gain(who, (int)abil->stats.exp, 1457 dragon_ability_gain(who, (int)abil->stats.exp,
1473 (int)((1+abil->resist[abil->stats.exp])/5.)); 1458 (int)((1+abil->resist[abil->stats.exp])/5.));
1474 } 1459 }
1475 1460
1476 if (abil->last_eat > 0 && atnr_is_dragon_enabled(abil->last_eat)) { 1461 if (abil->last_eat > 0 && atnr_is_dragon_enabled(abil->last_eat)) {
1477 /* apply new ability focus */ 1462 /* apply new ability focus */
1478 sprintf(buf, "Your metabolism now focuses on %s!", 1463 sprintf(buf, "Your metabolism now focuses on %s!",
1479 change_resist_msg[abil->last_eat]); 1464 change_resist_msg[abil->last_eat]);
1480 new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, buf); 1465 new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, buf);
1481 1466
1482 abil->stats.exp = abil->last_eat; 1467 abil->stats.exp = abil->last_eat;
1483 abil->last_eat = 0; 1468 abil->last_eat = 0;
1484 } 1469 }
1485 1470
1486 abil->level = who->level; 1471 abil->level = who->level;
1487 } 1472 }
1488 1473
1489 /* last but not least, set the new title for the dragon */ 1474 /* last but not least, set the new title for the dragon */
1490 set_dragon_name(who, abil, skin); 1475 set_dragon_name(who, abil, skin);
1491} 1476}
1500{ 1485{
1501 object *skill_obj; 1486 object *skill_obj;
1502 1487
1503 skill_obj = get_archetype_by_skill_name(skill_name, SKILL); 1488 skill_obj = get_archetype_by_skill_name(skill_name, SKILL);
1504 if (!skill_obj) { 1489 if (!skill_obj) {
1505 LOG(llevError, "add_player_exp: couldn't find skill %s\n", skill_name); 1490 LOG(llevError, "add_player_exp: couldn't find skill %s\n", skill_name);
1506 return NULL; 1491 return NULL;
1507 } 1492 }
1508 /* clear the flag - exp goes into this bucket, but player 1493 /* clear the flag - exp goes into this bucket, but player
1509 * still doesn't know it. 1494 * still doesn't know it.
1510 */ 1495 */
1511 CLEAR_FLAG(skill_obj, FLAG_CAN_USE_SKILL); 1496 CLEAR_FLAG(skill_obj, FLAG_CAN_USE_SKILL);
1512 skill_obj->stats.exp = 0; 1497 skill_obj->stats.exp = 0;
1513 skill_obj->level = 1; 1498 skill_obj->level = 1;
1514 insert_ob_in_ob(skill_obj, op); 1499 insert_ob_in_ob(skill_obj, op);
1515 if (op->contr) { 1500 if (op->contr) {
1516 op->contr->last_skill_ob[skill_obj->subtype] = skill_obj; 1501 op->contr->last_skill_ob[skill_obj->subtype] = skill_obj;
1517 op->contr->last_skill_exp[skill_obj->subtype] = -1; 1502 op->contr->last_skill_exp[skill_obj->subtype] = -1;
1518 } 1503 }
1519 return skill_obj; 1504 return skill_obj;
1520} 1505}
1521 1506
1522 1507
1529 */ 1514 */
1530void player_lvl_adj(object *who, object *op) { 1515void player_lvl_adj(object *who, object *op) {
1531 char buf[MAX_BUF]; 1516 char buf[MAX_BUF];
1532 1517
1533 if(!op) /* when rolling stats */ 1518 if(!op) /* when rolling stats */
1534 op = who; 1519 op = who;
1535 1520
1536 if(op->level < settings.max_level && op->stats.exp >= level_exp(op->level+1,who->expmul)) { 1521 if(op->level < settings.max_level && op->stats.exp >= level_exp(op->level+1,who->expmul)) {
1537 op->level++; 1522 op->level++;
1538 1523
1539 if (op != NULL && op == who && op->stats.exp > 1 && is_dragon_pl(who)) 1524 if (op != NULL && op == who && op->stats.exp > 1 && is_dragon_pl(who))
1540 dragon_level_gain(who); 1525 dragon_level_gain(who);
1541 1526
1542 /* Only roll these if it is the player (who) that gained the level */ 1527 /* Only roll these if it is the player (who) that gained the level */
1543 if(op==who && (who->level < 11) && who->type==PLAYER) { 1528 if(op==who && (who->level < 11) && who->type==PLAYER) {
1544 who->contr->levhp[who->level] = die_roll(2, 4, who, PREFER_HIGH)+1; 1529 who->contr->levhp[who->level] = die_roll(2, 4, who, PREFER_HIGH)+1;
1545 who->contr->levsp[who->level] = die_roll(2, 3, who, PREFER_HIGH); 1530 who->contr->levsp[who->level] = die_roll(2, 3, who, PREFER_HIGH);
1546 who->contr->levgrace[who->level]=die_roll(2, 2, who, PREFER_HIGH)-1; 1531 who->contr->levgrace[who->level]=die_roll(2, 2, who, PREFER_HIGH)-1;
1547 } 1532 }
1548 1533
1549 fix_player(who); 1534 fix_player(who);
1550 if(op->level>1) { 1535 if(op->level>1) {
1551 if (op->type!=PLAYER) 1536 if (op->type!=PLAYER)
1552 sprintf(buf,"You are now level %d in the %s skill.",op->level,op->name); 1537 sprintf(buf,"You are now level %d in the %s skill.",op->level,&op->name);
1553 else 1538 else
1554 sprintf(buf,"You are now level %d.",op->level); 1539 sprintf(buf,"You are now level %d.",op->level);
1555 if(who) new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); 1540 if(who) new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf);
1556 } 1541 }
1557 player_lvl_adj(who,op); /* To increase more levels */ 1542 player_lvl_adj(who,op); /* To increase more levels */
1558 } else if (op->level>1 && op->stats.exp<level_exp(op->level,who->expmul)) { 1543 } else if (op->level>1 && op->stats.exp<level_exp(op->level,who->expmul)) {
1559 op->level--; 1544 op->level--;
1560 fix_player(who); 1545 fix_player(who);
1561 if(op->type!=PLAYER) { 1546 if(op->type!=PLAYER) {
1562 sprintf(buf,"You are now level %d in the %s skill.",op->level,op->name); 1547 sprintf(buf,"You are now level %d in the %s skill.",op->level,&op->name);
1563 new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); 1548 new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf);
1564 } 1549 }
1565 player_lvl_adj(who,op); /* To decrease more levels */ 1550 player_lvl_adj(who,op); /* To decrease more levels */
1566 } 1551 }
1567 /* check if the spell data has changed */ 1552 /* check if the spell data has changed */
1568 esrv_update_spells(who->contr); 1553 esrv_update_spells(who->contr);
1569} 1554}
1570 1555
1573 * the given level. level should really never exceed max_level 1558 * the given level. level should really never exceed max_level
1574 */ 1559 */
1575 1560
1576sint64 level_exp(int level,double expmul) { 1561sint64 level_exp(int level,double expmul) {
1577 if (level > settings.max_level) 1562 if (level > settings.max_level)
1578 return (sint64) (expmul * levels[settings.max_level]); 1563 return (sint64) (expmul * levels[settings.max_level]);
1579 return (sint64) (expmul * levels[level]); 1564 return (sint64) (expmul * levels[level]);
1580} 1565}
1581 1566
1582/* 1567/*
1583 * Ensure that the permanent experience requirements in an exp object are met. 1568 * Ensure that the permanent experience requirements in an exp object are met.
1612 * NULL, in which case exp increases the players general 1597 * NULL, in which case exp increases the players general
1613 * total, but not any particular skill. 1598 * total, but not any particular skill.
1614 * flag is what to do if the player doesn't have the skill: 1599 * flag is what to do if the player doesn't have the skill:
1615 */ 1600 */
1616 1601
1617static void add_player_exp(object *op, sint64 exp, const char *skill_name, int flag) 1602static void add_player_exp (object * op, sint64 exp, const char *skill_name, int flag)
1618{ 1603{
1619 object *skill_obj=NULL; 1604 object *skill_obj = NULL;
1620 sint64 limit, exp_to_add; 1605 sint64 limit, exp_to_add;
1621 int i; 1606 int i;
1622 1607
1623 /* prevents some forms of abuse. */ 1608 /* prevents some forms of abuse. */
1624 if(op->contr->braced) exp=exp/5; 1609 if (op->contr->braced)
1610 exp = exp / 5;
1625 1611
1626 /* Try to find the matching skill. 1612 /* Try to find the matching skill.
1627 * We do a shortcut/time saving mechanism first - see if it matches 1613 * We do a shortcut/time saving mechanism first - see if it matches
1628 * chosen_skill. This means we don't need to search through 1614 * chosen_skill. This means we don't need to search through
1629 * the players inventory. 1615 * the players inventory.
1630 */ 1616 */
1631 if (skill_name) { 1617 if (skill_name)
1618 {
1632 if (op->chosen_skill && op->chosen_skill->type == SKILL && 1619 if (op->chosen_skill && op->chosen_skill->type == SKILL &&
1633 !strcmp(skill_name, op->chosen_skill->skill)) 1620 !strcmp (skill_name, op->chosen_skill->skill))
1634 skill_obj = op->chosen_skill; 1621 skill_obj = op->chosen_skill;
1635 else { 1622 else
1623 {
1636 for (i=0; i<NUM_SKILLS; i++) 1624 for (i = 0; i < NUM_SKILLS; i++)
1637 if (op->contr->last_skill_ob[i] && 1625 if (op->contr->last_skill_ob[i] &&
1638 !strcmp(op->contr->last_skill_ob[i]->skill, skill_name)) { 1626 !strcmp (op->contr->last_skill_ob[i]->skill, skill_name))
1627 {
1639 skill_obj = op->contr->last_skill_ob[i]; 1628 skill_obj = op->contr->last_skill_ob[i];
1640 break; 1629 break;
1641 } 1630 }
1642 1631
1643 /* Player doesn't have the skill. Check to see what to do, and give 1632 /* Player doesn't have the skill. Check to see what to do, and give
1644 * it to the player if necessary 1633 * it to the player if necessary
1645 */ 1634 */
1646 if (!skill_obj) { 1635 if (!skill_obj)
1647 if (flag == SK_EXP_NONE) return; 1636 {
1637 if (flag == SK_EXP_NONE)
1638 return;
1648 else if (flag == SK_EXP_ADD_SKILL) 1639 else if (flag == SK_EXP_ADD_SKILL)
1649 give_skill_by_name(op, skill_name); 1640 give_skill_by_name (op, skill_name);
1641 }
1642 }
1650 } 1643 }
1651 } 1644
1645 if (flag != SK_EXP_SKILL_ONLY)
1652 } 1646 {
1653
1654 /* Basically, you can never gain more experience in one shot 1647 /* Basically, you can never gain more experience in one shot
1655 * than half what you need to gain for next level. 1648 * than half what you need to gain for next level.
1656 */ 1649 */
1657 exp_to_add = exp; 1650 exp_to_add = exp;
1658 limit=(levels[op->level+1]-levels[op->level])/2; 1651 limit = (levels[op->level + 1] - levels[op->level]) / 2;
1659 if (exp_to_add > limit) exp_to_add=limit; 1652 if (exp_to_add > limit)
1653 exp_to_add = limit;
1660 1654
1661 ADD_EXP(op->stats.exp, (sint64) ((float) exp_to_add * (skill_obj? skill_obj->expmul:1))); 1655 ADD_EXP (op->stats.exp,
1656 (sint64) ((float) exp_to_add *
1657 (skill_obj ? skill_obj->expmul : 1)));
1662 if (settings.permanent_exp_ratio) { 1658 if (settings.permanent_exp_ratio)
1663 ADD_EXP(op->perm_exp, (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO * (skill_obj? skill_obj->expmul:1))); 1659 {
1660 ADD_EXP (op->perm_exp,
1661 (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO *
1662 (skill_obj ? skill_obj->expmul : 1)));
1664 calc_perm_exp(op); 1663 calc_perm_exp (op);
1665 } 1664 }
1666 1665
1667 player_lvl_adj(op,NULL); 1666 player_lvl_adj (op, NULL);
1667 }
1668
1668 if (skill_obj) { 1669 if (skill_obj)
1670 {
1669 exp_to_add = exp; 1671 exp_to_add = exp;
1670 limit=(levels[skill_obj->level+1]-levels[skill_obj->level])/2; 1672 limit = (levels[skill_obj->level + 1] - levels[skill_obj->level]) / 2;
1671 if (exp_to_add > limit) exp_to_add=limit; 1673 if (exp_to_add > limit)
1674 exp_to_add = limit;
1675
1672 ADD_EXP(skill_obj->stats.exp, exp_to_add); 1676 ADD_EXP (skill_obj->stats.exp, exp_to_add);
1673 if (settings.permanent_exp_ratio) { 1677 if (settings.permanent_exp_ratio)
1674 skill_obj->perm_exp += (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO); 1678 {
1679 skill_obj->perm_exp +=
1680 (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO);
1675 calc_perm_exp(skill_obj); 1681 calc_perm_exp (skill_obj);
1676 } 1682 }
1683
1677 player_lvl_adj(op,skill_obj); 1684 player_lvl_adj (op, skill_obj);
1678 } 1685 }
1679} 1686}
1680 1687
1681/* This function checks to make sure that object 'op' can 1688/* This function checks to make sure that object 'op' can
1682 * lost 'exp' experience. It returns the amount of exp 1689 * lost 'exp' experience. It returns the amount of exp
1690{ 1697{
1691 sint64 del_exp; 1698 sint64 del_exp;
1692 1699
1693 if (exp > op->stats.exp) exp = op->stats.exp; 1700 if (exp > op->stats.exp) exp = op->stats.exp;
1694 if (settings.permanent_exp_ratio) { 1701 if (settings.permanent_exp_ratio) {
1695 del_exp = (sint64) ((op->stats.exp - op->perm_exp) * PERM_EXP_MAX_LOSS_RATIO); 1702 del_exp = (sint64) ((op->stats.exp - op->perm_exp) * PERM_EXP_MAX_LOSS_RATIO);
1696 if (del_exp < 0) del_exp = 0; 1703 if (del_exp < 0) del_exp = 0;
1697 if (exp > del_exp) exp=del_exp; 1704 if (exp > del_exp) exp=del_exp;
1698 } 1705 }
1699 return exp; 1706 return exp;
1700} 1707}
1701 1708
1702sint64 check_exp_adjust(const object *op, sint64 exp) 1709sint64 check_exp_adjust(const object *op, sint64 exp)
1723 float fraction = (float) exp/(float) op->stats.exp; 1730 float fraction = (float) exp/(float) op->stats.exp;
1724 object *tmp; 1731 object *tmp;
1725 sint64 del_exp; 1732 sint64 del_exp;
1726 1733
1727 for(tmp=op->inv;tmp;tmp=tmp->below) 1734 for(tmp=op->inv;tmp;tmp=tmp->below)
1728 if(tmp->type==SKILL && tmp->stats.exp) { 1735 if(tmp->type==SKILL && tmp->stats.exp) {
1729 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp(tmp->skill, skill)) { 1736 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp(tmp->skill, skill)) {
1730 del_exp = check_exp_loss(tmp, exp); 1737 del_exp = check_exp_loss(tmp, exp);
1731 tmp->stats.exp -= del_exp; 1738 tmp->stats.exp -= del_exp;
1732 player_lvl_adj(op, tmp); 1739 player_lvl_adj(op, tmp);
1733 } else if (flag != SK_SUBTRACT_SKILL_EXP) { 1740 } else if (flag != SK_SUBTRACT_SKILL_EXP) {
1734 /* only want to process other skills if we are not trying 1741 /* only want to process other skills if we are not trying
1735 * to match a specific skill. 1742 * to match a specific skill.
1736 */ 1743 */
1737 del_exp = check_exp_loss(tmp, (sint64) (tmp->stats.exp * fraction)); 1744 del_exp = check_exp_loss(tmp, (sint64) (tmp->stats.exp * fraction));
1738 tmp->stats.exp -= del_exp; 1745 tmp->stats.exp -= del_exp;
1739 player_lvl_adj(op, tmp); 1746 player_lvl_adj(op, tmp);
1740 } 1747 }
1741 } 1748 }
1742 if (flag != SK_SUBTRACT_SKILL_EXP) { 1749 if (flag != SK_SUBTRACT_SKILL_EXP) {
1743 del_exp = check_exp_loss(op, exp); 1750 del_exp = check_exp_loss(op, exp);
1744 op->stats.exp -= del_exp; 1751 op->stats.exp -= del_exp;
1745 player_lvl_adj(op,NULL); 1752 player_lvl_adj(op,NULL);
1746 } 1753 }
1747} 1754}
1748 1755
1749 1756
1750 1757
1768#endif 1775#endif
1769#endif 1776#endif
1770 1777
1771 /* safety */ 1778 /* safety */
1772 if(!op) { 1779 if(!op) {
1773 LOG(llevError,"change_exp() called for null object!\n"); 1780 LOG(llevError,"change_exp() called for null object!\n");
1774 return; 1781 return;
1775 } 1782 }
1776 1783
1777 /* if no change in exp, just return - most of the below code 1784 /* if no change in exp, just return - most of the below code
1778 * won't do anything if the value is 0 anyways. 1785 * won't do anything if the value is 0 anyways.
1779 */ 1786 */
1783 * don't adjust level, since in most cases it is unrelated to 1790 * don't adjust level, since in most cases it is unrelated to
1784 * the exp they have - the monsters exp represents what its 1791 * the exp they have - the monsters exp represents what its
1785 * worth. 1792 * worth.
1786 */ 1793 */
1787 if(op->type != PLAYER) { 1794 if(op->type != PLAYER) {
1788 /* Sanity check */ 1795 /* Sanity check */
1789 if (!QUERY_FLAG(op, FLAG_ALIVE)) return; 1796 if (!QUERY_FLAG(op, FLAG_ALIVE)) return;
1790 1797
1791 /* reset exp to max allowed value. We subtract from 1798 /* reset exp to max allowed value. We subtract from
1792 * MAX_EXPERIENCE to prevent overflows. If the player somehow has 1799 * MAX_EXPERIENCE to prevent overflows. If the player somehow has
1793 * more than max exp, just return. 1800 * more than max exp, just return.
1794 */ 1801 */
1795 if (exp > 0 && ( op->stats.exp > (MAX_EXPERIENCE - exp))) { 1802 if (exp > 0 && ( op->stats.exp > (MAX_EXPERIENCE - exp))) {
1796 exp = MAX_EXPERIENCE - op->stats.exp; 1803 exp = MAX_EXPERIENCE - op->stats.exp;
1797 if (exp < 0) return; 1804 if (exp < 0) return;
1798 } 1805 }
1799 1806
1800 op->stats.exp += exp; 1807 op->stats.exp += exp;
1801 } 1808 }
1802 else { /* Players only */ 1809 else { /* Players only */
1803 if(exp>0) 1810 if(exp>0)
1804 add_player_exp(op, exp, skill_name, flag); 1811 add_player_exp(op, exp, skill_name, flag);
1805 else 1812 else
1806 /* note that when you lose exp, it doesn't go against 1813 /* note that when you lose exp, it doesn't go against
1807 * a particular skill, so we don't need to pass that 1814 * a particular skill, so we don't need to pass that
1808 * along. 1815 * along.
1809 */ 1816 */
1810 subtract_player_exp(op, FABS(exp), skill_name, flag); 1817 subtract_player_exp(op, FABS(exp), skill_name, flag);
1811 1818
1812 } 1819 }
1813} 1820}
1814 1821
1815/* Applies a death penalty experience, the size of this is defined by the 1822/* Applies a death penalty experience, the size of this is defined by the
1822 sint64 loss; 1829 sint64 loss;
1823 sint64 percentage_loss; /* defined by the setting 'death_penalty_percent' */ 1830 sint64 percentage_loss; /* defined by the setting 'death_penalty_percent' */
1824 sint64 level_loss; /* defined by the setting 'death_penalty_levels */ 1831 sint64 level_loss; /* defined by the setting 'death_penalty_levels */
1825 1832
1826 for(tmp=op->inv;tmp;tmp=tmp->below) 1833 for(tmp=op->inv;tmp;tmp=tmp->below)
1827 if(tmp->type==SKILL && tmp->stats.exp) { 1834 if(tmp->type==SKILL && tmp->stats.exp) {
1828 1835
1829 percentage_loss = tmp->stats.exp * settings.death_penalty_ratio/100; 1836 percentage_loss = tmp->stats.exp * settings.death_penalty_ratio/100;
1830 level_loss = tmp->stats.exp - levels[MAX(0,tmp->level - settings.death_penalty_level)]; 1837 level_loss = tmp->stats.exp - levels[MAX(0,tmp->level - settings.death_penalty_level)];
1831 1838
1832 /* With the revised exp system, you can get cases where 1839 /* With the revised exp system, you can get cases where
1833 * losing several levels would still require that you have more 1840 * losing several levels would still require that you have more
1834 * exp than you currently have - this is true if the levels 1841 * exp than you currently have - this is true if the levels
1835 * tables is a lot harder. 1842 * tables is a lot harder.
1836 */ 1843 */
1837 if (level_loss < 0) level_loss = 0; 1844 if (level_loss < 0) level_loss = 0;
1838 1845
1839 loss = check_exp_loss(tmp, MIN(level_loss, percentage_loss)); 1846 loss = check_exp_loss(tmp, MIN(level_loss, percentage_loss));
1840 1847
1841 tmp->stats.exp -= loss; 1848 tmp->stats.exp -= loss;
1842 player_lvl_adj(op,tmp); 1849 player_lvl_adj(op,tmp);
1843 } 1850 }
1844 1851
1845 percentage_loss = op->stats.exp * settings.death_penalty_ratio/100; 1852 percentage_loss = op->stats.exp * settings.death_penalty_ratio/100;
1846 level_loss = op->stats.exp - levels[MAX(0,op->level - settings.death_penalty_level)]; 1853 level_loss = op->stats.exp - levels[MAX(0,op->level - settings.death_penalty_level)];
1847 if (level_loss < 0) level_loss = 0; 1854 if (level_loss < 0) level_loss = 0;
1848 loss = check_exp_loss(op, MIN(level_loss, percentage_loss)); 1855 loss = check_exp_loss(op, MIN(level_loss, percentage_loss));
1861int did_make_save(const object *op, int level, int bonus) 1868int did_make_save(const object *op, int level, int bonus)
1862{ 1869{
1863 if (level > MAX_SAVE_LEVEL) level = MAX_SAVE_LEVEL; 1870 if (level > MAX_SAVE_LEVEL) level = MAX_SAVE_LEVEL;
1864 1871
1865 if ((random_roll(1, 20, op, PREFER_HIGH) + bonus) < savethrow[level]) 1872 if ((random_roll(1, 20, op, PREFER_HIGH) + bonus) < savethrow[level])
1866 return 0; 1873 return 0;
1867 return 1; 1874 return 1;
1868} 1875}
1869 1876

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines