tripl3dogdare
Members-
Posts
41 -
Joined
-
Last visited
-
Days Won
1
Everything posted by tripl3dogdare
-
When I attempt to use getAttributeModifiers to change the attributes of an item type defined as a Scala trait, the game crashes with an IllegalAccessError as such: net.minecraft.util.ReportedException: Ticking player at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:210) ~[NetworkSystem.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:806) ~[MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:687) ~[MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) ~[integratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:536) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_74] Caused by: java.lang.IllegalAccessError: tried to access field net.minecraft.item.Item.ATTACK_DAMAGE_MODIFIER from class chuunimod.item.ItemManaWeapon$class at chuunimod.item.ItemManaWeapon$class.getAttributeModifiers(ItemManaWeapon.scala:90) ~[itemManaWeapon$class.class:?] at chuunimod.item.ItemArmorPairingManaWeapon.getAttributeModifiers(ItemArmorPairingManaWeapon.scala:20) ~[itemArmorPairingManaWeapon.class:?] at net.minecraft.item.ItemStack.getAttributeModifiers(ItemStack.java:1043) ~[itemStack.class:?] at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2187) ~[EntityLivingBase.class:?] at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:259) ~[EntityPlayer.class:?] at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:341) ~[EntityPlayerMP.class:?] at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174) ~[NetHandlerPlayServer.class:?] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:216) ~[NetworkDispatcher$1.class:?] at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:308) ~[NetworkManager.class:?] at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:195) ~[NetworkSystem.class:?] ... 5 more The relevant trait: trait ItemManaWeapon extends ItemChuuniItem { //ItemChuuniItem directly extends net.minecraft.item.Item //omitted override def getAttributeModifiers(slot:EntityEquipmentSlot, stack:ItemStack) = FMLCommonHandler.instance.getEffectiveSide match { case Side.CLIENT => super.getAttributeModifiers(slot, stack) case Side.SERVER => { val map = super.getAttributeModifiers(slot, stack) if(slot == EntityEquipmentSlot.MAINHAND && stack.hasTagCompound && stack.getTagCompound.getBoolean("active")) { map.put(SharedMonsterAttributes.ATTACK_DAMAGE.getAttributeUnlocalizedName, new AttributeModifier(Item.ATTACK_DAMAGE_MODIFIER, "Weapon modifier", getAttackDmg(stack)-2, 0)) map.put(SharedMonsterAttributes.ATTACK_SPEED.getAttributeUnlocalizedName, new AttributeModifier(Item.ATTACK_SPEED_MODIFIER, "Weapon modifier", -(4-getAttackSpd(stack)), 0)) } map } } //omitted } The code is throwing an IllegalAccessError at "Item.ATTACK_DAMAGE_MODIFIER", and I have no idea why outside of some Java/Scala interop bull****. Please help!
-
I have only the vaguest idea why, but for some reason that worked. Thank you! My updated code is below for anyone having the same issue. object (x)Handler object ManaHandler { def instanceFor(player:EntityPlayer) = player.getCapability(Capabilities.MANA, null) def getHandlerInstance = new DefaultManaHandler def getStorageInstance = new DefaultManaHandler.Storage def getHandlerFactory = new Callable[DefaultManaHandler] { def call = new DefaultManaHandler } } object LevelHandler { def instanceFor(player:EntityPlayer) = player.getCapability(Capabilities.LEVEL, null) def getHandlerInstance = new DefaultLevelHandler def getStorageInstance = new DefaultLevelHandler.Storage def getHandlerFactory = new Callable[DefaultLevelHandler] { def call = new DefaultLevelHandler } } Capabilities.java public class Capabilities { @CapabilityInject(ManaHandler.class) public static final Capability<ManaHandler> MANA = null; @CapabilityInject(LevelHandler.class) public static final Capability<LevelHandler> LEVEL = null; } Moral of the story, don't try to inject capabilities into Scala code if you intend to use more than one.
-
Mana: class DefaultManaHandler(cur:Float=0,max:Float=250,regen:Float=.25f) extends ManaHandler(cur,max,regen) with ICapabilitySerializable[NBTTagCompound] { def hasCapability(capability:Capability[_], f:EnumFacing) = capability == ManaHandler.CAP def getCapability[T](capability:Capability[T], f:EnumFacing) = { if(capability == ManaHandler.CAP) this else null }.asInstanceOf[T] def serializeNBT:NBTTagCompound = new NBTManaHandler(this).nbt def deserializeNBT(nbt:NBTTagCompound) = new NBTManaHandler(nbt).copyTo(this) } object DefaultManaHandler { class Storage extends IStorage[ManaHandler] { def writeNBT(cap:Capability[ManaHandler], ins:ManaHandler, f:EnumFacing) = ins.asInstanceOf[DefaultManaHandler].serializeNBT def readNBT(cap:Capability[ManaHandler], ins:ManaHandler, f:EnumFacing, nbt:NBTBase) = ins.asInstanceOf[DefaultManaHandler].deserializeNBT(nbt.asInstanceOf[NBTTagCompound]) } } Levels: class DefaultLevelHandler(lvl:Int=1,xp:Float=0) extends LevelHandler(lvl,xp) with ICapabilitySerializable[NBTTagCompound] { def hasCapability(capability:Capability[_], f:EnumFacing) = capability == LevelHandler.CAP def getCapability[T](capability:Capability[T], f:EnumFacing) = { if(capability == LevelHandler.CAP) this else null }.asInstanceOf[T] def serializeNBT:NBTTagCompound = new NBTLevelHandler(this).nbt def deserializeNBT(nbt:NBTTagCompound) = new NBTLevelHandler(nbt).copyTo(this) } object DefaultLevelHandler { class Storage extends IStorage[LevelHandler] { def writeNBT(cap:Capability[LevelHandler], ins:LevelHandler, f:EnumFacing) = ins.asInstanceOf[DefaultLevelHandler].serializeNBT def readNBT(cap:Capability[LevelHandler], ins:LevelHandler, f:EnumFacing, nbt:NBTBase) = ins.asInstanceOf[DefaultLevelHandler].deserializeNBT(nbt.asInstanceOf[NBTTagCompound]) } }
-
Ah yes, sorry. The game crashes with this error when I try to load a world: java.lang.ClassCastException: chuunimod.capabilities.DefaultManaHandler cannot be cast to chuunimod.capabilities.LevelHandler at chuunimod.capabilities.LevelHandler$.instanceFor(LevelHandler.scala:58) at chuunimod.gui.GuiChuuniOverlay.onRenderGameOverlay(GuiChuuniOverlay.scala:22) at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_9_GuiChuuniOverlay_onRenderGameOverlay_Post.invoke(.dynamic) at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:168) at net.minecraftforge.client.GuiIngameForge.post(GuiIngameForge.java:888) at net.minecraftforge.client.GuiIngameForge.renderExperience(GuiIngameForge.java:586) at net.minecraftforge.client.GuiIngameForge.renderGameOverlay(GuiIngameForge.java:167) at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1125) at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1139) at net.minecraft.client.Minecraft.run(Minecraft.java:406) at net.minecraft.client.main.Main.main(Main.java:118) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97) at GradleStart.main(GradleStart.java:26) Full crash report: All I'm doing is trying to access the handlers via the instanceFor method to render their information to a GUI.
-
So I'm working on a fairly large mod in Scala, and I have two different capabilities, one for handling mana and the other for handling a custom level/exp system. However, it seems like I've done something wrong, as Forge appears to try to connect an instance of the mana handler to where there should be a level handler. ServerProxy (usually called CommonProxy, I'm weird) Relevant event handler code Relevant capability code There is also an abstract class LevelHandler, but none of it's code should really be relevant. DefaultLevelHandler is a typical double-inheritance from LevelHandler and ICapabilitySerializable, and it's Storage is fairly standard as well. The same is true of ManaHandler's parts. Can you spot my error? I'm completely stumped. Thanks!
-
[1.10] Packet/Capability Issues (SOLVED)
tripl3dogdare replied to tripl3dogdare's topic in Modder Support
Thanks for the suggestions! I've been working on it a lot trying to iron out the kinks... and I've hit another block. Everything is now working fine - the client and server are in sync, everything seems to be working properly, except the data isn't saving into the world file. Note: In working on the system, I ended up implementing some of your suggestions, namely using PlayerTickEvent and using a single "dirty" variable instead of the "last***" variables to determine whether an update is necessary. Relevant event handlers: IManaHandler (includes all the capability/packet code): CommonProxy (registers packet/capability among other things): I'm using NBTExplorer to directly track what data is saved, and while everything works fine ingame, the data only saves to the world file about 1/20ish times if that and I have no idea why. Edit: Apparently NBTExplorer being open was screwing with it... FML. -
So basically the gist of what I'm trying to do is send a packet from the server to the client to update a couple of simple Capability properties on a specific player. However, the client is not being updated, and it's values are locked at 0. The capability itself seems to work fine, and the packet is being both sent and received... Relevant event handler code: Mana handler "updateClient" method: Packet class: Long story short, if the player's mana has changed since the last tick I send a packet from the server to the client that should update their client-side mana values, but despite the packet being sent and received properly their mana doesn't update. Any ideas? I'm stumped. Edit: Ok, I'm officially stupid... I changed from the ByteBufUtils read methods to the builtin ones and it worked
-
[1.10] LivingHurtEvent not damaging entities
tripl3dogdare replied to tripl3dogdare's topic in Modder Support
I admit that that wasn't nearly the best way to go about it (the entire system). That's why I changed to this: @SubscribeEvent public void onLivingHurt(LivingHurtEvent e) { if(e.getSource().getEntity() instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)e.getSource().getEntity(); if(player.getHeldItemMainhand() == null || !ItemRegistry.buffPairs.containsKey(player.getHeldItemMainhand().getItem())) return; if(!player.getHeldItemMainhand().getTagCompound().getBoolean("active")) return; ItemTimedWeapon weapon = (ItemTimedWeapon)player.getHeldItemMainhand().getItem(); ItemCharacterArmor armor = (ItemCharacterArmor)ItemRegistry.buffPairs.get(weapon); for(ItemStack i : player.getArmorInventoryList()) { if(i != null && i.getItem() == armor) { e.setAmount(weapon.onActiveAttack(e, i)); break; } e.setAmount(weapon.onActiveAttack(e, null)); } } } -
[1.10] LivingHurtEvent not damaging entities
tripl3dogdare replied to tripl3dogdare's topic in Modder Support
No, I hadn't - however, attempting to do so led me to the problem(s), namely a NullPointerException when trying to get the item in an empty armor slot and an accidental recursive self-call in ItemCharacterArmor.getAttackMultiplier rather than referencing the desired variable. I apologize for my stupidity, and thank you for working through it with me. -
[1.10] LivingHurtEvent not damaging entities
tripl3dogdare replied to tripl3dogdare's topic in Modder Support
Basically the code checks three things: 1. Is a certain weapon in the player's main hand? If so: 2. Is the weapon active? and... 3. Is a specific piece of armor equipped? If the weapon is in the main hand but inactive, it leaves it as is. If the weapon is active, it adds the weapon's attack damage to the event damage. If both the weapon and the armor are equipped, it multiplies that result by the armor's damage multiplier. At least, that's what it should do. What it's actually doing, though, is preventing you from hitting at all if the weapon is active. (You can hit normally if it isn't.) -
[1.10] LivingHurtEvent not damaging entities
tripl3dogdare replied to tripl3dogdare's topic in Modder Support
I don't see what the issue is there, I'm simply breaking the outer loop rather than the inner one and that's the only thing I can see that you could be talking about. It's a rather obscure bit of Java syntax, but it should work perfectly fine. Edit: removed it anyway as it was redundant, but it didn't change anything -
I'm working on a mod that requires some rather complex damage overrides, so I'm catching the LivingHurtEvent to apply those. However, in certain cases the damage is not applied, as if the event is being canceled, despite never canceling it in my code. The code: @SubscribeEvent public void onLivingHurt(LivingHurtEvent e) { if(e.getSource().getEntity() instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)e.getSource().getEntity(); boolean weaponEquipped = false, armorEquipped = false; Item weapon = null, armor = null; for(Item weapon_ : ItemRegistry.buffPairs.keySet()) { weapon = weapon_; armor = ItemRegistry.buffPairs.get(weapon); if(player.getHeldItemMainhand().getItem() == weapon) { if(!player.getHeldItemMainhand().getTagCompound().getBoolean("active")) return; weaponEquipped = true; for(ItemStack i : player.getArmorInventoryList()) { if(i.getItem() == armor) { armorEquipped = true; break; } } break; } } if(weaponEquipped) e.setAmount(e.getAmount()+(float)((ItemTimedWeapon)weapon).getAttackDamage()-1f); if(armorEquipped) e.setAmount(e.getAmount()*(float)((ItemCharacterArmor)armor).getDamageMultiplier()); } } Basically, I'm checking 1) if the player is holding a specific weapon and if so 2) if the weapon is in the "active" state based on it's NBT, and finally 3) whether a corresponding armor item is equipped. Then I apply changes to the damage based on whether the weapon/armor is equipped. However, the item only does damage if it is not in the active state, otherwise it acts like you didn't hit at all. Really having trouble... any ideas? Edit: slight code updates, no fix