package com.hypixel.hytale.server.flock;
import com.hypixel.hytale.component.AddReason;
import com.hypixel.hytale.component.Archetype;
import com.hypixel.hytale.component.ArchetypeChunk;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.SystemGroup;
import com.hypixel.hytale.component.query.Query;
import com.hypixel.hytale.component.system.HolderSystem;
import com.hypixel.hytale.component.system.RefChangeSystem;
import com.hypixel.hytale.component.system.RefSystem;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.group.EntityGroup;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.FromWorldGen;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.damage.Damage;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageEventSystem;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageModule;
import com.hypixel.hytale.server.core.modules.entity.damage.DeathComponent;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.npc.role.RoleDebugFlags;
import java.util.EnumSet;
import java.util.UUID;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class FlockMembershipSystems {
public FlockMembershipSystems() {
}
public static boolean canJoinFlock(@Nonnull Ref<EntityStore> reference, @Nonnull Ref<EntityStore> flockReference, @Nonnull Store<EntityStore> store) {
Flock flockComponent = (Flock)store.getComponent(flockReference, Flock.getComponentType());
assert flockComponent != null;
PersistentFlockData flockData = flockComponent.getFlockData();
if (flockData == null) {
return false;
} else {
EntityGroup entityGroupComponent = (EntityGroup)store.getComponent(flockReference, EntityGroup.getComponentType());
assert entityGroupComponent != null;
if (entityGroupComponent.size() >= flockData.getMaxGrowSize()) {
return false;
} else {
NPCEntity npcComponent = (NPCEntity)store.getComponent(reference, NPCEntity.getComponentType());
if (npcComponent == null) {
return false;
} else {
String roleName = npcComponent.getRoleName();
return roleName != null && flockData.isFlockAllowedRole(roleName);
}
}
}
}
public static void join(@Nonnull Ref<EntityStore> ref, @Nonnull Ref<EntityStore> flockRef, @Nonnull Store<EntityStore> store) {
FlockMembership membership = new FlockMembership();
UUIDComponent uuidComponent = (UUIDComponent)store.getComponent(flockRef, UUIDComponent.getComponentType());
assert uuidComponent != null;
membership.setFlockId(uuidComponent.getUuid());
membership.setFlockRef(flockRef);
membership.setMembershipType(FlockMembership.Type.JOINING);
store.putComponent(ref, FlockMembership.getComponentType(), membership);
}
private static boolean canBecomeLeader(@Nonnull Ref<EntityStore> ref) {
Store<EntityStore> store = ref.getStore();
if (store.getComponent(ref, Player.getComponentType()) != null) {
return true;
} else {
NPCEntity npcComponent = (NPCEntity)store.getComponent(ref, NPCEntity.getComponentType());
return npcComponent != null && npcComponent.getRole() != null ? npcComponent.getRole().isCanLeadFlock() : false;
}
}
private static void markChunkNeedsSaving(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
TransformComponent transformComponent = (TransformComponent)store.getComponent(ref, TransformComponent.getComponentType());
if (transformComponent != null) {
transformComponent.markChunkDirty(store);
}
}
public static class EntityRef extends RefSystem<EntityStore> {
@Nonnull
private final ComponentType<EntityStore, FlockMembership> flockMembershipComponentType;
public EntityRef(@Nonnull ComponentType<EntityStore, FlockMembership> flockMembershipComponentType) {
this.flockMembershipComponentType = flockMembershipComponentType;
}
public Query<EntityStore> getQuery() {
return this.flockMembershipComponentType;
}
public void onEntityAdded(@Nonnull Ref<EntityStore> ref, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
commandBuffer.run((_store) -> this.joinOrCreateFlock(ref, _store));
}
private void joinOrCreateFlock(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
FlockMembership flockMembershipComponent = (FlockMembership)store.getComponent(ref, this.flockMembershipComponentType);
assert flockMembershipComponent != null;
UUID flockId = flockMembershipComponent.getFlockId();
Ref<EntityStore> flockReference = ((EntityStore)store.getExternalData()).getRefFromUUID(flockId);
EntityGroup entityGroup;
Flock flock;
if (flockReference != null) {
entityGroup = (EntityGroup)store.getComponent(flockReference, EntityGroup.getComponentType());
assert entityGroup != null;
flock = (Flock)store.getComponent(flockReference, Flock.getComponentType());
assert flock != null;
} else {
entityGroup = new EntityGroup();
flock = new Flock();
Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder();
holder.addComponent(UUIDComponent.getComponentType(), new UUIDComponent(flockId));
holder.addComponent(EntityGroup.getComponentType(), entityGroup);
holder.addComponent(Flock.getComponentType(), flock);
flockReference = store.addEntity(holder, AddReason.LOAD);
}
flockMembershipComponent.setFlockRef(flockReference);
if (entityGroup.isMember(ref)) {
throw new IllegalStateException(String.format("Entity %s attempting to reload into group with ID %s despite already being a member", ref, flockId));
} else {
entityGroup.add(ref);
if (flockMembershipComponent.getMembershipType() == FlockMembership.Type.LEADER) {
PersistentFlockData persistentFlockData = (PersistentFlockData)store.getComponent(ref, PersistentFlockData.getComponentType());
if (persistentFlockData != null) {
flock.setFlockData(persistentFlockData);
} else {
PersistentFlockData flockData = flock.getFlockData();
if (flockData != null) {
store.putComponent(ref, PersistentFlockData.getComponentType(), flockData);
}
}
Ref<EntityStore> oldLeaderRef = entityGroup.getLeaderRef();
entityGroup.setLeaderRef(ref);
if (oldLeaderRef != null && !oldLeaderRef.equals(ref)) {
FlockMembership oldLeaderComponent = (FlockMembership)store.getComponent(oldLeaderRef, this.flockMembershipComponentType);
if (oldLeaderComponent != null) {
oldLeaderComponent.setMembershipType(FlockMembership.Type.MEMBER);
}
store.tryRemoveComponent(oldLeaderRef, PersistentFlockData.getComponentType());
FlockMembershipSystems.markChunkNeedsSaving(oldLeaderRef, store);
}
markNeedsSave(ref, store, flock);
if (flock.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Set new leader, old=%s, new=%s, size=%s", flockId, oldLeaderRef, ref, entityGroup.size());
}
} else if (entityGroup.getLeaderRef() == null) {
setInterimLeader(store, flockMembershipComponent, entityGroup, ref, flock, flockId);
}
if (flock.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: reference=%s, size=%s", flockId, ref, entityGroup.size());
}
}
}
public void onEntityRemove(@Nonnull Ref<EntityStore> ref, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
FlockMembership membership = (FlockMembership)store.getComponent(ref, this.flockMembershipComponentType);
assert membership != null;
Ref<EntityStore> flockRef = membership.getFlockRef();
if (flockRef != null && flockRef.isValid()) {
Flock flockComponent = (Flock)commandBuffer.getComponent(flockRef, Flock.getComponentType());
assert flockComponent != null;
EntityGroup entityGroupComponent = (EntityGroup)commandBuffer.getComponent(flockRef, EntityGroup.getComponentType());
assert entityGroupComponent != null;
UUIDComponent uuidComponent = (UUIDComponent)commandBuffer.getComponent(flockRef, UUIDComponent.getComponentType());
assert uuidComponent != null;
UUID flockId = uuidComponent.getUuid();
if (reason != RemoveReason.REMOVE && !store.getArchetype(ref).contains(Player.getComponentType())) {
if (reason == RemoveReason.UNLOAD) {
entityGroupComponent.remove(ref);
if (!entityGroupComponent.isDissolved() && membership.getMembershipType().isActingAsLeader()) {
Ref<EntityStore> interimLeader = entityGroupComponent.testMembers((member) -> true, true);
if (interimLeader != null) {
FlockMembership interimLeaderMembership = (FlockMembership)store.getComponent(interimLeader, this.flockMembershipComponentType);
if (interimLeaderMembership == null) {
throw new IllegalStateException("Member is missing FlockMembership component!");
}
setInterimLeader(store, interimLeaderMembership, entityGroupComponent, interimLeader, flockComponent, flockId);
}
}
membership.unload();
if (entityGroupComponent.size() <= 0) {
commandBuffer.tryRemoveEntity(flockRef, RemoveReason.UNLOAD);
}
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Unloaded from flock, reference=%s, leader=%s, size=%s", flockId, ref, entityGroupComponent.getLeaderRef(), entityGroupComponent.size());
}
}
} else {
entityGroupComponent.remove(ref);
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Left flock, reference=%s, leader=%s, size=%s", flockId, ref, entityGroupComponent.getLeaderRef(), entityGroupComponent.size());
}
if (!entityGroupComponent.isDissolved() && entityGroupComponent.size() < 2) {
commandBuffer.removeEntity(flockRef, RemoveReason.REMOVE);
return;
}
if (entityGroupComponent.isDissolved()) {
return;
}
PersistentFlockData flockData = flockComponent.getFlockData();
if (flockData != null) {
flockData.decreaseSize();
}
Ref<EntityStore> leader = entityGroupComponent.getLeaderRef();
if (leader != null && !leader.equals(ref)) {
FlockMembershipSystems.markChunkNeedsSaving(leader, store);
return;
}
Ref<EntityStore> newLeader = entityGroupComponent.testMembers(FlockMembershipSystems::canBecomeLeader, true);
if (newLeader == null) {
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Leave failed to get new leader, reference=%s, leader=%s, size=%s", flockId, ref, entityGroupComponent.getLeaderRef(), entityGroupComponent.size());
}
commandBuffer.removeEntity(flockRef, RemoveReason.REMOVE);
return;
}
entityGroupComponent.setLeaderRef(newLeader);
FlockMembership flockMembershipComponent = (FlockMembership)store.getComponent(newLeader, this.flockMembershipComponentType);
assert flockMembershipComponent != null;
flockMembershipComponent.setMembershipType(FlockMembership.Type.LEADER);
if (flockData != null) {
commandBuffer.putComponent(newLeader, PersistentFlockData.getComponentType(), flockData);
}
markNeedsSave(newLeader, store, flockComponent);
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Set new leader, old=%s, new=%s, size=%s", flockId, ref, newLeader, entityGroupComponent.size());
}
}
}
}
private static void markNeedsSave(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull Flock flockComponent) {
NPCEntity npcComponent = (NPCEntity)store.getComponent(ref, NPCEntity.getComponentType());
if (npcComponent != null) {
Role role = npcComponent.getRole();
if (role != null) {
EnumSet<RoleDebugFlags> flags = role.getDebugSupport().getDebugFlags();
flockComponent.setTrace(flags.contains(RoleDebugFlags.Flock));
}
}
FlockMembershipSystems.markChunkNeedsSaving(ref, store);
}
private static void setInterimLeader(@Nonnull Store<EntityStore> store, @Nonnull FlockMembership interimLeaderMembership, @Nonnull EntityGroup entityGroup, Ref<EntityStore> interimLeader, @Nonnull Flock flockComponent, @Nonnull UUID flockId) {
interimLeaderMembership.setMembershipType(FlockMembership.Type.INTERIM_LEADER);
entityGroup.setLeaderRef(interimLeader);
markNeedsSave(interimLeader, store, flockComponent);
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Set new interim leader, old=%s, new=%s, size=%s", flockId, entityGroup.getLeaderRef(), interimLeader, entityGroup.size());
}
}
}
public static class RefChange extends RefChangeSystem<EntityStore, FlockMembership> {
@Nonnull
private final ComponentType<EntityStore, FlockMembership> flockMembershipComponentType;
public RefChange(@Nonnull ComponentType<EntityStore, FlockMembership> flockMembershipComponentType) {
this.flockMembershipComponentType = flockMembershipComponentType;
}
public Query<EntityStore> getQuery() {
return this.flockMembershipComponentType;
}
@Nonnull
public ComponentType<EntityStore, FlockMembership> componentType() {
return this.flockMembershipComponentType;
}
public void onComponentAdded(@Nonnull Ref<EntityStore> ref, @Nonnull FlockMembership component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
this.doJoin(ref, component, store, commandBuffer);
}
public void onComponentSet(@Nonnull Ref<EntityStore> ref, FlockMembership oldComponent, @Nonnull FlockMembership newComponent, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
assert oldComponent != null;
if (oldComponent.getMembershipType() == FlockMembership.Type.JOINING) {
this.doJoin(ref, newComponent, store, commandBuffer);
} else {
doLeave(ref, oldComponent, store, commandBuffer);
commandBuffer.run((_store) -> this.doJoin(ref, newComponent, store, commandBuffer));
}
}
public void onComponentRemoved(@Nonnull Ref<EntityStore> ref, @Nonnull FlockMembership component, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
if (component.getMembershipType() != FlockMembership.Type.JOINING) {
doLeave(ref, component, store, commandBuffer);
}
}
private void doJoin(@Nonnull Ref<EntityStore> ref, @Nonnull FlockMembership membershipComponent, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
Ref<EntityStore> flockRef = membershipComponent.getFlockRef();
if (flockRef != null) {
if (!flockRef.isValid()) {
((HytaleLogger.Api)FlockPlugin.get().getLogger().atWarning()).log("Entity %s attempting to join invalid flock with ref %s", ref, flockRef);
commandBuffer.removeComponent(ref, this.flockMembershipComponentType);
} else {
Flock flockComponent = (Flock)commandBuffer.getComponent(flockRef, Flock.getComponentType());
assert flockComponent != null;
EntityGroup entityGroupComponent = (EntityGroup)commandBuffer.getComponent(flockRef, EntityGroup.getComponentType());
assert entityGroupComponent != null;
UUIDComponent uuidComponent = (UUIDComponent)commandBuffer.getComponent(flockRef, UUIDComponent.getComponentType());
assert uuidComponent != null;
UUID flockId = uuidComponent.getUuid();
if (!entityGroupComponent.isMember(ref)) {
if (membershipComponent.getMembershipType() != FlockMembership.Type.JOINING) {
throw new IllegalStateException(String.format("Entity %s attempting to join group with ID %s but has wrong membership status %s", ref, flockId, membershipComponent.getMembershipType()));
} else {
boolean isDead = store.getArchetype(ref).contains(DeathComponent.getComponentType());
if (ref.isValid() && !isDead) {
Player playerComponent = (Player)commandBuffer.getComponent(ref, Player.getComponentType());
if (playerComponent != null && playerComponent.getGameMode() != GameMode.Adventure) {
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Failed to join, ref=%s. Player in creative mode.", flockId, ref);
}
commandBuffer.removeComponent(ref, this.flockMembershipComponentType);
} else {
PersistentFlockData flockData = flockComponent.getFlockData();
if (flockData == null) {
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Rejected join entity due to leader not being loaded, ref=%s, size=%s", flockId, ref, entityGroupComponent.size());
}
commandBuffer.removeComponent(ref, this.flockMembershipComponentType);
} else {
Ref<EntityStore> leader = entityGroupComponent.getLeaderRef();
boolean mustBecomeLeader = leader == null;
boolean wasFirstJoiner = mustBecomeLeader;
if (playerComponent != null) {
if (leader != null && store.getComponent(leader, Player.getComponentType()) != null) {
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Failed join 2 players, ref=%s, size=%s", flockId, ref, entityGroupComponent.size());
}
commandBuffer.removeComponent(ref, this.flockMembershipComponentType);
return;
}
mustBecomeLeader = true;
}
entityGroupComponent.add(ref);
if (mustBecomeLeader) {
setNewLeader(flockId, entityGroupComponent, flockComponent, ref, store, commandBuffer);
if (wasFirstJoiner && flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Joined no leader, ref=%s, size=%s", flockId, ref, entityGroupComponent.size());
}
} else {
membershipComponent.setMembershipType(FlockMembership.Type.MEMBER);
}
flockData.increaseSize();
FlockMembershipSystems.markChunkNeedsSaving(entityGroupComponent.getLeaderRef(), store);
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Joined join ref=%s, size=%s", flockId, ref, entityGroupComponent.size());
}
FlockMembershipSystems.markChunkNeedsSaving(ref, store);
}
}
} else {
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Failed to join entity ref=%s, size=%s", flockId, ref, entityGroupComponent.size());
}
commandBuffer.removeComponent(ref, this.flockMembershipComponentType);
}
}
}
}
}
}
private static void doLeave(@Nonnull Ref<EntityStore> ref, @Nonnull FlockMembership membershipComponent, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
Ref<EntityStore> flockReference = membershipComponent.getFlockRef();
if (flockReference != null && flockReference.isValid()) {
Flock flockComponent = (Flock)commandBuffer.getComponent(flockReference, Flock.getComponentType());
assert flockComponent != null;
EntityGroup entityGroupComponent = (EntityGroup)commandBuffer.getComponent(flockReference, EntityGroup.getComponentType());
assert entityGroupComponent != null;
UUIDComponent uuidComponent = (UUIDComponent)commandBuffer.getComponent(flockReference, UUIDComponent.getComponentType());
assert uuidComponent != null;
UUID flockId = uuidComponent.getUuid();
entityGroupComponent.remove(ref);
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Left flock, reference=%s, leader=%s, size=%s", flockId, ref, entityGroupComponent.getLeaderRef(), entityGroupComponent.size());
}
if (!entityGroupComponent.isDissolved() && entityGroupComponent.size() < 2) {
commandBuffer.removeEntity(flockReference, RemoveReason.REMOVE);
} else if (!entityGroupComponent.isDissolved()) {
PersistentFlockData flockData = flockComponent.getFlockData();
if (flockData != null) {
flockData.decreaseSize();
}
Ref<EntityStore> leader = entityGroupComponent.getLeaderRef();
if (leader != null && !ref.equals(leader)) {
FlockMembershipSystems.markChunkNeedsSaving(leader, store);
} else {
Ref<EntityStore> newLeader = entityGroupComponent.testMembers(FlockMembershipSystems::canBecomeLeader, true);
if (newLeader == null) {
if (flockComponent.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Leave failed to get new leader, reference=%s, leader=%s, size=%s", flockId, ref, entityGroupComponent.getLeaderRef(), entityGroupComponent.size());
}
commandBuffer.removeEntity(flockReference, RemoveReason.REMOVE);
return;
}
setNewLeader(flockId, entityGroupComponent, flockComponent, newLeader, store, commandBuffer);
}
}
}
}
private static void setNewLeader(@Nonnull UUID flockId, @Nonnull EntityGroup entityGroup, @Nonnull Flock flock, @Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
Ref<EntityStore> oldLeader = entityGroup.getLeaderRef();
if (oldLeader == null || !oldLeader.equals(ref)) {
entityGroup.setLeaderRef(ref);
if (oldLeader != null) {
FlockMembership oldLeaderComponent = (FlockMembership)store.getComponent(oldLeader, FlockMembership.getComponentType());
if (oldLeaderComponent != null) {
oldLeaderComponent.setMembershipType(FlockMembership.Type.MEMBER);
}
commandBuffer.tryRemoveComponent(oldLeader, PersistentFlockData.getComponentType());
FlockMembershipSystems.markChunkNeedsSaving(oldLeader, store);
}
FlockMembership flockMembershipComponent = (FlockMembership)store.getComponent(ref, FlockMembership.getComponentType());
assert flockMembershipComponent != null;
flockMembershipComponent.setMembershipType(FlockMembership.Type.LEADER);
NPCEntity newLeaderNpcComponent = (NPCEntity)store.getComponent(ref, NPCEntity.getComponentType());
if (newLeaderNpcComponent != null) {
Role role = newLeaderNpcComponent.getRole();
if (role != null) {
EnumSet<RoleDebugFlags> flags = role.getDebugSupport().getDebugFlags();
flock.setTrace(flags.contains(RoleDebugFlags.Flock));
}
}
PersistentFlockData flockData = flock.getFlockData();
if (flockData != null) {
commandBuffer.putComponent(ref, PersistentFlockData.getComponentType(), flockData);
}
FlockMembershipSystems.markChunkNeedsSaving(ref, store);
if (flock.isTrace()) {
FlockPlugin.get().getLogger().at(Level.INFO).log("Flock %s: Set new leader, old=%s, new=%s, size=%s", flockId, oldLeader, ref, entityGroup.size());
}
}
}
}
public static class OnDamageReceived extends DamageEventSystem {
@Nonnull
private final Query<EntityStore> query = FlockMembership.getComponentType();
public OnDamageReceived() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nonnull
public Query<EntityStore> getQuery() {
return this.query;
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage danage) {
FlockMembership flockMembershipComponent = (FlockMembership)archetypeChunk.getComponent(index, FlockMembership.getComponentType());
if (flockMembershipComponent != null) {
Ref<EntityStore> flockRef = flockMembershipComponent.getFlockRef();
if (flockRef != null && flockRef.isValid()) {
Flock flockComponent = (Flock)commandBuffer.getComponent(flockRef, Flock.getComponentType());
assert flockComponent != null;
flockComponent.getNextDamageData().onSufferedDamage(commandBuffer, danage);
if (flockMembershipComponent.getMembershipType().isActingAsLeader()) {
flockComponent.getNextLeaderDamageData().onSufferedDamage(commandBuffer, danage);
}
}
}
}
}
public static class OnDamageDealt extends DamageEventSystem {
public OnDamageDealt() {
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return DamageModule.get().getInspectDamageGroup();
}
@Nullable
public Query<EntityStore> getQuery() {
return Archetype.<EntityStore>empty();
}
public void handle(int index, @Nonnull ArchetypeChunk<EntityStore> archetypeChunk, @Nonnull Store<EntityStore> store, @Nonnull CommandBuffer<EntityStore> commandBuffer, @Nonnull Damage damage) {
Damage.Source var7 = damage.getSource();
if (var7 instanceof Damage.EntitySource entitySource) {
Ref<EntityStore> damageSourceRef = entitySource.getRef();
if (damageSourceRef.isValid()) {
FlockMembership flockMembershipComponent = (FlockMembership)commandBuffer.getComponent(damageSourceRef, FlockMembership.getComponentType());
if (flockMembershipComponent != null) {
Ref<EntityStore> flockReference = flockMembershipComponent.getFlockRef();
if (flockReference != null && flockReference.isValid()) {
Flock flockComponent = (Flock)commandBuffer.getComponent(flockReference, Flock.getComponentType());
assert flockComponent != null;
Ref<EntityStore> entityRef = archetypeChunk.getReferenceTo(index);
flockComponent.getNextDamageData().onInflictedDamage(entityRef, (double)damage.getAmount());
if (flockMembershipComponent.getMembershipType().isActingAsLeader()) {
flockComponent.getNextLeaderDamageData().onInflictedDamage(entityRef, (double)damage.getAmount());
}
}
}
}
}
}
}
public static class NPCAddedFromWorldGen extends HolderSystem<EntityStore> {
@Nullable
private final ComponentType<EntityStore, NPCEntity> npcComponentType = NPCEntity.getComponentType();
@Nonnull
private final ComponentType<EntityStore, FromWorldGen> fromWorldGenComponentType = FromWorldGen.getComponentType();
@Nonnull
private final ComponentType<EntityStore, FlockMembership> flockMembershipComponentType = FlockMembership.getComponentType();
@Nonnull
private final Query<EntityStore> query;
public NPCAddedFromWorldGen() {
this.query = Query.<EntityStore>and(this.npcComponentType, this.fromWorldGenComponentType, this.flockMembershipComponentType);
}
@Nonnull
public Query<EntityStore> getQuery() {
return this.query;
}
@Nullable
public SystemGroup<EntityStore> getGroup() {
return EntityModule.get().getPreClearMarkersGroup();
}
public void onEntityAdd(@Nonnull Holder<EntityStore> holder, @Nonnull AddReason reason, @Nonnull Store<EntityStore> store) {
holder.removeComponent(this.flockMembershipComponentType);
}
public void onEntityRemoved(@Nonnull Holder<EntityStore> holder, @Nonnull RemoveReason reason, @Nonnull Store<EntityStore> store) {
}
}
}