Atrinik Server  4.0
monster_guard.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 #ifndef __CPROTO__
33 
34 #include <global.h>
35 #include <monster_guard.h>
36 #include <faction.h>
37 #include <plugin.h>
38 #include <monster_data.h>
39 #include <toolkit/packet.h>
40 #include <player.h>
41 #include <object.h>
42 #include <object_methods.h>
43 
52 void monster_guard_activate_gate(object *op, int state)
53 {
54  HARD_ASSERT(op != NULL);
55 
56  SOFT_ASSERT(op->type == MONSTER, "Object is not a monster: %s",
57  object_get_str(op));
58  SOFT_ASSERT(op->map != NULL, "Object has no map: %s", object_get_str(op));
59 
60  if (!(op->behavior & BEHAVIOR_GUARD)) {
61  return;
62  }
63 
64  FOR_MAP_PREPARE(op->map, op->x, op->y, tmp) {
65  if (tmp->type != TYPE_HANDLE || tmp->slaying == NULL) {
66  continue;
67  }
68 
69  if (tmp->state == state) {
70  continue;
71  }
72 
73  object_apply(tmp, op, 0);
74 
75  char buf[HUGE_BUF];
76 
77  if (state == 1) {
78  snprintf(VS(buf), "%s shouts:\nThe gate, get the gate! Let no one "
79  "leave or enter until this matter is resolved!", op->name);
80  } else {
81  snprintf(VS(buf), "%s shouts:\nAll clear, open the gate!",
82  op->name);
83  }
84 
85  draw_info_map(CHAT_TYPE_GAME, NULL, COLOR_NAVY, op->map, op->x, op->y,
86  MAP_INFO_NORMAL, NULL, NULL, buf);
87 
88  break;
89  } FOR_MAP_FINISH();
90 }
91 
102 static bool monster_guard_get_bounty(object *op, player *pl, double *bounty)
103 {
104  HARD_ASSERT(op != NULL);
105  HARD_ASSERT(pl != NULL);
106  HARD_ASSERT(bounty != NULL);
107 
108  shstr *faction_name = object_get_value(op, "faction");
109 
110  if (faction_name == NULL) {
111  LOG(ERROR, "Monster has no faction: %s", object_get_str(op));
112  return false;
113  }
114 
115  faction_t faction = faction_find(faction_name);
116 
117  if (faction == NULL) {
118  LOG(ERROR, "Monster has invalid faction '%s': %s", faction_name,
119  object_get_str(op));
120  return false;
121  }
122 
123  *bounty = faction_get_bounty(faction, pl);
124 
125  /* No bounty, nothing to do. */
126  if (*bounty <= 0.0) {
127  return false;
128  }
129 
130  return true;
131 }
132 
146 bool monster_guard_check(object *op, object *target, const char *msg,
147  uint32_t distance)
148 {
149  HARD_ASSERT(op != NULL);
150  HARD_ASSERT(target != NULL);
151 
152  SOFT_ASSERT_RC(op->type == MONSTER, false, "Object is not a monster: %s",
153  object_get_str(op));
154  SOFT_ASSERT_RC(op->map != NULL, false, "Object has no map: %s",
155  object_get_str(op));
156 
157  if (!(op->behavior & BEHAVIOR_GUARD)) {
158  return false;
159  }
160 
161  /* Only care about players breaking the law. */
162  if (target->type != PLAYER) {
163  return false;
164  }
165 
166  /* Target is too far away for an interface, ignore. */
167  if (distance > MONSTER_DATA_INTERFACE_DISTANCE) {
168  return false;
169  }
170 
171  player *pl = CONTR(target);
172 
173  /* Player is talking to someone, don't disturb them... yet. */
174  if (OBJECT_VALID(pl->talking_to, pl->talking_to_count) &&
175  pl->talking_to != op) {
176  return false;
177  }
178 
179  /* Already talking to the guard, skip the beginning of the arrest. */
180  if (msg == NULL && pl->talking_to == op) {
181  return false;
182  }
183 
184  double bounty;
185  if (!monster_guard_get_bounty(op, pl, &bounty)) {
186  return false;
187  }
188 
189  pl->run_on = false;
190  pl->combat = false;
191  pl->combat_force = false;
192 
193  player_path_clear(pl);
194  pl->cs->packet_recv_cmd->len = 0;
195  player_set_talking_to(pl, op);
196 
197  int ret = trigger_event(EVENT_AI,
198  target,
199  op,
200  NULL,
201  msg != NULL ? msg : "hello",
203  0,
204  0,
205  0);
206  uint32_t secs = INTERFACE_TIMEOUT(ret);
207  monster_data_dialogs_add(op, target, MIN(secs, INTERFACE_TIMEOUT_MAX));
208 
209  return true;
210 }
211 
219 void monster_guard_check_close(object *op, object *target)
220 {
221  HARD_ASSERT(op != NULL);
222  HARD_ASSERT(target != NULL);
223 
224  SOFT_ASSERT(op->type == MONSTER, "Object is not a monster: %s",
225  object_get_str(op));
226  SOFT_ASSERT(op->map != NULL, "Object has no map: %s", object_get_str(op));
227 
228  if (!(op->behavior & BEHAVIOR_GUARD)) {
229  return;
230  }
231 
232  /* Already have an enemy. */
233  if (OBJECT_VALID(op->enemy, op->enemy_count)) {
234  return;
235  }
236 
237  /* Only care about players breaking the law. */
238  if (target->type != PLAYER) {
239  return;
240  }
241 
242  player *pl = CONTR(target);
243  double bounty;
244  if (!monster_guard_get_bounty(op, pl, &bounty)) {
245  return;
246  }
247 
248  set_npc_enemy(op, target, NULL);
249  draw_info_format(COLOR_NAVY, target, "%s says:\nThen pay with your blood!",
250  op->name);
251 }
252 
253 #endif
#define MONSTER
Definition: define.h:353
#define EVENT_AI_GUARD_STOP
Definition: plugin.h:111
tag_t enemy_count
Definition: object.h:216
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
static bool monster_guard_get_bounty(object *op, player *pl, double *bounty)
#define INTERFACE_TIMEOUT(ret)
Definition: define.h:1578
shstr * object_get_value(const object *op, const char *const key)
Definition: object.c:2515
unsigned int run_on
Definition: player.h:289
#define INTERFACE_TIMEOUT_MAX
Definition: define.h:1574
#define TYPE_HANDLE
Definition: define.h:401
#define PLAYER
Definition: define.h:122
double faction_get_bounty(faction_t faction, player *pl)
Definition: faction.c:734
struct obj * enemy
Definition: object.h:196
void player_set_talking_to(player *pl, object *npc)
Definition: player.c:2647
int object_apply(object *op, object *applier, int aflags)
#define EVENT_AI
Definition: plugin.h:101
int16_t y
Definition: object.h:276
#define BEHAVIOR_GUARD
Definition: object.h:620
void set_npc_enemy(object *npc, object *enemy, rv_vector *rv)
Definition: monster.c:85
const char * object_get_str(const object *op)
Definition: object.c:3151
#define MAP_INFO_NORMAL
Definition: global.h:83
struct mapdef * map
Definition: object.h:139
const char * name
Definition: object.h:168
faction_t faction_find(shstr *name)
Definition: faction.c:382
void monster_data_dialogs_add(object *op, object *activator, uint32_t secs)
Definition: monster_data.c:214
void monster_guard_activate_gate(object *op, int state)
Definition: monster_guard.c:52
bool monster_guard_check(object *op, object *target, const char *msg, uint32_t distance)
#define FOR_MAP_FINISH()
Definition: define.h:1759
uint8_t combat
Definition: player.h:543
tag_t talking_to_count
ID of ::talking_to.
Definition: player.h:572
void player_path_clear(player *pl)
Definition: player.c:1086
int16_t x
Definition: object.h:273
uint8_t combat_force
Definition: player.h:549
void draw_info_map(uint8_t type, const char *name, const char *color, mapstruct *map, int x, int y, int dist, object *op, object *op2, const char *buf)
Definition: info.c:195
socket_struct * cs
Definition: player.h:148
uint8_t behavior
Definition: object.h:399
uint8_t type
Definition: object.h:360
void monster_guard_check_close(object *op, object *target)
#define MONSTER_DATA_INTERFACE_DISTANCE
Definition: monster_data.h:53
#define OBJECT_VALID(_ob_, _count_)
Definition: object.h:548
object * talking_to
Object the player is talking to.
Definition: player.h:571
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:1752