Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/17/18 in all areas

  1. This is actually kinda tricky but here is the general gist: Create a list of AABB representing the player's body part hitboxes: the head, left leg, right leg, body, right arm, left arm. Using the LivingHurtEvent or whatnot grab the player being hurt and the player initiating the attack. Your attack vector is [attacker.eye] - [victim.eye] + [attacker.forward], or alternatively [attacker.forward] * [attacker.reach_distance]. Either should work but the second variant is preferrable. Transform the attack vector into the AABB space(which is the forward-Z identity space). Basically do it by manually rotating the vector around the Y axis by the degrees between the [victim.forward] and [unitZ] vectors, and then do the same with the victim's pitch(not the head pitch, the body pitch). Or construct a transform matrix and multiply the vector by it, it works too. There are a lot of math papers on the subject that might help you here. Now that you have the attack vector in AABB space simply check which boxes it intersects with - that's your hit bodypart. It may not intersect any though because of the way the game works. You could also implement BB boxes(not Axis-Aligned) and work with them but it's a bit more tricky albeit a better solution. Again, there are a lot of papers on the topic of BBxes, you just need to search for them. Unfortunately Iimplementing moving body parts like the legs and the arms is trickier since their transformations only exist on the client, so you would have to replicate them on the server in the even based on variables like swingProgress, but you might simply be lacking a few values which may or may not be important, then transform the vector to the space of animated body part and check whether it intersects that AABB. You only need to check that one AABB and you don't have to check it again. Do the same for all body parts. That's how I would do it anyway.
    1 point
  2. Linking works like this: When you rusts a block, you give it a registry name. This registry name is used to look up the blockstate.json file. That file points to models (optionally textures) and models point to textures.
    1 point
  3. This is plainly not true. It might have been at some time but I can tell you for certain that it isn't the case at most since 1.8.
    1 point
  4. 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.
    1 point
  5. Override Item#getItemUseAction and return whatever action you want it to be, in your case it would be DRINK
    1 point
  6. Ok so, this bit here (redacted for simplicity): from zipTree(jar.outputs.getFiles().getSingleFile()).matching { exclude 'com/draco18s/ores/**', 'com/draco18s/industry/**' } This removes my "actual mod" from being included in a compiled jar file. In this case, it excludes the folder com/draco18s/ores and com/draco18s/industry, as we only want the library in this jar. Then this bit here: from zipTree(jar.outputs.getFiles().getSingleFile()).matching { include 'com/draco18s/ores/**', 'assets/harderores/**', 'cog_config/**' exclude '**.xcf' } Makes sure to only include com/draco18s/ores, and its associated assets. The exclude line makes sure not to include large, layered, GIMP image files that aren't actually used by the mod (it's a template for the icons actually used). Your gradle file will already have one task that builds everything. You can rename it and modify the include/exclude as appropriate, then duplicate and modify again, using a new task name. At the bottom, these bits: oresJar.dependsOn('reobfJar') set up to make sure that gradle does all of the appropriate compilation tasks in the proper order. Lastly, this is a task that does a full compile (builds all the jars, redacted slightly for simplicity): task releaseJars(type: Copy) { from coreJarNoCog from oresJar rename '-(.*)jar', '.jar' rename '-(.*)zip', '.zip' into '.' } This task will already exist in your gradle file, you just need to add the from lines so that a full build builds all of your other jar tasks.
    1 point
×
×
  • Create New...

Important Information

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