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.

GrigLog

Members
  • Joined

  • Last visited

Everything posted by GrigLog

  1. No. You will have to figure out a lot of stuff yourself.
  2. Exact bit values for people in the future: 1 - MOVE or TARGET (in 1.12 there was no difference between two, now they are split. You will have to think which one you want to use) 2 - LOOK 4 - JUMP
  3. PlayerEvent.ItemPickupEvent
  4. What Im trying to do is to implement a "dash" mechanic on a Shift button. @SubscribeEvent public static void onEvent(InputEvent.KeyInputEvent event){ KeyBinding runBinding = Minecraft.getInstance().gameSettings.keyBindSprint; int key = event.getKey(); int runKey = runBinding.getKey().getKeyCode(); ClientPlayerEntity player = Minecraft.getInstance().player; if (key == runKey){ //some checks, and then: float yaw = player.rotationYaw; float x = -MathHelper.sin(yaw * 0.017453292F); float z = MathHelper.cos(yaw * 0.017453292F); double groundMotion = 5, airMotion = 2; if (player.isOnGround()) player.setMotion(new Vector3d(x * groundMotion, 0, z * groundMotion)); else player.setMotion(new Vector3d(x * airMotion, 0, z * airMotion)); } } And this code works. The problem is, it causes a lot of lag when the setMotion() is called - my fps drops from 60 to 50-40 and the dash movement looks discrete. I wonder why is it so and how it can be improved...
  5. Like this: -Xms128M -Xmx4096M This will limit RAM usage by 4 gb
  6. Im pretty sure you just need to limit your max RAM in java arguments
  7. Im sorry, there was a result actually - on server side capability got copied correctly, I just didn't see it from the game because its not synced. Now, how can I send that data to client? In which event?
  8. Well, thats exactly what Im struggling with. Ive also tried soulNew.setNbt(soul.getNbt()), but with no result The thing is, I actively use input events and I have to send player inputs to server somehow. I should probably make 2 separate capabilities (for mana and for inputs) later SoulCap class: public class SoulCap { public static int CATimerMax = 20; public static int dashWindowMax = 3; public static int dashCDMax = 20; public int parryTimer = 0; public int CATimer = 0; public int dashWindow = 0; public int dashCD = 0; public boolean justParried = false; public boolean rightClicked = false; public boolean leftClicked = false; public double mana = 0; public double maxMana = 10; public HashMap<String, Integer> usedKeyItems = new HashMap<>(); public boolean trySpendMana(double a) { if (mana >= a){ mana -= a; return true; } return false; } public void addMana(double a){ mana += a; if (mana > maxMana) mana = maxMana; } public CompoundNBT getNbt(){ CompoundNBT tag = new CompoundNBT(); tag.putInt("parryTimer", parryTimer); tag.putInt("CATimer", CATimer); tag.putBoolean("justParried", justParried); tag.putBoolean("rightClicked", rightClicked); tag.putBoolean("leftClicked", leftClicked); tag.putDouble("mana", mana); tag.putDouble("maxMana", maxMana); CompoundNBT keyItems = new CompoundNBT(); for (String s : usedKeyItems.keySet()){ keyItems.putInt(s, usedKeyItems.get(s)); } tag.put("usedKeyItems", keyItems); return tag; } public SoulCap setNbt(CompoundNBT nbt){ parryTimer = nbt.getInt("parryTimer"); CATimer= nbt.getInt("CATimer"); justParried = nbt.getBoolean("justParried"); rightClicked = nbt.getBoolean("rightClicked"); leftClicked = nbt.getBoolean("leftClicked"); mana = nbt.getDouble("mana"); maxMana = nbt.getDouble("maxMana"); CompoundNBT keyItems = nbt.getCompound("usedKeyItems"); for (String s : keyItems.keySet()){ usedKeyItems.put(s, keyItems.getInt(s)); } return this; } public static class SoulProvider implements ICapabilitySerializable<INBT> { @CapabilityInject(SoulCap.class) public static Capability<SoulCap> SOUL_CAP; private final LazyOptional<SoulCap> instance = LazyOptional.of(() -> new SoulCap()); @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return cap == SOUL_CAP ? instance.cast() : LazyOptional.empty(); } @Nonnull @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap) { return cap == SOUL_CAP ? instance.cast() : LazyOptional.empty(); } @Override public INBT serializeNBT() { return SOUL_CAP.getStorage().writeNBT(SOUL_CAP, this.instance.resolve().get(), null); } @Override public void deserializeNBT(INBT nbt) { SOUL_CAP.getStorage().readNBT(SOUL_CAP, this.instance.resolve().get(), null, nbt); } } public static class SoulStorage implements Capability.IStorage<SoulCap> { @Override public INBT writeNBT(Capability<SoulCap> capability, SoulCap soulCap, Direction side) { return soulCap.getNbt(); } @Override public void readNBT(Capability<SoulCap> capability, SoulCap soulCap, Direction side, INBT nbt) { soulCap.setNbt((CompoundNBT)nbt); } } }
  9. Forge 1.16.5-36.1.30. Docs say that PlayerEvent.Copy event is helpful for this, but I cant figure out what to do exactly. This is what I wrote and it doesnt work: EventHandler: @SubscribeEvent static void copyPlayerDataOnRespawn(PlayerEvent.Clone event){ SoulCap soul = SF.getSoul(event.getOriginal()); SoulCap soulNew = SF.getSoul(event.getPlayer()); soulNew = soul; SF.sendToClient((ServerPlayerEntity)event.getPlayer(), soulNew); } SF: public static SoulCap getSoul(PlayerEntity player){ return player.getCapability(SoulCap.SoulProvider.SOUL_CAP, null).resolve().orElse(null); } public static void sendToClient(ServerPlayerEntity player, SoulCap cap){ PacketSender.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), new SoulPacket(cap)); } SoulPacket: static void handle(SoulPacket p, Supplier<NetworkEvent.Context> ctx){ ctx.get().enqueueWork(() -> { if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_CLIENT) { ClientPlayerEntity player = Minecraft.getInstance().player; SoulCap cap = SF.getSoul(player); cap.setNbt(p.cap.getNbt()); if (cap.justParried) { player.stopActiveHand(); cap.justParried = false; } } else if (ctx.get().getDirection() == NetworkDirection.PLAY_TO_SERVER){ ServerPlayerEntity player = ctx.get().getSender(); SoulCap cap = SF.getSoul(player); cap.setNbt(p.cap.getNbt()); if (cap.justParried) { cap.justParried = false; } } }); ctx.get().setPacketHandled(true); } First of all, the sentToClient side can be easlily removed because at this point in code Minecraft.getInstance().player is still null. But I still have to sync sides somehow... And secondly, the capability is not actually getting copied. I guess its because in this case player.getCapability() only provides a copy of the asked capability, not an assignable reference. But there is no player.setCapability method... So what do I do?
  10. Ive made an armor model in Blockbench (just a bunch of random stripes), exported it as a .java object and binded a texture to it. The problem is, it is not rendered as it should, it just floats with the player. Model code (mostly generated by Blockbench): public class CustomArmorModel extends BipedModel<LivingEntity> { private final ModelRenderer Head; private final ModelRenderer Body; private final ModelRenderer RightArm; private final ModelRenderer LeftArm; private final ModelRenderer RightLeg; private final ModelRenderer LeftLeg; public CustomArmorModel() { super(1); textureWidth = 64; textureHeight = 64; Head = new ModelRenderer(this); Head.setRotationPoint(0.0F, 0.0F, 0.0F); Head.setTextureOffset(32, 0).addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, 0.5F, false); Body = new ModelRenderer(this); Body.setRotationPoint(0.0F, 0.0F, 0.0F); Body.setTextureOffset(16, 32).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, 0.25F, false); Body.setTextureOffset(0, 0).addBox(-1.0F, 2.0F, 3.0F, 1.0F, 1.0F, 1.0F, 0.0F, false); Body.setTextureOffset(40, 32).addBox(-8.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, 0.25F, false); RightArm = new ModelRenderer(this); RightArm.setRotationPoint(-5.0F, 2.0F, 0.0F); LeftArm = new ModelRenderer(this); LeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); LeftArm.setTextureOffset(48, 48).addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, 0.25F, false); RightLeg = new ModelRenderer(this); RightLeg.setRotationPoint(-1.9F, 12.0F, 0.0F); RightLeg.setTextureOffset(0, 32).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, 0.25F, false); LeftLeg = new ModelRenderer(this); LeftLeg.setRotationPoint(1.9F, 12.0F, 0.0F); LeftLeg.setTextureOffset(0, 48).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, 0.25F, false); } @Override public void render(MatrixStack matrixStack, IVertexBuilder buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha){ Head.render(matrixStack, buffer, packedLight, packedOverlay); Body.render(matrixStack, buffer, packedLight, packedOverlay); RightArm.render(matrixStack, buffer, packedLight, packedOverlay); LeftArm.render(matrixStack, buffer, packedLight, packedOverlay); RightLeg.render(matrixStack, buffer, packedLight, packedOverlay); LeftLeg.render(matrixStack, buffer, packedLight, packedOverlay); } } Whats wrong there? And are there other ways to make models, better than Blockbench?
  11. To display it, obviously)
  12. Looks like it works now, thanks
  13. Or PlayerLoggedIn is fine too?
  14. Yes, this time you were right. But how can I sync server with client now? I dont see any Event of (de)serialization
  15. Btw I obtain all Capabilities references in code like this: SoulCap cap = player.getCapability(SoulCap.SoulProvider.SOUL_CAP, null).resolve().get(); mb this one is incorrect?
  16. They are called, and they change the SoulProvider.instance and save it to nbt as intended. But looks like the player has some other instance of SoulProvider, which is never (de)serialized. I literally see maxMana=20 in debug and maxMana=10 in game.
  17. Ive made it like this, but nothing changed: public static class SoulProvider implements ICapabilitySerializable<INBT> { @CapabilityInject(SoulCap.class) public static Capability<SoulCap> SOUL_CAP; private final LazyOptional<SoulCap> instance = LazyOptional.of(() -> new SoulCap()); @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return cap == SOUL_CAP ? instance.cast() : LazyOptional.empty(); } @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap) { return cap == SOUL_CAP ? instance.cast() : LazyOptional.empty(); } @Override public INBT serializeNBT() { return SOUL_CAP.getStorage().writeNBT(SOUL_CAP, this.instance.resolve().get(), null); } @Override public void deserializeNBT(INBT nbt) { SOUL_CAP.getStorage().readNBT(SOUL_CAP, this.instance.resolve().get(), null, nbt); } }
  18. It works fine in-game, but when I re-enter the world, all the fields are set to their default values. Its strange because Ive implemented writeNBT and readNBT methods. Also client and server are synchronized, so its not the problem. Capability code: public class SoulCap { public int parryTimer = 0; public int CATimer = 0; public boolean justParried = false; public boolean rightClicked = false; public boolean leftClicked = false; public double mana = 0; public double maxMana = 10; public HashMap<String, Integer> usedKeyItems = new HashMap<>(); public boolean trySpendMana(double a) { if (mana >= a){ mana -= a; return true; } return false; } public void addMana(double a){ mana += a; if (mana > maxMana) mana = maxMana; } public CompoundNBT getNbt(){ CompoundNBT tag = new CompoundNBT(); tag.putInt("parryTimer", parryTimer); tag.putInt("CATimer", CATimer); tag.putBoolean("justParried", justParried); tag.putBoolean("rightClicked", rightClicked); tag.putBoolean("leftClicked", leftClicked); tag.putDouble("mana", mana); tag.putDouble("maxMana", maxMana); CompoundNBT keyItems = new CompoundNBT(); for (String s : usedKeyItems.keySet()){ keyItems.putInt(s, usedKeyItems.get(s)); } tag.put("usedKeyItems", keyItems); return tag; } public SoulCap setNbt(CompoundNBT nbt){ parryTimer = nbt.getInt("parryTimer"); CATimer= nbt.getInt("CATimer"); justParried = nbt.getBoolean("justParried"); rightClicked = nbt.getBoolean("rightClicked"); leftClicked = nbt.getBoolean("leftClicked"); mana = nbt.getDouble("mana"); maxMana = nbt.getDouble("maxMana"); CompoundNBT keyItems = nbt.getCompound("usedKeyItems"); for (String s : keyItems.keySet()){ usedKeyItems.put(s, keyItems.getInt(s)); } return this; } public static class SoulProvider implements ICapabilityProvider { @CapabilityInject(SoulCap.class) public static Capability<SoulCap> SOUL_CAP; private final LazyOptional<SoulCap> instance = LazyOptional.of(() -> new SoulCap()); @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { return cap == SOUL_CAP ? instance.cast() : LazyOptional.empty(); } @Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap) { return cap == SOUL_CAP ? instance.cast() : LazyOptional.empty(); } } public static class SoulStorage implements Capability.IStorage<SoulCap> { @Override public INBT writeNBT(Capability<SoulCap> capability, SoulCap soulCap, Direction side) { return soulCap.getNbt(); } @Override public void readNBT(Capability<SoulCap> capability, SoulCap soulCap, Direction side, INBT nbt) { soulCap.setNbt((CompoundNBT)nbt); } } } Registering: @Mod("soul") @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) public class Soul { // //various stuff // @SubscribeEvent public static void setup(final FMLCommonSetupEvent event) { CapabilityManager.INSTANCE.register(SoulCap.class, new SoulCap.SoulStorage(), () -> new SoulCap()); } } Attaching: @Mod.EventBusSubscriber public class CapabilityEvents { @SubscribeEvent static void playerCapability(AttachCapabilitiesEvent<Entity> event){ if (event.getObject() instanceof PlayerEntity) { event.addCapability(new ResourceLocation(Soul.id, "soul"), new SoulCap.SoulProvider()); } } }
  19. Looks like minecraft uses Blaze3D for rendering, but I have no idea what to do with these MatrixStacks, RenderTypeBuffers, etc, and I cant find any documentation about it. Vanilla examples are not helpful at all, because all the variables lost their original names and its impossible to understand whats going on. Any suggestions where to start?
  20. Oh hell, that was the problem, now it finally works XD Im just tired and didnt notice that, thanks a lot!
  21. I think Ive done everything as it and you say, and I looked through other mods code and it looks similar everywhere, but the arrows are still invisible, whats wrong? public class Entities { public static final EntityType<HolyArrow> holyArrow = EntityType.Builder .<HolyArrow>create(HolyArrow::new, EntityClassification.MISC) .size(1, 1) .build(""); } public class HolyArrow extends AbstractArrowEntity { public HolyArrow(World world, PlayerEntity player){ super(Entities.holyArrow, player, world); } public HolyArrow (EntityType<HolyArrow> type, World world){ super(Entities.holyArrow, world); } public IPacket<?> createSpawnPacket() { Entity entity = this.getShooter(); return NetworkHooks.getEntitySpawningPacket(entity); } public void onCollideWithPlayer(PlayerEntity entityIn) {} //no pickup @Override protected ItemStack getArrowStack() { return null; } } @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) public class RegistryEvents { @SubscribeEvent static void registerEntities(final RegistryEvent.Register<EntityType<?>> event){ event.getRegistry().registerAll(Entities.holyArrow.setRegistryName("holy_arrow")); } } @Mod.EventBusSubscriber(value=Dist.CLIENT, bus=Mod.EventBusSubscriber.Bus.MOD) public class ClientEvents { @SubscribeEvent public static void setupClient(FMLClientSetupEvent event){ RenderingRegistry.registerEntityRenderingHandler(Entities.holyArrow, HolyArrowRenderer::new); } }
  22. The problem is, in docs its only said how to register EntityTypes through DeferredRegisters... Ive added an override for getType() {return Entities.holyArrow;} now the arrows are simply invisible. Am I doing right? Ok, but it didnt change anything
  23. Ive already made an arrow entity (derived from vanilla one), and it works fine (they dont get picked up by a player), but for some reason my texture is not rendered, the arrow looks like vanilla one... Arrow code: public class HolyArrow extends ArrowEntity { public HolyArrow(World world, PlayerEntity player){ super(world, player); } public HolyArrow(EntityType<HolyArrow> type, World world){ super(type, world); } public void onCollideWithPlayer(PlayerEntity entityIn) {} //no pickup public static EntityType<HolyArrow> getRegistryType(){ return (EntityType<HolyArrow>) EntityType.Builder .<HolyArrow>create(HolyArrow::new, EntityClassification.MISC) .size(1, 1) .build("") .setRegistryName("holy_arrow"); } } Renderer (the texture method is never called): public class HolyArrowRenderer extends ArrowRenderer<HolyArrow> { public HolyArrowRenderer(EntityRendererManager e){ super(e); } @Override public ResourceLocation getEntityTexture(HolyArrow entity) { System.out.println("texture requested"); return new ResourceLocation(Soul.id, "textures/entity/holy_arrow.png"); } } Registering a renderer: @Mod.EventBusSubscriber(value=Dist.CLIENT, bus=Mod.EventBusSubscriber.Bus.MOD) public class ClientEvents { @SubscribeEvent public static void setupClient(FMLClientSetupEvent event){ RenderingRegistry.registerEntityRenderingHandler(Entities.holyArrow, HolyArrowRenderer::new); } } Registering an entity: @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) public class RegistryEvents { @SubscribeEvent static void registerEntities(final RegistryEvent.Register<EntityType<?>> event){ event.getRegistry().registerAll(Entities.holyArrow); } } Entity reference: public class Entities { public static final EntityType<HolyArrow> holyArrow = HolyArrow.getRegistryType(); }
  24. I was able to do the second thing. If someone is interested: 1) Subscribe to a right-click input event @SubscribeEvent public static void onEvent(InputEvent.MouseInputEvent event) { KeyBinding keyUse = Minecraft.getInstance().gameSettings.keyBindUseItem; if (event.getButton() == 1 && event.getAction() == 1) { //right button pressed down SoulCap soulCap = Minecraft.getInstance().player.getCapability(SoulProvider.SOUL_CAP, null).resolve().get(); soulCap.setRightClicked(true); //use a capability to save the info PacketSender.INSTANCE.sendToServer(new SoulPacket(soulCap)); //sync with server } } 2) Override an item onItemRightClick method to return ActionResult.resultPass when neccessary @Override public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand handIn) { ItemStack itemstack = player.getHeldItem(handIn); SoulCap soulCap = player.getCapability(SoulProvider.SOUL_CAP, null).resolve().get(); if (soulCap.getRightClicked()){ soulCap.setRightClicked(false); player.setActiveHand(handIn); //item is used as its supposed to return ActionResult.resultConsume(itemstack); } return ActionResult.resultPass(itemstack); }

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.