NPCSensorStatsCommand.java
package com.hypixel.hytale.server.npc.commands;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.function.consumer.TriConsumer;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.server.npc.asset.builder.Builder;
import com.hypixel.hytale.server.npc.asset.builder.BuilderInfo;
import com.hypixel.hytale.server.npc.asset.builder.BuilderSupport;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import com.hypixel.hytale.server.npc.role.Role;
import com.hypixel.hytale.server.npc.role.support.RoleStats;
import com.hypixel.hytale.server.npc.systems.PositionCacheSystems;
import com.hypixel.hytale.server.npc.util.expression.ExecutionContext;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.annotation.Nonnull;
public class NPCSensorStatsCommand extends AbstractPlayerCommand {
public NPCSensorStatsCommand() {
super("sensorstats", "server.commands.npc.sensorstats.desc");
}
protected void execute(@Nonnull CommandContext context, @Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref, @Nonnull PlayerRef playerRef, @Nonnull World world) {
NPCPlugin npcPlugin = NPCPlugin.get();
List<String> roles = npcPlugin.getRoleTemplateNames(true);
if (roles.isEmpty()) {
context.sendMessage(Message.translation("server.commands.npc.sensorstats.noroles"));
} else {
roles.sort(String::compareToIgnoreCase);
TransformComponent transformComponent = (TransformComponent)store.getComponent(ref, TransformComponent.getComponentType());
assert transformComponent != null;
Vector3d pos = new Vector3d(transformComponent.getPosition());
String name = (String)roles.getFirst();
int roleIndex = NPCPlugin.get().getIndex(name);
if (roleIndex < 0) {
throw new IllegalStateException("No such valid role: " + name);
} else {
Pair<Ref<EntityStore>, NPCEntity> npcPair = npcPlugin.spawnEntity(store, roleIndex, pos, (Vector3f)null, (Model)null, (TriConsumer)null);
NPCEntity npcComponent = npcPair.second();
StringBuilder out = new StringBuilder();
RoleStats roleStats = new RoleStats();
for(int i = 0; i < roles.size(); ++i) {
String roleName = (String)roles.get(i);
try {
roleStats.clear();
BuilderInfo builderInfo = NPCPlugin.get().prepareRoleBuilderInfo(NPCPlugin.get().getIndex(roleName));
Builder<Role> roleBuilder = builderInfo.getBuilder();
BuilderSupport builderSupport = new BuilderSupport(NPCPlugin.get().getBuilderManager(), npcComponent, EntityStore.REGISTRY.newHolder(), new ExecutionContext(), roleBuilder, roleStats);
Role role = NPCPlugin.buildRole(roleBuilder, builderInfo, builderSupport, roleIndex);
PositionCacheSystems.initialisePositionCache(role, builderSupport.getStateEvaluator(), 0.0);
} catch (Throwable t) {
context.sendMessage(Message.translation("server.commands.npc.spawn.templateNotFound").param("template", roleName));
npcPlugin.getLogger().at(Level.WARNING).log("Error spawning role " + roleName + ": " + t.getMessage());
continue;
}
if (!isRangesEmpty(roleStats, true)) {
out.append('\n').append("PLY ");
formatRanges(out, roleStats, "S=", true, RoleStats.RangeType.SORTED, 25);
formatRanges(out, roleStats, "U=", true, RoleStats.RangeType.UNSORTED, 9);
formatRanges(out, roleStats, "A=", true, RoleStats.RangeType.AVOIDANCE, 9);
formatBuckets(out, roleStats, "B=", true, 20);
out.append(roleName);
}
if (!isRangesEmpty(roleStats, false)) {
out.append('\n').append("ENT ");
formatRanges(out, roleStats, "S=", false, RoleStats.RangeType.SORTED, 25);
formatRanges(out, roleStats, "U=", false, RoleStats.RangeType.UNSORTED, 9);
formatRanges(out, roleStats, "A=", false, RoleStats.RangeType.AVOIDANCE, 9);
formatBuckets(out, roleStats, "B=", false, 20);
out.append(roleName);
}
}
npcPlugin.getLogger().at(Level.INFO).log(out.toString());
npcComponent.remove();
}
}
}
private static boolean isRangesEmpty(@Nonnull RoleStats roleStats, boolean isPlayer) {
return roleStats.getRanges(isPlayer, RoleStats.RangeType.SORTED) == null && roleStats.getRanges(isPlayer, RoleStats.RangeType.UNSORTED) == null && roleStats.getRanges(isPlayer, RoleStats.RangeType.AVOIDANCE) == null;
}
private static void formatBuckets(@Nonnull StringBuilder builder, @Nonnull RoleStats roleStats, @Nonnull String label, boolean isPlayer, int width) {
builder.append(label);
int length = builder.length();
IntArrayList buckets = roleStats.getBuckets(isPlayer);
for(int i = 0; i < buckets.size(); ++i) {
builder.append(buckets.getInt(i)).append(" ");
}
length = width + length - builder.length();
if (length > 0) {
builder.append(" ".repeat(length));
}
}
private static void formatRanges(@Nonnull StringBuilder builder, @Nonnull RoleStats roleStats, @Nonnull String label, boolean isPlayer, @Nonnull RoleStats.RangeType rangeType, int width) {
builder.append(label);
int length = builder.length();
int[] ranges = roleStats.getRangesSorted(isPlayer, rangeType);
if (ranges != null && ranges.length != 0) {
for(int range : ranges) {
builder.append(range).append(" ");
}
} else {
builder.append("- ");
}
length = width + length - builder.length();
if (length > 0) {
builder.append(" ".repeat(length));
}
}
}