use of slimeknights.tconstruct.library.materials.definition.MaterialId in project TinkersConstruct by SlimeKnights.
the class TinkerStationRepairRecipe method repairFromSlot.
/**
* Gets the amount to repair from the given slot
* @param tool Tool instance
* @param primaryMaterial Material of the primary head
* @param inv Inventory instance
* @param repairNeeded Amount of remaining repair needed
* @param slot Input slot
* @param amountConsumer Action to perform on repair, input is the amount consumed
* @return Repair from this slot
*/
protected int repairFromSlot(ToolStack tool, MaterialId primaryMaterial, ITinkerStationContainer inv, int repairNeeded, int slot, IntConsumer amountConsumer) {
ItemStack stack = inv.getInput(slot);
if (!stack.isEmpty()) {
// we have a recipe with matching stack, find out how much we can repair
MaterialId repairMaterial = getMaterialFrom(inv, slot);
if (!repairMaterial.equals(IMaterial.UNKNOWN_ID)) {
float durabilityPerItem = getRepairPerItem(tool, inv, slot, repairMaterial);
if (durabilityPerItem > 0) {
// if not the primary material, reduced effectiveness
durabilityPerItem *= getRepairWeight(tool, repairMaterial);
// main example is wood, +25% per level
for (ModifierEntry entry : tool.getModifierList()) {
durabilityPerItem = entry.getModifier().getRepairFactor(tool, entry.getLevel(), durabilityPerItem);
if (durabilityPerItem <= 0) {
return 0;
}
}
// apply this recipe as many times as we need (if stack has more than enough to repair) or can (if stack will not fully repair)
int applied = Math.min(stack.getCount(), (int) Math.ceil(repairNeeded / durabilityPerItem));
amountConsumer.accept(applied);
return (int) (applied * durabilityPerItem);
}
}
}
return 0;
}
use of slimeknights.tconstruct.library.materials.definition.MaterialId in project TinkersConstruct by SlimeKnights.
the class CraftingTableRepairKitRecipe method getRelevantInputs.
/**
* Gets the tool stack and the repair kit material from the crafting grid
* @param inv Crafting inventory
* @return Relevant inputs, or null if invalid
*/
@Nullable
protected Pair<ToolStack, MaterialId> getRelevantInputs(CraftingContainer inv) {
ToolStack tool = null;
MaterialId material = null;
for (int i = 0; i < inv.getContainerSize(); i++) {
ItemStack stack = inv.getItem(i);
if (stack.isEmpty()) {
continue;
}
// repair kit - update material
if (stack.getItem() == TinkerToolParts.repairKit.get()) {
// already found repair kit
if (material != null) {
return null;
}
MaterialId inputMaterial = IMaterialItem.getMaterialFromStack(stack).getId();
// if the material is invalid, also fail
if (inputMaterial.equals(IMaterial.UNKNOWN_ID)) {
return null;
}
material = inputMaterial;
} else if (toolMatches(stack)) {
// cannot repair multiple tools
if (tool != null) {
return null;
}
// tool must be damaged
tool = ToolStack.from(stack);
if (!tool.isBroken() && tool.getDamage() == 0) {
return null;
}
} else {
// unknown item input
return null;
}
}
if (tool == null || material == null) {
return null;
}
return Pair.of(tool, material);
}
use of slimeknights.tconstruct.library.materials.definition.MaterialId in project TinkersConstruct by SlimeKnights.
the class CraftingTableRepairKitRecipe method assemble.
@Override
public ItemStack assemble(CraftingContainer inv) {
Pair<ToolStack, MaterialId> inputs = getRelevantInputs(inv);
if (inputs == null) {
TConstruct.LOG.error("Recipe repair on {} failed to find items after matching", getId());
return ItemStack.EMPTY;
}
// first identify materials and durability
ToolStack tool = inputs.getFirst().copy();
// vanilla says 25% durability per ingot, repair kits are worth 2 ingots
float repairAmount = getRepairAmount(tool, inputs.getSecond());
if (repairAmount > 0) {
// main example is wood, +25% per level
for (ModifierEntry entry : tool.getModifierList()) {
repairAmount = entry.getModifier().getRepairFactor(tool, entry.getLevel(), repairAmount);
if (repairAmount <= 0) {
// failed to repair
return tool.createStack();
}
}
// repair the tool
ToolDamageUtil.repair(tool, (int) repairAmount);
}
// return final stack
return tool.createStack();
}
use of slimeknights.tconstruct.library.materials.definition.MaterialId in project TinkersConstruct by SlimeKnights.
the class ModifierUsageCommand method runForType.
private static int runForType(CommandContext<CommandSourceStack> context, ModifierUsages filter, @Nullable OptionalSlotType slotFilter) {
// recipe modifiers are used in a displayable modifier recipe
HashMultimap<SlotType, Modifier> recipeModifiers = context.getSource().getLevel().getRecipeManager().byType(RecipeTypes.TINKER_STATION).values().stream().filter(r -> r instanceof IModifierRecipe).map(r -> (IModifierRecipe) r).collect(Collector.of(HashMultimap::create, (map, r) -> map.put(r.getSlotType(), r.getModifier()), (m1, m2) -> {
m1.putAll(m2);
return m1;
}));
// material traits are used in material traits (kinda obvious)
IMaterialRegistry matReg = MaterialRegistry.getInstance();
Set<Modifier> materialTraits = matReg.getAllMaterials().stream().flatMap(mat -> {
MaterialId matId = mat.getIdentifier();
return Stream.concat(matReg.getDefaultTraits(matId).stream(), matReg.getAllStats(matId).stream().filter(stat -> matReg.hasUniqueTraits(matId, stat.getIdentifier())).flatMap(stat -> matReg.getTraits(matId, stat.getIdentifier()).stream()));
}).map(ModifierEntry::getModifier).collect(Collectors.toSet());
// finally, tool traits we limit to anything in the modifiable tag
Set<Modifier> toolTraits = TinkerTags.Items.MODIFIABLE.getValues().stream().filter(item -> item instanceof IModifiable).flatMap(item -> ((IModifiable) item).getToolDefinition().getData().getTraits().stream()).map(ModifierEntry::getModifier).collect(Collectors.toSet());
// next, get our list of modifiers
Stream<Modifier> modifierStream;
switch(filter) {
case RECIPE:
// filter to just one type of modifier if requested
if (slotFilter != null) {
modifierStream = recipeModifiers.get(slotFilter.slotType()).stream();
} else {
modifierStream = recipeModifiers.values().stream();
}
break;
case MATERIAL_TRAIT:
modifierStream = materialTraits.stream();
break;
case TOOL_TRAIT:
modifierStream = toolTraits.stream();
break;
default:
modifierStream = TinkerRegistries.MODIFIERS.getValues().stream();
break;
}
// if requested, filter out all
if (filter == ModifierUsages.UNUSED) {
modifierStream = modifierStream.filter(modifier -> !recipeModifiers.containsValue(modifier) && !materialTraits.contains(modifier) && !toolTraits.contains(modifier));
}
// start building the table for output
TablePrinter<ModifierUsageRow> table = new TablePrinter<>();
table.header("ID", r -> r.modifierId().toString());
if (filter != ModifierUsages.UNUSED) {
if (filter != ModifierUsages.RECIPE || slotFilter == null) {
table.header("Recipe", ModifierUsageRow::recipe);
}
if (filter != ModifierUsages.MATERIAL_TRAIT) {
table.header("material Trait", r -> r.materialTrait() ? "Material trait" : "");
}
if (filter != ModifierUsages.TOOL_TRAIT) {
table.header("tool Trait", r -> r.toolTrait() ? "Tool trait" : "");
}
}
StringBuilder logOutput = new StringBuilder();
logOutput.append(filter.logPrefix);
if (slotFilter != null) {
if (slotFilter.slotType() == null) {
logOutput.append(" (slotless)");
} else {
logOutput.append(" (").append(slotFilter.slotType().getName()).append(")");
}
}
logOutput.append(System.lineSeparator());
// for all the modifiers (sorted), add table rows
Collection<Modifier> finalList = modifierStream.sorted(Comparator.comparing(Modifier::getId)).toList();
finalList.forEach(modifier -> {
// determine which recipes use this by slot type
List<String> recipeUsages = SlotType.getAllSlotTypes().stream().filter(type -> recipeModifiers.containsEntry(type, modifier)).map(SlotType::getName).collect(Collectors.toList());
String recipes;
if (recipeUsages.isEmpty()) {
recipes = recipeModifiers.containsEntry(null, modifier) ? "slotless" : "";
} else {
recipes = String.join(", ", recipeUsages);
}
table.add(new ModifierUsageRow(modifier.getId(), recipes, toolTraits.contains(modifier), materialTraits.contains(modifier)));
});
// finally, output the table
table.build(logOutput);
TConstruct.LOG.info(logOutput.toString());
context.getSource().sendSuccess(SUCCESS, true);
return finalList.size();
}
use of slimeknights.tconstruct.library.materials.definition.MaterialId in project TinkersConstruct by SlimeKnights.
the class MaterialArgument method parse.
@Override
public IMaterial parse(StringReader reader) throws CommandSyntaxException {
MaterialId name = new MaterialId(ResourceLocation.read(reader));
IMaterial material = MaterialRegistry.getMaterial(name);
if (material == IMaterial.UNKNOWN) {
throw NOT_FOUND.createWithContext(reader, name);
}
return material;
}
Aggregations