Attaching the effeks to Entities - GiantLuigi4/Minecraft_Effekseer_Implementation GitHub Wiki

Basics

Here's the basic things you need for the packet,

  • An effek UUID, so that you don't override the previous effek for the entity if you spawn multiple
  • An entity UUID, so you don't override other entities once or track the wrong entity with your effek
  • The effek's resource location
  • (If you want to rotate it once and not rotate it constantly, you should probably write the location and rotation in the packet)

Keep in mind, the code shown here is untested and has had no effort put into optimization

Please do not copy/paste it, as it will most likely be very slow

Implementation

Forge

First of all, you need a channel for your packet.

For info on that, see the forge docs

	private static final ArrayList<ResourceLocation> trackedUUIDs = new ArrayList<>();
	private static final HashMap<ResourceLocation, ResourceLocation> effeksByTrackedUUID = new HashMap<>();

	// mod init
		channel.registerMessage(0, EffekseerExamplePacket.class, EffekseerExamplePacket::writePacketData, EffekseerExamplePacket::new,
				(packet, context)->{
					Effek effek = Effeks.get(packet.effekName.toString());
					if (effek == null) return;
					trackedUUIDs.add(new ResourceLocation(packet.entityUUID, packet.effekUUID));
					effeksByTrackedUUID.put(new ResourceLocation(packet.entityUUID, packet.effekUUID), packet.effekName);
					EffekEmitter emitter = effek.getOrCreate(new ResourceLocation(packet.entityUUID, packet.effekUUID).toString());
					for (Entity allEntity : Minecraft.getInstance().world.getAllEntities()) {
						if (allEntity.getUniqueID().toString().equals(packet.entityUUID)) {
							emitter.setPosition(allEntity.getPosX(), allEntity.getPosY(), allEntity.getPosZ());
							emitter.setDynamicInput(0, allEntity.rotationPitch);
							emitter.setDynamicInput(1, allEntity.rotationYaw);
						}
					}
					context.get().setPacketHandled(true);
				}
		);

Fabric

	private static final ArrayList<ResourceLocation> trackedUUIDs = new ArrayList<>();
	private static final HashMap<ResourceLocation, ResourceLocation> effeksByTrackedUUID = new HashMap<>();

		// mod init
		ClientPlayNetworking.registerGlobalReceiver(
				new Identifier("modid:entity_effek"), (client, handler, buffer, responder)-> {
					String entityUUID = buffer.readString();
					String effekUUID = buffer.readString();
					Identifier effekName = buffer.readIdentifier();
					Effek effek = Effeks.get(effekName.toString());
					if (effek == null) return;
					trackedUUIDs.add(new Identifier(entityUUID, effekUUID));
					effeksByTrackedUUID.put(new Identifier(entityUUID, effekUUID), effekName);
					EffekEmitter emitter = effek.getOrCreate(new Identifier(entityUUID, effekUUID).toString());
					for (Entity allEntity : MinecraftClient.getInstance().world.getEntities()) {
						if (allEntity.getUuid().toString().equals(entityUUID)) {
							emitter.setPosition(allEntity.getX(), allEntity.getY(), allEntity.getZ());
							emitter.setDynamicInput(0, allEntity.pitch);
							emitter.setDynamicInput(1, allEntity.yaw);
						}
					}
				}
		);

Keeping it tracked

Forge

The following code goes in a listener for ClientTickEvent (if you want a untested, probably slow implementation of it)

Fabric

The following code gets rewritten for yarn in an inject at the end of MinecraftClient$tick (if you want a untested, probably slow implementation of it)

(keep in mind, this is MCP)

		for (ResourceLocation trackedUUID : trackedUUIDs) {
			for (Entity allEntity : Minecraft.getInstance().world.getAllEntities()) {
				if (allEntity.getUniqueID().toString().equals(trackedUUID.getNamespace())) {
					Effek effek = Effeks.get(effeksByTrackedUUID.get(trackedUUID).toString());
					if (effek == null) continue; // should never happen, but race conditions exist so
					EffekEmitter emitter = effek.getOrCreate(trackedUUID.toString());
					emitter.setPosition(allEntity.getPosX(), allEntity.getPosY(), allEntity.getPosZ());
					emitter.setDynamicInput(0, allEntity.rotationPitch);
					emitter.setDynamicInput(1, allEntity.rotationYaw);
				}
			}
		}