Reorganise and clean up client event handlers

This commit is contained in:
Electroblob77
2020-06-06 23:25:56 +01:00
parent 6df0d2dc6e
commit 1a094e1970
50 changed files with 625 additions and 443 deletions
@@ -16,7 +16,13 @@ import electroblob.wizardry.client.gui.handbook.GuiWizardHandbook;
import electroblob.wizardry.client.model.ModelWizardArmour;
import electroblob.wizardry.client.particle.*;
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
import electroblob.wizardry.client.renderer.*;
import electroblob.wizardry.client.renderer.entity.*;
import electroblob.wizardry.client.renderer.entity.layers.*;
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
import electroblob.wizardry.client.renderer.tileentity.RenderArcaneWorkbench;
import electroblob.wizardry.client.renderer.tileentity.RenderLectern;
import electroblob.wizardry.client.renderer.tileentity.RenderMagicLight;
import electroblob.wizardry.client.renderer.tileentity.RenderStatue;
import electroblob.wizardry.command.SpellEmitter;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.data.DispenserCastingData;
@@ -210,12 +216,12 @@ public class ClientProxy extends CommonProxy {
@Override
public void playBlinkEffect(EntityPlayer player){
if(Minecraft.getMinecraft().player == player) WizardryClientEventHandler.playBlinkEffect();
if(Minecraft.getMinecraft().player == player) RenderBlinkEffect.playBlinkEffect();
}
@Override
public void shakeScreen(EntityPlayer player, float intensity){
if(Minecraft.getMinecraft().player == player) WizardryClientEventHandler.shakeScreen(intensity);
if(Minecraft.getMinecraft().player == player) ScreenShakeHandler.shakeScreen(intensity);
}
@Override
@@ -0,0 +1,42 @@
package electroblob.wizardry.client;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.Minecraft;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.relauncher.Side;
@EventBusSubscriber(Side.CLIENT)
public class ScreenShakeHandler {
/** The remaining time for which the screen shake effect will be active. */
private static int screenShakeCounter = 0;
private static final float SHAKINESS = 0.5f;
/** Starts the client-side screen shake effect. */
public static void shakeScreen(float intensity){
if(Wizardry.settings.screenShake){
screenShakeCounter = (int)(intensity / SHAKINESS);
Minecraft.getMinecraft().player.rotationPitch -= intensity * 0.5f; // Start halfway down
}
}
@SubscribeEvent
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
if(event.player == Minecraft.getMinecraft().player && event.phase == TickEvent.Phase.END){
if(Wizardry.settings.screenShake){
if(screenShakeCounter > 0){
float magnitude = screenShakeCounter * SHAKINESS;
Minecraft.getMinecraft().player.rotationPitch += screenShakeCounter % 2 == 0 ? magnitude : -magnitude;
screenShakeCounter--;
}
}else{
screenShakeCounter = 0;
}
}
}
}
@@ -1,61 +1,46 @@
package electroblob.wizardry.client;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockMagicLight;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
import electroblob.wizardry.data.DispenserCastingData;
import electroblob.wizardry.data.SpellEmitterData;
import electroblob.wizardry.data.WizardData;
import electroblob.wizardry.item.ISpellCastingItem;
import electroblob.wizardry.item.ItemArtefact;
import electroblob.wizardry.item.ItemSpectralBow;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.potion.PotionSlowTime;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardryTabs;
import electroblob.wizardry.spell.*;
import electroblob.wizardry.util.RayTracer;
import electroblob.wizardry.util.WizardryUtilities;
import electroblob.wizardry.spell.Possession;
import electroblob.wizardry.spell.SixthSense;
import electroblob.wizardry.spell.SlowTime;
import electroblob.wizardry.spell.Transience;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMerchant;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityDispenser;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.world.World;
import net.minecraftforge.client.event.*;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* Event handler responsible for client-side only events, mostly rendering.
*
* General-purpose client-side event handler for things that don't fit anywhere else or groups of related behaviours
* that are better kept together.
*
* @author Electroblob
* @since Wizardry 1.0
*/
@@ -63,76 +48,19 @@ import java.util.Locale;
@Mod.EventBusSubscriber(Side.CLIENT)
public final class WizardryClientEventHandler {
private static final ResourceLocation SIXTH_SENSE_MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker.png");
private static final ResourceLocation SIXTH_SENSE_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_overlay.png");
private static final ResourceLocation FROST_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/frost_overlay.png");
private static final ResourceLocation BLINK_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/blink_overlay.png");
private static final ResourceLocation POINTER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/pointer.png");
private static final ResourceLocation TARGET_POINTER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/target_pointer.png");
private WizardryClientEventHandler(){} // No instances!
/** The remaining time for which the blink screen overlay effect will be displayed in first-person. Since this is
* only for the first-person player (the instance of which is itself stored in a static variable), this can simply
* be stored statically here, rather than needing to be in {@code WizardData}. */
private static int blinkEffectTimer;
/** The number of ticks the blink effect lasts for. */
private static final int BLINK_EFFECT_DURATION = 8;
// Tick Events
// ===============================================================================================================
/** The remaining time for which the screen shake effect will be active. */
private static int screenShakeCounter = 0;
private static final float SHAKINESS = 0.5f;
/** Reflected into {@code GuiContainerCreative#searchField} */
private static final Field searchField;
private static GuiTextField currentSearchField = null;
static {
searchField = ObfuscationReflectionHelper.findField(GuiContainerCreative.class, "field_147062_A");
}
/** Starts the first-person blink overlay effect. */
public static void playBlinkEffect(){
if(Wizardry.settings.blinkEffect) blinkEffectTimer = BLINK_EFFECT_DURATION;
}
/** Starts the client-side screen shake effect. */
public static void shakeScreen(float intensity){
if(Wizardry.settings.screenShake){
screenShakeCounter = (int)(intensity / SHAKINESS);
Minecraft.getMinecraft().player.rotationPitch -= intensity * 0.5f; // Start halfway down
}
}
@SubscribeEvent
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
if(event.player == Minecraft.getMinecraft().player && event.phase == TickEvent.Phase.END){
if(Wizardry.settings.blinkEffect){
if(blinkEffectTimer > 0) blinkEffectTimer--;
}else{
blinkEffectTimer = 0;
}
if(Wizardry.settings.screenShake){
if(screenShakeCounter > 0){
float magnitude = screenShakeCounter * SHAKINESS;
Minecraft.getMinecraft().player.rotationPitch += screenShakeCounter % 2 == 0 ? magnitude : -magnitude;
screenShakeCounter--;
}
}else{
screenShakeCounter = 0;
}
// Only seems to work here...
// EntityLiving victim = Possession.getPossessee(Minecraft.getMinecraft().player);
// if(victim != null && victim.getHeldItemMainhand().isEmpty()){
// Minecraft.getMinecraft().player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY);
// }
// Reset shaders if their respective potions aren't active
// This is a player so the potion effects are synced by vanilla
if(Minecraft.getMinecraft().entityRenderer.getShaderGroup() != null){
if(Minecraft.getMinecraft().entityRenderer.getShaderGroup() != null){ // IntelliJ is wrong, this can be null
String activeShader = Minecraft.getMinecraft().entityRenderer.getShaderGroup().getShaderGroupName();
@@ -141,49 +69,16 @@ public final class WizardryClientEventHandler {
|| (activeShader.equals(Transience.SHADER.toString()) && !Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.transience))){
if(activeShader.equals(SixthSense.SHADER.toString())
|| activeShader.equals(Transience.SHADER.toString())) playBlinkEffect();
|| activeShader.equals(Transience.SHADER.toString())) RenderBlinkEffect.playBlinkEffect();
Minecraft.getMinecraft().entityRenderer.stopUseShader();
}
}
}
}
@SubscribeEvent
public static void onRenderHandEvent(RenderHandEvent event){
EntityLiving victim = Possession.getPossessee(Minecraft.getMinecraft().player);
if(victim != null){
victim.rotationYawHead = Minecraft.getMinecraft().player.rotationYaw;
if(Minecraft.getMinecraft().player.getHeldItemMainhand().isEmpty()){
event.setCanceled(true);
}
}
}
// This event is called every tick, not just when a movement key is pressed
@SubscribeEvent
public static void onInputUpdateEvent(InputUpdateEvent event){
// Prevents the player moving when paralysed
if(event.getEntityPlayer().isPotionActive(WizardryPotions.paralysis)){
event.getMovementInput().moveForward = 0;
event.getMovementInput().moveStrafe = 0;
event.getMovementInput().jump = false;
event.getMovementInput().sneak = false;
}
if(ItemArtefact.isArtefactActive(event.getEntityPlayer(), WizardryItems.charm_move_speed)
&& event.getEntityPlayer().isHandActive()
&& event.getEntityPlayer().getActiveItemStack().getItem() instanceof ItemWand){
// Normally speed is set to 20% when using items, this makes it 80%
event.getMovementInput().moveStrafe *= 4;
event.getMovementInput().moveForward *= 4;
}
}
// The classes referenced here used to handle their own client tick events, but since they're not client-only
// classes, that crashed the dedicated server...
@SubscribeEvent
public static void onClientTickEvent(TickEvent.ClientTickEvent event){
@@ -208,10 +103,13 @@ public final class WizardryClientEventHandler {
PotionSlowTime.cleanUpEntities(world);
}
}
// Input and Controls
// ===============================================================================================================
@SubscribeEvent
public static void onMouseEvent(MouseEvent event){
// Prevents the player looking around when paralysed
if(Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.paralysis)
&& Minecraft.getMinecraft().inGameHasFocus){
@@ -223,6 +121,45 @@ public final class WizardryClientEventHandler {
}
}
// This event is called every tick, not just when a movement key is pressed
@SubscribeEvent
public static void onInputUpdateEvent(InputUpdateEvent event){
// Prevents the player moving when paralysed
if(event.getEntityPlayer().isPotionActive(WizardryPotions.paralysis)){
event.getMovementInput().moveForward = 0;
event.getMovementInput().moveStrafe = 0;
event.getMovementInput().jump = false;
event.getMovementInput().sneak = false;
}
if(ItemArtefact.isArtefactActive(event.getEntityPlayer(), WizardryItems.charm_move_speed)
&& event.getEntityPlayer().isHandActive()
&& event.getEntityPlayer().getActiveItemStack().getItem() instanceof ItemWand){
// Normally speed is set to 20% when using items, this makes it 80%
event.getMovementInput().moveStrafe *= 4;
event.getMovementInput().moveForward *= 4;
}
}
// Rendering
// ===============================================================================================================
@SubscribeEvent
public static void onRenderHandEvent(RenderHandEvent event){
// Hide the player's empty hand in first-person when possessing
EntityLiving victim = Possession.getPossessee(Minecraft.getMinecraft().player);
if(victim != null){
victim.rotationYawHead = Minecraft.getMinecraft().player.rotationYaw;
if(Minecraft.getMinecraft().player.getHeldItemMainhand().isEmpty()){
event.setCanceled(true);
}
}
}
@SubscribeEvent
public static void onFOVUpdateEvent(FOVUpdateEvent event){
@@ -241,26 +178,6 @@ public final class WizardryClientEventHandler {
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F);
}
if(blinkEffectTimer > 0){
float f = ((float)Math.max(blinkEffectTimer - 2, 0))/BLINK_EFFECT_DURATION;
event.setNewfov(event.getFov() + f * f * 0.7f);
}
}
@SubscribeEvent
public static void onDrawBlockHighlightEvent(DrawBlockHighlightEvent event){
// Hide the block outline for magic light blocks unless the player can dispel them
if(event.getTarget().typeOfHit == RayTraceResult.Type.BLOCK
&& event.getPlayer().world.getBlockState(event.getTarget().getBlockPos()).getBlock() instanceof BlockMagicLight){
if((!(event.getPlayer().getHeldItemMainhand().getItem() instanceof ISpellCastingItem)
&& !(event.getPlayer().getHeldItemOffhand().getItem() instanceof ISpellCastingItem))
|| !ItemArtefact.isArtefactActive(event.getPlayer(), WizardryItems.charm_light)){
event.setCanceled(true);
}
}
}
// Brute-force fix for crystals not showing up when a wizard is given a spell book in the trade GUI.
@@ -289,237 +206,12 @@ public final class WizardryClientEventHandler {
}
}
@SubscribeEvent
public static void onInitGuiEvent(GuiScreenEvent.InitGuiEvent.Post event){
// Reduces reflection as much as possible - searchField is created on GUI init and never reassigned so we need
// not (and should not!) use reflection to retrieve it every time a key is typed
if(event.getGui() instanceof GuiContainerCreative){
try{
currentSearchField = (GuiTextField)searchField.get(event.getGui());
}catch(IllegalAccessException e){
e.printStackTrace();
}
}
}
@SubscribeEvent
public static void onKeyboardInputEvent(GuiScreenEvent.KeyboardInputEvent.Post event){
// Custom creative tab search behaviour
if(event.getGui() instanceof GuiContainerCreative){
GuiContainerCreative gui = (GuiContainerCreative)event.getGui();
CreativeTabs tab = CreativeTabs.CREATIVE_TAB_ARRAY[gui.getSelectedTabIndex()];
if(tab == WizardryTabs.SPELLS){
GuiContainerCreative.ContainerCreative container = (GuiContainerCreative.ContainerCreative)gui.inventorySlots;
container.itemList.clear(); // Required or duplicates will appear!
String searchText = currentSearchField.getText().toLowerCase(Locale.ROOT);
tab.displayAllRelevantItems(container.itemList);
if(!searchText.isEmpty()){
container.itemList.removeIf(s -> !Spell.byMetadata(s.getMetadata()).matches(searchText));
container.scrollTo(0); // Seems to refresh the GUI somehow so it displays correctly
}
}
}
}
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){
Minecraft mc = Minecraft.getMinecraft();
WizardData data = WizardData.get(mc.player);
RenderManager renderManager = event.getRenderer().getRenderManager();
ItemStack wand = mc.player.getHeldItemMainhand();
if(!(wand.getItem() instanceof ISpellCastingItem)){
wand = mc.player.getHeldItemOffhand();
}
// Target selection pointer
if(mc.player.isSneaking() && wand.getItem() instanceof ISpellCastingItem && WizardryUtilities.isLiving(event.getEntity())
&& data != null && data.selectedMinion != null){
// -> Moved this in here so it isn't called every tick
RayTraceResult rayTrace = RayTracer.standardEntityRayTrace(mc.world, mc.player, 16, false);
if(rayTrace != null && rayTrace.entityHit == event.getEntity()){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
// Disabling depth test allows it to be seen through everything.
GlStateManager.disableDepth();
GlStateManager.color(1, 1, 1, 1);
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX;
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
mc.renderEngine.bindTexture(TARGET_POINTER_TEXTURE);
buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex();
buffer.pos(0.2, 0.24, 0).tex(9f / 16f, 0).endVertex();
buffer.pos(0.2, -0.24, 0).tex(9f / 16f, 11f / 16f).endVertex();
buffer.pos(-0.2, -0.24, 0).tex(0, 11f / 16f).endVertex();
tessellator.draw();
GlStateManager.enableCull();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
}
// Summoned creature selection pointer
if(data != null && data.selectedMinion != null && data.selectedMinion.get() == event.getEntity()){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
// Disabling depth test allows it to be seen through everything.
GlStateManager.disableDepth();
GlStateManager.color(1, 1, 1, 1);
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX;
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
mc.renderEngine.bindTexture(POINTER_TEXTURE);
buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex();
buffer.pos(0.2, 0.24, 0).tex(9f / 16f, 0).endVertex();
buffer.pos(0.2, -0.24, 0).tex(9f / 16f, 11f / 16f).endVertex();
buffer.pos(-0.2, -0.24, 0).tex(0, 11f / 16f).endVertex();
tessellator.draw();
GlStateManager.enableCull();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
// Sixth sense
if(mc.player.isPotionActive(WizardryPotions.sixth_sense) && !(event.getEntity() instanceof EntityArmorStand)
&& event.getEntity() != mc.player && mc.player.getActivePotionEffect(WizardryPotions.sixth_sense) != null
&& event.getEntity().getDistance(mc.player) < Spells.sixth_sense.getProperty(Spell.EFFECT_RADIUS).floatValue()
* (1 + mc.player.getActivePotionEffect(WizardryPotions.sixth_sense).getAmplifier() * Constants.RANGE_INCREASE_PER_LEVEL)){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// Disabling depth test allows it to be seen through everything.
GlStateManager.disableDepth();
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height * 0.6, event.getZ());
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX;
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
mc.renderEngine.bindTexture(SIXTH_SENSE_MARKER_TEXTURE);
buffer.pos(-0.6, 0.6, 0).tex(0, 0).endVertex();
buffer.pos(0.6, 0.6, 0).tex(1, 0).endVertex();
buffer.pos(0.6, -0.6, 0).tex(1, 1).endVertex();
buffer.pos(-0.6, -0.6, 0).tex(0, 1).endVertex();
tessellator.draw();
GlStateManager.enableCull();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
}
@SubscribeEvent
public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){
if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET){
if(Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.sixth_sense)){
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
GlStateManager.color(1, 1, 1, 1);
GlStateManager.disableAlpha();
renderScreenOverlay(event, SIXTH_SENSE_OVERLAY_TEXTURE);
GlStateManager.enableAlpha();
GlStateManager.color(1, 1, 1, 1);
}
if(Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.frost)){
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
GlStateManager.color(1, 1, 1, 1);
GlStateManager.disableAlpha();
renderScreenOverlay(event, FROST_OVERLAY_TEXTURE);
GlStateManager.enableAlpha();
GlStateManager.color(1, 1, 1, 1);
}
if(blinkEffectTimer > 0){
float alpha = ((float)blinkEffectTimer)/BLINK_EFFECT_DURATION;
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ZERO);
GlStateManager.color(1, 1, 1, alpha);
GlStateManager.disableAlpha();
renderScreenOverlay(event, BLINK_OVERLAY_TEXTURE);
GlStateManager.enableAlpha();
GlStateManager.color(1, 1, 1, 1);
}
}
}
private static void renderScreenOverlay(RenderGameOverlayEvent.Post event, ResourceLocation texture){
/**
* Renders an overlay across the entire screen.
* @param resolution The screen resolution
* @param texture The overlay texture to display
*/
public static void renderScreenOverlay(ScaledResolution resolution, ResourceLocation texture){
GlStateManager.pushMatrix();
@@ -532,11 +224,12 @@ public final class WizardryClientEventHandler {
BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex();
buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D)
.endVertex();
buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex();
buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex();
buffer.pos(0, resolution.getScaledHeight(), -90).tex(0, 1).endVertex();
buffer.pos(resolution.getScaledWidth(), resolution.getScaledHeight(), -90).tex(1, 1).endVertex();
buffer.pos(resolution.getScaledWidth(), 0, -90).tex(1, 0).endVertex();
buffer.pos(0, 0, -90).tex(0, 0).endVertex();
tessellator.draw();
GlStateManager.depthMask(true);
@@ -0,0 +1,65 @@
package electroblob.wizardry.client.gui;
import electroblob.wizardry.registry.WizardryTabs;
import electroblob.wizardry.spell.Spell;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainerCreative;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import java.lang.reflect.Field;
import java.util.Locale;
@EventBusSubscriber(Side.CLIENT)
public class CustomCreativeSearchHandler {
/** Reflected into {@code GuiContainerCreative#searchField} */
private static final Field searchField;
private static GuiTextField currentSearchField = null;
static {
searchField = ObfuscationReflectionHelper.findField(GuiContainerCreative.class, "field_147062_A");
}
@SubscribeEvent
public static void onInitGuiEvent(GuiScreenEvent.InitGuiEvent.Post event){
// Reduces reflection as much as possible - searchField is created on GUI init and never reassigned so we need
// not (and should not!) use reflection to retrieve it every time a key is typed
if(event.getGui() instanceof GuiContainerCreative){
try{
currentSearchField = (GuiTextField)searchField.get(event.getGui());
}catch(IllegalAccessException e){
e.printStackTrace();
}
}
}
@SubscribeEvent
public static void onKeyboardInputEvent(GuiScreenEvent.KeyboardInputEvent.Post event){
// Custom creative tab search behaviour
if(event.getGui() instanceof GuiContainerCreative){
GuiContainerCreative gui = (GuiContainerCreative)event.getGui();
CreativeTabs tab = CreativeTabs.CREATIVE_TAB_ARRAY[gui.getSelectedTabIndex()];
if(tab == WizardryTabs.SPELLS){
GuiContainerCreative.ContainerCreative container = (GuiContainerCreative.ContainerCreative)gui.inventorySlots;
container.itemList.clear(); // Required or duplicates will appear!
String searchText = currentSearchField.getText().toLowerCase(Locale.ROOT);
tab.displayAllRelevantItems(container.itemList);
if(!searchText.isEmpty()){
container.itemList.removeIf(s -> !Spell.byMetadata(s.getMetadata()).matches(searchText));
container.scrollTo(0); // Seems to refresh the GUI somehow so it displays correctly
}
}
}
}
}
@@ -1,14 +1,14 @@
package electroblob.wizardry.client.renderer;
/** Instances of this class can calculate their distance from the camera viewpoint and sort themselves accordingly. */
class RayHelper implements Comparable<RayHelper> {
public class RayHelper implements Comparable<RayHelper> {
int ordinal;
double x1, y1, z1;
double x2, y2, z2;
public double x1, y1, z1;
public double x2, y2, z2;
double offsetX, offsetY, offsetZ;
RayHelper(int ordinal, double x1, double y1, double z1, double x2, double y2, double z2, double offsetX,
public RayHelper(int ordinal, double x1, double y1, double z1, double x2, double y2, double z2, double offsetX,
double offsetY, double offsetZ){
this.ordinal = ordinal;
this.x1 = x1;
@@ -37,13 +37,7 @@ class RayHelper implements Comparable<RayHelper> {
@Override
public int compareTo(RayHelper ray){
if(this.getDistanceFromViewpoint() > ray.getDistanceFromViewpoint()){
return -1;
}else if(this.getDistanceFromViewpoint() < ray.getDistanceFromViewpoint()){
return 1;
}else{
return 0;
}
return Double.compare(ray.getDistanceFromViewpoint(), this.getDistanceFromViewpoint());
}
}
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.effect;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.potion.PotionContainment;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.effect;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.registry.Spells;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.effect;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.data.WizardData;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.effect;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.registry.Spells;
@@ -1,6 +1,7 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.renderer.RayHelper;
import electroblob.wizardry.entity.construct.EntityBlackHole;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
@@ -63,7 +64,7 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
// coordinates which were inconsistent with my calculated ones. Since I know those will give the desired
// effect anyway, I just used them directly instead.
ArrayList<RayHelper> rays = new ArrayList<RayHelper>(1);
ArrayList<RayHelper> rays = new ArrayList<>(1);
for(int j = 0; j < 30; j++){
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityBubble;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityDecay;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.EntityDecoy;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelWizard;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.construct.EntityFireRing;
import net.minecraft.client.Minecraft;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.projectile.EntityForceArrow;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.construct.EntityForcefield;
import net.minecraft.client.renderer.BufferBuilder;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelHammer;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelIceGiant;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityIceSpike;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.projectile.EntityLightningDisc;
import net.minecraft.client.renderer.BufferBuilder;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.projectile.EntityMagicArrow;
import net.minecraft.client.renderer.BufferBuilder;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelPhoenix;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.spell.Possession;
import net.minecraft.client.renderer.entity.Render;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.projectile.EntityMagicProjectile;
import net.minecraft.client.Minecraft;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelRemnant;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.construct.EntityHealAura;
import electroblob.wizardry.entity.construct.EntityMagicConstruct;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.EntitySpiritHorse;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.EntitySpiritWolf;
@@ -1,5 +1,6 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.client.renderer.entity.layers.LayerStrayMinionClothing;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderSkeleton;
import net.minecraft.entity.monster.AbstractSkeleton;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.model.ModelWizard;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.entity.living.EntityBlazeMinion;
import net.minecraft.client.model.ModelBlaze;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityZombieSpawner;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.Disintegration;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockStatue;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.block.BlockStatue;
import electroblob.wizardry.client.ClientProxy;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.entity.living.EntityStrayMinion;
import net.minecraft.client.model.ModelSkeleton;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.ISummonedCreature;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.entity.layers;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
@@ -0,0 +1,77 @@
package electroblob.wizardry.client.renderer.overlay;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.WizardryClientEventHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
@EventBusSubscriber(Side.CLIENT)
public class RenderBlinkEffect {
/** The remaining time for which the blink screen overlay effect will be displayed in first-person. Since this is
* only for the first-person player (the instance of which is itself stored in a static variable), this can simply
* be stored statically here, rather than needing to be in {@code WizardData}. */
private static int blinkEffectTimer;
/** The number of ticks the blink effect lasts for. */
private static final int BLINK_EFFECT_DURATION = 8;
private static final ResourceLocation SCREEN_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/blink_overlay.png");
/** Starts the first-person blink overlay effect. */
public static void playBlinkEffect(){
if(Wizardry.settings.blinkEffect) blinkEffectTimer = BLINK_EFFECT_DURATION;
}
@SubscribeEvent
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
if(event.player == Minecraft.getMinecraft().player && event.phase == TickEvent.Phase.END){
if(Wizardry.settings.blinkEffect){
if(blinkEffectTimer > 0) blinkEffectTimer--;
}else{
blinkEffectTimer = 0;
}
}
}
@SubscribeEvent
public static void onFOVUpdateEvent(FOVUpdateEvent event){
if(blinkEffectTimer > 0){
float f = ((float)Math.max(blinkEffectTimer - 2, 0))/BLINK_EFFECT_DURATION;
event.setNewfov(event.getFov() + f * f * 0.7f);
}
}
@SubscribeEvent
public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){
if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET){
if(blinkEffectTimer > 0){
float alpha = ((float)blinkEffectTimer)/BLINK_EFFECT_DURATION;
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE, GL11.GL_ZERO);
GlStateManager.color(1, 1, 1, alpha);
GlStateManager.disableAlpha();
WizardryClientEventHandler.renderScreenOverlay(event.getResolution(), SCREEN_OVERLAY_TEXTURE);
GlStateManager.enableAlpha();
GlStateManager.color(1, 1, 1, 1);
}
}
}
}
@@ -0,0 +1,40 @@
package electroblob.wizardry.client.renderer.overlay;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.WizardryClientEventHandler;
import electroblob.wizardry.registry.WizardryPotions;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
@EventBusSubscriber(Side.CLIENT)
public class RenderFrostOverlay {
private static final ResourceLocation SCREEN_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/frost_overlay.png");
@SubscribeEvent
public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){
if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET){
if(Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.frost)){
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
GlStateManager.color(1, 1, 1, 1);
GlStateManager.disableAlpha();
WizardryClientEventHandler.renderScreenOverlay(event.getResolution(), SCREEN_OVERLAY_TEXTURE);
GlStateManager.enableAlpha();
GlStateManager.color(1, 1, 1, 1);
}
}
}
}
@@ -0,0 +1,104 @@
package electroblob.wizardry.client.renderer.overlay;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.WizardryClientEventHandler;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.spell.Spell;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
@EventBusSubscriber(Side.CLIENT)
public class RenderSixthSense {
private static final ResourceLocation MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker.png");
private static final ResourceLocation SCREEN_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_overlay.png");
@SubscribeEvent
public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){
if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET){
if(Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.sixth_sense)){
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
GlStateManager.color(1, 1, 1, 1);
GlStateManager.disableAlpha();
WizardryClientEventHandler.renderScreenOverlay(event.getResolution(), SCREEN_OVERLAY_TEXTURE);
GlStateManager.enableAlpha();
GlStateManager.color(1, 1, 1, 1);
}
}
}
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){
Minecraft mc = Minecraft.getMinecraft();
RenderManager renderManager = event.getRenderer().getRenderManager();
if(mc.player.isPotionActive(WizardryPotions.sixth_sense) && !(event.getEntity() instanceof EntityArmorStand)
&& event.getEntity() != mc.player && mc.player.getActivePotionEffect(WizardryPotions.sixth_sense) != null
&& event.getEntity().getDistance(mc.player) < Spells.sixth_sense.getProperty(Spell.EFFECT_RADIUS).floatValue()
* (1 + mc.player.getActivePotionEffect(WizardryPotions.sixth_sense).getAmplifier() * Constants.RANGE_INCREASE_PER_LEVEL)){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// Disabling depth test allows it to be seen through everything.
GlStateManager.disableDepth();
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height * 0.6, event.getZ());
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX;
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
mc.renderEngine.bindTexture(MARKER_TEXTURE);
buffer.pos(-0.6, 0.6, 0).tex(0, 0).endVertex();
buffer.pos(0.6, 0.6, 0).tex(1, 0).endVertex();
buffer.pos(0.6, -0.6, 0).tex(1, 1).endVertex();
buffer.pos(-0.6, -0.6, 0).tex(0, 1).endVertex();
tessellator.draw();
GlStateManager.enableCull();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
}
}
@@ -0,0 +1,134 @@
package electroblob.wizardry.client.renderer.overlay;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.data.WizardData;
import electroblob.wizardry.item.ISpellCastingItem;
import electroblob.wizardry.util.RayTracer;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
@EventBusSubscriber(Side.CLIENT)
public class RenderTargetPointers {
private static final ResourceLocation POINTER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/pointer.png");
private static final ResourceLocation TARGET_POINTER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/target_pointer.png");
@SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){
Minecraft mc = Minecraft.getMinecraft();
WizardData data = WizardData.get(mc.player);
RenderManager renderManager = event.getRenderer().getRenderManager();
ItemStack wand = mc.player.getHeldItemMainhand();
if(!(wand.getItem() instanceof ISpellCastingItem)){
wand = mc.player.getHeldItemOffhand();
}
// Target selection pointer
if(mc.player.isSneaking() && wand.getItem() instanceof ISpellCastingItem && WizardryUtilities.isLiving(event.getEntity())
&& data != null && data.selectedMinion != null){
// -> Moved this in here so it isn't called every tick
RayTraceResult rayTrace = RayTracer.standardEntityRayTrace(mc.world, mc.player, 16, false);
if(rayTrace != null && rayTrace.entityHit == event.getEntity()){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
// Disabling depth test allows it to be seen through everything.
GlStateManager.disableDepth();
GlStateManager.color(1, 1, 1, 1);
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX;
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
mc.renderEngine.bindTexture(TARGET_POINTER_TEXTURE);
buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex();
buffer.pos(0.2, 0.24, 0).tex(9f / 16f, 0).endVertex();
buffer.pos(0.2, -0.24, 0).tex(9f / 16f, 11f / 16f).endVertex();
buffer.pos(-0.2, -0.24, 0).tex(0, 11f / 16f).endVertex();
tessellator.draw();
GlStateManager.enableCull();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
}
// Summoned creature selection pointer
if(data != null && data.selectedMinion != null && data.selectedMinion.get() == event.getEntity()){
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix();
GlStateManager.disableCull();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
// Disabling depth test allows it to be seen through everything.
GlStateManager.disableDepth();
GlStateManager.color(1, 1, 1, 1);
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
// This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX;
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
mc.renderEngine.bindTexture(POINTER_TEXTURE);
buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex();
buffer.pos(0.2, 0.24, 0).tex(9f / 16f, 0).endVertex();
buffer.pos(0.2, -0.24, 0).tex(9f / 16f, 11f / 16f).endVertex();
buffer.pos(-0.2, -0.24, 0).tex(0, 11f / 16f).endVertex();
tessellator.draw();
GlStateManager.enableCull();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
GlStateManager.popMatrix();
}
}
}
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.overlay;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.data.WizardData;
@@ -90,7 +90,7 @@ public class RenderTransportationUI {
// However, if that's outside the render distance it won't render at all! To fudge our way around this
// problem, we're capping the distance to just below the render distance and adjusting the scale accordingly
double distanceCap = Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16 - 8;
double displayDist = distance > distanceCap ? distanceCap : distance;
double displayDist = Math.min(distance, distanceCap);
double factor = displayDist/distance;
GlStateManager.translate(position.x * factor, position.y * factor, position.z * factor);
@@ -109,9 +109,9 @@ public class RenderTransportationUI {
float f = location == target ? 1 : 0.5f; // Makes it obvious which one is being aimed at
buffer.pos(-iconSize, iconSize, 0).tex(0, 0).color(f, 1, f, f).endVertex();
buffer.pos(iconSize, iconSize, 0).tex(1, 0).color(f, 1, f, f).endVertex();
buffer.pos(iconSize, -iconSize, 0).tex(1, 1).color(f, 1, f, f).endVertex();
buffer.pos(-iconSize, iconSize, 0).tex(0, 0).color(f, 1, f, f).endVertex();
buffer.pos( iconSize, iconSize, 0).tex(1, 0).color(f, 1, f, f).endVertex();
buffer.pos( iconSize, -iconSize, 0).tex(1, 1).color(f, 1, f, f).endVertex();
buffer.pos(-iconSize, -iconSize, 0).tex(0, 1).color(f, 1, f, f).endVertex();
tessellator.draw();
@@ -157,10 +157,10 @@ public class RenderTransportationUI {
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR);
bufferbuilder.pos((double)(-i - 1), (double)(-1 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos((double)(-i - 1), (double)(8 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos((double)(i + 1), (double)(8 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos((double)(i + 1), (double)(-1 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos((-i - 1), (-1 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos((-i - 1), ( 8 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos(( i + 1), ( 8 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
bufferbuilder.pos(( i + 1), (-1 + verticalShift), 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex();
tessellator.draw();
GlStateManager.enableTexture2D();
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.tileentity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.ArcaneLock;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.tileentity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.tileentity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.tileentity.TileEntityLectern;
@@ -1,6 +1,10 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.tileentity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockMagicLight;
import electroblob.wizardry.item.ISpellCastingItem;
import electroblob.wizardry.item.ItemArtefact;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.tileentity.TileEntityMagicLight;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
@@ -8,8 +12,14 @@ import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import org.lwjgl.opengl.GL11;
@EventBusSubscriber(Side.CLIENT)
public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicLight> {
private static final ResourceLocation RAY_TEXTURE = new ResourceLocation(Wizardry.MODID,
@@ -125,4 +135,19 @@ public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicL
GlStateManager.popMatrix();
}
@SubscribeEvent
public static void onDrawBlockHighlightEvent(DrawBlockHighlightEvent event){
// Hide the block outline for magic light blocks unless the player can dispel them
if(event.getTarget().typeOfHit == RayTraceResult.Type.BLOCK
&& event.getPlayer().world.getBlockState(event.getTarget().getBlockPos()).getBlock() instanceof BlockMagicLight){
if((!(event.getPlayer().getHeldItemMainhand().getItem() instanceof ISpellCastingItem)
&& !(event.getPlayer().getHeldItemOffhand().getItem() instanceof ISpellCastingItem))
|| !ItemArtefact.isArtefactActive(event.getPlayer(), WizardryItems.charm_light)){
event.setCanceled(true);
}
}
}
}
@@ -1,4 +1,4 @@
package electroblob.wizardry.client.renderer;
package electroblob.wizardry.client.renderer.tileentity;
import electroblob.wizardry.tileentity.TileEntityStatue;
import net.minecraft.client.Minecraft;