From 6433d18907f6ab11d1a826a3b3ef522d12cd450d Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Sun, 21 May 2023 18:49:00 +0200 Subject: [PATCH] feat: implement detector --- .../anvilcraft/thaummach/RenderTicker.java | 107 +++++++++++- .../net/anvilcraft/thaummach/TMItems.java | 6 + .../thaummach/items/ItemDetector.java | 160 ++++++++++++++++++ .../assets/thaummach/lang/en_US.lang | 4 + .../thaummach/textures/guis/detector.png | Bin 0 -> 9189 bytes .../thaummach/textures/items/detector_0.png | Bin 0 -> 633 bytes .../thaummach/textures/items/detector_1.png | Bin 0 -> 608 bytes .../thaummach/textures/items/detector_2.png | Bin 0 -> 683 bytes 8 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/anvilcraft/thaummach/items/ItemDetector.java create mode 100644 src/main/resources/assets/thaummach/textures/guis/detector.png create mode 100644 src/main/resources/assets/thaummach/textures/items/detector_0.png create mode 100644 src/main/resources/assets/thaummach/textures/items/detector_1.png create mode 100644 src/main/resources/assets/thaummach/textures/items/detector_2.png diff --git a/src/main/java/net/anvilcraft/thaummach/RenderTicker.java b/src/main/java/net/anvilcraft/thaummach/RenderTicker.java index 7e97a4a..a5b2ac7 100644 --- a/src/main/java/net/anvilcraft/thaummach/RenderTicker.java +++ b/src/main/java/net/anvilcraft/thaummach/RenderTicker.java @@ -1,19 +1,124 @@ package net.anvilcraft.thaummach; +import java.util.Collection; + import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent.Phase; import cpw.mods.fml.common.gameevent.TickEvent.RenderTickEvent; +import dev.tilera.auracore.client.AuraManagerClient; +import dev.tilera.auracore.client.AuraManagerClient.NodeStats; import net.anvilcraft.thaummach.render.PortalRenderer; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; public class RenderTicker { @SubscribeEvent public void onRenderTickEvent(RenderTickEvent ev) { - if (Minecraft.getMinecraft().theWorld == null) + if (Minecraft.getMinecraft().theWorld == null || ev.phase != Phase.END) return; for (PortalRenderer ren : PortalRenderer.INSTANCES) { // TODO: optimize ren.createPortalView(); } + + EntityPlayer pl = Minecraft.getMinecraft().thePlayer; + if (pl == null) + // WTF + return; + + int foundDetectorType = -1; + + for (int i = 0; i < pl.inventory.getSizeInventory(); i++) { + ItemStack stack = pl.inventory.getStackInSlot(i); + if (stack != null && stack.getItem() == TMItems.detector) { + foundDetectorType = stack.getItemDamage(); + break; + } + } + + if (foundDetectorType >= 0) { + GuiDetector.INSTANCE.render(foundDetectorType); + } + } + + public static class GuiDetector extends Gui { + public static final GuiDetector INSTANCE = new GuiDetector(); + + public NodeStats findNode() { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + NodeStats closest = null; + double closestDistance = Double.MAX_VALUE; + Collection col = AuraManagerClient.auraClientList.values(); + for (NodeStats stats : col) { + int dim = stats.dimension; + if (player.dimension != dim) + continue; + double px = stats.x; + double py = stats.y; + double pz = stats.z; + double xd = px - player.posX; + double yd = py - player.posY; + double zd = pz - player.posZ; + double distSq = xd * xd + yd * yd + zd * zd; + if (!(distSq < closestDistance)) + continue; + closestDistance = distSq; + closest = stats; + } + return closest; + } + + public void render(int type) { + NodeStats aura = this.findNode(); + if (aura == null) + return; + + Minecraft mc = Minecraft.getMinecraft(); + ScaledResolution scaledresolution + = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + int k = scaledresolution.getScaledWidth(); + int l = scaledresolution.getScaledHeight(); + mc.entityRenderer.setupOverlayRendering(); + GL11.glEnable(3042); + GL11.glEnable(32826); + RenderHelper.enableStandardItemLighting(); + RenderHelper.disableStandardItemLighting(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + mc.renderEngine.bindTexture( + new ResourceLocation("thaummach", "textures/guis/detector.png") + ); + super.zLevel = -90.0F; + int sv = 48 * (aura.base * 2 - aura.level) / (aura.base * 2); + int st = 48 * (aura.base * 2 - aura.taint) / (aura.base * 2); + if (type == 0 || type == 2 || type >= 3) { + //if (aura.goodVibes > 0) { + // this.drawTexturedModalRect(k - 34, l - 17, 0, 72, 16, 16); + //} + + this.drawTexturedModalRect(k - 30, l - 67 + sv, 0, 0 + sv, 8, 48 - sv); + + this.drawTexturedModalRect(k - 31, l - 71, 23, 0, 10, 74); + } + + if (type == 1 || type == 2 || type >= 3) { + //if (aura.badVibes > 0) { + // this.drawTexturedModalRect(k - 19, l - 17, 0, 72, 16, 16); + //} + + this.drawTexturedModalRect(k - 15, l - 67 + st, 8, 0 + st, 8, 48 - st); + + this.drawTexturedModalRect(k - 16, l - 71, 39, 0, 10, 74); + } + + GL11.glDisable(32826); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } } } diff --git a/src/main/java/net/anvilcraft/thaummach/TMItems.java b/src/main/java/net/anvilcraft/thaummach/TMItems.java index 547fecb..620a02f 100644 --- a/src/main/java/net/anvilcraft/thaummach/TMItems.java +++ b/src/main/java/net/anvilcraft/thaummach/TMItems.java @@ -2,6 +2,7 @@ package net.anvilcraft.thaummach; import cpw.mods.fml.common.registry.GameRegistry; import net.anvilcraft.thaummach.items.ItemCrystallineBell; +import net.anvilcraft.thaummach.items.ItemDetector; import net.anvilcraft.thaummach.items.ItemFocus; import net.anvilcraft.thaummach.items.ItemRunicEssence; import net.anvilcraft.thaummach.items.ItemSingularity; @@ -11,6 +12,7 @@ import net.minecraft.item.Item; public class TMItems { public static Item crystallineBell; + public static Item detector; public static Item focus0; public static Item focus1; public static Item focus2; @@ -24,6 +26,8 @@ public class TMItems { public static void init() { crystallineBell = new ItemCrystallineBell(); + detector = new ItemDetector(); + focus0 = new ItemFocus(0); focus1 = new ItemFocus(1); focus2 = new ItemFocus(2); @@ -40,6 +44,8 @@ public class TMItems { GameRegistry.registerItem(crystallineBell, "crystalline_bell"); + GameRegistry.registerItem(detector, "detector"); + GameRegistry.registerItem(focus0, "focus0"); GameRegistry.registerItem(focus1, "focus1"); GameRegistry.registerItem(focus2, "focus2"); diff --git a/src/main/java/net/anvilcraft/thaummach/items/ItemDetector.java b/src/main/java/net/anvilcraft/thaummach/items/ItemDetector.java new file mode 100644 index 0000000..14ae298 --- /dev/null +++ b/src/main/java/net/anvilcraft/thaummach/items/ItemDetector.java @@ -0,0 +1,160 @@ +package net.anvilcraft.thaummach.items; + +import java.util.List; +import java.util.stream.IntStream; + +import dev.tilera.auracore.api.HelperLocation; +import dev.tilera.auracore.api.machine.IConnection; +import net.anvilcraft.thaummach.TMTab; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumRarity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +public class ItemDetector extends Item { + public IIcon[] icons; + + public ItemDetector() { + super(); + super.maxStackSize = 1; + this.setHasSubtypes(true); + this.setMaxDamage(0); + this.setCreativeTab(TMTab.INSTANCE); + } + + @Override + public EnumRarity getRarity(ItemStack itemstack) { + return EnumRarity.uncommon; + } + + @Override + public void registerIcons(IIconRegister reg) { + this.icons = IntStream.rangeClosed(0, 2) + .mapToObj((i) -> "thaummach:detector_" + i) + .map(reg::registerIcon) + .toArray(IIcon[] ::new); + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void getSubItems(Item alec1, CreativeTabs tab, List list) { + IntStream.rangeClosed(0, 2) + .mapToObj((i) -> new ItemStack(this, 1, i)) + .forEach(list::add); + } + + @Override + public IIcon getIconFromDamage(int meta) { + return this.icons[meta]; + } + + @Override + public String getUnlocalizedName(ItemStack stack) { + return "item.thaummach:detector_" + stack.getItemDamage(); + } + + @Override + public boolean onItemUseFirst( + ItemStack itemstack, + EntityPlayer entityplayer, + World world, + int x, + int y, + int z, + int l, + // useless parameters + float alec1, + float alec2, + float alec3 + ) { + TileEntity ent = world.getTileEntity(x, y, z); + if (ent instanceof IConnection) { + IConnection tet = (IConnection) ent; + if (itemstack.getItemDamage() == 0) { + if (world.isRemote) + return false; + entityplayer.addChatMessage(new ChatComponentText( + "Detected " + Math.round(tet.getPureVis()) + " Vis." + )); + world.playSoundEffect( + (double) x, (double) y, (double) z, "note.harp", 0.8F, 1.0F + ); + if (tet.getVisSuction((HelperLocation) null) > 0) { + entityplayer.addChatMessage(new ChatComponentText( + tet.getVisSuction((HelperLocation) null) + " Vis TCB" + )); + } + + return true; + } + + if (itemstack.getItemDamage() == 1) { + if (world.isRemote) + return false; + entityplayer.addChatMessage(new ChatComponentText( + "Detected " + Math.round(tet.getTaintedVis()) + " Taint." + )); + world.playSoundEffect( + (double) x, (double) y, (double) z, "note.harp", 0.8F, 1.0F + ); + if (tet.getTaintSuction((HelperLocation) null) > 0) { + entityplayer.addChatMessage(new ChatComponentText( + tet.getTaintSuction((HelperLocation) null) + " Taint TCB" + )); + } + + return true; + } + + if (itemstack.getItemDamage() == 2) { + if (world.isRemote) + return false; + int cap = Math.round( + (float) Math.round(tet.getPureVis() + tet.getTaintedVis()) + / tet.getMaxVis() * 100.0F + ); + int capp = Math.round( + (float) Math.round(tet.getPureVis()) / tet.getMaxVis() * 100.0F + ); + int capt = Math.round( + (float) Math.round(tet.getTaintedVis()) / tet.getMaxVis() * 100.0F + ); + entityplayer.addChatMessage(new ChatComponentText( + "Detected " + Math.round(tet.getPureVis()) + " Vis (" + capp + + "%) and " + Math.round(tet.getTaintedVis()) + " Taint (" + capt + + "%)." + )); + entityplayer.addChatMessage( + new ChatComponentText("The object is at " + cap + "% capacity.") + ); + world.playSoundEffect( + (double) x, + (double) y, + (double) z, + "note.harp", + 0.8F, + 1.0F + 1.0F * (float) cap / 100.0F + ); + if (tet.getTaintSuction((HelperLocation) null) > 0 + || tet.getVisSuction((HelperLocation) null) > 0) { + entityplayer.addChatMessage(new ChatComponentText( + "" + tet.getVisSuction((HelperLocation) null) + " Vis TCB, " + + tet.getTaintSuction((HelperLocation) null) + " Taint TCB" + )); + } + + return true; + } + } + + return super.onItemUseFirst( + itemstack, entityplayer, world, x, y, z, l, alec1, alec2, alec3 + ); + } +} diff --git a/src/main/resources/assets/thaummach/lang/en_US.lang b/src/main/resources/assets/thaummach/lang/en_US.lang index bb327cf..57a44e9 100644 --- a/src/main/resources/assets/thaummach/lang/en_US.lang +++ b/src/main/resources/assets/thaummach/lang/en_US.lang @@ -33,6 +33,10 @@ tile.thaummach:apparatus_wood_dusk_totem.name=Dusk Totem # ---- ITEMS ---- +item.thaummach:detector_0.name=Vis Detector +item.thaummach:detector_1.name=Taint Detector +item.thaummach:detector_2.name=Thaumic Detector + item.thaummach:focus_0.name=Arcane Focus item.thaummach:focus_1.name=Arcane Focus: Air item.thaummach:focus_2.name=Arcane Focus: Water diff --git a/src/main/resources/assets/thaummach/textures/guis/detector.png b/src/main/resources/assets/thaummach/textures/guis/detector.png new file mode 100644 index 0000000000000000000000000000000000000000..f36dc625a0e570fc3efcbbc191195f97164f85ed GIT binary patch literal 9189 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/thaummach/textures/items/detector_1.png b/src/main/resources/assets/thaummach/textures/items/detector_1.png new file mode 100644 index 0000000000000000000000000000000000000000..dc4af9fbd36776fc1b6e07042ad0f1b360835fe5 GIT binary patch literal 608 zcmV-m0-ybfP)4kCDx;>DtZIf!`hP(dX~sYMY( zTd+!n)lJD-w|UOKm^GV55S+(b-YoC`=bxE3hEj_EvQ7liNL2az;^=mDu&;6UcSmeH zfq!vsazJ_S(#o4ptLnW0?T;PUOyXms?O@j}L**2i{F?q}$chl>ej!C7VRL8JRbJgQ znwUsC_*tn$HeX|>a~a1OWWza(;T+|3F~OxH7Uyz}yI~nk*&=z!>{lmwrSeRvB>Pni zOARrmGF(tuGp+BP8EK^BV*>?y#uH=?tc%;WHpB>U)+6nt}?Va^tljGwUn zq}^6mmU+wuKV+?nU&j)H8lPDg%B}2@h+#ogP(!WQFO%7h>jXVsr~EC!j@< z-77VD$WQTl%q6BKK2R!G!vua`r=|TjpWECmEE6~1&_hu*XTCibL;jn3#+@C znQdV7JMmj#7)J0G{61efmg0PIQ1Ui^Kc+6OPQ0Kjb-MP*4Zs@PO3+GjJZFW9HM3xc uBL9`3Nz!TXTEU@N=rEDSzfSWn0R{k1U+F!aLGcp+0000IkP0P?D6CvWix|X3`9Y;( zikhP|`ex?6ce``@vT`Ws!R6g|Ise}|=YP*L$^A%En0jNocJ^g#6eKn}R6;E_JF1W^ zVS;|4&;ALJ4UC_U;7S)?EQAPqDJuzZw4R)hU&MBLMB1Y@G8!zCDzmID56PNPr5w3X zAy38%m2ly4yUS>7g{Qg8ZTYXS!NxJ64Eg&C(rLiCo+G(Zct# z8E;hLE-oGHXU+ahT3S4tyGP2gXb3eah?k3pA~f#$*-n-sqs3l6B^^BEb94V7vul$~ zCC7R4v4^_C2C55cb(JfbC3@etv6!CM-&vnTb&-d}YA23;ndNknmKWC!W^YPW|6iD7&csuiJ# zE!cUz#H5b}#{oxTuB22MMyoEV#J3eAB~+G#%I&h5as>=4Sp(BNB!lwBD&s)j49m(r zJL75-4Pgk5?-e{f>%kj%jaPXQre1|lvWZfr=+ok0V2bv0%FsH&YDW8Sh;O56bjRVw zP=dRsrtt@c2~w+Duvo-qjr_nEx7v5}W+BS`mtQp-4$_HzrXHGzze*2MWymAT{o7@K zbBVli_|HMg2~llHrw=)F4FwVMNX-1Zcs(QwkYhXKyF2Jga*2)q{hhxEFaXTP`9Jwv RSycc4002ovPDHLkV1mwAGvxpP literal 0 HcmV?d00001