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

Comparing deliantra/server/server/spell_attack.C (file contents):
Revision 1.57 by root, Sat May 17 14:11:13 2008 UTC vs.
Revision 1.58 by root, Sat May 17 14:57:23 2008 UTC

39 * op is the spell object. 39 * op is the spell object.
40 */ 40 */
41void 41void
42check_spell_knockback (object *op) 42check_spell_knockback (object *op)
43{ 43{
44 object *tmp, *tmp2; /* object on the map */
45 int weight_move; 44 int weight_move;
46 int frictionmod = 2; /*poor man's physics - multipy targets weight by this amount */ 45 int frictionmod = 2; /*poor man's physics - multipy targets weight by this amount */
47 46
48 if (!op->weight) 47 if (!op->weight)
49 { /*shouldn't happen but if cone object has no weight drop out */ 48 { /*shouldn't happen but if cone object has no weight drop out */
54 { 53 {
55 weight_move = op->weight + (op->weight * op->level) / 3; 54 weight_move = op->weight + (op->weight * op->level) / 3;
56 /*LOG (llevDebug, "DEBUG: arch weighs %d and masses %d (%s,level %d)\n", op->weight,weight_move,op->name,op->level); */ 55 /*LOG (llevDebug, "DEBUG: arch weighs %d and masses %d (%s,level %d)\n", op->weight,weight_move,op->name,op->level); */
57 } 56 }
58 57
59 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 58 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
60 { 59 {
61 int num_sections = 1; 60 int num_sections = 1;
62 61
63 /* don't move DM */ 62 /* don't move DM */
64 if (QUERY_FLAG (tmp, FLAG_WIZ)) 63 if (QUERY_FLAG (tmp, FLAG_WIZ))
71 /* don't move floors or immobile objects */ 70 /* don't move floors or immobile objects */
72 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) || (!QUERY_FLAG (tmp, FLAG_ALIVE) && QUERY_FLAG (tmp, FLAG_NO_PICK))) 71 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) || (!QUERY_FLAG (tmp, FLAG_ALIVE) && QUERY_FLAG (tmp, FLAG_NO_PICK)))
73 continue; 72 continue;
74 73
75 /* count the object's sections */ 74 /* count the object's sections */
76 for (tmp2 = tmp; tmp2 != NULL; tmp2 = tmp2->more) 75 for (object *tmp2 = tmp; tmp2; tmp2 = tmp2->more)
77 num_sections++; 76 num_sections++;
78 77
79 /* I'm not sure if it makes sense to divide by num_sections - bigger 78 /* I'm not sure if it makes sense to divide by num_sections - bigger
80 * objects should be harder to move, and we are moving the entire 79 * objects should be harder to move, and we are moving the entire
81 * object, not just the head, so the total weight should be relevant. 80 * object, not just the head, so the total weight should be relevant.
156} 155}
157 156
158/* move_bolt: moves bolt 'op'. Basically, it just advances a space, 157/* move_bolt: moves bolt 'op'. Basically, it just advances a space,
159 * and checks for various things that may stop it. 158 * and checks for various things that may stop it.
160 */ 159 */
161
162void 160void
163move_bolt (object *op) 161move_bolt (object *op)
164{ 162{
165 int mflags; 163 int mflags;
166 sint16 x, y; 164 sint16 x, y;
249 tmp->duration++; 247 tmp->duration++;
250 248
251 /* New forking code. Possibly create forks of this object 249 /* New forking code. Possibly create forks of this object
252 * going off in other directions. 250 * going off in other directions.
253 */ 251 */
254 if (rndm (0, 99) < tmp->stats.Dex) 252 if (tmp->stats.Dex && rndm (0, 99) < tmp->stats.Dex)
255 { /* stats.Dex % of forking */ 253 forklightning (op, tmp); /* stats.Dex % of forking */
256 forklightning (op, tmp);
257 }
258 254
259 /* In this way, the object left behind sticks on the space, but 255 /* In this way, the object left behind sticks on the space, but
260 * doesn't create any bolts that continue to move onward. 256 * doesn't create any bolts that continue to move onward.
261 */ 257 */
262 op->range = 0; 258 op->range = 0;
286 return 0; 282 return 0;
287 283
288 /* peterm: level dependency for bolts */ 284 /* peterm: level dependency for bolts */
289 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob); 285 tmp->stats.dam = spob->stats.dam + SP_level_dam_adjust (caster, spob);
290 tmp->attacktype = spob->attacktype; 286 tmp->attacktype = spob->attacktype;
287
291 if (spob->slaying) 288 if (spob->slaying)
292 tmp->slaying = spob->slaying; 289 tmp->slaying = spob->slaying;
290
293 tmp->range = spob->range + SP_level_range_adjust (caster, spob); 291 tmp->range = spob->range + SP_level_range_adjust (caster, spob);
294 tmp->duration = spob->duration + SP_level_duration_adjust (caster, spob); 292 tmp->duration = spob->duration + SP_level_duration_adjust (caster, spob);
295 tmp->stats.Dex = spob->stats.Dex; 293 tmp->stats.Dex = spob->stats.Dex;
296 tmp->stats.Con = spob->stats.Con; 294 tmp->stats.Con = spob->stats.Con;
297 295
433 } 431 }
434 432
435 if (op->attacktype) 433 if (op->attacktype)
436 { 434 {
437 hit_map (op, 0, op->attacktype, 1); 435 hit_map (op, 0, op->attacktype, 1);
436
438 if (op->destroyed ()) 437 if (op->destroyed ())
439 return; 438 return;
440 } 439 }
441 440
442 /* other_arch contains what this explodes into */ 441 /* other_arch contains what this explodes into */
520 for (tmp = op->ms ().bot; tmp; tmp = tmp->above) 519 for (tmp = op->ms ().bot; tmp; tmp = tmp->above)
521 { 520 {
522 if (QUERY_FLAG (tmp, FLAG_ALIVE)) 521 if (QUERY_FLAG (tmp, FLAG_ALIVE))
523 { 522 {
524 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1); 523 dam = hit_player (tmp, op->stats.dam, op, op->attacktype, 1);
524
525 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0) 525 if (op->destroyed () || !tmp->destroyed () || (op->stats.dam -= dam) < 0)
526 { 526 {
527 if (!QUERY_FLAG (op, FLAG_REMOVED)) 527 if (!QUERY_FLAG (op, FLAG_REMOVED))
528 { 528 {
529 op->destroy (); 529 op->destroy ();
703/* move_cone: causes cone object 'op' to move a space/hit creatures */ 703/* move_cone: causes cone object 'op' to move a space/hit creatures */
704 704
705void 705void
706move_cone (object *op) 706move_cone (object *op)
707{ 707{
708 int i;
709
710 /* if no map then hit_map will crash so just ignore object */ 708 /* if no map then hit_map will crash so just ignore object */
711 if (!op->map) 709 if (!op->map)
712 { 710 {
713 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown"); 711 LOG (llevError, "Tried to move_cone object %s without a map.\n", op->name ? &op->name : "unknown");
714 op->set_speed (0); 712 op->set_speed (0);
759 { 757 {
760 op->range = 0; /* just so it doesn't wrap */ 758 op->range = 0; /* just so it doesn't wrap */
761 return; 759 return;
762 } 760 }
763 761
764 for (i = -1; i < 2; i++) 762 for (int i = -1; i <= 1; i++)
765 { 763 {
766 sint16 x = op->x + freearr_x[absdir (op->stats.sp + i)], y = op->y + freearr_y[absdir (op->stats.sp + i)]; 764 sint16 x = op->x + freearr_x[absdir (op->stats.sp + i)], y = op->y + freearr_y[absdir (op->stats.sp + i)];
767 765
768 if (ok_to_put_more (op->map, x, y, op, op->attacktype)) 766 if (ok_to_put_more (op->map, x, y, op, op->attacktype))
769 { 767 {
1178 1176
1179/* op is a missile that needs to be moved */ 1177/* op is a missile that needs to be moved */
1180void 1178void
1181move_missile (object *op) 1179move_missile (object *op)
1182{ 1180{
1183 int i, mflags;
1184 object *owner;
1185 sint16 new_x, new_y;
1186 maptile *m;
1187
1188 if (op->range-- <= 0) 1181 if (op->range-- <= 0)
1189 { 1182 {
1190 op->destroy (); 1183 op->destroy ();
1191 return; 1184 return;
1192 } 1185 }
1193 1186
1194 owner = op->owner; 1187 mapxy pos (op);
1195#if 0 1188 pos.move (op->direction);
1196 /* It'd make things nastier if this wasn't here - spells cast by 1189
1197 * monster that are then killed would continue to survive 1190 if (!pos.normalise ())
1198 */
1199 if (owner == NULL)
1200 { 1191 {
1201 op->destroy (); 1192 op->destroy ();
1202 return; 1193 return;
1203 } 1194 }
1204#endif
1205 1195
1206 new_x = op->x + DIRX (op); 1196 mapspace &ms = pos.ms ();
1207 new_y = op->y + DIRY (op);
1208 1197
1209 mflags = get_map_flags (op->map, &m, new_x, new_y, &new_x, &new_y); 1198 if (ms.flags () & P_IS_ALIVE || ms.blocks (op))
1210
1211 if (!(mflags & P_OUT_OF_MAP) && ((mflags & P_IS_ALIVE) || OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, new_x, new_y))))
1212 { 1199 {
1213 hit_map (op, op->direction, AT_MAGIC, 1); 1200 hit_map (op, op->direction, AT_MAGIC, 1);
1214 /* Basically, missile only hits one thing then goes away. 1201 /* Basically, missile only hits one thing then goes away.
1215 * we need to remove it if someone hasn't already done so. 1202 * we need to remove it if someone hasn't already done so.
1216 */ 1203 */
1217 if (!op->destroyed ())
1218 op->destroy ();
1219
1220 return;
1221 }
1222
1223 op->remove ();
1224
1225 if (!op->direction || (mflags & P_OUT_OF_MAP))
1226 {
1227 op->destroy (); 1204 op->destroy ();
1228 return; 1205 return;
1229 } 1206 }
1230 1207
1208 if (!op->direction)
1209 {
1210 op->destroy ();
1211 return;
1212 }
1213
1231 i = spell_find_dir (m, new_x, new_y, op->owner); 1214 int i = spell_find_dir (pos.m, pos.x, pos.y, op->owner);
1232 if (i > 0 && i != op->direction) 1215 if (i > 0 && i != op->direction)
1233 { 1216 {
1234 op->direction = i; 1217 op->direction = i;
1235 SET_ANIMATION (op, op->direction); 1218 SET_ANIMATION (op, op->direction);
1236 } 1219 }
1237 1220
1238 m->insert (op, new_x, new_y, op); 1221 pos.insert (op, op);
1239} 1222}
1240 1223
1241/**************************************************************************** 1224/****************************************************************************
1242 * Destruction 1225 * Destruction
1243 ****************************************************************************/ 1226 ****************************************************************************/
1300 else 1283 else
1301 op->skill = NULL; 1284 op->skill = NULL;
1302 1285
1303 op->change_skill (find_skill_by_name (op, op->skill)); 1286 op->change_skill (find_skill_by_name (op, op->skill));
1304 1287
1305 for (i = -range; i < range; i++) 1288 for (i = -range; i <= range; i++)
1306 { 1289 {
1307 for (j = -range; j < range; j++) 1290 for (j = -range; j <= range; j++)
1308 { 1291 {
1309 m = op->map; 1292 m = op->map;
1310 sx = op->x + i; 1293 sx = op->x + i;
1311 sy = op->y + j; 1294 sy = op->y + j;
1312 1295
1329 (!friendly && (QUERY_FLAG (tmp, FLAG_FRIENDLY) || tmp->type == PLAYER))) 1312 (!friendly && (QUERY_FLAG (tmp, FLAG_FRIENDLY) || tmp->type == PLAYER)))
1330 { 1313 {
1331 if (spell_ob->subtype == SP_DESTRUCTION) 1314 if (spell_ob->subtype == SP_DESTRUCTION)
1332 { 1315 {
1333 hit_player (tmp, dam, op, spell_ob->attacktype, 0); 1316 hit_player (tmp, dam, op, spell_ob->attacktype, 0);
1317
1334 if (spell_ob->other_arch) 1318 if (spell_ob->other_arch)
1335 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op); 1319 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op);
1336 } 1320 }
1337 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100) 1321 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100)
1338 { 1322 {
1702 1686
1703 if ((mflags & P_IS_ALIVE) && (!owner || owner->x != hx || owner->y != hy || !on_same_map (owner, op))) 1687 if ((mflags & P_IS_ALIVE) && (!owner || owner->x != hx || owner->y != hy || !on_same_map (owner, op)))
1704 { 1688 {
1705 if (j) 1689 if (j)
1706 op->stats.dam = dam_save / 2; 1690 op->stats.dam = dam_save / 2;
1691
1707 hit_map (op, j, op->attacktype, 1); 1692 hit_map (op, j, op->attacktype, 1);
1708
1709 } 1693 }
1710 1694
1711 /* insert the other arch */ 1695 /* insert the other arch */
1712 if (op->other_arch && !(OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy)))) 1696 if (op->other_arch && !(OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, hx, hy))))
1713 m->insert (arch_to_object (op->other_arch), hx, hy, op); 1697 m->insert (arch_to_object (op->other_arch), hx, hy, op);
1911 if (QUERY_FLAG (target, FLAG_MONSTER)) 1895 if (QUERY_FLAG (target, FLAG_MONSTER))
1912 { 1896 {
1913 /* oky doky. got a target monster. Lets make a blinding attack */ 1897 /* oky doky. got a target monster. Lets make a blinding attack */
1914 if (target->head) 1898 if (target->head)
1915 target = target->head; 1899 target = target->head;
1900
1916 (void) hit_player (target, dam, op, spell->attacktype, 1); 1901 hit_player (target, dam, op, spell->attacktype, 1);
1917 return 1; /* one success only! */ 1902 return 1; /* one success only! */
1918 } 1903 }
1919 } 1904 }
1920 1905
1921 /* no live target, perhaps a wall is in the way? */ 1906 /* no live target, perhaps a wall is in the way? */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines