Atrinik Server  4.0
apply.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 <player.h>
34 #include <object_methods.h>
35 
52 int manual_apply(object *op, object *tmp, int aflag)
53 {
54  tmp = HEAD(tmp);
55 
56  if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(tmp, FLAG_APPLIED)) {
57  if (op->type == PLAYER) {
58  draw_info(COLOR_WHITE, op, "You should pay for it first.");
59  return OBJECT_METHOD_OK;
60  } else {
61  /* Monsters just skip unpaid items */
63  }
64  }
65 
66  /* Monsters must not apply random chests. */
67  if (op->type != PLAYER && tmp->type == TREASURE) {
69  }
70 
71  /* Trigger the APPLY event */
72  if (!(aflag & APPLY_NO_EVENT) && trigger_event(EVENT_APPLY, op, tmp, NULL, NULL, aflag, 0, 0, 0)) {
73  return OBJECT_METHOD_OK;
74  }
75 
76  /* Trigger the map-wide apply event. */
77  if (!(aflag & APPLY_NO_EVENT) && op->map && op->map->events) {
78  int retval = trigger_map_event(MEVENT_APPLY, op->map, op, tmp, NULL, NULL, aflag);
79 
80  if (retval) {
81  return retval - 1;
82  }
83  }
84 
85  aflag &= ~APPLY_NO_EVENT;
86 
87  if (tmp->item_level) {
88  int tmp_lev;
89 
90  if (tmp->item_skill && op->type == PLAYER) {
91  tmp_lev = CONTR(op)->skill_ptr[tmp->item_skill - 1]->level;
92  } else {
93  tmp_lev = op->level;
94  }
95 
96  if (tmp->item_level > tmp_lev) {
97  draw_info(COLOR_WHITE, op, "The item's level is too high to apply.");
98  return OBJECT_METHOD_OK;
99  }
100  }
101 
102  return object_apply(tmp, op, aflag);
103 }
104 
123 int player_apply(object *pl, object *op, int aflag, int quiet)
124 {
125  int tmp;
126 
127  if (op->env == NULL && QUERY_FLAG(pl, FLAG_FLYING)) {
128  /* Player is flying and applying object not in inventory */
129  if (!QUERY_FLAG(op, FLAG_FLYING) && !QUERY_FLAG(op, FLAG_FLY_ON)) {
130  draw_info(COLOR_WHITE, pl, "But you are floating high above the ground!");
131  return 0;
132  }
133  }
134 
135  tmp = manual_apply(pl, op, aflag);
136 
137  if (!quiet) {
138  if (tmp == OBJECT_METHOD_UNHANDLED) {
139  char *name = object_get_name_s(op, NULL);
140  draw_info_format(COLOR_WHITE, pl, "I don't know how to apply the "
141  "%s.", name);
142  efree(name);
143  } else if (tmp == OBJECT_METHOD_ERROR) {
144  if (op->env != pl) {
145  draw_info_format(COLOR_WHITE, pl, "You must get it first!\n");
146  }
147  }
148  }
149 
150  return tmp;
151 }
152 
161 void player_apply_below(object *pl)
162 {
163  object *tmp, *next;
164  int floors;
165 
166  if (pl->type != PLAYER) {
167  return;
168  }
169 
170  tmp = pl->below;
171 
172  /* This is perhaps more complicated. However, I want to make sure that
173  * we don't use a corrupt pointer for the next object, so we get the
174  * next object in the stack before applying. This is can only be a
175  * problem if player_apply() has a bug in that it uses the object but does
176  * not return a proper value. */
177  for (floors = 0; tmp != NULL; tmp = next) {
178  next = tmp->below;
179 
180  if (QUERY_FLAG(tmp, FLAG_IS_FLOOR)) {
181  floors++;
182  } else if (floors > 0) {
183  /* Process only floor objects after first floor object */
184  return;
185  }
186 
187  if (!IS_INVISIBLE(tmp, pl) || QUERY_FLAG(tmp, FLAG_WALK_ON) || QUERY_FLAG(tmp, FLAG_FLY_ON)) {
188  if (player_apply(pl, tmp, 0, 1) == 1) {
189  return;
190  }
191  }
192 
193  /* Process at most two floor objects */
194  if (floors >= 2) {
195  return;
196  }
197  }
198 }
uint8_t item_level
Definition: object.h:375
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
uint8_t item_skill
Definition: object.h:378
#define OBJECT_METHOD_ERROR
#define FLAG_FLY_ON
Definition: define.h:968
#define TREASURE
Definition: define.h:134
void player_apply_below(object *pl)
Definition: apply.c:161
#define PLAYER
Definition: define.h:122
#define FLAG_IS_FLOOR
Definition: define.h:1118
#define QUERY_FLAG(xyz, p)
Definition: define.h:761
#define EVENT_APPLY
Definition: plugin.h:75
int manual_apply(object *op, object *tmp, int aflag)
Definition: apply.c:52
int object_apply(object *op, object *applier, int aflags)
char * object_get_name_s(const object *op, const object *caller)
Definition: item.c:398
struct sound_ambient_match * next
Next match rule in a linked list.
Definition: sound_ambient.c:39
struct mapdef * map
Definition: object.h:139
#define FLAG_UNPAID
Definition: define.h:1251
struct obj * env
Definition: object.h:130
struct obj * below
Definition: object.h:114
Do not trigger an event.
Definition: define.h:1496
#define IS_INVISIBLE(__ob_, __player_)
Definition: define.h:1356
#define FLAG_FLYING
Definition: define.h:918
int trigger_map_event(int event_id, mapstruct *m, object *activator, object *other, object *other2, const char *text, int parm)
Definition: plugins.c:416
#define MEVENT_APPLY
Definition: plugin.h:135
#define HEAD(op)
Definition: object.h:657
#define OBJECT_METHOD_UNHANDLED
struct map_event * events
Definition: map.h:583
#define FLAG_APPLIED
Definition: define.h:1182
uint8_t type
Definition: object.h:360
#define OBJECT_METHOD_OK
int player_apply(object *pl, object *op, int aflag, int quiet)
Definition: apply.c:123
#define FLAG_WALK_ON
Definition: define.h:904
int8_t level
Definition: object.h:347