summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Blocks/BlockSignPost.h4
-rw-r--r--src/Entities/Player.cpp21
-rw-r--r--src/Mobs/Monster.cpp1
-rw-r--r--src/Mobs/Monster.h8
-rw-r--r--src/Protocol/Protocol18x.cpp63
-rw-r--r--src/WorldStorage/NBTChunkSerializer.cpp33
-rwxr-xr-xsrc/WorldStorage/WSSAnvil.cpp79
7 files changed, 168 insertions, 41 deletions
diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h
index 651154aff..5ae285bf0 100644
--- a/src/Blocks/BlockSignPost.h
+++ b/src/Blocks/BlockSignPost.h
@@ -65,7 +65,7 @@ public:
// There are 16 meta values which correspond to different directions.
// These values are equated to angles on a circle; 0x08 = 180 degrees.
- return (a_Meta < 0x08) ? (0x08 + a_Meta) : (0x08 - a_Meta);
+ return (a_Meta < 0x08) ? (0x08 - a_Meta) : (0x18 - a_Meta);
}
virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) override
@@ -74,7 +74,7 @@ public:
// There are 16 meta values which correspond to different directions.
// These values are equated to angles on a circle; 0x10 = 360 degrees.
- return 0x10 - a_Meta;
+ return 0x0f - a_Meta;
}
virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index adbaf1104..3a9360d1e 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -16,6 +16,7 @@
#include "../Items/ItemHandler.h"
#include "../Vector3.h"
#include "../FastRandom.h"
+#include <cmath>
#include "../WorldStorage/StatSerializer.h"
#include "../CompositeChat.h"
@@ -2183,20 +2184,18 @@ void cPlayer::ApplyFoodExhaustionFromMovement()
return;
}
- // Process exhaustion every two ticks as that is how frequently m_LastPos is updated
- // Otherwise, we apply exhaustion for a 'movement' every tick, one of which is an already processed value
- if (GetWorld()->GetWorldAge() % 2 != 0)
- {
- return;
- }
-
// Calculate the distance travelled, update the last pos:
- Vector3d Movement(GetPosition() - m_LastPos);
- Movement.y = 0; // Only take XZ movement into account
+ double SpeedX = m_Speed.x;
+ double SpeedZ = m_Speed.z;
+ double BaseExhaustion(sqrt((SpeedX * SpeedX) + (SpeedZ * SpeedZ)));
// Apply the exhaustion based on distance travelled:
- double BaseExhaustion = Movement.Length();
- if (IsSprinting())
+ if (IsFlying() || IsClimbing())
+ {
+ // Apply no exhaustion when flying or climbing.
+ BaseExhaustion = 0;
+ }
+ else if (IsSprinting())
{
// 0.1 pt per meter sprinted
BaseExhaustion = BaseExhaustion * 0.1;
diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp
index cb4edb951..4befe307d 100644
--- a/src/Mobs/Monster.cpp
+++ b/src/Mobs/Monster.cpp
@@ -101,6 +101,7 @@ cMonster::cMonster(const AString & a_ConfigName, eMonsterType a_MobType, const A
, m_TicksSinceLastDamaged(100)
, m_BurnsInDaylight(false)
, m_RelativeWalkSpeed(1)
+ , m_Age(1)
{
if (!a_ConfigName.empty())
{
diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h
index 1076c9544..2832a1570 100644
--- a/src/Mobs/Monster.h
+++ b/src/Mobs/Monster.h
@@ -112,10 +112,14 @@ public:
void SetRelativeWalkSpeed(double a_WalkSpeed) { m_RelativeWalkSpeed = a_WalkSpeed; } // tolua_export
// Overridables to handle ageable mobs
- virtual bool IsBaby (void) const { return false; }
virtual bool IsTame (void) const { return false; }
virtual bool IsSitting (void) const { return false; }
+ bool IsBaby (void) const { return m_Age < 0; }
+ char GetAge (void) const { return m_Age; }
+ void SetAge(char a_Age) { m_Age = a_Age; }
+
+
// tolua_begin
/** Returns true if the monster has a custom name. */
@@ -270,6 +274,8 @@ protected:
bool m_BurnsInDaylight;
double m_RelativeWalkSpeed;
+ char m_Age;
+
/** Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops*/
void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0);
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 9073b565c..db510825e 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -3312,7 +3312,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Bat.IsHanging() ? 1 : 0);
break;
} // case mtBat
-
+
case mtCreeper:
{
auto & Creeper = reinterpret_cast<const cCreeper &>(a_Mob);
@@ -3322,7 +3322,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Creeper.IsCharged() ? 1 : 0);
break;
} // case mtCreeper
-
+
case mtEnderman:
{
auto & Enderman = reinterpret_cast<const cEnderman &>(a_Mob);
@@ -3334,7 +3334,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Enderman.IsScreaming() ? 1 : 0);
break;
} // case mtEnderman
-
+
case mtGhast:
{
auto & Ghast = reinterpret_cast<const cGhast &>(a_Mob);
@@ -3342,7 +3342,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Ghast.IsCharging());
break;
} // case mtGhast
-
+
case mtHorse:
{
auto & Horse = reinterpret_cast<const cHorse &>(a_Mob);
@@ -3359,10 +3359,6 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
{
Flags |= 0x08;
}
- if (Horse.IsBaby())
- {
- Flags |= 0x10;
- }
if (Horse.IsEating())
{
Flags |= 0x20;
@@ -3386,6 +3382,9 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEInt32(Appearance);
a_Pkt.WriteBEUInt8(0x56); // Int at index 22
a_Pkt.WriteBEInt32(Horse.GetHorseArmour());
+
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Horse.GetAge());
break;
} // case mtHorse
@@ -3397,17 +3396,38 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
break;
} // case mtMagmaCube
+ case mtOcelot:
+ {
+ auto & Ocelot = reinterpret_cast<const cOcelot &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Ocelot.GetAge());
+ break;
+ } // case mtOcelot
+
case mtPig:
{
auto & Pig = reinterpret_cast<const cPig &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Pig.GetAge());
a_Pkt.WriteBEUInt8(0x10);
a_Pkt.WriteBEUInt8(Pig.IsSaddled() ? 1 : 0);
break;
} // case mtPig
-
+
+ case mtRabbit:
+ {
+ auto & Rabbit = reinterpret_cast<const cRabbit &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Rabbit.GetAge());
+ break;
+ } // case mtRabbit
+
case mtSheep:
{
auto & Sheep = reinterpret_cast<const cSheep &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Sheep.GetAge());
+
a_Pkt.WriteBEUInt8(0x10);
Byte SheepMetadata = 0;
SheepMetadata = Sheep.GetFurColor();
@@ -3418,7 +3438,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(SheepMetadata);
break;
} // case mtSheep
-
+
case mtSkeleton:
{
auto & Skeleton = reinterpret_cast<const cSkeleton &>(a_Mob);
@@ -3426,7 +3446,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Skeleton.IsWither() ? 1 : 0);
break;
} // case mtSkeleton
-
+
case mtSlime:
{
auto & Slime = reinterpret_cast<const cSlime &>(a_Mob);
@@ -3440,9 +3460,11 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
auto & Villager = reinterpret_cast<const cVillager &>(a_Mob);
a_Pkt.WriteBEUInt8(0x50);
a_Pkt.WriteBEInt32(Villager.GetVilType());
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Villager.GetAge());
break;
} // case mtVillager
-
+
case mtWitch:
{
auto & Witch = reinterpret_cast<const cWitch &>(a_Mob);
@@ -3460,7 +3482,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));
break;
} // case mtWither
-
+
case mtWolf:
{
auto & Wolf = reinterpret_cast<const cWolf &>(a_Mob);
@@ -3486,20 +3508,31 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Wolf.IsBegging() ? 1 : 0);
a_Pkt.WriteBEUInt8(0x14);
a_Pkt.WriteBEUInt8(Wolf.GetCollarColor());
+
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Wolf.GetAge());
break;
} // case mtWolf
-
+
case mtZombie:
{
auto & Zombie = reinterpret_cast<const cZombie &>(a_Mob);
a_Pkt.WriteBEUInt8(0x0c);
- a_Pkt.WriteBEUInt8(Zombie.IsBaby() ? 1 : 0);
+ a_Pkt.WriteBEInt8(Zombie.IsBaby() ? 1 : -1);
a_Pkt.WriteBEUInt8(0x0d);
a_Pkt.WriteBEUInt8(Zombie.IsVillagerZombie() ? 1 : 0);
a_Pkt.WriteBEUInt8(0x0e);
a_Pkt.WriteBEUInt8(Zombie.IsConverting() ? 1 : 0);
break;
} // case mtZombie
+
+ case mtZombiePigman:
+ {
+ auto & ZombiePigman = reinterpret_cast<const cZombiePigman &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(ZombiePigman.IsBaby() ? 1 : -1);
+ break;
+ } // case mtZombiePigman
} // switch (a_Mob.GetType())
}
diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp
index 10231ae3b..234c60d62 100644
--- a/src/WorldStorage/NBTChunkSerializer.cpp
+++ b/src/WorldStorage/NBTChunkSerializer.cpp
@@ -554,6 +554,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
m_Writer.AddInt ("Style", Horse.GetHorseStyle());
m_Writer.AddInt ("ArmorType", Horse.GetHorseArmour());
m_Writer.AddByte("Saddle", Horse.IsSaddled());
+ m_Writer.AddByte("Age", Horse.GetAge());
break;
}
case mtMagmaCube:
@@ -565,6 +566,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
{
m_Writer.AddByte("Sheared", ((const cSheep *)a_Monster)->IsSheared());
m_Writer.AddByte("Color", ((const cSheep *)a_Monster)->GetFurColor());
+ m_Writer.AddByte("Age", ((const cSheep *)a_Monster)->GetAge());
break;
}
case mtSlime:
@@ -580,6 +582,7 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtVillager:
{
m_Writer.AddInt("Profession", ((const cVillager *)a_Monster)->GetVilType());
+ m_Writer.AddByte("Age", ((const cVillager *)a_Monster)->GetAge());
break;
}
case mtWither:
@@ -601,13 +604,37 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
m_Writer.AddByte("Sitting", Wolf.IsSitting() ? 1 : 0);
m_Writer.AddByte("Angry", Wolf.IsAngry() ? 1 : 0);
m_Writer.AddByte("CollarColor", (unsigned char)Wolf.GetCollarColor());
+ m_Writer.AddByte("Age", Wolf.GetAge());
break;
}
case mtZombie:
{
m_Writer.AddByte("IsVillager", (((const cZombie *)a_Monster)->IsVillagerZombie() ? 1 : 0));
- m_Writer.AddByte("IsBaby", (((const cZombie *)a_Monster)->IsBaby() ? 1 : 0));
m_Writer.AddByte("IsConverting", (((const cZombie *)a_Monster)->IsConverting() ? 1 : 0));
+ m_Writer.AddByte("Age", (((const cZombie *)a_Monster)->GetAge()));
+ break;
+ }
+ case mtZombiePigman:
+ {
+ m_Writer.AddByte("Age", (((const cZombiePigman *)a_Monster)->GetAge()));
+ break;
+ }
+ case mtOcelot:
+ {
+ const cOcelot & Ocelot = *((cOcelot *)a_Monster);
+ m_Writer.AddByte("Age", Ocelot.GetAge());
+ break;
+ }
+ case mtPig:
+ {
+ const cPig & Pig = *((cPig *)a_Monster);
+ m_Writer.AddByte("Age", Pig.GetAge());
+ break;
+ }
+ case mtRabbit:
+ {
+ const cRabbit & Rabbit = *((cRabbit *)a_Monster);
+ m_Writer.AddByte("Age", Rabbit.GetAge());
break;
}
case mtInvalidType:
@@ -621,15 +648,11 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster)
case mtGuardian:
case mtIronGolem:
case mtMooshroom:
- case mtOcelot:
- case mtPig:
- case mtRabbit:
case mtSilverfish:
case mtSnowGolem:
case mtSpider:
case mtSquid:
case mtWitch:
- case mtZombiePigman:
{
// Other mobs have no special tags.
break;
diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp
index 95502a29b..62918f44e 100755
--- a/src/WorldStorage/WSSAnvil.cpp
+++ b/src/WorldStorage/WSSAnvil.cpp
@@ -2256,7 +2256,14 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
{
return;
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2346,6 +2353,13 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a
return;
}
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2365,7 +2379,14 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB
{
return;
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2385,7 +2406,14 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
return;
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2418,7 +2446,14 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_
{
Monster->SetSheared(a_NBT.GetByte(ShearedIdx) != 0);
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2583,7 +2618,15 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT &
{
return;
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
+
a_Entities.push_back(Monster.release());
}
@@ -2683,6 +2726,14 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
}
}
}
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2710,7 +2761,14 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a
{
return;
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}
@@ -2730,7 +2788,14 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT
{
return;
}
-
+
+ int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
+ if (AgeableIdx > 0)
+ {
+ Byte Age = a_NBT.GetByte(AgeableIdx);
+ Monster->SetAge(Age);
+ }
+
a_Entities.push_back(Monster.release());
}