Jump to content

[1.10.2] [Scala] Capabilities clashing with each other (SOLVED)


tripl3dogdare

Recommended Posts

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)

 

class ServerProxy {
def preInit {
	CapabilityManager.INSTANCE.register(classOf[ManaHandler], ManaHandler.getStorageInstance, ManaHandler.getHandlerFactory)
	CapabilityManager.INSTANCE.register(classOf[LevelHandler], LevelHandler.getStorageInstance, LevelHandler.getHandlerFactory)
	MinecraftForge.EVENT_BUS.register(new ChuuniEventHandler)
}
}

 

 

Relevant event handler code

 

@SubscribeEvent def addPlayerCapabilities(e:AttachCapabilitiesEvent.Entity) {
if(e.getEntity.isInstanceOf[EntityPlayer]) {
	e.addCapability(new ResourceLocation(ChuuniMod.MODID, "ManaHandler"), ManaHandler.getHandlerInstance)
	e.addCapability(new ResourceLocation(ChuuniMod.MODID, "LevelHandler"), LevelHandler.getHandlerInstance)
}
}

 

 

Relevant capability code

 

object LevelHandler {
@CapabilityInject(classOf[LevelHandler]) final val CAP:Capability[LevelHandler] = null

def instanceFor(player:EntityPlayer) = player.getCapability(CAP, null)
def getHandlerInstance = new DefaultLevelHandler
def getStorageInstance = new DefaultLevelHandler.Storage
def getHandlerFactory = new Callable[DefaultLevelHandler] { def call = new DefaultLevelHandler }
}

object ManaHandler {
@CapabilityInject(classOf[ManaHandler]) final val CAP:Capability[ManaHandler] = null

def instanceFor(player:EntityPlayer) = player.getCapability(CAP, null)
def getHandlerInstance = new DefaultManaHandler
def getStorageInstance = new DefaultManaHandler.Storage
def getHandlerFactory = new Callable[DefaultManaHandler] { def call = new DefaultManaHandler }
}

 

 

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!

Link to comment
Share on other sites

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:

 

---- Minecraft Crash Report ----
// Don't be sad. I'll do better next time, I promise!

Time: 10/7/16 5:31 PM
Description: Unexpected error

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)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Thread: Client thread
Stacktrace:
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)

-- Affected level --
Details:
Level name: MpServer
All players: 1 total; [EntityPlayerSP['tripl3_'/949, l='MpServer', x=8.50, y=65.00, z=8.50]]
Chunk stats: MultiplayerChunkCache: 0, 0
Level seed: 0
Level generator: ID 00 - default, ver 1. Features enabled: false
Level generator options: 
Level spawn location: World: (-116,64,124), Chunk: (at 12,4,12 in -8,7; contains blocks -128,0,112 to -113,255,127), Region: (-1,0; contains chunks -32,0 to -1,31, blocks -512,0,0 to -1,255,511)
Level time: 0 game time, 0 day time
Level dimension: 0
Level storage version: 0x00000 - Unknown?
Level weather: Rain time: 0 (now: false), thunder time: 0 (now: false)
Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: false
Forced entities: 1 total; [EntityPlayerSP['tripl3_'/949, l='MpServer', x=8.50, y=65.00, z=8.50]]
Retry entities: 0 total; []
Server brand: fml,forge
Server type: Integrated singleplayer server
Stacktrace:
at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:451)
at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2779)
at net.minecraft.client.Minecraft.run(Minecraft.java:435)
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)

