Atrinik Server  4.0
light_refill.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 <object.h>
34 #include <player.h>
35 #include <object_methods.h>
36 
38 static int
39 apply_func (object *op, object *applier, int aflags)
40 {
41  HARD_ASSERT(op != NULL);
42  HARD_ASSERT(applier != NULL);
43 
44  if (applier->type != PLAYER) {
46  }
47 
48  object *light = find_marked_object(applier);
49  if (light == NULL) {
50  draw_info_format(COLOR_WHITE, applier,
51  "You need to mark a light source that you "
52  "want to refill.");
53  return OBJECT_METHOD_OK;
54  }
55 
56  char *light_name = object_get_name_s(light, applier);
57 
58  if (light->type != LIGHT_APPLY ||
59  light->race == NULL ||
60  light->race != op->race) {
61  char *name = object_get_name_s(op, applier);
62  draw_info_format(COLOR_WHITE, applier,
63  "You can't refill the %s with the %s.",
64  light_name,
65  name);
66  efree(name);
67  goto out;
68  }
69 
70  int capacity_missing = light->stats.maxhp - light->stats.food;
71  if (capacity_missing == 0) {
72  draw_info_format(COLOR_WHITE, applier,
73  "The %s is full and can't be refilled.",
74  light_name);
75  goto out;
76  }
77 
78  int capacity_received = MIN(capacity_missing, op->stats.food);
79  light->stats.food += capacity_received;
80 
81  int percent = (double) light->stats.food / light->stats.maxhp * 100.0;
82  draw_info_format(COLOR_WHITE, applier,
83  "You refill the %s and it's now at %d%% of its capacity.",
84  light_name,
85  percent);
86 
87  /* Check whether the refilling object was all used up. If so,
88  * decrease it, otherwise split it from the stack (if any) and
89  * decrease the amount of units it gives back. */
90  if (op->stats.food - capacity_received <= 0) {
91  decrease_ob(op);
92  } else {
93  op = object_stack_get_reinsert(op, 1);
94  op->stats.food -= capacity_received;
95  }
96 
97 out:
98  efree(light_name);
99  return OBJECT_METHOD_OK;
100 }
101 
106 {
107  OBJECT_METHODS(LIGHT_REFILL)->apply_func = apply_func;
108 }
const char * race
Definition: object.h:174
OBJECT_TYPE_INIT_DEFINE(light_refill)
Definition: light_refill.c:105
static int apply_func(object *op, object *applier, int aflags)
Definition: light_refill.c:39
#define PLAYER
Definition: define.h:122
char * object_get_name_s(const object *op, const object *caller)
Definition: item.c:398
#define decrease_ob(xyz)
Definition: object.h:624
int32_t maxhp
Definition: living.h:75
#define OBJECT_METHOD_UNHANDLED
#define LIGHT_APPLY
Definition: define.h:336
living stats
Definition: object.h:481
uint8_t type
Definition: object.h:360
#define OBJECT_METHODS(type)
#define OBJECT_METHOD_OK
#define LIGHT_REFILL
Definition: define.h:361
object * object_stack_get_reinsert(object *op, uint32_t nrof)
Definition: object.c:2046
int16_t food
Definition: living.h:84
object * find_marked_object(object *op)
Definition: player.c:1393