Crossfire Server, Trunk
exit.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
18 #include "global.h"
19 
20 #include <string.h>
21 
22 #include "ob_methods.h"
23 #include "ob_types.h"
24 #include "sounds.h"
25 #include "sproto.h"
26 
27 static method_ret exit_type_move_on(object *trap, object *victim, object *originator);
28 static method_ret exit_type_apply(object *exit, object *op, int autoapply);
29 
33 void init_type_exit(void) {
36 }
37 
45 static method_ret exit_type_move_on(object *trap, object *victim, object *originator) {
46  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
47  return METHOD_OK;
48  if (victim->type == PLAYER && EXIT_PATH(trap)) {
49  /* Basically, don't show exits leading to random maps the
50  * players output.
51  */
52  if (trap->msg
53  && strncmp(EXIT_PATH(trap), "/!", 2)
54  && strncmp(EXIT_PATH(trap), "/random/", 8))
56  enter_exit(victim, trap);
57  }
58  common_post_ob_move_on(trap, victim, originator);
59  return METHOD_OK;
60 }
61 
83 static int is_legal_2ways_exit(object *op, object *exit) {
84  object *tmp;
85  object *exit_owner;
86  player *pp;
87  mapstruct *exitmap;
88 
89  if (exit->stats.exp != 1)
90  return 1; /*This is not a 2 way, so it is legal*/
91  if (!has_been_loaded(EXIT_PATH(exit)) && exit->race)
92  return 0; /* This is a reset town portal */
93  /* To know if an exit has a correspondent, we look at
94  * all the exits in destination and try to find one with same path as
95  * the current exit's position */
96  if (!strncmp(EXIT_PATH(exit), settings.localdir, strlen(settings.localdir)))
97  exitmap = ready_map_name(EXIT_PATH(exit), MAP_PLAYER_UNIQUE);
98  else
99  exitmap = ready_map_name(EXIT_PATH(exit), 0);
100  if (exitmap) {
101  tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit));
102  if (!tmp)
103  return 0;
104  for ((tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit))); tmp; tmp = tmp->above) {
105  if (tmp->type != EXIT)
106  continue; /*Not an exit*/
107  if (!EXIT_PATH(tmp))
108  continue; /*Not a valid exit*/
109  if ((EXIT_X(tmp) != exit->x) || (EXIT_Y(tmp) != exit->y))
110  continue; /*Not in the same place*/
111  if (strcmp(exit->map->path, EXIT_PATH(tmp)) != 0)
112  continue; /*Not in the same map*/
113 
114  /* From here we have found the exit is valid. However
115  * we do here the check of the exit owner. It is important
116  * for the town portals to prevent strangers from visiting
117  * your apartments
118  */
119  if (!exit->race)
120  return 1; /*No owner, free for all!*/
121  exit_owner = NULL;
122  for (pp = first_player; pp; pp = pp->next) {
123  if (!pp->ob)
124  continue;
125  if (pp->ob->name != exit->race)
126  continue;
127  exit_owner = pp->ob; /*We found a player which correspond to the player name*/
128  break;
129  }
130  if (!exit_owner)
131  return 0; /* No more owner*/
132  if (exit_owner->contr == op->contr)
133  return 1; /*It is your exit*/
134  if ((op->contr) /*A player tries to pass */
135  && ((exit_owner->contr->party == NULL) /*No pass if controller has no party*/
136  || (exit_owner->contr->party != op->contr->party))) /* Or not the same as op*/
137  return 0;
138  return 1;
139  }
140  }
141  return 0;
142 }
143 
151 static method_ret exit_type_apply(object *exit, object *op, int autoapply) {
152  (void)autoapply;
153  if (op->type != PLAYER)
154  return METHOD_ERROR;
155  if (!EXIT_PATH(exit) || !is_legal_2ways_exit(op, exit)) {
156  char name[MAX_BUF];
157 
158  query_name(exit, name, MAX_BUF);
160  "The %s is closed.", name);
161  } else {
162  /* Don't display messages for random maps. */
163  if (exit->msg
164  && strncmp(EXIT_PATH(exit), "/!", 2)
165  && strncmp(EXIT_PATH(exit), "/random/", 8))
167  enter_exit(op, exit);
168  }
169  return METHOD_OK;
170 }
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:173
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.c:1785
PLAYER
@ PLAYER
Definition: object.h:107
global.h
obj::map
struct mapdef * map
Definition: object.h:300
obj::race
sstring race
Definition: object.h:321
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
pl
Definition: player.h:105
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:439
pl::ob
object * ob
Definition: player.h:176
MAP_PLAYER_UNIQUE
#define MAP_PLAYER_UNIQUE
Definition: map.h:97
Ice.tmp
int tmp
Definition: Ice.py:207
is_legal_2ways_exit
static int is_legal_2ways_exit(object *op, object *exit)
Definition: exit.c:83
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:244
obj::msg
sstring msg
Definition: object.h:325
settings
struct Settings settings
Definition: init.c:39
liv::exp
int64_t exp
Definition: living.h:47
pl::next
struct pl * next
Definition: player.h:106
obj::name
sstring name
Definition: object.h:314
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:603
query_name
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:585
common_pre_ob_move_on
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:51
first_player
EXTERN player * first_player
Definition: global.h:115
obj::x
int16_t x
Definition: object.h:330
MSG_TYPE_APPLY_TRAP
#define MSG_TYPE_APPLY_TRAP
Definition: newclient.h:606
register_move_on
void register_move_on(int ob_type, move_on_func method)
Definition: ob_types.c:89
sproto.h
mapdef
Definition: map.h:317
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
exit_type_apply
static method_ret exit_type_apply(object *exit, object *op, int autoapply)
Definition: exit.c:151
EXIT_X
#define EXIT_X(xyz)
Definition: define.h:441
MAX_BUF
#define MAX_BUF
Definition: define.h:35
EXIT
@ EXIT
Definition: object.h:181
obj::y
int16_t y
Definition: object.h:330
register_apply
void register_apply(int ob_type, apply_func method)
Definition: ob_types.c:62
method_ret
char method_ret
Definition: ob_methods.h:14
ob_types.h
sounds.h
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:262
obj::stats
living stats
Definition: object.h:373
obj::contr
struct pl * contr
Definition: object.h:279
reputation.victim
victim
Definition: reputation.py:14
enter_exit
void enter_exit(object *op, object *exit_ob)
Definition: server.c:732
give.op
op
Definition: give.py:33
exit_type_move_on
static method_ret exit_type_move_on(object *trap, object *victim, object *originator)
Definition: exit.c:45
init_type_exit
void init_type_exit(void)
Definition: exit.c:33
EXIT_Y
#define EXIT_Y(xyz)
Definition: define.h:442
MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:604
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:309
METHOD_ERROR
#define METHOD_ERROR
Definition: ob_methods.h:17
ob_methods.h
mapdef::path
char path[HUGE_BUF]
Definition: map.h:358
pl::party
partylist * party
Definition: player.h:202
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Definition: newclient.h:408
common_post_ob_move_on
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:86
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:319
give.name
name
Definition: give.py:27
has_been_loaded
mapstruct * has_been_loaded(const char *name)
Definition: map.c:78
Settings::localdir
const char * localdir
Definition: global.h:244