This commit is contained in:
GearShocky 2025-03-16 02:45:46 +05:00
parent 1670e14ae8
commit 7c31180430
6 changed files with 181 additions and 17 deletions

View File

@ -0,0 +1,4 @@
kotlin version: 2.0.10
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
1. Kotlin compile daemon is ready

View File

@ -1,6 +1,9 @@
package ru.dbotthepony.mc.otm.entity
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.EntityDataSerializers
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.server.level.ServerBossEvent
import net.minecraft.server.level.ServerLevel
import net.minecraft.sounds.SoundEvent
@ -32,9 +35,32 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
val idleState = AnimationState()
val chargeState = AnimationState()
init {
entityData.set(isChargingb, false)
idleState.start(tickCount)
}
companion object {
fun createAttributes() : AttributeSupplier.Builder {
return createMonsterAttributes()
.add(Attributes.MAX_HEALTH, 300.0)
.add(Attributes.ARMOR, 20.0)
.add(Attributes.MOVEMENT_SPEED, 0.3)
.add(Attributes.STEP_HEIGHT, 1.0)
.add(Attributes.KNOCKBACK_RESISTANCE, 1.0)
}
private val isChargingb: EntityDataAccessor<Boolean> =
SynchedEntityData.defineId(Enforcer::class.java, EntityDataSerializers.BOOLEAN)
}
override fun defineSynchedData(builder: SynchedEntityData.Builder) {
super.defineSynchedData(builder)
builder.define(isChargingb, false)
}
var isCharging: Boolean
get() = entityData.get(isChargingb)
set(value) = entityData.set(isChargingb, value)
override fun registerGoals() {
goalSelector.addGoal(7, LookAtPlayerGoal(this, Player::class.java, 8f))
goalSelector.addGoal(3, NearestAttackableTargetGoal(this, LivingEntity::class.java, 10, true, true) { entity ->
@ -46,6 +72,7 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
})
goalSelector.addGoal(2, RammingGoal(this))
goalSelector.addGoal(2, StayNearGoal(this))
targetSelector.addGoal(1, HurtByTargetGoal(this))
}
@ -81,6 +108,12 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
bossEvent.progress = this.health / this.maxHealth
}
//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()
@ -93,12 +126,11 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
private var chargeTime = 0
private val windupTime = 20
private val maxChargeTime = 40
private var chargeDir: Vec3? = null
private var cooldown = 0
private val minCooldown = 20
private val maxCooldown = 60
private var isCharging = false
override fun canUse(): Boolean {
if (cooldown > 0) {
@ -110,22 +142,18 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
return target != null
}
override fun canContinueToUse(): Boolean {
return isCharging && chargeTime < maxChargeTime
}
override fun start() {
mob.playSound(MSoundEvents.ENFORCER_ALERT, 1.0f, 1.0f)
chargeTime = 0
mob.navigation.stop()
cooldown = minCooldown + mob.random.nextInt(maxCooldown - minCooldown)
isCharging = true
mob.isCharging = true
mob.chargeState.start(mob.tickCount)
}
override fun tick() {
if (!isCharging) return
if (!mob.isCharging) return
chargeTime++
val target = mob.target ?: return
@ -174,6 +202,7 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
mob.yHeadRot = mob.yRot
mob.move(net.minecraft.world.entity.MoverType.SELF, dir.scale(1.8))
//mob.setDeltaMovement(dir.scale(1.8))
if (mob.horizontalCollision) {
@ -203,23 +232,57 @@ class Enforcer(type: EntityType<Enforcer>, level: Level) : Monster(type,level) {
}
override fun stop() {
mob.isCharging = false
mob.setDeltaMovement(Vec3.ZERO)
chargeTime = 0
chargeDir = null
isCharging = false
mob.isCharging = false
mob.chargeState.stop()
}
}
companion object {
fun createAttributes() : AttributeSupplier.Builder {
return createMonsterAttributes()
.add(Attributes.MAX_HEALTH, 300.0)
.add(Attributes.ARMOR, 20.0)
.add(Attributes.MOVEMENT_SPEED, 0.3)
.add(Attributes.STEP_HEIGHT, 1.0)
.add(Attributes.KNOCKBACK_RESISTANCE, 1.0)
class StayNearGoal(private val mob: Enforcer) : Goal() {
private var target: LivingEntity? = null
private var moveCD = 0
private var movePos: Vec3? = null
override fun canUse(): Boolean {
return mob.target != null && !mob.isCharging
}
override fun canContinueToUse(): Boolean {
return canUse()
}
override fun start() {
target = mob.target
moveCD = 0
}
override fun tick() {
mob.lookControl.setLookAt(target, 30.0f, 30.0f)
val target = mob.target ?: return
if (moveCD > 0) {
moveCD--
return
}
moveCD = 10 + mob.random.nextInt(10)
val targetX = target.x
val targetZ = target.z
val angle = mob.random.nextDouble() * Math.PI * 2
val distance = 8.0 + mob.random.nextDouble() * 3.0
val offsetX = Math.cos(angle) * distance
val offsetZ = Math.sin(angle) * distance
movePos = Vec3(targetX + offsetX, target.y + 2.0, targetZ + offsetZ)
mob.navigation.moveTo(movePos!!.x, movePos!!.y, movePos!!.z, 1.5)
}
}
}

View File

@ -57,6 +57,7 @@ class Loader(type: EntityType<Loader>, level: Level) : Monster(type, level) {
super.defineSynchedData(builder)
builder.define(DATA_ATTACKING, false)
}
var isAttacking: Boolean
get() = this.entityData.get(DATA_ATTACKING)
set(value) {

View File

@ -0,0 +1,90 @@
package ru.dbotthepony.mc.otm.entity
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.world.damagesource.DamageTypes
import net.minecraft.world.entity.projectile.Projectile
import net.minecraft.world.entity.projectile.ProjectileUtil
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.LevelEvent
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.EntityHitResult
import net.minecraft.world.phys.HitResult
import net.neoforged.neoforge.event.EventHooks
import ru.dbotthepony.mc.otm.core.damageType
import ru.dbotthepony.mc.otm.registry.MDamageTypes
import ru.dbotthepony.mc.otm.registry.game.MEntityTypes
import ru.dbotthepony.mc.otm.registry.MatteryDamageSource
class RocketProjectile(level: Level) : Projectile(MEntityTypes.PLASMA, level) {
var inflictor: ItemStack? = null
var damage = 6.0f
var ttl = 200
override fun defineSynchedData(p_326003_: SynchedEntityData.Builder) {
}
override fun onHit(p_37260_: HitResult) {
super.onHit(p_37260_)
if (!level().isClientSide) {
discard()
}
}
override fun onHitEntity(p_37259_: EntityHitResult) {
super.onHitEntity(p_37259_)
if (!level().isClientSide) {
p_37259_.entity.hurt(MatteryDamageSource(level().registryAccess().damageType(DamageTypes.EXPLOSION), owner, inflictor), damage)
level().explode(this, x, y, z, 2.5f, Level.ExplosionInteraction.BLOCK)
}
}
override fun onHitBlock(p_37258_: BlockHitResult) {
super.onHitBlock(p_37258_)
}
override fun tick() {
if (--ttl <= 0) {
discard()
return
}
super.tick()
val trace = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity)
if (trace.type == HitResult.Type.BLOCK) {
val pos = (trace as BlockHitResult).blockPos
val state = level().getBlockState(pos)
level().explode(this, x, y, z, 2.5f, Level.ExplosionInteraction.BLOCK)
if (state.`is`(Blocks.NETHER_PORTAL) || state.`is`(Blocks.END_GATEWAY)) {
onHitBlock(trace)
// don't teleport plasma projectile
if (!level().isClientSide)
discard()
return
}
}
if (trace.type != HitResult.Type.MISS && !EventHooks.onProjectileImpact(this, trace)) {
onHit(trace)
}
checkInsideBlocks()
val x = x + deltaMovement.x
val y = y + deltaMovement.y
val z = z + deltaMovement.z
setPos(x, y, z)
}
}

View File

@ -333,6 +333,8 @@ object MNames {
// entities
const val PLASMA = "plasma_projectile"
const val ROCKET = "rocket_projectile"
const val RIDEABLE_DUMMY = "rideable_dummy"
const val BREAD_MONSTER = "bread_monster"
const val LOADER = "loader"

View File

@ -25,6 +25,10 @@ object MEntityTypes {
EntityType.Builder.of({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA)
}
val ROCKET: EntityType<RocketProjectile> by registry.register(MNames.ROCKET) {
EntityType.Builder.of({ _, level -> RocketProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.ROCKET)
}
val CARGO_CRATE_MINECARTS: Map<DyeColor?, EntityType<MinecartCargoCrate>> = registry.coloredWithBase(MNames.MINECART_CARGO_CRATE) { color ->
EntityType.Builder.of({ it, level -> MinecartCargoCrate(it, color, level)}, MobCategory.MISC).sized(0.98F, 0.7F).clientTrackingRange(8).build("dfu doesn't works ✅")