From b3feddfef372618c8a9d7a0abcaf18cfad866c18 Mon Sep 17 00:00:00 2001 From: daoge <3523206925@qq.com> Date: Tue, 3 Mar 2026 03:04:10 +0800 Subject: feat: TU19 (Dec 2014) Features & Content (#155) * try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki --- Minecraft.World/Animal.cpp | 85 +++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 27 deletions(-) (limited to 'Minecraft.World/Animal.cpp') diff --git a/Minecraft.World/Animal.cpp b/Minecraft.World/Animal.cpp index 45fc304f..31de7d75 100644 --- a/Minecraft.World/Animal.cpp +++ b/Minecraft.World/Animal.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" + #include "com.mojang.nbt.h" #include "net.minecraft.world.level.tile.h" #include "net.minecraft.world.item.h" @@ -9,11 +10,11 @@ #include "net.minecraft.world.entity.h" #include "net.minecraft.world.entity.projectile.h" #include "net.minecraft.world.damagesource.h" +#include "net.minecraft.world.entity.monster.h" +#include "net.minecraft.world.entity.ai.attributes.h" #include "Random.h" #include "Animal.h" - - Animal::Animal(Level *level) : AgableMob( level ) { // inLove = 0; // 4J removed - now synched data @@ -64,7 +65,8 @@ void Animal::aiStep() void Animal::checkHurtTarget(shared_ptr target, float d) { - if (dynamic_pointer_cast(target) != NULL) + // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF + if ( target->instanceof(eTYPE_PLAYER) ) { if (d < 3) { @@ -76,16 +78,14 @@ void Animal::checkHurtTarget(shared_ptr target, float d) } shared_ptr p = dynamic_pointer_cast(target); - if (p->getSelectedItem() != NULL && this->isFood(p->getSelectedItem())) - { - } - else + if (p->getSelectedItem() == NULL || !isFood(p->getSelectedItem())) { attackTarget = nullptr; } } - else if (dynamic_pointer_cast(target) != NULL) + // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF + else if ( target->instanceof(eTYPE_ANIMAL) ) { shared_ptr a = dynamic_pointer_cast(target); if (getAge() > 0 && a->getAge() < 0) @@ -166,21 +166,25 @@ float Animal::getWalkTargetValue(int x, int y, int z) return level->getBrightness(x, y, z) - 0.5f; } -bool Animal::hurt(DamageSource *dmgSource, int dmg) +bool Animal::hurt(DamageSource *dmgSource, float dmg) { + if (isInvulnerable()) return false; if (dynamic_cast(dmgSource) != NULL) { shared_ptr source = dmgSource->getDirectEntity(); - if (dynamic_pointer_cast(source) != NULL && !dynamic_pointer_cast(source)->isAllowedToAttackAnimals() ) + // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF + if ( source->instanceof(eTYPE_PLAYER) && !dynamic_pointer_cast(source)->isAllowedToAttackAnimals() ) { return false; } - if (source != NULL && source->GetType() == eTYPE_ARROW) + if ( (source != NULL) && source->instanceof(eTYPE_ARROW) ) { shared_ptr arrow = dynamic_pointer_cast(source); - if (dynamic_pointer_cast(arrow->owner) != NULL && ! dynamic_pointer_cast(arrow->owner)->isAllowedToAttackAnimals() ) + + // 4J: Check that the arrow's owner can attack animals (dispenser arrows are not owned) + if (arrow->owner != NULL && arrow->owner->instanceof(eTYPE_PLAYER) && !dynamic_pointer_cast(arrow->owner)->isAllowedToAttackAnimals() ) { return false; } @@ -188,6 +192,16 @@ bool Animal::hurt(DamageSource *dmgSource, int dmg) } fleeTime = 20 * 3; + + if (!useNewAi()) + { + AttributeInstance *speed = getAttribute(SharedMonsterAttributes::MOVEMENT_SPEED); + if (speed->getModifier(eModifierId_MOB_FLEEING) == NULL) + { + speed->addModifier(new AttributeModifier(*Animal::SPEED_MODIFIER_FLEEING)); + } + } + attackTarget = nullptr; setInLoveValue(0); @@ -293,10 +307,10 @@ bool Animal::isFood(shared_ptr itemInstance) return itemInstance->id == Item::wheat_Id; } -bool Animal::interact(shared_ptr player) +bool Animal::mobInteract(shared_ptr player) { shared_ptr item = player->inventory->getSelected(); - if (item != NULL && isFood(item) && getAge() == 0) + if (item != NULL && isFood(item) && getAge() == 0 && getInLoveValue() <= 0) { if (!player->abilities.instabuild) { @@ -344,7 +358,7 @@ bool Animal::interact(shared_ptr player) return false; } } - else if( (GetType() & eTYPE_MONSTER) == eTYPE_MONSTER) + else if( instanceof(eTYPE_MONSTER) ) { } @@ -352,20 +366,11 @@ bool Animal::interact(shared_ptr player) } setInLove(player); } - - - attackTarget = nullptr; - for (int i = 0; i < 7; i++) - { - double xa = random->nextGaussian() * 0.02; - double ya = random->nextGaussian() * 0.02; - double za = random->nextGaussian() * 0.02; - level->addParticle(eParticleType_heart, x + random->nextFloat() * bbWidth * 2 - bbWidth, y + .5f + random->nextFloat() * bbHeight, z + random->nextFloat() * bbWidth * 2 - bbWidth, xa, ya, za); - } + setInLove(); return true; } - return AgableMob::interact(player); + return AgableMob::mobInteract(player); } // 4J added @@ -391,6 +396,14 @@ shared_ptr Animal::getLoveCause() return loveCause.lock(); } +void Animal::setInLove() +{ + entityData->set(DATA_IN_LOVE, 20 * 30); + + attackTarget = nullptr; + level->broadcastEntityEvent(shared_from_this(), EntityEvent::IN_LOVE_HEARTS); +} + bool Animal::isInLove() { return entityData->getInteger(DATA_IN_LOVE) > 0; @@ -407,6 +420,24 @@ bool Animal::canMate(shared_ptr partner) return isInLove() && partner->isInLove(); } +void Animal::handleEntityEvent(byte id) +{ + if (id == EntityEvent::IN_LOVE_HEARTS) + { + for (int i = 0; i < 7; i++) + { + double xa = random->nextGaussian() * 0.02; + double ya = random->nextGaussian() * 0.02; + double za = random->nextGaussian() * 0.02; + level->addParticle(eParticleType_heart, x + random->nextFloat() * bbWidth * 2 - bbWidth, y + .5f + random->nextFloat() * bbHeight, z + random->nextFloat() * bbWidth * 2 - bbWidth, xa, ya, za); + } + } + else + { + AgableMob::handleEntityEvent(id); + } +} + void Animal::updateDespawnProtectedState() { if( level->isClientSide ) return; @@ -455,4 +486,4 @@ void Animal::setDespawnProtected() m_maxWanderZ = zt; m_isDespawnProtected = true; -} +} \ No newline at end of file -- cgit v1.2.3