public final class BattlegearClientEvents implements IResourceManagerReloadListener { private final BattlegearInGameGUI inGameGUI; public final QuiverModel quiverModel; public final ResourceLocation quiverDetails; public final ResourceLocation quiverBase; // public static final ResourceLocation patterns = new ResourceLocation("battlegear2", // "textures/heraldry/Patterns-small.png"); // public static int storageIndex; private static final int MAIN_INV = InventoryPlayer.getHotbarSize(); public static final GuiPlaceableButton[] tabsList = { new GuiBGInventoryButton(0), new GuiSigilButton(1) }; public static final BattlegearClientEvents INSTANCE = new BattlegearClientEvents(); private String[] attributeNames; private BattlegearClientEvents() { inGameGUI = new BattlegearInGameGUI(); quiverModel = new QuiverModel(); quiverDetails = new ResourceLocation("battlegear2", "textures/armours/quiver/QuiverDetails.png"); quiverBase = new ResourceLocation("battlegear2", "textures/armours/quiver/QuiverBase.png"); ((IReloadableResourceManager) FMLClientHandler.instance().getClient().getResourceManager()) .registerReloadListener(this); } /** Offset battle slots rendering according to config values */ @SubscribeEvent(priority = EventPriority.HIGHEST) public void postRenderBar(RenderItemBarEvent.BattleSlots event) { if (!event.isMainHand) { event.xOffset += BattlegearConfig.battleBarOffset[0]; event.yOffset += BattlegearConfig.battleBarOffset[1]; } else { event.xOffset += BattlegearConfig.battleBarOffset[2]; event.yOffset += BattlegearConfig.battleBarOffset[3]; } } /** Offset quiver slots rendering according to config values */ @SubscribeEvent(priority = EventPriority.HIGHEST) public void postRenderQuiver(RenderItemBarEvent.QuiverSlots event) { event.xOffset += BattlegearConfig.quiverBarOffset[0]; event.yOffset += BattlegearConfig.quiverBarOffset[1]; } /** Offset shield stamina rendering according to config values */ @SubscribeEvent(priority = EventPriority.HIGHEST) public void postRenderShield(RenderItemBarEvent.ShieldBar event) { event.xOffset += BattlegearConfig.shieldBarOffset[0]; event.yOffset += BattlegearConfig.shieldBarOffset[1]; } /** Render all the Battlegear HUD elements */ @SubscribeEvent(receiveCanceled = true) public void postRenderOverlay(RenderGameOverlayEvent.Post event) { if (event.type == RenderGameOverlayEvent.ElementType.HOTBAR && (BattlegearConfig.forceHUD || !event.isCanceled())) { inGameGUI.renderGameOverlay(event.partialTicks); } } /** * Bend the models when the item in left hand is used And stop the right hand inappropriate * bending */ @SubscribeEvent(priority = EventPriority.LOW) public void renderPlayerLeftItemUsage(RenderLivingEvent.Pre event) { if (event.entity instanceof EntityPlayer) { EntityPlayer entityPlayer = (EntityPlayer) event.entity; ItemStack offhand = ((InventoryPlayerBattle) entityPlayer.inventory).getCurrentOffhandWeapon(); if (offhand != null && event.renderer instanceof RenderPlayer) { ModelPlayer renderer = ((RenderPlayer) event.renderer).getPlayerModel(); renderer.heldItemLeft = 1; if (entityPlayer.getItemInUseCount() > 0 && entityPlayer.getItemInUse() == offhand) { EnumAction enumaction = offhand.getItemUseAction(); if (enumaction == EnumAction.BLOCK) { renderer.heldItemLeft = 3; } else if (enumaction == EnumAction.BOW) { renderer.aimedBow = true; } ItemStack mainhand = entityPlayer.inventory.getCurrentItem(); renderer.heldItemRight = mainhand != null ? 1 : 0; } else if (((IBattlePlayer) entityPlayer).isBlockingWithShield()) { renderer.heldItemLeft = 3; } } } } /** Reset models to default values */ @SubscribeEvent(priority = EventPriority.LOW) public void resetPlayerLeftHand(RenderPlayerEvent.Post event) { event.renderer.getPlayerModel().heldItemLeft = 0; } private static final int SKELETON_ARROW = 5; /** Render quiver on skeletons if possible */ @SubscribeEvent public void renderLiving(RenderLivingEvent.Post event) { if (BattlegearConfig.enableSkeletonQuiver && event.entity instanceof EntitySkeleton && event.renderer instanceof RenderSkeleton) { GL11.glPushMatrix(); GL11.glDisable(GL11.GL_CULL_FACE); GL11.glColor3f(1, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(quiverDetails); GL11.glTranslatef((float) event.x, (float) event.y, (float) event.z); GL11.glScalef(1, -1, 1); float f2 = interpolateRotation(event.entity.prevRenderYawOffset, event.entity.renderYawOffset, 0); GL11.glRotatef(180.0F - f2, 0.0F, 1.0F, 0.0F); if (event.entity.deathTime > 0) { float f3 = ((float) event.entity.deathTime + BattlegearClientTickHandeler.getPartialTick() - 1.0F) / 20.0F * 1.6F; f3 = MathHelper.sqrt_float(f3); if (f3 > 1.0F) { f3 = 1.0F; } GL11.glRotatef(-f3 * 90, 0.0F, 0.0F, 1.0F); } GL11.glTranslatef(0, -1.5F, 0); GL11.glRotatef(event.entity.rotationPitch, 0, 1, 0); if (event.entity.getEquipmentInSlot(3) != null) { // chest armor GL11.glTranslatef(0, 0, BattlegearRenderHelper.RENDER_UNIT); } ((ModelBiped) event.renderer.mainModel) .bipedBody.postRender(BattlegearRenderHelper.RENDER_UNIT); GL11.glScalef(1.05F, 1.05F, 1.05F); quiverModel.render(SKELETON_ARROW, BattlegearRenderHelper.RENDER_UNIT); Minecraft.getMinecraft().getTextureManager().bindTexture(quiverBase); GL11.glColor3f(0.10F, 0.10F, 0.10F); quiverModel.render(0, BattlegearRenderHelper.RENDER_UNIT); GL11.glColor3f(1, 1, 1); GL11.glEnable(GL11.GL_CULL_FACE); GL11.glPopMatrix(); } } /** Counter the bow use fov jerkyness with the draw enchantment */ @SubscribeEvent public void onBowFOV(FOVUpdateEvent event) { ItemStack stack = event.entity.getItemInUse(); if (EnchantmentHelper.getEnchantmentLevel(BaseEnchantment.bowCharge, stack) > 0) { int i = event.entity.getItemInUseDuration(); float f1 = (float) i / 20.0F; if (f1 > 1.0F) { f1 = 1.0F; } else { f1 *= f1; } event.newfov /= 1.0F - f1 * 0.15F; } } /** Fixes pick block */ @SubscribeEvent(priority = EventPriority.HIGHEST) public void replacePickBlock(MouseEvent event) { if (event.buttonstate) { Minecraft mc = FMLClientHandler.instance().getClient(); if (mc.thePlayer != null) { if (event.button - 100 == mc.gameSettings.keyBindPickBlock.getKeyCode()) { event.setCanceled(true); if (!((IBattlePlayer) mc.thePlayer).isBattlemode()) { boolean isCreative = mc.thePlayer.capabilities.isCreativeMode; ItemStack stack = getItemFromPointedAt(mc.objectMouseOver, mc.thePlayer); if (stack != null) { int k = -1; ItemStack temp; for (int slot = 0; slot < MAIN_INV; slot++) { temp = mc.thePlayer.inventory.getStackInSlot(slot); if (temp != null && stack.isItemEqual(temp) && ItemStack.areItemStackTagsEqual(stack, temp)) { k = slot; break; } } if (isCreative && k == -1) { k = mc.thePlayer.inventory.getFirstEmptyStack(); if (k < 0 || k >= MAIN_INV) { k = mc.thePlayer.inventory.currentItem; } } if (k >= 0 && k < MAIN_INV) { mc.thePlayer.inventory.currentItem = k; Battlegear.packetHandler.sendPacketToServer( new PickBlockPacket(stack, k).generatePacket()); } } } } } } } /** * Equivalent code to the creative pick block * * @param target The client target vector * @param player The player trying to pick * @return the stack expected for the creative pick button */ private static ItemStack getItemFromPointedAt(MovingObjectPosition target, EntityPlayer player) { if (target != null) { if (target.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { BlockPos pos = target.getBlockPos(); World world = player.getEntityWorld(); Block block = world.getBlockState(pos).getBlock(); if (block.isAir(world, pos)) { return null; } return block.getPickBlock(target, world, pos); } else { if (target.typeOfHit != MovingObjectPosition.MovingObjectType.ENTITY || target.entityHit == null || !player.capabilities.isCreativeMode) { return null; } return target.entityHit.getPickedResult(target); } } return null; } /** * Returns a rotation angle that is inbetween two other rotation angles. par1 and par2 are the * angles between which to interpolate, par3 is probably a float between 0.0 and 1.0 that tells us * where "between" the two angles we are. Example: par1 = 30, par2 = 50, par3 = 0.5, then return = * 40 */ public float interpolateRotation(float par1, float par2, float par3) { float f3 = par2 - par1; while (f3 < -180.0F) { f3 += 360.0F; } while (f3 >= 180.0F) { f3 -= 360.0F; } return par1 + par3 * f3; } /** Register a few "item" icons */ @SubscribeEvent public void preStitch(TextureStitchEvent.Pre event) { ClientProxy.backgroundIcon = new TextureAtlasSprite[] { event.map.registerSprite(new ResourceLocation("battlegear2:items/slots/mainhand")), event.map.registerSprite(new ResourceLocation("battlegear2:items/slots/offhand")) }; // storageIndex = PatternStore.DEFAULT.buildPatternAndStore(patterns); /*CrestImages.initialise(Minecraft.getMinecraft().getResourceManager()); for (HeraldryPattern pattern : HeraldryPattern.patterns) { pattern.registerIcon(event.map); }*/ } /** * Change attribute format when displayed on item tooltip * * @param event */ @SubscribeEvent public void onItemTooltip(ItemTooltipEvent event) { for (String txt : event.toolTip) { if (txt.startsWith(EnumChatFormatting.BLUE.toString())) { if (txt.contains(attributeNames[0]) || txt.contains(attributeNames[2])) event.toolTip.set( event.toolTip.indexOf(txt), EnumChatFormatting.DARK_GREEN + EnumChatFormatting.getTextWithoutFormattingCodes(txt)); else if (txt.contains(attributeNames[3])) event.toolTip.set( event.toolTip.indexOf(txt), EnumChatFormatting.DARK_GREEN + reformat(txt, 3)); else if (txt.contains(attributeNames[1])) event.toolTip.set(event.toolTip.indexOf(txt), EnumChatFormatting.GOLD + reformat(txt, 1)); } } if (event.itemStack.getItem() instanceof IBackStabbable) { event.toolTip.add( EnumChatFormatting.GOLD + StatCollector.translateToLocal("attribute.name.weapon.backstab")); } } // Equivalent of the ItemStack decimal formatter used in attribute tooltip display private static final Pattern FLOAT = Pattern.compile("\\d.\\d+"); /** * Format into "ratio" attribute localization * * @param txt current attribute local * @param type the attribute index * @return the new localization */ private String reformat(String txt, int type) { String result = EnumChatFormatting.getTextWithoutFormattingCodes(txt); Matcher matcher = FLOAT.matcher(result); if (matcher.find()) { int start = matcher.start(); int end = matcher.end(); String temp = result.substring(start, end).replace(",", "."); try { float value = Float.valueOf(temp) * 100; temp = ".plus.1"; if (start > 0 && result.charAt(start - 1) == '-') { temp = ".take.1"; } return StatCollector.translateToLocalFormatted( "attribute.modifier" + temp, ItemStack.DECIMALFORMAT.format(value), attributeNames[type]); } catch (NumberFormatException notNumber) { notNumber.printStackTrace(); } } return result; } /** * Help translating attributes * * @param attribute * @return the attribute name into the current language */ private String toLocal(BaseAttribute attribute) { return StatCollector.translateToLocal( "attribute.name." + attribute.getAttributeUnlocalizedName()); } /** Reload translation caches */ @Override public void onResourceManagerReload(IResourceManager resourceManager) { attributeNames = new String[] { toLocal(Attributes.armourPenetrate), toLocal(Attributes.daze), toLocal(Attributes.extendedReach), toLocal(Attributes.attackSpeed) }; } @SubscribeEvent(priority = EventPriority.LOW) public void postInitGui(GuiScreenEvent.InitGuiEvent.Post event) { if (Battlegear.battlegearEnabled && event.gui instanceof InventoryEffectRenderer) { if (!ClientProxy.tconstructEnabled || FMLClientHandler.instance().getClientPlayerEntity().capabilities.isCreativeMode) { onOpenGui( event.buttonList, ((InventoryEffectRenderer) event.gui).guiLeft - 30, ((InventoryEffectRenderer) event.gui).guiTop); } } } /** * Helper method to add buttons to a gui when opened * * @param buttons the List<GuiButton> of the opened gui * @param guiLeft horizontal placement parameter * @param guiTop vertical placement parameter */ public static void onOpenGui(List buttons, int guiLeft, int guiTop) { if (BattlegearConfig.enableGuiButtons) { int count = 0; for (GuiPlaceableButton tab : tabsList) { GuiPlaceableButton button = tab.copy(); button.place(count, guiLeft, guiTop); button.id = buttons.size() + 2; // Due to GuiInventory and GuiContainerCreative button performed actions, // without them having buttons... count++; buttons.add(button); } } } }