-- System Details --
Details:
Minecraft Version: 1.10.2
Operating System: Windows 10 (amd64) version 10.0
Java Version: 1.8.0_74, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 598666392 bytes (570 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
JVM Flags: 4 total; -Xincgc -Xmx1024M -Xms1024M -Xbootclasspath/a:C:\Program Files (x86)\Scala IDE\plugins\org.scala-lang.scala-library_2.11.8.v20160304-115712-1706a37eb8.jar;C:\Program Files (x86)\Scala IDE\plugins\org.scala-lang.scala-reflect_2.11.8.v20160304-115712-1706a37eb8.jar
IntCache: cache: 0, tcache: 0, allocated: 13, tallocated: 95
FML: MCP 9.32 Powered by Forge 12.18.1.2095 4 mods loaded, 4 mods active
States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
UCHIJAAAA	mcp{9.19} [Minecraft Coder Pack] (minecraft.jar) 
UCHIJAAAA	FML{8.0.99.99} [Forge Mod Loader] (forgeSrc-1.10.2-12.18.1.2095.jar) 
UCHIJAAAA	Forge{12.18.1.2095} [Minecraft Forge] (forgeSrc-1.10.2-12.18.1.2095.jar) 
UCHIJAAAA	chuunimod{INDEV} [ChuuniMod] (bin) 
Loaded coremods (and transformers): 
GL info: ' Vendor: 'NVIDIA Corporation' Version: '4.5.0 NVIDIA 358.91' Renderer: 'GeForce GTX 750 Ti/PCIe/SSE2'
Launched Version: 1.10.2
LWJGL: 2.9.4
OpenGL: GeForce GTX 750 Ti/PCIe/SSE2 GL version 4.5.0 NVIDIA 358.91, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing.
Using GL 1.3 texture combiners.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Shaders are available because OpenGL 2.1 is supported.
VBOs are available because OpenGL 1.5 is supported.

Using VBOs: Yes
Is Modded: Definitely; Client brand changed to 'fml,forge'
Type: Client (map_client.txt)
Resource Packs: 
Current Language: English (US)
Profiler Position: N/A (disabled)
CPU: 4x Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz

 

 

All I'm doing is trying to access the handlers via the instanceFor method to render their information to a GUI.

Link to comment
Share on other sites

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])
}
}

Link to comment
Share on other sites

Not really sure what you mean by the same class - the capability type is Handler, and the default implementation is DefaultHandler.

 

As to the debugger idea, the only option I have is the Eclipse debugger, which doesn't seem to be up to the task.

Link to comment
Share on other sites

DefaultLevelHandler implements both LevelHandler and ICapabilitySerializable (i.e. ICapabilityProvider)

Ah, ok. Honestly, I've used this structure before and not had any problems with keeping track of it... For brevity's sake I'll leave it for now, especially as I don't think that's where the problem is (the mana handler worked fine before I added the level handler)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • If you're seeking an unparalleled solution to recover lost or stolen cryptocurrency, let me introduce you to GearHead Engineers Solutions. Their exceptional team of cybersecurity experts doesn't just restore your funds; they restore your peace of mind. With a blend of cutting-edge technology and unparalleled expertise, GearHead Engineers swiftly navigates the intricate web of the digital underworld to reclaim what's rightfully yours. In your moment of distress, they become your steadfast allies, guiding you through the intricate process of recovery with transparency, trustworthiness, and unwavering professionalism. Their team of seasoned web developers and cyber specialists possesses the acumen to dissect the most sophisticated schemes, leaving no stone unturned in their quest for justice. They don't just stop at recovering your assets; they go the extra mile to identify and track down the perpetrators, ensuring they face the consequences of their deceitful actions. What sets  GearHead Engineers apart is not just their technical prowess, but their unwavering commitment to their clients. From the moment you reach out to them, you're met with compassion, understanding, and a resolute determination to right the wrongs inflicted upon you. It's not just about reclaiming lost funds; it's about restoring faith in the digital landscape and empowering individuals to reclaim control over their financial futures. If you find yourself ensnared in the clutches of cybercrime, don't despair. Reach out to GearHead Engineers and let them weave their magic. With their expertise by your side, you can turn the tide against adversity and emerge stronger than ever before. In the realm of cybersecurity, GearHead Engineers reigns supreme. Don't just take my word for it—experience their unparalleled excellence for yourself. Your journey to recovery starts here.
    • Ok so this specific code freezes the game on world creation. This is what gets me so confused, i get that it might not be the best thing, but is it really so generation heavy?
    • Wizard web recovery has exhibited unparalleled strength in the realm of recovery. They stand out as the premier team to collaborate with if you encounter withdrawal difficulties from the platform where you’ve invested. Recently, I engaged with them to recover over a million dollars trapped in an investment platform I’d been involved with for months. I furnished their team with every detail of the investment, including accounts, names, and wallet addresses to which I sent the funds. This decision proved to be the best I’ve made, especially after realizing the company had scammed me.   Wizard web recovery ensures exemplary service delivery and ensures the perpetrators face justice. They employ advanced techniques to ensure you regain access to your funds. Understandably, many individuals who have fallen victim to investment scams may still regret engaging in online services again due to the trauma of being scammed. However, I implore you to take action. Seek assistance from Wizard Web Recovery today and witness their remarkable capabilities. I am grateful that I resisted their enticements, and despite the time it took me to discover Wizard web recovery, they ultimately fulfilled my primary objective. Without wizard web recovery intervention, I would have remained despondent and perplexed indefinitely.
    • I've tested the same code on three different envionrments (Desktop win10, desktop Linux and Laptop Linux) and it kinda blows up all the same. Gonna try this code and see if i can tune it
    • Minecraft version? Mod loader?
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.