Skeleton go pew pew
Also zombie go boom
This commit is contained in:
parent
8d00672806
commit
653171cbb2
@ -109,3 +109,7 @@ publishing {
|
|||||||
// retrieving dependencies.
|
// retrieving dependencies.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loom {
|
||||||
|
accessWidenerPath = file("src/main/resources/plasticgun.accesswidener")
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
|||||||
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
|
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.item.Item;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -27,7 +28,9 @@ import systems.brn.plasticgun.shurikens.ShurikenItem;
|
|||||||
import systems.brn.plasticgun.testing.DamageTester;
|
import systems.brn.plasticgun.testing.DamageTester;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static systems.brn.plasticgun.lib.Util.generateItemMap;
|
||||||
import static systems.brn.plasticgun.lib.Util.id;
|
import static systems.brn.plasticgun.lib.Util.id;
|
||||||
|
|
||||||
public class PlasticGun implements ModInitializer {
|
public class PlasticGun implements ModInitializer {
|
||||||
@ -44,6 +47,11 @@ public class PlasticGun implements ModInitializer {
|
|||||||
|
|
||||||
public static final ArrayList<CraftingItem> craftingItems = new ArrayList<>();
|
public static final ArrayList<CraftingItem> craftingItems = new ArrayList<>();
|
||||||
|
|
||||||
|
public static Map<Item, Gun> itemGunMap;
|
||||||
|
public static Map<Item, BulletItem> itemBulletItemMap;
|
||||||
|
public static Map<Item, GrenadeItem> itemGrenadeItemMap;
|
||||||
|
public static Map<Item, ShurikenItem> itemShurikenItemMap;
|
||||||
|
|
||||||
public static EntityType<BulletEntity> BULLET_ENTITY_TYPE;
|
public static EntityType<BulletEntity> BULLET_ENTITY_TYPE;
|
||||||
|
|
||||||
public static EntityType<GrenadeEntity> GRENADE_ENTITY_TYPE;
|
public static EntityType<GrenadeEntity> GRENADE_ENTITY_TYPE;
|
||||||
@ -80,32 +88,32 @@ public class PlasticGun implements ModInitializer {
|
|||||||
bullets.add(new BulletItem("force_container", 99, 0, 888, false, 0, 1));
|
bullets.add(new BulletItem("force_container", 99, 0, 888, false, 0, 1));
|
||||||
|
|
||||||
// Guns
|
// Guns
|
||||||
guns.add(new Gun("357_revolver", 1, 8, 5, 6, 45, 357, 14, 0, 0, 2, 4, 0.2f, 0.5f, -1, 1));
|
guns.add(new Gun("forcegun", 0, 2, 5, 20, 10, 888, 0, 0, 20, 0f, 0f, 5f, 10f, 0, 0)); // 0
|
||||||
guns.add(new Gun("colt_1903", 0.3, 10, 5, 8, 38, 32, 5, 0, 0, 1, 3, 0.1f, 0.3f, -1, 1));
|
guns.add(new Gun("p2022", 0.2, 12, 5, 10, 41, 9, 5, 0, 0, 1f, 4, 0.1f, 0.25f, -1, 1)); // 1.8
|
||||||
guns.add(new Gun("colt_45", 0.4, 9, 5, 7, 48, 45, 5, 0, 0, 1.5f, 2, 0.15f, 0.4f, -1, 1));
|
guns.add(new Gun("colt_1903", 0.3, 10, 5, 8, 38, 32, 5, 0, 0, 1, 3, 0.1f, 0.3f, -1, 1)); // 3
|
||||||
guns.add(new Gun("colt_peacemaker", 0.6, 8, 5, 6, 43, 45, 5, 0, 0, 0.9f, 2, 0.2f, 0.5f, -1, 1));
|
guns.add(new Gun("ak_47", 0.2, 4, 5, 30, 45, 762, 0, 0, 0, 1f, 2, 0.2f, 0.4f, -1, 1)); // 9
|
||||||
guns.add(new Gun("p2022", 0.2, 12, 5, 10, 41, 9, 5, 0, 0, 1f, 4, 0.1f, 0.25f, -1, 1));
|
guns.add(new Gun("colt_45", 0.4, 9, 5, 7, 48, 45, 5, 0, 0, 1.5f, 2, 0.15f, 0.4f, -1, 1)); // 3.6
|
||||||
guns.add(new Gun("snub_nosed_revolver", 0.4, 7, 3, 5, 36, 38, 14, 0, 0, 1f, 2, 0.2f, 0.45f, -1, 1));
|
guns.add(new Gun("snub_nosed_revolver", 0.4, 7, 3, 5, 36, 38, 14, 0, 0, 1f, 2, 0.2f, 0.45f, -1, 1)); // 2.8
|
||||||
guns.add(new Gun("tokarev_tt_33", 0.7, 10, 5, 8, 45, 762, 5, 0, 0, 1.5f, 2.5f, 0.25f, 0.5f, -1, 1));
|
guns.add(new Gun("colt_peacemaker", 0.6, 8, 5, 6, 43, 45, 5, 0, 0, 0.9f, 2, 0.2f, 0.5f, -1, 1)); // 4.8
|
||||||
guns.add(new Gun("ak_47", 0.2, 4, 5, 30, 45, 762, 0, 0, 0, 1f, 2, 0.2f, 0.4f, -1, 1));
|
guns.add(new Gun("tokarev_tt_33", 0.7, 10, 5, 8, 45, 762, 5, 0, 0, 1.5f, 2.5f, 0.25f, 0.5f, -1, 1)); // 7
|
||||||
guns.add(new Gun("awp", 1, 4, 20, 1, 75, 762, 20, 0, 0, 2f, 8, 0.3f, 0.6f, -1, 1));
|
guns.add(new Gun("357_revolver", 1, 8, 5, 6, 45, 357, 14, 0, 0, 2, 4, 0.2f, 0.5f, -1, 1)); // 8
|
||||||
|
guns.add(new Gun("awp", 1, 4, 20, 1, 75, 762, 20, 0, 0, 2f, 8, 0.3f, 0.6f, -1, 1)); // 4
|
||||||
guns.add(new Gun("rpg9", 2, 4, 20, 1, 10, 999, 8, 20, 0, 3f, 0.5f, 1, 2, -1, 1));
|
guns.add(new Gun("rpg9", 2, 4, 20, 1, 10, 999, 8, 20, 0, 3f, 0.5f, 1, 2, -1, 1)); // 8
|
||||||
guns.add(new Gun("forcegun", 0, 2, 5, 20, 10, 888, 0, 0, 20, 0f, 0f, 5f, 10f, 0, 0));
|
|
||||||
|
|
||||||
|
|
||||||
grenades.add(new GrenadeItem("grenade_an_m14", 1, 5f, 0.5f, 40, true, false, 0, 0, 0, 8, 0)); // AN-M14 Incendiary Grenade
|
grenades.add(new GrenadeItem("grenade_m18", 1, 0.1f, 0.2f, 50, false, false, 0, 0, 100, 15, 30)); // 0.02
|
||||||
grenades.add(new GrenadeItem("grenade_m34", 1, 10f, 0.5f, 60, true, true, 0, 0, 0, 10, 0)); // M34 White Phosphorus Incendiary Fragmentation Grenade
|
grenades.add(new GrenadeItem("grenade_m7a3", 1, 0.1f, 0.2f, 90, false, false, 80, 40, 50, 8, 40)); // 0.02
|
||||||
grenades.add(new GrenadeItem("grenade_m18", 1, 0.1f, 0.2f, 50, false, false, 0, 0, 100, 15, 30)); // M18 Smoke Grenade
|
grenades.add(new GrenadeItem("grenade_m84", 1, 0.5f, 0.2f, 120, false, false, 160, 160, 5, 12, 10)); // 0.1
|
||||||
grenades.add(new GrenadeItem("grenade_m84", 1, 0.5f, 0.2f, 120, false, false, 10, 10, 5, 12, 10)); // M84 Stun Grenade (Flashbang)
|
grenades.add(new GrenadeItem("grenade_no_69", 1, 5.5f, 0.4f, 60, false, false, 0, 0, 0, 10, 0)); // 2.2
|
||||||
grenades.add(new GrenadeItem("grenade_rgd_5", 1, 6.5f, 0.5f, 60, false, true, 0, 0, 0, 10, 0)); // RGD-5 Fragmentation Grenade
|
grenades.add(new GrenadeItem("grenade_an_m14", 1, 5f, 0.5f, 40, true, false, 0, 0, 0, 8, 0)); // 2.5
|
||||||
grenades.add(new GrenadeItem("grenade_thermite", 1, 4f, 0.3f, 80, true, false, 0, 0, 0, 8, 15)); // Thermite Grenade
|
grenades.add(new GrenadeItem("grenade_thermite", 1, 4f, 0.3f, 80, true, false, 0, 0, 0, 8, 15)); // 1.2
|
||||||
grenades.add(new GrenadeItem("grenade_f1", 1, 7f, 0.5f, 60, false, true, 0, 0, 0, 10, 0)); // F1 Soviet Fragmentation Grenade
|
grenades.add(new GrenadeItem("grenade_mk3a2", 1, 6f, 0.4f, 60, false, false, 0, 0, 0, 10, 0)); // 2.4
|
||||||
grenades.add(new GrenadeItem("grenade_mk3a2", 1, 6f, 0.4f, 60, false, false, 0, 0, 0, 10, 0)); // Mk3A2 Offensive Grenade
|
grenades.add(new GrenadeItem("grenade_m34", 1, 10f, 0.5f, 60, true, true, 0, 0, 0, 10, 0)); // 5
|
||||||
grenades.add(new GrenadeItem("grenade_m7a3", 1, 0.1f, 0.2f, 90, false, false, 0, 0, 50, 8, 40)); // M7A3 CS Gas Grenade
|
grenades.add(new GrenadeItem("grenade_f1", 1, 7f, 0.5f, 60, false, true, 0, 0, 0, 10, 0)); // 3.5
|
||||||
grenades.add(new GrenadeItem("grenade_no_69", 1, 5.5f, 0.4f, 60, false, false, 0, 0, 0, 10, 0)); // No. 69 British Offensive Grenade
|
grenades.add(new GrenadeItem("grenade_rgd_5", 1, 6.5f, 0.5f, 60, false, true, 0, 0, 0, 10, 0)); // 3.25
|
||||||
grenades.add(new GrenadeItem("grenade_rgo", 1, 6.5f, 0.5f, 90, false, true, 0, 0, 0, 10, 0)); // RGO Fragmentation Grenade
|
grenades.add(new GrenadeItem("grenade_rgo", 1, 6.5f, 0.5f, 90, false, true, 0, 0, 0, 10, 0)); // 3.25
|
||||||
grenades.add(new GrenadeItem("grenade_k417", 1, 7f, 0.5f, 70, false, true, 0, 0, 0, 10, 0)); // K417 Fragmentation Grenade
|
grenades.add(new GrenadeItem("grenade_k417", 1, 7f, 0.5f, 70, false, true, 0, 0, 0, 10, 0)); // 3.5
|
||||||
|
|
||||||
|
|
||||||
weaponArmors.add(new WeaponArmor("kevlar_vest", 200, 0.8, 0.8, 0.4, 0.3));
|
weaponArmors.add(new WeaponArmor("kevlar_vest", 200, 0.8, 0.8, 0.4, 0.3));
|
||||||
weaponArmors.add(new WeaponArmor("flak_vest", 500, 0.8, 0.4, 0.8, 0.2));
|
weaponArmors.add(new WeaponArmor("flak_vest", 500, 0.8, 0.4, 0.8, 0.2));
|
||||||
@ -142,6 +150,10 @@ public class PlasticGun implements ModInitializer {
|
|||||||
craftingItems.add(new CraftingItem("titanium_alloy"));
|
craftingItems.add(new CraftingItem("titanium_alloy"));
|
||||||
craftingItems.add(new CraftingItem("trigger_mechanism"));
|
craftingItems.add(new CraftingItem("trigger_mechanism"));
|
||||||
|
|
||||||
|
itemGunMap = generateItemMap(guns);
|
||||||
|
itemBulletItemMap = generateItemMap(bullets);
|
||||||
|
itemGrenadeItemMap = generateItemMap(grenades);
|
||||||
|
itemShurikenItemMap = generateItemMap(shurikens);
|
||||||
|
|
||||||
GRENADE_ENTITY_TYPE = Registry.register(
|
GRENADE_ENTITY_TYPE = Registry.register(
|
||||||
Registries.ENTITY_TYPE,
|
Registries.ENTITY_TYPE,
|
||||||
|
@ -33,10 +33,10 @@ public class BulletEntity extends PersistentProjectileEntity implements PolymerE
|
|||||||
private ItemStack itemStack = Items.ARROW.getDefaultStack();
|
private ItemStack itemStack = Items.ARROW.getDefaultStack();
|
||||||
private final float scale;
|
private final float scale;
|
||||||
|
|
||||||
public BulletEntity(ServerPlayerEntity player, ItemStack stack, Hand hand, Gun gun, float scale, double damage, float speed, double explosionPower, double repulsionPower, boolean isIncendiary) {
|
public BulletEntity(LivingEntity livingEntity, ItemStack stack, Hand hand, Gun gun, float scale, double damage, float speed, double explosionPower, double repulsionPower, boolean isIncendiary) {
|
||||||
super(BULLET_ENTITY_TYPE, player.getPos().x, player.getPos().y + 1.5d, player.getPos().z, player.getServerWorld(), stack, player.getStackInHand(hand));
|
super(BULLET_ENTITY_TYPE, livingEntity.getPos().x, livingEntity.getPos().y + 1.75d, livingEntity.getPos().z, livingEntity.getEntityWorld(), stack, livingEntity.getStackInHand(hand));
|
||||||
this.setOwner(player);
|
this.setOwner(livingEntity);
|
||||||
this.setVelocity(player, player.getPitch(), player.getYaw(), 0.0F, speed, 0);
|
this.setVelocity(livingEntity, livingEntity.getPitch(), livingEntity.getYaw(), 0.0F, speed, 0);
|
||||||
this.pickupType = PickupPermission.DISALLOWED;
|
this.pickupType = PickupPermission.DISALLOWED;
|
||||||
this.setDamage(damage);
|
this.setDamage(damage);
|
||||||
this.setSilent(true);
|
this.setSilent(true);
|
||||||
|
@ -128,7 +128,7 @@ public class GrenadeEntity extends ThrowableProjectile implements PolymerEntity
|
|||||||
if (flashBangDuration > 0) {
|
if (flashBangDuration > 0) {
|
||||||
for (Entity entity : nearbyEntities) {
|
for (Entity entity : nearbyEntities) {
|
||||||
if (entity instanceof LivingEntity livingEntity) {
|
if (entity instanceof LivingEntity livingEntity) {
|
||||||
livingEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, stunDuration, 255, true, false));
|
livingEntity.addStatusEffect(new StatusEffectInstance(StatusEffects.BLINDNESS, flashBangDuration, 255, true, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flashBangDuration = 0;
|
flashBangDuration = 0;
|
||||||
|
@ -3,6 +3,7 @@ package systems.brn.plasticgun.grenades;
|
|||||||
import eu.pb4.polymer.core.api.item.PolymerItem;
|
import eu.pb4.polymer.core.api.item.PolymerItem;
|
||||||
import net.minecraft.component.DataComponentTypes;
|
import net.minecraft.component.DataComponentTypes;
|
||||||
import net.minecraft.component.type.LoreComponent;
|
import net.minecraft.component.type.LoreComponent;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.*;
|
import net.minecraft.item.*;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
@ -57,7 +58,7 @@ public class GrenadeItem extends SimpleItem implements PolymerItem {
|
|||||||
Text.translatable("gun.description.particle_count", smokeCount)
|
Text.translatable("gun.description.particle_count", smokeCount)
|
||||||
)))
|
)))
|
||||||
.maxDamage(explosionTarget + 1)
|
.maxDamage(explosionTarget + 1)
|
||||||
, id(path), Items.FLOWER_POT
|
, id(path), Items.STICK
|
||||||
);
|
);
|
||||||
this.explosionTarget = explosionTarget;
|
this.explosionTarget = explosionTarget;
|
||||||
this.isIncendiary = isIncendiary;
|
this.isIncendiary = isIncendiary;
|
||||||
@ -110,12 +111,18 @@ public class GrenadeItem extends SimpleItem implements PolymerItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void turnIntoEntity(ServerPlayerEntity player, @Nullable ItemStack stack, int speed, int timer) {
|
public void turnIntoEntity(ServerPlayerEntity player, @Nullable ItemStack stack, int speed, int timer) {
|
||||||
GrenadeEntity grenadeEntity = new GrenadeEntity(player, stack, timer, 1f, speed, explosionPower, repulsionPower, isIncendiary, isFragmentation, flashBangDuration, stunDuration, smokeTicks, 8, smokeCount);
|
GrenadeEntity grenadeEntity = new GrenadeEntity(player, stack, timer, 0.5f, speed, explosionPower, repulsionPower, isIncendiary, isFragmentation, flashBangDuration, stunDuration, smokeTicks, 8, smokeCount);
|
||||||
player.getServerWorld().spawnEntity(grenadeEntity);
|
player.getServerWorld().spawnEntity(grenadeEntity);
|
||||||
player.getServerWorld().playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
player.getServerWorld().playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void turnIntoEntity(Entity entity, @Nullable ItemStack stack, int speed, int timer) {
|
||||||
|
GrenadeEntity grenadeEntity = new GrenadeEntity(entity.getEntityWorld(), entity.getPos(), stack, timer, 1f, explosionPower, repulsionPower, isIncendiary, isFragmentation, flashBangDuration, stunDuration, smokeTicks, 8, smokeCount);
|
||||||
|
entity.getEntityWorld().spawnEntity(grenadeEntity);
|
||||||
|
entity.getEntityWorld().playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
public void checkExplosions(ServerWorld world, PlayerEntity playerEntity, ItemStack stackInSlot) {
|
public void checkExplosions(ServerWorld world, PlayerEntity playerEntity, ItemStack stackInSlot) {
|
||||||
if (playerEntity instanceof ServerPlayerEntity player && !world.isClient()) {
|
if (playerEntity instanceof ServerPlayerEntity player && !world.isClient()) {
|
||||||
int timer = stackInSlot.getOrDefault(GRENADE_TIMER_COMPONENT, -1);
|
int timer = stackInSlot.getOrDefault(GRENADE_TIMER_COMPONENT, -1);
|
||||||
|
@ -3,6 +3,9 @@ package systems.brn.plasticgun.guns;
|
|||||||
import eu.pb4.polymer.core.api.item.PolymerItem;
|
import eu.pb4.polymer.core.api.item.PolymerItem;
|
||||||
import net.minecraft.component.DataComponentTypes;
|
import net.minecraft.component.DataComponentTypes;
|
||||||
import net.minecraft.component.type.LoreComponent;
|
import net.minecraft.component.type.LoreComponent;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.*;
|
import net.minecraft.item.*;
|
||||||
import net.minecraft.network.packet.s2c.play.PositionFlag;
|
import net.minecraft.network.packet.s2c.play.PositionFlag;
|
||||||
@ -16,7 +19,9 @@ import net.minecraft.text.Text;
|
|||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.random.Random;
|
import net.minecraft.util.math.random.Random;
|
||||||
|
import net.minecraft.world.LocalDifficulty;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
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;
|
||||||
@ -25,6 +30,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static systems.brn.plasticgun.PlasticGun.bullets;
|
import static systems.brn.plasticgun.PlasticGun.bullets;
|
||||||
|
import static systems.brn.plasticgun.PlasticGun.itemBulletItemMap;
|
||||||
import static systems.brn.plasticgun.lib.GunComponents.*;
|
import static systems.brn.plasticgun.lib.GunComponents.*;
|
||||||
import static systems.brn.plasticgun.lib.Util.*;
|
import static systems.brn.plasticgun.lib.Util.*;
|
||||||
|
|
||||||
@ -112,6 +118,7 @@ public class Gun extends SimpleItem implements PolymerItem {
|
|||||||
stack.remove(GUN_AMMO_COMPONENT);
|
stack.remove(GUN_AMMO_COMPONENT);
|
||||||
} else {
|
} else {
|
||||||
stack.set(GUN_AMMO_COMPONENT, chamber);
|
stack.set(GUN_AMMO_COMPONENT, chamber);
|
||||||
|
stack.set(GUN_LAST_LOADED_AMMO, bulletStack);
|
||||||
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.PLAYERS, 0.5f, 1.0f);
|
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.PLAYERS, 0.5f, 1.0f);
|
||||||
}
|
}
|
||||||
stack.set(GUN_LOADING_COMPONENT, 1);
|
stack.set(GUN_LOADING_COMPONENT, 1);
|
||||||
@ -126,6 +133,7 @@ public class Gun extends SimpleItem implements PolymerItem {
|
|||||||
stack.remove(GUN_AMMO_COMPONENT);
|
stack.remove(GUN_AMMO_COMPONENT);
|
||||||
} else {
|
} else {
|
||||||
stack.set(GUN_AMMO_COMPONENT, chamber);
|
stack.set(GUN_AMMO_COMPONENT, chamber);
|
||||||
|
stack.set(GUN_LAST_LOADED_AMMO, bulletStack);
|
||||||
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.PLAYERS, 1f, 2.5f);
|
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.PLAYERS, 1f, 2.5f);
|
||||||
}
|
}
|
||||||
bulletStack.decrement(targetCount);
|
bulletStack.decrement(targetCount);
|
||||||
@ -136,6 +144,7 @@ public class Gun extends SimpleItem implements PolymerItem {
|
|||||||
}
|
}
|
||||||
if (player.isCreative()) {
|
if (player.isCreative()) {
|
||||||
stack.set(GUN_AMMO_COMPONENT, new ItemStack(ammo.getFirst(), clipSize)); // Ensure ammo.get(0) is a valid item
|
stack.set(GUN_AMMO_COMPONENT, new ItemStack(ammo.getFirst(), clipSize)); // Ensure ammo.get(0) is a valid item
|
||||||
|
stack.set(GUN_LAST_LOADED_AMMO, bulletStack);
|
||||||
}
|
}
|
||||||
updateDamage(stack);
|
updateDamage(stack);
|
||||||
} else {
|
} else {
|
||||||
@ -144,6 +153,36 @@ public class Gun extends SimpleItem implements PolymerItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reload(World world, MobEntity mobEntity, Hand hand, Random random, LocalDifficulty localDifficulty) {
|
||||||
|
if (!world.isClient()) {
|
||||||
|
ItemStack stack = mobEntity.getStackInHand(hand);
|
||||||
|
int currentReloadCooldown = stack.getOrDefault(GUN_RELOAD_COOLDOWN_COMPONENT, 0);
|
||||||
|
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY);
|
||||||
|
int bulletsInChamber = chamber.getCount();
|
||||||
|
int currentReload = stack.getOrDefault(GUN_LOADING_COMPONENT, 1);
|
||||||
|
if (currentReload == 1 && bulletsInChamber > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentReloadCooldown == 0) {
|
||||||
|
stack.set(GUN_RELOAD_COOLDOWN_COMPONENT, reloadTarget);
|
||||||
|
ItemStack oldChamber = stack.getOrDefault(GUN_LAST_LOADED_AMMO, ItemStack.EMPTY);
|
||||||
|
Item ammoItem = (oldChamber == null || oldChamber.isEmpty())
|
||||||
|
? ammo.get(selectWeaponIndex(random, localDifficulty, ammo.size()))
|
||||||
|
: oldChamber.getItem();
|
||||||
|
ItemStack bulletStack = new ItemStack(ammoItem, world.getRandom().nextBetween(1, ammoItem.getMaxCount()));
|
||||||
|
if (!bulletStack.isEmpty()) { // we have ammo
|
||||||
|
if (currentReload < reloadCount) { // still reloading
|
||||||
|
stack.set(GUN_LOADING_COMPONENT, currentReload + 1);
|
||||||
|
} else if (currentReload == reloadCount) { // now reload
|
||||||
|
stack.set(GUN_AMMO_COMPONENT, bulletStack);
|
||||||
|
stack.set(GUN_LAST_LOADED_AMMO, bulletStack);
|
||||||
|
stack.set(GUN_LOADING_COMPONENT, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void updateDamage(ItemStack stack) {
|
public void updateDamage(ItemStack stack) {
|
||||||
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
|
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
|
||||||
BulletItem bulletItem = null;
|
BulletItem bulletItem = null;
|
||||||
@ -194,40 +233,60 @@ public class Gun extends SimpleItem implements PolymerItem {
|
|||||||
stack.set(DataComponentTypes.LORE, newLore);
|
stack.set(DataComponentTypes.LORE, newLore);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doRecoil(ServerPlayerEntity player) {
|
public void doRecoil(LivingEntity entity) {
|
||||||
Random rng = player.getServerWorld().getRandom();
|
if (entity.getEntityWorld() instanceof ServerWorld serverWorld) {
|
||||||
// Get the player's current position and yaw
|
Random rng = entity.getWorld().getRandom();
|
||||||
Vec3d pos = player.getPos();
|
// Get the entity's current position and yaw
|
||||||
float yaw = player.getYaw();
|
Vec3d pos = entity.getPos();
|
||||||
float newPitch = player.getPitch();
|
float yaw = entity.getYaw();
|
||||||
Vec3d currentLook = player.getRotationVector().multiply(-1);
|
float newPitch = entity.getPitch();
|
||||||
|
Vec3d currentLook = entity.getRotationVector().multiply(-1);
|
||||||
newPitch -= verticalRecoilMin + rng.nextFloat() * (verticalRecoilMax - verticalRecoilMin);
|
newPitch -= verticalRecoilMin + rng.nextFloat() * (verticalRecoilMax - verticalRecoilMin);
|
||||||
yaw -= (float) (horizontalRecoilMin + rng.nextFloat() * (horizontalRecoilMax - horizontalRecoilMin));
|
yaw -= (float) (horizontalRecoilMin + rng.nextFloat() * (horizontalRecoilMax - horizontalRecoilMin));
|
||||||
|
|
||||||
|
|
||||||
player.teleport(player.getServerWorld(), pos.x, pos.y, pos.z, PositionFlag.ROT, yaw, newPitch);
|
entity.teleport(serverWorld, pos.x, pos.y, pos.z, PositionFlag.ROT, yaw, newPitch);
|
||||||
double velocityRecoil = rng.nextDouble() * (velocityRecoilMax - velocityRecoilMin);
|
double velocityRecoil = rng.nextDouble() * (velocityRecoilMax - velocityRecoilMin);
|
||||||
if (velocityRecoil > 0) {
|
if (velocityRecoil > 0) {
|
||||||
player.setVelocity(currentLook.multiply(velocityRecoil));
|
entity.setVelocity(currentLook.multiply(velocityRecoil));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shoot(ServerWorld world, PlayerEntity user, Hand hand) {
|
public void shoot(ServerWorld world, LivingEntity user, Hand hand) {
|
||||||
if (user instanceof ServerPlayerEntity player && !world.isClient()) {
|
if (!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);
|
||||||
int currentCooldown = stack.getOrDefault(GUN_COOLDOWN_COMPONENT, 0);
|
int currentCooldown = stack.getOrDefault(GUN_COOLDOWN_COMPONENT, 0);
|
||||||
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
|
ItemStack chamber = stack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
|
||||||
|
|
||||||
BulletItem bullet = null;
|
BulletItem bullet = null;
|
||||||
for (BulletItem bulletTemp : bullets) {
|
if (itemBulletItemMap.containsKey(chamber.getItem())) {
|
||||||
if (bulletTemp == chamber.getItem()) {
|
bullet = itemBulletItemMap.get(chamber.getItem());
|
||||||
bullet = bulletTemp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chamber.isEmpty() && currentReload == 1 && currentCooldown == 0) {
|
if (!chamber.isEmpty() && currentReload == 1 && currentCooldown == 0) {
|
||||||
|
BulletEntity bulletEntity = getBulletEntity(user, hand, bullet, chamber);
|
||||||
|
world.spawnEntity(bulletEntity);
|
||||||
|
world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENTITY_GENERIC_EXPLODE.value(), SoundCategory.PLAYERS, 0.1f, 1.2f);
|
||||||
|
chamber.decrement(1);
|
||||||
|
stack.set(GUN_COOLDOWN_COMPONENT, cooldownTarget);
|
||||||
|
doRecoil(user);
|
||||||
|
if (chamber.isEmpty()) {
|
||||||
|
stack.remove(GUN_AMMO_COMPONENT);
|
||||||
|
} else {
|
||||||
|
stack.set(GUN_AMMO_COMPONENT, chamber);
|
||||||
|
}
|
||||||
|
} else if (cooldownTarget > 0) {
|
||||||
|
world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.PLAYERS, 1.0f, 2.0f);
|
||||||
|
} else if (currentReload > 1) {
|
||||||
|
world.playSound(null, user.getX(), user.getY(), user.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
||||||
|
}
|
||||||
|
updateDamage(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull BulletEntity getBulletEntity(LivingEntity entity, Hand hand, BulletItem bullet, ItemStack chamber) {
|
||||||
boolean isIncendiary = false;
|
boolean isIncendiary = false;
|
||||||
double explosionPower = explosionPowerGun;
|
double explosionPower = explosionPowerGun;
|
||||||
double repulsionPower = repulsionPowerGun;
|
double repulsionPower = repulsionPowerGun;
|
||||||
@ -238,23 +297,6 @@ public class Gun extends SimpleItem implements PolymerItem {
|
|||||||
repulsionPower *= bullet.repulsionPowerCoefficient;
|
repulsionPower *= bullet.repulsionPowerCoefficient;
|
||||||
}
|
}
|
||||||
|
|
||||||
BulletEntity bulletEntity = new BulletEntity(player, chamber, hand, this, 1f, damage, speed, explosionPower, repulsionPower, isIncendiary);
|
return new BulletEntity(entity, chamber, hand, this, 0.25f, damage, speed, explosionPower, repulsionPower, isIncendiary);
|
||||||
world.spawnEntity(bulletEntity);
|
|
||||||
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENTITY_GENERIC_EXPLODE.value(), SoundCategory.PLAYERS, 0.1f, 1.2f);
|
|
||||||
chamber.decrement(1);
|
|
||||||
stack.set(GUN_COOLDOWN_COMPONENT, cooldownTarget);
|
|
||||||
doRecoil(player);
|
|
||||||
if (chamber.isEmpty()) {
|
|
||||||
stack.remove(GUN_AMMO_COMPONENT);
|
|
||||||
} else {
|
|
||||||
stack.set(GUN_AMMO_COMPONENT, chamber);
|
|
||||||
}
|
|
||||||
} else if (cooldownTarget > 0) {
|
|
||||||
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.BLOCK_FIRE_EXTINGUISH, SoundCategory.PLAYERS, 1.0f, 2.0f);
|
|
||||||
} else if (currentReload > 1) {
|
|
||||||
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
|
||||||
}
|
|
||||||
updateDamage(stack);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
181
src/main/java/systems/brn/plasticgun/guns/WeaponShootGoal.java
Normal file
181
src/main/java/systems/brn/plasticgun/guns/WeaponShootGoal.java
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
package systems.brn.plasticgun.guns;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Source code recreated from a .class file by IntelliJ IDEA
|
||||||
|
// (powered by FernFlower decompiler)
|
||||||
|
//
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.RangedAttackMob;
|
||||||
|
import net.minecraft.entity.ai.goal.Goal;
|
||||||
|
import net.minecraft.entity.mob.HostileEntity;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
|
import net.minecraft.item.BowItem;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
|
import static systems.brn.plasticgun.PlasticGun.guns;
|
||||||
|
import static systems.brn.plasticgun.PlasticGun.itemGunMap;
|
||||||
|
import static systems.brn.plasticgun.lib.GunComponents.*;
|
||||||
|
|
||||||
|
public class WeaponShootGoal<T extends HostileEntity & RangedAttackMob> extends Goal {
|
||||||
|
private final T actor;
|
||||||
|
private final double speed;
|
||||||
|
private final float squaredRange;
|
||||||
|
private int targetSeeingTicker;
|
||||||
|
private boolean movingToLeft;
|
||||||
|
private boolean backward;
|
||||||
|
private int combatTicks = -1;
|
||||||
|
private int lockedTicks = 0;
|
||||||
|
|
||||||
|
public WeaponShootGoal(T actor, double speed, float range) {
|
||||||
|
this.actor = actor;
|
||||||
|
this.speed = speed;
|
||||||
|
this.squaredRange = range * range;
|
||||||
|
this.setControls(EnumSet.of(Control.MOVE, Control.LOOK));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canStart() {
|
||||||
|
return this.actor.getTarget() != null && this.isHoldingGun();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isHoldingGun() {
|
||||||
|
ItemStack mainHandStack = this.actor.getMainHandStack();
|
||||||
|
ItemStack offhandHandStack = this.actor.getOffHandStack();
|
||||||
|
return itemGunMap.containsKey(mainHandStack.getItem()) || itemGunMap.containsKey(offhandHandStack.getItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldContinue() {
|
||||||
|
return (this.canStart() || !this.actor.getNavigation().isIdle()) && this.isHoldingGun();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
super.start();
|
||||||
|
this.actor.setAttacking(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
super.stop();
|
||||||
|
this.actor.setAttacking(false);
|
||||||
|
this.targetSeeingTicker = 0;
|
||||||
|
this.actor.clearActiveItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldRunEveryTick() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLookingAtEntity(Entity targetEntity, float yawThreshold, float pitchThreshold) {
|
||||||
|
double deltaX = targetEntity.getX() - this.actor.getX();
|
||||||
|
double deltaZ = targetEntity.getZ() - this.actor.getZ();
|
||||||
|
double deltaY;
|
||||||
|
|
||||||
|
if (targetEntity instanceof LivingEntity livingEntity) {
|
||||||
|
deltaY = livingEntity.getEyeY() - this.actor.getEyeY();
|
||||||
|
} else {
|
||||||
|
deltaY = (targetEntity.getBoundingBox().minY + targetEntity.getBoundingBox().maxY) / 2.0 - this.actor.getEyeY();
|
||||||
|
}
|
||||||
|
|
||||||
|
double distance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ);
|
||||||
|
float targetYaw = (float) (MathHelper.atan2(deltaZ, deltaX) * (180 / Math.PI)) - 90.0F;
|
||||||
|
float targetPitch = (float) (-(MathHelper.atan2(deltaY, distance) * (180 / Math.PI)));
|
||||||
|
|
||||||
|
float currentYaw = this.actor.getYaw();
|
||||||
|
float currentPitch = this.actor.getPitch();
|
||||||
|
|
||||||
|
float yawDifference = MathHelper.wrapDegrees(currentYaw - targetYaw);
|
||||||
|
float pitchDifference = MathHelper.wrapDegrees(currentPitch - targetPitch);
|
||||||
|
|
||||||
|
return Math.abs(yawDifference) < yawThreshold && Math.abs(pitchDifference) < pitchThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
LivingEntity livingEntity = this.actor.getTarget();
|
||||||
|
if (livingEntity != null) {
|
||||||
|
double d = this.actor.squaredDistanceTo(livingEntity.getX(), livingEntity.getY(), livingEntity.getZ());
|
||||||
|
boolean canSeeTarget = this.actor.getVisibilityCache().canSee(livingEntity);
|
||||||
|
boolean wasSeeingTarget = this.targetSeeingTicker > 0;
|
||||||
|
|
||||||
|
// Update target seeing ticker based on visibility
|
||||||
|
if (canSeeTarget != wasSeeingTarget) {
|
||||||
|
this.targetSeeingTicker = 0;
|
||||||
|
}
|
||||||
|
this.targetSeeingTicker = canSeeTarget ? this.targetSeeingTicker + 1 : this.targetSeeingTicker - 1;
|
||||||
|
|
||||||
|
// Manage navigation and combat ticks
|
||||||
|
if (d <= this.squaredRange && this.targetSeeingTicker >= 20) {
|
||||||
|
this.actor.getNavigation().stop();
|
||||||
|
this.combatTicks++;
|
||||||
|
} else {
|
||||||
|
this.actor.getNavigation().startMovingTo(livingEntity, this.speed);
|
||||||
|
this.combatTicks = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Randomize movement directions
|
||||||
|
if (this.combatTicks >= 20) {
|
||||||
|
if (this.actor.getRandom().nextFloat() < 0.3) {
|
||||||
|
this.movingToLeft = !this.movingToLeft;
|
||||||
|
}
|
||||||
|
if (this.actor.getRandom().nextFloat() < 0.3) {
|
||||||
|
this.backward = !this.backward;
|
||||||
|
}
|
||||||
|
this.combatTicks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update strafing behavior
|
||||||
|
if (this.combatTicks > -1) {
|
||||||
|
if (d > this.squaredRange * 0.75) {
|
||||||
|
this.backward = false;
|
||||||
|
} else if (d < this.squaredRange * 0.25) {
|
||||||
|
this.backward = true;
|
||||||
|
}
|
||||||
|
this.actor.getMoveControl().strafeTo(this.backward ? -0.5F : 0.5F, this.movingToLeft ? 0.5F : -0.5F);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simplified looking at the target
|
||||||
|
this.actor.lookAtEntity(livingEntity, 30.0F, 30.0F);
|
||||||
|
if (isLookingAtEntity(livingEntity, 1, 1)) {
|
||||||
|
lockedTicks++;
|
||||||
|
} else {
|
||||||
|
lockedTicks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hand gunHand = this.actor.getActiveHand();
|
||||||
|
ItemStack gunStack = this.actor.getStackInHand(gunHand);
|
||||||
|
if (itemGunMap.containsKey(gunStack.getItem())) {
|
||||||
|
Gun gun = itemGunMap.get(gunStack.getItem());
|
||||||
|
// Handle item usage
|
||||||
|
gun.reload(this.actor.getEntityWorld(), this.actor, gunHand, this.actor.getRandom(), this.actor.getWorld().getLocalDifficulty(this.actor.getBlockPos()));
|
||||||
|
if (!canSeeTarget && this.targetSeeingTicker < -60) {
|
||||||
|
this.actor.clearActiveItem();
|
||||||
|
} else if (canSeeTarget) {
|
||||||
|
this.actor.clearActiveItem();
|
||||||
|
int currentReload = gunStack.getOrDefault(GUN_LOADING_COMPONENT, 1);
|
||||||
|
int currentCooldown = gunStack.getOrDefault(GUN_COOLDOWN_COMPONENT, 1);
|
||||||
|
ItemStack chamber = gunStack.getOrDefault(GUN_AMMO_COMPONENT, ItemStack.EMPTY).copy();
|
||||||
|
if (!chamber.isEmpty() && currentReload == 1 && currentCooldown == 0 && lockedTicks >= 10) {
|
||||||
|
if (this.actor.getEntityWorld() instanceof ServerWorld serverWorld) {
|
||||||
|
gun.shoot(serverWorld, this.actor, gunHand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.targetSeeingTicker >= -60) {
|
||||||
|
ItemStack mainHand = this.actor.getStackInHand(Hand.MAIN_HAND);
|
||||||
|
ItemStack offHand = this.actor.getStackInHand(Hand.OFF_HAND);
|
||||||
|
if (itemGunMap.containsKey(mainHand.getItem())) {
|
||||||
|
this.actor.setCurrentHand(Hand.MAIN_HAND);
|
||||||
|
}
|
||||||
|
if (itemGunMap.containsKey(offHand.getItem())) {
|
||||||
|
this.actor.setCurrentHand(Hand.OFF_HAND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package systems.brn.plasticgun.lib;
|
package systems.brn.plasticgun.lib;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.entity.ItemEntity;
|
import net.minecraft.entity.ItemEntity;
|
||||||
|
import net.minecraft.entity.mob.SkeletonEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
@ -26,24 +28,14 @@ public class EventHandler {
|
|||||||
ItemStack stack = playerEntity.getStackInHand(hand);
|
ItemStack stack = playerEntity.getStackInHand(hand);
|
||||||
if (!world.isClient) {
|
if (!world.isClient) {
|
||||||
Item stackInHand = playerEntity.getStackInHand(hand).getItem();
|
Item stackInHand = playerEntity.getStackInHand(hand).getItem();
|
||||||
for (Gun gun : guns) {
|
if (itemGunMap.containsKey(stackInHand)) {
|
||||||
if (gun == stackInHand) {
|
itemGunMap.get(stackInHand).reload(world, playerEntity, hand);
|
||||||
gun.reload(world, playerEntity, hand);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (itemGrenadeItemMap.containsKey(stackInHand)) {
|
||||||
|
itemGrenadeItemMap.get(stackInHand).unpin(world, playerEntity, hand);
|
||||||
}
|
}
|
||||||
for (GrenadeItem grenade : grenades) {
|
if (itemShurikenItemMap.containsKey(stackInHand)) {
|
||||||
if (grenade != null && grenade == stackInHand) {
|
itemShurikenItemMap.get(stackInHand).chuck(world, playerEntity, hand);
|
||||||
grenade.unpin(world, playerEntity, hand);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ShurikenItem shuriken : shurikens) {
|
|
||||||
if (shuriken != null && shuriken == stackInHand) {
|
|
||||||
shuriken.chuck(world, playerEntity, hand);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -58,64 +50,55 @@ public class EventHandler {
|
|||||||
Hand hand = player.getActiveHand();
|
Hand hand = player.getActiveHand();
|
||||||
ItemStack stackInHand = player.getStackInHand(hand);
|
ItemStack stackInHand = player.getStackInHand(hand);
|
||||||
Item itemInHand = stackInHand.getItem();
|
Item itemInHand = stackInHand.getItem();
|
||||||
for (Gun gun : guns) {
|
|
||||||
if (gun == itemInHand) {
|
if (itemGunMap.containsKey(itemInHand)) {
|
||||||
decrementComponent(GUN_COOLDOWN_COMPONENT, stackInHand);
|
decrementComponent(GUN_COOLDOWN_COMPONENT, stackInHand);
|
||||||
decrementComponent(GUN_RELOAD_COOLDOWN_COMPONENT, stackInHand);
|
decrementComponent(GUN_RELOAD_COOLDOWN_COMPONENT, stackInHand);
|
||||||
|
|
||||||
if (player.handSwinging && player.handSwingTicks == -1) {
|
if (player.handSwinging && player.handSwingTicks == -1) {
|
||||||
gun.shoot(world, player, hand);
|
itemGunMap.get(itemInHand).shoot(world, player, hand);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (itemGrenadeItemMap.containsKey(itemInHand)) {
|
||||||
|
itemGrenadeItemMap.get(itemInHand).chuck(world, player, hand);
|
||||||
for (GrenadeItem grenade : grenades) {
|
|
||||||
if (grenade != null && grenade == itemInHand) {
|
|
||||||
if (player.handSwinging && player.handSwingTicks == -1) {
|
|
||||||
grenade.chuck(world, player, hand);
|
|
||||||
}
|
}
|
||||||
break;
|
if (itemShurikenItemMap.containsKey(itemInHand)) {
|
||||||
|
itemShurikenItemMap.get(itemInHand).chuck(world, player, hand);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (ShurikenItem shuriken : shurikens) {
|
|
||||||
if (shuriken != null && shuriken == itemInHand) {
|
|
||||||
if (player.handSwinging && player.handSwingTicks == -1) {
|
|
||||||
shuriken.chuck(world, player, hand);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PlayerInventory playerInventory = player.getInventory();
|
PlayerInventory playerInventory = player.getInventory();
|
||||||
for (int i = 1; i < playerInventory.main.size(); i++) {
|
for (int i = 1; i < playerInventory.main.size(); i++) {
|
||||||
ItemStack stackInSlot = playerInventory.main.get(i);
|
ItemStack stackInSlot = playerInventory.main.get(i);
|
||||||
Item itemInSlot = stackInSlot.getItem();
|
Item itemInSlot = stackInSlot.getItem();
|
||||||
for (GrenadeItem grenadeItem : grenades) {
|
if (itemGrenadeItemMap.containsKey(itemInSlot)) {
|
||||||
if (grenadeItem == itemInSlot) {
|
|
||||||
decrementComponent(GRENADE_TIMER_COMPONENT, stackInSlot);
|
decrementComponent(GRENADE_TIMER_COMPONENT, stackInSlot);
|
||||||
|
GrenadeItem grenadeItem = itemGrenadeItemMap.get(itemInHand);
|
||||||
GrenadeItem.updateDamage(stackInSlot, grenadeItem);
|
GrenadeItem.updateDamage(stackInSlot, grenadeItem);
|
||||||
grenadeItem.checkExplosions(world, player, stackInSlot);
|
grenadeItem.checkExplosions(world, player, stackInSlot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (SkeletonEntity skeletonEntity : world.getEntitiesByType(EntityType.SKELETON, entity -> true)) {
|
||||||
|
for (ItemStack itemStack : skeletonEntity.getEquippedItems()) {
|
||||||
|
if (itemGunMap.containsKey(itemStack.getItem())) {
|
||||||
|
decrementComponent(GUN_COOLDOWN_COMPONENT, itemStack);
|
||||||
|
decrementComponent(GUN_RELOAD_COOLDOWN_COMPONENT, itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onEntityLoad(Entity entity, ServerWorld world) {
|
public static void onEntityLoad(Entity entity, ServerWorld world) {
|
||||||
if (entity instanceof ItemEntity itemEntity) {
|
if (entity instanceof ItemEntity itemEntity) {
|
||||||
ItemStack entityStack = itemEntity.getStack();
|
ItemStack entityStack = itemEntity.getStack();
|
||||||
for (GrenadeItem grenadeItem : grenades) {
|
Item item = entityStack.getItem();
|
||||||
if (entityStack.getItem() == grenadeItem) {
|
if (itemGrenadeItemMap.containsKey(item)) {
|
||||||
|
GrenadeItem grenadeItem = itemGrenadeItemMap.get(item);
|
||||||
Entity owner = itemEntity.getOwner();
|
Entity owner = itemEntity.getOwner();
|
||||||
int timer = (1 + grenadeItem.explosionTarget) - entityStack.getDamage();
|
int timer = (1 + grenadeItem.explosionTarget) - entityStack.getDamage();
|
||||||
if (timer <= grenadeItem.explosionTarget) {
|
if (timer <= grenadeItem.explosionTarget) {
|
||||||
if (owner instanceof ServerPlayerEntity player) {
|
if (owner instanceof ServerPlayerEntity player) {
|
||||||
GrenadeEntity grenadeEntity = new GrenadeEntity(player, entityStack, timer, 1f, 0, grenadeItem.explosionPower, grenadeItem.repulsionPower, grenadeItem.isIncendiary, grenadeItem.isFragmentation, grenadeItem.flashBangDuration, grenadeItem.stunDuration, grenadeItem.smokeTicks, grenadeItem.smokeRadius, grenadeItem.smokeCount);
|
GrenadeEntity grenadeEntity = new GrenadeEntity(player, entityStack, timer, 0.5f, 0, grenadeItem.explosionPower, grenadeItem.repulsionPower, grenadeItem.isIncendiary, grenadeItem.isFragmentation, grenadeItem.flashBangDuration, grenadeItem.stunDuration, grenadeItem.smokeTicks, grenadeItem.smokeRadius, grenadeItem.smokeCount);
|
||||||
grenadeEntity.setVelocity(entity.getVelocity());
|
grenadeEntity.setVelocity(entity.getVelocity());
|
||||||
world.spawnEntity(grenadeEntity);
|
world.spawnEntity(grenadeEntity);
|
||||||
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.UI_BUTTON_CLICK.value(), SoundCategory.PLAYERS, 1.0f, 2.0f);
|
||||||
@ -126,8 +109,6 @@ public class EventHandler {
|
|||||||
}
|
}
|
||||||
entity.discard();
|
entity.discard();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package systems.brn.plasticgun.lib;
|
|||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import eu.pb4.polymer.core.api.other.PolymerComponent;
|
import eu.pb4.polymer.core.api.other.PolymerComponent;
|
||||||
import net.minecraft.component.ComponentType;
|
import net.minecraft.component.ComponentType;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
@ -15,6 +16,7 @@ public class GunComponents {
|
|||||||
public static final ComponentType<Integer> GUN_LOADING_COMPONENT = register("gun_load", builder -> builder.codec(Codec.INT));
|
public static final ComponentType<Integer> GUN_LOADING_COMPONENT = register("gun_load", builder -> builder.codec(Codec.INT));
|
||||||
public static final ComponentType<Integer> GUN_COOLDOWN_COMPONENT = register("gun_cooldown", builder -> builder.codec(Codec.INT));
|
public static final ComponentType<Integer> GUN_COOLDOWN_COMPONENT = register("gun_cooldown", builder -> builder.codec(Codec.INT));
|
||||||
public static final ComponentType<Integer> GUN_RELOAD_COOLDOWN_COMPONENT = register("gun_reload_cooldown", builder -> builder.codec(Codec.INT));
|
public static final ComponentType<Integer> GUN_RELOAD_COOLDOWN_COMPONENT = register("gun_reload_cooldown", builder -> builder.codec(Codec.INT));
|
||||||
|
public static final ComponentType<ItemStack> GUN_LAST_LOADED_AMMO = register("gun_last_load", builder -> builder.codec(ItemStack.CODEC));
|
||||||
public static final ComponentType<Integer> GRENADE_TIMER_COMPONENT = register("grenade_tuner", builder -> builder.codec(Codec.INT));
|
public static final ComponentType<Integer> GRENADE_TIMER_COMPONENT = register("grenade_tuner", builder -> builder.codec(Codec.INT));
|
||||||
|
|
||||||
private static <T> ComponentType<T> register(String id, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
|
private static <T> ComponentType<T> register(String id, UnaryOperator<ComponentType.Builder<T>> builderOperator) {
|
||||||
|
@ -22,16 +22,18 @@ import net.minecraft.util.Pair;
|
|||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.util.math.random.Random;
|
||||||
|
import net.minecraft.world.Difficulty;
|
||||||
|
import net.minecraft.world.LocalDifficulty;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.explosion.Explosion;
|
import net.minecraft.world.explosion.Explosion;
|
||||||
import net.minecraft.world.explosion.ExplosionBehavior;
|
import net.minecraft.world.explosion.ExplosionBehavior;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
import systems.brn.plasticgun.PlasticGun;
|
||||||
import systems.brn.plasticgun.defence.WeaponArmor;
|
import systems.brn.plasticgun.defence.WeaponArmor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import static net.minecraft.world.explosion.Explosion.getExposure;
|
import static net.minecraft.world.explosion.Explosion.getExposure;
|
||||||
import static systems.brn.plasticgun.PlasticGun.MOD_ID;
|
import static systems.brn.plasticgun.PlasticGun.MOD_ID;
|
||||||
@ -220,4 +222,43 @@ public class Util {
|
|||||||
}
|
}
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends Item> Map<Item, T> generateItemMap(List<T> extendedItems) {
|
||||||
|
Map<Item, T> itemMap = new HashMap<>();
|
||||||
|
for (T item : extendedItems) {
|
||||||
|
itemMap.put(item, item);
|
||||||
|
}
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDifficultyAdjustedChance(LocalDifficulty localDifficulty, World world) {
|
||||||
|
Difficulty worldDifficulty = world.getDifficulty();
|
||||||
|
|
||||||
|
// Calculate chance modifiers based on difficulties
|
||||||
|
float localDifficultyFactor = localDifficulty.getLocalDifficulty();
|
||||||
|
int worldDifficultyFactor = switch (worldDifficulty) {
|
||||||
|
case PEACEFUL -> 0;
|
||||||
|
case EASY -> 1;
|
||||||
|
case NORMAL -> 2;
|
||||||
|
case HARD -> 3;
|
||||||
|
default -> 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Determine the chance to equip a gun
|
||||||
|
int baseChance = 20; // Base chance denominator
|
||||||
|
return (int) (baseChance / (localDifficultyFactor * worldDifficultyFactor));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static int selectWeaponIndex(Random random, LocalDifficulty localDifficulty, int size) {
|
||||||
|
double difficultyFactor = localDifficulty.getClampedLocalDifficulty();
|
||||||
|
double biasFactor = 1.0 - difficultyFactor; // Higher difficulty means lower index less likely
|
||||||
|
|
||||||
|
// Bias towards lower indices
|
||||||
|
double r = random.nextDouble() * biasFactor;
|
||||||
|
int index = (int) (r * size * size);
|
||||||
|
|
||||||
|
// Ensure index is within bounds
|
||||||
|
return Math.min(index, size - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
package systems.brn.plasticgun.mixins;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.ai.goal.BowAttackGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.GoalSelector;
|
||||||
|
import net.minecraft.entity.ai.goal.MeleeAttackGoal;
|
||||||
|
import net.minecraft.entity.mob.AbstractSkeletonEntity;
|
||||||
|
import net.minecraft.entity.projectile.ProjectileUtil;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.item.RangedWeaponItem;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.math.random.Random;
|
||||||
|
import net.minecraft.world.Difficulty;
|
||||||
|
import net.minecraft.world.LocalDifficulty;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
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;
|
||||||
|
import systems.brn.plasticgun.PlasticGun;
|
||||||
|
import systems.brn.plasticgun.guns.Gun;
|
||||||
|
import systems.brn.plasticgun.guns.WeaponShootGoal;
|
||||||
|
|
||||||
|
import static systems.brn.plasticgun.PlasticGun.guns;
|
||||||
|
import static systems.brn.plasticgun.PlasticGun.itemGunMap;
|
||||||
|
import static systems.brn.plasticgun.lib.Util.getDifficultyAdjustedChance;
|
||||||
|
|
||||||
|
@Mixin(AbstractSkeletonEntity.class)
|
||||||
|
public class AbstractSkeletonEntityGunMixin {
|
||||||
|
@Unique
|
||||||
|
protected boolean isHoldingGun() {
|
||||||
|
AbstractSkeletonEntity thisObject = (AbstractSkeletonEntity) (Object) this;
|
||||||
|
ItemStack mainHandStack = thisObject.getMainHandStack();
|
||||||
|
ItemStack offhandHandStack = thisObject.getOffHandStack();
|
||||||
|
return itemGunMap.containsKey(mainHandStack.getItem()) || itemGunMap.containsKey(offhandHandStack.getItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "canUseRangedWeapon", at = @At("HEAD"), cancellable = true)
|
||||||
|
public void canUseRangedWeapon(RangedWeaponItem weapon, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
cir.setReturnValue(weapon == Items.BOW || itemGunMap.containsKey(weapon));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "updateAttackType", at = @At("HEAD"), cancellable = true)
|
||||||
|
public void updateAttackType(CallbackInfo ci) {
|
||||||
|
AbstractSkeletonEntity thisObject = (AbstractSkeletonEntity) (Object) this;
|
||||||
|
|
||||||
|
// Remove existing attack goals
|
||||||
|
thisObject.goalSelector.remove(thisObject.bowAttackGoal);
|
||||||
|
thisObject.goalSelector.remove(thisObject.meleeAttackGoal);
|
||||||
|
|
||||||
|
// Add WeaponShootGoal if holding a gun
|
||||||
|
if (isHoldingGun()) {
|
||||||
|
thisObject.goalSelector.add(4, new WeaponShootGoal<>(thisObject, 1.0, 15.0F));
|
||||||
|
} else {
|
||||||
|
// Keep existing logic for bows
|
||||||
|
ItemStack itemStack = thisObject.getStackInHand(ProjectileUtil.getHandPossiblyHolding(thisObject, Items.BOW));
|
||||||
|
if (itemStack.isOf(Items.BOW)) {
|
||||||
|
int attackInterval = thisObject.getWorld().getDifficulty() == Difficulty.HARD ? 20 : 40;
|
||||||
|
BowAttackGoal<AbstractSkeletonEntity> bowAttackGoal = new BowAttackGoal<>(thisObject, 1.0, attackInterval, 15.0F);
|
||||||
|
thisObject.goalSelector.add(4, bowAttackGoal);
|
||||||
|
} else {
|
||||||
|
// Default to melee attack if no bow
|
||||||
|
MeleeAttackGoal meleeAttackGoal = new MeleeAttackGoal(thisObject, 1.2, false) {
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
super.stop();
|
||||||
|
thisObject.setAttacking(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
super.start();
|
||||||
|
thisObject.setAttacking(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thisObject.goalSelector.add(4, meleeAttackGoal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "initEquipment", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/mob/AbstractSkeletonEntity;equipStack(Lnet/minecraft/entity/EquipmentSlot;Lnet/minecraft/item/ItemStack;)V"), cancellable = true)
|
||||||
|
protected void initEquipment(Random random, LocalDifficulty localDifficulty, CallbackInfo ci) {
|
||||||
|
AbstractSkeletonEntity thisObject = (AbstractSkeletonEntity) (Object) this;
|
||||||
|
|
||||||
|
// Get world difficulty
|
||||||
|
World world = thisObject.getWorld();
|
||||||
|
int difficultyAdjustedChance = getDifficultyAdjustedChance(localDifficulty, world);
|
||||||
|
|
||||||
|
// Equip item based on adjusted chance
|
||||||
|
if (random.nextInt(difficultyAdjustedChance) == 0) {
|
||||||
|
thisObject.equipStack(EquipmentSlot.MAINHAND, new ItemStack(guns.get(random.nextInt(guns.size()))));
|
||||||
|
} else {
|
||||||
|
thisObject.equipStack(EquipmentSlot.MAINHAND, new ItemStack(Items.BOW));
|
||||||
|
}
|
||||||
|
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
package systems.brn.plasticgun.mixins;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
import net.minecraft.entity.mob.MobEntity;
|
||||||
|
import net.minecraft.entity.mob.ZombieEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.util.math.random.Random;
|
||||||
|
import net.minecraft.world.Difficulty;
|
||||||
|
import net.minecraft.world.LocalDifficulty;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import systems.brn.plasticgun.PlasticGun;
|
||||||
|
import systems.brn.plasticgun.grenades.GrenadeItem;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static systems.brn.plasticgun.PlasticGun.grenades;
|
||||||
|
import static systems.brn.plasticgun.lib.Util.getDifficultyAdjustedChance;
|
||||||
|
import static systems.brn.plasticgun.lib.Util.selectWeaponIndex;
|
||||||
|
|
||||||
|
@Mixin(ZombieEntity.class)
|
||||||
|
public abstract class ZombieGrenadeMixin extends MobEntity {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract void tick();
|
||||||
|
|
||||||
|
// Constructor required for the Mixin
|
||||||
|
protected ZombieGrenadeMixin(EntityType<? extends MobEntity> entityType, World world) {
|
||||||
|
super(entityType, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "initEquipment", at = @At("HEAD"), cancellable = true)
|
||||||
|
protected void initEquipment(Random random, LocalDifficulty localDifficulty, CallbackInfo ci) {
|
||||||
|
super.initEquipment(random, localDifficulty);
|
||||||
|
|
||||||
|
World world = this.getWorld();
|
||||||
|
int difficultyAdjustedChance = getDifficultyAdjustedChance(localDifficulty, world);
|
||||||
|
|
||||||
|
// Equip item based on adjusted chance
|
||||||
|
if (random.nextInt(difficultyAdjustedChance) == 0) {
|
||||||
|
int i = random.nextInt(20);
|
||||||
|
ItemStack stackToEquip;
|
||||||
|
|
||||||
|
if (i < 8) {
|
||||||
|
stackToEquip = new ItemStack(Items.IRON_SWORD);
|
||||||
|
} else if (i < 14) {
|
||||||
|
int grenadeIndex = selectWeaponIndex(random, localDifficulty, grenades.size());
|
||||||
|
stackToEquip = new ItemStack(grenades.get(grenadeIndex));
|
||||||
|
Arrays.fill(this.handDropChances, 0F);
|
||||||
|
} else {
|
||||||
|
stackToEquip = new ItemStack(Items.IRON_SHOVEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.equipStack(EquipmentSlot.MAINHAND, stackToEquip);
|
||||||
|
}
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "dropEquipment", at = @At("RETURN"))
|
||||||
|
protected void dropEquipment(ServerWorld world, DamageSource source, boolean causedByPlayer, CallbackInfo ci) {
|
||||||
|
ItemStack mainHandItem = this.getEquippedStack(EquipmentSlot.MAINHAND);
|
||||||
|
ItemStack offHandItem = this.getEquippedStack(EquipmentSlot.OFFHAND);
|
||||||
|
for (GrenadeItem grenadeItem : grenades) {
|
||||||
|
if (mainHandItem.getItem() == grenadeItem) {
|
||||||
|
grenadeItem.turnIntoEntity(this, mainHandItem, 0, grenadeItem.explosionTarget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (offHandItem.getItem() == grenadeItem) {
|
||||||
|
grenadeItem.turnIntoEntity(this, offHandItem, 0, grenadeItem.explosionTarget);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,7 @@ import static systems.brn.plasticgun.lib.Util.getFinalDamage;
|
|||||||
|
|
||||||
public class ShurikenEntity extends ThrowableProjectile implements PolymerEntity {
|
public class ShurikenEntity extends ThrowableProjectile implements PolymerEntity {
|
||||||
public ShurikenEntity(ServerPlayerEntity player, ItemStack itemStack, float speed, double damage) {
|
public ShurikenEntity(ServerPlayerEntity player, ItemStack itemStack, float speed, double damage) {
|
||||||
super(SHURIKEN_ENTITY_TYPE, player, itemStack, 1f, speed, damage, PickupPermission.ALLOWED, (byte) 0);
|
super(SHURIKEN_ENTITY_TYPE, player, itemStack, 0.5f, speed, damage, PickupPermission.ALLOWED, (byte) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShurikenEntity(EntityType<ShurikenEntity> bulletEntityEntityType, World world) {
|
public ShurikenEntity(EntityType<ShurikenEntity> bulletEntityEntityType, World world) {
|
||||||
|
@ -20,7 +20,7 @@ public class ThrowableProjectile extends PersistentProjectileEntity implements P
|
|||||||
private final float scale;
|
private final float scale;
|
||||||
|
|
||||||
public ThrowableProjectile(EntityType<? extends ThrowableProjectile> entityType, World world, Vec3d pos, ItemStack itemStack, float scale, double damage, PickupPermission pickupPermission, byte penetration) {
|
public ThrowableProjectile(EntityType<? extends ThrowableProjectile> entityType, World world, Vec3d pos, ItemStack itemStack, float scale, double damage, PickupPermission pickupPermission, byte penetration) {
|
||||||
super(entityType, pos.getX(), pos.getY() + 1.5d, pos.getZ(), world, itemStack, itemStack);
|
super(entityType, pos.getX(), pos.getY() + 1.5d, pos.getZ(), world, itemStack, null);
|
||||||
this.pickupType = pickupPermission;
|
this.pickupType = pickupPermission;
|
||||||
this.setDamage(damage);
|
this.setDamage(damage);
|
||||||
this.setSilent(true);
|
this.setSilent(true);
|
||||||
|
@ -8,6 +8,10 @@
|
|||||||
"contact": {},
|
"contact": {},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/plasticgun/icon.png",
|
"icon": "assets/plasticgun/icon.png",
|
||||||
|
"accessWidener" : "plasticgun.accesswidener",
|
||||||
|
"mixins": [
|
||||||
|
"plasticgun.mixins.json"
|
||||||
|
],
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
|
5
src/main/resources/plasticgun.accesswidener
Normal file
5
src/main/resources/plasticgun.accesswidener
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
accessWidener v2 named
|
||||||
|
accessible field net/minecraft/entity/mob/MobEntity goalSelector Lnet/minecraft/entity/ai/goal/GoalSelector;
|
||||||
|
accessible field net/minecraft/entity/mob/AbstractSkeletonEntity bowAttackGoal Lnet/minecraft/entity/ai/goal/BowAttackGoal;
|
||||||
|
accessible field net/minecraft/entity/mob/AbstractSkeletonEntity meleeAttackGoal Lnet/minecraft/entity/ai/goal/MeleeAttackGoal;
|
||||||
|
accessible method net/minecraft/entity/mob/MobEntity initEquipment (Lnet/minecraft/util/math/random/Random;Lnet/minecraft/world/LocalDifficulty;)V
|
15
src/main/resources/plasticgun.mixins.json
Normal file
15
src/main/resources/plasticgun.mixins.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"package": "systems.brn.plasticgun.mixins",
|
||||||
|
"compatibilityLevel": "JAVA_21",
|
||||||
|
"mixins": [
|
||||||
|
"AbstractSkeletonEntityGunMixin",
|
||||||
|
"ZombieGrenadeMixin"
|
||||||
|
],
|
||||||
|
"client": [],
|
||||||
|
"server": [],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user