Crossfire Server  1.75.0
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 }
Sound-related defines.
void enter_exit(object *op, object *exit_ob)
Tries to move &#39;op&#39; to exit_ob.
Definition: server.cpp:727
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
#define MSG_TYPE_APPLY_FAILURE
Apply OK, but no/bad result.
Definition: newclient.h:640
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
#define METHOD_ERROR
Definition: ob_methods.h:17
#define MSG_TYPE_APPLY_TRAP
Have activated a trap.
Definition: newclient.h:642
player * first_player
First player.
Definition: init.cpp:106
partylist * party
Party this player is part of.
Definition: player.h:205
object * above
Pointer to the object stacked above this one.
Definition: object.h:296
int16_t y
Position in the map for this object.
Definition: object.h:335
void register_move_on(int ob_type, move_on_func method)
Registers the move_on method for the given type.
Definition: ob_types.cpp:98
int16_t x
Definition: object.h:335
Global type definitions and header inclusions.
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.cpp:308
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:425
#define NDI_NAVY
Definition: newclient.h:248
char method_ret
Define some standard return values for callbacks which don&#39;t need to return any other results...
Definition: ob_methods.h:14
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:108
See Exit.
Definition: object.h:186
uint32_t unique
If set, this is a per player unique map.
Definition: map.h:333
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:360
#define METHOD_OK
Definition: ob_methods.h:15
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.cpp:594
sstring msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:330
sstring race
Human, goblin, dragon, etc.
Definition: object.h:326
This is a game-map.
Definition: map.h:320
#define EXIT_PATH(xyz)
Definition: define.h:439
object * ob
The object representing the player.
Definition: player.h:179
#define EXIT_X(xyz)
Definition: define.h:441
void init_type_exit(void)
Initializer for the EXIT object type.
Definition: exit.cpp:34
static method_ret exit_type_move_on(object *trap, object *victim, object *originator)
Move on this Exit object.
Definition: exit.cpp:46
living stats
Str, Con, Dex, etc.
Definition: object.h:378
#define EXIT_Y(xyz)
Definition: define.h:442
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
Object type variables.
void common_post_ob_move_on(object *trap, object *victim, object *originator)
See Player.
Definition: object.h:112
static int is_legal_2ways_exit(object *op, object *exit)
This fonction return true if the exit is not a 2 ways one or it is 2 ways, valid exit.
Definition: exit.cpp:84
#define MAP_PLAYER_UNIQUE
This map is player-specific.
Definition: map.h:95
sstring name
The name of the object, obviously...
Definition: object.h:319
static method_ret exit_type_apply(object *exit, object *op, int autoapply)
Handles applying an exit.
Definition: exit.cpp:153
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
#define MSG_TYPE_APPLY_SUCCESS
Was able to apply object.
Definition: newclient.h:639
#define GET_MAP_OB(M, X, Y)
Gets the bottom object on a map.
Definition: map.h:173
int64_t exp
Experience.
Definition: living.h:47
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:270
mapstruct * has_been_loaded(const char *name)
Checks whether map has been loaded.
Definition: map.cpp:79
One player.
Definition: player.h:107
mapstruct * ready_map_name(const char *name, int flags)
Makes sure the given map is loaded and swapped in.
Definition: map.cpp:1777
Object type functions and variables.
void register_apply(int ob_type, apply_func method)
Registers the apply method for the given type.
Definition: ob_types.cpp:62