1
0
mirror of https://github.com/chylex/Hardcore-Ender-Expansion-2.git synced 2024-10-17 08:42:49 +02:00
Hardcore-Ender-Expansion-2/.idea/shelf/Ender_Eye/shelved.patch
2021-01-15 18:42:49 +01:00

70 lines
20 KiB
Diff

Index: src/main/java/chylex/hee/game/entity/living/EntityBossEnderEye.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>package chylex.hee.game.entity.living\r\nimport chylex.hee.game.entity.CustomCreatureType\r\nimport chylex.hee.game.entity.living.behavior.EnderEyePhase\r\nimport chylex.hee.game.entity.living.behavior.EnderEyePhase.Floating\r\nimport chylex.hee.game.entity.living.behavior.EnderEyePhase.Hibernated\r\nimport chylex.hee.game.entity.living.behavior.EnderEyePhase.OpenEye\r\nimport chylex.hee.game.entity.living.behavior.EnderEyePhase.Ready\r\nimport chylex.hee.game.entity.living.behavior.EnderEyePhase.Staring\r\nimport chylex.hee.game.entity.living.helpers.EntityBodyHeadless\r\nimport chylex.hee.game.entity.living.helpers.EntityLookSlerp\r\nimport chylex.hee.game.entity.living.helpers.EntityMoveFlyingForward\r\nimport chylex.hee.game.entity.util.EntityData\r\nimport chylex.hee.game.mechanics.damage.Damage\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.ALL_PROTECTIONS\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.ARMOR_PROTECTION\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.DIFFICULTY_SCALING\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.ENCHANTMENT_PROTECTION\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.FIRE_TYPE\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.NUDITY_DANGER\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.PEACEFUL_EXCLUSION\r\nimport chylex.hee.game.mechanics.damage.IDamageProcessor.Companion.RAPID_DAMAGE\r\nimport chylex.hee.init.ModEntities\r\nimport chylex.hee.network.client.PacketClientLaunchInstantly\r\nimport chylex.hee.system.migration.vanilla.EntityFlying\r\nimport chylex.hee.system.migration.vanilla.EntityLivingBase\r\nimport chylex.hee.system.migration.vanilla.EntityPlayer\r\nimport chylex.hee.system.migration.vanilla.EntityPlayerMP\r\nimport chylex.hee.system.util.TagCompound\r\nimport chylex.hee.system.util.Vec3\r\nimport chylex.hee.system.util.directionTowards\r\nimport chylex.hee.system.util.facades.Resource\r\nimport chylex.hee.system.util.floorToInt\r\nimport chylex.hee.system.util.heeTag\r\nimport chylex.hee.system.util.math.LerpedFloat\r\nimport chylex.hee.system.util.motionY\r\nimport chylex.hee.system.util.nextInt\r\nimport chylex.hee.system.util.nextItemOrNull\r\nimport chylex.hee.system.util.posVec\r\nimport chylex.hee.system.util.scale\r\nimport chylex.hee.system.util.selectVulnerableEntities\r\nimport chylex.hee.system.util.use\r\nimport chylex.hee.system.util.withY\r\nimport net.minecraft.block.material.PushReaction\r\nimport net.minecraft.entity.CreatureAttribute\r\nimport net.minecraft.entity.Entity\r\nimport net.minecraft.entity.EntitySize\r\nimport net.minecraft.entity.EntityType\r\nimport net.minecraft.entity.ILivingEntityData\r\nimport net.minecraft.entity.Pose\r\nimport net.minecraft.entity.SharedMonsterAttributes.ATTACK_DAMAGE\r\nimport net.minecraft.entity.SharedMonsterAttributes.FLYING_SPEED\r\nimport net.minecraft.entity.SharedMonsterAttributes.FOLLOW_RANGE\r\nimport net.minecraft.entity.SharedMonsterAttributes.MAX_HEALTH\r\nimport net.minecraft.entity.SpawnReason\r\nimport net.minecraft.entity.ai.controller.BodyController\r\nimport net.minecraft.entity.monster.IMob\r\nimport net.minecraft.nbt.CompoundNBT\r\nimport net.minecraft.network.IPacket\r\nimport net.minecraft.network.datasync.DataSerializers\r\nimport net.minecraft.util.DamageSource\r\nimport net.minecraft.util.ResourceLocation\r\nimport net.minecraft.util.math.AxisAlignedBB\r\nimport net.minecraft.util.math.Vec3d\r\nimport net.minecraft.util.text.ITextComponent\r\nimport net.minecraft.world.BossInfo\r\nimport net.minecraft.world.DifficultyInstance\r\nimport net.minecraft.world.IWorld\r\nimport net.minecraft.world.ServerBossInfo\r\nimport net.minecraft.world.World\r\nimport net.minecraftforge.common.ForgeHooks\r\nimport net.minecraftforge.fml.network.NetworkHooks\r\nimport kotlin.math.abs\r\n\r\nclass EntityBossEnderEye(type: EntityType<EntityBossEnderEye>, world: World) : EntityFlying(type, world), IMob{\r\n\tconstructor(world: World) : this(ModEntities.ENDER_EYE, world)\r\n\t\r\n\tcompanion object{\r\n\t\tprivate val DAMAGE_MELEE = Damage(DIFFICULTY_SCALING, ARMOR_PROTECTION(false), ENCHANTMENT_PROTECTION)\r\n\t\tprivate val DAMAGE_LASER = Damage(FIRE_TYPE(5), DIFFICULTY_SCALING, *ALL_PROTECTIONS, NUDITY_DANGER, RAPID_DAMAGE(2))\r\n\t\tprivate val DAMAGE_DASH = Damage(DIFFICULTY_SCALING, PEACEFUL_EXCLUSION)\r\n\t\t\r\n\t\tprivate val DATA_SLEEPING = EntityData.register<EntityBossEnderEye, Boolean>(DataSerializers.BOOLEAN)\r\n\t\tprivate val DATA_DEMON_LEVEL = EntityData.register<EntityBossEnderEye, Byte>(DataSerializers.BYTE)\r\n\t\tprivate val DATA_ARM_POSITION = EntityData.register<EntityBossEnderEye, Byte>(DataSerializers.BYTE)\r\n\t\tprivate val DATA_ROTATE_TARGET_ID = EntityData.register<EntityBossEnderEye, Int>(DataSerializers.VARINT)\r\n\t\t\r\n\t\tprivate val DEMON_LEVEL_DMG = arrayOf(1.0F, 1.15F, 1.3F, 1.5F, 1.75F, 2.0F)\r\n\t\tprivate val DEMON_LEVEL_XP = arrayOf(1.0F, 1.2F, 1.5F, 1.8F, 2.0F, 2.2F)\r\n\t\t\r\n\t\tprivate const val KNOCKBACK_MP = 0.15\r\n\t\t\r\n\t\tprivate const val SLEEPING_TAG = \"Sleeping\"\r\n\t\tprivate const val DEMON_LEVEL_TAG = \"DemonLevel\"\r\n\t\tprivate const val PHASE_TAG = \"Phase\"\r\n\t\tprivate const val PHASE_DATA_TAG = \"PhaseData\"\r\n\t\t\r\n\t\tconst val ARMS_LIMP: Byte = 0\r\n\t\tconst val ARMS_HUG: Byte = 1\r\n\t\tconst val ARMS_ATTACK: Byte = 2\r\n\t}\r\n\t\r\n\t// Instance\r\n\t\r\n\tprivate val bossInfo = ServerBossInfo(displayName, BossInfo.Color.PINK, BossInfo.Overlay.PROGRESS).apply { isVisible = false }\r\n\t\r\n\tvar isSleepingProp by EntityData(DATA_SLEEPING)\r\n\t\tprivate set\r\n\t\r\n\tvar demonLevel by EntityData(DATA_DEMON_LEVEL)\r\n\t\tprivate set\r\n\t\r\n\tvar armPosition by EntityData(DATA_ARM_POSITION)\r\n\tval clientArmAngle = LerpedFloat(0F)\r\n\t\r\n\tprivate var rotateTargetId by EntityData(DATA_ROTATE_TARGET_ID)\r\n\t\r\n\tprivate val damageMultiplier\r\n\t\tget() = DEMON_LEVEL_DMG.getOrElse(demonLevel.toInt()){ 1F }\r\n\t\r\n\tprivate val experienceMultiplier\r\n\t\tget() = DEMON_LEVEL_XP.getOrElse(demonLevel.toInt()){ 1F }\r\n\t\r\n\tprivate var bossPhase: EnderEyePhase = Hibernated\r\n\tprivate var fallAsleepTimer = 0\r\n\t\r\n\tinit{\r\n\t\tmoveController = EntityMoveFlyingForward(this)\r\n\t\tlookController = EntityLookSlerp(this, adjustmentSpeed = 0.5F, maxInstantAngle = 5F)\r\n\t\t\r\n\t\thealth = maxHealth * 0.5F\r\n\t\tbossInfo.percent = 0.5F\r\n\t}\r\n\t\r\n\toverride fun registerData(){\r\n\t\tsuper.registerData()\r\n\t\tdataManager.register(DATA_SLEEPING, true)\r\n\t\tdataManager.register(DATA_DEMON_LEVEL, 0)\r\n\t\tdataManager.register(DATA_ARM_POSITION, ARMS_LIMP)\r\n\t\tdataManager.register(DATA_ROTATE_TARGET_ID, Int.MIN_VALUE)\r\n\t}\r\n\t\r\n\toverride fun registerAttributes(){\r\n\t\tsuper.registerAttributes()\r\n\t\t\r\n\t\tattributes.registerAttribute(ATTACK_DAMAGE)\r\n\t\tattributes.registerAttribute(FLYING_SPEED)\r\n\t\t\r\n\t\tgetAttribute(MAX_HEALTH).baseValue = 300.0\r\n\t\tgetAttribute(ATTACK_DAMAGE).baseValue = 4.0\r\n\t\tgetAttribute(FLYING_SPEED).baseValue = 0.0925\r\n\t\tgetAttribute(FOLLOW_RANGE).baseValue = 16.0\r\n\t\t\r\n\t\texperienceValue = 50\r\n\t}\r\n\t\r\n\tprivate fun updateDemonLevelAttributes(){\r\n\t\tgetAttribute(ATTACK_DAMAGE).baseValue = 4.0 * damageMultiplier\r\n\t\texperienceValue = (50 * experienceMultiplier).floorToInt()\r\n\t}\r\n\t\r\n\toverride fun createSpawnPacket(): IPacket<*>{\r\n\t\treturn NetworkHooks.getEntitySpawningPacket(this)\r\n\t}\r\n\t\r\n\toverride fun livingTick(){\r\n\t\tval isSleeping = isSleeping\r\n\t\t\r\n\t\tif (isSleeping){\r\n\t\t\tbossInfo.isVisible = false\r\n\t\t}\r\n\t\telse{\r\n\t\t\tbossInfo.isVisible = true\r\n\t\t\tbossInfo.percent = health / maxHealth\r\n\t\t}\r\n\t\t\r\n\t\tif (world.isRemote){\r\n\t\t\tval currentArmAngle = clientArmAngle.currentValue\r\n\t\t\tval targetArmAngle = when(armPosition){\r\n\t\t\t\tARMS_ATTACK -> rotationPitch - 180F\r\n\t\t\t\tARMS_HUG -> rotationPitch - 90F\r\n\t\t\t\telse -> 0F\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif (abs(targetArmAngle - currentArmAngle) < 5F){\r\n\t\t\t\tclientArmAngle.update(targetArmAngle)\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tclientArmAngle.update(currentArmAngle + ((targetArmAngle - currentArmAngle) * 0.6F).coerceIn(-25F, 25F))\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif (!isSleeping){\r\n\t\t\t\trotateTargetId.takeIf { it != Int.MIN_VALUE }?.let(world::getEntityByID)?.let {\r\n\t\t\t\t\tlookController.setLookPositionWithEntity(it, 0F, 0F)\r\n\t\t\t\t\tlookController.tick() // reduces rotation latency\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\telse{\r\n\t\t\tif (ticksExisted == 1){\r\n\t\t\t\tupdateDemonLevelAttributes()\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tval currentTarget = attackTarget\r\n\t\t\t\r\n\t\t\tif (currentTarget == null){\r\n\t\t\t\tif (!isSleeping && (bossPhase is Ready && ++fallAsleepTimer > rand.nextInt(35, 75))){\r\n\t\t\t\t\tisSleepingProp = true\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if (!currentTarget.isAlive || (currentTarget is EntityPlayer && (currentTarget.isCreative || currentTarget.isSpectator))){\r\n\t\t\t\tattackTarget = null\r\n\t\t\t\tsetRotateTarget(null)\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tbossPhase = bossPhase.tick(this)\r\n\t\t}\r\n\t\t\r\n\t\tsuper.livingTick()\r\n\t}\r\n\t\r\n\t// Spawning\r\n\t\r\n\toverride fun onInitialSpawn(world: IWorld, difficulty: DifficultyInstance, reason: SpawnReason, data: ILivingEntityData?, nbt: CompoundNBT?): ILivingEntityData?{\r\n\t\tval yaw = ((rotationYaw + 45F).toInt() / 90) * 90F\r\n\t\tsetPositionAndRotation(posX, posY, posZ, yaw, 0F)\r\n\t\t\r\n\t\treturn super.onInitialSpawn(world, difficulty, reason, data, nbt)\r\n\t}\r\n\t\r\n\tprivate fun wakeUp(source: DamageSource){\r\n\t\tif (!(isSleeping || bossPhase == Hibernated)){\r\n\t\t\treturn\r\n\t\t}\r\n\t\t\r\n\t\tisSleepingProp = false\r\n\t\tfallAsleepTimer = 0\r\n\t\t\r\n\t\tif (bossPhase !is Ready){\r\n\t\t\tbossPhase = OpenEye()\r\n\t\t\tattackTarget = source.trueSource as? EntityPlayer\r\n\t\t}\r\n\t}\r\n\t\r\n\tfun updateDemonLevel(newLevel: Byte){\r\n\t\tdemonLevel = newLevel\r\n\t\tupdateDemonLevelAttributes()\r\n\t}\r\n\t\r\n\toverride fun canDespawn(distanceToClosestPlayerSq: Double): Boolean{\r\n\t\treturn false\r\n\t}\r\n\t\r\n\toverride fun preventDespawn(): Boolean{\r\n\t\treturn true\r\n\t}\r\n\t\r\n\t// Battle\r\n\t\r\n\tfun forceFindNewTarget(): EntityPlayer?{\r\n\t\tval attacker = revengeTarget as? EntityPlayer\r\n\t\t\r\n\t\tif (attacker != null){\r\n\t\t\trevengeTarget = null\r\n\t\t\treturn attacker\r\n\t\t}\r\n\t\t\r\n\t\tval range = getAttribute(FOLLOW_RANGE).value\r\n\t\tval targets = world.selectVulnerableEntities.inRange<EntityPlayer>(posVec, range).filter(::canEntityBeSeen)\r\n\t\t\r\n\t\treturn rng.nextItemOrNull(targets).also { attackTarget = it }\r\n\t}\r\n\t\r\n\toverride fun setAttackTarget(newTarget: EntityLivingBase?){\r\n\t\tsuper.setAttackTarget(newTarget)\r\n\t\t\r\n\t\tif (attackTarget != null){\r\n\t\t\tfallAsleepTimer = 0\r\n\t\t}\r\n\t}\r\n\t\r\n\tfun setRotateTarget(target: EntityLivingBase?){\r\n\t\trotateTargetId = target?.entityId ?: Int.MIN_VALUE\r\n\t}\r\n\t\r\n\toverride fun attackEntityAsMob(entity: Entity): Boolean{\r\n\t\treturn DAMAGE_MELEE.dealToFrom(entity, this)\r\n\t}\r\n\t\r\n\toverride fun attackEntityFrom(source: DamageSource, amount: Float): Boolean{\r\n\t\tif (isInvulnerableTo(source) || amount < 6F){\r\n\t\t\treturn false\r\n\t\t}\r\n\t\t\r\n\t\twakeUp(source)\r\n\t\treturn bossPhase is Ready && super.attackEntityFrom(source, amount)\r\n\t}\r\n\t\r\n\toverride fun isInvulnerableTo(source: DamageSource): Boolean{\r\n\t\treturn super.isInvulnerableTo(source) || source.isProjectile || source.immediateSource !is EntityPlayer\r\n\t}\r\n\t\r\n\tfun performBlastKnockback(target: Entity, strength: Float){\r\n\t\tval ratio = Vec3.fromXZ(target.posX, target.posZ).directionTowards(Vec3.fromXZ(posX, posZ)).scale(strength)\r\n\t\t\r\n\t\tif (target is EntityLivingBase){\r\n\t\t\ttarget.knockBack(this, strength, ratio.x, ratio.z)\r\n\t\t\t\r\n\t\t\tif (target is EntityPlayer){\r\n\t\t\t\tPacketClientLaunchInstantly(target, target.motion).sendToPlayer(target)\r\n\t\t\t}\r\n\t\t}\r\n\t\telse{\r\n\t\t\ttarget.addVelocity(ratio.x, strength.toDouble(), ratio.z)\r\n\t\t}\r\n\t}\r\n\t\r\n\t// Movement\r\n\t\r\n\toverride fun createBodyController(): BodyController{\r\n\t\treturn EntityBodyHeadless(this)\r\n\t}\r\n\t\r\n\toverride fun moveRelative(friction: Float, dir: Vec3d){\r\n\t\tsuper.moveRelative(EntityMoveFlyingForward.AIR_FRICTION, dir)\r\n\t}\r\n\t\r\n\toverride fun canBePushed(): Boolean{\r\n\t\treturn false\r\n\t}\r\n\t\r\n\toverride fun getPushReaction(): PushReaction{\r\n\t\treturn PushReaction.BLOCK\r\n\t}\r\n\t\r\n\toverride fun getCollisionBoundingBox(): AxisAlignedBB?{\r\n\t\treturn boundingBox.takeIf { isAlive && isSleeping }\r\n\t}\r\n\t\r\n\toverride fun collideWithEntity(entity: Entity){}\r\n\toverride fun applyEntityCollision(entity: Entity){}\r\n\t\r\n\toverride fun addVelocity(x: Double, y: Double, z: Double){\r\n\t\tsuper.addVelocity(x * KNOCKBACK_MP, y * KNOCKBACK_MP, z * KNOCKBACK_MP)\r\n\t}\r\n\t\r\n\toverride fun knockBack(entity: Entity, strength: Float, xRatio: Double, zRatio: Double){\r\n\t\tval bossPhase = bossPhase\r\n\t\t\r\n\t\tif (isSleeping || bossPhase !is Ready || !bossPhase.currentAttack.canTakeKnockback){\r\n\t\t\treturn\r\n\t\t}\r\n\t\t\r\n\t\tif (!ForgeHooks.onLivingKnockBack(this, entity, strength, xRatio, zRatio).isCanceled){\r\n\t\t\tmotion = motion.add(Vec3.fromXZ(-xRatio, -zRatio).normalize().scale(KNOCKBACK_MP).withY(0.005))\r\n\t\t\t\r\n\t\t\tif (motionY > 0.05){\r\n\t\t\t\tmotionY = 0.05\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t\r\n\t// Boss info\r\n\t\r\n\toverride fun addTrackingPlayer(player: EntityPlayerMP){\r\n\t\tsuper.addTrackingPlayer(player)\r\n\t\tbossInfo.addPlayer(player)\r\n\t}\r\n\t\r\n\toverride fun removeTrackingPlayer(player: EntityPlayerMP){\r\n\t\tsuper.removeTrackingPlayer(player)\r\n\t\tbossInfo.removePlayer(player)\r\n\t}\r\n\t\r\n\toverride fun setCustomName(name: ITextComponent?){\r\n\t\tsuper.setCustomName(name)\r\n\t\tbossInfo.name = displayName\r\n\t}\r\n\t\r\n\t// Properties\r\n\t\r\n\toverride fun getLootTable(): ResourceLocation{\r\n\t\treturn Resource.Custom(\"entities/ender_eye\")\r\n\t}\r\n\t\r\n\toverride fun getCreatureAttribute(): CreatureAttribute{\r\n\t\treturn CustomCreatureType.ENDER\r\n\t}\r\n\t\r\n\toverride fun getStandingEyeHeight(pose: Pose, size: EntitySize): Float{\r\n\t\treturn size.height * 0.5F\r\n\t}\r\n\t\r\n\toverride fun isSleeping(): Boolean{\r\n\t\treturn isSleepingProp\r\n\t}\r\n\t\r\n\t// Serialization\r\n\t\r\n\toverride fun writeAdditional(nbt: TagCompound) = nbt.heeTag.use {\r\n\t\tsuper.writeAdditional(nbt)\r\n\t\t\r\n\t\tputBoolean(SLEEPING_TAG, isSleeping)\r\n\t\tputByte(DEMON_LEVEL_TAG, demonLevel)\r\n\t\t\r\n\t\tputString(PHASE_TAG, when(bossPhase){\r\n\t\t\tHibernated -> \"Hibernated\"\r\n\t\t\tis OpenEye -> \"OpenEye\"\r\n\t\t\tis Floating -> \"Floating\"\r\n\t\t\tis Staring -> \"Staring\"\r\n\t\t\tis Ready -> \"Ready\"\r\n\t\t})\r\n\t\t\r\n\t\tput(PHASE_DATA_TAG, bossPhase.serializeNBT())\r\n\t}\r\n\t\r\n\toverride fun readAdditional(nbt: TagCompound) = nbt.heeTag.use {\r\n\t\tsuper.readAdditional(nbt)\r\n\t\t\r\n\t\tisSleepingProp = getBoolean(SLEEPING_TAG)\r\n\t\tdemonLevel = getByte(DEMON_LEVEL_TAG)\r\n\t\t\r\n\t\tbossPhase = when(getString(PHASE_TAG)){\r\n\t\t\t\"Hibernated\" -> Hibernated\r\n\t\t\t\"OpenEye\" -> OpenEye()\r\n\t\t\t\"Floating\" -> Floating(0)\r\n\t\t\t\"Staring\" -> Staring()\r\n\t\t\telse -> Ready()\r\n\t\t}\r\n\t\t\r\n\t\tbossPhase.deserializeNBT(getCompound(PHASE_DATA_TAG))\r\n\t}\r\n}\r\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/main/java/chylex/hee/game/entity/living/EntityBossEnderEye.kt (revision 41aa0b6695a1ac98e2d75beae7cb260618fe1f25)
+++ src/main/java/chylex/hee/game/entity/living/EntityBossEnderEye.kt (date 1579751793267)
@@ -1,5 +1,7 @@
package chylex.hee.game.entity.living
import chylex.hee.game.entity.CustomCreatureType
+import chylex.hee.game.entity.living.behavior.EnderEyeAttack.KnockbackDash
+import chylex.hee.game.entity.living.behavior.EnderEyeAttack.Melee
import chylex.hee.game.entity.living.behavior.EnderEyePhase
import chylex.hee.game.entity.living.behavior.EnderEyePhase.Floating
import chylex.hee.game.entity.living.behavior.EnderEyePhase.Hibernated
@@ -38,6 +40,7 @@
import chylex.hee.system.util.posVec
import chylex.hee.system.util.scale
import chylex.hee.system.util.selectVulnerableEntities
+import chylex.hee.system.util.totalTime
import chylex.hee.system.util.use
import chylex.hee.system.util.withY
import net.minecraft.block.material.PushReaction
@@ -122,6 +125,7 @@
private var bossPhase: EnderEyePhase = Hibernated
private var fallAsleepTimer = 0
+ private var lastKnockbackDashTime = 0L
init{
moveController = EntityMoveFlyingForward(this)
@@ -350,7 +354,11 @@
return
}
- if (!ForgeHooks.onLivingKnockBack(this, entity, strength, xRatio, zRatio).isCanceled){
+ if (bossPhase.currentAttack is Melee && rand.nextInt(13) == 0 && world.totalTime - lastKnockbackDashTime >= 200L){
+ super.knockBack(entity, strength, xRatio, zRatio)
+ bossPhase.currentAttack = KnockbackDash()
+ }
+ else if (!ForgeHooks.onLivingKnockBack(this, entity, strength, xRatio, zRatio).isCanceled){
motion = motion.add(Vec3.fromXZ(-xRatio, -zRatio).normalize().scale(KNOCKBACK_MP).withY(0.005))
if (motionY > 0.05){
Index: src/main/java/chylex/hee/game/entity/living/behavior/EnderEyeAttack.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>package chylex.hee.game.entity.living.behavior\r\nimport chylex.hee.game.entity.living.EntityBossEnderEye\r\nimport chylex.hee.system.util.directionTowards\r\nimport chylex.hee.system.util.lookPosVec\r\nimport chylex.hee.system.util.square\r\nimport chylex.hee.system.util.totalTime\r\n\r\nsealed class EnderEyeAttack{\r\n\tabstract val canTakeKnockback: Boolean\r\n\tabstract fun tick(entity: EntityBossEnderEye): Boolean\r\n\t\r\n\tclass Melee : EnderEyeAttack(){\r\n\t\toverride val canTakeKnockback = true\r\n\t\tprivate var lastAttackTime = 0L\r\n\t\t\r\n\t\toverride fun tick(entity: EntityBossEnderEye): Boolean = with(entity){\r\n\t\t\tval target = attackTarget ?: forceFindNewTarget()\r\n\t\t\t\r\n\t\t\tif (target == null){\r\n\t\t\t\tarmPosition = EntityBossEnderEye.ARMS_LIMP\r\n\t\t\t\taiMoveSpeed = 0F\r\n\t\t\t\tsetRotateTarget(null)\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\tarmPosition = EntityBossEnderEye.ARMS_HUG\r\n\t\t\t\tlookController.setLookPositionWithEntity(target, 0F, 0F)\r\n\t\t\t\tsetRotateTarget(target)\r\n\t\t\t\t\r\n\t\t\t\tval currentVec = lookPosVec\r\n\t\t\t\tval targetVec = target.lookPosVec\r\n\t\t\t\tval distSq = targetVec.squareDistanceTo(currentVec)\r\n\t\t\t\t\r\n\t\t\t\tif (distSq > square(1.2)){\r\n\t\t\t\t\tmoveHelper.setMoveTo(targetVec.x, targetVec.y, targetVec.z, 1.0)\r\n\t\t\t\t}\r\n\t\t\t\telse{\r\n\t\t\t\t\tif (currentVec.directionTowards(targetVec).dotProduct(motion.normalize()) > 0.0){\r\n\t\t\t\t\t\tmotion = motion.scale(0.4)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\tif (distSq < square(1.4)){\r\n\t\t\t\t\tval currentTime = world.totalTime\r\n\t\t\t\t\t\r\n\t\t\t\t\tif (currentTime - lastAttackTime >= 20L){\r\n\t\t\t\t\t\tlastAttackTime = currentTime\r\n\t\t\t\t\t\tattackEntityAsMob(target)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n}\r\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/main/java/chylex/hee/game/entity/living/behavior/EnderEyeAttack.kt (revision 41aa0b6695a1ac98e2d75beae7cb260618fe1f25)
+++ src/main/java/chylex/hee/game/entity/living/behavior/EnderEyeAttack.kt (date 1579750426662)
@@ -52,4 +52,13 @@
return true
}
}
+
+ class KnockbackDash : EnderEyeAttack(){
+ override val canTakeKnockback = false
+
+ override fun tick(entity: EntityBossEnderEye): Boolean{
+ // TODO
+ return false
+ }
+ }
}