1 | /* |
1 | /* |
2 | * static char *rcsid_living_c = |
2 | * static char *rcsid_living_c = |
3 | * "$Id: living.C,v 1.4 2006/09/01 17:16:47 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 | |
… | |
… | |
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 | */ |
371 | int change_abil(object *op, object *tmp) { |
371 | int 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++) { |
… | |
… | |
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); |
|
|
505 | op->race=add_string("undead"); |
503 | op->race = "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); |
|
|
509 | if(op->arch->clone.race) |
|
|
510 | op->race=add_string(op->arch->clone.race); |
506 | op->race = 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)){ |
… | |
… | |
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 | |
769 | void fix_player(object *op) { |
763 | void 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; |
… | |
… | |
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) { |
|
|
806 | free_string(op->slaying); |
|
|
807 | op->slaying=NULL; |
798 | op->slaying = 0; |
808 | } |
799 | |
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 | |
… | |
… | |
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); |
… | |
… | |
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) |
|
|
1032 | free_string (op->slaying); |
|
|
1033 | add_refcount(op->slaying = tmp->slaying); |
1022 | 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; |
… | |
… | |
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; |
… | |
… | |
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) { |
|
|
1080 | if (op->slaying != NULL) |
|
|
1081 | free_string (op->slaying); |
|
|
1082 | add_refcount(op->slaying = tmp->slaying); |
1067 | 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 | op->current_weapon = tmp; |
1072 | op->current_weapon = tmp; |
… | |
… | |
1547 | } |
1531 | } |
1548 | |
1532 | |
1549 | fix_player(who); |
1533 | fix_player(who); |
1550 | if(op->level>1) { |
1534 | if(op->level>1) { |
1551 | if (op->type!=PLAYER) |
1535 | if (op->type!=PLAYER) |
1552 | 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); |
1553 | else |
1537 | else |
1554 | sprintf(buf,"You are now level %d.",op->level); |
1538 | sprintf(buf,"You are now level %d.",op->level); |
1555 | 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); |
1556 | } |
1540 | } |
1557 | player_lvl_adj(who,op); /* To increase more levels */ |
1541 | player_lvl_adj(who,op); /* To increase more levels */ |
1558 | } 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)) { |
1559 | op->level--; |
1543 | op->level--; |
1560 | fix_player(who); |
1544 | fix_player(who); |
1561 | if(op->type!=PLAYER) { |
1545 | if(op->type!=PLAYER) { |
1562 | 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); |
1563 | new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); |
1547 | new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); |
1564 | } |
1548 | } |
1565 | player_lvl_adj(who,op); /* To decrease more levels */ |
1549 | player_lvl_adj(who,op); /* To decrease more levels */ |
1566 | } |
1550 | } |
1567 | /* check if the spell data has changed */ |
1551 | /* check if the spell data has changed */ |
… | |
… | |
1599 | op->perm_exp = p_exp_min; |
1583 | op->perm_exp = p_exp_min; |
1600 | |
1584 | |
1601 | /* Cap permanent experience. */ |
1585 | /* Cap permanent experience. */ |
1602 | if (op->perm_exp < 0) |
1586 | if (op->perm_exp < 0) |
1603 | op->perm_exp = 0; |
1587 | op->perm_exp = 0; |
1604 | else if (op->perm_exp > MAX_EXPERIENCE) |
1588 | else if (op->perm_exp > (sint64) MAX_EXPERIENCE) |
1605 | op->perm_exp = MAX_EXPERIENCE; |
1589 | op->perm_exp = MAX_EXPERIENCE; |
1606 | } |
1590 | } |
1607 | |
1591 | |
1608 | |
1592 | |
1609 | /* Add experience to a player - exp should only be positive. |
1593 | /* Add experience to a player - exp should only be positive. |
… | |
… | |
1722 | } |
1706 | } |
1723 | |
1707 | |
1724 | sint64 check_exp_adjust(const object *op, sint64 exp) |
1708 | sint64 check_exp_adjust(const object *op, sint64 exp) |
1725 | { |
1709 | { |
1726 | if (exp<0) return check_exp_loss(op, exp); |
1710 | if (exp<0) return check_exp_loss(op, exp); |
1727 | else return MIN(exp, MAX_EXPERIENCE - op->stats.exp); |
1711 | else return MIN(exp, (sint64) MAX_EXPERIENCE - op->stats.exp); |
1728 | } |
1712 | } |
1729 | |
1713 | |
1730 | |
1714 | |
1731 | /* Subtracts experience from player. |
1715 | /* Subtracts experience from player. |
1732 | * 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 |
… | |
… | |
1812 | |
1796 | |
1813 | /* reset exp to max allowed value. We subtract from |
1797 | /* reset exp to max allowed value. We subtract from |
1814 | * MAX_EXPERIENCE to prevent overflows. If the player somehow has |
1798 | * MAX_EXPERIENCE to prevent overflows. If the player somehow has |
1815 | * more than max exp, just return. |
1799 | * more than max exp, just return. |
1816 | */ |
1800 | */ |
1817 | if (exp > 0 && ( op->stats.exp > (MAX_EXPERIENCE - exp))) { |
1801 | if (exp > 0 && ( op->stats.exp > (sint64) (MAX_EXPERIENCE - exp))) { |
1818 | exp = MAX_EXPERIENCE - op->stats.exp; |
1802 | exp = MAX_EXPERIENCE - op->stats.exp; |
1819 | if (exp < 0) return; |
1803 | if (exp < 0) return; |
1820 | } |
1804 | } |
1821 | |
1805 | |
1822 | op->stats.exp += exp; |
1806 | op->stats.exp += exp; |