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.1 by elmex, Sun Aug 13 17:16:00 2006 UTC vs.
Revision 1.6 by pippijn, Thu Sep 7 09:37:12 2006 UTC

1/* 1/*
2 * static char *rcsid_living_c = 2 * static char *rcsid_living_c =
3 * "$Id: living.C,v 1.1 2006/08/13 17:16:00 elmex Exp $"; 3 * "$Id: living.C,v 1.6 2006/09/07 09:37:12 pippijn 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 evt = find_event(tmp,EVENT_ATTACK);
1089 if (evt != NULL) {
1090 if (op->current_weapon_script)
1091 free_string(op->current_weapon_script);
1092 op->current_weapon_script=add_string(query_name(tmp));
1093 }
1094 op->current_weapon = tmp; 1073 op->current_weapon = tmp;
1095 if(settings.spell_encumbrance == TRUE && op->type==PLAYER) 1074 if(settings.spell_encumbrance == TRUE && op->type==PLAYER)
1096 op->contr->encumbrance+=(int)3*tmp->weight/1000; 1075 op->contr->encumbrance+=(int)3*tmp->weight/1000;
1097 break; 1076 break;
1098 1077
1099 case ARMOUR: /* Only the best of these three are used: */ 1078 case ARMOUR: /* Only the best of these three are used: */
1100 if(settings.spell_encumbrance == TRUE && op->type==PLAYER) 1079 if(settings.spell_encumbrance == TRUE && op->type==PLAYER)
1101 op->contr->encumbrance+=(int)tmp->weight/1000; 1080 op->contr->encumbrance+=(int)tmp->weight/1000;
1102 1081
1103 case BRACERS: 1082 case BRACERS:
1104 case FORCE: 1083 case FORCE:
1105 if(tmp->stats.wc) { 1084 if(tmp->stats.wc) {
1106 if(best_wc<tmp->stats.wc+tmp->magic) { 1085 if(best_wc<tmp->stats.wc+tmp->magic) {
1107 wc+=best_wc; 1086 wc+=best_wc;
1108 best_wc=tmp->stats.wc+tmp->magic; 1087 best_wc=tmp->stats.wc+tmp->magic;
1109 } else 1088 } else
1110 wc+=tmp->stats.wc+tmp->magic; 1089 wc+=tmp->stats.wc+tmp->magic;
1111 } 1090 }
1112 if(tmp->stats.ac) { 1091 if(tmp->stats.ac) {
1113 if(best_ac<tmp->stats.ac+tmp->magic) { 1092 if(best_ac<tmp->stats.ac+tmp->magic) {
1114 ac+=best_ac; /* Remove last bonus */ 1093 ac+=best_ac; /* Remove last bonus */
1115 best_ac=tmp->stats.ac+tmp->magic; 1094 best_ac=tmp->stats.ac+tmp->magic;
1116 } 1095 }
1117 else /* To nullify the below effect */ 1096 else /* To nullify the below effect */
1118 ac+=tmp->stats.ac+tmp->magic; 1097 ac+=tmp->stats.ac+tmp->magic;
1119 } 1098 }
1120 if(tmp->stats.wc) wc-=(tmp->stats.wc+tmp->magic); 1099 if(tmp->stats.wc) wc-=(tmp->stats.wc+tmp->magic);
1121 if(tmp->stats.ac) ac-=(tmp->stats.ac+tmp->magic); 1100 if(tmp->stats.ac) ac-=(tmp->stats.ac+tmp->magic);
1122 if(ARMOUR_SPEED(tmp)&&ARMOUR_SPEED(tmp)/10.0<max) 1101 if(ARMOUR_SPEED(tmp)&&ARMOUR_SPEED(tmp)/10.0<max)
1123 max=ARMOUR_SPEED(tmp)/10.0; 1102 max=ARMOUR_SPEED(tmp)/10.0;
1124 break; 1103 break;
1125 } /* switch tmp->type */ 1104 } /* switch tmp->type */
1126 } /* item is equipped */ 1105 } /* item is equipped */
1127 } /* for loop of items */ 1106 } /* for loop of items */
1128 1107
1129 /* 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
1130 * have generated intermediate values which we now need to assign. 1109 * have generated intermediate values which we now need to assign.
1131 */ 1110 */
1135 * than that, we take: 'total resistance = resistance from potion'. 1114 * than that, we take: 'total resistance = resistance from potion'.
1136 * 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
1137 * 'total resistance = vulnerability from cursed potion'. 1116 * 'total resistance = vulnerability from cursed potion'.
1138 */ 1117 */
1139 for (i=0; i<NROFATTACKS; i++) { 1118 for (i=0; i<NROFATTACKS; i++) {
1140 op->resist[i] = prot[i] - vuln[i]; 1119 op->resist[i] = prot[i] - vuln[i];
1141 if (potion_resist[i] && ((potion_resist[i] > op->resist[i]) || 1120 if (potion_resist[i] && ((potion_resist[i] > op->resist[i]) ||
1142 (potion_resist[i] < 0))) 1121 (potion_resist[i] < 0)))
1143 op->resist[i] = potion_resist[i]; 1122 op->resist[i] = potion_resist[i];
1144 } 1123 }
1145 1124
1146 /* Figure out the players sp/mana/hp totals. */ 1125 /* Figure out the players sp/mana/hp totals. */
1147 if(op->type==PLAYER) { 1126 if(op->type==PLAYER) {
1148 int pl_level; 1127 int pl_level;
1149 1128
1150 check_stat_bounds(&(op->stats)); 1129 check_stat_bounds(&(op->stats));
1151 pl_level=op->level; 1130 pl_level=op->level;
1152 1131
1153 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! */
1154 1133
1155 /* 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,
1156 * 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.
1157 */ 1136 */
1158 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++) {
1159 j=op->contr->levhp[i]+con_bonus[op->stats.Con]/2; 1138 j=op->contr->levhp[i]+con_bonus[op->stats.Con]/2;
1160 if(i%2 && con_bonus[op->stats.Con]%2) { 1139 if(i%2 && con_bonus[op->stats.Con]%2) {
1161 if (con_bonus[op->stats.Con]>0) 1140 if (con_bonus[op->stats.Con]>0)
1162 j++; 1141 j++;
1163 else 1142 else
1164 j--; 1143 j--;
1165 } 1144 }
1166 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 */
1167 } 1146 }
1168 1147
1169 for(i=11;i<=op->level;i++) 1148 for(i=11;i<=op->level;i++)
1170 op->stats.maxhp+=2; 1149 op->stats.maxhp+=2;
1171 1150
1172 if(op->stats.hp>op->stats.maxhp) 1151 if(op->stats.hp>op->stats.maxhp)
1173 op->stats.hp=op->stats.maxhp; 1152 op->stats.hp=op->stats.maxhp;
1174 1153
1175 /* Sp gain is controlled by the level of the player's 1154 /* Sp gain is controlled by the level of the player's
1176 * relevant experience object (mana_obj, see above) 1155 * relevant experience object (mana_obj, see above)
1177 */ 1156 */
1178 /* following happen when skills system is not used */ 1157 /* following happen when skills system is not used */
1179 if(!mana_obj) mana_obj = op; 1158 if(!mana_obj) mana_obj = op;
1180 if(!grace_obj) grace_obj = op; 1159 if(!grace_obj) grace_obj = op;
1181 /* set maxsp */ 1160 /* set maxsp */
1182 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;
1183 1162
1184 if (mana_obj == op && op->type == PLAYER) { 1163 if (mana_obj == op && op->type == PLAYER) {
1185 op->stats.maxsp = 1; 1164 op->stats.maxsp = 1;
1186 } else { 1165 } else {
1187 sp_tmp=0.0; 1166 sp_tmp=0.0;
1188 for(i=1;i<=mana_obj->level&&i<=10;i++) { 1167 for(i=1;i<=mana_obj->level&&i<=10;i++) {
1189 float stmp; 1168 float stmp;
1190 1169
1191 /* Got some extra bonus at first level */ 1170 /* Got some extra bonus at first level */
1192 if(i<2) { 1171 if(i<2) {
1193 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] +
1194 (float)sp_bonus[op->stats.Int])/6.0); 1173 (float)sp_bonus[op->stats.Int])/6.0);
1195 } else { 1174 } else {
1196 stmp=(float)op->contr->levsp[i] 1175 stmp=(float)op->contr->levsp[i]
1197 +(2.0 * (float)sp_bonus[op->stats.Pow] + 1176 +(2.0 * (float)sp_bonus[op->stats.Pow] +
1198 (float)sp_bonus[op->stats.Int])/12.0; 1177 (float)sp_bonus[op->stats.Int])/12.0;
1199 } 1178 }
1200 if (stmp<1.0) stmp=1.0; 1179 if (stmp<1.0) stmp=1.0;
1201 sp_tmp+=stmp; 1180 sp_tmp+=stmp;
1202 } 1181 }
1203 op->stats.maxsp=(int)sp_tmp; 1182 op->stats.maxsp=(int)sp_tmp;
1204 1183
1205 for(i=11;i<=mana_obj->level;i++) 1184 for(i=11;i<=mana_obj->level;i++)
1206 op->stats.maxsp+=2; 1185 op->stats.maxsp+=2;
1207 } 1186 }
1208 /* Characters can get their sp supercharged via rune of transferrance */ 1187 /* Characters can get their sp supercharged via rune of transferrance */
1209 if(op->stats.sp>op->stats.maxsp*2) 1188 if(op->stats.sp>op->stats.maxsp*2)
1210 op->stats.sp=op->stats.maxsp*2; 1189 op->stats.sp=op->stats.maxsp*2;
1211 1190
1212 /* 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 */
1213 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;
1214 1193
1215 if (grace_obj == op && op->type == PLAYER) { 1194 if (grace_obj == op && op->type == PLAYER) {
1216 op->stats.maxgrace = 1; 1195 op->stats.maxgrace = 1;
1217 } else { 1196 } else {
1218 /* 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
1219 * 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
1220 * 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
1221 * step of 8 - with floats, even fractional ones are useful. 1200 * step of 8 - with floats, even fractional ones are useful.
1222 */ 1201 */
1223 sp_tmp=0.0; 1202 sp_tmp=0.0;
1224 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++) {
1225 float grace_tmp=0.0; 1204 float grace_tmp=0.0;
1226 1205
1227 /* Got some extra bonus at first level */ 1206 /* Got some extra bonus at first level */
1228 if(i<2) { 1207 if(i<2) {
1229 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] +
1230 2.0 * (float)grace_bonus[op->stats.Wis])/6.0); 1209 2.0 * (float)grace_bonus[op->stats.Wis])/6.0);
1231 } else { 1210 } else {
1232 grace_tmp=(float)op->contr->levgrace[i] 1211 grace_tmp=(float)op->contr->levgrace[i]
1233 +((float)grace_bonus[op->stats.Pow] + 1212 +((float)grace_bonus[op->stats.Pow] +
1234 2.0 * (float)grace_bonus[op->stats.Wis])/12.0; 1213 2.0 * (float)grace_bonus[op->stats.Wis])/12.0;
1235 } 1214 }
1236 if (grace_tmp<1.0) grace_tmp=1.0; 1215 if (grace_tmp<1.0) grace_tmp=1.0;
1237 sp_tmp+=grace_tmp; 1216 sp_tmp+=grace_tmp;
1238 } 1217 }
1239 op->stats.maxgrace=(int)sp_tmp; 1218 op->stats.maxgrace=(int)sp_tmp;
1240 1219
1241 /* two grace points per level after 11 */ 1220 /* two grace points per level after 11 */
1242 for(i=11;i<=grace_obj->level;i++) 1221 for(i=11;i<=grace_obj->level;i++)
1243 op->stats.maxgrace+=2; 1222 op->stats.maxgrace+=2;
1244 } 1223 }
1245 /* No limit on grace vs maxgrace */ 1224 /* No limit on grace vs maxgrace */
1246 1225
1247 if(op->contr->braced) { 1226 if(op->contr->braced) {
1248 ac+=2; 1227 ac+=2;
1249 wc+=4; 1228 wc+=4;
1250 } 1229 }
1251 else 1230 else
1252 ac-=dex_bonus[op->stats.Dex]; 1231 ac-=dex_bonus[op->stats.Dex];
1253 1232
1254 /* In new exp/skills system, wc bonuses are related to 1233 /* In new exp/skills system, wc bonuses are related to
1255 * the players level in a relevant exp object (wc_obj) 1234 * the players level in a relevant exp object (wc_obj)
1256 * not the general player level -b.t. 1235 * not the general player level -b.t.
1257 * I changed this slightly so that wc bonuses are better 1236 * I changed this slightly so that wc bonuses are better
1258 * than before. This is to balance out the fact that 1237 * than before. This is to balance out the fact that
1259 * the player no longer gets a personal weapon w/ 1 1238 * the player no longer gets a personal weapon w/ 1
1260 * improvement every level, now its fighterlevel/5. So 1239 * improvement every level, now its fighterlevel/5. So
1261 * we give the player a bonus here in wc and dam 1240 * we give the player a bonus here in wc and dam
1262 * to make up for the change. Note that I left the 1241 * to make up for the change. Note that I left the
1263 * monster bonus the same as before. -b.t. 1242 * monster bonus the same as before. -b.t.
1264 */ 1243 */
1265 1244
1266 if(op->type==PLAYER && wc_obj && wc_obj->level>1) { 1245 if(op->type==PLAYER && wc_obj && wc_obj->level>1) {
1267 wc-=(wc_obj->level+thaco_bonus[op->stats.Str]); 1246 wc-=(wc_obj->level+thaco_bonus[op->stats.Str]);
1268 for(i=1;i<wc_obj->level;i++) { 1247 for(i=1;i<wc_obj->level;i++) {
1269 /* addtional wc every 6 levels */ 1248 /* addtional wc every 6 levels */
1270 if(!(i%6)) wc--; 1249 if(!(i%6)) wc--;
1271 /* addtional dam every 4 levels. */ 1250 /* addtional dam every 4 levels. */
1272 if(!(i%4) && (dam_bonus[op->stats.Str]>=0)) 1251 if(!(i%4) && (dam_bonus[op->stats.Str]>=0))
1273 op->stats.dam+=(1+(dam_bonus[op->stats.Str]/5)); 1252 op->stats.dam+=(1+(dam_bonus[op->stats.Str]/5));
1274 } 1253 }
1275 } else 1254 } else
1276 wc-=(op->level+thaco_bonus[op->stats.Str]); 1255 wc-=(op->level+thaco_bonus[op->stats.Str]);
1277 1256
1278 op->stats.dam+=dam_bonus[op->stats.Str]; 1257 op->stats.dam+=dam_bonus[op->stats.Str];
1279 1258
1280 if(op->stats.dam<1) 1259 if(op->stats.dam<1)
1281 op->stats.dam=1; 1260 op->stats.dam=1;
1282 1261
1283 op->speed=1.0+speed_bonus[op->stats.Dex]; 1262 op->speed=1.0+speed_bonus[op->stats.Dex];
1284 if (settings.search_items && op->contr->search_str[0]) 1263 if (settings.search_items && op->contr->search_str[0])
1285 op->speed -= 1; 1264 op->speed -= 1;
1286 if (op->attacktype==0) 1265 if (op->attacktype==0)
1287 op->attacktype=op->arch->clone.attacktype; 1266 op->attacktype=op->arch->clone.attacktype;
1288 1267
1289 } /* End if player */ 1268 } /* End if player */
1290 1269
1291 if(added_speed>=0) 1270 if(added_speed>=0)
1292 op->speed+=added_speed/10.0; 1271 op->speed+=added_speed/10.0;
1293 else /* Something wrong here...: */ 1272 else /* Something wrong here...: */
1294 op->speed /= (float)(1.0-added_speed); 1273 op->speed /= (float)(1.0-added_speed);
1295 1274
1296 /* Max is determined by armour */ 1275 /* Max is determined by armour */
1297 if(op->speed>max) 1276 if(op->speed>max)
1298 op->speed=max; 1277 op->speed=max;
1299 1278
1300 if(op->type == PLAYER) { 1279 if(op->type == PLAYER) {
1301 /* 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)
1302 * or below (negative number) that the player is carrying. If above 1281 * or below (negative number) that the player is carrying. If above
1303 * weight limit, then player suffers a speed reduction based on how 1282 * weight limit, then player suffers a speed reduction based on how
1304 * much above he is, and what is max carry is 1283 * much above he is, and what is max carry is
1305 */ 1284 */
1306 f=(op->carrying/1000)-max_carry[op->stats.Str]; 1285 f=(op->carrying/1000)-max_carry[op->stats.Str];
1307 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]);
1308 } 1287 }
1309 1288
1310 op->speed+=bonus_speed/10.0; /* Not affected by limits */ 1289 op->speed+=bonus_speed/10.0; /* Not affected by limits */
1311 1290
1312 /* 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
1315 op->speed = op->speed * speed_reduce_from_disease; 1294 op->speed = op->speed * speed_reduce_from_disease;
1316 1295
1317 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;
1318 1297
1319 if(op->type == PLAYER) { 1298 if(op->type == PLAYER) {
1320 float M,W,s,D,K,S,M2; 1299 float M,W,s,D,K,S,M2;
1321 1300
1322 /* (This formula was made by vidarl@ifi.uio.no) 1301 /* (This formula was made by vidarl@ifi.uio.no)
1323 * Note that we never used these values again - basically 1302 * Note that we never used these values again - basically
1324 * all of these could be subbed into one big equation, but 1303 * all of these could be subbed into one big equation, but
1325 * that would just be a real pain to read. 1304 * that would just be a real pain to read.
1326 */ 1305 */
1327 M=(max_carry[op->stats.Str]-121)/121.0; 1306 M=(max_carry[op->stats.Str]-121)/121.0;
1328 M2=max_carry[op->stats.Str]/100.0; 1307 M2=max_carry[op->stats.Str]/100.0;
1329 W=weapon_weight/20000.0; 1308 W=weapon_weight/20000.0;
1330 s=2-weapon_speed/10.0; 1309 s=2-weapon_speed/10.0;
1331 D=(op->stats.Dex-14)/14.0; 1310 D=(op->stats.Dex-14)/14.0;
1332 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;
1333 K*=(4+op->level)/(float)(6+op->level)*1.2; 1312 K*=(4+op->level)/(float)(6+op->level)*1.2;
1334 if(K<=0) K=0.01; 1313 if(K<=0) K=0.01;
1335 S=op->speed/(K*s); 1314 S=op->speed/(K*s);
1336 op->contr->weapon_sp=S; 1315 op->contr->weapon_sp=S;
1337 } 1316 }
1338 /* 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: */
1339 if(op->type!=PLAYER&&op->arch!=NULL&& 1318 if(op->type!=PLAYER&&op->arch!=NULL&&
1340 op->stats.dam>op->arch->clone.stats.dam*3) 1319 op->stats.dam>op->arch->clone.stats.dam*3)
1341 op->stats.dam=op->arch->clone.stats.dam*3; 1320 op->stats.dam=op->arch->clone.stats.dam*3;
1342 1321
1343 /* 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
1344 * 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,
1345 * so its value is the same. 1324 * so its value is the same.
1346 */ 1325 */
1378 */ 1357 */
1379 1358
1380int allowed_class(const object *op) { 1359int allowed_class(const object *op) {
1381 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&&
1382 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&&
1383 op->stats.Cha>0; 1362 op->stats.Cha>0;
1384} 1363}
1385 1364
1386/* 1365/*
1387 * set the new dragon name after gaining levels or 1366 * set the new dragon name after gaining levels or
1388 * changing ability focus (later this can be extended to 1367 * changing ability focus (later this can be extended to
1402 if (!abil || !skin) return; 1381 if (!abil || !skin) return;
1403 1382
1404 /* first, look for the highest level */ 1383 /* first, look for the highest level */
1405 for(i=0; i<NROFATTACKS; i++) { 1384 for(i=0; i<NROFATTACKS; i++) {
1406 if (atnr_is_dragon_enabled(i) && 1385 if (atnr_is_dragon_enabled(i) &&
1407 (atnr==-1 || abil->resist[i] > abil->resist[atnr])) { 1386 (atnr==-1 || abil->resist[i] > abil->resist[atnr])) {
1408 level = abil->resist[i]; 1387 level = abil->resist[i];
1409 atnr = i; 1388 atnr = i;
1410 } 1389 }
1411 } 1390 }
1412 1391
1429 else if (level == 3) 1408 else if (level == 3)
1430 sprintf(pl->contr->title, "%s dragon", attacks[atnr]); 1409 sprintf(pl->contr->title, "%s dragon", attacks[atnr]);
1431 else { 1410 else {
1432 /* special titles for extra high resistance! */ 1411 /* special titles for extra high resistance! */
1433 if (skin->resist[atnr] > 80) 1412 if (skin->resist[atnr] > 80)
1434 sprintf(pl->contr->title, "legendary %s dragon", attacks[atnr]); 1413 sprintf(pl->contr->title, "legendary %s dragon", attacks[atnr]);
1435 else if (skin->resist[atnr] > 50) 1414 else if (skin->resist[atnr] > 50)
1436 sprintf(pl->contr->title, "ancient %s dragon", attacks[atnr]); 1415 sprintf(pl->contr->title, "ancient %s dragon", attacks[atnr]);
1437 else 1416 else
1438 sprintf(pl->contr->title, "big %s dragon", attacks[atnr]); 1417 sprintf(pl->contr->title, "big %s dragon", attacks[atnr]);
1439 } 1418 }
1440 } 1419 }
1441 1420
1442 strcpy(pl->contr->own_title, ""); 1421 strcpy(pl->contr->own_title, "");
1443} 1422}
1453 object *tmp = NULL; /* tmp. object */ 1432 object *tmp = NULL; /* tmp. object */
1454 char buf[MAX_BUF]; /* tmp. string buffer */ 1433 char buf[MAX_BUF]; /* tmp. string buffer */
1455 1434
1456 /* now grab the 'dragon_ability'-forces from the player's inventory */ 1435 /* now grab the 'dragon_ability'-forces from the player's inventory */
1457 for (tmp=who->inv; tmp!=NULL; tmp=tmp->below) { 1436 for (tmp=who->inv; tmp!=NULL; tmp=tmp->below) {
1458 if (tmp->type == FORCE) { 1437 if (tmp->type == FORCE) {
1459 if (strcmp(tmp->arch->name, "dragon_ability_force")==0) 1438 if (strcmp(tmp->arch->name, "dragon_ability_force")==0)
1460 abil = tmp; 1439 abil = tmp;
1461 if (strcmp(tmp->arch->name, "dragon_skin_force")==0) 1440 if (strcmp(tmp->arch->name, "dragon_skin_force")==0)
1462 skin = tmp; 1441 skin = tmp;
1463 } 1442 }
1464 } 1443 }
1465 /* if the force is missing -> bail out */ 1444 /* if the force is missing -> bail out */
1466 if (abil == NULL) return; 1445 if (abil == NULL) return;
1467 1446
1468 /* The ability_force keeps track of maximum level ever achieved. 1447 /* The ability_force keeps track of maximum level ever achieved.
1469 * New abilties can only be gained by surpassing this max level 1448 * New abilties can only be gained by surpassing this max level
1470 */ 1449 */
1471 if (who->level > abil->level) { 1450 if (who->level > abil->level) {
1472 /* increase our focused ability */ 1451 /* increase our focused ability */
1473 abil->resist[abil->stats.exp]++; 1452 abil->resist[abil->stats.exp]++;
1474 1453
1475 1454
1476 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) {
1477 /* time to hand out a new ability-gift */ 1456 /* time to hand out a new ability-gift */
1478 dragon_ability_gain(who, (int)abil->stats.exp, 1457 dragon_ability_gain(who, (int)abil->stats.exp,
1479 (int)((1+abil->resist[abil->stats.exp])/5.)); 1458 (int)((1+abil->resist[abil->stats.exp])/5.));
1480 } 1459 }
1481 1460
1482 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)) {
1483 /* apply new ability focus */ 1462 /* apply new ability focus */
1484 sprintf(buf, "Your metabolism now focuses on %s!", 1463 sprintf(buf, "Your metabolism now focuses on %s!",
1485 change_resist_msg[abil->last_eat]); 1464 change_resist_msg[abil->last_eat]);
1486 new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, buf); 1465 new_draw_info(NDI_UNIQUE|NDI_BLUE, 0, who, buf);
1487 1466
1488 abil->stats.exp = abil->last_eat; 1467 abil->stats.exp = abil->last_eat;
1489 abil->last_eat = 0; 1468 abil->last_eat = 0;
1490 } 1469 }
1491 1470
1492 abil->level = who->level; 1471 abil->level = who->level;
1493 } 1472 }
1494 1473
1495 /* last but not least, set the new title for the dragon */ 1474 /* last but not least, set the new title for the dragon */
1496 set_dragon_name(who, abil, skin); 1475 set_dragon_name(who, abil, skin);
1497} 1476}
1506{ 1485{
1507 object *skill_obj; 1486 object *skill_obj;
1508 1487
1509 skill_obj = get_archetype_by_skill_name(skill_name, SKILL); 1488 skill_obj = get_archetype_by_skill_name(skill_name, SKILL);
1510 if (!skill_obj) { 1489 if (!skill_obj) {
1511 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);
1512 return NULL; 1491 return NULL;
1513 } 1492 }
1514 /* clear the flag - exp goes into this bucket, but player 1493 /* clear the flag - exp goes into this bucket, but player
1515 * still doesn't know it. 1494 * still doesn't know it.
1516 */ 1495 */
1517 CLEAR_FLAG(skill_obj, FLAG_CAN_USE_SKILL); 1496 CLEAR_FLAG(skill_obj, FLAG_CAN_USE_SKILL);
1518 skill_obj->stats.exp = 0; 1497 skill_obj->stats.exp = 0;
1519 skill_obj->level = 1; 1498 skill_obj->level = 1;
1520 insert_ob_in_ob(skill_obj, op); 1499 insert_ob_in_ob(skill_obj, op);
1521 if (op->contr) { 1500 if (op->contr) {
1522 op->contr->last_skill_ob[skill_obj->subtype] = skill_obj; 1501 op->contr->last_skill_ob[skill_obj->subtype] = skill_obj;
1523 op->contr->last_skill_exp[skill_obj->subtype] = -1; 1502 op->contr->last_skill_exp[skill_obj->subtype] = -1;
1524 } 1503 }
1525 return skill_obj; 1504 return skill_obj;
1526} 1505}
1527 1506
1528 1507
1535 */ 1514 */
1536void player_lvl_adj(object *who, object *op) { 1515void player_lvl_adj(object *who, object *op) {
1537 char buf[MAX_BUF]; 1516 char buf[MAX_BUF];
1538 1517
1539 if(!op) /* when rolling stats */ 1518 if(!op) /* when rolling stats */
1540 op = who; 1519 op = who;
1541 1520
1542 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)) {
1543 op->level++; 1522 op->level++;
1544 1523
1545 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))
1546 dragon_level_gain(who); 1525 dragon_level_gain(who);
1547 1526
1548 /* 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 */
1549 if(op==who && (who->level < 11) && who->type==PLAYER) { 1528 if(op==who && (who->level < 11) && who->type==PLAYER) {
1550 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;
1551 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);
1552 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;
1553 } 1532 }
1554 1533
1555 fix_player(who); 1534 fix_player(who);
1556 if(op->level>1) { 1535 if(op->level>1) {
1557 if (op->type!=PLAYER) 1536 if (op->type!=PLAYER)
1558 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);
1559 else 1538 else
1560 sprintf(buf,"You are now level %d.",op->level); 1539 sprintf(buf,"You are now level %d.",op->level);
1561 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);
1562 } 1541 }
1563 player_lvl_adj(who,op); /* To increase more levels */ 1542 player_lvl_adj(who,op); /* To increase more levels */
1564 } 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)) {
1565 op->level--; 1544 op->level--;
1566 fix_player(who); 1545 fix_player(who);
1567 if(op->type!=PLAYER) { 1546 if(op->type!=PLAYER) {
1568 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);
1569 new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); 1548 new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf);
1570 } 1549 }
1571 player_lvl_adj(who,op); /* To decrease more levels */ 1550 player_lvl_adj(who,op); /* To decrease more levels */
1572 } 1551 }
1573 /* check if the spell data has changed */ 1552 /* check if the spell data has changed */
1574 esrv_update_spells(who->contr); 1553 esrv_update_spells(who->contr);
1575} 1554}
1576 1555
1579 * the given level. level should really never exceed max_level 1558 * the given level. level should really never exceed max_level
1580 */ 1559 */
1581 1560
1582sint64 level_exp(int level,double expmul) { 1561sint64 level_exp(int level,double expmul) {
1583 if (level > settings.max_level) 1562 if (level > settings.max_level)
1584 return (sint64) (expmul * levels[settings.max_level]); 1563 return (sint64) (expmul * levels[settings.max_level]);
1585 return (sint64) (expmul * levels[level]); 1564 return (sint64) (expmul * levels[level]);
1586} 1565}
1587 1566
1588/* 1567/*
1589 * 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.
1605 op->perm_exp = p_exp_min; 1584 op->perm_exp = p_exp_min;
1606 1585
1607 /* Cap permanent experience. */ 1586 /* Cap permanent experience. */
1608 if (op->perm_exp < 0) 1587 if (op->perm_exp < 0)
1609 op->perm_exp = 0; 1588 op->perm_exp = 0;
1610 else if (op->perm_exp > MAX_EXPERIENCE) 1589 else if (op->perm_exp > (sint64) MAX_EXPERIENCE)
1611 op->perm_exp = MAX_EXPERIENCE; 1590 op->perm_exp = MAX_EXPERIENCE;
1612} 1591}
1613 1592
1614 1593
1615/* Add experience to a player - exp should only be positive. 1594/* Add experience to a player - exp should only be positive.
1618 * NULL, in which case exp increases the players general 1597 * NULL, in which case exp increases the players general
1619 * total, but not any particular skill. 1598 * total, but not any particular skill.
1620 * 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:
1621 */ 1600 */
1622 1601
1623static 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)
1624{ 1603{
1625 object *skill_obj=NULL; 1604 object *skill_obj = NULL;
1626 sint64 limit, exp_to_add; 1605 sint64 limit, exp_to_add;
1627 int i; 1606 int i;
1628 1607
1629 /* prevents some forms of abuse. */ 1608 /* prevents some forms of abuse. */
1630 if(op->contr->braced) exp=exp/5; 1609 if (op->contr->braced)
1610 exp = exp / 5;
1631 1611
1632 /* Try to find the matching skill. 1612 /* Try to find the matching skill.
1633 * 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
1634 * chosen_skill. This means we don't need to search through 1614 * chosen_skill. This means we don't need to search through
1635 * the players inventory. 1615 * the players inventory.
1636 */ 1616 */
1637 if (skill_name) { 1617 if (skill_name)
1618 {
1638 if (op->chosen_skill && op->chosen_skill->type == SKILL && 1619 if (op->chosen_skill && op->chosen_skill->type == SKILL &&
1639 !strcmp(skill_name, op->chosen_skill->skill)) 1620 !strcmp (skill_name, op->chosen_skill->skill))
1640 skill_obj = op->chosen_skill; 1621 skill_obj = op->chosen_skill;
1641 else { 1622 else
1623 {
1642 for (i=0; i<NUM_SKILLS; i++) 1624 for (i = 0; i < NUM_SKILLS; i++)
1643 if (op->contr->last_skill_ob[i] && 1625 if (op->contr->last_skill_ob[i] &&
1644 !strcmp(op->contr->last_skill_ob[i]->skill, skill_name)) { 1626 !strcmp (op->contr->last_skill_ob[i]->skill, skill_name))
1627 {
1645 skill_obj = op->contr->last_skill_ob[i]; 1628 skill_obj = op->contr->last_skill_ob[i];
1646 break; 1629 break;
1647 } 1630 }
1648 1631
1649 /* 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
1650 * it to the player if necessary 1633 * it to the player if necessary
1651 */ 1634 */
1652 if (!skill_obj) { 1635 if (!skill_obj)
1653 if (flag == SK_EXP_NONE) return; 1636 {
1637 if (flag == SK_EXP_NONE)
1638 return;
1654 else if (flag == SK_EXP_ADD_SKILL) 1639 else if (flag == SK_EXP_ADD_SKILL)
1655 give_skill_by_name(op, skill_name); 1640 give_skill_by_name (op, skill_name);
1641 }
1642 }
1656 } 1643 }
1657 } 1644
1645 if (flag != SK_EXP_SKILL_ONLY)
1658 } 1646 {
1659
1660 /* Basically, you can never gain more experience in one shot 1647 /* Basically, you can never gain more experience in one shot
1661 * than half what you need to gain for next level. 1648 * than half what you need to gain for next level.
1662 */ 1649 */
1663 exp_to_add = exp; 1650 exp_to_add = exp;
1664 limit=(levels[op->level+1]-levels[op->level])/2; 1651 limit = (levels[op->level + 1] - levels[op->level]) / 2;
1665 if (exp_to_add > limit) exp_to_add=limit; 1652 if (exp_to_add > limit)
1653 exp_to_add = limit;
1666 1654
1667 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)));
1668 if (settings.permanent_exp_ratio) { 1658 if (settings.permanent_exp_ratio)
1669 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)));
1670 calc_perm_exp(op); 1663 calc_perm_exp (op);
1671 } 1664 }
1672 1665
1673 player_lvl_adj(op,NULL); 1666 player_lvl_adj (op, NULL);
1667 }
1668
1674 if (skill_obj) { 1669 if (skill_obj)
1670 {
1675 exp_to_add = exp; 1671 exp_to_add = exp;
1676 limit=(levels[skill_obj->level+1]-levels[skill_obj->level])/2; 1672 limit = (levels[skill_obj->level + 1] - levels[skill_obj->level]) / 2;
1677 if (exp_to_add > limit) exp_to_add=limit; 1673 if (exp_to_add > limit)
1674 exp_to_add = limit;
1675
1678 ADD_EXP(skill_obj->stats.exp, exp_to_add); 1676 ADD_EXP (skill_obj->stats.exp, exp_to_add);
1679 if (settings.permanent_exp_ratio) { 1677 if (settings.permanent_exp_ratio)
1680 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);
1681 calc_perm_exp(skill_obj); 1681 calc_perm_exp (skill_obj);
1682 } 1682 }
1683
1683 player_lvl_adj(op,skill_obj); 1684 player_lvl_adj (op, skill_obj);
1684 } 1685 }
1685} 1686}
1686 1687
1687/* This function checks to make sure that object 'op' can 1688/* This function checks to make sure that object 'op' can
1688 * lost 'exp' experience. It returns the amount of exp 1689 * lost 'exp' experience. It returns the amount of exp
1696{ 1697{
1697 sint64 del_exp; 1698 sint64 del_exp;
1698 1699
1699 if (exp > op->stats.exp) exp = op->stats.exp; 1700 if (exp > op->stats.exp) exp = op->stats.exp;
1700 if (settings.permanent_exp_ratio) { 1701 if (settings.permanent_exp_ratio) {
1701 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);
1702 if (del_exp < 0) del_exp = 0; 1703 if (del_exp < 0) del_exp = 0;
1703 if (exp > del_exp) exp=del_exp; 1704 if (exp > del_exp) exp=del_exp;
1704 } 1705 }
1705 return exp; 1706 return exp;
1706} 1707}
1707 1708
1708sint64 check_exp_adjust(const object *op, sint64 exp) 1709sint64 check_exp_adjust(const object *op, sint64 exp)
1709{ 1710{
1710 if (exp<0) return check_exp_loss(op, exp); 1711 if (exp<0) return check_exp_loss(op, exp);
1711 else return MIN(exp, MAX_EXPERIENCE - op->stats.exp); 1712 else return MIN(exp, (sint64) MAX_EXPERIENCE - op->stats.exp);
1712} 1713}
1713 1714
1714 1715
1715/* Subtracts experience from player. 1716/* Subtracts experience from player.
1716 * if skill is set and flag == SK_SUBTRACT_SKILL_EXP, then we 1717 * if skill is set and flag == SK_SUBTRACT_SKILL_EXP, then we
1729 float fraction = (float) exp/(float) op->stats.exp; 1730 float fraction = (float) exp/(float) op->stats.exp;
1730 object *tmp; 1731 object *tmp;
1731 sint64 del_exp; 1732 sint64 del_exp;
1732 1733
1733 for(tmp=op->inv;tmp;tmp=tmp->below) 1734 for(tmp=op->inv;tmp;tmp=tmp->below)
1734 if(tmp->type==SKILL && tmp->stats.exp) { 1735 if(tmp->type==SKILL && tmp->stats.exp) {
1735 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp(tmp->skill, skill)) { 1736 if (flag == SK_SUBTRACT_SKILL_EXP && skill && !strcmp(tmp->skill, skill)) {
1736 del_exp = check_exp_loss(tmp, exp); 1737 del_exp = check_exp_loss(tmp, exp);
1737 tmp->stats.exp -= del_exp; 1738 tmp->stats.exp -= del_exp;
1738 player_lvl_adj(op, tmp); 1739 player_lvl_adj(op, tmp);
1739 } else if (flag != SK_SUBTRACT_SKILL_EXP) { 1740 } else if (flag != SK_SUBTRACT_SKILL_EXP) {
1740 /* only want to process other skills if we are not trying 1741 /* only want to process other skills if we are not trying
1741 * to match a specific skill. 1742 * to match a specific skill.
1742 */ 1743 */
1743 del_exp = check_exp_loss(tmp, (sint64) (tmp->stats.exp * fraction)); 1744 del_exp = check_exp_loss(tmp, (sint64) (tmp->stats.exp * fraction));
1744 tmp->stats.exp -= del_exp; 1745 tmp->stats.exp -= del_exp;
1745 player_lvl_adj(op, tmp); 1746 player_lvl_adj(op, tmp);
1746 } 1747 }
1747 } 1748 }
1748 if (flag != SK_SUBTRACT_SKILL_EXP) { 1749 if (flag != SK_SUBTRACT_SKILL_EXP) {
1749 del_exp = check_exp_loss(op, exp); 1750 del_exp = check_exp_loss(op, exp);
1750 op->stats.exp -= del_exp; 1751 op->stats.exp -= del_exp;
1751 player_lvl_adj(op,NULL); 1752 player_lvl_adj(op,NULL);
1752 } 1753 }
1753} 1754}
1754 1755
1755 1756
1756 1757
1774#endif 1775#endif
1775#endif 1776#endif
1776 1777
1777 /* safety */ 1778 /* safety */
1778 if(!op) { 1779 if(!op) {
1779 LOG(llevError,"change_exp() called for null object!\n"); 1780 LOG(llevError,"change_exp() called for null object!\n");
1780 return; 1781 return;
1781 } 1782 }
1782 1783
1783 /* 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
1784 * won't do anything if the value is 0 anyways. 1785 * won't do anything if the value is 0 anyways.
1785 */ 1786 */
1789 * 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
1790 * the exp they have - the monsters exp represents what its 1791 * the exp they have - the monsters exp represents what its
1791 * worth. 1792 * worth.
1792 */ 1793 */
1793 if(op->type != PLAYER) { 1794 if(op->type != PLAYER) {
1794 /* Sanity check */ 1795 /* Sanity check */
1795 if (!QUERY_FLAG(op, FLAG_ALIVE)) return; 1796 if (!QUERY_FLAG(op, FLAG_ALIVE)) return;
1796 1797
1797 /* reset exp to max allowed value. We subtract from 1798 /* reset exp to max allowed value. We subtract from
1798 * MAX_EXPERIENCE to prevent overflows. If the player somehow has 1799 * MAX_EXPERIENCE to prevent overflows. If the player somehow has
1799 * more than max exp, just return. 1800 * more than max exp, just return.
1800 */ 1801 */
1801 if (exp > 0 && ( op->stats.exp > (MAX_EXPERIENCE - exp))) { 1802 if (exp > 0 && ( op->stats.exp > (sint64) (MAX_EXPERIENCE - exp))) {
1802 exp = MAX_EXPERIENCE - op->stats.exp; 1803 exp = MAX_EXPERIENCE - op->stats.exp;
1803 if (exp < 0) return; 1804 if (exp < 0) return;
1804 } 1805 }
1805 1806
1806 op->stats.exp += exp; 1807 op->stats.exp += exp;
1807 } 1808 }
1808 else { /* Players only */ 1809 else { /* Players only */
1809 if(exp>0) 1810 if(exp>0)
1810 add_player_exp(op, exp, skill_name, flag); 1811 add_player_exp(op, exp, skill_name, flag);
1811 else 1812 else
1812 /* note that when you lose exp, it doesn't go against 1813 /* note that when you lose exp, it doesn't go against
1813 * a particular skill, so we don't need to pass that 1814 * a particular skill, so we don't need to pass that
1814 * along. 1815 * along.
1815 */ 1816 */
1816 subtract_player_exp(op, FABS(exp), skill_name, flag); 1817 subtract_player_exp(op, FABS(exp), skill_name, flag);
1817 1818
1818 } 1819 }
1819} 1820}
1820 1821
1821/* 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
1828 sint64 loss; 1829 sint64 loss;
1829 sint64 percentage_loss; /* defined by the setting 'death_penalty_percent' */ 1830 sint64 percentage_loss; /* defined by the setting 'death_penalty_percent' */
1830 sint64 level_loss; /* defined by the setting 'death_penalty_levels */ 1831 sint64 level_loss; /* defined by the setting 'death_penalty_levels */
1831 1832
1832 for(tmp=op->inv;tmp;tmp=tmp->below) 1833 for(tmp=op->inv;tmp;tmp=tmp->below)
1833 if(tmp->type==SKILL && tmp->stats.exp) { 1834 if(tmp->type==SKILL && tmp->stats.exp) {
1834 1835
1835 percentage_loss = tmp->stats.exp * settings.death_penalty_ratio/100; 1836 percentage_loss = tmp->stats.exp * settings.death_penalty_ratio/100;
1836 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)];
1837 1838
1838 /* With the revised exp system, you can get cases where 1839 /* With the revised exp system, you can get cases where
1839 * losing several levels would still require that you have more 1840 * losing several levels would still require that you have more
1840 * exp than you currently have - this is true if the levels 1841 * exp than you currently have - this is true if the levels
1841 * tables is a lot harder. 1842 * tables is a lot harder.
1842 */ 1843 */
1843 if (level_loss < 0) level_loss = 0; 1844 if (level_loss < 0) level_loss = 0;
1844 1845
1845 loss = check_exp_loss(tmp, MIN(level_loss, percentage_loss)); 1846 loss = check_exp_loss(tmp, MIN(level_loss, percentage_loss));
1846 1847
1847 tmp->stats.exp -= loss; 1848 tmp->stats.exp -= loss;
1848 player_lvl_adj(op,tmp); 1849 player_lvl_adj(op,tmp);
1849 } 1850 }
1850 1851
1851 percentage_loss = op->stats.exp * settings.death_penalty_ratio/100; 1852 percentage_loss = op->stats.exp * settings.death_penalty_ratio/100;
1852 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)];
1853 if (level_loss < 0) level_loss = 0; 1854 if (level_loss < 0) level_loss = 0;
1854 loss = check_exp_loss(op, MIN(level_loss, percentage_loss)); 1855 loss = check_exp_loss(op, MIN(level_loss, percentage_loss));
1867int did_make_save(const object *op, int level, int bonus) 1868int did_make_save(const object *op, int level, int bonus)
1868{ 1869{
1869 if (level > MAX_SAVE_LEVEL) level = MAX_SAVE_LEVEL; 1870 if (level > MAX_SAVE_LEVEL) level = MAX_SAVE_LEVEL;
1870 1871
1871 if ((random_roll(1, 20, op, PREFER_HIGH) + bonus) < savethrow[level]) 1872 if ((random_roll(1, 20, op, PREFER_HIGH) + bonus) < savethrow[level])
1872 return 0; 1873 return 0;
1873 return 1; 1874 return 1;
1874} 1875}
1875 1876

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines