summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Entities/Entity.cpp5
-rw-r--r--src/Entities/Entity.h3
-rw-r--r--src/Entities/Pickup.cpp10
-rw-r--r--src/Entities/Player.cpp70
-rw-r--r--src/Entities/Player.h11
5 files changed, 95 insertions, 4 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 4cf10a219..9eb03acde 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -370,6 +370,11 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
if (m_Health <= 0)
{
KilledBy(a_TDI.Attacker);
+
+ if (a_TDI.Attacker != NULL)
+ {
+ a_TDI.Attacker->Killed(this);
+ }
}
return true;
}
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index df03d635b..a111b128d 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -299,6 +299,9 @@ public:
/// Called when the health drops below zero. a_Killer may be NULL (environmental damage)
virtual void KilledBy(cEntity * a_Killer);
+ /// Called when the entity kills another entity
+ virtual void Killed(cEntity * a_Victim) {}
+
/// Heals the specified amount of HPs
void Heal(int a_HitPoints);
diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp
index 497b41683..0fd006485 100644
--- a/src/Entities/Pickup.cpp
+++ b/src/Entities/Pickup.cpp
@@ -192,6 +192,16 @@ bool cPickup::CollectedBy(cPlayer * a_Dest)
int NumAdded = a_Dest->GetInventory().AddItem(m_Item);
if (NumAdded > 0)
{
+ // Check achievements
+ switch (m_Item.m_ItemType)
+ {
+ case E_BLOCK_LOG: a_Dest->AwardAchievement(achMineWood); break;
+ case E_ITEM_LEATHER: a_Dest->AwardAchievement(achKillCow); break;
+ case E_ITEM_DIAMOND: a_Dest->AwardAchievement(achDiamonds); break;
+ case E_ITEM_BLAZE_ROD: a_Dest->AwardAchievement(achBlazeRod); break;
+ default: break;
+ }
+
m_Item.m_ItemCount -= NumAdded;
m_World->BroadcastCollectPickup(*this, *a_Dest);
// Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;)
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 1df473eb2..48bb509b9 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -17,6 +17,7 @@
#include "../Vector3.h"
#include "../WorldStorage/StatSerializer.h"
+#include "../CompositeChat.h"
#include "inifile/iniFile.h"
#include "json/json.h"
@@ -876,10 +877,6 @@ void cPlayer::KilledBy(cEntity * a_Killer)
cPlayer* Killer = (cPlayer*)a_Killer;
GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), Killer->GetName().c_str()));
-
- Killer->GetStatManager().AddValue(statPlayerKills);
-
- m_World->GetScoreBoard().AddPlayerScore(Killer->GetName(), cObjective::otPlayerKillCount, 1);
}
else
{
@@ -898,6 +895,33 @@ void cPlayer::KilledBy(cEntity * a_Killer)
+void cPlayer::Killed(cEntity * a_Victim)
+{
+ cScoreboard & ScoreBoard = m_World->GetScoreBoard();
+
+ if (a_Victim->IsPlayer())
+ {
+ m_Stats.AddValue(statPlayerKills);
+
+ ScoreBoard.AddPlayerScore(GetName(), cObjective::otPlayerKillCount, 1);
+ }
+ else if (a_Victim->IsMob())
+ {
+ if (((cMonster *)a_Victim)->GetMobFamily() == cMonster::mfHostile)
+ {
+ AwardAchievement(achKillMonster);
+ }
+
+ m_Stats.AddValue(statMobKills);
+ }
+
+ ScoreBoard.AddPlayerScore(GetName(), cObjective::otTotalKillCount, 1);
+}
+
+
+
+
+
void cPlayer::Respawn(void)
{
m_Health = GetMaxHealth();
@@ -1116,6 +1140,44 @@ void cPlayer::SetIP(const AString & a_IP)
+unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach)
+{
+ eStatistic Prerequisite = cStatInfo::GetPrerequisite(a_Ach);
+
+ if (Prerequisite != statInvalid)
+ {
+ if (m_Stats.GetValue(Prerequisite) == 0)
+ {
+ return 0;
+ }
+ }
+
+ StatValue Old = m_Stats.GetValue(a_Ach);
+
+ if (Old > 0)
+ {
+ return m_Stats.AddValue(a_Ach);
+ }
+ else
+ {
+ cCompositeChat Msg;
+ Msg.AddTextPart(m_PlayerName + " has just earned the achievement ");
+ Msg.AddTextPart(cStatInfo::GetName(a_Ach)); // TODO 2014-05-12 xdot: Use the proper cCompositeChat submessage type and send the actual title
+ m_World->BroadcastChat(Msg);
+
+ StatValue New = m_Stats.AddValue(a_Ach);
+
+ /* Achievement Get! */
+ m_ClientHandle->SendStatistics(m_Stats);
+
+ return New;
+ }
+}
+
+
+
+
+
void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
{
SetPosition(a_PosX, a_PosY, a_PosZ);
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 82a138290..b5c9d75cc 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -179,6 +179,15 @@ public:
/** Return the associated statistic and achievement manager. */
cStatManager & GetStatManager() { return m_Stats; }
+
+ /** Awards the player an achievement.
+ *
+ * If all prerequisites are met, this method will award the achievement and will broadcast a chat message.
+ * If the achievement has been already awarded to the player, this method will just increment the stat counter.
+ *
+ * Returns the _new_ stat value. (0 = Could not award achievement)
+ */
+ unsigned int AwardAchievement(const eStatistic a_Ach);
void SetIP(const AString & a_IP);
@@ -311,6 +320,8 @@ public:
void AbortEating(void);
virtual void KilledBy(cEntity * a_Killer) override;
+
+ virtual void Killed(cEntity * a_Victim) override;
void Respawn(void); // tolua_export