Crossfire Server, Trunk  R22047
power_crystal.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2007 Mark Wedel & Crossfire Development Team
5  Copyright (C) 1992 Frank Tore Johansen
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The authors can be reached via e-mail at crossfire-devel@real-time.com
22 */
27 #include <global.h>
28 #include <ob_methods.h>
29 #include <ob_types.h>
30 #include <sproto.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34 
35 static method_ret power_crystal_type_apply(ob_methods *context, object *op, object *applier, int aflags);
36 
37 #define LEVELS 7
38 
40 static const char* crystal_levels[LEVELS] = {
41  "empty.",
42  "almost empty.",
43  "partially filled.",
44  "half full.",
45  "well charged.",
46  "almost full.",
47  "fully charged.",
48 };
49 
56 static int crystal_level(const object *op, int sp) {
57  int i = (sp*10) / op->stats.maxsp;
58  if (sp == 0)
59  return 0;
60  else if (i == 0)
61  return 1;
62  else if (i < 3)
63  return 2;
64  else if (i < 6)
65  return 3;
66  else if (i < 9)
67  return 4;
68  else if (sp == op->stats.maxsp)
69  return 6;
70  else
71  return 5;
72 }
73 
81 static void add_capacity(const object *op, StringBuffer *buf, int previous_sp) {
82  int current = crystal_level(op, op->stats.sp);
83 
84  assert(current >= 0 && current < LEVELS);
85 
86  if (previous_sp != -1) {
87  int previous = crystal_level(op, previous_sp);
88  assert(previous >= 0 && previous < LEVELS);
89  if (current == previous) {
90  stringbuffer_append_string(buf, "still ");
91  } else {
92  stringbuffer_append_string(buf, "now ");
93  }
94  }
95 
97 }
98 
99 static void power_crystal_describe(const ob_methods *context, const object *op, const object *observer, int use_media_tags, char *buf, size_t size) {
101  char *final;
102 
103  buf[0] = '\0';
104  query_name(op, buf, size-1);
105  buf[size-1] = 0;
107 
108  /* Avoid division by zero... */
109  if (op->stats.maxsp == 0) {
110  stringbuffer_append_printf(sb, "(capacity %d).", op->stats.maxsp);
111  } else {
112  int i;
113  if (op->stats.maxsp > 1000) { /*higher capacity crystals*/
114  i = (op->stats.maxsp%1000)/100;
115  if (i)
116  stringbuffer_append_printf(sb, "(capacity %d.%dk). It is ", op->stats.maxsp/1000, i);
117  else
118  stringbuffer_append_printf(sb, "(capacity %dk). It is ", op->stats.maxsp/1000);
119  } else
120  stringbuffer_append_printf(sb, "(capacity %d). It is ", op->stats.maxsp);
121  add_capacity(op, sb, -1);
122  }
123 
124  final = stringbuffer_finish(sb);
125  strncat(buf, final, size);
126  free(final);
127 }
128 
135 }
136 
148 static method_ret power_crystal_type_apply(ob_methods *context, object *op, object *applier, int aflags) {
149  int available_power;
150  int power_space;
151  int power_grab;
153  char name[MAX_BUF], *message;
154 
155  available_power = applier->stats.sp-applier->stats.maxsp;
156  power_space = op->stats.maxsp-op->stats.sp;
157  power_grab = 0;
158  query_name(op, name, sizeof(name));
159  if (available_power >= 0 && power_space > 0) {
160  power_grab = MIN(power_space, 0.5*applier->stats.sp);
161  stringbuffer_append_string(sb, "You transfer power to the ");
162  }
163  if (available_power < 0 && op->stats.sp > 0) {
164  power_grab = -MIN(-available_power, op->stats.sp);
165  stringbuffer_append_string(sb, "You grab power from the ");
166  }
167 
168  if (power_grab == 0)
169  stringbuffer_append_string(sb, "Nothing happens.");
170  else {
171  int sp = op->stats.sp;
172  stringbuffer_append_printf(sb, "%s. It is ", name);
173  applier->stats.sp -= power_grab;
174  op->stats.sp += power_grab;
175  op->speed = (float)op->stats.sp/(float)op->stats.maxsp;
177  if (applier->type == PLAYER)
178  esrv_update_item(UPD_ANIMSPEED, applier, op);
179  add_capacity(op, sb, sp);
180  }
181 
182  message = stringbuffer_finish(sb);
183  if (applier->type == PLAYER)
185  free(message);
186 
187  return METHOD_OK;
188 }
#define LEVELS
Definition: power_crystal.c:37
static void power_crystal_describe(const ob_methods *context, const object *op, const object *observer, int use_media_tags, char *buf, size_t size)
Definition: power_crystal.c:99
StringBuffer * buf
Definition: readable.c:1591
void register_describe(int ob_type, describe_func method)
Definition: ob_types.c:80
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.c:340
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:308
#define MSG_TYPE_APPLY
Definition: newclient.h:384
#define MIN(x, y)
Definition: compat.h:17
char method_ret
Definition: ob_methods.h:14
static const char * crystal_levels[LEVELS]
Definition: power_crystal.c:40
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
#define METHOD_OK
Definition: ob_methods.h:15
static method_ret power_crystal_type_apply(ob_methods *context, object *op, object *applier, int aflags)
void register_apply(int ob_type, apply_func method)
Definition: ob_types.c:62
static void add_capacity(const object *op, StringBuffer *buf, int previous_sp)
Definition: power_crystal.c:81
#define MAX_BUF
Definition: define.h:35
#define UPD_ANIMSPEED
Definition: newclient.h:295
const char * name
Definition: treasure.h:83
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:598
void init_type_power_crystal(void)
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
#define NDI_UNIQUE
Definition: newclient.h:245
static int crystal_level(const object *op, int sp)
Definition: power_crystal.c:56
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:583
void object_update_speed(object *op)
Definition: object.c:1086
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76