277 lines
12 KiB
Java
277 lines
12 KiB
Java
package com.hypixel.hytale.server.npc.commands;
|
|
|
|
import com.hypixel.hytale.component.Component;
|
|
import com.hypixel.hytale.component.ComponentType;
|
|
import com.hypixel.hytale.component.Ref;
|
|
import com.hypixel.hytale.component.RemoveReason;
|
|
import com.hypixel.hytale.component.Store;
|
|
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.command.system.CommandContext;
|
|
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
|
|
import com.hypixel.hytale.server.core.command.system.arguments.system.OptionalArg;
|
|
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
|
|
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
|
|
import com.hypixel.hytale.server.core.entity.UUIDComponent;
|
|
import com.hypixel.hytale.server.core.entity.group.EntityGroup;
|
|
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.flock.FlockPlugin;
|
|
import com.hypixel.hytale.server.npc.NPCPlugin;
|
|
import com.hypixel.hytale.server.npc.entities.NPCEntity;
|
|
import it.unimi.dsi.fastutil.Pair;
|
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
|
import it.unimi.dsi.fastutil.ints.IntList;
|
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
|
|
import java.util.UUID;
|
|
import java.util.logging.Level;
|
|
import javax.annotation.Nonnull;
|
|
import javax.annotation.Nullable;
|
|
|
|
public class NPCRunTestsCommand extends AbstractPlayerCommand {
|
|
@Nonnull
|
|
private static final Message MESSAGE_COMMANDS_NPC_RUN_TESTS_SPECIFY_ROLES = Message.translation("server.commands.npc.runtests.specifyroles");
|
|
@Nonnull
|
|
private final OptionalArg<String> rolesArg = this.withOptionalArg("roles", "server.commands.npc.runtests.roles.desc", ArgTypes.STRING);
|
|
@Nonnull
|
|
private final FlagArg presetArg = this.withFlagArg("preset", "server.commands.npc.runtests.preset.desc");
|
|
@Nonnull
|
|
private final FlagArg passArg = this.withFlagArg("pass", "server.commands.npc.runtests.pass.desc");
|
|
@Nonnull
|
|
private final FlagArg failArg = this.withFlagArg("fail", "server.commands.npc.runtests.fail.desc");
|
|
@Nonnull
|
|
private final FlagArg abortArg = this.withFlagArg("abort", "server.commands.npc.runtests.abort.desc");
|
|
|
|
public NPCRunTestsCommand() {
|
|
super("runtests", "server.commands.npc.runtests.desc");
|
|
}
|
|
|
|
@Override
|
|
protected void execute(
|
|
@Nonnull CommandContext context, @Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref, @Nonnull PlayerRef playerRef, @Nonnull World world
|
|
) {
|
|
NPCRunTestsCommand.NPCTestData testDataComponent = store.ensureAndGetComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
|
|
TransformComponent playerTransformComponent = store.getComponent(ref, TransformComponent.getComponentType());
|
|
|
|
assert playerTransformComponent != null;
|
|
|
|
if (!testDataComponent.npcRoles.isEmpty()) {
|
|
if (this.passArg.get(context)) {
|
|
setNextRole(testDataComponent, ref, store, world);
|
|
return;
|
|
}
|
|
|
|
if (this.failArg.get(context)) {
|
|
testDataComponent.failedRoles.add(testDataComponent.npcRoles.getInt(testDataComponent.index));
|
|
setNextRole(testDataComponent, ref, store, world);
|
|
return;
|
|
}
|
|
|
|
if (this.abortArg.get(context)) {
|
|
reportResults(ref, testDataComponent, store);
|
|
Ref<EntityStore> npcRef = world.getEntityRef(testDataComponent.targetUUID);
|
|
if (npcRef != null) {
|
|
cleanupNPC(npcRef, store);
|
|
}
|
|
|
|
store.removeComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
|
|
return;
|
|
}
|
|
}
|
|
|
|
String[] roles;
|
|
if (this.presetArg.get(context)) {
|
|
roles = NPCPlugin.get().getPresetCoverageTestNPCs();
|
|
} else {
|
|
if (!this.rolesArg.provided(context)) {
|
|
context.sendMessage(MESSAGE_COMMANDS_NPC_RUN_TESTS_SPECIFY_ROLES);
|
|
store.removeComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
|
|
return;
|
|
}
|
|
|
|
String roleString = this.rolesArg.get(context);
|
|
if (roleString == null || roleString.isEmpty()) {
|
|
context.sendMessage(MESSAGE_COMMANDS_NPC_RUN_TESTS_SPECIFY_ROLES);
|
|
store.removeComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
|
|
return;
|
|
}
|
|
|
|
roles = roleString.split(",");
|
|
}
|
|
|
|
for (String role : roles) {
|
|
int flockSize;
|
|
try {
|
|
int idx = role.indexOf(35);
|
|
flockSize = idx < 0 ? 1 : Integer.parseInt(role.substring(idx + 1));
|
|
if (idx > 0) {
|
|
role = role.substring(0, idx);
|
|
}
|
|
} catch (NumberFormatException var15) {
|
|
context.sendMessage(Message.translation("server.commands.npc.runtests.invalidflocksize").param("role", role));
|
|
continue;
|
|
}
|
|
|
|
int builderIndex = NPCPlugin.get().getIndex(role);
|
|
if (builderIndex == Integer.MIN_VALUE) {
|
|
context.sendMessage(Message.translation("server.commands.npc.spawn.templateNotFound").param("template", role));
|
|
} else {
|
|
testDataComponent.npcRoles.add(builderIndex);
|
|
testDataComponent.flockSizes.add(flockSize);
|
|
}
|
|
}
|
|
|
|
if (testDataComponent.targetUUID == null) {
|
|
spawnNPC(ref, testDataComponent, 0, playerTransformComponent.getPosition(), playerTransformComponent.getRotation(), store);
|
|
}
|
|
}
|
|
|
|
private static void setNextRole(
|
|
@Nonnull NPCRunTestsCommand.NPCTestData testData, @Nonnull Ref<EntityStore> reference, @Nonnull Store<EntityStore> store, @Nonnull World world
|
|
) {
|
|
Ref<EntityStore> npcReference = world.getEntityRef(testData.targetUUID);
|
|
testData.index++;
|
|
if (testData.index >= testData.npcRoles.size()) {
|
|
reportResults(reference, testData, store);
|
|
if (npcReference != null) {
|
|
cleanupNPC(npcReference, store);
|
|
}
|
|
|
|
store.removeComponent(reference, NPCRunTestsCommand.NPCTestData.getComponentType());
|
|
} else {
|
|
Vector3d position;
|
|
Vector3f rotation;
|
|
if (npcReference != null) {
|
|
TransformComponent npcTransformComponent = store.getComponent(npcReference, TransformComponent.getComponentType());
|
|
|
|
assert npcTransformComponent != null;
|
|
|
|
position = npcTransformComponent.getPosition();
|
|
rotation = npcTransformComponent.getRotation();
|
|
cleanupNPC(npcReference, store);
|
|
} else {
|
|
TransformComponent transformComponent = store.getComponent(reference, TransformComponent.getComponentType());
|
|
|
|
assert transformComponent != null;
|
|
|
|
position = transformComponent.getPosition();
|
|
rotation = transformComponent.getRotation();
|
|
}
|
|
|
|
spawnNPC(reference, testData, testData.index, position, rotation, store);
|
|
}
|
|
}
|
|
|
|
private static void cleanupNPC(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
|
|
Ref<EntityStore> flockReference = FlockPlugin.getFlockReference(ref, store);
|
|
if (flockReference != null) {
|
|
ObjectArrayList<Ref<EntityStore>> members = new ObjectArrayList();
|
|
EntityGroup entityGroupComponent = store.getComponent(flockReference, EntityGroup.getComponentType());
|
|
|
|
assert entityGroupComponent != null;
|
|
|
|
entityGroupComponent.forEachMember((index, memberx, list) -> list.add(memberx), members);
|
|
ObjectListIterator var5 = members.iterator();
|
|
|
|
while (var5.hasNext()) {
|
|
Ref<EntityStore> member = (Ref<EntityStore>)var5.next();
|
|
store.removeEntity(member, RemoveReason.REMOVE);
|
|
}
|
|
}
|
|
|
|
store.removeEntity(ref, RemoveReason.REMOVE);
|
|
}
|
|
|
|
private static void spawnNPC(
|
|
@Nonnull Ref<EntityStore> playerReference,
|
|
@Nonnull NPCRunTestsCommand.NPCTestData testData,
|
|
int index,
|
|
@Nonnull Vector3d position,
|
|
@Nullable Vector3f rotation,
|
|
@Nonnull Store<EntityStore> store
|
|
) {
|
|
Pair<Ref<EntityStore>, NPCEntity> npcPair = NPCPlugin.get().spawnEntity(store, testData.npcRoles.getInt(index), position, rotation, null, null);
|
|
Ref<EntityStore> npcRef = (Ref<EntityStore>)npcPair.first();
|
|
NPCEntity npcComponent = (NPCEntity)npcPair.second();
|
|
int flockSize = testData.flockSizes.getInt(index);
|
|
if (flockSize > 1) {
|
|
TransformComponent npcTransformComponent = store.getComponent(npcRef, TransformComponent.getComponentType());
|
|
|
|
assert npcTransformComponent != null;
|
|
|
|
FlockPlugin.trySpawnFlock(
|
|
npcRef, npcComponent, store, npcComponent.getRoleIndex(), npcTransformComponent.getPosition(), npcTransformComponent.getRotation(), flockSize, null
|
|
);
|
|
}
|
|
|
|
String roleName = npcComponent.getRoleName();
|
|
PlayerRef playerRefComponent = store.getComponent(playerReference, PlayerRef.getComponentType());
|
|
|
|
assert playerRefComponent != null;
|
|
|
|
playerRefComponent.sendMessage(
|
|
Message.translation("server.commands.npc.runtests.testing")
|
|
.param("role", roleName)
|
|
.insert("\n")
|
|
.insert(Message.translation("server.npc.tests." + roleName))
|
|
);
|
|
UUIDComponent npcUUIDComponent = store.getComponent(npcRef, UUIDComponent.getComponentType());
|
|
|
|
assert npcUUIDComponent != null;
|
|
|
|
testData.targetUUID = npcUUIDComponent.getUuid();
|
|
}
|
|
|
|
private static void reportResults(
|
|
@Nonnull Ref<EntityStore> playerReference, @Nonnull NPCRunTestsCommand.NPCTestData testData, @Nonnull Store<EntityStore> store
|
|
) {
|
|
NPCPlugin npcPlugin = NPCPlugin.get();
|
|
Message msg = Message.translation("server.commands.npc.runtests.results");
|
|
|
|
for (int i = 0; i < testData.npcRoles.size(); i++) {
|
|
int index = testData.npcRoles.getInt(i);
|
|
msg.insert(" " + npcPlugin.getName(index) + ": ");
|
|
String result = i >= testData.index
|
|
? "server.commands.npc.runtests.notrun"
|
|
: (testData.failedRoles.contains(index) ? "server.commands.npc.runtests.fail" : "server.commands.npc.runtests.pass");
|
|
msg.insert(Message.translation(result));
|
|
msg.insert("\n");
|
|
}
|
|
|
|
PlayerRef playerRef = store.getComponent(playerReference, PlayerRef.getComponentType());
|
|
|
|
assert playerRef != null;
|
|
|
|
playerRef.sendMessage(msg);
|
|
npcPlugin.getLogger().at(Level.INFO).log(msg.getRawText());
|
|
}
|
|
|
|
public static class NPCTestData implements Component<EntityStore> {
|
|
private final IntList npcRoles = new IntArrayList();
|
|
private final IntList flockSizes = new IntArrayList();
|
|
private final IntSet failedRoles = new IntOpenHashSet();
|
|
private int index;
|
|
private UUID targetUUID;
|
|
|
|
public static ComponentType<EntityStore, NPCRunTestsCommand.NPCTestData> getComponentType() {
|
|
return NPCPlugin.get().getNpcTestDataComponentType();
|
|
}
|
|
|
|
@Nonnull
|
|
@Override
|
|
public Component<EntityStore> clone() {
|
|
NPCRunTestsCommand.NPCTestData data = new NPCRunTestsCommand.NPCTestData();
|
|
data.npcRoles.addAll(this.npcRoles);
|
|
data.index = this.index;
|
|
data.failedRoles.addAll(this.failedRoles);
|
|
return data;
|
|
}
|
|
}
|
|
}
|