1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992 Frank Tore Johansen |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
11 | * option) 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, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
16 | * GNU General Public License for more details. |
17 | * |
17 | * |
18 | * You should have received a copy of the Affero GNU General Public License |
18 | * You should have received a copy of the Affero GNU General Public License |
19 | * and the GNU General Public License along with this program. If not, see |
19 | * and the GNU General Public License along with this program. If not, see |
20 | * <http://www.gnu.org/licenses/>. |
20 | * <http://www.gnu.org/licenses/>. |
21 | * |
21 | * |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
23 | */ |
23 | */ |
24 | |
24 | |
25 | #include <assert.h> |
25 | #include <assert.h> |
26 | #include <global.h> |
26 | #include <global.h> |
27 | #include <living.h> |
27 | #include <living.h> |
28 | #include <material.h> |
28 | #include <material.h> |
29 | #include <skills.h> |
29 | #include <skills.h> |
30 | #include <sounds.h> |
30 | #include <sounds.h> |
31 | #include <sproto.h> |
31 | #include <sproto.h> |
32 | |
|
|
33 | typedef struct att_msg_str |
|
|
34 | { |
|
|
35 | char *msg1; |
|
|
36 | char *msg2; |
|
|
37 | } att_msg; |
|
|
38 | |
32 | |
39 | /*#define ATTACK_DEBUG*/ |
33 | /*#define ATTACK_DEBUG*/ |
40 | |
34 | |
41 | /* did_make_save_item just checks to make sure the item actually |
35 | /* did_make_save_item just checks to make sure the item actually |
42 | * made its saving throw based on the tables. It does not take |
36 | * made its saving throw based on the tables. It does not take |
… | |
… | |
254 | * returns 1 if it hits something, 0 otherwise. |
248 | * returns 1 if it hits something, 0 otherwise. |
255 | */ |
249 | */ |
256 | int |
250 | int |
257 | hit_map (object *op, int dir, uint32_t type, int full_hit) |
251 | hit_map (object *op, int dir, uint32_t type, int full_hit) |
258 | { |
252 | { |
259 | maptile *map; |
|
|
260 | sint16 x, y; |
253 | sint16 x, y; |
261 | int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ |
254 | int retflag = 0; /* added this flag.. will return 1 if it hits a monster */ |
262 | |
255 | |
263 | if (op->flag [FLAG_FREED]) |
256 | if (op->flag [FLAG_FREED]) |
264 | { |
257 | { |
… | |
… | |
364 | if (op->destroyed ()) |
357 | if (op->destroyed ()) |
365 | break; |
358 | break; |
366 | } |
359 | } |
367 | } |
360 | } |
368 | |
361 | |
369 | return 0; |
362 | return retflag; |
370 | } |
363 | } |
371 | |
364 | |
372 | static void |
365 | static void |
373 | attack_message (int dam, int type, object *op, object *hitter) |
366 | attack_message (int dam, int type, object *op, object *hitter) |
374 | { |
367 | { |
… | |
… | |
1025 | * arrow, move_apply() calls this function, arrow sticks in demon, |
1018 | * arrow, move_apply() calls this function, arrow sticks in demon, |
1026 | * attack_ob_simple() returns, and we've got an arrow that still exists |
1019 | * attack_ob_simple() returns, and we've got an arrow that still exists |
1027 | * but is no longer on the map. Ugh. (Beware: Such things can happen at |
1020 | * but is no longer on the map. Ugh. (Beware: Such things can happen at |
1028 | * other places as well!) |
1021 | * other places as well!) |
1029 | */ |
1022 | */ |
1030 | if (hitter->destroyed () || hitter->env != NULL) |
1023 | if (hitter->destroyed () || hitter->env) |
1031 | { |
1024 | { |
1032 | if (container) |
1025 | if (container) |
1033 | container->destroy (); |
1026 | container->destroy (); |
1034 | |
1027 | |
1035 | return 0; |
1028 | return 0; |
1036 | } |
1029 | } |
1037 | |
1030 | |
1038 | /* Missile hit victim */ |
1031 | /* Missile hit victim */ |
1039 | /* if the speed is > 10, then this is a fast moving arrow, we go straight |
1032 | /* if the speed is >= 10, then this is a fast moving arrow, we go straight |
1040 | * through the target |
1033 | * through the target |
1041 | */ |
1034 | */ |
1042 | if (hit_something && op->speed <= 10.0) |
1035 | if (hit_something) |
|
|
1036 | if (op->speed < 10.0) |
1043 | { |
1037 | { |
1044 | /* Stop arrow */ |
1038 | /* Stop arrow */ |
1045 | if (!container) |
1039 | if (!container) |
1046 | { |
1040 | { |
1047 | hitter = fix_stopped_arrow (hitter); |
1041 | hitter = fix_stopped_arrow (hitter); |
1048 | if (!hitter) |
1042 | if (!hitter) |
1049 | return 0; |
1043 | return 0; |
1050 | } |
1044 | } |
1051 | else |
1045 | else |
1052 | container->destroy (); |
1046 | container->destroy (); |
1053 | |
1047 | |
1054 | /* Try to stick arrow into victim */ |
1048 | /* Try to stick arrow into victim */ |
1055 | if (!victim->destroyed () && stick_arrow (hitter, victim)) |
1049 | if (!victim->destroyed () && stick_arrow (hitter, victim)) |
|
|
1050 | return 0; |
|
|
1051 | |
|
|
1052 | /* Else try to put arrow on victim's map square |
|
|
1053 | * remove check for P_WALL here. If the arrow got to this |
|
|
1054 | * space, that is good enough - with the new movement code, |
|
|
1055 | * there is now the potential for lots of spaces where something |
|
|
1056 | * can fly over but not otherwise move over. What is the correct |
|
|
1057 | * way to handle those otherwise? |
|
|
1058 | */ |
|
|
1059 | if (victim->x != hitter->x || victim->y != hitter->y) |
|
|
1060 | { |
|
|
1061 | if (victim->destroyed ()) |
|
|
1062 | hitter->destroy (); |
|
|
1063 | else |
|
|
1064 | { |
|
|
1065 | hitter->remove (); |
|
|
1066 | hitter->x = victim->x; |
|
|
1067 | hitter->y = victim->y; |
|
|
1068 | insert_ob_in_map (hitter, victim->map, hitter, 0); |
|
|
1069 | } |
|
|
1070 | } |
|
|
1071 | else |
|
|
1072 | /* Else leave arrow where it is */ |
|
|
1073 | merge_ob (hitter, NULL); |
|
|
1074 | |
1056 | return 0; |
1075 | return 0; |
1057 | |
|
|
1058 | /* Else try to put arrow on victim's map square |
|
|
1059 | * remove check for P_WALL here. If the arrow got to this |
|
|
1060 | * space, that is good enough - with the new movement code, |
|
|
1061 | * there is now the potential for lots of spaces where something |
|
|
1062 | * can fly over but not otherwise move over. What is the correct |
|
|
1063 | * way to handle those otherwise? |
|
|
1064 | */ |
|
|
1065 | if (victim->x != hitter->x || victim->y != hitter->y) |
|
|
1066 | { |
|
|
1067 | if (victim->destroyed ()) |
|
|
1068 | hitter->destroy (); |
|
|
1069 | else |
|
|
1070 | { |
|
|
1071 | hitter->remove (); |
|
|
1072 | hitter->x = victim->x; |
|
|
1073 | hitter->y = victim->y; |
|
|
1074 | insert_ob_in_map (hitter, victim->map, hitter, 0); |
|
|
1075 | } |
|
|
1076 | } |
1076 | } |
1077 | else |
1077 | else |
1078 | /* Else leave arrow where it is */ |
|
|
1079 | merge_ob (hitter, NULL); |
|
|
1080 | |
|
|
1081 | return 0; |
|
|
1082 | } |
|
|
1083 | |
|
|
1084 | if (hit_something && op->speed >= 10.0) |
|
|
1085 | op->set_speed (op->speed - 1.f); |
1078 | op->set_speed (op->speed - 1.f); |
1086 | |
1079 | |
1087 | /* Missile missed victim - reassemble missile */ |
1080 | /* Missile missed victim - reassemble missile */ |
1088 | if (container) |
1081 | if (container) |
1089 | { |
1082 | { |
1090 | hitter->remove (); |
1083 | hitter->remove (); |
… | |
… | |
1158 | * MSW 2002-07-17 |
1151 | * MSW 2002-07-17 |
1159 | */ |
1152 | */ |
1160 | int |
1153 | int |
1161 | kill_object (object *op, int dam, object *hitter, int type) |
1154 | kill_object (object *op, int dam, object *hitter, int type) |
1162 | { |
1155 | { |
1163 | char buf[MAX_BUF]; |
|
|
1164 | shstr skill; |
1156 | shstr skill; |
1165 | int maxdam = 0; |
1157 | int maxdam = 0; |
1166 | int battleg = 0; /* true if op standing on battleground */ |
1158 | int battleg = 0; /* true if op standing on battleground */ |
1167 | int pk = 0; /* true if op and what controls hitter are both players */ |
1159 | int pk = 0; /* true if op and what controls hitter are both players */ |
1168 | object *owner = 0; |
1160 | object *owner = 0; |
… | |
… | |
1434 | int |
1426 | int |
1435 | hit_player (object *op, int dam, object *hitter, uint32_t type, int full_hit) |
1427 | hit_player (object *op, int dam, object *hitter, uint32_t type, int full_hit) |
1436 | { |
1428 | { |
1437 | int magic = type & AT_MAGIC; |
1429 | int magic = type & AT_MAGIC; |
1438 | int body_attack = op && op->head; /* Did we hit op's head? */ |
1430 | int body_attack = op && op->head; /* Did we hit op's head? */ |
1439 | int maxdam = 0, ndam = 0, attacktype = 1; |
1431 | int maxdam = 0, ndam = 0; |
1440 | int maxattacktype; |
1432 | int maxattacktype; |
1441 | int simple_attack; |
1433 | int simple_attack; |
1442 | int rtn_kill = 0; |
1434 | int rtn_kill = 0; |
1443 | int friendlyfire; |
1435 | int friendlyfire; |
1444 | |
1436 | |