实现丘比特之箭的效果

This commit is contained in:
17146 2025-05-10 01:45:38 +08:00 committed by Light_Quanta
parent d6dd218413
commit dc0fad50ff
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
7 changed files with 118 additions and 11 deletions

View file

@ -0,0 +1,14 @@
package com.atsuishio.superbwarfare.entity;
import net.minecraft.world.entity.npc.Villager;
public interface CupidLove {
static CupidLove getInstance(Villager villager) {
return (CupidLove) villager;
}
void superbwarfare$setCupidLove(boolean love);
boolean superbwarfare$getCupidLove();
}

View file

@ -0,0 +1,26 @@
package com.atsuishio.superbwarfare.mixins;
import com.atsuishio.superbwarfare.entity.CupidLove;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.behavior.VillagerMakeLove;
import net.minecraft.world.entity.npc.Villager;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(VillagerMakeLove.class)
public class VillagerMakeLoveMixin {
@Inject(method = "takeVacantBed(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/npc/Villager;)Ljava/util/Optional;",
at = @At("HEAD"), cancellable = true)
private void takeVacantBed(ServerLevel pLevel, Villager pVillager, CallbackInfoReturnable<Optional<BlockPos>> cir) {
CupidLove entity = CupidLove.getInstance(pVillager);
if (entity.superbwarfare$getCupidLove()) {
cir.setReturnValue(Optional.of(pVillager.getOnPos()));
}
}
}

View file

