Atrinik Server 2.5
types/creator.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 
00041 static int check_for_duplicate_ob(object *op, mapstruct *map, int x, int y)
00042 {
00043     object *tmp;
00044 
00045     for (tmp = GET_MAP_OB(map, x, y); tmp; tmp = tmp->above)
00046     {
00047         if (tmp != op && tmp->name == op->name && tmp->type == op->type && tmp->arch == op->arch)
00048         {
00049             return 1;
00050         }
00051     }
00052 
00053     return 0;
00054 }
00055 
00062 void move_creator(object *op)
00063 {
00064     if (op->stats.hp <= 0 && !QUERY_FLAG(op, FLAG_LIFESAVE))
00065     {
00066         return;
00067     }
00068 
00069     /* Create from other_arch */
00070     if (op->other_arch)
00071     {
00072         object *tmp = arch_to_object(op->other_arch);
00073 
00074         if (op->slaying)
00075         {
00076             FREE_AND_ADD_REF_HASH(tmp->name, op->slaying);
00077             FREE_AND_ADD_REF_HASH(tmp->title, op->slaying);
00078         }
00079 
00080         tmp->x = op->x;
00081         tmp->y = op->y;
00082         tmp->level = op->level;
00083 
00084         if (QUERY_FLAG(op, FLAG_ONE_DROP) && check_for_duplicate_ob(tmp, op->map, op->x, op->y))
00085         {
00086             return;
00087         }
00088 
00089         op->stats.hp--;
00090         insert_ob_in_map(tmp, op->map, op, 0);
00091     }
00092     /* Clone from inventory. System objects won't be copied, with an exception for player movers. */
00093     else if (op->inv)
00094     {
00095         object *source, *tmp;
00096         int didit = 0, cloneindex = 0;
00097 
00098         /* Create single random item from inventory? */
00099         if (QUERY_FLAG(op, FLAG_SPLITTING))
00100         {
00101             int numobs = 0;
00102 
00103             /* Count applicable items */
00104             for (tmp = op->inv; tmp; tmp = tmp->below)
00105             {
00106                 if (!QUERY_FLAG(tmp, FLAG_SYS_OBJECT) || tmp->type == PLAYERMOVER)
00107                 {
00108                     numobs++;
00109                 }
00110             }
00111 
00112             if (numobs == 0)
00113             {
00114                 return;
00115             }
00116 
00117             cloneindex = rndm(1, numobs) - 1;
00118         }
00119 
00120         for (source = op->inv; source && cloneindex >= 0; source = source->below)
00121         {
00122             /* Don't clone sys objects */
00123             if (QUERY_FLAG(source, FLAG_SYS_OBJECT) && source->type != PLAYERMOVER)
00124             {
00125                 continue;
00126             }
00127 
00128             /* Count down to target if creating a single random item */
00129             if (QUERY_FLAG(op, FLAG_SPLITTING) && --cloneindex >= 0)
00130             {
00131                 continue;
00132             }
00133 
00134             tmp = object_create_clone(source);
00135             tmp->x = op->x;
00136             tmp->y = op->y;
00137 
00138             if (QUERY_FLAG(op, FLAG_ONE_DROP) && check_for_duplicate_ob(tmp, op->map, op->x, op->y))
00139             {
00140                 continue;
00141             }
00142 
00143             insert_ob_in_map(tmp, op->map, op, 0);
00144             didit = 1;
00145         }
00146 
00147         /* Reduce count if we cloned any object from inventory */
00148         if (didit)
00149         {
00150             op->stats.hp--;
00151         }
00152     }
00153     else
00154     {
00155         LOG(llevDebug, "Creator object with no other_arch/inventory: %s (%d, %d)\n", op->map->path, op->x, op->y);
00156     }
00157 }