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.32 by pippijn, Sat Jan 6 14:42:31 2007 UTC vs.
Revision 1.45 by root, Mon Apr 16 06:23:43 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game for X-windows
3 3 *
4 Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team 4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
5 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
6 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
7 7 *
8 This program is free software; you can redistribute it and/or modify 8 * This program 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 2 of the License, or 10 * the Free Software Foundation; either version 2 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,
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 GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 21 *
22 The authors can be reached via e-mail at <crossfire@schmorp.de> 22 * The authors can be reached via e-mail at <crossfire@schmorp.de>
23*/ 23 */
24 24
25#include <global.h> 25#include <global.h>
26#include <object.h> 26#include <object.h>
27#include <living.h> 27#include <living.h>
28#ifndef __CEXTRACT__
29# include <sproto.h> 28#include <sproto.h>
30#endif
31#include <spells.h> 29#include <spells.h>
32#include <sounds.h> 30#include <sounds.h>
33 31
34/* cast_magic_storm: This is really used mostly for spell 32/* cast_magic_storm: This is really used mostly for spell
35 * fumbles at the like. tmp is the object to propogate. 33 * fumbles at the like. tmp is the object to propogate.
156 /* If it starts with a letter, presume it is a description */ 154 /* If it starts with a letter, presume it is a description */
157 if (isalpha (*stringarg)) 155 if (isalpha (*stringarg))
158 { 156 {
159 artifact *al = find_artifactlist (missile->type)->items; 157 artifact *al = find_artifactlist (missile->type)->items;
160 158
161 for (; al != NULL; al = al->next) 159 for (; al; al = al->next)
162 if (!strcasecmp (al->item->name, stringarg)) 160 if (!strcasecmp (al->item->name, stringarg))
163 break; 161 break;
164 162
165 if (!al) 163 if (!al)
166 { 164 {
375 * normal applies. 373 * normal applies.
376 */ 374 */
377int 375int
378cast_invisible (object *op, object *caster, object *spell_ob) 376cast_invisible (object *op, object *caster, object *spell_ob)
379{ 377{
380 object *tmp;
381
382 if (op->invisible > 1000) 378 if (op->invisible > 1000)
383 { 379 {
384 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further"); 380 new_draw_info (NDI_UNIQUE, 0, op, "You can not extend the duration of your invisibility any further");
385 return 0; 381 return 0;
386 } 382 }
402 else 398 else
403 op->contr->tmp_invis = 1; 399 op->contr->tmp_invis = 1;
404 400
405 op->contr->hidden = 0; 401 op->contr->hidden = 0;
406 } 402 }
403
407 if (makes_invisible_to (op, op)) 404 if (makes_invisible_to (op, op))
408 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!"); 405 new_draw_info (NDI_UNIQUE, 0, op, "You can't see your hands!");
409 else 406 else
410 new_draw_info (NDI_UNIQUE, 0, op, "You feel more transparent!"); 407 new_draw_info (NDI_UNIQUE, 0, op, "You feel more transparent!");
411 408
412 update_object (op, UP_OBJ_FACE); 409 update_object (op, UP_OBJ_CHANGE);
413 410
414 /* Only search the active objects - only these should actually do 411 /* Only search the active objects - only these should actually do
415 * harm to the player. 412 * harm to the player.
416 */ 413 */
417 for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next) 414 for_all_actives (tmp)
418 if (tmp->enemy == op) 415 if (tmp->enemy == op)
419 tmp->enemy = NULL; 416 tmp->enemy = 0;
417
420 return 1; 418 return 1;
421} 419}
422 420
423/* earth to dust spell. Basically destroys earthwalls in the area. 421/* earth to dust spell. Basically destroys earthwalls in the area.
424 */ 422 */
567} 565}
568 566
569int 567int
570perceive_self (object *op) 568perceive_self (object *op)
571{ 569{
570 char buf[MAX_BUF];
572 char *cp = describe_item (op, op), buf[MAX_BUF]; 571 const char *cp = describe_item (op, op);
573 archetype *at = archetype::find (ARCH_DEPLETION); 572 archetype *at = archetype::find (ARCH_DEPLETION);
574 object *tmp; 573 object *tmp;
575 int i; 574 int i;
576 575
577 tmp = find_god (determine_god (op)); 576 tmp = find_god (determine_god (op));
606 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) 605 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
607 { 606 {
608 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force")) 607 if (tmp->type == FORCE && !strcmp (tmp->arch->name, "dragon_ability_force"))
609 { 608 {
610 if (tmp->stats.exp == 0) 609 if (tmp->stats.exp == 0)
611 {
612 sprintf (buf, "Your metabolism isn't focused on anything."); 610 sprintf (buf, "Your metabolism isn't focused on anything.");
613 }
614 else 611 else
615 {
616 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 612 sprintf (buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
617 } 613
618 new_draw_info (NDI_UNIQUE, 0, op, buf); 614 new_draw_info (NDI_UNIQUE, 0, op, buf);
619 break; 615 break;
620 } 616 }
621 } 617 }
622 } 618 }
619
623 return 1; 620 return 1;
624} 621}
625 622
626/* int cast_create_town_portal (object *op, object *caster, int dir) 623/* int cast_create_town_portal (object *op, object *caster, int dir)
627 * 624 *
1164 object *poison; 1161 object *poison;
1165 int heal = 0, success = 0; 1162 int heal = 0, success = 0;
1166 1163
1167 tmp = find_target_for_friendly_spell (op, dir); 1164 tmp = find_target_for_friendly_spell (op, dir);
1168 1165
1169 if (tmp == NULL) 1166 if (!tmp)
1170 return 0; 1167 return 0;
1171 1168
1172 /* Figure out how many hp this spell might cure. 1169 /* Figure out how many hp this spell might cure.
1173 * could be zero if this spell heals effects, not damage. 1170 * could be zero if this spell heals effects, not damage.
1174 */ 1171 */
1177 heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp; 1174 heal += random_roll (spell->stats.hp, 6, op, PREFER_HIGH) + spell->stats.hp;
1178 1175
1179 if (heal) 1176 if (heal)
1180 { 1177 {
1181 if (tmp->stats.hp >= tmp->stats.maxhp) 1178 if (tmp->stats.hp >= tmp->stats.maxhp)
1182 {
1183 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed."); 1179 new_draw_info (NDI_UNIQUE, 0, tmp, "You are already fully healed.");
1184 }
1185 else 1180 else
1186 { 1181 {
1187 /* See how many points we actually heal. Instead of messages 1182 /* See how many points we actually heal. Instead of messages
1188 * based on type of spell, we instead do messages based 1183 * based on type of spell, we instead do messages based
1189 * on amount of damage healed. 1184 * on amount of damage healed.
1191 if (heal > (tmp->stats.maxhp - tmp->stats.hp)) 1186 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1192 heal = tmp->stats.maxhp - tmp->stats.hp; 1187 heal = tmp->stats.maxhp - tmp->stats.hp;
1193 tmp->stats.hp += heal; 1188 tmp->stats.hp += heal;
1194 1189
1195 if (tmp->stats.hp >= tmp->stats.maxhp) 1190 if (tmp->stats.hp >= tmp->stats.maxhp)
1196 {
1197 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!"); 1191 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel just fine!");
1198 }
1199 else if (heal > 50) 1192 else if (heal > 50)
1200 {
1201 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!"); 1193 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds close!");
1202 }
1203 else if (heal > 25) 1194 else if (heal > 25)
1204 {
1205 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close."); 1195 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds mostly close.");
1206 }
1207 else if (heal > 10) 1196 else if (heal > 10)
1208 {
1209 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade."); 1197 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to fade.");
1210 }
1211 else 1198 else
1212 {
1213 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close."); 1199 new_draw_info (NDI_UNIQUE, 0, tmp, "Your wounds start to close.");
1214 } 1200
1215 success = 1; 1201 success = 1;
1216 } 1202 }
1217 } 1203 }
1204
1218 if (spell->attacktype & AT_DISEASE) 1205 if (spell->attacktype & AT_DISEASE)
1219 if (cure_disease (tmp, op)) 1206 if (cure_disease (tmp, op))
1220 success = 1; 1207 success = 1;
1221 1208
1222 if (spell->attacktype & AT_POISON) 1209 if (spell->attacktype & AT_POISON)
1228 success = 1; 1215 success = 1;
1229 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed"); 1216 new_draw_info (NDI_UNIQUE, 0, tmp, "Your body feels cleansed");
1230 poison->stats.food = 1; 1217 poison->stats.food = 1;
1231 } 1218 }
1232 } 1219 }
1220
1233 if (spell->attacktype & AT_CONFUSION) 1221 if (spell->attacktype & AT_CONFUSION)
1234 { 1222 {
1235 poison = present_in_ob_by_name (FORCE, "confusion", tmp); 1223 poison = present_in_ob_by_name (FORCE, "confusion", tmp);
1236 if (poison) 1224 if (poison)
1237 { 1225 {
1238 success = 1; 1226 success = 1;
1239 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer"); 1227 new_draw_info (NDI_UNIQUE, 0, tmp, "Your mind feels clearer");
1240 poison->duration = 1; 1228 poison->duration = 1;
1241 } 1229 }
1242 } 1230 }
1231
1243 if (spell->attacktype & AT_BLIND) 1232 if (spell->attacktype & AT_BLIND)
1244 { 1233 {
1245 at = archetype::find ("blindness"); 1234 at = archetype::find ("blindness");
1246 poison = present_arch_in_ob (at, tmp); 1235 poison = present_arch_in_ob (at, tmp);
1247 if (poison) 1236 if (poison)
1249 success = 1; 1238 success = 1;
1250 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return."); 1239 new_draw_info (NDI_UNIQUE, 0, tmp, "Your vision begins to return.");
1251 poison->stats.food = 1; 1240 poison->stats.food = 1;
1252 } 1241 }
1253 } 1242 }
1243
1254 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) 1244 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp)
1255 { 1245 {
1256 tmp->stats.sp += spell->last_sp; 1246 tmp->stats.sp += spell->last_sp;
1257 if (tmp->stats.sp > tmp->stats.maxsp) 1247 if (tmp->stats.sp > tmp->stats.maxsp)
1258 tmp->stats.sp = tmp->stats.maxsp; 1248 tmp->stats.sp = tmp->stats.maxsp;
1259 success = 1; 1249 success = 1;
1260 new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!"); 1250 new_draw_info (NDI_UNIQUE, 0, tmp, "Magical energy surges through your body!");
1261 } 1251 }
1252
1262 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) 1253 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace)
1263 { 1254 {
1264 tmp->stats.grace += spell->last_grace; 1255 tmp->stats.grace += spell->last_grace;
1265 if (tmp->stats.grace > tmp->stats.maxgrace) 1256 if (tmp->stats.grace > tmp->stats.maxgrace)
1266 tmp->stats.grace = tmp->stats.maxgrace; 1257 tmp->stats.grace = tmp->stats.maxgrace;
1267 success = 1; 1258 success = 1;
1268 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!"); 1259 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel redeemed with your god!");
1269 } 1260 }
1261
1270 if (spell->stats.food && tmp->stats.food < 999) 1262 if (spell->stats.food && tmp->stats.food < 999)
1271 { 1263 {
1272 tmp->stats.food += spell->stats.food; 1264 tmp->stats.food += spell->stats.food;
1273 if (tmp->stats.food > 999) 1265 if (tmp->stats.food > 999)
1274 tmp->stats.food = 999; 1266 tmp->stats.food = 999;
1275 success = 1; 1267 success = 1;
1276 /* We could do something a bit better like the messages for healing above */ 1268 /* We could do something a bit better like the messages for healing above */
1277 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food"); 1269 new_draw_info (NDI_UNIQUE, 0, tmp, "You feel your belly fill with food");
1278 } 1270 }
1271
1279 return success; 1272 return success;
1280} 1273}
1281 1274
1282 1275
1283/* This is used for the spells that gain stats. There are no spells 1276/* This is used for the spells that gain stats. There are no spells
1531 change_abil (tmp, force); /* Mostly to display any messages */ 1524 change_abil (tmp, force); /* Mostly to display any messages */
1532 insert_ob_in_ob (force, tmp); 1525 insert_ob_in_ob (force, tmp);
1533 tmp->update_stats (); 1526 tmp->update_stats ();
1534 return 1; 1527 return 1;
1535} 1528}
1536
1537
1538 1529
1539/* Alchemy code by Mark Wedel 1530/* Alchemy code by Mark Wedel
1540 * 1531 *
1541 * This code adds a new spell, called alchemy. Alchemy will turn 1532 * This code adds a new spell, called alchemy. Alchemy will turn
1542 * objects to gold nuggets, the value of the gold nuggets being 1533 * objects to gold nuggets, the value of the gold nuggets being
1552 * For example, if an item is worth 110 gold, you will get 1543 * For example, if an item is worth 110 gold, you will get
1553 * 4 large nuggets, and from 0-10 small nuggets. 1544 * 4 large nuggets, and from 0-10 small nuggets.
1554 * 1545 *
1555 * There is also a chance (1:30) that you will get nothing at all 1546 * There is also a chance (1:30) that you will get nothing at all
1556 * for the object. There is also a maximum weight that will be 1547 * for the object. There is also a maximum weight that will be
1557 * alchemied. 1548 * alchemised.
1558 */ 1549 */
1559
1560/* I didn't feel like passing these as arguements to the
1561 * two functions that need them. Real values are put in them
1562 * when the spell is cast, and these are freed when the spell
1563 * is finished.
1564 */
1565static object *small, *large;
1566
1567static void 1550static void
1568alchemy_object (object *obj, int *small_nuggets, int *large_nuggets, int *weight) 1551alchemy_object (object *obj, uint64 &total_value, int &total_weight)
1569{ 1552{
1570 uint64 value = query_cost (obj, NULL, F_TRUE); 1553 uint64 value = query_cost (obj, NULL, F_TRUE);
1571 1554
1572 /* Give third price when we alchemy money (This should hopefully 1555 /* Give third price when we alchemy money (This should hopefully
1573 * make it so that it isn't worth it to alchemy money, sell 1556 * make it so that it isn't worth it to alchemy money, sell
1574 * the nuggets, alchemy the gold from that, etc. 1557 * the nuggets, alchemy the gold from that, etc.
1575 * Otherwise, give 9 silver on the gold for other objects, 1558 * Otherwise, give 9 silver on the gold for other objects,
1576 * so that it would still be more affordable to haul 1559 * so that it would still be more affordable to haul
1577 * the stuff back to town. 1560 * the stuff back to town.
1578 */ 1561 */
1579
1580 if (QUERY_FLAG (obj, FLAG_UNPAID)) 1562 if (QUERY_FLAG (obj, FLAG_UNPAID))
1581 value = 0; 1563 value = 0;
1582 else if (obj->type == MONEY || obj->type == GEM) 1564 else if (obj->type == MONEY || obj->type == GEM)
1583 value /= 3; 1565 value /= 3;
1584 else 1566 else
1585 value = (value * 9) / 10; 1567 value = value * 9 / 10;
1586 1568
1587 value /= 4; // fix by GHJ, don't understand, pcg
1588
1589 if ((obj->value > 0) && rndm (0, 29)) 1569 if (obj->value > 0 && rndm (0, 29))
1590 { 1570 total_value += value;
1591 int count;
1592 1571
1593 count = value / large->value;
1594 *large_nuggets += count;
1595 value -= (uint64) count *(uint64) large->value;
1596
1597 count = value / small->value;
1598 *small_nuggets += count;
1599 }
1600
1601 /* Turn 25 small nuggets into 1 large nugget. If the value
1602 * of large nuggets is not evenly divisable by the small nugget
1603 * value, take off an extra small_nugget (Assuming small_nuggets!=0)
1604 */
1605 if (*small_nuggets * small->value >= large->value)
1606 {
1607 (*large_nuggets)++;
1608 *small_nuggets -= large->value / small->value;
1609 if (*small_nuggets && large->value % small->value)
1610 (*small_nuggets)--;
1611 }
1612 weight += obj->weight; 1572 total_weight += obj->total_weight ();
1573
1613 obj->destroy (); 1574 obj->destroy ();
1614} 1575}
1615 1576
1616static void 1577static void
1617update_map (object *op, maptile *m, int small_nuggets, int large_nuggets, int x, int y) 1578update_map (object *op, maptile *m, int small_nuggets, object *small, int large_nuggets, object *large, int x, int y)
1618{ 1579{
1619 object *tmp;
1620 int flag = 0; 1580 int flag = 0;
1621 1581
1622 /* Put any nuggets below the player, but we can only pass this 1582 /* Put any nuggets below the player, but we can only pass this
1623 * flag if we are on the same space as the player 1583 * flag if we are on the same space as the player
1624 */ 1584 */
1625 if (x == op->x && y == op->y && op->map == m) 1585 if (x == op->x && y == op->y && op->map == m)
1626 flag = INS_BELOW_ORIGINATOR; 1586 flag = INS_BELOW_ORIGINATOR;
1627 1587
1628 if (small_nuggets) 1588 if (small_nuggets)
1629 { 1589 {
1630 tmp = small->clone (); 1590 object *tmp = small->clone ();
1631 tmp->nrof = small_nuggets; 1591 tmp->nrof = small_nuggets;
1632 m->insert (tmp, x, y, op, flag); 1592 m->insert (tmp, x, y, op, flag);
1633 } 1593 }
1634 1594
1635 if (large_nuggets) 1595 if (large_nuggets)
1636 { 1596 {
1637 tmp = large->clone (); 1597 object *tmp = large->clone ();
1638 tmp->nrof = large_nuggets; 1598 tmp->nrof = large_nuggets;
1639 m->insert (tmp, x, y, op, flag); 1599 m->insert (tmp, x, y, op, flag);
1640 } 1600 }
1601
1602 if (object *pl = m->at (x, y).player ())
1603 if (pl->contr->ns)
1604 pl->contr->ns->look_position = 0;
1641} 1605}
1642 1606
1643int 1607int
1644alchemy (object *op, object *caster, object *spell_ob) 1608alchemy (object *op, object *caster, object *spell_ob)
1645{ 1609{
1646 int x, y, weight = 0, weight_max, large_nuggets, small_nuggets, mflags;
1647 sint16 nx, ny;
1648 object *next, *tmp;
1649 maptile *mp;
1650
1651 if (op->type != PLAYER) 1610 if (op->type != PLAYER)
1652 return 0; 1611 return 0;
1653 1612
1613 object *large = get_archetype ("largenugget");
1614 object *small = get_archetype ("smallnugget");
1615
1654 /* Put a maximum weight of items that can be alchemied. Limits the power 1616 /* Put a maximum weight of items that can be alchemised. Limits the power
1655 * some, and also prevents people from alcheming every table/chair/clock 1617 * some, and also prevents people from alchemising every table/chair/clock
1656 * in sight 1618 * in sight
1657 */ 1619 */
1658 weight_max = spell_ob->duration + +SP_level_duration_adjust (caster, spell_ob); 1620 int duration = spell_ob->duration + SP_level_duration_adjust (caster, spell_ob);
1659 weight_max *= 1000; 1621 int weight_max = duration * 1000;
1660 small = get_archetype ("smallnugget"), large = get_archetype ("largenugget"); 1622 uint64 value_max = duration * 1000;
1661 1623
1624 int weight = 0;
1625
1662 for (y = op->y - 1; y <= op->y + 1; y++) 1626 for (int y = op->y - 1; y <= op->y + 1; y++)
1663 { 1627 {
1664 for (x = op->x - 1; x <= op->x + 1; x++) 1628 for (int x = op->x - 1; x <= op->x + 1; x++)
1665 { 1629 {
1630 uint64 value = 0;
1631
1666 nx = x; 1632 sint16 nx = x;
1667 ny = y; 1633 sint16 ny = y;
1668 1634
1669 mp = op->map; 1635 maptile *mp = op->map;
1670 1636
1671 mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny); 1637 int mflags = get_map_flags (mp, &mp, nx, ny, &nx, &ny);
1672 1638
1673 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC)) 1639 if (mflags & (P_OUT_OF_MAP | P_NO_MAGIC))
1674 continue; 1640 continue;
1675 1641
1676 /* Treat alchemy a little differently - most spell effects 1642 /* Treat alchemy a little differently - most spell effects
1678 * ground level effect. 1644 * ground level effect.
1679 */ 1645 */
1680 if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK) 1646 if (GET_MAP_MOVE_BLOCK (mp, nx, ny) & MOVE_WALK)
1681 continue; 1647 continue;
1682 1648
1683 small_nuggets = 0; 1649 for (object *next, *tmp = mp->at (nx, ny).bot; tmp; tmp = next)
1684 large_nuggets = 0;
1685
1686 for (tmp = GET_MAP_OB (mp, nx, ny); tmp != NULL; tmp = next)
1687 { 1650 {
1688 next = tmp->above; 1651 next = tmp->above;
1652
1689 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) && 1653 if (tmp->weight > 0 && !QUERY_FLAG (tmp, FLAG_NO_PICK) &&
1690 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON)) 1654 !QUERY_FLAG (tmp, FLAG_ALIVE) && !QUERY_FLAG (tmp, FLAG_IS_CAULDRON))
1691 { 1655 {
1692
1693 if (tmp->inv) 1656 if (tmp->inv)
1694 { 1657 {
1695 object *next1, *tmp1; 1658 object *next1, *tmp1;
1696 1659
1697 for (tmp1 = tmp->inv; tmp1 != NULL; tmp1 = next1) 1660 for (tmp1 = tmp->inv; tmp1; tmp1 = next1)
1698 { 1661 {
1699 next1 = tmp1->below; 1662 next1 = tmp1->below;
1700 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) && 1663 if (tmp1->weight > 0 && !QUERY_FLAG (tmp1, FLAG_NO_PICK) &&
1701 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON)) 1664 !QUERY_FLAG (tmp1, FLAG_ALIVE) && !QUERY_FLAG (tmp1, FLAG_IS_CAULDRON))
1702 alchemy_object (tmp1, &small_nuggets, &large_nuggets, &weight); 1665 alchemy_object (tmp1, value, weight);
1703 } 1666 }
1704 } 1667 }
1668
1705 alchemy_object (tmp, &small_nuggets, &large_nuggets, &weight); 1669 alchemy_object (tmp, value, weight);
1706 1670
1707 if (weight > weight_max) 1671 if (weight > weight_max)
1708 { 1672 break;
1709 update_map (op, mp, small_nuggets, large_nuggets, nx, ny);
1710 large->destroy ();
1711 small->destroy ();
1712 return 1;
1713 } 1673 }
1714 } /* is alchemable object */ 1674 }
1715 } /* process all objects on this space */ 1675
1676 value = min (value, value_max);
1677
1678 uint64 count = value / large->value;
1679 int large_nuggets = count;
1680 value -= count * large->value;
1681
1682 count = value / small->value;
1683 int small_nuggets = count;
1716 1684
1717 /* Insert all the nuggets at one time. This probably saves time, but 1685 /* Insert all the nuggets at one time. This probably saves time, but
1718 * it also prevents us from alcheming nuggets that were just created 1686 * it also prevents us from alcheming nuggets that were just created
1719 * with this spell. 1687 * with this spell.
1720 */ 1688 */
1721 update_map (op, mp, small_nuggets, large_nuggets, nx, ny); 1689 update_map (op, mp, small_nuggets, small, large_nuggets, large, nx, ny);
1722 }
1723 }
1724 1690
1691 if (weight > weight_max)
1692 goto bailout;
1693 }
1694 }
1695
1696bailout:
1725 large->destroy (); 1697 large->destroy ();
1726 small->destroy (); 1698 small->destroy ();
1727 /* reset this so that if player standing on a big pile of stuff,
1728 * it is redrawn properly.
1729 */
1730 op->contr->ns->look_position = 0;
1731 return 1; 1699 return 1;
1732} 1700}
1733 1701
1734 1702
1735/* This function removes the cursed/damned status on equipped 1703/* This function removes the cursed/damned status on equipped
1762 } 1730 }
1763 1731
1764 if (op->type == PLAYER) 1732 if (op->type == PLAYER)
1765 { 1733 {
1766 if (success) 1734 if (success)
1767 {
1768 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now."); 1735 new_draw_info (NDI_UNIQUE, 0, op, "You feel like some of your items are looser now.");
1769 }
1770 else 1736 else
1771 { 1737 {
1772 if (was_one) 1738 if (was_one)
1773 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse."); 1739 new_draw_info (NDI_UNIQUE, 0, op, "You failed to remove the curse.");
1774 else 1740 else
2187 /* Basically, if the object is magical and not counterspell, 2153 /* Basically, if the object is magical and not counterspell,
2188 * we will more or less remove the object. Don't counterspell 2154 * we will more or less remove the object. Don't counterspell
2189 * monsters either. 2155 * monsters either.
2190 */ 2156 */
2191 2157
2192 if (head->attacktype & AT_MAGIC && 2158 if (head->attacktype & AT_MAGIC
2193 !(head->attacktype & AT_COUNTERSPELL) && !QUERY_FLAG (head, FLAG_MONSTER) && (op->level > head->level)) 2159 && !(head->attacktype & AT_COUNTERSPELL)
2160 && !QUERY_FLAG (head, FLAG_MONSTER)
2161 && (op->level > head->level))
2194 head->destroy (); 2162 head->destroy ();
2195 else 2163 else
2196 switch (head->type) 2164 switch (head->type)
2197 { 2165 {
2198 case SPELL_EFFECT: 2166 case SPELL_EFFECT:
2167 // XXX: Don't affect floor spelleffects. See also XXX comment
2168 // about sanctuary in spell_util.C
2169 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR))
2170 continue;
2171
2199 if (op->level > head->level) 2172 if (op->level > head->level)
2200 head->destroy (); 2173 head->destroy ();
2201 2174
2202 break; 2175 break;
2203 2176
2350 /* create the golem object */ 2323 /* create the golem object */
2351 tmp = arch_to_object (spell->other_arch); 2324 tmp = arch_to_object (spell->other_arch);
2352 2325
2353 /* if animated by a player, give the player control of the golem */ 2326 /* if animated by a player, give the player control of the golem */
2354 CLEAR_FLAG (tmp, FLAG_MONSTER); 2327 CLEAR_FLAG (tmp, FLAG_MONSTER);
2355 SET_FLAG (tmp, FLAG_FRIENDLY);
2356 tmp->stats.exp = 0; 2328 tmp->stats.exp = 0;
2357 add_friendly_object (tmp); 2329 add_friendly_object (tmp);
2358 tmp->type = GOLEM; 2330 tmp->type = GOLEM;
2359 tmp->set_owner (op); 2331 tmp->set_owner (op);
2360 set_spell_skill (op, caster, spell, tmp); 2332 set_spell_skill (op, caster, spell, tmp);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines