fireball
This commit is contained in:
parent
24485696f3
commit
5e3fcddd34
@ -11,26 +11,34 @@ import net.minecraft.sounds.SoundEvents
|
|||||||
import net.minecraft.sounds.SoundSource
|
import net.minecraft.sounds.SoundSource
|
||||||
import net.minecraft.util.Mth
|
import net.minecraft.util.Mth
|
||||||
import net.minecraft.world.BossEvent
|
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.AnimationState
|
||||||
import net.minecraft.world.entity.EntityType
|
import net.minecraft.world.entity.EntityType
|
||||||
import net.minecraft.world.entity.LivingEntity
|
import net.minecraft.world.entity.LivingEntity
|
||||||
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
|
import net.minecraft.world.entity.ai.attributes.AttributeSupplier
|
||||||
import net.minecraft.world.entity.ai.attributes.Attributes
|
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.HurtByTargetGoal
|
||||||
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal
|
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal
|
||||||
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
|
import net.minecraft.world.entity.ai.navigation.GroundPathNavigation
|
||||||
import net.minecraft.world.entity.ai.navigation.PathNavigation
|
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.npc.Villager
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.entity.projectile.SmallFireball
|
||||||
import net.minecraft.world.level.Level
|
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.TranslatableComponent
|
||||||
|
import ru.dbotthepony.mc.otm.core.isFire
|
||||||
import ru.dbotthepony.mc.otm.registry.MNames
|
import ru.dbotthepony.mc.otm.registry.MNames
|
||||||
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
|
import ru.dbotthepony.mc.otm.registry.game.MSoundEvents
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
|
class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
|
||||||
val idleState = AnimationState()
|
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.MOVEMENT_SPEED, 0.3)
|
||||||
.add(Attributes.STEP_HEIGHT, 1.0)
|
.add(Attributes.STEP_HEIGHT, 1.0)
|
||||||
.add(Attributes.KNOCKBACK_RESISTANCE, 1.0)
|
.add(Attributes.KNOCKBACK_RESISTANCE, 1.0)
|
||||||
|
.add(Attributes.FOLLOW_RANGE, 32.0)
|
||||||
}
|
}
|
||||||
private val IS_CHARGING: EntityDataAccessor<Boolean> =
|
private val IS_CHARGING: EntityDataAccessor<Boolean> =
|
||||||
SynchedEntityData.defineId(Enforcer::class.java, EntityDataSerializers.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, RammingGoal(this))
|
||||||
goalSelector.addGoal(2, StayNearGoal(this))
|
goalSelector.addGoal(2, StayNearGoal(this))
|
||||||
|
goalSelector.addGoal(2, BlazeFireballGoal(this))
|
||||||
targetSelector.addGoal(1, HurtByTargetGoal(this))
|
targetSelector.addGoal(1, HurtByTargetGoal(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +105,18 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
|
|||||||
override fun getDeathSound(): SoundEvent {
|
override fun getDeathSound(): SoundEvent {
|
||||||
return SoundEvents.VAULT_BREAK
|
return SoundEvents.VAULT_BREAK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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
|
///boss healthbar
|
||||||
private val bossEvent: ServerBossEvent =
|
private val bossEvent: ServerBossEvent =
|
||||||
ServerBossEvent(TranslatableComponent(MNames.ENFORCER), BossEvent.BossBarColor.RED, BossEvent.BossBarOverlay.PROGRESS)
|
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
|
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
|
//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
|
//WE ARE BEYOND THAT, THOSE ARE MY GREAT WAR-MACHINES
|
||||||
override fun getMaxHeadYRot(): Int {
|
override fun getMaxHeadYRot(): Int {
|
||||||
return 180
|
return 180
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun die(cause: net.minecraft.world.damagesource.DamageSource) {
|
fun shootFireball(math: Float) {
|
||||||
super.die(cause)
|
if (level().isClientSide) return
|
||||||
bossEvent.removeAllPlayers()
|
|
||||||
|
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
|
//charge attack, could possibly leave a smoke trail too idk
|
||||||
class RammingGoal(private val mob: Enforcer) : Goal() {
|
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)
|
target.push(knockback.x, 0.5, knockback.z)
|
||||||
|
|
||||||
val damageAmount = 6.0f
|
val damageAmount = 10.0f
|
||||||
target.hurt(mob.damageSources().mobAttack(mob), damageAmount)
|
target.hurt(mob.damageSources().mobAttack(mob), damageAmount)
|
||||||
|
|
||||||
stop()
|
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)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user