Crossfire Server, Branch 1.12  R12190
mood_floor.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 mood_floor_type_process(ob_methods *context, object *op);
00035 static method_ret mood_floor_type_trigger(ob_methods *context, object *op, object *cause, int state);
00036 
00040 void init_type_mood_floor(void) {
00041     register_process(MOOD_FLOOR, mood_floor_type_process);
00042     register_trigger(MOOD_FLOOR, mood_floor_type_trigger);
00043 }
00044 
00062 static void do_mood_floor(object *op, object *op2) {
00063     object *tmp;
00064     object *tmp2;
00065 
00066     for (tmp = GET_MAP_OB(op->map, op->x, op->y); tmp; tmp = tmp->above)
00067         if (QUERY_FLAG(tmp, FLAG_MONSTER))
00068             break;
00069 
00070     /* doesn't effect players, and if there is a player on this space, won't also
00071     * be a monster here.
00072     */
00073     if (!tmp || tmp->type == PLAYER)
00074         return;
00075 
00076     switch (op->last_sp) {
00077     case 0:                     /* furious--make all monsters mad */
00078         if (QUERY_FLAG(tmp, FLAG_UNAGGRESSIVE))
00079             CLEAR_FLAG(tmp, FLAG_UNAGGRESSIVE);
00080         if (QUERY_FLAG(tmp, FLAG_FRIENDLY)) {
00081             CLEAR_FLAG(tmp, FLAG_FRIENDLY);
00082             remove_friendly_object(tmp);
00083             tmp->attack_movement = 0;
00084             /* lots of checks here, but want to make sure we don't
00085              * dereference a null value
00086              */
00087             if (tmp->type == GOLEM
00088             && tmp->owner
00089             && tmp->owner->type == PLAYER
00090             && tmp->owner->contr->ranges[range_golem] == tmp) {
00091                 tmp->owner->contr->ranges[range_golem] = NULL;
00092                 tmp->owner->contr->golem_count = 0;
00093             }
00094             tmp->owner = NULL;
00095         }
00096         break;
00097 
00098     case 1:                     /* angry -- get neutral monsters mad */
00099         if (QUERY_FLAG(tmp, FLAG_UNAGGRESSIVE)
00100         && !QUERY_FLAG(tmp, FLAG_FRIENDLY))
00101             CLEAR_FLAG(tmp, FLAG_UNAGGRESSIVE);
00102         break;
00103 
00104     case 2:                     /* calm -- pacify unfriendly monsters */
00105         if (!QUERY_FLAG(tmp, FLAG_UNAGGRESSIVE)) {
00106             SET_FLAG(tmp, FLAG_UNAGGRESSIVE);
00107             tmp->enemy = NULL;
00108         }
00109         break;
00110 
00111     case 3:                     /* make all monsters fall asleep */
00112         if (!QUERY_FLAG(tmp, FLAG_SLEEP))
00113             SET_FLAG(tmp, FLAG_SLEEP);
00114         break;
00115 
00116     case 4:                     /* charm all monsters */
00117         if (op == op2)
00118             break;           /* only if 'connected' */
00119 
00120         for (tmp2 = GET_MAP_OB(op2->map, op2->x, op2->y); tmp2->type != PLAYER; tmp2 = tmp2->above)
00121             if (tmp2->above == NULL)
00122                 break;
00123         if (tmp2->type != PLAYER)
00124             break;
00125         set_owner(tmp, tmp2);
00126         SET_FLAG(tmp, FLAG_MONSTER);
00127         tmp->stats.exp = 0;
00128         SET_FLAG(tmp, FLAG_FRIENDLY);
00129         add_friendly_object(tmp);
00130         tmp->attack_movement = PETMOVE;
00131         break;
00132 
00133     default:
00134         break;
00135     }
00136 }
00137 
00144 static method_ret mood_floor_type_process(ob_methods *context, object *op) {
00145     do_mood_floor(op, op);
00146     return METHOD_OK;
00147 }
00148 
00157 static method_ret mood_floor_type_trigger(ob_methods *context, object *op, object *cause, int state) {
00158     do_mood_floor(op, cause);
00159     return METHOD_OK;
00160 }