package minefantasy.mf2.mechanics; import java.util.Iterator; import java.util.List; import java.util.Random; import minefantasy.mf2.MineFantasyII; import minefantasy.mf2.api.MineFantasyAPI; import minefantasy.mf2.api.archery.AmmoMechanicsMF; import minefantasy.mf2.api.archery.IFirearm; import minefantasy.mf2.api.armour.CogworkArmour; import minefantasy.mf2.api.heating.IHotItem; import minefantasy.mf2.api.helpers.ArmourCalculator; import minefantasy.mf2.api.helpers.PlayerTagData; import minefantasy.mf2.api.helpers.TacticalManager; import minefantasy.mf2.api.knowledge.ResearchLogic; import minefantasy.mf2.api.rpg.RPGElements; import minefantasy.mf2.api.rpg.SkillList; import minefantasy.mf2.config.ConfigHardcore; import minefantasy.mf2.config.ConfigMobs; import minefantasy.mf2.config.ConfigWeapon; import minefantasy.mf2.entity.mob.EntityDragon; import minefantasy.mf2.item.armour.ItemApron; import minefantasy.mf2.item.food.ItemFoodMF; import minefantasy.mf2.item.gadget.ItemCrossbow; import minefantasy.mf2.item.list.ToolListMF; import minefantasy.mf2.item.weapon.ItemWeaponMF; import minefantasy.mf2.util.MFLogUtil; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ChatComponentText; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.StatCollector; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.WorldServer; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.PlayerEvent; import cpw.mods.fml.common.gameevent.TickEvent; public class PlayerTickHandlerMF { private static Random rand = new Random(); private static ItemStack lastStack; //SPRINT JUMPING //DEFAULT:= 0:22 (50seconds till starve, 35s till nosprint) (16m in MC time for 4 missing bars) //SLOW=5: = 2:20 (5mins till starve, 3:30 till nosprint) (1h 40m in MC time for 4 missing bars) //EXHAUSTION SCALE = 3.0F = 1hunger @SubscribeEvent public void onPlayerTick(TickEvent.PlayerTickEvent event) { if(event.phase == TickEvent.Phase.END) { ItemStack held = event.player.getHeldItem(); if(held != null) { int parry = ItemWeaponMF.getParry(held); if(parry > 0) { ItemWeaponMF.setParry(held, parry-1); } } //COMMON TacticalManager.applyArmourWeight(event.player); if(event.player.ticksExisted % 20 == 0) { CogworkArmour.updateVars(event.player); if(event.player.isBurning() && TacticalManager.getResistance(event.player, DamageSource.inFire) <= 0.0F) { event.player.extinguish(); } CogworkArmour.tickUser(event.player); } if(event.player.worldObj.isRemote) { if(isNextStep(event.player)) { onStep(event.player, event.player.getEntityData().getInteger(stepNBT) % 2 == 0); } } /* if(RPGElements.isSystemActive) { if(event.player.isSprinting() && event.player.ticksExisted % 10 == 0) { SkillList.athletics.addXP(event.player, 1); } else if(event.player.isSneaking() && TacticalManager.isEntityMoving(event.player) && event.player.ticksExisted % 10 == 0) { SkillList.sneak.addXP(event.player, 1); } } */ //CLIENT if(event.player.worldObj.isRemote) { playSounds(event.player); } //DRAGON EVENT if(!event.player.worldObj.isRemote) { tickDragonSpawner(event.player); } //updatePitch(event.player); (This keeps track of player camera angles, could make a mechanic based on swinging the camera) } if(event.phase == TickEvent.Phase.START) { applyBalance(event.player); ItemFoodMF.onTick(event.player); if(!event.player.worldObj.isRemote && !(!ConfigHardcore.HCChotBurn && ItemApron.isUserProtected(event.player)) && event.player.ticksExisted % 100 == 0) { for(int a = 0; a < event.player.inventory.getSizeInventory(); a++) { ItemStack item = event.player.inventory.getStackInSlot(a); if(item != null && item.getItem() instanceof IHotItem) { event.player.setFire(5); event.player.attackEntityFrom(DamageSource.onFire, 1.0F); } } } if(event.player.worldObj.isRemote) { ItemStack item = event.player.getHeldItem(); if(lastStack == null && item != null) { if(item.getItem() instanceof IFirearm) { NBTTagCompound nbt = AmmoMechanicsMF.getNBT(item); if(nbt.hasKey(ItemCrossbow.useTypeNBT) && nbt.getString(ItemCrossbow.useTypeNBT).equalsIgnoreCase("fire")) { nbt.setString(ItemCrossbow.useTypeNBT, "null"); } } } if(lastStack != null && (item == null || item != lastStack)) { if(lastStack.getItem() instanceof IFirearm) { NBTTagCompound nbt = AmmoMechanicsMF.getNBT(lastStack); if(nbt.hasKey(ItemCrossbow.useTypeNBT) && nbt.getString(ItemCrossbow.useTypeNBT).equalsIgnoreCase("fire")) { nbt.setString(ItemCrossbow.useTypeNBT, "null"); } } } lastStack = item; } float weight = ArmourCalculator.getTotalWeightOfWorn(event.player, false); if(weight > 100F) { if(event.player.isInWater()) { event.player.motionY -= (weight/20000F); } } } } private void onStep(EntityPlayer player, boolean alternateStep) { if(CogworkArmour.isWearingAnyCogwork(player)) { String s = alternateStep ? "in" : "out"; player.playSound("tile.piston."+s, 0.5F, 1.0F); float f1 = 2.0F; //player.rotationPitch += (alternateStep ? f1 : -f1); CogworkArmour.onStep(player); } else if(ArmourCalculator.getTotalWeightOfWorn(player, false) >= 50) { player.playSound("mob.irongolem.throw", 1.0F, 1.0F); } } private static String stepNBT = "MF_LastStep"; private boolean isNextStep(EntityPlayer player) { int prevStep = player.getEntityData().getInteger(stepNBT); int stepcount = (int) player.distanceWalkedOnStepModified; player.getEntityData().setInteger(stepNBT, stepcount); return prevStep != stepcount; } /* private static String lastPitchNBT = "MF_last_AimPitch"; public static void setLastPitch(EntityPlayer user, float value) { user.getEntityData().setFloat(lastPitchNBT, value); } public static void updatePitch(EntityPlayer user) { user.getEntityData().setFloat(lastPitchNBT, user.rotationPitch); } public static float getPitchMovement(EntityPlayer user) { float lastPitch = user.getEntityData().getFloat(lastPitchNBT) + 1000F; float nowPitch = user.rotationPitch + 1000F; return nowPitch - lastPitch; } */ private void tickDragonSpawner(EntityPlayer player) { if(player.worldObj.difficultySetting != EnumDifficulty.PEACEFUL && player.dimension == 0) { int i = ConfigMobs.dragonInterval; float chance = ConfigMobs.dragonChance; if(this.getDragonEnemyPoints(player) >= 100) { i /= 2;//twice as frequent } if(this.getDragonEnemyPoints(player) >= 50) { chance *= 2;//twice the chance } if(!player.worldObj.isRemote && player.worldObj.getTotalWorldTime() % i == 0 && rand.nextFloat()*100F < chance) { spawnDragon(player); } } } public static void spawnDragon(EntityPlayer player) { spawnDragon(player, 64); } public static void spawnDragon(EntityPlayer player, int offset) { int y = (int) (player.posY + offset); boolean canMobSpawn = !player.worldObj.isRemote && canDragonSpawnOnPlayer(player, y); if(canMobSpawn && !player.worldObj.isRemote) { int tier = getDragonTier(player);//Gets tier on kills EntityDragon dragon = new EntityDragon(player.worldObj); dragon.setPosition(player.posX, y, player.posZ); player.worldObj.spawnEntityInWorld(dragon); dragon.setDragon(tier); dragon.disengage(100); player.worldObj.playSoundEffect(dragon.posX, dragon.posY-16D, dragon.posZ, "mob.enderdragon.growl", 3.0F, 1.5F); dragon.fireBreathCooldown = 200; if(ConfigMobs.dragonMSG && !player.worldObj.isRemote) { player.addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + StatCollector.translateToLocal("event.dragonnear.name"))); List list = player.worldObj.playerEntities; Iterator players = list.iterator(); while(players.hasNext()) { Object instance = players.next(); if(instance != null && instance instanceof EntityPlayer) { if(((EntityPlayer)instance).getDistanceToEntity(player) < 256D && instance != player) { ((EntityPlayer)instance).addChatMessage(new ChatComponentText(EnumChatFormatting.GOLD + StatCollector.translateToLocal("event.dragonnear.name"))); } } } } } } private static boolean canDragonSpawnOnPlayer(EntityPlayer player, int y) { for(int x = -3; x <= 3; x++) { for(int z = -3; z <= 3; z++) { if(!player.worldObj.canBlockSeeTheSky((int)player.posX + x, y, (int)player.posZ + z)) { return false; } } } return true; } private void playSounds(EntityPlayer user) { } private void applyBalance(EntityPlayer entityPlayer) { float weight = 2.0F; float pitchBalance = entityPlayer.getEntityData().hasKey("MF_Balance_Pitch") ? entityPlayer.getEntityData().getFloat("MF_Balance_Pitch"): 0F; float yawBalance = entityPlayer.getEntityData().hasKey("MF_Balance_Yaw") ? entityPlayer.getEntityData().getFloat("MF_Balance_Yaw"): 0F; if(pitchBalance > 0) { if(pitchBalance < 1.0F && pitchBalance > -1.0F)weight = pitchBalance; pitchBalance -= weight; if(ConfigWeapon.useBalance) { entityPlayer.rotationPitch += pitchBalance > 0 ? weight : -weight; } if(pitchBalance < 0)pitchBalance = 0; } if(yawBalance > 0) { if(yawBalance < 1.0F && yawBalance > -1.0F)weight = yawBalance; yawBalance -= weight; if(ConfigWeapon.useBalance) { MFLogUtil.logDebug("Weapon Balance Move"); entityPlayer.rotationYaw += yawBalance > 0 ? weight : -weight; } if(yawBalance < 0)yawBalance = 0; } entityPlayer.getEntityData().setFloat("MF_Balance_Pitch", pitchBalance); entityPlayer.getEntityData().setFloat("MF_Balance_Yaw", yawBalance); } @SubscribeEvent public void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { onPlayerEnterWorld(event.player); } @SubscribeEvent public void onPlayerTravel(PlayerEvent.PlayerChangedDimensionEvent event) { onPlayerEnterWorld(event.player); } @SubscribeEvent public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) { onPlayerEnterWorld(event.player); } public void onPlayerEnterWorld(EntityPlayer player) { if(player.worldObj.isRemote)return; NBTTagCompound persist = PlayerTagData.getPersistedData(player); MFLogUtil.logDebug("Sync data"); ResearchLogic.syncData((EntityPlayer) player); if(!persist.hasKey("MF_HasBook")) { persist.setBoolean("MF_HasBook", true); if(player.capabilities.isCreativeMode)return; player.inventory.addItemStackToInventory(new ItemStack(ToolListMF.researchBook)); } if(RPGElements.isSystemActive) { RPGElements.initSkills(player); } } public static int getDragonTier(EntityPlayer player) { int kills = getDragonEnemyPoints(player); if(kills < 10) { return 0;//Young 100% } if(kills < 20) { if(rand.nextInt(3) == 0)return 1;//33% chance for Adult return 0;//Young } if(kills < 35) { if(rand.nextInt(3) == 0)return 0;//33% chance for Young return 1;//Adult } if(kills < 50) { if(rand.nextInt(10) == 0)return 0;//10% chance for Young if(rand.nextInt(10) == 0)return 2;//10% chance for Mature return 1;//Adult } if(kills < 60) { if(rand.nextInt(4) == 0)return 2;//25% chance for Mature return 1;//Adult } if(kills >= 70) { if(rand.nextInt(10) == 0)return 1;//10% chance for Adult if(rand.nextInt(5) == 0)return 3;//20% chance Elder return 2;//Mature } if(kills > 100) { if(rand.nextInt(100) == 0)return 4;//1% chance Ancient if(rand.nextInt(2) == 0)return 3;//50% chance Elder return 2;//Mature } return 0;//Young 100% } public static void addDragonKill(EntityPlayer player) { addDragonEnemyPts(player, 1); } public static void addDragonEnemyPts(EntityPlayer player, int i) { setDragonEnemyPts(player, getDragonEnemyPoints(player)+i); } public static void setDragonEnemyPts(EntityPlayer player, int i) { if(i < 0) { i = 0; } NBTTagCompound nbt = PlayerTagData.getPersistedData(player); nbt.setInteger("MF_DragonKills", i); } public static int getDragonEnemyPoints(EntityPlayer player) { NBTTagCompound nbt = PlayerTagData.getPersistedData(player); return nbt.getInteger("MF_DragonKills"); } }