Crossfire Server, Trunk  R22047
teleporter.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2008 Crossfire Development Team
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  The authors can be reached via e-mail at crossfire-devel@real-time.com
21 */
22 
28 #include <global.h>
29 #include <ob_methods.h>
30 #include <ob_types.h>
31 #include <sounds.h>
32 #include <sproto.h>
33 #include <string.h>
34 
35 static method_ret teleporter_type_process(ob_methods *context, object *op);
36 static method_ret teleporter_type_trigger(ob_methods *context, object *op, object *cause, int state);
37 
44 }
45 
52 static void move_teleporter(object *op) {
53  object *tmp, *head;
54 
55  /* if this is a multipart teleporter, handle the other parts
56  * The check for speed isn't strictly needed - basically, if
57  * there is an old multipart teleporter in which the other parts
58  * have speed, we don't really want to call it twice for the same
59  * function - in fact, as written below, part N would get called
60  * N times without the speed check.
61  */
62  if (op->more && FABS(op->more->speed) < MIN_ACTIVE_SPEED)
63  move_teleporter(op->more);
64 
65  head = HEAD(op);
66  for (tmp = op->above; tmp != NULL; tmp = tmp->above) {
67  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) continue; /* Ignore floors */
68  if (op->other_arch && strcmp(op->other_arch->name,tmp->name) != 0 ) continue; /* Ignore if other_arch doesn't match */
69  if (QUERY_FLAG(tmp, FLAG_WIZPASS)) continue; /* Don't teleport the DM */
70  /*
71  * Use the subtype as a bitmask to specify types of objects to *ignore*:
72  * 1 -- non-player
73  * 2 -- players
74  * 4 -- non-monster
75  * 8 -- monsters
76  * 16 -- no-pick objects
77  * ... -- add more as needed
78  *
79  * For most purposes, restricting players/non-players is the big win here.
80  * For objects, use the other_arch field to restrict it to the particular object.
81  */
82  if ( (op->subtype & 1) && tmp->type != PLAYER ) continue; /* If flagged for player only */
83  if ( (op->subtype & 2) && tmp->type == PLAYER ) continue; /* If flagged for non-player only */
84  if ( (op->subtype & 4) && !QUERY_FLAG(tmp, FLAG_MONSTER) ) continue; /* If flagged for monster only */
85  if ( (op->subtype & 8) && QUERY_FLAG(tmp, FLAG_MONSTER) ) continue; /* If flagged for non-monster only */
86  if ( (op->subtype & 16) && QUERY_FLAG(tmp, FLAG_NO_PICK) ) continue; /* If flagged skip non-pickupable objects */
87  /* ... */
88  break;
89  }
90 
91  /* If nothing above us to move, nothing to do */
92  if (!tmp) return;
93 
94  if (EXIT_PATH(head)) {
95  if (tmp->type == PLAYER) {
96  if (events_execute_object_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
97  return;
98  enter_exit(tmp, head);
99  }
100  else
101  /* Currently only players can transfer maps */
102  return;
103  } else if (EXIT_X(head) || EXIT_Y(head)) {
104  if (out_of_map(head->map, EXIT_X(head), EXIT_Y(head))) {
105  LOG(llevError, "Removed illegal teleporter.\n");
106  object_remove(head);
108  return;
109  }
110  if (events_execute_object_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
111  return;
112  transfer_ob(tmp, EXIT_X(head), EXIT_Y(head), 0, head);
113  } else {
114  /* Random teleporter */
115  if (events_execute_object_event(op, EVENT_TRIGGER, tmp, NULL, NULL, SCRIPT_FIX_ALL) != 0)
116  return;
117  teleport(head, TELEPORTER, tmp);
118  }
119 }
120 
127 static method_ret teleporter_type_process(ob_methods *context, object *op) {
128  move_teleporter(op);
129  return METHOD_OK;
130 }
131 
140 static method_ret teleporter_type_trigger(ob_methods *context, object *op, object *cause, int state) {
141  move_teleporter(op);
142  return METHOD_OK;
143 }
#define FLAG_IS_FLOOR
Definition: define.h:303
void enter_exit(object *op, object *exit_ob)
Definition: server.c:708
#define FABS(x)
Definition: define.h:22
static method_ret teleporter_type_trigger(ob_methods *context, object *op, object *cause, int state)
Definition: teleporter.c:140
#define SCRIPT_FIX_ALL
Definition: global.h:370
char method_ret
Definition: ob_methods.h:14
void object_free_drop_inventory(object *ob)
Definition: object.c:1316
#define METHOD_OK
Definition: ob_methods.h:15
void init_type_teleporter(void)
Definition: teleporter.c:41
#define EXIT_PATH(xyz)
Definition: define.h:454
static method_ret teleporter_type_process(ob_methods *context, object *op)
Definition: teleporter.c:127
int teleport(object *teleporter, uint8_t tele_type, object *user)
Definition: move.c:194
#define EXIT_X(xyz)
Definition: define.h:456
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define EXIT_Y(xyz)
Definition: define.h:457
void register_trigger(int ob_type, trigger_func method)
Definition: ob_types.c:98
static void move_teleporter(object *op)
Definition: teleporter.c:52
int out_of_map(mapstruct *m, int x, int y)
Definition: map.c:2321
void register_process(int ob_type, process_func method)
Definition: ob_types.c:71
#define MIN_ACTIVE_SPEED
Definition: define.h:676
#define FLAG_MONSTER
Definition: define.h:245
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: events.cpp:259
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
int transfer_ob(object *op, int x, int y, int randomly, object *originator)
Definition: move.c:150
#define FLAG_NO_PICK
Definition: define.h:239
#define EVENT_TRIGGER
Definition: events.h:33
#define FLAG_WIZPASS
Definition: define.h:315
void object_remove(object *op)
Definition: object.c:1588