aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/Arrow.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/Arrow.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/Arrow.cpp')
-rw-r--r--Minecraft.World/Arrow.cpp110
1 files changed, 72 insertions, 38 deletions
diff --git a/Minecraft.World/Arrow.cpp b/Minecraft.World/Arrow.cpp
index 1b102c65..743f966b 100644
--- a/Minecraft.World/Arrow.cpp
+++ b/Minecraft.World/Arrow.cpp
@@ -7,6 +7,9 @@
#include "net.minecraft.world.item.h"
#include "net.minecraft.world.damagesource.h"
#include "net.minecraft.world.item.enchantment.h"
+#include "net.minecraft.network.packet.h"
+#include "..\Minecraft.Client\ServerPlayer.h"
+#include "..\Minecraft.Client\PlayerConnection.h"
#include "com.mojang.nbt.h"
#include "Arrow.h"
@@ -48,16 +51,18 @@ void Arrow::_init()
Arrow::Arrow(Level *level) : Entity( level )
{
_init();
-
- this->setSize(0.5f, 0.5f);
+
+ viewScale = 10;
+ setSize(0.5f, 0.5f);
}
-Arrow::Arrow(Level *level, shared_ptr<Mob> mob, shared_ptr<Mob> target, float power, float uncertainty) : Entity( level )
+Arrow::Arrow(Level *level, shared_ptr<LivingEntity> mob, shared_ptr<LivingEntity> target, float power, float uncertainty) : Entity( level )
{
_init();
-
- this->owner = mob;
- if ( dynamic_pointer_cast<Player>( mob ) != NULL) pickup = PICKUP_ALLOWED;
+
+ viewScale = 10;
+ owner = mob;
+ if ( mob->instanceof(eTYPE_PLAYER) ) pickup = PICKUP_ALLOWED;
y = mob->y + mob->getHeadHeight() - 0.1f;
@@ -82,29 +87,31 @@ Arrow::Arrow(Level *level, shared_ptr<Mob> mob, shared_ptr<Mob> target, float po
Arrow::Arrow(Level *level, double x, double y, double z) : Entity( level )
{
_init();
+
+ viewScale = 10;
+ setSize(0.5f, 0.5f);
- this->setSize(0.5f, 0.5f);
-
- this->setPos(x, y, z);
- this->heightOffset = 0;
+ setPos(x, y, z);
+ heightOffset = 0;
}
-Arrow::Arrow(Level *level, shared_ptr<Mob> mob, float power) : Entity( level )
+Arrow::Arrow(Level *level, shared_ptr<LivingEntity> mob, float power) : Entity( level )
{
_init();
- this->owner = mob;
- if ( dynamic_pointer_cast<Player>( mob ) != NULL) pickup = PICKUP_ALLOWED;
+ viewScale = 10;
+ owner = mob;
+ if ( mob->instanceof(eTYPE_PLAYER) ) pickup = PICKUP_ALLOWED;
setSize(0.5f, 0.5f);
- this->moveTo(mob->x, mob->y + mob->getHeadHeight(), mob->z, mob->yRot, mob->xRot);
+ moveTo(mob->x, mob->y + mob->getHeadHeight(), mob->z, mob->yRot, mob->xRot);
x -= Mth::cos(yRot / 180 * PI) * 0.16f;
y -= 0.1f;
z -= Mth::sin(yRot / 180 * PI) * 0.16f;
- this->setPos(x, y, z);
- this->heightOffset = 0;
+ setPos(x, y, z);
+ heightOffset = 0;
xd = -Mth::sin(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI);
zd = Mth::cos(yRot / 180 * PI) * Mth::cos(xRot / 180 * PI);
@@ -128,9 +135,9 @@ void Arrow::shoot(double xd, double yd, double zd, float pow, float uncertainty)
yd /= dist;
zd /= dist;
- xd += (random->nextGaussian()) * 0.0075f * uncertainty;
- yd += (random->nextGaussian()) * 0.0075f * uncertainty;
- zd += (random->nextGaussian()) * 0.0075f * uncertainty;
+ xd += (random->nextGaussian() * (random->nextBoolean() ? -1 : 1)) * 0.0075f * uncertainty;
+ yd += (random->nextGaussian() * (random->nextBoolean() ? -1 : 1)) * 0.0075f * uncertainty;
+ zd += (random->nextGaussian() * (random->nextBoolean() ? -1 : 1)) * 0.0075f * uncertainty;
xd *= pow;
yd *= pow;
@@ -142,8 +149,8 @@ void Arrow::shoot(double xd, double yd, double zd, float pow, float uncertainty)
double sd = sqrt(xd * xd + zd * zd);
- yRotO = this->yRot = (float) (atan2(xd, zd) * 180 / PI);
- xRotO = this->xRot = (float) (atan2(yd, sd) * 180 / PI);
+ yRotO = yRot = (float) (atan2(xd, zd) * 180 / PI);
+ xRotO = xRot = (float) (atan2(yd, sd) * 180 / PI);
life = 0;
}
@@ -161,8 +168,8 @@ void Arrow::lerpMotion(double xd, double yd, double zd)
if (xRotO == 0 && yRotO == 0)
{
double sd = sqrt(xd * xd + zd * zd);
- yRotO = this->yRot = (float) (atan2( xd, zd) * 180 / PI);
- xRotO = this->xRot = (float) (atan2( yd, sd) * 180 / PI);
+ yRotO = yRot = (float) (atan2( xd, zd) * 180 / PI);
+ xRotO = xRot = (float) (atan2( yd, sd) * 180 / PI);
xRotO = xRot;
yRotO = yRot;
app.DebugPrintf("%f %f : 0x%x\n",xRot,yRot,&yRot);
@@ -179,8 +186,8 @@ void Arrow::tick()
if (xRotO == 0 && yRotO == 0)
{
double sd = sqrt(xd * xd + zd * zd);
- yRotO = this->yRot = (float) (atan2(xd, zd) * 180 / PI);
- xRotO = this->xRot = (float) (atan2(yd, sd) * 180 / PI);
+ yRotO = yRot = (float) (atan2(xd, zd) * 180 / PI);
+ xRotO = xRot = (float) (atan2(yd, sd) * 180 / PI);
}
@@ -269,6 +276,16 @@ void Arrow::tick()
res = new HitResult(hitEntity);
}
+ if ( (res != NULL) && (res->entity != NULL) && res->entity->instanceof(eTYPE_PLAYER))
+ {
+ shared_ptr<Player> player = dynamic_pointer_cast<Player>(res->entity);
+ // 4J: Check for owner being null
+ if ( player->abilities.invulnerable || ((owner != NULL) && (owner->instanceof(eTYPE_PLAYER) && !dynamic_pointer_cast<Player>(owner)->canHarmPlayer(player))))
+ {
+ res = NULL;
+ }
+ }
+
if (res != NULL)
{
if (res->entity != NULL)
@@ -294,15 +311,19 @@ void Arrow::tick()
// 4J Stu - We should not set the entity on fire unless we can cause some damage (this doesn't necessarily mean that the arrow hit lowered their health)
// set targets on fire first because we want cooked
// pork/chicken/steak
- if (this->isOnFire())
+ if (isOnFire() && res->entity->GetType() != eTYPE_ENDERMAN)
{
res->entity->setOnFire(5);
}
- shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(res->entity);
- if (mob != NULL)
+ if (res->entity->instanceof(eTYPE_LIVINGENTITY))
{
- mob->arrowCount++;
+ shared_ptr<LivingEntity> mob = dynamic_pointer_cast<LivingEntity>(res->entity);
+
+ if (!level->isClientSide)
+ {
+ mob->setArrowCount(mob->getArrowCount() + 1);
+ }
if (knockback > 0)
{
float pushLen = sqrt(xd * xd + zd * zd);
@@ -316,12 +337,17 @@ void Arrow::tick()
{
ThornsEnchantment::doThornsAfterAttack(owner, mob, random);
}
+
+ if (owner != NULL && res->entity != owner && owner->GetType() == eTYPE_SERVERPLAYER)
+ {
+ dynamic_pointer_cast<ServerPlayer>(owner)->connection->send( shared_ptr<GameEventPacket>( new GameEventPacket(GameEventPacket::SUCCESSFUL_BOW_HIT, 0)) );
+ }
}
// 4J : WESTY : For award, need to track if creeper was killed by arrow from the player.
- if ( (dynamic_pointer_cast<Player>(owner) != NULL ) && // arrow owner is a player
- ( res->entity->isAlive() == false ) && // target is now dead
- ( dynamic_pointer_cast<Creeper>( res->entity ) != NULL ) ) // target is a creeper
+ if (owner != NULL && owner->instanceof(eTYPE_PLAYER) // arrow owner is a player
+ && !res->entity->isAlive() // target is now dead
+ && (res->entity->GetType() == eTYPE_CREEPER)) // target is a creeper
{
dynamic_pointer_cast<Player>(owner)->awardStat(
@@ -330,9 +356,8 @@ void Arrow::tick()
);
}
- // 4J - sound change brought forward from 1.2.3
- level->playSound(shared_from_this(), eSoundType_RANDOM_BOW_HIT, 1.0f, 1.2f / (random->nextFloat() * 0.2f + 0.9f));
- remove();
+ playSound( eSoundType_RANDOM_BOW_HIT, 1.0f, 1.2f / (random->nextFloat() * 0.2f + 0.9f));
+ if (res->entity->GetType() != eTYPE_ENDERDRAGON) remove();
}
else
{
@@ -365,11 +390,15 @@ void Arrow::tick()
z -= (zd / dd) * 0.05f;
}
- // 4J - sound change brought forward from 1.2.3
- level->playSound(shared_from_this(), eSoundType_RANDOM_BOW_HIT, 1.0f, 1.2f / (random->nextFloat() * 0.2f + 0.9f));
+ playSound(eSoundType_RANDOM_BOW_HIT, 1.0f, 1.2f / (random->nextFloat() * 0.2f + 0.9f));
inGround = true;
shakeTime = 7;
setCritArrow(false);
+
+ if (lastTile != 0)
+ {
+ Tile::tiles[lastTile]->entityInside(level, xTile, yTile, zTile, shared_from_this() );
+ }
}
}
delete res;
@@ -480,12 +509,17 @@ void Arrow::playerTouch(shared_ptr<Player> player)
if (bRemove)
{
- level->playSound(shared_from_this(), eSoundType_RANDOM_POP, 0.2f, ((random->nextFloat() - random->nextFloat()) * 0.7f + 1.0f) * 2.0f);
+ playSound(eSoundType_RANDOM_POP, 0.2f, ((random->nextFloat() - random->nextFloat()) * 0.7f + 1.0f) * 2.0f);
player->take(shared_from_this(), 1);
remove();
}
}
+bool Arrow::makeStepSound()
+{
+ return false;
+}
+
float Arrow::getShadowHeightOffs()
{
return 0;