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.2 by root, Thu Aug 17 20:23:32 2006 UTC vs.
Revision 1.6 by elmex, Tue Aug 29 11:58:02 2006 UTC

1/* 1/*
2 * static char *rcsid_spell_effect_c = 2 * static char *rcsid_spell_effect_c =
3 * "$Id: spell_effect.C,v 1.2 2006/08/17 20:23:32 root Exp $"; 3 * "$Id: spell_effect.C,v 1.6 2006/08/29 11:58:02 elmex Exp $";
4 */ 4 */
5 5
6 6
7/* 7/*
8 CrossFire, A Multiplayer game for X-windows 8 CrossFire, A Multiplayer game for X-windows
66 object *wand, *tmp; 66 object *wand, *tmp;
67 int ncharges; 67 int ncharges;
68 68
69 wand = find_marked_object(op); 69 wand = find_marked_object(op);
70 if(wand == NULL || wand->type != WAND) { 70 if(wand == NULL || wand->type != WAND) {
71 new_draw_info(NDI_UNIQUE, 0, op, "You need to mark the wand you want to recharge."); 71 new_draw_info(NDI_UNIQUE, 0, op, "You need to mark the wand you want to recharge.");
72 return 0; 72 return 0;
73 } 73 }
74 if(!(random_roll(0, 3, op, PREFER_HIGH))) { 74 if(!(random_roll(0, 3, op, PREFER_HIGH))) {
75 new_draw_info_format(NDI_UNIQUE, 0, op, 75 new_draw_info_format(NDI_UNIQUE, 0, op,
76 "The %s vibrates violently, then explodes!",query_name(wand)); 76 "The %s vibrates violently, then explodes!",query_name(wand));
77 play_sound_map(op->map, op->x, op->y, SOUND_OB_EXPLODE); 77 play_sound_map(op->map, op->x, op->y, SOUND_OB_EXPLODE);
78 esrv_del_item(op->contr, wand->count); 78 esrv_del_item(op->contr, wand->count);
79 remove_ob(wand); 79 remove_ob(wand);
80 free_object(wand); 80 free_object(wand);
81 tmp = get_archetype("fireball"); 81 tmp = get_archetype("fireball");
82 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob)) / 10; 82 tmp->stats.dam = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob)) / 10;
83 if (!tmp->stats.dam) tmp->stats.dam = 1; 83 if (!tmp->stats.dam) tmp->stats.dam = 1;
84 tmp->stats.hp = tmp->stats.dam / 2; 84 tmp->stats.hp = tmp->stats.dam / 2;
85 if (tmp->stats.hp < 2) tmp->stats.hp = 2; 85 if (tmp->stats.hp < 2) tmp->stats.hp = 2;
86 tmp->x = op->x; 86 tmp->x = op->x;
87 tmp->y = op->y; 87 tmp->y = op->y;
88 insert_ob_in_map(tmp, op->map, NULL, 0); 88 insert_ob_in_map(tmp, op->map, NULL, 0);
89 return 1; 89 return 1;
90 } 90 }
91 91
92 ncharges = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob)); 92 ncharges = (spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob));
93 if (wand->inv && wand->inv->level) 93 if (wand->inv && wand->inv->level)
94 ncharges /= wand->inv->level; 94 ncharges /= wand->inv->level;
95 else { 95 else {
96 new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.", 96 new_draw_info_format(NDI_UNIQUE, 0, op, "Your %s is broken.",
97 query_name(wand)); 97 query_name(wand));
98 return 0; 98 return 0;
99 } 99 }
100 if (!ncharges) ncharges = 1; 100 if (!ncharges) ncharges = 1;
101 101
102 wand->stats.food += ncharges; 102 wand->stats.food += ncharges;
103 new_draw_info_format(NDI_UNIQUE, 0, op, 103 new_draw_info_format(NDI_UNIQUE, 0, op,
104 "The %s glows with power.",query_name(wand)); 104 "The %s glows with power.",query_name(wand));
105 if(wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) { 105 if(wand->arch && QUERY_FLAG(&wand->arch->clone, FLAG_ANIMATE)) {
106 SET_FLAG(wand, FLAG_ANIMATE); 106 SET_FLAG(wand, FLAG_ANIMATE);
107 wand->speed = wand->arch->clone.speed; 107 wand->speed = wand->arch->clone.speed;
108 update_ob_speed(wand); 108 update_ob_speed(wand);
109 } 109 }
110 return 1; 110 return 1;
111} 111}
112
113/******************************************************************************
114 * Start of polymorph related functions.
115 *
116 * Changed around for 0.94.3 - it will now look through and use all the
117 * possible choices for objects/monsters (before it was teh first 80 -
118 * arbitrary hardcoded limit in this file.) Doing this will be a bit
119 * slower however - while before, it traversed the archetypes once and
120 * stored them into an array, it will now potentially traverse it
121 * an average of 1.5 times. This is probably more costly on the polymorph
122 * item function, since it is possible a couple lookups might be needed before
123 * an item of proper value is generated.
124 */
125
126/* polymorph_living - takes a living object (op) and turns it into
127 * another monster of some sort. Currently, we only deal with single
128 * space monsters.
129 */
130
131void polymorph_living(object *op) {
132 archetype *at;
133 int nr = 0, x = op->x, y = op->y, numat=0, choice,friendly;
134 mapstruct *map = op->map;
135 object *tmp, *next, *owner;
136
137 if(op->head != NULL || op->more != NULL)
138 return;
139
140 /* High level creatures are immune, as are creatures immune to magic. Otherwise,
141 * give the creature a saving throw.
142 */
143 if (op->level>=20 || did_make_save(op, op->level, op->resist[ATNR_MAGIC]/10) ||
144 (op->resist[ATNR_MAGIC]==100))
145 return;
146
147 /* First, count up the number of legal matches */
148 for(at = first_archetype ; at != NULL; at = at->next)
149 if(QUERY_FLAG((&at->clone),FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER) &&
150 at->more == NULL && EDITABLE((&at->clone)))
151 {
152 numat++;
153 }
154 if (!numat) return; /* no valid matches? if so, return */
155
156 /* Next make a choice, and loop through until we get to it */
157 choice = rndm(0, numat-1);
158 for(at = first_archetype ; at != NULL; at = at->next)
159 if(QUERY_FLAG((&at->clone),FLAG_MONSTER) == QUERY_FLAG(op, FLAG_MONSTER) &&
160 at->more == NULL && EDITABLE((&at->clone)))
161 {
162 if (!choice) break;
163 else choice--;
164 }
165
166 /* Look through the monster. Unapply anything they have applied,
167 * and remove any spells. Note that if this is extended
168 * to players, that would need to get fixed somehow.
169 */
170 for(tmp = op->inv; tmp != NULL; tmp = next) {
171 next = tmp->below;
172 if(QUERY_FLAG(tmp, FLAG_APPLIED))
173 manual_apply(op,tmp,0);
174 if(tmp->type == SPELL) {
175 remove_ob(tmp);
176 free_object(tmp);
177 }
178 }
179
180 /* Remove the object, preserve some values for the new object */
181 remove_ob(op);
182 owner = get_owner(op);
183 friendly = QUERY_FLAG(op, FLAG_FRIENDLY);
184 if (friendly)
185 remove_friendly_object(op);
186
187 copy_object(&(at->clone),op);
188 if (owner != NULL)
189 set_owner(op,owner);
190 if (friendly) {
191 SET_FLAG(op, FLAG_FRIENDLY);
192 op->attack_movement = PETMOVE;
193 add_friendly_object(op);
194 }
195
196 /* Put the new creature on the map */
197 op->x = x; op->y = y;
198 if ((op = insert_ob_in_map (op, map, owner,0)) == NULL)
199 return;
200
201 if (HAS_RANDOM_ITEMS(op))
202 /* No GT_APPLY here because we'll do it manually. */
203 create_treasure(op->randomitems,op,GT_INVISIBLE,map->difficulty,0);
204
205 /* Apply any objects. This limits it to the first 20 items, which
206 * I guess is reasonable.
207 */
208 for(tmp = op->inv, nr = 0; tmp != NULL && ++nr < 20; tmp = next) {
209 next = tmp->below;
210 (void) monster_check_apply(op,tmp);
211 }
212}
213
214
215/* polymorph_melt Destroys item from polymorph failure
216 * who is the caster of the polymorph, op is the
217 * object destroyed. We should probably do something
218 * more clever ala nethack - create an iron golem or
219 * something.
220 */
221void polymorph_melt(object *who, object *op)
222{
223 /* Not unique */
224 new_draw_info_format(NDI_GREY, 0, who,
225 "%s%s glows red, melts and evaporates!",
226 op->nrof?"":"The ",query_name(op));
227 play_sound_map(op->map, op->x, op->y, SOUND_OB_EVAPORATE);
228 remove_ob(op);
229 free_object(op);
230 return;
231}
232
233/* polymorph_item - changes an item to another item of similar type.
234 * who is the caster of spell, op is the object to be changed.
235 */
236void polymorph_item(object *who, object *op) {
237 archetype *at;
238 int max_value, difficulty, tries=0,choice, charges=op->stats.food,numat=0;
239 object *new_ob;
240
241 /* We try and limit the maximum value of the changd object. */
242 max_value = op->value * 2;
243 if(max_value > 20000)
244 max_value = 20000 + (max_value - 20000) / 3;
245
246 /* Look through and try to find matching items. Can't turn into something
247 * invisible. Also, if the value is too high now, it would almost
248 * certainly be too high below.
249 */
250 for(at = first_archetype ; at != NULL; at = at->next) {
251 if(at->clone.type == op->type && !at->clone.invisible &&
252 at->clone.value > 0 && at->clone.value < max_value &&
253 !QUERY_FLAG(&at->clone, FLAG_NO_DROP) &&
254 !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP))
255 numat++;
256 }
257
258 if(!numat)
259 return;
260
261 difficulty = op->magic * 5;
262 if (difficulty<0) difficulty=0;
263 new_ob = get_object();
264 do {
265 choice = rndm(0, numat-1);
266 for(at = first_archetype ; at != NULL; at = at->next) {
267 if(at->clone.type == op->type && !at->clone.invisible &&
268 at->clone.value > 0 && at->clone.value < max_value &&
269 !QUERY_FLAG(&at->clone, FLAG_NO_DROP) &&
270 !QUERY_FLAG(&at->clone, FLAG_STARTEQUIP)) {
271 if (!choice) break;
272 else choice--;
273 }
274 }
275 copy_object(&(at->clone),new_ob);
276 fix_generated_item(new_ob,op,difficulty,FABS(op->magic),GT_ENVIRONMENT);
277 ++tries;
278 } while (new_ob->value > max_value && tries<10);
279 if (new_ob->invisible) {
280 LOG(llevError,"polymorph_item: fix_generated_object made %s invisible?!\n", new_ob->name);
281 free_object(new_ob);
282 }
283
284 /* Unable to generate an acceptable item? Melt it */
285 if (tries==10) {
286 polymorph_melt(who, op);
287 free_object(new_ob);
288 return;
289 }
290
291 if(op->nrof && new_ob->nrof) {
292 new_ob->nrof = op->nrof;
293 /* decrease the number of items */
294 if (new_ob->nrof>2) new_ob->nrof -= rndm(0, op->nrof/2-1);
295 }
296
297 /* We don't want rings to keep sustenance/hungry status. There are propably
298 * other cases too that should be checked.
299 */
300 if(charges && op->type != RING && op->type != FOOD)
301 op->stats.food = charges;
302
303 new_ob->x = op->x;
304 new_ob->y = op->y;
305 remove_ob(op);
306 free_object(op);
307 /*
308 * Don't want objects merged or re-arranged, as it then messes up the
309 * order
310 */
311 insert_ob_in_map(new_ob,who->map,new_ob,INS_NO_MERGE | INS_NO_WALK_ON);
312}
313
314/* polymorh - caster who has hit object op. */
315void polymorph(object *op, object *who) {
316
317 int tmp;
318
319 /* Can't polymorph players right now */
320 /* polymorphing generators opens up all sorts of abuses */
321 if(op->type == PLAYER || QUERY_FLAG(op, FLAG_GENERATOR))
322 return;
323
324 if(QUERY_FLAG(op, FLAG_MONSTER)) {
325 polymorph_living(op);
326 return;
327 }
328 /* If it is a living object of some other type, don't handle
329 * it now.
330 */
331 if(QUERY_FLAG(op, FLAG_ALIVE))
332 return;
333
334 /* Don't want to morph flying arrows, etc... */
335 if(FABS(op->speed) > 0.001 && !QUERY_FLAG(op, FLAG_ANIMATE))
336 return;
337
338 /* Do some sanity checking here. type=0 is unknown, objects
339 * without archetypes are not good. As are a few other
340 * cases.
341 */
342 if(op->type == 0 || op->arch == NULL ||
343 QUERY_FLAG(op,FLAG_NO_PICK)
344 || op->move_block || op->type == TREASURE)
345 return;
346
347 tmp = rndm(0, 7);
348 if (tmp) polymorph_item(who, op);
349 else polymorph_melt(who, op);
350}
351
352
353/* cast_polymorph -
354 * object *op is the player/monster
355 * caster is object that cast it.
356 * spell_ob is the actually spell object.
357 * dir is the direction.
358 * Returns 0 on illegal cast, otherwise 1.
359 */
360
361int cast_polymorph(object *op, object *caster, object *spell_ob, int dir) {
362 object *tmp, *next;
363 int range, mflags, maxrange;
364 mapstruct *m;
365
366 if(dir == 0)
367 return 0;
368
369 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob);
370 for(range = 1;range < maxrange; range++) {
371 sint16 x=op->x+freearr_x[dir]*range,y=op->y+freearr_y[dir]*range;
372 object *image;
373
374 m = op->map;
375 mflags = get_map_flags(m, &m, x, y, &x, &y);
376
377 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP))
378 break;
379
380 if (GET_MAP_MOVE_BLOCK(m, x, y) & MOVE_FLY_LOW)
381 break;
382
383 /* Get the top most object */
384 for(tmp = get_map_ob(m,x,y); tmp != NULL && tmp->above != NULL;
385 tmp = tmp->above);
386
387 /* Now start polymorphing the objects, top down */
388 while (tmp!=NULL) {
389 /* Once we find the floor, no need to go further */
390 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) break;
391 next = tmp->below;
392 polymorph(tmp, op);
393 tmp = next;
394 }
395 image = arch_to_object(spell_ob->other_arch);
396 image->x = x;
397 image->y = y;
398 image->stats.food = 5;
399 image->speed_left = 0.1;
400 insert_ob_in_map(image,m,op,0);
401 }
402 return 1;
403}
404
405
406 112
407/* Create a missile (nonmagic - magic +4). Will either create bolts or arrows 113/* Create a missile (nonmagic - magic +4). Will either create bolts or arrows
408 * based on whether a crossbow or bow is equiped. If neither, it defaults to 114 * based on whether a crossbow or bow is equiped. If neither, it defaults to
409 * arrows. 115 * arrows.
410 * Sets the plus based on the casters level. It is also settable with the 116 * Sets the plus based on the casters level. It is also settable with the
423 tag_t tag; 129 tag_t tag;
424 130
425 missile_name = "arrow"; 131 missile_name = "arrow";
426 132
427 for (tmp=op->inv; tmp != NULL; tmp=tmp->below) 133 for (tmp=op->inv; tmp != NULL; tmp=tmp->below)
428 if (tmp->type == BOW && QUERY_FLAG(tmp, FLAG_APPLIED)) { 134 if (tmp->type == BOW && QUERY_FLAG(tmp, FLAG_APPLIED)) {
429 missile_name=tmp->race; 135 missile_name=tmp->race;
430 } 136 }
431 137
432 missile_plus = spell->stats.dam + SP_level_dam_adjust(caster, spell); 138 missile_plus = spell->stats.dam + SP_level_dam_adjust(caster, spell);
433 139
434 if (find_archetype(missile_name)==NULL) { 140 if (find_archetype(missile_name)==NULL) {
435 LOG(llevDebug, "Cast create_missile: could not find archetype %s\n", 141 LOG(llevDebug, "Cast create_missile: could not find archetype %s\n",
436 missile_name); 142 missile_name);
437 return 0; 143 return 0;
438 } 144 }
439 missile = get_archetype(missile_name); 145 missile = get_archetype(missile_name);
440 146
441 if (stringarg) { 147 if (stringarg) {
442 /* If it starts with a letter, presume it is a description */ 148 /* If it starts with a letter, presume it is a description */
443 if (isalpha(*stringarg)) { 149 if (isalpha(*stringarg)) {
444 artifact *al = find_artifactlist(missile->type)->items; 150 artifact *al = find_artifactlist(missile->type)->items;
445 151
446 for ( ; al != NULL; al=al->next) 152 for ( ; al != NULL; al=al->next)
447 if (!strcasecmp(al->item->name, stringarg)) break; 153 if (!strcasecmp(al->item->name, stringarg)) break;
448 154
449 if (!al) { 155 if (!al) {
450 free_object(missile); 156 free_object(missile);
451 new_draw_info_format(NDI_UNIQUE, 0, op ,"No such object %ss of %s", missile_name, 157 new_draw_info_format(NDI_UNIQUE, 0, op ,"No such object %ss of %s", missile_name,
452 stringarg); 158 stringarg);
453 return 0; 159 return 0;
454 } 160 }
455 if (al->item->slaying) { 161 if (al->item->slaying) {
456 free_object(missile); 162 free_object(missile);
457 new_draw_info_format(NDI_UNIQUE, 0, op ,"You are not allowed to create %ss of %s", 163 new_draw_info_format(NDI_UNIQUE, 0, op ,"You are not allowed to create %ss of %s",
458 missile_name, stringarg); 164 missile_name, stringarg);
459 return 0; 165 return 0;
460 } 166 }
461 give_artifact_abilities(missile, al->item); 167 give_artifact_abilities(missile, al->item);
462 /* These special arrows cost something extra. Don't have them also be magical - 168 /* These special arrows cost something extra. Don't have them also be magical -
463 * otherwise, in most cases, not enough will be created. I don't want to get into 169 * otherwise, in most cases, not enough will be created. I don't want to get into
464 * the parsing of having to do both plus and type. 170 * the parsing of having to do both plus and type.
465 */ 171 */
466 bonus_plus = 1 + (al->item->value / 5); 172 bonus_plus = 1 + (al->item->value / 5);
467 missile_plus=0; 173 missile_plus=0;
468 } else 174 } else
469 if (atoi(stringarg) < missile_plus) 175 if (atoi(stringarg) < missile_plus)
470 missile_plus = atoi(stringarg); 176 missile_plus = atoi(stringarg);
471 } 177 }
472 if (missile_plus > 4) 178 if (missile_plus > 4)
473 missile_plus = 4; 179 missile_plus = 4;
474 else if (missile_plus < -4) 180 else if (missile_plus < -4)
475 missile_plus = -4; 181 missile_plus = -4;
476 182
477 missile->nrof = spell->duration + SP_level_duration_adjust(caster, spell); 183 missile->nrof = spell->duration + SP_level_duration_adjust(caster, spell);
478 missile->nrof -= 3 * (missile_plus + bonus_plus); 184 missile->nrof -= 3 * (missile_plus + bonus_plus);
479 if (missile->nrof < 1) 185 if (missile->nrof < 1)
480 missile->nrof=1; 186 missile->nrof=1;
481 187
482 missile->magic = missile_plus; 188 missile->magic = missile_plus;
483 /* Can't get any money for these objects */ 189 /* Can't get any money for these objects */
484 missile->value=0; 190 missile->value=0;
485 191
487 tag = missile->count; 193 tag = missile->count;
488 194
489 if ( ! cast_create_obj (op, caster, missile, dir) && op->type == PLAYER 195 if ( ! cast_create_obj (op, caster, missile, dir) && op->type == PLAYER
490 && ! was_destroyed (missile, tag)) 196 && ! was_destroyed (missile, tag))
491 { 197 {
492 pick_up(op, missile); 198 pick_up(op, missile);
493 } 199 }
494 return 1; 200 return 1;
495} 201}
496 202
497 203
505 211
506 food_value=spell_ob->stats.food + 212 food_value=spell_ob->stats.food +
507 + 50 * SP_level_duration_adjust(caster,spell_ob); 213 + 50 * SP_level_duration_adjust(caster,spell_ob);
508 214
509 if(stringarg) { 215 if(stringarg) {
510 at = find_archetype_by_object_type_name(FOOD, stringarg); 216 at = find_archetype_by_object_type_name(FOOD, stringarg);
511 if (at == NULL) 217 if (at == NULL)
512 at = find_archetype_by_object_type_name(DRINK, stringarg); 218 at = find_archetype_by_object_type_name(DRINK, stringarg);
513 if (at == NULL || at->clone.stats.food > food_value) 219 if (at == NULL || at->clone.stats.food > food_value)
514 stringarg = NULL; 220 stringarg = NULL;
515 } 221 }
516 222
517 if(!stringarg) { 223 if(!stringarg) {
518 archetype *at_tmp; 224 archetype *at_tmp;
519 225
520 /* We try to find the archetype with the maximum food value. 226 /* We try to find the archetype with the maximum food value.
521 * This removes the dependancy of hard coded food values in this 227 * This removes the dependancy of hard coded food values in this
522 * function, and addition of new food types is automatically added. 228 * function, and addition of new food types is automatically added.
523 * We don't use flesh types because the weight values of those need 229 * We don't use flesh types because the weight values of those need
524 * to be altered from the donor. 230 * to be altered from the donor.
525 */ 231 */
526 232
527 /* We assume the food items don't have multiple parts */ 233 /* We assume the food items don't have multiple parts */
528 for (at_tmp=first_archetype; at_tmp!=NULL; at_tmp=at_tmp->next) { 234 for (at_tmp=first_archetype; at_tmp!=NULL; at_tmp=at_tmp->next) {
529 if (at_tmp->clone.type==FOOD || at_tmp->clone.type==DRINK) { 235 if (at_tmp->clone.type==FOOD || at_tmp->clone.type==DRINK) {
530 /* Basically, if the food value is something that is creatable 236 /* Basically, if the food value is something that is creatable
531 * under the limits of the spell and it is higher than 237 * under the limits of the spell and it is higher than
532 * the item we have now, take it instead. 238 * the item we have now, take it instead.
533 */ 239 */
534 if (at_tmp->clone.stats.food<=food_value && 240 if (at_tmp->clone.stats.food<=food_value &&
535 (!at || at_tmp->clone.stats.food>at->clone.stats.food)) 241 (!at || at_tmp->clone.stats.food>at->clone.stats.food))
536 at=at_tmp; 242 at=at_tmp;
537 } 243 }
538 } 244 }
539 } 245 }
540 /* Pretty unlikely (there are some very low food items), but you never 246 /* Pretty unlikely (there are some very low food items), but you never
541 * know 247 * know
542 */ 248 */
543 if (!at) { 249 if (!at) {
544 new_draw_info(NDI_UNIQUE, 0, op, "You don't have enough experience to create any food."); 250 new_draw_info(NDI_UNIQUE, 0, op, "You don't have enough experience to create any food.");
545 return 0; 251 return 0;
546 } 252 }
547 253
548 food_value/=at->clone.stats.food; 254 food_value/=at->clone.stats.food;
549 new_op = get_object(); 255 new_op = arch_to_object (at);
550 copy_object(&at->clone, new_op);
551 new_op->nrof = food_value; 256 new_op->nrof = food_value;
552 257
553 new_op->value = 0; 258 new_op->value = 0;
554 if (new_op->nrof<1) new_op->nrof = 1; 259 if (new_op->nrof<1) new_op->nrof = 1;
555 260
562 object *tmp; 267 object *tmp;
563 mapstruct *m; 268 mapstruct *m;
564 269
565 270
566 if(!dir) { 271 if(!dir) {
567 examine_monster(op,op); 272 examine_monster(op,op);
568 return 1; 273 return 1;
569 } 274 }
570 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob); 275 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob);
571 for(r=1;r < maxrange; r++) { 276 for(r=1;r < maxrange; r++) {
572 sint16 x=op->x+r*freearr_x[dir],y=op->y+r*freearr_y[dir]; 277 sint16 x=op->x+r*freearr_x[dir],y=op->y+r*freearr_y[dir];
573 278
574 m = op->map; 279 m = op->map;
575 mflags = get_map_flags(m, &m, x, y, &x, &y); 280 mflags = get_map_flags(m, &m, x, y, &x, &y);
576 281
577 if (mflags & P_OUT_OF_MAP) break; 282 if (mflags & P_OUT_OF_MAP) break;
578 283
579 if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) { 284 if (!QUERY_FLAG(op, FLAG_WIZCAST) && (mflags & P_NO_MAGIC)) {
580 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks your magic."); 285 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks your magic.");
581 return 0; 286 return 0;
582 } 287 }
583 if (mflags & P_IS_ALIVE) { 288 if (mflags & P_IS_ALIVE) {
584 for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) 289 for(tmp=get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above)
585 if(QUERY_FLAG(tmp, FLAG_ALIVE)&&(tmp->type==PLAYER||QUERY_FLAG(tmp, FLAG_MONSTER))) { 290 if(QUERY_FLAG(tmp, FLAG_ALIVE)&&(tmp->type==PLAYER||QUERY_FLAG(tmp, FLAG_MONSTER))) {
586 new_draw_info(NDI_UNIQUE, 0,op,"You detect something."); 291 new_draw_info(NDI_UNIQUE, 0,op,"You detect something.");
587 if(tmp->head!=NULL) 292 if(tmp->head!=NULL)
588 tmp=tmp->head; 293 tmp=tmp->head;
589 examine_monster(op,tmp); 294 examine_monster(op,tmp);
590 return 1; 295 return 1;
591 } 296 }
592 } 297 }
593 } 298 }
594 new_draw_info(NDI_UNIQUE, 0,op,"You detect nothing."); 299 new_draw_info(NDI_UNIQUE, 0,op,"You detect nothing.");
595 return 1; 300 return 1;
596} 301}
597 302
606int makes_invisible_to(object *pl, object *mon) 311int makes_invisible_to(object *pl, object *mon)
607{ 312{
608 313
609 if (!pl->invisible) return 0; 314 if (!pl->invisible) return 0;
610 if (pl->type == PLAYER ) { 315 if (pl->type == PLAYER ) {
611 /* If race isn't set, then invisible unless it is undead */ 316 /* If race isn't set, then invisible unless it is undead */
612 if (!pl->contr->invis_race) { 317 if (!pl->contr->invis_race) {
613 if (QUERY_FLAG(mon, FLAG_UNDEAD)) return 0; 318 if (QUERY_FLAG(mon, FLAG_UNDEAD)) return 0;
614 return 1; 319 return 1;
615 } 320 }
616 /* invis_race is set if we get here */ 321 /* invis_race is set if we get here */
617 if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon)) 322 if (!strcmp(pl->contr->invis_race, "undead") && is_true_undead(mon))
618 return 1; 323 return 1;
619 /* No race, can't be invisible to it */ 324 /* No race, can't be invisible to it */
620 if (!mon->race) return 0; 325 if (!mon->race) return 0;
621 if (strstr(mon->race, pl->contr->invis_race)) return 1; 326 if (strstr(mon->race, pl->contr->invis_race)) return 1;
622 /* Nothing matched above, return 0 */ 327 /* Nothing matched above, return 0 */
623 return 0; 328 return 0;
624 } else { 329 } else {
625 /* monsters are invisible to everything */ 330 /* monsters are invisible to everything */
626 return 1; 331 return 1;
627 } 332 }
628} 333}
629 334
630/* Makes the player or character invisible. 335/* Makes the player or character invisible.
631 * Note the spells to 'stack', but perhaps in odd ways. 336 * Note the spells to 'stack', but perhaps in odd ways.
638 */ 343 */
639int cast_invisible(object *op, object *caster, object *spell_ob) { 344int cast_invisible(object *op, object *caster, object *spell_ob) {
640 object *tmp; 345 object *tmp;
641 346
642 if(op->invisible>1000) { 347 if(op->invisible>1000) {
643 new_draw_info(NDI_UNIQUE, 0,op,"You can not extend the duration of your invisibility any further"); 348 new_draw_info(NDI_UNIQUE, 0,op,"You can not extend the duration of your invisibility any further");
644 return 0; 349 return 0;
645 } 350 }
646 351
647 /* Remove the switch with 90% duplicate code - just handle the differences with 352 /* Remove the switch with 90% duplicate code - just handle the differences with
648 * and if statement or two. 353 * and if statement or two.
649 */ 354 */
650 op->invisible += spell_ob->duration + SP_level_duration_adjust(caster, spell_ob); 355 op->invisible += spell_ob->duration + SP_level_duration_adjust(caster, spell_ob);
651 /* max duration */ 356 /* max duration */
652 if(op->invisible>1000) op->invisible = 1000; 357 if(op->invisible>1000) op->invisible = 1000;
653 358
654 if (op->type == PLAYER) { 359 if (op->type == PLAYER) {
655 if (op->contr->invis_race) FREE_AND_CLEAR_STR(op->contr->invis_race); 360 if (op->contr->invis_race) FREE_AND_CLEAR_STR(op->contr->invis_race);
656 if (spell_ob->race) 361 if (spell_ob->race)
657 op->contr->invis_race = add_refcount(spell_ob->race); 362 op->contr->invis_race = add_refcount(spell_ob->race);
658 if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS)) 363 if (QUERY_FLAG(spell_ob, FLAG_MAKE_INVIS))
659 op->contr->tmp_invis=0; 364 op->contr->tmp_invis=0;
660 else 365 else
661 op->contr->tmp_invis=1; 366 op->contr->tmp_invis=1;
662 367
663 op->contr->hidden = 0; 368 op->contr->hidden = 0;
664 } 369 }
665 if (makes_invisible_to(op, op)) 370 if (makes_invisible_to(op, op))
666 new_draw_info(NDI_UNIQUE, 0,op,"You can't see your hands!"); 371 new_draw_info(NDI_UNIQUE, 0,op,"You can't see your hands!");
667 else 372 else
668 new_draw_info(NDI_UNIQUE, 0,op,"You feel more transparent!"); 373 new_draw_info(NDI_UNIQUE, 0,op,"You feel more transparent!");
669 374
670 update_object(op,UP_OBJ_FACE); 375 update_object(op,UP_OBJ_FACE);
671 376
672 /* Only search the active objects - only these should actually do 377 /* Only search the active objects - only these should actually do
673 * harm to the player. 378 * harm to the player.
674 */ 379 */
675 for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next) 380 for (tmp = active_objects; tmp != NULL; tmp = tmp->active_next)
676 if (tmp->enemy == op) 381 if (tmp->enemy == op)
677 tmp->enemy = NULL; 382 tmp->enemy = NULL;
678 return 1; 383 return 1;
679} 384}
680 385
681/* earth to dust spell. Basically destroys earthwalls in the area. 386/* earth to dust spell. Basically destroys earthwalls in the area.
682 */ 387 */
685 int range,i,j, mflags; 390 int range,i,j, mflags;
686 sint16 sx, sy; 391 sint16 sx, sy;
687 mapstruct *m; 392 mapstruct *m;
688 393
689 if(op->type!=PLAYER) 394 if(op->type!=PLAYER)
690 return 0; 395 return 0;
691 396
692 range=spell_ob->range + SP_level_range_adjust(caster, spell_ob); 397 range=spell_ob->range + SP_level_range_adjust(caster, spell_ob);
693 398
694 for(i= -range;i<=range;i++) 399 for(i= -range;i<=range;i++)
695 for(j= -range;j<=range;j++) { 400 for(j= -range;j<=range;j++) {
696 sx = op->x + i; 401 sx = op->x + i;
697 sy = op->y + j; 402 sy = op->y + j;
698 m = op->map; 403 m = op->map;
699 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy); 404 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
700 405
701 if (mflags & P_OUT_OF_MAP) continue; 406 if (mflags & P_OUT_OF_MAP) continue;
702 407
703 // earth to dust tears down everything that can be teared down 408 // earth to dust tears down everything that can be teared down
704 for (tmp = get_map_ob(m, sx, sy); tmp != NULL; tmp = next) 409 for (tmp = get_map_ob(m, sx, sy); tmp != NULL; tmp = next)
705 { 410 {
706 next = tmp->above; 411 next = tmp->above;
707 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN)) 412 if (QUERY_FLAG (tmp, FLAG_TEAR_DOWN))
708 hit_player (tmp, 9998, op, AT_PHYSICAL, 0); 413 hit_player (tmp, 9998, op, AT_PHYSICAL, 0);
709 } 414 }
710 } 415 }
711 return 1; 416 return 1;
712} 417}
713 418
714 419
715void execute_word_of_recall(object *op) { 420void execute_word_of_recall(object *op) {
716 object *wor=op; 421 object *wor=op;
717 while(op!=NULL && op->type!=PLAYER) 422 while(op!=NULL && op->type!=PLAYER)
718 op=op->env; 423 op=op->env;
719 424
720 if(op!=NULL && op->map) { 425 if(op!=NULL && op->map) {
721 if ((get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_CLERIC) && (!QUERY_FLAG(op,FLAG_WIZCAST))) 426 if ((get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL) & P_NO_CLERIC) && (!QUERY_FLAG(op,FLAG_WIZCAST)))
722 new_draw_info(NDI_UNIQUE, 0,op,"You feel something fizzle inside you."); 427 new_draw_info(NDI_UNIQUE, 0,op,"You feel something fizzle inside you.");
723 else 428 else
724 enter_exit(op,wor); 429 enter_exit(op,wor);
725 } 430 }
726 remove_ob(wor); 431 remove_ob(wor);
727 free_object(wor); 432 free_object(wor);
728} 433}
729 434
734int cast_word_of_recall(object *op, object *caster, object *spell_ob) { 439int cast_word_of_recall(object *op, object *caster, object *spell_ob) {
735 object *dummy; 440 object *dummy;
736 int time; 441 int time;
737 442
738 if(op->type!=PLAYER) 443 if(op->type!=PLAYER)
739 return 0; 444 return 0;
740 445
741 if (find_obj_by_type_subtype(op,SPELL_EFFECT, SP_WORD_OF_RECALL)) 446 if (find_obj_by_type_subtype(op,SPELL_EFFECT, SP_WORD_OF_RECALL))
742 { 447 {
743 new_draw_info(NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you." ); 448 new_draw_info(NDI_UNIQUE, 0, op, "You feel a force starting to build up inside you." );
744 return 1; 449 return 1;
745 } 450 }
746 451
747 dummy=get_archetype(FORCE_NAME); 452 dummy=get_archetype(FORCE_NAME);
748 if(dummy == NULL){ 453 if(dummy == NULL){
749 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 454 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
750 LOG(llevError,"cast_word_of_recall: get_archetype(force) failed!\n"); 455 LOG(llevError,"cast_word_of_recall: get_archetype(force) failed!\n");
751 return 0; 456 return 0;
752 } 457 }
753 time = spell_ob->duration - SP_level_duration_adjust(caster, spell_ob); 458 time = spell_ob->duration - SP_level_duration_adjust(caster, spell_ob);
754 if (time <1 ) time=1; 459 if (time <1 ) time=1;
755 460
756 /* value of speed really doesn't make much difference, as long as it is 461 /* value of speed really doesn't make much difference, as long as it is
781 */ 486 */
782int cast_wonder(object *op, object *caster, int dir, object *spell_ob) { 487int cast_wonder(object *op, object *caster, int dir, object *spell_ob) {
783 object *newspell; 488 object *newspell;
784 489
785 if(!rndm(0, 3)) 490 if(!rndm(0, 3))
786 return cast_cone(op,caster,dir, spell_ob); 491 return cast_cone(op,caster,dir, spell_ob);
787 492
788 if (spell_ob->randomitems) { 493 if (spell_ob->randomitems) {
789 newspell = generate_treasure(spell_ob->randomitems, caster->level); 494 newspell = generate_treasure(spell_ob->randomitems, caster->level);
790 if (!newspell) { 495 if (!newspell) {
791 LOG(llevError,"cast_wonder: Unable to get a spell!\n"); 496 LOG(llevError,"cast_wonder: Unable to get a spell!\n");
792 return 0; 497 return 0;
793 } 498 }
794 if (newspell->type != SPELL) { 499 if (newspell->type != SPELL) {
795 LOG(llevError,"cast_wonder: spell returned is not a spell (%d, %s)!\n", 500 LOG(llevError,"cast_wonder: spell returned is not a spell (%d, %s)!\n",
796 newspell->type, newspell->name); 501 newspell->type, newspell->name);
797 return 0; 502 return 0;
798 } 503 }
799 /* Prevent inifinit recursion */ 504 /* Prevent inifinit recursion */
800 if (newspell->subtype == SP_WONDER) { 505 if (newspell->subtype == SP_WONDER) {
801 LOG(llevError,"cast_wonder: spell returned is another wonder spell!\n"); 506 LOG(llevError,"cast_wonder: spell returned is another wonder spell!\n");
802 return 0; 507 return 0;
803 } 508 }
804 return cast_spell(op,caster,dir,newspell, NULL); 509 return cast_spell(op,caster,dir,newspell, NULL);
805 } 510 }
806 return 1; 511 return 1;
807} 512}
808 513
809 514
813 object *tmp; 518 object *tmp;
814 int i; 519 int i;
815 520
816 tmp=find_god(determine_god(op)); 521 tmp=find_god(determine_god(op));
817 if (tmp) 522 if (tmp)
818 new_draw_info_format(NDI_UNIQUE, 0, op, "You worship %s", tmp->name); 523 new_draw_info_format(NDI_UNIQUE, 0, op, "You worship %s", tmp->name);
819 else 524 else
820 new_draw_info(NDI_UNIQUE, 0,op,"You worship no god"); 525 new_draw_info(NDI_UNIQUE, 0,op,"You worship no god");
821 526
822 tmp=present_arch_in_ob(at,op); 527 tmp=present_arch_in_ob(at,op);
823 528
824 if(*cp=='\0' && tmp==NULL) 529 if(*cp=='\0' && tmp==NULL)
825 new_draw_info(NDI_UNIQUE, 0,op,"You feel very mundane"); 530 new_draw_info(NDI_UNIQUE, 0,op,"You feel very mundane");
826 else { 531 else {
827 new_draw_info(NDI_UNIQUE, 0,op,"You have:"); 532 new_draw_info(NDI_UNIQUE, 0,op,"You have:");
828 new_draw_info(NDI_UNIQUE, 0,op,cp); 533 new_draw_info(NDI_UNIQUE, 0,op,cp);
829 if (tmp!=NULL) { 534 if (tmp!=NULL) {
830 for (i=0; i<NUM_STATS; i++) { 535 for (i=0; i<NUM_STATS; i++) {
831 if (get_attr_value(&tmp->stats, i)<0) { 536 if (get_attr_value(&tmp->stats, i)<0) {
832 new_draw_info_format(NDI_UNIQUE, 0,op, 537 new_draw_info_format(NDI_UNIQUE, 0,op,
833 "Your %s is depleted by %d", statname[i], 538 "Your %s is depleted by %d", statname[i],
834 -(get_attr_value(&tmp->stats,i))); 539 -(get_attr_value(&tmp->stats,i)));
835 } 540 }
836 } 541 }
837 } 542 }
838 } 543 }
839 544
840 if (is_dragon_pl(op)) { 545 if (is_dragon_pl(op)) {
841 /* now grab the 'dragon_ability'-force from the player's inventory */ 546 /* now grab the 'dragon_ability'-force from the player's inventory */
842 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) { 547 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) {
843 if (tmp->type == FORCE && !strcmp(tmp->arch->name, "dragon_ability_force")) { 548 if (tmp->type == FORCE && !strcmp(tmp->arch->name, "dragon_ability_force")) {
844 if(tmp->stats.exp == 0) { 549 if(tmp->stats.exp == 0) {
845 sprintf(buf, "Your metabolism isn't focused on anything."); 550 sprintf(buf, "Your metabolism isn't focused on anything.");
846 } else { 551 } else {
847 sprintf(buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]); 552 sprintf(buf, "Your metabolism is focused on %s.", change_resist_msg[tmp->stats.exp]);
848 } 553 }
849 new_draw_info(NDI_UNIQUE, 0,op, buf); 554 new_draw_info(NDI_UNIQUE, 0,op, buf);
850 break; 555 break;
851 } 556 }
852 } 557 }
853 } 558 }
854 return 1; 559 return 1;
855} 560}
856 561
857/* int cast_create_town_portal (object *op, object *caster, int dir) 562/* int cast_create_town_portal (object *op, object *caster, int dir)
884 /* Check to see if the map the player is currently on is a per player unique 589 /* Check to see if the map the player is currently on is a per player unique
885 * map. This can be determined in that per player unique maps have the 590 * map. This can be determined in that per player unique maps have the
886 * full pathname listed. 591 * full pathname listed.
887 */ 592 */
888 if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir)) && 593 if (!strncmp(op->map->path, settings.localdir, strlen(settings.localdir)) &&
889 settings.create_home_portals != TRUE ) 594 settings.create_home_portals != TRUE )
890 { 595 {
891 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You can't cast that here.\n"); 596 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You can't cast that here.\n");
892 return 0;
893 }
894
895 /* Check to see if the player is on a transport */
896 if (op->contr && op->contr->transport) {
897 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You need to exit the transport to cast that.\n");
898 return 0; 597 return 0;
899 }
900 598 }
599
901 /* The first thing to do is to check if we have a marked destination 600 /* The first thing to do is to check if we have a marked destination
902 * dummy is used to make a check inventory for the force 601 * dummy is used to make a check inventory for the force
903 */ 602 */
904 dummy=arch_to_object(spell->other_arch); 603 dummy=arch_to_object(spell->other_arch);
905 if(dummy == NULL){ 604 if(dummy == NULL){
906 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 605 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
907 LOG(llevError,"get_object failed (force in cast_create_town_portal for %s!\n",op->name); 606 LOG(llevError,"get_object failed (force in cast_create_town_portal for %s!\n",op->name);
908 return 0; 607 return 0;
909 } 608 }
910 force=check_inv_recursive (op,dummy); 609 force=check_inv_recursive (op,dummy);
911 610
912 if (force==NULL) { 611 if (force==NULL) {
913 /* Here we know there is no destination marked up. 612 /* Here we know there is no destination marked up.
914 * We have 2 things to do: 613 * We have 2 things to do:
915 * 1. Mark the destination in the player inventory. 614 * 1. Mark the destination in the player inventory.
916 * 2. Let the player know it worked. 615 * 2. Let the player know it worked.
917 */ 616 */
918 free_string (dummy->name); 617 free_string (dummy->name);
919 dummy->name = add_string (op->map->path); 618 dummy->name = add_string (op->map->path);
920 EXIT_X(dummy)= op->x; 619 EXIT_X(dummy)= op->x;
921 EXIT_Y(dummy)= op->y; 620 EXIT_Y(dummy)= op->y;
922 insert_ob_in_ob (dummy,op); 621 insert_ob_in_ob (dummy,op);
923 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You fix this place in your mind.\nYou feel you are able to come here from anywhere."); 622 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"You fix this place in your mind.\nYou feel you are able to come here from anywhere.");
924 return 1; 623 return 1;
925 } 624 }
926 free_object (dummy); 625 free_object (dummy);
927 626
928 /* Here we know where the town portal should go to 627 /* Here we know where the town portal should go to
929 * We should kill any existing portal associated with the player. 628 * We should kill any existing portal associated with the player.
942 */ 641 */
943 642
944 /* First step: killing existing town portals */ 643 /* First step: killing existing town portals */
945 dummy=get_archetype(spell->race); 644 dummy=get_archetype(spell->race);
946 if(dummy == NULL){ 645 if(dummy == NULL){
947 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 646 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
948 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); 647 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name);
949 return 0; 648 return 0;
950 } 649 }
951 perm_portal = find_archetype (spell->slaying); 650 perm_portal = find_archetype (spell->slaying);
952 651
953 /* To kill a town portal, we go trough the player's inventory, 652 /* To kill a town portal, we go trough the player's inventory,
954 * for each marked portal in player's inventory, 653 * for each marked portal in player's inventory,
956 * -We find any portal in the specified location. 655 * -We find any portal in the specified location.
957 * If it has the good name, we destruct it. 656 * If it has the good name, we destruct it.
958 * -We destruct the force indicating that portal. 657 * -We destruct the force indicating that portal.
959 */ 658 */
960 while ( (old_force=check_inv_recursive (op,dummy))) { 659 while ( (old_force=check_inv_recursive (op,dummy))) {
961 exitx=EXIT_X(old_force); 660 exitx=EXIT_X(old_force);
962 exity=EXIT_Y(old_force); 661 exity=EXIT_Y(old_force);
963 LOG (llevDebug,"Trying to kill a portal in %s (%d,%d)\n",old_force->race,exitx,exity); 662 LOG (llevDebug,"Trying to kill a portal in %s (%d,%d)\n",old_force->race,exitx,exity);
964 663
965 if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir))) 664 if (!strncmp(old_force->race, settings.localdir, strlen(settings.localdir)))
966 exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE); 665 exitmap = ready_map_name(old_force->race, MAP_PLAYER_UNIQUE);
967 else exitmap = ready_map_name(old_force->race, 0); 666 else exitmap = ready_map_name(old_force->race, 0);
968 667
969 if (exitmap) { 668 if (exitmap) {
970 tmp=present_arch (perm_portal,exitmap,exitx,exity); 669 tmp=present_arch (perm_portal,exitmap,exitx,exity);
971 while (tmp) { 670 while (tmp) {
972 if (tmp->name == old_force->name) { 671 if (tmp->name == old_force->name) {
973 remove_ob (tmp); 672 remove_ob (tmp);
974 free_object (tmp); 673 free_object (tmp);
975 break; 674 break;
976 } else { 675 } else {
977 tmp = tmp->above; 676 tmp = tmp->above;
978 } 677 }
979 } 678 }
980 } 679 }
981 remove_ob (old_force); 680 remove_ob (old_force);
982 free_object (old_force); 681 free_object (old_force);
983 LOG (llevDebug,"\n"); 682 LOG (llevDebug,"\n");
984 } 683 }
985 free_object (dummy); 684 free_object (dummy);
986 685
987 /* Creating the portals. 686 /* Creating the portals.
988 * The very first thing to do is to ensure 687 * The very first thing to do is to ensure
994 * from the players inventory above. 693 * from the players inventory above.
995 */ 694 */
996 695
997 /* Ensure exit map is loaded*/ 696 /* Ensure exit map is loaded*/
998 if (!strncmp(force->name, settings.localdir, strlen(settings.localdir))) 697 if (!strncmp(force->name, settings.localdir, strlen(settings.localdir)))
999 exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE); 698 exitmap = ready_map_name(force->name, MAP_PLAYER_UNIQUE);
1000 else 699 else
1001 exitmap = ready_map_name(force->name, 0); 700 exitmap = ready_map_name(force->name, 0);
1002 701
1003 /* If we were unable to load (ex. random map deleted), warn player*/ 702 /* If we were unable to load (ex. random map deleted), warn player*/
1004 if (exitmap==NULL) { 703 if (exitmap==NULL) {
1005 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"Something strange happens.\nYou can't remember where to go!?"); 704 new_draw_info(NDI_UNIQUE | NDI_NAVY, 0,op,"Something strange happens.\nYou can't remember where to go!?");
1006 remove_ob(force); 705 remove_ob(force);
1007 free_object(force); 706 free_object(force);
1008 return 1; 707 return 1;
1009 } 708 }
1010 709
1011 op_level = caster_level(caster, spell); 710 op_level = caster_level(caster, spell);
1012 if (op_level<15) 711 if (op_level<15)
1013 snprintf (portal_message,1024,"\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n",op->name); 712 snprintf (portal_message,1024,"\nThe air moves around you and\na huge smell of ammonia\nsurounds you as you pass\nthrough %s's tiny portal\nPouah!\n",op->name);
1023 */ 722 */
1024 723
1025 snprintf (portal_name,1024,"%s's portal to %s",op->name,force->name); 724 snprintf (portal_name,1024,"%s's portal to %s",op->name,force->name);
1026 dummy=get_archetype(spell->slaying); /*The portal*/ 725 dummy=get_archetype(spell->slaying); /*The portal*/
1027 if(dummy == NULL) { 726 if(dummy == NULL) {
1028 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 727 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
1029 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); 728 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name);
1030 return 0; 729 return 0;
1031 } 730 }
1032 EXIT_PATH(dummy) = add_string (force->name); 731 EXIT_PATH(dummy) = add_string (force->name);
1033 EXIT_X(dummy)=EXIT_X(force); 732 EXIT_X(dummy)=EXIT_X(force);
1034 EXIT_Y(dummy)=EXIT_Y(force); 733 EXIT_Y(dummy)=EXIT_Y(force);
1035 FREE_AND_COPY(dummy->name, portal_name); 734 FREE_AND_COPY(dummy->name, portal_name);
1042 * object, so on future castings, we can know that he has an active 741 * object, so on future castings, we can know that he has an active
1043 * town portal. 742 * town portal.
1044 */ 743 */
1045 tmp=get_archetype(spell->race); 744 tmp=get_archetype(spell->race);
1046 if(tmp == NULL){ 745 if(tmp == NULL){
1047 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 746 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
1048 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); 747 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name);
1049 return 0; 748 return 0;
1050 } 749 }
1051 tmp->race=add_string (op->map->path); 750 tmp->race=add_string (op->map->path);
1052 FREE_AND_COPY(tmp->name, portal_name); 751 FREE_AND_COPY(tmp->name, portal_name);
1053 EXIT_X(tmp)=dummy->x; 752 EXIT_X(tmp)=dummy->x;
1054 EXIT_Y(tmp)=dummy->y; 753 EXIT_Y(tmp)=dummy->y;
1061 * where this portal goes to. 760 * where this portal goes to.
1062 */ 761 */
1063 snprintf (portal_name,1024,"%s's portal to %s",op->name,op->map->path); 762 snprintf (portal_name,1024,"%s's portal to %s",op->name,op->map->path);
1064 dummy=get_archetype (spell->slaying); /*The portal*/ 763 dummy=get_archetype (spell->slaying); /*The portal*/
1065 if(dummy == NULL) { 764 if(dummy == NULL) {
1066 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 765 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
1067 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name); 766 LOG(llevError,"get_object failed (perm_magic_portal) in cast_create_town_portal for %s!\n",op->name);
1068 return 0; 767 return 0;
1069 } 768 }
1070 EXIT_PATH(dummy) = add_string (op->map->path); 769 EXIT_PATH(dummy) = add_string (op->map->path);
1071 EXIT_X(dummy)=op->x; 770 EXIT_X(dummy)=op->x;
1072 EXIT_Y(dummy)=op->y; 771 EXIT_Y(dummy)=op->y;
1073 FREE_AND_COPY(dummy->name, portal_name); 772 FREE_AND_COPY(dummy->name, portal_name);
1081 /* Now we create another town portal marker that 780 /* Now we create another town portal marker that
1082 * points back to the one we just made 781 * points back to the one we just made
1083 */ 782 */
1084 tmp=get_archetype(spell->race); 783 tmp=get_archetype(spell->race);
1085 if(tmp == NULL){ 784 if(tmp == NULL){
1086 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 785 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
1087 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name); 786 LOG(llevError,"get_object failed (force) in cast_create_town_portal for %s!\n",op->name);
1088 return 0; 787 return 0;
1089 } 788 }
1090 tmp->race=add_string(force->name); 789 tmp->race=add_string(force->name);
1091 FREE_AND_COPY(tmp->name, portal_name); 790 FREE_AND_COPY(tmp->name, portal_name);
1092 EXIT_X(tmp)=dummy->x; 791 EXIT_X(tmp)=dummy->x;
1093 EXIT_Y(tmp)=dummy->y; 792 EXIT_Y(tmp)=dummy->y;
1113 mapstruct *m; 812 mapstruct *m;
1114 const char *name; 813 const char *name;
1115 archetype *at; 814 archetype *at;
1116 815
1117 if(!dir) { 816 if(!dir) {
1118 dir=op->facing; 817 dir=op->facing;
1119 x = op->x; 818 x = op->x;
1120 y = op->y; 819 y = op->y;
1121 } else { 820 } else {
1122 x = op->x+freearr_x[dir]; 821 x = op->x+freearr_x[dir];
1123 y = op->y+freearr_y[dir]; 822 y = op->y+freearr_y[dir];
1124 } 823 }
1125 m = op->map; 824 m = op->map;
1126 825
1127 if ((spell_ob->move_block || x != op->x || y != op->y) && 826 if ((spell_ob->move_block || x != op->x || y != op->y) &&
1128 (get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE) || 827 (get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE) ||
1129 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) { 828 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) == spell_ob->move_block))) {
1130 new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way."); 829 new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way.");
1131 return 0; 830 return 0;
1132 } 831 }
1133 if (spell_ob->other_arch) { 832 if (spell_ob->other_arch) {
1134 tmp = arch_to_object(spell_ob->other_arch); 833 tmp = arch_to_object(spell_ob->other_arch);
1135 } else if (spell_ob->race) { 834 } else if (spell_ob->race) {
1136 char buf1[MAX_BUF]; 835 char buf1[MAX_BUF];
1137 836
1138 sprintf(buf1,spell_ob->race,dir); 837 sprintf(buf1,spell_ob->race,dir);
1139 at = find_archetype(buf1); 838 at = find_archetype(buf1);
1140 if (!at) { 839 if (!at) {
1141 LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1); 840 LOG(llevError, "summon_wall: Unable to find archetype %s\n", buf1);
1142 new_draw_info(NDI_UNIQUE, 0,op,"This spell is broken."); 841 new_draw_info(NDI_UNIQUE, 0,op,"This spell is broken.");
1143 return 0; 842 return 0;
1144 } 843 }
1145 tmp = arch_to_object(at); 844 tmp = arch_to_object(at);
1146 } else { 845 } else {
1147 LOG(llevError,"magic_wall: spell %s lacks other_arch\n", 846 LOG(llevError,"magic_wall: spell %s lacks other_arch\n",
1148 spell_ob->name); 847 spell_ob->name);
1149 return 0; 848 return 0;
1150 } 849 }
1151 850
1152 if (tmp->type == SPELL_EFFECT) { 851 if (tmp->type == SPELL_EFFECT) {
1153 tmp->attacktype = spell_ob->attacktype; 852 tmp->attacktype = spell_ob->attacktype;
1154 tmp->duration = spell_ob->duration + 853 tmp->duration = spell_ob->duration +
1155 SP_level_duration_adjust(caster, spell_ob); 854 SP_level_duration_adjust(caster, spell_ob);
1156 tmp->stats.dam = spell_ob->stats.dam + 855 tmp->stats.dam = spell_ob->stats.dam +
1157 SP_level_dam_adjust(caster, spell_ob); 856 SP_level_dam_adjust(caster, spell_ob);
1158 tmp->range = 0; 857 tmp->range = 0;
1159 } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) { 858 } else if (QUERY_FLAG(tmp, FLAG_ALIVE)) {
1160 tmp->stats.hp = spell_ob->duration + 859 tmp->stats.hp = spell_ob->duration +
1161 SP_level_duration_adjust(caster, spell_ob); 860 SP_level_duration_adjust(caster, spell_ob);
1162 tmp->stats.maxhp = tmp->stats.hp; 861 tmp->stats.maxhp = tmp->stats.hp;
1163 set_owner(tmp,op); 862 set_owner(tmp,op);
1164 set_spell_skill(op, caster, spell_ob, tmp); 863 set_spell_skill(op, caster, spell_ob, tmp);
1165 } 864 }
1166 if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) { 865 if (QUERY_FLAG(spell_ob, FLAG_IS_USED_UP) || QUERY_FLAG(tmp, FLAG_IS_USED_UP)) {
1167 tmp->stats.food = spell_ob->duration + 866 tmp->stats.food = spell_ob->duration +
1168 SP_level_duration_adjust(caster, spell_ob); 867 SP_level_duration_adjust(caster, spell_ob);
1169 SET_FLAG(tmp, FLAG_IS_USED_UP); 868 SET_FLAG(tmp, FLAG_IS_USED_UP);
1170 } 869 }
1171 if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) { 870 if (QUERY_FLAG(spell_ob, FLAG_TEAR_DOWN)) {
1172 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob); 871 tmp->stats.hp = spell_ob->stats.dam + SP_level_dam_adjust(caster, spell_ob);
1173 tmp->stats.maxhp = tmp->stats.hp; 872 tmp->stats.maxhp = tmp->stats.hp;
1174 SET_FLAG(tmp, FLAG_TEAR_DOWN); 873 SET_FLAG(tmp, FLAG_TEAR_DOWN);
1175 SET_FLAG(tmp, FLAG_ALIVE); 874 SET_FLAG(tmp, FLAG_ALIVE);
1176 } 875 }
1177 876
1178 /* This can't really hurt - if the object doesn't kill anything, 877 /* This can't really hurt - if the object doesn't kill anything,
1179 * these fields just won't be used. 878 * these fields just won't be used.
1180 */ 879 */
1184 tmp->y = y; 883 tmp->y = y;
1185 tmp->level = caster_level(caster, spell_ob) / 2; 884 tmp->level = caster_level(caster, spell_ob) / 2;
1186 885
1187 name = tmp->name; 886 name = tmp->name;
1188 if ((tmp = insert_ob_in_map (tmp, m, op,0)) == NULL) { 887 if ((tmp = insert_ob_in_map (tmp, m, op,0)) == NULL) {
1189 new_draw_info_format(NDI_UNIQUE, 0,op,"Something destroys your %s", name); 888 new_draw_info_format(NDI_UNIQUE, 0,op,"Something destroys your %s", name);
1190 return 0; 889 return 0;
1191 } 890 }
1192 /* If this is a spellcasting wall, need to insert the spell object */ 891 /* If this is a spellcasting wall, need to insert the spell object */
1193 if (tmp->other_arch && tmp->other_arch->clone.type == SPELL) 892 if (tmp->other_arch && tmp->other_arch->clone.type == SPELL)
1194 insert_ob_in_ob(arch_to_object(tmp->other_arch), tmp); 893 insert_ob_in_ob(arch_to_object(tmp->other_arch), tmp);
1195 894
1196 /* This code causes the wall to extend some distance in 895 /* This code causes the wall to extend some distance in
1197 * each direction, or until an obstruction is encountered. 896 * each direction, or until an obstruction is encountered.
1198 * posblocked and negblocked help determine how far the 897 * posblocked and negblocked help determine how far the
1199 * created wall can extend, it won't go extend through 898 * created wall can extend, it won't go extend through
1202 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob); 901 maxrange = spell_ob->range + SP_level_range_adjust(caster, spell_ob);
1203 posblocked=0; 902 posblocked=0;
1204 negblocked=0; 903 negblocked=0;
1205 904
1206 for(i=1; i<=maxrange; i++) { 905 for(i=1; i<=maxrange; i++) {
1207 int dir2; 906 int dir2;
1208 907
1209 dir2 = (dir<4)?(dir+2):dir-2; 908 dir2 = (dir<4)?(dir+2):dir-2;
1210 909
1211 x = tmp->x+i*freearr_x[dir2]; 910 x = tmp->x+i*freearr_x[dir2];
1212 y = tmp->y+i*freearr_y[dir2]; 911 y = tmp->y+i*freearr_y[dir2];
1213 m = tmp->map; 912 m = tmp->map;
1214 913
1215 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) && 914 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) &&
1216 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) && 915 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) &&
1217 !posblocked) { 916 !posblocked) {
1218 tmp2 = get_object(); 917 tmp2 = get_object();
1219 copy_object(tmp,tmp2); 918 copy_object(tmp,tmp2);
1220 tmp2->x = x; 919 tmp2->x = x;
1221 tmp2->y = y; 920 tmp2->y = y;
1222 insert_ob_in_map(tmp2,m,op,0); 921 insert_ob_in_map(tmp2,m,op,0);
1223 /* If this is a spellcasting wall, need to insert the spell object */ 922 /* If this is a spellcasting wall, need to insert the spell object */
1224 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 923 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1225 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2); 924 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2);
1226 925
1227 } else posblocked=1; 926 } else posblocked=1;
1228 927
1229 x = tmp->x-i*freearr_x[dir2]; 928 x = tmp->x-i*freearr_x[dir2];
1230 y = tmp->y-i*freearr_y[dir2]; 929 y = tmp->y-i*freearr_y[dir2];
1231 m = tmp->map; 930 m = tmp->map;
1232 931
1233 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) && 932 if(!(get_map_flags(m, &m, x, y, &x, &y) & (P_OUT_OF_MAP|P_IS_ALIVE)) &&
1234 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) && 933 ((spell_ob->move_block & GET_MAP_MOVE_BLOCK(m, x, y)) != spell_ob->move_block) &&
1235 !negblocked) { 934 !negblocked) {
1236 tmp2 = get_object(); 935 tmp2 = get_object();
1237 copy_object(tmp,tmp2); 936 copy_object(tmp,tmp2);
1238 tmp2->x = x; 937 tmp2->x = x;
1239 tmp2->y = y; 938 tmp2->y = y;
1240 insert_ob_in_map(tmp2,m,op,0); 939 insert_ob_in_map(tmp2,m,op,0);
1241 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL) 940 if (tmp2->other_arch && tmp2->other_arch->clone.type == SPELL)
1242 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2); 941 insert_ob_in_ob(arch_to_object(tmp2->other_arch), tmp2);
1243 } else negblocked=1; 942 } else negblocked=1;
1244 } 943 }
1245 944
1246 if(QUERY_FLAG(tmp, FLAG_BLOCKSVIEW)) 945 if(QUERY_FLAG(tmp, FLAG_BLOCKSVIEW))
1247 update_all_los(op->map, op->x, op->y); 946 update_all_los(op->map, op->x, op->y);
1248 947
1249 return 1; 948 return 1;
1250} 949}
1251 950
1252int dimension_door(object *op,object *caster, object *spob, int dir) { 951int dimension_door(object *op,object *caster, object *spob, int dir) {
1254 int mflags; 953 int mflags;
1255 mapstruct *m; 954 mapstruct *m;
1256 sint16 sx, sy; 955 sint16 sx, sy;
1257 956
1258 if(op->type!=PLAYER) 957 if(op->type!=PLAYER)
1259 return 0; 958 return 0;
1260 959
1261 if(!dir) { 960 if(!dir) {
1262 new_draw_info(NDI_UNIQUE, 0,op,"In what direction?"); 961 new_draw_info(NDI_UNIQUE, 0,op,"In what direction?");
1263 return 0; 962 return 0;
1264 } 963 }
1265 964
1266 /* Given the new outdoor maps, can't let players dimension door for 965 /* Given the new outdoor maps, can't let players dimension door for
1267 * ever, so put limits in. 966 * ever, so put limits in.
1268 */ 967 */
1269 maxdist = spob->range + 968 maxdist = spob->range +
1270 SP_level_range_adjust(caster, spob); 969 SP_level_range_adjust(caster, spob);
1271 970
1272 if(op->contr->count) { 971 if(op->contr->count) {
1273 if (op->contr->count > maxdist) { 972 if (op->contr->count > maxdist) {
1274 new_draw_info(NDI_UNIQUE, 0, op, "You can't dimension door that far!"); 973 new_draw_info(NDI_UNIQUE, 0, op, "You can't dimension door that far!");
1275 return 0; 974 return 0;
1276 } 975 }
1277 976
1278 for(dist=0;dist<op->contr->count; dist++) { 977 for(dist=0;dist<op->contr->count; dist++) {
1279 mflags = get_map_flags(op->map, &m, 978 mflags = get_map_flags(op->map, &m,
1280 op->x+freearr_x[dir]*(dist+1), op->y+freearr_y[dir]*(dist+1), 979 op->x+freearr_x[dir]*(dist+1), op->y+freearr_y[dir]*(dist+1),
1281 &sx, &sy); 980 &sx, &sy);
1282 981
1283 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break; 982 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break;
1284 983
1285 if ((mflags & P_BLOCKSVIEW) && 984 if ((mflags & P_BLOCKSVIEW) &&
1286 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break; 985 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break;
1287 } 986 }
1288 987
1289 if(dist<op->contr->count) { 988 if(dist<op->contr->count) {
1290 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks the magic of the spell.\n"); 989 new_draw_info(NDI_UNIQUE, 0,op,"Something blocks the magic of the spell.\n");
990 op->contr->count=0;
991 return 0;
992 }
1291 op->contr->count=0; 993 op->contr->count=0;
1292 return 0;
1293 }
1294 op->contr->count=0;
1295 994
1296 /* Remove code that puts player on random space on maps. IMO, 995 /* Remove code that puts player on random space on maps. IMO,
1297 * a lot of maps probably have areas the player should not get to, 996 * a lot of maps probably have areas the player should not get to,
1298 * but may not be marked as NO_MAGIC (as they may be bounded 997 * but may not be marked as NO_MAGIC (as they may be bounded
1299 * by such squares). Also, there are probably treasure rooms and 998 * by such squares). Also, there are probably treasure rooms and
1300 * lots of other maps that protect areas with no magic, but the 999 * lots of other maps that protect areas with no magic, but the
1301 * areas themselves don't contain no magic spaces. 1000 * areas themselves don't contain no magic spaces.
1302 */ 1001 */
1303 /* This call here is really just to normalize the coordinates */ 1002 /* This call here is really just to normalize the coordinates */
1304 mflags = get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist, 1003 mflags = get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1305 &sx, &sy); 1004 &sx, &sy);
1306 if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) { 1005 if (mflags&P_IS_ALIVE || OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) {
1307 new_draw_info(NDI_UNIQUE, 0,op,"You cast your spell, but nothing happens.\n"); 1006 new_draw_info(NDI_UNIQUE, 0,op,"You cast your spell, but nothing happens.\n");
1308 return 1; /* Maybe the penalty should be more severe... */ 1007 return 1; /* Maybe the penalty should be more severe... */
1309 } 1008 }
1310 } else { 1009 } else {
1311 /* Player didn't specify a distance, so lets see how far 1010 /* Player didn't specify a distance, so lets see how far
1312 * we can move the player. Don't know why this stopped on 1011 * we can move the player. Don't know why this stopped on
1313 * spaces that blocked the players view. 1012 * spaces that blocked the players view.
1314 */ 1013 */
1315 1014
1316 for(dist=0; dist < maxdist; dist++) { 1015 for(dist=0; dist < maxdist; dist++) {
1317 mflags = get_map_flags(op->map, &m, 1016 mflags = get_map_flags(op->map, &m,
1318 op->x+freearr_x[dir] * (dist+1), 1017 op->x+freearr_x[dir] * (dist+1),
1319 op->y+freearr_y[dir] * (dist+1), 1018 op->y+freearr_y[dir] * (dist+1),
1320 &sx, &sy); 1019 &sx, &sy);
1321 1020
1322 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break; 1021 if (mflags & (P_NO_MAGIC | P_OUT_OF_MAP)) break;
1323 1022
1324 if ((mflags & P_BLOCKSVIEW) && 1023 if ((mflags & P_BLOCKSVIEW) &&
1325 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break; 1024 OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break;
1326 1025
1327 } 1026 }
1328 1027
1329 /* If the destination is blocked, keep backing up until we 1028 /* If the destination is blocked, keep backing up until we
1330 * find a place for the player. 1029 * find a place for the player.
1331 */ 1030 */
1332 for(;dist>0; dist--) { 1031 for(;dist>0; dist--) {
1333 if (get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist, 1032 if (get_map_flags(op->map, &m,op->x+freearr_x[dir]*dist, op->y+freearr_y[dir]*dist,
1334 &sx, &sy) & (P_OUT_OF_MAP|P_IS_ALIVE)) continue; 1033 &sx, &sy) & (P_OUT_OF_MAP|P_IS_ALIVE)) continue;
1335 1034
1336 1035
1337 if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break; 1036 if (!OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, sx, sy))) break;
1338 1037
1339 } 1038 }
1340 if(!dist) { 1039 if(!dist) {
1341 new_draw_info(NDI_UNIQUE, 0,op,"Your spell failed!\n"); 1040 new_draw_info(NDI_UNIQUE, 0,op,"Your spell failed!\n");
1342 return 0; 1041 return 0;
1343 } 1042 }
1344 } 1043 }
1345 1044
1346 /* Actually move the player now */ 1045 /* Actually move the player now */
1347 remove_ob(op); 1046 remove_ob(op);
1348 op->x+=freearr_x[dir]*dist; 1047 op->x+=freearr_x[dir]*dist;
1373 /* Figure out how many hp this spell might cure. 1072 /* Figure out how many hp this spell might cure.
1374 * could be zero if this spell heals effects, not damage. 1073 * could be zero if this spell heals effects, not damage.
1375 */ 1074 */
1376 heal = spell->stats.dam; 1075 heal = spell->stats.dam;
1377 if (spell->stats.hp) 1076 if (spell->stats.hp)
1378 heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH) + 1077 heal += random_roll(spell->stats.hp, 6, op, PREFER_HIGH) +
1379 spell->stats.hp; 1078 spell->stats.hp;
1380 1079
1381 if (heal) { 1080 if (heal) {
1382 if (tmp->stats.hp >= tmp->stats.maxhp) {
1383 new_draw_info(NDI_UNIQUE, 0,tmp, "You are already fully healed.");
1384 }
1385 else {
1386 /* See how many points we actually heal. Instead of messages
1387 * based on type of spell, we instead do messages based
1388 * on amount of damage healed.
1389 */
1390 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1391 heal = tmp->stats.maxhp - tmp->stats.hp;
1392 tmp->stats.hp += heal;
1393
1394 if (tmp->stats.hp >= tmp->stats.maxhp) { 1081 if (tmp->stats.hp >= tmp->stats.maxhp) {
1082 new_draw_info(NDI_UNIQUE, 0,tmp, "You are already fully healed.");
1083 }
1084 else {
1085 /* See how many points we actually heal. Instead of messages
1086 * based on type of spell, we instead do messages based
1087 * on amount of damage healed.
1088 */
1089 if (heal > (tmp->stats.maxhp - tmp->stats.hp))
1090 heal = tmp->stats.maxhp - tmp->stats.hp;
1091 tmp->stats.hp += heal;
1092
1093 if (tmp->stats.hp >= tmp->stats.maxhp) {
1395 new_draw_info(NDI_UNIQUE, 0,tmp, "You feel just fine!"); 1094 new_draw_info(NDI_UNIQUE, 0,tmp, "You feel just fine!");
1396 } else if (heal > 50) { 1095 } else if (heal > 50) {
1397 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds close!"); 1096 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds close!");
1398 } else if (heal > 25) { 1097 } else if (heal > 25) {
1399 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds mostly close."); 1098 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds mostly close.");
1400 } else if (heal > 10) { 1099 } else if (heal > 10) {
1401 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to fade."); 1100 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to fade.");
1402 } else { 1101 } else {
1403 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to close."); 1102 new_draw_info(NDI_UNIQUE, 0,tmp, "Your wounds start to close.");
1404 } 1103 }
1405 success=1; 1104 success=1;
1406 } 1105 }
1407 } 1106 }
1408 if (spell->attacktype & AT_DISEASE) 1107 if (spell->attacktype & AT_DISEASE)
1409 if (cure_disease (tmp, op)) 1108 if (cure_disease (tmp, op))
1410 success = 1; 1109 success = 1;
1411 1110
1412 if (spell->attacktype & AT_POISON) { 1111 if (spell->attacktype & AT_POISON) {
1413 at = find_archetype("poisoning"); 1112 at = find_archetype("poisoning");
1414 poison=present_arch_in_ob(at,tmp); 1113 poison=present_arch_in_ob(at,tmp);
1415 if (poison) { 1114 if (poison) {
1416 success = 1; 1115 success = 1;
1417 new_draw_info(NDI_UNIQUE, 0,tmp, "Your body feels cleansed"); 1116 new_draw_info(NDI_UNIQUE, 0,tmp, "Your body feels cleansed");
1418 poison->stats.food = 1; 1117 poison->stats.food = 1;
1419 } 1118 }
1420 } 1119 }
1421 if (spell->attacktype & AT_CONFUSION) { 1120 if (spell->attacktype & AT_CONFUSION) {
1422 poison=present_in_ob_by_name(FORCE,"confusion", tmp); 1121 poison=present_in_ob_by_name(FORCE,"confusion", tmp);
1423 if (poison) { 1122 if (poison) {
1424 success = 1; 1123 success = 1;
1425 new_draw_info(NDI_UNIQUE, 0,tmp, "Your mind feels clearer"); 1124 new_draw_info(NDI_UNIQUE, 0,tmp, "Your mind feels clearer");
1426 poison->duration = 1; 1125 poison->duration = 1;
1427 } 1126 }
1428 } 1127 }
1429 if (spell->attacktype & AT_BLIND) { 1128 if (spell->attacktype & AT_BLIND) {
1430 at=find_archetype("blindness"); 1129 at=find_archetype("blindness");
1431 poison=present_arch_in_ob(at,tmp); 1130 poison=present_arch_in_ob(at,tmp);
1432 if (poison) { 1131 if (poison) {
1433 success = 1; 1132 success = 1;
1434 new_draw_info(NDI_UNIQUE, 0,tmp,"Your vision begins to return."); 1133 new_draw_info(NDI_UNIQUE, 0,tmp,"Your vision begins to return.");
1435 poison->stats.food = 1; 1134 poison->stats.food = 1;
1436 } 1135 }
1437 } 1136 }
1438 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) { 1137 if (spell->last_sp && tmp->stats.sp < tmp->stats.maxsp) {
1439 tmp->stats.sp += spell->last_sp; 1138 tmp->stats.sp += spell->last_sp;
1440 if (tmp->stats.sp > tmp->stats.maxsp) tmp->stats.sp = tmp->stats.maxsp; 1139 if (tmp->stats.sp > tmp->stats.maxsp) tmp->stats.sp = tmp->stats.maxsp;
1441 success = 1; 1140 success = 1;
1442 new_draw_info(NDI_UNIQUE, 0,tmp,"Magical energy surges through your body!"); 1141 new_draw_info(NDI_UNIQUE, 0,tmp,"Magical energy surges through your body!");
1443 } 1142 }
1444 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) { 1143 if (spell->last_grace && tmp->stats.grace < tmp->stats.maxgrace) {
1445 tmp->stats.grace += spell->last_grace; 1144 tmp->stats.grace += spell->last_grace;
1446 if (tmp->stats.grace > tmp->stats.maxgrace) tmp->stats.grace = tmp->stats.maxgrace; 1145 if (tmp->stats.grace > tmp->stats.maxgrace) tmp->stats.grace = tmp->stats.maxgrace;
1447 success = 1; 1146 success = 1;
1448 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel redeemed with your god!"); 1147 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel redeemed with your god!");
1449 } 1148 }
1450 if (spell->stats.food && tmp->stats.food < 999) { 1149 if (spell->stats.food && tmp->stats.food < 999) {
1451 tmp->stats.food += spell->stats.food; 1150 tmp->stats.food += spell->stats.food;
1452 if (tmp->stats.food > 999) tmp->stats.food=999; 1151 if (tmp->stats.food > 999) tmp->stats.food=999;
1453 success = 1; 1152 success = 1;
1454 /* We could do something a bit better like the messages for healing above */ 1153 /* We could do something a bit better like the messages for healing above */
1455 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel your belly fill with food"); 1154 new_draw_info(NDI_UNIQUE, 0,tmp,"You feel your belly fill with food");
1456 } 1155 }
1457 return success; 1156 return success;
1458} 1157}
1459 1158
1460 1159
1477 object *force=NULL; 1176 object *force=NULL;
1478 int i; 1177 int i;
1479 1178
1480 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */ 1179 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1481 if(dir!=0) { 1180 if(dir!=0) {
1482 tmp=find_target_for_friendly_spell(op,dir); 1181 tmp=find_target_for_friendly_spell(op,dir);
1483 } else { 1182 } else {
1484 tmp = op; 1183 tmp = op;
1485 } 1184 }
1486 1185
1487 if(tmp==NULL) return 0; 1186 if(tmp==NULL) return 0;
1488 1187
1489 /* If we've already got a force of this type, don't add a new one. */ 1188 /* If we've already got a force of this type, don't add a new one. */
1490 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) { 1189 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) {
1491 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) { 1190 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1492 if (tmp2->name == spell_ob->name) { 1191 if (tmp2->name == spell_ob->name) {
1493 force=tmp2; /* the old effect will be "refreshed" */ 1192 force=tmp2; /* the old effect will be "refreshed" */
1494 break; 1193 break;
1495 } 1194 }
1496 else if (spell_ob->race && spell_ob->race == tmp2->name) { 1195 else if (spell_ob->race && spell_ob->race == tmp2->name) {
1497 if ( !silent ) 1196 if ( !silent )
1498 new_draw_info_format(NDI_UNIQUE, 0, op, 1197 new_draw_info_format(NDI_UNIQUE, 0, op,
1499 "You can not cast %s while %s is in effect", 1198 "You can not cast %s while %s is in effect",
1500 spell_ob->name, tmp2->name_pl); 1199 spell_ob->name, tmp2->name_pl);
1501 return 0; 1200 return 0;
1502 } 1201 }
1503 } 1202 }
1504 } 1203 }
1505 if(force==NULL) { 1204 if(force==NULL) {
1506 force=get_archetype(FORCE_NAME); 1205 force=get_archetype(FORCE_NAME);
1507 force->subtype = FORCE_CHANGE_ABILITY; 1206 force->subtype = FORCE_CHANGE_ABILITY;
1508 free_string(force->name); 1207 free_string(force->name);
1509 if (spell_ob->race) 1208 if (spell_ob->race)
1510 force->name = add_refcount(spell_ob->race); 1209 force->name = add_refcount(spell_ob->race);
1511 else 1210 else
1211 force->name = add_refcount(spell_ob->name);
1212 free_string(force->name_pl);
1512 force->name = add_refcount(spell_ob->name); 1213 force->name_pl = add_refcount(spell_ob->name);
1513 free_string(force->name_pl);
1514 force->name_pl = add_refcount(spell_ob->name);
1515 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force."); 1214 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1516 1215
1517 } else { 1216 } else {
1518 int duration; 1217 int duration;
1519 1218
1520 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1219 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1521 if (duration > force->duration) { 1220 if (duration > force->duration) {
1522 force->duration = duration; 1221 force->duration = duration;
1523 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 1222 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1524 } else { 1223 } else {
1525 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1224 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1526 } 1225 }
1527 return 1; 1226 return 1;
1528 } 1227 }
1529 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1228 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1530 force->speed = 1.0; 1229 force->speed = 1.0;
1531 force->speed_left = -1.0; 1230 force->speed_left = -1.0;
1532 SET_FLAG(force, FLAG_APPLIED); 1231 SET_FLAG(force, FLAG_APPLIED);
1533 1232
1534 /* Now start processing the effects. First, protections */ 1233 /* Now start processing the effects. First, protections */
1535 for (i=0; i < NROFATTACKS; i++) { 1234 for (i=0; i < NROFATTACKS; i++) {
1536 if (spell_ob->resist[i]) { 1235 if (spell_ob->resist[i]) {
1537 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust(caster, spell_ob); 1236 force->resist[i] = spell_ob->resist[i] + SP_level_dam_adjust(caster, spell_ob);
1538 if (force->resist[i] > 100) force->resist[i] = 100; 1237 if (force->resist[i] > 100) force->resist[i] = 100;
1539 } 1238 }
1540 } 1239 }
1541 if (spell_ob->stats.hp) 1240 if (spell_ob->stats.hp)
1542 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust(caster,spell_ob); 1241 force->stats.hp = spell_ob->stats.hp + SP_level_dam_adjust(caster,spell_ob);
1543 1242
1544 if (tmp->type == PLAYER) { 1243 if (tmp->type == PLAYER) {
1545 /* Stat adjustment spells */ 1244 /* Stat adjustment spells */
1546 for (i=0; i < NUM_STATS; i++) { 1245 for (i=0; i < NUM_STATS; i++) {
1547 sint8 stat = get_attr_value(&spell_ob->stats, i), k, sm; 1246 sint8 stat = get_attr_value(&spell_ob->stats, i), k, sm;
1548 if (stat) { 1247 if (stat) {
1549 sm=0; 1248 sm=0;
1550 for (k=0; k<stat; k++) 1249 for (k=0; k<stat; k++)
1551 sm += rndm(1, 3); 1250 sm += rndm(1, 3);
1552 1251
1553 if ((get_attr_value(&tmp->stats, i) + sm) > (15 + 5 * stat)) { 1252 if ((get_attr_value(&tmp->stats, i) + sm) > (15 + 5 * stat)) {
1554 sm = (15 + 5 * stat) - get_attr_value(&tmp->stats, i); 1253 sm = (15 + 5 * stat) - get_attr_value(&tmp->stats, i);
1555 if (sm<0) sm = 0; 1254 if (sm<0) sm = 0;
1556 } 1255 }
1557 set_attr_value(&force->stats, i, sm); 1256 set_attr_value(&force->stats, i, sm);
1558 if (!sm) 1257 if (!sm)
1559 new_draw_info(NDI_UNIQUE, 0,op,no_gain_msgs[i]); 1258 new_draw_info(NDI_UNIQUE, 0,op,no_gain_msgs[i]);
1560 } 1259 }
1561 } 1260 }
1562 } 1261 }
1563 1262
1564 force->move_type = spell_ob->move_type; 1263 force->move_type = spell_ob->move_type;
1565 1264
1566 if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK)) 1265 if (QUERY_FLAG(spell_ob, FLAG_SEE_IN_DARK))
1567 SET_FLAG(force, FLAG_SEE_IN_DARK); 1266 SET_FLAG(force, FLAG_SEE_IN_DARK);
1568 1267
1569 if (QUERY_FLAG(spell_ob, FLAG_XRAYS)) 1268 if (QUERY_FLAG(spell_ob, FLAG_XRAYS))
1570 SET_FLAG(force, FLAG_XRAYS); 1269 SET_FLAG(force, FLAG_XRAYS);
1571 1270
1572 /* Haste/bonus speed */ 1271 /* Haste/bonus speed */
1573 if (spell_ob->stats.exp) { 1272 if (spell_ob->stats.exp) {
1574 if (op->speed > 0.5f) force->stats.exp = (sint64) ((float) spell_ob->stats.exp / (op->speed + 0.5f)); 1273 if (op->speed > 0.5f) force->stats.exp = (sint64) ((float) spell_ob->stats.exp / (op->speed + 0.5f));
1575 else 1274 else
1576 force->stats.exp = spell_ob->stats.exp; 1275 force->stats.exp = spell_ob->stats.exp;
1577 } 1276 }
1578 1277
1579 force->stats.wc = spell_ob->stats.wc; 1278 force->stats.wc = spell_ob->stats.wc;
1580 force->stats.ac = spell_ob->stats.ac; 1279 force->stats.ac = spell_ob->stats.ac;
1581 force->attacktype = spell_ob->attacktype; 1280 force->attacktype = spell_ob->attacktype;
1595 int i; 1294 int i;
1596 object *god = find_god(determine_god(op)), *tmp2, *force=NULL, *tmp; 1295 object *god = find_god(determine_god(op)), *tmp2, *force=NULL, *tmp;
1597 1296
1598 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */ 1297 /* if dir = 99 op defaults to tmp, eat_special_food() requires this. */
1599 if(dir!=0) { 1298 if(dir!=0) {
1600 tmp=find_target_for_friendly_spell(op,dir); 1299 tmp=find_target_for_friendly_spell(op,dir);
1601 } else { 1300 } else {
1602 tmp = op; 1301 tmp = op;
1603 } 1302 }
1604 1303
1605 /* If we've already got a force of this type, don't add a new one. */ 1304 /* If we've already got a force of this type, don't add a new one. */
1606 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) { 1305 for(tmp2=tmp->inv; tmp2!=NULL; tmp2=tmp2->below) {
1607 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) { 1306 if (tmp2->type==FORCE && tmp2->subtype == FORCE_CHANGE_ABILITY) {
1608 if (tmp2->name == spell_ob->name) { 1307 if (tmp2->name == spell_ob->name) {
1609 force=tmp2; /* the old effect will be "refreshed" */ 1308 force=tmp2; /* the old effect will be "refreshed" */
1610 break; 1309 break;
1611 } 1310 }
1612 else if (spell_ob->race && spell_ob->race == tmp2->name) { 1311 else if (spell_ob->race && spell_ob->race == tmp2->name) {
1613 new_draw_info_format(NDI_UNIQUE, 0, op, 1312 new_draw_info_format(NDI_UNIQUE, 0, op,
1614 "You can not cast %s while %s is in effect", 1313 "You can not cast %s while %s is in effect",
1615 spell_ob->name, tmp2->name_pl); 1314 spell_ob->name, tmp2->name_pl);
1616 return 0; 1315 return 0;
1617 } 1316 }
1618 } 1317 }
1619 } 1318 }
1620 if(force==NULL) { 1319 if(force==NULL) {
1621 force=get_archetype(FORCE_NAME); 1320 force=get_archetype(FORCE_NAME);
1622 force->subtype = FORCE_CHANGE_ABILITY; 1321 force->subtype = FORCE_CHANGE_ABILITY;
1623 free_string(force->name); 1322 free_string(force->name);
1624 if (spell_ob->race) 1323 if (spell_ob->race)
1625 force->name = add_refcount(spell_ob->race); 1324 force->name = add_refcount(spell_ob->race);
1626 else 1325 else
1326 force->name = add_refcount(spell_ob->name);
1327 free_string(force->name_pl);
1627 force->name = add_refcount(spell_ob->name); 1328 force->name_pl = add_refcount(spell_ob->name);
1628 free_string(force->name_pl);
1629 force->name_pl = add_refcount(spell_ob->name);
1630 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force."); 1329 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force.");
1631 } else { 1330 } else {
1632 int duration; 1331 int duration;
1633 1332
1634 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1333 duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1635 if (duration > force->duration) { 1334 if (duration > force->duration) {
1636 force->duration = duration; 1335 force->duration = duration;
1637 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 1336 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
1638 } else { 1337 } else {
1639 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect."); 1338 new_draw_info(NDI_UNIQUE, 0, op, "Recasting the spell had no effect.");
1640 } 1339 }
1641 return 0; 1340 return 0;
1642 } 1341 }
1643 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50; 1342 force->duration = spell_ob->duration + SP_level_duration_adjust(caster, spell_ob) * 50;
1644 force->speed = 1.0; 1343 force->speed = 1.0;
1645 force->speed_left = -1.0; 1344 force->speed_left = -1.0;
1646 SET_FLAG(force, FLAG_APPLIED); 1345 SET_FLAG(force, FLAG_APPLIED);
1647 1346
1648 if(!god) { 1347 if(!god) {
1649 new_draw_info(NDI_UNIQUE, 0,op,"Your blessing seems empty."); 1348 new_draw_info(NDI_UNIQUE, 0,op,"Your blessing seems empty.");
1650 } else { 1349 } else {
1651 /* Only give out good benefits, and put a max on it */ 1350 /* Only give out good benefits, and put a max on it */
1652 for (i=0; i<NROFATTACKS; i++) { 1351 for (i=0; i<NROFATTACKS; i++) {
1653 if (god->resist[i]>0) { 1352 if (god->resist[i]>0) {
1654 force->resist[i] = MIN(god->resist[i], spell_ob->resist[ATNR_GODPOWER]); 1353 force->resist[i] = MIN(god->resist[i], spell_ob->resist[ATNR_GODPOWER]);
1655 } 1354 }
1656 } 1355 }
1657 force->path_attuned|=god->path_attuned; 1356 force->path_attuned|=god->path_attuned;
1658 if (spell_ob->attacktype) { 1357 if (spell_ob->attacktype) {
1659 force->attacktype|=god->attacktype | AT_PHYSICAL; 1358 force->attacktype|=god->attacktype | AT_PHYSICAL;
1660 if(god->slaying) force->slaying = add_string(god->slaying); 1359 if(god->slaying) force->slaying = add_string(god->slaying);
1661 } 1360 }
1662 if (tmp != op) { 1361 if (tmp != op) {
1663 new_draw_info_format(NDI_UNIQUE, 0, op, "You bless %s.", tmp->name); 1362 new_draw_info_format(NDI_UNIQUE, 0, op, "You bless %s.", tmp->name);
1664 new_draw_info_format(NDI_UNIQUE, 0, tmp, "%s blessed you.", op->name); 1363 new_draw_info_format(NDI_UNIQUE, 0, tmp, "%s blessed you.", op->name);
1665 } else { 1364 } else {
1666 new_draw_info_format(NDI_UNIQUE, 0,tmp, 1365 new_draw_info_format(NDI_UNIQUE, 0,tmp,
1667 "You are blessed by %s!",god->name); 1366 "You are blessed by %s!",god->name);
1668 } 1367 }
1669 1368
1670 } 1369 }
1671 force->stats.wc = spell_ob->stats.wc; 1370 force->stats.wc = spell_ob->stats.wc;
1672 force->stats.ac = spell_ob->stats.ac; 1371 force->stats.ac = spell_ob->stats.ac;
1673 1372
1706 * is finished. 1405 * is finished.
1707 */ 1406 */
1708static object *small, *large; 1407static object *small, *large;
1709 1408
1710static void alchemy_object(object *obj, int *small_nuggets, 1409static void alchemy_object(object *obj, int *small_nuggets,
1711 int *large_nuggets, int *weight) 1410 int *large_nuggets, int *weight)
1712{ 1411{
1713 uint64 value=query_cost(obj, NULL, F_TRUE); 1412 uint64 value=query_cost(obj, NULL, F_TRUE);
1714 1413
1715 /* Give third price when we alchemy money (This should hopefully 1414 /* Give third price when we alchemy money (This should hopefully
1716 * make it so that it isn't worth it to alchemy money, sell 1415 * make it so that it isn't worth it to alchemy money, sell
1719 * so that it would still be more affordable to haul 1418 * so that it would still be more affordable to haul
1720 * the stuff back to town. 1419 * the stuff back to town.
1721 */ 1420 */
1722 1421
1723 if (QUERY_FLAG(obj, FLAG_UNPAID)) 1422 if (QUERY_FLAG(obj, FLAG_UNPAID))
1724 value=0; 1423 value=0;
1725 else if (obj->type==MONEY || obj->type==GEM) 1424 else if (obj->type==MONEY || obj->type==GEM)
1726 value /=3; 1425 value /=3;
1727 else 1426 else
1728 value = (value*9)/10; 1427 value = (value*9)/10;
1729 1428
1730 value /= 4; // fix by GHJ, don't understand, pcg 1429 value /= 4; // fix by GHJ, don't understand, pcg
1731 1430
1732 if ((obj->value>0) && rndm(0, 29)) { 1431 if ((obj->value>0) && rndm(0, 29)) {
1733 int count; 1432 int count;
1734 1433
1735 count = value / large->value; 1434 count = value / large->value;
1736 *large_nuggets += count; 1435 *large_nuggets += count;
1737 value -= (uint64)count * (uint64)large->value; 1436 value -= (uint64)count * (uint64)large->value;
1738 count = value / small->value; 1437 count = value / small->value;
1739 *small_nuggets += count; 1438 *small_nuggets += count;
1740 } 1439 }
1741 1440
1742 /* Turn 25 small nuggets into 1 large nugget. If the value 1441 /* Turn 25 small nuggets into 1 large nugget. If the value
1743 * of large nuggets is not evenly divisable by the small nugget 1442 * of large nuggets is not evenly divisable by the small nugget
1744 * value, take off an extra small_nugget (Assuming small_nuggets!=0) 1443 * value, take off an extra small_nugget (Assuming small_nuggets!=0)
1745 */ 1444 */
1746 if (*small_nuggets * small->value >= large->value) { 1445 if (*small_nuggets * small->value >= large->value) {
1747 (*large_nuggets)++; 1446 (*large_nuggets)++;
1748 *small_nuggets -= large->value / small->value; 1447 *small_nuggets -= large->value / small->value;
1749 if (*small_nuggets && large->value % small->value) 1448 if (*small_nuggets && large->value % small->value)
1750 (*small_nuggets)--; 1449 (*small_nuggets)--;
1751 } 1450 }
1752 weight += obj->weight; 1451 weight += obj->weight;
1753 remove_ob(obj); 1452 remove_ob(obj);
1754 free_object(obj); 1453 free_object(obj);
1755} 1454}
1756 1455
1757static void update_map(object *op, mapstruct *m, int small_nuggets, int large_nuggets, 1456static void update_map(object *op, mapstruct *m, int small_nuggets, int large_nuggets,
1758 int x, int y) 1457 int x, int y)
1759{ 1458{
1760 object *tmp; 1459 object *tmp;
1761 int flag=0; 1460 int flag=0;
1762 1461
1763 /* Put any nuggets below the player, but we can only pass this 1462 /* Put any nuggets below the player, but we can only pass this
1764 * flag if we are on the same space as the player 1463 * flag if we are on the same space as the player
1765 */ 1464 */
1766 if (x == op->x && y == op->y && op->map == m) flag = INS_BELOW_ORIGINATOR; 1465 if (x == op->x && y == op->y && op->map == m) flag = INS_BELOW_ORIGINATOR;
1767 1466
1768 if (small_nuggets) { 1467 if (small_nuggets) {
1769 tmp = get_object(); 1468 tmp = get_object();
1770 copy_object(small, tmp); 1469 copy_object(small, tmp);
1771 tmp-> nrof = small_nuggets; 1470 tmp-> nrof = small_nuggets;
1772 tmp->x = x; 1471 tmp->x = x;
1773 tmp->y = y; 1472 tmp->y = y;
1774 insert_ob_in_map(tmp, m, op, flag); 1473 insert_ob_in_map(tmp, m, op, flag);
1775 } 1474 }
1776 if (large_nuggets) { 1475 if (large_nuggets) {
1777 tmp = get_object(); 1476 tmp = get_object();
1778 copy_object(large, tmp); 1477 copy_object(large, tmp);
1779 tmp-> nrof = large_nuggets; 1478 tmp-> nrof = large_nuggets;
1780 tmp->x = x; 1479 tmp->x = x;
1781 tmp->y = y; 1480 tmp->y = y;
1782 insert_ob_in_map(tmp, m, op, flag); 1481 insert_ob_in_map(tmp, m, op, flag);
1783 } 1482 }
1784} 1483}
1785 1484
1786int alchemy(object *op, object *caster, object *spell_ob) 1485int alchemy(object *op, object *caster, object *spell_ob)
1787{ 1486{
1789 sint16 nx, ny; 1488 sint16 nx, ny;
1790 object *next,*tmp; 1489 object *next,*tmp;
1791 mapstruct *mp; 1490 mapstruct *mp;
1792 1491
1793 if(op->type!=PLAYER) 1492 if(op->type!=PLAYER)
1794 return 0; 1493 return 0;
1795 1494
1796 /* Put a maximum weight of items that can be alchemied. Limits the power 1495 /* Put a maximum weight of items that can be alchemied. Limits the power
1797 * some, and also prevents people from alcheming every table/chair/clock 1496 * some, and also prevents people from alcheming every table/chair/clock
1798 * in sight 1497 * in sight
1799 */ 1498 */
1801 weight_max *= 1000; 1500 weight_max *= 1000;
1802 small=get_archetype("smallnugget"), 1501 small=get_archetype("smallnugget"),
1803 large=get_archetype("largenugget"); 1502 large=get_archetype("largenugget");
1804 1503
1805 for(y= op->y-1;y<=op->y+1;y++) { 1504 for(y= op->y-1;y<=op->y+1;y++) {
1806 for(x= op->x-1;x<=op->x+1;x++) { 1505 for(x= op->x-1;x<=op->x+1;x++) {
1807 nx = x; 1506 nx = x;
1808 ny = y; 1507 ny = y;
1809 1508
1810 mp = op->map; 1509 mp = op->map;
1811 1510
1812 mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny); 1511 mflags = get_map_flags(mp, &mp, nx, ny, &nx, &ny);
1813 1512
1814 if(mflags & (P_OUT_OF_MAP | P_NO_MAGIC)) 1513 if(mflags & (P_OUT_OF_MAP | P_NO_MAGIC))
1815 continue; 1514 continue;
1816 1515
1817 /* Treat alchemy a little differently - most spell effects 1516 /* Treat alchemy a little differently - most spell effects
1818 * use fly as the movement type - for alchemy, consider it 1517 * use fly as the movement type - for alchemy, consider it
1819 * ground level effect. 1518 * ground level effect.
1820 */ 1519 */
1821 if (GET_MAP_MOVE_BLOCK(mp, nx, ny) & MOVE_WALK) 1520 if (GET_MAP_MOVE_BLOCK(mp, nx, ny) & MOVE_WALK)
1822 continue; 1521 continue;
1823 1522
1824 small_nuggets=0; 1523 small_nuggets=0;
1825 large_nuggets=0; 1524 large_nuggets=0;
1826 1525
1827 for(tmp=get_map_ob(mp,nx,ny);tmp!=NULL;tmp=next) { 1526 for(tmp=get_map_ob(mp,nx,ny);tmp!=NULL;tmp=next) {
1828 next=tmp->above; 1527 next=tmp->above;
1829 if (tmp->weight>0 && !QUERY_FLAG(tmp, FLAG_NO_PICK) &&
1830 !QUERY_FLAG(tmp, FLAG_ALIVE) &&
1831 !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
1832
1833 if (tmp->inv) {
1834 object *next1, *tmp1;
1835 for (tmp1 = tmp->inv; tmp1!=NULL; tmp1=next1) {
1836 next1 = tmp1->below;
1837 if (tmp1->weight>0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK) && 1528 if (tmp->weight>0 && !QUERY_FLAG(tmp, FLAG_NO_PICK) &&
1838 !QUERY_FLAG(tmp1, FLAG_ALIVE) && 1529 !QUERY_FLAG(tmp, FLAG_ALIVE) &&
1839 !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON)) 1530 !QUERY_FLAG(tmp, FLAG_IS_CAULDRON)) {
1840 alchemy_object(tmp1, &small_nuggets, &large_nuggets, 1531
1841 &weight); 1532 if (tmp->inv) {
1842 } 1533 object *next1, *tmp1;
1843 } 1534 for (tmp1 = tmp->inv; tmp1!=NULL; tmp1=next1) {
1535 next1 = tmp1->below;
1536 if (tmp1->weight>0 && !QUERY_FLAG(tmp1, FLAG_NO_PICK) &&
1537 !QUERY_FLAG(tmp1, FLAG_ALIVE) &&
1538 !QUERY_FLAG(tmp1, FLAG_IS_CAULDRON))
1539 alchemy_object(tmp1, &small_nuggets, &large_nuggets,
1540 &weight);
1541 }
1542 }
1844 alchemy_object(tmp, &small_nuggets, &large_nuggets, &weight); 1543 alchemy_object(tmp, &small_nuggets, &large_nuggets, &weight);
1845 1544
1846 if (weight>weight_max) { 1545 if (weight>weight_max) {
1847 update_map(op, mp, small_nuggets, large_nuggets, nx, ny); 1546 update_map(op, mp, small_nuggets, large_nuggets, nx, ny);
1848 free_object(large); 1547 free_object(large);
1849 free_object(small); 1548 free_object(small);
1850 return 1; 1549 return 1;
1851 } 1550 }
1852 } /* is alchemable object */ 1551 } /* is alchemable object */
1853 } /* process all objects on this space */ 1552 } /* process all objects on this space */
1854 1553
1855 /* Insert all the nuggets at one time. This probably saves time, but 1554 /* Insert all the nuggets at one time. This probably saves time, but
1856 * it also prevents us from alcheming nuggets that were just created 1555 * it also prevents us from alcheming nuggets that were just created
1857 * with this spell. 1556 * with this spell.
1858 */ 1557 */
1859 update_map(op, mp, small_nuggets, large_nuggets, nx, ny); 1558 update_map(op, mp, small_nuggets, large_nuggets, nx, ny);
1860 } 1559 }
1861 } 1560 }
1862 free_object(large); 1561 free_object(large);
1863 free_object(small); 1562 free_object(small);
1864 /* reset this so that if player standing on a big pile of stuff, 1563 /* reset this so that if player standing on a big pile of stuff,
1865 * it is redrawn properly. 1564 * it is redrawn properly.
1875int remove_curse(object *op, object *caster, object *spell) { 1574int remove_curse(object *op, object *caster, object *spell) {
1876 object *tmp; 1575 object *tmp;
1877 int success = 0, was_one = 0; 1576 int success = 0, was_one = 0;
1878 1577
1879 for (tmp = op->inv; tmp; tmp = tmp->below) 1578 for (tmp = op->inv; tmp; tmp = tmp->below)
1880 if (QUERY_FLAG(tmp, FLAG_APPLIED) && 1579 if (QUERY_FLAG(tmp, FLAG_APPLIED) &&
1881 ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED)) || 1580 ((QUERY_FLAG(tmp, FLAG_CURSED) && QUERY_FLAG(spell, FLAG_CURSED)) ||
1882 (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) { 1581 (QUERY_FLAG(tmp, FLAG_DAMNED) && QUERY_FLAG(spell, FLAG_DAMNED)))) {
1883 1582
1884 was_one++; 1583 was_one++;
1885 if (tmp->level <= caster_level(caster, spell)) { 1584 if (tmp->level <= caster_level(caster, spell)) {
1886 success++; 1585 success++;
1887 if (QUERY_FLAG(spell, FLAG_DAMNED)) 1586 if (QUERY_FLAG(spell, FLAG_DAMNED))
1888 CLEAR_FLAG(tmp, FLAG_DAMNED); 1587 CLEAR_FLAG(tmp, FLAG_DAMNED);
1889 1588
1890 CLEAR_FLAG(tmp, FLAG_CURSED); 1589 CLEAR_FLAG(tmp, FLAG_CURSED);
1891 CLEAR_FLAG(tmp, FLAG_KNOWN_CURSED); 1590 CLEAR_FLAG(tmp, FLAG_KNOWN_CURSED);
1892 tmp->value = 0; /* Still can't sell it */ 1591 tmp->value = 0; /* Still can't sell it */
1893 if (op->type == PLAYER) 1592 if (op->type == PLAYER)
1894 esrv_send_item(op, tmp); 1593 esrv_send_item(op, tmp);
1895 } 1594 }
1896 } 1595 }
1897 1596
1898 if (op->type==PLAYER) { 1597 if (op->type==PLAYER) {
1899 if (success) { 1598 if (success) {
1900 new_draw_info(NDI_UNIQUE, 0,op, "You feel like some of your items are looser now."); 1599 new_draw_info(NDI_UNIQUE, 0,op, "You feel like some of your items are looser now.");
1901 } else { 1600 } else {
1902 if (was_one) 1601 if (was_one)
1903 new_draw_info(NDI_UNIQUE, 0,op, "You failed to remove the curse."); 1602 new_draw_info(NDI_UNIQUE, 0,op, "You failed to remove the curse.");
1904 else 1603 else
1905 new_draw_info(NDI_UNIQUE, 0,op, "You are not using any cursed items."); 1604 new_draw_info(NDI_UNIQUE, 0,op, "You are not using any cursed items.");
1906 } 1605 }
1907 } 1606 }
1908 return success; 1607 return success;
1909} 1608}
1910 1609
1911/* Identifies objects in the players inventory/on the ground */ 1610/* Identifies objects in the players inventory/on the ground */
1918 1617
1919 if (num_ident < 1) num_ident=1; 1618 if (num_ident < 1) num_ident=1;
1920 1619
1921 1620
1922 for (tmp = op->inv; tmp ; tmp = tmp->below) { 1621 for (tmp = op->inv; tmp ; tmp = tmp->below) {
1923 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify(tmp)) { 1622 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && need_identify(tmp)) {
1924 identify(tmp); 1623 identify(tmp);
1925 if (op->type==PLAYER) { 1624 if (op->type==PLAYER) {
1926 new_draw_info_format(NDI_UNIQUE, 0, op, 1625 new_draw_info_format(NDI_UNIQUE, 0, op,
1927 "You have %s.", long_desc(tmp, op)); 1626 "You have %s.", long_desc(tmp, op));
1928 if (tmp->msg) { 1627 if (tmp->msg) {
1929 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:"); 1628 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:");
1930 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg); 1629 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg);
1931 } 1630 }
1932 } 1631 }
1933 num_ident--; 1632 num_ident--;
1934 success=1; 1633 success=1;
1935 if (!num_ident) break; 1634 if (!num_ident) break;
1936 } 1635 }
1937 } 1636 }
1938 /* If all the power of the spell has been used up, don't go and identify 1637 /* If all the power of the spell has been used up, don't go and identify
1939 * stuff on the floor. Only identify stuff on the floor if the spell 1638 * stuff on the floor. Only identify stuff on the floor if the spell
1940 * was not fully used. 1639 * was not fully used.
1941 */ 1640 */
1942 if (num_ident) { 1641 if (num_ident) {
1943 for(tmp = get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) 1642 for(tmp = get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above)
1944 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible && 1643 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && !tmp->invisible &&
1945 need_identify(tmp)) { 1644 need_identify(tmp)) {
1946 1645
1947 identify(tmp); 1646 identify(tmp);
1948 if (op->type==PLAYER) { 1647 if (op->type==PLAYER) {
1949 new_draw_info_format(NDI_UNIQUE, 0,op, 1648 new_draw_info_format(NDI_UNIQUE, 0,op,
1950 "On the ground is %s.", long_desc(tmp, op)); 1649 "On the ground is %s.", long_desc(tmp, op));
1951 if (tmp->msg) { 1650 if (tmp->msg) {
1952 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:"); 1651 new_draw_info(NDI_UNIQUE, 0,op, "The item has a story:");
1953 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg); 1652 new_draw_info(NDI_UNIQUE, 0,op, tmp->msg);
1954 } 1653 }
1955 esrv_send_item(op, tmp); 1654 esrv_send_item(op, tmp);
1956 } 1655 }
1957 num_ident--; 1656 num_ident--;
1958 success=1; 1657 success=1;
1959 if (!num_ident) break; 1658 if (!num_ident) break;
1960 } 1659 }
1961 } 1660 }
1962 if (!success) 1661 if (!success)
1963 new_draw_info(NDI_UNIQUE, 0,op, "You can't reach anything unidentified."); 1662 new_draw_info(NDI_UNIQUE, 0,op, "You can't reach anything unidentified.");
1964 else { 1663 else {
1965 spell_effect(spell, op->x, op->y, op->map, op); 1664 spell_effect(spell, op->x, op->y, op->map, op);
1966 } 1665 }
1967 return success; 1666 return success;
1968} 1667}
1969 1668
1970 1669
1982 range = spell->range + SP_level_range_adjust(caster, spell); 1681 range = spell->range + SP_level_range_adjust(caster, spell);
1983 1682
1984 if (!skill) skill=caster; 1683 if (!skill) skill=caster;
1985 1684
1986 for (x = op->x - range; x <= op->x + range; x++) 1685 for (x = op->x - range; x <= op->x + range; x++)
1987 for (y = op->y - range; y <= op->y + range; y++) { 1686 for (y = op->y - range; y <= op->y + range; y++) {
1988 1687
1989 m = op->map; 1688 m = op->map;
1990 mflags = get_map_flags(m, &m, x, y, &nx, &ny); 1689 mflags = get_map_flags(m, &m, x, y, &nx, &ny);
1991 if (mflags & P_OUT_OF_MAP) continue; 1690 if (mflags & P_OUT_OF_MAP) continue;
1992 1691
1993 /* For most of the detections, we only detect objects above the 1692 /* For most of the detections, we only detect objects above the
1994 * floor. But this is not true for show invisible. 1693 * floor. But this is not true for show invisible.
1995 * Basically, we just go and find the top object and work 1694 * Basically, we just go and find the top object and work
1996 * down - that is easier than working up. 1695 * down - that is easier than working up.
1997 */ 1696 */
1998 1697
1999 for (last=NULL, tmp=get_map_ob(m, nx, ny); tmp; tmp=tmp->above) last=tmp; 1698 for (last=NULL, tmp=get_map_ob(m, nx, ny); tmp; tmp=tmp->above) last=tmp;
2000 /* Shouldn't happen, but if there are no objects on a space, this 1699 /* Shouldn't happen, but if there are no objects on a space, this
2001 * would happen. 1700 * would happen.
2002 */ 1701 */
2003 if (!last) continue; 1702 if (!last) continue;
2004 1703
2005 done_one=0; 1704 done_one=0;
2006 floor=0; 1705 floor=0;
2007 detect = NULL; 1706 detect = NULL;
2008 for (tmp=last; tmp; tmp=tmp->below) { 1707 for (tmp=last; tmp; tmp=tmp->below) {
2009 1708
2010 /* show invisible */ 1709 /* show invisible */
2011 if (QUERY_FLAG(spell, FLAG_MAKE_INVIS) && 1710 if (QUERY_FLAG(spell, FLAG_MAKE_INVIS) &&
2012 /* Might there be other objects that we can make visibile? */ 1711 /* Might there be other objects that we can make visibile? */
2013 (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) || 1712 (tmp->invisible && (QUERY_FLAG(tmp, FLAG_MONSTER) ||
2014 (tmp->type==PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) || 1713 (tmp->type==PLAYER && !QUERY_FLAG(tmp, FLAG_WIZ)) ||
2015 tmp->type==CF_HANDLE || 1714 tmp->type==CF_HANDLE ||
2016 tmp->type==TRAPDOOR || tmp->type==EXIT || tmp->type==HOLE || 1715 tmp->type==TRAPDOOR || tmp->type==EXIT || tmp->type==HOLE ||
2017 tmp->type==BUTTON || tmp->type==TELEPORTER || 1716 tmp->type==BUTTON || tmp->type==TELEPORTER ||
2018 tmp->type==GATE || tmp->type==LOCKED_DOOR || 1717 tmp->type==GATE || tmp->type==LOCKED_DOOR ||
2019 tmp->type==WEAPON || tmp->type==ALTAR || tmp->type==SIGN || 1718 tmp->type==WEAPON || tmp->type==ALTAR || tmp->type==SIGN ||
2020 tmp->type==TRIGGER_PEDESTAL || tmp->type==SPECIAL_KEY || 1719 tmp->type==TRIGGER_PEDESTAL || tmp->type==SPECIAL_KEY ||
2021 tmp->type==TREASURE || tmp->type==BOOK || 1720 tmp->type==TREASURE || tmp->type==BOOK ||
2022 tmp->type==HOLY_ALTAR))) { 1721 tmp->type==HOLY_ALTAR))) {
2023 if(random_roll(0, skill->level-1, op, PREFER_HIGH) > level/4) { 1722 if(random_roll(0, skill->level-1, op, PREFER_HIGH) > level/4) {
2024 tmp->invisible=0; 1723 tmp->invisible=0;
2025 done_one = 1; 1724 done_one = 1;
2026 } 1725 }
2027 } 1726 }
2028 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) floor=1; 1727 if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) floor=1;
2029 1728
2030 /* All detections below this point don't descend beneath the floor, 1729 /* All detections below this point don't descend beneath the floor,
2031 * so just continue on. We could be clever and look at the type of 1730 * so just continue on. We could be clever and look at the type of
2032 * detection to completely break out if we don't care about objects beneath 1731 * detection to completely break out if we don't care about objects beneath
2033 * the floor, but once we get to the floor, not likely a very big issue anyways. 1732 * the floor, but once we get to the floor, not likely a very big issue anyways.
2034 */ 1733 */
2035 if (floor) continue; 1734 if (floor) continue;
2036 1735
2037 /* I had thought about making detect magic and detect curse 1736 /* I had thought about making detect magic and detect curse
2038 * show the flash the magic item like it does for detect monster. 1737 * show the flash the magic item like it does for detect monster.
2039 * however, if the object is within sight, this would then make it 1738 * however, if the object is within sight, this would then make it
2040 * difficult to see what object is magical/cursed, so the 1739 * difficult to see what object is magical/cursed, so the
2041 * effect wouldn't be as apparant. 1740 * effect wouldn't be as apparant.
2042 */ 1741 */
2043 1742
2044 /* detect magic */ 1743 /* detect magic */
2045 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) && 1744 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) &&
2046 !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) && 1745 !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) &&
2047 !QUERY_FLAG(tmp, FLAG_IDENTIFIED) && 1746 !QUERY_FLAG(tmp, FLAG_IDENTIFIED) &&
2048 is_magical(tmp)) { 1747 is_magical(tmp)) {
2049 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 1748 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL);
2050 /* make runes more visibile */ 1749 /* make runes more visibile */
2051 if(tmp->type==RUNE && tmp->attacktype&AT_MAGIC) 1750 if(tmp->type==RUNE && tmp->attacktype&AT_MAGIC)
2052 tmp->stats.Cha/=4; 1751 tmp->stats.Cha/=4;
2053 done_one = 1; 1752 done_one = 1;
2054 } 1753 }
2055 /* detect monster */ 1754 /* detect monster */
2056 if (QUERY_FLAG(spell, FLAG_MONSTER) && 1755 if (QUERY_FLAG(spell, FLAG_MONSTER) &&
2057 (QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type==PLAYER)) { 1756 (QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type==PLAYER)) {
2058 done_one = 2; 1757 done_one = 2;
2059 if (!detect) detect=tmp; 1758 if (!detect) detect=tmp;
2060 } 1759 }
2061 /* Basically, if race is set in the spell, then the creatures race must 1760 /* Basically, if race is set in the spell, then the creatures race must
2062 * match that. if the spell race is set to GOD, then the gods opposing 1761 * match that. if the spell race is set to GOD, then the gods opposing
2063 * race must match. 1762 * race must match.
2064 */ 1763 */
2065 if (spell->race && QUERY_FLAG(tmp,FLAG_MONSTER) && tmp->race && 1764 if (spell->race && QUERY_FLAG(tmp,FLAG_MONSTER) && tmp->race &&
2066 ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying,tmp->race)) || 1765 ((!strcmp(spell->race, "GOD") && god && god->slaying && strstr(god->slaying,tmp->race)) ||
2067 (strstr(spell->race, tmp->race)))) { 1766 (strstr(spell->race, tmp->race)))) {
2068 done_one = 2; 1767 done_one = 2;
2069 if (!detect) detect=tmp; 1768 if (!detect) detect=tmp;
2070 } 1769 }
2071 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && 1770 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) &&
2072 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) { 1771 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2073 SET_FLAG(tmp, FLAG_KNOWN_CURSED); 1772 SET_FLAG(tmp, FLAG_KNOWN_CURSED);
2074 done_one = 1; 1773 done_one = 1;
2075 } 1774 }
2076 } /* for stack of objects on this space */ 1775 } /* for stack of objects on this space */
2077 1776
2078 /* Code here puts an effect of the spell on the space, so you can see 1777 /* Code here puts an effect of the spell on the space, so you can see
2079 * where the magic is. 1778 * where the magic is.
2080 */ 1779 */
2081 if (done_one) { 1780 if (done_one) {
2082 object *detect_ob = arch_to_object(spell->other_arch); 1781 object *detect_ob = arch_to_object(spell->other_arch);
2083 detect_ob->x = nx; 1782 detect_ob->x = nx;
2084 detect_ob->y = ny; 1783 detect_ob->y = ny;
2085 /* if this is set, we want to copy the face */ 1784 /* if this is set, we want to copy the face */
2086 if (done_one == 2 && detect) { 1785 if (done_one == 2 && detect) {
2087 detect_ob->face = detect->face; 1786 detect_ob->face = detect->face;
2088 detect_ob->animation_id = detect->animation_id; 1787 detect_ob->animation_id = detect->animation_id;
2089 detect_ob->anim_speed = detect->anim_speed; 1788 detect_ob->anim_speed = detect->anim_speed;
2090 detect_ob->last_anim=0; 1789 detect_ob->last_anim=0;
2091 /* by default, the detect_ob is already animated */ 1790 /* by default, the detect_ob is already animated */
2092 if (!QUERY_FLAG(detect, FLAG_ANIMATE)) CLEAR_FLAG(detect_ob, FLAG_ANIMATE); 1791 if (!QUERY_FLAG(detect, FLAG_ANIMATE)) CLEAR_FLAG(detect_ob, FLAG_ANIMATE);
2093 } 1792 }
2094 insert_ob_in_map(detect_ob, m, op,0); 1793 insert_ob_in_map(detect_ob, m, op,0);
2095 } 1794 }
2096 } /* for processing the surrounding spaces */ 1795 } /* for processing the surrounding spaces */
2097 1796
2098 1797
2099 /* Now process objects in the players inventory if detect curse or magic */ 1798 /* Now process objects in the players inventory if detect curse or magic */
2100 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) { 1799 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) || QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL)) {
2101 done_one = 0; 1800 done_one = 0;
2102 for (tmp = op->inv; tmp; tmp = tmp->below) { 1801 for (tmp = op->inv; tmp; tmp = tmp->below) {
2103 if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) { 1802 if (!tmp->invisible && !QUERY_FLAG(tmp, FLAG_IDENTIFIED)) {
2104 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) && 1803 if (QUERY_FLAG(spell, FLAG_KNOWN_MAGICAL) &&
2105 is_magical(tmp) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL)) { 1804 is_magical(tmp) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL)) {
2106 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 1805 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL);
2107 if (op->type==PLAYER) 1806 if (op->type==PLAYER)
2108 esrv_send_item (op, tmp); 1807 esrv_send_item (op, tmp);
2109 } 1808 }
2110 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) && 1809 if (QUERY_FLAG(spell, FLAG_KNOWN_CURSED) && !QUERY_FLAG(tmp, FLAG_KNOWN_CURSED) &&
2111 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) { 1810 (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED))) {
2112 SET_FLAG(tmp, FLAG_KNOWN_CURSED); 1811 SET_FLAG(tmp, FLAG_KNOWN_CURSED);
2113 if (op->type==PLAYER) 1812 if (op->type==PLAYER)
2114 esrv_send_item (op, tmp); 1813 esrv_send_item (op, tmp);
2115 } 1814 }
2116 } /* if item is not identified */ 1815 } /* if item is not identified */
2117 } /* for the players inventory */ 1816 } /* for the players inventory */
2118 } /* if detect magic/curse and object is a player */ 1817 } /* if detect magic/curse and object is a player */
2119 return 1; 1818 return 1;
2120} 1819}
2121 1820
2122 1821
2180 y = op->y+freearr_y[dir]; 1879 y = op->y+freearr_y[dir];
2181 1880
2182 mflags = get_map_flags(m, &m, x, y, &x, &y); 1881 mflags = get_map_flags(m, &m, x, y, &x, &y);
2183 1882
2184 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) { 1883 if (!(mflags & P_OUT_OF_MAP) && mflags & P_IS_ALIVE) {
2185 for(plyr=get_map_ob(m, x, y); plyr!=NULL; plyr=plyr->above) 1884 for(plyr=get_map_ob(m, x, y); plyr!=NULL; plyr=plyr->above)
2186 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE)) 1885 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2187 break; 1886 break;
2188 } 1887 }
2189 1888
2190 1889
2191 /* If we did not find a player in the specified direction, transfer 1890 /* If we did not find a player in the specified direction, transfer
2192 * to anyone on top of us. This is used for the rune of transference mostly. 1891 * to anyone on top of us. This is used for the rune of transference mostly.
2193 */ 1892 */
2194 if(plyr==NULL) 1893 if(plyr==NULL)
2195 for(plyr=get_map_ob(op->map,op->x,op->y); plyr!=NULL; plyr=plyr->above) 1894 for(plyr=get_map_ob(op->map,op->x,op->y); plyr!=NULL; plyr=plyr->above)
2196 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE)) 1895 if (plyr != op && QUERY_FLAG(plyr, FLAG_ALIVE))
2197 break; 1896 break;
2198 1897
2199 if (!plyr) { 1898 if (!plyr) {
2200 new_draw_info(NDI_BLACK, 0, op, "There is no one there."); 1899 new_draw_info(NDI_BLACK, 0, op, "There is no one there.");
2201 return 0; 1900 return 0;
2202 } 1901 }
2203 /* give sp */ 1902 /* give sp */
2204 if(spell->stats.dam > 0) { 1903 if(spell->stats.dam > 0) {
2205 plyr->stats.sp += spell->stats.dam + SP_level_dam_adjust(caster, spell); 1904 plyr->stats.sp += spell->stats.dam + SP_level_dam_adjust(caster, spell);
2206 charge_mana_effect(plyr, caster_level(caster, spell)); 1905 charge_mana_effect(plyr, caster_level(caster, spell));
2207 return 1; 1906 return 1;
2208 } 1907 }
2209 /* suck sp away. Can't suck sp from yourself */ 1908 /* suck sp away. Can't suck sp from yourself */
2210 else if (op != plyr) { 1909 else if (op != plyr) {
2211 /* old dragin magic used floats. easier to just use ints and divide by 100 */ 1910 /* old dragin magic used floats. easier to just use ints and divide by 100 */
2212 1911
2213 int rate = -spell->stats.dam + SP_level_dam_adjust(caster, spell), sucked; 1912 int rate = -spell->stats.dam + SP_level_dam_adjust(caster, spell), sucked;
2214 1913
2215 if (rate > 95) rate=95; 1914 if (rate > 95) rate=95;
2216 1915
2217 sucked = (plyr->stats.sp * rate) / 100; 1916 sucked = (plyr->stats.sp * rate) / 100;
2218 plyr->stats.sp -= sucked; 1917 plyr->stats.sp -= sucked;
2219 if (QUERY_FLAG(op, FLAG_ALIVE)) { 1918 if (QUERY_FLAG(op, FLAG_ALIVE)) {
2220 /* Player doesn't get full credit */ 1919 /* Player doesn't get full credit */
2221 sucked = (sucked * rate) / 100; 1920 sucked = (sucked * rate) / 100;
2222 op->stats.sp += sucked; 1921 op->stats.sp += sucked;
2223 if (sucked > 0) { 1922 if (sucked > 0) {
2224 charge_mana_effect(op, caster_level(caster, spell)); 1923 charge_mana_effect(op, caster_level(caster, spell));
2225 } 1924 }
2226 } 1925 }
2227 return 1; 1926 return 1;
2228 } 1927 }
2229 return 0; 1928 return 0;
2230} 1929}
2231 1930
2232 1931
2248 m = op->map; 1947 m = op->map;
2249 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy); 1948 mflags = get_map_flags(m, &m, sx, sy, &sx, &sy);
2250 if (mflags & P_OUT_OF_MAP) return; 1949 if (mflags & P_OUT_OF_MAP) return;
2251 1950
2252 for(tmp=get_map_ob(m,sx,sy); tmp!=NULL; tmp=next) { 1951 for(tmp=get_map_ob(m,sx,sy); tmp!=NULL; tmp=next) {
2253 next = tmp->above; 1952 next = tmp->above;
2254 1953
2255 /* Need to look at the head object - otherwise, if tmp 1954 /* Need to look at the head object - otherwise, if tmp
2256 * points to a monster, we don't have all the necessary 1955 * points to a monster, we don't have all the necessary
2257 * info for it. 1956 * info for it.
2258 */ 1957 */
2259 if (tmp->head) head = tmp->head; 1958 if (tmp->head) head = tmp->head;
2260 else head = tmp; 1959 else head = tmp;
2261 1960
2262 /* don't attack our own spells */ 1961 /* don't attack our own spells */
2263 if(tmp->owner && tmp->owner == op->owner) continue; 1962 if(tmp->owner && tmp->owner == op->owner) continue;
2264 1963
2265 /* Basically, if the object is magical and not counterspell, 1964 /* Basically, if the object is magical and not counterspell,
2266 * we will more or less remove the object. Don't counterspell 1965 * we will more or less remove the object. Don't counterspell
2267 * monsters either. 1966 * monsters either.
2268 */ 1967 */
2269 1968
2270 if (head->attacktype & AT_MAGIC && 1969 if (head->attacktype & AT_MAGIC &&
2271 !(head->attacktype & AT_COUNTERSPELL) && 1970 !(head->attacktype & AT_COUNTERSPELL) &&
2272 !QUERY_FLAG(head,FLAG_MONSTER) && 1971 !QUERY_FLAG(head,FLAG_MONSTER) &&
2273 (op->level > head->level)) { 1972 (op->level > head->level)) {
2274 remove_ob(head); 1973 remove_ob(head);
2275 free_object(head); 1974 free_object(head);
2276 } else switch(head->type) { 1975 } else switch(head->type) {
2277 case SPELL_EFFECT: 1976 case SPELL_EFFECT:
2278 if(op->level > head->level) { 1977 if(op->level > head->level) {
2279 remove_ob(head); 1978 remove_ob(head);
2280 free_object(head); 1979 free_object(head);
2281 } 1980 }
2282 break; 1981 break;
2283 1982
2284 /* I really don't get this rune code that much - that 1983 /* I really don't get this rune code that much - that
2285 * random chance seems really low. 1984 * random chance seems really low.
2286 */ 1985 */
2287 case RUNE: 1986 case RUNE:
2288 if(rndm(0, 149) == 0) { 1987 if(rndm(0, 149) == 0) {
2289 head->stats.hp--; /* weaken the rune */ 1988 head->stats.hp--; /* weaken the rune */
2290 if(!head->stats.hp) { 1989 if(!head->stats.hp) {
2291 remove_ob(head); 1990 remove_ob(head);
2292 free_object(head); 1991 free_object(head);
2293 } 1992 }
2294 } 1993 }
2295 break; 1994 break;
2296 } 1995 }
2297 } 1996 }
2298} 1997}
2299 1998
2300 1999
2301 2000
2304 char buf[MAX_BUF]; 2003 char buf[MAX_BUF];
2305 2004
2306 object *tmp, *god=find_god(determine_god(op)); 2005 object *tmp, *god=find_god(determine_god(op));
2307 2006
2308 if(!god) { 2007 if(!god) {
2309 new_draw_info(NDI_UNIQUE, 0,op, 2008 new_draw_info(NDI_UNIQUE, 0,op,
2310 "You can't consecrate anything if you don't worship a god!"); 2009 "You can't consecrate anything if you don't worship a god!");
2311 return 0; 2010 return 0;
2312 } 2011 }
2313 2012
2314 for(tmp=op->below;tmp;tmp=tmp->below) { 2013 for(tmp=op->below;tmp;tmp=tmp->below) {
2315 if(QUERY_FLAG(tmp,FLAG_IS_FLOOR)) break; 2014 if(QUERY_FLAG(tmp,FLAG_IS_FLOOR)) break;
2316 if(tmp->type==HOLY_ALTAR) { 2015 if(tmp->type==HOLY_ALTAR) {
2317 2016
2318 if(tmp->level > caster_level(caster, spell)) { 2017 if(tmp->level > caster_level(caster, spell)) {
2319 new_draw_info_format(NDI_UNIQUE, 0,op, 2018 new_draw_info_format(NDI_UNIQUE, 0,op,
2320 "You are not powerful enough to reconsecrate the %s", tmp->name); 2019 "You are not powerful enough to reconsecrate the %s", tmp->name);
2321 return 0; 2020 return 0;
2322 } else { 2021 } else {
2323 /* If we got here, we are consecrating an altar */ 2022 /* If we got here, we are consecrating an altar */
2324 if(tmp->name) free_string(tmp->name); 2023 if(tmp->name) free_string(tmp->name);
2325 sprintf(buf,"Altar of %s",god->name); 2024 sprintf(buf,"Altar of %s",god->name);
2326 tmp->name = add_string(buf); 2025 tmp->name = add_string(buf);
2327 tmp->level = caster_level(caster, spell); 2026 tmp->level = caster_level(caster, spell);
2328 tmp->other_arch = god->arch; 2027 tmp->other_arch = god->arch;
2329 if(op->type==PLAYER) esrv_update_item(UPD_NAME, op, tmp); 2028 if(op->type==PLAYER) esrv_update_item(UPD_NAME, op, tmp);
2330 new_draw_info_format(NDI_UNIQUE,0, op, 2029 new_draw_info_format(NDI_UNIQUE,0, op,
2331 "You consecrated the altar to %s!",god->name); 2030 "You consecrated the altar to %s!",god->name);
2332 return 1; 2031 return 1;
2333 } 2032 }
2334 } 2033 }
2335 } 2034 }
2336 new_draw_info(NDI_UNIQUE, 0,op,"You are not standing over an altar!"); 2035 new_draw_info(NDI_UNIQUE, 0,op,"You are not standing over an altar!");
2337 return 0; 2036 return 0;
2338} 2037}
2339 2038
2355 sint16 x, y; 2054 sint16 x, y;
2356 mapstruct *m; 2055 mapstruct *m;
2357 materialtype_t *mt; 2056 materialtype_t *mt;
2358 2057
2359 if(!spell->other_arch){ 2058 if(!spell->other_arch){
2360 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!"); 2059 new_draw_info(NDI_UNIQUE, 0,op,"Oops, program error!");
2361 LOG(llevError,"animate_weapon failed: spell %s missing other_arch!\n", spell->name); 2060 LOG(llevError,"animate_weapon failed: spell %s missing other_arch!\n", spell->name);
2362 return 0; 2061 return 0;
2363 } 2062 }
2364 /* exit if it's not a player using this spell. */ 2063 /* exit if it's not a player using this spell. */
2365 if(op->type!=PLAYER) return 0; 2064 if(op->type!=PLAYER) return 0;
2366 2065
2367 /* if player already has a golem, abort */ 2066 /* if player already has a golem, abort */
2368 if(op->contr->ranges[range_golem]!=NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) { 2067 if(op->contr->ranges[range_golem]!=NULL && op->contr->golem_count == op->contr->ranges[range_golem]->count) {
2369 control_golem(op->contr->ranges[range_golem],dir); 2068 control_golem(op->contr->ranges[range_golem],dir);
2370 return 0; 2069 return 0;
2371 } 2070 }
2372 2071
2373 /* if no direction specified, pick one */ 2072 /* if no direction specified, pick one */
2374 if(!dir) 2073 if(!dir)
2375 dir=find_free_spot(NULL,op->map,op->x,op->y,1,9); 2074 dir=find_free_spot(NULL,op->map,op->x,op->y,1,9);
2376 2075
2377 m = op->map; 2076 m = op->map;
2378 x = op->x+freearr_x[dir]; 2077 x = op->x+freearr_x[dir];
2379 y = op->y+freearr_y[dir]; 2078 y = op->y+freearr_y[dir];
2380 2079
2381 /* if there's no place to put the golem, abort */ 2080 /* if there's no place to put the golem, abort */
2382 if((dir==-1) || (get_map_flags(m, &m, x, y, &x, &y) & P_OUT_OF_MAP) || 2081 if((dir==-1) || (get_map_flags(m, &m, x, y, &x, &y) & P_OUT_OF_MAP) ||
2383 ((spell->other_arch->clone.move_type & GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) { 2082 ((spell->other_arch->clone.move_type & GET_MAP_MOVE_BLOCK(m, x, y)) == spell->other_arch->clone.move_type)) {
2384 new_draw_info(NDI_UNIQUE, 0,op,"There is something in the way."); 2083 new_draw_info(NDI_UNIQUE, 0,op,"There is something in the way.");
2385 return 0; 2084 return 0;
2386 } 2085 }
2387 2086
2388 /* Use the weapon marked by the player. */ 2087 /* Use the weapon marked by the player. */
2389 weapon = find_marked_object(op); 2088 weapon = find_marked_object(op);
2390 2089
2391 if (!weapon) { 2090 if (!weapon) {
2392 new_draw_info(NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!"); 2091 new_draw_info(NDI_BLACK, 0, op, "You must mark a weapon to use with this spell!");
2393 return 0; 2092 return 0;
2394 } 2093 }
2395 if (spell->race && strcmp(weapon->arch->name, spell->race)) { 2094 if (spell->race && strcmp(weapon->arch->name, spell->race)) {
2396 new_draw_info(NDI_UNIQUE, 0,op,"The spell fails to transform your weapon."); 2095 new_draw_info(NDI_UNIQUE, 0,op,"The spell fails to transform your weapon.");
2397 return 0; 2096 return 0;
2398 } 2097 }
2399 if (weapon->type != WEAPON) { 2098 if (weapon->type != WEAPON) {
2400 new_draw_info(NDI_UNIQUE, 0,op,"You need to wield a weapon to animate it."); 2099 new_draw_info(NDI_UNIQUE, 0,op,"You need to wield a weapon to animate it.");
2401 return 0; 2100 return 0;
2402 } 2101 }
2403 if (QUERY_FLAG(weapon, FLAG_APPLIED)) { 2102 if (QUERY_FLAG(weapon, FLAG_APPLIED)) {
2404 new_draw_info_format(NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell", 2103 new_draw_info_format(NDI_BLACK, 0, op, "You need to unequip %s before using it in this spell",
2405 query_name(weapon)); 2104 query_name(weapon));
2406 return 0; 2105 return 0;
2407 } 2106 }
2408 2107
2409 if (weapon->nrof > 1) { 2108 if (weapon->nrof > 1) {
2410 tmp = get_split_ob(weapon, 1); 2109 tmp = get_split_ob(weapon, 1);
2411 esrv_send_item(op, weapon); 2110 esrv_send_item(op, weapon);
2412 weapon = tmp; 2111 weapon = tmp;
2413 } 2112 }
2414 2113
2415 /* create the golem object */ 2114 /* create the golem object */
2416 tmp=arch_to_object(spell->other_arch); 2115 tmp=arch_to_object(spell->other_arch);
2417 2116
2430 /* Give the weapon to the golem now. A bit of a hack to check the 2129 /* Give the weapon to the golem now. A bit of a hack to check the
2431 * removed flag - it should only be set if get_split_object was 2130 * removed flag - it should only be set if get_split_object was
2432 * used above. 2131 * used above.
2433 */ 2132 */
2434 if (!QUERY_FLAG(weapon, FLAG_REMOVED)) 2133 if (!QUERY_FLAG(weapon, FLAG_REMOVED))
2435 remove_ob (weapon); 2134 remove_ob (weapon);
2436 insert_ob_in_ob (weapon, tmp); 2135 insert_ob_in_ob (weapon, tmp);
2437 esrv_send_item(op, weapon); 2136 esrv_send_item(op, weapon);
2438 /* To do everything necessary to let a golem use the weapon is a pain, 2137 /* To do everything necessary to let a golem use the weapon is a pain,
2439 * so instead, just set it as equipped (otherwise, we need to update 2138 * so instead, just set it as equipped (otherwise, we need to update
2440 * body_info, skills, etc) 2139 * body_info, skills, etc)
2448 * if you're using a crappy weapon, it shouldn't be as good. 2147 * if you're using a crappy weapon, it shouldn't be as good.
2449 */ 2148 */
2450 2149
2451 /* modify weapon's animated wc */ 2150 /* modify weapon's animated wc */
2452 tmp->stats.wc = tmp->stats.wc - SP_level_range_adjust(caster,spell) 2151 tmp->stats.wc = tmp->stats.wc - SP_level_range_adjust(caster,spell)
2453 - 5 * weapon->stats.Dex - 2 * weapon->stats.Str - weapon->magic; 2152 - 5 * weapon->stats.Dex - 2 * weapon->stats.Str - weapon->magic;
2454 if(tmp->stats.wc<-127) tmp->stats.wc = -127; 2153 if(tmp->stats.wc<-127) tmp->stats.wc = -127;
2455 2154
2456 /* Modify hit points for weapon */ 2155 /* Modify hit points for weapon */
2457 tmp->stats.maxhp = tmp->stats.maxhp + spell->duration + 2156 tmp->stats.maxhp = tmp->stats.maxhp + spell->duration +
2458 SP_level_duration_adjust(caster, spell) + 2157 SP_level_duration_adjust(caster, spell) +
2459 + 8 * weapon->magic + 12 * weapon->stats.Con; 2158 + 8 * weapon->magic + 12 * weapon->stats.Con;
2460 if(tmp->stats.maxhp<0) tmp->stats.maxhp=10; 2159 if(tmp->stats.maxhp<0) tmp->stats.maxhp=10;
2461 tmp->stats.hp = tmp->stats.maxhp; 2160 tmp->stats.hp = tmp->stats.maxhp;
2462 2161
2463 /* Modify weapon's damage */ 2162 /* Modify weapon's damage */
2464 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust(caster, spell) 2163 tmp->stats.dam = spell->stats.dam + SP_level_dam_adjust(caster, spell)
2465 + weapon->stats.dam 2164 + weapon->stats.dam
2466 + weapon->magic 2165 + weapon->magic
2467 + 5 * weapon->stats.Str; 2166 + 5 * weapon->stats.Str;
2468 if(tmp->stats.dam<0) tmp->stats.dam=127; 2167 if(tmp->stats.dam<0) tmp->stats.dam=127;
2469 2168
2470 2169
2471 /* attacktype */ 2170 /* attacktype */
2472 if ( ! tmp->attacktype) 2171 if ( ! tmp->attacktype)
2473 tmp->attacktype = AT_PHYSICAL; 2172 tmp->attacktype = AT_PHYSICAL;
2474 2173
2475 mt = NULL; 2174 mt = NULL;
2476 if (op->materialname != NULL) 2175 if (op->materialname != NULL)
2477 mt = name_to_material(op->materialname); 2176 mt = name_to_material(op->materialname);
2478 if (mt != NULL) { 2177 if (mt != NULL) {
2479 for (i=0; i < NROFATTACKS; i++) 2178 for (i=0; i < NROFATTACKS; i++)
2480 tmp->resist[i] = 50 - (mt->save[i] * 5); 2179 tmp->resist[i] = 50 - (mt->save[i] * 5);
2481 a = mt->save[0]; 2180 a = mt->save[0];
2482 } else { 2181 } else {
2483 for (i=0; i < NROFATTACKS; i++) 2182 for (i=0; i < NROFATTACKS; i++)
2484 tmp->resist[i] = 5; 2183 tmp->resist[i] = 5;
2485 a = 10; 2184 a = 10;
2486 } 2185 }
2487 /* Set weapon's immunity */ 2186 /* Set weapon's immunity */
2488 tmp->resist[ATNR_CONFUSION] = 100; 2187 tmp->resist[ATNR_CONFUSION] = 100;
2489 tmp->resist[ATNR_POISON] = 100; 2188 tmp->resist[ATNR_POISON] = 100;
2490 tmp->resist[ATNR_SLOW] = 100; 2189 tmp->resist[ATNR_SLOW] = 100;
2504 tmp->speed = 0.4 + 0.1 * SP_level_range_adjust(caster,spell); 2203 tmp->speed = 0.4 + 0.1 * SP_level_range_adjust(caster,spell);
2505 2204
2506 if(tmp->speed > 3.33) tmp->speed = 3.33; 2205 if(tmp->speed > 3.33) tmp->speed = 3.33;
2507 2206
2508 if (!spell->race) { 2207 if (!spell->race) {
2509 sprintf(buf, "animated %s", weapon->name); 2208 sprintf(buf, "animated %s", weapon->name);
2510 if(tmp->name) free_string(tmp->name); 2209 if(tmp->name) free_string(tmp->name);
2511 tmp->name = add_string(buf); 2210 tmp->name = add_string(buf);
2512 2211
2513 tmp->face = weapon->face; 2212 tmp->face = weapon->face;
2514 tmp->animation_id = weapon->animation_id; 2213 tmp->animation_id = weapon->animation_id;
2515 tmp->anim_speed = weapon->anim_speed; 2214 tmp->anim_speed = weapon->anim_speed;
2516 tmp->last_anim = weapon->last_anim; 2215 tmp->last_anim = weapon->last_anim;
2517 tmp->state = weapon->state; 2216 tmp->state = weapon->state;
2518 if(QUERY_FLAG(weapon, FLAG_ANIMATE)) { 2217 if(QUERY_FLAG(weapon, FLAG_ANIMATE)) {
2519 SET_FLAG(tmp,FLAG_ANIMATE); 2218 SET_FLAG(tmp,FLAG_ANIMATE);
2520 } else { 2219 } else {
2521 CLEAR_FLAG(tmp,FLAG_ANIMATE); 2220 CLEAR_FLAG(tmp,FLAG_ANIMATE);
2522 } 2221 }
2523 update_ob_speed(tmp); 2222 update_ob_speed(tmp);
2524 } 2223 }
2525 2224
2526 /* make experience increase in proportion to the strength of the summoned creature. */ 2225 /* make experience increase in proportion to the strength of the summoned creature. */
2527 tmp->stats.exp *= 1 + (MAX(spell->stats.maxgrace, spell->stats.sp) / caster_level(caster, spell)); 2226 tmp->stats.exp *= 1 + (MAX(spell->stats.maxgrace, spell->stats.sp) / caster_level(caster, spell));
2528 2227
2545 2244
2546 if(!op->map) return 0; /* shouldnt happen */ 2245 if(!op->map) return 0; /* shouldnt happen */
2547 2246
2548 success=change_map_light(op->map,spell->stats.dam); 2247 success=change_map_light(op->map,spell->stats.dam);
2549 if(!success) { 2248 if(!success) {
2550 if (spell->stats.dam < 0) 2249 if (spell->stats.dam < 0)
2551 new_draw_info(NDI_UNIQUE,0,op,"It can be no brighter here."); 2250 new_draw_info(NDI_UNIQUE,0,op,"It can be no brighter here.");
2552 else 2251 else
2553 new_draw_info(NDI_UNIQUE,0,op,"It can be no darker here."); 2252 new_draw_info(NDI_UNIQUE,0,op,"It can be no darker here.");
2554 } 2253 }
2555 return success; 2254 return success;
2556} 2255}
2557 2256
2558 2257
2582 set_spell_skill(op, caster, spell, new_aura); 2281 set_spell_skill(op, caster, spell, new_aura);
2583 new_aura->attacktype= spell->attacktype; 2282 new_aura->attacktype= spell->attacktype;
2584 2283
2585 new_aura->level = caster_level(caster, spell); 2284 new_aura->level = caster_level(caster, spell);
2586 if (refresh) 2285 if (refresh)
2587 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect."); 2286 new_draw_info(NDI_UNIQUE, 0, op, "You recast the spell while in effect.");
2588 else 2287 else
2589 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force."); 2288 new_draw_info(NDI_UNIQUE, 0, op, "You create an aura of magical force.");
2590 insert_ob_in_ob(new_aura, op); 2289 insert_ob_in_ob(new_aura, op);
2591 return 1; 2290 return 1;
2592} 2291}
2593 2292
2594 2293
2595/* move aura function. An aura is a part of someone's inventory, 2294/* move aura function. An aura is a part of someone's inventory,
2614 */ 2313 */
2615 remove_ob(aura); 2314 remove_ob(aura);
2616 2315
2617 /* exit if we're out of gas */ 2316 /* exit if we're out of gas */
2618 if(aura->duration--< 0) { 2317 if(aura->duration--< 0) {
2619 free_object(aura); 2318 free_object(aura);
2620 return; 2319 return;
2621 } 2320 }
2622 2321
2623 /* auras only exist in inventories */ 2322 /* auras only exist in inventories */
2624 if(env == NULL || env->map==NULL) { 2323 if(env == NULL || env->map==NULL) {
2625 free_object(aura); 2324 free_object(aura);
2626 return; 2325 return;
2627 } 2326 }
2628 aura->x = env->x; 2327 aura->x = env->x;
2629 aura->y = env->y; 2328 aura->y = env->y;
2630 2329
2631 /* we need to jump out of the inventory for a bit 2330 /* we need to jump out of the inventory for a bit
2632 * in order to hit the map conveniently. 2331 * in order to hit the map conveniently.
2633 */ 2332 */
2634 insert_ob_in_map(aura,env->map,aura,0); 2333 insert_ob_in_map(aura,env->map,aura,0);
2635 2334
2636 for(i=1;i<9;i++) { 2335 for(i=1;i<9;i++) {
2637 sint16 nx, ny; 2336 sint16 nx, ny;
2638 nx = aura->x + freearr_x[i]; 2337 nx = aura->x + freearr_x[i];
2639 ny = aura->y + freearr_y[i]; 2338 ny = aura->y + freearr_y[i];
2640 mflags = get_map_flags(env->map, &m, nx, ny, &nx, &ny); 2339 mflags = get_map_flags(env->map, &m, nx, ny, &nx, &ny);
2641 2340
2642 /* Consider the movement tyep of the person with the aura as 2341 /* Consider the movement tyep of the person with the aura as
2643 * movement type of the aura. Eg, if the player is flying, the aura 2342 * movement type of the aura. Eg, if the player is flying, the aura
2644 * is flying also, if player is walking, it is on the ground, etc. 2343 * is flying also, if player is walking, it is on the ground, etc.
2645 */ 2344 */
2646 if (!(mflags & P_OUT_OF_MAP) && !(OB_TYPE_MOVE_BLOCK(env, GET_MAP_MOVE_BLOCK(m, nx, ny)))) { 2345 if (!(mflags & P_OUT_OF_MAP)
2346 && !(OB_TYPE_MOVE_BLOCK(env, GET_MAP_MOVE_BLOCK(m, nx, ny))))
2347 {
2647 hit_map(aura,i,aura->attacktype,0); 2348 hit_map(aura,i,aura->attacktype,0);
2648 2349
2649 if(aura->other_arch) { 2350 if(aura->other_arch) {
2650 object *new_ob; 2351 object *new_ob;
2651 2352
2652 new_ob = arch_to_object(aura->other_arch); 2353 new_ob = arch_to_object(aura->other_arch);
2653 new_ob->x = nx; 2354 new_ob->x = nx;
2654 new_ob->y = ny; 2355 new_ob->y = ny;
2655 insert_ob_in_map(new_ob,m,aura,0); 2356 insert_ob_in_map(new_ob,m,aura,0);
2656 } 2357 }
2657 } 2358 }
2658 } 2359 }
2659 /* put the aura back in the player's inventory */ 2360 /* put the aura back in the player's inventory */
2660 remove_ob(aura); 2361 remove_ob(aura);
2661 insert_ob_in_ob(aura, env); 2362 insert_ob_in_ob(aura, env);
2662} 2363}
2667 2368
2668void move_peacemaker(object *op) { 2369void move_peacemaker(object *op) {
2669 object *tmp; 2370 object *tmp;
2670 2371
2671 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) { 2372 for(tmp=get_map_ob(op->map,op->x,op->y);tmp!=NULL;tmp=tmp->above) {
2672 int atk_lev, def_lev; 2373 int atk_lev, def_lev;
2673 object *victim=tmp; 2374 object *victim=tmp;
2674 2375
2675 if (tmp->head) victim=tmp->head; 2376 if (tmp->head) victim=tmp->head;
2676 if (!QUERY_FLAG(victim,FLAG_MONSTER)) continue; 2377 if (!QUERY_FLAG(victim,FLAG_MONSTER)) continue;
2677 if (QUERY_FLAG(victim,FLAG_UNAGGRESSIVE)) continue; 2378 if (QUERY_FLAG(victim,FLAG_UNAGGRESSIVE)) continue;
2678 if (victim->stats.exp == 0) continue; 2379 if (victim->stats.exp == 0) continue;
2679 2380
2680 def_lev = MAX(1,victim->level); 2381 def_lev = MAX(1,victim->level);
2681 atk_lev = MAX(1,op->level); 2382 atk_lev = MAX(1,op->level);
2682 2383
2683 if (rndm(0, atk_lev-1) > def_lev) { 2384 if (rndm(0, atk_lev-1) > def_lev) {
2684 /* make this sucker peaceful. */ 2385 /* make this sucker peaceful. */
2685 2386
2686 change_exp(get_owner(op),victim->stats.exp, op->skill, 0); 2387 change_exp(get_owner(op),victim->stats.exp, op->skill, 0);
2687 victim->stats.exp=0; 2388 victim->stats.exp=0;
2688#if 0 2389#if 0
2689 /* No idea why these were all set to zero - if something 2390 /* No idea why these were all set to zero - if something
2690 * makes this creature agressive, he should still do damage. 2391 * makes this creature agressive, he should still do damage.
2691 */ 2392 */
2692 victim->stats.dam = 0; 2393 victim->stats.dam = 0;
2693 victim->stats.sp = 0; 2394 victim->stats.sp = 0;
2694 victim->stats.grace = 0; 2395 victim->stats.grace = 0;
2695 victim->stats.Pow = 0; 2396 victim->stats.Pow = 0;
2696#endif 2397#endif
2697 victim->attack_movement = RANDO2; 2398 victim->attack_movement = RANDO2;
2698 SET_FLAG(victim,FLAG_UNAGGRESSIVE); 2399 SET_FLAG(victim,FLAG_UNAGGRESSIVE);
2699 SET_FLAG(victim,FLAG_RUN_AWAY); 2400 SET_FLAG(victim,FLAG_RUN_AWAY);
2700 SET_FLAG(victim,FLAG_RANDOM_MOVE); 2401 SET_FLAG(victim,FLAG_RANDOM_MOVE);
2701 CLEAR_FLAG(victim,FLAG_MONSTER); 2402 CLEAR_FLAG(victim,FLAG_MONSTER);
2702 if(victim->name) { 2403 if(victim->name) {
2703 new_draw_info_format(NDI_UNIQUE,0,op->owner,"%s no longer feels like fighting.",victim->name); 2404 new_draw_info_format(NDI_UNIQUE,0,op->owner,"%s no longer feels like fighting.",victim->name);
2704 } 2405 }
2705 } 2406 }
2706 } 2407 }
2707} 2408}
2708 2409
2709 2410
2710/* This writes a rune that contains the appropriate message. 2411/* This writes a rune that contains the appropriate message.
2714int write_mark(object *op, object *spell, const char *msg) { 2415int write_mark(object *op, object *spell, const char *msg) {
2715 char rune[HUGE_BUF]; 2416 char rune[HUGE_BUF];
2716 object *tmp; 2417 object *tmp;
2717 2418
2718 if (!msg || msg[0] == 0) { 2419 if (!msg || msg[0] == 0) {
2719 new_draw_info(NDI_UNIQUE, 0, op, "Write what?"); 2420 new_draw_info(NDI_UNIQUE, 0, op, "Write what?");
2720 return 0; 2421 return 0;
2721 } 2422 }
2722 2423
2723 if (strcasestr_local(msg, "endmsg")) { 2424 if (strcasestr_local(msg, "endmsg")) {
2724 new_draw_info(NDI_UNIQUE, 0, op, "Trying to cheat are we?"); 2425 new_draw_info(NDI_UNIQUE, 0, op, "Trying to cheat are we?");
2725 LOG(llevInfo,"write_rune: player %s tried to write bogus rune %s\n", op->name, msg); 2426 LOG(llevInfo,"write_rune: player %s tried to write bogus rune %s\n", op->name, msg);
2726 return 0; 2427 return 0;
2727 } 2428 }
2728 if (!spell->other_arch) return 0; 2429 if (!spell->other_arch) return 0;
2729 tmp = arch_to_object(spell->other_arch); 2430 tmp = arch_to_object(spell->other_arch);
2730 strncpy(rune, msg, HUGE_BUF-2); 2431 strncpy(rune, msg, HUGE_BUF-2);
2731 rune[HUGE_BUF-2] = 0; 2432 rune[HUGE_BUF-2] = 0;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines