Atrinik Server  4.0
connection.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
30 #include <global.h>
31 #include <plugin.h>
32 #include <object.h>
33 #include <object_methods.h>
34 
44 void connection_object_add(object *op, mapstruct *map, int connected)
45 {
46  objectlink *ol2, *ol;
47 
48  if (!op || !map) {
49  return;
50  }
51 
52  /* Remove previous connection if any. */
53  if (QUERY_FLAG(op, FLAG_IS_LINKED)) {
55  }
56 
58  op->path_attuned = connected;
59 
60  for (ol = map->buttons; ol; ol = ol->next) {
61  if (ol->value == connected) {
62  break;
63  }
64  }
65 
66  ol2 = get_objectlink();
67  ol2->objlink.ob = op;
68  ol2->id = op->count;
69 
70  /* Link to the existing one. */
71  if (ol) {
72  ol2->next = ol->objlink.link;
73  ol->objlink.link = ol2;
74  } else {
75  /* Create new. */
76 
77  ol = get_objectlink();
78  ol->value = connected;
79 
80  ol->next = map->buttons;
81  map->buttons = ol;
82  ol->objlink.link = ol2;
83  }
84 }
85 
91 void connection_object_remove(object *op)
92 {
93  objectlink *ol, **ol2, *tmp;
94 
95  if (!op->map) {
96  return;
97  }
98 
99  if (!QUERY_FLAG(op, FLAG_IS_LINKED)) {
100  return;
101  }
102 
103  for (ol = op->map->buttons; ol; ol = ol->next) {
104  for (ol2 = &ol->objlink.link; (tmp = *ol2); ol2 = &tmp->next) {
105  if (tmp->objlink.ob == op) {
106  *ol2 = tmp->next;
107  free_objectlink_simple(ol);
108  return;
109  }
110  }
111  }
112 
114 }
115 
124 int
125 connection_object_get_value (const object *op)
126 {
127  HARD_ASSERT(op != NULL);
128 
129  if (op->map == NULL || !QUERY_FLAG(op, FLAG_IS_LINKED)) {
130  return 0;
131  }
132 
133  return op->path_attuned;
134 }
135 
146 {
147  objectlink *ol, *ol2;
148 
149  HARD_ASSERT(op != NULL);
150  HARD_ASSERT(map != NULL);
151 
152  for (ol = map->buttons; ol != NULL; ol = ol->next) {
153  for (ol2 = ol->objlink.link; ol2 != NULL; ol2 = ol2->next) {
154  if (OBJECT_VALID(ol2->objlink.ob, ol2->id) &&
155  ol2->objlink.ob->path_attuned == op->path_attuned) {
156  return ol->objlink.link;
157  }
158  }
159  }
160 
161  return NULL;
162 }
163 
177 static int64_t connection_trigger_do(object *op, int state, bool button)
178 {
179  if (op->map == NULL) {
180  return 0;
181  }
182 
183  int64_t down = 0;
184 
185  for (int i = -1; i < TILED_NUM; i++) {
186  if (i != -1 && (op->map->tile_path[i] == NULL ||
187  !(op->path_repelled & (1 << i)))) {
188  continue;
189  }
190 
191  mapstruct *map = op->map;
192 
193  if (i != -1) {
194  if (op->map->in_memory == MAP_SAVING) {
195  map = has_been_loaded_sh(map->tile_path[i]);
196  } else {
197  map = ready_map_name(map->tile_path[i], NULL, MAP_NAME_SHARED);
198  }
199 
200  if (map == NULL) {
201  LOG(ERROR, "Could not load map: %s", op->map->tile_path[i]);
202  continue;
203  }
204  }
205 
206  for (objectlink *ol = connection_object_links(op, map); ol != NULL;
207  ol = ol->next) {
208  object *tmp = ol->objlink.ob;
209 
210  if (button) {
211  if (object_trigger_button(tmp, op, state) == OBJECT_METHOD_OK) {
212  if (tmp->value) {
213  down = 1;
214 
215  if (QUERY_FLAG(tmp, FLAG_CONNECT_RESET)) {
216  tmp->value = 0;
217  }
218  }
219  }
220  } else {
221  /* If the criteria isn't appropriate, don't do anything. */
222  if (state && QUERY_FLAG(tmp, FLAG_CONNECT_NO_PUSH)) {
223  continue;
224  }
225 
226  if (!state && QUERY_FLAG(tmp, FLAG_CONNECT_NO_RELEASE)) {
227  continue;
228  }
229 
230  if (HAS_EVENT(tmp, EVENT_TRIGGER) &&
232  tmp,
233  op,
234  NULL,
235  NULL,
236  0,
237  0,
238  0,
239  0) != 0) {
240  continue;
241  }
242 
243  object_trigger(tmp, op, state);
244  }
245  }
246  }
247 
248  return down;
249 }
250 
258 void connection_trigger(object *op, int state)
259 {
260  HARD_ASSERT(op != NULL);
261 
262  connection_trigger_do(op, state, false);
263 }
264 
272 void connection_trigger_button(object *op, int state)
273 {
274  int64_t old_state, down;
275 
276  HARD_ASSERT(op != NULL);
277 
278  old_state = op->value;
279  down = connection_trigger_do(op, state, true);
280 
281  if (down) {
282  op->value = down;
283  }
284 
285  if (op->value != old_state) {
286  connection_trigger(op, op->value);
287  }
288 
289  if (op->value && QUERY_FLAG(op, FLAG_CONNECT_RESET)) {
290  op->value = 0;
291  }
292 }
#define FLAG_CONNECT_NO_PUSH
Definition: define.h:1098
Definition: object.h:488
#define FLAG_IS_LINKED
Definition: define.h:1150
int trigger_event(int event_type, object *const activator, object *const me, object *const other, const char *msg, int parm1, int parm2, int parm3, int flags)
Definition: plugins.c:510
uint32_t in_memory
Definition: map.h:627
void connection_trigger_button(object *op, int state)
Definition: connection.c:272
void connection_object_remove(object *op)
Definition: connection.c:91
long value
Definition: object.h:509
#define HAS_EVENT(ob, event)
Definition: plugin.h:179
uint32_t path_attuned
Definition: object.h:255
static objectlink * connection_object_links(object *op, mapstruct *map)
Definition: connection.c:145
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
uint32_t path_repelled
Definition: object.h:258
tag_t id
Definition: object.h:506
object * ob
Definition: object.h:496
#define EVENT_TRIGGER
Definition: plugin.h:93
struct mapdef * map
Definition: object.h:139
static int64_t connection_trigger_do(object *op, int state, bool button)
Definition: connection.c:177
objectlink * buttons
Definition: map.h:588
#define SET_FLAG(xyz, p)
Definition: define.h:741
shstr * tile_path[TILED_NUM]
Definition: map.h:571
#define FLAG_CONNECT_NO_RELEASE
Definition: define.h:1102
union oblnk::@3 objlink
#define MAP_SAVING
Definition: map.h:176
int connection_object_get_value(const object *op)
Definition: connection.c:125
int object_trigger_button(object *op, object *cause, int state)
#define TILED_NUM
Definition: global.h:208
void connection_trigger(object *op, int state)
Definition: connection.c:258
#define FLAG_CONNECT_RESET
Definition: define.h:956
#define MAP_NAME_SHARED
Definition: map.h:157
struct oblnk * link
Definition: object.h:493
tag_t count
Definition: object.h:142
struct oblnk * next
Definition: object.h:500
#define CLEAR_FLAG(xyz, p)
Definition: define.h:751
int object_trigger(object *op, object *cause, int state)
mapstruct * has_been_loaded_sh(shstr *name)
Definition: map.c:389
#define OBJECT_METHOD_OK
#define OBJECT_VALID(_ob_, _count_)
Definition: object.h:548
mapstruct * ready_map_name(const char *name, mapstruct *originator, int flags)
Definition: map.c:1584
Definition: map.h:536
int64_t value
Definition: object.h:240
void connection_object_add(object *op, mapstruct *map, int connected)
Definition: connection.c:44