From 5e3fcddd34ffa44594d1682dcceb94636fe30c2f Mon Sep 17 00:00:00 2001 From: GearShocky Date: Sun, 16 Mar 2025 13:20:21 +0500 Subject: [PATCH] fireball --- .../ru/dbotthepony/mc/otm/entity/Enforcer.kt | 117 ++++++++++++++++-- 1 file changed, 107 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Enforcer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Enforcer.kt index a38ffaaa9..00dc0fbd9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Enforcer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Enforcer.kt @@ -11,26 +11,34 @@ import net.minecraft.sounds.SoundEvents import net.minecraft.sounds.SoundSource import net.minecraft.util.Mth import net.minecraft.world.BossEvent -import net.minecraft.world.phys.Vec3 +import net.minecraft.world.damagesource.DamageSource import net.minecraft.world.entity.AnimationState import net.minecraft.world.entity.EntityType import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.ai.attributes.AttributeSupplier import net.minecraft.world.entity.ai.attributes.Attributes -import net.minecraft.world.entity.ai.goal.* +import net.minecraft.world.entity.ai.goal.Goal +import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal import net.minecraft.world.entity.ai.navigation.GroundPathNavigation import net.minecraft.world.entity.ai.navigation.PathNavigation -import net.minecraft.world.entity.monster.* +import net.minecraft.world.entity.monster.AbstractIllager +import net.minecraft.world.entity.monster.AbstractSkeleton +import net.minecraft.world.entity.monster.Monster +import net.minecraft.world.entity.monster.Zombie import net.minecraft.world.entity.npc.Villager import net.minecraft.world.entity.player.Player +import net.minecraft.world.entity.projectile.SmallFireball import net.minecraft.world.level.Level - +import net.minecraft.world.phys.Vec3 import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.core.isFire import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.registry.game.MSoundEvents import java.util.* +import kotlin.math.cos +import kotlin.math.sin class Enforcer(type: EntityType, level: Level) : Monster(type,level) { val idleState = AnimationState() @@ -48,6 +56,7 @@ class Enforcer(type: EntityType, level: Level) : Monster(type,level) { .add(Attributes.MOVEMENT_SPEED, 0.3) .add(Attributes.STEP_HEIGHT, 1.0) .add(Attributes.KNOCKBACK_RESISTANCE, 1.0) + .add(Attributes.FOLLOW_RANGE, 32.0) } private val IS_CHARGING: EntityDataAccessor = SynchedEntityData.defineId(Enforcer::class.java, EntityDataSerializers.BOOLEAN) @@ -79,6 +88,7 @@ class Enforcer(type: EntityType, level: Level) : Monster(type,level) { goalSelector.addGoal(2, RammingGoal(this)) goalSelector.addGoal(2, StayNearGoal(this)) + goalSelector.addGoal(2, BlazeFireballGoal(this)) targetSelector.addGoal(1, HurtByTargetGoal(this)) } @@ -95,7 +105,19 @@ class Enforcer(type: EntityType, level: Level) : Monster(type,level) { override fun getDeathSound(): SoundEvent { return SoundEvents.VAULT_BREAK } -///boss healthbar + + //fire inv + //there should be a better way + override fun isInvulnerableTo(source: DamageSource): Boolean { + return source.isFire || super.isInvulnerableTo(source) + } + + override fun hurt(source: DamageSource, amount: Float): Boolean { + if (source.isFire) return false + return super.hurt(source, amount) + } + + ///boss healthbar private val bossEvent: ServerBossEvent = ServerBossEvent(TranslatableComponent(MNames.ENFORCER), BossEvent.BossBarColor.RED, BossEvent.BossBarOverlay.PROGRESS) @@ -114,17 +136,42 @@ class Enforcer(type: EntityType, level: Level) : Monster(type,level) { bossEvent.progress = this.health / this.maxHealth } + override fun die(cause: net.minecraft.world.damagesource.DamageSource) { + super.die(cause) + bossEvent.removeAllPlayers() + } + /// + //this stuff removes 180-degree head rotation limits that minecraft mobs have, since this is a turret on a tank, we don't need such limits //WE ARE BEYOND THAT, THOSE ARE MY GREAT WAR-MACHINES override fun getMaxHeadYRot(): Int { return 180 } - override fun die(cause: net.minecraft.world.damagesource.DamageSource) { - super.die(cause) - bossEvent.removeAllPlayers() + fun shootFireball(math: Float) { + if (level().isClientSide) return + + val offset_dist = 1.4 + val viewVector = this.getViewVector(1.0F).normalize() + val leftVec = Vec3(viewVector.z, 0.0, -viewVector.x).normalize().scale(offset_dist) + + val gun_x = x + leftVec.x + val gun_z = z + leftVec.z + val gun_y = y + 1.2 + + //stfu idea i like my underscores + + val fireballX = gun_x + val fireballY = gun_y + val fireballZ = gun_z + + val fireball = SmallFireball(level(), fireballX, fireballY, fireballZ, viewVector) + fireball.shootFromRotation(this, this.xRot, this.yHeadRot, 0.0F, 1.5F, 0.2F) + fireball.setPos(fireballX, fireballY, fireballZ) + fireball.owner = this + + level().addFreshEntity(fireball) } -/// //charge attack, could possibly leave a smoke trail too idk class RammingGoal(private val mob: Enforcer) : Goal() { @@ -238,7 +285,7 @@ class Enforcer(type: EntityType, level: Level) : Monster(type,level) { target.push(knockback.x, 0.5, knockback.z) - val damageAmount = 6.0f + val damageAmount = 10.0f target.hurt(mob.damageSources().mobAttack(mob), damageAmount) stop() @@ -298,4 +345,54 @@ class Enforcer(type: EntityType, level: Level) : Monster(type,level) { mob.navigation.moveTo(movePos!!.x, movePos!!.y, movePos!!.z, 1.5) } } + + class BlazeFireballGoal(private val mob: Enforcer) : Goal() { + private var cooldown = 0 + private var fireTick = 0 + + init { + setFlags(EnumSet.of(Goal.Flag.LOOK)) + } + + override fun canUse(): Boolean { + return mob.target != null && !mob.isCharging() + } + + override fun canContinueToUse(): Boolean { + return canUse() + } + + override fun tick() { + val target = mob.target ?: return + mob.lookControl.setLookAt(target, 30.0f, 30.0f) + + if (cooldown > 0) { + fireTick = 20 + cooldown-- + return + } + + if (fireTick > 0){ + fireTick -- + + if (fireTick == 15){ + mob.shootFireball(0.5f) + //could have a better firing sound + mob.playSound(SoundEvents.BLAZE_SHOOT, 1.0f, 1.0f) + } + if (fireTick == 10){ + mob.shootFireball(0.5f) + mob.playSound(SoundEvents.BLAZE_SHOOT, 1.0f, 1.0f) + } + if (fireTick == 5){ + mob.shootFireball(0.5f) + mob.playSound(SoundEvents.BLAZE_SHOOT, 1.0f, 1.0f) + } + + return + } else { + cooldown = 5 + mob.random.nextInt(10) + } + } + } }