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.68 by elmex, Mon Oct 6 08:46:33 2008 UTC vs.
Revision 1.74 by root, Sun Dec 28 07:48:44 2008 UTC

1008 int mflags; 1008 int mflags;
1009 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir]; 1009 sint16 dx = op->x + freearr_x[dir], dy = op->y + freearr_y[dir];
1010 maptile *m; 1010 maptile *m;
1011 1011
1012 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy); 1012 mflags = get_map_flags (op->map, &m, dx, dy, &dx, &dy);
1013
1014 // when creating a bomb below ourself it should always work, even
1015 // when movement is blocked (somehow we got here, somehow we are here,
1016 // so we should also be able to make a bomb here). (originally added
1017 // to fix create bomb traps in doors, which cast with dir=0).
1018 if (dir)
1019 {
1013 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK)) 1020 if ((mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, dx, dy) & MOVE_WALK))
1014 { 1021 {
1015 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way."); 1022 new_draw_info (NDI_UNIQUE, 0, op, "There is something in the way.");
1016 return 0; 1023 return 0;
1024 }
1017 } 1025 }
1018 1026
1019 tmp = arch_to_object (spell->other_arch); 1027 tmp = arch_to_object (spell->other_arch);
1020 1028
1021 /* level dependencies for bomb */ 1029 /* level dependencies for bomb */
1250 1258
1251 object *tmp = get_archetype (FORCE_NAME); 1259 object *tmp = get_archetype (FORCE_NAME);
1252 tmp->speed = 0.01; 1260 tmp->speed = 0.01;
1253 tmp->stats.food = time; 1261 tmp->stats.food = time;
1254 SET_FLAG (tmp, FLAG_IS_USED_UP); 1262 SET_FLAG (tmp, FLAG_IS_USED_UP);
1255 tmp->glow_radius = radius;
1256 if (tmp->glow_radius > MAX_LIGHT_RADII)
1257 tmp->glow_radius = MAX_LIGHT_RADII; 1263 tmp->glow_radius = min (MAX_LIGHT_RADIUS, radius);
1258
1259 tmp = insert_ob_in_ob (tmp, op); 1264 tmp = insert_ob_in_ob (tmp, op);
1260 1265
1261 if (tmp->glow_radius > op->glow_radius) 1266 if (tmp->glow_radius > op->glow_radius)
1262 op->glow_radius = tmp->glow_radius; 1267 op->glow_radius = tmp->glow_radius;
1263 1268
1265} 1270}
1266 1271
1267int 1272int
1268cast_destruction (object *op, object *caster, object *spell_ob) 1273cast_destruction (object *op, object *caster, object *spell_ob)
1269{ 1274{
1270 int i, j, range, mflags, friendly = 0, dam, dur;
1271 sint16 sx, sy;
1272 maptile *m;
1273 object *tmp;
1274 const char *skill;
1275
1276 range = spell_ob->range + SP_level_range_adjust (caster, spell_ob); 1275 int range = spell_ob->range + SP_level_range_adjust (caster, spell_ob);
1277 dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob); 1276 int dam = spell_ob->stats.dam + SP_level_dam_adjust (caster, spell_ob);
1278 dur = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob); 1277 int dur = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
1279 if (QUERY_FLAG (op, FLAG_FRIENDLY) || op->type == PLAYER) 1278
1280 friendly = 1; 1279 bool friendly = op->flag [FLAG_FRIENDLY] || op->is_player ();
1281 1280
1282 /* destruction doesn't use another spell object, so we need 1281 /* destruction doesn't use another spell object, so we need
1283 * update op's skill pointer so that exp is properly awarded. 1282 * update op's skill pointer so that exp is properly awarded.
1284 * We do some shortcuts here - since this is just temporary
1285 * and we'll reset the values back, we don't need to go through
1286 * the full share string/free_string route.
1287 */ 1283 */
1288 skill = op->skill; 1284 const shstr skill = op->skill;
1285
1289 if (caster == op) 1286 if (caster == op)
1290 op->skill = spell_ob->skill; 1287 op->skill = spell_ob->skill;
1291 else if (caster->skill) 1288 else if (caster->skill)
1292 op->skill = caster->skill; 1289 op->skill = caster->skill;
1293 else 1290 else
1294 op->skill = NULL; 1291 op->skill = 0;
1295 1292
1296 op->change_skill (find_skill_by_name (op, op->skill)); 1293 op->change_skill (find_skill_by_name (op, op->skill));
1297 1294
1298 for (i = -range; i <= range; i++) 1295 unordered_mapwalk (op, -range, -range, range, range)
1299 { 1296 {
1300 for (j = -range; j <= range; j++) 1297 mapspace &ms = m->at (nx, ny);
1301 {
1302 m = op->map;
1303 sx = op->x + i;
1304 sy = op->y + j;
1305 1298
1306 mflags = get_map_flags (m, &m, sx, sy, &sx, &sy);
1307 if (mflags & P_OUT_OF_MAP)
1308 continue;
1309
1310 if (mflags & P_IS_ALIVE) 1299 if (ms.flags () & P_IS_ALIVE)
1300 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1301 if (tmp->flag [FLAG_ALIVE] || tmp->is_player ())
1311 { 1302 {
1312 for (tmp = GET_MAP_OB (m, sx, sy); tmp; tmp = tmp->above) 1303 tmp = tmp->head_ ();
1313 if (QUERY_FLAG (tmp, FLAG_ALIVE) || tmp->type == PLAYER)
1314 break;
1315 1304
1316 if (tmp) 1305 if ((friendly && !tmp->flag [FLAG_FRIENDLY] && !tmp->is_player ())
1306 || (!friendly && (tmp->flag [FLAG_FRIENDLY] || tmp->is_player ())))
1317 { 1307 {
1318 if (tmp->head) 1308 if (spell_ob->subtype == SP_DESTRUCTION)
1319 tmp = tmp->head;
1320
1321 if ((friendly && !QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->type != PLAYER) ||
1322 (!friendly && (QUERY_FLAG (tmp, FLAG_FRIENDLY) || tmp->type == PLAYER)))
1323 { 1309 {
1324 if (spell_ob->subtype == SP_DESTRUCTION)
1325 {
1326 hit_player (tmp, dam, op, spell_ob->attacktype, 0); 1310 hit_player (tmp, dam, op, spell_ob->attacktype, 0);
1327 1311
1328 if (spell_ob->other_arch) 1312 if (spell_ob->other_arch)
1329 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op); 1313 m->insert (arch_to_object (spell_ob->other_arch), nx, ny, op);
1330 } 1314 }
1331 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist[ATNR_MAGIC] != 100) 1315 else if (spell_ob->subtype == SP_FAERY_FIRE && tmp->resist [ATNR_MAGIC] != 100)
1332 { 1316 {
1333 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch) 1317 if (make_object_glow (tmp, 1, dur) && spell_ob->other_arch)
1334 m->insert (arch_to_object (spell_ob->other_arch), sx, sy, op); 1318 m->insert (arch_to_object (spell_ob->other_arch), nx, ny, op);
1335 }
1336 } 1319 }
1337 } 1320 }
1338 } 1321 }
1339 }
1340 } 1322 }
1341 1323
1342 op->skill = skill; 1324 op->skill = skill;
1343 return 1; 1325 return 1;
1344} 1326}
1492 /* If there is nothing living on this space, no need to go further */ 1474 /* If there is nothing living on this space, no need to go further */
1493 if (!(mflags & P_IS_ALIVE)) 1475 if (!(mflags & P_IS_ALIVE))
1494 continue; 1476 continue;
1495 1477
1496 // players can only affect spaces that they can actually see 1478 // players can only affect spaces that they can actually see
1479 if (caster
1497 if (caster && caster->contr 1480 && caster->contr
1498 && caster->contr->visibility_at (m, nx, ny) < 70) 1481 && caster->contr->darkness_at (m, nx, ny) == LOS_BLOCKED)
1499 continue; 1482 continue;
1500 1483
1501 for (tmp = GET_MAP_TOP (m, nx, ny); tmp; tmp = tmp->below) 1484 for (tmp = GET_MAP_TOP (m, nx, ny); tmp; tmp = tmp->below)
1502 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1485 if (QUERY_FLAG (tmp, FLAG_MONSTER))
1503 break; 1486 break;
1613 } /* for y */ 1596 } /* for y */
1614 1597
1615 return 1; 1598 return 1;
1616} 1599}
1617 1600
1618
1619/* Move_ball_spell: This handles ball type spells that just sort of wander 1601/* Move_ball_spell: This handles ball type spells that just sort of wander
1620 * about. was called move_ball_lightning, but since more than the ball 1602 * about. was called move_ball_lightning, but since more than the ball
1621 * lightning spell used it, that seemed misnamed. 1603 * lightning spell used it, that seemed misnamed.
1622 * op is the spell effect. 1604 * op is the spell effect.
1623 * note that duration is handled by process_object() in time.c 1605 * note that duration is handled by process_object() in time.c
1648 for (i = 1; i < 9; i++) 1630 for (i = 1; i < 9; i++)
1649 { 1631 {
1650 /* i bit 0: alters sign of offset 1632 /* i bit 0: alters sign of offset
1651 * other bits (i / 2): absolute value of offset 1633 * other bits (i / 2): absolute value of offset
1652 */ 1634 */
1653
1654 int offset = ((i ^ j) & 1) ? (i / 2) : -(i / 2); 1635 int offset = ((i ^ j) & 1) ? (i / 2) : -(i / 2);
1655 int tmpdir = absdir (op->direction + offset); 1636 int tmpdir = absdir (op->direction + offset);
1656 1637
1657 nx = op->x + freearr_x[tmpdir]; 1638 nx = op->x + freearr_x[tmpdir];
1658 ny = op->y + freearr_y[tmpdir]; 1639 ny = op->y + freearr_y[tmpdir];
1660 { 1641 {
1661 dir = tmpdir; 1642 dir = tmpdir;
1662 break; 1643 break;
1663 } 1644 }
1664 } 1645 }
1646
1665 if (dir == 0) 1647 if (dir == 0)
1666 { 1648 {
1667 nx = op->x; 1649 nx = op->x;
1668 ny = op->y; 1650 ny = op->y;
1669 m = op->map; 1651 m = op->map;
1890 int dam, mflags; 1872 int dam, mflags;
1891 maptile *m; 1873 maptile *m;
1892 1874
1893 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell); 1875 dam = spell->stats.dam + SP_level_dam_adjust (caster, spell);
1894 1876
1895 if (!dir) 1877 if (dir)
1896 {
1897 new_draw_info (NDI_UNIQUE, 0, op, "In what direction?");
1898 return 0;
1899 } 1878 {
1900
1901 x = op->x + freearr_x[dir]; 1879 x = op->x + freearr_x[dir];
1902 y = op->y + freearr_y[dir]; 1880 y = op->y + freearr_y[dir];
1903 m = op->map; 1881 m = op->map;
1904 1882
1905 mflags = get_map_flags (m, &m, x, y, &x, &y); 1883 mflags = get_map_flags (m, &m, x, y, &x, &y);
1906 1884
1907 if (mflags & P_OUT_OF_MAP) 1885 if (mflags & P_OUT_OF_MAP)
1908 { 1886 {
1909 new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there."); 1887 new_draw_info (NDI_UNIQUE, 0, op, "Nothing is there.");
1910 return 0; 1888 return 0;
1911 } 1889 }
1912 1890
1913 if (mflags & P_IS_ALIVE && spell->attacktype) 1891 if (mflags & P_IS_ALIVE && spell->attacktype)
1914 { 1892 {
1915 for (target = GET_MAP_OB (m, x, y); target; target = target->above) 1893 for (target = GET_MAP_OB (m, x, y); target; target = target->above)
1916 if (QUERY_FLAG (target, FLAG_MONSTER)) 1894 if (QUERY_FLAG (target, FLAG_MONSTER))
1917 { 1895 {
1918 /* oky doky. got a target monster. Lets make a blinding attack */ 1896 /* oky doky. got a target monster. Lets make a blinding attack */
1919 if (target->head) 1897 if (target->head)
1920 target = target->head; 1898 target = target->head;
1921 1899
1922 hit_player (target, dam, op, spell->attacktype, 1); 1900 hit_player (target, dam, op, spell->attacktype, 1);
1923 return 1; /* one success only! */ 1901 return 1; /* one success only! */
1902 }
1924 } 1903 }
1925 }
1926 1904
1927 /* no live target, perhaps a wall is in the way? */ 1905 /* no live target, perhaps a wall is in the way? */
1928 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y))) 1906 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)))
1929 { 1907 {
1930 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way."); 1908 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
1931 return 0; 1909 return 0;
1910 }
1932 } 1911 }
1933 1912
1934 /* ok, looks groovy to just insert a new light on the map */ 1913 /* ok, looks groovy to just insert a new light on the map */
1935 tmp = arch_to_object (spell->other_arch); 1914 tmp = arch_to_object (spell->other_arch);
1936 if (!tmp) 1915 if (!tmp)
1937 { 1916 {
1938 LOG (llevError, "Error: spell arch for cast_light() missing.\n"); 1917 LOG (llevError, "Error: spell arch for cast_light() missing.\n");
1939 return 0; 1918 return 0;
1940 } 1919 }
1920
1941 tmp->stats.food = spell->duration + SP_level_duration_adjust (caster, spell); 1921 tmp->stats.food = spell->duration + SP_level_duration_adjust (caster, spell);
1922
1942 if (tmp->glow_radius) 1923 if (tmp->glow_radius)
1943 {
1944 tmp->glow_radius = spell->range + SP_level_range_adjust (caster, spell); 1924 tmp->glow_radius = min (MAX_LIGHT_RADIUS, spell->range + SP_level_range_adjust (caster, spell));
1945 if (tmp->glow_radius > MAX_LIGHT_RADII)
1946 tmp->glow_radius = MAX_LIGHT_RADII;
1947 }
1948 1925
1926 if (dir)
1949 m->insert (tmp, x, y, op); 1927 m->insert (tmp, x, y, op);
1928 else
1929 caster->outer_env ()->insert (tmp);
1930
1950 return 1; 1931 return 1;
1951} 1932}
1952 1933
1953/* cast_cause_disease: this spell looks along <dir> from the 1934/* cast_cause_disease: this spell looks along <dir> from the
1954 * player and infects someone. 1935 * player and infects someone.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines