Clean repo for open source release
Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
This commit is contained in:
@@ -0,0 +1,318 @@
|
||||
package com.tiedup.remake.entities;
|
||||
|
||||
import com.tiedup.remake.core.TiedUpMod;
|
||||
import com.tiedup.remake.v2.BodyRegionV2;
|
||||
import com.tiedup.remake.items.ModItems;
|
||||
import com.tiedup.remake.items.base.ItemCollar;
|
||||
import com.tiedup.remake.state.CollarRegistry;
|
||||
import com.tiedup.remake.state.IBondageState;
|
||||
import com.tiedup.remake.util.tasks.ItemTask;
|
||||
import com.tiedup.remake.util.tasks.JobLoader;
|
||||
import java.util.UUID;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Manages the job system for EntityKidnapper.
|
||||
*
|
||||
* <p>The job system allows kidnappers to assign tasks to their captives.
|
||||
* When a job is assigned:
|
||||
* <ol>
|
||||
* <li>Worker UUID is stored for tracking</li>
|
||||
* <li>Shock collar is put on the worker</li>
|
||||
* <li>Worker is untied and freed to complete the job</li>
|
||||
* <li>Kidnapper waits for job completion</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>This system IS persisted to NBT via {@link #save(CompoundTag)} and {@link #load(CompoundTag)}.
|
||||
*/
|
||||
public class KidnapperJobManager {
|
||||
|
||||
private final EntityKidnapper kidnapper;
|
||||
|
||||
/** Current job assigned to worker. */
|
||||
@Nullable
|
||||
private ItemTask currentJob = null;
|
||||
|
||||
/** UUID of worker doing the current job (freed but tracked). */
|
||||
@Nullable
|
||||
private UUID jobWorkerUUID = null;
|
||||
|
||||
public KidnapperJobManager(EntityKidnapper kidnapper) {
|
||||
this.kidnapper = kidnapper;
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// STATE QUERIES
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Check if waiting for worker to complete job.
|
||||
* Note: Worker is NOT a captive during job - they are tracked by UUID.
|
||||
*/
|
||||
public boolean isWaitingForJobToBeCompleted() {
|
||||
return this.currentJob != null && this.jobWorkerUUID != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current job assigned to worker.
|
||||
*/
|
||||
@Nullable
|
||||
public ItemTask getCurrentJob() {
|
||||
return this.currentJob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UUID of the worker doing the current job.
|
||||
*/
|
||||
@Nullable
|
||||
public UUID getJobWorkerUUID() {
|
||||
return this.jobWorkerUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the UUID of the worker doing the current job.
|
||||
* Used by maids to register labor workers for attack protection.
|
||||
*/
|
||||
public void setJobWorkerUUID(@Nullable UUID workerUUID) {
|
||||
this.jobWorkerUUID = workerUUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the job worker entity by UUID.
|
||||
* @return The worker as Player, or null if not found/offline
|
||||
*/
|
||||
@Nullable
|
||||
public Player getJobWorker() {
|
||||
if (this.jobWorkerUUID == null) {
|
||||
return null;
|
||||
}
|
||||
return kidnapper.level().getPlayerByUUID(this.jobWorkerUUID);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// JOB ASSIGNMENT
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Assign a job to the kidnapper's current captive.
|
||||
* This will:
|
||||
* <ol>
|
||||
* <li>Store the worker UUID</li>
|
||||
* <li>Untie the captive (remove bind and gag)</li>
|
||||
* <li>Free them from captivity</li>
|
||||
* <li>Put a shock collar on them (AFTER untie)</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param job The job to assign
|
||||
* @return true if job was assigned
|
||||
*/
|
||||
public boolean assignJob(ItemTask job) {
|
||||
if (!kidnapper.hasCaptives() || job == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.currentJob != null) {
|
||||
TiedUpMod.LOGGER.warn(
|
||||
"[KidnapperJobManager] {} already has an active job",
|
||||
kidnapper.getNpcName()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
IBondageState captive = kidnapper.getCaptive();
|
||||
if (captive == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store job and worker info
|
||||
this.currentJob = job;
|
||||
this.jobWorkerUUID = captive.asLivingEntity().getUUID();
|
||||
|
||||
TiedUpMod.LOGGER.info(
|
||||
"[KidnapperJobManager] {} assigned job to {}: {}",
|
||||
kidnapper.getNpcName(),
|
||||
captive.getKidnappedName(),
|
||||
job.toDisplayString()
|
||||
);
|
||||
|
||||
// IMPORTANT: Order matters here!
|
||||
// 1. First untie (this clears ALL bondage slots including collar)
|
||||
// 2. Then free from captivity
|
||||
// 3. Finally put collar on (so it's not cleared by untie)
|
||||
|
||||
// Untie the worker (remove bind and gag so they can work)
|
||||
captive.untie(false);
|
||||
|
||||
TiedUpMod.LOGGER.info(
|
||||
"[KidnapperJobManager] {} untied {} for job",
|
||||
kidnapper.getNpcName(),
|
||||
captive.getKidnappedName()
|
||||
);
|
||||
|
||||
// Free from captivity (they keep the collar, we track via UUID)
|
||||
captive.free(false);
|
||||
|
||||
TiedUpMod.LOGGER.info(
|
||||
"[KidnapperJobManager] {} freed {} to complete job",
|
||||
kidnapper.getNpcName(),
|
||||
captive.getKidnappedName()
|
||||
);
|
||||
|
||||
// Put a shock collar on the worker AFTER untie/free
|
||||
ItemStack shockCollar = new ItemStack(ModItems.SHOCK_COLLAR_AUTO.get());
|
||||
if (shockCollar.getItem() instanceof ItemCollar collarItem) {
|
||||
// Add kidnapper as owner so the collar is linked
|
||||
collarItem.addOwner(
|
||||
shockCollar,
|
||||
kidnapper.getUUID(),
|
||||
kidnapper.getNpcName()
|
||||
);
|
||||
// Lock the collar so they can't remove it
|
||||
shockCollar = collarItem.setLocked(shockCollar, true);
|
||||
}
|
||||
captive.equip(BodyRegionV2.NECK, shockCollar);
|
||||
|
||||
// Register collar in CollarRegistry for tracking
|
||||
registerJobCollar(captive.asLivingEntity(), shockCollar);
|
||||
|
||||
TiedUpMod.LOGGER.info(
|
||||
"[KidnapperJobManager] {} put shock collar (locked, owned) on {}",
|
||||
kidnapper.getNpcName(),
|
||||
captive.getKidnappedName()
|
||||
);
|
||||
|
||||
// Hold shocker controller
|
||||
kidnapper.setItemInHand(
|
||||
InteractionHand.MAIN_HAND,
|
||||
new ItemStack(ModItems.SHOCKER_CONTROLLER.get())
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign a random job using JobLoader.
|
||||
*
|
||||
* @return true if job was assigned
|
||||
*/
|
||||
public boolean assignRandomJob() {
|
||||
return assignJob(JobLoader.getRandomJob());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the current job and worker tracking.
|
||||
*/
|
||||
public void clearCurrentJob() {
|
||||
if (this.currentJob != null || this.jobWorkerUUID != null) {
|
||||
TiedUpMod.LOGGER.info(
|
||||
"[KidnapperJobManager] {} cleared job",
|
||||
kidnapper.getNpcName()
|
||||
);
|
||||
this.currentJob = null;
|
||||
this.jobWorkerUUID = null;
|
||||
|
||||
// Clear held shocker controller
|
||||
kidnapper.setItemInHand(InteractionHand.MAIN_HAND, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// COLLAR REGISTRY
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Register a job collar in the CollarRegistry.
|
||||
* This allows tracking the worker via the collar system.
|
||||
*
|
||||
* @param wearer The entity wearing the collar
|
||||
* @param collarStack The collar ItemStack
|
||||
*/
|
||||
private void registerJobCollar(LivingEntity wearer, ItemStack collarStack) {
|
||||
if (wearer == null || kidnapper.level().isClientSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(kidnapper.level() instanceof ServerLevel serverLevel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CollarRegistry registry = CollarRegistry.get(serverLevel);
|
||||
if (registry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Register kidnapper as owner of the wearer
|
||||
registry.registerCollar(wearer.getUUID(), kidnapper.getUUID());
|
||||
|
||||
TiedUpMod.LOGGER.debug(
|
||||
"[KidnapperJobManager] Registered job collar for {} owned by {}",
|
||||
wearer.getName().getString(),
|
||||
kidnapper.getNpcName()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a job collar from the CollarRegistry.
|
||||
* Called when the job is completed and collar is removed.
|
||||
*
|
||||
* @param wearer The entity whose collar is being removed
|
||||
*/
|
||||
public void unregisterJobCollar(LivingEntity wearer) {
|
||||
if (wearer == null || kidnapper.level().isClientSide()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(kidnapper.level() instanceof ServerLevel serverLevel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CollarRegistry registry = CollarRegistry.get(serverLevel);
|
||||
if (registry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Unregister the wearer
|
||||
registry.unregisterWearer(wearer.getUUID());
|
||||
|
||||
TiedUpMod.LOGGER.debug(
|
||||
"[KidnapperJobManager] Unregistered job collar for {}",
|
||||
wearer.getName().getString()
|
||||
);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// NBT PERSISTENCE
|
||||
// ========================================
|
||||
|
||||
/**
|
||||
* Save job manager state to NBT.
|
||||
* @param tag The tag to save to
|
||||
*/
|
||||
public void save(CompoundTag tag) {
|
||||
if (this.currentJob != null) {
|
||||
tag.put("CurrentJob", this.currentJob.save());
|
||||
}
|
||||
if (this.jobWorkerUUID != null) {
|
||||
tag.putUUID("JobWorkerUUID", this.jobWorkerUUID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load job manager state from NBT.
|
||||
* @param tag The tag to load from
|
||||
*/
|
||||
public void load(CompoundTag tag) {
|
||||
if (tag.contains("CurrentJob")) {
|
||||
this.currentJob = ItemTask.load(tag.getCompound("CurrentJob"));
|
||||
}
|
||||
if (tag.contains("JobWorkerUUID")) {
|
||||
this.jobWorkerUUID = tag.getUUID("JobWorkerUUID");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user