Crossfire Server, Trunk  R20513
converter.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
18 #include "global.h"
19 
20 #include <string.h>
21 
22 #include "ob_methods.h"
23 #include "ob_types.h"
24 #include "shop.h"
25 #include "sounds.h"
26 #include "sproto.h"
27 
28 /*
29  * convert_item() returns 1 if anything was converted, 0 if the item was not
30  * what the converter wants, -1 if the converter is broken.
31  */
32 #define CONV_FROM(xyz) xyz->slaying
33 #define CONV_TO(xyz) xyz->other_arch
34 #define CONV_NR(xyz) (unsigned char)xyz->stats.sp
35 #define CONV_NEED(xyz) (unsigned long)xyz->stats.food
36 
37 static int convert_item(object *item, object *converter);
38 
39 static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator);
40 
44 void init_type_converter(void) {
46 }
47 
57 static int convert_item(object *item, object *converter) {
58  int nr = 0;
59  uint32_t price_in;
60 
61  /* We make some assumptions - we assume if it takes money as it type,
62  * it wants some amount. We don't make change (ie, if something costs
63  * 3 gp and player drops a platinum, tough luck)
64  */
65  if (!strcmp(CONV_FROM(converter), "money")) {
66  int cost;
67 
68  if (item->type != MONEY)
69  return 0;
70 
71  nr = (item->nrof*item->value)/CONV_NEED(converter);
72  if (!nr)
73  return 0;
74 
75  cost = nr*CONV_NEED(converter)/item->value;
76  /* take into account rounding errors */
77  if (nr*CONV_NEED(converter)%item->value)
78  cost++;
79  object_decrease_nrof(item, cost);
80 
81  price_in = cost*item->value;
82  } else {
83  if (item->type == PLAYER
84  || CONV_FROM(converter) != item->arch->name
85  || (CONV_NEED(converter) && CONV_NEED(converter) > item->nrof))
86  return 0;
87 
88  /* silently burn unpaid items (only if they match what we want) */
89  if (QUERY_FLAG(item, FLAG_UNPAID)) {
90  object_remove(item);
92  item = create_archetype("burnout");
93  if (item != NULL)
94  object_insert_in_map_at(item, converter->map, converter, 0, converter->x, converter->y);
95  return 1;
96  }
97 
98  if (CONV_NEED(converter)) {
99  nr = item->nrof/CONV_NEED(converter);
100  object_decrease_nrof(item, nr*CONV_NEED(converter));
101  price_in = nr*CONV_NEED(converter)*item->value;
102  } else {
103  price_in = item->value;
104  object_remove(item);
106  }
107  }
108 
109  if (converter->inv != NULL) {
110  int i;
111  object *ob_to_copy;
112 
113  /* select random object from inventory to copy */
114  ob_to_copy = converter->inv;
115  i = 1;
116  FOR_BELOW_PREPARE(converter->inv, ob) {
117  if (rndm(0, i) == 0)
118  ob_to_copy = ob;
119  i++;
120  } FOR_BELOW_FINISH();
121  item = object_create_clone(ob_to_copy);
124  } else {
125  if (converter->other_arch == NULL) {
126  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);
127  return -1;
128  }
129  item = object_create_arch(converter->other_arch);
130  fix_generated_item(item, converter, 0, 0, GT_MINIMAL);
131  }
132 
133  if (CONV_NR(converter))
134  item->nrof = CONV_NR(converter);
135  if (nr)
136  item->nrof *= nr;
137  if (item->type != MONEY && shop_contains(converter))
138  SET_FLAG(item, FLAG_UNPAID);
139  else if (price_in < item->nrof*item->value && settings.allow_broken_converters == FALSE) {
140  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);
142  return -1;
143  }
144  object_insert_in_map_at(item, converter->map, converter, 0, converter->x, converter->y);
145  return 1;
146 }
147 
156 static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) {
157  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
158  return METHOD_OK;
159  if (convert_item(victim, trap) < 0) {
160  object *op;
161  char name[MAX_BUF];
162 
163  query_name(trap, name, MAX_BUF);
165  "The %s seems to be broken!", name);
166 
167  op = create_archetype("burnout");
168  if (op != NULL)
169  object_insert_in_map_at(op, trap->map, trap, 0, trap->x, trap->y);
170  }
171  common_post_ob_move_on(trap, victim, originator);
172  return METHOD_OK;
173 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
Sound-related defines.
#define FLAG_UNPAID
Object hasn&#39;t been paid for yet.
Definition: define.h:236
bool shop_contains(object *ob)
Check if an object is in a shop.
Definition: shop.c:1239
#define SET_FLAG(xyz, p)
Definition: define.h:223
Typedefs for ob_methods.
Definition: ob_methods.h:45
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:51
#define MSG_TYPE_APPLY_FAILURE
Apply OK, but no/bad result.
Definition: newclient.h:599
#define METHOD_ERROR
Definition: ob_methods.h:17
See Money.
Definition: object.h:137
int allow_broken_converters
If set, converters will work even if price of generated item is higher than the price of converted it...
Definition: global.h:314
#define FALSE
Definition: compat.h:11
Global type definitions and header inclusions.
struct archt * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:413
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:384
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
int rndm(int min, int max)
Returns a number between min and max.
Definition: utils.c:161
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
int16_t y
Position in the map for this object.
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.c:1921
void init_type_converter(void)
Initializer for the CONVERTER object type.
Definition: converter.c:44
object * create_archetype(const char *name)
Finds which archetype matches the given name, and returns a new object containing a copy of the arche...
Definition: arch.c:620
void register_move_on(int ob_type, move_on_func method)
Registers the move_on method for the given type.
Definition: ob_types.c:89
static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator)
Move on this Converter object.
Definition: converter.c:156
#define METHOD_OK
Definition: ob_methods.h:15
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
const char * name
The name of the object, obviously...
Definition: object.h:311
static int convert_item(object *item, object *converter)
Transforms an item into another item.
Definition: converter.c:57
#define FLAG_IS_A_TEMPLATE
Object has no ingame life until instantiated.
Definition: define.h:375
object * object_create_clone(object *asrc)
Create clone from object to another.
Definition: object.c:3832
uint32_t nrof
How many of the objects.
Definition: object.h:333
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
void fix_generated_item(object *op, object *creator, int difficulty, int max_magic, int flags)
fix_generated_item(): This is called after an item is generated, in order to set it up right...
Definition: treasure.c:1110
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
object * object_create_arch(archetype *at)
Create a full object using the given archetype.
Definition: arch.c:736
See Converter.
Definition: object.h:216
int16_t x
Definition: object.h:326
Object type variables.
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:87
See Player.
Definition: object.h:107
unsigned int uint32_t
Definition: win32.h:162
const char * name
Usually monster-name/combination.
Definition: treasure.h:83
object * object_decrease_nrof(object *op, uint32_t i)
Decreases a specified number from the amount of an object.
Definition: object.c:2505
struct archt * arch
Pointer to archetype.
Definition: object.h:412
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
struct Settings settings
Server settings.
Definition: init.c:40
void object_unset_flag_inv(object *op, int flag)
Desactivate recursively a flag on an object inventory.
Definition: object.c:3101
#define CONV_NEED(xyz)
Definition: converter.c:35
#define CONV_NR(xyz)
Definition: converter.c:34
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
#define NDI_UNIQUE
Print immediately, don&#39;t buffer.
Definition: newclient.h:245
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
Do minimal adjustments, don&#39;t make artifacts, and so on.
Definition: treasure.h:36
#define CONV_FROM(xyz)
Definition: converter.c:32
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.c:625
#define FOR_BELOW_PREPARE(op_, it_)
Constructs a loop iterating over all objects below an object.
Definition: define.h:739
Object type functions and variables.
int32_t value
How much money it is worth (or contains)
Definition: object.h:350
const char * name
More definite name, like "generate_kobold".
Definition: object.h:466
#define FOR_BELOW_FINISH()
Finishes FOR_BELOW_PREPARE().
Definition: define.h:746
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654