This commit is contained in:
Bruno Rybársky 2024-07-25 10:58:11 +02:00
parent adb3d51347
commit 67817c4ec3
6 changed files with 145 additions and 58 deletions

@ -4,24 +4,17 @@ import eu.pb4.polymer.core.api.entity.PolymerEntityUtils;
import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils; import eu.pb4.polymer.resourcepack.api.PolymerResourcePackUtils;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
import net.fabricmc.fabric.api.event.player.UseItemCallback; import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.world.World;
import systems.brn.plasticgun.bullets.BulletEntity; import systems.brn.plasticgun.bullets.BulletEntity;
import systems.brn.plasticgun.bullets.BulletItem; import systems.brn.plasticgun.bullets.BulletItem;
import systems.brn.plasticgun.guns.Gun; import systems.brn.plasticgun.guns.Gun;
import systems.brn.plasticgun.lib.EventHandler; import systems.brn.plasticgun.lib.EventHandler;
import systems.brn.plasticgun.testing.DamageTester;
import java.util.ArrayList; import java.util.ArrayList;
@ -37,15 +30,17 @@ public class PlasticGun implements ModInitializer {
public static EntityType<BulletEntity> BULLET_ENTITY_TYPE; public static EntityType<BulletEntity> BULLET_ENTITY_TYPE;
public static EntityType<DamageTester> DAMAGE_TESTER_ENTITY_TYPE;
@Override @Override
public void onInitialize() { public void onInitialize() {
// Bullets - Batch 1 (Better Bullets First) // Bullets - Batch 1 (Better Bullets First)
bullets.add(new BulletItem("357_magnum", 1.2, 357)); bullets.add(new BulletItem("357_magnum", 1.4, 357));
bullets.add(new BulletItem("32_acp_high_velocity", 0.9, 32)); bullets.add(new BulletItem("32_acp_high_velocity", 0.9, 32));
bullets.add(new BulletItem("45_acp_hollow_point", 1.1, 45)); bullets.add(new BulletItem("45_acp_hollow_point", 1.2, 45));
bullets.add(new BulletItem("9mm_jhp", 1.05, 9)); bullets.add(new BulletItem("9mm_jhp", 1.05, 9));
bullets.add(new BulletItem("38_special_p", 1.1, 38)); bullets.add(new BulletItem("38_special_p", 1.3, 38));
bullets.add(new BulletItem("762_tokarev_ap", 1.2, 762)); bullets.add(new BulletItem("762_tokarev_ap", 1.2, 762));
// Bullets - Batch 2 (Standard Bullets) // Bullets - Batch 2 (Standard Bullets)
@ -57,13 +52,13 @@ public class PlasticGun implements ModInitializer {
bullets.add(new BulletItem("762_tokarev", 1.1, 762)); bullets.add(new BulletItem("762_tokarev", 1.1, 762));
// Guns // Guns
guns.add(new Gun("357_revolver", 0.5, 3, 6, 40, 357)); guns.add(new Gun("357_revolver", 0.3, 3, 6, 43, 357));
guns.add(new Gun("colt_1903", 0.4, 2, 8, 35, 32)); guns.add(new Gun("colt_1903", 0.25, 2, 8, 38, 32));
guns.add(new Gun("colt_45", 0.7, 2, 7, 45, 45)); guns.add(new Gun("colt_45", 0.4, 2, 7, 48, 45));
guns.add(new Gun("colt_peacemaker", 0.6, 4, 6, 40, 45)); guns.add(new Gun("colt_peacemaker", 0.35, 4, 6, 43, 45));
guns.add(new Gun("p2022", 0.5, 2, 10, 38, 9)); guns.add(new Gun("p2022", 0.3, 2, 10, 41, 9));
guns.add(new Gun("snub_nosed_revolver", 0.5, 3, 5, 35, 38)); guns.add(new Gun("snub_nosed_revolver", 0.3, 3, 5, 36, 38));
guns.add(new Gun("tokarev_tt_33", 0.6, 2, 8, 42, 762)); guns.add(new Gun("tokarev_tt_33", 0.35, 2, 8, 45, 762));
BULLET_ENTITY_TYPE = Registry.register( BULLET_ENTITY_TYPE = Registry.register(
@ -73,6 +68,15 @@ public class PlasticGun implements ModInitializer {
); );
PolymerEntityUtils.registerType(BULLET_ENTITY_TYPE); PolymerEntityUtils.registerType(BULLET_ENTITY_TYPE);
DAMAGE_TESTER_ENTITY_TYPE = Registry.register(
Registries.ENTITY_TYPE,
id("damagetester"),
EntityType.Builder.<DamageTester>create(DamageTester::new, SpawnGroup.MISC).build()
);
FabricDefaultAttributeRegistry.register(DAMAGE_TESTER_ENTITY_TYPE, DamageTester.createDamageTesterAttributes());
PolymerEntityUtils.registerType(DAMAGE_TESTER_ENTITY_TYPE);
// Detect item use // Detect item use
UseItemCallback.EVENT.register(EventHandler::onItemUse); UseItemCallback.EVENT.register(EventHandler::onItemUse);

@ -1,13 +1,10 @@
package systems.brn.plasticgun.bullets; package systems.brn.plasticgun.bullets;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.PersistentProjectileEntity; import net.minecraft.entity.projectile.PersistentProjectileEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.BlockHitResult;
@ -18,7 +15,8 @@ import net.minecraft.world.World;
import eu.pb4.polymer.core.api.entity.PolymerEntity; import eu.pb4.polymer.core.api.entity.PolymerEntity;
import systems.brn.plasticgun.guns.Gun; import systems.brn.plasticgun.guns.Gun;
import static net.minecraft.particle.ParticleTypes.CRIT; import java.lang.reflect.Method;
import static systems.brn.plasticgun.PlasticGun.BULLET_ENTITY_TYPE; import static systems.brn.plasticgun.PlasticGun.BULLET_ENTITY_TYPE;
import static systems.brn.plasticgun.PlasticGun.bullets; import static systems.brn.plasticgun.PlasticGun.bullets;
@ -30,10 +28,19 @@ public class BulletEntity extends PersistentProjectileEntity implements PolymerE
this.setOwner(player); this.setOwner(player);
this.setVelocity(player, player.getPitch(), player.getYaw(), 0.0F, speed, 0); this.setVelocity(player, player.getPitch(), player.getYaw(), 0.0F, speed, 0);
this.pickupType = PickupPermission.CREATIVE_ONLY; this.pickupType = PickupPermission.CREATIVE_ONLY;
player.setPitch(player.getPitch() + 5);
this.setDamage(damage); this.setDamage(damage);
this.setSilent(true); this.setSilent(true);
this.gun = gun; this.gun = gun;
this.setCustomPierceLevel((byte) 1);
}
public void setCustomPierceLevel(byte level) {
try {
Method method = PersistentProjectileEntity.class.getDeclaredMethod("setPierceLevel", byte.class);
method.setAccessible(true); // Allow access to private methods
method.invoke(this, level);
} catch (Exception ignored) {
}
} }
public BulletEntity(EntityType<BulletEntity> entityType, World world) { public BulletEntity(EntityType<BulletEntity> entityType, World world) {
@ -59,28 +66,27 @@ public class BulletEntity extends PersistentProjectileEntity implements PolymerE
protected void onBlockHit(BlockHitResult blockHitResult) { protected void onBlockHit(BlockHitResult blockHitResult) {
if (blockHitResult.getType() == HitResult.Type.BLOCK) { if (blockHitResult.getType() == HitResult.Type.BLOCK) {
BlockState block = this.getWorld().getBlockState(blockHitResult.getBlockPos()); BlockState block = this.getWorld().getBlockState(blockHitResult.getBlockPos());
SoundEvent soundEvent = block.getSoundGroup().getHitSound(); SoundEvent soundEvent = block.getSoundGroup().getHitSound();
setSilent(false); setSilent(false);
playSound(soundEvent, 4.0F, 1.0F); playSound(soundEvent, 4.0F, 1.0F);
setSilent(true); setSilent(true);
} }
this.setOnFire(true);
super.onBlockHit(blockHitResult); super.onBlockHit(blockHitResult);
this.setOnFire(false);
this.discard();
} }
@Override @Override
protected void onEntityHit(EntityHitResult entityHitResult) { protected void onEntityHit(EntityHitResult entityHitResult) {
Vec3d pos = entityHitResult.getPos();
entityHitResult.getEntity().getEntityWorld().addParticle(CRIT, true, pos.x, pos.y, pos.z, 3, 0, 0);
Vec3d diff = entityHitResult.getPos();
diff.subtract(entityHitResult.getEntity().getPos());
double height = diff.y;
if (entityHitResult.getEntity() instanceof PlayerEntity && height >= 1.75 && height <= 2) {
this.setDamage(2);
}
setSilent(false); setSilent(false);
playSound(SoundEvents.BLOCK_BAMBOO_HIT, 4.0F, 1.0F); playSound(SoundEvents.BLOCK_BAMBOO_HIT, 4.0F, 1.0F);
setSilent(true); setSilent(true);
super.onEntityHit(entityHitResult); super.onEntityHit(entityHitResult);
this.discard();
} }
} }

@ -2,29 +2,23 @@ package systems.brn.plasticgun.guns;
import eu.pb4.polymer.core.api.item.PolymerItem; import eu.pb4.polymer.core.api.item.PolymerItem;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents; import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.StackReference;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.network.packet.s2c.play.PositionFlag;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.screen.slot.Slot;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.sound.SoundEvents; import net.minecraft.sound.SoundEvents;
import net.minecraft.util.ActionResult;
import net.minecraft.util.ClickType;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import systems.brn.plasticgun.bullets.BulletEntity; import systems.brn.plasticgun.bullets.BulletEntity;
import systems.brn.plasticgun.bullets.BulletItem; import systems.brn.plasticgun.bullets.BulletItem;
import systems.brn.plasticgun.lib.SimpleItem; import systems.brn.plasticgun.lib.SimpleItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set;
import static systems.brn.plasticgun.PlasticGun.bullets; import static systems.brn.plasticgun.PlasticGun.bullets;
import static systems.brn.plasticgun.lib.GunComponents.GUN_AMMO_COMPONENT; import static systems.brn.plasticgun.lib.GunComponents.GUN_AMMO_COMPONENT;
@ -46,7 +40,7 @@ public class Gun extends SimpleItem implements PolymerItem {
.maxCount(1) .maxCount(1)
.component(GUN_AMMO_COMPONENT, ItemStack.EMPTY) .component(GUN_AMMO_COMPONENT, ItemStack.EMPTY)
.maxDamage(clipSize + 1) .maxDamage(clipSize + 1)
, id(path), Items.WOODEN_HOE , id(path), Items.WOODEN_SWORD
); );
Item item = Registry.register(Registries.ITEM, id(path), this); Item item = Registry.register(Registries.ITEM, id(path), this);
ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(content -> content.add(item)); ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(content -> content.add(item));
@ -65,7 +59,7 @@ public class Gun extends SimpleItem implements PolymerItem {
} }
public void reload(World world, PlayerEntity user, Hand hand) { public void reload(World world, PlayerEntity user, Hand hand) {
if (user instanceof ServerPlayerEntity player) { if (user instanceof ServerPlayerEntity player && !world.isClient()) {
ItemStack stack = user.getStackInHand(hand); ItemStack stack = user.getStackInHand(hand);
ItemStack bulletStack = findBulletStack(ammo, player); ItemStack bulletStack = findBulletStack(ammo, player);
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy(); ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
@ -121,23 +115,35 @@ public class Gun extends SimpleItem implements PolymerItem {
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy(); ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
int numBullets = chamber.getCount(); int numBullets = chamber.getCount();
int currentReload = stack.getOrDefault(GUN_LOADING_COMPONENT, 1); int currentReload = stack.getOrDefault(GUN_LOADING_COMPONENT, 1);
if (currentReload < reloadCount) { if (currentReload != 1) {
numBullets = -1; numBullets = -clipSize;
} }
stack.setDamage(clipSize - numBullets); stack.setDamage((clipSize - numBullets) + 1);
}
public void doRecoil(ServerPlayerEntity player) {
// Get the player's current position and yaw
Vec3d pos = player.getPos();
float yaw = player.getYaw();
float newPitch = player.getPitch();
newPitch -= player.getWorld().getRandom().nextBetween(1, 4);
yaw -= player.getWorld().getRandom().nextBetween(-2, 2);
player.teleport(player.getServerWorld(), pos.x, pos.y, pos.z, Set.of(PositionFlag.X_ROT, PositionFlag.Y_ROT), yaw, newPitch);
} }
public void shoot(World world, PlayerEntity user, Hand hand) { public void shoot(World world, PlayerEntity user, Hand hand) {
if (user instanceof ServerPlayerEntity player) { if (user instanceof ServerPlayerEntity player && !world.isClient()) {
ItemStack stack = user.getStackInHand(hand); ItemStack stack = user.getStackInHand(hand);
int currentReload = stack.getOrDefault(GUN_LOADING_COMPONENT, 1); int currentReload = stack.getOrDefault(GUN_LOADING_COMPONENT, 1);
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY); ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
if (!chamber.isEmpty() && currentReload == 1) { if (!chamber.isEmpty() && currentReload == 1) {
BulletEntity bulletEntity = new BulletEntity(user.getPos(), player, chamber, user.getStackInHand(hand), this, damage, speed); BulletEntity bulletEntity = new BulletEntity(user.getPos(), player, chamber, user.getStackInHand(hand), this, damage, speed);
world.spawnEntity(bulletEntity); world.spawnEntity(bulletEntity);
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENTITY_GENERIC_EXPLODE.value(), SoundCategory.PLAYERS, 0.1f, 1.2f); world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENTITY_GENERIC_EXPLODE.value(), SoundCategory.PLAYERS, 0.1f, 1.2f);
chamber.decrement(1); chamber.decrement(1);
doRecoil(player);
if (chamber.isEmpty()) { if (chamber.isEmpty()) {
stack.remove(GUN_AMMO_COMPONENT); stack.remove(GUN_AMMO_COMPONENT);
} else { } else {

@ -1,16 +1,10 @@
package systems.brn.plasticgun.lib; package systems.brn.plasticgun.lib;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult; import net.minecraft.util.TypedActionResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
import systems.brn.plasticgun.guns.Gun; import systems.brn.plasticgun.guns.Gun;

@ -67,7 +67,7 @@ public class Util {
return !stack1.isEmpty() && stack1.getItem() == stack2.getItem() && ItemStack.areItemsAndComponentsEqual(stack1, stack2); return !stack1.isEmpty() && stack1.getItem() == stack2.getItem() && ItemStack.areItemsAndComponentsEqual(stack1, stack2);
} }
public static ItemStack insertStackIntoInventory(Inventory inventory, ItemStack stack) { public static void insertStackIntoInventory(Inventory inventory, ItemStack stack) {
// First, try to merge with existing stacks // First, try to merge with existing stacks
for (int i = 0; i < inventory.size(); i++) { for (int i = 0; i < inventory.size(); i++) {
ItemStack slotStack = inventory.getStack(i); ItemStack slotStack = inventory.getStack(i);
@ -78,7 +78,7 @@ public class Util {
stack.decrement(transferAmount); stack.decrement(transferAmount);
inventory.markDirty(); inventory.markDirty();
if (stack.isEmpty()) { if (stack.isEmpty()) {
return ItemStack.EMPTY; return;
} }
} }
} }
@ -91,10 +91,9 @@ public class Util {
inventory.setStack(i, stack.copy()); inventory.setStack(i, stack.copy());
stack.setCount(0); stack.setCount(0);
inventory.markDirty(); inventory.markDirty();
return ItemStack.EMPTY; return;
} }
} }
return stack;
} }
} }

@ -0,0 +1,78 @@
package systems.brn.plasticgun.testing;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.DefaultAttributeContainer;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Arm;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import eu.pb4.polymer.core.api.entity.PolymerEntity;
import java.util.Collections;
import static systems.brn.plasticgun.PlasticGun.*;
public class DamageTester extends LivingEntity implements PolymerEntity {
public DamageTester(Vec3d pos, World world) {
super(DAMAGE_TESTER_ENTITY_TYPE, world);
this.setPos(pos.x, pos.y, pos.z);
}
public DamageTester(EntityType<systems.brn.plasticgun.testing.DamageTester> entityType, World world) {
super(entityType, world);
}
@Override
public boolean damage(DamageSource source, float amount) {
Entity attacker = source.getAttacker();
if (attacker instanceof PlayerEntity player) {
player.sendMessage(Text.literal("You damaged by " + amount));
if (player.isSneaking()) {
this.remove(RemovalReason.KILLED);
}
}
return false;
}
public static DefaultAttributeContainer.Builder createDamageTesterAttributes() {
return LivingEntity.createLivingAttributes()
.add(EntityAttributes.GENERIC_MAX_HEALTH, 1.0)
.add(EntityAttributes.GENERIC_ATTACK_DAMAGE, 0.0);
}
@Override
public EntityType<?> getPolymerEntityType(ServerPlayerEntity player) {
return EntityType.ZOMBIE;
}
@Override
public Iterable<ItemStack> getArmorItems() {
return Collections.emptyList();
}
@Override
public ItemStack getEquippedStack(EquipmentSlot slot) {
return Items.WITHER_SKELETON_SKULL.getDefaultStack();
}
@Override
public void equipStack(EquipmentSlot slot, ItemStack stack) {
}
@Override
public Arm getMainArm() {
return Arm.RIGHT;
}
}