1 | /* |
1 | /* |
2 | * static char *rcsid_living_c = |
2 | * static char *rcsid_living_c = |
3 | * "$Id: living.C,v 1.3 2006/08/29 08:01:35 root Exp $"; |
3 | * "$Id: living.C,v 1.5 2006/09/03 00:18:40 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
499 | */ |
499 | */ |
500 | if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) |
500 | if(!QUERY_FLAG(&op->arch->clone,FLAG_UNDEAD)) |
501 | if ( QUERY_FLAG(op,FLAG_UNDEAD) != QUERY_FLAG(&refop,FLAG_UNDEAD)) { |
501 | if ( QUERY_FLAG(op,FLAG_UNDEAD) != QUERY_FLAG(&refop,FLAG_UNDEAD)) { |
502 | success=1; |
502 | success=1; |
503 | if(flag>0) { |
503 | if(flag>0) { |
504 | if(op->race) free_string(op->race); |
|
|
505 | op->race=add_string("undead"); |
504 | op->race = "undead"; |
506 | new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce drains away!"); |
505 | new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce drains away!"); |
507 | } else { |
506 | } else { |
508 | if(op->race) free_string(op->race); |
|
|
509 | if(op->arch->clone.race) |
|
|
510 | op->race=add_string(op->arch->clone.race); |
507 | op->race = op->arch->clone.race; |
511 | else |
|
|
512 | op->race = NULL; |
|
|
513 | new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce returns!"); |
508 | new_draw_info(NDI_UNIQUE, 0, op,"Your lifeforce returns!"); |
514 | } |
509 | } |
515 | } |
510 | } |
516 | |
511 | |
517 | if ( QUERY_FLAG(op,FLAG_STEALTH) != QUERY_FLAG(&refop,FLAG_STEALTH)){ |
512 | if ( QUERY_FLAG(op,FLAG_STEALTH) != QUERY_FLAG(&refop,FLAG_STEALTH)){ |
… | |
… | |
766 | spell system split, grace points now added to system --peterm |
761 | spell system split, grace points now added to system --peterm |
767 | */ |
762 | */ |
768 | |
763 | |
769 | void fix_player(object *op) { |
764 | void fix_player(object *op) { |
770 | int i,j; |
765 | int i,j; |
771 | event *evt; |
|
|
772 | float f,max=9,added_speed=0,bonus_speed=0, sp_tmp,speed_reduce_from_disease=1; |
766 | float f,max=9,added_speed=0,bonus_speed=0, sp_tmp,speed_reduce_from_disease=1; |
773 | int weapon_weight=0,weapon_speed=0; |
767 | int weapon_weight=0,weapon_speed=0; |
774 | int best_wc=0, best_ac=0, wc=0, ac=0; |
768 | int best_wc=0, best_ac=0, wc=0, ac=0; |
775 | int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; |
769 | int prot[NROFATTACKS], vuln[NROFATTACKS], potion_resist[NROFATTACKS]; |
776 | object *grace_obj=NULL,*mana_obj=NULL,*wc_obj=NULL,*tmp; |
770 | object *grace_obj=NULL,*mana_obj=NULL,*wc_obj=NULL,*tmp; |
… | |
… | |
800 | op->contr->ranges[range_misc] = NULL; |
794 | op->contr->ranges[range_misc] = NULL; |
801 | op->contr->ranges[range_skill] = NULL; |
795 | op->contr->ranges[range_skill] = NULL; |
802 | } |
796 | } |
803 | memcpy(op->body_used, op->body_info, sizeof(op->body_info)); |
797 | memcpy(op->body_used, op->body_info, sizeof(op->body_info)); |
804 | |
798 | |
805 | if(op->slaying!=NULL) { |
|
|
806 | free_string(op->slaying); |
|
|
807 | op->slaying=NULL; |
799 | op->slaying = 0; |
808 | } |
800 | |
809 | if(!QUERY_FLAG(op,FLAG_WIZ)) { |
801 | if(!QUERY_FLAG(op,FLAG_WIZ)) { |
810 | CLEAR_FLAG(op, FLAG_XRAYS); |
802 | CLEAR_FLAG(op, FLAG_XRAYS); |
811 | CLEAR_FLAG(op, FLAG_MAKE_INVIS); |
803 | CLEAR_FLAG(op, FLAG_MAKE_INVIS); |
812 | } |
804 | } |
813 | |
805 | |
… | |
… | |
1011 | if (!QUERY_FLAG(tmp,FLAG_APPLIED)) break; |
1003 | if (!QUERY_FLAG(tmp,FLAG_APPLIED)) break; |
1012 | |
1004 | |
1013 | if (IS_COMBAT_SKILL(tmp->subtype)) wc_obj=tmp; |
1005 | if (IS_COMBAT_SKILL(tmp->subtype)) wc_obj=tmp; |
1014 | |
1006 | |
1015 | if (op->chosen_skill) { |
1007 | if (op->chosen_skill) { |
1016 | LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", op->name); |
1008 | LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); |
1017 | } |
1009 | } |
1018 | op->chosen_skill = tmp; |
1010 | op->chosen_skill = tmp; |
1019 | if(tmp->stats.dam>0) { /* skill is a 'weapon' */ |
1011 | if(tmp->stats.dam>0) { /* skill is a 'weapon' */ |
1020 | if(!QUERY_FLAG(op,FLAG_READY_WEAPON)) |
1012 | if(!QUERY_FLAG(op,FLAG_READY_WEAPON)) |
1021 | weapon_speed = (int) WEAPON_SPEED(tmp); |
1013 | weapon_speed = (int) WEAPON_SPEED(tmp); |
… | |
… | |
1025 | if(tmp->magic) op->stats.dam += tmp->magic; |
1017 | if(tmp->magic) op->stats.dam += tmp->magic; |
1026 | } |
1018 | } |
1027 | if(tmp->stats.wc) |
1019 | if(tmp->stats.wc) |
1028 | wc-=(tmp->stats.wc+tmp->magic); |
1020 | wc-=(tmp->stats.wc+tmp->magic); |
1029 | |
1021 | |
1030 | if(tmp->slaying!=NULL) { |
1022 | if (tmp->slaying!=NULL) |
1031 | if (op->slaying != NULL) |
|
|
1032 | free_string (op->slaying); |
|
|
1033 | add_refcount(op->slaying = tmp->slaying); |
1023 | op->slaying = tmp->slaying; |
1034 | } |
|
|
1035 | |
1024 | |
1036 | if(tmp->stats.ac) |
1025 | if(tmp->stats.ac) |
1037 | ac-=(tmp->stats.ac+tmp->magic); |
1026 | ac-=(tmp->stats.ac+tmp->magic); |
1038 | if(settings.spell_encumbrance == TRUE && op->type==PLAYER) |
1027 | if(settings.spell_encumbrance == TRUE && op->type==PLAYER) |
1039 | op->contr->encumbrance+=(int)3*tmp->weight/1000; |
1028 | op->contr->encumbrance+=(int)3*tmp->weight/1000; |
… | |
… | |
1041 | op->contr->ranges[range_skill] = op; |
1030 | op->contr->ranges[range_skill] = op; |
1042 | break; |
1031 | break; |
1043 | |
1032 | |
1044 | case SKILL_TOOL: |
1033 | case SKILL_TOOL: |
1045 | if (op->chosen_skill) { |
1034 | if (op->chosen_skill) { |
1046 | LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", op->name); |
1035 | LOG(llevDebug, "fix_player, op %s has multiple skills applied\n", &op->name); |
1047 | } |
1036 | } |
1048 | op->chosen_skill = tmp; |
1037 | op->chosen_skill = tmp; |
1049 | if (op->type == PLAYER) |
1038 | if (op->type == PLAYER) |
1050 | op->contr->ranges[range_skill] = op; |
1039 | op->contr->ranges[range_skill] = op; |
1051 | break; |
1040 | break; |
… | |
… | |
1074 | ac-=tmp->stats.ac+tmp->magic; |
1063 | ac-=tmp->stats.ac+tmp->magic; |
1075 | op->stats.dam+=(tmp->stats.dam+tmp->magic); |
1064 | op->stats.dam+=(tmp->stats.dam+tmp->magic); |
1076 | weapon_weight=tmp->weight; |
1065 | weapon_weight=tmp->weight; |
1077 | weapon_speed=((int)WEAPON_SPEED(tmp)*2-tmp->magic)/2; |
1066 | weapon_speed=((int)WEAPON_SPEED(tmp)*2-tmp->magic)/2; |
1078 | if(weapon_speed<0) weapon_speed=0; |
1067 | if(weapon_speed<0) weapon_speed=0; |
1079 | if(tmp->slaying!=NULL) { |
|
|
1080 | if (op->slaying != NULL) |
|
|
1081 | free_string (op->slaying); |
|
|
1082 | add_refcount(op->slaying = tmp->slaying); |
1068 | op->slaying = tmp->slaying; |
1083 | } |
|
|
1084 | /* If there is desire that two handed weapons should do |
1069 | /* If there is desire that two handed weapons should do |
1085 | * extra strength damage, this is where the code should |
1070 | * extra strength damage, this is where the code should |
1086 | * go. |
1071 | * go. |
1087 | */ |
1072 | */ |
1088 | op->current_weapon = tmp; |
1073 | op->current_weapon = tmp; |
… | |
… | |
1547 | } |
1532 | } |
1548 | |
1533 | |
1549 | fix_player(who); |
1534 | fix_player(who); |
1550 | if(op->level>1) { |
1535 | if(op->level>1) { |
1551 | if (op->type!=PLAYER) |
1536 | if (op->type!=PLAYER) |
1552 | sprintf(buf,"You are now level %d in the %s skill.",op->level,op->name); |
1537 | sprintf(buf,"You are now level %d in the %s skill.",op->level,&op->name); |
1553 | else |
1538 | else |
1554 | sprintf(buf,"You are now level %d.",op->level); |
1539 | sprintf(buf,"You are now level %d.",op->level); |
1555 | if(who) new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); |
1540 | if(who) new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); |
1556 | } |
1541 | } |
1557 | player_lvl_adj(who,op); /* To increase more levels */ |
1542 | player_lvl_adj(who,op); /* To increase more levels */ |
1558 | } else if (op->level>1 && op->stats.exp<level_exp(op->level,who->expmul)) { |
1543 | } else if (op->level>1 && op->stats.exp<level_exp(op->level,who->expmul)) { |
1559 | op->level--; |
1544 | op->level--; |
1560 | fix_player(who); |
1545 | fix_player(who); |
1561 | if(op->type!=PLAYER) { |
1546 | if(op->type!=PLAYER) { |
1562 | sprintf(buf,"You are now level %d in the %s skill.",op->level,op->name); |
1547 | sprintf(buf,"You are now level %d in the %s skill.",op->level,&op->name); |
1563 | new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); |
1548 | new_draw_info(NDI_UNIQUE|NDI_RED, 0, who,buf); |
1564 | } |
1549 | } |
1565 | player_lvl_adj(who,op); /* To decrease more levels */ |
1550 | player_lvl_adj(who,op); /* To decrease more levels */ |
1566 | } |
1551 | } |
1567 | /* check if the spell data has changed */ |
1552 | /* check if the spell data has changed */ |
… | |
… | |
1612 | * NULL, in which case exp increases the players general |
1597 | * NULL, in which case exp increases the players general |
1613 | * total, but not any particular skill. |
1598 | * total, but not any particular skill. |
1614 | * flag is what to do if the player doesn't have the skill: |
1599 | * flag is what to do if the player doesn't have the skill: |
1615 | */ |
1600 | */ |
1616 | |
1601 | |
1617 | static void add_player_exp(object *op, sint64 exp, const char *skill_name, int flag) |
1602 | static void add_player_exp (object * op, sint64 exp, const char *skill_name, int flag) |
1618 | { |
1603 | { |
1619 | object *skill_obj=NULL; |
1604 | object *skill_obj = NULL; |
1620 | sint64 limit, exp_to_add; |
1605 | sint64 limit, exp_to_add; |
1621 | int i; |
1606 | int i; |
1622 | |
1607 | |
1623 | /* prevents some forms of abuse. */ |
1608 | /* prevents some forms of abuse. */ |
1624 | if(op->contr->braced) exp=exp/5; |
1609 | if (op->contr->braced) |
|
|
1610 | exp = exp / 5; |
1625 | |
1611 | |
1626 | /* Try to find the matching skill. |
1612 | /* Try to find the matching skill. |
1627 | * We do a shortcut/time saving mechanism first - see if it matches |
1613 | * We do a shortcut/time saving mechanism first - see if it matches |
1628 | * chosen_skill. This means we don't need to search through |
1614 | * chosen_skill. This means we don't need to search through |
1629 | * the players inventory. |
1615 | * the players inventory. |
1630 | */ |
1616 | */ |
1631 | if (skill_name) { |
1617 | if (skill_name) |
|
|
1618 | { |
1632 | if (op->chosen_skill && op->chosen_skill->type == SKILL && |
1619 | if (op->chosen_skill && op->chosen_skill->type == SKILL && |
1633 | !strcmp(skill_name, op->chosen_skill->skill)) |
1620 | !strcmp (skill_name, op->chosen_skill->skill)) |
1634 | skill_obj = op->chosen_skill; |
1621 | skill_obj = op->chosen_skill; |
1635 | else { |
1622 | else |
|
|
1623 | { |
1636 | for (i=0; i<NUM_SKILLS; i++) |
1624 | for (i = 0; i < NUM_SKILLS; i++) |
1637 | if (op->contr->last_skill_ob[i] && |
1625 | if (op->contr->last_skill_ob[i] && |
1638 | !strcmp(op->contr->last_skill_ob[i]->skill, skill_name)) { |
1626 | !strcmp (op->contr->last_skill_ob[i]->skill, skill_name)) |
|
|
1627 | { |
1639 | skill_obj = op->contr->last_skill_ob[i]; |
1628 | skill_obj = op->contr->last_skill_ob[i]; |
1640 | break; |
1629 | break; |
1641 | } |
1630 | } |
1642 | |
1631 | |
1643 | /* Player doesn't have the skill. Check to see what to do, and give |
1632 | /* Player doesn't have the skill. Check to see what to do, and give |
1644 | * it to the player if necessary |
1633 | * it to the player if necessary |
1645 | */ |
1634 | */ |
1646 | if (!skill_obj) { |
1635 | if (!skill_obj) |
|
|
1636 | { |
1647 | if (flag == SK_EXP_NONE) return; |
1637 | if (flag == SK_EXP_NONE) |
|
|
1638 | return; |
1648 | else if (flag == SK_EXP_ADD_SKILL) |
1639 | else if (flag == SK_EXP_ADD_SKILL) |
1649 | give_skill_by_name(op, skill_name); |
1640 | give_skill_by_name (op, skill_name); |
1650 | } |
|
|
1651 | } |
1641 | } |
|
|
1642 | } |
|
|
1643 | } |
|
|
1644 | |
|
|
1645 | if (flag != SK_EXP_SKILL_ONLY) |
1652 | } |
1646 | { |
1653 | |
|
|
1654 | /* Basically, you can never gain more experience in one shot |
1647 | /* Basically, you can never gain more experience in one shot |
1655 | * than half what you need to gain for next level. |
1648 | * than half what you need to gain for next level. |
1656 | */ |
1649 | */ |
1657 | exp_to_add = exp; |
|
|
1658 | limit=(levels[op->level+1]-levels[op->level])/2; |
|
|
1659 | if (exp_to_add > limit) exp_to_add=limit; |
|
|
1660 | |
|
|
1661 | ADD_EXP(op->stats.exp, (sint64) ((float) exp_to_add * (skill_obj? skill_obj->expmul:1))); |
|
|
1662 | if (settings.permanent_exp_ratio) { |
|
|
1663 | ADD_EXP(op->perm_exp, (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO * (skill_obj? skill_obj->expmul:1))); |
|
|
1664 | calc_perm_exp(op); |
|
|
1665 | } |
|
|
1666 | |
|
|
1667 | player_lvl_adj(op,NULL); |
|
|
1668 | if (skill_obj) { |
|
|
1669 | exp_to_add = exp; |
1650 | exp_to_add = exp; |
|
|
1651 | limit = (levels[op->level + 1] - levels[op->level]) / 2; |
|
|
1652 | if (exp_to_add > limit) |
|
|
1653 | exp_to_add = limit; |
|
|
1654 | |
|
|
1655 | ADD_EXP (op->stats.exp, |
|
|
1656 | (sint64) ((float) exp_to_add * |
|
|
1657 | (skill_obj ? skill_obj->expmul : 1))); |
|
|
1658 | if (settings.permanent_exp_ratio) |
|
|
1659 | { |
|
|
1660 | ADD_EXP (op->perm_exp, |
|
|
1661 | (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO * |
|
|
1662 | (skill_obj ? skill_obj->expmul : 1))); |
|
|
1663 | calc_perm_exp (op); |
|
|
1664 | } |
|
|
1665 | |
|
|
1666 | player_lvl_adj (op, NULL); |
|
|
1667 | } |
|
|
1668 | |
|
|
1669 | if (skill_obj) |
|
|
1670 | { |
|
|
1671 | exp_to_add = exp; |
1670 | limit=(levels[skill_obj->level+1]-levels[skill_obj->level])/2; |
1672 | limit = (levels[skill_obj->level + 1] - levels[skill_obj->level]) / 2; |
1671 | if (exp_to_add > limit) exp_to_add=limit; |
1673 | if (exp_to_add > limit) |
|
|
1674 | exp_to_add = limit; |
|
|
1675 | |
1672 | ADD_EXP(skill_obj->stats.exp, exp_to_add); |
1676 | ADD_EXP (skill_obj->stats.exp, exp_to_add); |
1673 | if (settings.permanent_exp_ratio) { |
1677 | if (settings.permanent_exp_ratio) |
|
|
1678 | { |
|
|
1679 | skill_obj->perm_exp += |
1674 | skill_obj->perm_exp += (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO); |
1680 | (sint64) ((float) exp_to_add * PERM_EXP_GAIN_RATIO); |
1675 | calc_perm_exp(skill_obj); |
1681 | calc_perm_exp (skill_obj); |
1676 | } |
1682 | } |
|
|
1683 | |
1677 | player_lvl_adj(op,skill_obj); |
1684 | player_lvl_adj (op, skill_obj); |
1678 | } |
1685 | } |
1679 | } |
1686 | } |
1680 | |
1687 | |
1681 | /* This function checks to make sure that object 'op' can |
1688 | /* This function checks to make sure that object 'op' can |
1682 | * lost 'exp' experience. It returns the amount of exp |
1689 | * lost 'exp' experience. It returns the amount of exp |