Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Jimmeh

Members
  • Posts

    85
  • Joined

  • Last visited

Converted

  • Gender
    Undisclosed
  • Personal Text
    I am new!

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Jimmeh's Achievements

Stone Miner

Stone Miner (3/8)

0

Reputation

  1. I too am trying to learn how to make custom GUI's. Another person pointed me to this open source mod to use as reference. Using this class as a guide, I've now actually gotten a custom texture to print on screen close to how I want. https://github.com/Tfarcenim/ClassicBar/blob/1.14.x/src/main/java/tfar/classicbar/overlays/HealthBarRenderer.java I replaced his "drawTexturedModalRect()" with "GuiUtils.drawTexturedModalRect()". In his ModUtils class, he also has a tool to draw a String on screen, which I believe also exists in "GuiUtils" found in Forge and/or possibly in GlManager. I remember seeing it somewhere. Hope this helps!
  2. Ah, my apologies. I'm normally good about that. I found a much more detailed error: Caused by: net.minecraft.util.ResourceLocationException: Non [a-z0-9/._-] character in path of location: arcana:textures/gui/testHealth.png However, I'm still at a loss here. From what I see there, I'm not using any "Non [a-z0-9/._-] character". I appreciate your help!
  3. Hey! I'm trying to learn how to make a custom GUI/HUD by trying to draw my own health bar. I'm attempting to load a ResourceLocation of the test texture but it keeps throwing an ExceptionInInitializerError: null. Here's my code: private static final ResourceLocation BAR = new ResourceLocation(Arcana.MOD_ID, "textures/gui/testHealth.png"); In my main class: public static final String MOD_ID = "arcana"; And finally my resources file structure is attached below. Any ideas or guidance would be appreciated! Thanks!
  4. Hi there! I'm trying to get into modding (gave it a go a couple years ago but gave up). I remember back then there was a Gui class that would be extended to draw your own custom HUD elements. Looking for this class now, I can't seem to find it or a class that sounds like an obvious replacement. I can't seem to find any recent tutorials going over this. Following older tutorials, it would look something like this: public class TestHUD extends Gui { private static final List<RenderGameOverlayEvent.ElementType> skip = Arrays.asList( RenderGameOverlayEvent.ElementType.HEALTH, RenderGameOverlayEvent.ElementType.FOOD, RenderGameOverlayEvent.ElementType.HOTBAR ); public TestHUD() { MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void onRender(RenderGameOverlayEvent.Pre event){ if(skip.contains(event.getType())){ event.setCanceled(true); } if(event.getType() == RenderGameOverlayEvent.ElementType.TEXT){ //Apparently the TEXT 'layer' provides the best result for rendering custom things. //Perhaps it's the last layer to get rendered? Or first? Minecraft mc = Minecraft.getInstance(); mc.getRenderManager().textureManager.bindTexture(new ResourceLocation("")); drawTextureModalRect(x, y, 0, 0, width, height); } } } Here, I'm simply trying to cancel the rendering of the health bar, food bar and hotbar (both the health and food bars don't render, as intended - however, the hotbar still renders). Then I would want to draw my custom HUD on the screen and this is where I'm having an issue finding which class I need to extend. If you can offer any advice or guidance, I'd greatly appreciate it! Thanks!
  5. Your assumption was correct. I should've noticed that about the Sponge event. It works just fine using the FML events. Well, that'll do for my questions right now. Thanks for all the help! It's appreciated!
  6. Okay, this makes sense! However, it's looking like my proxies aren't getting instantiated even though I'm using the annotation. I believe this to be so because I get a NullPointerException when trying to call "proxy.preInit()". I've watched a few tutorials for this and I'm not doing anything different from them. If you have a moment, could you take a look and see if there's something wrong that catches your eye? Thanks! @SidedProxy(clientSide = "com.aurelios.client.ClientProxy", serverSide = "com.aurelios.server.ServerProxy") public static IProxy proxy; @Listener public void onGamePreInit(GamePreInitializationEvent event){ AureliosPacketHandler.init(); proxy.preInit(); } This is a SpongeForge mod (hence why I'm using GamePreInitializationEvent). For clarity, I did cast GamePreInitializationEvent to FMLPreInitializationEvent and the cast didn't fail, so I think it's safe to assume they are the same thing (or rather an extension of the FML event). And attached is my project structure, so that you can see I have the annotation pointing to the correct classes. Also, I just noticed your name. If you're the Jabelar that wrote the tutorials on Blogspot, thanks for doing that! I have everyone of those bookmarked. They have and definitely will continue to come in handy!
  7. Hi there! I'm jumping into Forge modding for the second time (I didn't last long the first after coming from using Spigot for a few years). All I'm trying to do right now is for the server to send a packet to the player that runs a command. This packet will tell the client to open a GUI. Now, I have the network part of this down, or at least, there's no errors coming from that. The error pops up when I'm trying to call Minecraft.getMinecraft().displayGuiScreen(new myGui()); I call this in my implementation of IMessageHandler, making sure that I have registered this handler to be receiving packets on the client side.I have no idea as to why the above code is throwing the NoSuchMethodError when it's running clientside. My only guess is that it has to do with run-time classpaths being different than compile-time, but I have a shadow plugin I'm using with Gradle to shade in my dependencies. Any help is greatly appreciated! Here's where I'm registering my IMessage and IMessageHandler classes: public class AureliosPacketHandler { public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel("aurelios"); private static int id = -1; public static void init() { INSTANCE.registerMessage(PacketOpenGui.GuiPacketHandler.class, PacketOpenGui.class, id++, Side.CLIENT); } } And here's the classes themselves: public class PacketOpenGui implements IMessage { private GuiTypes guiType; public PacketOpenGui(){} public PacketOpenGui(GuiTypes type){ this.guiType = type; } @Override public void fromBytes(ByteBuf buf) { guiType = GuiTypes.getGuiType(buf.readInt()).get(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(guiType.getID()); } public static class GuiPacketHandler implements IMessageHandler<PacketOpenGui, IMessage> { @Override public IMessage onMessage(PacketOpenGui message, MessageContext ctx) { Minecraft.getMinecraft().displayGuiScreen(message.guiType.getGui()); return null; } } } For reference, GuiTypes is simply an Enum to make things easier on me down the road. Again, thanks for any help!
  8. Extremely simple question, yet strangely, not one I can actually find an answer to on here. How do I add colors and styles to a message I'm sending to players? All the forum threads I can find say EnumChatFormatting but that doesn't seem to exist anymore. Thanks!
  9. Sorry about the late reply. I've been pretty busy! Okay, so I have the deobfuscated console logs of the server and client here. I've tried to "cross reference" them to figure things out, but I'm still having a difficult time. setDead() is only being called clientside, I've noticed. Here's the server: http://hastebin.com/pahiqamasu.css Here's the console: http://hastebin.com/ayihawusez.sql And here's the class in which I've overridden the despawnEntity() and setDead() methods (I left in the whole class that way the line numbers would line up correctly): http://hastebin.com/xehapoquyi.java Once again, all help is greatly appreciated! Thank you!
  10. Alrighty. So I've managed to get the deobfuscated console logs for the client and server. I've sat here trying to trace it one method to the next to figure out why this thing keeps despawning, but I can't seem to figure it out. I've added breakpoints every where I can think to put them, especially within EntityLiving#despawnEntity(). I even added the LivingEntitySpawn.AllowDespawn event, setting that result to Result.DENY, and that did absolutely nothing (in fact, it didn't even fire). I'm completely lost on what to do D: Here's the server console log: http://hastebin.com/acidipizuw.css Here's the EntityAbilityBase referred to in that log: http://hastebin.com/rinejibele.java And lastly, the EntityRock referred to as well: http://hastebin.com/mudoquguwe.java Once again, any help is greatly appreciated, because right now, I can't make custom entities
  11. Okay, so I think I've kinda narrowed it down. I've added printing stacktraces to "despawnEntity()" and "setDead()". The results seem to be this: - Entity spawns - Immediately despawns (despawnEntity()) server side - Client isn't "updated" about this because I still get "onLivingUpdate()" calls client-side - Entity eventually is setDead() client side after a few seconds. I have absolutely no idea where to go from here. There seems to be a break in server -> client synchronicity. That's the best guess I have right now Here's the entity class that I'm using: public class EntityAbilityBase extends EntityTameable { public EntityAbilityBase(World worldIn) { super(worldIn); } @Override public EntityAgeable createChild(EntityAgeable ageable) { return null; } /** * Checks if this entity is running on a client. * * Required since MCP's isClientWorld returns the exact opposite... * * @return true if the entity runs on a client or false if it runs on a server */ public final boolean isClient() { return worldObj.isRemote; } /** * Checks if this entity is running on a server. * * @return true if the entity runs on a server or false if it runs on a client */ public final boolean isServer() { return !worldObj.isRemote; } @Override protected void despawnEntity(){ System.out.println("DESPAWNED " + this.worldObj.isRemote); for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { System.out.println(ste); } super.despawnEntity(); } @Override public void setDead(){ for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { System.out.println(ste); } super.setDead(); } } Here's the server console log: http://hastebin.com/ulijiloyuq.css And here's the client console log, which finally has setDead() called seconds after the server despawns: http://hastebin.com/aharugajuf.md As always, any help is now beyond appreciated Thanks!
  12. Hey, so I just tested that. It's immediately despawning server-side right after it's spawned in, however, the client-representation isn't "despawned" for a few seconds after, which I find weird. Unfortunately, I have no idea where to go from here Any direction is greatly appreciated!
  13. Hey there! So I have a custom entity that I'm spawning when a player left clicks in the air. I'm doing this via a custom packet sent to the server telling it to spawn that entity. That's all good and well. However, the entity spawns in, doesn't do anything, then despawns after a few seconds. I have no idea where I'm going wrong. I believe I've done the packet handling, entity class, and AI correctly. Here's the respective code: Packet and IMessageHandler classes: public class PacketEntityRockSpawn implements IMessage { //sent from client to server telling it to spawn an EntityRock //Don't need to return anything because we'll keep rock count on server side private String entityID; public PacketEntityRockSpawn(){} public PacketEntityRockSpawn(String id){ this.entityID = id; } @Override public void fromBytes(ByteBuf buf) { entityID = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, entityID); } public static class HandlerEntityRockSpawn implements IMessageHandler<PacketEntityRockSpawn, IMessage> { public HandlerEntityRockSpawn(){} @Override public IMessage onMessage(PacketEntityRockSpawn message, MessageContext ctx) { //received packet from client EntityPlayer player = ctx.getServerHandler().playerEntity; Entity entity = EntityList.createEntityByIDFromName(Test.MODID + "." + message.entityID, player.worldObj); World worldIn = player.worldObj; if (entity instanceof EntityRock && player.worldObj instanceof WorldServer) { ((WorldServer)player.worldObj).addScheduledTask(new Runnable() { @Override public void run() { EntityRock entityRock = (EntityRock) entity; entityRock.setOwner(player); entityRock.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityRock)), (IEntityLivingData) null); worldIn.spawnEntityInWorld(entity); entityRock.playLivingSound(); PlayerHandler.getClientInfo(player).rocks.add(entityRock); System.out.println("" + PlayerHandler.getClientInfo(player).rocks.size()); } }); } return null; } } } Custom Entity Class: public class EntityRock extends EntityAbilityBase{ private EntityLivingBase owner; private double maxTravelDistance; private BlockPos startPosition; private final int HOME_RADIUS = 10; private static final DataParameter<Boolean> DATA_FOLLOWING = EntityDataManager.createKey(EntityRock.class, DataSerializers.BOOLEAN); private static final DataParameter<Boolean> DATA_LAUNCHED = EntityDataManager.createKey(EntityRock.class, DataSerializers.BOOLEAN); public EntityRock(World worldIn) { super(worldIn); this.setSize(1f, 1f); this.experienceValue = 200; this.stepHeight = 1; } public void setOwner(EntityLivingBase base){ this.owner = base; this.setOwnerId(owner.getUniqueID()); this.posX = owner.posX + this.rand.nextInt(3); this.posY = owner.posY + owner.getEyeHeight(); this.posZ = owner.posZ + this.rand.nextInt(3); setHomePosAndDistance(getOwner().getPosition(), HOME_RADIUS); } @Override protected void entityInit(){ super.entityInit(); dataManager.register(DATA_FOLLOWING, true); dataManager.register(DATA_LAUNCHED, false); } @Override protected void initEntityAI(){ System.out.println("TASK ADDED"); this.tasks.addTask(0, new EntityAIFollowBender(this, 1.0, 2.0)); } @Override protected void applyEntityAttributes(){ super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(200.0D); //100 full hearts this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(1.0D); } @Override protected PathNavigate getNewNavigator(World world){ return new PathNavigateFlying(this, world); } /** * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons * use this to react to sunlight and start to burn. */ public void onLivingUpdate() { if(isServerWorld() && getOwner() != null && !getOwner().isDead){ if(dataManager.get(DATA_FOLLOWING)){ setHomePosAndDistance(getOwner().getPosition(), HOME_RADIUS); } else if(dataManager.get(DATA_LAUNCHED)){ setHomePosAndDistance(this.getPosition(), HOME_RADIUS); } } super.onLivingUpdate(); } public void launch(EntityPlayer player) { int yaw = (int)player.rotationYaw; if(yaw<0) { //due to the yaw running a -360 to positive 360 yaw += 360; } //not sure why it's that way yaw+=22; //centers coordinates you may want to drop this line yaw%=360; //and this one if you want a strict interpretation of the zones int facing = yaw/45; // 360degrees divided by 45 == 8 zones (4 normal direction, 4 diagonal) //----------------------- RayTraceResult result = player.worldObj.rayTraceBlocks(player.getPositionEyes(1.0f), player.getLookVec()); //remove task of following owner //add task of going to target //turn step height to 0 //mark start position //play sound if(result == null) return; /*if(result.typeOfHit != RayTraceResult.Type.MISS) this.tasks.removeTask(followTask); if(result.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos pos = new BlockPos(result.hitVec); this.tasks.addTask(0, launhTask = new EntityAITargetBlock(this, 2.0D, Integer.MAX_VALUE, pos)); } else if(result.typeOfHit == RayTraceResult.Type.ENTITY && result.entityHit instanceof EntityLivingBase) this.tasks.addTask(0, entityLaunchTask = new EntityAITargetEntity(this, false, (EntityLivingBase) result.entityHit)); this.stepHeight = 0; this.startPosition = new BlockPos(this.getPositionVector());*/ } @Override public boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack){ if(hand.equals(EnumHand.MAIN_HAND)){ } //remove task of following owner //add task of going to target //turn step height to 0 //mark start position //play sound return true; } @Override public void writeEntityToNBT(NBTTagCompound compound){ super.writeEntityToNBT(compound); } @Override public void readFromNBT(NBTTagCompound compound){ super.readFromNBT(compound); } @Override public EntityAgeable createChild(EntityAgeable ageable) { return null; } @Override public boolean canBePushed(){ return false; } @Override public void fall(float distance, float damageMultiplier) { } @Override public boolean isAIDisabled(){return false;} protected SoundEvent getAmbientSound(){ return TestSounds.Guard; } protected SoundEvent getHurtSound(){return TestSounds.Guard;} protected SoundEvent getDeathSound(){return TestSounds.Guard;} The "base" class it extends: public class EntityAbilityBase extends EntityTameable { public EntityAbilityBase(World worldIn) { super(worldIn); } @Override public EntityAgeable createChild(EntityAgeable ageable) { return null; } /** * Checks if this entity is running on a client. * * Required since MCP's isClientWorld returns the exact opposite... * * @return true if the entity runs on a client or false if it runs on a server */ public final boolean isClient() { return worldObj.isRemote; } /** * Checks if this entity is running on a server. * * @return true if the entity runs on a server or false if it runs on a client */ public final boolean isServer() { return !worldObj.isRemote; } } The AI task that it gets: public class EntityAIFollowBender extends EntityAIAbilityBase { private EntityLivingBase owner; private double minRadius; public EntityAIFollowBender(EntityAbilityBase ability, double speed, double minRadius) { super(ability, speed); this.minRadius = minRadius; } @Override public boolean shouldExecute(){ owner = ability.getOwner(); if(owner == null || owner.isDead || (owner != null && owner.getPositionVector().distanceTo(ability.getPositionVector()) <= minRadius)){ System.out.println("NOT EXECUTE"); return false; } System.out.println("EXECUTE"); return true; } @Override public void updateTask(){ //if(ability.getNavigator() instanceof PathNavigateFlying){ // ((PathNavigateFlying) ability.getNavigator()).tryMoveToBender(owner, speed); //} else { ability.getNavigator().tryMoveToEntityLiving(owner, speed); //} } } The base class that the AI task extends: public class EntityAIAbilityBase extends EntityAIBase { protected final EntityAbilityBase ability; protected final World world; protected final Random random; protected final double speed; public EntityAIAbilityBase(EntityAbilityBase ability, double speed){ this.ability = ability; this.world = ability.worldObj; this.random = ability.getRNG(); this.speed = speed; } @Override public boolean shouldExecute() { return true; } protected boolean tryMoveToBlockPos(BlockPos pos){ return ability.getNavigator().tryMoveToXYZ(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, speed); } } The custom PathNavigate: public class PathNavigateFlying extends PathNavigateSwimmer { private Random rand = new Random(); private double posX, posY, posZ; public PathNavigateFlying(EntityLiving entitylivingIn, World worldIn) { super(entitylivingIn, worldIn); } @Override protected PathFinder getPathFinder(){ return new PathFinder(new NodeProcessorFlying()); } @Override protected boolean canNavigate(){ return true; } public boolean tryMoveToBender(Entity entity, double speed){ this.posX = entity.posX + Offsets.values()[this.rand.nextInt(3)].getOutput(); this.posY = entity.posY + entity.getEyeHeight(); this.posZ = entity.posZ + Offsets.values()[this.rand.nextInt(3)].getOutput(); boolean a = super.tryMoveToXYZ(posX, posY, posZ, speed); System.out.println("move: " + String.valueOf(this.currentPath == null) + " " + String.valueOf(this.currentPath.getCurrentPathLength() == 0)); return a; } private enum Offsets{ ONE(0), TWO(0.5), THREE(1.0); private double output; Offsets(double in){output = in;} public double getOutput() { return output; } } } And finally the custom node processor: public class NodeProcessorFlying extends SwimNodeProcessor { /** * Returns PathPoint for given coordinates */ @Override public PathPoint getPathPointToCoords(double x, double y, double target){ return openPoint( MathHelper.floor_double(x - (entity.width / 2.0)), MathHelper.floor_double(y + 0.5), MathHelper.floor_double(target - (entity.width / 2.0)) ); } @Override public int findPathOptions(PathPoint[] pathOptions, PathPoint currentPoint, PathPoint targetPoint, float maxDistance){ int i = 0; for(EnumFacing facing: EnumFacing.values()){ PathPoint pathPoint = getSafePoint(entity, currentPoint.xCoord + facing.getFrontOffsetX(), currentPoint.yCoord + facing.getFrontOffsetY(), currentPoint.zCoord + facing.getFrontOffsetZ() ); if(pathPoint != null && !pathPoint.visited && pathPoint.distanceTo(targetPoint) < maxDistance){ pathOptions[i++] = pathPoint; } } return i; } /** * Returns a point that the entity can safely move to */ private PathPoint getSafePoint(Entity entityIn, int x, int y, int z){ BlockPos pos = new BlockPos(x, y, z); entitySizeX = MathHelper.floor_float(entityIn.width + 1); entitySizeY = MathHelper.floor_float(entityIn.height + 1); entitySizeZ = MathHelper.floor_float(entityIn.width + 1); for(int ix = 0; ix < entitySizeX; ix++){ for(int iy = 0; iy < entitySizeY; iy++){ for(int iz = 0; iz < entitySizeZ; iz++){ IBlockState state = blockaccess.getBlockState(pos.add(ix, iy, iz)); if(state.getMaterial() != Material.AIR){ return null; } } } } return openPoint(x, y, z); } I know this is a lot to look at, so any help is greatly appreciated!
  14. For anyone that happens to come across this same problem, just make sure that you registered your event class common/server side and not specifically just client side. Mine was fixed (well, believed to be fixed - I'll update the code tomorrow) by making sure it was registered common/server side.
×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.