diff --git a/Minecraft.World/Entity.cpp b/Minecraft.World/Entity.cpp index 7d3d5820..f47bf644 100644 --- a/Minecraft.World/Entity.cpp +++ b/Minecraft.World/Entity.cpp @@ -898,17 +898,15 @@ void Entity::move(double xa, double ya, double za, bool noEntityCubes) // 4J - checkFallDamage(ya, onGround); if (xaOrg != xa) xd = 0; - if (yaOrg != ya) { - // Fireblade - updated logic here cause previous check completely broke head hitter logic - bool isSlimeBlock = false; - if (level != nullptr) { - int blockBelowX = Mth::floor(x); - int blockBelowY = Mth::floor(y - 0.1f - heightOffset); - int blockBelowZ = Mth::floor(z); - int blockId = level->getTile(blockBelowX, blockBelowY, blockBelowZ); - isSlimeBlock = (blockId == Tile::slimeBlock->id); - } - if (!isSlimeBlock) { + if (yaOrg != ya) + { + int xt = Mth::floor(x); + int yt = Mth::floor(y - 0.2f - heightOffset); + int zt = Mth::floor(z); + Tile *tile = Tile::tiles[level->getTile(xt, yt, zt)]; + if (tile != nullptr) { + tile->updateEntityAfterFallOn(level, self); + } else { yd = 0; } } @@ -1117,6 +1115,10 @@ void Entity::causeFallDamage(float distance) if (rider.lock() != nullptr) rider.lock()->causeFallDamage(distance); } +void Entity::causeFallDamage(float distance, float multiplier) +{ + if (rider.lock() != nullptr) rider.lock()->causeFallDamage(distance, multiplier); +} bool Entity::isInWaterOrRain() { diff --git a/Minecraft.World/Entity.h b/Minecraft.World/Entity.h index e0fb1a44..3457f217 100644 --- a/Minecraft.World/Entity.h +++ b/Minecraft.World/Entity.h @@ -256,6 +256,7 @@ protected: public: bool isFireImmune(); void clearFallDamageQueue(); + virtual void causeFallDamage(float distance, float multiplier); // from decomp protected: virtual void causeFallDamage(float distance); diff --git a/Minecraft.World/LivingEntity.cpp b/Minecraft.World/LivingEntity.cpp index acaf00a4..d5f2dda9 100644 --- a/Minecraft.World/LivingEntity.cpp +++ b/Minecraft.World/LivingEntity.cpp @@ -168,6 +168,7 @@ void LivingEntity::checkFallDamage(double ya, bool onGround) if (onGround) { + // TODO: LANDING PARTICLES HERE int xt = Mth::floor(x); int yt = Mth::floor(y - 0.2f - heightOffset); int zt = Mth::floor(z); @@ -188,6 +189,10 @@ void LivingEntity::checkFallDamage(double ya, bool onGround) { auto ent = shared_from_this(); Tile::tiles[t]->fallOn(level, xt, yt, zt, ent, fallDistance); + if (t == Tile::slimeBlock->id && !isSneaking()) + { + m_clearFallDamageThisTick = true; + } } } } diff --git a/Minecraft.World/SlimeTile.cpp b/Minecraft.World/SlimeTile.cpp index b7a9b0d6..cba8338b 100644 --- a/Minecraft.World/SlimeTile.cpp +++ b/Minecraft.World/SlimeTile.cpp @@ -40,54 +40,59 @@ int SlimeTile::getPistonPushReaction() void SlimeTile::fallOn(Level *level, int x, int y, int z, shared_ptr entity, float distance) { - HalfTransparentTile::fallOn(level, x, y, z, entity, distance); + assert(entity != nullptr); - if (entity == nullptr) - return; + bool sneaking = entity->isSneaking(); - entity->clearFallDamageQueue(); - - entity->fallDistance = 0.0f; - - if (entity->isSneaking() || std::abs(entity->yd) < 0.1f) + if (!sneaking) { - entity->yd = 0.0f; - return; + entity->causeFallDamage(distance, 0.0f); // no damage } - - if (entity->yd < 0.0f) + else { - entity->yd = -entity->yd; - - if (!(entity->instanceof(eTYPE_LIVINGENTITY))) - { - entity->yd *= 0.8f; - } + Tile::fallOn(level, x, y, z, entity, distance); // normal fall damage } } void SlimeTile::stepOn(Level *level, int x, int y, int z, shared_ptr entity) { - if (entity != nullptr) - { - entity->clearFallDamageQueue(); + assert(entity != nullptr); + + if ((std::abs)(entity->yd) < 0.1) { + bool sneaking = entity->isSneaking(); + + if (!sneaking) { + double factor = (std::abs)(entity->yd) * 0.2 + 0.4; + + entity->xd *= factor; + entity->zd *= factor; + } } - if (entity != nullptr && - std::abs(entity->yd) < 0.1f && - !entity->isSneaking()) - { - double d0 = 0.4 + std::abs(entity->yd) * 0.2; - - entity->xd *= d0; - entity->zd *= d0; - level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_MOB_SLIME_SMALL, 0.4f, 0.8f + level->random->nextFloat() * 0.4f); - } - - HalfTransparentTile::stepOn(level, x, y, z, entity); + Tile::stepOn(level, x, y, z, entity); } void SlimeTile::updateEntityAfterFallOn(Level* level, shared_ptr entity) { - // stub + assert(entity != nullptr); + + bool sneaking = entity->isSneaking(); + + if (!sneaking) { + if (!(entity->yd > -0.08 && entity->yd < 0.0)) + { + if (entity->yd < 0.0) + { + entity->yd = -entity->yd; // bounce + } + } + else + { + Tile::updateEntityAfterFallOn(level, entity); // LAB_02a7a4e4 goto + } + } + else + { + Tile::updateEntityAfterFallOn(level, entity); // LAB_02a7a4e4 definition + } } diff --git a/Minecraft.World/SoundTypes.h b/Minecraft.World/SoundTypes.h index b28b0ebd..75d98f73 100644 --- a/Minecraft.World/SoundTypes.h +++ b/Minecraft.World/SoundTypes.h @@ -348,6 +348,7 @@ enum eMATERIALSOUND_TYPE eMaterialSoundType_WOOD, eMaterialSoundType_GRAVEL, eMaterialSoundType_GRASS, + eMaterialSoundType_SLIME, eMaterialSoundType_METAL, eMaterialSoundType_GLASS, eMaterialSoundType_CLOTH, diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index eed25a61..1206e8e7 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -370,7 +370,7 @@ void Tile::staticCtor() Tile::SOUND_GRAVEL = new Tile::SoundType(eMaterialSoundType_GRAVEL, 1, 1); Tile::SOUND_GRASS = new Tile::SoundType(eMaterialSoundType_GRASS, 1, 1); Tile::SOUND_STONE = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1); - Tile::SOUND_SLIME = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1, eSoundType_MOB_SLIME_BIG, eSoundType_MOB_SLIME_BIG); + Tile::SOUND_SLIME = new Tile::SoundType(eMaterialSoundType_SLIME, 1, 1, eSoundType_MOB_SLIME_BIG, eSoundType_MOB_SLIME_BIG); Tile::SOUND_METAL = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1.5f); Tile::SOUND_GLASS = new Tile::SoundType(eMaterialSoundType_STONE, 1, 1, eSoundType_RANDOM_GLASS,eSoundType_STEP_STONE); Tile::SOUND_CLOTH = new Tile::SoundType(eMaterialSoundType_CLOTH, 1, 1); @@ -1642,7 +1642,7 @@ void Tile::registerIcons(IconRegister *iconRegister) void Tile::updateEntityAfterFallOn(Level *level, shared_ptr entity) { if (!entity) return; - entity->fallDistance = 0.0f; + entity->yd = 0; } wstring Tile::getTileItemIconName() @@ -1673,6 +1673,9 @@ Tile::SoundType::SoundType(eMATERIALSOUND_TYPE eMaterialSound, float volume, flo case eMaterialSoundType_GRASS: this->iBreakSound=eSoundType_DIG_GRASS; break; + case eMaterialSoundType_SLIME: + this->iStepSound=eSoundType_MOB_SLIME_SMALL; + break; case eMaterialSoundType_METAL: this->iBreakSound=eSoundType_DIG_STONE; break; @@ -1722,6 +1725,9 @@ Tile::SoundType::SoundType(eMATERIALSOUND_TYPE eMaterialSound, float volume, flo case eMaterialSoundType_GRASS: this->iStepSound=eSoundType_STEP_GRASS; break; + case eMaterialSoundType_SLIME: + this->iStepSound=eSoundType_MOB_SLIME_SMALL; + break; case eMaterialSoundType_METAL: this->iStepSound=eSoundType_STEP_METAL; break;