… | |
… | |
899 | esrv_send_item (op, tmp); |
899 | esrv_send_item (op, tmp); |
900 | } |
900 | } |
901 | return 1; |
901 | return 1; |
902 | } |
902 | } |
903 | |
903 | |
904 | |
|
|
905 | /* |
904 | /* |
906 | * convert_item() returns 1 if anything was converted, 0 if the item was not |
905 | * convert_item() returns 1 if anything was converted, 0 if the item was not |
907 | * what the converter wants, -1 if the converter is broken. |
906 | * what the converter wants, -1 if the converter is broken. |
908 | */ |
907 | */ |
909 | #define CONV_FROM(xyz) xyz->slaying |
908 | #define CONV_FROM(xyz) xyz->slaying |
… | |
… | |
924 | |
923 | |
925 | /* We make some assumptions - we assume if it takes money as it type, |
924 | /* We make some assumptions - we assume if it takes money as it type, |
926 | * it wants some amount. We don't make change (ie, if something costs |
925 | * it wants some amount. We don't make change (ie, if something costs |
927 | * 3 gp and player drops a platinum, tough luck) |
926 | * 3 gp and player drops a platinum, tough luck) |
928 | */ |
927 | */ |
929 | if (!strcmp (CONV_FROM (converter), "money")) |
928 | if (CONV_FROM (converter) == shstr_money) |
930 | { |
929 | { |
931 | int cost; |
|
|
932 | |
|
|
933 | if (item->type != MONEY) |
930 | if (item->type != MONEY) |
934 | return 0; |
931 | return 0; |
935 | |
932 | |
936 | nr = (item->nrof * item->value) / CONV_NEED (converter); |
933 | nr = (item->nrof * item->value) / CONV_NEED (converter); |
937 | if (!nr) |
934 | if (!nr) |
938 | return 0; |
935 | return 0; |
|
|
936 | |
|
|
937 | converter->play_sound (sound_find ("shop_buy")); |
|
|
938 | |
939 | cost = nr * CONV_NEED (converter) / item->value; |
939 | int cost = nr * CONV_NEED (converter) / item->value; |
940 | /* take into account rounding errors */ |
940 | /* take into account rounding errors */ |
941 | if (nr * CONV_NEED (converter) % item->value) |
941 | if (nr * CONV_NEED (converter) % item->value) |
942 | cost++; |
942 | cost++; |
|
|
943 | |
943 | decrease_ob_nr (item, cost); |
944 | decrease_ob_nr (item, cost); |
944 | |
945 | |
945 | price_in = cost * item->value; |
946 | price_in = cost * item->value; |
946 | } |
947 | } |
947 | else |
948 | else |
948 | { |
949 | { |
949 | if (item->type == PLAYER || CONV_FROM (converter) != item->arch->archname || |
950 | if (item->type == PLAYER || CONV_FROM (converter) != item->arch->archname || |
950 | (CONV_NEED (converter) && CONV_NEED (converter) > (uint16) item->nrof)) |
951 | (CONV_NEED (converter) && CONV_NEED (converter) > (uint16) item->nrof)) |
951 | return 0; |
952 | return 0; |
952 | |
953 | |
|
|
954 | converter->play_sound (sound_find ("convert_item")); |
|
|
955 | |
953 | if (CONV_NEED (converter)) |
956 | if (CONV_NEED (converter)) |
954 | { |
957 | { |
955 | nr = item->nrof / CONV_NEED (converter); |
958 | nr = item->nrof / CONV_NEED (converter); |
956 | decrease_ob_nr (item, nr * CONV_NEED (converter)); |
959 | decrease_ob_nr (item, nr * CONV_NEED (converter)); |
957 | price_in = nr * CONV_NEED (converter) * item->value; |
960 | price_in = nr * CONV_NEED (converter) * item->value; |
… | |
… | |
961 | price_in = item->value; |
964 | price_in = item->value; |
962 | item->destroy (); |
965 | item->destroy (); |
963 | } |
966 | } |
964 | } |
967 | } |
965 | |
968 | |
966 | if (converter->inv != NULL) |
969 | if (converter->inv) |
967 | { |
970 | { |
968 | object *ob; |
971 | object *ob; |
969 | int i; |
972 | int i; |
970 | object *ob_to_copy; |
973 | object *ob_to_copy; |
971 | |
974 | |
972 | /* select random object from inventory to copy */ |
975 | /* select random object from inventory to copy */ |
973 | ob_to_copy = converter->inv; |
976 | ob_to_copy = converter->inv; |
974 | for (ob = converter->inv->below, i = 1; ob != NULL; ob = ob->below, i++) |
977 | for (ob = converter->inv->below, i = 1; ob; ob = ob->below, i++) |
975 | { |
|
|
976 | if (rndm (0, i) == 0) |
978 | if (rndm (0, i) == 0) |
977 | { |
|
|
978 | ob_to_copy = ob; |
979 | ob_to_copy = ob; |
979 | } |
980 | |
980 | } |
|
|
981 | item = object_create_clone (ob_to_copy); |
981 | item = object_create_clone (ob_to_copy); |
982 | CLEAR_FLAG (item, FLAG_IS_A_TEMPLATE); |
982 | CLEAR_FLAG (item, FLAG_IS_A_TEMPLATE); |
983 | unflag_inv (item, FLAG_IS_A_TEMPLATE); |
983 | unflag_inv (item, FLAG_IS_A_TEMPLATE); |
984 | } |
984 | } |
985 | else |
985 | else |
… | |
… | |
995 | fix_generated_item (item, converter, 0, 0, GT_MINIMAL); |
995 | fix_generated_item (item, converter, 0, 0, GT_MINIMAL); |
996 | } |
996 | } |
997 | |
997 | |
998 | if (CONV_NR (converter)) |
998 | if (CONV_NR (converter)) |
999 | item->nrof = CONV_NR (converter); |
999 | item->nrof = CONV_NR (converter); |
|
|
1000 | |
1000 | if (nr) |
1001 | if (nr) |
1001 | item->nrof *= nr; |
1002 | item->nrof *= nr; |
|
|
1003 | |
1002 | if (is_in_shop (converter)) |
1004 | if (is_in_shop (converter)) |
1003 | SET_FLAG (item, FLAG_UNPAID); |
1005 | SET_FLAG (item, FLAG_UNPAID); |
1004 | else if (price_in < item->nrof * item->value) |
1006 | else if (price_in < item->nrof * item->value) |
1005 | { |
1007 | { |
1006 | LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", |
1008 | LOG (llevDebug, "converter output price higher than input: %s at %s (%d, %d) in value %d, out value %d for %s\n", |
1007 | &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); |
1009 | &converter->name, &converter->map->path, converter->x, converter->y, price_in, item->nrof * item->value, &item->name); |
1008 | |
|
|
1009 | /** |
1010 | /** |
1010 | * elmex: we are going to let the game continue, as the mapcreator |
1011 | * elmex: we are going to let the game continue, as the mapcreator |
1011 | * probably had something in mind when doing this |
1012 | * hopefully had something in mind when doing this. |
1012 | */ |
1013 | */ |
1013 | } |
1014 | } |
|
|
1015 | |
1014 | SET_FLAG (item, FLAG_IDENTIFIED); |
1016 | SET_FLAG (item, FLAG_IDENTIFIED); |
1015 | insert_ob_in_map_at (item, converter->map, converter, 0, converter->x, converter->y); |
1017 | insert_ob_in_map_at (item, converter->map, converter, 0, converter->x, converter->y); |
1016 | return 1; |
1018 | return 1; |
1017 | } |
1019 | } |
1018 | |
1020 | |
… | |
… | |
1140 | double opinion; |
1142 | double opinion; |
1141 | object *tmp, *next; |
1143 | object *tmp, *next; |
1142 | |
1144 | |
1143 | SET_FLAG (op, FLAG_NO_APPLY); /* prevent loops */ |
1145 | SET_FLAG (op, FLAG_NO_APPLY); /* prevent loops */ |
1144 | |
1146 | |
|
|
1147 | bool has_unpaid = false; |
|
|
1148 | |
|
|
1149 | // quite inefficient to do this here twice, but the api doesn'T lend itself to |
|
|
1150 | // a quick and small change :( |
|
|
1151 | for (object::depth_iterator item = op->begin (); item != op->end (); ++item) |
|
|
1152 | if (item->flag [FLAG_UNPAID]) |
|
|
1153 | { |
|
|
1154 | has_unpaid = true; |
|
|
1155 | break; |
|
|
1156 | } |
|
|
1157 | |
1145 | if (op->type != PLAYER) |
1158 | if (op->type != PLAYER) |
1146 | { |
1159 | { |
1147 | /* Remove all the unpaid objects that may be carried here. |
1160 | /* Remove all the unpaid objects that may be carried here. |
1148 | * This could be pets or monsters that are somehow in |
1161 | * This could be pets or monsters that are somehow in |
1149 | * the shop. |
1162 | * the shop. |
… | |
… | |
1175 | /* unpaid objects, or non living objects, can't transfer by |
1188 | /* unpaid objects, or non living objects, can't transfer by |
1176 | * shop mats. Instead, put it on a nearby space. |
1189 | * shop mats. Instead, put it on a nearby space. |
1177 | */ |
1190 | */ |
1178 | if (QUERY_FLAG (op, FLAG_UNPAID) || !QUERY_FLAG (op, FLAG_ALIVE)) |
1191 | if (QUERY_FLAG (op, FLAG_UNPAID) || !QUERY_FLAG (op, FLAG_ALIVE)) |
1179 | { |
1192 | { |
1180 | |
|
|
1181 | /* Somebody dropped an unpaid item, just move to an adjacent place. */ |
1193 | /* Somebody dropped an unpaid item, just move to an adjacent place. */ |
1182 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
1194 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
1183 | |
1195 | |
1184 | if (i != -1) |
1196 | if (i != -1) |
1185 | rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); |
1197 | rv = transfer_ob (op, op->x + freearr_x[i], op->y + freearr_y[i], 0, shop_mat); |
… | |
… | |
1193 | } |
1205 | } |
1194 | else if (can_pay (op) && get_payment (op)) |
1206 | else if (can_pay (op) && get_payment (op)) |
1195 | { |
1207 | { |
1196 | /* this is only used for players */ |
1208 | /* this is only used for players */ |
1197 | rv = teleport (shop_mat, SHOP_MAT, op); |
1209 | rv = teleport (shop_mat, SHOP_MAT, op); |
|
|
1210 | |
|
|
1211 | if (has_unpaid) |
|
|
1212 | op->contr->play_sound (sound_find ("shop_buy")); |
|
|
1213 | else if (is_in_shop (op)) |
|
|
1214 | op->contr->play_sound (sound_find ("shop_enter")); |
|
|
1215 | else |
|
|
1216 | op->contr->play_sound (sound_find ("shop_leave")); |
1198 | |
1217 | |
1199 | if (shop_mat->msg) |
1218 | if (shop_mat->msg) |
1200 | new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); |
1219 | new_draw_info (NDI_UNIQUE, 0, op, shop_mat->msg); |
1201 | /* This check below is a bit simplistic - generally it should be correct, |
1220 | /* This check below is a bit simplistic - generally it should be correct, |
1202 | * but there is never a guarantee that the bottom space on the map is |
1221 | * but there is never a guarantee that the bottom space on the map is |
… | |
… | |
1217 | } |
1236 | } |
1218 | } |
1237 | } |
1219 | else |
1238 | else |
1220 | { |
1239 | { |
1221 | /* if we get here, a player tried to leave a shop but was not able |
1240 | /* if we get here, a player tried to leave a shop but was not able |
1222 | * to afford the items he has. We try to move the player so that |
1241 | * to afford the items he has. We try to move the player so that |
1223 | * they are not on the mat anymore |
1242 | * they are not on the mat anymore |
1224 | */ |
1243 | */ |
1225 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
1244 | int i = find_free_spot (op, op->map, op->x, op->y, 1, 9); |
1226 | |
1245 | |
1227 | if (i == -1) |
1246 | if (i == -1) |
1228 | { |
|
|
1229 | LOG (llevError, "Internal shop-mat problem.\n"); |
1247 | LOG (llevError, "Internal shop-mat problem.\n"); |
1230 | } |
|
|
1231 | else |
1248 | else |
1232 | { |
1249 | { |
1233 | op->remove (); |
1250 | op->remove (); |
1234 | op->x += freearr_x[i]; |
1251 | op->x += freearr_x[i]; |
1235 | op->y += freearr_y[i]; |
1252 | op->y += freearr_y[i]; |
… | |
… | |
1446 | transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab); |
1463 | transfer_ob (ab, (int) EXIT_X (trap), (int) EXIT_Y (trap), 0, ab); |
1447 | } |
1464 | } |
1448 | } |
1465 | } |
1449 | goto leave; |
1466 | goto leave; |
1450 | } |
1467 | } |
1451 | |
|
|
1452 | |
1468 | |
1453 | case CONVERTER: |
1469 | case CONVERTER: |
1454 | if (convert_item (victim, trap) < 0) |
1470 | if (convert_item (victim, trap) < 0) |
1455 | { |
1471 | { |
1456 | new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap)); |
1472 | new_draw_info_format (NDI_UNIQUE, 0, originator, "The %s seems to be broken!", query_name (trap)); |