Crossfire Server, Branch 1.12  R12190
creator.c
Go to the documentation of this file.
00001 /*
00002     CrossFire, A Multiplayer game for X-windows
00003 
00004     Copyright (C) 2008 Crossfire Development Team
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 
00020     The authors can be reached via e-mail at crossfire-devel@real-time.com
00021 */
00022 
00028 #include <global.h>
00029 #include <ob_methods.h>
00030 #include <ob_types.h>
00031 #include <sounds.h>
00032 #include <sproto.h>
00033 
00034 static method_ret creator_type_process(ob_methods *context, object *op);
00035 static method_ret creator_type_trigger(ob_methods *context, object *op, object *cause, int state);
00036 
00040 void init_type_creator(void) {
00041     register_process(CREATOR, creator_type_process);
00042     register_trigger(CREATOR, creator_type_trigger);
00043 }
00044 
00064 static void move_creator(object *creator) {
00065     object *new_ob;
00066 
00067     if (!QUERY_FLAG(creator, FLAG_LIFESAVE) && --creator->stats.hp < 0) {
00068         creator->stats.hp = -1;
00069         return;
00070     }
00071 
00072     if (creator->inv != NULL) {
00073         object *ob;
00074         int i;
00075         object *ob_to_copy;
00076 
00077         /* select random object from inventory to copy */
00078         ob_to_copy = creator->inv;
00079         for (ob = creator->inv->below, i = 1; ob != NULL; ob = ob->below, i++) {
00080             if (rndm(0, i) == 0) {
00081                 ob_to_copy = ob;
00082             }
00083         }
00084         new_ob = object_create_clone(ob_to_copy);
00085         CLEAR_FLAG(new_ob, FLAG_IS_A_TEMPLATE);
00086         unflag_inv(new_ob, FLAG_IS_A_TEMPLATE);
00087     } else {
00088         if (creator->other_arch == NULL) {
00089             LOG(llevError, "move_creator: Creator doesn't have other arch set: %s (%s, %d, %d)\n", creator->name ? creator->name : "(null)", creator->map->path, creator->x, creator->y);
00090             return;
00091         }
00092 
00093         new_ob = object_create_arch(creator->other_arch);
00094         fix_generated_item(new_ob, creator, 0, 0, GT_MINIMAL);
00095     }
00096 
00097     /* Make sure this multipart object fits */
00098     if (new_ob->arch->more && ob_blocked(new_ob, creator->map, creator->x, creator->y)) {
00099         free_object(new_ob);
00100         return;
00101     }
00102 
00103     if (creator->level != 0)
00104         new_ob->level = creator->level;
00105 
00106     insert_ob_in_map_at(new_ob, creator->map, creator, 0, creator->x, creator->y);
00107     if (QUERY_FLAG(new_ob, FLAG_FREED))
00108         return;
00109 
00110     if (creator->slaying) {
00111         FREE_AND_COPY(new_ob->name, creator->slaying);
00112         FREE_AND_COPY(new_ob->title, creator->slaying);
00113     }
00114 }
00115 
00122 static method_ret creator_type_process(ob_methods *context, object *op) {
00123     move_creator(op);
00124     return METHOD_OK;
00125 }
00126 
00135 static method_ret creator_type_trigger(ob_methods *context, object *op, object *cause, int state) {
00136     move_creator(op);
00137     return METHOD_OK;
00138 }