1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team |
5 | * Copyright (©) 2002 Mark Wedel & Crossfire Development Team |
6 | * Copyright (©) 1992,2007 Frank Tore Johansen |
6 | * Copyright (©) 1992 Frank Tore Johansen |
7 | * |
7 | * |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
8 | * Deliantra is free software: you can redistribute it and/or modify it under |
9 | * the terms of the Affero GNU General Public License as published by the |
9 | * the terms of the Affero GNU General Public License as published by the |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
10 | * Free Software Foundation, either version 3 of the License, or (at your |
11 | * option) any later version. |
11 | * option) any later version. |
… | |
… | |
242 | next_tmp = tmp->below; |
242 | next_tmp = tmp->below; |
243 | |
243 | |
244 | /* we mark special prayers with the STARTEQUIP flag, so if it isn't |
244 | /* we mark special prayers with the STARTEQUIP flag, so if it isn't |
245 | * in that category, not something we need to worry about. |
245 | * in that category, not something we need to worry about. |
246 | */ |
246 | */ |
247 | if (tmp->type != SPELL || !QUERY_FLAG (tmp, FLAG_STARTEQUIP)) |
247 | if (tmp->type != SPELL || !tmp->flag [FLAG_STARTEQUIP]) |
248 | continue; |
248 | continue; |
249 | |
249 | |
250 | if (god->randomitems == NULL) |
250 | if (god->randomitems == NULL) |
251 | { |
251 | { |
252 | LOG (llevError, "BUG: check_special_prayers(): god %s without randomitems\n", &god->name); |
252 | LOG (llevError, "BUG: check_special_prayers(): god %s without randomitems\n", &god->name); |
… | |
… | |
285 | * Unapplies up to number worth of items of type |
285 | * Unapplies up to number worth of items of type |
286 | */ |
286 | */ |
287 | static void |
287 | static void |
288 | stop_using_item (object *op, int type, int number) |
288 | stop_using_item (object *op, int type, int number) |
289 | { |
289 | { |
290 | object *tmp; |
|
|
291 | |
|
|
292 | for (tmp = op->inv; tmp && number; tmp = tmp->below) |
290 | for (object *tmp = op->inv; tmp && number; tmp = tmp->below) |
293 | if (tmp->type == type && QUERY_FLAG (tmp, FLAG_APPLIED)) |
291 | if (tmp->type == type && tmp->flag [FLAG_APPLIED]) |
294 | { |
292 | { |
295 | apply_special (op, tmp, AP_UNAPPLY | AP_IGNORE_CURSE); |
293 | op->apply (tmp, AP_UNAPPLY | AP_IGNORE_CURSE); |
296 | number--; |
294 | --number; |
297 | } |
295 | } |
298 | } |
296 | } |
299 | |
297 | |
300 | /** |
298 | /** |
301 | * If the god does/doesnt have this flag, we |
299 | * If the god does/doesnt have this flag, we |
… | |
… | |
303 | * already exist. For players only! |
301 | * already exist. For players only! |
304 | */ |
302 | */ |
305 | static void |
303 | static void |
306 | update_priest_flag (object *god, object *exp_ob, uint32 flag) |
304 | update_priest_flag (object *god, object *exp_ob, uint32 flag) |
307 | { |
305 | { |
308 | if (QUERY_FLAG (god, flag) && !QUERY_FLAG (exp_ob, flag)) |
306 | if (god->flag [flag] && !exp_ob->flag [flag]) |
309 | SET_FLAG (exp_ob, flag); |
307 | exp_ob->flag [flag]; |
310 | else if (QUERY_FLAG (exp_ob, flag) && !QUERY_FLAG (god, flag)) |
308 | else if (exp_ob->flag [flag] && !god->flag [flag]) |
311 | { |
309 | { |
312 | /* When this is called with the exp_ob set to the player, |
310 | /* When this is called with the exp_ob set to the player, |
313 | * this check is broken, because most all players arch |
311 | * this check is broken, because most all players arch |
314 | * allow use of weapons. I'm not actually sure why this |
312 | * allow use of weapons. I'm not actually sure why this |
315 | * check is here - I guess if you had a case where the |
313 | * check is here - I guess if you had a case where the |
… | |
… | |
317 | * the god places on it, this may make sense. But I don't think |
315 | * the god places on it, this may make sense. But I don't think |
318 | * there is any case like that. |
316 | * there is any case like that. |
319 | */ |
317 | */ |
320 | |
318 | |
321 | /* if (!(QUERY_FLAG(&(exp_ob->arch->clone),flag)))*/ |
319 | /* if (!(QUERY_FLAG(&(exp_ob->arch->clone),flag)))*/ |
322 | CLEAR_FLAG (exp_ob, flag); |
320 | exp_ob->clr_flag (flag); |
323 | }; |
321 | }; |
324 | } |
322 | } |
325 | |
323 | |
326 | /** |
324 | /** |
327 | * Forbids or let player use something item type. |
325 | * Forbids or let player use something item type. |
… | |
… | |
331 | * string is the string to print out. |
329 | * string is the string to print out. |
332 | */ |
330 | */ |
333 | static int |
331 | static int |
334 | worship_forbids_use (object *op, object *exp_obj, uint32 flag, const char *string) |
332 | worship_forbids_use (object *op, object *exp_obj, uint32 flag, const char *string) |
335 | { |
333 | { |
336 | if (QUERY_FLAG (op->arch, flag)) |
334 | if (op->arch->flag [flag]) |
337 | if (QUERY_FLAG (op, flag) != QUERY_FLAG (exp_obj, flag)) |
335 | if (op->flag [flag] != exp_obj->flag [flag]) |
338 | { |
336 | { |
339 | update_priest_flag (exp_obj, op, flag); |
337 | update_priest_flag (exp_obj, op, flag); |
340 | if (QUERY_FLAG (op, flag)) |
338 | if (op->flag [flag]) |
341 | new_draw_info_format (NDI_UNIQUE, 0, op, "You may use %s again.", string); |
339 | new_draw_info_format (NDI_UNIQUE, 0, op, "You may use %s again.", string); |
342 | else |
340 | else |
343 | { |
341 | { |
344 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are forbidden to use %s.", string); |
342 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are forbidden to use %s.", string); |
345 | return 1; |
343 | return 1; |
… | |
… | |
369 | for (item = op->inv; item; item = next) |
367 | for (item = op->inv; item; item = next) |
370 | { |
368 | { |
371 | next = item->below; |
369 | next = item->below; |
372 | |
370 | |
373 | // remove all invisible startequip items which are not skill, exp or force |
371 | // remove all invisible startequip items which are not skill, exp or force |
374 | if (QUERY_FLAG (item, FLAG_STARTEQUIP) && item->invisible && |
372 | if (item->flag [FLAG_STARTEQUIP] && item->invisible && |
375 | (item->type != SKILL) && (item->type != FORCE)) |
373 | (item->type != SKILL) && (item->type != FORCE)) |
376 | { |
374 | { |
377 | if (item->type == SPELL) |
375 | if (item->type == SPELL) |
378 | { |
376 | { |
379 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", &item->name); |
377 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", &item->name); |
380 | esrv_remove_spell (op->contr, item); |
378 | esrv_remove_spell (op->contr, item); |
381 | } |
379 | } |
382 | |
380 | |
383 | player_unready_range_ob (op->contr, item); |
|
|
384 | item->destroy (); |
381 | item->destroy (); |
385 | } |
382 | } |
386 | } |
383 | } |
387 | |
384 | |
388 | /* remove any godgiven items from the old god */ |
385 | /* remove any godgiven items from the old god */ |
389 | if (old_god) |
386 | if (old_god) |
390 | for (tr = old_god->randomitems->items; tr; tr = tr->next) |
387 | for (tr = old_god->randomitems->items; tr; tr = tr->next) |
391 | if (tr->item && QUERY_FLAG (tr->item, FLAG_STARTEQUIP)) |
388 | if (tr->item && tr->item->flag [FLAG_STARTEQUIP]) |
392 | follower_remove_similar_item (op, tr->item); |
389 | follower_remove_similar_item (op, tr->item); |
393 | |
390 | |
394 | if (!op || !new_god) |
391 | if (!op || !new_god) |
395 | return; |
392 | return; |
396 | |
393 | |
… | |
… | |
427 | /* The archetype should always be defined - if we crash here because it doesn't, |
424 | /* The archetype should always be defined - if we crash here because it doesn't, |
428 | * things are really messed up anyways. |
425 | * things are really messed up anyways. |
429 | */ |
426 | */ |
430 | skop = give_skill_by_name (op, get_archetype_by_type_subtype (SKILL, SK_PRAYING)->skill); |
427 | skop = give_skill_by_name (op, get_archetype_by_type_subtype (SKILL, SK_PRAYING)->skill); |
431 | |
428 | |
432 | sk_applied = QUERY_FLAG (skop, FLAG_APPLIED); /* save skill status */ |
429 | sk_applied = skop->flag [FLAG_APPLIED]; /* save skill status */ |
433 | |
430 | |
434 | /* Clear the "undead" status. We also need to force a call to change_abil, |
431 | /* Clear the "undead" status. We also need to force a call to change_abil, |
435 | * so I set undeadified for that. |
432 | * so I set undeadified for that. |
436 | * - gros, 21th July 2006. |
433 | * - gros, 21th July 2006. |
437 | */ |
434 | */ |
438 | if (old_god && QUERY_FLAG (old_god, FLAG_UNDEAD)) |
435 | if (old_god && old_god->flag [FLAG_UNDEAD]) |
439 | { |
436 | { |
440 | CLEAR_FLAG (skop, FLAG_UNDEAD); |
437 | skop->clr_flag (FLAG_UNDEAD); |
441 | undeadified = 1; |
438 | undeadified = 1; |
442 | } |
439 | } |
443 | |
440 | |
444 | if (skop->title) |
441 | if (skop->title) |
445 | { |
442 | { |
… | |
… | |
447 | new_draw_info_format (NDI_UNIQUE, 0, op, "%s's blessing is withdrawn from you.", &skop->title); |
444 | new_draw_info_format (NDI_UNIQUE, 0, op, "%s's blessing is withdrawn from you.", &skop->title); |
448 | |
445 | |
449 | /* The point of this is to really show what abilities the player just lost */ |
446 | /* The point of this is to really show what abilities the player just lost */ |
450 | if (sk_applied || undeadified) |
447 | if (sk_applied || undeadified) |
451 | { |
448 | { |
452 | CLEAR_FLAG (skop, FLAG_APPLIED); |
449 | skop->clr_flag (FLAG_APPLIED); |
453 | change_abil (op, skop); |
450 | change_abil (op, skop); |
454 | } |
451 | } |
455 | } |
452 | } |
456 | |
453 | |
457 | /* now change to the new gods attributes to exp_obj */ |
454 | /* now change to the new gods attributes to exp_obj */ |
… | |
… | |
508 | stop_using_item (op, BOOTS, 1); |
505 | stop_using_item (op, BOOTS, 1); |
509 | stop_using_item (op, GLOVES, 1); |
506 | stop_using_item (op, GLOVES, 1); |
510 | stop_using_item (op, SHIELD, 1); |
507 | stop_using_item (op, SHIELD, 1); |
511 | } |
508 | } |
512 | |
509 | |
513 | SET_FLAG (skop, FLAG_APPLIED); |
510 | skop->set_flag (FLAG_APPLIED); |
514 | change_abil (op, skop); |
511 | change_abil (op, skop); |
515 | |
512 | |
516 | /* return to previous skill status */ |
513 | /* return to previous skill status */ |
517 | if (!sk_applied) |
514 | if (!sk_applied) |
518 | CLEAR_FLAG (skop, FLAG_APPLIED); |
515 | skop->clr_flag (FLAG_APPLIED); |
519 | |
516 | |
520 | check_special_prayers (op, new_god); |
517 | check_special_prayers (op, new_god); |
521 | } |
518 | } |
522 | |
519 | |
523 | archetype * |
520 | archetype * |
… | |
… | |
556 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
553 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
557 | { |
554 | { |
558 | if (tmp->invisible) |
555 | if (tmp->invisible) |
559 | continue; |
556 | continue; |
560 | |
557 | |
561 | if (QUERY_FLAG (tmp, FLAG_DAMNED) && !remove_damnation) |
558 | if (tmp->flag [FLAG_DAMNED] && !remove_damnation) |
562 | continue; |
559 | continue; |
563 | |
560 | |
564 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
561 | if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]) |
565 | { |
562 | { |
566 | success = 1; |
563 | success = 1; |
567 | CLEAR_FLAG (tmp, FLAG_DAMNED); |
564 | tmp->clr_flag (FLAG_DAMNED); |
568 | CLEAR_FLAG (tmp, FLAG_CURSED); |
565 | tmp->clr_flag (FLAG_CURSED); |
569 | CLEAR_FLAG (tmp, FLAG_KNOWN_CURSED); |
566 | tmp->clr_flag (FLAG_KNOWN_CURSED); |
570 | |
567 | |
571 | if (object *pl = tmp->visible_to ()) |
568 | if (object *pl = tmp->visible_to ()) |
572 | esrv_update_item (UPD_FLAGS, pl, tmp); |
569 | esrv_update_item (UPD_FLAGS, pl, tmp); |
573 | } |
570 | } |
574 | } |
571 | } |
… | |
… | |
650 | object *weapon; |
647 | object *weapon; |
651 | uint32 attacktype; |
648 | uint32 attacktype; |
652 | int tmp; |
649 | int tmp; |
653 | |
650 | |
654 | for (weapon = op->inv; weapon; weapon = weapon->below) |
651 | for (weapon = op->inv; weapon; weapon = weapon->below) |
655 | if ((weapon->type == WEAPON || weapon->type == BOW) && QUERY_FLAG (weapon, FLAG_APPLIED)) |
652 | if ((weapon->type == WEAPON || weapon->type == BOW) && weapon->flag [FLAG_APPLIED]) |
656 | break; |
653 | break; |
657 | |
654 | |
658 | if (!weapon || god_examines_item (god, weapon) <= 0) |
655 | if (!weapon || god_examines_item (god, weapon) <= 0) |
659 | return 0; |
656 | return 0; |
660 | |
657 | |
… | |
… | |
712 | { |
709 | { |
713 | int reaction = 1; |
710 | int reaction = 1; |
714 | object *item = NULL, *skop; |
711 | object *item = NULL, *skop; |
715 | |
712 | |
716 | for (item = op->inv; item; item = item->below) |
713 | for (item = op->inv; item; item = item->below) |
717 | if (QUERY_FLAG (item, FLAG_APPLIED)) |
714 | if (item->flag [FLAG_APPLIED]) |
718 | reaction += god_examines_item (god, item) * (item->magic ? abs (item->magic) : 1); |
715 | reaction += god_examines_item (god, item) * (item->magic ? abs (item->magic) : 1); |
719 | |
716 | |
720 | /* well, well. Looks like we screwed up. Time for god's revenge */ |
717 | /* well, well. Looks like we screwed up. Time for god's revenge */ |
721 | if (reaction < 0) |
718 | if (reaction < 0) |
722 | { |
719 | { |