Skip to content

Commit

Permalink
Merge pull request #648
Browse files Browse the repository at this point in the history
* Merge pull request #1 from TartaricAcid/1.20

* Merge remote-tracking branch 'origin/1.20' into 1.20

* maid can ride or stop owner controlledVehicle when owner is riding or…

* fix an issue

* 修正部分问题
  • Loading branch information
Azumic authored Jan 21, 2025
1 parent 7fe376a commit e88eac8
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.github.tartaricacid.touhoulittlemaid.api.mixin;

public interface IPlayerMixin {
boolean tlmInRemoveVehicleCooldown();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.tartaricacid.touhoulittlemaid.entity.ai.brain;

import com.github.tartaricacid.touhoulittlemaid.api.task.IMaidTask;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.MaidFollowOwnerVehicleTask;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.ride.MaidRideBegTask;
import com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task.*;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
Expand Down Expand Up @@ -94,12 +95,13 @@ private static void registerCoreGoals(Brain<EntityMaid> brain) {
Pair<Integer, BehaviorControl<? super EntityMaid>> interactWithDoor = Pair.of(2, MaidInteractWithDoor.create());
Pair<Integer, BehaviorControl<? super EntityMaid>> walkToTarget = Pair.of(2, new MoveToTargetSink());
Pair<Integer, BehaviorControl<? super EntityMaid>> followOwner = Pair.of(3, new MaidFollowOwnerTask(0.5f, 2));
Pair<Integer, BehaviorControl<? super EntityMaid>> followOwnerVehicle = Pair.of(3, new MaidFollowOwnerVehicleTask(0.5f, 2));
Pair<Integer, BehaviorControl<? super EntityMaid>> healSelf = Pair.of(3, new MaidHealSelfTask());
Pair<Integer, BehaviorControl<? super EntityMaid>> pickupItem = Pair.of(10, new MaidPickupEntitiesTask(EntityMaid::isPickup, 0.6f));
Pair<Integer, BehaviorControl<? super EntityMaid>> clearSleep = Pair.of(99, new MaidClearSleepTask());

brain.addActivity(Activity.CORE, ImmutableList.of(swimJump, climb, breathAirEaten, look, maidPanic, maidAwait, interactWithDoor,
walkToTarget, followOwner, healSelf, pickupItem, clearSleep));
walkToTarget, followOwner, followOwnerVehicle, healSelf, pickupItem, clearSleep));
}

private static void registerIdleGoals(Brain<EntityMaid> brain) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.task;

import com.github.tartaricacid.touhoulittlemaid.api.mixin.IPlayerMixin;
import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid;
import com.github.tartaricacid.touhoulittlemaid.mixin.EntityAccessor;
import com.google.common.collect.ImmutableMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.Behavior;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.player.Player;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

