diff options
| author | daoge <3523206925@qq.com> | 2026-03-03 03:04:10 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-03 03:04:10 +0800 |
| commit | b3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch) | |
| tree | 267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.World/Animal.cpp | |
| parent | 84c31a2331f7a0ec85b9d438992e244f60e5020f (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.cpp | 85 |
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 |
