
LK1905
Members-
Content Count
29 -
Joined
-
Last visited
Community Reputation
0 NeutralAbout LK1905
-
Rank
Tree Puncher
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
I solved the problem. The problem as that I didn't have the getMaxHealth() method saved within my serializeNBT() method, so the game still thought the value was zero. Saving that value fixed the problem.
-
LK1905 started following [SOLVED][1.16.4] Changing an entity's max health
-
I'm trying to modify an entity's max health based on a stat, but either its not working or my client isn't acknowledging the change. The method for the change. Full class here. @Override public void modifyMaxHealth(LivingEntity entity) { if(entity == null) { return; } entity = getEntity(); final float newAmount = getMaxHealth(); final float oldAmount; final UUID MODIFIER_ID = UUID.fromString("d5d0d878-b3c2-469b-ba89-ac01c0635a9c"); final ModifiableAttributeInstance health = entity.getAttribute(Attributes.MAX_HEALTH); final AttributeModifier mod = new AttributeModifier(MODIFIER_ID, "Max Health", newAmount, AttributeModifier.Operation.ADDITION); final AttributeModifier oldMod = health.getModifier(MODIFIER_ID); if(oldMod != null) { health.removeModifier(oldMod); oldAmount = (float) oldMod.getAmount(); }else { oldAmount = 0; } health.applyPersistentModifier(mod); final float amountToHeal = newAmount - oldAmount; if(amountToHeal > 0) { entity.heal(amountToHeal); } } The sync method: @Override public void sync(ServerPlayerEntity player) { if(entity instanceof ServerPlayerEntity) { PacketHandler.sendTo(new SkillsPacket(serializeNBT()), player); if(!player.world.isRemote) { ModifiableAttributeInstance attribute = player.getAttribute(Attributes.MAX_HEALTH); SEntityPropertiesPacket packet = new SEntityPropertiesPacket(player.getEntityId(), Collections.singleton(attribute)); ((ServerWorld) player.getEntityWorld()).getChunkProvider().sendToTrackingAndSelf(player, packet); } } } My player event class: package lk1905.gielinorcraft.events; import lk1905.gielinorcraft.Gielinorcraft; import lk1905.gielinorcraft.api.skill.ISkills; import lk1905.gielinorcraft.capability.skill.SkillCapability; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimensionEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; @Mod.EventBusSubscriber(modid = Gielinorcraft.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE) public class PlayerEventHandler { @SubscribeEvent public static void onPlayerClone(PlayerEvent.Clone event) { if(!event.isWasDeath()) { return; } ISkills oldSkills = event.getOriginal().getCapability(SkillCapability.SKILL_CAP, null).orElse(null); ISkills newSkills = event.getPlayer().getCapability(SkillCapability.SKILL_CAP, null).orElse(null); if(oldSkills != null) { if(newSkills != null) { for(int i = 0; i < 26; i++) { newSkills.setXp(i, oldSkills.getXp(i)); newSkills.setStaticLevel(i, oldSkills.getStaticLevel(i)); newSkills.setLevel(i, oldSkills.getLevel(i)); } } } } @SubscribeEvent public static void onPlayerChangedDimensionEvent(PlayerChangedDimensionEvent event) { ServerPlayerEntity player = (ServerPlayerEntity) event.getPlayer(); if(!player.world.isRemote) { player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.sync(player)); player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.modifyMaxHealth(player)); } } @SubscribeEvent public static void onRespawnEvent(PlayerRespawnEvent event) { ServerPlayerEntity player = (ServerPlayerEntity) event.getPlayer(); if(!player.world.isRemote) { player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.sync(player)); player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.modifyMaxHealth(player)); } } @SubscribeEvent public static void onPlayerConnect(PlayerLoggedInEvent event) { ServerPlayerEntity player = (ServerPlayerEntity) event.getPlayer(); if(!player.world.isRemote) { player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.sync(player)); player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.modifyMaxHealth(player)); } } } Full repo here, if you need to look at anything else.
-
I've changed the serializeNBT and deserialize methods so the value of i is in the key: @Override public CompoundNBT serializeNBT() { CompoundNBT data = new CompoundNBT(); for(int i = 0; i < 26; i++) { data.putInt("xp_" + i, (int) xp[i]); data.putInt("dynamic_" + i, dynamicLevels[i]); data.putInt("static_" + i, staticLevels[i]); } return data; } @Override public void deserializeNBT(CompoundNBT data) { for(int i = 0; i < 26; i++) { xp[i] = data.getInt("xp_" + i); dynamicLevels[i] = data.getInt("dynamic_" + i); staticLevels[i] = data.getInt("static_" + i); } } And now it works, thank you! (I think thats what the first person to reply to this post was trying to tell me to do but I didn't understand at the time).
-
Okay, I believe I've done what you have told me, and my gui does update me gaining xp. However, theres something wrong with my sync method, as whenever it is called, it resets all xp values to zero. So the values in my gui are lost when reloading the world. Heres the sync method in my Skills class: @Override public void sync(ServerPlayerEntity player) { if(entity instanceof ServerPlayerEntity) { PacketHandler.sendTo(new SkillsPacket(serializeNBT()), player); } } Heres my attempt at syncing on login, in my player event handler: @SubscribeEvent public static void onPlayerConnect(PlayerLoggedInEvent event) { ServerPlayerEntity player = (ServerPlayerEntity) event.getPlayer(); if(!player.world.isRemote) { player.getCapability(SkillCapability.SKILL_CAP).ifPresent(c -> c.sync(player)); } } Updated my git repo, here.
-
My GUI doesn't update the xp values. This is how I reference the player in my GUI: private PlayerEntity player = Minecraft.getInstance().player; private LazyOptional<ISkills> cap = player.getCapability(SkillCapability.SKILL_CAP); private ISkills skills = cap.orElse(null); Do I need to reference the Server Player instead? If so, how? Or Is the client player already supposed to know my server player data from my events/packets? If so, why aren't they working? They're in the OP.
-
I don't think there's anything wrong with the SkillStorage, as I can gain xp just fine, in the correct skills, the data is just reset to zero when i close and reopen the world. I also have the "Hitpoints" skill set to level 10 and 1154 xp by default. If I comment out my PlayerLoggedInEvent, the skill is correctly set to those values in game, and is reset to those values when I leave the world. But with the event enabled, both the level and xp values are set to 1 and 0.