summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Bindings/AllToLua.pkg1
-rw-r--r--src/Bindings/ManualBindings.cpp5
-rw-r--r--src/Entities/Player.cpp21
-rw-r--r--src/Scoreboard.cpp135
-rw-r--r--src/Scoreboard.h131
-rw-r--r--src/WorldStorage/ScoreboardSerializer.cpp14
6 files changed, 200 insertions, 107 deletions
diff --git a/src/Bindings/AllToLua.pkg b/src/Bindings/AllToLua.pkg
index 6537437cd..1a2140771 100644
--- a/src/Bindings/AllToLua.pkg
+++ b/src/Bindings/AllToLua.pkg
@@ -75,6 +75,7 @@ $cfile "../Mobs/Monster.h"
$cfile "../CompositeChat.h"
$cfile "../Map.h"
$cfile "../MapManager.h"
+$cfile "../Scoreboard.h"
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index 461186d3b..fcdd728be 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -2583,6 +2583,11 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_beginmodule(tolua_S, "cMapManager");
tolua_function(tolua_S, "DoWithMap", tolua_DoWithID<cMapManager, cMap, &cMapManager::DoWithMap>);
tolua_endmodule(tolua_S);
+
+ tolua_beginmodule(tolua_S, "cScoreboard");
+ tolua_function(tolua_S, "ForEachObjective", tolua_ForEach<cScoreboard, cObjective, &cScoreboard::ForEachObjective>);
+ tolua_function(tolua_S, "ForEachTeam", tolua_ForEach<cScoreboard, cTeam, &cScoreboard::ForEachTeam>);
+ tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cPlugin");
tolua_function(tolua_S, "Call", tolua_cPlugin_Call);
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index f419ee09c..8f94f1feb 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -858,6 +858,8 @@ void cPlayer::KilledBy(cEntity * a_Killer)
else if (a_Killer->IsPlayer())
{
GetWorld()->BroadcastChatDeath(Printf("%s was killed by %s", GetName().c_str(), ((cPlayer *)a_Killer)->GetName().c_str()));
+
+ m_World->GetScoreBoard().AddPlayerScore(((cPlayer *)a_Killer)->GetName(), cObjective::otPlayerKillCount, 1);
}
else
{
@@ -867,24 +869,7 @@ void cPlayer::KilledBy(cEntity * a_Killer)
GetWorld()->BroadcastChatDeath(Printf("%s was killed by a %s", GetName().c_str(), KillerClass.c_str()));
}
- class cIncrementCounterCB
- : public cObjectiveCallback
- {
- AString m_Name;
- public:
- cIncrementCounterCB(const AString & a_Name) : m_Name(a_Name) {}
-
- virtual bool Item(cObjective * a_Objective) override
- {
- a_Objective->AddScore(m_Name, 1);
- return true;
- }
- } IncrementCounter (GetName());
-
- cScoreboard & Scoreboard = m_World->GetScoreBoard();
-
- // Update scoreboard objectives
- Scoreboard.ForEachObjectiveWith(cObjective::E_TYPE_DEATH_COUNT, IncrementCounter);
+ m_World->GetScoreBoard().AddPlayerScore(GetName(), cObjective::otDeathCount, 1);
}
diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp
index 61ecac5b7..05fd0314d 100644
--- a/src/Scoreboard.cpp
+++ b/src/Scoreboard.cpp
@@ -17,19 +17,19 @@ AString cObjective::TypeToString(eType a_Type)
{
switch (a_Type)
{
- case E_TYPE_DUMMY: return "dummy";
- case E_TYPE_DEATH_COUNT: return "deathCount";
- case E_TYPE_PLAYER_KILL_COUNT: return "playerKillCount";
- case E_TYPE_TOTAL_KILL_COUNT: return "totalKillCount";
- case E_TYPE_HEALTH: return "health";
- case E_TYPE_ACHIEVEMENT: return "achievement";
- case E_TYPE_STAT: return "stat";
- case E_TYPE_STAT_ITEM_CRAFT: return "stat.craftItem";
- case E_TYPE_STAT_ITEM_USE: return "stat.useItem";
- case E_TYPE_STAT_ITEM_BREAK: return "stat.breakItem";
- case E_TYPE_STAT_BLOCK_MINE: return "stat.mineBlock";
- case E_TYPE_STAT_ENTITY_KILL: return "stat.killEntity";
- case E_TYPE_STAT_ENTITY_KILLED_BY: return "stat.entityKilledBy";
+ case otDummy: return "dummy";
+ case otDeathCount: return "deathCount";
+ case otPlayerKillCount: return "playerKillCount";
+ case otTotalKillCount: return "totalKillCount";
+ case otHealth: return "health";
+ case otAchievement: return "achievement";
+ case otStat: return "stat";
+ case otStatItemCraft: return "stat.craftItem";
+ case otStatItemUse: return "stat.useItem";
+ case otStatItemBreak: return "stat.breakItem";
+ case otStatBlockMine: return "stat.mineBlock";
+ case otStatEntityKill: return "stat.killEntity";
+ case otStatEntityKilledBy: return "stat.entityKilledBy";
default: return "";
}
@@ -46,19 +46,19 @@ cObjective::eType cObjective::StringToType(const AString & a_Name)
const char * m_String;
} TypeMap [] =
{
- {E_TYPE_DUMMY, "dummy"},
- {E_TYPE_DEATH_COUNT, "deathCount"},
- {E_TYPE_PLAYER_KILL_COUNT, "playerKillCount"},
- {E_TYPE_TOTAL_KILL_COUNT, "totalKillCount"},
- {E_TYPE_HEALTH, "health"},
- {E_TYPE_ACHIEVEMENT, "achievement"},
- {E_TYPE_STAT, "stat"},
- {E_TYPE_STAT_ITEM_CRAFT, "stat.craftItem"},
- {E_TYPE_STAT_ITEM_USE, "stat.useItem"},
- {E_TYPE_STAT_ITEM_BREAK, "stat.breakItem"},
- {E_TYPE_STAT_BLOCK_MINE, "stat.mineBlock"},
- {E_TYPE_STAT_ENTITY_KILL, "stat.killEntity"},
- {E_TYPE_STAT_ENTITY_KILLED_BY, "stat.entityKilledBy"}
+ {otDummy, "dummy" },
+ {otDeathCount, "deathCount" },
+ {otPlayerKillCount, "playerKillCount" },
+ {otTotalKillCount, "totalKillCount" },
+ {otHealth, "health" },
+ {otAchievement, "achievement" },
+ {otStat, "stat" },
+ {otStatItemCraft, "stat.craftItem" },
+ {otStatItemUse, "stat.useItem" },
+ {otStatItemBreak, "stat.breakItem" },
+ {otStatBlockMine, "stat.mineBlock" },
+ {otStatEntityKill, "stat.killEntity" },
+ {otStatEntityKilledBy, "stat.entityKilledBy"}
};
for (size_t i = 0; i < ARRAYCOUNT(TypeMap); i++)
{
@@ -67,7 +67,7 @@ cObjective::eType cObjective::StringToType(const AString & a_Name)
return TypeMap[i].m_Type;
}
} // for i - TypeMap[]
- return E_TYPE_DUMMY;
+ return otDummy;
}
@@ -246,6 +246,17 @@ void cTeam::Reset(void)
+void cTeam::SetDisplayName(const AString & a_Name)
+{
+ m_DisplayName = a_Name;
+
+ // TODO 2014-03-01 xdot: Update clients
+}
+
+
+
+
+
unsigned int cTeam::GetNumPlayers(void) const
{
return m_Players.size();
@@ -257,7 +268,7 @@ unsigned int cTeam::GetNumPlayers(void) const
cScoreboard::cScoreboard(cWorld * a_World) : m_World(a_World)
{
- for (int i = 0; i < (int) E_DISPLAY_SLOT_COUNT; ++i)
+ for (int i = 0; i < (int) dsCount; ++i)
{
m_Display[i] = NULL;
}
@@ -306,6 +317,8 @@ bool cScoreboard::RemoveObjective(const AString & a_Name)
ASSERT(m_World != NULL);
m_World->BroadcastScoreboardObjective(it->second.GetName(), it->second.GetDisplayName(), 1);
+ // TODO 2014-03-01 xdot: Remove objective from display slot
+
return true;
}
@@ -410,7 +423,7 @@ cTeam * cScoreboard::QueryPlayerTeam(const AString & a_Name)
void cScoreboard::SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot)
{
- ASSERT(a_Slot < E_DISPLAY_SLOT_COUNT);
+ ASSERT(a_Slot < dsCount);
cObjective * Objective = GetObjective(a_Objective);
@@ -435,7 +448,7 @@ void cScoreboard::SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot)
cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot)
{
- ASSERT(a_Slot < E_DISPLAY_SLOT_COUNT);
+ ASSERT(a_Slot < dsCount);
return m_Display[a_Slot];
}
@@ -444,7 +457,7 @@ cObjective * cScoreboard::GetObjectiveIn(eDisplaySlot a_Slot)
-void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback)
+bool cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback)
{
cCSLock Lock(m_CSObjectives);
@@ -455,10 +468,66 @@ void cScoreboard::ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallb
// Call callback
if (a_Callback.Item(&it->second))
{
- return;
+ return false;
}
}
}
+ return true;
+}
+
+
+
+
+
+bool cScoreboard::ForEachObjective(cObjectiveCallback& a_Callback)
+{
+ cCSLock Lock(m_CSObjectives);
+
+ for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it)
+ {
+ // Call callback
+ if (a_Callback.Item(&it->second))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+
+
+bool cScoreboard::ForEachTeam(cTeamCallback& a_Callback)
+{
+ cCSLock Lock(m_CSObjectives);
+
+ for (cTeamMap::iterator it = m_Teams.begin(); it != m_Teams.end(); ++it)
+ {
+ // Call callback
+ if (a_Callback.Item(&it->second))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+
+
+void cScoreboard::AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value)
+{
+ cCSLock Lock(m_CSObjectives);
+
+ for (cObjectiveMap::iterator it = m_Objectives.begin(); it != m_Objectives.end(); ++it)
+ {
+ if (it->second.GetType() == a_Type)
+ {
+ it->second.AddScore(a_Name, a_Value);
+ }
+ }
}
@@ -474,7 +543,7 @@ void cScoreboard::SendTo(cClientHandle & a_Client)
it->second.SendTo(a_Client);
}
- for (int i = 0; i < (int) E_DISPLAY_SLOT_COUNT; ++i)
+ for (int i = 0; i < (int) dsCount; ++i)
{
// Avoid race conditions
cObjective * Objective = m_Display[i];
diff --git a/src/Scoreboard.h b/src/Scoreboard.h
index f64ba2bce..e22ecaeb1 100644
--- a/src/Scoreboard.h
+++ b/src/Scoreboard.h
@@ -14,9 +14,11 @@
class cObjective;
+class cTeam;
class cWorld;
typedef cItemCallback<cObjective> cObjectiveCallback;
+typedef cItemCallback<cTeam> cTeamCallback;
@@ -31,23 +33,23 @@ public:
enum eType
{
- E_TYPE_DUMMY,
+ otDummy,
- E_TYPE_DEATH_COUNT,
- E_TYPE_PLAYER_KILL_COUNT,
- E_TYPE_TOTAL_KILL_COUNT,
- E_TYPE_HEALTH,
+ otDeathCount,
+ otPlayerKillCount,
+ otTotalKillCount,
+ otHealth,
- E_TYPE_ACHIEVEMENT,
+ otAchievement,
- E_TYPE_STAT,
- E_TYPE_STAT_ITEM_CRAFT,
- E_TYPE_STAT_ITEM_USE,
- E_TYPE_STAT_ITEM_BREAK,
+ otStat,
+ otStatItemCraft,
+ otStatItemUse,
+ otStatItemBreak,
- E_TYPE_STAT_BLOCK_MINE,
- E_TYPE_STAT_ENTITY_KILL,
- E_TYPE_STAT_ENTITY_KILLED_BY
+ otStatBlockMine,
+ otStatEntityKill,
+ otStatEntityKilledBy
};
// tolua_end
@@ -67,31 +69,37 @@ public:
const AString & GetName(void) const { return m_Name; }
const AString & GetDisplayName(void) const { return m_DisplayName; }
- /// Resets the objective
+ /** Resets the objective */
void Reset(void);
- /// Returns the score of the specified player
+ /** Returns the score of the specified player */
Score GetScore(const AString & a_Name) const;
- /// Sets the score of the specified player
+ /** Sets the score of the specified player */
void SetScore(const AString & a_Name, Score a_Score);
- /// Resets the score of the specified player
+ /** Resets the score of the specified player */
void ResetScore(const AString & a_Name);
- /// Adds a_Delta and returns the new score
+ /** Adds a_Delta and returns the new score */
Score AddScore(const AString & a_Name, Score a_Delta);
- /// Subtracts a_Delta and returns the new score
+ /** Subtracts a_Delta and returns the new score */
Score SubScore(const AString & a_Name, Score a_Delta);
void SetDisplayName(const AString & a_Name);
// tolua_end
- /// Send this objective to the specified client
+ /** Send this objective to the specified client */
void SendTo(cClientHandle & a_Client);
+ static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates
+ {
+ return "cObjective";
+ }
+
+
private:
typedef std::pair<AString, Score> cTrackedPlayer;
@@ -109,7 +117,8 @@ private:
friend class cScoreboardSerializer;
-};
+
+}; // tolua_export
@@ -127,21 +136,21 @@ public:
const AString & a_Prefix, const AString & a_Suffix
);
- /// Adds a new player to the team
+ // tolua_begin
+
+ /** Adds a new player to the team */
bool AddPlayer(const AString & a_Name);
- /// Removes a player from the team
+ /** Removes a player from the team */
bool RemovePlayer(const AString & a_Name);
- /// Returns whether the specified player is in this team
+ /** Returns whether the specified player is in this team */
bool HasPlayer(const AString & a_Name) const;
- /// Removes all registered players
+ /** Removes all registered players */
void Reset(void);
- // tolua_begin
-
- /// Returns the number of registered players
+ /** Returns the number of registered players */
unsigned int GetNumPlayers(void) const;
bool AllowsFriendlyFire(void) const { return m_AllowsFriendlyFire; }
@@ -163,6 +172,11 @@ public:
// tolua_end
+ static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates
+ {
+ return "cTeam";
+ }
+
private:
typedef std::set<AString> cPlayerNameSet;
@@ -180,7 +194,8 @@ private:
friend class cScoreboardSerializer;
-};
+
+}; // tolua_export
@@ -193,11 +208,11 @@ public:
enum eDisplaySlot
{
- E_DISPLAY_SLOT_LIST = 0,
- E_DISPLAY_SLOT_SIDEBAR,
- E_DISPLAY_SLOT_NAME,
+ dsList = 0,
+ dsSidebar,
+ dsName,
- E_DISPLAY_SLOT_COUNT
+ dsCount
};
// tolua_end
@@ -209,44 +224,61 @@ public:
// tolua_begin
- /// Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision
+ /** Registers a new scoreboard objective, returns the cObjective instance, NULL on name collision */
cObjective * RegisterObjective(const AString & a_Name, const AString & a_DisplayName, cObjective::eType a_Type);
- /// Removes a registered objective, returns true if operation was successful
+ /** Removes a registered objective, returns true if operation was successful */
bool RemoveObjective(const AString & a_Name);
- /// Retrieves the objective with the specified name, NULL if not found
+ /** Retrieves the objective with the specified name, NULL if not found */
cObjective * GetObjective(const AString & a_Name);
- /// Registers a new team, returns the cTeam instance, NULL on name collision
+ /** Registers a new team, returns the cTeam instance, NULL on name collision */
cTeam * RegisterTeam(const AString & a_Name, const AString & a_DisplayName, const AString & a_Prefix, const AString & a_Suffix);
- /// Removes a registered team, returns true if operation was successful
+ /** Removes a registered team, returns true if operation was successful */
bool RemoveTeam(const AString & a_Name);
- /// Retrieves the team with the specified name, NULL if not found
+ /** Retrieves the team with the specified name, NULL if not found */
cTeam * GetTeam(const AString & a_Name);
- cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn)
-
void SetDisplay(const AString & a_Objective, eDisplaySlot a_Slot);
- void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot);
-
cObjective * GetObjectiveIn(eDisplaySlot a_Slot);
- /// Execute callback for each objective with the specified type
- void ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback);
-
unsigned int GetNumObjectives(void) const;
unsigned int GetNumTeams(void) const;
+ void AddPlayerScore(const AString & a_Name, cObjective::eType a_Type, cObjective::Score a_Value = 1);
+
// tolua_end
- /// Send this scoreboard to the specified client
+ /** Send this scoreboard to the specified client */
void SendTo(cClientHandle & a_Client);
+ cTeam * QueryPlayerTeam(const AString & a_Name); // WARNING: O(n logn)
+
+ /** Execute callback for each objective with the specified type
+ *
+ * Returns true if all objectives processed, false if the callback aborted by returning true.
+ */
+ bool ForEachObjectiveWith(cObjective::eType a_Type, cObjectiveCallback& a_Callback);
+
+ /** Execute callback for each objective.
+ *
+ * Returns true if all objectives have been processed, false if the callback aborted by returning true.
+ */
+ bool ForEachObjective(cObjectiveCallback& a_Callback); // Exported in ManualBindings.cpp
+
+ /** Execute callback for each team.
+ *
+ * Returns true if all teams have been processed, false if the callback aborted by returning true.
+ */
+ bool ForEachTeam(cTeamCallback& a_Callback); // Exported in ManualBindings.cpp
+
+ void SetDisplay(cObjective * a_Objective, eDisplaySlot a_Slot);
+
private:
@@ -265,11 +297,12 @@ private:
cWorld * m_World;
- cObjective* m_Display[E_DISPLAY_SLOT_COUNT];
+ cObjective * m_Display[dsCount];
friend class cScoreboardSerializer;
-} ;
+
+}; // tolua_export
diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp
index 9b8b661c4..6c885bb45 100644
--- a/src/WorldStorage/ScoreboardSerializer.cpp
+++ b/src/WorldStorage/ScoreboardSerializer.cpp
@@ -173,13 +173,13 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
a_Writer.BeginCompound("DisplaySlots");
- cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_LIST);
+ cObjective * Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsList);
a_Writer.AddString("slot_0", (Objective == NULL) ? "" : Objective->GetName());
- Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_SIDEBAR);
+ Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsSidebar);
a_Writer.AddString("slot_1", (Objective == NULL) ? "" : Objective->GetName());
- Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_NAME);
+ Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsName);
a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName());
a_Writer.EndCompound(); // DisplaySlots
@@ -280,7 +280,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
{
AString Name, DisplayName, Prefix, Suffix;
- bool AllowsFriendlyFire = false, CanSeeFriendlyInvisible = false;
+ bool AllowsFriendlyFire = true, CanSeeFriendlyInvisible = false;
int CurrLine = a_NBT.FindChildByName(Child, "Name");
if (CurrLine >= 0)
@@ -346,7 +346,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
{
AString Name = a_NBT.GetString(CurrLine);
- m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_LIST);
+ m_ScoreBoard->SetDisplay(Name, cScoreboard::dsList);
}
CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_1");
@@ -354,7 +354,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
{
AString Name = a_NBT.GetString(CurrLine);
- m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_SIDEBAR);
+ m_ScoreBoard->SetDisplay(Name, cScoreboard::dsSidebar);
}
CurrLine = a_NBT.FindChildByName(DisplaySlots, "slot_2");
@@ -362,7 +362,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
{
AString Name = a_NBT.GetString(CurrLine);
- m_ScoreBoard->SetDisplay(Name, cScoreboard::E_DISPLAY_SLOT_NAME);
+ m_ScoreBoard->SetDisplay(Name, cScoreboard::dsName);
}
return true;