Skip to content

Commit

Permalink
喷火器
Browse files Browse the repository at this point in the history
  • Loading branch information
ChloePrime committed Oct 19, 2024
1 parent 323ee7d commit 9ca04d7
Show file tree
Hide file tree
Showing 40 changed files with 533 additions and 9 deletions.
5 changes: 4 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@
*.jar filter=lfs diff=lfs merge=lfs -text
*.rns filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.efkefc filter=lfs diff=lfs merge=lfs -text
*.efkmat filter=lfs diff=lfs merge=lfs -text
*.efkmatd filter=lfs diff=lfs merge=lfs -text
22 changes: 22 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ mixin {
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }

boolean USE_LOCAL_AAAP = false

repositories {
// NeoForge
maven { url "https://maven.neoforged.net/releases/" }
Expand All @@ -156,6 +158,8 @@ repositories {
includeGroup "maven.modrinth"
}
}
// Architectury
maven { url "https://maven.architectury.dev/" }

repositories {
maven { url 'https://modmaven.dev/' }
Expand All @@ -177,6 +181,14 @@ repositories {
}
}

// AAAParticles
USE_LOCAL_AAAP = file('../AAAParticles').exists();
if (USE_LOCAL_AAAP) {
flatDir {
dir '../AAAParticles/forge/build/libs'
}
}

maven { // Registrate
url "https://maven.tterrag.com/"
}
Expand Down Expand Up @@ -204,6 +216,16 @@ dependencies {
jarJar.ranged(it, "[1.20.1-1.2,)")
}

// AAA粒子
var aaap = USE_LOCAL_AAAP
? "libs:aaa_particles:1.20.1-1.4.6.a-forge"
: "maven.modrinth:aaa-particles:1.20.1-1.4.5-forge"
implementation(jarJar(fg.deobf(aaap))) {
jarJar.ranged(it, "[1.20.1-1,)")
}
implementation fg.deobf("dev.architectury:architectury-forge:9.2.14")
runtimeOnly fg.deobf("maven.modrinth:embeddium:0.3.31+mc1.20.1")

// MEK, 用于测试能量武器
runtimeOnly fg.deobf("mekanism:Mekanism:${mekanism_version}")// core

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;

import java.util.Random;
import java.util.random.RandomGenerator;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package mod.chloeprime.modtechpoweredarsenal.client.lightland.guns;

