mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 19:35:00 -04:00
split player in remote and local player, entity effect particles
This commit is contained in:
parent
8517ca0424
commit
15918d9a90
@ -33,7 +33,7 @@ import de.bixilon.minosoft.data.entities.entities.monster.piglin.PiglinBrute
|
||||
import de.bixilon.minosoft.data.entities.entities.monster.raid.*
|
||||
import de.bixilon.minosoft.data.entities.entities.npc.villager.Villager
|
||||
import de.bixilon.minosoft.data.entities.entities.npc.villager.WanderingTrader
|
||||
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
|
||||
import de.bixilon.minosoft.data.entities.entities.player.RemotePlayerEntity
|
||||
import de.bixilon.minosoft.data.entities.entities.projectile.*
|
||||
import de.bixilon.minosoft.data.entities.entities.vehicle.*
|
||||
import de.bixilon.minosoft.data.entities.meta.EntityMetaData
|
||||
@ -156,7 +156,7 @@ object DefaultEntityFactories : DefaultFactory<EntityFactory<out Entity>>(
|
||||
ZombieVillager,
|
||||
ZombiePigman,
|
||||
ZombifiedPiglin,
|
||||
PlayerEntity,
|
||||
RemotePlayerEntity,
|
||||
FishingHook,
|
||||
GlowSquid,
|
||||
EvokerFangs,
|
||||
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.inventory.InventorySlots.EquipmentSlots
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.mappings.effects.StatusEffect
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||
import de.bixilon.minosoft.data.physics.Speedable
|
||||
import de.bixilon.minosoft.data.physics.PhysicsEntity
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
||||
@ -34,13 +34,15 @@ import glm_.vec3.Vec3
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.util.*
|
||||
import kotlin.math.pow
|
||||
import kotlin.random.Random
|
||||
|
||||
abstract class Entity(
|
||||
protected val connection: PlayConnection,
|
||||
val entityType: EntityType,
|
||||
override var position: Vec3,
|
||||
var rotation: EntityRotation,
|
||||
) : Speedable {
|
||||
) : PhysicsEntity {
|
||||
protected val random = Random
|
||||
val equipment: MutableMap<EquipmentSlots, ItemStack> = mutableMapOf()
|
||||
val activeStatusEffects: MutableMap<StatusEffect, StatusEffectInstance> = synchronizedMapOf()
|
||||
|
||||
@ -62,6 +64,8 @@ abstract class Entity(
|
||||
Vec3(+(entityType.width / 2 + HITBOX_MARGIN), entityType.height, +(entityType.width / 2 + HITBOX_MARGIN))
|
||||
)
|
||||
|
||||
private var lastTickTime = -1L
|
||||
|
||||
fun forceMove(deltaPosition: Vec3) {
|
||||
position = position + deltaPosition
|
||||
}
|
||||
@ -232,8 +236,16 @@ abstract class Entity(
|
||||
check(deltaMillis > 0L) { "Delta tick time is <= 0: $deltaMillis" }
|
||||
|
||||
tickMovement(deltaMillis)
|
||||
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - lastTickTime >= ProtocolDefinition.TICK_TIME) {
|
||||
realTick()
|
||||
lastTickTime = currentTime
|
||||
}
|
||||
}
|
||||
|
||||
open fun realTick() {}
|
||||
|
||||
private val aabb: AABB
|
||||
get() = defaultAABB + position
|
||||
|
||||
|
@ -17,17 +17,25 @@ import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.data.entities.attributes.DefaultEntityAttributes
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||
import de.bixilon.minosoft.data.player.Hands
|
||||
import de.bixilon.minosoft.data.text.ChatColors
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.data.text.RGBColor.Companion.asRGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell.AmbientEntityEffectParticle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell.EntityEffectParticle
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.vertical
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.chance
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
abstract class LivingEntity(connection: PlayConnection, entityType: EntityType, position: Vec3, rotation: EntityRotation) : Entity(connection, entityType, position, rotation) {
|
||||
private val entityEffectParticle = connection.registries.particleTypeRegistry[EntityEffectParticle]
|
||||
private val ambientEntityEffectParticle = connection.registries.particleTypeRegistry[AmbientEntityEffectParticle]
|
||||
|
||||
private fun getLivingEntityFlag(bitMask: Int): Boolean {
|
||||
return entityMetaData.sets.getBitMask(EntityMetaDataFields.LIVING_ENTITY_FLAGS, bitMask)
|
||||
}
|
||||
|
||||
// = isUsingItem
|
||||
@get:EntityMetaDataFunction(name = "Is hand active")
|
||||
val isHandActive: Boolean
|
||||
get() = getLivingEntityFlag(0x01)
|
||||
@ -52,8 +60,8 @@ abstract class LivingEntity(connection: PlayConnection, entityType: EntityType,
|
||||
}
|
||||
|
||||
@get:EntityMetaDataFunction(name = "Effect color")
|
||||
val effectColor: Int
|
||||
get() = entityMetaData.sets.getInt(EntityMetaDataFields.LIVING_ENTITY_EFFECT_COLOR)
|
||||
val effectColor: RGBColor
|
||||
get() = entityMetaData.sets.getInt(EntityMetaDataFields.LIVING_ENTITY_EFFECT_COLOR).asRGBColor()
|
||||
|
||||
@get:EntityMetaDataFunction(name = "Is effect ambient")
|
||||
val effectAmbient: Boolean
|
||||
@ -70,4 +78,46 @@ abstract class LivingEntity(connection: PlayConnection, entityType: EntityType,
|
||||
@get:EntityMetaDataFunction(name = "Bed location")
|
||||
val bedPosition: Vec3i?
|
||||
get() = entityMetaData.sets.getBlockPosition(EntityMetaDataFields.LIVING_ENTITY_BED_POSITION)
|
||||
|
||||
|
||||
private fun tickStatusEffects() {
|
||||
if (entityEffectParticle == null && ambientEntityEffectParticle == null) {
|
||||
return
|
||||
}
|
||||
if (effectColor == ChatColors.BLACK) {
|
||||
return
|
||||
}
|
||||
var spawnParticles = if (isInvisible) {
|
||||
random.nextInt(15) == 0
|
||||
} else {
|
||||
random.nextBoolean()
|
||||
}
|
||||
|
||||
if (effectAmbient) {
|
||||
spawnParticles = spawnParticles && random.chance(20)
|
||||
}
|
||||
|
||||
if (!spawnParticles) {
|
||||
return
|
||||
}
|
||||
|
||||
val particlePosition = position + Vec3.vertical(
|
||||
{ entityType.width * ((2.0f * random.nextFloat() - 1.0f) * 0.5f) },
|
||||
entityType.height * random.nextFloat()
|
||||
)
|
||||
if (effectAmbient) {
|
||||
ambientEntityEffectParticle ?: return
|
||||
connection.world += AmbientEntityEffectParticle(connection, particlePosition, effectColor, ambientEntityEffectParticle.default())
|
||||
} else {
|
||||
entityEffectParticle ?: return
|
||||
connection.world += EntityEffectParticle(connection, particlePosition, effectColor, entityEffectParticle.default())
|
||||
}
|
||||
}
|
||||
|
||||
override fun realTick() {
|
||||
super.realTick()
|
||||
tickStatusEffects()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -17,8 +17,6 @@ import de.bixilon.minosoft.data.entities.EntityMetaDataFields
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.data.entities.entities.EntityMetaDataFunction
|
||||
import de.bixilon.minosoft.data.entities.entities.LivingEntity
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityFactory
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||
import de.bixilon.minosoft.data.player.Hands
|
||||
import de.bixilon.minosoft.data.player.PlayerProperties
|
||||
@ -27,7 +25,7 @@ import de.bixilon.minosoft.data.player.tab.TabListItem
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
class PlayerEntity(
|
||||
abstract class PlayerEntity(
|
||||
connection: PlayConnection,
|
||||
entityType: EntityType,
|
||||
position: Vec3 = Vec3(0, 0, 0),
|
||||
@ -82,8 +80,4 @@ class PlayerEntity(
|
||||
@get:EntityMetaDataFunction(name = "Right shoulder entity data")
|
||||
val rightShoulderData: Map<String, Any>?
|
||||
get() = entityMetaData.sets.getNBT(EntityMetaDataFields.PLAYER_RIGHT_SHOULDER_DATA)
|
||||
|
||||
companion object : EntityFactory<PlayerEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("player")
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.entities.entities.player
|
||||
|
||||
import de.bixilon.minosoft.data.abilities.Gamemodes
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityFactory
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||
import de.bixilon.minosoft.data.player.PlayerProperties
|
||||
import de.bixilon.minosoft.data.player.PlayerProperty
|
||||
import de.bixilon.minosoft.data.player.tab.TabListItem
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
class RemotePlayerEntity(
|
||||
connection: PlayConnection,
|
||||
entityType: EntityType,
|
||||
position: Vec3 = Vec3(0, 0, 0),
|
||||
rotation: EntityRotation = EntityRotation(0.0, 0.0),
|
||||
name: String = "TBA",
|
||||
properties: Map<PlayerProperties, PlayerProperty> = mapOf(),
|
||||
tabListItem: TabListItem = TabListItem(name = name, gamemode = Gamemodes.SURVIVAL, properties = properties),
|
||||
) : PlayerEntity(connection, entityType, position, rotation, name, properties, tabListItem) {
|
||||
|
||||
companion object : EntityFactory<PlayerEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("minecraft:player")
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ open class BlockItem(
|
||||
val block: Block = registries.blockRegistry[data["block"].asInt]
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
|
||||
if (!connection.player.entity.gamemode.canBuild) {
|
||||
if (!connection.player.gamemode.canBuild) {
|
||||
return BlockUsages.PASS
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ open class BlockItem(
|
||||
|
||||
connection.world[placePosition] = placeBlockState
|
||||
|
||||
if (connection.player.entity.gamemode != Gamemodes.CREATIVE) {
|
||||
if (connection.player.gamemode != Gamemodes.CREATIVE) {
|
||||
itemStack.count--
|
||||
connection.player.inventory.validate()
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ abstract class MiningToolItem(
|
||||
}
|
||||
|
||||
protected fun interactWithTool(connection: PlayConnection, blockPosition: Vec3i, replace: BlockState?): BlockUsages {
|
||||
if (!connection.player.entity.gamemode.useTools) {
|
||||
if (!connection.player.gamemode.useTools) {
|
||||
return BlockUsages.PASS
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,6 @@ object GameMoveChangeGameEventHandler : GameEventHandler {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:gamemode_change".asResourceLocation()
|
||||
|
||||
override fun handle(data: Float, connection: PlayConnection) {
|
||||
connection.player.entity.tabListItem.gamemode = Gamemodes[data.toInt()]
|
||||
connection.player.tabListItem.gamemode = Gamemodes[data.toInt()]
|
||||
}
|
||||
}
|
||||
|
@ -42,19 +42,19 @@ class CollisionDetector(val connection: PlayConnection) {
|
||||
return result
|
||||
}
|
||||
|
||||
fun collide(speedable: Speedable, deltaPosition: Vec3, collisionsToCheck: VoxelShape, aabb: AABB): Vec3 {
|
||||
fun collide(physicsEntity: PhysicsEntity, deltaPosition: Vec3, collisionsToCheck: VoxelShape, aabb: AABB): Vec3 {
|
||||
val delta = Vec3(deltaPosition)
|
||||
if (delta.y != 0.0f) {
|
||||
delta.y = collisionsToCheck.computeOffset(aabb, deltaPosition.y, Axes.Y)
|
||||
if (delta.y != deltaPosition.y) {
|
||||
speedable.onGround = false
|
||||
speedable.velocity.y = 0.0f
|
||||
physicsEntity.onGround = false
|
||||
physicsEntity.velocity.y = 0.0f
|
||||
if (deltaPosition.y < 0) {
|
||||
speedable.onGround = true
|
||||
physicsEntity.onGround = true
|
||||
}
|
||||
aabb += Vec3(0f, delta.y, 0f)
|
||||
} else if (delta.y < 0) {
|
||||
speedable.onGround = false
|
||||
physicsEntity.onGround = false
|
||||
}
|
||||
}
|
||||
if ((deltaPosition.x != 0f || deltaPosition.z != 0f)) {
|
||||
@ -72,21 +72,21 @@ class CollisionDetector(val connection: PlayConnection) {
|
||||
delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X)
|
||||
aabb += Vec3(delta.x, 0f, 0f)
|
||||
if (delta.x != deltaPosition.x) {
|
||||
speedable.velocity.x = 0.0f
|
||||
physicsEntity.velocity.x = 0.0f
|
||||
}
|
||||
}
|
||||
if (delta.z != 0.0f) {
|
||||
delta.z = collisionsToCheck.computeOffset(aabb, deltaPosition.z, Axes.Z)
|
||||
aabb += Vec3(0f, 0f, delta.z)
|
||||
if (delta.z != deltaPosition.z) {
|
||||
speedable.velocity.z = 0.0f
|
||||
physicsEntity.velocity.z = 0.0f
|
||||
}
|
||||
}
|
||||
if (delta.x != 0.0f && !xPriority) {
|
||||
delta.x = collisionsToCheck.computeOffset(aabb, deltaPosition.x, Axes.X)
|
||||
// no need to offset the aabb any more, as it won't be used any more
|
||||
if (delta.x != deltaPosition.x) {
|
||||
speedable.velocity.x = 0.0f
|
||||
physicsEntity.velocity.x = 0.0f
|
||||
}
|
||||
}
|
||||
if (delta.length() > deltaPosition.length() + Entity.STEP_HEIGHT) {
|
||||
|
@ -15,7 +15,7 @@ package de.bixilon.minosoft.data.physics
|
||||
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
interface Speedable {
|
||||
interface PhysicsEntity {
|
||||
val position: Vec3
|
||||
val velocity: Vec3
|
||||
var onGround: Boolean
|
@ -16,6 +16,7 @@ import de.bixilon.minosoft.data.abilities.ItemCooldown
|
||||
import de.bixilon.minosoft.data.accounts.Account
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
|
||||
import de.bixilon.minosoft.data.entities.entities.player.RemotePlayerEntity
|
||||
import de.bixilon.minosoft.data.mappings.items.Item
|
||||
import de.bixilon.minosoft.data.mappings.other.containers.Container
|
||||
import de.bixilon.minosoft.data.mappings.other.containers.PlayerInventory
|
||||
@ -26,14 +27,13 @@ import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class Player(
|
||||
class LocalPlayerEntity(
|
||||
account: Account,
|
||||
connection: PlayConnection,
|
||||
) {
|
||||
) : PlayerEntity(connection, connection.registries.entityTypeRegistry[RemotePlayerEntity.RESOURCE_LOCATION]!!, Vec3.EMPTY, EntityRotation(0.0, 0.0), account.username) {
|
||||
val healthCondition = PlayerHealthCondition()
|
||||
val experienceCondition = PlayerExperienceCondition()
|
||||
var spawnPosition: Vec3i = Vec3i.EMPTY
|
||||
val entity: PlayerEntity = PlayerEntity(connection, connection.registries.entityTypeRegistry[PlayerEntity.RESOURCE_LOCATION]!!, Vec3.EMPTY, EntityRotation(0.0, 0.0), account.username)
|
||||
|
||||
@Deprecated(message = "Will be replaced with some kind of teleport manager, ...")
|
||||
var isSpawnConfirmed = false
|
@ -184,7 +184,7 @@ class World(
|
||||
}
|
||||
|
||||
private fun randomTick(radius: Int) {
|
||||
val blockPosition = connection.player.entity.position.blockPosition + { random.nextInt(radius) } - { random.nextInt(radius) }
|
||||
val blockPosition = connection.player.position.blockPosition + { random.nextInt(radius) } - { random.nextInt(radius) }
|
||||
|
||||
val blockState = this[blockPosition] ?: return
|
||||
|
||||
|
@ -150,7 +150,7 @@ class BlockOutlineRenderer(
|
||||
return
|
||||
}
|
||||
|
||||
if (connection.player.entity.gamemode == Gamemodes.ADVENTURE || connection.player.entity.gamemode == Gamemodes.SPECTATOR) {
|
||||
if (connection.player.gamemode == Gamemodes.ADVENTURE || connection.player.gamemode == Gamemodes.SPECTATOR) {
|
||||
if (raycastHit.blockState.block.blockEntityType == null) {
|
||||
unload()
|
||||
return
|
||||
|
@ -76,7 +76,7 @@ class HUDWorldDebugNode(hudRenderer: HUDRenderer) : DebugScreenNode(hudRenderer)
|
||||
|
||||
|
||||
// ToDo: Prepare on change
|
||||
gamemodeText.sText = "Gamemode: ${hudRenderer.connection.player.entity.gamemode.name.lowercase(Locale.getDefault())}"
|
||||
gamemodeText.sText = "Gamemode: ${hudRenderer.connection.player.gamemode.name.lowercase(Locale.getDefault())}"
|
||||
positionText.sText = "XYZ ${getPosition()}"
|
||||
blockPositionText.sText = "Block ${getBlockPosition()}"
|
||||
chunkPositionText.sText = "Chunk ${getChunkLocation()}"
|
||||
|
@ -91,7 +91,7 @@ class LeftClickHandler(
|
||||
return false
|
||||
}
|
||||
|
||||
if (!connection.player.entity.gamemode.canBreak) {
|
||||
if (!connection.player.gamemode.canBreak) {
|
||||
cancelDigging()
|
||||
return false
|
||||
}
|
||||
@ -140,7 +140,7 @@ class LeftClickHandler(
|
||||
val canStartBreaking = currentTime - breakSent >= ProtocolDefinition.TICK_TIME
|
||||
|
||||
|
||||
val canInstantBreak = connection.player.baseAbilities.canInstantBreak || connection.player.entity.gamemode == Gamemodes.CREATIVE
|
||||
val canInstantBreak = connection.player.baseAbilities.canInstantBreak || connection.player.gamemode == Gamemodes.CREATIVE
|
||||
|
||||
if (canInstantBreak) {
|
||||
if (!canStartBreaking) {
|
||||
@ -189,17 +189,17 @@ class LeftClickHandler(
|
||||
}
|
||||
}
|
||||
|
||||
connection.player.entity.activeStatusEffects[hasteStatusEffect]?.let {
|
||||
connection.player.activeStatusEffects[hasteStatusEffect]?.let {
|
||||
speedMultiplier *= (0.2f * it.amplifier) + 1.0f
|
||||
}
|
||||
|
||||
connection.player.entity.activeStatusEffects[miningFatigueStatusEffect]?.let {
|
||||
connection.player.activeStatusEffects[miningFatigueStatusEffect]?.let {
|
||||
speedMultiplier *= 0.3f.pow(it.amplifier + 1)
|
||||
}
|
||||
|
||||
// ToDo: Check if is in water
|
||||
|
||||
if (!connection.player.entity.onGround) {
|
||||
if (!connection.player.onGround) {
|
||||
speedMultiplier /= 5.0f
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class Camera(
|
||||
private var lastMouseX = 0.0
|
||||
private var lastMouseY = 0.0
|
||||
val playerEntity: PlayerEntity
|
||||
get() = connection.player.entity
|
||||
get() = connection.player
|
||||
var yaw = 0.0
|
||||
var pitch = 0.0
|
||||
private var zoom = 0.0f
|
||||
@ -222,7 +222,7 @@ class Camera(
|
||||
if (renderWindow.inputHandler.currentKeyConsumer != null) { // ToDo
|
||||
return
|
||||
}
|
||||
var cameraSpeed = if (connection.player.entity.isFlying) {
|
||||
var cameraSpeed = if (connection.player.isFlying) {
|
||||
flyingSpeed
|
||||
} else {
|
||||
walkingSpeed
|
||||
|
@ -21,6 +21,8 @@ import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.Ex
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.dust.DustParticle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.fire.SmokeParticle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava.LavaParticle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell.AmbientEntityEffectParticle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell.EntityEffectParticle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.suspend.DolphinParticle
|
||||
|
||||
object DefaultParticleFactory : DefaultFactory<ParticleFactory<out Particle>>(
|
||||
@ -32,4 +34,6 @@ object DefaultParticleFactory : DefaultFactory<ParticleFactory<out Particle>>(
|
||||
SmokeParticle,
|
||||
DolphinParticle,
|
||||
DustParticle,
|
||||
EntityEffectParticle,
|
||||
AmbientEntityEffectParticle,
|
||||
)
|
||||
|
@ -14,7 +14,7 @@
|
||||
package de.bixilon.minosoft.gui.rendering.particle.types
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
||||
import de.bixilon.minosoft.data.physics.Speedable
|
||||
import de.bixilon.minosoft.data.physics.PhysicsEntity
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleMesh
|
||||
@ -36,7 +36,7 @@ abstract class Particle(
|
||||
final override val position: Vec3,
|
||||
final override val velocity: Vec3 = Vec3.EMPTY,
|
||||
data: ParticleData? = null,
|
||||
) : Speedable {
|
||||
) : PhysicsEntity {
|
||||
protected val data: ParticleData = data ?: let {
|
||||
val resourceLocation = this::class.companionObjectInstance as ParticleFactory<*>
|
||||
connection.registries.particleTypeRegistry[resourceLocation]!!.default()
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
class AmbientEntityEffectParticle(connection: PlayConnection, position: Vec3, color: RGBColor, data: ParticleData? = null) : SpellParticle(connection, position, Vec3(color.red, color.green, color.blue), data) {
|
||||
|
||||
init {
|
||||
this.color = color.with(alpha = 0.15f)
|
||||
}
|
||||
|
||||
companion object : ParticleFactory<AmbientEntityEffectParticle> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:ambient_entity_effect".asResourceLocation()
|
||||
|
||||
override fun build(connection: PlayConnection, position: Vec3, velocity: Vec3, data: ParticleData): AmbientEntityEffectParticle {
|
||||
return AmbientEntityEffectParticle(connection, position, color = RGBColor(velocity.x, velocity.y, velocity.z), data)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
||||
import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleFactory
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
import glm_.vec3.Vec3
|
||||
|
||||
class EntityEffectParticle(connection: PlayConnection, position: Vec3, color: RGBColor, data: ParticleData? = null) : SpellParticle(connection, position, Vec3(color.red, color.green, color.blue), data) {
|
||||
|
||||
init {
|
||||
this.color = color
|
||||
}
|
||||
|
||||
companion object : ParticleFactory<EntityEffectParticle> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = "minecraft:entity_effect".asResourceLocation()
|
||||
|
||||
override fun build(connection: PlayConnection, position: Vec3, velocity: Vec3, data: ParticleData): EntityEffectParticle {
|
||||
return EntityEffectParticle(connection, position, color = RGBColor(velocity.x, velocity.y, velocity.z), data)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.spell
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.particle.data.ParticleData
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.SimpleTextureParticle
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.MMath
|
||||
import glm_.vec3.Vec3
|
||||
import kotlin.random.Random
|
||||
|
||||
abstract class SpellParticle(connection: PlayConnection, position: Vec3, velocity: Vec3, data: ParticleData? = null) : SimpleTextureParticle(connection, position, Vec3(0.5f - Random.nextFloat(), velocity.y, 0.5 - Random.nextFloat()), data) {
|
||||
|
||||
init {
|
||||
friction = 0.96f
|
||||
gravityStrength = -0.1f
|
||||
accelerateIfYBlocked = true
|
||||
this.velocity.y *= 0.20000000298023224f
|
||||
if (velocity.x == 0.0f && velocity.z == 0.0f) {
|
||||
this.velocity.x *= 0.10000000149011612f
|
||||
this.velocity.z *= 0.10000000149011612f
|
||||
}
|
||||
super.scale *= 0.75f
|
||||
maxAge = (8.0f / (random.nextFloat() * 0.8f + 0.2f)).toInt()
|
||||
this.physics = false
|
||||
|
||||
// ToDo: Toggle if using spyglass
|
||||
}
|
||||
|
||||
override fun realTick() {
|
||||
super.realTick()
|
||||
|
||||
color = color.with(alpha = MMath.lerp(0.05f, color.floatAlpha, 1.0f))
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ import de.bixilon.minosoft.data.mappings.recipes.Recipes
|
||||
import de.bixilon.minosoft.data.mappings.versions.Registries
|
||||
import de.bixilon.minosoft.data.mappings.versions.Version
|
||||
import de.bixilon.minosoft.data.physics.CollisionDetector
|
||||
import de.bixilon.minosoft.data.player.Player
|
||||
import de.bixilon.minosoft.data.player.LocalPlayerEntity
|
||||
import de.bixilon.minosoft.data.player.tab.TabList
|
||||
import de.bixilon.minosoft.data.scoreboard.ScoreboardManager
|
||||
import de.bixilon.minosoft.data.tags.Tag
|
||||
@ -75,7 +75,7 @@ class PlayConnection(
|
||||
|
||||
var rendering: Rendering? = null
|
||||
private set
|
||||
lateinit var player: Player
|
||||
lateinit var player: LocalPlayerEntity
|
||||
private set
|
||||
|
||||
private lateinit var entityTickTask: TimeWorkerTask
|
||||
@ -186,7 +186,7 @@ class PlayConnection(
|
||||
version.load(latch) // ToDo: show gui loader
|
||||
assetsManager = MultiAssetsManager(version.assetsManager, Minosoft.MINOSOFT_ASSETS_MANAGER, Minosoft.MINECRAFT_FALLBACK_ASSETS_MANAGER)
|
||||
registries.parentRegistries = version.registries
|
||||
player = Player(account, this)
|
||||
player = LocalPlayerEntity(account, this)
|
||||
|
||||
if (!RenderConstants.DISABLE_RENDERING && !StaticConfiguration.HEADLESS_MODE) {
|
||||
val renderer = Rendering(this)
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
package de.bixilon.minosoft.protocol.packets.c2s.login
|
||||
|
||||
import de.bixilon.minosoft.data.player.Player
|
||||
import de.bixilon.minosoft.data.player.LocalPlayerEntity
|
||||
import de.bixilon.minosoft.protocol.packets.c2s.PlayC2SPacket
|
||||
import de.bixilon.minosoft.protocol.protocol.PlayOutByteBuffer
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
@ -23,7 +23,7 @@ class LoginStartC2SP(
|
||||
val username: String,
|
||||
) : PlayC2SPacket {
|
||||
|
||||
constructor(player: Player) : this(player.entity.name)
|
||||
constructor(player: LocalPlayerEntity) : this(player.name)
|
||||
|
||||
override fun write(buffer: PlayOutByteBuffer) {
|
||||
buffer.writeString(username)
|
||||
|
@ -35,7 +35,7 @@ class LoginSuccessS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
override fun handle(connection: PlayConnection) {
|
||||
connection.connectionState = ConnectionStates.PLAY
|
||||
|
||||
val playerEntity = connection.player.entity
|
||||
val playerEntity = connection.player
|
||||
playerEntity.tabListItem.name = name
|
||||
playerEntity.tabListItem.displayName = ChatComponent.of(name)
|
||||
|
||||
|
@ -41,7 +41,7 @@ class ExplosionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
val blockPosition = Vec3i(position + record)
|
||||
connection.world.setBlockState(blockPosition, null)
|
||||
}
|
||||
connection.player.entity.velocity = connection.player.entity.velocity + velocity
|
||||
connection.player.velocity = connection.player.velocity + velocity
|
||||
|
||||
connection.fireEvent(ExplosionEvent(connection, this))
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ class JoinGameS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
if (connection.fireEvent(JoinGameEvent(connection, this))) {
|
||||
return
|
||||
}
|
||||
val playerEntity = connection.player.entity
|
||||
val playerEntity = connection.player
|
||||
playerEntity.tabListItem.gamemode = gamemode
|
||||
|
||||
connection.world.hardcore = isHardcore
|
||||
|
@ -46,7 +46,7 @@ class PlayerAbilitiesS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
}
|
||||
|
||||
override fun log() {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Player abilities: (isInvulnerable=$isInvulnerable, isFlying=$isFlying, canFly=$canFly, canInstantBuild=$canInstantBuild, flyingSpeed=$flyingSpeed, walkingSpeed=$walkingSpeed)" }
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "LocalPlayerEntity abilities: (isInvulnerable=$isInvulnerable, isFlying=$isFlying, canFly=$canFly, canInstantBuild=$canInstantBuild, flyingSpeed=$flyingSpeed, walkingSpeed=$walkingSpeed)" }
|
||||
}
|
||||
|
||||
override fun handle(connection: PlayConnection) {
|
||||
|
@ -16,6 +16,7 @@ import de.bixilon.minosoft.config.StaticConfiguration
|
||||
import de.bixilon.minosoft.data.PlayerPropertyData
|
||||
import de.bixilon.minosoft.data.entities.EntityRotation
|
||||
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
|
||||
import de.bixilon.minosoft.data.entities.entities.player.RemotePlayerEntity
|
||||
import de.bixilon.minosoft.data.entities.meta.EntityMetaData
|
||||
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
@ -66,9 +67,9 @@ class PlayerEntitySpawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
if (buffer.versionId < ProtocolVersions.V_19W34A) {
|
||||
metaData = buffer.readMetaData()
|
||||
}
|
||||
entity = PlayerEntity(
|
||||
entity = RemotePlayerEntity(
|
||||
connection = buffer.connection,
|
||||
entityType = buffer.connection.registries.entityTypeRegistry[PlayerEntity.RESOURCE_LOCATION]!!,
|
||||
entityType = buffer.connection.registries.entityTypeRegistry[RemotePlayerEntity.RESOURCE_LOCATION]!!,
|
||||
position = position,
|
||||
rotation = EntityRotation(yaw.toFloat(), pitch.toFloat(), 0.0f),
|
||||
name = name,
|
||||
@ -91,6 +92,6 @@ class PlayerEntitySpawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
}
|
||||
|
||||
override fun log() {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Player entity spawn (position=${entity.position}, entityId=$entityId, name=${entity.name}, uuid=$entityUUID)" }
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "LocalPlayerEntity entity spawn (position=${entity.position}, entityId=$entityId, name=${entity.name}, uuid=$entityUUID)" }
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class PositionAndRotationS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
}
|
||||
|
||||
override fun handle(connection: PlayConnection) {
|
||||
val entity = connection.player.entity
|
||||
val entity = connection.player
|
||||
// correct position with flags (relative position possible)
|
||||
if (BitByte.isBitMask(flags, 0x01)) {
|
||||
position.x += entity.position.x
|
||||
@ -82,6 +82,6 @@ class PositionAndRotationS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
}
|
||||
|
||||
override fun log() {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "Player position (position=$position, rotation=$rotation, onGround=$isOnGround)" }
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.VERBOSE) { "LocalPlayerEntity position (position=$position, rotation=$rotation, onGround=$isOnGround)" }
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +89,8 @@ class RespawnS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
connection.world.chunks.clear()
|
||||
connection.world.dimension = dimension
|
||||
connection.player.isSpawnConfirmed = false
|
||||
connection.player.entity.tabListItem.gamemode = gamemode
|
||||
connection.player.entity.velocity = Vec3()
|
||||
connection.player.tabListItem.gamemode = gamemode
|
||||
connection.player.velocity = Vec3()
|
||||
|
||||
connection.fireEvent(RespawnEvent(connection, this))
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ class TabListDataS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
} ?: continue
|
||||
|
||||
|
||||
if (entity === connection.player.entity) {
|
||||
if (entity === connection.player) {
|
||||
entity.tabListItem.specialMerge(data)
|
||||
continue
|
||||
}
|
||||
|
@ -97,10 +97,15 @@ object MMath {
|
||||
|
||||
val Float.ceilInt: Int get() = glm.ceil(this).toInt()
|
||||
|
||||
val Boolean.positiveNegative: Int get() =
|
||||
if (this) {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
val Boolean.positiveNegative: Int
|
||||
get() =
|
||||
if (this) {
|
||||
1
|
||||
} else {
|
||||
-1
|
||||
}
|
||||
|
||||
fun lerp(delta: Float, start: Float, end: Float): Float {
|
||||
return start + delta * (end - start)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user