Crossfire Server, Trunk
exit.cpp
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 
19 #include "global.h"
20 
21 #include <string.h>
22 
23 #include "ob_methods.h"
24 #include "ob_types.h"
25 #include "sounds.h"
26 #include "sproto.h"
27 
28 static method_ret exit_type_move_on(object *trap, object *victim, object *originator);
29 static method_ret exit_type_apply(object *exit, object *op, int autoapply);
30 
34 void init_type_exit(void) {
37 }
38 
46 static method_ret exit_type_move_on(object *trap, object *victim, object *originator) {
47  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
48  return METHOD_OK;
49  if (victim->type == PLAYER && EXIT_PATH(trap)) {
50  /* Basically, don't show exits leading to random maps the
51  * players output.
52  */
53  if (trap->msg
54  && strncmp(EXIT_PATH(trap), "/!", 2)
55  && strncmp(EXIT_PATH(trap), "/random/", 8))
57  enter_exit(victim, trap);
58  }
59  common_post_ob_move_on(trap, victim, originator);
60  return METHOD_OK;
61 }
62 
84 static int is_legal_2ways_exit(object *op, object *exit) {
85  object *tmp;
86  object *exit_owner;
87  player *pp;
88  mapstruct *exitmap;
89 
90  if (exit->stats.exp != 1)
91  return 1; /*This is not a 2 way, so it is legal*/
92  if (!has_been_loaded(EXIT_PATH(exit)) && exit->race)
93  return 0; /* This is a reset town portal */
94  /* To know if an exit has a correspondent, we look at
95  * all the exits in destination and try to find one with same path as
96  * the current exit's position */
97  if (!strncmp(EXIT_PATH(exit), settings.localdir, strlen(settings.localdir)))
98  exitmap = ready_map_name(EXIT_PATH(exit), MAP_PLAYER_UNIQUE);
99  else
100  exitmap = ready_map_name(EXIT_PATH(exit), 0);
101  if (exitmap) {
102  tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit));
103  if (!tmp)
104  return 0;
105  for ((tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit))); tmp; tmp = tmp->above) {
106  if (tmp->type != EXIT)
107  continue; /*Not an exit*/
108  if (!EXIT_PATH(tmp))
109  continue; /*Not a valid exit*/
110  if ((EXIT_X(tmp) != exit->x) || (EXIT_Y(tmp) != exit->y))
111  continue; /*Not in the same place*/
112  if (strcmp(exit->map->path, EXIT_PATH(tmp)) != 0)
113  continue; /*Not in the same map*/
114 
115  /* From here we have found the exit is valid. However
116  * we do here the check of the exit owner. It is important
117  * for the town portals to prevent strangers from visiting
118  * your apartments
119  */
120  if (!exit->race)
121  return 1; /*No owner, free for all!*/
122  exit_owner = NULL;
123  for (pp = first_player; pp; pp = pp->next) {
124  if (!pp->ob)
125  continue;
126  if (pp->ob->name != exit->race)
127  continue;
128  exit_owner = pp->ob; /*We found a player which correspond to the player name*/
129  break;
130  }
131  if (!exit_owner)
132  return 0; /* No more owner*/
133  if (exit_owner->contr == op->contr)
134  return 1; /*It is your exit*/
135  if ((op->contr) /*A player tries to pass */
136  && ((exit_owner->contr->party == NULL) /*No pass if controller has no party*/
137  || (exit_owner->contr->party != op->contr->party))) /* Or not the same as op*/
138  return 0;
139  return 1;
140  }
141  }
142  return 0;
143 }
144 
152 static method_ret exit_type_apply(object *exit, object *op, int autoapply) {
153  (void)autoapply;
154  if (op->type != PLAYER)
155  return METHOD_ERROR;
156  if (!EXIT_PATH(exit) || !is_legal_2ways_exit(op, exit)) {
157  char name[MAX_BUF];
158 
159  query_name(exit, name, MAX_BUF);
161  "The %s is closed.", name);
162  } else {
163  /* Don't display messages for random maps. */
164  if (exit->msg
165  && strncmp(EXIT_PATH(exit), "/!", 2)
166  && strncmp(EXIT_PATH(exit), "/random/", 8))
168  enter_exit(op, exit);
169  }
170  return METHOD_OK;
171 }
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:173
PLAYER
@ PLAYER
Definition: object.h:110
global.h
first_player
player * first_player
Definition: init.cpp:106
settings
struct Settings settings
Definition: init.cpp:139
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.cpp:1793
obj::map
struct mapdef * map
Definition: object.h:303
obj::race
sstring race
Definition: object.h:324
has_been_loaded
mapstruct * has_been_loaded(const char *name)
Definition: map.cpp:78
register_apply
void register_apply(int ob_type, apply_func method)
Definition: ob_types.cpp:62
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
register_move_on
void register_move_on(int ob_type, move_on_func method)
Definition: ob_types.cpp:89
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,...) PRINTF_ARGS(6
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
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:244
obj::msg
sstring msg
Definition: object.h:328
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:317
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.cpp:585
init_type_exit
void init_type_exit(void)
Definition: exit.cpp:34
common_pre_ob_move_on
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.cpp:35
exit_type_move_on
static method_ret exit_type_move_on(object *trap, object *victim, object *originator)
Definition: exit.cpp:46
obj::x
int16_t x
Definition: object.h:333
MSG_TYPE_APPLY_TRAP
#define MSG_TYPE_APPLY_TRAP
Definition: newclient.h:606
sproto.h
mapdef
Definition: map.h:317
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
EXIT_X
#define EXIT_X(xyz)
Definition: define.h:441
MAX_BUF
#define MAX_BUF
Definition: define.h:35
exit_type_apply
static method_ret exit_type_apply(object *exit, object *op, int autoapply)
Definition: exit.cpp:152
EXIT
@ EXIT
Definition: object.h:184
obj::y
int16_t y
Definition: object.h:333
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:376
obj::contr
struct pl * contr
Definition: object.h:282
is_legal_2ways_exit
static int is_legal_2ways_exit(object *op, object *exit)
Definition: exit.cpp:84
reputation.victim
victim
Definition: reputation.py:14
enter_exit
void enter_exit(object *op, object *exit_ob)
Definition: server.cpp:732
give.op
op
Definition: give.py: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.cpp:308
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.cpp:67
give.name
name
Definition: give.py:27
Settings::localdir
const char * localdir
Definition: global.h:249