From 70c1354a4a96698758a88c032866288f79de6f5a Mon Sep 17 00:00:00 2001 From: Benjamin Culkin Date: Sat, 24 Aug 2024 08:16:37 -0400 Subject: Initial commit --- .../jp/plusplus/fbs/alchemy/AlchemyRegistry.java | 907 +++++++++++++++++++++ 1 file changed, 907 insertions(+) create mode 100644 src/main/java/jp/plusplus/fbs/alchemy/AlchemyRegistry.java (limited to 'src/main/java/jp/plusplus/fbs/alchemy/AlchemyRegistry.java') diff --git a/src/main/java/jp/plusplus/fbs/alchemy/AlchemyRegistry.java b/src/main/java/jp/plusplus/fbs/alchemy/AlchemyRegistry.java new file mode 100644 index 0000000..c14952b --- /dev/null +++ b/src/main/java/jp/plusplus/fbs/alchemy/AlchemyRegistry.java @@ -0,0 +1,907 @@ +package jp.plusplus.fbs.alchemy; + +import jp.plusplus.fbs.FBS; +import jp.plusplus.fbs.alchemy.characteristic.*; +import jp.plusplus.fbs.item.ItemCore; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.util.StatCollector; +import net.minecraftforge.oredict.OreDictionary; + +import java.util.*; + +/** + * Created by plusplus_F on 2015/09/08. + * たぶん錬金術はわりと規模がでかくなると思うんで分離 + */ +public class AlchemyRegistry { + //特性 + private ArrayList> characteristics=new ArrayList>(); + private HashMap, Integer> characteristicsIdMap=new HashMap, Integer>(); + //素材 + private HashMap> materials=new HashMap>(); + private HashMap> materialNames=new HashMap>(); + //鑑定 + private HashMap> appraisalItems=new HashMap>(); + //調合 + private ArrayList recipes=new ArrayList(); + private ArrayList productExpPairs=new ArrayList(); + //カゴ + private ArrayList basketItems=new ArrayList(); + + private static AlchemyRegistry instance=new AlchemyRegistry(); + private static Random rand=new Random(); + + private AlchemyRegistry(){} + + public static Random getRandom(){ return instance.rand; } + + + public static void RegisterAlchemy(){ + //------------------------------------------------------------------------------------------------------- + // 特性 + //------------------------------------------------------------------------------------------------------- + AddCharacteristic(CharacteristicSanity.Gain.class); + AddCharacteristic(CharacteristicSanity.Lose.class); + AddCharacteristic(CharacteristicHealth.Gain.class); + AddCharacteristic(CharacteristicHealth.Lose.class); + if(FBS.cooperatesSS2){ + AddCharacteristic(CharacteristicWater.Gain.class); + AddCharacteristic(CharacteristicWater.Lose.class); + AddCharacteristic(CharacteristicStamina.Gain.class); + AddCharacteristic(CharacteristicStamina.Lose.class); + } + AddCharacteristic(CharacteristicExp.Gain.class); + AddCharacteristic(CharacteristicExp.Lose.class); + AddCharacteristic(CharacteristicLook.class); + AddCharacteristic(CharacteristicWeight.class); + AddCharacteristic(CharacteristicQuality.class); + AddCharacteristic(CharacteristicCleverness.Gain.class); + AddCharacteristic(CharacteristicPoison.Gain.class); + AddCharacteristic(CharacteristicPoison.Lose.class); + AddCharacteristic(CharacteristicPower.Gain.class); + AddCharacteristic(CharacteristicPower.Lose.class); + AddCharacteristic(CharacteristicSpeed.Gain.class); + AddCharacteristic(CharacteristicSpeed.Lose.class); + AddCharacteristic(CharacteristicConfusion.Gain.class); + AddCharacteristic(CharacteristicConfusion.Lose.class); + + //------------------------------------------------------------------------------------------------------- + // 鑑定 + //------------------------------------------------------------------------------------------------------- + RegisterAppraisal(new ItemStack(Items.potionitem), new ItemStack(ItemCore.alchemyMaterial, 1, 0), 63); + RegisterAppraisal(new ItemStack(Items.potionitem), new ItemStack(ItemCore.alchemyMaterial, 1, 1), 1); + RegisterAppraisal(new ItemStack(Items.lava_bucket), new ItemStack(ItemCore.alchemyMaterial, 1, 2), 1); + + RegisterAppraisal("treeLeaves", new ItemStack(ItemCore.alchemyMaterial, 1, 3), 63); + RegisterAppraisal("treeLeaves", new ItemStack(ItemCore.alchemyMaterial, 1, 6), 1); + RegisterAppraisal(new ItemStack(Items.stick), new ItemStack(ItemCore.alchemyMaterial, 1, 4), 63); + RegisterAppraisal(new ItemStack(Items.stick), new ItemStack(ItemCore.alchemyMaterial, 1, 7), 1); + + for(int i=0;i45)){ + RegisterAppraisal(new ItemStack(ItemCore.mushroomUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, i), 10); + } + } + RegisterAppraisal(new ItemStack(ItemCore.herbUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 18), 60); + RegisterAppraisal(new ItemStack(ItemCore.herbUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 36), 3); + RegisterAppraisal(new ItemStack(ItemCore.herbUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 37), 3); + + RegisterAppraisal(new ItemStack(ItemCore.mushroomUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 25), 50); + RegisterAppraisal(new ItemStack(ItemCore.mushroomUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 42), 3); + RegisterAppraisal(new ItemStack(ItemCore.mushroomUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 43), 3); + RegisterAppraisal(new ItemStack(ItemCore.mushroomUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 44), 3); + RegisterAppraisal(new ItemStack(ItemCore.mushroomUnknown), new ItemStack(ItemCore.alchemyMaterial, 1, 45), 3); + + for(int i=0;i chara){ + instance.characteristics.add(chara); + instance.characteristicsIdMap.put(chara, instance.characteristics.size()-1); + } + + /** + * 特性からIdを得る + * @param chara + * @return + */ + public static int GetCharacteristicId(Class chara){ + if(!instance.characteristicsIdMap.containsKey(chara)){ + AddCharacteristic(chara); + } + + return instance.characteristicsIdMap.get(chara); + } + + /** + * Idから特性を得る + * @param id + * @return + */ + public static Class GetCharacteristicFromId(int id){ + if(id<0 || id>=instance.characteristics.size()) return null; + return instance.characteristics.get(id); + } + + /** + * 特性のリストをnbtに書き込む + * @param nbt + * @param list + */ + public static void WriteCharacteristicToNBT(NBTTagCompound nbt, ArrayList list){ + NBTTagList tags=new NBTTagList(); + for(CharacteristicBase cb : list){ + NBTTagCompound tag=new NBTTagCompound(); + tag.setInteger("id", cb.getId()); + cb.writeToNBT(tag); + tags.appendTag(tag); + } + + nbt.setTag("characteristics", tags); + nbt.setBoolean("appraisal", true); + } + + /** + * nbtから特性リストを得る + * @param nbt + * @return + */ + public static ArrayList ReadCharacteristicFromNBT(NBTTagCompound nbt){ + ArrayList ret=new ArrayList(); + + if(nbt!=null && nbt.hasKey("characteristics")){ + NBTTagList tags=(NBTTagList)nbt.getTag("characteristics"); + for(int i=0;i cbs=AlchemyRegistry.ReadCharacteristicFromNBT(itemStack.getTagCompound()); + + for(CharacteristicBase cb : cbs){ + list.add(cb.getNameColor()+"-"+cb.getLocalizedName()+":"+cb.getLocalizedEffectValue()); + } + } + } + + //-------------------------------------------------------------------------------------- + // 素材 + //-------------------------------------------------------------------------------------- + + /** + * 素材としてアイテムスタックを登録する + * @param name + * @param itemStack + */ + public static void RegisterMaterial(String name, ItemStack itemStack){ + if(!instance.materials.containsKey(name)){ + ArrayList list=new ArrayList(); + instance.materials.put(name, list); + } + + instance.materials.get(name).add(itemStack); + RegisterMaterialName(itemStack, name); + } + + /** + * アイテムスタックがその素材として使えるかを返す + * @param name + * @param itemStack + * @return + */ + public static boolean IsMatching(String name, ItemStack itemStack){ + if(!instance.materials.containsKey(name)) return false; + ArrayList list=instance.materials.get(name); + + for(ItemStack item : list){ + if(item.isItemEqual(itemStack)){ + return true; + } + } + + return false; + } + + private static Map.Entry> cachedMaterial; + /** + * アイテムスタックの持つ素材名を得る + * @param itemStack + * @return + */ + public static ArrayList GetMaterialNames(ItemStack itemStack){ + if(cachedMaterial!=null && cachedMaterial.getKey().isItemEqual(itemStack)){ + return cachedMaterial.getValue(); + } + + for(Map.Entry> e : instance.materialNames.entrySet()){ + if(e.getKey().isItemEqual(itemStack)){ + cachedMaterial=e; + return e.getValue(); + } + } + return null; + } + private static void RegisterMaterialName(ItemStack itemStack, String name){ + ArrayList list=GetMaterialNames(itemStack); + + if(list!=null){ + //素材名リストがある場合直接追加 + list.add(name); + } + else{ + //素材名リストがない場合リスト作ってマップに追加 + list=new ArrayList(); + list.add(name); + + instance.materialNames.put(itemStack, list); + } + } + + /** + * listに素材名一覧を追加する + * @param itemStack + * @param list + * @param flag + */ + public static void AddMaterialInfo(ItemStack itemStack, List list, boolean flag){ + list.add(StatCollector.translateToLocal("alchemy.fbs.material")); + ArrayList names= AlchemyRegistry.GetMaterialNames(itemStack); + if(names!=null && !names.isEmpty()){ + for(String str : names){ + list.add("-"+str); + } + } + } + //-------------------------------------------------------------------------------------- + // 鑑定 + //-------------------------------------------------------------------------------------- + + /** + * 鑑定アイテムを登録する + * @param input + * @param output 鑑定品(ItemはIAlchemyMaterialを継承しておくこと) + * @param weight 出現重み + */ + public static void RegisterAppraisal(ItemStack input, ItemStack output, int weight){ + AppraisalItemStack ais=new AppraisalItemStack(input); + ArrayList list=GetAppraisals(ais); + list.add(new WeightedItemStack(weight, output)); + } + /** + * 鑑定アイテムを登録する(鉱石辞書編) + * @param input + * @param output 鑑定品(ItemはIAlchemyMaterialを継承しておくこと) + * @param weight 出現重み + */ + public static void RegisterAppraisal(String input, ItemStack output, int weight){ + AppraisalItemStack ais=new AppraisalItemStack(input); + ArrayList list=GetAppraisals(ais); + list.add(new WeightedItemStack(weight, output)); + } + private static ArrayList GetAppraisals(AppraisalItemStack ais){ + ArrayList list; + + for(AppraisalItemStack aiss : instance.appraisalItems.keySet()){ + if(aiss.equals(ais)){ + return instance.appraisalItems.get(aiss); + } + } + list=new ArrayList(); + instance.appraisalItems.put(ais, list); + return list; + } + + public static ArrayList GetAppraisalList(ItemStack input){ + for(AppraisalItemStack aiss : instance.appraisalItems.keySet()){ + if(aiss.isItemEqual(input)) return instance.appraisalItems.get(aiss); + } + return null; + } + public static ArrayList GetAlllAppraisal(){ + ArrayList ret=new ArrayList(); + for(Map.Entry> e : instance.appraisalItems.entrySet()){ + for(WeightedItemStack wis : e.getValue()){ + ret.add(new ItemPair(e.getKey().getItemStack(), wis.getItemStack())); + } + } + return ret; + } + + /** + * そのアイテムが鑑定できるか判定する + * @param input + * @return + */ + public static boolean CanAppraisal(ItemStack input){ + NBTTagCompound nbt=input.getTagCompound(); + if(nbt!=null && nbt.getBoolean("appraisal")) return false; + + return GetAppraisalList(input)!=null; + } + + /** + * 鑑定したアイテムを得る。この時ランダムで特性が付与される。 + * @param input + * @return 鑑定できないアイテムであればnull + */ + public static ItemStack GetRandomAppraisal(ItemStack input){ + ArrayList list=GetAppraisalList(input); + if(list.isEmpty()) return null; + + int ws=0; + for(WeightedItemStack wis : list){ + ws+=wis.getWeight(); + } + + int r=instance.rand.nextInt(ws); + ws=0; + for(int i=0;i cList=((IAlchemyMaterial)ret.getItem()).addCharacteristics(ret, instance.rand); + if(cList!=null && !cList.isEmpty()){ + ret.setTagCompound(new NBTTagCompound()); + WriteCharacteristicToNBT(ret.getTagCompound(), cList); + // FBS.logger.info("written"); + } + //FBS.logger.info(cList.toString()); + + return ret; + } + ws+=wis.getWeight(); + } + + return null; + } + + + //-------------------------------------------------------------------------------------- + // 調合 + //-------------------------------------------------------------------------------------- + private static Recipe cachedRecipe; + public static void RegisterRecipe(ItemStack key, ItemStack output, int lv, float prob, double exp, String ... materials){ + instance.recipes.add(new Recipe(lv, prob, key, output, materials)); + RegisterProductExpPair(output, exp); + } + public static Recipe GetRecipe(ItemStack key){ + if(cachedRecipe!=null && cachedRecipe.isKey(key)) return cachedRecipe; + + for(Recipe r : instance.recipes){ + if(r.isKey(key)){ + cachedRecipe=r; + return cachedRecipe; + } + } + + return null; + } + /** + * レシピと投入済み素材リストから、inputが未投入の素材か判定する + * @param key + * @param input + * @param inputMaterials + * @return + */ + public static boolean IsMaterial(ItemStack key, ItemStack input, ArrayList inputMaterials){ + //レシピを得る + Recipe r=GetRecipe(key); + return IsMaterial(r, input, inputMaterials); + } + public static boolean IsMaterial(Recipe recipe, ItemStack input, ArrayList inputMaterials){ + if(recipe==null) return false; + + //matから未投入素材リストを得る + LinkedList mats=recipe.getMaterialList(); + LinkedList tmp=new LinkedList(inputMaterials); + for(int i=0;i inputMaterials){ + return IsSatisfied(GetRecipe(key), inputMaterials); + } + public static boolean IsSatisfied(Recipe recipe, ArrayList inputMaterials){ + if(recipe==null) return false; + + //matから未投入素材リストを得る + LinkedList mats=recipe.getMaterialList(); + + //投入素材数が違うのに条件を満たしているはずがないだろ! + if(inputMaterials.size()!=mats.size()){ + return false; + } + + //投入素材リストを走査し、必要素材リストの中身を抜いていく + LinkedList tmp=new LinkedList(inputMaterials); + for(int i=0;i inputMaterials){ + Recipe r=GetRecipe(key); + ItemStack ret=r.getProduct(); + + IAlchemyProduct prod=((IAlchemyProduct) ret.getItem()); + ArrayList characteristics;//完成品の持つ特性 + + //------------------------初期特性------------------------------ + characteristics=prod.getDefaultCharacteristics(ret, instance.rand); + + //-----------------------引継ぎ特性----------------------------- + LinkedList inherits=new LinkedList(); + for(ItemStack mat : inputMaterials){ + ArrayList aList=ReadCharacteristicFromNBT(mat.getTagCompound()); + for(CharacteristicBase cb : aList){ + if(prod.canInherit(ret, cb)) inherits.add(cb); + } + } + + //-----------------------引継ぎ判定----------------------------- + int max=prod.getMaxInheritAmount(ret); + for(int i=0;i inputMaterials){ + ItemStack ret=recipe.getProduct().copy(); + + IAlchemyProduct prod=((IAlchemyProduct) ret.getItem()); + ArrayList characteristics;//完成品の持つ特性 + + //------------------------初期特性------------------------------ + characteristics=prod.getDefaultCharacteristics(ret, instance.rand); + + //-----------------------引継ぎ特性----------------------------- + LinkedList inherits=new LinkedList(); + for(ItemStack mat : inputMaterials){ + ArrayList aList=ReadCharacteristicFromNBT(mat.getTagCompound()); + for(CharacteristicBase cb : aList){ + if(prod.canInherit(ret, cb)) inherits.add(cb); + } + } + + //-----------------------引継ぎ判定----------------------------- + int max=prod.getMaxInheritAmount(ret); + for(int i=0;i GetRecieps(){ + return instance.recipes; + } + + private static ProductExpPair cachedPEP; + public static void RegisterProductExpPair(ItemStack p, double e){ + instance.productExpPairs.add(new ProductExpPair(p, e)); + } + public static double GetProductExp(ItemStack p){ + if(cachedPEP!=null && cachedPEP.isItemEqual(p)){ + return cachedPEP.getExp(); + } + + for(ProductExpPair pep : instance.productExpPairs){ + if(pep.isItemEqual(p)){ + cachedPEP=pep; + return pep.getExp(); + } + } + + return 0; + } + + private static ItemStack cachedBasketItem; + public static void RegisterBasketItem(ItemStack itemStack){ + instance.basketItems.add(itemStack); + } + public static boolean isBasketItem(ItemStack itemStack){ + if(cachedBasketItem!=null && cachedBasketItem.isItemEqual(itemStack)) return true; + + for(ItemStack is : instance.basketItems){ + if(is.isItemEqual(itemStack)){ + cachedBasketItem=is; + return true; + } + } + return false; + } + + //------------------------------------------------------------------------------------- + public static class AppraisalItemStack{ + private boolean isOre; + private int oreId; + private ItemStack itemStack; + + public AppraisalItemStack(ItemStack item){ + isOre=false; + itemStack=item; + } + public AppraisalItemStack(String oreId){ + isOre=true; + this.oreId= OreDictionary.getOreID(oreId); + } + public boolean isItemEqual(ItemStack m){ + if (isOre){ + int[] ids=OreDictionary.getOreIDs(m); + for(int i : ids){ + if(i==oreId) return true; + } + return false; + } + else{ + return itemStack.isItemEqual(m); + } + } + + public ItemStack getItemStack(){ + if(itemStack==null && isOre){ + itemStack=OreDictionary.getOres(OreDictionary.getOreName(oreId)).get(0).copy(); + } + return itemStack; + } + + @Override + public boolean equals(Object obj){ + if(obj instanceof AppraisalItemStack){ + AppraisalItemStack ais=(AppraisalItemStack)obj; + if(isOre!=ais.isOre) return false; + return isOre?oreId==ais.oreId:itemStack.isItemEqual(ais.itemStack); + } + return false; + } + } + public static class WeightedItemStack{ + private int weight; + private ItemStack itemStack; + + public WeightedItemStack(int w, ItemStack stack){ + weight=w; + itemStack=stack; + } + + public int getWeight(){ return weight; } + public ItemStack getItemStack(){ return itemStack; } + + } + public static class Recipe{ + protected int level; + protected float prob; + protected ItemStack key; + protected ItemStack output; + protected String[] materials; + + public Recipe(int level, float prob, ItemStack key, ItemStack output, String ... materials){ + this.level=level; + this.prob=prob; + this.key=key; + this.output=output; + this.materials=materials; + } + + public ItemStack getKey(){ return key; } + public boolean isKey(ItemStack itemStack){ + return key.isItemEqual(itemStack); + } + public ItemStack getProduct(){ + return output; + } + public int getLevel(){ return level; } + public float getProb(){ return prob; } + + public LinkedList getMaterialList(){ + LinkedList list=new LinkedList(); + for(String n : materials) list.add(n); + return list; + } + } + public static class ProductExpPair{ + public ItemStack product; + public double exp; + + public ProductExpPair(ItemStack p, double e){ + product=p; + exp=e; + } + public boolean isItemEqual(ItemStack item){ + return product.isItemEqual(item); + } + public double getExp(){ + return exp; + } + } + public static class ItemPair{ + private ItemStack item1; + private ItemStack item2; + public ItemPair(ItemStack i1, ItemStack i2){ + item1=i1; + item2=i2; + } + public ItemStack getItem1(){ return item1; } + public ItemStack getItem2(){ return item2; } + } +} -- cgit v1.2.3