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.12 by root, Thu Sep 14 22:33:59 2006 UTC vs.
Revision 1.26 by root, Mon Jan 8 18:18:35 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
3 3
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 Copyright (C) 1992 Frank Tore Johansen
6 7
7 This program is free software; you can redistribute it and/or modify 8 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 it under the terms of the GNU General Public License as published by
158 * -b.t. 159 * -b.t.
159 */ 160 */
160 161
161#define MAX_EXP_IN_OBJ levels[settings.max_level]/(MAX_EXP_CAT - 1) 162#define MAX_EXP_IN_OBJ levels[settings.max_level]/(MAX_EXP_CAT - 1)
162 163
163#ifndef WIN32
164extern uint64 *levels;
165#else
166extern sint64 *levels; 164extern sint64 *levels;
167#endif
168 165
169#define MAX_SAVE_LEVEL 110 166#define MAX_SAVE_LEVEL 110
170 167
171/* This no longer needs to be changed anytime the number of 168/* This no longer needs to be changed anytime the number of
172 * levels is increased - rather, did_make_save will do the 169 * levels is increased - rather, did_make_save will do the
228 "You feel stupid!", 225 "You feel stupid!",
229 "You feel less potent!" 226 "You feel less potent!"
230}; 227};
231 228
232const char *const statname[NUM_STATS] = { 229const char *const statname[NUM_STATS] = {
233 "strength", "dexterity", "constitution", "wisdom", "charisma", "intelligence", "power" 230 "strength", "dexterity", "constitution", "intelligence", "wisdom", "power", "charisma"
234}; 231};
235 232
236const char *const short_stat_name[NUM_STATS] = { 233const char *const short_stat_name[NUM_STATS] = {
237 "Str", "Dex", "Con", "Wis", "Cha", "Int", "Pow" 234 "Str", "Dex", "Con", "Int", "Wis", "Pow", "Cha"
238}; 235};
239 236
240/* 237/*
241 * sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on 238 * sets Str/Dex/con/Wis/Cha/Int/Pow in stats to value, depending on
242 * what attr is (STR to POW). 239 * what attr is (STR to POW).
243 */ 240 */
244
245void 241void
246set_attr_value (living * stats, int attr, sint8 value) 242set_attr_value (living *stats, int attr, sint8 value)
247{ 243{
248 switch (attr) 244 switch (attr)
249 { 245 {
250 case STR: 246 case STR:
251 stats->Str = value; 247 stats->Str = value;
273 269
274/* 270/*
275 * Like set_attr_value(), but instead the value (which can be negative) 271 * Like set_attr_value(), but instead the value (which can be negative)
276 * is added to the specified stat. 272 * is added to the specified stat.
277 */ 273 */
278
279void 274void
280change_attr_value (living * stats, int attr, sint8 value) 275change_attr_value (living *stats, int attr, sint8 value)
281{ 276{
282 if (value == 0) 277 if (value == 0)
283 return; 278 return;
279
284 switch (attr) 280 switch (attr)
285 { 281 {
286 case STR: 282 case STR:
287 stats->Str += value; 283 stats->Str += value;
288 break; 284 break;
312/* 308/*
313 * returns the specified stat. See also set_attr_value(). 309 * returns the specified stat. See also set_attr_value().
314 */ 310 */
315 311
316sint8 312sint8
317get_attr_value (const living * stats, int attr) 313get_attr_value (const living *stats, int attr)
318{ 314{
319 switch (attr) 315 switch (attr)
320 { 316 {
321 case STR:
322 return (stats->Str); 317 case STR: return stats->Str;
323 case DEX:
324 return (stats->Dex); 318 case DEX: return stats->Dex;
325 case CON:
326 return (stats->Con); 319 case CON: return stats->Con;
327 case WIS:
328 return (stats->Wis); 320 case WIS: return stats->Wis;
329 case CHA:
330 return (stats->Cha); 321 case CHA: return stats->Cha;
331 case INT:
332 return (stats->Int); 322 case INT: return stats->Int;
333 case POW:
334 return (stats->Pow); 323 case POW: return stats->Pow;
335 } 324 }
325
336 return 0; 326 return 0;
337} 327}
338 328
339/* 329/*
340 * Ensures that all stats (str/dex/con/wis/cha/int) are within the 330 * Ensures that all stats (str/dex/con/wis/cha/int) are within the
341 * 1-30 stat limit. 331 * 1-30 stat limit.
342 */ 332 */
343 333
344void 334void
345check_stat_bounds (living * stats) 335check_stat_bounds (living *stats)
346{ 336{
347 int i, v; 337 int i, v;
348 338
349 for (i = 0; i < NUM_STATS; i++) 339 for (i = 0; i < NUM_STATS; i++)
350 if ((v = get_attr_value (stats, i)) > MAX_STAT) 340 if ((v = get_attr_value (stats, i)) > MAX_STAT)
382 char message[MAX_BUF]; 372 char message[MAX_BUF];
383 int potion_max = 0; 373 int potion_max = 0;
384 374
385 /* remember what object was like before it was changed. note that 375 /* remember what object was like before it was changed. note that
386 * refop is a local copy of op only to be used for detecting changes 376 * refop is a local copy of op only to be used for detecting changes
387 * found by fix_player. refop is not a real object 377 * found by update_stats. refop is not a real object
388 */ 378 */
389 object_pod refop = *op; 379 object_copy refop = *op;
390 380
391 if (op->type == PLAYER) 381 if (op->type == PLAYER)
392 { 382 {
393 if (tmp->type == POTION) 383 if (tmp->type == POTION)
394 { 384 {
412 nstat = 1; 402 nstat = 1;
413 else if (nstat > 20 + get_attr_value (&(op->arch->clone.stats), j)) 403 else if (nstat > 20 + get_attr_value (&(op->arch->clone.stats), j))
414 { 404 {
415 nstat = 20 + get_attr_value (&(op->arch->clone.stats), j); 405 nstat = 20 + get_attr_value (&(op->arch->clone.stats), j);
416 } 406 }
407
417 if (nstat != ostat) 408 if (nstat != ostat)
418 { 409 {
419 set_attr_value (&(op->contr->orig_stats), j, nstat); 410 set_attr_value (&(op->contr->orig_stats), j, nstat);
420 potion_max = 0; 411 potion_max = 0;
421 } 412 }
423 { 414 {
424 /* potion is useless - player has already hit the natural maximum */ 415 /* potion is useless - player has already hit the natural maximum */
425 potion_max = 1; 416 potion_max = 1;
426 } 417 }
427 } 418 }
419
428 /* This section of code ups the characters normal stats also. I am not 420 /* This section of code ups the characters normal stats also. I am not
429 * sure if this is strictly necessary, being that fix_player probably 421 * sure if this is strictly necessary, being that fix_player probably
430 * recalculates this anyway. 422 * recalculates this anyway.
431 */ 423 */
432 for (j = 0; j < NUM_STATS; j++) 424 for (j = 0; j < NUM_STATS; j++)
433 change_attr_value (&(op->stats), j, flag * get_attr_value (&(tmp->stats), j)); 425 change_attr_value (&(op->stats), j, flag * get_attr_value (&(tmp->stats), j));
426
434 check_stat_bounds (&(op->stats)); 427 check_stat_bounds (&(op->stats));
435 } /* end of potion handling code */ 428 } /* end of potion handling code */
436 } 429 }
437 430
438 /* reset attributes that fix_player doesn't reset since it doesn't search 431 /* reset attributes that fix_player doesn't reset since it doesn't search
452 445
453 /* call fix_player since op object could have whatever attribute due 446 /* call fix_player since op object could have whatever attribute due
454 * to multiple items. if fix_player always has to be called after 447 * to multiple items. if fix_player always has to be called after
455 * change_ability then might as well call it from here 448 * change_ability then might as well call it from here
456 */ 449 */
457 fix_player (op); 450 op->update_stats ();
458 451
459 /* Fix player won't add the bows ability to the player, so don't 452 /* Fix player won't add the bows ability to the player, so don't
460 * print out message if this is a bow. 453 * print out message if this is a bow.
461 */ 454 */
462 if (tmp->attacktype & AT_CONFUSION && tmp->type != BOW) 455 if (tmp->attacktype & AT_CONFUSION && tmp->type != BOW)
463 { 456 {
464 success = 1; 457 success = 1;
465 DIFF_MSG (flag, "Your hands begin to glow red.", "Your hands stop glowing red."); 458 DIFF_MSG (flag, "Your hands begin to glow red.", "Your hands stop glowing red.");
466 } 459 }
460
467 if (QUERY_FLAG (op, FLAG_LIFESAVE) != QUERY_FLAG (&refop, FLAG_LIFESAVE)) 461 if (QUERY_FLAG (op, FLAG_LIFESAVE) != QUERY_FLAG (&refop, FLAG_LIFESAVE))
468 { 462 {
469 success = 1; 463 success = 1;
470 DIFF_MSG (flag, "You feel very protected.", "You don't feel protected anymore."); 464 DIFF_MSG (flag, "You feel very protected.", "You don't feel protected anymore.");
471 } 465 }
466
472 if (QUERY_FLAG (op, FLAG_REFL_MISSILE) != QUERY_FLAG (&refop, FLAG_REFL_MISSILE)) 467 if (QUERY_FLAG (op, FLAG_REFL_MISSILE) != QUERY_FLAG (&refop, FLAG_REFL_MISSILE))
473 { 468 {
474 success = 1; 469 success = 1;
475 DIFF_MSG (flag, "A magic force shimmers around you.", "The magic force fades away."); 470 DIFF_MSG (flag, "A magic force shimmers around you.", "The magic force fades away.");
476 } 471 }
472
477 if (QUERY_FLAG (op, FLAG_REFL_SPELL) != QUERY_FLAG (&refop, FLAG_REFL_SPELL)) 473 if (QUERY_FLAG (op, FLAG_REFL_SPELL) != QUERY_FLAG (&refop, FLAG_REFL_SPELL))
478 { 474 {
479 success = 1; 475 success = 1;
480 DIFF_MSG (flag, "You feel more safe now, somehow.", "Suddenly you feel less safe, somehow."); 476 DIFF_MSG (flag, "You feel more safe now, somehow.", "Suddenly you feel less safe, somehow.");
481 } 477 }
478
482 /* movement type has changed. We don't care about cases where 479 /* movement type has changed. We don't care about cases where
483 * user has multiple items giving the same type appled like we 480 * user has multiple items giving the same type appled like we
484 * used to - that is more work than what we gain, plus messages 481 * used to - that is more work than what we gain, plus messages
485 * can be misleading (a little higher could be miscontrued from 482 * can be misleading (a little higher could be miscontrued from
486 * from fly high) 483 * from fly high)
534 if (QUERY_FLAG (op, FLAG_STEALTH) != QUERY_FLAG (&refop, FLAG_STEALTH)) 531 if (QUERY_FLAG (op, FLAG_STEALTH) != QUERY_FLAG (&refop, FLAG_STEALTH))
535 { 532 {
536 success = 1; 533 success = 1;
537 DIFF_MSG (flag, "You walk more quietly.", "You walk more noisily."); 534 DIFF_MSG (flag, "You walk more quietly.", "You walk more noisily.");
538 } 535 }
536
539 if (QUERY_FLAG (op, FLAG_MAKE_INVIS) != QUERY_FLAG (&refop, FLAG_MAKE_INVIS)) 537 if (QUERY_FLAG (op, FLAG_MAKE_INVIS) != QUERY_FLAG (&refop, FLAG_MAKE_INVIS))
540 { 538 {
541 success = 1; 539 success = 1;
542 DIFF_MSG (flag, "You become transparent.", "You can see yourself."); 540 DIFF_MSG (flag, "You become transparent.", "You can see yourself.");
543 } 541 }
542
544 /* blinded you can tell if more blinded since blinded player has minimal 543 /* blinded you can tell if more blinded since blinded player has minimal
545 * vision 544 * vision
546 */ 545 */
547 if (QUERY_FLAG (tmp, FLAG_BLIND)) 546 if (QUERY_FLAG (tmp, FLAG_BLIND))
548 { 547 {
655 654
656 new_draw_info (NDI_UNIQUE | NDI_BLUE, 0, op, message); 655 new_draw_info (NDI_UNIQUE | NDI_BLUE, 0, op, message);
657 } 656 }
658 } 657 }
659 658
660 if (tmp->type != EXPERIENCE && !potion_max) 659 if (!potion_max)
661 { 660 {
662 for (j = 0; j < NUM_STATS; j++) 661 for (j = 0; j < NUM_STATS; j++)
663 { 662 {
664 if ((i = get_attr_value (&(tmp->stats), j)) != 0) 663 if ((i = get_attr_value (&(tmp->stats), j)) != 0)
665 { 664 {
666 success = 1; 665 success = 1;
667 DIFF_MSG (i * flag, gain_msg[j], lose_msg[j]); 666 DIFF_MSG (i * flag, gain_msg[j], lose_msg[j]);
668 } 667 }
669 } 668 }
670 } 669 }
670
671 return success; 671 return success;
672} 672}
673 673
674/* 674/*
675 * Stat draining by Vick 930307 675 * Stat draining by Vick 930307
676 * (Feeling evil, I made it work as well now. -Frank 8) 676 * (Feeling evil, I made it work as well now. -Frank 8)
677 */ 677 */
678 678
679void 679void
680drain_stat (object *op) 680object::drain_stat ()
681{ 681{
682 drain_specific_stat (op, RANDOM () % NUM_STATS); 682 drain_specific_stat (RANDOM () % NUM_STATS);
683} 683}
684 684
685void 685void
686drain_specific_stat (object *op, int deplete_stats) 686object::drain_specific_stat (int deplete_stats)
687{ 687{
688 object *tmp; 688 object *tmp;
689 archetype *at; 689 archetype *at;
690 690
691 at = archetype::find (ARCH_DEPLETION); 691 at = archetype::find (ARCH_DEPLETION);
694 LOG (llevError, "Couldn't find archetype depletion.\n"); 694 LOG (llevError, "Couldn't find archetype depletion.\n");
695 return; 695 return;
696 } 696 }
697 else 697 else
698 { 698 {
699 tmp = present_arch_in_ob (at, op); 699 tmp = present_arch_in_ob (at, this);
700
700 if (!tmp) 701 if (!tmp)
701 { 702 {
702 tmp = arch_to_object (at); 703 tmp = arch_to_object (at);
703 tmp = insert_ob_in_ob (tmp, op); 704 tmp = insert_ob_in_ob (tmp, this);
704 SET_FLAG (tmp, FLAG_APPLIED); 705 SET_FLAG (tmp, FLAG_APPLIED);
705 } 706 }
706 } 707 }
707 708
708 new_draw_info (NDI_UNIQUE, 0, op, drain_msg[deplete_stats]); 709 new_draw_info (NDI_UNIQUE, 0, this, drain_msg[deplete_stats]);
709 change_attr_value (&tmp->stats, deplete_stats, -1); 710 change_attr_value (&tmp->stats, deplete_stats, -1);
710 fix_player (op); 711 update_stats ();
711} 712}
712 713
713/* 714/*
714 * A value of 0 indicates timeout, otherwise change the luck of the object. 715 * A value of 0 indicates timeout, otherwise change the luck of the object.
715 * via an applied bad_luck object. 716 * via an applied bad_luck object.
716 */ 717 */
717
718void 718void
719change_luck (object *op, int value) 719object::change_luck (int value)
720{ 720{
721 object *tmp;
722 archetype *at;
723 int new_luck;
724
725 at = archetype::find ("luck"); 721 archetype *at = archetype::find ("luck");
726 if (!at) 722 if (!at)
727 LOG (llevError, "Couldn't find archetype luck.\n"); 723 LOG (llevError, "Couldn't find archetype luck.\n");
728 else 724 else
729 { 725 {
730 tmp = present_arch_in_ob (at, op); 726 object *tmp = present_arch_in_ob (at, this);
727
731 if (!tmp) 728 if (!tmp)
732 { 729 {
733 if (!value) 730 if (!value)
734 return; 731 return;
732
735 tmp = arch_to_object (at); 733 tmp = arch_to_object (at);
736 tmp = insert_ob_in_ob (tmp, op); 734 tmp = insert_ob_in_ob (tmp, this);
737 SET_FLAG (tmp, FLAG_APPLIED); 735 SET_FLAG (tmp, FLAG_APPLIED);
738 } 736 }
737
739 if (value) 738 if (value)
740 { 739 {
741 /* Limit the luck value of the bad luck object to +/-100. This 740 /* Limit the luck value of the bad luck object to +/-100. This
742 * (arbitrary) value prevents overflows (both in the bad luck object and 741 * (arbitrary) value prevents overflows (both in the bad luck object and
743 * in op itself). 742 * in op itself).
744 */ 743 */
745 new_luck = tmp->stats.luck + value; 744 int new_luck = tmp->stats.luck + value;
745
746 if (new_luck >= -100 && new_luck <= 100) 746 if (new_luck >= -100 && new_luck <= 100)
747 { 747 {
748 op->stats.luck += value; 748 stats.luck += value;
749 tmp->stats.luck = new_luck; 749 tmp->stats.luck = new_luck;
750 } 750 }
751 } 751 }
752 else 752 else
753 { 753 {
754 if (!tmp->stats.luck) 754 if (!tmp->stats.luck)
755 {
756 return; 755 return;
757 } 756
758 /* Randomly change the players luck. Basically, we move it 757 /* Randomly change the players luck. Basically, we move it
759 * back neutral (if greater>0, subtract, otherwise add) 758 * back neutral (if greater>0, subtract, otherwise add)
760 */ 759 */
761 if (RANDOM () % (FABS (tmp->stats.luck)) >= RANDOM () % 30) 760 if (RANDOM () % (FABS (tmp->stats.luck)) >= RANDOM () % 30)
762 { 761 {
763 int diff = tmp->stats.luck > 0 ? -1 : 1; 762 int diff = tmp->stats.luck > 0 ? -1 : 1;
764 763
765 op->stats.luck += diff; 764 stats.luck += diff;
766 tmp->stats.luck += diff; 765 tmp->stats.luck += diff;
767 } 766 }
768 } 767 }
769 } 768 }
770} 769}
771 770
772/* 771/*
773 * Subtracts stat-bonuses given by the class which the player has chosen. 772 * Subtracts stat-bonuses given by the class which the player has chosen.
774 */ 773 */
775
776void 774void
777remove_statbonus (object *op) 775object::remove_statbonus ()
778{ 776{
779 op->stats.Str -= op->arch->clone.stats.Str; 777 stats.Str -= arch->clone.stats.Str;
780 op->stats.Dex -= op->arch->clone.stats.Dex; 778 stats.Dex -= arch->clone.stats.Dex;
781 op->stats.Con -= op->arch->clone.stats.Con; 779 stats.Con -= arch->clone.stats.Con;
782 op->stats.Wis -= op->arch->clone.stats.Wis; 780 stats.Wis -= arch->clone.stats.Wis;
783 op->stats.Pow -= op->arch->clone.stats.Pow; 781 stats.Pow -= arch->clone.stats.Pow;
784 op->stats.Cha -= op->arch->clone.stats.Cha; 782 stats.Cha -= arch->clone.stats.Cha;
785 op->stats.Int -= op->arch->clone.stats.Int; 783 stats.Int -= arch->clone.stats.Int;
784
786 op->contr->orig_stats.Str -= op->arch->clone.stats.Str; 785 contr->orig_stats.Str -= arch->clone.stats.Str;
787 op->contr->orig_stats.Dex -= op->arch->clone.stats.Dex; 786 contr->orig_stats.Dex -= arch->clone.stats.Dex;
788 op->contr->orig_stats.Con -= op->arch->clone.stats.Con; 787 contr->orig_stats.Con -= arch->clone.stats.Con;
789 op->contr->orig_stats.Wis -= op->arch->clone.stats.Wis; 788 contr->orig_stats.Wis -= arch->clone.stats.Wis;
790 op->contr->orig_stats.Pow -= op->arch->clone.stats.Pow; 789 contr->orig_stats.Pow -= arch->clone.stats.Pow;
791 op->contr->orig_stats.Cha -= op->arch->clone.stats.Cha; 790 contr->orig_stats.Cha -= arch->clone.stats.Cha;
792 op->contr->orig_stats.Int -= op->arch->clone.stats.Int; 791 contr->orig_stats.Int -= arch->clone.stats.Int;
793} 792}
794 793
795/* 794/*
796 * Adds stat-bonuses given by the class which the player has chosen. 795 * Adds stat-bonuses given by the class which the player has chosen.
797 */ 796 */
798
799void 797void
800add_statbonus (object *op) 798object::add_statbonus ()
801{ 799{
802 op->stats.Str += op->arch->clone.stats.Str; 800 stats.Str += arch->clone.stats.Str;
803 op->stats.Dex += op->arch->clone.stats.Dex; 801 stats.Dex += arch->clone.stats.Dex;
804 op->stats.Con += op->arch->clone.stats.Con; 802 stats.Con += arch->clone.stats.Con;
805 op->stats.Wis += op->arch->clone.stats.Wis; 803 stats.Wis += arch->clone.stats.Wis;
806 op->stats.Pow += op->arch->clone.stats.Pow; 804 stats.Pow += arch->clone.stats.Pow;
807 op->stats.Cha += op->arch->clone.stats.Cha; 805 stats.Cha += arch->clone.stats.Cha;
808 op->stats.Int += op->arch->clone.stats.Int; 806 stats.Int += arch->clone.stats.Int;
807
809 op->contr->orig_stats.Str += op->arch->clone.stats.Str; 808 contr->orig_stats.Str += arch->clone.stats.Str;
810 op->contr->orig_stats.Dex += op->arch->clone.stats.Dex; 809 contr->orig_stats.Dex += arch->clone.stats.Dex;
811 op->contr->orig_stats.Con += op->arch->clone.stats.Con; 810 contr->orig_stats.Con += arch->clone.stats.Con;
812 op->contr->orig_stats.Wis += op->arch->clone.stats.Wis; 811 contr->orig_stats.Wis += arch->clone.stats.Wis;
813 op->contr->orig_stats.Pow += op->arch->clone.stats.Pow; 812 contr->orig_stats.Pow += arch->clone.stats.Pow;
814 op->contr->orig_stats.Cha += op->arch->clone.stats.Cha; 813 contr->orig_stats.Cha += arch->clone.stats.Cha;
815 op->contr->orig_stats.Int += op->arch->clone.stats.Int; 814 contr->orig_stats.Int += arch->clone.stats.Int;
816} 815}
817 816
818/* 817/*
819 * Updates all abilities given by applied objects in the inventory 818 * Updates all abilities given by applied objects in the inventory
820 * of the given object. Note: This function works for both monsters 819 * of the given object. Note: This function works for both monsters
826/* July 95 - inserted stuff to handle new skills/exp system - b.t. 825/* July 95 - inserted stuff to handle new skills/exp system - b.t.
827 spell system split, grace points now added to system --peterm 826 spell system split, grace points now added to system --peterm
828 */ 827 */
829 828
830void 829void
831fix_player (object *op) 830object::update_stats ()
832{ 831{
833 int i, j; 832 int i, j;
834 float f, max = 9, added_speed = 0, bonus_speed = 0, sp_tmp, speed_reduce_from_disease = 1; 833 float f, max = 9, added_speed = 0, bonus_speed = 0, sp_tmp, speed_reduce_from_disease = 1;
835 int weapon_weight = 0, weapon_speed = 0; 834 int weapon_weight = 0, weapon_speed = 0;
836 int best_wc = 0, best_ac = 0, wc = 0, ac = 0; 835 int best_wc = 0, best_ac = 0, wc = 0, ac = 0;
837 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; 836 int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS];
838 object *grace_obj = NULL, *mana_obj = NULL, *wc_obj = NULL, *tmp; 837 object *grace_obj = NULL, *mana_obj = NULL, *wc_obj = NULL, *tmp;
838 float old_speed = speed;
839 839
840 /* First task is to clear all the values back to their original values */ 840 /* First task is to clear all the values back to their original values */
841 if (op->type == PLAYER) 841 if (type == PLAYER)
842 { 842 {
843 for (i = 0; i < NUM_STATS; i++) 843 for (i = 0; i < NUM_STATS; i++)
844 {
845 set_attr_value (&(op->stats), i, get_attr_value (&(op->contr->orig_stats), i)); 844 set_attr_value (&(stats), i, get_attr_value (&(contr->orig_stats), i));
846 } 845
847 if (settings.spell_encumbrance == TRUE) 846 if (settings.spell_encumbrance == TRUE)
848 op->contr->encumbrance = 0; 847 contr->encumbrance = 0;
849 848
850 op->attacktype = 0; 849 attacktype = 0;
851 op->contr->digestion = 0; 850 contr->digestion = 0;
852 op->contr->gen_hp = 0; 851 contr->gen_hp = 0;
853 op->contr->gen_sp = 0; 852 contr->gen_sp = 0;
854 op->contr->gen_grace = 0; 853 contr->gen_grace = 0;
855 op->contr->gen_sp_armour = 10; 854 contr->gen_sp_armour = 10;
856 op->contr->item_power = 0; 855 contr->item_power = 0;
857 856
858 /* Don't clobber all the range_ values. range_golem otherwise 857 /* Don't clobber all the range_ values. range_golem otherwise
859 * gets reset for no good reason, and we don't want to reset 858 * gets reset for no good reason, and we don't want to reset
860 * range_magic (what spell is readied). These three below 859 * range_magic (what spell is readied). These three below
861 * well get filled in based on what the player has equipped. 860 * well get filled in based on what the player has equipped.
862 */ 861 */
863 op->contr->ranges[range_bow] = NULL; 862 contr->ranges[range_bow] = NULL;
864 op->contr->ranges[range_misc] = NULL; 863 contr->ranges[range_misc] = NULL;
865 op->contr->ranges[range_skill] = NULL; 864 contr->ranges[range_skill] = NULL;
866 } 865 }
866
867 memcpy (op->body_used, op->body_info, sizeof (op->body_info)); 867 memcpy (body_used, body_info, sizeof (body_info));
868 868
869 op->slaying = 0; 869 slaying = 0;
870 870
871 if (!QUERY_FLAG (op, FLAG_WIZ)) 871 if (!QUERY_FLAG (this, FLAG_WIZ))
872 { 872 {
873 CLEAR_FLAG (op, FLAG_XRAYS); 873 CLEAR_FLAG (this, FLAG_XRAYS);
874 CLEAR_FLAG (op, FLAG_MAKE_INVIS); 874 CLEAR_FLAG (this, FLAG_MAKE_INVIS);
875 } 875 }
876 876
877 CLEAR_FLAG (op, FLAG_LIFESAVE); 877 CLEAR_FLAG (this, FLAG_LIFESAVE);
878 CLEAR_FLAG (op, FLAG_STEALTH); 878 CLEAR_FLAG (this, FLAG_STEALTH);
879 CLEAR_FLAG (op, FLAG_BLIND); 879 CLEAR_FLAG (this, FLAG_BLIND);
880 if (!QUERY_FLAG (&op->arch->clone, FLAG_REFL_SPELL))
881 CLEAR_FLAG (op, FLAG_REFL_SPELL);
882 if (!QUERY_FLAG (&op->arch->clone, FLAG_REFL_MISSILE))
883 CLEAR_FLAG (op, FLAG_REFL_MISSILE);
884 if (!QUERY_FLAG (&op->arch->clone, FLAG_UNDEAD))
885 CLEAR_FLAG (op, FLAG_UNDEAD);
886 if (!QUERY_FLAG (&op->arch->clone, FLAG_SEE_IN_DARK))
887 CLEAR_FLAG (op, FLAG_SEE_IN_DARK);
888 880
881 if (!QUERY_FLAG (&arch->clone, FLAG_REFL_SPELL )) CLEAR_FLAG (this, FLAG_REFL_SPELL);
882 if (!QUERY_FLAG (&arch->clone, FLAG_REFL_MISSILE)) CLEAR_FLAG (this, FLAG_REFL_MISSILE);
883 if (!QUERY_FLAG (&arch->clone, FLAG_UNDEAD )) CLEAR_FLAG (this, FLAG_UNDEAD);
884 if (!QUERY_FLAG (&arch->clone, FLAG_SEE_IN_DARK )) CLEAR_FLAG (this, FLAG_SEE_IN_DARK);
885
889 op->path_attuned = op->arch->clone.path_attuned; 886 path_attuned = arch->clone.path_attuned;
890 op->path_repelled = op->arch->clone.path_repelled; 887 path_repelled = arch->clone.path_repelled;
891 op->path_denied = op->arch->clone.path_denied; 888 path_denied = arch->clone.path_denied;
892 op->glow_radius = op->arch->clone.glow_radius; 889 glow_radius = arch->clone.glow_radius;
893 op->move_type = op->arch->clone.move_type; 890 move_type = arch->clone.move_type;
894 op->chosen_skill = NULL; 891 chosen_skill = NULL;
895 892
896 /* initializing resistances from the values in player/monster's 893 /* initializing resistances from the values in player/monster's
897 * archetype clone 894 * archetype clone
898 */ 895 */
899 memcpy (&op->resist, &op->arch->clone.resist, sizeof (op->resist)); 896 memcpy (&resist, &arch->clone.resist, sizeof (resist));
900 897
901 for (i = 0; i < NROFATTACKS; i++) 898 for (i = 0; i < NROFATTACKS; i++)
902 { 899 {
903 if (op->resist[i] > 0) 900 if (resist[i] > 0)
904 prot[i] = op->resist[i], vuln[i] = 0; 901 prot[i] = resist[i], vuln[i] = 0;
905 else 902 else
906 vuln[i] = -(op->resist[i]), prot[i] = 0; 903 vuln[i] = -(resist[i]), prot[i] = 0;
907 potion_resist[i] = 0; 904 potion_resist[i] = 0;
908 } 905 }
909 906
910 wc = op->arch->clone.stats.wc; 907 wc = arch->clone.stats.wc;
911 op->stats.dam = op->arch->clone.stats.dam; 908 stats.dam = arch->clone.stats.dam;
912 909
913 /* for players which cannot use armour, they gain AC -1 per 3 levels, 910 /* for players which cannot use armour, they gain AC -1 per 3 levels,
914 * plus a small amount of physical resist, those poor suckers. ;) 911 * plus a small amount of physical resist, those poor suckers. ;)
915 * the fact that maxlevel is factored in could be considered sort of bogus - 912 * the fact that maxlevel is factored in could be considered sort of bogus -
916 * we should probably give them some bonus and cap it off - otherwise, 913 * we should probably give them some bonus and cap it off - otherwise,
917 * basically, if a server updates its max level, these playes may find 914 * basically, if a server updates its max level, these playes may find
918 * that their protection from physical goes down 915 * that their protection from physical goes down
919 */ 916 */
920 if (!QUERY_FLAG (op, FLAG_USE_ARMOUR) && op->type == PLAYER) 917 if (!QUERY_FLAG (this, FLAG_USE_ARMOUR) && type == PLAYER)
921 { 918 {
922 ac = MAX (-10, op->arch->clone.stats.ac - op->level / 3); 919 ac = MAX (-10, arch->clone.stats.ac - level / 3);
923 prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * op->level / settings.max_level)) / 100; 920 prot[ATNR_PHYSICAL] += ((100 - prot[AT_PHYSICAL]) * (80 * level / settings.max_level)) / 100;
924 } 921 }
925 else 922 else
926 ac = op->arch->clone.stats.ac; 923 ac = arch->clone.stats.ac;
927 924
928 op->stats.luck = op->arch->clone.stats.luck; 925 stats.luck = arch->clone.stats.luck;
929 op->speed = op->arch->clone.speed; 926 speed = arch->clone.speed;
930 927
931 /* OK - we've reset most all the objects attributes to sane values. 928 /* OK - we've reset most all the objects attributes to sane values.
932 * now go through and make adjustments for what the player has equipped. 929 * now go through and make adjustments for what the player has equipped.
933 */ 930 */
934 931
935 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 932 for (tmp = inv; tmp; tmp = tmp->below)
936 { 933 {
937 /* See note in map.c:update_position about making this additive 934 /* See note in map.c:update_position about making this additive
938 * since light sources are never applied, need to put check here. 935 * since light sources are never applied, need to put check here.
939 */ 936 */
940 if (tmp->glow_radius > op->glow_radius) 937 if (tmp->glow_radius > glow_radius)
941 op->glow_radius = tmp->glow_radius; 938 glow_radius = tmp->glow_radius;
942 939
943 /* This happens because apply_potion calls change_abil with the potion 940 /* This happens because apply_potion calls change_abil with the potion
944 * applied so we can tell the player what chagned. But change_abil 941 * applied so we can tell the player what chagned. But change_abil
945 * then calls this function. 942 * then calls this function.
946 */ 943 */
947 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == POTION) 944 if (QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type == POTION)
948 {
949 continue; 945 continue;
950 }
951 946
952 /* For some things, we don't care what is equipped */ 947 /* For some things, we don't care what is equipped */
953 if (tmp->type == SKILL) 948 if (tmp->type == SKILL)
954 { 949 {
955 /* Want to take the highest skill here. */ 950 /* Want to take the highest skill here. */
958 if (!mana_obj) 953 if (!mana_obj)
959 mana_obj = tmp; 954 mana_obj = tmp;
960 else if (tmp->level > mana_obj->level) 955 else if (tmp->level > mana_obj->level)
961 mana_obj = tmp; 956 mana_obj = tmp;
962 } 957 }
958
963 if (IS_GRACE_SKILL (tmp->subtype)) 959 if (IS_GRACE_SKILL (tmp->subtype))
964 { 960 {
965 if (!grace_obj) 961 if (!grace_obj)
966 grace_obj = tmp; 962 grace_obj = tmp;
967 else if (tmp->level > grace_obj->level) 963 else if (tmp->level > grace_obj->level)
979 * up, etc. 975 * up, etc.
980 */ 976 */
981 if ((QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type != CONTAINER && tmp->type != CLOSE_CON) || 977 if ((QUERY_FLAG (tmp, FLAG_APPLIED) && tmp->type != CONTAINER && tmp->type != CLOSE_CON) ||
982 (tmp->type == SKILL && tmp->subtype == SK_PRAYING)) 978 (tmp->type == SKILL && tmp->subtype == SK_PRAYING))
983 { 979 {
984 if (op->type == PLAYER) 980 if (type == PLAYER)
985 { 981 {
986 if (tmp->type == BOW) 982 if (tmp->type == BOW)
987 op->contr->ranges[range_bow] = tmp; 983 contr->ranges[range_bow] = tmp;
988 984
989 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN) 985 if (tmp->type == WAND || tmp->type == ROD || tmp->type == HORN)
990 op->contr->ranges[range_misc] = tmp; 986 contr->ranges[range_misc] = tmp;
991 987
992 for (i = 0; i < NUM_STATS; i++) 988 for (i = 0; i < NUM_STATS; i++)
993 change_attr_value (&(op->stats), i, get_attr_value (&(tmp->stats), i)); 989 change_attr_value (&(stats), i, get_attr_value (&(tmp->stats), i));
994 990
995 /* these are the items that currently can change digestion, regeneration, 991 /* these are the items that currently can change digestion, regeneration,
996 * spell point recovery and mana point recovery. Seems sort of an arbitary 992 * spell point recovery and mana point recovery. Seems sort of an arbitary
997 * list, but other items store other info into stats array. 993 * list, but other items store other info into stats array.
998 */ 994 */
999 if ((tmp->type == EXPERIENCE) || (tmp->type == WEAPON) || 995 if ((tmp->type == WEAPON) ||
1000 (tmp->type == ARMOUR) || (tmp->type == HELMET) || 996 (tmp->type == ARMOUR) || (tmp->type == HELMET) ||
1001 (tmp->type == SHIELD) || (tmp->type == RING) || 997 (tmp->type == SHIELD) || (tmp->type == RING) ||
1002 (tmp->type == BOOTS) || (tmp->type == GLOVES) || 998 (tmp->type == BOOTS) || (tmp->type == GLOVES) ||
1003 (tmp->type == AMULET) || (tmp->type == GIRDLE) || 999 (tmp->type == AMULET) || (tmp->type == GIRDLE) ||
1004 (tmp->type == BRACERS) || (tmp->type == CLOAK) || (tmp->type == DISEASE) || (tmp->type == FORCE) || (tmp->type == SKILL)) 1000 (tmp->type == BRACERS) || (tmp->type == CLOAK) ||
1001 (tmp->type == DISEASE) || (tmp->type == FORCE) ||
1002 (tmp->type == SKILL))
1005 { 1003 {
1006 op->contr->digestion += tmp->stats.food; 1004 contr->digestion += tmp->stats.food;
1007 op->contr->gen_hp += tmp->stats.hp; 1005 contr->gen_hp += tmp->stats.hp;
1008 op->contr->gen_sp += tmp->stats.sp; 1006 contr->gen_sp += tmp->stats.sp;
1009 op->contr->gen_grace += tmp->stats.grace; 1007 contr->gen_grace += tmp->stats.grace;
1010 op->contr->gen_sp_armour += tmp->gen_sp_armour; 1008 contr->gen_sp_armour += tmp->gen_sp_armour;
1011 op->contr->item_power += tmp->item_power; 1009 contr->item_power += tmp->item_power;
1012 } 1010 }
1013 } /* if this is a player */ 1011 } /* if this is a player */
1014 1012
1015 /* Update slots used for items */ 1013 /* Update slots used for items */
1016 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 1014 if (QUERY_FLAG (tmp, FLAG_APPLIED))
1017 {
1018 for (i = 0; i < NUM_BODY_LOCATIONS; i++) 1015 for (i = 0; i < NUM_BODY_LOCATIONS; i++)
1019 op->body_used[i] += tmp->body_info[i]; 1016 body_used[i] += tmp->body_info[i];
1020 }
1021 1017
1022 if (tmp->type == SYMPTOM) 1018 if (tmp->type == SYMPTOM)
1023 { 1019 {
1024 speed_reduce_from_disease = tmp->last_sp / 100.0; 1020 speed_reduce_from_disease = tmp->last_sp / 100.0;
1025 if (speed_reduce_from_disease == 0) 1021 if (speed_reduce_from_disease == 0)
1034 if (tmp->type != POTION) 1030 if (tmp->type != POTION)
1035 { 1031 {
1036 for (i = 0; i < NROFATTACKS; i++) 1032 for (i = 0; i < NROFATTACKS; i++)
1037 { 1033 {
1038 /* Potential for cursed potions, in which case we just can use 1034 /* Potential for cursed potions, in which case we just can use
1039 * a straight MAX, as potion_resist is initialized to zero. 1035 * a straight MAX, as potion_resist is initialised to zero.
1040 */ 1036 */
1041 if (tmp->type == POTION_EFFECT) 1037 if (tmp->type == POTION_EFFECT)
1042 { 1038 {
1043 if (potion_resist[i]) 1039 if (potion_resist[i])
1044 potion_resist[i] = MAX (potion_resist[i], tmp->resist[i]); 1040 potion_resist[i] = MAX (potion_resist[i], tmp->resist[i]);
1052 } 1048 }
1053 } 1049 }
1054 1050
1055 /* There may be other things that should not adjust the attacktype */ 1051 /* There may be other things that should not adjust the attacktype */
1056 if (tmp->type != BOW && tmp->type != SYMPTOM) 1052 if (tmp->type != BOW && tmp->type != SYMPTOM)
1057 op->attacktype |= tmp->attacktype; 1053 attacktype |= tmp->attacktype;
1058 1054
1059 op->path_attuned |= tmp->path_attuned; 1055 path_attuned |= tmp->path_attuned;
1060 op->path_repelled |= tmp->path_repelled; 1056 path_repelled |= tmp->path_repelled;
1061 op->path_denied |= tmp->path_denied; 1057 path_denied |= tmp->path_denied;
1062 op->stats.luck += tmp->stats.luck; 1058 stats.luck += tmp->stats.luck;
1063 op->move_type |= tmp->move_type; 1059 move_type |= tmp->move_type;
1064 1060
1065 if (QUERY_FLAG (tmp, FLAG_LIFESAVE)) 1061 if (QUERY_FLAG (tmp, FLAG_LIFESAVE )) SET_FLAG (this, FLAG_LIFESAVE);
1066 SET_FLAG (op, FLAG_LIFESAVE); 1062 if (QUERY_FLAG (tmp, FLAG_REFL_SPELL )) SET_FLAG (this, FLAG_REFL_SPELL);
1067 if (QUERY_FLAG (tmp, FLAG_REFL_SPELL)) 1063 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE)) SET_FLAG (this, FLAG_REFL_MISSILE);
1068 SET_FLAG (op, FLAG_REFL_SPELL); 1064 if (QUERY_FLAG (tmp, FLAG_STEALTH )) SET_FLAG (this, FLAG_STEALTH);
1069 if (QUERY_FLAG (tmp, FLAG_REFL_MISSILE)) 1065 if (QUERY_FLAG (tmp, FLAG_XRAYS )) SET_FLAG (this, FLAG_XRAYS);
1070 SET_FLAG (op, FLAG_REFL_MISSILE); 1066 if (QUERY_FLAG (tmp, FLAG_BLIND )) SET_FLAG (this, FLAG_BLIND);
1071 if (QUERY_FLAG (tmp, FLAG_STEALTH)) 1067 if (QUERY_FLAG (tmp, FLAG_SEE_IN_DARK )) SET_FLAG (this, FLAG_SEE_IN_DARK);
1072 SET_FLAG (op, FLAG_STEALTH);
1073 if (QUERY_FLAG (tmp, FLAG_XRAYS))
1074 SET_FLAG (op, FLAG_XRAYS);
1075 if (QUERY_FLAG (tmp, FLAG_BLIND))
1076 SET_FLAG (op, FLAG_BLIND);
1077 if (QUERY_FLAG (tmp, FLAG_SEE_IN_DARK))
1078 SET_FLAG (op, FLAG_SEE_IN_DARK);
1079 1068
1080 if (QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (&op->arch->clone, FLAG_UNDEAD)) 1069 if (QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (&arch->clone, FLAG_UNDEAD))
1081 SET_FLAG (op, FLAG_UNDEAD); 1070 SET_FLAG (this, FLAG_UNDEAD);
1082 1071
1083 if (QUERY_FLAG (tmp, FLAG_MAKE_INVIS)) 1072 if (QUERY_FLAG (tmp, FLAG_MAKE_INVIS))
1084 { 1073 {
1085 SET_FLAG (op, FLAG_MAKE_INVIS); 1074 SET_FLAG (this, FLAG_MAKE_INVIS);
1086 op->invisible = 1; 1075 invisible = 1;
1087 } 1076 }
1088 1077
1089 if (tmp->stats.exp && tmp->type != SKILL) 1078 if (tmp->stats.exp && tmp->type != SKILL)
1090 { 1079 {
1091 if (tmp->stats.exp > 0) 1080 if (tmp->stats.exp > 0)
1106 break; 1095 break;
1107 1096
1108 if (IS_COMBAT_SKILL (tmp->subtype)) 1097 if (IS_COMBAT_SKILL (tmp->subtype))
1109 wc_obj = tmp; 1098 wc_obj = tmp;
1110 1099
1111 if (op->chosen_skill) 1100 if (chosen_skill)
1112 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); 1101 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &name);
1113 1102
1114 op->chosen_skill = tmp; 1103 chosen_skill = tmp;
1115 1104
1116 if (tmp->stats.dam > 0) 1105 if (tmp->stats.dam > 0)
1117 { /* skill is a 'weapon' */ 1106 { /* skill is a 'weapon' */
1118 if (!QUERY_FLAG (op, FLAG_READY_WEAPON)) 1107 if (!QUERY_FLAG (this, FLAG_READY_WEAPON))
1119 weapon_speed = (int) WEAPON_SPEED (tmp); 1108 weapon_speed = (int) WEAPON_SPEED (tmp);
1109
1120 if (weapon_speed < 0) 1110 if (weapon_speed < 0)
1121 weapon_speed = 0; 1111 weapon_speed = 0;
1112
1122 weapon_weight = tmp->weight; 1113 weapon_weight = tmp->weight;
1123 op->stats.dam += tmp->stats.dam * (1 + (op->chosen_skill->level / 9)); 1114 stats.dam += tmp->stats.dam * (1 + (chosen_skill->level / 9));
1115
1124 if (tmp->magic) 1116 if (tmp->magic)
1125 op->stats.dam += tmp->magic; 1117 stats.dam += tmp->magic;
1126 } 1118 }
1127 1119
1128 if (tmp->stats.wc) 1120 if (tmp->stats.wc)
1129 wc -= (tmp->stats.wc + tmp->magic); 1121 wc -= (tmp->stats.wc + tmp->magic);
1130 1122
1131 if (tmp->slaying != NULL) 1123 if (tmp->slaying != NULL)
1132 op->slaying = tmp->slaying; 1124 slaying = tmp->slaying;
1133 1125
1134 if (tmp->stats.ac) 1126 if (tmp->stats.ac)
1135 ac -= (tmp->stats.ac + tmp->magic); 1127 ac -= (tmp->stats.ac + tmp->magic);
1128
1136 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1129 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1137 op->contr->encumbrance += (int) 3 *tmp->weight / 1000; 1130 contr->encumbrance += (int) 3 *tmp->weight / 1000;
1138 1131
1139 if (op->type == PLAYER) 1132 if (type == PLAYER)
1140 op->contr->ranges[range_skill] = op; 1133 contr->ranges[range_skill] = this;
1134
1141 break; 1135 break;
1142 1136
1143 case SKILL_TOOL: 1137 case SKILL_TOOL:
1144 if (op->chosen_skill) 1138 if (chosen_skill)
1145 {
1146 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); 1139 LOG (llevDebug, "fix_player, op %s has multiple skills applied\n", &name);
1147 } 1140
1148 op->chosen_skill = tmp; 1141 chosen_skill = tmp;
1142
1149 if (op->type == PLAYER) 1143 if (type == PLAYER)
1150 op->contr->ranges[range_skill] = op; 1144 contr->ranges[range_skill] = this;
1151 break; 1145 break;
1152 1146
1153 case SHIELD: 1147 case SHIELD:
1154 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1148 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1155 op->contr->encumbrance += (int) tmp->weight / 2000; 1149 contr->encumbrance += (int) tmp->weight / 2000;
1156 case RING: 1150 case RING:
1157 case AMULET: 1151 case AMULET:
1158 case GIRDLE: 1152 case GIRDLE:
1159 case HELMET: 1153 case HELMET:
1160 case BOOTS: 1154 case BOOTS:
1161 case GLOVES: 1155 case GLOVES:
1162 case CLOAK: 1156 case CLOAK:
1163 if (tmp->stats.wc) 1157 if (tmp->stats.wc)
1164 wc -= (tmp->stats.wc + tmp->magic); 1158 wc -= (tmp->stats.wc + tmp->magic);
1159
1165 if (tmp->stats.dam) 1160 if (tmp->stats.dam)
1166 op->stats.dam += (tmp->stats.dam + tmp->magic); 1161 stats.dam += (tmp->stats.dam + tmp->magic);
1162
1167 if (tmp->stats.ac) 1163 if (tmp->stats.ac)
1168 ac -= (tmp->stats.ac + tmp->magic); 1164 ac -= (tmp->stats.ac + tmp->magic);
1165
1169 break; 1166 break;
1170 1167
1171 case WEAPON: 1168 case WEAPON:
1172 wc -= (tmp->stats.wc + tmp->magic); 1169 wc -= (tmp->stats.wc + tmp->magic);
1170
1173 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0) 1171 if (tmp->stats.ac && tmp->stats.ac + tmp->magic > 0)
1174 ac -= tmp->stats.ac + tmp->magic; 1172 ac -= tmp->stats.ac + tmp->magic;
1173
1175 op->stats.dam += (tmp->stats.dam + tmp->magic); 1174 stats.dam += (tmp->stats.dam + tmp->magic);
1176 weapon_weight = tmp->weight; 1175 weapon_weight = tmp->weight;
1177 weapon_speed = ((int) WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2; 1176 weapon_speed = ((int) WEAPON_SPEED (tmp) * 2 - tmp->magic) / 2;
1177
1178 if (weapon_speed < 0) 1178 if (weapon_speed < 0)
1179 weapon_speed = 0; 1179 weapon_speed = 0;
1180
1180 op->slaying = tmp->slaying; 1181 slaying = tmp->slaying;
1181 /* If there is desire that two handed weapons should do 1182 /* If there is desire that two handed weapons should do
1182 * extra strength damage, this is where the code should 1183 * extra strength damage, this is where the code should
1183 * go. 1184 * go.
1184 */ 1185 */
1185 op->current_weapon = tmp; 1186 current_weapon = tmp;
1186 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1187 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1187 op->contr->encumbrance += (int) 3 *tmp->weight / 1000; 1188 contr->encumbrance += (int) 3 *tmp->weight / 1000;
1188 1189
1189 break; 1190 break;
1190 1191
1191 case ARMOUR: /* Only the best of these three are used: */ 1192 case ARMOUR: /* Only the best of these three are used: */
1192 if (settings.spell_encumbrance == TRUE && op->type == PLAYER) 1193 if (settings.spell_encumbrance == TRUE && type == PLAYER)
1193 op->contr->encumbrance += (int) tmp->weight / 1000; 1194 contr->encumbrance += (int) tmp->weight / 1000;
1194 1195
1195 case BRACERS: 1196 case BRACERS:
1196 case FORCE: 1197 case FORCE:
1197 if (tmp->stats.wc) 1198 if (tmp->stats.wc)
1198 { 1199 {
1202 best_wc = tmp->stats.wc + tmp->magic; 1203 best_wc = tmp->stats.wc + tmp->magic;
1203 } 1204 }
1204 else 1205 else
1205 wc += tmp->stats.wc + tmp->magic; 1206 wc += tmp->stats.wc + tmp->magic;
1206 } 1207 }
1208
1207 if (tmp->stats.ac) 1209 if (tmp->stats.ac)
1208 { 1210 {
1209 if (best_ac < tmp->stats.ac + tmp->magic) 1211 if (best_ac < tmp->stats.ac + tmp->magic)
1210 { 1212 {
1211 ac += best_ac; /* Remove last bonus */ 1213 ac += best_ac; /* Remove last bonus */
1212 best_ac = tmp->stats.ac + tmp->magic; 1214 best_ac = tmp->stats.ac + tmp->magic;
1213 } 1215 }
1214 else /* To nullify the below effect */ 1216 else /* To nullify the below effect */
1215 ac += tmp->stats.ac + tmp->magic; 1217 ac += tmp->stats.ac + tmp->magic;
1216 } 1218 }
1219
1217 if (tmp->stats.wc) 1220 if (tmp->stats.wc)
1218 wc -= (tmp->stats.wc + tmp->magic); 1221 wc -= (tmp->stats.wc + tmp->magic);
1222
1219 if (tmp->stats.ac) 1223 if (tmp->stats.ac)
1220 ac -= (tmp->stats.ac + tmp->magic); 1224 ac -= (tmp->stats.ac + tmp->magic);
1225
1221 if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.0 < max) 1226 if (ARMOUR_SPEED (tmp) && ARMOUR_SPEED (tmp) / 10.0 < max)
1222 max = ARMOUR_SPEED (tmp) / 10.0; 1227 max = ARMOUR_SPEED (tmp) / 10.0;
1228
1223 break; 1229 break;
1224 } /* switch tmp->type */ 1230 } /* switch tmp->type */
1225 } /* item is equipped */ 1231 } /* item is equipped */
1226 } /* for loop of items */ 1232 } /* for loop of items */
1227 1233
1235 * If there is a cursed (and no uncursed) potion in effect, we take 1241 * If there is a cursed (and no uncursed) potion in effect, we take
1236 * 'total resistance = vulnerability from cursed potion'. 1242 * 'total resistance = vulnerability from cursed potion'.
1237 */ 1243 */
1238 for (i = 0; i < NROFATTACKS; i++) 1244 for (i = 0; i < NROFATTACKS; i++)
1239 { 1245 {
1240 op->resist[i] = prot[i] - vuln[i]; 1246 resist[i] = prot[i] - vuln[i];
1247
1241 if (potion_resist[i] && ((potion_resist[i] > op->resist[i]) || (potion_resist[i] < 0))) 1248 if (potion_resist[i] && ((potion_resist[i] > resist[i]) || (potion_resist[i] < 0)))
1242 op->resist[i] = potion_resist[i]; 1249 resist[i] = potion_resist[i];
1243 } 1250 }
1244 1251
1245 /* Figure out the players sp/mana/hp totals. */ 1252 /* Figure out the players sp/mana/hp totals. */
1246 if (op->type == PLAYER) 1253 if (type == PLAYER)
1247 { 1254 {
1248 int pl_level; 1255 int pl_level;
1249 1256
1250 check_stat_bounds (&(op->stats)); 1257 check_stat_bounds (&(stats));
1251 pl_level = op->level; 1258 pl_level = level;
1252 1259
1253 if (pl_level < 1) 1260 if (pl_level < 1)
1254 pl_level = 1; /* safety, we should always get 1 levels worth of hp! */ 1261 pl_level = 1; /* safety, we should always get 1 levels worth of hp! */
1255 1262
1256 /* You basically get half a con bonus/level. But we do take into account rounding, 1263 /* You basically get half a con bonus/level. But we do take into account rounding,
1257 * so if your bonus is 7, you still get 7 worth of bonus every 2 levels. 1264 * so if your bonus is 7, you still get 7 worth of bonus every 2 levels.
1258 */ 1265 */
1259 for (i = 1, op->stats.maxhp = 0; i <= pl_level && i <= 10; i++) 1266 for (i = 1, stats.maxhp = 0; i <= pl_level && i <= 10; i++)
1260 { 1267 {
1261 j = op->contr->levhp[i] + con_bonus[op->stats.Con] / 2; 1268 j = contr->levhp[i] + con_bonus[stats.Con] / 2;
1269
1262 if (i % 2 && con_bonus[op->stats.Con] % 2) 1270 if (i % 2 && con_bonus[stats.Con] % 2)
1263 { 1271 {
1264 if (con_bonus[op->stats.Con] > 0) 1272 if (con_bonus[stats.Con] > 0)
1265 j++; 1273 j++;
1266 else 1274 else
1267 j--; 1275 j--;
1268 } 1276 }
1277
1269 op->stats.maxhp += j > 1 ? j : 1; /* always get at least 1 hp/level */ 1278 stats.maxhp += j > 1 ? j : 1; /* always get at least 1 hp/level */
1270 } 1279 }
1271 1280
1272 for (i = 11; i <= op->level; i++) 1281 for (i = 11; i <= level; i++)
1273 op->stats.maxhp += 2; 1282 stats.maxhp += 2;
1274 1283
1275 if (op->stats.hp > op->stats.maxhp) 1284 if (stats.hp > stats.maxhp)
1276 op->stats.hp = op->stats.maxhp; 1285 stats.hp = stats.maxhp;
1277 1286
1278 /* Sp gain is controlled by the level of the player's 1287 /* Sp gain is controlled by the level of the player's
1279 * relevant experience object (mana_obj, see above) 1288 * relevant experience object (mana_obj, see above)
1280 */ 1289 */
1281 /* following happen when skills system is not used */ 1290 /* following happen when skills system is not used */
1282 if (!mana_obj) 1291 if (!mana_obj)
1283 mana_obj = op; 1292 mana_obj = this;
1293
1284 if (!grace_obj) 1294 if (!grace_obj)
1285 grace_obj = op; 1295 grace_obj = this;
1296
1286 /* set maxsp */ 1297 /* set maxsp */
1287 if (!mana_obj || !mana_obj->level || op->type != PLAYER) 1298 if (!mana_obj || !mana_obj->level || type != PLAYER)
1288 mana_obj = op; 1299 mana_obj = this;
1289 1300
1290 if (mana_obj == op && op->type == PLAYER) 1301 if (mana_obj == this && type == PLAYER)
1291 {
1292 op->stats.maxsp = 1; 1302 stats.maxsp = 1;
1293 }
1294 else 1303 else
1295 { 1304 {
1296 sp_tmp = 0.0; 1305 sp_tmp = 0.0;
1306
1297 for (i = 1; i <= mana_obj->level && i <= 10; i++) 1307 for (i = 1; i <= mana_obj->level && i <= 10; i++)
1298 { 1308 {
1299 float stmp; 1309 float stmp;
1300 1310
1301 /* Got some extra bonus at first level */ 1311 /* Got some extra bonus at first level */
1302 if (i < 2) 1312 if (i < 2)
1303 {
1304 stmp = op->contr->levsp[i] + ((2.0 * (float) sp_bonus[op->stats.Pow] + (float) sp_bonus[op->stats.Int]) / 6.0); 1313 stmp = contr->levsp[i] + ((2.0 * (float) sp_bonus[stats.Pow] + (float) sp_bonus[stats.Int]) / 6.0);
1305 }
1306 else 1314 else
1307 {
1308 stmp = (float) op->contr->levsp[i] + (2.0 * (float) sp_bonus[op->stats.Pow] + (float) sp_bonus[op->stats.Int]) / 12.0; 1315 stmp = (float) contr->levsp[i] + (2.0 * (float) sp_bonus[stats.Pow] + (float) sp_bonus[stats.Int]) / 12.0;
1309 } 1316
1310 if (stmp < 1.0) 1317 if (stmp < 1.0)
1311 stmp = 1.0; 1318 stmp = 1.0;
1319
1312 sp_tmp += stmp; 1320 sp_tmp += stmp;
1313 } 1321 }
1322
1314 op->stats.maxsp = (int) sp_tmp; 1323 stats.maxsp = (int) sp_tmp;
1315 1324
1316 for (i = 11; i <= mana_obj->level; i++) 1325 for (i = 11; i <= mana_obj->level; i++)
1317 op->stats.maxsp += 2; 1326 stats.maxsp += 2;
1318 } 1327 }
1319 /* Characters can get their sp supercharged via rune of transferrance */ 1328 /* Characters can get their sp supercharged via rune of transferrance */
1320 if (op->stats.sp > op->stats.maxsp * 2) 1329 if (stats.sp > stats.maxsp * 2)
1321 op->stats.sp = op->stats.maxsp * 2; 1330 stats.sp = stats.maxsp * 2;
1322 1331
1323 /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */ 1332 /* set maxgrace, notice 3-4 lines below it depends on both Wis and Pow */
1324 if (!grace_obj || !grace_obj->level || op->type != PLAYER) 1333 if (!grace_obj || !grace_obj->level || type != PLAYER)
1325 grace_obj = op; 1334 grace_obj = this;
1326 1335
1327 if (grace_obj == op && op->type == PLAYER) 1336 if (grace_obj == this && type == PLAYER)
1328 {
1329 op->stats.maxgrace = 1; 1337 stats.maxgrace = 1;
1330 }
1331 else 1338 else
1332 { 1339 {
1333 /* store grace in a float - this way, the divisions below don't create 1340 /* store grace in a float - this way, the divisions below don't create
1334 * big jumps when you go from level to level - with int's, it then 1341 * big jumps when you go from level to level - with int's, it then
1335 * becomes big jumps when the sums of the bonuses jump to the next 1342 * becomes big jumps when the sums of the bonuses jump to the next
1336 * step of 8 - with floats, even fractional ones are useful. 1343 * step of 8 - with floats, even fractional ones are useful.
1337 */ 1344 */
1338 sp_tmp = 0.0; 1345 sp_tmp = 0.0;
1339 for (i = 1, op->stats.maxgrace = 0; i <= grace_obj->level && i <= 10; i++) 1346 for (i = 1, stats.maxgrace = 0; i <= grace_obj->level && i <= 10; i++)
1340 { 1347 {
1341 float grace_tmp = 0.0; 1348 float grace_tmp = 0.0;
1342 1349
1343 /* Got some extra bonus at first level */ 1350 /* Got some extra bonus at first level */
1344 if (i < 2) 1351 if (i < 2)
1345 {
1346 grace_tmp = op->contr->levgrace[i] + (((float) grace_bonus[op->stats.Pow] + 1352 grace_tmp = contr->levgrace[i] + (((float) grace_bonus[stats.Pow] +
1347 2.0 * (float) grace_bonus[op->stats.Wis]) / 6.0); 1353 2.0 * (float) grace_bonus[stats.Wis]) / 6.0);
1348 }
1349 else 1354 else
1350 {
1351 grace_tmp = (float) op->contr->levgrace[i] 1355 grace_tmp = (float) contr->levgrace[i]
1352 + ((float) grace_bonus[op->stats.Pow] + 2.0 * (float) grace_bonus[op->stats.Wis]) / 12.0; 1356 + ((float) grace_bonus[stats.Pow] + 2.0 * (float) grace_bonus[stats.Wis]) / 12.0;
1353 } 1357
1354 if (grace_tmp < 1.0) 1358 if (grace_tmp < 1.0)
1355 grace_tmp = 1.0; 1359 grace_tmp = 1.0;
1360
1356 sp_tmp += grace_tmp; 1361 sp_tmp += grace_tmp;
1357 } 1362 }
1363
1358 op->stats.maxgrace = (int) sp_tmp; 1364 stats.maxgrace = (int) sp_tmp;
1359 1365
1360 /* two grace points per level after 11 */ 1366 /* two grace points per level after 11 */
1361 for (i = 11; i <= grace_obj->level; i++) 1367 for (i = 11; i <= grace_obj->level; i++)
1362 op->stats.maxgrace += 2; 1368 stats.maxgrace += 2;
1363 } 1369 }
1364 /* No limit on grace vs maxgrace */ 1370 /* No limit on grace vs maxgrace */
1365 1371
1366 if (op->contr->braced) 1372 if (contr->braced)
1367 { 1373 {
1368 ac += 2; 1374 ac += 2;
1369 wc += 4; 1375 wc += 4;
1370 } 1376 }
1371 else 1377 else
1372 ac -= dex_bonus[op->stats.Dex]; 1378 ac -= dex_bonus[stats.Dex];
1373 1379
1374 /* In new exp/skills system, wc bonuses are related to 1380 /* In new exp/skills system, wc bonuses are related to
1375 * the players level in a relevant exp object (wc_obj) 1381 * the players level in a relevant exp object (wc_obj)
1376 * not the general player level -b.t. 1382 * not the general player level -b.t.
1377 * I changed this slightly so that wc bonuses are better 1383 * I changed this slightly so that wc bonuses are better
1381 * we give the player a bonus here in wc and dam 1387 * we give the player a bonus here in wc and dam
1382 * to make up for the change. Note that I left the 1388 * to make up for the change. Note that I left the
1383 * monster bonus the same as before. -b.t. 1389 * monster bonus the same as before. -b.t.
1384 */ 1390 */
1385 1391
1386 if (op->type == PLAYER && wc_obj && wc_obj->level > 1) 1392 if (type == PLAYER && wc_obj && wc_obj->level > 1)
1387 { 1393 {
1388 wc -= (wc_obj->level + thaco_bonus[op->stats.Str]); 1394 wc -= (wc_obj->level + thaco_bonus[stats.Str]);
1389 for (i = 1; i < wc_obj->level; i++) 1395 for (i = 1; i < wc_obj->level; i++)
1390 { 1396 {
1391 /* addtional wc every 6 levels */ 1397 /* addtional wc every 6 levels */
1392 if (!(i % 6)) 1398 if (!(i % 6))
1393 wc--; 1399 wc--;
1394 /* addtional dam every 4 levels. */ 1400 /* addtional dam every 4 levels. */
1395 if (!(i % 4) && (dam_bonus[op->stats.Str] >= 0)) 1401 if (!(i % 4) && (dam_bonus[stats.Str] >= 0))
1396 op->stats.dam += (1 + (dam_bonus[op->stats.Str] / 5)); 1402 stats.dam += (1 + (dam_bonus[stats.Str] / 5));
1397 } 1403 }
1398 } 1404 }
1399 else 1405 else
1400 wc -= (op->level + thaco_bonus[op->stats.Str]); 1406 wc -= (level + thaco_bonus[stats.Str]);
1401 1407
1402 op->stats.dam += dam_bonus[op->stats.Str]; 1408 stats.dam += dam_bonus[stats.Str];
1403 1409
1404 if (op->stats.dam < 1) 1410 if (stats.dam < 1)
1405 op->stats.dam = 1; 1411 stats.dam = 1;
1406 1412
1407 op->speed = 1.0 + speed_bonus[op->stats.Dex]; 1413 speed = 1.0 + speed_bonus[stats.Dex];
1414
1408 if (settings.search_items && op->contr->search_str[0]) 1415 if (settings.search_items && contr->search_str[0])
1409 op->speed -= 1; 1416 speed -= 1;
1417
1410 if (op->attacktype == 0) 1418 if (attacktype == 0)
1411 op->attacktype = op->arch->clone.attacktype; 1419 attacktype = arch->clone.attacktype;
1412 1420
1413 } /* End if player */ 1421 } /* End if player */
1414 1422
1415 if (added_speed >= 0) 1423 if (added_speed >= 0)
1416 op->speed += added_speed / 10.0; 1424 speed += added_speed / 10.0;
1417 else /* Something wrong here...: */ 1425 else /* Something wrong here...: */
1418 op->speed /= (float) (1.0 - added_speed); 1426 speed /= (float) (1.0 - added_speed);
1419 1427
1420 /* Max is determined by armour */ 1428 /* Max is determined by armour */
1421 if (op->speed > max) 1429 if (speed > max)
1422 op->speed = max; 1430 speed = max;
1423 1431
1424 if (op->type == PLAYER) 1432 if (type == PLAYER)
1425 { 1433 {
1426 /* f is a number the represents the number of kg above (positive num) 1434 /* f is a number the represents the number of kg above (positive num)
1427 * or below (negative number) that the player is carrying. If above 1435 * or below (negative number) that the player is carrying. If above
1428 * weight limit, then player suffers a speed reduction based on how 1436 * weight limit, then player suffers a speed reduction based on how
1429 * much above he is, and what is max carry is 1437 * much above he is, and what is max carry is
1430 */ 1438 */
1431 f = (op->carrying / 1000) - max_carry[op->stats.Str]; 1439 f = (carrying / 1000) - max_carry[stats.Str];
1432 if (f > 0) 1440 if (f > 0)
1433 op->speed = op->speed / (1.0 + f / max_carry[op->stats.Str]); 1441 speed = speed / (1.0 + f / max_carry[stats.Str]);
1434 } 1442 }
1435 1443
1436 op->speed += bonus_speed / 10.0; /* Not affected by limits */ 1444 speed += bonus_speed / 10.0; /* Not affected by limits */
1437 1445
1438 /* Put a lower limit on speed. Note with this speed, you move once every 1446 /* Put a lower limit on speed. Note with this speed, you move once every
1439 * 100 ticks or so. This amounts to once every 12 seconds of realtime. 1447 * 100 ticks or so. This amounts to once every 12 seconds of realtime.
1440 */ 1448 */
1441 op->speed = op->speed * speed_reduce_from_disease; 1449 speed = speed * speed_reduce_from_disease;
1442 1450
1443 if (op->speed < 0.01 && op->type == PLAYER) 1451 if (speed < 0.01 && type == PLAYER)
1444 op->speed = 0.01; 1452 speed = 0.01;
1445 1453
1446 if (op->type == PLAYER) 1454 if (type == PLAYER)
1447 { 1455 {
1448 float M, W, s, D, K, S, M2; 1456 float M, W, s, D, K, S, M2;
1449 1457
1450 /* (This formula was made by vidarl@ifi.uio.no) 1458 /* (This formula was made by vidarl@ifi.uio.no)
1451 * Note that we never used these values again - basically 1459 * Note that we never used these values again - basically
1452 * all of these could be subbed into one big equation, but 1460 * all of these could be subbed into one big equation, but
1453 * that would just be a real pain to read. 1461 * that would just be a real pain to read.
1454 */ 1462 */
1455 M = (max_carry[op->stats.Str] - 121) / 121.0; 1463 M = (max_carry[stats.Str] - 121) / 121.0;
1456 M2 = max_carry[op->stats.Str] / 100.0; 1464 M2 = max_carry[stats.Str] / 100.0;
1457 W = weapon_weight / 20000.0; 1465 W = weapon_weight / 20000.0;
1458 s = 2 - weapon_speed / 10.0; 1466 s = 2 - weapon_speed / 10.0;
1459 D = (op->stats.Dex - 14) / 14.0; 1467 D = (stats.Dex - 14) / 14.0;
1460 K = 1 + M / 3.0 - W / (3 * M2) + op->speed / 5.0 + D / 2.0; 1468 K = 1 + M / 3.0 - W / (3 * M2) + speed / 5.0 + D / 2.0;
1461 K *= (4 + op->level) / (float) (6 + op->level) * 1.2; 1469 K *= (4 + level) / (float) (6 + level) * 1.2;
1462 if (K <= 0) 1470 if (K <= 0)
1463 K = 0.01; 1471 K = 0.01;
1464 S = op->speed / (K * s); 1472 S = speed / (K * s);
1465 op->contr->weapon_sp = S; 1473 contr->weapon_sp = S;
1466 } 1474 }
1475
1467 /* I want to limit the power of small monsters with big weapons: */ 1476 /* I want to limit the power of small monsters with big weapons: */
1468 if (op->type != PLAYER && op->arch != NULL && op->stats.dam > op->arch->clone.stats.dam * 3) 1477 if (type != PLAYER && arch != NULL && stats.dam > arch->clone.stats.dam * 3)
1469 op->stats.dam = op->arch->clone.stats.dam * 3; 1478 stats.dam = arch->clone.stats.dam * 3;
1470 1479
1471 /* Prevent overflows of wc - best you can get is ABS(120) - this 1480 /* Prevent overflows of wc - best you can get is ABS(120) - this
1472 * should be more than enough - remember, AC is also in 8 bits, 1481 * should be more than enough - remember, AC is also in 8 bits,
1473 * so its value is the same. 1482 * so its value is the same.
1474 */ 1483 */
1475 if (wc > 120) 1484 if (wc > 120)
1476 wc = 120; 1485 wc = 120;
1477 else if (wc < -120) 1486 else if (wc < -120)
1478 wc = -120; 1487 wc = -120;
1488
1479 op->stats.wc = wc; 1489 stats.wc = wc;
1480 1490
1481 if (ac > 120) 1491 if (ac > 120)
1482 ac = 120; 1492 ac = 120;
1483 else if (ac < -120) 1493 else if (ac < -120)
1484 ac = -120; 1494 ac = -120;
1495
1485 op->stats.ac = ac; 1496 stats.ac = ac;
1486 1497
1487 /* if for some reason the creature doesn't have any move type, 1498 /* if for some reason the creature doesn't have any move type,
1488 * give them walking as a default. 1499 * give them walking as a default.
1489 * The second case is a special case - to more closely mimic the 1500 * The second case is a special case - to more closely mimic the
1490 * old behaviour - if your flying, your not walking - just 1501 * old behaviour - if your flying, your not walking - just
1491 * one or the other. 1502 * one or the other.
1492 */ 1503 */
1493 if (op->move_type == 0) 1504 if (move_type == 0)
1494 op->move_type = MOVE_WALK; 1505 move_type = MOVE_WALK;
1495 else if (op->move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH)) 1506 else if (move_type & (MOVE_FLY_LOW | MOVE_FLY_HIGH))
1496 op->move_type &= ~MOVE_WALK; 1507 move_type &= ~MOVE_WALK;
1497 1508
1498 update_ob_speed (op); 1509 if (speed != old_speed)
1510 set_speed (speed);
1499 1511
1500 /* It is quite possible that a player's spell costing might have changed, 1512 /* It is quite possible that a player's spell costing might have changed,
1501 * so we will check that now. 1513 * so we will check that now.
1502 */ 1514 */
1503 if (op->type == PLAYER) 1515 if (type == PLAYER)
1516 {
1517 esrv_update_stats (contr);
1504 esrv_update_spells (op->contr); 1518 esrv_update_spells (contr);
1519 }
1505} 1520}
1506 1521
1507/* 1522/*
1508 * Returns true if the given player is a legal class. 1523 * Returns true if the given player is a legal class.
1509 * The function to add and remove class-bonuses to the stats doesn't 1524 * The function to add and remove class-bonuses to the stats doesn't
1510 * check if the stat becomes negative, thus this function 1525 * check if the stat becomes negative, thus this function
1511 * merely checks that all stats are 1 or more, and returns 1526 * merely checks that all stats are 1 or more, and returns
1512 * false otherwise. 1527 * false otherwise.
1513 */ 1528 */
1514
1515int 1529int
1516allowed_class (const object *op) 1530allowed_class (const object *op)
1517{ 1531{
1518 return op->stats.Dex > 0 && op->stats.Str > 0 && op->stats.Con > 0 && 1532 return op->stats.Dex > 0 && op->stats.Str > 0 && op->stats.Con > 0 &&
1519 op->stats.Int > 0 && op->stats.Wis > 0 && op->stats.Pow > 0 && op->stats.Cha > 0; 1533 op->stats.Int > 0 && op->stats.Wis > 0 && op->stats.Pow > 0 && op->stats.Cha > 0;
1665 */ 1679 */
1666 CLEAR_FLAG (skill_obj, FLAG_CAN_USE_SKILL); 1680 CLEAR_FLAG (skill_obj, FLAG_CAN_USE_SKILL);
1667 skill_obj->stats.exp = 0; 1681 skill_obj->stats.exp = 0;
1668 skill_obj->level = 1; 1682 skill_obj->level = 1;
1669 insert_ob_in_ob (skill_obj, op); 1683 insert_ob_in_ob (skill_obj, op);
1684
1670 if (op->contr) 1685 if (op->contr)
1671 { 1686 {
1672 op->contr->last_skill_ob[skill_obj->subtype] = skill_obj; 1687 op->contr->last_skill_ob [skill_obj->subtype] = skill_obj;
1673 op->contr->last_skill_exp[skill_obj->subtype] = -1; 1688 if (op->contr->ns)
1689 op->contr->ns->last_skill_exp[skill_obj->subtype] = -1;//TODO: should be made superfluous
1674 } 1690 }
1691
1675 return skill_obj; 1692 return skill_obj;
1676} 1693}
1677 1694
1678 1695
1679/* player_lvl_adj() - for the new exp system. we are concerned with 1696/* player_lvl_adj() - for the new exp system. we are concerned with
1704 who->contr->levhp[who->level] = die_roll (2, 4, who, PREFER_HIGH) + 1; 1721 who->contr->levhp[who->level] = die_roll (2, 4, who, PREFER_HIGH) + 1;
1705 who->contr->levsp[who->level] = die_roll (2, 3, who, PREFER_HIGH); 1722 who->contr->levsp[who->level] = die_roll (2, 3, who, PREFER_HIGH);
1706 who->contr->levgrace[who->level] = die_roll (2, 2, who, PREFER_HIGH) - 1; 1723 who->contr->levgrace[who->level] = die_roll (2, 2, who, PREFER_HIGH) - 1;
1707 } 1724 }
1708 1725
1709 fix_player (who); 1726 who->update_stats ();
1710 if (op->level > 1) 1727 if (op->level > 1)
1711 { 1728 {
1712 if (op->type != PLAYER) 1729 if (op->type != PLAYER)
1713 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); 1730 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name);
1714 else 1731 else
1719 player_lvl_adj (who, op); /* To increase more levels */ 1736 player_lvl_adj (who, op); /* To increase more levels */
1720 } 1737 }
1721 else if (op->level > 1 && op->stats.exp < level_exp (op->level, who->expmul)) 1738 else if (op->level > 1 && op->stats.exp < level_exp (op->level, who->expmul))
1722 { 1739 {
1723 op->level--; 1740 op->level--;
1724 fix_player (who); 1741 who->update_stats ();
1725 if (op->type != PLAYER) 1742 if (op->type != PLAYER)
1726 { 1743 {
1727 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name); 1744 sprintf (buf, "You are now level %d in the %s skill.", op->level, &op->name);
1728 new_draw_info (NDI_UNIQUE | NDI_RED, 0, who, buf); 1745 new_draw_info (NDI_UNIQUE | NDI_RED, 0, who, buf);
1729 } 1746 }
1730 player_lvl_adj (who, op); /* To decrease more levels */ 1747 player_lvl_adj (who, op); /* To decrease more levels */
1731 } 1748 }
1749
1732 /* check if the spell data has changed */ 1750 /* check if the spell data has changed */
1751 esrv_update_stats (who->contr);
1733 esrv_update_spells (who->contr); 1752 esrv_update_spells (who->contr);
1734} 1753}
1735 1754
1736/* 1755/*
1737 * Returns how much experience is needed for a player to become 1756 * Returns how much experience is needed for a player to become
1771 op->perm_exp = 0; 1790 op->perm_exp = 0;
1772 else if (op->perm_exp > (sint64) MAX_EXPERIENCE) 1791 else if (op->perm_exp > (sint64) MAX_EXPERIENCE)
1773 op->perm_exp = MAX_EXPERIENCE; 1792 op->perm_exp = MAX_EXPERIENCE;
1774} 1793}
1775 1794
1776
1777/* Add experience to a player - exp should only be positive. 1795/* Add experience to a player - exp should only be positive.
1778 * Updates permanent exp for the skill we are adding to. 1796 * Updates permanent exp for the skill we are adding to.
1779 * skill_name is the skill to add exp to. Skill name can be 1797 * skill_name is the skill to add exp to. Skill name can be
1780 * NULL, in which case exp increases the players general 1798 * NULL, in which case exp increases the players general
1781 * total, but not any particular skill. 1799 * total, but not any particular skill.
1782 * flag is what to do if the player doesn't have the skill: 1800 * flag is what to do if the player doesn't have the skill:
1783 */ 1801 */
1784
1785static void 1802static void
1786add_player_exp (object *op, sint64 exp, const char *skill_name, int flag) 1803add_player_exp (object *op, sint64 exp, const char *skill_name, int flag)
1787{ 1804{
1788 object *skill_obj = NULL; 1805 object *skill_obj = NULL;
1789 sint64 limit, exp_to_add; 1806 sint64 limit, exp_to_add;
1959void 1976void
1960change_exp (object *op, sint64 exp, const char *skill_name, int flag) 1977change_exp (object *op, sint64 exp, const char *skill_name, int flag)
1961{ 1978{
1962 1979
1963#ifdef EXP_DEBUG 1980#ifdef EXP_DEBUG
1964# ifndef WIN32
1965 LOG (llevDebug, "change_exp() called for %s, exp = %lld\n", query_name (op), exp);
1966# else
1967 LOG (llevDebug, "change_exp() called for %s, exp = %I64d\n", query_name (op), exp); 1981 LOG (llevDebug, "change_exp() called for %s, exp = %" PRId64 "\n", query_name (op), exp);
1968# endif
1969#endif 1982#endif
1970 1983
1971 /* safety */ 1984 /* safety */
1972 if (!op) 1985 if (!op)
1973 { 1986 {
2076 if (level > MAX_SAVE_LEVEL) 2089 if (level > MAX_SAVE_LEVEL)
2077 level = MAX_SAVE_LEVEL; 2090 level = MAX_SAVE_LEVEL;
2078 2091
2079 if ((random_roll (1, 20, op, PREFER_HIGH) + bonus) < savethrow[level]) 2092 if ((random_roll (1, 20, op, PREFER_HIGH) + bonus) < savethrow[level])
2080 return 0; 2093 return 0;
2094
2081 return 1; 2095 return 1;
2082} 2096}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines