Crossfire Server, Branch 1.12
R12190
|
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 */ 00023 00027 #include <global.h> 00028 #include <ob_methods.h> 00029 #include <ob_types.h> 00030 #include <sounds.h> 00031 #include <sproto.h> 00032 00033 static method_ret exit_type_move_on(ob_methods *context, object *trap, object *victim, object *originator); 00034 static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply); 00035 00039 void init_type_exit(void) { 00040 register_move_on(EXIT, exit_type_move_on); 00041 register_apply(EXIT, exit_type_apply); 00042 } 00043 00052 static method_ret exit_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) { 00053 if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR) 00054 return METHOD_OK; 00055 if (victim->type == PLAYER && EXIT_PATH(trap)) { 00056 /* Basically, don't show exits leading to random maps the 00057 * players output. 00058 */ 00059 if (trap->msg 00060 && strncmp(EXIT_PATH(trap), "/!", 2) 00061 && strncmp(EXIT_PATH(trap), "/random/", 8)) 00062 draw_ext_info(NDI_NAVY, 0, victim, MSG_TYPE_APPLY, MSG_TYPE_APPLY_TRAP, trap->msg, NULL); 00063 enter_exit(victim, trap); 00064 } 00065 common_post_ob_move_on(trap, victim, originator); 00066 return METHOD_OK; 00067 } 00068 00090 static int is_legal_2ways_exit(object *op, object *exit) { 00091 object *tmp; 00092 object *exit_owner; 00093 player *pp; 00094 mapstruct *exitmap; 00095 00096 if (exit->stats.exp != 1) 00097 return 1; /*This is not a 2 way, so it is legal*/ 00098 if (!has_been_loaded(EXIT_PATH(exit)) && exit->race) 00099 return 0; /* This is a reset town portal */ 00100 /* To know if an exit has a correspondant, we look at 00101 * all the exits in destination and try to find one with same path as 00102 * the current exit's position */ 00103 if (!strncmp(EXIT_PATH(exit), settings.localdir, strlen(settings.localdir))) 00104 exitmap = ready_map_name(EXIT_PATH(exit), MAP_PLAYER_UNIQUE); 00105 else 00106 exitmap = ready_map_name(EXIT_PATH(exit), 0); 00107 if (exitmap) { 00108 tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit)); 00109 if (!tmp) 00110 return 0; 00111 for ((tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit))); tmp; tmp = tmp->above) { 00112 if (tmp->type != EXIT) 00113 continue; /*Not an exit*/ 00114 if (!EXIT_PATH(tmp)) 00115 continue; /*Not a valid exit*/ 00116 if ((EXIT_X(tmp) != exit->x) || (EXIT_Y(tmp) != exit->y)) 00117 continue; /*Not in the same place*/ 00118 if (strcmp(exit->map->path, EXIT_PATH(tmp)) != 0) 00119 continue; /*Not in the same map*/ 00120 00121 /* From here we have found the exit is valid. However 00122 * we do here the check of the exit owner. It is important 00123 * for the town portals to prevent strangers from visiting 00124 * your apartments 00125 */ 00126 if (!exit->race) 00127 return 1; /*No owner, free for all!*/ 00128 exit_owner = NULL; 00129 for (pp = first_player; pp; pp = pp->next) { 00130 if (!pp->ob) 00131 continue; 00132 if (pp->ob->name != exit->race) 00133 continue; 00134 exit_owner = pp->ob; /*We found a player which correspond to the player name*/ 00135 break; 00136 } 00137 if (!exit_owner) 00138 return 0; /* No more owner*/ 00139 if (exit_owner->contr == op->contr) 00140 return 1; /*It is your exit*/ 00141 if (exit_owner /*There is a owner*/ 00142 && (op->contr) /*A player tries to pass */ 00143 && ((exit_owner->contr->party == NULL) /*No pass if controller has no party*/ 00144 || (exit_owner->contr->party != op->contr->party))) /* Or not the same as op*/ 00145 return 0; 00146 return 1; 00147 } 00148 } 00149 return 0; 00150 } 00151 00160 static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply) { 00161 if (op->type != PLAYER) 00162 return METHOD_ERROR; 00163 if (!EXIT_PATH(exit) || !is_legal_2ways_exit(op, exit)) { 00164 char name[MAX_BUF]; 00165 00166 query_name(exit, name, MAX_BUF); 00167 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, 00168 "The %s is closed.", "The %s is closed.", name); 00169 } else { 00170 /* Don't display messages for random maps. */ 00171 if (exit->msg 00172 && strncmp(EXIT_PATH(exit), "/!", 2) 00173 && strncmp(EXIT_PATH(exit), "/random/", 8)) 00174 draw_ext_info(NDI_NAVY, 0, op, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, exit->msg, NULL); 00175 enter_exit(op, exit); 00176 } 00177 return METHOD_OK; 00178 }