From 7c311804304971550c448f99e26ef87e276cd9c7 Mon Sep 17 00:00:00 2001 From: GearShocky Date: Sun, 16 Mar 2025 02:45:46 +0500 Subject: [PATCH] h2 --- .kotlin/errors/errors-1741839380575.log | 4 + .../ru/dbotthepony/mc/otm/entity/Enforcer.kt | 97 +++++++++++++++---- .../ru/dbotthepony/mc/otm/entity/Loader.kt | 1 + .../mc/otm/entity/RocketProjectile.kt | 90 +++++++++++++++++ .../ru/dbotthepony/mc/otm/registry/MNames.kt | 2 + .../mc/otm/registry/game/MEntityTypes.kt | 4 + 6 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 .kotlin/errors/errors-1741839380575.log create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/entity/RocketProjectile.kt diff --git a/.kotlin/errors/errors-1741839380575.log b/.kotlin/errors/errors-1741839380575.log new file mode 100644 index 000000000..b27a18502 --- /dev/null +++ b/.kotlin/errors/errors-1741839380575.log @@ -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 + 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 035c93c70..638ba5a24 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Enforcer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Enforcer.kt @@ -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, 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 = + 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, 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, 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, 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, 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, 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, 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) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Loader.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Loader.kt index d0d3a5e50..9c52b1a9d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Loader.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/Loader.kt @@ -57,6 +57,7 @@ class Loader(type: EntityType, level: Level) : Monster(type, level) { super.defineSynchedData(builder) builder.define(DATA_ATTACKING, false) } + var isAttacking: Boolean get() = this.entityData.get(DATA_ATTACKING) set(value) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/entity/RocketProjectile.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/RocketProjectile.kt new file mode 100644 index 000000000..4e10d0c50 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/entity/RocketProjectile.kt @@ -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) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt index f0da3cd6f..8a63d73d4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt @@ -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" diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MEntityTypes.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MEntityTypes.kt index 433d89964..604272653 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MEntityTypes.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/game/MEntityTypes.kt @@ -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 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> = 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 ✅")