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  exitmap = has_been_loaded(EXIT_PATH(exit));
93  if (!exitmap && exit->race)
94  return 0; /* This is a reset town portal */
95  /* To know if an exit has a correspondent, we look at
96  * all the exits in destination and try to find one with same path as
97  * the current exit's position */
98  if (exitmap->unique)
99  exitmap = ready_map_name(EXIT_PATH(exit), MAP_PLAYER_UNIQUE);
100  else
101  exitmap = ready_map_name(EXIT_PATH(exit), 0);
102  if (exitmap) {
103  tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit));
104  if (!tmp)
105  return 0;
106  for ((tmp = GET_MAP_OB(exitmap, EXIT_X(exit), EXIT_Y(exit))); tmp; tmp = tmp->above) {
107  if (tmp->type != EXIT)
108  continue; /*Not an exit*/
109  if (!EXIT_PATH(tmp))
110  continue; /*Not a valid exit*/
111  if ((EXIT_X(tmp) != exit->x) || (EXIT_Y(tmp) != exit->y))
112  continue; /*Not in the same place*/
113  if (strcmp(exit->map->path, EXIT_PATH(tmp)) != 0)
114  continue; /*Not in the same map*/
115 
116  /* From here we have found the exit is valid. However
117  * we do here the check of the exit owner. It is important
118  * for the town portals to prevent strangers from visiting
119  * your apartments
120  */
121  if (!exit->race)
122  return 1; /*No owner, free for all!*/
123  exit_owner = NULL;
124  for (pp = first_player; pp; pp = pp->next) {
125  if (!pp->ob)
126  continue;
127  if (pp->ob->name != exit->race)
128  continue;
129  exit_owner = pp->ob; /*We found a player which correspond to the player name*/
130  break;
131  }
132  if (!exit_owner)
133  return 0; /* No more owner*/
134  if (exit_owner->contr == op->contr)
135  return 1; /*It is your exit*/
136  if ((op->contr) /*A player tries to pass */
137  && ((exit_owner->contr->party == NULL) /*No pass if controller has no party*/
138  || (exit_owner->contr->party != op->contr->party))) /* Or not the same as op*/
139  return 0;
140  return 1;
141  }
142  }
143  return 0;
144 }
145 
153 static method_ret exit_type_apply(object *exit, object *op, int autoapply) {
154  (void)autoapply;
155  if (op->type != PLAYER)
156  return METHOD_ERROR;
157  if (!EXIT_PATH(exit) || !is_legal_2ways_exit(op, exit)) {
158  char name[MAX_BUF];
159 
160  query_name(exit, name, MAX_BUF);
162  "The %s is closed.", name);
163  } else {
164  /* Don't display messages for random maps. */
165  if (exit->msg
166  && strncmp(EXIT_PATH(exit), "/!", 2)
167  && strncmp(EXIT_PATH(exit), "/random/", 8))
169  enter_exit(op, exit);
170  }
171  return METHOD_OK;
172 }
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:170
living::exp
int64_t exp
Definition: living.h:47
PLAYER
@ PLAYER
Definition: object.h:112
player::next
player * next
Definition: player.h:106
global.h
first_player
player * first_player
Definition: init.cpp:106
player
Definition: player.h:105
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.cpp:1762
has_been_loaded
mapstruct * has_been_loaded(const char *name)
Definition: map.cpp:79
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
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:439
object::x
int16_t x
Definition: object.h:335
player::ob
object * ob
Definition: player.h:177
object::map
struct mapstruct * map
Definition: object.h:305
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
MAP_PLAYER_UNIQUE
#define MAP_PLAYER_UNIQUE
Definition: map.h:92
Ice.tmp
int tmp
Definition: Ice.py:207
NDI_NAVY
#define NDI_NAVY
Definition: newclient.h:233
mapstruct::path
char path[HUGE_BUF]
Definition: map.h:353
object::y
int16_t y
Definition: object.h:335
object::contr
struct player * contr
Definition: object.h:284
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:592
query_name
void query_name(const object *op, char *buf, size_t size)
Definition: item.cpp:588
init_type_exit
void init_type_exit(void)
Definition: exit.cpp:34
sword_of_souls.victim
victim
Definition: sword_of_souls.py:12
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
MSG_TYPE_APPLY_TRAP
#define MSG_TYPE_APPLY_TRAP
Definition: newclient.h:595
sproto.h
object::race
sstring race
Definition: object.h:326
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:153
EXIT
@ EXIT
Definition: object.h:186
method_ret
char method_ret
Definition: ob_methods.h:14
ob_types.h
sounds.h
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
object::name
sstring name
Definition: object.h:319
is_legal_2ways_exit
static int is_legal_2ways_exit(object *op, object *exit)
Definition: exit.cpp:84
mapstruct
Definition: map.h:313
enter_exit
void enter_exit(object *op, object *exit_ob)
Definition: server.cpp:738
give.op
op
Definition: give.py:33
object::msg
sstring msg
Definition: object.h:330
EXIT_Y
#define EXIT_Y(xyz)
Definition: define.h:442
player::party
partylist * party
Definition: player.h:203
MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:593
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
mapstruct::unique
uint32_t unique
Definition: map.h:326
ob_methods.h
object::stats
living stats
Definition: object.h:378
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Definition: newclient.h:397
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