diff --git a/gradle.properties b/gradle.properties index e974bb5..a5db867 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.20.1 yarn_mappings=1.20.1+build.10 loader_version=0.18.3 # Mod Properties -mod_version=26.2.5.1 +mod_version=26.2.6 maven_group=dev.tggamesyt archives_base_name=szar # Dependencies diff --git a/src/client/java/dev/tggamesyt/szar/client/GypsyEntityRenderer.java b/src/client/java/dev/tggamesyt/szar/client/GypsyEntityRenderer.java index 2c0e07c..e180e21 100644 --- a/src/client/java/dev/tggamesyt/szar/client/GypsyEntityRenderer.java +++ b/src/client/java/dev/tggamesyt/szar/client/GypsyEntityRenderer.java @@ -3,6 +3,7 @@ package dev.tggamesyt.szar.client; import dev.tggamesyt.szar.GypsyEntity; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.client.render.entity.feature.HeldItemFeatureRenderer; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.EntityModelLayers; import net.minecraft.util.Identifier; @@ -16,6 +17,11 @@ public class GypsyEntityRenderer new BipedEntityModel<>(context.getPart(EntityModelLayers.PLAYER)), 0.5F ); + // 🔥 THIS is what makes items appear in hands + this.addFeature(new HeldItemFeatureRenderer<>( + this, + context.getHeldItemRenderer() + )); } @Override diff --git a/src/client/java/dev/tggamesyt/szar/client/NaziEntityRenderer.java b/src/client/java/dev/tggamesyt/szar/client/NaziEntityRenderer.java index dc9bf8f..ba591e4 100644 --- a/src/client/java/dev/tggamesyt/szar/client/NaziEntityRenderer.java +++ b/src/client/java/dev/tggamesyt/szar/client/NaziEntityRenderer.java @@ -3,21 +3,29 @@ package dev.tggamesyt.szar.client; import dev.tggamesyt.szar.NaziEntity; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.client.render.entity.feature.HeldItemFeatureRenderer; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.EntityModelLayers; +import net.minecraft.client.render.entity.model.PlayerEntityModel; import net.minecraft.util.Identifier; public class NaziEntityRenderer - extends MobEntityRenderer> { + extends MobEntityRenderer> { public NaziEntityRenderer(EntityRendererFactory.Context context) { super( context, - new BipedEntityModel<>(context.getPart(EntityModelLayers.PLAYER)), + new PlayerEntityModel<>(context.getPart(EntityModelLayers.PLAYER), false), 0.5F ); + + this.addFeature(new HeldItemFeatureRenderer<>( + this, + context.getHeldItemRenderer() + )); } + @Override public Identifier getTexture(NaziEntity entity) { return new Identifier("szar", "textures/entity/nazi.png"); diff --git a/src/main/java/dev/tggamesyt/szar/AK47AttackGoal.java b/src/main/java/dev/tggamesyt/szar/AK47AttackGoal.java new file mode 100644 index 0000000..5e2e895 --- /dev/null +++ b/src/main/java/dev/tggamesyt/szar/AK47AttackGoal.java @@ -0,0 +1,72 @@ +package dev.tggamesyt.szar; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.goal.Goal; +import net.minecraft.util.math.MathHelper; + +import java.util.EnumSet; + +public class AK47AttackGoal extends Goal { + + private final NaziEntity mob; + private final float range; + private final int cooldownTicks; + private int cooldown; + + public AK47AttackGoal(NaziEntity mob, float range, int cooldownTicks) { + this.mob = mob; + this.range = range; + this.cooldownTicks = cooldownTicks; + this.setControls(EnumSet.of(Control.MOVE, Control.LOOK)); + } + + @Override + public boolean canStart() { + return mob.getTarget() != null && mob.getTarget().isAlive(); + } + + @Override + public void tick() { + LivingEntity target = mob.getTarget(); + if (target == null) return; + + mob.getLookControl().lookAt(target, 30.0F, 30.0F); + + double distanceSq = mob.squaredDistanceTo(target); + if (distanceSq > range * range) { + mob.getNavigation().startMovingTo(target, 1.0); + return; + } + + mob.getNavigation().stop(); + + if (cooldown > 0) { + cooldown--; + return; + } + + shoot(target); + cooldown = cooldownTicks; + } + + private void shoot(LivingEntity target) { + BulletEntity bullet = new BulletEntity(mob.getWorld(), mob); + + double dx = target.getX() - mob.getX(); + double dy = target.getBodyY(0.5) - bullet.getY(); + double dz = target.getZ() - mob.getZ(); + + float velocity = 4.5F; + float inaccuracy = 1.0F; + + bullet.setVelocity( + dx, + dy, + dz, + velocity, + inaccuracy + ); + + mob.getWorld().spawnEntity(bullet); + } +} diff --git a/src/main/java/dev/tggamesyt/szar/BulletEntity.java b/src/main/java/dev/tggamesyt/szar/BulletEntity.java index 994f45c..9a09412 100644 --- a/src/main/java/dev/tggamesyt/szar/BulletEntity.java +++ b/src/main/java/dev/tggamesyt/szar/BulletEntity.java @@ -3,9 +3,11 @@ package dev.tggamesyt.szar; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.projectile.thrown.ThrownItemEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.registry.RegistryKeys; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.world.World; @@ -34,12 +36,18 @@ public class BulletEntity extends ThrownItemEntity { Entity owner = getOwner(); if (owner instanceof LivingEntity livingOwner) { - target.damage( - getWorld().getDamageSources().mobProjectile(this, livingOwner), - 13.0F + DamageSource source = new DamageSource( + getWorld().getRegistryManager() + .get(RegistryKeys.DAMAGE_TYPE) + .entryOf(Szar.BULLET_DAMAGE), + this, + livingOwner ); + + target.damage(source, 13.0F); } discard(); } + } diff --git a/src/main/java/dev/tggamesyt/szar/NaziEntity.java b/src/main/java/dev/tggamesyt/szar/NaziEntity.java index eeb4757..43ffe9a 100644 --- a/src/main/java/dev/tggamesyt/szar/NaziEntity.java +++ b/src/main/java/dev/tggamesyt/szar/NaziEntity.java @@ -1,6 +1,7 @@ package dev.tggamesyt.szar; import net.minecraft.entity.EntityType; +import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.ai.goal.LookAroundGoal; import net.minecraft.entity.ai.goal.MeleeAttackGoal; import net.minecraft.entity.ai.goal.WanderAroundFarGoal; @@ -24,13 +25,14 @@ public class NaziEntity extends PathAwareEntity implements Arrestable{ private HitterEntity leader; public NaziEntity(EntityType type, World world) { super(type, world); + this.equipStack(EquipmentSlot.MAINHAND, new ItemStack(Szar.AK47)); } @Override protected void initGoals() { this.goalSelector.add(2, new FollowLeaderWanderGoal(this, 1.0D, 6.0F)); this.goalSelector.add(3, new WanderAroundFarGoal(this, 0.8D)); - this.goalSelector.add(1, new MeleeAttackGoal(this, 1.2D, true)); + this.goalSelector.add(1, new AK47AttackGoal(this, 16.0F, 2)); } diff --git a/src/main/java/dev/tggamesyt/szar/Szar.java b/src/main/java/dev/tggamesyt/szar/Szar.java index 26f7bf1..9c61125 100644 --- a/src/main/java/dev/tggamesyt/szar/Szar.java +++ b/src/main/java/dev/tggamesyt/szar/Szar.java @@ -23,6 +23,7 @@ import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper import net.minecraft.advancement.Advancement; import net.minecraft.block.*; import net.minecraft.entity.*; +import net.minecraft.entity.damage.DamageType; import net.minecraft.entity.data.DataTracker; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.data.TrackedDataHandlerRegistry; @@ -91,6 +92,12 @@ public class Szar implements ModInitializer { RegistryKey.of(RegistryKeys.POINT_OF_INTEREST_TYPE, new Identifier(MOD_ID, "chemical_workbench_poi")); public static PointOfInterestType CHEMICAL_WORKBENCH_POI = PointOfInterestHelper.register(new Identifier(MOD_ID, "chemical_workbench_poi"), 1, 1, CHEMICAL_WORKBENCH); + + public static final RegistryKey BULLET_DAMAGE = + RegistryKey.of( + RegistryKeys.DAMAGE_TYPE, + new Identifier("szar", "bullet") + ); public static VillagerProfession DROG_DEALER = Registry.register( Registries.VILLAGER_PROFESSION, new Identifier(MOD_ID, "drog_dealer"), @@ -446,7 +453,6 @@ public class Szar implements ModInitializer { } return ActionResult.PASS; }); - } public static final StructurePieceType TNT_OBELISK_PIECE = Registry.register( diff --git a/src/main/resources/assets/szar/lang/en_us.json b/src/main/resources/assets/szar/lang/en_us.json index 0c4bd1d..76375b7 100644 --- a/src/main/resources/assets/szar/lang/en_us.json +++ b/src/main/resources/assets/szar/lang/en_us.json @@ -34,11 +34,14 @@ "item.szar.police_handcuff": "Police Handcuff", "entity.szar.gypsy": "Cigány", "entity.szar.plane": "Plane", + "entity.szar.hitler": "Hitler", "item.szar.hitler_spawn_egg":"Hitler Spawn Egg", "entity.szar.nazi": "Nazi", "item.szar.nazi_spawn_egg":"Nazi Spawn Egg", "item.szar.bullet": "Bullet", "item.szar.ak47": "AK47", - "entity.szar.bullet": "Bullet" + "entity.szar.bullet": "Bullet", + "death.attack.bullet": "%1$s was shot by %2$s", + "death.attack.bullet.player": "%1$s was shot by %2$s" } diff --git a/src/main/resources/data/szar/damage_type/bullet.json b/src/main/resources/data/szar/damage_type/bullet.json new file mode 100644 index 0000000..88832a7 --- /dev/null +++ b/src/main/resources/data/szar/damage_type/bullet.json @@ -0,0 +1,6 @@ +{ + "message_id": "bullet", + "exhaustion": 0.1, + "scaling": "when_caused_by_living_non_player", + "effects": "hurt" +}