Crossfire Server, Trunk  R20513
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, 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;
106 
107  /* Avoid division by zero... */
108  if (op->stats.maxsp == 0) {
109  stringbuffer_append_printf(sb, "(capacity %d).", op->stats.maxsp);
110  } else {
111  int i;
112  if (op->stats.maxsp > 1000) { /*higher capacity crystals*/
113  i = (op->stats.maxsp%1000)/100;
114  if (i)
115  stringbuffer_append_printf(sb, "(capacity %d.%dk). It is ", op->stats.maxsp/1000, i);
116  else
117  stringbuffer_append_printf(sb, "(capacity %dk). It is ", op->stats.maxsp/1000);
118  } else
119  stringbuffer_append_printf(sb, "(capacity %d). It is ", op->stats.maxsp);
120  add_capacity(op, sb, -1);
121  }
122 
123  final = stringbuffer_finish(sb);
124  strncat(buf, final, size);
125  free(final);
126 }
127 
134 }
135 
147 static method_ret power_crystal_type_apply(ob_methods *context, object *op, object *applier, int aflags) {
148  int available_power;
149  int power_space;
150  int power_grab;
152  char name[MAX_BUF], *message;
153 
154  available_power = applier->stats.sp-applier->stats.maxsp;
155  power_space = op->stats.maxsp-op->stats.sp;
156  power_grab = 0;
157  query_name(op, name, sizeof(name));
158  if (available_power >= 0 && power_space > 0) {
159  power_grab = MIN(power_space, 0.5*applier->stats.sp);
160  stringbuffer_append_string(sb, "You transfer power to the ");
161  }
162  if (available_power < 0 && op->stats.sp > 0) {
163  power_grab = -MIN(-available_power, op->stats.sp);
164  stringbuffer_append_string(sb, "You grab power from the ");
165  }
166 
167  if (power_grab == 0)
168  stringbuffer_append_string(sb, "Nothing happens.");
169  else {
170  int sp = op->stats.sp;
171  stringbuffer_append_printf(sb, "%s. It is ", name);
172  applier->stats.sp -= power_grab;
173  op->stats.sp += power_grab;
174  op->speed = (float)op->stats.sp/(float)op->stats.maxsp;
176  if (applier->type == PLAYER)
177  esrv_update_item(UPD_ANIMSPEED, applier, op);
178  add_capacity(op, sb, sp);
179  }
180 
181  message = stringbuffer_finish(sb);
182  if (applier->type == PLAYER)
184  free(message);
185 
186  return METHOD_OK;
187 }
#define LEVELS
Definition: power_crystal.c:37
Typedefs for ob_methods.
Definition: ob_methods.h:45
void register_describe(int ob_type, describe_func method)
Registers the describe method for the given type.
Definition: ob_types.c:80
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.c:57
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
Definition: main.c:342
See Power Crystal.
Definition: object.h:242
int16_t sp
Spell points.
Definition: living.h:41
Global type definitions and header inclusions.
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:384
int16_t maxsp
Max spell points.
Definition: living.h:42
#define MIN(x, y)
Definition: compat.h:17
char method_ret
Define some standard return values for callbacks which don&#39;t need to return any other results...
Definition: ob_methods.h:14
static const char * crystal_levels[LEVELS]
Existing levels, dot-terminated.
Definition: power_crystal.c:40
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Append a string to a string buffer instance.
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)
This function handles the application of power crystals.
void register_apply(int ob_type, apply_func method)
Registers the apply method for the given type.
Definition: ob_types.c:62
float speed
The overall speed of this object.
Definition: object.h:328
static void add_capacity(const object *op, StringBuffer *buf, int previous_sp)
Add the capacity of the crystal to the buffer.
Definition: power_crystal.c:81
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
#define UPD_ANIMSPEED
Definition: newclient.h:295
static void power_crystal_describe(const ob_methods *context, const object *op, const object *observer, char *buf, size_t size)
Definition: power_crystal.c:99
Object type variables.
See Player.
Definition: object.h:107
const char * name
Usually monster-name/combination.
Definition: treasure.h:83
living stats
Str, Con, Dex, etc.
Definition: object.h:368
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
#define MSG_TYPE_APPLY_SUCCESS
Was able to apply object.
Definition: newclient.h:598
void init_type_power_crystal(void)
Initializer for the POWER_CRYSTAL object type.
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Append a formatted string to a string buffer instance.
Definition: stringbuffer.c:104
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
static int crystal_level(const object *op, int sp)
Return the level, [0..LEVELS[, of charge of the item.
Definition: power_crystal.c:56
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.c:25
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.c:625
Object type functions and variables.
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.c:1129
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.c:76