API重构工作 #2 完成DataAPI重构统一

This commit is contained in:
叁玖领域 2025-10-18 01:52:45 +08:00
parent 8d5b91e54a
commit f8e1376a6c
5 changed files with 432 additions and 40 deletions

View File

@ -31,6 +31,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
@ -51,6 +52,7 @@ import net.minecraftforge.fml.event.config.ModConfigEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import top.r3944realms.superleadrope.api.SuperLeadRopeApi; import top.r3944realms.superleadrope.api.SuperLeadRopeApi;
import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo; import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
import top.r3944realms.superleadrope.config.LeashCommonConfig; import top.r3944realms.superleadrope.config.LeashCommonConfig;
import top.r3944realms.superleadrope.config.LeashConfigManager; import top.r3944realms.superleadrope.config.LeashConfigManager;
@ -269,8 +271,10 @@ public class CommonEventHandler {
entities.forEach(entity -> LeashDataInnerAPI.LeashOperations.detach(entity, telEntity)); entities.forEach(entity -> LeashDataInnerAPI.LeashOperations.detach(entity, telEntity));
return; return;
} }
for (Entity beLeashedEntity : entities) { for (Entity beLeashedEntity : entities) {
// --- 保存状态快照 --- // --- 保存状态快照 ---
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.teleportWithHolder(beLeashedEntity, telEntity, beLeashedEntity.level(), level, beLeashedEntity.position(), targetPos))) continue;
Pose originalPose = beLeashedEntity.getPose(); Pose originalPose = beLeashedEntity.getPose();
boolean originalIsSprinting = beLeashedEntity.isSprinting(); boolean originalIsSprinting = beLeashedEntity.isSprinting();
float originalYaw = beLeashedEntity.getYRot(); float originalYaw = beLeashedEntity.getYRot();
@ -290,7 +294,6 @@ public class CommonEventHandler {
// --- 解除骑乘 --- // --- 解除骑乘 ---
List<Entity> allPassengers = RidingFinder.getEntityFromRidingShip(originalRidingRelationship, serverLevel::getEntity); List<Entity> allPassengers = RidingFinder.getEntityFromRidingShip(originalRidingRelationship, serverLevel::getEntity);
RidingDismounts.dismountEntities(allPassengers); RidingDismounts.dismountEntities(allPassengers);
// --- 传送实体及乘客 --- // --- 传送实体及乘客 ---
for (Entity entity : allPassengers) { for (Entity entity : allPassengers) {
if (entity.level() != serverLevel) { if (entity.level() != serverLevel) {

View File

@ -15,12 +15,23 @@
package top.r3944realms.superleadrope.api.event; package top.r3944realms.superleadrope.api.event;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.eventbus.api.Cancelable; import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.event.IModBusEvent; import net.minecraftforge.fml.event.IModBusEvent;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import top.r3944realms.superleadrope.api.type.capabilty.LeashHolder;
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@SuppressWarnings("unused")
public abstract class SuperLeadRopeEvent extends Event implements IModBusEvent { public abstract class SuperLeadRopeEvent extends Event implements IModBusEvent {
private final Entity LeashedEntity; private final Entity LeashedEntity;
@ -31,7 +42,8 @@ public abstract class SuperLeadRopeEvent extends Event implements IModBusEvent {
public Entity getLeashedEntity() { public Entity getLeashedEntity() {
return LeashedEntity; return LeashedEntity;
} }
// ADD LEASH
@SuppressWarnings("unused")
@Cancelable @Cancelable
public static class AddLeash extends SuperLeadRopeEvent { public static class AddLeash extends SuperLeadRopeEvent {
private final Entity holderEntity; private final Entity holderEntity;
@ -39,11 +51,14 @@ public abstract class SuperLeadRopeEvent extends Event implements IModBusEvent {
private final Double maxLeashDistance; private final Double maxLeashDistance;
@Nullable @Nullable
private final Double elasticDistanceScale; private final Double elasticDistanceScale;
protected AddLeash(Entity leashedEntity, Entity holderEntity) { public AddLeash(Entity leashedEntity, Entity holderEntity) {
this(leashedEntity, holderEntity, null, null);
}
public AddLeash(Entity leashedEntity, Entity holderEntity, @Nullable Double maxLeashDistance, @Nullable Double elasticDistanceScale) {
super(leashedEntity); super(leashedEntity);
this.holderEntity = holderEntity; this.holderEntity = holderEntity;
this.maxLeashDistance = null; this.maxLeashDistance = maxLeashDistance;
this.elasticDistanceScale = null; this.elasticDistanceScale = elasticDistanceScale;
} }
public Entity getHolderEntity() { public Entity getHolderEntity() {
return holderEntity; return holderEntity;
@ -55,19 +70,218 @@ public abstract class SuperLeadRopeEvent extends Event implements IModBusEvent {
return elasticDistanceScale; return elasticDistanceScale;
} }
} }
// ADD LEASH // REMOVE LEASH
@SuppressWarnings("unused")
@Cancelable
public static class RemoveLeash extends SuperLeadRopeEvent {
private final LeashHolder leashHolder;
public RemoveLeash(Entity leashedEntity, UUID holderEntity) {
this(leashedEntity, holderEntity, null, false);
}
public RemoveLeash(Entity leashedEntity, BlockPos holderKnot) {
this(leashedEntity, null, holderKnot, true);
}
private RemoveLeash(Entity leashedEntity, @Nullable UUID holderEntity, @Nullable BlockPos holderPos, boolean isSuperLeadRopeKnot) {
super(leashedEntity);
if (isSuperLeadRopeKnot) {
leashHolder = new LeashHolder(holderPos);
} else leashHolder = new LeashHolder(holderEntity);
}
public LeashHolder getLeashHolder() {
return leashHolder;
}
}
// TRANSFORM LEASH // TRANSFORM LEASH
@SuppressWarnings("unused")
@Cancelable
public static class TransferLeash extends SuperLeadRopeEvent {
private final LeashHolder oldLeashHolder;
private final Entity newLeashHolder;
public TransferLeash(Entity leashedEntity, UUID holderEntity, Entity newLeashHolder) {
this(leashedEntity, holderEntity, null, false , newLeashHolder);
}
public TransferLeash(Entity leashedEntity, BlockPos holderKnot, Entity newLeashHolder) {
this(leashedEntity, null, holderKnot, true, newLeashHolder);
}
private TransferLeash(Entity leashedEntity, @Nullable UUID holderEntity, @Nullable BlockPos holderPos, boolean isSuperLeadRopeKnot, Entity newLeashHolder) {
super(leashedEntity);
if (isSuperLeadRopeKnot) {
oldLeashHolder = new LeashHolder(holderPos);
} else oldLeashHolder = new LeashHolder(holderEntity);
this.newLeashHolder = newLeashHolder;
}
// REMOVE LEASH public Entity getNewLeashHolder() {
return newLeashHolder;
}
public LeashHolder getOldLeashHolder() {
return oldLeashHolder;
}
}
// MODIFY LEASH MAX_LEASH_LENGTH / ELASTIC_DISTANCE_SCALE // MODIFY LEASH MAX_LEASH_LENGTH / ELASTIC_DISTANCE_SCALE
@SuppressWarnings("unused")
@Cancelable
public static class ModifyValue extends SuperLeadRopeEvent {
@Nullable
private final LeashHolder holder;
@Nullable
private final Double oldValue;
@Nullable
private final Double newValue;
private final Type type;
private final Scope scope;
public enum Type {
MAX_DISTANCE,
ELASTIC_DISTANCE_SCALE,
}
public enum Scope {
STATIC,
INSTANCE
}
public ModifyValue(Entity leashedEntity, UUID holderUUID, @Nullable Double oldValue, @Nullable Double newValue, Type type) {
super(leashedEntity);
this.holder = new LeashHolder(holderUUID);
this.oldValue = oldValue;
this.newValue = newValue;
this.type = type;
this.scope = Scope.INSTANCE;
}
public ModifyValue(Entity leashedEntity, BlockPos knotBlockpos, @Nullable Double oldValue, @Nullable Double newValue, Type type) {
super(leashedEntity);
this.holder = new LeashHolder(knotBlockpos);
this.oldValue = oldValue;
this.newValue = newValue;
this.type = type;
this.scope = Scope.INSTANCE;
}
public ModifyValue(Entity leashedEntity, @Nullable Double oldValue, @Nullable Double newValue, Type type) {
super(leashedEntity);
this.holder = null;
this.oldValue = oldValue;
this.newValue = newValue;
this.type = type;
this.scope = Scope.STATIC;
}
public @Nullable LeashHolder getHolder() {
return holder;
}
public @Nullable Double getOldValue() {
return oldValue;
}
public @Nullable Double getNewValue() {
return newValue;
}
public Type getType() {
return type;
}
public Scope getScope() {
return scope;
}
}
// HAS FOCUS // HAS FOCUS
@SuppressWarnings("unused")
@Cancelable
public static class hasFocus extends SuperLeadRopeEvent {
private final Map<UUID, LeashInfo> vaildLeashHolders ;
private final Map<BlockPos, LeashInfo> vaildLeashKnots;
private final Entity finalForceTarget;
private Vec3 combinedForce;
public hasFocus(Entity leashedEntity, Entity finalForceTarget, Vec3 combinedForce, Map<UUID, LeashInfo> vaildLeashHolders, Map<BlockPos, LeashInfo> vaildLeashKnots) {
super(leashedEntity);
this.finalForceTarget = finalForceTarget;
this.combinedForce = combinedForce;
this.vaildLeashHolders = new HashMap<>(vaildLeashHolders);
this.vaildLeashKnots = new HashMap<>(vaildLeashKnots);
}
public Entity getFinalForceTarget() {
return finalForceTarget;
}
public Vec3 getCombinedForce() {
return combinedForce;
}
public void setCombinedForce(Vec3 combinedForce) {
this.combinedForce = combinedForce;
}
public Map<UUID, LeashInfo> getVaildLeashHolders() {
return vaildLeashHolders;
}
public Map<BlockPos, LeashInfo> getVaildLeashKnots() {
return vaildLeashKnots;
}
}
// KEEP NOT BREAK TICK // KEEP NOT BREAK TICK
@SuppressWarnings("unused")
public static class keepNotBreakTick extends SuperLeadRopeEvent {
private final int remainedTicks;
private final Entity holderEntity;
private final Map.Entry<?, LeashInfo> entry;
public keepNotBreakTick(Entity leashedEntity, int remainedTicks, Entity holderEntity, Map.Entry<?, LeashInfo> entry) {
super(leashedEntity);
this.remainedTicks = remainedTicks;
this.holderEntity = holderEntity;
this.entry = entry;
}
public Entity getHolderEntity() {
return holderEntity;
}
public int getRemainedTicks() {
return remainedTicks;
}
public void resetRemainedTicks() {
entry.setValue(entry.getValue().resetKeepTicks());
}
public int getMaxKeepTicks() {
return entry.getValue().maxKeepLeashTicks();
}
}
// TELEPORT // TELEPORT
@Cancelable
@SuppressWarnings("unused")
public static class teleportWithHolder extends SuperLeadRopeEvent {
private final Entity holderEntity;
private final Level originalLevel, newLevel;
private final Vec3 originalPosition, newPosition;
public teleportWithHolder(Entity leashedEntity, Entity holderEntity, Level originalLevel, Level newLevel, Vec3 originalPosition, Vec3 newPosition) {
super(leashedEntity);
this.holderEntity = holderEntity;
this.originalLevel = originalLevel;
this.newLevel = newLevel;
this.originalPosition = originalPosition;
this.newPosition = newPosition;
}
public Entity getHolderEntity() {
return holderEntity;
}
public Vec3 getOriginalPosition() {
return originalPosition;
}
public Level getOriginalLevel() {
return originalLevel;
}
public Level getNewLevel() {
return newLevel;
}
public Vec3 getNewPosition() {
return newPosition;
}
}
} }

View File

@ -0,0 +1,30 @@
/*
* Super Lead rope mod
* Copyright (C) 2025 R3944Realms
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package top.r3944realms.superleadrope.api.type.capabilty;
import net.minecraft.core.BlockPos;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public record LeashHolder(@Nullable UUID holderUUID, @Nullable BlockPos knotPos, boolean isKnot) {
public LeashHolder(UUID holderUUID) {
this (holderUUID, null, false);
}
public LeashHolder(BlockPos knotPos) {
this(null, knotPos, true);
}
}

View File

@ -25,12 +25,15 @@ import top.r3944realms.superleadrope.SuperLeadRope;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import static top.r3944realms.superleadrope.config.LeashCommonConfig.Common.OFFSET_PATTERN; import static top.r3944realms.superleadrope.config.LeashCommonConfig.Common.OFFSET_PATTERN;
public class LeashConfigManager { public class LeashConfigManager {
// ========== 最值检测 ==========
public static final Predicate<Double> MAX_DISTANCE_CHECK = distance -> distance == null || (distance >= 6.0 && distance <= 256.0);
public static final Predicate<Double> ELASTIC_DISTANCE_CHECK = distance -> distance == null || (distance >= 0.2 && distance <= 4.0);
// ========== 偏移映射 ========== // ========== 偏移映射 ==========
private final Map<String, double[]> entityHolderMap = new ConcurrentHashMap<>(); private final Map<String, double[]> entityHolderMap = new ConcurrentHashMap<>();
private final Map<String, double[]> tagHolderMap = new ConcurrentHashMap<>(); private final Map<String, double[]> tagHolderMap = new ConcurrentHashMap<>();

View File

@ -33,6 +33,7 @@ import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.loading.FMLEnvironment; import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PacketDistributor;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
@ -40,9 +41,11 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import top.r3944realms.superleadrope.CommonEventHandler; import top.r3944realms.superleadrope.CommonEventHandler;
import top.r3944realms.superleadrope.SuperLeadRope; import top.r3944realms.superleadrope.SuperLeadRope;
import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent;
import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo; import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo;
import top.r3944realms.superleadrope.compat.CurtainCompat; import top.r3944realms.superleadrope.compat.CurtainCompat;
import top.r3944realms.superleadrope.api.type.capabilty.ILeashData; import top.r3944realms.superleadrope.api.type.capabilty.ILeashData;
import top.r3944realms.superleadrope.config.LeashConfigManager;
import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity; import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity;
import top.r3944realms.superleadrope.core.register.SLPSoundEvents; import top.r3944realms.superleadrope.core.register.SLPSoundEvents;
import top.r3944realms.superleadrope.network.NetworkHandler; import top.r3944realms.superleadrope.network.NetworkHandler;
@ -68,24 +71,25 @@ import java.util.stream.Stream;
* </thead> * </thead>
* <tbody> * <tbody>
* <tr> * <tr>
* <th>距离 maxDistance</th> * <th>距离 maxDistance * elasticDistanceScale</th>
* <th>正常弹性拉力重置 keepLeashTicks 为最大值</th> * <th>正常弹性拉力重置 keepLeashTicks 为最大值</th>
* </tr> * </tr>
* <tr> * <tr>
* <th>maxDistance < distance 2*maxDistance</th> * <th>maxDistance * elasticDistanceScale < distance 配置extremeSnapFactor * maxDistance * elasticDistanceScale</th>
* <th>增强拉力并减少 keepLeashTicks每Tick减1</th> * <th>增强拉力并减少 keepLeashTicks每Tick减1</th>
* </tr> * </tr>
* <tr> * <tr>
* <th>distance > 2*maxDistance && keepLeashTicks > 0</th> * <th>distance > 配置extremeSnapFactor * maxDistance * elasticDistanceScale && keepLeashTicks > 0</th>
* <th>施加更强拉力并减少Tick</th> * <th>施加更强拉力并减少Tick</th>
* </tr> * </tr>
* <tr> * <tr>
* <th>distance > 2*maxDistance && keepLeashTicks == 0</th> * <th>distance > 配置extremeSnapFactor * maxDistance * elasticDistanceScale && keepLeashTicks == 0</th>
* <th>立即断裂</th> * <th>立即断裂</th>
* </tr> * </tr>
* </tbody> * </tbody>
* </table> * </table>
*/ */
@SuppressWarnings("DuplicatedCode")
public class LeashDataImpl implements ILeashData { public class LeashDataImpl implements ILeashData {
private final Entity entity; private final Entity entity;
private boolean needsSync = false; private boolean needsSync = false;
@ -157,6 +161,8 @@ public class LeashDataImpl implements ILeashData {
@Override @Override
public void setStaticMaxDistance(@Nullable Double distance) { public void setStaticMaxDistance(@Nullable Double distance) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(distance)) return;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, getStaticMaxDistance(), distance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return;
staticMaxDistance = distance; staticMaxDistance = distance;
} }
@ -178,14 +184,15 @@ public class LeashDataImpl implements ILeashData {
public void updateAllMaxDistance() { public void updateAllMaxDistance() {
leashHolders.forEach((uuid, leashInfo) -> { leashHolders.forEach((uuid, leashInfo) -> {
if (leashInfo.isNeedUpdateDistance()) { if (leashInfo.isNeedUpdateDistance()) {
setMaxDistance(uuid, getCurrentMaxDistance()); setMaxDistanceInner(uuid, getCurrentMaxDistance());
} }
}); });
leashKnots.forEach((blockPos, leashInfo) -> { leashKnots.forEach((blockPos, leashInfo) -> {
if (leashInfo.isNeedUpdateDistance()) { if (leashInfo.isNeedUpdateDistance()) {
setMaxDistance(blockPos, getCurrentMaxDistance()); setMaxDistanceInner(blockPos, getCurrentMaxDistance());
} }
}); });
markForSync();
} }
@Override @Override
@ -194,8 +201,10 @@ public class LeashDataImpl implements ILeashData {
} }
@Override @Override
public void setStaticElasticDistanceScale(@Nullable Double distance) { public void setStaticElasticDistanceScale(@Nullable Double scale) {
staticElasticDistanceScale = distance; if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, getStaticElasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return;
staticElasticDistanceScale = scale;
} }
@Override @Override
@ -216,14 +225,15 @@ public class LeashDataImpl implements ILeashData {
public void updateAllElasticDistanceScale() { public void updateAllElasticDistanceScale() {
leashHolders.forEach((uuid, leashInfo) -> { leashHolders.forEach((uuid, leashInfo) -> {
if (leashInfo.isNeedUpdateScale()) { if (leashInfo.isNeedUpdateScale()) {
setElasticDistanceScale(uuid, getCurrentElasticDistanceScale()); setElasticDistanceScaleInner(uuid, getCurrentElasticDistanceScale());
} }
}); });
leashKnots.forEach((blockPos, leashInfo) -> { leashKnots.forEach((blockPos, leashInfo) -> {
if (leashInfo.isNeedUpdateScale()) { if (leashInfo.isNeedUpdateScale()) {
setElasticDistanceScale(blockPos, getCurrentMaxDistance()); setElasticDistanceScaleInner(blockPos, getCurrentMaxDistance());
} }
}); });
markForSync();
} }
@Override @Override
@ -273,7 +283,8 @@ public class LeashDataImpl implements ILeashData {
|| (isSuperKnot && leashKnots.containsKey(((SuperLeashKnotEntity) holder).getPos()))) { || (isSuperKnot && leashKnots.containsKey(((SuperLeashKnotEntity) holder).getPos()))) {
return false; return false;
} }
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(maxDistance) || !LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(elasticDistanceScale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.AddLeash(holder, this.entity, maxDistance, elasticDistanceScale))) return false;
if (!canBeLeashed()) { if (!canBeLeashed()) {
Optional<UUID> uuidOptional = occupyLeash(); Optional<UUID> uuidOptional = occupyLeash();
if (uuidOptional.isEmpty()) { if (uuidOptional.isEmpty()) {
@ -338,6 +349,20 @@ public class LeashDataImpl implements ILeashData {
return true; return true;
} }
private <K> void updateLeashInfoInner(
@NotNull Map<K, LeashInfo> map,
K key,
Function<LeashInfo, LeashInfo> updater
) {
LeashInfo old = map.get(key);
if (old == null || old.holderIdOpt().isEmpty()) return;
LeashInfo updated = updater.apply(old);
if (updated == null) return;
map.put(key, updated);
}
@Override @Override
public boolean setMaxDistance(Entity holder, @Nullable Double newMaxDistance) { public boolean setMaxDistance(Entity holder, @Nullable Double newMaxDistance) {
return holder instanceof SuperLeashKnotEntity superLeashKnotEntity ? return holder instanceof SuperLeashKnotEntity superLeashKnotEntity ?
@ -353,15 +378,17 @@ public class LeashDataImpl implements ILeashData {
} }
@Override @Override
public boolean setMaxDistance(Entity holder, @Nullable Double distance, int maxKeepTicks, String reserved) { public boolean setMaxDistance(Entity holder, @Nullable Double newMaxDistance, int maxKeepTicks, String reserved) {
return holder instanceof SuperLeashKnotEntity superLeashKnotEntity ? return holder instanceof SuperLeashKnotEntity superLeashKnotEntity ?
setMaxDistance(superLeashKnotEntity.getPos(), distance, maxKeepTicks, reserved) : setMaxDistance(superLeashKnotEntity.getPos(), newMaxDistance, maxKeepTicks, reserved) :
setMaxDistance(holder.getUUID(), distance, maxKeepTicks, reserved); setMaxDistance(holder.getUUID(), newMaxDistance, maxKeepTicks, reserved);
} }
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setMaxDistance(UUID holderUUID, @Nullable Double newMaxDistance) { public boolean setMaxDistance(UUID holderUUID, @Nullable Double newMaxDistance) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return false;
return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo( return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(), old.holderUUIDOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -373,10 +400,27 @@ public class LeashDataImpl implements ILeashData {
old.maxKeepLeashTicks() old.maxKeepLeashTicks()
)); ));
} }
@SuppressWarnings("OptionalGetWithoutIsPresent")
public void setMaxDistanceInner(UUID holderUUID, @Nullable Double newMaxDistance) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return;
updateLeashInfoInner(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(),
old.holderIdOpt().get(),
old.marks(),
old.reserved(),
newMaxDistance,
old.elasticDistanceScale(),
old.keepLeashTicks(),
old.maxKeepLeashTicks()
));
}
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setMaxDistance(UUID holderUUID, @Nullable Double newMaxDistance, int newMaxKeepLeashTicks) { public boolean setMaxDistance(UUID holderUUID, @Nullable Double newMaxDistance, int newMaxKeepLeashTicks) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return false;
return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo( return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(), old.holderUUIDOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -391,13 +435,15 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setMaxDistance(UUID holderUUID, @Nullable Double distance, int maxKeepTicks, String reserved) { public boolean setMaxDistance(UUID holderUUID, @Nullable Double newMaxDistance, int maxKeepTicks, String reserved) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return false;
return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo( return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(), old.holderUUIDOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
old.marks(), old.marks(),
reserved, reserved,
distance, newMaxDistance,
old.elasticDistanceScale(), old.elasticDistanceScale(),
Math.min(old.keepLeashTicks(), maxKeepTicks), Math.min(old.keepLeashTicks(), maxKeepTicks),
maxKeepTicks maxKeepTicks
@ -407,6 +453,8 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setMaxDistance(BlockPos knotPos, @Nullable Double newMaxDistance) { public boolean setMaxDistance(BlockPos knotPos, @Nullable Double newMaxDistance) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return false;
return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo( return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(), old.blockPosOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -419,9 +467,27 @@ public class LeashDataImpl implements ILeashData {
)); ));
} }
@SuppressWarnings("OptionalGetWithoutIsPresent")
public void setMaxDistanceInner(BlockPos knotPos, @Nullable Double newMaxDistance) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return;
updateLeashInfoInner(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(),
old.holderIdOpt().get(),
old.marks(),
old.reserved(),
newMaxDistance,
old.elasticDistanceScale(),
old.keepLeashTicks(),
old.maxKeepLeashTicks()
));
}
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setMaxDistance(BlockPos knotPos, @Nullable Double newMaxDistance, int newMaxKeepLeashTicks) { public boolean setMaxDistance(BlockPos knotPos, @Nullable Double newMaxDistance, int newMaxKeepLeashTicks) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return false;
return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo( return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(), old.blockPosOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -436,13 +502,15 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setMaxDistance(BlockPos knotPos, @Nullable Double distance, int maxKeepTicks, String reserved) { public boolean setMaxDistance(BlockPos knotPos, @Nullable Double newMaxDistance, int maxKeepTicks, String reserved) {
if (!LeashConfigManager.MAX_DISTANCE_CHECK.test(newMaxDistance)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).maxDistance(), newMaxDistance, SuperLeadRopeEvent.ModifyValue.Type.MAX_DISTANCE))) return false;
return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo( return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(), old.blockPosOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
old.marks(), old.marks(),
reserved, reserved,
distance, newMaxDistance,
old.elasticDistanceScale(), old.elasticDistanceScale(),
Math.min(old.keepLeashTicks(), maxKeepTicks), Math.min(old.keepLeashTicks(), maxKeepTicks),
maxKeepTicks maxKeepTicks
@ -460,6 +528,8 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setElasticDistanceScale(UUID holderUUID, @Nullable Double scale) { public boolean setElasticDistanceScale(UUID holderUUID, @Nullable Double scale) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return false;
return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo( return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(), old.holderUUIDOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -471,10 +541,27 @@ public class LeashDataImpl implements ILeashData {
old.maxKeepLeashTicks() old.maxKeepLeashTicks()
)); ));
} }
@SuppressWarnings("OptionalGetWithoutIsPresent")
public void setElasticDistanceScaleInner(UUID holderUUID, @Nullable Double scale) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return;
updateLeashInfoInner(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(),
old.holderIdOpt().get(),
old.marks(),
old.reserved(),
old.maxDistance(),
scale,
old.keepLeashTicks(),
old.maxKeepLeashTicks()
));
}
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setElasticDistanceScale(BlockPos knotPos, @Nullable Double scale) { public boolean setElasticDistanceScale(BlockPos knotPos, @Nullable Double scale) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return false;
return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo( return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(), old.blockPosOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -486,6 +573,21 @@ public class LeashDataImpl implements ILeashData {
old.maxKeepLeashTicks() old.maxKeepLeashTicks()
)); ));
} }
@SuppressWarnings("OptionalGetWithoutIsPresent")
public void setElasticDistanceScaleInner(BlockPos knotPos, @Nullable Double scale) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return;
updateLeashInfoInner(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(),
old.holderIdOpt().get(),
old.marks(),
old.reserved(),
old.maxDistance(),
scale,
old.keepLeashTicks(),
old.maxKeepLeashTicks()
));
}
@Override @Override
public boolean setElasticDistanceScale(Entity holder, @Nullable Double scale, int newMaxKeepLeashTicks) { public boolean setElasticDistanceScale(Entity holder, @Nullable Double scale, int newMaxKeepLeashTicks) {
@ -505,6 +607,8 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setElasticDistanceScale(UUID holderUUID, @Nullable Double scale, int newMaxKeepLeashTicks) { public boolean setElasticDistanceScale(UUID holderUUID, @Nullable Double scale, int newMaxKeepLeashTicks) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return false;
return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo( return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(), old.holderUUIDOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -520,6 +624,8 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setElasticDistanceScale(UUID holderUUID, @Nullable Double scale, int maxKeepTicks, String reserved) { public boolean setElasticDistanceScale(UUID holderUUID, @Nullable Double scale, int maxKeepTicks, String reserved) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, holderUUID, leashHolders.get(holderUUID).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return false;
return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo( return updateLeashInfo(leashHolders, holderUUID, old -> new LeashInfo(
old.holderUUIDOpt().get(), old.holderUUIDOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -535,6 +641,8 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setElasticDistanceScale(BlockPos knotPos, @Nullable Double scale, int newMaxKeepLeashTicks) { public boolean setElasticDistanceScale(BlockPos knotPos, @Nullable Double scale, int newMaxKeepLeashTicks) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return false;
return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo( return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(), old.blockPosOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -550,6 +658,8 @@ public class LeashDataImpl implements ILeashData {
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@Override @Override
public boolean setElasticDistanceScale(BlockPos knotPos, @Nullable Double scale, int newMaxKeepLeashTicks, String reserved) { public boolean setElasticDistanceScale(BlockPos knotPos, @Nullable Double scale, int newMaxKeepLeashTicks, String reserved) {
if (!LeashConfigManager.ELASTIC_DISTANCE_CHECK.test(scale)) return false;
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.ModifyValue(this.entity, knotPos, leashKnots.get(knotPos).elasticDistanceScale(), scale, SuperLeadRopeEvent.ModifyValue.Type.ELASTIC_DISTANCE_SCALE))) return false;
return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo( return updateLeashInfo(leashKnots, knotPos, old -> new LeashInfo(
old.blockPosOpt().get(), old.blockPosOpt().get(),
old.holderIdOpt().get(), old.holderIdOpt().get(),
@ -570,14 +680,16 @@ public class LeashDataImpl implements ILeashData {
Vec3 combinedForce = Vec3.ZERO; Vec3 combinedForce = Vec3.ZERO;
Vec3 combinedDirection = Vec3.ZERO; Vec3 combinedDirection = Vec3.ZERO;
int validLeashes = 0; int validLeashes = 0;
Map<UUID, LeashInfo> vaildLeashHolders = new HashMap<>();
// 1. 计算所有拴绳的合力和平均方向 Map<BlockPos, LeashInfo> vaildLeashKnots = new HashMap<>();
// 计算所有拴绳的合力和平均方向
for (Map.Entry<UUID, LeashInfo> entry : leashHolders.entrySet()) { for (Map.Entry<UUID, LeashInfo> entry : leashHolders.entrySet()) {
Vec3 force = calculateLeashForceForUUID(entry); Vec3 force = calculateLeashForceForUUID(entry);
if (force != null) { if (force != null) {
combinedForce = combinedForce.add(force); combinedForce = combinedForce.add(force);
combinedDirection = combinedDirection.add(force.normalize()); combinedDirection = combinedDirection.add(force.normalize());
validLeashes++; validLeashes++;
vaildLeashHolders.put(entry.getKey(), entry.getValue());
} }
} }
@ -587,13 +699,16 @@ public class LeashDataImpl implements ILeashData {
combinedForce = combinedForce.add(force); combinedForce = combinedForce.add(force);
combinedDirection = combinedDirection.add(force.normalize()); combinedDirection = combinedDirection.add(force.normalize());
validLeashes++; validLeashes++;
vaildLeashKnots.put(entry.getKey(), entry.getValue());
} }
} }
boolean hasForce = !combinedForce.equals(Vec3.ZERO); boolean hasForce = !combinedForce.equals(Vec3.ZERO);
Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce); Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce);
if (targetEntity != null && hasForce) { if (targetEntity != null && hasForce) {
SuperLeadRopeEvent.hasFocus hasFocus = new SuperLeadRopeEvent.hasFocus(this.entity, targetEntity, combinedForce, vaildLeashHolders, vaildLeashKnots);
if (MinecraftForge.EVENT_BUS.post(hasFocus)) return;
combinedForce = hasFocus.getCombinedForce();
// 玩家与普通实体统一力应用 // 玩家与普通实体统一力应用
if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player)) { if (targetEntity instanceof ServerPlayer player && CurtainCompat.isNotFakePlayer(player)) {
RindingLeash.applyForceToPlayer( RindingLeash.applyForceToPlayer(
@ -733,7 +848,7 @@ public class LeashDataImpl implements ILeashData {
} else { } else {
if (!delayedHolders.contains(uuid)) { if (!delayedHolders.contains(uuid)) {
SuperLeadRope.logger.warn("Could not apply leash forces for {}, because it is not found(it will be removed from list).", uuid); SuperLeadRope.logger.warn("Could not apply leash forces for {}, because it is not found(it will be removed from list).", uuid);
leashHolders.remove(uuid); leashHolders.remove(uuid); //保持系统稳定的移除不走事件
} }
return null; return null;
} }
@ -764,6 +879,7 @@ public class LeashDataImpl implements ILeashData {
// 计算临界拉力 // 计算临界拉力
Vec3 pullForce = calculateCriticalPullForce(holderPos, entityPos, distance, maxDistance, elasticLimitDistance); Vec3 pullForce = calculateCriticalPullForce(holderPos, entityPos, distance, maxDistance, elasticLimitDistance);
entry.setValue(info.decrementKeepTicks()); entry.setValue(info.decrementKeepTicks());
MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.keepNotBreakTick(this.entity, entry.getValue().keepLeashTicks(), holder, entry));
return pullForce; return pullForce;
} }
// 断裂 // 断裂
@ -844,6 +960,7 @@ public class LeashDataImpl implements ILeashData {
} }
@Override @Override
public boolean removeLeash(UUID holderUUID) { public boolean removeLeash(UUID holderUUID) {
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.RemoveLeash(this.entity, holderUUID))) return false;
boolean removed = leashHolders.remove(holderUUID) != null; boolean removed = leashHolders.remove(holderUUID) != null;
if (removed) { if (removed) {
LeashStateInnerAPI.Operations.detach(entity, holderUUID); LeashStateInnerAPI.Operations.detach(entity, holderUUID);
@ -852,35 +969,56 @@ public class LeashDataImpl implements ILeashData {
return removed; return removed;
} }
@Override private void removeLeashInner(BlockPos knotPos) {
public boolean removeLeash(BlockPos knotPos) { if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.RemoveLeash(this.entity, knotPos))) return;
boolean removed = leashKnots.remove(knotPos) != null;
if (removed) {
LeashStateInnerAPI.Operations.detach(entity, knotPos);
}
}
private void removeLeashInner(UUID holderUUID) {
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.RemoveLeash(this.entity, holderUUID))) return;
boolean removed = leashHolders.remove(holderUUID) != null;
if (removed) {
LeashStateInnerAPI.Operations.detach(entity, holderUUID);
}
}
@Override
public boolean removeLeash(BlockPos knotPos) {
if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.RemoveLeash(this.entity, knotPos))) return false;
boolean removed = leashKnots.remove(knotPos) != null; boolean removed = leashKnots.remove(knotPos) != null;
if (removed) { if (removed) {
LeashStateInnerAPI.Operations.detach(entity, knotPos); LeashStateInnerAPI.Operations.detach(entity, knotPos);
markForSync();
} }
return removed; return removed;
} }
@Override @Override
public void removeAllLeashes() { public void removeAllLeashes() {
leashHolders.clear(); removeAllHolderLeashesInner();
leashKnots.clear(); removeAllKnotLeashes();
LeashStateInnerAPI.Offset.removeHolderAll(entity);
markForSync(); markForSync();
} }
private void removeAllHolderLeashesInner() {
leashHolders.forEach((uuid, leashHolder) -> removeLeashInner(uuid));
}
private void removeAllKnotLeashesInner() {
leashKnots.forEach((blockPos, leashHolder) -> removeLeashInner(blockPos));
}
@Override @Override
public void removeAllHolderLeashes() { public void removeAllHolderLeashes() {
leashHolders.clear(); removeAllHolderLeashesInner();
LeashStateInnerAPI.Offset.removeAllHolderUUIDs(entity);
markForSync(); markForSync();
} }
@Override @Override
public void removeAllKnotLeashes() { public void removeAllKnotLeashes() {
leashKnots.clear(); removeAllKnotLeashesInner();
LeashStateInnerAPI.Offset.removeAllHolderBlockPoses(entity);
markForSync(); markForSync();
} }
@ -901,6 +1039,7 @@ public class LeashDataImpl implements ILeashData {
// 将拴绳持有者转移到新实体(非拴绳结 -> 任意) // 将拴绳持有者转移到新实体(非拴绳结 -> 任意)
@Override @Override
public boolean transferLeash(UUID oldHolderUUID, Entity newHolder) { public boolean transferLeash(UUID oldHolderUUID, Entity newHolder) {
if(MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.TransferLeash(this.entity, oldHolderUUID, newHolder))) return false;
LeashInfo info = leashHolders.remove(oldHolderUUID); LeashInfo info = leashHolders.remove(oldHolderUUID);
if (info == null || newHolder == null) return false; if (info == null || newHolder == null) return false;
if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) { if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) {
@ -916,6 +1055,7 @@ public class LeashDataImpl implements ILeashData {
} }
@Override @Override
public boolean transferLeash(UUID oldHolderUUID, Entity newHolder, String reserved) { public boolean transferLeash(UUID oldHolderUUID, Entity newHolder, String reserved) {
if(MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.TransferLeash(this.entity, oldHolderUUID, newHolder))) return false;
LeashInfo info = leashHolders.remove(oldHolderUUID); LeashInfo info = leashHolders.remove(oldHolderUUID);
if (info == null || newHolder == null) return false; if (info == null || newHolder == null) return false;
if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) { if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) {
@ -932,6 +1072,7 @@ public class LeashDataImpl implements ILeashData {
@Override @Override
public boolean transferLeash(BlockPos knotPos, Entity newHolder) { public boolean transferLeash(BlockPos knotPos, Entity newHolder) {
if(MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.TransferLeash(this.entity, knotPos, newHolder))) return false;
LeashInfo info = leashKnots.remove(knotPos); LeashInfo info = leashKnots.remove(knotPos);
if (info == null || newHolder == null) return false; if (info == null || newHolder == null) return false;
if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) { if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) {
@ -948,6 +1089,7 @@ public class LeashDataImpl implements ILeashData {
@Override @Override
public boolean transferLeash(BlockPos knotPos, Entity newHolder, String reserved) { public boolean transferLeash(BlockPos knotPos, Entity newHolder, String reserved) {
if(MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.TransferLeash(this.entity, knotPos, newHolder))) return false;
LeashInfo info = leashKnots.remove(knotPos); LeashInfo info = leashKnots.remove(knotPos);
if (info == null || newHolder == null) return false; if (info == null || newHolder == null) return false;
if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) { if(newHolder instanceof SuperLeashKnotEntity superLeashKnotEntity) {