Crossfire Server, Branches 1.12  R18729
exit.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2007 Mark Wedel & Crossfire Development Team
5  Copyright (C) 1992 Frank Tore Johansen
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The authors can be reached via e-mail at crossfire-devel@real-time.com
22 */
23 
27 #include <global.h>
28 #include <ob_methods.h>
29 #include <ob_types.h>
30 #include <sounds.h>
31 #include <sproto.h>
32 
33 static method_ret exit_type_move_on(ob_methods *context, object *trap, object *victim, object *originator);
34 static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply);
35 
39 void init_type_exit(void) {
42 }
43 
52 static method_ret exit_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) {
53  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
54  return METHOD_OK;
55  if (victim->type == PLAYER && EXIT_PATH(trap)) {
56  /* Basically, don't show exits leading to random maps the
57  * players output.
58  */
59  if (trap->msg
60  && strncmp(EXIT_PATH(trap), "/!", 2)
61  && strncmp(EXIT_PATH(trap), "/random/", 8))
62  draw_ext_info(NDI_NAVY, 0, victim, MSG_TYPE_APPLY, MSG_TYPE_APPLY_TRAP, trap->msg, NULL);
63  enter_exit(victim, trap);
64  }
65  common_post_ob_move_on(trap, victim, originator);
66  return METHOD_OK;
67 }
68 
90 static int is_legal_2ways_exit(object *op, object *exit) {
91  object *tmp;
92  object *exit_owner;
93  player *pp;
94  mapstruct *exitmap;
95 
96  if (exit->stats.exp != 1)
97  return 1; /*This is not a 2 way, so it is legal*/
98  if (!has_been_loaded(EXIT_PATH(exit)) && exit->race)
99  return 0; /* This is a reset town portal */
100  /* To know if an exit has a correspondant, we look at
101  * all the exits in destination and try to find one with same path as
102  * the current exit's position */
103  if (!strncmp(EXIT_PATH(exit), settings.localdir, strlen(settings.localdir)))
104  exitmap = ready_map_name(EXIT_PATH(exit), MAP_PLAYER_UNIQUE);
105  else
106  exitmap = ready_map_name(EXIT_PATH(exit), 0);
107  if (exitmap) {
108  tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit));
109  if (!tmp)
110  return 0;
111  for ((tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit))); tmp; tmp = tmp->above) {
112  if (tmp->type != EXIT)
113  continue; /*Not an exit*/
114  if (!EXIT_PATH(tmp))
115  continue; /*Not a valid exit*/
116  if ((EXIT_X(tmp) != exit->x) || (EXIT_Y(tmp) != exit->y))
117  continue; /*Not in the same place*/
118  if (strcmp(exit->map->path, EXIT_PATH(tmp)) != 0)
119  continue; /*Not in the same map*/
120 
121  /* From here we have found the exit is valid. However
122  * we do here the check of the exit owner. It is important
123  * for the town portals to prevent strangers from visiting
124  * your apartments
125  */
126  if (!exit->race)
127  return 1; /*No owner, free for all!*/
128  exit_owner = NULL;
129  for (pp = first_player; pp; pp = pp->next) {
130  if (!pp->ob)
131  continue;
132  if (pp->ob->name != exit->race)
133  continue;
134  exit_owner = pp->ob; /*We found a player which correspond to the player name*/
135  break;
136  }
137  if (!exit_owner)
138  return 0; /* No more owner*/
139  if (exit_owner->contr == op->contr)
140  return 1; /*It is your exit*/
141  if (exit_owner /*There is a owner*/
142  && (op->contr) /*A player tries to pass */
143  && ((exit_owner->contr->party == NULL) /*No pass if controller has no party*/
144  || (exit_owner->contr->party != op->contr->party))) /* Or not the same as op*/
145  return 0;
146  return 1;
147  }
148  }
149  return 0;
150 }
151 
160 static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply) {
161  if (op->type != PLAYER)
162  return METHOD_ERROR;
163  if (!EXIT_PATH(exit) || !is_legal_2ways_exit(op, exit)) {
164  char name[MAX_BUF];
165 
166  query_name(exit, name, MAX_BUF);
168  "The %s is closed.", "The %s is closed.", name);
169  } else {
170  /* Don't display messages for random maps. */
171  if (exit->msg
172  && strncmp(EXIT_PATH(exit), "/!", 2)
173  && strncmp(EXIT_PATH(exit), "/random/", 8))
175  enter_exit(op, exit);
176  }
177  return METHOD_OK;
178 }
char path[HUGE_BUF]
Definition: map.h:384
Definition: player.h:146
void enter_exit(object *op, object *exit_ob)
Definition: server.c:740
const char * race
Definition: object.h:171
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:51
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:519
#define METHOD_ERROR
Definition: ob_methods.h:44
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.c:1809
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
sint64 exp
Definition: living.h:88
struct obj * above
Definition: object.h:146
static int is_legal_2ways_exit(object *op, object *exit)
Definition: exit.c:90
sint16 x
Definition: object.h:179
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
void init_type_exit(void)
Definition: exit.c:39
#define PLAYER
Definition: define.h:113
partylist * party
Definition: player.h:237
#define NDI_NAVY
Definition: newclient.h:197
char method_ret
Definition: ob_methods.h:41
static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply)
Definition: exit.c:160
void register_move_on(int ob_type, move_on_func method)
Definition: ob_types.c:106
#define METHOD_OK
Definition: ob_methods.h:42
struct mapdef * map
Definition: object.h:155
static method_ret exit_type_move_on(ob_methods *context, object *trap, object *victim, object *originator)
Definition: exit.c:52
const char * name
Definition: object.h:167
#define EXIT_PATH(xyz)
Definition: define.h:748
#define EXIT_X(xyz)
Definition: define.h:750
sint16 y
Definition: object.h:179
void register_apply(int ob_type, apply_func method)
Definition: ob_types.c:79
struct pl * contr
Definition: object.h:134
#define MSG_TYPE_APPLY
Definition: newclient.h:330
#define EXIT
Definition: define.h:228
#define EXIT_Y(xyz)
Definition: define.h:751
#define MAX_BUF
Definition: define.h:81
#define MSG_TYPE_APPLY_TRAP
Definition: newclient.h:521
object * ob
Definition: player.h:207
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:88
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:518
#define MAP_PLAYER_UNIQUE
Definition: map.h:117
const char * localdir
Definition: global.h:335
living stats
Definition: object.h:219
mapstruct * has_been_loaded(const char *name)
Definition: map.c:87
struct Settings settings
Definition: init.c:48
const char * msg
Definition: object.h:175
EXTERN player * first_player
Definition: global.h:190
struct pl * next
Definition: player.h:147
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
#define NDI_UNIQUE
Definition: newclient.h:219
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:628
Definition: map.h:346
uint8 type
Definition: object.h:189