From b93d1b5027afc55be3a5e1c882c023d400f2bbfa Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 20:04:01 +0100 Subject: [PATCH 01/10] Implented Spawn Experience Orb packet. --- source/Protocol/Protocol.h | 1 + source/Protocol/Protocol125.cpp | 18 ++++++++++++++++++ source/Protocol/Protocol125.h | 1 + source/Protocol/Protocol17x.cpp | 15 +++++++++++++++ source/Protocol/Protocol17x.h | 1 + source/Protocol/ProtocolRecognizer.cpp | 10 ++++++++++ source/Protocol/ProtocolRecognizer.h | 1 + 7 files changed, 47 insertions(+) diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h index 542060ece..18cf3676a 100644 --- a/source/Protocol/Protocol.h +++ b/source/Protocol/Protocol.h @@ -86,6 +86,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; virtual void SendRespawn (void) = 0; virtual void SendExperience (void) = 0; + virtual void SendExperienceOrb (const cEntity & a_Entity) = 0; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) = 0; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index 54be65b12..3b753479d 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -17,6 +17,7 @@ Documentation: #include "../World.h" #include "ChunkDataSerializer.h" #include "../Entities/Entity.h" +#include "../Entities/ExpOrb.h" #include "../Mobs/Monster.h" #include "../Entities/Pickup.h" #include "../Entities/Player.h" @@ -72,6 +73,7 @@ enum PACKET_ENT_STATUS = 0x26, PACKET_ATTACH_ENTITY = 0x27, PACKET_METADATA = 0x28, + PACKET_SPAWN_EXPERIENCE_ORB = 0x1A, PACKET_EXPERIENCE = 0x2b, PACKET_PRE_CHUNK = 0x32, PACKET_MAP_CHUNK = 0x33, @@ -705,6 +707,22 @@ void cProtocol125::SendExperience(void) +void cProtocol125::SendExperienceOrb(const cEntity & a_Entity) +{ + cCSLock Lock(m_CSPacket); + WriteByte(PACKET_SPAWN_EXPERIENCE_ORB); + WriteInt(a_Entity.GetUniqueID()); + WriteInt((int) a_Entity.GetPosX()); + WriteInt((int) a_Entity.GetPosY()); + WriteInt((int) a_Entity.GetPosZ()); + WriteShort(((cExpOrb &)a_Entity).GetReward()); + Flush(); +} + + + + + void cProtocol125::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) { // Not needed in this protocol version diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h index c5f44c818..2182ea356 100644 --- a/source/Protocol/Protocol125.h +++ b/source/Protocol/Protocol125.h @@ -63,6 +63,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendRespawn (void) override; virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cEntity & a_Entity) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; diff --git a/source/Protocol/Protocol17x.cpp b/source/Protocol/Protocol17x.cpp index ae1df7395..cf5c84599 100644 --- a/source/Protocol/Protocol17x.cpp +++ b/source/Protocol/Protocol17x.cpp @@ -17,6 +17,7 @@ Implements the 1.7.x protocol classes: #include "../World.h" #include "../WorldStorage/FastNBT.h" #include "../StringCompression.h" +#include "../Entities/ExpOrb.h" #include "../Entities/Minecart.h" #include "../Entities/FallingBlock.h" #include "../Entities/Pickup.h" @@ -609,6 +610,20 @@ void cProtocol172::SendExperience (void) +void cProtocol172::SendExperienceOrb(const cEntity & a_Entity) +{ + cPacketizer Pkt(*this, 0x11); + Pkt.WriteVarInt(a_Entity.GetUniqueID()); + Pkt.WriteInt((int) a_Entity.GetPosX()); + Pkt.WriteInt((int) a_Entity.GetPosY()); + Pkt.WriteInt((int) a_Entity.GetPosZ()); + Pkt.WriteShort(((cExpOrb &)a_Entity).GetReward()); +} + + + + + void cProtocol172::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) // a_Src coords are Block * 8 { cPacketizer Pkt(*this, 0x29); // Sound Effect packet diff --git a/source/Protocol/Protocol17x.h b/source/Protocol/Protocol17x.h index e3f2ad922..6b8d2ce79 100644 --- a/source/Protocol/Protocol17x.h +++ b/source/Protocol/Protocol17x.h @@ -73,6 +73,7 @@ public: virtual void SendRespawn (void) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cEntity & a_Entity) override; virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index 64bd83075..ad00e8d38 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -476,6 +476,16 @@ void cProtocolRecognizer::SendExperience(void) +void cProtocolRecognizer::SendExperienceOrb(const cEntity & a_Entity) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendExperienceOrb(a_Entity); +} + + + + + void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) { ASSERT(m_Protocol != NULL); diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h index 03f48fb35..62e624980 100644 --- a/source/Protocol/ProtocolRecognizer.h +++ b/source/Protocol/ProtocolRecognizer.h @@ -98,6 +98,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendRespawn (void) override; virtual void SendExperience (void) override; + virtual void SendExperienceOrb (const cEntity & a_Entity) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; From f86f67907cf3812c09ad10166677e9c91b1f1198 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 20:04:39 +0100 Subject: [PATCH 02/10] Implented SendExperienceOrb in ClientHandle. --- source/ClientHandle.cpp | 9 +++++++++ source/ClientHandle.h | 1 + source/Entities/Entity.h | 1 + source/Mobs/Monster.cpp | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index daf09d4ea..1bc741aa6 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -1885,6 +1885,15 @@ void cClientHandle::SendExperience(void) +void cClientHandle::SendExperienceOrb(const cEntity & a_Entity) +{ + m_Protocol->SendExperienceOrb(a_Entity); +} + + + + + void cClientHandle::SendSoundEffect(const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) { m_Protocol->SendSoundEffect(a_SoundName, a_SrcX, a_SrcY, a_SrcZ, a_Volume, a_Pitch); diff --git a/source/ClientHandle.h b/source/ClientHandle.h index b887bb11a..2857b0dcd 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -121,6 +121,7 @@ public: void SendPlayerSpawn (const cPlayer & a_Player); void SendRespawn (void); void SendExperience (void); + void SendExperienceOrb (const cEntity & a_Entity); void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch); // a_Src coords are Block * 8 void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); diff --git a/source/Entities/Entity.h b/source/Entities/Entity.h index dafda7826..de5f176ae 100644 --- a/source/Entities/Entity.h +++ b/source/Entities/Entity.h @@ -74,6 +74,7 @@ public: etBoat, etTNT, etProjectile, + etExpOrb, // Common variations etMob = etMonster, // DEPRECATED, use etMonster instead! diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp index 8a5717e27..f250e1757 100644 --- a/source/Mobs/Monster.cpp +++ b/source/Mobs/Monster.cpp @@ -7,6 +7,7 @@ #include "../ClientHandle.h" #include "../World.h" #include "../Entities/Player.h" +#include "../Entities/ExpOrb.h" #include "../Defines.h" #include "../MonsterConfig.h" #include "../MersenneTwister.h" @@ -258,6 +259,9 @@ void cMonster::KilledBy(cEntity * a_Killer) { m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f); } + // ToDo: Proper Exp per mob. + cExpOrb * ExpOrb = new cExpOrb(GetPosX(), GetPosY(), GetPosZ(), 1); + ExpOrb->Initialize(m_World); m_DestroyTimer = 0; } From 6641db058392dd6d7e170b95cd8616b920add63c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 20:05:52 +0100 Subject: [PATCH 03/10] Implented ExpOrb class. --- source/Entities/ExpOrb.cpp | 60 ++++++++++++++++++++++++++++++++++++++ source/Entities/ExpOrb.h | 29 ++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 source/Entities/ExpOrb.cpp create mode 100644 source/Entities/ExpOrb.h diff --git a/source/Entities/ExpOrb.cpp b/source/Entities/ExpOrb.cpp new file mode 100644 index 000000000..200f6e181 --- /dev/null +++ b/source/Entities/ExpOrb.cpp @@ -0,0 +1,60 @@ +#include "Globals.h" + +#include "ExpOrb.h" +#include "Player.h" +#include "../ClientHandle.h" + + +cExpOrb::cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward) : + cEntity(etExpOrb, a_X, a_Y, a_Z, 0.98, 0.98), + m_Reward(a_Reward) +{ +} + + + + + +cExpOrb::cExpOrb(const Vector3d & a_Pos, int a_Reward) : + cEntity(etExpOrb, a_Pos.x, a_Pos.y, a_Pos.z, 0.98, 0.98), + m_Reward(a_Reward) +{ +} + + + + + +void cExpOrb::SpawnOn(cClientHandle & a_Client) +{ + a_Client.SendExperienceOrb(*this); + m_bDirtyPosition = false; + m_bDirtySpeed = false; + m_bDirtyOrientation = false; + m_bDirtyHead = false; +} + + + + + +void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) +{ + cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 3)); + if (a_ClosestPlayer) + { + Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition()); + Vector3f a_Distance(a_PlayerPos - GetPosition()); + if (a_Distance.Length() < 0.1f) + { + a_ClosestPlayer->DeltaExperience(m_Reward); + a_ClosestPlayer->SendExperience(); + Destroy(true); + } + a_Distance.y = 0; + a_Distance.Normalize(); + a_Distance *= 3; + SetSpeedX( a_Distance.x ); + SetSpeedZ( a_Distance.z ); + } +} \ No newline at end of file diff --git a/source/Entities/ExpOrb.h b/source/Entities/ExpOrb.h new file mode 100644 index 000000000..0f1b6ede7 --- /dev/null +++ b/source/Entities/ExpOrb.h @@ -0,0 +1,29 @@ + +#pragma once + +#include "Entity.h" + + + + + +class cExpOrb : + public cEntity +{ + typedef cExpOrb super; + +public: + + cExpOrb(double a_X, double a_Y, double a_Z, int a_Reward); + cExpOrb(const Vector3d & a_Pos, int a_Reward); + + // Override functions + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void SpawnOn(cClientHandle & a_Client) override; + + // cExpOrb functions + short int GetReward(void) const { return m_Reward; } + +protected: + int m_Reward; +} ; \ No newline at end of file From dd76700d8d0491f385efee1a539462501cb41ad4 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 21:03:26 +0100 Subject: [PATCH 04/10] Added cWorld::SpawnExperienceOrb function. Most mobs now give proper Exp. --- source/Mobs/Monster.cpp | 53 ++++++++++++++++++++++++++++++++++++++--- source/World.cpp | 11 +++++++++ source/World.h | 3 +++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp index f250e1757..a74881978 100644 --- a/source/Mobs/Monster.cpp +++ b/source/Mobs/Monster.cpp @@ -259,9 +259,56 @@ void cMonster::KilledBy(cEntity * a_Killer) { m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f); } - // ToDo: Proper Exp per mob. - cExpOrb * ExpOrb = new cExpOrb(GetPosX(), GetPosY(), GetPosZ(), 1); - ExpOrb->Initialize(m_World); + int Exp; + switch (m_MobType) + { + // Animals + case cMonster::mtChicken: + case cMonster::mtCow: + case cMonster::mtHorse: + case cMonster::mtPig: + case cMonster::mtSheep: + case cMonster::mtSquid: + case cMonster::mtMooshroom: + case cMonster::mtOcelot: + case cMonster::mtWolf: + { + Exp = m_World->GetTickRandomNumber(2) + 1; + } + + // Monsters + case cMonster::mtCaveSpider: + case cMonster::mtCreeper: + case cMonster::mtEnderman: + case cMonster::mtGhast: + case cMonster::mtSilverfish: + case cMonster::mtSkeleton: + case cMonster::mtSpider: + case cMonster::mtWitch: + case cMonster::mtZombie: + case cMonster::mtZombiePigman: + case cMonster::mtSlime: + case cMonster::mtMagmaCube: + { + Exp = 6 + (m_World->GetTickRandomNumber(2)); + } + + // Bosses + case cMonster::mtEnderDragon: + { + Exp = 12000; + } + case cMonster::mtWither: + { + Exp = 50; + } + + default: + { + Exp = 0; + } + } + m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Exp); m_DestroyTimer = 0; } diff --git a/source/World.cpp b/source/World.cpp index 531952e37..432ab32e9 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -13,6 +13,7 @@ #include "OSSupport/Timer.h" // Entities (except mobs): +#include "Entities/ExpOrb.h" #include "Entities/Pickup.h" #include "Entities/Player.h" #include "Entities/TNTEntity.h" @@ -1561,6 +1562,16 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double +void cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) +{ + cExpOrb * ExpOrb = new cExpOrb(a_X, a_Y, a_Z, a_Reward); + ExpOrb->Initialize(this); +} + + + + + void cWorld::SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff) { cTNTEntity * TNT = new cTNTEntity(a_X, a_Y, a_Z, a_FuseTimeInSec); diff --git a/source/World.h b/source/World.h index d10aa3b78..9397f8b75 100644 --- a/source/World.h +++ b/source/World.h @@ -353,6 +353,9 @@ public: /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false); + /// Spawns an experience orb at the given location with the given reward. + void SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); + /// Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff = 1); From 0fef69e6124d6725ef42917beccf2d6a1e4a7918 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 25 Nov 2013 21:24:41 +0100 Subject: [PATCH 05/10] Fixed cFile compilation on Linux. --- source/OSSupport/File.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/OSSupport/File.cpp b/source/OSSupport/File.cpp index 274aa52da..9f7c0d439 100644 --- a/source/OSSupport/File.cpp +++ b/source/OSSupport/File.cpp @@ -394,13 +394,14 @@ AStringVector cFile::GetFolderContents(const AString & a_Folder) DIR * dp; struct dirent *dirp; - if (*a_Directory == 0) + AString Folder = a_Folder; + if (Folder.empty()) { - a_Directory = "."; + Folder = "."; } - if ((dp = opendir(a_Directory)) == NULL) + if ((dp = opendir(Folder.c_str())) == NULL) { - LOGERROR("Error (%i) opening directory \"%s\"\n", errno, a_Directory ); + LOGERROR("Error (%i) opening directory \"%s\"\n", errno, Folder.c_str()); } else { From 18b5ccbc0836dbfb4adcff76dbfbde340bcabbc1 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 21:43:43 +0100 Subject: [PATCH 06/10] Fixed Details Xoft gave. Increased the range where orbs (should) track you. Blazes give 10 xp now. --- source/ClientHandle.cpp | 4 ++-- source/ClientHandle.h | 3 ++- source/Entities/ExpOrb.cpp | 2 +- source/Entities/ExpOrb.h | 2 +- source/Mobs/Monster.cpp | 18 +++++++++++------- source/Protocol/Protocol.h | 3 ++- source/Protocol/Protocol125.cpp | 12 ++++++------ source/Protocol/Protocol125.h | 2 +- source/Protocol/Protocol17x.cpp | 12 ++++++------ source/Protocol/Protocol17x.h | 2 +- source/Protocol/ProtocolRecognizer.cpp | 4 ++-- source/Protocol/ProtocolRecognizer.h | 2 +- 12 files changed, 36 insertions(+), 30 deletions(-) diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 1bc741aa6..b3e12ce77 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -1885,9 +1885,9 @@ void cClientHandle::SendExperience(void) -void cClientHandle::SendExperienceOrb(const cEntity & a_Entity) +void cClientHandle::SendExperienceOrb(const cExpOrb & a_ExpOrb) { - m_Protocol->SendExperienceOrb(a_Entity); + m_Protocol->SendExperienceOrb(a_ExpOrb); } diff --git a/source/ClientHandle.h b/source/ClientHandle.h index 2857b0dcd..b3550110d 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -25,6 +25,7 @@ class cChunkDataSerializer; class cInventory; class cMonster; class cPawn; +class cExpOrb; class cPickup; class cPlayer; class cProtocol; @@ -121,7 +122,7 @@ public: void SendPlayerSpawn (const cPlayer & a_Player); void SendRespawn (void); void SendExperience (void); - void SendExperienceOrb (const cEntity & a_Entity); + void SendExperienceOrb (const cExpOrb & a_ExpOrb); void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch); // a_Src coords are Block * 8 void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); diff --git a/source/Entities/ExpOrb.cpp b/source/Entities/ExpOrb.cpp index 200f6e181..1e5ee00ce 100644 --- a/source/Entities/ExpOrb.cpp +++ b/source/Entities/ExpOrb.cpp @@ -40,7 +40,7 @@ void cExpOrb::SpawnOn(cClientHandle & a_Client) void cExpOrb::Tick(float a_Dt, cChunk & a_Chunk) { - cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 3)); + cPlayer * a_ClosestPlayer(m_World->FindClosestPlayer(Vector3f(GetPosition()), 4)); if (a_ClosestPlayer) { Vector3f a_PlayerPos(a_ClosestPlayer->GetPosition()); diff --git a/source/Entities/ExpOrb.h b/source/Entities/ExpOrb.h index 0f1b6ede7..a062eedd3 100644 --- a/source/Entities/ExpOrb.h +++ b/source/Entities/ExpOrb.h @@ -22,7 +22,7 @@ public: virtual void SpawnOn(cClientHandle & a_Client) override; // cExpOrb functions - short int GetReward(void) const { return m_Reward; } + int GetReward(void) const { return m_Reward; } protected: int m_Reward; diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp index a74881978..091623c8a 100644 --- a/source/Mobs/Monster.cpp +++ b/source/Mobs/Monster.cpp @@ -259,7 +259,7 @@ void cMonster::KilledBy(cEntity * a_Killer) { m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f); } - int Exp; + int Reward; switch (m_MobType) { // Animals @@ -273,7 +273,7 @@ void cMonster::KilledBy(cEntity * a_Killer) case cMonster::mtOcelot: case cMonster::mtWolf: { - Exp = m_World->GetTickRandomNumber(2) + 1; + Reward = m_World->GetTickRandomNumber(2) + 1; } // Monsters @@ -290,25 +290,29 @@ void cMonster::KilledBy(cEntity * a_Killer) case cMonster::mtSlime: case cMonster::mtMagmaCube: { - Exp = 6 + (m_World->GetTickRandomNumber(2)); + Reward = 6 + (m_World->GetTickRandomNumber(2)); + } + case cMonster::mtBlaze: + { + Reward = 10; } // Bosses case cMonster::mtEnderDragon: { - Exp = 12000; + Reward = 12000; } case cMonster::mtWither: { - Exp = 50; + Reward = 50; } default: { - Exp = 0; + Reward = 0; } } - m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Exp); + m_World->SpawnExperienceOrb(GetPosX(), GetPosY(), GetPosZ(), Reward); m_DestroyTimer = 0; } diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h index 18cf3676a..9d8183361 100644 --- a/source/Protocol/Protocol.h +++ b/source/Protocol/Protocol.h @@ -16,6 +16,7 @@ +class cExpOrb; class cPlayer; class cEntity; class cWindow; @@ -86,7 +87,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0; virtual void SendRespawn (void) = 0; virtual void SendExperience (void) = 0; - virtual void SendExperienceOrb (const cEntity & a_Entity) = 0; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) = 0; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0; diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index 3b753479d..b1dd17ea1 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -707,15 +707,15 @@ void cProtocol125::SendExperience(void) -void cProtocol125::SendExperienceOrb(const cEntity & a_Entity) +void cProtocol125::SendExperienceOrb(const cExpOrb & a_ExpOrb) { cCSLock Lock(m_CSPacket); WriteByte(PACKET_SPAWN_EXPERIENCE_ORB); - WriteInt(a_Entity.GetUniqueID()); - WriteInt((int) a_Entity.GetPosX()); - WriteInt((int) a_Entity.GetPosY()); - WriteInt((int) a_Entity.GetPosZ()); - WriteShort(((cExpOrb &)a_Entity).GetReward()); + WriteInt(a_ExpOrb.GetUniqueID()); + WriteInt((int) a_ExpOrb.GetPosX()); + WriteInt((int) a_ExpOrb.GetPosY()); + WriteInt((int) a_ExpOrb.GetPosZ()); + WriteShort(a_ExpOrb.GetReward()); Flush(); } diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h index 2182ea356..5a9218f5b 100644 --- a/source/Protocol/Protocol125.h +++ b/source/Protocol/Protocol125.h @@ -63,7 +63,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendRespawn (void) override; virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cEntity & a_Entity) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; diff --git a/source/Protocol/Protocol17x.cpp b/source/Protocol/Protocol17x.cpp index cf5c84599..746e1c127 100644 --- a/source/Protocol/Protocol17x.cpp +++ b/source/Protocol/Protocol17x.cpp @@ -610,14 +610,14 @@ void cProtocol172::SendExperience (void) -void cProtocol172::SendExperienceOrb(const cEntity & a_Entity) +void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb) { cPacketizer Pkt(*this, 0x11); - Pkt.WriteVarInt(a_Entity.GetUniqueID()); - Pkt.WriteInt((int) a_Entity.GetPosX()); - Pkt.WriteInt((int) a_Entity.GetPosY()); - Pkt.WriteInt((int) a_Entity.GetPosZ()); - Pkt.WriteShort(((cExpOrb &)a_Entity).GetReward()); + Pkt.WriteVarInt(a_ExpOrb.GetUniqueID()); + Pkt.WriteInt((int) a_ExpOrb.GetPosX()); + Pkt.WriteInt((int) a_ExpOrb.GetPosY()); + Pkt.WriteInt((int) a_ExpOrb.GetPosZ()); + Pkt.WriteShort(a_ExpOrb.GetReward()); } diff --git a/source/Protocol/Protocol17x.h b/source/Protocol/Protocol17x.h index 6b8d2ce79..255cb4ef5 100644 --- a/source/Protocol/Protocol17x.h +++ b/source/Protocol/Protocol17x.h @@ -73,7 +73,7 @@ public: virtual void SendRespawn (void) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cEntity & a_Entity) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index ad00e8d38..489149d74 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -476,10 +476,10 @@ void cProtocolRecognizer::SendExperience(void) -void cProtocolRecognizer::SendExperienceOrb(const cEntity & a_Entity) +void cProtocolRecognizer::SendExperienceOrb(const cExpOrb & a_ExpOrb) { ASSERT(m_Protocol != NULL); - m_Protocol->SendExperienceOrb(a_Entity); + m_Protocol->SendExperienceOrb(a_ExpOrb); } diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h index 62e624980..9ca0c1c88 100644 --- a/source/Protocol/ProtocolRecognizer.h +++ b/source/Protocol/ProtocolRecognizer.h @@ -98,7 +98,7 @@ public: virtual void SendPlayerSpawn (const cPlayer & a_Player) override; virtual void SendRespawn (void) override; virtual void SendExperience (void) override; - virtual void SendExperienceOrb (const cEntity & a_Entity) override; + virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override; virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override; From 960b1654a60dc4ae850b8758b4b1bed1f34a46cb Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 21:48:43 +0100 Subject: [PATCH 07/10] Exported cWorld::SpawnExperienceOrb() function to the Lua API. --- source/Bindings.cpp | 43 ++++++++++++++++++++++++++++++++++++++++++- source/Bindings.h | 2 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index ad3ad8423..7bea672da 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 11/23/13 19:57:30. +** Generated automatically by tolua++-1.0.92 on 11/25/13 21:47:32. */ #ifndef __cplusplus @@ -12589,6 +12589,45 @@ tolua_lerror: } #endif //#ifndef TOLUA_DISABLE +/* method: SpawnExperienceOrb of class cWorld */ +#ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SpawnExperienceOrb00 +static int tolua_AllToLua_cWorld_SpawnExperienceOrb00(lua_State* tolua_S) +{ +#ifndef TOLUA_RELEASE + tolua_Error tolua_err; + if ( + !tolua_isusertype(tolua_S,1,"cWorld",0,&tolua_err) || + !tolua_isnumber(tolua_S,2,0,&tolua_err) || + !tolua_isnumber(tolua_S,3,0,&tolua_err) || + !tolua_isnumber(tolua_S,4,0,&tolua_err) || + !tolua_isnumber(tolua_S,5,0,&tolua_err) || + !tolua_isnoobj(tolua_S,6,&tolua_err) + ) + goto tolua_lerror; + else +#endif + { + cWorld* self = (cWorld*) tolua_tousertype(tolua_S,1,0); + double a_X = ((double) tolua_tonumber(tolua_S,2,0)); + double a_Y = ((double) tolua_tonumber(tolua_S,3,0)); + double a_Z = ((double) tolua_tonumber(tolua_S,4,0)); + int a_Reward = ((int) tolua_tonumber(tolua_S,5,0)); +#ifndef TOLUA_RELEASE + if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnExperienceOrb'", NULL); +#endif + { + self->SpawnExperienceOrb(a_X,a_Y,a_Z,a_Reward); + } + } + return 0; +#ifndef TOLUA_RELEASE + tolua_lerror: + tolua_error(tolua_S,"#ferror in function 'SpawnExperienceOrb'.",&tolua_err); + return 0; +#endif +} +#endif //#ifndef TOLUA_DISABLE + /* method: SpawnPrimedTNT of class cWorld */ #ifndef TOLUA_DISABLE_tolua_AllToLua_cWorld_SpawnPrimedTNT00 static int tolua_AllToLua_cWorld_SpawnPrimedTNT00(lua_State* tolua_S) @@ -30430,6 +30469,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_constant(tolua_S,"etBoat",cEntity::etBoat); tolua_constant(tolua_S,"etTNT",cEntity::etTNT); tolua_constant(tolua_S,"etProjectile",cEntity::etProjectile); + tolua_constant(tolua_S,"etExpOrb",cEntity::etExpOrb); tolua_constant(tolua_S,"etMob",cEntity::etMob); tolua_function(tolua_S,"GetEntityType",tolua_AllToLua_cEntity_GetEntityType00); tolua_function(tolua_S,"IsPlayer",tolua_AllToLua_cEntity_IsPlayer00); @@ -30801,6 +30841,7 @@ TOLUA_API int tolua_AllToLua_open (lua_State* tolua_S) tolua_function(tolua_S,"SetBlockMeta",tolua_AllToLua_cWorld_SetBlockMeta01); tolua_function(tolua_S,"SpawnItemPickups",tolua_AllToLua_cWorld_SpawnItemPickups00); tolua_function(tolua_S,"SpawnItemPickups",tolua_AllToLua_cWorld_SpawnItemPickups01); + tolua_function(tolua_S,"SpawnExperienceOrb",tolua_AllToLua_cWorld_SpawnExperienceOrb00); tolua_function(tolua_S,"SpawnPrimedTNT",tolua_AllToLua_cWorld_SpawnPrimedTNT00); tolua_function(tolua_S,"DigBlock",tolua_AllToLua_cWorld_DigBlock00); tolua_function(tolua_S,"SendBlockTo",tolua_AllToLua_cWorld_SendBlockTo00); diff --git a/source/Bindings.h b/source/Bindings.h index bc8589293..8d20bd0dc 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 11/23/13 19:57:31. +** Generated automatically by tolua++-1.0.92 on 11/25/13 21:47:33. */ /* Exported function */ From a0c6342a294077b67f509b6f319468f56e39e344 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 21:51:52 +0100 Subject: [PATCH 08/10] Documented SpawnExperienceOrb in cWorld --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 44e4bb35f..9f558f58c 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2075,6 +2075,7 @@ end { Params = "{{cItems|Pickups}}, X, Y, Z, SpeedX, SpeedY, SpeedZ", Return = "", Notes = "Spawns the specified pickups at the position specified. All the pickups fly away from the spawn position using the specified speed." }, }, SpawnMob = { Params = "X, Y, Z, {{cMonster|MonsterType}}", Return = "EntityID", Notes = "Spawns the specified type of mob at the specified coords. Returns the EntityID of the creates entity, or -1 on failure. " }, + SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "", Notes = "Spawns an {{cExpOrb|experience orb at the specified coords, with the given reward" }, SpawnPrimedTNT = { Params = "X, Y, Z, FuseTimeSecs, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse time. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." }, TryGetHeight = { Params = "BlockX, BlockZ", Return = "IsValid, Height", Notes = "Returns true and height of the highest non-air block if the chunk is loaded, or false otherwise." }, UnloadUnusedChunks = { Params = "", Return = "", Notes = "Unloads chunks that are no longer needed, and are saved. NOTE: This API is deprecated and will be removed soon." }, From 1358a74412b45b1c214bfe58f4c5160ca75f4da7 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 25 Nov 2013 22:09:20 +0100 Subject: [PATCH 09/10] Added ExpOrb.cpp and ExpOrb.h to MCServer.vcproj. --- VC2008/MCServer.vcproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 93a34d90a..f9acdd852 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -1267,6 +1267,14 @@ RelativePath="..\source\Entities\ProjectileEntity.h" > + + + + From 686e0c12e2fa1b8d8e0970306e57cbcfa247f5f5 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Tue, 26 Nov 2013 15:37:15 +0100 Subject: [PATCH 10/10] cWorld::SpawnExperienceOrb() now returns the entity ID of the spawned orb. Documented etExpOrb. --- MCServer/Plugins/APIDump/APIDesc.lua | 3 ++- source/Bindings.cpp | 7 ++++--- source/Bindings.h | 2 +- source/World.cpp | 3 ++- source/World.h | 4 ++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 9f558f58c..6545c1f9f 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -769,6 +769,7 @@ end { etBoat = { Notes = "The entity is a {{cBoat}}" }, etEntity = { Notes = "No further specialization available" }, + etExpOrb = { Notes = "The entity is a {{cExpOrb}}" }, etFallingBlock = { Notes = "The entity is a {{cFallingBlock}}" }, etMob = { Notes = "The entity is a {{cMonster}} descendant" }, etMonster = { Notes = "The entity is a {{cMonster}} descendant" }, @@ -2075,7 +2076,7 @@ end { Params = "{{cItems|Pickups}}, X, Y, Z, SpeedX, SpeedY, SpeedZ", Return = "", Notes = "Spawns the specified pickups at the position specified. All the pickups fly away from the spawn position using the specified speed." }, }, SpawnMob = { Params = "X, Y, Z, {{cMonster|MonsterType}}", Return = "EntityID", Notes = "Spawns the specified type of mob at the specified coords. Returns the EntityID of the creates entity, or -1 on failure. " }, - SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "", Notes = "Spawns an {{cExpOrb|experience orb at the specified coords, with the given reward" }, + SpawnExperienceOrb = { Params = "X, Y, Z, Reward", Return = "EntityID", Notes = "Spawns an {{cExpOrb|experience orb}} at the specified coords, with the given reward" }, SpawnPrimedTNT = { Params = "X, Y, Z, FuseTimeSecs, InitialVelocityCoeff", Return = "", Notes = "Spawns a {{cTNTEntity|primed TNT entity}} at the specified coords, with the given fuse time. The entity gets a random speed multiplied by the InitialVelocityCoeff, 1 being the default value." }, TryGetHeight = { Params = "BlockX, BlockZ", Return = "IsValid, Height", Notes = "Returns true and height of the highest non-air block if the chunk is loaded, or false otherwise." }, UnloadUnusedChunks = { Params = "", Return = "", Notes = "Unloads chunks that are no longer needed, and are saved. NOTE: This API is deprecated and will be removed soon." }, diff --git a/source/Bindings.cpp b/source/Bindings.cpp index 7bea672da..62a16b38b 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 11/25/13 21:47:32. +** Generated automatically by tolua++-1.0.92 on 11/26/13 15:29:19. */ #ifndef __cplusplus @@ -12616,10 +12616,11 @@ static int tolua_AllToLua_cWorld_SpawnExperienceOrb00(lua_State* tolua_S) if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SpawnExperienceOrb'", NULL); #endif { - self->SpawnExperienceOrb(a_X,a_Y,a_Z,a_Reward); + int tolua_ret = (int) self->SpawnExperienceOrb(a_X,a_Y,a_Z,a_Reward); + tolua_pushnumber(tolua_S,(lua_Number)tolua_ret); } } - return 0; + return 1; #ifndef TOLUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'SpawnExperienceOrb'.",&tolua_err); diff --git a/source/Bindings.h b/source/Bindings.h index 8d20bd0dc..240ceec30 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 11/25/13 21:47:33. +** Generated automatically by tolua++-1.0.92 on 11/26/13 15:29:20. */ /* Exported function */ diff --git a/source/World.cpp b/source/World.cpp index 432ab32e9..de64b1c20 100644 --- a/source/World.cpp +++ b/source/World.cpp @@ -1562,10 +1562,11 @@ void cWorld::SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double -void cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) +int cWorld::SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward) { cExpOrb * ExpOrb = new cExpOrb(a_X, a_Y, a_Z, a_Reward); ExpOrb->Initialize(this); + return ExpOrb->GetUniqueID(); } diff --git a/source/World.h b/source/World.h index 9397f8b75..284e96bbb 100644 --- a/source/World.h +++ b/source/World.h @@ -353,8 +353,8 @@ public: /// Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified: void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false); - /// Spawns an experience orb at the given location with the given reward. - void SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); + /// Spawns an experience orb at the given location with the given reward. It returns the UniqueID of the spawned experience orb. + int SpawnExperienceOrb(double a_X, double a_Y, double a_Z, int a_Reward); /// Spawns a new primed TNT entity at the specified block coords and specified fuse duration. Initial velocity is given based on the relative coefficient provided void SpawnPrimedTNT(double a_X, double a_Y, double a_Z, double a_FuseTimeInSec, double a_InitialVelocityCoeff = 1);