import com.tacz.guns.api.event.common.GunFireEvent;
import mod.chloeprime.aaaparticles.api.common.AAALevel;
import mod.chloeprime.aaaparticles.api.common.ParticleEmitterInfo;
import mod.chloeprime.gunsmithlib.api.util.Gunsmith;
import mod.chloeprime.modtechpoweredarsenal.ModTechPoweredArsenal;
import mod.chloeprime.modtechpoweredarsenal.client.standard.MinecraftHolder;
import mod.chloeprime.modtechpoweredarsenal.common.standard.guns.FlamethrowerBehavior;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(Dist.CLIENT)
public class FlamethrowerVisuals {
public static final ResourceLocation COMMON_FLAME_EFFEK_ID = ModTechPoweredArsenal.loc("explosion/flamethrower");
public static final ResourceLocation SOUL_FLAME_EFFEK_ID = ModTechPoweredArsenal.loc("explosion/flamethrower_soul");

@SubscribeEvent
public static void onClientShot(GunFireEvent event) {
if (event.getLogicalSide().isServer()) {
return;
}
var gun = Gunsmith.getGunInfo(event.getGunItemStack()).orElse(null);
if (gun == null) {
return;
}
int type = FlamethrowerBehavior.getType(gun);
if (type == 0 || event.getShooter().isUnderWater()) {
return;
}
var shooter = event.getShooter();
if (shooter == null || !shooter.level().isClientSide) {
return;
}
var particle = type == FlamethrowerBehavior.BULLET_FLAME_TYPE_SOUL
? SOUL_FLAME_EFFEK_ID
: COMMON_FLAME_EFFEK_ID;
var pei = ParticleEmitterInfo.create(shooter.level(), particle)
.bindOnEntity(shooter)
.useEntityHeadSpace()
.entitySpaceRelativePosition(0.06, -0.28, -0.8);
MinecraftHolder.MC.execute(() -> {
if (shooter.isAlive()) {
AAALevel.addParticle(shooter.level(), true, pei);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package mod.chloeprime.modtechpoweredarsenal.client.standard;

import net.minecraft.client.Minecraft;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public class MinecraftHolder {
public static final Minecraft MC = Minecraft.getInstance();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package mod.chloeprime.modtechpoweredarsenal.common.lightland.guns;

import com.google.common.base.Suppliers;
import dev.xkmc.l2library.base.effects.EffectUtil;
import mod.chloeprime.modtechpoweredarsenal.ModLoadStatus;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.registries.ForgeRegistries;

import javax.annotation.Nullable;
import java.util.function.Supplier;

@Mod.EventBusSubscriber
public class SoulFlamethrowerBehaviorLCProxy {
private static final Supplier<MobEffect> SOUL_FLAME_DEBUFF = Suppliers.memoize(
() -> ForgeRegistries.MOB_EFFECTS.getValue(
new ResourceLocation("l2complements", "flame")
)
);

public static void addSoulFlameDebuff(LivingEntity victim, @Nullable Entity shooter) {
var size = victim.getActiveEffectsMap().size();
int time = ModLoadStatus.L2H_INSTALLED
? SoulFlamethrowerBehaviorLHProxy.getFlameThornDebuffDuration()
: 5 * 20;
EffectUtil.addEffect(victim, new MobEffectInstance(SOUL_FLAME_DEBUFF.get(), time, size), EffectUtil.AddReason.FORCE, shooter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package mod.chloeprime.modtechpoweredarsenal.common.lightland.guns;

import dev.xkmc.l2hostility.init.data.LHConfig;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber
public class SoulFlamethrowerBehaviorLHProxy {
public static int getFlameThornDebuffDuration() {
return LHConfig.COMMON.flameThornTime.get();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,10 @@ public static void onAmmoHitBlock(AmmoHitBlockEvent event) {
private static final ResourceLocation BULLET_HOLE_ID = new ResourceLocation("tacz", "bullet_hole");

@ApiStatus.Internal
public static int onServerSpawnBulletHole(Projectile bullet, ParticleOptions particle, IntSupplier original) {
public static boolean disableServerBulletHole(Projectile bullet, ParticleOptions particle) {
if (bullet.getPersistentData().getBoolean(PDK_HAS_PLASMA_VISUAL)) {
if (BULLET_HOLE_ID.equals(ForgeRegistries.PARTICLE_TYPES.getKey(particle.getType()))) {
return 0;
}
return BULLET_HOLE_ID.equals(ForgeRegistries.PARTICLE_TYPES.getKey(particle.getType()));
}
return original.getAsInt();
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ public static RecombinationPerk create() {

public static final int BUFF_DURATION = 20 * 30; // 30s
public static final String PDK_IS_SHOOTING = ModTechPoweredArsenal.loc("recombination.is_shooting").toString();
public static final TagKey<DamageType> ANY_MAGIC = TagKey.create(Registries.DAMAGE_TYPE, ModTechPoweredArsenal.loc("any_magic"));

@Override
public boolean canApplyAtEnchantingTable(@Nonnull ItemStack stack) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package mod.chloeprime.modtechpoweredarsenal.common.standard.guns;

import com.google.common.collect.Sets;
import com.tacz.guns.api.event.common.EntityHurtByGunEvent;
import com.tacz.guns.api.event.common.GunDamageSourcePart;
import com.tacz.guns.api.item.attachment.AttachmentType;
import mod.chloeprime.gunsmithlib.api.common.BulletCreateEvent;
import mod.chloeprime.gunsmithlib.api.util.GunInfo;
import mod.chloeprime.gunsmithlib.api.util.Gunsmith;
import mod.chloeprime.modtechpoweredarsenal.ModLoadStatus;
import mod.chloeprime.modtechpoweredarsenal.ModTechPoweredArsenal;
import mod.chloeprime.modtechpoweredarsenal.common.lightland.MtpaL2Module;
import mod.chloeprime.modtechpoweredarsenal.common.lightland.guns.SoulFlamethrowerBehaviorLCProxy;
import mod.chloeprime.modtechpoweredarsenal.common.standard.util.DamageSourceUtil;
import mod.chloeprime.modtechpoweredarsenal.mixin.minecraft.DamageSourcesAccessor;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.DamageTypeTags;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import java.util.Optional;
import java.util.Set;

@Mod.EventBusSubscriber
public class FlamethrowerBehavior {
public static final Set<ResourceLocation> FLAMETHROWERS = Sets.newConcurrentHashSet(Set.of(
ModTechPoweredArsenal.loc("flamethrower")
));
public static final Set<ResourceLocation> SOUL_FUEL_MAGS = Sets.newConcurrentHashSet(Set.of(
MtpaL2Module.loc("ammo_mod_soul_fuel")
));
public static final String PDK_BULLET_FLAME_TYPE = ModTechPoweredArsenal.loc("flame_type").toString();
public static final int BULLET_FLAME_TYPE_HEAT = 1;
public static final int BULLET_FLAME_TYPE_SOUL = 2;

public static int getType(GunInfo gun) {
if (!FLAMETHROWERS.contains(gun.gunId())) {
return 0;
}
return willShootSoulFlame(gun) ? BULLET_FLAME_TYPE_SOUL : BULLET_FLAME_TYPE_HEAT;
}

public static boolean willShootSoulFlame(GunInfo gun) {
return SOUL_FUEL_MAGS.contains(gun.gunItem().getAttachmentId(gun.gunStack(), AttachmentType.EXTENDED_MAG));
}

@SubscribeEvent
public static void onBulletCreate(BulletCreateEvent event) {
if (event.getBullet().level().isClientSide) {
return;
}
Optional<GunInfo> gunInfo = Gunsmith.getGunInfo(event.getGun());
var isValidGun = gunInfo
.map(GunInfo::gunId)
.filter(FLAMETHROWERS::contains)
.isPresent();
if (!isValidGun) {
return;
}
var type = getType(gunInfo.get());
if (type <= 0) {
return;
}
event.getBullet().getPersistentData().putInt(PDK_BULLET_FLAME_TYPE, type);
}

@SubscribeEvent(priority = EventPriority.HIGH)
public static void onPreHurt(EntityHurtByGunEvent.Pre event) {
var source1 = event.getDamageSource(GunDamageSourcePart.NON_ARMOR_PIERCING);
var source2 = event.getDamageSource(GunDamageSourcePart.ARMOR_PIERCING);

var bullet = event.getBullet();
var victim = event.getHurtEntity();
if (victim == null || bullet == null) {
return;
}
var type = bullet.getPersistentData().getInt(PDK_BULLET_FLAME_TYPE);
DamageSource newSource;
switch (type) {
case BULLET_FLAME_TYPE_HEAT -> {
newSource = ((DamageSourcesAccessor) victim.damageSources()).invokeSource(DamageTypes.IN_FIRE, bullet, event.getAttacker());
}
case BULLET_FLAME_TYPE_SOUL -> {
if (source1.is(DamageSourceUtil.ANY_MAGIC)) {
return;
}
newSource = victim.damageSources().indirectMagic(bullet, event.getAttacker());
}
default -> {
return;
}
}
event.setDamageSource(GunDamageSourcePart.NON_ARMOR_PIERCING, newSource);
event.setDamageSource(GunDamageSourcePart.ARMOR_PIERCING, newSource);
}

@SubscribeEvent
public static void onPostHurt(EntityHurtByGunEvent.Post event) {
if (event.getLogicalSide().isClient()) {
return;
}
if (!(event.getHurtEntity() instanceof LivingEntity victim)) {
return;
}
int type = event.getBullet().getPersistentData().getInt(PDK_BULLET_FLAME_TYPE);
switch (type) {
case BULLET_FLAME_TYPE_HEAT -> {
victim.setRemainingFireTicks((int) (event.getBaseAmount() * 20));
}
case BULLET_FLAME_TYPE_SOUL -> {
if (ModLoadStatus.L2C_INSTALLED) {
SoulFlamethrowerBehaviorLCProxy.addSoulFlameDebuff(victim, event.getAttacker());
}
}
}
}

public static boolean disableServerBulletHole(Projectile bullet, ParticleOptions particle) {
return bullet.getPersistentData().getInt(PDK_BULLET_FLAME_TYPE) > 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap;
import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import mod.chloeprime.modtechpoweredarsenal.ModTechPoweredArsenal;
import mod.chloeprime.modtechpoweredarsenal.common.standard.internal.ClassicDamageSource;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
Expand All @@ -12,6 +14,9 @@
import java.util.OptionalDouble;

public class DamageSourceUtil {
public static final TagKey<DamageType> IS_MAGIC = TagKey.create(Registries.DAMAGE_TYPE, new ResourceLocation("forge", "any_magic"));
public static final TagKey<DamageType> ANY_MAGIC = TagKey.create(Registries.DAMAGE_TYPE, ModTechPoweredArsenal.loc("any_magic"));

public static void addTag(DamageSource source, TagKey<DamageType> tag) {
((ClassicDamageSource) source).mtpa$addTag(tag);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package mod.chloeprime.modtechpoweredarsenal.mixin.minecraft;

import net.minecraft.resources.ResourceKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageSources;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;

import javax.annotation.Nullable;

@Mixin(DamageSources.class)
public interface DamageSourcesAccessor {
@Invoker
DamageSource invokeSource(ResourceKey<DamageType> id, @Nullable Entity var1, @Nullable Entity var2);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.tacz.guns.entity.EntityKineticBullet;
import mod.chloeprime.modtechpoweredarsenal.common.standard.attachments.PlasmaVisualDispatcher;
import mod.chloeprime.modtechpoweredarsenal.common.standard.guns.FlamethrowerBehavior;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntityType;
Expand All @@ -21,8 +22,13 @@ public abstract class PlasmaBulletHoleDoNotUseServerDispatchMixin extends Projec
value = "INVOKE", remap = true,
target = "Lnet/minecraft/server/level/ServerLevel;sendParticles(Lnet/minecraft/core/particles/ParticleOptions;DDDIDDDD)I"
))
private <T extends ParticleOptions> int plasmaBulletHoleDoNotUseServerDispatch(ServerLevel instance, T particle, double v, double pType, double pPosX, int pPosY, double pPosZ, double pParticleCount, double pXOffset, double pYOffset, Operation<Integer> original) {
return PlasmaVisualDispatcher.onServerSpawnBulletHole(this, particle, () -> original.call(instance, particle, v, pType, pPosX, pPosY, pPosZ, pParticleCount, pXOffset, pYOffset));
private <T extends ParticleOptions> int selectivelyDisableBulletHole(ServerLevel instance, T particle, double v, double pType, double pPosX, int pPosY, double pPosZ, double pParticleCount, double pXOffset, double pYOffset, Operation<Integer> original) {
var disable = false;
//noinspection ConstantValue
disable = disable || PlasmaVisualDispatcher.disableServerBulletHole(this, particle);
disable = disable || FlamethrowerBehavior.disableServerBulletHole(this, particle);
//noinspection MixinExtrasOperationParameters
return disable ? 0 : original.call(instance, particle, v, pType, pPosX, pPosY, pPosZ, pParticleCount, pXOffset, pYOffset);
}

public PlasmaBulletHoleDoNotUseServerDispatchMixin(EntityType<? extends Projectile> pEntityType, Level pLevel) {
Expand Down
Git LFS file not shown
Git LFS file not shown
Loading

0 comments on commit 9ca04d7

Please sign in to comment.