Crossfire Server, Trunk  R20513
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(ob_methods *context, object *trap, object *victim, object *originator);
28 static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply);
29 
33 void init_type_exit(void) {
36 }
37 
46 static method_ret exit_type_move_on(ob_methods *context, 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 (exit_owner /*There is a owner*/
136  && (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 
154 static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int 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 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
One player.
Definition: player.h:92
Sound-related defines.
void enter_exit(object *op, object *exit_ob)
Tries to move &#39;op&#39; to exit_ob.
Definition: server.c:706
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
Typedefs for ob_methods.
Definition: ob_methods.h:45
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:51
#define MSG_TYPE_APPLY_FAILURE
Apply OK, but no/bad result.
Definition: newclient.h:599
#define METHOD_ERROR
Definition: ob_methods.h:17
#define MSG_TYPE_APPLY_TRAP
Have activated a trap.
Definition: newclient.h:601
mapstruct * ready_map_name(const char *name, int flags)
Makes sure the given map is loaded and swapped in.
Definition: map.c:1803
int64_t exp
Experience.
Definition: living.h:46
struct obj * above
Pointer to the object stacked above this one.
Definition: object.h:288
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.c:84
Global type definitions and header inclusions.
void init_type_exit(void)
Initializer for the EXIT object type.
Definition: exit.c:33
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.c:310
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:384
partylist * party
Party this player is part of.
Definition: player.h:186
#define NDI_NAVY
Definition: newclient.h:223
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
int16_t y
Position in the map for this object.
Definition: object.h:326
static method_ret exit_type_apply(ob_methods *context, object *exit, object *op, int autoapply)
Handles applying an exit.
Definition: exit.c:154
See Exit.
Definition: object.h:181
void register_move_on(int ob_type, move_on_func method)
Registers the move_on method for the given type.
Definition: ob_types.c:89
#define METHOD_OK
Definition: ob_methods.h:15
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
static method_ret exit_type_move_on(ob_methods *context, object *trap, object *victim, object *originator)
Move on this Exit object.
Definition: exit.c:46
const char * name
The name of the object, obviously...
Definition: object.h:311
#define EXIT_PATH(xyz)
Definition: define.h:455
#define EXIT_X(xyz)
Definition: define.h:457
void register_apply(int ob_type, apply_func method)
Registers the apply method for the given type.
Definition: ob_types.c:62
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
#define EXIT_Y(xyz)
Definition: define.h:458
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
int16_t x
Definition: object.h:326
Object type variables.
object * ob
The object representing the player.
Definition: player.h:158
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:87
See Player.
Definition: object.h:107
#define MAP_PLAYER_UNIQUE
This map is player-specific.
Definition: map.h:97
const char * localdir
Read/write data files.
Definition: global.h:245
living stats
Str, Con, Dex, etc.
Definition: object.h:368
mapstruct * has_been_loaded(const char *name)
Checks whether map has been loaded.
Definition: map.c:79
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
struct Settings settings
Server settings.
Definition: init.c:40
#define MSG_TYPE_APPLY_SUCCESS
Was able to apply object.
Definition: newclient.h:598
const char * msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:322
EXTERN player * first_player
First player.
Definition: global.h:117
struct pl * next
Pointer to next player, NULL if this is last.
Definition: player.h:93
#define GET_MAP_OB(M, X, Y)
Gets the bottom object on a map.
Definition: map.h:172
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.c:625
This is a game-map.
Definition: map.h:325
Object type functions and variables.