Reorganise and clean up client event handlers
This commit is contained in:
@@ -16,7 +16,13 @@ import electroblob.wizardry.client.gui.handbook.GuiWizardHandbook;
|
|||||||
import electroblob.wizardry.client.model.ModelWizardArmour;
|
import electroblob.wizardry.client.model.ModelWizardArmour;
|
||||||
import electroblob.wizardry.client.particle.*;
|
import electroblob.wizardry.client.particle.*;
|
||||||
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
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.command.SpellEmitter;
|
||||||
import electroblob.wizardry.constants.Constants;
|
import electroblob.wizardry.constants.Constants;
|
||||||
import electroblob.wizardry.data.DispenserCastingData;
|
import electroblob.wizardry.data.DispenserCastingData;
|
||||||
@@ -210,12 +216,12 @@ public class ClientProxy extends CommonProxy {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void playBlinkEffect(EntityPlayer player){
|
public void playBlinkEffect(EntityPlayer player){
|
||||||
if(Minecraft.getMinecraft().player == player) WizardryClientEventHandler.playBlinkEffect();
|
if(Minecraft.getMinecraft().player == player) RenderBlinkEffect.playBlinkEffect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void shakeScreen(EntityPlayer player, float intensity){
|
public void shakeScreen(EntityPlayer player, float intensity){
|
||||||
if(Minecraft.getMinecraft().player == player) WizardryClientEventHandler.shakeScreen(intensity);
|
if(Minecraft.getMinecraft().player == player) ScreenShakeHandler.shakeScreen(intensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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,60 +1,45 @@
|
|||||||
package electroblob.wizardry.client;
|
package electroblob.wizardry.client;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
||||||
import electroblob.wizardry.block.BlockMagicLight;
|
|
||||||
import electroblob.wizardry.constants.Constants;
|
|
||||||
import electroblob.wizardry.data.DispenserCastingData;
|
import electroblob.wizardry.data.DispenserCastingData;
|
||||||
import electroblob.wizardry.data.SpellEmitterData;
|
import electroblob.wizardry.data.SpellEmitterData;
|
||||||
import electroblob.wizardry.data.WizardData;
|
|
||||||
import electroblob.wizardry.item.ISpellCastingItem;
|
|
||||||
import electroblob.wizardry.item.ItemArtefact;
|
import electroblob.wizardry.item.ItemArtefact;
|
||||||
import electroblob.wizardry.item.ItemSpectralBow;
|
import electroblob.wizardry.item.ItemSpectralBow;
|
||||||
import electroblob.wizardry.item.ItemWand;
|
import electroblob.wizardry.item.ItemWand;
|
||||||
import electroblob.wizardry.potion.PotionSlowTime;
|
import electroblob.wizardry.potion.PotionSlowTime;
|
||||||
import electroblob.wizardry.registry.Spells;
|
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.registry.WizardryPotions;
|
import electroblob.wizardry.registry.WizardryPotions;
|
||||||
import electroblob.wizardry.registry.WizardryTabs;
|
import electroblob.wizardry.spell.Possession;
|
||||||
import electroblob.wizardry.spell.*;
|
import electroblob.wizardry.spell.SixthSense;
|
||||||
import electroblob.wizardry.util.RayTracer;
|
import electroblob.wizardry.spell.SlowTime;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.spell.Transience;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiMerchant;
|
import net.minecraft.client.gui.GuiMerchant;
|
||||||
import net.minecraft.client.gui.GuiTextField;
|
import net.minecraft.client.gui.ScaledResolution;
|
||||||
import net.minecraft.client.gui.inventory.GuiContainerCreative;
|
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
import net.minecraft.client.renderer.GlStateManager;
|
import net.minecraft.client.renderer.GlStateManager;
|
||||||
import net.minecraft.client.renderer.OpenGlHelper;
|
|
||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.creativetab.CreativeTabs;
|
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
|
||||||
import net.minecraft.entity.item.EntityArmorStand;
|
|
||||||
import net.minecraft.inventory.Slot;
|
import net.minecraft.inventory.Slot;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityDispenser;
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
|
||||||
import net.minecraft.village.MerchantRecipe;
|
import net.minecraft.village.MerchantRecipe;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.event.*;
|
import net.minecraftforge.client.event.*;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
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
|
* @author Electroblob
|
||||||
* @since Wizardry 1.0
|
* @since Wizardry 1.0
|
||||||
@@ -63,76 +48,19 @@ import java.util.Locale;
|
|||||||
@Mod.EventBusSubscriber(Side.CLIENT)
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
public final class WizardryClientEventHandler {
|
public final class WizardryClientEventHandler {
|
||||||
|
|
||||||
private static final ResourceLocation SIXTH_SENSE_MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker.png");
|
private WizardryClientEventHandler(){} // No instances!
|
||||||
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");
|
|
||||||
|
|
||||||
/** The remaining time for which the blink screen overlay effect will be displayed in first-person. Since this is
|
// Tick Events
|
||||||
* 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;
|
|
||||||
|
|
||||||
/** 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
|
@SubscribeEvent
|
||||||
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
|
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
|
||||||
|
|
||||||
if(event.player == Minecraft.getMinecraft().player && event.phase == TickEvent.Phase.END){
|
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
|
// Reset shaders if their respective potions aren't active
|
||||||
// This is a player so the potion effects are synced by vanilla
|
// 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();
|
String activeShader = Minecraft.getMinecraft().entityRenderer.getShaderGroup().getShaderGroupName();
|
||||||
|
|
||||||
@@ -141,7 +69,7 @@ public final class WizardryClientEventHandler {
|
|||||||
|| (activeShader.equals(Transience.SHADER.toString()) && !Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.transience))){
|
|| (activeShader.equals(Transience.SHADER.toString()) && !Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.transience))){
|
||||||
|
|
||||||
if(activeShader.equals(SixthSense.SHADER.toString())
|
if(activeShader.equals(SixthSense.SHADER.toString())
|
||||||
|| activeShader.equals(Transience.SHADER.toString())) playBlinkEffect();
|
|| activeShader.equals(Transience.SHADER.toString())) RenderBlinkEffect.playBlinkEffect();
|
||||||
|
|
||||||
Minecraft.getMinecraft().entityRenderer.stopUseShader();
|
Minecraft.getMinecraft().entityRenderer.stopUseShader();
|
||||||
}
|
}
|
||||||
@@ -149,41 +77,8 @@ public final class WizardryClientEventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
// The classes referenced here used to handle their own client tick events, but since they're not client-only
|
||||||
public static void onRenderHandEvent(RenderHandEvent event){
|
// classes, that crashed the dedicated server...
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onClientTickEvent(TickEvent.ClientTickEvent event){
|
public static void onClientTickEvent(TickEvent.ClientTickEvent event){
|
||||||
|
|
||||||
@@ -209,6 +104,9 @@ public final class WizardryClientEventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Input and Controls
|
||||||
|
// ===============================================================================================================
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onMouseEvent(MouseEvent event){
|
public static void onMouseEvent(MouseEvent event){
|
||||||
|
|
||||||
@@ -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
|
@SubscribeEvent
|
||||||
public static void onFOVUpdateEvent(FOVUpdateEvent event){
|
public static void onFOVUpdateEvent(FOVUpdateEvent event){
|
||||||
|
|
||||||
@@ -241,26 +178,6 @@ public final class WizardryClientEventHandler {
|
|||||||
|
|
||||||
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F);
|
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.
|
// 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){
|
* Renders an overlay across the entire screen.
|
||||||
// Reduces reflection as much as possible - searchField is created on GUI init and never reassigned so we need
|
* @param resolution The screen resolution
|
||||||
// not (and should not!) use reflection to retrieve it every time a key is typed
|
* @param texture The overlay texture to display
|
||||||
if(event.getGui() instanceof GuiContainerCreative){
|
*/
|
||||||
try{
|
public static void renderScreenOverlay(ScaledResolution resolution, ResourceLocation texture){
|
||||||
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){
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
GlStateManager.pushMatrix();
|
||||||
|
|
||||||
@@ -532,11 +224,12 @@ public final class WizardryClientEventHandler {
|
|||||||
BufferBuilder buffer = tessellator.getBuffer();
|
BufferBuilder buffer = tessellator.getBuffer();
|
||||||
|
|
||||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
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)
|
buffer.pos(0, resolution.getScaledHeight(), -90).tex(0, 1).endVertex();
|
||||||
.endVertex();
|
buffer.pos(resolution.getScaledWidth(), resolution.getScaledHeight(), -90).tex(1, 1).endVertex();
|
||||||
buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex();
|
buffer.pos(resolution.getScaledWidth(), 0, -90).tex(1, 0).endVertex();
|
||||||
buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex();
|
buffer.pos(0, 0, -90).tex(0, 0).endVertex();
|
||||||
|
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
|
|
||||||
GlStateManager.depthMask(true);
|
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;
|
package electroblob.wizardry.client.renderer;
|
||||||
|
|
||||||
/** Instances of this class can calculate their distance from the camera viewpoint and sort themselves accordingly. */
|
/** 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;
|
int ordinal;
|
||||||
double x1, y1, z1;
|
public double x1, y1, z1;
|
||||||
double x2, y2, z2;
|
public double x2, y2, z2;
|
||||||
double offsetX, offsetY, offsetZ;
|
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){
|
double offsetY, double offsetZ){
|
||||||
this.ordinal = ordinal;
|
this.ordinal = ordinal;
|
||||||
this.x1 = x1;
|
this.x1 = x1;
|
||||||
@@ -37,13 +37,7 @@ class RayHelper implements Comparable<RayHelper> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(RayHelper ray){
|
public int compareTo(RayHelper ray){
|
||||||
if(this.getDistanceFromViewpoint() > ray.getDistanceFromViewpoint()){
|
return Double.compare(ray.getDistanceFromViewpoint(), this.getDistanceFromViewpoint());
|
||||||
return -1;
|
|
||||||
}else if(this.getDistanceFromViewpoint() < ray.getDistanceFromViewpoint()){
|
|
||||||
return 1;
|
|
||||||
}else{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.effect;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.potion.PotionContainment;
|
import electroblob.wizardry.potion.PotionContainment;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.effect;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.effect;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.data.WizardData;
|
import electroblob.wizardry.data.WizardData;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.effect;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
|
import electroblob.wizardry.client.renderer.RayHelper;
|
||||||
import electroblob.wizardry.entity.construct.EntityBlackHole;
|
import electroblob.wizardry.entity.construct.EntityBlackHole;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.*;
|
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
|
// coordinates which were inconsistent with my calculated ones. Since I know those will give the desired
|
||||||
// effect anyway, I just used them directly instead.
|
// 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++){
|
for(int j = 0; j < 30; j++){
|
||||||
|
|
||||||
+1
-1
@@ -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.Render;
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.construct.EntityBubble;
|
import electroblob.wizardry.entity.construct.EntityBubble;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.construct.EntityDecay;
|
import electroblob.wizardry.entity.construct.EntityDecay;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.living.EntityDecoy;
|
import electroblob.wizardry.entity.living.EntityDecoy;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.model.ModelWizard;
|
import electroblob.wizardry.client.model.ModelWizard;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.construct.EntityFireRing;
|
import electroblob.wizardry.entity.construct.EntityFireRing;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.projectile.EntityForceArrow;
|
import electroblob.wizardry.entity.projectile.EntityForceArrow;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.construct.EntityForcefield;
|
import electroblob.wizardry.entity.construct.EntityForcefield;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.model.ModelHammer;
|
import electroblob.wizardry.client.model.ModelHammer;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.model.ModelIceGiant;
|
import electroblob.wizardry.client.model.ModelIceGiant;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.construct.EntityIceSpike;
|
import electroblob.wizardry.entity.construct.EntityIceSpike;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.projectile.EntityLightningDisc;
|
import electroblob.wizardry.entity.projectile.EntityLightningDisc;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.projectile.EntityMagicArrow;
|
import electroblob.wizardry.entity.projectile.EntityMagicArrow;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.model.ModelPhoenix;
|
import electroblob.wizardry.client.model.ModelPhoenix;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.spell.Possession;
|
import electroblob.wizardry.spell.Possession;
|
||||||
import net.minecraft.client.renderer.entity.Render;
|
import net.minecraft.client.renderer.entity.Render;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.projectile.EntityMagicProjectile;
|
import electroblob.wizardry.entity.projectile.EntityMagicProjectile;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.model.ModelRemnant;
|
import electroblob.wizardry.client.model.ModelRemnant;
|
||||||
+1
-1
@@ -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.EntityHealAura;
|
||||||
import electroblob.wizardry.entity.construct.EntityMagicConstruct;
|
import electroblob.wizardry.entity.construct.EntityMagicConstruct;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.living.EntitySpiritHorse;
|
import electroblob.wizardry.entity.living.EntitySpiritHorse;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.living.EntitySpiritWolf;
|
import electroblob.wizardry.entity.living.EntitySpiritWolf;
|
||||||
+2
-1
@@ -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.RenderManager;
|
||||||
import net.minecraft.client.renderer.entity.RenderSkeleton;
|
import net.minecraft.client.renderer.entity.RenderSkeleton;
|
||||||
import net.minecraft.entity.monster.AbstractSkeleton;
|
import net.minecraft.entity.monster.AbstractSkeleton;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.model.ModelWizard;
|
import electroblob.wizardry.client.model.ModelWizard;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.living.EntityBlazeMinion;
|
import electroblob.wizardry.entity.living.EntityBlazeMinion;
|
||||||
import net.minecraft.client.model.ModelBlaze;
|
import net.minecraft.client.model.ModelBlaze;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.construct.EntityZombieSpawner;
|
import electroblob.wizardry.entity.construct.EntityZombieSpawner;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity.layers;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.spell.Disintegration;
|
import electroblob.wizardry.spell.Disintegration;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity.layers;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.block.BlockStatue;
|
import electroblob.wizardry.block.BlockStatue;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity.layers;
|
||||||
|
|
||||||
import electroblob.wizardry.block.BlockStatue;
|
import electroblob.wizardry.block.BlockStatue;
|
||||||
import electroblob.wizardry.client.ClientProxy;
|
import electroblob.wizardry.client.ClientProxy;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity.layers;
|
||||||
|
|
||||||
import electroblob.wizardry.entity.living.EntityStrayMinion;
|
import electroblob.wizardry.entity.living.EntityStrayMinion;
|
||||||
import net.minecraft.client.model.ModelSkeleton;
|
import net.minecraft.client.model.ModelSkeleton;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.entity.layers;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.living.ISummonedCreature;
|
import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||||
+1
-1
@@ -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.Minecraft;
|
||||||
import net.minecraft.client.model.ModelBase;
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+9
-9
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.overlay;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.data.WizardData;
|
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
|
// 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
|
// 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 distanceCap = Minecraft.getMinecraft().gameSettings.renderDistanceChunks * 16 - 8;
|
||||||
double displayDist = distance > distanceCap ? distanceCap : distance;
|
double displayDist = Math.min(distance, distanceCap);
|
||||||
double factor = displayDist/distance;
|
double factor = displayDist/distance;
|
||||||
|
|
||||||
GlStateManager.translate(position.x * factor, position.y * factor, position.z * factor);
|
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
|
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(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, 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(1, 1).color(f, 1, f, f).endVertex();
|
||||||
buffer.pos(-iconSize, -iconSize, 0).tex(0, 1).color(f, 1, f, f).endVertex();
|
buffer.pos(-iconSize, -iconSize, 0).tex(0, 1).color(f, 1, f, f).endVertex();
|
||||||
|
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
@@ -157,10 +157,10 @@ public class RenderTransportationUI {
|
|||||||
Tessellator tessellator = Tessellator.getInstance();
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||||
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR);
|
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((-i - 1), (-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((-i - 1), ( 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(( i + 1), ( 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();
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
GlStateManager.enableTexture2D();
|
GlStateManager.enableTexture2D();
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.tileentity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.spell.ArcaneLock;
|
import electroblob.wizardry.spell.ArcaneLock;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.tileentity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.tileentity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.tileentity.TileEntityLectern;
|
import electroblob.wizardry.tileentity.TileEntityLectern;
|
||||||
+26
-1
@@ -1,6 +1,10 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.tileentity;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
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 electroblob.wizardry.tileentity.TileEntityMagicLight;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.renderer.*;
|
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.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.MathHelper;
|
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;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
@EventBusSubscriber(Side.CLIENT)
|
||||||
public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicLight> {
|
public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicLight> {
|
||||||
|
|
||||||
private static final ResourceLocation RAY_TEXTURE = new ResourceLocation(Wizardry.MODID,
|
private static final ResourceLocation RAY_TEXTURE = new ResourceLocation(Wizardry.MODID,
|
||||||
@@ -125,4 +135,19 @@ public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicL
|
|||||||
GlStateManager.popMatrix();
|
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
-1
@@ -1,4 +1,4 @@
|
|||||||
package electroblob.wizardry.client.renderer;
|
package electroblob.wizardry.client.renderer.tileentity;
|
||||||
|
|
||||||
import electroblob.wizardry.tileentity.TileEntityStatue;
|
import electroblob.wizardry.tileentity.TileEntityStatue;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
Reference in New Issue
Block a user