00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00027 #include <global.h>
00028 #include <ob_methods.h>
00029 #include <ob_types.h>
00030 #include <sounds.h>
00031 #include <sproto.h>
00032
00033
00034
00035
00036
00037 #define CONV_FROM(xyz) xyz->slaying
00038 #define CONV_TO(xyz) xyz->other_arch
00039 #define CONV_NR(xyz) (unsigned char)xyz->stats.sp
00040 #define CONV_NEED(xyz) (unsigned long)xyz->stats.food
00041
00042 static int convert_item(object *item, object *converter);
00043
00044 static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator);
00045
00049 void init_type_converter(void) {
00050 register_move_on(CONVERTER, converter_type_move_on);
00051 }
00052
00062 static int convert_item(object *item, object *converter) {
00063 int nr = 0;
00064 uint32 price_in;
00065
00066
00067
00068
00069
00070 if (!strcmp(CONV_FROM(converter), "money")) {
00071 int cost;
00072
00073 if (item->type != MONEY)
00074 return 0;
00075
00076 nr = (item->nrof*item->value)/CONV_NEED(converter);
00077 if (!nr)
00078 return 0;
00079
00080 cost = nr*CONV_NEED(converter)/item->value;
00081
00082 if (nr*CONV_NEED(converter)%item->value)
00083 cost++;
00084 decrease_ob_nr(item, cost);
00085
00086 price_in = cost*item->value;
00087 } else {
00088 if (item->type == PLAYER
00089 || CONV_FROM(converter) != item->arch->name
00090 || (CONV_NEED(converter) && CONV_NEED(converter) > item->nrof))
00091 return 0;
00092
00093
00094 if (QUERY_FLAG(item, FLAG_UNPAID)) {
00095 remove_ob(item);
00096 free_object(item);
00097 item = create_archetype("burnout");
00098 if (item != NULL)
00099 insert_ob_in_map_at(item, converter->map, converter, 0, converter->x, converter->y);
00100 return 1;
00101 }
00102
00103 if (CONV_NEED(converter)) {
00104 nr = item->nrof/CONV_NEED(converter);
00105 decrease_ob_nr(item, nr*CONV_NEED(converter));
00106 price_in = nr*CONV_NEED(converter)*item->value;
00107 } else {
00108 price_in = item->value;
00109 remove_ob(item);
00110 free_object(item);
00111 }
00112 }
00113
00114 if (converter->inv != NULL) {
00115 object *ob;
00116 int i;
00117 object *ob_to_copy;
00118
00119
00120 ob_to_copy = converter->inv;
00121 for (ob = converter->inv->below, i = 1; ob != NULL; ob = ob->below, i++) {
00122 if (rndm(0, i) == 0)
00123 ob_to_copy = ob;
00124 }
00125 item = object_create_clone(ob_to_copy);
00126 CLEAR_FLAG(item, FLAG_IS_A_TEMPLATE);
00127 unflag_inv(item, FLAG_IS_A_TEMPLATE);
00128 } else {
00129 if (converter->other_arch == NULL) {
00130 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);
00131 return -1;
00132 }
00133 item = object_create_arch(converter->other_arch);
00134 fix_generated_item(item, converter, 0, 0, GT_MINIMAL);
00135 }
00136
00137 if (CONV_NR(converter))
00138 item->nrof = CONV_NR(converter);
00139 if (nr)
00140 item->nrof *= nr;
00141 if (is_in_shop(converter))
00142 SET_FLAG(item, FLAG_UNPAID);
00143 else if (price_in < item->nrof*item->value && settings.allow_broken_converters == FALSE) {
00144 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);
00145 free_object(item);
00146 return -1;
00147 }
00148 insert_ob_in_map_at(item, converter->map, converter, 0, converter->x, converter->y);
00149 return 1;
00150 }
00151
00160 static method_ret converter_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) {
00161 if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
00162 return METHOD_OK;
00163 if (convert_item(victim, trap) < 0) {
00164 object *op;
00165 char name[MAX_BUF];
00166
00167 query_name(trap, name, MAX_BUF);
00168 draw_ext_info_format(NDI_UNIQUE, 0, originator, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
00169 "The %s seems to be broken!", "The %s seems to be broken!",
00170 name);
00171
00172 op = create_archetype("burnout");
00173 if (op != NULL) {
00174 op->x = trap->x;
00175 op->y = trap->y;
00176 insert_ob_in_map(op, trap->map, trap, 0);
00177 }
00178 }
00179 common_post_ob_move_on(trap, victim, originator);
00180 return METHOD_OK;
00181 }