Crossfire Server, Branches 1.12  R18729
converter.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 */
23 
27 #include <global.h>
28 #include <ob_methods.h>
29 #include <ob_types.h>
30 #include <sounds.h>
31 #include <sproto.h>
32 
33 /*
34  * convert_item() returns 1 if anything was converted, 0 if the item was not
35  * what the converter wants, -1 if the converter is broken.
36  */
37 #define CONV_FROM(xyz) xyz->slaying
38 #define CONV_TO(xyz) xyz->other_arch
39 #define CONV_NR(xyz) (unsigned char)xyz->stats.sp
40 #define CONV_NEED(xyz) (unsigned long)xyz->stats.food
41 
42 static int convert_item(object *item, object *converter);
43 
44 static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator);
45 
49 void init_type_converter(void) {
51 }
52 
62 static int convert_item(object *item, object *converter) {
63  int nr = 0;
64  uint32 price_in;
65 
66  /* We make some assumptions - we assume if it takes money as it type,
67  * it wants some amount. We don't make change (ie, if something costs
68  * 3 gp and player drops a platinum, tough luck)
69  */
70  if (!strcmp(CONV_FROM(converter), "money")) {
71  int cost;
72 
73  if (item->type != MONEY)
74  return 0;
75 
76  nr = (item->nrof*item->value)/CONV_NEED(converter);
77  if (!nr)
78  return 0;
79 
80  cost = nr*CONV_NEED(converter)/item->value;
81  /* take into account rounding errors */
82  if (nr*CONV_NEED(converter)%item->value)
83  cost++;
84  decrease_ob_nr(item, cost);
85 
86  price_in = cost*item->value;
87  } else {
88  if (item->type == PLAYER
89  || CONV_FROM(converter) != item->arch->name
90  || (CONV_NEED(converter) && CONV_NEED(converter) > item->nrof))
91  return 0;
92 
93  /* silently burn unpaid items (only if they match what we want) */
94  if (QUERY_FLAG(item, FLAG_UNPAID)) {
95  remove_ob(item);
96  free_object(item);
97  item = create_archetype("burnout");
98  if (item != NULL)
99  insert_ob_in_map_at(item, converter->map, converter, 0, converter->x, converter->y);
100  return 1;
101  }
102 
103  if (CONV_NEED(converter)) {
104  nr = item->nrof/CONV_NEED(converter);
105  decrease_ob_nr(item, nr*CONV_NEED(converter));
106  price_in = nr*CONV_NEED(converter)*item->value;
107  } else {
108  price_in = item->value;
109  remove_ob(item);
110  free_object(item);
111  }
112  }
113 
114  if (converter->inv != NULL) {
115  object *ob;
116  int i;
117  object *ob_to_copy;
118 
119  /* select random object from inventory to copy */
120  ob_to_copy = converter->inv;
121  for (ob = converter->inv->below, i = 1; ob != NULL; ob = ob->below, i++) {
122  if (rndm(0, i) == 0)
123  ob_to_copy = ob;
124  }
125  item = object_create_clone(ob_to_copy);
128  } else {
129  if (converter->other_arch == NULL) {
130  LOG(llevError, "move_creator: Converter doesn't have other arch set: %s (%s, %d, %d)\n", converter->name ? converter->name : "(null)", converter->map->path, converter->x, converter->y);
131  return -1;
132  }
133  item = object_create_arch(converter->other_arch);
134  fix_generated_item(item, converter, 0, 0, GT_MINIMAL);
135  }
136 
137  if (CONV_NR(converter))
138  item->nrof = CONV_NR(converter);
139  if (nr)
140  item->nrof *= nr;
141  if (is_in_shop(converter))
142  SET_FLAG(item, FLAG_UNPAID);
143  else if (price_in < item->nrof*item->value && settings.allow_broken_converters == FALSE) {
144  LOG(llevError, "Broken converter %s at %s (%d, %d) in value %d, out value %d for %s\n", converter->name, converter->map->path, converter->x, converter->y, price_in, item->nrof*item->value, item->name);
145  free_object(item);
146  return -1;
147  }
148  insert_ob_in_map_at(item, converter->map, converter, 0, converter->x, converter->y);
149  return 1;
150 }
151 
160 static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) {
161  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
162  return METHOD_OK;
163  if (convert_item(victim, trap) < 0) {
164  object *op;
165  char name[MAX_BUF];
166 
167  query_name(trap, name, MAX_BUF);
169  "The %s seems to be broken!", "The %s seems to be broken!",
170  name);
171 
172  op = create_archetype("burnout");
173  if (op != NULL) {
174  op->x = trap->x;
175  op->y = trap->y;
176  insert_ob_in_map(op, trap->map, trap, 0);
177  }
178  }
179  common_post_ob_move_on(trap, victim, originator);
180  return METHOD_OK;
181 }
char path[HUGE_BUF]
Definition: map.h:384
#define FLAG_UNPAID
Definition: define.h:532
int is_in_shop(object *ob)
Definition: shop.c:1414
#define FALSE
Definition: exp.c:42
#define SET_FLAG(xyz, p)
Definition: define.h:510
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:51
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:519
#define METHOD_ERROR
Definition: ob_methods.h:44
#define MONEY
Definition: define.h:148
void unflag_inv(object *op, int flag)
Definition: object.c:2894
object * insert_ob_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1761
int allow_broken_converters
Definition: global.h:405
sint16 x
Definition: object.h:179
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
struct archt * other_arch
Definition: object.h:264
#define PLAYER
Definition: define.h:113
char method_ret
Definition: ob_methods.h:41
int rndm(int min, int max)
Definition: utils.c:174
void remove_ob(object *op)
Definition: object.c:1515
void init_type_converter(void)
Definition: converter.c:49
object * create_archetype(const char *name)
Definition: arch.c:625
void register_move_on(int ob_type, move_on_func method)
Definition: ob_types.c:106
static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator)
Definition: converter.c:160
#define METHOD_OK
Definition: ob_methods.h:42
struct mapdef * map
Definition: object.h:155
const char * name
Definition: object.h:167
static int convert_item(object *item, object *converter)
Definition: converter.c:62
struct obj * below
Definition: object.h:145
#define FLAG_IS_A_TEMPLATE
Definition: define.h:671
object * object_create_clone(object *asrc)
Definition: object.c:3608
uint32 nrof
Definition: object.h:184
sint16 y
Definition: object.h:179
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
#define MSG_TYPE_APPLY
Definition: newclient.h:330
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
Definition: treasure.c:1070
#define MAX_BUF
Definition: define.h:81
object * object_create_arch(archetype *at)
Definition: arch.c:741
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:88
struct archt * arch
Definition: object.h:263
object * decrease_ob_nr(object *op, uint32 i)
Definition: object.c:2345
struct Settings settings
Definition: init.c:48
#define CONV_NEED(xyz)
Definition: converter.c:40
#define CONV_NR(xyz)
Definition: converter.c:39
struct obj * inv
Definition: object.h:148
#define NDI_UNIQUE
Definition: newclient.h:219
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
unsigned int uint32
Definition: global.h:58
#define CONV_FROM(xyz)
Definition: converter.c:37
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:628
void free_object(object *ob)
Definition: object.c:1238
sint32 value
Definition: object.h:201
#define CONVERTER
Definition: define.h:285
const char * name
Definition: object.h:322
uint8 type
Definition: object.h:189