summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/account-server/accounthandler.cpp24
-rw-r--r--src/account-server/serverhandler.cpp1
-rw-r--r--src/game-server/character.cpp24
3 files changed, 41 insertions, 8 deletions
diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp
index af04119a..99faad62 100644
--- a/src/account-server/accounthandler.cpp
+++ b/src/account-server/accounthandler.cpp
@@ -35,6 +35,7 @@
#include "net/messagein.hpp"
#include "net/messageout.hpp"
#include "net/netcomputer.hpp"
+#include "utils/functors.h"
#include "utils/logger.h"
#include "utils/stringfilter.h"
#include "utils/tokencollector.hpp"
@@ -54,6 +55,15 @@ static void addUpdateHost(MessageOut *msg)
static std::vector< unsigned int > initAttr;
+/*
+ * Map attribute ids to values that they need to be initialised to at account
+ * creation.
+ * The pair contains two elements of the same value (the default) so that the
+ * iterators can be used to copy a range.
+ */
+
+static std::map< unsigned int, std::pair< double, double> > defAttr;
+
class AccountHandler : public ConnectionHandler
{
public:
@@ -145,8 +155,19 @@ AccountHandler::AccountHandler(const std::string &attrFile):
}
for_each_xml_child_node(attributenode, node)
if (xmlStrEqual(attributenode->name, BAD_CAST "stat"))
+ {
+ unsigned int id = XML::getProperty(attributenode, "id", 0);
+ if (!id) continue;
if (utils::toupper(XML::getProperty(attributenode, "modifiable", "false")) == "TRUE")
- initAttr.push_back(XML::getProperty(attributenode, "id", 0)); // id
+ initAttr.push_back(id);
+ // Store as string initially to check that the property is defined.
+ std::string defStr = XML::getProperty(attributenode, "default", "");
+ if (!defStr.empty())
+ {
+ double val = string_to<double>()(defStr);
+ defAttr.insert(std::make_pair(id, std::make_pair(val, val)));
+ }
+ }
}
}
@@ -691,6 +712,7 @@ void AccountHandler::handleCharacterCreateMessage(AccountClient &client, Message
(unsigned int) (initAttr.at(i)),
std::make_pair((double) (attributes[i]),
(double) (attributes[i]))));
+ newCharacter->mAttributes.insert(defAttr.begin(), defAttr.end());
newCharacter->setAccount(acc);
newCharacter->setLevel(1);
newCharacter->setCharacterPoints(0);
diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp
index 106f582e..c68cb623 100644
--- a/src/account-server/serverhandler.cpp
+++ b/src/account-server/serverhandler.cpp
@@ -116,6 +116,7 @@ NetComputer *ServerHandler::computerConnected(ENetPeer *peer)
void ServerHandler::computerDisconnected(NetComputer *comp)
{
+ LOG_INFO("Game-server disconnected.");
delete comp;
}
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index e24871c2..ae1ba37e 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -345,6 +345,7 @@ void Character::sendStatus()
void Character::modifiedAllAttribute()
{
+ LOG_DEBUG("Marking all attributes as changed, requiring recalculation.");
for (AttributeMap::iterator it = mAttributes.begin(),
it_end = mAttributes.end();
it != it_end; ++it)
@@ -356,25 +357,29 @@ void Character::modifiedAttribute(unsigned int attr)
// Much of this is remnants from the previous attribute system (placeholder?)
// This could be improved by defining what attributes are derived from others
// in xml or otherwise, so only those that need to be recomputed are.
+ LOG_DEBUG("Received modified attribute recalculation request for "
+ << attr << ".");
if (!mAttributes.count(attr)) return;
double newBase = getAttribute(attr);
+ std::set< unsigned int > deps;
+
switch (attr) {
case ATTR_STR:
- modifiedAttribute(ATTR_INV_CAPACITY);
+ deps.insert(ATTR_INV_CAPACITY);
break;
case ATTR_AGI:
- modifiedAttribute(ATTR_DODGE);
+ deps.insert(ATTR_DODGE);
break;
case ATTR_VIT:
- modifiedAttribute(ATTR_MAX_HP);
- modifiedAttribute(ATTR_HP_REGEN);
- modifiedAttribute(ATTR_DEFENSE);
+ deps.insert(ATTR_MAX_HP);
+ deps.insert(ATTR_HP_REGEN);
+ deps.insert(ATTR_DEFENSE);
break;
case ATTR_INT:
break;
case ATTR_DEX:
- modifiedAttribute(ATTR_ACCURACY);
+ deps.insert(ATTR_ACCURACY);
break;
case ATTR_WIL:
break;
@@ -410,7 +415,7 @@ void Character::modifiedAttribute(unsigned int attr)
break;
case ATTR_MOVE_SPEED_TPS:
newBase = 3.0 + getModifiedAttribute(ATTR_AGI) * 0.08; // Provisional.
- modifiedAttribute(ATTR_MOVE_SPEED_RAW);
+ deps.insert(ATTR_MOVE_SPEED_RAW);
break;
case ATTR_MOVE_SPEED_RAW:
newBase = utils::tpsToSpeed(getModifiedAttribute(ATTR_MOVE_SPEED_TPS));
@@ -423,7 +428,12 @@ void Character::modifiedAttribute(unsigned int attr)
if (newBase != getAttribute(attr))
Being::setAttribute(attr, newBase, false);
+ else
+ LOG_DEBUG("No changes to sync.");
flagAttribute(attr);
+ for (std::set<unsigned int>::const_iterator it = deps.begin(),
+ it_end = deps.end(); it != it_end; ++it)
+ modifiedAttribute(*it);
}
void Character::flagAttribute(int attr)