|
31 | 31 | #include "improved-edit.h" |
32 | 32 | #include "talents.h" /* crafting talent system */ |
33 | 33 | #include "dg_scripts.h" |
| 34 | +#include "resource_system.h" |
34 | 35 |
|
35 | 36 | #ifndef TRUE |
36 | 37 | #define TRUE 1 |
@@ -738,6 +739,7 @@ int craft_group_by_material(int material) |
738 | 739 | return CRAFT_GROUP_STONE; |
739 | 740 |
|
740 | 741 | case CRAFT_MAT_COAL: |
| 742 | + case CRAFT_MAT_DRAGONBLOOD: |
741 | 743 | return CRAFT_GROUP_REFINING; |
742 | 744 | } |
743 | 745 | return CRAFT_GROUP_NONE; |
@@ -3479,6 +3481,7 @@ int obj_material_to_craft_material(int material) |
3479 | 3481 | case MATERIAL_DRAGONMETAL: |
3480 | 3482 | return CRAFT_MAT_DRAGONMETAL; |
3481 | 3483 | case MATERIAL_DRAGONSCALE: |
| 3484 | + case MATERIAL_DRAGONHIDE: |
3482 | 3485 | return CRAFT_MAT_DRAGONSCALE; |
3483 | 3486 | case MATERIAL_DRAGONBONE: |
3484 | 3487 | return CRAFT_MAT_DRAGONBONE; |
@@ -3516,6 +3519,8 @@ int obj_material_to_craft_material(int material) |
3516 | 3519 | return CRAFT_MAT_BONE; |
3517 | 3520 | case MATERIAL_STONE: |
3518 | 3521 | return CRAFT_MAT_STONE; |
| 3522 | + case MATERIAL_DRAGONBLOOD: |
| 3523 | + return CRAFT_MAT_DRAGONBLOOD; |
3519 | 3524 | } |
3520 | 3525 | return CRAFT_MAT_NONE; |
3521 | 3526 | } |
@@ -3563,6 +3568,8 @@ int craft_material_to_obj_material(int craftmat) |
3563 | 3568 | return MATERIAL_LEATHER; |
3564 | 3569 | case CRAFT_MAT_PRISTINE_GRADE_HIDE: |
3565 | 3570 | return MATERIAL_LEATHER; |
| 3571 | + case CRAFT_MAT_DRAGONBLOOD: |
| 3572 | + return MATERIAL_DRAGONBLOOD; |
3566 | 3573 | case CRAFT_MAT_ASH_WOOD: |
3567 | 3574 | return MATERIAL_ASH; |
3568 | 3575 | case CRAFT_MAT_MAPLE_WOOD: |
@@ -5234,14 +5241,44 @@ void newcraft_refine(struct char_data *ch, const char *argument) |
5234 | 5241 | { |
5235 | 5242 | if ((material = refining_recipes[recipe].materials[i][0]) != 0) |
5236 | 5243 | { |
5237 | | - if (GET_CRAFT_MAT(ch, material) <= refining_recipes[recipe].materials[i][1]) |
| 5244 | + /* Special handling for dragonmetal: second material can be any hard metal grade 2+ */ |
| 5245 | + if (recipe == REFINE_RECIPE_DRAGONMETAL && i == 1) |
5238 | 5246 | { |
5239 | | - send_to_char(ch, "You need %d units of %s to make %d units of %s.\r\n", |
| 5247 | + /* Check for any grade 2+ hard metal */ |
| 5248 | + int has_hard_metal_grade2 = 0; |
| 5249 | + int j = 0; |
| 5250 | + |
| 5251 | + for (j = CRAFT_MAT_COPPER; j < NUM_CRAFT_MATS; j++) |
| 5252 | + { |
| 5253 | + if (craft_group_by_material(j) == CRAFT_GROUP_HARD_METALS && |
| 5254 | + material_grade(j) >= 3 && |
| 5255 | + GET_CRAFT_MAT(ch, j) >= refining_recipes[recipe].materials[i][1]) |
| 5256 | + { |
| 5257 | + has_hard_metal_grade2 = 1; |
| 5258 | + break; |
| 5259 | + } |
| 5260 | + } |
| 5261 | + |
| 5262 | + if (!has_hard_metal_grade2) |
| 5263 | + { |
| 5264 | + send_to_char(ch, "You need %d units of a grade 3 or higher hard metal to make %d units of %s.\r\n", |
5240 | 5265 | refining_recipes[recipe].materials[i][1], |
5241 | | - crafting_materials[refining_recipes[recipe].materials[i][0]], |
5242 | 5266 | refining_recipes[recipe].result[1], |
5243 | 5267 | crafting_materials[refining_recipes[recipe].result[0]]); |
5244 | | - fail = TRUE; |
| 5268 | + fail = TRUE; |
| 5269 | + } |
| 5270 | + } |
| 5271 | + else |
| 5272 | + { |
| 5273 | + if (GET_CRAFT_MAT(ch, material) < refining_recipes[recipe].materials[i][1]) |
| 5274 | + { |
| 5275 | + send_to_char(ch, "You need %d units of %s to make %d units of %s.\r\n", |
| 5276 | + refining_recipes[recipe].materials[i][1], |
| 5277 | + crafting_materials[refining_recipes[recipe].materials[i][0]], |
| 5278 | + refining_recipes[recipe].result[1], |
| 5279 | + crafting_materials[refining_recipes[recipe].result[0]]); |
| 5280 | + fail = TRUE; |
| 5281 | + } |
5245 | 5282 | } |
5246 | 5283 | } |
5247 | 5284 | } |
@@ -5274,14 +5311,41 @@ void newcraft_refine(struct char_data *ch, const char *argument) |
5274 | 5311 | { |
5275 | 5312 | if ((material = refining_recipes[recipe].materials[i][0]) != 0) |
5276 | 5313 | { |
5277 | | - GET_CRAFT_MAT(ch, material) -= refining_recipes[recipe].materials[i][1]; |
5278 | | - GET_CRAFT(ch).refining_materials[i][0] = material; |
5279 | | - GET_CRAFT(ch).refining_materials[i][1] = refining_recipes[recipe].materials[i][1]; |
5280 | | - send_to_char(ch, "You allocate %d units of %s to your refining of %d units of %s.\r\n", |
5281 | | - refining_recipes[recipe].materials[i][1], |
5282 | | - crafting_materials[refining_recipes[recipe].materials[i][0]], |
5283 | | - refining_recipes[recipe].result[1], |
5284 | | - crafting_materials[refining_recipes[recipe].result[0]]); |
| 5314 | + /* Special handling for dragonmetal: second material can be any hard metal grade 2+ */ |
| 5315 | + if (recipe == REFINE_RECIPE_DRAGONMETAL && i == 1) |
| 5316 | + { |
| 5317 | + /* Find and use the first available grade 2+ hard metal */ |
| 5318 | + int j = 0; |
| 5319 | + for (j = CRAFT_MAT_COPPER; j < NUM_CRAFT_MATS; j++) |
| 5320 | + { |
| 5321 | + if (craft_group_by_material(j) == CRAFT_GROUP_HARD_METALS && |
| 5322 | + material_grade(j) >= 3 && |
| 5323 | + GET_CRAFT_MAT(ch, j) >= refining_recipes[recipe].materials[i][1]) |
| 5324 | + { |
| 5325 | + material = j; |
| 5326 | + GET_CRAFT_MAT(ch, material) -= refining_recipes[recipe].materials[i][1]; |
| 5327 | + GET_CRAFT(ch).refining_materials[i][0] = material; |
| 5328 | + GET_CRAFT(ch).refining_materials[i][1] = refining_recipes[recipe].materials[i][1]; |
| 5329 | + send_to_char(ch, "You allocate %d units of %s to your refining of %d units of %s.\r\n", |
| 5330 | + refining_recipes[recipe].materials[i][1], |
| 5331 | + crafting_materials[material], |
| 5332 | + refining_recipes[recipe].result[1], |
| 5333 | + crafting_materials[refining_recipes[recipe].result[0]]); |
| 5334 | + break; |
| 5335 | + } |
| 5336 | + } |
| 5337 | + } |
| 5338 | + else |
| 5339 | + { |
| 5340 | + GET_CRAFT_MAT(ch, material) -= refining_recipes[recipe].materials[i][1]; |
| 5341 | + GET_CRAFT(ch).refining_materials[i][0] = material; |
| 5342 | + GET_CRAFT(ch).refining_materials[i][1] = refining_recipes[recipe].materials[i][1]; |
| 5343 | + send_to_char(ch, "You allocate %d units of %s to your refining of %d units of %s.\r\n", |
| 5344 | + refining_recipes[recipe].materials[i][1], |
| 5345 | + crafting_materials[refining_recipes[recipe].materials[i][0]], |
| 5346 | + refining_recipes[recipe].result[1], |
| 5347 | + crafting_materials[refining_recipes[recipe].result[0]]); |
| 5348 | + } |
5285 | 5349 | } |
5286 | 5350 | } |
5287 | 5351 |
|
@@ -5974,8 +6038,183 @@ ACMD(do_setmaterial) |
5974 | 6038 |
|
5975 | 6039 | ACMD(do_list_craft_materials) |
5976 | 6040 | { |
| 6041 | + char arg[MAX_INPUT_LENGTH]; |
| 6042 | + char arg2[MAX_INPUT_LENGTH]; |
| 6043 | + char buf[MAX_INPUT_LENGTH]; |
| 6044 | + struct obj_data *obj = NULL; |
| 6045 | + int craft_material = CRAFT_MAT_NONE; |
| 6046 | + int quantity = 1; |
5977 | 6047 | int i = 0, mat = 0, count = 0; |
5978 | 6048 |
|
| 6049 | + half_chop_c(argument, arg, sizeof(arg), arg2, sizeof(arg2)); |
| 6050 | + |
| 6051 | + /* Handle 'list_craft_materials store <item>' */ |
| 6052 | + if (*arg && !str_cmp(arg, "store")) |
| 6053 | + { |
| 6054 | + if (!*arg2) |
| 6055 | + { |
| 6056 | + send_to_char(ch, "Store which item?\r\n"); |
| 6057 | + return; |
| 6058 | + } |
| 6059 | + |
| 6060 | + /* Find the item in inventory */ |
| 6061 | + if (!(obj = get_obj_in_list_vis(ch, arg2, NULL, ch->carrying))) |
| 6062 | + { |
| 6063 | + send_to_char(ch, "You don't have %s %s.\r\n", AN(arg2), arg2); |
| 6064 | + return; |
| 6065 | + } |
| 6066 | + |
| 6067 | + /* Check if it's a material item */ |
| 6068 | + if (GET_OBJ_TYPE(obj) != ITEM_MATERIAL) |
| 6069 | + { |
| 6070 | + send_to_char(ch, "%s is not a crafting material.\r\n", CAP(GET_OBJ_SHORT(obj))); |
| 6071 | + return; |
| 6072 | + } |
| 6073 | + |
| 6074 | + /* Get quantity from object (VAL 0) */ |
| 6075 | + quantity = MAX(1, GET_OBJ_VAL(obj, 0)); |
| 6076 | + |
| 6077 | + /* Convert object material to craft material type */ |
| 6078 | + craft_material = obj_material_to_craft_material(GET_OBJ_MATERIAL(obj)); |
| 6079 | + |
| 6080 | + if (craft_material == CRAFT_MAT_NONE) |
| 6081 | + { |
| 6082 | + send_to_char(ch, "%s cannot be stored as crafting material.\r\n", CAP(GET_OBJ_SHORT(obj))); |
| 6083 | + return; |
| 6084 | + } |
| 6085 | + |
| 6086 | + int stored = quantity; |
| 6087 | + |
| 6088 | + if (stored > 0) |
| 6089 | + { |
| 6090 | + GET_CRAFT_MAT(ch, craft_material) += stored; |
| 6091 | + send_to_char(ch, "You store %d unit%s of %s.\r\n", stored, stored == 1 ? "" : "s", crafting_materials[craft_material]); |
| 6092 | + extract_obj(obj); |
| 6093 | + } |
| 6094 | + else |
| 6095 | + { |
| 6096 | + send_to_char(ch, "You don't have enough storage space for that material.\r\n"); |
| 6097 | + } |
| 6098 | + |
| 6099 | + return; |
| 6100 | + } |
| 6101 | + |
| 6102 | + /* Handle 'list_craft_materials unstore <# to unstore> <name of material>' */ |
| 6103 | + if (*arg && !str_cmp(arg, "unstore") && false) // disabled for now |
| 6104 | + { |
| 6105 | + char quantity_str[MAX_INPUT_LENGTH]; |
| 6106 | + char material_name_buf[MAX_INPUT_LENGTH]; |
| 6107 | + int unstore_quantity = 0; |
| 6108 | + int material_type = CRAFT_MAT_NONE; |
| 6109 | + int j = 0; |
| 6110 | + struct obj_data *new_mat_obj = NULL; |
| 6111 | + int obj_material = MATERIAL_UNDEFINED; |
| 6112 | + |
| 6113 | + /* Parse arguments using half_chop: unstore <qty> <material> */ |
| 6114 | + half_chop(arg2, quantity_str, material_name_buf); |
| 6115 | + |
| 6116 | + if (!*quantity_str || !*material_name_buf) |
| 6117 | + { |
| 6118 | + send_to_char(ch, "Usage: materials unstore <quantity> <material name>\r\n"); |
| 6119 | + send_to_char(ch, "Example: materials unstore 5 copper\r\n"); |
| 6120 | + return; |
| 6121 | + } |
| 6122 | + |
| 6123 | + unstore_quantity = atoi(quantity_str); |
| 6124 | + |
| 6125 | + if (unstore_quantity <= 0) |
| 6126 | + { |
| 6127 | + send_to_char(ch, "You must unstore at least 1 unit.\r\n"); |
| 6128 | + return; |
| 6129 | + } |
| 6130 | + |
| 6131 | + /* Find the material type by name */ |
| 6132 | + for (j = 0; j < NUM_CRAFT_MATS; j++) |
| 6133 | + { |
| 6134 | + if (is_abbrev(material_name_buf, crafting_materials[j])) |
| 6135 | + { |
| 6136 | + material_type = j; |
| 6137 | + break; |
| 6138 | + } |
| 6139 | + } |
| 6140 | + |
| 6141 | + if (material_type == CRAFT_MAT_NONE) |
| 6142 | + { |
| 6143 | + send_to_char(ch, "Unknown material '%s'.\r\n", material_name_buf); |
| 6144 | + return; |
| 6145 | + } |
| 6146 | + |
| 6147 | + if (GET_CRAFT_MAT(ch, material_type) < unstore_quantity) |
| 6148 | + { |
| 6149 | + send_to_char(ch, "You only have %d unit%s of %s stored.\r\n", |
| 6150 | + GET_CRAFT_MAT(ch, material_type), |
| 6151 | + GET_CRAFT_MAT(ch, material_type) == 1 ? "" : "s", |
| 6152 | + crafting_materials[material_type]); |
| 6153 | + return; |
| 6154 | + } |
| 6155 | + |
| 6156 | + /* Create ITEM_MATERIAL object */ |
| 6157 | + if ((new_mat_obj = read_object(ITEM_PROTOTYPE, VIRTUAL)) == NULL) |
| 6158 | + { |
| 6159 | + send_to_char(ch, "Error: Could not create material object.\r\n"); |
| 6160 | + return; |
| 6161 | + } |
| 6162 | + |
| 6163 | + /* Convert craft material type to object material */ |
| 6164 | + obj_material = craft_material_to_obj_material(material_type); |
| 6165 | + |
| 6166 | + /* Set up the material object */ |
| 6167 | + GET_OBJ_TYPE(new_mat_obj) = ITEM_MATERIAL; |
| 6168 | + GET_OBJ_MATERIAL(new_mat_obj) = obj_material; |
| 6169 | + GET_OBJ_VAL(new_mat_obj, 0) = unstore_quantity; |
| 6170 | + GET_OBJ_VAL(new_mat_obj, 1) = 0; |
| 6171 | + GET_OBJ_VAL(new_mat_obj, 2) = 0; |
| 6172 | + GET_OBJ_VAL(new_mat_obj, 3) = 0; |
| 6173 | + |
| 6174 | + /* Set keywords for interaction */ |
| 6175 | + snprintf(buf, sizeof(buf), "material %s bundle", crafting_materials[material_type]); |
| 6176 | + if (new_mat_obj->name) |
| 6177 | + free(new_mat_obj->name); |
| 6178 | + new_mat_obj->name = strdup(buf); |
| 6179 | + |
| 6180 | + /* Set short description */ |
| 6181 | + snprintf(buf, sizeof(buf), "bundle of %s", crafting_materials[material_type]); |
| 6182 | + if (new_mat_obj->short_description) |
| 6183 | + free(new_mat_obj->short_description); |
| 6184 | + new_mat_obj->short_description = strdup(buf); |
| 6185 | + |
| 6186 | + /* Set long description */ |
| 6187 | + snprintf(buf, sizeof(buf), "A bundle of %s material (%d unit%s) lies here.", |
| 6188 | + crafting_materials[material_type], unstore_quantity, |
| 6189 | + unstore_quantity == 1 ? "" : "s"); |
| 6190 | + if (new_mat_obj->description) |
| 6191 | + free(new_mat_obj->description); |
| 6192 | + new_mat_obj->description = strdup(buf); |
| 6193 | + |
| 6194 | + /* Give to player */ |
| 6195 | + obj_to_char(new_mat_obj, ch); |
| 6196 | + |
| 6197 | + /* Deduct from storage */ |
| 6198 | + GET_CRAFT_MAT(ch, material_type) -= unstore_quantity; |
| 6199 | + |
| 6200 | + send_to_char(ch, "You unstore %d unit%s of %s.\r\n", unstore_quantity, |
| 6201 | + unstore_quantity == 1 ? "" : "s", crafting_materials[material_type]); |
| 6202 | + |
| 6203 | + return; |
| 6204 | + } |
| 6205 | + |
| 6206 | + /* Handle invalid arguments */ |
| 6207 | + if (*arg) |
| 6208 | + { |
| 6209 | + send_to_char(ch, "Usage: materials [store <item>] [unstore <quantity> <material>]\r\n"); |
| 6210 | + send_to_char(ch, " materials - Show your stored materials\r\n"); |
| 6211 | + send_to_char(ch, " materials store <item> - Store a material item\r\n"); |
| 6212 | + send_to_char(ch, " materials unstore <qty> <material> - Unstore materials\r\n"); |
| 6213 | + return; |
| 6214 | + } |
| 6215 | + |
| 6216 | + /* Show crafting materials by default */ |
| 6217 | + |
5979 | 6218 | send_to_char(ch, "\tc"); |
5980 | 6219 | text_line(ch, "HARD METALS", 80, '-', '-'); |
5981 | 6220 | send_to_char(ch, "\tn"); |
|
0 commit comments