Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
400 lines
13 KiB
Java
400 lines
13 KiB
Java
package com.tiedup.remake.worldgen;
|
|
|
|
import com.tiedup.remake.cells.CampOwnership;
|
|
import com.tiedup.remake.core.TiedUpMod;
|
|
import com.tiedup.remake.entities.EntityKidnapper;
|
|
import com.tiedup.remake.entities.EntityKidnapperElite;
|
|
import com.tiedup.remake.entities.EntityMaid;
|
|
import com.tiedup.remake.entities.EntitySlaveTrader;
|
|
import com.tiedup.remake.entities.ModEntities;
|
|
import java.util.UUID;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.MobSpawnType;
|
|
import net.minecraft.world.level.ServerLevelAccessor;
|
|
import net.minecraft.world.level.block.Mirror;
|
|
import net.minecraft.world.level.block.Rotation;
|
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
|
import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece;
|
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
|
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
|
|
|
/**
|
|
* Structure piece for kidnapper camp tents.
|
|
*
|
|
* Phase: Kidnapper Revamp - Cell System
|
|
*
|
|
* Handles data markers:
|
|
* - "kidnapper" - Spawns a regular kidnapper
|
|
* - "kidnapper_elite" - Spawns an elite kidnapper
|
|
* - "slave_trader" - Spawns a slave trader (brain of the camp)
|
|
* - "maid" - Spawns a maid (linked to trader)
|
|
* - "loot" - Places a loot chest
|
|
*/
|
|
public class KidnapperCampPiece extends TemplateStructurePiece {
|
|
|
|
/** Temporary storage for trader UUID during structure generation */
|
|
@Nullable
|
|
private UUID spawnedTraderUUID;
|
|
|
|
/** Temporary storage for camp data during structure generation */
|
|
@Nullable
|
|
private CampOwnership.CampData currentCamp;
|
|
|
|
public KidnapperCampPiece(
|
|
StructureTemplateManager templateManager,
|
|
ResourceLocation templateLocation,
|
|
BlockPos pos,
|
|
Rotation rotation
|
|
) {
|
|
super(
|
|
ModStructures.CAMP_PIECE.get(),
|
|
0,
|
|
templateManager,
|
|
templateLocation,
|
|
templateLocation.toString(),
|
|
makeSettings(rotation),
|
|
pos
|
|
);
|
|
}
|
|
|
|
public KidnapperCampPiece(
|
|
StructureTemplateManager templateManager,
|
|
CompoundTag tag
|
|
) {
|
|
super(ModStructures.CAMP_PIECE.get(), tag, templateManager, location ->
|
|
makeSettings(Rotation.NONE)
|
|
);
|
|
}
|
|
|
|
private static StructurePlaceSettings makeSettings(Rotation rotation) {
|
|
return new StructurePlaceSettings()
|
|
.setRotation(rotation)
|
|
.setMirror(Mirror.NONE)
|
|
.setRotationPivot(BlockPos.ZERO)
|
|
.addProcessor(BlockIgnoreProcessor.STRUCTURE_BLOCK)
|
|
.addProcessor(new MarkerProcessor());
|
|
}
|
|
|
|
@Override
|
|
protected void handleDataMarker(
|
|
String marker,
|
|
BlockPos pos,
|
|
ServerLevelAccessor level,
|
|
RandomSource random,
|
|
BoundingBox box
|
|
) {
|
|
// Handle data markers from structure blocks
|
|
// Data markers are placed using jigsaw blocks or structure blocks with "Data" mode
|
|
|
|
if (!(level instanceof ServerLevel serverLevel)) {
|
|
return;
|
|
}
|
|
|
|
switch (marker.toLowerCase()) {
|
|
case "kidnapper" -> {
|
|
// Spawn a kidnapper at this position
|
|
spawnKidnapper(serverLevel, pos, random, false);
|
|
}
|
|
case "kidnapper_elite" -> {
|
|
// Spawn elite kidnapper at this position
|
|
spawnKidnapper(serverLevel, pos, random, true);
|
|
}
|
|
case "slave_trader" -> {
|
|
// Spawn slave trader (brain of camp)
|
|
spawnSlaveTrader(serverLevel, pos, random);
|
|
}
|
|
case "maid" -> {
|
|
// Spawn maid (linked to trader)
|
|
spawnMaid(serverLevel, pos, random);
|
|
}
|
|
case "loot" -> {
|
|
// TODO: Place loot chest
|
|
}
|
|
default -> {
|
|
TiedUpMod.LOGGER.debug(
|
|
"[KidnapperCampPiece] Unknown data marker: {} at {}",
|
|
marker,
|
|
pos.toShortString()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Spawn a kidnapper at the given position.
|
|
*
|
|
* @param level The server level
|
|
* @param pos Position to spawn at
|
|
* @param random Random source
|
|
* @param elite Whether to spawn an elite kidnapper
|
|
*/
|
|
private void spawnKidnapper(
|
|
ServerLevel level,
|
|
BlockPos pos,
|
|
RandomSource random,
|
|
boolean elite
|
|
) {
|
|
EntityKidnapper kidnapper;
|
|
|
|
if (elite) {
|
|
kidnapper = ModEntities.KIDNAPPER_ELITE.get().create(level);
|
|
} else {
|
|
kidnapper = ModEntities.KIDNAPPER.get().create(level);
|
|
}
|
|
|
|
if (kidnapper != null) {
|
|
kidnapper.moveTo(
|
|
pos.getX() + 0.5,
|
|
pos.getY(),
|
|
pos.getZ() + 0.5,
|
|
random.nextFloat() * 360F,
|
|
0.0F
|
|
);
|
|
kidnapper.finalizeSpawn(
|
|
level,
|
|
level.getCurrentDifficultyAt(pos),
|
|
MobSpawnType.STRUCTURE,
|
|
null,
|
|
null
|
|
);
|
|
level.addFreshEntity(kidnapper);
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[KidnapperCampPiece] Spawned {} at {} from data marker",
|
|
elite ? "elite kidnapper" : "kidnapper",
|
|
pos.toShortString()
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Spawn a slave trader at the given position.
|
|
* Creates/updates the camp data in CampOwnership.
|
|
*
|
|
* @param level The server level
|
|
* @param pos Position to spawn at
|
|
* @param random Random source
|
|
*/
|
|
private void spawnSlaveTrader(
|
|
ServerLevel level,
|
|
BlockPos pos,
|
|
RandomSource random
|
|
) {
|
|
EntitySlaveTrader trader = ModEntities.SLAVE_TRADER.get().create(level);
|
|
if (trader == null) {
|
|
TiedUpMod.LOGGER.warn(
|
|
"[KidnapperCampPiece] Failed to create SlaveTrader entity"
|
|
);
|
|
return;
|
|
}
|
|
|
|
trader.moveTo(
|
|
pos.getX() + 0.5,
|
|
pos.getY(),
|
|
pos.getZ() + 0.5,
|
|
random.nextFloat() * 360F,
|
|
0.0F
|
|
);
|
|
trader.finalizeSpawn(
|
|
level,
|
|
level.getCurrentDifficultyAt(pos),
|
|
MobSpawnType.STRUCTURE,
|
|
null,
|
|
null
|
|
);
|
|
|
|
// Create or get the camp in CampOwnership registry
|
|
CampOwnership registry = CampOwnership.get(level);
|
|
CampOwnership.CampData camp = registry.findNearestAliveCamp(pos, 50);
|
|
|
|
if (camp == null) {
|
|
// Create a new camp
|
|
UUID campId = UUID.randomUUID();
|
|
registry.registerCamp(campId, trader.getUUID(), null, pos);
|
|
camp = registry.getCamp(campId);
|
|
} else {
|
|
// Update existing camp with this trader
|
|
camp.setTraderUUID(trader.getUUID());
|
|
camp.setCenter(pos);
|
|
registry.setDirty();
|
|
}
|
|
|
|
// Link trader to camp
|
|
if (camp != null) {
|
|
trader.setCampUUID(camp.getCampId());
|
|
this.currentCamp = camp;
|
|
}
|
|
|
|
// Store for maid linking
|
|
this.spawnedTraderUUID = trader.getUUID();
|
|
|
|
level.addFreshEntity(trader);
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[KidnapperCampPiece] Spawned slave trader {} at {} from data marker, camp={}",
|
|
trader.getNpcName(),
|
|
pos.toShortString(),
|
|
camp != null ? camp.getCampId().toString().substring(0, 8) : "null"
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Spawn a maid at the given position.
|
|
* Must be called AFTER trader spawns to establish link.
|
|
*
|
|
* @param level The server level
|
|
* @param pos Position to spawn at
|
|
* @param random Random source
|
|
*/
|
|
private void spawnMaid(
|
|
ServerLevel level,
|
|
BlockPos pos,
|
|
RandomSource random
|
|
) {
|
|
EntityMaid maid = ModEntities.MAID.get().create(level);
|
|
if (maid == null) {
|
|
TiedUpMod.LOGGER.warn(
|
|
"[KidnapperCampPiece] Failed to create Maid entity"
|
|
);
|
|
return;
|
|
}
|
|
|
|
maid.moveTo(
|
|
pos.getX() + 0.5,
|
|
pos.getY(),
|
|
pos.getZ() + 0.5,
|
|
random.nextFloat() * 360F,
|
|
0.0F
|
|
);
|
|
maid.finalizeSpawn(
|
|
level,
|
|
level.getCurrentDifficultyAt(pos),
|
|
MobSpawnType.STRUCTURE,
|
|
null,
|
|
null
|
|
);
|
|
|
|
// Link to trader (must be spawned after trader)
|
|
boolean linkedSuccessfully = false;
|
|
|
|
if (this.spawnedTraderUUID != null) {
|
|
maid.setMasterTraderUUID(this.spawnedTraderUUID);
|
|
|
|
// Find the trader entity and update its maid reference
|
|
Entity traderEntity = level.getEntity(this.spawnedTraderUUID);
|
|
if (traderEntity instanceof EntitySlaveTrader trader) {
|
|
trader.setMaidUUID(maid.getUUID());
|
|
linkedSuccessfully = true;
|
|
|
|
TiedUpMod.LOGGER.debug(
|
|
"[KidnapperCampPiece] Linked maid {} to trader {}",
|
|
maid.getNpcName(),
|
|
trader.getNpcName()
|
|
);
|
|
}
|
|
|
|
// Link maid to camp
|
|
if (this.currentCamp != null) {
|
|
this.currentCamp.setMaidUUID(maid.getUUID());
|
|
CampOwnership.get(level).setDirty();
|
|
}
|
|
}
|
|
|
|
// Fallback: If no trader link established, search for nearby trader/camp
|
|
if (!linkedSuccessfully) {
|
|
TiedUpMod.LOGGER.debug(
|
|
"[KidnapperCampPiece] Maid at {} - no direct trader link, searching nearby...",
|
|
pos.toShortString()
|
|
);
|
|
|
|
// Try to find a nearby camp first
|
|
CampOwnership registry = CampOwnership.get(level);
|
|
CampOwnership.CampData camp = registry.findNearestAliveCamp(
|
|
pos,
|
|
50
|
|
);
|
|
|
|
if (camp != null && camp.getTraderUUID() != null) {
|
|
// Found a camp with a trader - link to it
|
|
maid.setMasterTraderUUID(camp.getTraderUUID());
|
|
camp.setMaidUUID(maid.getUUID());
|
|
registry.setDirty();
|
|
|
|
// Try to update the trader entity too
|
|
Entity traderEntity = level.getEntity(camp.getTraderUUID());
|
|
if (traderEntity instanceof EntitySlaveTrader trader) {
|
|
trader.setMaidUUID(maid.getUUID());
|
|
linkedSuccessfully = true;
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[KidnapperCampPiece] Maid {} linked to trader {} via camp fallback",
|
|
maid.getNpcName(),
|
|
trader.getNpcName()
|
|
);
|
|
}
|
|
}
|
|
|
|
// Last resort: search for nearby trader entities
|
|
if (!linkedSuccessfully) {
|
|
java.util.List<EntitySlaveTrader> nearbyTraders =
|
|
level.getEntitiesOfClass(
|
|
EntitySlaveTrader.class,
|
|
maid.getBoundingBox().inflate(50)
|
|
);
|
|
|
|
if (!nearbyTraders.isEmpty()) {
|
|
EntitySlaveTrader trader = nearbyTraders.get(0);
|
|
maid.setMasterTraderUUID(trader.getUUID());
|
|
trader.setMaidUUID(maid.getUUID());
|
|
linkedSuccessfully = true;
|
|
|
|
// Update camp if trader has one
|
|
if (trader.getCampUUID() != null) {
|
|
CampOwnership.CampData traderCamp = registry.getCamp(
|
|
trader.getCampUUID()
|
|
);
|
|
if (traderCamp != null) {
|
|
traderCamp.setMaidUUID(maid.getUUID());
|
|
registry.setDirty();
|
|
}
|
|
}
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[KidnapperCampPiece] Maid {} linked to nearby trader {} via entity search fallback",
|
|
maid.getNpcName(),
|
|
trader.getNpcName()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!linkedSuccessfully) {
|
|
TiedUpMod.LOGGER.warn(
|
|
"[KidnapperCampPiece] Maid spawned at {} but no trader found! Maid will be orphaned.",
|
|
pos.toShortString()
|
|
);
|
|
}
|
|
|
|
level.addFreshEntity(maid);
|
|
|
|
TiedUpMod.LOGGER.info(
|
|
"[KidnapperCampPiece] Spawned maid {} at {} from data marker, linked to trader={}",
|
|
maid.getNpcName(),
|
|
pos.toShortString(),
|
|
this.spawnedTraderUUID != null
|
|
? this.spawnedTraderUUID.toString().substring(0, 8)
|
|
: "null"
|
|
);
|
|
}
|
|
}
|