Crossfire Server, Branch 1.12  R12190
common_apply.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 */
00027 #include <global.h>
00028 #include <ob_methods.h>
00029 #include <ob_types.h>
00030 #include <sproto.h>
00031 
00041 method_ret common_ob_move_on(ob_methods *context, object *trap, object *victim, object *originator) {
00042     if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
00043         return METHOD_OK;
00044     LOG(llevDebug, "name %s, arch %s, type %d with fly/walk on/off not handled in move_apply()\n", trap->name, trap->arch->name, trap->type);
00045     common_post_ob_move_on(trap, victim, originator);
00046     return METHOD_OK;
00047 }
00048 
00049 static int ob_move_on_recursion_depth = 0;
00050 
00051 method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator) {
00052     /* If player is DM, only 2 cases to consider:
00053      * - exits
00054      * - opened containers on the ground, which should be closed.
00055      */
00056     if (QUERY_FLAG(victim, FLAG_WIZPASS)
00057     && trap->type != EXIT
00058     && trap->type != SIGN
00059     && trap->type != CONTAINER
00060     && !QUERY_FLAG(trap, FLAG_APPLIED))
00061         return METHOD_ERROR;
00062 
00063     /* common_ob_move_on() is the most likely candidate for causing unwanted and
00064      * possibly unlimited recursion.
00065      */
00066     /* The following was changed because it was causing perfectly correct
00067      * maps to fail.  1)  it's not an error to recurse:
00068      * rune detonates, summoning monster.  monster lands on nearby rune.
00069      * nearby rune detonates.  This sort of recursion is expected and
00070      * proper.  This code was causing needless crashes.
00071      */
00072     if (ob_move_on_recursion_depth >= 500) {
00073         LOG(llevDebug, "WARNING: move_apply(): aborting recursion [trap arch %s, name %s; victim arch %s, name %s]\n", trap->arch->name, trap->name, victim->arch->name, victim->name);
00074         return METHOD_ERROR;
00075     }
00076     ob_move_on_recursion_depth++;
00077     if (trap->head)
00078         trap = trap->head;
00079 
00080     /* Lauwenmark: Handle for plugin trigger event */
00081     if (execute_event(trap, EVENT_TRIGGER, originator, victim, NULL, SCRIPT_FIX_ALL) != 0) {
00082         ob_move_on_recursion_depth--;
00083         return METHOD_ERROR;
00084     }
00085     return METHOD_OK;
00086 }
00087 
00088 void common_post_ob_move_on(object *trap, object *victim, object *originator) {
00089     ob_move_on_recursion_depth--;
00090     if (ob_move_on_recursion_depth < 0) /* Safety net :) */
00091         ob_move_on_recursion_depth = 0;
00092 }