Skip to content

Commit

Permalink
Expose Tiers, for future tool builder
Browse files Browse the repository at this point in the history
Signed-off-by: TheSilkMiner <thesilkminer@outlook.com>
  • Loading branch information
TheSilkMiner committed May 27, 2022
1 parent 48978be commit db63b41
Show file tree
Hide file tree
Showing 6 changed files with 408 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.blamejared.contenttweaker.vanilla.api.zen.util;

import com.blamejared.contenttweaker.core.api.ContentTweakerConstants;
import com.blamejared.contenttweaker.vanilla.api.zen.ContentTweakerVanillaConstants;
import com.blamejared.crafttweaker.api.annotation.ZenRegister;
import com.blamejared.crafttweaker_annotations.annotations.NativeTypeRegistration;
import net.minecraft.world.item.Tier;
import org.openzen.zencode.java.ZenCodeType;

@NativeTypeRegistration(value = Tier.class, zenCodeName = ContentTweakerVanillaConstants.VANILLA_UTIL_PACKAGE + ".Tier")
@ZenRegister(loaders = ContentTweakerConstants.CONTENT_LOADER_ID)
public final class TierNative {
private TierNative() {}

@ZenCodeType.Getter("uses")
public static int uses(final Tier $this) {
return $this.getUses();
}

@ZenCodeType.Getter("speed")
public static float speed(final Tier $this) {
return $this.getSpeed();
}

@ZenCodeType.Getter("attackDamageBonus")
public static float attackDamageBonus(final Tier $this) {
return $this.getAttackDamageBonus();
}

@ZenCodeType.Getter("level")
public static int level(final Tier $this) {
return $this.getLevel();
}

@ZenCodeType.Getter("enchantmentValue")
public static int enchantmentValue(final Tier $this) {
return $this.getEnchantmentValue();
}

// TODO("repairIngredient")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.blamejared.contenttweaker.fabric.api.zen.util;

import com.blamejared.contenttweaker.core.api.ContentTweakerConstants;
import com.blamejared.contenttweaker.fabric.util.ContentTweakerTierRegistry;
import com.blamejared.contenttweaker.vanilla.api.zen.ContentTweakerVanillaConstants;
import com.blamejared.contenttweaker.vanilla.api.zen.object.ItemReference;
import com.blamejared.crafttweaker.api.CraftTweakerAPI;
import com.blamejared.crafttweaker.api.annotation.ZenRegister;
import com.blamejared.crafttweaker.api.util.NameUtil;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.crafting.Ingredient;
import org.openzen.zencode.java.ZenCodeType;

import java.util.List;

@ZenCodeType.Expansion(ContentTweakerVanillaConstants.VANILLA_UTIL_PACKAGE + ".Tier")
@ZenRegister(loaders = ContentTweakerConstants.CONTENT_LOADER_ID)
public final class FabricTierExpansions {
private FabricTierExpansions() {}

@ZenCodeType.StaticExpansionMethod
public static Tier of(
final String name,
final int level,
final int uses,
final float speed,
final float attackDamageBonus,
final int enchantmentValue,
final ItemReference repairItem // TODO("Figure out ingredients")
) {
final ResourceLocation tierName = ContentTweakerConstants.rl(NameUtil.fixing(name, (fixed, mistakes) -> report(name, fixed, mistakes)));
if (level < 0) {
throw new IllegalArgumentException("Level for tier " + tierName + " cannot be negative");
}
if (uses <= 0) {
throw new IllegalArgumentException("Uses for tier " + tierName + " cannot be negative or zero");
}
// TODO("Additional checks?")
return ContentTweakerTierRegistry.of().create(tierName, level, uses, speed, attackDamageBonus, enchantmentValue, () -> Ingredient.of(repairItem.get()));
}

private static void report(final String original, final String fixed, final List<String> mistakes) {
CraftTweakerAPI.LOGGER.warn(() -> "The given name '%s' is not valid: it has been fixed to '%s'.\nMistakes:%s".formatted(
original,
fixed,
String.join("\n", mistakes)
));
}

@ZenCodeType.Getter("name")
@ZenCodeType.Nullable
public static ResourceLocation name(final Tier $this) {
try {
return ContentTweakerTierRegistry.of().nameOf($this);
} catch (final IllegalStateException e) {
// Catch because it's rare: users should not have access to a Tier we do not know about in ContentTweaker
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.blamejared.contenttweaker.fabric.util;

import com.google.common.base.Suppliers;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.crafting.Ingredient;

import java.util.Objects;
import java.util.function.Supplier;

final class ContentTweakerTier implements Tier {
private final int uses;
private final float speed;
private final float attackDamageBonus;
private final int level;
private final int enchantmentValue;
private final Supplier<Ingredient> reference;

ContentTweakerTier(final int uses, final float speed, final float attackDamageBonus, final int level, final int enchantmentValue, final Supplier<Ingredient> reference) {
this.uses = uses;
this.speed = speed;
this.attackDamageBonus = attackDamageBonus;
this.level = level;
this.enchantmentValue = enchantmentValue;
this.reference = Suppliers.memoize(Objects.requireNonNull(reference)::get);
}

@Override
public int getUses() {
return this.uses;
}

@Override
public float getSpeed() {
return this.speed;
}

@Override
public float getAttackDamageBonus() {
return this.attackDamageBonus;
}

@Override
public int getLevel() {
return this.level;
}

@Override
public int getEnchantmentValue() {
return this.enchantmentValue;
}

@Override
public Ingredient getRepairIngredient() {
return this.reference.get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.blamejared.contenttweaker.fabric.util;

import com.google.common.base.Suppliers;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.Tiers;
import net.minecraft.world.item.crafting.Ingredient;

import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;

public final class ContentTweakerTierRegistry {
private static final Supplier<ContentTweakerTierRegistry> INSTANCE = Suppliers.memoize(
() -> new ContentTweakerTierRegistry(ContentTweakerTierRegistry::vanillaTiers, ContentTweakerTierRegistry::vanillaLevels)
);

private final BiMap<ResourceLocation, Tier> knownTiers;
private final BiMap<Tier, ResourceLocation> inverse;
private final Int2ObjectMap<Tier> tiersByLevel;

private ContentTweakerTierRegistry(
final Supplier<Map<ResourceLocation, Tier>> vanillaTiers,
final Function<Map<ResourceLocation, Tier>, Map<Integer, Tier>> tierCreator
) {
this.knownTiers = HashBiMap.create(vanillaTiers.get());
this.inverse = this.knownTiers.inverse();
this.tiersByLevel = new Int2ObjectArrayMap<>(tierCreator.apply(this.knownTiers));
}

public static ContentTweakerTierRegistry of() {
return INSTANCE.get();
}

private static Map<ResourceLocation, Tier> vanillaTiers() {
return Arrays.stream(Tiers.values()).collect(Collectors.toMap(it -> new ResourceLocation(it.name().toLowerCase(Locale.ENGLISH)), Function.identity()));
}

private static Map<Integer, Tier> vanillaLevels(final Map<ResourceLocation, Tier> tiers) {
return tiers.values().stream().collect(Collectors.toMap(Tier::getLevel, Function.identity()));
}

public Tier create(
final ResourceLocation name,
final int level,
final int uses,
final float speed,
final float attackDamageBonus,
final int enchantmentValue,
final Supplier<Ingredient> repairItem
) {
if (this.knownTiers.containsKey(name)) {
throw new IllegalArgumentException("Tier already exists: " + name);
}
final Tier tier = new ContentTweakerTier(uses, speed, attackDamageBonus, level, enchantmentValue, Objects.requireNonNull(repairItem));
this.knownTiers.put(name, tier);
if (!this.tiersByLevel.containsKey(level)) { // In Fabric, all tiers with the same level are the same
this.tiersByLevel.put(level, tier);
}
return tier;
}

public ResourceLocation nameOf(final Tier tier) {
return this.inverse.computeIfAbsent(Objects.requireNonNull(tier), it -> {
throw new IllegalStateException("No such tier with name " + it + " is known: either it does not exist or it was not found");
});
}

public Tier ofLevel(final int level) {
return this.tiersByLevel.get(level);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.blamejared.contenttweaker.forge.api.zen.rt;

import com.blamejared.contenttweaker.core.api.ContentTweakerConstants;
import com.blamejared.contenttweaker.core.api.zen.rt.ResourceLocationNative;
import com.blamejared.contenttweaker.vanilla.api.zen.ContentTweakerVanillaConstants;
import com.blamejared.crafttweaker.api.annotation.ZenRegister;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Tier;
import org.openzen.zencode.java.ZenCodeType;

import java.util.Objects;
import java.util.stream.Stream;

@ZenCodeType.Name(ContentTweakerVanillaConstants.VANILLA_RT_PACKAGE + ".TierSortingStruct")
@ZenRegister(loaders = ContentTweakerConstants.CONTENT_LOADER_ID)
public final class TierSortingStruct {

@ZenCodeType.Expansion(ResourceLocationNative.CLASS_NAME)
@ZenRegister(loaders = ContentTweakerConstants.CONTENT_LOADER_ID)
public static final class ResourceLocationCaster {
private ResourceLocationCaster() {}

@ZenCodeType.Caster(implicit = true)
public static TierSortingStruct asTierSortingStruct(final ResourceLocation $this) {
return TierSortingStruct.of($this);
}
}

@ZenCodeType.Expansion(ContentTweakerVanillaConstants.VANILLA_UTIL_PACKAGE + ".Tier")
@ZenRegister(loaders = ContentTweakerConstants.CONTENT_LOADER_ID)
public static final class TierCaster {
private TierCaster() {}

@ZenCodeType.Caster(implicit = true)
public static TierSortingStruct asTierSortingStruct(final Tier $this) {
return TierSortingStruct.of($this);
}
}

@ZenCodeType.Expansion("string")
@ZenRegister(loaders = ContentTweakerConstants.CONTENT_LOADER_ID)
public static final class StringCaster {
private StringCaster() {}

@ZenCodeType.Caster(implicit = true)
public static TierSortingStruct asTierSortingStruct(final String $this) {
return TierSortingStruct.of($this);
}
}

private final ResourceLocation rl;
private final String name;
private final Tier tier;

private TierSortingStruct(final ResourceLocation rl, final String name, final Tier tier) {
this.rl = rl;
this.name = name;
this.tier = tier;
}

static TierSortingStruct of(final ResourceLocation rl) {
return new TierSortingStruct(Objects.requireNonNull(rl), null, null);
}

static TierSortingStruct of(final String name) {
return new TierSortingStruct(null, Objects.requireNonNull(name), null);
}

static TierSortingStruct of(final Tier tier) {
return new TierSortingStruct(null, null, Objects.requireNonNull(tier));
}

public Object get() {
return Stream.of(this.rl, this.name, this.tier).filter(Objects::nonNull).findFirst().orElseGet(Object::new);
}
}

0 comments on commit db63b41

Please sign in to comment.