Atrinik Server 2.5
types/altar.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00032 #define ARCH_SACRIFICE(xyz) ((xyz)->slaying)
00033 #define NROF_SACRIFICE(xyz) ((xyz)->stats.food)
00034 
00042 int apply_altar(object *altar, object *sacrifice, object *originator)
00043 {
00044     /* Only players can make sacrifices on spell casting altars. */
00045     if (altar->stats.sp != -1 && (!originator || originator->type != PLAYER))
00046     {
00047         return 0;
00048     }
00049 
00050     if (operate_altar(altar, &sacrifice))
00051     {
00052         /* Simple check. with an altar. We call it a Potion - altars are
00053          * stationary - it is up to map designers to use them
00054          * properly. */
00055         if (altar->stats.sp != -1)
00056         {
00057             new_draw_info_format(0, COLOR_WHITE, originator, "The altar casts %s.", spells[altar->stats.sp].name);
00058             cast_spell(originator, altar, altar->last_sp, altar->stats.sp, 0, CAST_POTION, NULL);
00059             /* If it is connected, push the button. Fixes some problems
00060              * with old maps. */
00061             push_button(altar);
00062         }
00063         else
00064         {
00065             /* Works only once */
00066             altar->value = 1;
00067             push_button(altar);
00068         }
00069 
00070         return sacrifice == NULL;
00071     }
00072 
00073     return 0;
00074 }
00075 
00089 int check_altar_sacrifice(object *altar, object *sacrifice)
00090 {
00091     if (!IS_LIVE(sacrifice) && !QUERY_FLAG(sacrifice, FLAG_IS_LINKED))
00092     {
00093         if ((ARCH_SACRIFICE(altar) == sacrifice->arch->name || ARCH_SACRIFICE(altar) == sacrifice->name || ARCH_SACRIFICE(altar) == sacrifice->slaying) && NROF_SACRIFICE(altar) <= (sint16)(sacrifice->nrof ? sacrifice->nrof : 1))
00094         {
00095             return 1;
00096         }
00097 
00098         if (strcmp(ARCH_SACRIFICE(altar), "money") == 0 && sacrifice->type == MONEY && sacrifice->nrof * sacrifice->value >= (uint32) NROF_SACRIFICE(altar))
00099         {
00100             return 1;
00101         }
00102     }
00103 
00104     return 0;
00105 }
00106 
00118 int operate_altar(object *altar, object **sacrifice)
00119 {
00120     if (!altar->map)
00121     {
00122         LOG(llevBug, "operate_altar(): altar has no map\n");
00123         return 0;
00124     }
00125 
00126     if (!altar->slaying || altar->value)
00127     {
00128         return 0;
00129     }
00130 
00131     if (!check_altar_sacrifice(altar, *sacrifice))
00132     {
00133         return 0;
00134     }
00135 
00136     /* check_altar_sacrifice should have already verified that enough money
00137      * has been dropped. */
00138     if (!strcmp(ARCH_SACRIFICE(altar), "money"))
00139     {
00140         int number = NROF_SACRIFICE(altar) / (*sacrifice)->value;
00141 
00142         /* Round up any sacrifices.  Altars don't make change either */
00143         if (NROF_SACRIFICE(altar) % (*sacrifice)->value)
00144         {
00145             number++;
00146         }
00147 
00148         *sacrifice = decrease_ob_nr(*sacrifice, number);
00149     }
00150     else
00151     {
00152         *sacrifice = decrease_ob_nr(*sacrifice, NROF_SACRIFICE(altar));
00153     }
00154 
00155     if (altar->msg)
00156     {
00157         new_info_map(0, COLOR_WHITE, altar->map, altar->x, altar->y, MAP_INFO_NORMAL, altar->msg);
00158     }
00159 
00160     return 1;
00161 }