public class MaidFollowOwnerVehicleTask extends Behavior<EntityMaid> {
private static final int RANGE = 3;
private final float speedModifier;
private final int stopDistance;
private Entity ownerControlledVehicle;
private Type type = Type.NONE;

public MaidFollowOwnerVehicleTask(float speedModifier, int stopDistance) {
super(ImmutableMap.of(MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED));
this.speedModifier = speedModifier;
this.stopDistance = stopDistance;
}

@Override
protected boolean checkExtraStartConditions(ServerLevel worldIn, EntityMaid maid) {
// 必须是跟随模式并且自身可以移动
if (!this.maidStateConditions(maid)) {
return false;
}

// 主人必须在场
LivingEntity owner = maid.getOwner();
if (!this.ownerStateConditions(owner) || !(owner instanceof Player player)) {
return false;
}

Entity ownerControlledVehicle = owner.getControlledVehicle();
Entity maidVehicle = maid.getVehicle();

// 如果主人下船(载具)了,女仆也下船。反之上船了,女仆也跟着上船
// 当然,这个载具必须还有空位才可以
if (ownerControlledVehicle == null) {
// 玩家下船有大约 60 tick 冷却时间,在此时间内,一定范围内的女仆才能主动下船,避免误伤
boolean isCooldown = ((IPlayerMixin) player).tlmInRemoveVehicleCooldown();
boolean maidInDismountRange = maid.distanceTo(owner) < RANGE;
if (maid.isPassenger() && isCooldown && maidInDismountRange) {
this.type = Type.STOP;
return true;
}
return false;
}

// 玩家和女仆同坐一艘船,不需要判断
if (maidVehicle != null && maidVehicle == ownerControlledVehicle) {
return false;
}

// 乘坐的载具不能添加新的乘客了,不执行
if (!((EntityAccessor) ownerControlledVehicle).tlmCanAddPassenger(maid)) {
return false;
}

// 女仆开始尝试骑乘载具
if (maid.closerThan(ownerControlledVehicle, RANGE)) {
this.ownerControlledVehicle = ownerControlledVehicle;
this.type = Type.RIDE;
return true;
} else if (!maid.getBrain().hasMemoryValue(MemoryModuleType.WALK_TARGET)) {
BehaviorUtils.setWalkAndLookTargetMemories(maid, ownerControlledVehicle, speedModifier, stopDistance);
return false;
}

return false;
}

@Override
protected void start(ServerLevel worldIn, EntityMaid maid, long gameTimeIn) {
switch (this.type) {
case RIDE -> Optional.ofNullable(this.ownerControlledVehicle).ifPresent(maid::startRiding);
case STOP -> maid.stopRiding();
}
}

@Override
protected void stop(ServerLevel worldIn, EntityMaid maid, long gameTimeIn) {
this.ownerControlledVehicle = null;
this.type = Type.NONE;
}

private boolean canBrainMoving(EntityMaid maid) {
// 不需要判断是否女仆正在骑乘
return !maid.isMaidInSittingPose() && !maid.isSleeping() && !maid.isLeashed();
}

private boolean maidStateConditions(EntityMaid maid) {
return !maid.isHomeModeEnable() && this.canBrainMoving(maid) && maid.isRideable();
}

private boolean ownerStateConditions(@Nullable LivingEntity owner) {
return owner != null && owner.isAlive() && !owner.isSpectator() && !owner.isDeadOrDying();
}

enum Type {
RIDE,
STOP,
NONE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.tartaricacid.touhoulittlemaid.mixin;

import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

@Mixin(Entity.class)
public interface EntityAccessor {
@Invoker("canAddPassenger")
boolean tlmCanAddPassenger(Entity pPassenger);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.github.tartaricacid.touhoulittlemaid.mixin;

import com.github.tartaricacid.touhoulittlemaid.api.mixin.IPlayerMixin;
import net.minecraft.Util;
import net.minecraft.world.entity.player.Player;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(Player.class)
public class PlayerMixin implements IPlayerMixin {
@Unique
private long removeVehicleTimestamp = -1L;

@Inject(method = "removeVehicle()V", at = @At("HEAD"))
private void tlmRemoveVehicle(CallbackInfo ci) {
removeVehicleTimestamp = Util.getMillis();
}

@Override
public boolean tlmInRemoveVehicleCooldown() {
// 三秒冷却时间
return Util.getMillis() - removeVehicleTimestamp < 3000;
}
}
13 changes: 10 additions & 3 deletions src/main/resources/touhou_little_maid.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@
"compatibilityLevel": "JAVA_17",
"refmap": "touhou_little_maid.refmap.json",
"mixins": [
"EntityMixin", "FenceGateBlockAccessor", "FishingHookPredicateMixin", "MixinArrowEntity", "MixinStructureTemplate",
"MixinThrownTrident"
"EntityAccessor",
"EntityMixin",
"FenceGateBlockAccessor",
"FishingHookPredicateMixin",
"MixinArrowEntity",
"MixinStructureTemplate",
"MixinThrownTrident", "PlayerMixin"
],
"client": [
"client.HumanoidModelMixin", "client.ItemPropertiesMixin", "client.LanguageMixin",
"client.HumanoidModelMixin",
"client.ItemPropertiesMixin",
"client.LanguageMixin",
"client.LivingEntityRendererMixin"
],
"injectors": {
Expand Down

0 comments on commit e88eac8

Please sign in to comment.