Crossfire Server, Branch 1.12  R12190
scroll.c
Go to the documentation of this file.
00001 /*
00002     CrossFire, A Multiplayer game for X-windows
00003 
00004     Copyright (C) 2007 Mark Wedel & Crossfire Development Team
00005     Copyright (C) 1992 Frank Tore Johansen
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 
00021     The authors can be reached via e-mail at crossfire-devel@real-time.com
00022 */
00026 #include <global.h>
00027 #include <ob_methods.h>
00028 #include <ob_types.h>
00029 #include <sounds.h>
00030 #include <sproto.h>
00031 
00032 static method_ret scroll_type_apply(ob_methods *context, object *op, object *applier, int aflags);
00033 
00037 void init_type_scroll(void) {
00038     register_apply(SCROLL, scroll_type_apply);
00039 }
00040 
00057 static method_ret scroll_type_apply(ob_methods *context, object *scroll,
00058     object *applier, int aflags) {
00059     object *skapplier;
00060     object *head;
00061     sstring name;
00062 
00063     if (applier->head)
00064         head = applier->head;
00065     else
00066         head = applier;
00067 
00068     if (QUERY_FLAG(applier, FLAG_BLIND)&&!QUERY_FLAG(applier, FLAG_WIZ)) {
00069         draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR,
00070             "You are unable to read while blind.", NULL);
00071         return METHOD_OK;
00072     }
00073 
00074     if (!scroll->inv || scroll->inv->type != SPELL) {
00075         draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
00076             "The scroll just doesn't make sense!", NULL);
00077         return METHOD_OK;
00078     }
00079 
00080     if (applier->type == PLAYER) {
00081         /* players need a literacy skill to read stuff! */
00082         int exp_gain = 0;
00083 
00084         /* hard code literacy - scroll->skill points to where the exp
00085          * should go for anything killed by the spell.
00086          */
00087         skapplier = find_skill_by_name(applier, skill_names[SK_LITERACY]);
00088 
00089         if (!skapplier) {
00090             draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
00091                 "You are unable to decipher the strange symbols.", NULL);
00092             return METHOD_OK;
00093         }
00094 
00095         if (!QUERY_FLAG(scroll, FLAG_IDENTIFIED))
00096             identify(scroll);
00097 
00098         if (QUERY_FLAG(scroll, FLAG_CURSED) || QUERY_FLAG(scroll, FLAG_DAMNED)) {
00099             /* Player made a mistake, let's shake her/him :)
00100              * a failure of -35 means merely mana drain, -80 means
00101              * mana blast. But if server settings say 'no failure effect',
00102              * we still want to drain mana.
00103              * As for power, hey, better take care what you apply :)
00104              */
00105             int failure = -35;
00106 
00107             if (settings.spell_failure_effects == TRUE)
00108                 failure = -rndm(35, 100);
00109             scroll_failure(applier, failure, MAX(20, (scroll->level-skapplier->level)*5));
00110             decrease_ob(scroll);
00111             return METHOD_OK;
00112         }
00113 
00114         if ((exp_gain = calc_skill_exp(applier, scroll, skapplier)))
00115             change_exp(applier, exp_gain, skapplier->skill, 0);
00116     }
00117 
00118     /* need to keep the name, as the scroll may be destroyed when on the ground (reading a scroll of alchemy for instance) */
00119     name = scroll->inv->name;
00120     cast_spell(applier, scroll, head->facing, scroll->inv, NULL);
00121 
00122     if (QUERY_FLAG(scroll, FLAG_BLESSED) && die_roll(1, 100, applier, 1) < 10) {
00123         draw_ext_info_format(NDI_BLACK, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS,
00124             "Your scroll of %s glows for a second!",
00125             "Your scroll of %s glows for a second!",
00126             name);
00127     } else {
00128         draw_ext_info_format(NDI_BLACK, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS,
00129             "The scroll of %s turns to dust.",
00130             "The scroll of %s turns to dust.",
00131             name);
00132 
00133         decrease_ob(scroll);
00134     }
00135     return METHOD_OK;
00136 }