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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines