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.75 by root, Mon Aug 27 05:10:51 2007 UTC vs.
Revision 1.86 by root, Sat May 17 14:57:23 2008 UTC

1/* 1/*
2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team 4 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Crossfire TRT is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version. 11 * (at your 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,
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 GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * 20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de> 21 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 22 */
23 23
24#include <assert.h> 24#include <assert.h>
25#include <global.h> 25#include <global.h>
26#include <living.h> 26#include <living.h>
62 CLEAR_FLAG (op, FLAG_DAMNED); 62 CLEAR_FLAG (op, FLAG_DAMNED);
63 CLEAR_FLAG (op, FLAG_CURSED); 63 CLEAR_FLAG (op, FLAG_CURSED);
64 CLEAR_FLAG (op, FLAG_KNOWN_MAGICAL); 64 CLEAR_FLAG (op, FLAG_KNOWN_MAGICAL);
65 CLEAR_FLAG (op, FLAG_KNOWN_CURSED); 65 CLEAR_FLAG (op, FLAG_KNOWN_CURSED);
66 66
67 if (op->env && op->env->type == PLAYER) 67 if (object *pl = op->visible_to ())
68 esrv_send_item (op->env, op); 68 esrv_update_item (UPD_FLAGS, pl, op);
69 } 69 }
70} 70}
71 71
72/* did_make_save_item just checks to make sure the item actually 72/* did_make_save_item just checks to make sure the item actually
73 * made its saving throw based on the tables. It does not take 73 * made its saving throw based on the tables. It does not take
163 */ 163 */
164 if (type & (AT_FIRE | AT_ELECTRICITY) && op->other_arch && QUERY_FLAG (op, FLAG_IS_LIGHTABLE)) 164 if (type & (AT_FIRE | AT_ELECTRICITY) && op->other_arch && QUERY_FLAG (op, FLAG_IS_LIGHTABLE))
165 { 165 {
166 const char *arch = op->other_arch->archname; 166 const char *arch = op->other_arch->archname;
167 167
168 op = decrease_ob_nr (op, 1); 168 if (op->decrease ())
169
170 if (op)
171 fix_stopped_item (op, m, originator); 169 fix_stopped_item (op, m, originator);
172 170
173 if ((op = get_archetype (arch)) != NULL) 171 if ((op = archetype::get (arch)))
174 { 172 {
175 if (env) 173 if (env)
176 { 174 {
177 op->x = env->x, op->y = env->y; 175 op->x = env->x, op->y = env->y; //???? wtf
178 insert_ob_in_ob (op, env); 176 env->insert (op);
179 if (env->contr)
180 esrv_send_item (env, op);
181 } 177 }
182 else 178 else
183 { 179 {
184 op->x = x, op->y = y; 180 op->x = x, op->y = y;
185 insert_ob_in_map (op, m, originator, 0); 181 insert_ob_in_map (op, m, originator, 0);
196 return; 192 return;
197 } 193 }
198 194
199 if (op->nrof > 1) 195 if (op->nrof > 1)
200 { 196 {
201 op = decrease_ob_nr (op, rndm (0, op->nrof - 1)); 197 if (op->decrease (rndm (0, op->nrof - 1)))
202
203 if (op)
204 fix_stopped_item (op, m, originator); 198 fix_stopped_item (op, m, originator);
205 } 199 }
206 else 200 else
207 {
208 if (op->env)
209 {
210 object *tmp = op->in_player ();
211
212 if (tmp)
213 esrv_del_item (tmp->contr, op->count);
214 }
215
216 op->destroy (); 201 op->destroy ();
217 }
218 202
219 if (type & (AT_FIRE | AT_ELECTRICITY)) 203 if (type & (AT_FIRE | AT_ELECTRICITY))
220 if (env) 204 if (env)
221 { 205 {
222 op = get_archetype ("burnout"); 206 op = archetype::get (shstr_burnout);
223 op->x = env->x, op->y = env->y; 207 op->x = env->x, op->y = env->y;
224 insert_ob_in_ob (op, env); 208 env->insert (op);
225 } 209 }
226 else 210 else
227 replace_insert_ob_in_map ("burnout", originator); 211 replace_insert_ob_in_map (shstr_burnout, originator);
228 212
229 return; 213 return;
230 } 214 }
231 215
232 /* The value of 50 is arbitrary. */ 216 /* The value of 50 is arbitrary. */
233 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2)) 217 if (type & AT_COLD && (op->resist[ATNR_COLD] < 50) && !QUERY_FLAG (op, FLAG_NO_PICK) && (RANDOM () & 2))
234 { 218 {
235 object *tmp; 219 object *tmp;
236 archetype *at = archetype::find ("icecube"); 220 archetype *at = archetype::find (shstr_icecube);
237 221
238 if (at == NULL) 222 if (at == NULL)
239 return; 223 return;
240 224
241 op = stop_item (op); 225 op = stop_item (op);
295 } 279 }
296 280
297 if (op->head) 281 if (op->head)
298 op = op->head; 282 op = op->head;
299 283
300 map = op->map; 284 mapxy pos (op);
301 x = op->x + freearr_x[dir]; 285 pos.move (dir);
302 y = op->y + freearr_y[dir];
303 286
304 if (!xy_normalise (map, x, y)) 287 if (!pos.normalise ())
305 return 0; 288 return 0;
306 289
307 // elmex: a safe map tile can't be hit! 290 // elmex: a safe map tile can't be hit!
308 // this should prevent most harmful effects on items and players there. 291 // this should prevent most harmful effects on items and players there.
309 mapspace &ms = map->at (x, y); 292 mapspace &ms = pos.ms ();
310 293
311 if (ms.flags () & P_SAFE) 294 if (ms.flags () & P_SAFE)
312 return 0; 295 return 0;
313 296
314 /* peterm: a few special cases for special attacktypes --counterspell 297 /* peterm: a few special cases for special attacktypes --counterspell
352 335
353 /* Something could have happened to 'tmp' while 'tmp->below' was processed. 336 /* Something could have happened to 'tmp' while 'tmp->below' was processed.
354 * For example, 'tmp' was put in an icecube. 337 * For example, 'tmp' was put in an icecube.
355 * This is one of the few cases where on_same_map should not be used. 338 * This is one of the few cases where on_same_map should not be used.
356 */ 339 */
357 if (tmp->map != map || tmp->x != x || tmp->y != y) 340 if (tmp->map != pos.m || tmp->x != pos.x || tmp->y != pos.y)
358 continue; 341 continue;
359 342
360 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 343 if (QUERY_FLAG (tmp, FLAG_ALIVE))
361 { 344 {
362 hit_player (tmp, op->stats.dam, op, type, full_hit); 345 hit_player (tmp, op->stats.dam, op, type, full_hit);
539 { 522 {
540 int mtype; 523 int mtype;
541 524
542 switch (hitter->current_weapon->weapontype) 525 switch (hitter->current_weapon->weapontype)
543 { 526 {
544 case WEAP_HIT: 527 case WEAP_HIT:
545 mtype = ATM_BASIC; 528 mtype = ATM_BASIC;
546 break; 529 break;
547 case WEAP_SLASH: 530 case WEAP_SLASH:
548 mtype = ATM_SLASH; 531 mtype = ATM_SLASH;
549 break; 532 break;
550 case WEAP_PIERCE: 533 case WEAP_PIERCE:
551 mtype = ATM_PIERCE; 534 mtype = ATM_PIERCE;
552 break; 535 break;
553 case WEAP_CLEAVE: 536 case WEAP_CLEAVE:
554 mtype = ATM_CLEAVE; 537 mtype = ATM_CLEAVE;
555 break; 538 break;
556 case WEAP_SLICE: 539 case WEAP_SLICE:
557 mtype = ATM_SLICE; 540 mtype = ATM_SLICE;
558 break; 541 break;
559 case WEAP_STAB: 542 case WEAP_STAB:
560 mtype = ATM_STAB; 543 mtype = ATM_STAB;
561 break; 544 break;
562 case WEAP_WHIP: 545 case WEAP_WHIP:
563 mtype = ATM_WHIP; 546 mtype = ATM_WHIP;
564 break; 547 break;
565 case WEAP_CRUSH: 548 case WEAP_CRUSH:
566 mtype = ATM_CRUSH; 549 mtype = ATM_CRUSH;
567 break; 550 break;
568 case WEAP_BLUD: 551 case WEAP_BLUD:
569 mtype = ATM_BLUD; 552 mtype = ATM_BLUD;
570 break; 553 break;
571 default: 554 default:
572 mtype = ATM_BASIC; 555 mtype = ATM_BASIC;
573 break; 556 break;
574 } 557 }
558
575 for (i = 0; i < MAXATTACKMESS && attack_mess[mtype][i].level != -1; i++) 559 for (i = 0; i < MAXATTACKMESS && attack_mess[mtype][i].level != -1; i++)
576 if (dam < attack_mess[mtype][i].level || attack_mess[mtype][i + 1].level == -1) 560 if (dam < attack_mess[mtype][i].level || attack_mess[mtype][i + 1].level == -1)
577 { 561 {
578 sprintf (buf1, "%s %s%s", attack_mess[mtype][i].buf1, &op->name, attack_mess[mtype][i].buf2); 562 sprintf (buf1, "%s %s%s", attack_mess[mtype][i].buf1, &op->name, attack_mess[mtype][i].buf2);
579 strcpy (buf2, attack_mess[mtype][i].buf3); 563 strcpy (buf2, attack_mess[mtype][i].buf3);
689 if (QUERY_FLAG (*target, FLAG_FREED) || QUERY_FLAG (*hitter, FLAG_FREED)) 673 if (QUERY_FLAG (*target, FLAG_FREED) || QUERY_FLAG (*hitter, FLAG_FREED))
690 { 674 {
691 LOG (llevError, "BUG: get_attack_mode(): freed object\n"); 675 LOG (llevError, "BUG: get_attack_mode(): freed object\n");
692 return 1; 676 return 1;
693 } 677 }
678
694 if ((*target)->head) 679 if ((*target)->head)
695 *target = (*target)->head; 680 *target = (*target)->head;
681
696 if ((*hitter)->head) 682 if ((*hitter)->head)
697 *hitter = (*hitter)->head; 683 *hitter = (*hitter)->head;
684
685 if ((*target)->type == LOCKED_DOOR)
686 return 1; // locked doors cannot be hit
687
698 if ((*hitter)->env != NULL || (*target)->env != NULL) 688 if ((*hitter)->env || (*target)->env)
699 { 689 {
700 *simple_attack = 1; 690 *simple_attack = 1;
701 return 0; 691 return 0;
702 } 692 }
693
703 if (QUERY_FLAG (*target, FLAG_REMOVED) 694 if (QUERY_FLAG (*target, FLAG_REMOVED)
704 || QUERY_FLAG (*hitter, FLAG_REMOVED) || (*hitter)->map == NULL || !on_same_map ((*hitter), (*target))) 695 || QUERY_FLAG (*hitter, FLAG_REMOVED)
696 || !(*hitter)->map
697 || !on_same_map (*hitter, *target))
705 { 698 {
706 LOG (llevError, "BUG: hitter (arch %s, name %s) with no relation to " "target\n", &(*hitter)->arch->archname, &(*hitter)->name); 699 LOG (llevError | logBacktrace, "BUG: hitter (%s) with no relation to target (%s)\n",
700 (*hitter)->debug_desc (), (*target)->debug_desc ());
707 return 1; 701 return 1;
708 } 702 }
703
709 *simple_attack = 0; 704 *simple_attack = 0;
710 return 0; 705 return 0;
711} 706}
712 707
713static int 708static int
877 * debate - 5000 is 5 kg, so arrows, knives, and other light weapons 872 * debate - 5000 is 5 kg, so arrows, knives, and other light weapons
878 * stick around. 873 * stick around.
879 */ 874 */
880 if (op->weight <= 5000 && tmp->stats.hp >= 0) 875 if (op->weight <= 5000 && tmp->stats.hp >= 0)
881 { 876 {
882 tmp = tmp->head_ (); 877 tmp->head_ ()->insert (op);
883
884 op->remove ();
885 op = insert_ob_in_ob (op, tmp);
886
887 if (tmp->type == PLAYER)
888 esrv_send_item (tmp, op);
889
890 return 1; 878 return 1;
891 } 879 }
892 else 880 else
893 return 0; 881 return 0;
894} 882}
1208 1196
1209 /* High damage acid has better chance of corroding 1197 /* High damage acid has better chance of corroding
1210 objects */ 1198 objects */
1211 if (rndm (0, dam + 4) > random_roll (0, 39, op, PREFER_HIGH) + 2 * tmp->magic) 1199 if (rndm (0, dam + 4) > random_roll (0, 39, op, PREFER_HIGH) + 2 * tmp->magic)
1212 { 1200 {
1213 if (op->type == PLAYER)
1214 /* Make this more visible */
1215 new_draw_info_format (NDI_UNIQUE | NDI_RED, 0, op,
1216 "The %s's acid corrodes your %s!", query_name (hitter), query_name (tmp));
1217 flag = 1; 1201 flag = 1;
1218 tmp->magic--; 1202 tmp->magic--;
1219 if (op->type == PLAYER) 1203
1220 esrv_send_item (op, tmp); 1204 if (object *pl = tmp->visible_to ())
1205 {
1206 /* Make this more visible */
1207 new_draw_info_format (NDI_UNIQUE | NDI_RED, 0, pl,
1208 "The %s's acid corrodes your %s!", query_name (hitter), query_name (tmp));
1209
1210 esrv_send_item (op, tmp); //TODO: UPD_NAME should be enough (it's enough in other cases)
1211 }
1221 } 1212 }
1222 } 1213 }
1223 1214
1224 if (flag) 1215 if (flag)
1225 op->update_stats (); /* Something was corroded */ 1216 op->update_stats (); /* Something was corroded */
1447 pk = 1; 1438 pk = 1;
1448 1439
1449 /* Player killed something */ 1440 /* Player killed something */
1450 if (owner->type == PLAYER) 1441 if (owner->type == PLAYER)
1451 { 1442 {
1452 Log_Kill (owner->name,
1453 query_name (op), op->type, (owner != hitter) ? query_name (hitter) : NULL, (owner != hitter) ? hitter->type : 0);
1454
1455 /* Log players killing other players - makes it easier to detect 1443 /* Log players killing other players - makes it easier to detect
1456 * and filter out malicious player killers - that is why the 1444 * and filter out malicious player killers - that is why the
1457 * ip address is included. 1445 * ip address is included.
1458 */ 1446 */
1459 if (op->type == PLAYER && !battleg) 1447 if (op->type == PLAYER && !battleg)
1636 } 1624 }
1637 1625
1638 op->destroy (); 1626 op->destroy ();
1639 } 1627 }
1640 else 1628 else
1641 {
1642 /* Player has been killed! */ 1629 /* Player has been killed! */
1643 if (owner->type == PLAYER) 1630 op->contr->killer = owner->type == PLAYER ? owner : hitter;
1644 snprintf (op->contr->killer, sizeof (op->contr->killer), "%s the %s", &owner->name, owner->contr->title);
1645 else
1646 assign (op->contr->killer, hitter->name);
1647 }
1648 1631
1649 /* This was return -1 - that doesn't seem correct - if we return -1, process 1632 /* This was return -1 - that doesn't seem correct - if we return -1, process
1650 * continues in the calling function. 1633 * continues in the calling function.
1651 */ 1634 */
1652 return maxdam; 1635 return maxdam;
1958 return maxdam; 1941 return maxdam;
1959 } 1942 }
1960 1943
1961 op->remove (); 1944 op->remove ();
1962 1945
1963 for (i = 0; i < NROFNEWOBJS (op); i++) 1946 for (i = 0; i < op->stats.food; i++)
1964 { /* This doesn't handle op->more yet */ 1947 { /* This doesn't handle op->more yet */
1965 object *tmp = arch_to_object (op->other_arch); 1948 object *tmp = arch_to_object (op->other_arch);
1966 int j; 1949 int j;
1967 1950
1968 tmp->stats.hp = op->stats.hp; 1951 tmp->stats.hp = op->stats.hp;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines