Jump to content

Johny1234

Members
  • Posts

    2
  • Joined

  • Last visited

Converted

  • URL
    https://github.com/jano1221/

Johny1234's Achievements

Tree Puncher

Tree Puncher (2/8)

1

Reputation

  1. Hey, thanks for answer I couldn't fall asleep and have figured it out all now. It seems to work as intended. (Im using that custom capability and EntityJoinWorldEvent ) Thank you for advice, i will put it on GitHub and link it here tommorow! Actually it will be helpful becouse im deleteing bits of my code all the time, and next day i realise i could use that for something else?
  2. Hey guys! This is my first topic here, although I am a frequent visitor, so at first i would like to say hello to all of you:) I'm sorry if anything below is not understandable, but im not native speaker and i don't have a lot occasions to write something in english. Today i have faced a serious obstacle which i can't work around by myself. I'm working on a mod where i have added few custom VillageProfessions. I would like these custom villagers to be spawned in world only when player uses a special item on regular villager, which i had already implemented. The issue is that my custom villagers aslo spawn on world generation in regular villages, because of the VillagerRegistery.setRandomProfession() method. (i believe that it could be the problem) I'v tried using Events like LivingSpawnEvent.CheckSpawn and LivingSpawnEvent.SpecialSpawn to check if the spawned entity is one of my custom villagers, and if so then replace it with another one with profession 5(nitwit), but it seems that that events are not fired when villagers are being spawned in villages. Then I'v tried to add a custom capability to EntityVillager, which contained a single boolean field canSpawn intialized as false, and then i wanted to use it in EntityJoinWorldEvent becouse i figured out that this event was fired on villagers spawn (wow...who would have thought) @SubscribeEvent public void entityJoinWorldEvent(EntityJoinWorldEvent event) { if(event.getEntity() instanceof EntityVillager) { EntityVillager villager = (EntityVillager) event.getEntity(); ICanSpawn canSpawn = villager.getCapability(CanSpawnProvider.CANSPAWN,null); if(canSpawn.getCanSpawn() == false)//Fellow line 61 from stacktrace { //this checks if the joining villager profession is in arraylist of my custom professions if(CustomVillagerUtils.contains(villager.getProfessionForge())) { event.setCanceled(true); EntityVillager replacementVillager = new EntityVillager(event.getWorld(),5); replacementVillager.setPosition(villager.posX, villager.posY, villager.posZ); event.getWorld().spawnEntity(replacementVillager); System.out.println("Canceled spawning CUSTOMVILLAGER - Added NITWIT instead"); } } //else if canSpawn == true, then spawn villager with my custom profession } } And this is called when item is being used on EntityVillager: public static void tryOutTheVillager(EntityPlayer player, EntityVillager target) { if (isValidForTransformation(target)) { ICanSpawn canSpawn = player.getCapability(CanSpawnProvider.CANSPAWN, null); canSpawn.setCanSpawn(true); //this line also was generating NullPointerException turnVillagerIntoCustomVillager(player, target); //this just replaces current villager with a new custom one // canSpawn.setCanSpawn(false); } } But this was a huge failure (i think that i didnt assigned the capability to the EntityVillager properly, and the entities cant see it, but i really dont know - today was my 1rst attempt on adding capabilites and i didnt figured out how does them work yet) [01:13:42] [Server thread/ERROR] [FML]: Exception caught during firing event net.minecraftforge.event.entity.EntityJoinWorldEvent@6fec275d: java.lang.NullPointerException: null at com.johny12340.customvillagers.common.util.handlers.EventHandler.entityJoinWorldEvent(EventHandler.java:61) ~[EventHandler.class:?] at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_20_EventHandler_entityJoinWorldEvent_EntityJoinWorldEvent.invoke(.dynamic) ~[?:?] at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90) ~[ASMEventHandler.class:?] at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182) [EventBus.class:?] at net.minecraft.world.World.spawnEntity(World.java:1313) [World.class:?] at net.minecraft.world.WorldServer.spawnEntity(WorldServer.java:1121) [WorldServer.class:?] at net.minecraft.world.gen.structure.StructureVillagePieces$Village.spawnVillagers(StructureVillagePieces.java:1899) [StructureVillagePieces$Village.class:?] at net.minecraft.world.gen.structure.StructureVillagePieces$House4Garden.addComponentParts(StructureVillagePieces.java:1394) [StructureVillagePieces$House4Garden.class:?] at net.minecraft.world.gen.structure.StructureStart.generateStructure(StructureStart.java:51) [StructureStart.class:?] at net.minecraft.world.gen.structure.MapGenStructure.generateStructure(MapGenStructure.java:102) [MapGenStructure.class:?] at net.minecraft.world.gen.ChunkGeneratorOverworld.populate(ChunkGeneratorOverworld.java:412) [ChunkGeneratorOverworld.class:?] at net.minecraft.world.chunk.Chunk.populate(Chunk.java:1094) [Chunk.class:?] at net.minecraft.world.chunk.Chunk.populate(Chunk.java:1074) [Chunk.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:169) [ChunkProviderServer.class:?] at net.minecraft.server.MinecraftServer.initialWorldChunkLoad(MinecraftServer.java:383) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(IntegratedServer.java:143) [IntegratedServer.class:?] at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:160) [IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:552) [MinecraftServer.class:?] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_192] Is there any other way to do this you guys can think of, or you can see what im missing in my previous attemps? I was thinking on some way to Override the vanilla VillagerRegistery.setRandomProfession() or use the InitMapGenEvent but dunno how for now. Aslo i will attach my capabilities code here, so maybe someone can tell me what i am doing wrong ;-; ICanSpawn public interface ICanSpawn { boolean getCanSpawn(); void setCanSpawn(boolean canSpawn); } CanSpawn public class CanSpawn implements ICanSpawn { private boolean canSpawn; public CanSpawn() { this.canSpawn = false; } @Override public boolean getCanSpawn() { System.out.println("getCanSpawn:"+canSpawn); return this.canSpawn; } @Override public void setCanSpawn(boolean canSpawn) { this.canSpawn = canSpawn; } } CanSpawnStorage public class CanSpawnStorage implements IStorage<ICanSpawn> { @Nullable @Override public NBTBase writeNBT(Capability<ICanSpawn> capability, ICanSpawn instance, EnumFacing side) { NBTTagCompound tags = new NBTTagCompound(); tags.setBoolean("canspawn", instance.getCanSpawn()); return tags; } @Override public void readNBT(Capability<ICanSpawn> capability, ICanSpawn instance, EnumFacing side, NBTBase nbt) { NBTTagCompound tags = (NBTTagCompound) nbt; if (tags.hasKey("canspawn")) { instance.setCanSpawn(tags.getBoolean("canspawn")); } } } CanSpawnProvider public class CanSpawnProvider implements ICapabilitySerializable<NBTTagCompound> //I was using ICapabilityProvider before (cuz i thought that this needn't to be serialized) { @CapabilityInject(ICanSpawn.class) public final static Capability<ICanSpawn> CANSPAWN = null; private ICanSpawn instance = CANSPAWN.getDefaultInstance(); @Override public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) { System.out.println("hasCapability:"+CANSPAWN.getName()); return capability == CANSPAWN; } @Nullable @Override public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) { System.out.println("getCapability:"+CANSPAWN.getName()); if (CANSPAWN != null && CANSPAWN == capability) return (T) instance; return null; } @Override public NBTTagCompound serializeNBT() { return (NBTTagCompound) CANSPAWN.getStorage().writeNBT(CANSPAWN, instance, null); } @Override public void deserializeNBT(NBTTagCompound nbt) { CANSPAWN.getStorage().readNBT(CANSPAWN, instance, null, nbt); } } CanSpawnFactory public class CanSpawnFactory implements Callable<ICanSpawn> { @Override public ICanSpawn call() throws Exception { return new CanSpawn(); } } This is being called in my CommonProxy.preInit method: CapabilityManager.INSTANCE.register(ICanSpawn.class, new CanSpawnStorage(), new CanSpawnFactory()); And here i'm attaching the capability to EntityVillager public class CapabilityHandler { public static final ResourceLocation CANSPAWN = new ResourceLocation(CustomVillagers.MODID, "canspawn"); @SubscribeEvent public void attachCapability(AttachCapabilitiesEvent<Entity> event) { if (!(event.getObject() instanceof EntityVillager)) return; event.addCapability(CANSPAWN, new CanSpawnProvider()); } } Oh f**k nvm, i have worked it around by myself... i didnt registered the CapabilityHandler, thats why it was throwing the NullPointerException at me. Still did not tested if the capability changes and if this method even work, but i will do it tomorow cuz im falling asleep now ? I will update the post then. Since I've already pasted all this here i will publish it, so maybe it will help someone, and maybe someone will look throught/review my code and tell me what i have done wrong and what i can improve. (also still maybe there is a better way of achieving the main goal -preventing the custom villagers from spawning- which i can't think of now) SOLUTION You can check how i solved this problem here: GitHub (It's a silly mod which im making to have fun with friends on server) Basicly its the same way as before (Custom Capability and EntityJoinWorldEvent) but i did some improvements.
×
×
  • Create New...

Important Information

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