Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import java.util.Locale;
import java.util.Map;

import static org.purpurmc.purpurextras.util.EntityStatePreserverUtil.preserveEntityState;

/**
* If enabled, entities with type on the left will be transformed into entity of type on the right.
* This overrides vanilla transformations. Vanilla mob ids are used to identify mobs.
Expand Down Expand Up @@ -85,12 +87,15 @@ public void onLightningStrike(EntityDamageByEntityEvent event) {
spawnEntity(targetEntity, location);
}

private void spawnEntity(Object entity, Location location) {
private Entity spawnEntity(Object entity, Location location) {
Entity spawnedEntity = null;
if (entity instanceof EntityType entityType) {
location.getWorld().spawnEntity(location, entityType, CreatureSpawnEvent.SpawnReason.LIGHTNING);
spawnedEntity = location.getWorld().spawnEntity(location, entityType, CreatureSpawnEvent.SpawnReason.LIGHTNING);
} else if (entity instanceof Entiddy entiddy) {
entiddy.entiddy().spawn(location, CreatureSpawnEvent.SpawnReason.LIGHTNING);
spawnedEntity = entiddy.entiddy().spawn(location, CreatureSpawnEvent.SpawnReason.LIGHTNING);
}

return spawnedEntity;
}

private void getEntityTypeOrSpecial(String key, String value) {
Expand Down Expand Up @@ -136,7 +141,10 @@ public void onLightningStrike(EntityZapEvent event) {
entity.remove();
String specialEntityKey = specialEntity.entiddy().toString().toLowerCase(Locale.ROOT);
Object targetEntity = entities.get(specialEntityKey);
spawnEntity(targetEntity, location);
Entity spawnedEntity = spawnEntity(targetEntity, location);
if(spawnedEntity instanceof LivingEntity newEntity) {
preserveEntityState((LivingEntity) entity, newEntity);
}
return;
}
Object targetEntity = entities.get(entity.getType().getKey().getKey());
Expand All @@ -146,7 +154,10 @@ public void onLightningStrike(EntityZapEvent event) {
return;
}
entity.remove();
spawnEntity(targetEntity, location);
Entity spawnedEntity = spawnEntity(targetEntity, location);
if(spawnedEntity instanceof LivingEntity newEntity) {
preserveEntityState((LivingEntity) entity, newEntity);
}
event.setCancelled(true);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package org.purpurmc.purpurextras.util;

import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.potion.PotionEffect;


public class EntityStatePreserverUtil {

private EntityStatePreserverUtil() {

}

/**
* Copy persistent state from one LivingEntity to another.
*/
public static void preserveEntityState(LivingEntity oldEntity, LivingEntity transformedEntity) {
if (oldEntity == null || transformedEntity == null) return;
preserveGeneralProperties(oldEntity, transformedEntity);

}


private static void preserveGeneralProperties(LivingEntity oldEntity, LivingEntity transformedEntity) {
preserveEquipment(oldEntity.getEquipment(), transformedEntity);
preserveHealth(oldEntity, transformedEntity);
preserveSurvivalState(oldEntity, transformedEntity);
preservePotionEffect(oldEntity, transformedEntity);
preserveFlags(oldEntity, transformedEntity);
preserveFireAndFreeze(oldEntity, transformedEntity);
preservePoseAndRotation(oldEntity, transformedEntity);
preserveExtraStates(oldEntity, transformedEntity);


}

private static void preserveExtraStates(LivingEntity oldEntity, LivingEntity transformedEntity) {
preserveVelocity(oldEntity, transformedEntity);
transformedEntity.setPortalCooldown(oldEntity.getPortalCooldown());
transformedEntity.setAI(oldEntity.hasAI());
transformedEntity.setGliding(oldEntity.isGliding());
transformedEntity.setSneaking(oldEntity.isSneaking());
}

private static void preserveSurvivalState(LivingEntity oldEntity, LivingEntity transformedEntity) {
transformedEntity.setAbsorptionAmount(oldEntity.getAbsorptionAmount());
transformedEntity.setMaximumAir(oldEntity.getMaximumAir());
transformedEntity.setRemainingAir(oldEntity.getRemainingAir());
transformedEntity.setNoDamageTicks(oldEntity.getNoDamageTicks());
}

private static void preserveVelocity(LivingEntity oldEntity, LivingEntity transformedEntity) {
// Velocity (only if same entity type family, else may cause issues)
if (oldEntity.getType() == transformedEntity.getType()) {
transformedEntity.setVelocity(oldEntity.getVelocity());
}
}

private static void preservePoseAndRotation(LivingEntity oldEntity, LivingEntity transformedEntity) {
transformedEntity.setPose(oldEntity.getPose());
transformedEntity.setRotation(oldEntity.getLocation().getYaw(), oldEntity.getLocation().getPitch());
}

private static void preserveFireAndFreeze(LivingEntity oldEntity, LivingEntity transformedEntity) {
transformedEntity.setFireTicks(oldEntity.getFireTicks());
transformedEntity.setFreezeTicks(oldEntity.getFreezeTicks());
}

private static void preserveFlags(LivingEntity oldEntity, LivingEntity transformedEntity) {
transformedEntity.setCustomNameVisible(oldEntity.isCustomNameVisible());
transformedEntity.setGlowing(oldEntity.isGlowing());
transformedEntity.setGravity(oldEntity.hasGravity());
transformedEntity.setCollidable(oldEntity.isCollidable());
transformedEntity.setSilent(oldEntity.isSilent());
transformedEntity.setInvisible(oldEntity.isInvisible());
transformedEntity.setInvulnerable(oldEntity.isInvulnerable());
transformedEntity.setPersistent(oldEntity.isPersistent());
}

private static void preservePotionEffect(LivingEntity oldEntity, LivingEntity transformedEntity) {
transformedEntity.getActivePotionEffects().forEach(pe -> transformedEntity.removePotionEffect(pe.getType()));
for (PotionEffect effect : oldEntity.getActivePotionEffects()) {
transformedEntity.addPotionEffect(effect);
}
}

private static void preserveHealth(LivingEntity oldEntity, LivingEntity transformedEntity) {
transformedEntity.setHealth(oldEntity.getHealth());
}

private static void preserveEquipment(EntityEquipment oldEquipment, Entity spawnedEntity) {
if (spawnedEntity instanceof LivingEntity newEntity && oldEquipment != null) {
EntityEquipment newEquipment = newEntity.getEquipment();
if (newEquipment != null) {
// Copy armor items
newEquipment.setArmorContents(oldEquipment.getArmorContents());

// Copy armor drop chances
newEquipment.setHelmetDropChance(oldEquipment.getHelmetDropChance());
newEquipment.setChestplateDropChance(oldEquipment.getChestplateDropChance());
newEquipment.setLeggingsDropChance(oldEquipment.getLeggingsDropChance());
newEquipment.setBootsDropChance(oldEquipment.getBootsDropChance());

// Copy hand items and their drop chances
newEquipment.setItemInMainHand(oldEquipment.getItemInMainHand());
newEquipment.setItemInMainHandDropChance(oldEquipment.getItemInMainHandDropChance());
newEquipment.setItemInOffHand(oldEquipment.getItemInOffHand());
newEquipment.setItemInOffHandDropChance(oldEquipment.getItemInOffHandDropChance());
}
}
}


}