This commit is contained in:
GearShocky 2025-03-16 13:20:21 +05:00
parent 24485696f3
commit 5e3fcddd34

View File

@ -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<Enforcer>, level: Level) : Monster(type,level) {
val idleState = AnimationState()
@ -48,6 +56,7 @@ class Enforcer(type: EntityType<Enforcer>, 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<Boolean> =
SynchedEntityData.defineId(Enforcer::class.java, EntityDataSerializers.BOOLEAN)
@ -79,6 +88,7 @@ class Enforcer(type: EntityType<Enforcer>, 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<Enforcer>, 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<Enforcer>, 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<Enforcer>, 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<Enforcer>, 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)
}
}
}
}