@ -0,0 +1,45 @@
package com.atsuishio.superbwarfare.mixins;
import com.atsuishio.superbwarfare.entity.CupidLove;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.npc.Villager;
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;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Villager.class)
public class VillagerMixin implements CupidLove {
@Unique
public boolean superbwarfare$cupidLove;
@Override
public void superbwarfare$setCupidLove(boolean love) {
this.superbwarfare$cupidLove = love;
}
@Override
public boolean superbwarfare$getCupidLove() {
return this.superbwarfare$cupidLove;
}
@Inject(method = "addAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
public void addAdditionalSaveData(CompoundTag pCompound, CallbackInfo ci) {
pCompound.putBoolean("SuperbwarfareCupidLove", this.superbwarfare$cupidLove);
}
@Inject(method = "readAdditionalSaveData(Lnet/minecraft/nbt/CompoundTag;)V", at = @At("RETURN"))
public void readAdditionalSaveData(CompoundTag pCompound, CallbackInfo ci) {
this.superbwarfare$cupidLove = pCompound.getBoolean("SuperbwarfareCupidLove");
}
@Inject(method = "canBreed()Z", at = @At("HEAD"), cancellable = true)
public void canBreed(CallbackInfoReturnable<Boolean> cir) {
if (this.superbwarfare$cupidLove && ((Villager) (Object) this).getAge() == 0) {
cir.setReturnValue(true);
}
}
}

View file

@ -1,13 +1,22 @@
package com.atsuishio.superbwarfare.perk.functional; package com.atsuishio.superbwarfare.perk.functional;
import com.atsuishio.superbwarfare.entity.CupidLove;
import com.atsuishio.superbwarfare.item.gun.data.GunData; import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.perk.Perk; import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkInstance; import com.atsuishio.superbwarfare.perk.PerkInstance;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Pair;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.VillagerMakeLove;
import net.minecraft.world.entity.animal.Animal; import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.entity.schedule.Activity;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class CupidArrow extends Perk { public class CupidArrow extends Perk {
@ -29,6 +38,23 @@ public class CupidArrow extends Perk {
if (target instanceof Animal animal && animal.canFallInLove()) { if (target instanceof Animal animal && animal.canFallInLove()) {
animal.setInLove(attacker); animal.setInLove(attacker);
} }
if (target instanceof Villager villager && !villager.isBaby()) {
CupidLove cupidLove = CupidLove.getInstance(villager);
cupidLove.superbwarfare$setCupidLove(true);
if (villager.canBreed()) {
villager.getBrain().setActiveActivityIfPossible(Activity.IDLE);
villager.getBrain().addActivity(Activity.IDLE, ImmutableList.of(Pair.of(1, new VillagerMakeLove())));
}
}
if (target.level() instanceof ServerLevel serverLevel) {
double d0 = serverLevel.random.nextGaussian() * 0.02D;
double d1 = serverLevel.random.nextGaussian() * 0.02D;
double d2 = serverLevel.random.nextGaussian() * 0.02D;
ParticleTool.sendParticle(serverLevel, ParticleTypes.HEART, target.getRandomX(1.0D), target.getRandomY() + 0.5D, target.getRandomZ(1.0D),
5, d0, d1, d2, 0.1, false);
}
} }
@Override @Override
@ -40,14 +66,4 @@ public class CupidArrow extends Perk {
public boolean shouldCancelHurtEvent(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) { public boolean shouldCancelHurtEvent(float damage, GunData data, PerkInstance instance, LivingEntity target, DamageSource source) {
return true; return true;
} }
@Override
public double getDisplayDamage(double damage, GunData data, PerkInstance instance) {
return 0;
}
@Override
public double getExtraDisplayDamage(double damage, GunData data, PerkInstance instance) {
return 0;
}
} }

View file

@ -345,6 +345,8 @@
"des.superbwarfare.powerful_attraction": "Experience and items dropped by slain mods will instantly be transferred to your inventory.", "des.superbwarfare.powerful_attraction": "Experience and items dropped by slain mods will instantly be transferred to your inventory.",
"item.superbwarfare.intelligent_chip": "Intelligent Chip", "item.superbwarfare.intelligent_chip": "Intelligent Chip",
"des.superbwarfare.intelligent_chip": "Aims at enemies automatically (Do not use this in PVP mode)", "des.superbwarfare.intelligent_chip": "Aims at enemies automatically (Do not use this in PVP mode)",
"item.superbwarfare.cupid_arrow": "Cupid's Arrow",
"des.superbwarfare.cupid_arrow": "Make the target fall in love after being hit. Deals no damage to living entities.",
"item.superbwarfare.kill_clip": "Kill Clip", "item.superbwarfare.kill_clip": "Kill Clip",
"des.superbwarfare.kill_clip": "Increases the damage of weapon after dealing a final blow.", "des.superbwarfare.kill_clip": "Increases the damage of weapon after dealing a final blow.",

View file

@ -345,6 +345,8 @@
"des.superbwarfare.powerful_attraction": "击杀目标后掉落的物品和经验会直接转移到自身", "des.superbwarfare.powerful_attraction": "击杀目标后掉落的物品和经验会直接转移到自身",
"item.superbwarfare.intelligent_chip": "智慧芯片", "item.superbwarfare.intelligent_chip": "智慧芯片",
"des.superbwarfare.intelligent_chip": "自动瞄准敌人请勿在PVP使用此模组", "des.superbwarfare.intelligent_chip": "自动瞄准敌人请勿在PVP使用此模组",
"item.superbwarfare.cupid_arrow": "丘比特之箭",
"des.superbwarfare.cupid_arrow": "命中后会使目标坠入爱河,不会对生物造成伤害",
"item.superbwarfare.kill_clip": "杀戮弹匣", "item.superbwarfare.kill_clip": "杀戮弹匣",
"des.superbwarfare.kill_clip": "完成击杀后填装可提升武器伤害", "des.superbwarfare.kill_clip": "完成击杀后填装可提升武器伤害",

View file

@ -8,7 +8,9 @@
"EntityMixin", "EntityMixin",
"FishingHookMixin", "FishingHookMixin",
"LivingEntityMixin", "LivingEntityMixin",
"PlayerMixin" "PlayerMixin",
"VillagerMakeLoveMixin",
"VillagerMixin"
], ],
"client": [ "client": [
"CameraMixin", "CameraMixin",