1 | /* |
1 | /* |
2 | * CrossFire, A Multiplayer game |
2 | * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. |
3 | * |
3 | * |
4 | * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team |
4 | * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team |
5 | * Copyright (C) 2001 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team |
6 | * Copyright (C) 1992 Frank Tore Johansen |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
7 | * |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
8 | * Crossfire TRT is free software; you can redistribute it and/or modify it |
9 | * it under the terms of the GNU General Public License as published by |
9 | * under the terms of the GNU General Public License as published by the Free |
10 | * the Free Software Foundation; either version 2 of the License, or |
10 | * Software Foundation; either version 2 of the License, or (at your option) |
11 | * (at your option) any later version. |
11 | * any later version. |
12 | * |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
13 | * This program is distributed in the hope that it will be useful, but |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
16 | * GNU General Public License for more details. |
16 | * for more details. |
17 | * |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
18 | * You should have received a copy of the GNU General Public License along |
19 | * along with this program; if not, write to the Free Software |
19 | * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51 |
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
21 | * |
21 | * |
22 | * The authors can be reached via e-mail to <crossfire@schmorp.de> |
22 | * The authors can be reached via e-mail to <crossfire@schmorp.de> |
23 | */ |
23 | */ |
24 | |
24 | |
25 | #include <cmath> |
25 | #include <cmath> |
26 | |
26 | |
… | |
… | |
69 | |
69 | |
70 | /* If the director has race set, only affect objects with a arch, |
70 | /* If the director has race set, only affect objects with a arch, |
71 | * name or race that matches. |
71 | * name or race that matches. |
72 | */ |
72 | */ |
73 | if ((op->race) && |
73 | if ((op->race) && |
74 | ((!(victim->arch && arch_flag && victim->arch->name) || op->race != victim->arch->name)) && |
74 | ((!(victim->arch && arch_flag && victim->arch->archname) || op->race != victim->arch->archname)) && |
75 | ((!(victim->name && name_flag) || op->race != victim->name)) && |
75 | ((!(victim->name && name_flag) || op->race != victim->name)) && |
76 | ((!(victim->race && race_flag) || op->race != victim->race))) |
76 | ((!(victim->race && race_flag) || op->race != victim->race))) |
77 | return 1; |
77 | return 1; |
78 | |
78 | |
79 | /* If the director has slaying set, only affect objects where none |
79 | /* If the director has slaying set, only affect objects where none |
80 | * of arch, name, or race match. |
80 | * of arch, name, or race match. |
81 | */ |
81 | */ |
82 | if ((op->slaying) && (((victim->arch && arch_flag && victim->arch->name && op->slaying == victim->arch->name))) || |
82 | if ((op->slaying) && (((victim->arch && arch_flag && victim->arch->archname && op->slaying == victim->arch->archname))) || |
83 | ((victim->name && name_flag && op->slaying == victim->name)) || |
83 | ((victim->name && name_flag && op->slaying == victim->name)) || |
84 | ((victim->race && race_flag && op->slaying == victim->race))) |
84 | ((victim->race && race_flag && op->slaying == victim->race))) |
85 | return 1; |
85 | return 1; |
86 | |
86 | |
87 | return 0; |
87 | return 0; |
… | |
… | |
425 | return 0; |
425 | return 0; |
426 | |
426 | |
427 | op = op->below; |
427 | op = op->below; |
428 | while (op != NULL) |
428 | while (op != NULL) |
429 | { |
429 | { |
430 | if (strcmp (op->arch->name, item) == 0) |
430 | if (strcmp (op->arch->archname, item) == 0) |
431 | { |
431 | { |
432 | if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED) |
432 | if (!QUERY_FLAG (op, FLAG_CURSED) && !QUERY_FLAG (op, FLAG_DAMNED) |
433 | /* Loophole bug? -FD- */ && !QUERY_FLAG (op, FLAG_UNPAID)) |
433 | /* Loophole bug? -FD- */ && !QUERY_FLAG (op, FLAG_UNPAID)) |
434 | { |
434 | { |
435 | if (op->nrof == 0) /* this is necessary for artifact sacrifices --FD-- */ |
435 | if (op->nrof == 0) /* this is necessary for artifact sacrifices --FD-- */ |
… | |
… | |
459 | prev = op; |
459 | prev = op; |
460 | op = op->below; |
460 | op = op->below; |
461 | |
461 | |
462 | while (op != NULL) |
462 | while (op != NULL) |
463 | { |
463 | { |
464 | if (strcmp (op->arch->name, item) == 0) |
464 | if (strcmp (op->arch->archname, item) == 0) |
465 | { |
465 | { |
466 | if (op->nrof >= nrof) |
466 | if (op->nrof >= nrof) |
467 | { |
467 | { |
468 | decrease_ob_nr (op, nrof); |
468 | decrease_ob_nr (op, nrof); |
469 | return; |
469 | return; |
… | |
… | |
855 | { |
855 | { |
856 | base = base - (base * settings.armor_speed_improvement) / 100; |
856 | base = base - (base * settings.armor_speed_improvement) / 100; |
857 | pow++; |
857 | pow++; |
858 | } |
858 | } |
859 | |
859 | |
860 | ARMOUR_SPEED (armour) = (ARMOUR_SPEED (&armour->arch->clone) * base) / 100; |
860 | ARMOUR_SPEED (armour) = (ARMOUR_SPEED (armour->arch) * base) / 100; |
861 | } |
861 | } |
862 | else |
862 | else |
863 | ARMOUR_SPEED (armour) = (ARMOUR_SPEED (&armour->arch->clone) * (100 + armour->magic * settings.armor_speed_improvement)) / 100; |
863 | ARMOUR_SPEED (armour) = (ARMOUR_SPEED (armour->arch) * (100 + armour->magic * settings.armor_speed_improvement)) / 100; |
864 | |
864 | |
865 | if (!settings.armor_weight_linear) |
865 | if (!settings.armor_weight_linear) |
866 | { |
866 | { |
867 | int base = 100; |
867 | int base = 100; |
868 | int pow = 0; |
868 | int pow = 0; |
… | |
… | |
871 | { |
871 | { |
872 | base = base - (base * settings.armor_weight_reduction) / 100; |
872 | base = base - (base * settings.armor_weight_reduction) / 100; |
873 | pow++; |
873 | pow++; |
874 | } |
874 | } |
875 | |
875 | |
876 | armour->weight = (armour->arch->clone.weight * base) / 100; |
876 | armour->weight = (armour->arch->weight * base) / 100; |
877 | } |
877 | } |
878 | else |
878 | else |
879 | armour->weight = (armour->arch->clone.weight * (100 - armour->magic * settings.armor_weight_reduction)) / 100; |
879 | armour->weight = (armour->arch->weight * (100 - armour->magic * settings.armor_weight_reduction)) / 100; |
880 | |
880 | |
881 | if (armour->weight <= 0) |
881 | if (armour->weight <= 0) |
882 | { |
882 | { |
883 | LOG (llevInfo, "Warning: enchanted armours can have negative weight\n."); |
883 | LOG (llevInfo, "Warning: enchanted armours can have negative weight\n."); |
884 | armour->weight = 1; |
884 | armour->weight = 1; |
885 | } |
885 | } |
886 | |
886 | |
887 | armour->item_power = get_power_from_ench (armour->arch->clone.item_power + armour->magic); |
887 | armour->item_power = get_power_from_ench (armour->arch->item_power + armour->magic); |
888 | |
888 | |
889 | if (op->type == PLAYER) |
889 | if (op->type == PLAYER) |
890 | { |
890 | { |
891 | esrv_send_item (op, armour); |
891 | esrv_send_item (op, armour); |
892 | if (QUERY_FLAG (armour, FLAG_APPLIED)) |
892 | if (QUERY_FLAG (armour, FLAG_APPLIED)) |
… | |
… | |
944 | |
944 | |
945 | price_in = cost * item->value; |
945 | price_in = cost * item->value; |
946 | } |
946 | } |
947 | else |
947 | else |
948 | { |
948 | { |
949 | if (item->type == PLAYER || CONV_FROM (converter) != item->arch->name || |
949 | if (item->type == PLAYER || CONV_FROM (converter) != item->arch->archname || |
950 | (CONV_NEED (converter) && CONV_NEED (converter) > (uint16) item->nrof)) |
950 | (CONV_NEED (converter) && CONV_NEED (converter) > (uint16) item->nrof)) |
951 | return 0; |
951 | return 0; |
952 | |
952 | |
953 | if (CONV_NEED (converter)) |
953 | if (CONV_NEED (converter)) |
954 | { |
954 | { |
… | |
… | |
1245 | */ |
1245 | */ |
1246 | static void |
1246 | static void |
1247 | apply_sign (object *op, object *sign, int autoapply) |
1247 | apply_sign (object *op, object *sign, int autoapply) |
1248 | { |
1248 | { |
1249 | readable_message_type *msgType; |
1249 | readable_message_type *msgType; |
1250 | char newbuf[HUGE_BUF]; |
|
|
1251 | |
1250 | |
1252 | if (sign->msg == NULL) |
1251 | if (sign->msg == NULL) |
1253 | { |
1252 | { |
1254 | new_draw_info (NDI_UNIQUE, 0, op, "Nothing is written on it."); |
1253 | new_draw_info (NDI_UNIQUE, 0, op, "Nothing is written on it."); |
1255 | return; |
1254 | return; |
… | |
… | |
1276 | if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ) && !sign->move_on) |
1275 | if (QUERY_FLAG (op, FLAG_BLIND) && !QUERY_FLAG (op, FLAG_WIZ) && !sign->move_on) |
1277 | { |
1276 | { |
1278 | new_draw_info (NDI_UNIQUE, 0, op, "You are unable to read while blind."); |
1277 | new_draw_info (NDI_UNIQUE, 0, op, "You are unable to read while blind."); |
1279 | return; |
1278 | return; |
1280 | } |
1279 | } |
|
|
1280 | |
|
|
1281 | if (op->contr) |
|
|
1282 | if (client *ns = op->contr->ns) |
|
|
1283 | { |
1281 | msgType = get_readable_message_type (sign); |
1284 | msgType = get_readable_message_type (sign); |
|
|
1285 | |
|
|
1286 | if (ns->can_msg) |
|
|
1287 | ns->send_msg (NDI_NAVY, msgType->msgtype, &sign->msg); |
|
|
1288 | else |
|
|
1289 | { |
|
|
1290 | char newbuf[HUGE_BUF]; |
1282 | snprintf (newbuf, sizeof (newbuf), "%hhu %s", autoapply ? 1 : 0, &sign->msg); |
1291 | snprintf (newbuf, sizeof (newbuf), "%u %s", autoapply ? 1 : 0, &sign->msg); |
1283 | draw_ext_info (NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, newbuf, &sign->msg); |
1292 | draw_ext_info (NDI_UNIQUE | NDI_NAVY, 0, op, msgType->message_type, msgType->message_subtype, newbuf, &sign->msg); |
|
|
1293 | } |
|
|
1294 | } |
1284 | } |
1295 | } |
1285 | |
1296 | |
1286 | /** |
1297 | /** |
1287 | * 'victim' moves onto 'trap' |
1298 | * 'victim' moves onto 'trap' |
1288 | * 'victim' leaves 'trap' |
1299 | * 'victim' leaves 'trap' |
… | |
… | |
1311 | * proper. This code was causing needless crashes. |
1322 | * proper. This code was causing needless crashes. |
1312 | */ |
1323 | */ |
1313 | if (recursion_depth >= 500) |
1324 | if (recursion_depth >= 500) |
1314 | { |
1325 | { |
1315 | LOG (llevDebug, "WARNING: move_apply(): aborting recursion " |
1326 | LOG (llevDebug, "WARNING: move_apply(): aborting recursion " |
1316 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->name, &trap->name, &victim->arch->name, &victim->name); |
1327 | "[trap arch %s, name %s; victim arch %s, name %s]\n", &trap->arch->archname, &trap->name, &victim->arch->archname, &victim->name); |
1317 | return; |
1328 | return; |
1318 | } |
1329 | } |
|
|
1330 | |
1319 | recursion_depth++; |
1331 | recursion_depth++; |
1320 | if (trap->head) |
1332 | if (trap->head) |
1321 | trap = trap->head; |
1333 | trap = trap->head; |
1322 | |
1334 | |
1323 | if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) |
1335 | if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator))) |
… | |
… | |
1518 | } |
1530 | } |
1519 | goto leave; |
1531 | goto leave; |
1520 | |
1532 | |
1521 | default: |
1533 | default: |
1522 | LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " |
1534 | LOG (llevDebug, "name %s, arch %s, type %d with fly/walk on/off not " |
1523 | "handled in move_apply()\n", &trap->name, &trap->arch->name, trap->type); |
1535 | "handled in move_apply()\n", &trap->name, &trap->arch->archname, trap->type); |
1524 | goto leave; |
1536 | goto leave; |
1525 | } |
1537 | } |
1526 | |
1538 | |
1527 | leave: |
1539 | leave: |
1528 | recursion_depth--; |
1540 | recursion_depth--; |
… | |
… | |
2027 | shstr_cmp dragon_ability_force ("dragon_ability_force"); |
2039 | shstr_cmp dragon_ability_force ("dragon_ability_force"); |
2028 | shstr_cmp dragon_skin_force ("dragon_skin_force"); |
2040 | shstr_cmp dragon_skin_force ("dragon_skin_force"); |
2029 | |
2041 | |
2030 | for (tmp = op->inv; tmp; tmp = tmp->below) |
2042 | for (tmp = op->inv; tmp; tmp = tmp->below) |
2031 | if (tmp->type == FORCE) |
2043 | if (tmp->type == FORCE) |
2032 | if (tmp->arch->name == dragon_skin_force) |
2044 | if (tmp->arch->archname == dragon_skin_force) |
2033 | skin = tmp; |
2045 | skin = tmp; |
2034 | else if (tmp->arch->name == dragon_ability_force) |
2046 | else if (tmp->arch->archname == dragon_ability_force) |
2035 | abil = tmp; |
2047 | abil = tmp; |
2036 | |
2048 | |
2037 | /* if either skin or ability are missing, this is an old player |
2049 | /* if either skin or ability are missing, this is an old player |
2038 | which is not to be considered a dragon -> bail out */ |
2050 | which is not to be considered a dragon -> bail out */ |
2039 | if (skin == NULL || abil == NULL) |
2051 | if (skin == NULL || abil == NULL) |
… | |
… | |
3846 | */ |
3858 | */ |
3847 | int i, j; |
3859 | int i, j; |
3848 | |
3860 | |
3849 | for (i = 0; i < NUM_STATS; i++) |
3861 | for (i = 0; i < NUM_STATS; i++) |
3850 | { |
3862 | { |
3851 | int race_bonus = pl->arch->clone.stats.stat (i); |
3863 | int race_bonus = pl->arch->stats.stat (i); |
3852 | sint8 stat = stats->stat (i) + ns->stat (i); |
3864 | sint8 stat = stats->stat (i) + ns->stat (i); |
3853 | |
3865 | |
3854 | if (stat > 20 + race_bonus) |
3866 | if (stat > 20 + race_bonus) |
3855 | { |
3867 | { |
3856 | excess_stat++; |
3868 | excess_stat++; |
… | |
… | |
3866 | |
3878 | |
3867 | if (i == CHA) |
3879 | if (i == CHA) |
3868 | continue; /* exclude cha from this */ |
3880 | continue; /* exclude cha from this */ |
3869 | |
3881 | |
3870 | int stat = stats->stat (i); |
3882 | int stat = stats->stat (i); |
3871 | int race_bonus = pl->arch->clone.stats.stat (i); |
3883 | int race_bonus = pl->arch->stats.stat (i); |
3872 | if (stat < 20 + race_bonus) |
3884 | if (stat < 20 + race_bonus) |
3873 | { |
3885 | { |
3874 | change_attr_value (stats, i, 1); |
3886 | change_attr_value (stats, i, 1); |
3875 | excess_stat--; |
3887 | excess_stat--; |
3876 | } |
3888 | } |
… | |
… | |
3945 | { |
3957 | { |
3946 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name (transformer), query_name (marked)); |
3958 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name (transformer), query_name (marked)); |
3947 | return; |
3959 | return; |
3948 | } |
3960 | } |
3949 | /* check whether they are compatible or not */ |
3961 | /* check whether they are compatible or not */ |
3950 | find = strstr (marked->slaying, transformer->arch->name); |
3962 | find = strstr (marked->slaying, transformer->arch->archname); |
3951 | if (!find || (*(find + strlen (transformer->arch->name)) != ':')) |
3963 | if (!find || (*(find + strlen (transformer->arch->archname)) != ':')) |
3952 | { |
3964 | { |
3953 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name (transformer), query_name (marked)); |
3965 | new_draw_info_format (NDI_UNIQUE, 0, pl, "You can't use the %s with your %s!", query_name (transformer), query_name (marked)); |
3954 | return; |
3966 | return; |
3955 | } |
3967 | } |
3956 | find += strlen (transformer->arch->name) + 1; |
3968 | find += strlen (transformer->arch->archname) + 1; |
3957 | /* Item can be used, now find how many and what it yields */ |
3969 | /* Item can be used, now find how many and what it yields */ |
3958 | if (isdigit (*(find))) |
3970 | if (isdigit (*(find))) |
3959 | { |
3971 | { |
3960 | yield = atoi (find); |
3972 | yield = atoi (find); |
3961 | if (yield < 1) |
3973 | if (yield < 1) |