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

Comparing deliantra/server/server/spell_effect.C (file contents):
Revision 1.89 by root, Mon Sep 29 06:32:09 2008 UTC vs.
Revision 1.99 by elmex, Tue Jan 13 13:29:57 2009 UTC

345 345
346 return 1; 346 return 1;
347 } 347 }
348 348
349 /* invis_race is set if we get here */ 349 /* invis_race is set if we get here */
350 if (!strcmp (pl->contr->invis_race, "undead") && is_true_undead (mon)) 350 if (pl->contr->invis_race == shstr_undead && is_true_undead (mon))
351 return 1; 351 return 1;
352 352
353 /* No race, can't be invisible to it */ 353 /* No race, can't be invisible to it */
354 if (!mon->race) 354 if (!mon->race)
355 return 0; 355 return 0;
356 356
357 if (strstr (mon->race, pl->contr->invis_race)) 357 if (mon->race.contains (pl->contr->invis_race))
358 return 1; 358 return 1;
359 359
360 /* Nothing matched above, return 0 */ 360 /* Nothing matched above, return 0 */
361 return 0; 361 return 0;
362 } 362 }
1549 range = spell->range + SP_level_range_adjust (caster, spell); 1549 range = spell->range + SP_level_range_adjust (caster, spell);
1550 1550
1551 if (!skill) 1551 if (!skill)
1552 skill = caster; 1552 skill = caster;
1553 1553
1554 for (x = op->x - range; x <= op->x + range; x++) 1554 unordered_mapwalk (op, -range, -range, range, range)
1555 for (y = op->y - range; y <= op->y + range; y++)
1556 { 1555 {
1557 m = op->map;
1558 mflags = get_map_flags (m, &m, x, y, &nx, &ny);
1559 if (mflags & P_OUT_OF_MAP)
1560 continue;
1561
1562 /* For most of the detections, we only detect objects above the 1556 /* For most of the detections, we only detect objects above the
1563 * floor. But this is not true for show invisible. 1557 * floor. But this is not true for show invisible.
1564 * Basically, we just go and find the top object and work 1558 * Basically, we just go and find the top object and work
1565 * down - that is easier than working up. 1559 * down - that is easier than working up.
1566 */ 1560 */
1567 1561
1568 for (last = NULL, tmp = GET_MAP_OB (m, nx, ny); tmp; tmp = tmp->above) 1562 for (last = NULL, tmp = m->at (nx, ny).bot; tmp; tmp = tmp->above)
1569 last = tmp; 1563 last = tmp;
1570 1564
1571 /* Shouldn't happen, but if there are no objects on a space, this 1565 /* Shouldn't happen, but if there are no objects on a space, this
1572 * would happen. 1566 * would happen.
1573 */ 1567 */
1574 if (!last) 1568 if (!last)
1575 continue; 1569 continue;
1576 1570
1577 done_one = 0; 1571 done_one = 0;
1578 floor = 0; 1572 floor = 0;
1579 detect = NULL; 1573 detect = NULL;
1580 for (tmp = last; tmp; tmp = tmp->below) 1574 for (tmp = last; tmp; tmp = tmp->below)
1581 { 1575 {
1582 /* show invisible */ 1576 /* show invisible */
1583 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) && 1577 if (QUERY_FLAG (spell, FLAG_MAKE_INVIS) &&
1584 /* Might there be other objects that we can make visible? */ 1578 /* Might there be other objects that we can make visible? */
1585 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) || 1579 (tmp->invisible && (QUERY_FLAG (tmp, FLAG_MONSTER) ||
1586 (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ)) || 1580 (tmp->type == PLAYER && !QUERY_FLAG (tmp, FLAG_WIZ))
1587 tmp->type == CF_HANDLE || 1581 || tmp->type == CF_HANDLE
1588 tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE || 1582 || tmp->type == TRAPDOOR || tmp->type == EXIT || tmp->type == HOLE
1589 tmp->type == BUTTON || tmp->type == TELEPORTER || 1583 || tmp->type == BUTTON || tmp->type == TELEPORTER
1590 tmp->type == GATE || tmp->type == LOCKED_DOOR || 1584 || tmp->type == GATE || tmp->type == LOCKED_DOOR
1591 tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN || 1585 || tmp->type == WEAPON || tmp->type == ALTAR || tmp->type == SIGN
1592 tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY || 1586 || tmp->type == TRIGGER_PEDESTAL || tmp->type == SPECIAL_KEY
1593 tmp->type == TREASURE || tmp->type == BOOK || tmp->type == HOLY_ALTAR))) 1587 || tmp->type == TREASURE || tmp->type == BOOK || tmp->type == HOLY_ALTAR)))
1594 { 1588 {
1595 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4) 1589 if (random_roll (0, skill->level - 1, op, PREFER_HIGH) > level / 4)
1596 { 1590 {
1597 tmp->invisible = 0; 1591 tmp->invisible = 0;
1598 done_one = 1; 1592 done_one = 1;
1599 } 1593 }
1600 } 1594 }
1601 1595
1602 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) 1596 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
1603 floor = 1; 1597 floor = 1;
1604 1598
1605 /* All detections below this point don't descend beneath the floor, 1599 /* All detections below this point don't descend beneath the floor,
1606 * so just continue on. We could be clever and look at the type of 1600 * so just continue on. We could be clever and look at the type of
1607 * detection to completely break out if we don't care about objects beneath 1601 * detection to completely break out if we don't care about objects beneath
1608 * the floor, but once we get to the floor, not likely a very big issue anyways. 1602 * the floor, but once we get to the floor, not likely a very big issue anyways.
1609 */ 1603 */
1610 if (floor) 1604 if (floor)
1611 continue; 1605 continue;
1612 1606
1613 /* I had thought about making detect magic and detect curse 1607 /* I had thought about making detect magic and detect curse
1614 * show the flash the magic item like it does for detect monster. 1608 * show the flash the magic item like it does for detect monster.
1615 * however, if the object is within sight, this would then make it 1609 * however, if the object is within sight, this would then make it
1616 * difficult to see what object is magical/cursed, so the 1610 * difficult to see what object is magical/cursed, so the
1617 * effect wouldn't be as apparant. 1611 * effect wouldn't be as apparent.
1618 */ 1612 */
1619 1613
1620 /* detect magic */ 1614 /* detect magic */
1621 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) && 1615 if (QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL) &&
1622 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp)) 1616 !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && is_magical (tmp))
1623 { 1617 {
1624 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL); 1618 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
1625 /* make runes more visibile */ 1619 /* make runes more visibile */
1626 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC) 1620 if (tmp->type == RUNE && tmp->attacktype & AT_MAGIC)
1627 tmp->stats.Cha /= 4; 1621 tmp->stats.Cha /= 4;
1622
1628 done_one = 1; 1623 done_one = 1;
1629 } 1624 }
1625
1630 /* detect monster */ 1626 /* detect monster */
1631 if (QUERY_FLAG (spell, FLAG_MONSTER) && (QUERY_FLAG (tmp, FLAG_MONSTER) || tmp->type == PLAYER)) 1627 if (QUERY_FLAG (spell, FLAG_MONSTER) && (QUERY_FLAG (tmp, FLAG_MONSTER) || tmp->type == PLAYER))
1632 { 1628 {
1633 done_one = 2; 1629 done_one = 2;
1630
1634 if (!detect) 1631 if (!detect)
1635 detect = tmp; 1632 detect = tmp;
1636 } 1633 }
1634
1637 /* Basically, if race is set in the spell, then the creatures race must 1635 /* Basically, if race is set in the spell, then the creatures race must
1638 * match that. if the spell race is set to GOD, then the gods opposing 1636 * match that. if the spell race is set to GOD, then the gods opposing
1639 * race must match. 1637 * race must match.
1640 */ 1638 */
1641 if (spell->race && QUERY_FLAG (tmp, FLAG_MONSTER) && tmp->race && 1639 if (spell->race && QUERY_FLAG (tmp, FLAG_MONSTER) && tmp->race &&
1642 ((!strcmp (spell->race, "GOD") && god && god->slaying && strstr (god->slaying, tmp->race)) || 1640 ((spell->race == shstr_GOD && god && god->slaying.contains (tmp->race)) ||
1643 (strstr (spell->race, tmp->race)))) 1641 spell->race.contains (tmp->race)))
1644 { 1642 {
1645 done_one = 2; 1643 done_one = 2;
1644
1646 if (!detect) 1645 if (!detect)
1647 detect = tmp; 1646 detect = tmp;
1648 } 1647 }
1648
1649 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) && 1649 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED) &&
1650 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 1650 (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)))
1651 { 1651 {
1652 SET_FLAG (tmp, FLAG_KNOWN_CURSED); 1652 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
1653 done_one = 1; 1653 done_one = 1;
1654 } 1654 }
1655 } /* for stack of objects on this space */ 1655 } /* for stack of objects on this space */
1656 1656
1657 /* Code here puts an effect of the spell on the space, so you can see 1657 /* Code here puts an effect of the spell on the space, so you can see
1658 * where the magic is. 1658 * where the magic is.
1659 */ 1659 */
1660 if (done_one) 1660 if (done_one)
1661 { 1661 {
1662 object *detect_ob = arch_to_object (spell->other_arch); 1662 object *detect_ob = arch_to_object (spell->other_arch);
1663 1663
1664 /* if this is set, we want to copy the face */ 1664 /* if this is set, we want to copy the face */
1665 if (done_one == 2 && detect) 1665 if (done_one == 2 && detect)
1666 { 1666 {
1667 detect_ob->face = detect->face; 1667 detect_ob->face = detect->face;
1668 detect_ob->animation_id = detect->animation_id; 1668 detect_ob->animation_id = detect->animation_id;
1669 detect_ob->anim_speed = detect->anim_speed; 1669 detect_ob->anim_speed = detect->anim_speed;
1670 detect_ob->last_anim = 0; 1670 detect_ob->last_anim = 0;
1671 /* by default, the detect_ob is already animated */ 1671 /* by default, the detect_ob is already animated */
1672 if (!QUERY_FLAG (detect, FLAG_ANIMATE)) 1672 if (!QUERY_FLAG (detect, FLAG_ANIMATE))
1673 CLEAR_FLAG (detect_ob, FLAG_ANIMATE); 1673 CLEAR_FLAG (detect_ob, FLAG_ANIMATE);
1674 } 1674 }
1675 1675
1676 m->insert (detect_ob, nx, ny, op); 1676 m->insert (detect_ob, nx, ny, op);
1677 } 1677 }
1678 } /* for processing the surrounding spaces */ 1678 } /* for processing the surrounding spaces */
1679 1679
1680 1680
1681 /* Now process objects in the players inventory if detect curse or magic */ 1681 /* Now process objects in the players inventory if detect curse or magic */
1682 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) || QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL)) 1682 if (QUERY_FLAG (spell, FLAG_KNOWN_CURSED) || QUERY_FLAG (spell, FLAG_KNOWN_MAGICAL))
1683 { 1683 {
1727 1727
1728 new_draw_info (NDI_UNIQUE, 0, victim, "You feel energy course through you."); 1728 new_draw_info (NDI_UNIQUE, 0, victim, "You feel energy course through you.");
1729 1729
1730 if (victim->stats.sp >= victim->stats.maxsp * 2) 1730 if (victim->stats.sp >= victim->stats.maxsp * 2)
1731 { 1731 {
1732 object *tmp;
1733
1734 new_draw_info (NDI_UNIQUE, 0, victim, "Your head explodes!"); 1732 new_draw_info (NDI_UNIQUE, 0, victim, "Your head explodes!");
1735
1736 /* Explodes a fireball centered at player */
1737 tmp = get_archetype (EXPLODING_FIREBALL);
1738 tmp->dam_modifier = random_roll (1, caster_level, victim, PREFER_LOW) / 5 + 1;
1739 tmp->stats.maxhp = random_roll (1, caster_level, victim, PREFER_LOW) / 10 + 2;
1740
1741 tmp->insert_at (victim);
1742 victim->stats.sp = 2 * victim->stats.maxsp; 1733 victim->stats.sp = 2 * victim->stats.maxsp;
1734 create_exploding_ball_at (victim, caster_level);
1743 } 1735 }
1744 else if (victim->stats.sp >= victim->stats.maxsp * 1.88) 1736 else if (victim->stats.sp >= victim->stats.maxsp * 1.88)
1745 new_draw_info (NDI_UNIQUE | NDI_ORANGE, 0, victim, "You feel like your head is going to explode."); 1737 new_draw_info (NDI_UNIQUE | NDI_ORANGE, 0, victim, "You feel like your head is going to explode.");
1746 else if (victim->stats.sp >= victim->stats.maxsp * 1.66) 1738 else if (victim->stats.sp >= victim->stats.maxsp * 1.66)
1747 new_draw_info (NDI_UNIQUE, 0, victim, "You get a splitting headache!"); 1739 new_draw_info (NDI_UNIQUE, 0, victim, "You get a splitting headache!");
2010 if (!weapon) 2002 if (!weapon)
2011 { 2003 {
2012 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2004 new_draw_info (NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!");
2013 return 0; 2005 return 0;
2014 } 2006 }
2007
2015 if (spell->race && strcmp (weapon->arch->archname, spell->race)) 2008 if (spell->race && weapon->arch->archname != spell->race)
2016 { 2009 {
2017 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon."); 2010 new_draw_info (NDI_UNIQUE, 0, op, "The spell fails to transform your weapon.");
2018 return 0; 2011 return 0;
2019 } 2012 }
2013
2020 if (weapon->type != WEAPON) 2014 if (weapon->type != WEAPON)
2021 { 2015 {
2022 new_draw_info (NDI_UNIQUE, 0, op, "You need to wield a weapon to animate it."); 2016 new_draw_info (NDI_UNIQUE, 0, op, "You need to wield a weapon to animate it.");
2023 return 0; 2017 return 0;
2024 } 2018 }
2019
2025 if (QUERY_FLAG (weapon, FLAG_APPLIED)) 2020 if (QUERY_FLAG (weapon, FLAG_APPLIED))
2026 { 2021 {
2027 new_draw_info_format (NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", query_name (weapon)); 2022 new_draw_info_format (NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", query_name (weapon));
2028 return 0; 2023 return 0;
2029 } 2024 }
2146/* cast_daylight() - changes the map darkness level *lower* */ 2141/* cast_daylight() - changes the map darkness level *lower* */
2147 2142
2148/* cast_change_map_lightlevel: Was cast_daylight/nightfall. 2143/* cast_change_map_lightlevel: Was cast_daylight/nightfall.
2149 * This changes the light level for the entire map. 2144 * This changes the light level for the entire map.
2150 */ 2145 */
2151
2152int 2146int
2153cast_change_map_lightlevel (object *op, object *caster, object *spell) 2147cast_change_map_lightlevel (object *op, object *caster, object *spell)
2154{ 2148{
2155 int success; 2149 int success;
2156 2150
2164 if (spell->stats.dam < 0) 2158 if (spell->stats.dam < 0)
2165 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here."); 2159 new_draw_info (NDI_UNIQUE, 0, op, "It can be no brighter here.");
2166 else 2160 else
2167 new_draw_info (NDI_UNIQUE, 0, op, "It can be no darker here."); 2161 new_draw_info (NDI_UNIQUE, 0, op, "It can be no darker here.");
2168 } 2162 }
2163
2169 return success; 2164 return success;
2170} 2165}
2171 2166
2172/* create an aura spell object and put it in the player's inventory. 2167/* create an aura spell object and put it in the player's inventory.
2173 * as usual, op is player, caster is the object casting the spell, 2168 * as usual, op is player, caster is the object casting the spell,
2271 * op is the piece object. 2266 * op is the piece object.
2272 */ 2267 */
2273void 2268void
2274move_peacemaker (object *op) 2269move_peacemaker (object *op)
2275{ 2270{
2276 object *tmp; 2271 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
2277
2278 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
2279 { 2272 {
2280 int atk_lev, def_lev; 2273 int atk_lev, def_lev;
2281 object *victim = tmp->head_ (); 2274 object *victim = tmp->head_ ();
2282 2275
2283 if (!QUERY_FLAG (victim, FLAG_MONSTER)) 2276 if (!QUERY_FLAG (victim, FLAG_MONSTER))
2318 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name); 2311 new_draw_info_format (NDI_UNIQUE, 0, op->owner, "%s no longer feels like fighting.", &victim->name);
2319 } 2312 }
2320 } 2313 }
2321} 2314}
2322 2315
2323
2324/* This writes a rune that contains the appropriate message. 2316/* This writes a rune that contains the appropriate message.
2325 * There really isn't any adjustments we make. 2317 * There really isn't any adjustments we make.
2326 */ 2318 */
2327
2328int 2319int
2329write_mark (object *op, object *spell, const char *msg) 2320write_mark (object *op, object *spell, const char *msg)
2330{ 2321{
2331 char rune[HUGE_BUF];
2332 object *tmp;
2333
2334 if (!msg || msg[0] == 0) 2322 if (!msg || msg[0] == 0)
2335 { 2323 {
2336 new_draw_info (NDI_UNIQUE, 0, op, "Write what?"); 2324 new_draw_info (NDI_UNIQUE, 0, op, "Write what?");
2337 return 0; 2325 return 0;
2338 } 2326 }
2341 { 2329 {
2342 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2330 new_draw_info (NDI_UNIQUE, 0, op, "Trying to cheat are we?");
2343 LOG (llevInfo, "write_rune: player %s tried to write bogus rune %s\n", &op->name, msg); 2331 LOG (llevInfo, "write_rune: player %s tried to write bogus rune %s\n", &op->name, msg);
2344 return 0; 2332 return 0;
2345 } 2333 }
2334
2346 if (!spell->other_arch) 2335 if (!spell->other_arch)
2347 return 0; 2336 return 0;
2337
2348 tmp = arch_to_object (spell->other_arch); 2338 object *tmp = arch_to_object (spell->other_arch);
2349
2350 snprintf (rune, sizeof (rune), "%s\n", msg);
2351 2339
2352 tmp->race = op->name; /*Save the owner of the rune */ 2340 tmp->race = op->name; /*Save the owner of the rune */
2353 tmp->msg = rune; 2341 tmp->msg = msg;
2354 2342
2355 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR); 2343 tmp->insert_at (op, op, INS_BELOW_ORIGINATOR);
2344
2356 return 1; 2345 return 1;
2357} 2346}
2347

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines