Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Izzy Axel

Forge Modder
  • Joined

  • Last visited

Everything posted by Izzy Axel

  1. Oh, I see what you mean, I already have functions to add and subtract mana, so I should just send the packets from those functions instead of from the items that use them. That won't affect the HUD issue I don't think though. Adding a PlayerRespawnEvent handler and syncing there fixed it. It's required to sync client IEEP when the player joins world, and when they respawn, one or the other leads to problems.
  2. I have getters and setters for everything in the IEEP. I'm sending a sync packet anywhere where the mana values are changed, after the change is made. I know about the handlers thing, I haven't gotten around to cleaning that up, that's what I made the AAEventHandler class for today. The sync packet at the moment syncs mana values, hasLearnendAboutMana, and hasReceivedJournal, tied to the HUD being shown for that player, and not re-giving the journal item to the player every time they join the world. Also, the change you mentioned about not getting the entity from the ID in the sync packet, replacing that with Minecraft#thePlayer will cause an EntityClientPlayerMP loaded on invalid side SERVER crash, not quite sure why.
  3. Alright, I'll make those changes. I'm sending them from mana.ManaHandler#provideMana, mana.ManaPersistence#syncPersistenceToClient and syncPersistenceOnRespawn (which didn't help so I'll probably remove it), achievements.AchievementListener#achievementGet, main.handlers.AAEventHandler#onJoin, main.messages.MessageRegenMana.RegenManaHandler#onMessage, and main.messages.MessageRegainMana.RegainManaHandler#onMessage
  4. Arcane Artificing I'm sending all the important IEEP properties/the ones that should be synced through death and reconstruction to the client, including hasLearnedAboutMana. The HUD works fine across reconstructions via dimensional travel but when a player dies, that doesn't get synced for some reason, even though I'm sending the same sync packet as every other situation I checked by printing the value in the HUD class, and after death it changes to false.
  5. Ok, that works, but after the player dies, the HUD element doesn't update to the new IEEP, it acts like the player hasn't learned about mana yet, (one of the values in the IEEP) and therefore doesn't display the HUD element. Relogging fixes it. I'm not sure if I should tie the showing of the HUD to the achievement that is setting the IEEP variable for it, or the way I've been doing with IEEP; achievements seem to get reset a lot... HUD Event Handler IEEP
  6. Just when you think it's done... So, there's definitely an issue with this method of carrying IEEP over death, namely that it doesn't work right; everything gets reset, because of how the IEEP is getting copied. The identifier used to register it already exists during death reconstruction so the new one gets renamed, and therefore the new IEEP is not used, the old is wiped, and I'm left trying to read from the old one. I hope I'm wrong, but it's looking there's going to be reflection going on to directly alter the protected HashMap for the IEEP, since there are no other methods for setting IEEP. event handler public class ManaPersistence { public static ManaPersistence INSTANCE = new ManaPersistence(); @SubscribeEvent public void persistMana(PlayerEvent.Clone event) { EntityPlayer playerOrig = event.original; EntityPlayer playerNew = event.entityPlayer; AAExtendedPlayer propsOrig = (AAExtendedPlayer)playerOrig.getExtendedProperties(AAExtendedPlayer.EEPName); playerNew.registerExtendedProperties(AAExtendedPlayer.EEPName, propsOrig); } @SubscribeEvent public void syncPersistenceToClient(EntityJoinWorldEvent event) { if(!event.world.isRemote && event.entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)event.entity; AAExtendedPlayer props = (AAExtendedPlayer)player.getExtendedProperties(AAExtendedPlayer.EEPName); ArcaneArtificing.snw.sendToAll(new MessageSyncMana(player.getEntityId(), props.getWhiteMana(), props.getBlueMana(), props.getBlackMana(), props.getGreenMana(), props.getRedMana(), props.hasLearnedAboutmana())); } } @SubscribeEvent public void syncOnDisconnect(cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent event) { if(!event.player.worldObj.isRemote) { AAExtendedPlayer props = (AAExtendedPlayer)event.player.getExtendedProperties(AAExtendedPlayer.EEPName); ArcaneArtificing.snw.sendToAll(new MessageSyncMana(event.player.getEntityId(), props.getWhiteMana(), props.getBlueMana(), props.getBlackMana(), props.getGreenMana(), props.getRedMana(), props.hasLearnedAboutmana())); } } }
  7. Ok...I had to delete the playerdata or make a new world on SSP, and delete the playerdata on SMP; the old IEEP values were interfering. So now everything works. Thanks! EDIT: wait crap no there's still one more issue; persistence over exiting/rejoining. At least with simply exiting an SSP world and going back in when one type is halfway down, upon entering the world again, it resets to full. Seems like maybe I need to sync NBT on a player logout event? Fixed
  8. Ok, implemented the signed method, but 2 problems still; in SMP, holding the keybind neither adds mana on the client or server, and in SSP, it adds mana on the server and can be used, but the client/HUD doesn't update. On SSP, persistence seems to work though, so that's good...maybe. Everything Relevant
  9. Yes, I know that's wrong. So I'm doing... @SubscribeEvent public void syncPersistenceToClient(EntityJoinWorldEvent event) { if(!event.world.isRemote && event.entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)event.entity; ArcaneArtificing.snw.sendToAll(new MessageSyncManaPersistence(player.getEntityId())); } } Do I need to send each mana's value individually to set on the client side, and set them there? Edit: Ok there's another problem, apparently I'm trying to load EntityClientPlayerMP on the server, stacktrace points to the registration of the mana client sync packet, which gets sent at the end of the handler for the packet that manipulates the mana on the server, so...can I not chain packets like that? Everything
  10. Will this work? public class ManaPersistence { public void persistMana(PlayerEvent.Clone event) { if(!event.wasDeath) { EntityPlayer playerOrig = event.original; EntityPlayer playerNew = event.entityPlayer; AAExtendedPlayer propsOrig = (AAExtendedPlayer)playerOrig.getExtendedProperties(AAExtendedPlayer.EEPName); AAExtendedPlayer propsNew = (AAExtendedPlayer)playerNew.getExtendedProperties(AAExtendedPlayer.EEPName); propsNew = propsOrig; } } } Unfortunately I cant easily test this until I solve the other issue I'm having, which is getting the IEEP variables for mana to set correctly. I have a keybind that when held should refill mana, currently I just have it giving it quickly and for free to test. I have a GUI element that reflects changes made to the mana variables in the IEEP. I send a packet to the server from the keybinding class with the client's entity ID, then I've tried checking and adding mana using IEEP in the packet handler and in proxies, and a few other ways, but nothing's worked, the GUI doesn't update and no mana is given/stored in IEEP. Any idea what I'm doing wrong? I also tried slowing the player down via the packet/proxy serverside, like the effect when you draw a bow, and that results in 1 tick bursts of slowness every 10ish ticks...this is really confusing.
  11. The issue is, my IEEP doesn't carry over across reconstructions such as travelling to a dimension, what's the preferred method of making this data persistent, or is there an issue with my IEEP? Death I think I do want stored mana to be lost on, but you shouldn't have the mana you've collected vanish when you travel to a dimension. <__< IEEP
  12. That does not appear to be in 1.7.10's KeyBinding... Edit: KeyBinding#getIsKeyPressed works.
  13. For holding, no, I want the player to be able to hold the key down and have the code constantly run. So moving to a ClientTickEvent might fix that? With KeyInputEvent, holding the key only made the code run once. (er, twice, just, it wasn't continuous) (What is WITH this forum's formatting going wonky randomly? <__<) Edit: I changed it to a ClientTickEvent, but it's still not detecting the key is being held down, is there a different method I have to check for in KeyBinding? public class GatherManaKeybind extends KeyBinding { public GatherManaKeybind() { super("key.gatherMana", Keyboard.KEY_G, "key.categories." + AAReference.MODID); } @SubscribeEvent() public void onKeyInput(TickEvent.ClientTickEvent event) { if(event.phase == TickEvent.Phase.END && this.isPressed()) { ~snip~ } } }
  14. First, how do you detect a player holding down a keybind, and constantly perform an action? Second, my keybind is running all of its code twice. I'm using KeyInputEvent, and its getPhase() returns an EventPriority (?!) so...how do I fix that? Keybind public class GatherManaKeybind extends KeyBinding { public GatherManaKeybind() { super("key.gatherMana", Keyboard.KEY_G, "key.categories." + AAReference.MODID); } @SubscribeEvent(priority = EventPriority.HIGHEST) public void onKeyInput(InputEvent.KeyInputEvent event) { if(this.isPressed()) { ~do it to it, but not twice~ } } } ClientProxy @Override public void preInit(FMLPreInitializationEvent event) { super.preInit(event); GatherManaKeybind gatherKBD = new GatherManaKeybind(); FMLCommonHandler.instance().bus().register(gatherKBD); ClientRegistry.registerKeyBinding(gatherKBD); }
  15. Fairly simple with a TileEntity. As for rendering, you can attach an ISimpleBlockRenderingHandler or TileEntitySpecialRenderer to it. There are plenty of tutorials for that out there, so here's how I did the block: Block TileEntity
  16. I haven't figured out how to do this, or if it's even possible, so any help would be appreciated. There are several instances where I'd like to give an EntityThrowable projectile a model, all of them too complex to do in the Tessellator and keep my sanity intact.
  17. I don't see anything blatant that would cause that, you could try the way I did it, with packets, which also affords you more control over how the player is placed in the destination dimension: Main class: public static SimpleNetworkWrapper snw; @EventHandler public void preinit(FMLPreInitializationEvent event) { snw = NetworkRegistry.INSTANCE.newSimpleChannel(modid); snw.registerMessage(MessageTeleportToDimension.TeleportHandler.class, MessageTeleportToDimension.class, idnumber, Side.SERVER); } Packet: public class MessageTeleportToDimension implements IMessage { int dim; int id; public MessageTeleportToDimension(){} public MessageTeleportToDimension(int dim, int id) { this.dim = dim; this.id = id; } @Override public void fromBytes(ByteBuf buf) { this.dim = buf.readInt(); this.id = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.dim); buf.writeInt(this.id); } public static class TeleportHandler implements IMessageHandler<MessageTeleportToDimension, IMessage> { @Override public IMessage onMessage(MessageTeleportToDimension message, MessageContext ctx) { Entity ent = ctx.getServerHandler().playerEntity.worldObj.getEntityByID(message.id); if(ent instanceof EntityPlayerMP) { EntityPlayerMP player = (EntityPlayerMP)ent; player.mcServer.getConfigurationManager().transferPlayerToDimension(player, message.dim, new CustomTeleporter(player.mcServer.worldServerForDimension(message.dim))); player.fallDistance = 0.0f; } return message; } } } Custom Teleporter (I used this to teleport the player to the overworld without forming a Nether portal, this is where your placement logic would go) public class CustomTeleporter extends Teleporter { final WorldServer worldServer; public CustomTeleporter(WorldServer worldServer) { super(worldServer); this.worldServer = worldServer; } @Override public boolean makePortal(Entity entity){~} @Override public void placeInPortal(Entity entity, double x, double y, double z, float yaw){~} } OnRightClick: MainClass.snw.sendToServer(new MessageTeleportToDimension(dimensionid, player.getEntityId()));
  18. Uh ok...for some reason it started working after I added an item renderer for a completely unrelated item...*shrugs*
  19. Bump. Still got no clue whats going on with the rendering interactions between mods, what am I doing wrong?
  20. That would be why I didn't see getArmorModel. An adapter doesn't seem hard, but this isn't working and gives no errors, so I'm not sure what to do now: ItemCrownOfIris: public class ItemCrownOfIris extends ItemArmor implements ISpecialArmor { public ItemCrownOfIris(ArmorMaterial armormat, int renderIndex, int slot) { super(armormat, renderIndex, slot); this.setUnlocalizedName("crownOfIris"); this.setTextureName(AAReference.MODID + ":" + getUnlocalizedName().substring(5)); this.setMaxStackSize(1); this.setCreativeTab(AACreativeTab.aaTab); AAUtils.AADespawn.registerItemToNeverDespawn(this); MinecraftForge.EVENT_BUS.register(this); } @SideOnly(Side.CLIENT) @Override public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armorSlot) { return new IrisRender(); } @Override public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) { return AAReference.MODID + ":textures/models/armor/crownOfIrisInvis.png"; } @Override public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot) {} @Override public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot) { return new ArmorProperties(1000, 1000, 1000); } @Override public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { return 0; } @SubscribeEvent(receiveCanceled = true) public void onDamage(LivingHurtEvent event) { if(event.entityLiving instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)event.entityLiving; AAExtendedPlayer props = (AAExtendedPlayer)player.getExtendedProperties(AAExtendedPlayer.EEPName); if(props.hasCrown()) { for(int i = 0; i < (int)event.ammount * 4; i++) { if(!event.entity.worldObj.isRemote) { ArcaneArtificing.snw.sendToAllAround(new MessageDoParticles(AAReference.CrownRainbowFX, player.posX + ((itemRand.nextInt(3) - 1) * itemRand.nextFloat()), player.posY + 1.5 + ((itemRand.nextInt(3) - 1) * itemRand.nextFloat()), player.posZ + ((itemRand.nextInt(3) - 1) * itemRand.nextFloat()), 0, 0, 0, 40f, 20), new NetworkRegistry.TargetPoint(player.dimension, player.posX, player.posY, player.posZ, 256)); } } event.ammount = 0; } } } } IrisRender: public class IrisRender extends ModelBiped { IModelCustom CrownOfIris; ResourceLocation CrownTexture; public IrisRender() { super(); this.CrownOfIris = AdvancedModelLoader.loadModel(new ResourceLocation(AAReference.MODID, "models/CrownOfIris.obj")); this.CrownTexture = new ResourceLocation(AAReference.MODID, "textures/models/armor/crownOfIris.png"); } @Override public void render(Entity entity, float time, float armsLegs, float headAngleY, float headAngleX, float p_78088_6_, float p_78088_7_) { if(entity instanceof EntityPlayer) { GL11.glPushMatrix(); GL11.glTranslatef(0.0F, 0.5F, 0.0F); this.CrownOfIris.renderAll(); GL11.glPopMatrix(); } } } Edit: Imma derp Imma derp Imma derp derp derp! Never bound a texture to it. I'm not sure where else to get access to the TextureManager, so this might not work on server/may be bad practice, but this works on SSP: public class IrisRender extends ModelBiped { IModelCustom CrownOfIris = AdvancedModelLoader.loadModel(new ResourceLocation(AAReference.MODID, "models/CrownOfIris.obj")); ResourceLocation CrownTexture = new ResourceLocation(AAReference.MODID, "textures/models/armor/crownOfIris.png"); @Override public void render(Entity entity, float time, float armsLegs, float headAngleY, float headAngleX, float p_78088_6_, float p_78088_7_) { if(entity instanceof EntityPlayer) { GL11.glPushMatrix(); Minecraft.getMinecraft().getTextureManager().bindTexture(this.CrownTexture); GL11.glRotatef(time, 0.0f, 1.0f, 0.0f); GL11.glTranslatef(0.0F, 16.0F * p_78088_7_, 0.0F); this.CrownOfIris.renderAll(); GL11.glPopMatrix(); } } } Edit 2: It isn't working on a server with other mods, it is working on a server with only my mod, and it's overwriting all other mod's armor rendering, (though not vanilla) so we got a problem
  21. I've been looking into this for a while now, but the other threads asking about this either got no answers, got answers that didn't explain much and seemed to be outdated (the getArmorModel function in ItemArmor doesn't exist in 1.7.10?), or pointed to mod sources that just confused me more than when I started (iChun's hat mod, Botania, etc). So, what's the best way to render an IModelCustom on the player? I already have IEEP and a player tick handler set up to tell when the armor is being worn, and the armor is finished, so all that's left is rendering. Armor Item I tried this and many different things in it, but it did absolutely nothing every time: IItemRender with this in main mod class: MinecraftForgeClient.registerItemRenderer(AAItems.crownOfIris, new IrisRender());
  22. Thanks, that worked, now everything's working as intended
  23. Ok, I moved the positioning to the teleporter, and I fixed the item removal by using IEEP with the dimension change event, but there's still one issue, even if you break your bed, you still teleport to its location instead of world spawn. public class OverworldTeleporterNP extends Teleporter { final WorldServer worldServer; public OverworldTeleporterNP(WorldServer worldServer) { super(worldServer); this.worldServer = worldServer; } @Override public boolean makePortal(Entity entity){return true;} @Override public void placeInPortal(Entity entity, double x, double y, double z, float yaw) { if(entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer)entity; ChunkCoordinates bed = player.getBedLocation(0); if(bed != null) { bed.posY = player.worldObj.getTopSolidOrLiquidBlock(bed.posX, bed.posZ); player.setPositionAndUpdate(bed.posX, bed.posY + 1, bed.posZ); } else { ChunkCoordinates spawn = player.worldObj.getSpawnPoint(); spawn.posY = player.worldObj.getTopSolidOrLiquidBlock(spawn.posX, spawn.posZ); player.setPositionAndUpdate(spawn.posX, spawn.posY + 1, spawn.posZ); } } } }
  24. This has been happening with teleporting into my dimension too, the coordinates you spawn at don't match the coordinates given to the setLocationAndAngles. Yeah, I printed the coordinates, they're both the same: the player's bed, only the packet actually spawns you at the right location. You typically spawn deep underground in a wall, or way up in the air with the teleportation inside the tick event, and always within 200 blocks of the printed coordinates, on the x and z axes. Splitting it to do the teleportation in the packet and the removing of the item from the inventory in the tick event doesn't work either, it teleports to the right location, and takes multiple items. Aaaaand the mystery deepens, I just got one time where it took none of the item, and the next, it took 4. Tick Event Packet Teleporter
  25. Oookay...not sure why I thought I would need a packet, but after putting that stuff in the tick event and overriding the placeInPortal methods, when the teleportion is in the packet it spawns me at my bed, when in the tick event, it spawns me in the middle of some random ocean 300ish blocks away from my bed or world spawn //Safeguard Talisman if(player.dimension == -1 && !props.isInNether()) { props.setInNether(true); } if(player.dimension != -1 && props.isInNether()) { props.setInNether(false); } if(props.isInNether()) { if(player.inventory.hasItem(AAItems.safeguardTalisman)) { if(player.worldObj.getBlock((int)player.posX, (int)player.posY, (int)player.posZ).equals(Blocks.lava) || player.worldObj.getBlock((int)player.posX, (int)player.posY, (int)player.posZ).equals(Blocks.flowing_lava) || player.isBurning()) { if(event.side == Side.SERVER) { if(player instanceof EntityPlayerMP) { EntityPlayerMP playerMP = (EntityPlayerMP)player; for (int i = 0; i < playerMP.inventory.mainInventory.length - 4; ++i) { if (playerMP.inventory.mainInventory[i] != null && playerMP.inventory.mainInventory[i].getItem() == AAItems.safeguardTalisman) { playerMP.inventory.mainInventory[i] = null; break; } } playerMP.mcServer.getConfigurationManager().transferPlayerToDimension(playerMP, 0, new TeleporterNP(playerMP.mcServer.worldServerForDimension(0))); ChunkCoordinates bed = playerMP.getBedLocation(0); if(bed != null) { bed.posY = playerMP.worldObj.getTopSolidOrLiquidBlock(bed.posX, bed.posZ); playerMP.setLocationAndAngles(bed.posX, bed.posY, bed.posZ, playerMP.rotationYaw, playerMP.rotationPitch); } else { ChunkCoordinates spawn = playerMP.worldObj.getSpawnPoint(); spawn.posY = playerMP.worldObj.getTopSolidOrLiquidBlock(spawn.posX, spawn.posZ); playerMP.setLocationAndAngles(spawn.posX, spawn.posY, spawn.posZ, playerMP.rotationYaw, playerMP.rotationPitch); } playerMP.fallDistance = 0.0f; } } props.setInNether(false); } } }

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.