ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/attack.C
(Generate patch)

Comparing deliantra/server/server/attack.C (file contents):
Revision 1.140 by root, Sun May 2 20:37:58 2010 UTC vs.
Revision 1.150 by root, Wed Nov 16 23:42:02 2016 UTC

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 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
33typedef 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 */
256int 250int
257hit_map (object *op, int dir, uint32_t type, int full_hit) 251hit_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
372static void 365static void
373attack_message (int dam, int type, object *op, object *hitter) 366attack_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 */ 1078 op->set_speed (op->speed - 1.f);
1079 merge_ob (hitter, NULL);
1080
1081 return 0;
1082 }
1083
1084 if (hit_something && op->speed >= 10.0)
1085 --op->speed;
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 */
1160int 1153int
1161kill_object (object *op, int dam, object *hitter, int type) 1154kill_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;
1271 skill = owner->current_weapon->skill; 1263 skill = owner->current_weapon->skill;
1272 else 1264 else
1273 { 1265 {
1274 LOG (llevError | logBacktrace, 1266 LOG (llevError | logBacktrace,
1275 "BUG: kill_object - unable to find skill that killed monster\n" 1267 "BUG: kill_object - unable to find skill that killed monster\n"
1276 "op: %s\n" "hitter: %s\n" "owner: %s\n", 1268 "op: %s\n" "hitter: %s\n" "op: %s\n",
1277 owner->debug_desc (), hitter->debug_desc (), op->debug_desc ()); 1269 op->debug_desc (), hitter->debug_desc (), op->debug_desc ());
1278 skill = 0; 1270 skill = 0;
1279 } 1271 }
1280 1272
1281 /* We have the skill we want to credit to - now find the object this goes 1273 /* We have the skill we want to credit to - now find the object this goes
1282 * to. Make sure skop is an actual skill, and not a skill tool! 1274 * to. Make sure skop is an actual skill, and not a skill tool!
1434int 1426int
1435hit_player (object *op, int dam, object *hitter, uint32_t type, int full_hit) 1427hit_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
1813 int maxduration; 1805 int maxduration;
1814 1806
1815 tmp = present_in_ob_by_name (FORCE, shstr_confusion, op); 1807 tmp = present_in_ob_by_name (FORCE, shstr_confusion, op);
1816 if (!tmp) 1808 if (!tmp)
1817 { 1809 {
1818 tmp = get_archetype (FORCE_NAME); 1810 tmp = archetype::get (FORCE_NAME);
1819 tmp = insert_ob_in_ob (tmp, op); 1811 tmp = insert_ob_in_ob (tmp, op);
1820 } 1812 }
1821 1813
1822 /* Duration added per hit and max. duration of confusion both depend 1814 /* Duration added per hit and max. duration of confusion both depend
1823 * on the player's resistance 1815 * on the player's resistance
1824 */ 1816 */
1825 tmp->speed = 0.05; 1817 tmp->set_speed (0.05);
1826 tmp->subtype = FORCE_CONFUSION; 1818 tmp->subtype = FORCE_CONFUSION;
1827 tmp->duration = 8 + max (1, 5 * (100 - op->resist[ATNR_CONFUSION]) / 100); 1819 tmp->duration = 8 + max (1, 5 * (100 - op->resist[ATNR_CONFUSION]) / 100);
1828 tmp->name = shstr_confusion; 1820 tmp->name = shstr_confusion;
1829 maxduration = max (2, 30 * (100 - op->resist[ATNR_CONFUSION]) / 100); 1821 maxduration = max (2, 30 * (100 - op->resist[ATNR_CONFUSION]) / 100);
1830 1822
1838} 1830}
1839 1831
1840void 1832void
1841blind_player (object *op, object *hitter, int dam) 1833blind_player (object *op, object *hitter, int dam)
1842{ 1834{
1843 object *tmp, *owner;
1844
1845 /* Save some work if we know it isn't going to affect the player */ 1835 /* Save some work if we know it isn't going to affect the player */
1846 if (op->resist[ATNR_BLIND] == 100) 1836 if (op->resist[ATNR_BLIND] == 100)
1847 return; 1837 return;
1848 1838
1849 tmp = present_in_ob (BLINDNESS, op); 1839 object *tmp = present_in_ob (BLINDNESS, op);
1850 if (!tmp) 1840 if (!tmp)
1851 { 1841 {
1852 tmp = get_archetype (shstr_blindness); 1842 tmp = archetype::get (shstr_blindness);
1853 tmp->set_flag (FLAG_BLIND); 1843 tmp->set_flag (FLAG_BLIND);
1854 tmp->set_flag (FLAG_APPLIED); 1844 tmp->set_flag (FLAG_APPLIED);
1855 /* use floats so we don't lose too much precision due to rounding errors. 1845 // use floats so we don't lose too much precision due to rounding errors.
1856 * speed is a float anyways. 1846 tmp->set_speed (lerp<float> (op->resist [ATNR_BLIND], 0, 100, tmp->speed, MIN_ACTIVE_SPEED));
1857 */
1858 tmp->speed *= (100 - op->resist[ATNR_BLIND]) * .01f;
1859 1847
1860 tmp = insert_ob_in_ob (tmp, op); 1848 tmp = insert_ob_in_ob (tmp, op);
1861 change_abil (op, tmp); /* Mostly to display any messages */ 1849 change_abil (op, tmp); /* Mostly to display any messages */
1862 op->update_stats (); /* This takes care of some other stuff */ 1850 op->update_stats (); /* This takes care of some other stuff */
1863 1851
1864 if (hitter->owner)
1865 owner = hitter->owner;
1866 else
1867 owner = hitter;
1868
1869 new_draw_info_format (NDI_UNIQUE, 0, owner, "Your attack blinds %s!", query_name (op)); 1852 new_draw_info_format (NDI_UNIQUE, 0, hitter->outer_owner (), "Your attack blinds %s!", query_name (op));
1870 } 1853 }
1871 1854
1872 tmp->stats.food += dam; 1855 tmp->stats.food += dam;
1873 min_it (tmp->stats.food, 10); 1856 min_it (tmp->stats.food, 10);
1874} 1857}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines