diff options
Diffstat (limited to 'src/Entities')
-rw-r--r-- | src/Entities/Entity.cpp | 56 | ||||
-rw-r--r-- | src/Entities/Entity.h | 6 | ||||
-rw-r--r-- | src/Entities/EntityEffect.cpp | 91 | ||||
-rw-r--r-- | src/Entities/EntityEffect.h | 8 | ||||
-rw-r--r-- | src/Entities/ExpBottleEntity.cpp | 19 | ||||
-rw-r--r-- | src/Entities/ExpBottleEntity.h | 5 | ||||
-rw-r--r-- | src/Entities/ItemFrame.cpp | 2 | ||||
-rw-r--r-- | src/Entities/Minecart.cpp | 85 | ||||
-rw-r--r-- | src/Entities/Player.cpp | 54 | ||||
-rw-r--r-- | src/Entities/Player.h | 7 |
10 files changed, 244 insertions, 89 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 89d1cffa1..8ef24828e 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -135,7 +135,7 @@ const char * cEntity::GetParentClass(void) const bool cEntity::Initialize(cWorld & a_World) { - if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this)) + if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this) && !IsPlayer()) { return false; } @@ -260,7 +260,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R void cEntity::SetYawFromSpeed(void) { const double EPS = 0.0000001; - if ((abs(m_Speed.x) < EPS) && (abs(m_Speed.z) < EPS)) + if ((std::abs(m_Speed.x) < EPS) && (std::abs(m_Speed.z) < EPS)) { // atan2() may overflow or is undefined, pick any number SetYaw(0); @@ -277,7 +277,7 @@ void cEntity::SetPitchFromSpeed(void) { const double EPS = 0.0000001; double xz = sqrt(m_Speed.x * m_Speed.x + m_Speed.z * m_Speed.z); // Speed XZ-plane component - if ((abs(xz) < EPS) && (abs(m_Speed.y) < EPS)) + if ((std::abs(xz) < EPS) && (std::abs(m_Speed.y) < EPS)) { // atan2() may overflow or is undefined, pick any number SetPitch(0); @@ -342,6 +342,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) a_TDI.FinalDamage += (int)ceil(2.5 * SmiteLevel); break; } + default: break; } } } @@ -387,7 +388,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) case cMonster::mtGhast: case cMonster::mtZombiePigman: case cMonster::mtMagmaCube: - { + { break; }; default: StartBurning(BurnTicks * 20); @@ -417,7 +418,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI) } if (!Player->IsOnGround()) - { + { if ((a_TDI.DamageType == dtAttack) || (a_TDI.DamageType == dtArrowAttack)) { a_TDI.FinalDamage += 2; @@ -927,12 +928,13 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) float fallspeed; if (IsBlockWater(BlockIn)) { - fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water. + fallspeed = m_Gravity * a_Dt / 3; // Fall 3x slower in water + ApplyFriction(NextSpeed, 0.7, a_Dt); } else if (BlockIn == E_BLOCK_COBWEB) { NextSpeed.y *= 0.05; // Reduce overall falling speed - fallspeed = 0; // No falling. + fallspeed = 0; // No falling } else { @@ -941,20 +943,9 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) } NextSpeed.y += fallspeed; } - - // Friction - if (NextSpeed.SqrLength() > 0.0004f) + else { - NextSpeed.x *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.x) < 0.05) - { - NextSpeed.x = 0; - } - NextSpeed.z *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.z) < 0.05) - { - NextSpeed.z = 0; - } + ApplyFriction(NextSpeed, 0.7, a_Dt); } // Adjust X and Z speed for COBWEB temporary. This speed modification should be handled inside block handlers since we @@ -1025,7 +1016,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) if (Tracer.HitNormal.y != 0.f) NextSpeed.y = 0.f; if (Tracer.HitNormal.z != 0.f) NextSpeed.z = 0.f; - if (Tracer.HitNormal.y == 1) // Hit BLOCK_FACE_YP, we are on the ground + if (Tracer.HitNormal.y == 1.f) // Hit BLOCK_FACE_YP, we are on the ground { m_bOnGround = true; } @@ -1060,6 +1051,27 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) +void cEntity::ApplyFriction(Vector3d & a_Speed, double a_SlowdownMultiplier, float a_Dt) +{ + if (a_Speed.SqrLength() > 0.0004f) + { + a_Speed.x *= a_SlowdownMultiplier / (1 + a_Dt); + if (fabs(a_Speed.x) < 0.05) + { + a_Speed.x = 0; + } + a_Speed.z *= a_SlowdownMultiplier / (1 + a_Dt); + if (fabs(a_Speed.z) < 0.05) + { + a_Speed.z = 0; + } + } +} + + + + + void cEntity::TickBurning(cChunk & a_Chunk) { // Remember the current burning state: @@ -1949,7 +1961,7 @@ void cEntity::SteerVehicle(float a_Forward, float a_Sideways) { return; } - if ((a_Forward != 0) || (a_Sideways != 0)) + if ((a_Forward != 0.f) || (a_Sideways != 0.f)) { m_AttachedTo->HandleSpeedFromAttachee(a_Forward, a_Sideways); } diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 774cdb062..3fa7e80c1 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -535,6 +535,12 @@ protected: virtual void Destroyed(void) {} // Called after the entity has been destroyed + /** Applies friction to an entity + @param a_Speed The speed vector to apply changes to + @param a_SlowdownMultiplier The factor to reduce the speed by + */ + static void ApplyFriction(Vector3d & a_Speed, double a_SlowdownMultiplier, float a_Dt); + /** Called in each tick to handle air-related processing i.e. drowning */ virtual void HandleAir(void); diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 3e28392f4..98c5d23b4 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -34,14 +34,14 @@ cEntityEffect::eType cEntityEffect::GetPotionEffectType(short a_ItemDamage) case 0x08: return cEntityEffect::effWeakness; case 0x09: return cEntityEffect::effStrength; case 0x0a: return cEntityEffect::effSlowness; + case 0x0b: return cEntityEffect::effJumpBoost; case 0x0c: return cEntityEffect::effInstantDamage; case 0x0d: return cEntityEffect::effWaterBreathing; case 0x0e: return cEntityEffect::effInvisibility; - + // No effect potions case 0x00: case 0x07: - case 0x0b: // Will be potion of leaping in 1.8 case 0x0f: { break; @@ -96,6 +96,7 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) base = 1800; break; } + default: break; } // If potion is level II, half the duration. If not, stays the same @@ -233,6 +234,92 @@ void cEntityEffect::OnTick(cPawn & a_Target) //////////////////////////////////////////////////////////////////////////////// +// cEntityEffectSpeed: + +void cEntityEffectSpeed::OnActivate(cPawn & a_Target) +{ + if (a_Target.IsMob()) + { + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() + 0.2 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() + 0.2 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() + 0.26 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() + 0.2 * m_Intensity); + } +} + + + + + +void cEntityEffectSpeed::OnDeactivate(cPawn & a_Target) +{ + if (a_Target.IsMob()) + { + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() - 0.2 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() - 0.2 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() - 0.26 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() - 0.2 * m_Intensity); + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cEntityEffectSlowness: + +void cEntityEffectSlowness::OnActivate(cPawn & a_Target) +{ + if (a_Target.IsMob()) + { + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() - 0.15 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() - 0.15 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() - 0.195 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() - 0.15 * m_Intensity); + } +} + + + + + +void cEntityEffectSlowness::OnDeactivate(cPawn & a_Target) +{ + if (a_Target.IsMob()) + { + cMonster * Mob = (cMonster*) &a_Target; + Mob->SetRelativeWalkSpeed(Mob->GetRelativeWalkSpeed() + 0.15 * m_Intensity); + } + else if (a_Target.IsPlayer()) + { + cPlayer * Player = (cPlayer*) &a_Target; + Player->SetNormalMaxSpeed(Player->GetNormalMaxSpeed() + 0.15 * m_Intensity); + Player->SetSprintingMaxSpeed(Player->GetSprintingMaxSpeed() + 0.195 * m_Intensity); + Player->SetFlyingMaxSpeed(Player->GetFlyingMaxSpeed() + 0.15 * m_Intensity); + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// // cEntityEffectInstantHealth: void cEntityEffectInstantHealth::OnActivate(cPawn & a_Target) diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h index 47c298f57..7cf9cd3d5 100644 --- a/src/Entities/EntityEffect.h +++ b/src/Entities/EntityEffect.h @@ -137,6 +137,10 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } + + virtual void OnActivate(cPawn & a_Target) override; + + virtual void OnDeactivate(cPawn & a_Target) override; }; @@ -152,6 +156,10 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } + + virtual void OnActivate(cPawn & a_Target) override; + + virtual void OnDeactivate(cPawn & a_Target) override; }; diff --git a/src/Entities/ExpBottleEntity.cpp b/src/Entities/ExpBottleEntity.cpp index 202dde942..ee142a5a2 100644 --- a/src/Entities/ExpBottleEntity.cpp +++ b/src/Entities/ExpBottleEntity.cpp @@ -19,9 +19,26 @@ cExpBottleEntity::cExpBottleEntity(cEntity * a_Creator, double a_X, double a_Y, void cExpBottleEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) { + Break(a_HitPos); +} + + + + + +void cExpBottleEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) +{ + Break(a_HitPos); +} + + + + + +void cExpBottleEntity::Break(const Vector3d &a_HitPos) +{ // Spawn an experience orb with a reward between 3 and 11. m_World->BroadcastSoundParticleEffect(2002, POSX_TOINT, POSY_TOINT, POSZ_TOINT, 0); m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), 3 + m_World->GetTickRandomNumber(8)); - Destroy(); } diff --git a/src/Entities/ExpBottleEntity.h b/src/Entities/ExpBottleEntity.h index d62a84469..d36110f97 100644 --- a/src/Entities/ExpBottleEntity.h +++ b/src/Entities/ExpBottleEntity.h @@ -29,5 +29,10 @@ protected: // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; + virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override; + + /** Breaks the bottle, fires its particle effects and sounds + @param a_HitPos The position where the bottle will break */ + void Break(const Vector3d &a_HitPos); }; // tolua_export diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index 3ccb95998..f512324eb 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -28,7 +28,7 @@ void cItemFrame::OnRightClicked(cPlayer & a_Player) { // Item not empty, rotate, clipping values to zero to three inclusive m_Rotation++; - if (m_Rotation >= 4) + if (m_Rotation >= 8) { m_Rotation = 0; } diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 5fabbb542..2df64d5c1 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -13,6 +13,7 @@ #include "Player.h" #include "../BoundingBox.h" +#define NO_SPEED 0.0 #define MAX_SPEED 8 #define MAX_SPEED_NEGATIVE -MAX_SPEED @@ -220,7 +221,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedZ() != 0) // Don't do anything if cart is stationary + if (GetSpeedZ() != NO_SPEED) // Don't do anything if cart is stationary { if (GetSpeedZ() > 0) { @@ -239,13 +240,13 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { SetYaw(180); SetPosY(floor(GetPosY()) + 0.55); - SetSpeedY(0); - SetSpeedZ(0); + SetSpeedY(NO_SPEED); + SetSpeedZ(NO_SPEED); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedX() != 0) + if (GetSpeedX() != NO_SPEED) { if (GetSpeedX() > 0) { @@ -305,9 +306,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) case E_META_RAIL_ASCEND_XM: // ASCEND EAST { SetYaw(180); - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); - if (GetSpeedX() >= 0) + if (GetSpeedX() >= NO_SPEED) { if (GetSpeedX() <= MAX_SPEED) { @@ -424,9 +425,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedZ() != 0) + if (GetSpeedZ() != NO_SPEED) { - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { AddSpeedZ(AccelDecelSpeed); } @@ -441,15 +442,15 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { SetYaw(180); SetPosY(floor(GetPosY()) + 0.55); - SetSpeedY(0); - SetSpeedZ(0); + SetSpeedY(NO_SPEED); + SetSpeedZ(NO_SPEED); bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); if (EntCol || BlckCol) return; - if (GetSpeedX() != 0) + if (GetSpeedX() != NO_SPEED) { - if (GetSpeedX() > 0) + if (GetSpeedX() > NO_SPEED) { AddSpeedX(AccelDecelSpeed); } @@ -463,9 +464,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_XM: // ASCEND EAST { SetYaw(180); - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); - if (GetSpeedX() >= 0) + if (GetSpeedX() >= NO_SPEED) { if (GetSpeedX() <= MAX_SPEED) { @@ -483,9 +484,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_XP: // ASCEND WEST { SetYaw(180); - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); - if (GetSpeedX() > 0) + if (GetSpeedX() > NO_SPEED) { AddSpeedX(AccelDecelSpeed); SetSpeedY(GetSpeedX()); @@ -503,9 +504,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH { SetYaw(270); - SetSpeedX(0); + SetSpeedX(NO_SPEED); - if (GetSpeedZ() >= 0) + if (GetSpeedZ() >= NO_SPEED) { if (GetSpeedZ() <= MAX_SPEED) { @@ -523,9 +524,9 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH { SetYaw(270); - SetSpeedX(0); + SetSpeedX(NO_SPEED); - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { AddSpeedZ(AccelDecelSpeed); SetSpeedY(GetSpeedZ()); @@ -576,7 +577,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_XP: case E_META_RAIL_XM_XP: { - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); break; } @@ -584,7 +585,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) case E_META_RAIL_ASCEND_ZP: case E_META_RAIL_ZM_ZP: { - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); break; } @@ -593,12 +594,12 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) { if (GetPosZ() > floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { SetSpeedX(-GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() > floor(GetPosX()) + 0.5) @@ -608,82 +609,82 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedZ(-GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } - SetSpeedY(0); + SetSpeedY(NO_SPEED); break; } case E_META_RAIL_CURVED_ZM_XP: { if (GetPosZ() > floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() > 0) + if (GetSpeedZ() > NO_SPEED) { SetSpeedX(GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() < floor(GetPosX()) + 0.5) { - if (GetSpeedX() < 0) + if (GetSpeedX() < NO_SPEED) { SetSpeedZ(GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } - SetSpeedY(0); + SetSpeedY(NO_SPEED); break; } case E_META_RAIL_CURVED_ZP_XM: { if (GetPosZ() < floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() < 0) + if (GetSpeedZ() < NO_SPEED) { SetSpeedX(GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() > floor(GetPosX()) + 0.5) { - if (GetSpeedX() > 0) + if (GetSpeedX() > NO_SPEED) { SetSpeedZ(GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } - SetSpeedY(0); + SetSpeedY(NO_SPEED); break; } case E_META_RAIL_CURVED_ZP_XP: { if (GetPosZ() < floor(GetPosZ()) + 0.5) { - if (GetSpeedZ() < 0) + if (GetSpeedZ() < NO_SPEED) { SetSpeedX(-GetSpeedZ() * 0.7); } - SetSpeedZ(0); + SetSpeedZ(NO_SPEED); SetPosZ(floor(GetPosZ()) + 0.5); } else if (GetPosX() < floor(GetPosX()) + 0.5) { - if (GetSpeedX() < 0) + if (GetSpeedX() < NO_SPEED) { SetSpeedZ(-GetSpeedX() * 0.7); } - SetSpeedX(0); + SetSpeedX(NO_SPEED); SetPosX(floor(GetPosX()) + 0.5); } SetSpeedY(0); @@ -876,7 +877,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - if (abs(Distance.z) < 0.001) + if (std::abs(Distance.z) < 0.001) { Distance.z = 0.001; } @@ -925,7 +926,7 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); // Prevent division by small numbers - if (abs(Distance.z) < 0.001) + if (std::abs(Distance.z) < 0.001) { Distance.z = 0.001; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index a2934d036..1bdb752c5 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -267,7 +267,7 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) cTimer t1; if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime()) { - m_World->SendPlayerList(this); + m_World->BroadcastPlayerListUpdatePing(*this); m_LastPlayerListTime = t1.GetNowTime(); } @@ -452,6 +452,11 @@ void cPlayer::CancelChargingBow(void) void cPlayer::SetTouchGround(bool a_bTouchGround) { + if (IsGameModeSpectator()) // You can fly through the ground in Spectator + { + return; + } + m_bTouchGround = a_bTouchGround; if (!m_bTouchGround) @@ -586,7 +591,7 @@ bool cPlayer::Feed(int a_Food, double a_Saturation) void cPlayer::AddFoodExhaustion(double a_Exhaustion) { - if (!IsGameModeCreative()) + if (!(IsGameModeCreative() || IsGameModeSpectator())) { m_FoodExhaustionLevel = std::min(m_FoodExhaustionLevel + a_Exhaustion, 40.0); } @@ -628,15 +633,6 @@ void cPlayer::FinishEating(void) return; } ItemHandler->OnFoodEaten(m_World, this, &Item); - - GetInventory().RemoveOneEquippedItem(); - - // if the food is mushroom soup, return a bowl to the inventory - if (Item.m_ItemType == E_ITEM_MUSHROOM_SOUP) - { - cItem EmptyBowl(E_ITEM_BOWL); - GetInventory().AddItem(EmptyBowl, true, true); - } } @@ -820,7 +816,7 @@ void cPlayer::SetCustomName(const AString & a_CustomName) { return; } - m_World->BroadcastPlayerListItem(GetTabListName(), false, 0); // Remove old tab-list entry + AString OldCustomName = m_CustomName; m_CustomName = a_CustomName; if (m_CustomName.length() > 16) @@ -828,8 +824,8 @@ void cPlayer::SetCustomName(const AString & a_CustomName) m_CustomName = m_CustomName.substr(0, 16); } + m_World->BroadcastPlayerListUpdateDisplayName(*this, m_CustomName); m_World->BroadcastSpawnEntity(*this, m_ClientHandle); - m_World->BroadcastPlayerListItem(GetTabListName(), true, GetClientHandle()->GetPing()); } @@ -855,9 +851,9 @@ bool cPlayer::DoTakeDamage(TakeDamageInfo & a_TDI) { if ((a_TDI.DamageType != dtInVoid) && (a_TDI.DamageType != dtPlugin)) { - if (IsGameModeCreative()) + if (IsGameModeCreative() || IsGameModeSpectator()) { - // No damage / health in creative mode if not void or plugin damage + // No damage / health in creative or spectator mode if not void or plugin damage return false; } } @@ -1075,6 +1071,14 @@ bool cPlayer::IsGameModeAdventure(void) const +bool cPlayer::IsGameModeSpectator(void) const +{ + return (m_GameMode == gmSpectator) || // Either the player is explicitly in Spectator + ((m_GameMode == gmNotSet) && m_World->IsGameModeSpectator()); // or they inherit from the world and the world is Adventure +} + + + void cPlayer::SetTeam(cTeam * a_Team) { @@ -1190,11 +1194,13 @@ void cPlayer::SetGameMode(eGameMode a_GameMode) m_GameMode = a_GameMode; m_ClientHandle->SendGameMode(a_GameMode); - if (!IsGameModeCreative()) + if (!(IsGameModeCreative() || IsGameModeSpectator())) { SetFlying(false); SetCanFly(false); } + + m_World->BroadcastPlayerListUpdateGameMode(*this); } @@ -1372,6 +1378,7 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos) void cPlayer::SetVisible(bool a_bVisible) { + // Need to Check if the player or other players are in gamemode spectator, but will break compatibility if (a_bVisible && !m_bVisible) // Make visible { m_bVisible = true; @@ -1466,7 +1473,7 @@ AString cPlayer::GetColor(void) const -AString cPlayer::GetTabListName(void) const +AString cPlayer::GetPlayerListName(void) const { const AString & Color = GetColor(); @@ -1554,6 +1561,11 @@ void cPlayer::TossPickup(const cItem & a_Item) void cPlayer::TossItems(const cItems & a_Items) { + if (IsGameModeSpectator()) // Players can't toss items in spectator + { + return; + } + m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size()); double vX = 0, vY = 0, vZ = 0; @@ -1715,7 +1727,11 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents); m_LoadedWorldName = root.get("world", "world").asString(); - a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), true); + a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), false); + if (a_World == NULL) + { + a_World = cRoot::Get()->GetDefaultWorld(); + } m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); @@ -1836,7 +1852,7 @@ bool cPlayer::SaveToDisk() void cPlayer::UseEquippedItem(int a_Amount) { - if (IsGameModeCreative()) // No damage in creative + if (IsGameModeCreative() || IsGameModeSpectator()) // No damage in creative or spectator { return; } diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 49380c776..ffd0b7e03 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -171,6 +171,9 @@ public: /** Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world */ bool IsGameModeAdventure(void) const; + /** Returns true if the player is in Spectator mode, either explicitly, or by inheriting from current world */ + bool IsGameModeSpectator(void) const; + AString GetIP(void) const { return m_IP; } // tolua_export /** Returns the associated team, NULL if none */ @@ -251,8 +254,8 @@ public: The returned value either is empty, or includes the cChatColor::Delimiter. */ AString GetColor(void) const; - /** Returns the name that is used in the tablist. */ - AString GetTabListName(void) const; + /** Returns the name that is used in the playerlist. */ + AString GetPlayerListName(void) const; /** tosses the item in the selected hotbar slot */ void TossEquippedItem(char a_Amount = 1); |