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,2011,2012,2013,2014,2015,2016 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. |
12 | * |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
16 | * GNU General Public License for more details. |
17 | * |
17 | * |
18 | * You should have received a copy of the Affero GNU General Public License |
18 | * You should have received a copy of the Affero GNU General Public License |
19 | * and the GNU General Public License along with this program. If not, see |
19 | * and the GNU General Public License along with this program. If not, see |
20 | * <http://www.gnu.org/licenses/>. |
20 | * <http://www.gnu.org/licenses/>. |
21 | * |
21 | * |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
22 | * The authors can be reached via e-mail to <support@deliantra.net> |
23 | */ |
23 | */ |
24 | |
24 | |
25 | /* Oct 3, 1995 - Code laid down for initial gods, priest alignment, and |
25 | /* Oct 3, 1995 - Code laid down for initial gods, priest alignment, and |
26 | * monster race initialization. b.t. |
26 | * monster race initialization. b.t. |
… | |
… | |
62 | |
62 | |
63 | return 0; |
63 | return 0; |
64 | } |
64 | } |
65 | |
65 | |
66 | /** |
66 | /** |
67 | * Returns a string that is the name of the god that should be natively worshipped by a |
67 | * Returns a string that is the name of the god that should be natively worshipped by a |
68 | * creature of who has race *race |
68 | * creature of who has race *race |
69 | * if we can't find a god that is appropriate, we return NULL |
69 | * if we can't find a god that is appropriate, we return NULL |
70 | */ |
70 | */ |
71 | static shstr_tmp |
71 | static shstr_tmp |
72 | get_god_for_race (shstr_cmp race) |
72 | get_god_for_race (shstr_cmp race) |
… | |
… | |
80 | } |
80 | } |
81 | |
81 | |
82 | /** |
82 | /** |
83 | * Determines if op worships a god. |
83 | * Determines if op worships a god. |
84 | * Returns the godname if they do or "none" if they have no god. |
84 | * Returns the godname if they do or "none" if they have no god. |
85 | * In the case of an NPC, if they have no god, we try and guess |
85 | * In the case of an NPC, if they have no god, we try and guess |
86 | * who they should worship based on their race. If that fails we |
86 | * who they should worship based on their race. If that fails we |
87 | * give them a random one. |
87 | * give them a random one. |
88 | */ |
88 | */ |
89 | shstr_tmp |
89 | shstr_tmp |
90 | determine_god (object *op) |
90 | determine_god (object *op) |
91 | { |
91 | { |
… | |
… | |
214 | return 0; |
214 | return 0; |
215 | |
215 | |
216 | if (follower_has_similar_item (op, tr->item)) |
216 | if (follower_has_similar_item (op, tr->item)) |
217 | return 0; |
217 | return 0; |
218 | |
218 | |
219 | object *tmp = arch_to_object (tr->item); |
219 | object *tmp = tr->item->instance (); |
220 | new_draw_info_format (NDI_UNIQUE, 0, op, "%s lets %s appear in your hands.", &god->name, query_short_name (tmp)); |
220 | new_draw_info_format (NDI_UNIQUE, 0, op, "%s lets %s appear in your hands.", &god->name, query_short_name (tmp)); |
221 | op->insert (tmp); |
221 | op->insert (tmp); |
222 | |
222 | |
223 | return 1; |
223 | return 1; |
224 | } |
224 | } |
… | |
… | |
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 |
302 | * give/remove it from the experience object if it doesnt/does |
300 | * give/remove it from the experience object if it doesnt/does |
303 | * already exist. For players only! |
301 | * already exist. For players only! |
304 | */ |
302 | */ |
305 | static void |
303 | static inline 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 | exp_ob->flag [flag] = god->flag [flag]; |
309 | SET_FLAG (exp_ob, flag); |
307 | return; |
310 | else if (QUERY_FLAG (exp_ob, flag) && !QUERY_FLAG (god, flag)) |
308 | |
|
|
309 | // old code follows for reference... |
|
|
310 | if (god->flag [flag] && !exp_ob->flag [flag]) |
|
|
311 | exp_ob->set_flag (flag); |
|
|
312 | else if (exp_ob->flag [flag] && !god->flag [flag]) |
311 | { |
313 | { |
312 | /* When this is called with the exp_ob set to the player, |
314 | /* When this is called with the exp_ob set to the player, |
313 | * this check is broken, because most all players arch |
315 | * this check is broken, because most all players arch |
314 | * allow use of weapons. I'm not actually sure why this |
316 | * allow use of weapons. I'm not actually sure why this |
315 | * check is here - I guess if you had a case where the |
317 | * check is here - I guess if you had a case where the |
316 | * value in the archetype (wisdom) should over ride the restrictions |
318 | * value in the archetype (wisdom) should over ride the restrictions |
317 | * the god places on it, this may make sense. But I don't think |
319 | * the god places on it, this may make sense. But I don't think |
318 | * there is any case like that. |
320 | * there is any case like that. |
319 | */ |
321 | */ |
320 | |
|
|
321 | /* if (!(QUERY_FLAG(&(exp_ob->arch->clone),flag)))*/ |
322 | /* if (!(QUERY_FLAG(&(exp_ob->arch->clone),flag)))*/ |
322 | CLEAR_FLAG (exp_ob, flag); |
323 | exp_ob->clr_flag (flag); |
323 | }; |
324 | }; |
324 | } |
325 | } |
325 | |
326 | |
326 | /** |
327 | /** |
327 | * Forbids or let player use something item type. |
328 | * Forbids or let player use something item type. |
… | |
… | |
331 | * string is the string to print out. |
332 | * string is the string to print out. |
332 | */ |
333 | */ |
333 | static int |
334 | static int |
334 | worship_forbids_use (object *op, object *exp_obj, uint32 flag, const char *string) |
335 | worship_forbids_use (object *op, object *exp_obj, uint32 flag, const char *string) |
335 | { |
336 | { |
336 | if (QUERY_FLAG (op->arch, flag)) |
337 | if (op->arch->flag [flag]) |
337 | if (QUERY_FLAG (op, flag) != QUERY_FLAG (exp_obj, flag)) |
338 | if (op->flag [flag] != exp_obj->flag [flag]) |
338 | { |
339 | { |
339 | update_priest_flag (exp_obj, op, flag); |
340 | update_priest_flag (exp_obj, op, flag); |
340 | if (QUERY_FLAG (op, flag)) |
341 | if (op->flag [flag]) |
341 | new_draw_info_format (NDI_UNIQUE, 0, op, "You may use %s again.", string); |
342 | new_draw_info_format (NDI_UNIQUE, 0, op, "You may use %s again.", string); |
342 | else |
343 | else |
343 | { |
344 | { |
344 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are forbidden to use %s.", string); |
345 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are forbidden to use %s.", string); |
345 | return 1; |
346 | return 1; |
… | |
… | |
354 | * switched to a new god. It handles basically all the stat changes |
355 | * switched to a new god. It handles basically all the stat changes |
355 | * that happen to the player, including the removal of godgiven |
356 | * that happen to the player, including the removal of godgiven |
356 | * items (from the former cult). |
357 | * items (from the former cult). |
357 | */ |
358 | */ |
358 | void |
359 | void |
359 | become_follower (object *op, object *new_god) |
360 | object::become_follower (object *new_god) |
360 | { |
361 | { |
361 | object *old_god = NULL; /* old god */ |
362 | object *old_god = 0; /* old god */ |
362 | treasure *tr; |
363 | treasure *tr; |
363 | object *item, *skop, *next; |
364 | object *item, *skop, *next; |
364 | int i, sk_applied, undeadified = 0; /* Turns to true if changing god can changes the undead status of the player. */ |
365 | int i, sk_applied, undeadified = 0; /* Turns to true if changing god can changes the undead status of the player. */ |
365 | |
366 | |
|
|
367 | if (!contr) |
|
|
368 | return; |
|
|
369 | |
|
|
370 | contr->queue_stats_update (); |
|
|
371 | |
366 | old_god = find_god (determine_god (op)); |
372 | old_god = find_god (determine_god (this)); |
367 | |
373 | |
368 | /* take away any special god-characteristic items. */ |
374 | /* take away any special god-characteristic items. */ |
369 | for (item = op->inv; item; item = next) |
375 | for (item = inv; item; item = next) |
370 | { |
376 | { |
371 | next = item->below; |
377 | next = item->below; |
372 | |
378 | |
373 | // remove all invisible startequip items which are not skill, exp or force |
379 | // remove all invisible startequip items which are not skill, exp or force |
374 | if (QUERY_FLAG (item, FLAG_STARTEQUIP) && item->invisible && |
380 | if (item->flag [FLAG_STARTEQUIP] && item->invisible |
375 | (item->type != SKILL) && (item->type != FORCE)) |
381 | && item->type != SKILL && item->type != FORCE) |
376 | { |
382 | { |
377 | if (item->type == SPELL) |
383 | if (item->type == SPELL) |
378 | { |
384 | { |
379 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You lose knowledge of %s.", &item->name); |
385 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, this, "You lose knowledge of %s.", &item->name); |
380 | esrv_remove_spell (op->contr, item); |
386 | esrv_remove_spell (contr, item); |
381 | } |
387 | } |
382 | |
388 | |
383 | player_unready_range_ob (op->contr, item); |
|
|
384 | item->destroy (); |
389 | item->destroy (); |
385 | } |
390 | } |
386 | } |
391 | } |
387 | |
392 | |
388 | /* remove any godgiven items from the old god */ |
393 | /* remove any godgiven items from the old god */ |
389 | if (old_god) |
394 | if (old_god) |
390 | for (tr = old_god->randomitems->items; tr; tr = tr->next) |
395 | for (tr = old_god->randomitems->items; tr; tr = tr->next) |
391 | if (tr->item && QUERY_FLAG (tr->item, FLAG_STARTEQUIP)) |
396 | if (tr->item && tr->item->flag [FLAG_STARTEQUIP]) |
392 | follower_remove_similar_item (op, tr->item); |
397 | follower_remove_similar_item (this, tr->item); |
393 | |
398 | |
394 | if (!op || !new_god) |
399 | if (!new_god) |
395 | return; |
400 | return; |
396 | |
401 | |
397 | if (new_god->slaying && op->race.contains (new_god->slaying)) |
402 | if (new_god->slaying && new_god->slaying.contains (race)) |
398 | { |
403 | { |
399 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "Fool! %s detests your kind!", &new_god->name); |
404 | failmsgf ("Fool! %s detests your kind! H<This god does not accept followers of your race.>", &new_god->name); |
400 | |
405 | |
401 | if (random_roll (0, op->level - 1, op, PREFER_LOW) - 5 > 0) |
406 | if (random_roll (0, level - 1, this, PREFER_LOW) - 5 > 0) |
402 | { |
407 | { |
403 | object *tmp = get_archetype (LOOSE_MANA); |
408 | object *tmp = archetype::get (LOOSE_MANA); |
404 | |
409 | |
405 | cast_magic_storm (op, tmp, new_god->level + 10); |
410 | cast_magic_storm (this, tmp, new_god->level + 10); |
406 | } |
411 | } |
407 | |
412 | |
408 | return; |
413 | return; |
409 | } |
414 | } |
410 | |
415 | |
411 | /* give the player any special god-characteristic-items. */ |
416 | /* give the player any special god-characteristic-items. */ |
412 | for (tr = new_god->randomitems->items; tr; tr = tr->next) |
417 | for (tr = new_god->randomitems->items; tr; tr = tr->next) |
413 | { |
|
|
414 | if (tr->item && tr->item->invisible && tr->item->type != SPELLBOOK |
418 | if (tr->item && tr->item->invisible && tr->item->type != SPELLBOOK |
415 | && tr->item->type != BOOK && tr->item->type != SPELL) |
419 | && tr->item->type != BOOK && tr->item->type != SPELL) |
416 | god_gives_present (op, new_god, tr); |
420 | god_gives_present (this, new_god, tr); |
417 | } |
|
|
418 | |
421 | |
419 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "You become a follower of %s!", &new_god->name); |
422 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, this, "You become a follower of %s!", &new_god->name); |
420 | |
423 | |
421 | for (skop = op->inv; skop; skop = skop->below) |
424 | for (skop = inv; skop; skop = skop->below) |
422 | if (skop->type == SKILL && skop->subtype == SK_PRAYING) |
425 | if (skop->type == SKILL && skop->subtype == SK_PRAYING) |
423 | break; |
426 | break; |
424 | |
427 | |
425 | /* Player has no skill - give them the skill */ |
428 | /* Player has no skill - give them the skill */ |
426 | if (!skop) |
429 | if (!skop) |
427 | /* The archetype should always be defined - if we crash here because it doesn't, |
430 | /* The archetype should always be defined - if we crash here because it doesn't, |
428 | * things are really messed up anyways. |
431 | * things are really messed up anyways. |
429 | */ |
432 | */ |
430 | skop = give_skill_by_name (op, get_archetype_by_type_subtype (SKILL, SK_PRAYING)->skill); |
433 | skop = give_skill_by_name (this, shstr_praying); |
431 | |
434 | |
432 | sk_applied = QUERY_FLAG (skop, FLAG_APPLIED); /* save skill status */ |
435 | sk_applied = skop->flag [FLAG_APPLIED]; /* save skill status */ |
433 | |
436 | |
434 | /* Clear the "undead" status. We also need to force a call to change_abil, |
437 | /* Clear the "undead" status. We also need to force a call to change_abil, |
435 | * so I set undeadified for that. |
438 | * so I set undeadified for that. |
436 | * - gros, 21th July 2006. |
439 | * - gros, 21th July 2006. |
437 | */ |
440 | */ |
438 | if (old_god && QUERY_FLAG (old_god, FLAG_UNDEAD)) |
441 | if (old_god && old_god->flag [FLAG_UNDEAD]) |
439 | { |
442 | { |
440 | CLEAR_FLAG (skop, FLAG_UNDEAD); |
443 | skop->clr_flag (FLAG_UNDEAD); |
441 | undeadified = 1; |
444 | undeadified = 1; |
442 | } |
445 | } |
443 | |
446 | |
444 | if (skop->title) |
447 | if (skop->title) |
445 | { |
448 | { |
446 | /* get rid of old god */ |
449 | /* get rid of old god */ |
447 | new_draw_info_format (NDI_UNIQUE, 0, op, "%s's blessing is withdrawn from you.", &skop->title); |
450 | new_draw_info_format (NDI_UNIQUE, 0, this, "%s's blessing is withdrawn from you.", &skop->title); |
448 | |
451 | |
449 | /* The point of this is to really show what abilities the player just lost */ |
452 | /* The point of this is to really show what abilities the player just lost */ |
450 | if (sk_applied || undeadified) |
453 | if (sk_applied || undeadified) |
451 | { |
454 | { |
452 | CLEAR_FLAG (skop, FLAG_APPLIED); |
455 | skop->clr_flag (FLAG_APPLIED); |
453 | change_abil (op, skop); |
456 | change_abil (this, skop); |
454 | } |
457 | } |
455 | } |
458 | } |
456 | |
459 | |
457 | /* now change to the new gods attributes to exp_obj */ |
460 | /* now change to the new gods attributes to exp_obj */ |
458 | skop->title = new_god->name; |
461 | skop->title = new_god->name; |
… | |
… | |
461 | skop->path_denied = new_god->path_denied; |
464 | skop->path_denied = new_god->path_denied; |
462 | /* copy god's resistances */ |
465 | /* copy god's resistances */ |
463 | memcpy (skop->resist, new_god->resist, sizeof (new_god->resist)); |
466 | memcpy (skop->resist, new_god->resist, sizeof (new_god->resist)); |
464 | |
467 | |
465 | /* make sure that certain immunities do NOT get passed |
468 | /* make sure that certain immunities do NOT get passed |
466 | * to the follower! |
469 | * to the follower! |
467 | */ |
470 | */ |
468 | for (i = 0; i < NROFATTACKS; i++) |
471 | for (i = 0; i < NROFATTACKS; i++) |
469 | if (skop->resist[i] > 30 && (i == ATNR_FIRE || i == ATNR_COLD || i == ATNR_ELECTRICITY || i == ATNR_POISON)) |
472 | if (skop->resist[i] > 30 && (i == ATNR_FIRE || i == ATNR_COLD || i == ATNR_ELECTRICITY || i == ATNR_POISON)) |
470 | skop->resist[i] = 30; |
473 | skop->resist[i] = 30; |
471 | |
474 | |
… | |
… | |
482 | update_priest_flag (new_god, skop, FLAG_MAKE_INVIS); |
485 | update_priest_flag (new_god, skop, FLAG_MAKE_INVIS); |
483 | update_priest_flag (new_god, skop, FLAG_UNDEAD); |
486 | update_priest_flag (new_god, skop, FLAG_UNDEAD); |
484 | update_priest_flag (new_god, skop, FLAG_BLIND); |
487 | update_priest_flag (new_god, skop, FLAG_BLIND); |
485 | update_priest_flag (new_god, skop, FLAG_XRAYS); /* better have this if blind! */ |
488 | update_priest_flag (new_god, skop, FLAG_XRAYS); /* better have this if blind! */ |
486 | |
489 | |
487 | new_draw_info_format (NDI_UNIQUE, 0, op, "You are bathed in %s's aura.", &new_god->name); |
490 | new_draw_info_format (NDI_UNIQUE, 0, this, "You are bathed in %s's aura.", &new_god->name); |
488 | |
491 | |
489 | /* Weapon/armour use are special...handle flag toggles here as this can |
492 | /* Weapon/armour use are special...handle flag toggles here as this can |
490 | * only happen when gods are worshipped and if the new priest could |
493 | * only happen when gods are worshipped and if the new priest could |
491 | * have used armour/weapons in the first place. |
494 | * have used armour/weapons in the first place. |
492 | * |
495 | * |
493 | * This also can happen for monks which cannot use weapons. In this case |
496 | * This also can happen for monks which cannot use weapons. In this case |
494 | * do not allow to use weapons even if the god otherwise would allow it. |
497 | * do not allow to use weapons even if the god otherwise would allow it. |
495 | */ |
498 | */ |
496 | if (!present_in_ob_by_name (FORCE, "no weapon force", op)) |
499 | if (!present_in_ob_by_name (FORCE, "no weapon force", this)) |
497 | update_priest_flag (new_god, skop, FLAG_USE_WEAPON); |
500 | update_priest_flag (new_god, skop, FLAG_USE_WEAPON); |
498 | |
501 | |
499 | update_priest_flag (new_god, skop, FLAG_USE_ARMOUR); |
502 | update_priest_flag (new_god, skop, FLAG_USE_ARMOUR); |
500 | |
503 | |
501 | if (worship_forbids_use (op, skop, FLAG_USE_WEAPON, "weapons")) |
504 | if (worship_forbids_use (this, skop, FLAG_USE_WEAPON, "weapons")) |
502 | stop_using_item (op, WEAPON, 2); |
505 | stop_using_item (this, WEAPON, 2); |
503 | |
506 | |
504 | if (worship_forbids_use (op, skop, FLAG_USE_ARMOUR, "armour")) |
507 | if (worship_forbids_use (this, skop, FLAG_USE_ARMOUR, "armour")) |
505 | { |
508 | { |
506 | stop_using_item (op, ARMOUR, 1); |
509 | stop_using_item (this, ARMOUR, 1); |
507 | stop_using_item (op, HELMET, 1); |
510 | stop_using_item (this, HELMET, 1); |
508 | stop_using_item (op, BOOTS, 1); |
511 | stop_using_item (this, BOOTS, 1); |
509 | stop_using_item (op, GLOVES, 1); |
512 | stop_using_item (this, GLOVES, 1); |
510 | stop_using_item (op, SHIELD, 1); |
513 | stop_using_item (this, SHIELD, 1); |
511 | } |
514 | } |
512 | |
515 | |
513 | SET_FLAG (skop, FLAG_APPLIED); |
516 | skop->set_flag (FLAG_APPLIED); |
514 | (void) change_abil (op, skop); |
517 | change_abil (this, skop); |
515 | |
518 | |
516 | /* return to previous skill status */ |
519 | /* return to previous skill status */ |
517 | if (!sk_applied) |
520 | if (!sk_applied) |
518 | CLEAR_FLAG (skop, FLAG_APPLIED); |
521 | { |
|
|
522 | skop->clr_flag (FLAG_APPLIED); |
|
|
523 | contr->queue_stats_update (); |
|
|
524 | } |
519 | |
525 | |
520 | check_special_prayers (op, new_god); |
526 | check_special_prayers (this, new_god); |
521 | } |
527 | } |
522 | |
528 | |
523 | archetype * |
529 | archetype * |
524 | determine_holy_arch (object *god, shstr_cmp type) |
530 | determine_holy_arch (object *god, shstr_cmp type) |
525 | { |
531 | { |
… | |
… | |
556 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
562 | for (object *tmp = op->inv; tmp; tmp = tmp->below) |
557 | { |
563 | { |
558 | if (tmp->invisible) |
564 | if (tmp->invisible) |
559 | continue; |
565 | continue; |
560 | |
566 | |
561 | if (QUERY_FLAG (tmp, FLAG_DAMNED) && !remove_damnation) |
567 | if (tmp->flag [FLAG_DAMNED] && !remove_damnation) |
562 | continue; |
568 | continue; |
563 | |
569 | |
564 | if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) |
570 | if (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]) |
565 | { |
571 | { |
566 | success = 1; |
572 | success = 1; |
567 | CLEAR_FLAG (tmp, FLAG_DAMNED); |
573 | tmp->clr_flag (FLAG_DAMNED); |
568 | CLEAR_FLAG (tmp, FLAG_CURSED); |
574 | tmp->clr_flag (FLAG_CURSED); |
569 | CLEAR_FLAG (tmp, FLAG_KNOWN_CURSED); |
575 | tmp->clr_flag (FLAG_KNOWN_CURSED); |
570 | |
576 | |
571 | if (object *pl = tmp->visible_to ()) |
577 | if (object *pl = tmp->visible_to ()) |
572 | esrv_update_item (UPD_FLAGS, pl, tmp); |
578 | esrv_update_item (UPD_FLAGS, pl, tmp); |
573 | } |
579 | } |
574 | } |
580 | } |
… | |
… | |
645 | * attacktype, slaying and such. |
651 | * attacktype, slaying and such. |
646 | */ |
652 | */ |
647 | static int |
653 | static int |
648 | god_enchants_weapon (object *op, object *god, object *tr, object *skill) |
654 | god_enchants_weapon (object *op, object *god, object *tr, object *skill) |
649 | { |
655 | { |
650 | object *weapon; |
656 | if (!op->contr) |
651 | uint32 attacktype; |
657 | return 0; |
652 | int tmp; |
|
|
653 | |
658 | |
654 | for (weapon = op->inv; weapon; weapon = weapon->below) |
659 | object *weapon = op->contr->combat_ob; |
655 | if ((weapon->type == WEAPON || weapon->type == BOW) && QUERY_FLAG (weapon, FLAG_APPLIED)) |
|
|
656 | break; |
|
|
657 | |
660 | |
|
|
661 | if (!weapon) |
|
|
662 | return 0; |
|
|
663 | |
|
|
664 | if (weapon->type != WEAPON && weapon->type != BOW) |
|
|
665 | return 0; |
|
|
666 | |
658 | if (!weapon || god_examines_item (god, weapon) <= 0) |
667 | if (god_examines_item (god, weapon) <= 0) |
659 | return 0; |
668 | return 0; |
660 | |
669 | |
661 | /* First give it a title, so other gods won't touch it */ |
670 | /* First give it a title, so other gods won't touch it */ |
662 | if (!weapon->title) |
671 | if (!weapon->title) |
663 | { |
672 | { |
… | |
… | |
676 | new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s now hungers to slay enemies of your god!", &weapon->name); |
685 | new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s now hungers to slay enemies of your god!", &weapon->name); |
677 | return 1; |
686 | return 1; |
678 | } |
687 | } |
679 | |
688 | |
680 | /* Add the gods attacktype */ |
689 | /* Add the gods attacktype */ |
681 | attacktype = (weapon->attacktype == 0) ? AT_PHYSICAL : weapon->attacktype; |
690 | uint32 attacktype = (weapon->attacktype == 0) ? AT_PHYSICAL : weapon->attacktype; |
|
|
691 | |
682 | if ((attacktype & god->attacktype) != god->attacktype) |
692 | if ((attacktype & god->attacktype) != god->attacktype) |
683 | { |
693 | { |
684 | new_draw_info (NDI_UNIQUE, 0, op, "Your weapon suddenly glows!"); |
694 | new_draw_info (NDI_UNIQUE, 0, op, "Your weapon suddenly glows!"); |
685 | weapon->attacktype = attacktype | god->attacktype; |
695 | weapon->attacktype = attacktype | god->attacktype; |
686 | return 1; |
696 | return 1; |
687 | } |
697 | } |
688 | |
698 | |
689 | /* Higher magic value */ |
699 | /* Higher magic value */ |
690 | tmp = follower_level_to_enchantments (skill->level, tr->level); |
700 | if (weapon->magic < follower_level_to_enchantments (skill->level, tr->level)) |
691 | if (weapon->magic < tmp) |
|
|
692 | { |
701 | { |
693 | new_draw_info (NDI_UNIQUE, 0, op, "A phosphorescent glow envelops your weapon!"); |
702 | new_draw_info (NDI_UNIQUE, 0, op, "A phosphorescent glow envelops your weapon!"); |
694 | weapon->magic++; |
703 | weapon->magic++; |
695 | |
704 | |
696 | if (object *pl = weapon->visible_to ()) |
705 | if (object *pl = weapon->visible_to ()) |
… | |
… | |
712 | { |
721 | { |
713 | int reaction = 1; |
722 | int reaction = 1; |
714 | object *item = NULL, *skop; |
723 | object *item = NULL, *skop; |
715 | |
724 | |
716 | for (item = op->inv; item; item = item->below) |
725 | for (item = op->inv; item; item = item->below) |
717 | if (QUERY_FLAG (item, FLAG_APPLIED)) |
726 | if (item->flag [FLAG_APPLIED]) |
718 | reaction += god_examines_item (god, item) * (item->magic ? abs (item->magic) : 1); |
727 | reaction += god_examines_item (god, item) * (item->magic ? abs (item->magic) : 1); |
719 | |
728 | |
720 | /* well, well. Looks like we screwed up. Time for god's revenge */ |
729 | /* well, well. Looks like we screwed up. Time for god's revenge */ |
721 | if (reaction < 0) |
730 | if (reaction < 0) |
722 | { |
731 | { |
… | |
… | |
728 | break; |
737 | break; |
729 | |
738 | |
730 | if (skop) |
739 | if (skop) |
731 | loss = 0.05f * skop->stats.exp; |
740 | loss = 0.05f * skop->stats.exp; |
732 | |
741 | |
733 | change_exp (op, -random_roll (0, loss * angry - 1, op, PREFER_LOW), skop ? &skop->skill : "none", SK_SUBTRACT_SKILL_EXP); |
742 | change_exp (op, -random_roll (0, loss * angry - 1, op, PREFER_LOW), skop ? skop->skill : shstr_none, SK_SUBTRACT_SKILL_EXP); |
734 | |
743 | |
735 | if (random_roll (0, angry, op, PREFER_LOW)) |
744 | if (random_roll (0, angry, op, PREFER_LOW)) |
736 | { |
745 | { |
737 | object *tmp = get_archetype (LOOSE_MANA); |
746 | object *tmp = archetype::get (LOOSE_MANA); |
738 | |
747 | |
739 | cast_magic_storm (op, tmp, op->level + (angry * 3)); |
748 | cast_magic_storm (op, tmp, op->level + (angry * 3)); |
740 | } |
749 | } |
741 | |
750 | |
742 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "%s becomes angry and punishes you!", &god->name); |
751 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, op, "%s becomes angry and punishes you!", &god->name); |
… | |
… | |
745 | return reaction; |
754 | return reaction; |
746 | } |
755 | } |
747 | |
756 | |
748 | /** |
757 | /** |
749 | * Every once in a while the god will intervene to help the worshiper. |
758 | * Every once in a while the god will intervene to help the worshiper. |
750 | * Later, this fctn can be used to supply quests, etc for the |
759 | * Later, this fctn can be used to supply quests, etc for the |
751 | * priest. -b.t. |
760 | * priest. -b.t. |
752 | * called from pray_at_altar() currently. |
761 | * called from pray_at_altar() currently. |
753 | */ |
762 | */ |
754 | static void |
763 | static void |
755 | god_intervention (object *op, object *god, object *skill) |
764 | god_intervention (object *op, object *god, object *skill) |
756 | { |
765 | { |
757 | treasure *tr; |
766 | treasure *tr; |
… | |
… | |
803 | if (op->stats.grace < item->stats.grace || op->stats.grace < op->stats.maxgrace) |
812 | if (op->stats.grace < item->stats.grace || op->stats.grace < op->stats.maxgrace) |
804 | { |
813 | { |
805 | /* Follower lacks the required grace for the following |
814 | /* Follower lacks the required grace for the following |
806 | * treasure list items. */ |
815 | * treasure list items. */ |
807 | |
816 | |
808 | object *tmp = get_archetype (HOLY_POSSESSION); |
817 | object *tmp = archetype::get (HOLY_POSSESSION); |
809 | cast_change_ability (op, op, tmp, 0, 1); |
818 | cast_change_ability (op, op, tmp, 0, 1); |
810 | tmp->destroy (); |
819 | tmp->destroy (); |
811 | return; |
820 | return; |
812 | } |
821 | } |
813 | |
822 | |
… | |
… | |
980 | return; |
989 | return; |
981 | |
990 | |
982 | /* hmm. what happend depends on pl's current god, level, etc */ |
991 | /* hmm. what happend depends on pl's current god, level, etc */ |
983 | if (!pl_god) |
992 | if (!pl_god) |
984 | { /*new convert */ |
993 | { /*new convert */ |
985 | become_follower (pl, altar->other_arch); |
994 | pl->become_follower (altar->other_arch); |
986 | return; |
995 | return; |
987 | } |
996 | } |
988 | else if (pl_god->name == altar->other_arch->object::name) |
997 | else if (pl_god->name == altar->other_arch->object::name) |
989 | { |
998 | { |
990 | /* pray at your gods altar */ |
999 | /* pray at your gods altar */ |
… | |
… | |
1029 | object *tmp; |
1038 | object *tmp; |
1030 | |
1039 | |
1031 | /* you really screwed up */ |
1040 | /* you really screwed up */ |
1032 | angry = 3; |
1041 | angry = 3; |
1033 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, pl, "Foul Priest! %s punishes you!", &pl_god->name); |
1042 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, pl, "Foul Priest! %s punishes you!", &pl_god->name); |
1034 | tmp = get_archetype (LOOSE_MANA); |
1043 | tmp = archetype::get (LOOSE_MANA); |
1035 | cast_magic_storm (pl, tmp, pl_god->level + 20); |
1044 | cast_magic_storm (pl, tmp, pl_god->level + 20); |
1036 | } |
1045 | } |
1037 | else |
1046 | else |
1038 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, pl, "Foolish heretic! %s is livid!", &pl_god->name); |
1047 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, pl, "Foolish heretic! %s is livid!", &pl_god->name); |
1039 | } |
1048 | } |
1040 | else |
1049 | else |
1041 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, pl, "Heretic! %s is angered!", &pl_god->name); |
1050 | new_draw_info_format (NDI_UNIQUE | NDI_NAVY, 0, pl, "Heretic! %s is angered!", &pl_god->name); |
1042 | |
1051 | |
1043 | /* whether we will be successfull in defecting or not - |
1052 | /* whether we will be successfull in defecting or not - |
1044 | * we lose experience from the clerical experience obj |
1053 | * we lose experience from the clerical experience obj |
1045 | */ |
1054 | */ |
1046 | |
1055 | |
1047 | loss = angry * (skill->stats.exp / 10); |
1056 | loss = angry * (skill->stats.exp / 10); |
1048 | if (loss) |
1057 | if (loss) |
1049 | change_exp (pl, -random_roll64 (0, loss, pl, PREFER_LOW), skill ? &skill->skill : "none", SK_SUBTRACT_SKILL_EXP); |
1058 | change_exp (pl, -random_roll64 (0, loss, pl, PREFER_LOW), skill ? skill->skill : shstr_none, SK_SUBTRACT_SKILL_EXP); |
1050 | |
1059 | |
1051 | /* May switch Gods, but its random chance based on our current level |
1060 | /* May switch Gods, but its random chance based on our current level |
1052 | * note it gets harder to swap gods the higher we get |
1061 | * note it gets harder to swap gods the higher we get |
1053 | */ |
1062 | */ |
1054 | if ((angry == 1) && !(random_roll (0, skill->level, pl, PREFER_LOW))) |
1063 | if ((angry == 1) && !(random_roll (0, skill->level, pl, PREFER_LOW))) |
1055 | become_follower (pl, altar->other_arch); |
1064 | pl->become_follower (altar->other_arch); |
1056 | else |
1065 | else |
1057 | { |
1066 | { |
1058 | /* toss this player off the altar. He can try again. */ |
1067 | /* toss this player off the altar. He can try again. */ |
1059 | new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, pl, "A divine force pushes you off the altar."); |
1068 | new_draw_info (NDI_UNIQUE | NDI_NAVY, 0, pl, "A divine force pushes you off the altar."); |
1060 | pl->contr->fire_on = 0; |
1069 | pl->contr->fire_on = 0; |