Atrinik Server  4.0
monster_data.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 
32 #include <global.h>
33 #include <monster_data.h>
34 #include <toolkit/packet.h>
35 #include <monster_guard.h>
36 #include <player.h>
37 #include <object.h>
38 
39 #ifndef __CPROTO__
40 
42 
48 void monster_data_init(object *op)
49 {
50  HARD_ASSERT(op != NULL);
51  SOFT_ASSERT(op->type == MONSTER, "Object is not a monster: %s",
52  object_get_str(op));
53 
54  op->custom_attrset = ecalloc(1, sizeof(monster_data_t));
55 }
56 
62 void monster_data_deinit(object *op)
63 {
64  HARD_ASSERT(op != NULL);
65  SOFT_ASSERT(op->type == MONSTER, "Object is not a monster: %s",
66  object_get_str(op));
67 
69  SOFT_ASSERT(monster_data != NULL, "Missing monster data for: %s",
70  object_get_str(op));
71 
72  monster_data_dialog_t *dialog, *tmp;
73 
74  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
76  }
77 
78  efree(monster_data);
79 }
80 
89 void monster_data_enemy_update(object *op, object *enemy)
90 {
91  HARD_ASSERT(op != NULL);
92  SOFT_ASSERT(op->type == MONSTER, "Object is not a monster: %s",
93  object_get_str(op));
94 
96  SOFT_ASSERT(monster_data != NULL, "Missing monster data for: %s",
97  object_get_str(op));
98 
99  if (enemy == NULL) {
100  monster_data->enemy_coords.map = NULL;
101  } else {
102  monster_data->enemy_coords.x = enemy->x;
103  monster_data->enemy_coords.y = enemy->y;
104  monster_data->enemy_coords.map = enemy->map;
105  }
106 }
107 
120 bool monster_data_enemy_get_coords(object *op, mapstruct **map, uint16_t *x,
121  uint16_t *y)
122 {
123  HARD_ASSERT(op != NULL);
124  SOFT_ASSERT_RC(op->type == MONSTER, false, "Object is not a monster: %s",
125  object_get_str(op));
126 
128  SOFT_ASSERT_RC(monster_data != NULL, false, "Missing monster data for: %s",
129  object_get_str(op));
130 
131  if (monster_data->enemy_coords.map == NULL) {
132  return false;
133  }
134 
135  *map = monster_data->enemy_coords.map;
136  *x = monster_data->enemy_coords.x;
137  *y = monster_data->enemy_coords.y;
138 
139  return true;
140 }
141 
148 {
149  HARD_ASSERT(dialog != NULL);
150  efree(dialog);
151 }
152 
159 {
160  HARD_ASSERT(dialog != NULL);
161 
162  if (dialog->ob->type != PLAYER) {
163  return;
164  }
165 
166  packet_struct *packet = packet_new(CLIENT_CMD_INTERFACE, 32, 0);
167  socket_send_packet(CONTR(dialog->ob)->cs, packet);
168 }
169 
181  monster_data_dialog_t *dialog)
182 {
183  HARD_ASSERT(monster_data != NULL);
184  HARD_ASSERT(dialog != NULL);
185 
186  if (!OBJECT_VALID(dialog->ob, dialog->count)) {
187  goto invalid;
188  }
189 
190  if (pticks > dialog->expire) {
191  /* Close the dialog for players. */
193  goto invalid;
194  }
195 
196  return true;
197 
198 invalid:
199  DL_DELETE(monster_data->dialogs, dialog);
201  return false;
202 }
203 
214 void monster_data_dialogs_add(object *op, object *activator, uint32_t secs)
215 {
216  HARD_ASSERT(op != NULL);
217  HARD_ASSERT(activator != NULL);
218 
220  SOFT_ASSERT(monster_data != NULL, "Missing monster data for: %s",
221  object_get_str(op));
222 
223  monster_data_dialog_t *dialog, *tmp;
224  long expire = pticks + (secs + MONSTER_DATA_INTERFACE_TIMEOUT) * MAX_TICKS;
225 
226  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
227  if (!monster_data_dialogs_verify(monster_data, dialog)) {
228  continue;
229  }
230 
231  if (dialog->ob == activator && dialog->count == activator->count) {
232  dialog->expire = expire;
233  return;
234  }
235  }
236 
237  dialog = ecalloc(1, sizeof(*dialog));
238  dialog->ob = activator;
239  dialog->count = activator->count;
240  dialog->expire = expire;
241  DL_APPEND(monster_data->dialogs, dialog);
242 }
243 
254 void monster_data_dialogs_remove(object *op, object *activator)
255 {
256  HARD_ASSERT(op != NULL);
257  HARD_ASSERT(activator != NULL);
258 
260  SOFT_ASSERT(monster_data != NULL, "Missing monster data for: %s",
261  object_get_str(op));
262 
263  monster_data_dialog_t *dialog, *tmp;
264 
265  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
266  if (!monster_data_dialogs_verify(monster_data, dialog)) {
267  continue;
268  }
269 
270  if (dialog->ob == activator && dialog->count == activator->count) {
271  DL_DELETE(monster_data->dialogs, dialog);
272  monster_guard_check_close(op, activator);
274  break;
275  }
276  }
277 }
278 
290 bool monster_data_dialogs_check(object *op, object *activator)
291 {
292  HARD_ASSERT(op != NULL);
293  HARD_ASSERT(activator != NULL);
294 
296  SOFT_ASSERT_RC(monster_data != NULL, false, "Missing monster data for: %s",
297  object_get_str(op));
298 
299  monster_data_dialog_t *dialog, *tmp;
300 
301  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
302  if (!monster_data_dialogs_verify(monster_data, dialog)) {
303  continue;
304  }
305 
306  if (dialog->ob == activator && dialog->count == activator->count) {
307  return true;
308  }
309  }
310 
311  return false;
312 }
313 
321 size_t monster_data_dialogs_num(object *op)
322 {
323  HARD_ASSERT(op != NULL);
324 
326  SOFT_ASSERT_RC(monster_data != NULL, 0, "Missing monster data for: %s",
327  object_get_str(op));
328 
329  monster_data_dialog_t *dialog, *tmp;
330  size_t num = 0;
331 
332  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
333  if (!monster_data_dialogs_verify(monster_data, dialog)) {
334  continue;
335  }
336 
337  num++;
338  }
339 
340  return num;
341 }
342 
350 {
351  HARD_ASSERT(op != NULL);
352 
354  SOFT_ASSERT(monster_data != NULL, "Missing monster data for: %s",
355  object_get_str(op));
356 
357  if (pticks - monster_data->last_cleanup < MONSTER_DATA_INTERFACE_CLEANUP *
358  MAX_TICKS) {
359  return;
360  }
361 
362  monster_data->last_cleanup = pticks;
363 
364  monster_data_dialog_t *dialog, *tmp;
365 
366  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
367  if (!monster_data_dialogs_verify(monster_data, dialog)) {
368  continue;
369  }
370 
371  rv_vector rv;
372 
373  if (get_rangevector(op, dialog->ob, &rv, RV_MANHATTAN_DISTANCE) &&
375  continue;
376  }
377 
378  DL_DELETE(monster_data->dialogs, dialog);
379  monster_guard_check_close(op, dialog->ob);
381  }
382 }
383 
390 {
391  HARD_ASSERT(op != NULL);
392 
394  SOFT_ASSERT(monster_data != NULL, "Missing monster data for: %s",
395  object_get_str(op));
396 
397  monster_data_dialog_t *dialog, *tmp;
398 
399  DL_FOREACH_SAFE(monster_data->dialogs, dialog, tmp) {
401  DL_DELETE(monster_data->dialogs, dialog);
402  monster_guard_check_close(op, dialog->ob);
404  }
405 }
406 
407 #endif
struct monster_data::@15 enemy_coords
#define MONSTER
Definition: define.h:353
int get_rangevector(object *op1, object *op2, rv_vector *retval, int flags)
Definition: map.c:2238
unsigned int distance
Definition: map.h:775
void * custom_attrset
Definition: object.h:160
static void monster_data_dialogs_close(monster_data_dialog_t *dialog)
Definition: monster_data.c:158
void monster_data_dialogs_add(object *op, object *activator, uint32_t secs)
Definition: monster_data.c:214
#define MONSTER_DATA_INTERFACE_CLEANUP
Definition: monster_data.h:39
void monster_data_enemy_update(object *op, object *enemy)
Definition: monster_data.c:89
void monster_data_dialogs_cleanup(object *op)
Definition: monster_data.c:349
#define PLAYER
Definition: define.h:122
long last_cleanup
Definition: monster_data.h:92
#define RV_MANHATTAN_DISTANCE
Definition: map.h:801
int16_t y
Definition: object.h:276
bool monster_data_dialogs_check(object *op, object *activator)
Definition: monster_data.c:290
void monster_data_init(object *op)
Definition: monster_data.c:48
const char * object_get_str(const object *op)
Definition: object.c:3151
#define MONSTER_DATA(_obj)
Definition: monster_data.h:98
struct mapdef * map
Definition: object.h:139
void monster_data_dialogs_purge(object *op)
Definition: monster_data.c:389
mapstruct * map
The map.
Definition: monster_data.h:81
bool monster_data_enemy_get_coords(object *op, mapstruct **map, uint16_t *x, uint16_t *y)
Definition: monster_data.c:120
size_t monster_data_dialogs_num(object *op)
Definition: monster_data.c:321
uint16_t y
Y.
Definition: monster_data.h:80
uint64_t num
Number of successful updates.
Definition: metaserver.c:43
tag_t count
ID of the object.
Definition: monster_data.h:63
int16_t x
Definition: object.h:273
uint16_t x
X.
Definition: monster_data.h:79
tag_t count
Definition: object.h:142
object * ob
Object that is talking to the monster.
Definition: monster_data.h:62
static void monster_data_dialogs_free(monster_data_dialog_t *dialog)
Definition: monster_data.c:147
uint8_t type
Definition: object.h:360
void monster_data_dialogs_remove(object *op, object *activator)
Definition: monster_data.c:254
static bool monster_data_dialogs_verify(monster_data_t *monster_data, monster_data_dialog_t *dialog)
Definition: monster_data.c:180
#define MONSTER_DATA_INTERFACE_DISTANCE
Definition: monster_data.h:53
void monster_guard_check_close(object *op, object *target)
#define OBJECT_VALID(_ob_, _count_)
Definition: object.h:548
void monster_data_deinit(object *op)
Definition: monster_data.c:62
monster_data_dialog_t * dialogs
Definition: monster_data.h:87
Definition: map.h:536
#define MONSTER_DATA_INTERFACE_TIMEOUT
Definition: monster_data.h:44