aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/Animal.cpp
diff options
context:
space:
mode:
authordaoge <3523206925@qq.com>2026-03-03 03:04:10 +0800
committerGitHub <noreply@github.com>2026-03-03 03:04:10 +0800
commitb3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch)
tree267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.World/Animal.cpp
parent84c31a2331f7a0ec85b9d438992e244f60e5020f (diff)
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 <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.World/Animal.cpp')
-rw-r--r--Minecraft.World/Animal.cpp85
1 files changed, 58 insertions, 27 deletions
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<Entity> target, float d)
{
- if (dynamic_pointer_cast<Player>(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<Entity> target, float d)
}
shared_ptr<Player> p = dynamic_pointer_cast<Player>(target);
- if (p->getSelectedItem() != NULL && this->isFood(p->getSelectedItem()))
- {
- }
- else
+ if (p->getSelectedItem() == NULL || !isFood(p->getSelectedItem()))
{
attackTarget = nullptr;
}
}
- else if (dynamic_pointer_cast<Animal>(target) != NULL)
+ // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF
+ else if ( target->instanceof(eTYPE_ANIMAL) )
{
shared_ptr<Animal> a = dynamic_pointer_cast<Animal>(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<EntityDamageSource *>(dmgSource) != NULL)
{
shared_ptr<Entity> source = dmgSource->getDirectEntity();
- if (dynamic_pointer_cast<Player>(source) != NULL && !dynamic_pointer_cast<Player>(source)->isAllowedToAttackAnimals() )
+ // 4J-JEV: Changed from dynamic cast to use eINSTANCEOF
+ if ( source->instanceof(eTYPE_PLAYER) && !dynamic_pointer_cast<Player>(source)->isAllowedToAttackAnimals() )
{
return false;
}
- if (source != NULL && source->GetType() == eTYPE_ARROW)
+ if ( (source != NULL) && source->instanceof(eTYPE_ARROW) )
{
shared_ptr<Arrow> arrow = dynamic_pointer_cast<Arrow>(source);
- if (dynamic_pointer_cast<Player>(arrow->owner) != NULL && ! dynamic_pointer_cast<Player>(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<Player>(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> itemInstance)
return itemInstance->id == Item::wheat_Id;
}
-bool Animal::interact(shared_ptr<Player> player)
+bool Animal::mobInteract(shared_ptr<Player> player)
{
shared_ptr<ItemInstance> 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> 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> 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<Player> 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<Animal> 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