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:
219
src/main/java/com/tiedup/remake/tasks/ForceFeedingTask.java
Normal file
219
src/main/java/com/tiedup/remake/tasks/ForceFeedingTask.java
Normal file
@@ -0,0 +1,219 @@
|
||||
package com.tiedup.remake.tasks;
|
||||
|
||||
import com.tiedup.remake.core.TiedUpMod;
|
||||
import com.tiedup.remake.entities.EntityDamsel;
|
||||
import com.tiedup.remake.network.ModNetwork;
|
||||
import com.tiedup.remake.network.action.PacketForceFeeding;
|
||||
import com.tiedup.remake.state.IBondageState;
|
||||
import com.tiedup.remake.state.PlayerBindState;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
/**
|
||||
* Server-side task for force feeding a gagged entity.
|
||||
* Player must keep looking at the target for 5 seconds to complete.
|
||||
*/
|
||||
public class ForceFeedingTask extends TimedInteractTask {
|
||||
|
||||
private Player feeder;
|
||||
private ItemStack foodStack;
|
||||
private int sourceSlot;
|
||||
|
||||
public ForceFeedingTask(
|
||||
IBondageState targetState,
|
||||
LivingEntity targetEntity,
|
||||
int seconds,
|
||||
Level level,
|
||||
Player feeder,
|
||||
ItemStack foodStack,
|
||||
int sourceSlot
|
||||
) {
|
||||
super(targetState, targetEntity, seconds, level);
|
||||
this.feeder = feeder;
|
||||
this.foodStack = foodStack.copy();
|
||||
this.sourceSlot = sourceSlot;
|
||||
}
|
||||
|
||||
public void setFeeder(Player feeder) {
|
||||
this.feeder = feeder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update() {
|
||||
// Cancel if feeder is gone or dead
|
||||
if (feeder == null || !feeder.isAlive() || feeder.isRemoved()) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetEntity != null) {
|
||||
double distance = feeder.distanceTo(targetEntity);
|
||||
if (distance > 4.0) {
|
||||
TiedUpMod.LOGGER.debug(
|
||||
"[ForceFeedingTask] Feeder {} moved too far from target ({} blocks), cancelling",
|
||||
feeder.getName().getString(),
|
||||
String.format("%.1f", distance)
|
||||
);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!feeder.hasLineOfSight(targetEntity)) {
|
||||
TiedUpMod.LOGGER.debug(
|
||||
"[ForceFeedingTask] Feeder {} lost line of sight to target, cancelling",
|
||||
feeder.getName().getString()
|
||||
);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onComplete() {
|
||||
if (!isTargetValid()) {
|
||||
TiedUpMod.LOGGER.warn(
|
||||
"[ForceFeedingTask] Target entity no longer valid, cancelling task"
|
||||
);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (feeder == null || !feeder.isAlive()) {
|
||||
TiedUpMod.LOGGER.warn(
|
||||
"[ForceFeedingTask] Feeder no longer valid, cancelling task"
|
||||
);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the item in the source slot is still edible
|
||||
ItemStack slotStack = feeder.getInventory().getItem(sourceSlot);
|
||||
if (slotStack.isEmpty() || !slotStack.getItem().isEdible()) {
|
||||
TiedUpMod.LOGGER.warn(
|
||||
"[ForceFeedingTask] Food item no longer in slot {}, cancelling",
|
||||
sourceSlot
|
||||
);
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
TiedUpMod.LOGGER.info(
|
||||
"[ForceFeedingTask] Force feeding complete for {}",
|
||||
targetEntity.getName().getString()
|
||||
);
|
||||
|
||||
if (targetEntity instanceof Player targetPlayer) {
|
||||
// Feed the player using vanilla eat mechanics
|
||||
targetPlayer.eat(targetPlayer.level(), slotStack.copy());
|
||||
slotStack.shrink(1);
|
||||
} else if (targetEntity instanceof EntityDamsel damsel) {
|
||||
// Use existing NPC feed method (handles shrink internally)
|
||||
damsel.feedByPlayer(feeder, slotStack);
|
||||
}
|
||||
|
||||
// Play eating sound at target
|
||||
targetEntity
|
||||
.level()
|
||||
.playSound(
|
||||
null,
|
||||
targetEntity.getX(),
|
||||
targetEntity.getY(),
|
||||
targetEntity.getZ(),
|
||||
SoundEvents.GENERIC_EAT,
|
||||
SoundSource.PLAYERS,
|
||||
1.0F,
|
||||
1.0F
|
||||
);
|
||||
|
||||
// Send messages
|
||||
String targetName = targetEntity.getName().getString();
|
||||
String feederName = feeder.getName().getString();
|
||||
|
||||
if (feeder instanceof ServerPlayer serverFeeder) {
|
||||
serverFeeder.displayClientMessage(
|
||||
Component.literal(
|
||||
"You force fed " + targetName + "."
|
||||
).withStyle(ChatFormatting.GRAY),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
if (targetEntity instanceof ServerPlayer serverTarget) {
|
||||
serverTarget.displayClientMessage(
|
||||
Component.literal("You have been force fed.").withStyle(
|
||||
ChatFormatting.GRAY
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
stop();
|
||||
|
||||
// Send completion packets (stateInfo = -1)
|
||||
if (targetEntity instanceof ServerPlayer serverTarget) {
|
||||
PacketForceFeeding completionPacket = new PacketForceFeeding(
|
||||
-1,
|
||||
this.getMaxSeconds(),
|
||||
false,
|
||||
feederName
|
||||
);
|
||||
ModNetwork.sendToPlayer(completionPacket, serverTarget);
|
||||
}
|
||||
|
||||
if (feeder instanceof ServerPlayer serverFeeder) {
|
||||
PacketForceFeeding completionPacket = new PacketForceFeeding(
|
||||
-1,
|
||||
this.getMaxSeconds(),
|
||||
true,
|
||||
targetName
|
||||
);
|
||||
ModNetwork.sendToPlayer(completionPacket, serverFeeder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendProgressPackets() {
|
||||
if (stopped) return;
|
||||
|
||||
String feederName =
|
||||
feeder != null ? feeder.getName().getString() : "Someone";
|
||||
String targetName = targetEntity.getName().getString();
|
||||
|
||||
// Packet to target (if player): isActiveRole=false, shows feeder's name
|
||||
if (targetEntity instanceof ServerPlayer serverTarget) {
|
||||
PacketForceFeeding victimPacket = new PacketForceFeeding(
|
||||
this.getState(),
|
||||
this.getMaxSeconds(),
|
||||
false,
|
||||
feederName
|
||||
);
|
||||
ModNetwork.sendToPlayer(victimPacket, serverTarget);
|
||||
}
|
||||
|
||||
// Packet to feeder: isActiveRole=true, shows target's name
|
||||
if (feeder instanceof ServerPlayer serverFeeder) {
|
||||
PacketForceFeeding feederPacket = new PacketForceFeeding(
|
||||
this.getState(),
|
||||
this.getMaxSeconds(),
|
||||
true,
|
||||
targetName
|
||||
);
|
||||
ModNetwork.sendToPlayer(feederPacket, serverFeeder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpTargetState() {
|
||||
// Server-side: nothing to do - client handles its own PlayerStateTask via packets
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user