diff --git a/dGame/dComponents/CharacterComponent.cpp b/dGame/dComponents/CharacterComponent.cpp
index 3daa437e..590758b6 100644
--- a/dGame/dComponents/CharacterComponent.cpp
+++ b/dGame/dComponents/CharacterComponent.cpp
@@ -32,6 +32,7 @@ CharacterComponent::CharacterComponent(Entity* parent, Character* character) : C
m_EditorEnabled = false;
m_EditorLevel = m_GMLevel;
+ m_Reputation = 0;
m_CurrentActivity = 0;
m_CountryCode = 0;
@@ -256,7 +257,10 @@ void CharacterComponent::LoadFromXML() {
Game::logger->Log("CharacterComponent", "Failed to find char tag while loading XML!\n");
return;
}
-
+ if (character->QueryAttribute("rpt", &m_Reputation) == tinyxml2::XML_NO_ATTRIBUTE) {
+ SetReputation(0);
+ }
+
character->QueryInt64Attribute("ls", &m_Uscore);
// Load the statistics
@@ -378,6 +382,8 @@ void CharacterComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
}
character->SetAttribute("ls", m_Uscore);
+ // Custom attribute to keep track of reputation.
+ character->SetAttribute("rpt", GetReputation());
character->SetAttribute("stt", StatisticsToString().c_str());
// Set the zone statistics of the form ...
diff --git a/dGame/dComponents/CharacterComponent.h b/dGame/dComponents/CharacterComponent.h
index 62076fad..04245bf9 100644
--- a/dGame/dComponents/CharacterComponent.h
+++ b/dGame/dComponents/CharacterComponent.h
@@ -146,6 +146,18 @@ public:
*/
bool GetPvpEnabled() const;
+ /**
+ * Returns the characters lifetime reputation
+ * @return The lifetime reputation of this character.
+ */
+ int64_t GetReputation() { return m_Reputation; };
+
+ /**
+ * Sets the lifetime reputation of the character to newValue
+ * @param newValue the value to set reputation to
+ */
+ void SetReputation(int64_t newValue) { m_Reputation = newValue; };
+
/**
* Sets the current value of PvP combat being enabled
* @param value whether to enable PvP combat
@@ -291,6 +303,11 @@ private:
*/
int64_t m_Uscore;
+ /**
+ * The lifetime reputation earned by the entity
+ */
+ int64_t m_Reputation;
+
/**
* Whether the character is landing by rocket
*/
diff --git a/dGame/dMission/Mission.cpp b/dGame/dMission/Mission.cpp
index 748bebd4..f7b57071 100644
--- a/dGame/dMission/Mission.cpp
+++ b/dGame/dMission/Mission.cpp
@@ -518,24 +518,11 @@ void Mission::YieldRewards() {
if (info->reward_reputation > 0) {
missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_EARN_REPUTATION, 0, 0L, "", info->reward_reputation);
- auto character = entity->GetCharacter();
- if (!character) return;
-
- auto charId = character->GetID();
- auto propertyCloneId = character->GetPropertyCloneID();
-
- auto reputationUpdate = Database::CreatePreppedStmt("UPDATE properties SET reputation = reputation + ? where owner_id = ? AND clone_id = ?");
-
- reputationUpdate->setInt64(1, info->reward_reputation);
- reputationUpdate->setInt(2, charId);
- reputationUpdate->setInt64(3, propertyCloneId);
-
- reputationUpdate->executeUpdate();
-
- delete reputationUpdate;
- reputationUpdate = nullptr;
-
- GameMessages::SendUpdateReputation(entity->GetObjectID(), info->reward_reputation, entity->GetSystemAddress());
+ auto character = entity->GetComponent();
+ if (character) {
+ character->SetReputation(character->GetReputation() + info->reward_reputation);
+ GameMessages::SendUpdateReputation(entity->GetObjectID(), character->GetReputation(), entity->GetSystemAddress());
+ }
}
if (info->reward_maxhealth > 0) {
diff --git a/dNet/WorldPackets.cpp b/dNet/WorldPackets.cpp
index 399ab9e5..ae8f71a4 100644
--- a/dNet/WorldPackets.cpp
+++ b/dNet/WorldPackets.cpp
@@ -12,6 +12,7 @@
#include "LDFFormat.h"
#include "dServer.h"
#include "dZoneManager.h"
+#include "CharacterComponent.h"
#include "ZCompression.h"
void WorldPackets::SendLoadStaticZone(const SystemAddress& sysAddr, float x, float y, float z, uint32_t checksum) {
@@ -126,26 +127,34 @@ void WorldPackets::SendServerState ( const SystemAddress& sysAddr ) {
SEND_PACKET
}
-void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, const LWOOBJID& objectID, const std::string& xmlData, const std::u16string& username, int32_t gm) {
+void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm) {
RakNet::BitStream bitStream;
PacketUtils::WriteHeader(bitStream, CLIENT, MSG_CLIENT_CREATE_CHARACTER);
RakNet::BitStream data;
- data.Write(6); //LDF key count
+ data.Write(7); //LDF key count
- LDFData* objid = new LDFData(u"objid", objectID);
+ auto character = entity->GetComponent();
+ if (!character) {
+ Game::logger->Log("WorldPackets", "Entity is not a character?? what??");
+ return;
+ }
+
+ LDFData* objid = new LDFData(u"objid", entity->GetObjectID());
LDFData* lot = new LDFData(u"template", 1);
LDFData * xmlConfigData = new LDFData(u"xmlData", xmlData);
LDFData* name = new LDFData(u"name", username);
LDFData* gmlevel = new LDFData(u"gmlevel", gm);
LDFData* chatmode = new LDFData(u"chatmode", gm);
-
+ LDFData* reputation = new LDFData(u"reputation", character->GetReputation());
+
objid->WriteToPacket(&data);
lot->WriteToPacket(&data);
name->WriteToPacket(&data);
gmlevel->WriteToPacket(&data);
chatmode->WriteToPacket(&data);
xmlConfigData->WriteToPacket(&data);
+ reputation->WriteToPacket(&data);
delete objid;
delete lot;
@@ -153,7 +162,8 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, const LWOOB
delete gmlevel;
delete chatmode;
delete name;
-
+ delete reputation;
+
#ifdef _WIN32
bitStream.Write(data.GetNumberOfBytesUsed() + 1);
bitStream.Write(0);
@@ -175,7 +185,7 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, const LWOOB
PacketUtils::SavePacket("chardata.bin", (const char *)bitStream.GetData(), static_cast(bitStream.GetNumberOfBytesUsed()));
SEND_PACKET
- Game::logger->Log("WorldPackets", "Sent CreateCharacter for ID: %llu\n", objectID);
+ Game::logger->Log("WorldPackets", "Sent CreateCharacter for ID: %llu\n", entity->GetObjectID());
}
void WorldPackets::SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::unordered_map unacceptedItems) {
diff --git a/dNet/WorldPackets.h b/dNet/WorldPackets.h
index ff51a7f6..3508d6f0 100644
--- a/dNet/WorldPackets.h
+++ b/dNet/WorldPackets.h
@@ -4,6 +4,7 @@
#include "dCommonVars.h"
#include
#include
+#include "Entity.h"
class User;
struct SystemAddress;
@@ -16,7 +17,7 @@ namespace WorldPackets {
void SendCharacterDeleteResponse(const SystemAddress& sysAddr, bool response);
void SendTransferToWorld(const SystemAddress& sysAddr, const std::string& serverIP, uint32_t serverPort, bool mythranShift);
void SendServerState(const SystemAddress& sysAddr);
- void SendCreateCharacter(const SystemAddress& sysAddr, const LWOOBJID& objectID, const std::string& xmlData, const std::u16string& username, int32_t gm);
+ void SendCreateCharacter(const SystemAddress& sysAddr, Entity* entity, const std::string& xmlData, const std::u16string& username, int32_t gm);
void SendChatModerationResponse(const SystemAddress& sysAddr, bool requestAccepted, uint32_t requestID, const std::string& receiver, std::unordered_map unacceptedItems);
void SendGMLevelChange(const SystemAddress& sysAddr, bool success, uint8_t highestLevel, uint8_t prevLevel, uint8_t newLevel);
}
diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp
index c9b6b00b..c8f2641e 100644
--- a/dWorldServer/WorldServer.cpp
+++ b/dWorldServer/WorldServer.cpp
@@ -1013,15 +1013,15 @@ void HandlePacket(Packet* packet) {
Character* c = user->GetLastUsedChar();
if (c != nullptr) {
std::u16string username = GeneralUtils::ASCIIToUTF16(c->GetName());
- WorldPackets::SendCreateCharacter(packet->systemAddress, c->GetObjectID(), c->GetXMLData(), username, c->GetGMLevel());
- WorldPackets::SendServerState(packet->systemAddress);
-
Game::server->GetReplicaManager()->AddParticipant(packet->systemAddress);
EntityInfo info {};
info.lot = 1;
Entity* player = EntityManager::Instance()->CreateEntity(info, UserManager::Instance()->GetUser(packet->systemAddress));
+ WorldPackets::SendCreateCharacter(packet->systemAddress, player, c->GetXMLData(), username, c->GetGMLevel());
+ WorldPackets::SendServerState(packet->systemAddress);
+
const auto respawnPoint = player->GetCharacter()->GetRespawnPoint(dZoneManager::Instance()->GetZone()->GetWorldID());
EntityManager::Instance()->ConstructEntity(player, UNASSIGNED_SYSTEM_ADDRESS, true);