feat: add multiplayer capture vertical slice
This commit is contained in:
+170
@@ -0,0 +1,170 @@
|
||||
package dev.projectcapture.hytale.command;
|
||||
|
||||
import com.hypixel.hytale.component.Ref;
|
||||
import com.hypixel.hytale.component.Store;
|
||||
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.RequiredArg;
|
||||
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
|
||||
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractCommandCollection;
|
||||
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
|
||||
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
|
||||
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 dev.projectcapture.hytale.gameplay.MultiplayerCreatureService;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/** Registers the server-authoritative playable multiplayer vertical-slice commands. */
|
||||
public final class ProjectCaptureCommands {
|
||||
private ProjectCaptureCommands() {
|
||||
}
|
||||
|
||||
public static void register(JavaPlugin plugin, MultiplayerCreatureService service) {
|
||||
plugin.getCommandRegistry().registerCommand(new RootCommand(service));
|
||||
}
|
||||
|
||||
private static final class RootCommand extends AbstractCommandCollection {
|
||||
private RootCommand(MultiplayerCreatureService service) {
|
||||
super("projectcapture", "ProjectCapture creature commands");
|
||||
addAliases("pc");
|
||||
addSubCommand(new PartyCommand(service));
|
||||
addSubCommand(new CompanionCommand(service));
|
||||
addSubCommand(new CaptureCommand(service));
|
||||
addSubCommand(new EncounterCommand(service));
|
||||
addSubCommand(new GrantCapsulesCommand(service));
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class PlayerCommand extends AbstractPlayerCommand {
|
||||
protected final MultiplayerCreatureService service;
|
||||
|
||||
private PlayerCommand(String name, String description, MultiplayerCreatureService service) {
|
||||
super(name, description);
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
protected final UUID playerId(PlayerRef player) {
|
||||
return player.getUuid();
|
||||
}
|
||||
|
||||
protected final void message(CommandContext context, String text) {
|
||||
context.sendMessage(Message.raw("[ProjectCapture] " + text));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PartyCommand extends PlayerCommand {
|
||||
private PartyCommand(MultiplayerCreatureService service) {
|
||||
super("party", "Show your ProjectCapture party", service);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(
|
||||
CommandContext context,
|
||||
Store<EntityStore> store,
|
||||
Ref<EntityStore> playerRef,
|
||||
PlayerRef player,
|
||||
World world
|
||||
) {
|
||||
MultiplayerCreatureService.PartyView party = service.party(playerId(player));
|
||||
String creatures = party.creatures().isEmpty()
|
||||
? "empty"
|
||||
: party.creatures().stream()
|
||||
.map(creature -> creature.speciesId() + " Lv." + creature.level())
|
||||
.collect(java.util.stream.Collectors.joining(", "));
|
||||
message(context, "Party: " + creatures + " | Field capsules: " + party.fieldCapsules()
|
||||
+ " | Companion: " + party.activeCompanionId().map(UUID::toString).orElse("none"));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CompanionCommand extends PlayerCommand {
|
||||
private final RequiredArg<UUID> creatureId = withRequiredArg("creatureId", "UUID from /pc party", ArgTypes.UUID);
|
||||
|
||||
private CompanionCommand(MultiplayerCreatureService service) {
|
||||
super("companion", "Set a captured party creature as your companion", service);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(
|
||||
CommandContext context,
|
||||
Store<EntityStore> store,
|
||||
Ref<EntityStore> playerRef,
|
||||
PlayerRef player,
|
||||
World world
|
||||
) {
|
||||
UUID id = context.get(creatureId);
|
||||
service.setCompanion(playerId(player), id);
|
||||
message(context, "Companion saved: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CaptureCommand extends PlayerCommand {
|
||||
private CaptureCommand(MultiplayerCreatureService service) {
|
||||
super("capture", "Throw one crafted field capsule at your active encounter", service);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(
|
||||
CommandContext context,
|
||||
Store<EntityStore> store,
|
||||
Ref<EntityStore> playerRef,
|
||||
PlayerRef player,
|
||||
World world
|
||||
) {
|
||||
MultiplayerCreatureService.CaptureOutcome outcome = service.capture(playerId(player), System.nanoTime());
|
||||
if (outcome.captured()) {
|
||||
message(context, "Captured " + outcome.creatureId().orElseThrow() + " ("
|
||||
+ Math.round(outcome.probability() * 100) + "% chance)."
|
||||
+ (outcome.addedToParty() ? " Added to your party." : " Your party is full; stored safely."));
|
||||
} else {
|
||||
message(context, "The creature broke free ("
|
||||
+ Math.round(outcome.probability() * 100) + "% chance). Try again with another capsule.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class EncounterCommand extends PlayerCommand {
|
||||
private final RequiredArg<String> speciesId = withRequiredArg("speciesId", "Namespaced species ID", ArgTypes.STRING);
|
||||
|
||||
private EncounterCommand(MultiplayerCreatureService service) {
|
||||
super("encounter", "Development command: open a personal wild encounter", service);
|
||||
requirePermission("projectcapture.debug.encounter");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(
|
||||
CommandContext context,
|
||||
Store<EntityStore> store,
|
||||
Ref<EntityStore> playerRef,
|
||||
PlayerRef player,
|
||||
World world
|
||||
) {
|
||||
MultiplayerCreatureService.EncounterView encounter = service.openEncounter(
|
||||
playerId(player), context.get(speciesId), 5, System.nanoTime());
|
||||
message(context, "Personal wild encounter: " + encounter.speciesId() + " Lv." + encounter.level());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class GrantCapsulesCommand extends PlayerCommand {
|
||||
private final RequiredArg<Integer> amount = withRequiredArg("amount", "Number of field capsules", ArgTypes.INTEGER);
|
||||
|
||||
private GrantCapsulesCommand(MultiplayerCreatureService service) {
|
||||
super("grantcapsules", "Development command: grant crafted field-capsule test inventory", service);
|
||||
requirePermission("projectcapture.debug.grantcapsules");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void execute(
|
||||
CommandContext context,
|
||||
Store<EntityStore> store,
|
||||
Ref<EntityStore> playerRef,
|
||||
PlayerRef player,
|
||||
World world
|
||||
) {
|
||||
int requested = context.get(amount);
|
||||
service.grantFieldCapsules(playerId(player), requested);
|
||||
message(context, "Added " + requested + " field capsules to your server-authoritative test inventory.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user