From 70c1354a4a96698758a88c032866288f79de6f5a Mon Sep 17 00:00:00 2001 From: Benjamin Culkin Date: Sat, 24 Aug 2024 08:16:37 -0400 Subject: Initial commit --- .../java/jp/plusplus/fbs/spirit/SpiritManager.java | 385 +++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 src/main/java/jp/plusplus/fbs/spirit/SpiritManager.java (limited to 'src/main/java/jp/plusplus/fbs/spirit/SpiritManager.java') diff --git a/src/main/java/jp/plusplus/fbs/spirit/SpiritManager.java b/src/main/java/jp/plusplus/fbs/spirit/SpiritManager.java new file mode 100644 index 0000000..1eb7880 --- /dev/null +++ b/src/main/java/jp/plusplus/fbs/spirit/SpiritManager.java @@ -0,0 +1,385 @@ +package jp.plusplus.fbs.spirit; + +import jp.plusplus.fbs.FBS; +import jp.plusplus.fbs.Registry; +import jp.plusplus.fbs.alchemy.AlchemyRegistry; +import jp.plusplus.fbs.alchemy.characteristic.CharacteristicBase; +import jp.plusplus.fbs.alchemy.characteristic.CharacteristicQuality; +import jp.plusplus.fbs.api.event.SpiritTalkEvent; +import jp.plusplus.fbs.exprop.SanityManager; +import jp.plusplus.fbs.item.ItemCore; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemSword; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.FoodStats; +import net.minecraft.util.MathHelper; +import net.minecraft.util.StatCollector; +import net.minecraftforge.common.MinecraftForge; +import shift.sextiarysector.SextiarySector; +import shift.sextiarysector.api.SextiarySectorAPI; +import shift.sextiarysector.packet.PacketPlayerData; +import shift.sextiarysector.packet.SSPacketHandler; +import shift.sextiarysector.player.CustomPlayerData; +import shift.sextiarysector.player.EntityPlayerManager; +import shift.sextiarysector.player.MoistureStats; +import shift.sextiarysector.player.StaminaStats; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Random; + +/** + * Created by plusplus_F on 2015/11/02. + * 精霊の人格の管理、メッセージの表示などを扱う + */ +public class SpiritManager { + private static SpiritManager instance=new SpiritManager(); + + private Random rand=new Random(); + private ArrayList characterMale=new ArrayList(); + private ArrayList characterFemale=new ArrayList(); + private ArrayList tools=new ArrayList(); + + private SpiritManager(){} + + public static void register(){ + registerTool(ItemCore.spiritSword, ItemSword.class); + + registerSpiritCharacter(false, "fbs.alice"); + registerSpiritCharacter(false, "fbs.tama"); + registerSpiritCharacter(false, "fbs.hiyo"); + registerSpiritCharacter(false, "fbs.kako"); + registerSpiritCharacter(true, "fbs.d"); + registerSpiritCharacter(true, "fbs.kouta"); + + SkillManager.register(); + } + + public static void openGui(EntityPlayer player){ + int x= MathHelper.floor_double(player.posX); + int y= MathHelper.floor_double(player.posY); + int z= MathHelper.floor_double(player.posZ); + + player.openGui(FBS.instance, FBS.GUI_SPIRIT_MAIN_ID, player.worldObj, x,y,z); + } + + public static int findSpiritToolIndex(EntityPlayer player){ + int size=player.inventory.getSizeInventory(); + for(int i=0;i tool){ + instance.tools.add(new ToolEntry(spiritTool, tool)); + } + public static ToolEntry getTool(Item item){ + for(ToolEntry te : instance.tools){ + if(te.matches(item)){ + return te; + } + } + return null; + } + public static boolean isTool(Item item){ + return getTool(item)!=null; + } + + /** + * 契約可能な精霊の人格を登録する + * @param isMale trueの場合、それは男性であることを示す + * @param character 精霊の内部名 + */ + public static void registerSpiritCharacter(boolean isMale, String character){ + if(isMale) instance.characterMale.add(character); + else instance.characterFemale.add(character); + } + + /** + * 契約可能な精霊の名前をランダムで取得する + * @param isMale trueの場合、それは男性であることを示す + * @return 精霊の内部名 + */ + public static String getRandomCharacter(boolean isMale){ + if(isMale){ + return instance.characterMale.get(instance.rand.nextInt(instance.characterMale.size())); + } + else{ + return instance.characterFemale.get(instance.rand.nextInt(instance.characterFemale.size())); + } + } + + /** + * 精霊武器アイテムスタックのNBTを更新する + * @param itemStack + * @param status + */ + public static void updateNBT(ItemStack itemStack, SpiritStatus status){ + NBTTagCompound nbt=new NBTTagCompound(); + SpiritStatus.writeToNBT(status, nbt); + itemStack.setTagCompound(nbt); + } + + /** + * ゲーム中に表示される精霊武器の名前を取得する + * @param itemStack + * @return + */ + public static String getSpiritDisplayName(ItemStack itemStack){ + SpiritStatus ss=SpiritStatus.readFromNBT(itemStack.getTagCompound()); + if(ss==null) return "Unnamed"; + return StatCollector.translateToLocal("item.fbs.spirit.name").replaceAll("%owner%", ss.getOwnerName()).replaceAll("%spirit%", ss.getName()); + } + + /** + * プレイヤーに対し精霊が話しかける。 + * メッセージは最大で10行(0-9) + * @param player 対象プレイヤー + * @param character 人格 + * @param event イベント + * @param params その他引数 + */ + public static void talk(EntityPlayer player, String character, String event, @Nullable ItemStack spiritToolStack, Object ... params){ + if(player.worldObj.isRemote) return; + + ItemStack itemStack=null; + SpiritStatus status=null; + + if(spiritToolStack!=null){ + itemStack=spiritToolStack; + } + else{ + itemStack=findSpiritTool(player); + } + if(itemStack==null) return; + status=SpiritStatus.readFromNBT(itemStack.getTagCompound()); + if(status==null) return; + + if(!status.isOwner(player)) return; + + //設定を確認する + if(event.equals("morning") || event.equals("noon") || event.equals("night")){ + if(!status.getConfiguration().get("enableTimeSignalMessage") && !status.getConfiguration().get("enableMessage")) return; + } + else if(!status.getConfiguration().get("enableMessage")){ + return; + } + + SpiritTalkEvent ste=new SpiritTalkEvent(player, character, event, params); + boolean isCanceled=MinecraftForge.EVENT_BUS.post(ste); + if(!isCanceled){ + + for(int i=0;i<10;i++){ + String m="spirit.talk."+character+"."+event+"."+i; + if(!StatCollector.canTranslate(m)) break; + + m=translateString(m, status); + player.addChatComponentMessage(new ChatComponentText("<"+spiritToolStack.getDisplayName()+">"+m)); + } + } + } + + /** + * いい感じにローカライズする + * @param key + * @param status + * @return + */ + public static String translateString(String key, SpiritStatus status, Object ... params){ + String m=StatCollector.translateToLocal(key); + m=m.replaceAll("%spirit%", status.getName()); + m=m.replaceAll("%owner%", status.getOwnerName()); + return m; + } + + public static void addInformation(ItemStack itemStack, EntityPlayer player, List list, boolean flag){ + ISpiritTool ist=(ISpiritTool)itemStack.getItem(); + SpiritStatus ss=SpiritStatus.readFromNBT(itemStack.getTagCompound()); + + list.add("[Status]"); + list.add("Level:"+ss.getLv()); + list.add(String.format("Damage:%.1f", ist.calcDamage(ss)+0.5)); + list.add("Harvest Level:"+ist.calcDigLv(ss)); + + int t=ist.calcDurable(ss); + list.add("Durability:"+(t-ss.getItemDamage())+"/"+t); + } + + /** + * 精霊の祝福 + * @param player + */ + public static void bless(EntityPlayer player, ItemStack tool){ + SpiritStatus status=SpiritStatus.readFromNBT(tool.getTagCompound()); + //もうめんどくさいんでハードコード + + //ライフ・満腹度・水分・スタミナのいずれか + int r=instance.rand.nextInt(FBS.cooperatesSS2?4:2); + switch (r){ + case 0: + player.heal(player.getMaxHealth()); + player.addChatComponentMessage(new ChatComponentText(StatCollector.translateToLocal("spirit.bless.fbs.health"))); + break; + + case 1: + FoodStats fs=player.getFoodStats(); + fs.addStats(20, 1.f); + player.addChatComponentMessage(new ChatComponentText(StatCollector.translateToLocal("spirit.bless.fbs.food"))); + break; + + case 2: + instance.blessForSS2(player, 0); + player.addChatComponentMessage(new ChatComponentText(StatCollector.translateToLocal("spirit.bless.fbs.moisture"))); + break; + + case 3: + instance.blessForSS2(player, 1); + player.addChatComponentMessage(new ChatComponentText(StatCollector.translateToLocal("spirit.bless.fbs.stamina"))); + break; + } + + + //さらに、マイナス効果を全て打ち消しランダムでエンチャント効果 + ItemStack dummy=new ItemStack(Items.milk_bucket); + player.curePotionEffects(dummy); + + Potion p; + switch (instance.rand.nextInt(13)){ + case 0: p=Potion.damageBoost; break; + case 1: p=Potion.digSpeed; break; + case 2: p=Potion.fireResistance; break; + case 3: p=Potion.invisibility; break; + case 4: p=Potion.moveSpeed; break; + case 5: p=Potion.jump; break; + case 6: p=Potion.nightVision; break; + case 7: p=Potion.nightVision; break; + case 8: p=Potion.regeneration; break; + case 9: p=Potion.resistance; break; + case 10: p=Potion.waterBreathing; break; + case 11: p=Registry.potionCleverness; break; + case 12: p=Registry.potionContract; break; + default: p=Potion.heal; break; + } + + player.addPotionEffect(new PotionEffect(p.getId(), 20*(60+3*status.getLv()), status.getLv()/15)); + status.updateLastBlessDate(player.worldObj.getCurrentDate().get(Calendar.DATE)); + + NBTTagCompound nbt=new NBTTagCompound(); + SpiritStatus.writeToNBT(status, nbt); + tool.setTagCompound(nbt); + + //精霊の涙 + ItemStack tear=AlchemyRegistry.getItemStack(ItemCore.alchemyMaterial, status.hasSkill("fbs.sentimental")?2:1, 40); + if(player.inventory.addItemStackToInventory(tear) && tear.stackSize>0){ + player.entityDropItem(tear, 0); + } + + talk(player, status.getCharacter(), "bless", tool); + } + + /** + * 精霊の修理 + * @param player + * @param tool + * @param potionIndex + */ + public static void repair(EntityPlayer player, ItemStack tool, int potionIndex){ + if(potionIndex==-1){ + int s=player.inventory.getSizeInventory(); + for(int i=0;i cbs=AlchemyRegistry.ReadCharacteristicFromNBT(potion.getTagCompound()); + for(CharacteristicBase cb :cbs){ + if(cb instanceof CharacteristicQuality){ + scale=cb.getMPScale(); + break; + } + } + + //回復する + SpiritStatus status=SpiritStatus.readFromNBT(tool.getTagCompound()); + status.repair((int)(500*scale)); + + //更新 + NBTTagCompound nbt1=new NBTTagCompound(); + SpiritStatus.writeToNBT(status, nbt1); + tool.setTagCompound(nbt1); + } + + public void blessForSS2(EntityPlayer player, int type){ + if(type==0){ + SextiarySectorAPI.addMoistureStats(player, 20, 20); + } + else{ + SextiarySectorAPI.addStaminaStats(player, 100, 50); + } + + if(player instanceof EntityPlayerMP) SSPacketHandler.INSTANCE.sendTo(new PacketPlayerData(EntityPlayerManager.getCustomPlayerData(player)), (EntityPlayerMP)player); + } + + /** + * 使用した武器と精霊武器のクラスを関連付ける。 + */ + public static class ToolEntry{ + private Class tool; + private Item spiritTool; + + public ToolEntry(Item spiritTool, Class tool){ + this.spiritTool=spiritTool; + this.tool=tool; + } + + public boolean matches(Item item){ + return tool.isAssignableFrom(item.getClass()); + } + + public ItemStack getSpiritToolStack(boolean isMale, String character, String name, EntityPlayer owner, ItemStack material){ + ItemStack ret=new ItemStack(spiritTool); + SpiritStatus ss=new SpiritStatus(isMale, character, name, owner); + + //先天スキルの設定 + float r=new Random().nextFloat(); + if(r<0.05f) ss.setSkill("fbs.precocious", 0); + else if(r<0.10f) ss.setSkill("fbs.lateBloomer", 0); + else if(r<0.15f) ss.setSkill("fbs.hero", 0); + else if(r<0.20f) ss.setSkill("fbs.skillful", 0); + else if(r<0.25f) ss.setSkill("fbs.sentimental", 0); + + ((ISpiritTool) spiritTool).calcInitialValue(ss, material); + updateNBT(ret, ss); + + SanityManager.setSpirit(owner, ss.getName(), ss.getLv()); + + return ret; + } + } +} -- cgit v1.2.3