summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gui/status.cpp161
-rw-r--r--src/gui/status.h22
-rw-r--r--src/gui/statuswindow.cpp101
-rw-r--r--src/gui/statuswindow.h9
-rw-r--r--src/localplayer.cpp16
-rw-r--r--src/localplayer.h17
-rw-r--r--src/net/ea/charserverhandler.cpp2
-rw-r--r--src/net/ea/generalhandler.cpp15
-rw-r--r--src/net/ea/playerhandler.cpp229
-rw-r--r--src/net/ea/protocol.h24
-rw-r--r--src/net/tmwserv/generalhandler.cpp8
11 files changed, 281 insertions, 323 deletions
diff --git a/src/gui/status.cpp b/src/gui/status.cpp
index 497eef79..02f3de4e 100644
--- a/src/gui/status.cpp
+++ b/src/gui/status.cpp
@@ -32,7 +32,8 @@
#include "gui/widgets/windowcontainer.h"
#include "net/net.h"
-#include "net/ea/playerhandler.h"
+#include "net/playerhandler.h"
+#include "net/ea/protocol.h"
#include "utils/gettext.h"
#include "utils/mathutils.h"
@@ -79,29 +80,38 @@ StatusWindow::StatusWindow():
mStatsTotalLabel->setAlignment(gcn::Graphics::CENTER);
// Derived Stats
- mStatsAttackLabel = new Label(_("Attack:"));
- mStatsDefenseLabel= new Label(_("Defense:"));
- mStatsMagicAttackLabel = new Label(_("M.Attack:"));
- mStatsMagicDefenseLabel = new Label(_("M.Defense:"));
- // Gettext flag for next line: xgettext:no-c-format
- mStatsAccuracyLabel = new Label(_("% Accuracy:"));
- // Gettext flag for next line: xgettext:no-c-format
- mStatsEvadeLabel = new Label(_("% Evade:"));
- // Gettext flag for next line: xgettext:no-c-format
- mStatsReflexLabel = new Label(_("% Reflex:"));
-
- mStatsAttackPoints = new Label;
- mStatsDefensePoints = new Label;
- mStatsMagicAttackPoints = new Label;
- mStatsMagicDefensePoints = new Label;
- mStatsAccuracyPoints = new Label;
- mStatsEvadePoints = new Label;
- mStatsReflexPoints = new Label;
-
- // New labels
+ static const char *dAttrNames[7] = {
+ _("Attack"),
+ _("Defense"),
+ _("M.Attack"),
+ _("M.Defense"),
+ // Gettext flag for next line: xgettext:no-c-format
+ _("% Accuracy"),
+ // Gettext flag for next line: xgettext:no-c-format
+ _("% Evade"),
+ // Gettext flag for next line: xgettext:no-c-format
+ _("% Crit Chance")
+ };
+
+ for (int i = 0; i < 7; i++)
+ {
+ mDStatsLabel[i] = new Label(dAttrNames[i]);
+ mDPointsLabel[i] = new Label;
+ }
+
+ // Stats labels
+ static const char *attrNames[6] = {
+ _("Strength"),
+ _("Agility"),
+ _("Vitality"),
+ _("Intelligence"),
+ _("Dexterity"),
+ _("Luck")
+ };
+
for (int i = 0; i < 6; i++)
{
- mStatsLabel[i] = new Label("0");
+ mStatsLabel[i] = new Label(attrNames[i]);
mStatsLabel[i]->setAlignment(gcn::Graphics::CENTER);
mStatsDisplayLabel[i] = new Label;
mPointsLabel[i] = new Label("0");
@@ -144,26 +154,19 @@ StatusWindow::StatusWindow():
place(10, 2 + i, mStatsButton[i]);
place(12, 2 + i, mPointsLabel[i]).setPadding(5);
}
- place(14, 2, mStatsAttackLabel, 7).setPadding(5);
- place(14, 3, mStatsDefenseLabel, 7).setPadding(5);
- place(14, 4, mStatsMagicAttackLabel, 7).setPadding(5);
- place(14, 5, mStatsMagicDefenseLabel, 7).setPadding(5);
- place(14, 6, mStatsAccuracyLabel, 7).setPadding(5);
- place(14, 7, mStatsEvadeLabel, 7).setPadding(5);
- place(14, 8, mStatsReflexLabel, 7).setPadding(5);
- place(21, 2, mStatsAttackPoints, 3).setPadding(5);
- place(21, 3, mStatsDefensePoints, 3).setPadding(5);
- place(21, 4, mStatsMagicAttackPoints, 3).setPadding(5);
- place(21, 5, mStatsMagicDefensePoints, 3).setPadding(5);
- place(21, 6, mStatsAccuracyPoints, 3).setPadding(5);
- place(21, 7, mStatsEvadePoints, 3).setPadding(5);
- place(21, 8, mStatsReflexPoints, 3).setPadding(5);
+ for (int i = 0; i < 7; i++)
+ {
+ place(14, 2 + i, mDStatsLabel[i], 7).setPadding(5);
+ place(21, 2 + i, mDPointsLabel[i], 3).setPadding(5);
+ }
+
place(0, 8, mRemainingStatsPointsLabel, 3).setPadding(5);
Layout &layout = getLayout();
layout.setRowHeight(0, Layout::AUTO_SET);
loadWindowState();
+ update();
}
void StatusWindow::update()
@@ -193,73 +196,41 @@ void StatusWindow::update()
// Stats Part
// ----------
- static const char *attrNames[6] = {
- N_("Strength"),
- N_("Agility"),
- N_("Vitality"),
- N_("Intelligence"),
- N_("Dexterity"),
- N_("Luck")
- };
int statusPoints = player_node->getCharacterPoints();
// Update labels
for (int i = 0; i < 6; i++)
{
- mStatsLabel[i]->setCaption(gettext(attrNames[i]));
- mStatsDisplayLabel[i]->setCaption(toString((int) player_node->mAttr[i]));
- mPointsLabel[i]->setCaption(toString((int) player_node->mAttrUp[i]));
+ int base = player_node->getAttributeBase(i + STR);
+ int bonus = player_node->getAttributeEffective(i + STR) - base;
+ std::string value = toString(base);
+ if (bonus)
+ value += strprintf(" (%+d)", bonus);
+ mStatsDisplayLabel[i]->setCaption(value);
+ mPointsLabel[i]->setCaption(toString(player_node->
+ getAttributeBase(i + STR_U)));
- mStatsLabel[i]->adjustSize();
mStatsDisplayLabel[i]->adjustSize();
mPointsLabel[i]->adjustSize();
- mStatsButton[i]->setEnabled(player_node->mAttrUp[i] <= statusPoints);
+ mStatsButton[i]->setEnabled(player_node->getAttributeBase(i + STR_U)
+ <= statusPoints);
}
mRemainingStatsPointsLabel->setCaption(
strprintf(_("Remaining Status Points: %d"), statusPoints));
mRemainingStatsPointsLabel->adjustSize();
// Derived Stats Points
-
- // Attack TODO: Count equipped Weapons and items attack bonuses
- mStatsAttackPoints->setCaption(
- toString(player_node->ATK + player_node->ATK_BONUS));
- mStatsAttackPoints->adjustSize();
-
- // Defense TODO: Count equipped Armors and items defense bonuses
- mStatsDefensePoints->setCaption(
- toString(player_node->DEF + player_node->DEF_BONUS));
- mStatsDefensePoints->adjustSize();
-
- // Magic Attack TODO: Count equipped items M.Attack bonuses
- mStatsMagicAttackPoints->setCaption(
- toString(player_node->MATK + player_node->MATK_BONUS));
- mStatsMagicAttackPoints->adjustSize();
-
- // Magic Defense TODO: Count equipped items M.Defense bonuses
- mStatsMagicDefensePoints->setCaption(
- toString(player_node->MDEF + player_node->MDEF_BONUS));
- mStatsMagicDefensePoints->adjustSize();
-
- // Accuracy %
- mStatsAccuracyPoints->setCaption(toString(player_node->HIT));
- mStatsAccuracyPoints->adjustSize();
-
- // Evasion %
- mStatsEvadePoints->setCaption(toString(player_node->FLEE));
- mStatsEvadePoints->adjustSize();
-
- // Reflex %
- mStatsReflexPoints->setCaption(toString(player_node->DEX / 4)); // + counter
- mStatsReflexPoints->adjustSize();
-}
-
-void StatusWindow::draw(gcn::Graphics *g)
-{
- update();
-
- Window::draw(g);
+ for (int i = 0; i < 7; i++)
+ {
+ int base = player_node->getAttributeBase(i + ATK);
+ int bonus = player_node->getAttributeEffective(i + ATK) - base;
+ std::string value = toString(base);
+ if (bonus)
+ value += strprintf(" (%+d)", bonus);
+ mDPointsLabel[i]->setCaption(value);
+ mDPointsLabel[i]->adjustSize();
+ }
}
void StatusWindow::action(const gcn::ActionEvent &event)
@@ -269,17 +240,17 @@ void StatusWindow::action(const gcn::ActionEvent &event)
if (event.getId().length() == 3)
{
if (event.getId() == "STR")
- Net::getPlayerHandler()->increaseAttribute(LocalPlayer::STR);
+ Net::getPlayerHandler()->increaseAttribute(STR);
if (event.getId() == "AGI")
- Net::getPlayerHandler()->increaseAttribute(LocalPlayer::AGI);
+ Net::getPlayerHandler()->increaseAttribute(AGI);
if (event.getId() == "VIT")
- Net::getPlayerHandler()->increaseAttribute(LocalPlayer::VIT);
+ Net::getPlayerHandler()->increaseAttribute(VIT);
if (event.getId() == "INT")
- Net::getPlayerHandler()->increaseAttribute(LocalPlayer::INT);
+ Net::getPlayerHandler()->increaseAttribute(INT);
if (event.getId() == "DEX")
- Net::getPlayerHandler()->increaseAttribute(LocalPlayer::DEX);
+ Net::getPlayerHandler()->increaseAttribute(DEX);
if (event.getId() == "LUK")
- Net::getPlayerHandler()->increaseAttribute(LocalPlayer::LUK);
+ Net::getPlayerHandler()->increaseAttribute(LUK);
}
}
@@ -367,7 +338,7 @@ void StatusWindow::updateMPBar(ProgressBar *bar, bool showMax)
else
bar->setText(toString(player_node->mMp));
- if (player_node->MATK <= 0)
+ if (player_node->getAttributeEffective(MATK) <= 0)
bar->setColor(100, 100, 100); // grey, to indicate that we lack magic
else
bar->setColor(26, 102, 230); // blue, to indicate that we have magic
diff --git a/src/gui/status.h b/src/gui/status.h
index 3e5df917..6e8371c2 100644
--- a/src/gui/status.h
+++ b/src/gui/status.h
@@ -48,15 +48,16 @@ class StatusWindow : public Window, public gcn::ActionListener
void action(const gcn::ActionEvent &event);
/**
- * Draw this window
- */
- void draw(gcn::Graphics *graphics);
-
- /**
* Updates this dialog with values from PLAYER_INFO *char_info
*/
void update();
+ // TODO: only update what changed
+ std::string update(int id) { update(); return ""; }
+
+ // future use
+ void addAttribute(int id, const std::string &name, bool modifiable) {}
+
static void updateHPBar(ProgressBar *bar, bool showMax = false);
static void updateMPBar(ProgressBar *bar, bool showMax = false);
static void updateXPBar(ProgressBar *bar, bool percent = true);
@@ -76,15 +77,8 @@ class StatusWindow : public Window, public gcn::ActionListener
/**
* Derived Statistics captions
*/
- gcn::Label *mStatsAttackLabel, *mStatsDefenseLabel;
- gcn::Label *mStatsMagicAttackLabel, *mStatsMagicDefenseLabel;
- gcn::Label *mStatsAccuracyLabel, *mStatsEvadeLabel;
- gcn::Label *mStatsReflexLabel;
-
- gcn::Label *mStatsAttackPoints, *mStatsDefensePoints;
- gcn::Label *mStatsMagicAttackPoints, *mStatsMagicDefensePoints;
- gcn::Label *mStatsAccuracyPoints, *mStatsEvadePoints;
- gcn::Label *mStatsReflexPoints;
+ gcn::Label *mDStatsLabel[7];
+ gcn::Label *mDPointsLabel[7];
/**
* Stats captions.
diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp
index 5f29e5a5..e8706a82 100644
--- a/src/gui/statuswindow.cpp
+++ b/src/gui/statuswindow.cpp
@@ -85,24 +85,6 @@ StatusWindow::StatusWindow():
gcn::Label *mStatsTitleLabel = new Label("Stats");
gcn::Label *mStatsTotalLabel = new Label("Total");
- // Derived Stats
-/*
- mStatsAttackLabel = new Label("Attack:");
- mStatsDefenseLabel= new Label("Defense:");
- mStatsMagicAttackLabel = new Label("M.Attack:");
- mStatsMagicDefenseLabel = new Label("M.Defense:");
- mStatsAccuracyLabel = new Label("% Accuracy:");
- mStatsEvadeLabel = new Label("% Evade:");
- mStatsReflexLabel = new Label("% Reflex:");
-
- mStatsAttackPoints = new Label;
- mStatsDefensePoints = new Label;
- mStatsMagicAttackPoints = new Label;
- mStatsMagicDefensePoints = new Label;
- mStatsAccuracyPoints = new Label("% Accuracy:");
- mStatsEvadePoints = new Label("% Evade:");
- mStatsReflexPoints = new Label("% Reflex:");
-*/
// New labels
for (int i = 0; i < 6; i++) {
mStatsLabel[i] = new Label;
@@ -126,8 +108,6 @@ StatusWindow::StatusWindow():
mStatsMinus[4] = new Button("-", "INT-", this);
mStatsMinus[5] = new Button("-", "WIL-", this);
-
-
// Set position
mStatsTitleLabel->setPosition(mHpLabel->getX(), mHpLabel->getY() + 23 );
mStatsTotalLabel->setPosition(110, mStatsTitleLabel->getY() + 15);
@@ -145,23 +125,7 @@ StatusWindow::StatusWindow():
mCharacterPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 25);
mCorrectionPointsLabel->setPosition(5, mStatsDisplayLabel[5]->getY() + 35);
-/*
- mStatsAttackLabel->setPosition(220, mStatsLabel[0]->getY());
- mStatsDefenseLabel->setPosition(220, mStatsLabel[1]->getY());
- mStatsMagicAttackLabel->setPosition(220, mStatsLabel[2]->getY());
- mStatsMagicDefenseLabel->setPosition(220, mStatsLabel[3]->getY());
- mStatsAccuracyLabel->setPosition(220, mStatsLabel[4]->getY());
- mStatsEvadeLabel->setPosition(220, mStatsLabel[5]->getY());
- mStatsReflexLabel->setPosition(220, mStatsLabel[6]->getY());
-
- mStatsAttackPoints->setPosition(310, mStatsLabel[0]->getY());
- mStatsDefensePoints->setPosition(310, mStatsLabel[1]->getY());
- mStatsMagicAttackPoints->setPosition(310, mStatsLabel[2]->getY());
- mStatsMagicDefensePoints->setPosition(310, mStatsLabel[3]->getY());
- mStatsAccuracyPoints->setPosition(310, mStatsLabel[4]->getY());
- mStatsEvadePoints->setPosition(310, mStatsLabel[5]->getY());
- mStatsReflexPoints->setPosition(310, mStatsLabel[6]->getY());
-*/
+
// Assemble
add(mStatsTitleLabel);
add(mStatsTotalLabel);
@@ -171,22 +135,7 @@ StatusWindow::StatusWindow():
add(mStatsDisplayLabel[i]);
add(mStatsPlus[i]);
add(mStatsMinus[i]);
- }/*
- add(mStatsAttackLabel);
- add(mStatsDefenseLabel);
- add(mStatsMagicAttackLabel);
- add(mStatsMagicDefenseLabel);
- add(mStatsAccuracyLabel);
- add(mStatsEvadeLabel);
- add(mStatsReflexLabel);
-
- add(mStatsAttackPoints);
- add(mStatsDefensePoints);
- add(mStatsMagicAttackPoints);
- add(mStatsMagicDefensePoints);
- add(mStatsAccuracyPoints);
- add(mStatsEvadePoints);
- add(mStatsReflexPoints);*/
+ }
add(mCharacterPointsLabel);
add(mCorrectionPointsLabel);
@@ -242,52 +191,24 @@ void StatusWindow::update()
mCorrectionPointsLabel->setCaption("Correction Points: " +
toString(correctionPoints));
mCorrectionPointsLabel->adjustSize();
-/*
- // Derived Stats Points
-
- // Attack TODO: Count equipped Weapons and items attack bonuses
- mStatsAttackPoints->setCaption(
- toString(player_node->ATK + player_node->ATK_BONUS));
- mStatsAttackPoints->adjustSize();
-
- // Defense TODO: Count equipped Armors and items defense bonuses
- mStatsDefensePoints->setCaption(
- toString(player_node->DEF + player_node->DEF_BONUS));
- mStatsDefensePoints->adjustSize();
-
- // Magic Attack TODO: Count equipped items M.Attack bonuses
- mStatsMagicAttackPoints->setCaption(
- toString(player_node->MATK + player_node->MATK_BONUS));
- mStatsMagicAttackPoints->adjustSize();
-
- // Magic Defense TODO: Count equipped items M.Defense bonuses
- mStatsMagicDefensePoints->setCaption(
- toString(player_node->MDEF + player_node->MDEF_BONUS));
- mStatsMagicDefensePoints->adjustSize();
-
- // Accuracy %
- mStatsAccuracyPoints->setCaption(toString(player_node->HIT));
- mStatsAccuracyPoints->adjustSize();
-
- // Evasion %
- mStatsEvadePoints->setCaption(toString(player_node->FLEE));
- mStatsEvadePoints->adjustSize();
-
- // Reflex %
- mStatsReflexPoints->setCaption(toString(player_node->DEX / 4)); // + counter
- mStatsReflexPoints->adjustSize();
-*/
+
// Update Second column widgets position
mMoneyLabel->setPosition(mLvlLabel->getX() + mLvlLabel->getWidth() + 20,
mLvlLabel->getY());
+ update();
}
-void StatusWindow::draw(gcn::Graphics *g)
+std::string StatusWindow::update(int id)
{
+ // TODO: only update what changed
update();
+}
- Window::draw(g);
+void StatusWindow::addAttribute(int id, const std::string &name,
+ bool modifiable)
+{
+ // future use
}
void StatusWindow::action(const gcn::ActionEvent &event)
diff --git a/src/gui/statuswindow.h b/src/gui/statuswindow.h
index 7b3b8ae0..d5bd8fd6 100644
--- a/src/gui/statuswindow.h
+++ b/src/gui/statuswindow.h
@@ -50,15 +50,14 @@ class StatusWindow : public Window, public gcn::ActionListener
void action(const gcn::ActionEvent &event);
/**
- * Draw this window
- */
- void draw(gcn::Graphics *graphics);
-
- /**
* Updates this dialog with values from PLAYER_INFO *char_info
*/
void update();
+ std::string update(int id);
+
+ void addAttribute(int id, const std::string &name, bool modifiable);
+
static void updateHPBar(ProgressBar *bar, bool showMax = false);
private:
diff --git a/src/localplayer.cpp b/src/localplayer.cpp
index 84fcbe3c..18bc77b0 100644
--- a/src/localplayer.cpp
+++ b/src/localplayer.cpp
@@ -41,6 +41,11 @@
#include "gui/palette.h"
#include "gui/skilldialog.h"
#include "gui/storagewindow.h"
+#ifdef TMWSERV_SUPPORT
+#include "gui/statuswindow.h"
+#else
+#include "gui/status.h"
+#endif
#include "gui/widgets/chattab.h"
@@ -90,8 +95,6 @@ LocalPlayer::LocalPlayer(int id, int job, Map *map):
mXpForNextLevel(0), mJobXpForNextLevel(0),
mMp(0), mMaxMp(0),
mAttackRange(0),
- ATK(0), MATK(0), DEF(0), MDEF(0), HIT(0), FLEE(0),
- ATK_BONUS(0), MATK_BONUS(0), DEF_BONUS(0), MDEF_BONUS(0), FLEE_BONUS(0),
#endif
mEquipment(new Equipment),
mInStorage(false),
@@ -798,6 +801,9 @@ void LocalPlayer::setAttributeBase(int num, int value)
Particle* effect = particleEngine->addEffect("graphics/particles/skillup.particle.xml", 0, 0);
this->controlParticle(effect);
}
+
+ if (statusWindow)
+ statusWindow->update(num);
}
void LocalPlayer::setAttributeEffective(int num, int value)
@@ -805,6 +811,9 @@ void LocalPlayer::setAttributeEffective(int num, int value)
mAttributeEffective[num] = value;
if (skillDialog)
skillDialog->update(num);
+
+ if (statusWindow)
+ statusWindow->update(num);
}
void LocalPlayer::setSkillPoints(int points)
@@ -844,6 +853,9 @@ void LocalPlayer::setLevelProgress(int percent)
addMessageToQueue(toString(percent - mLevelProgress) + " xp");
}
mLevelProgress = percent;
+
+ if (statusWindow)
+ statusWindow->update();
}
void LocalPlayer::pickedUp(const ItemInfo &itemInfo, int amount)
diff --git a/src/localplayer.h b/src/localplayer.h
index ea6d76d5..4bcd43a3 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -35,8 +35,6 @@ class Inventory;
class Item;
class Map;
-#ifdef TMWSERV_SUPPORT
-
/**
* Attributes used during combat. Available to all the beings.
*/
@@ -88,22 +86,18 @@ enum
NB_CHARACTER_ATTRIBUTES = CHAR_ATTR_END
};
-#endif
-
/**
* The local player character.
*/
class LocalPlayer : public Player
{
public:
+#ifdef TMWSERV_SUPPORT
enum Attribute
{
-#ifdef TMWSERV_SUPPORT
STR = 0, AGI, DEX, VIT, INT, WIL, CHR
-#else
- STR = 0, AGI, VIT, INT, DEX, LUK
-#endif
};
+#endif
/**
* Constructor.
@@ -286,13 +280,6 @@ class LocalPlayer : public Player
Uint16 mMp, mMaxMp;
Uint16 mAttackRange;
-
- Uint8 mAttr[6];
- Uint8 mAttrUp[6];
-
- int ATK, MATK, DEF, MDEF, HIT, FLEE;
- int ATK_BONUS, MATK_BONUS, DEF_BONUS, MDEF_BONUS, FLEE_BONUS;
-
#endif
int getHp() const
diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp
index 4ffea0c9..a09f11f9 100644
--- a/src/net/ea/charserverhandler.cpp
+++ b/src/net/ea/charserverhandler.cpp
@@ -205,7 +205,7 @@ LocalPlayer *CharServerHandler::readPlayerData(MessageIn &msg, int &slot)
tempPlayer->setSprite(Being::MISC2_SPRITE, msg.readInt16());
tempPlayer->setName(msg.readString(24));
for (int i = 0; i < 6; i++) {
- tempPlayer->mAttr[i] = msg.readInt8();
+ tempPlayer->setAttributeBase(i + STR, msg.readInt8());
}
slot = msg.readInt8(); // character slot
msg.readInt8(); // unknown
diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp
index 8ff62d37..bbadd44f 100644
--- a/src/net/ea/generalhandler.cpp
+++ b/src/net/ea/generalhandler.cpp
@@ -23,6 +23,7 @@
#include "gui/inventorywindow.h"
#include "gui/skilldialog.h"
+#include "gui/status.h"
#include "net/ea/network.h"
#include "net/ea/protocol.h"
@@ -203,6 +204,20 @@ void GeneralHandler::guiWindowsLoaded()
partyTab = new PartyTab;
inventoryWindow->setSplitAllowed(false);
skillDialog->loadSkills("ea-skills.xml");
+
+ /*statusWindow->addAttribute(STR, _("Strength"), true);
+ statusWindow->addAttribute(AGI, _("Agility"), true);
+ statusWindow->addAttribute(VIT, _("Vitality"), true);
+ statusWindow->addAttribute(INT, _("Intelligence"), true);
+ statusWindow->addAttribute(DEX, _("Dexterity"), true);
+ statusWindow->addAttribute(LUK, _("Luck"), true);
+
+ statusWindow->addAttribute(ATK, _("Attack"), false);
+ statusWindow->addAttribute(DEF, _("Defense"), false);
+ statusWindow->addAttribute(MATK, _("M.Attack"), false);
+ statusWindow->addAttribute(MDEF, _("M.Defense"), false);
+ statusWindow->addAttribute(HIT, _("% Accuracy"), false);
+ statusWindow->addAttribute(FLEE, _("% Evade"), false);*/
}
void GeneralHandler::guiWindowsUnloaded()
diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp
index 9b4c56e2..9464723a 100644
--- a/src/net/ea/playerhandler.cpp
+++ b/src/net/ea/playerhandler.cpp
@@ -53,6 +53,9 @@ OkDialog *deathNotice = NULL;
// everything beyond will reset the port hard.
static const int MAP_TELEPORT_SCROLL_DISTANCE = 8;
+#define ATTR_BONUS(atr) \
+(player_node->getAttributeEffective(atr) - player_node->getAttributeBase(atr))
+
// TODO Move somewhere else
namespace {
@@ -223,17 +226,14 @@ void PlayerHandler::handleMessage(MessageIn &msg)
switch (type)
{
case 0x0000: player_node->setWalkSpeed(value); break;
+ case 0x0004: break; // manner
case 0x0005: player_node->setHp(value); break;
case 0x0006: player_node->setMaxHp(value); break;
case 0x0007: player_node->mMp = value; break;
case 0x0008: player_node->mMaxMp = value; break;
- case 0x0009:
- player_node->setCharacterPoints(value);
- break;
+ case 0x0009: player_node->setCharacterPoints(value); break;
case 0x000b: player_node->setLevel(value); break;
- case 0x000c:
- player_node->setSkillPoints(value);
- break;
+ case 0x000c: player_node->setSkillPoints(value); break;
case 0x0018:
if (value >= player_node->getMaxWeight() / 2 &&
player_node->getTotalWeight() <
@@ -249,13 +249,44 @@ void PlayerHandler::handleMessage(MessageIn &msg)
player_node->setTotalWeight(value);
break;
case 0x0019: player_node->setMaxWeight(value); break;
- case 0x0029: player_node->ATK = value; break;
- case 0x002b: player_node->MATK = value; break;
- case 0x002d: player_node->DEF = value; break;
- case 0x002e: player_node->DEF_BONUS = value; break;
- case 0x002f: player_node->MDEF = value; break;
- case 0x0031: player_node->HIT = value; break;
- case 0x0032: player_node->FLEE = value; break;
+
+ case 0x0029: player_node->setAttributeEffective(ATK, value
+ + ATTR_BONUS(ATK));
+ player_node->setAttributeBase(ATK, value);
+ break;
+ case 0x002a: value += player_node->getAttributeBase(ATK);
+ player_node->setAttributeEffective(ATK, value); break;
+
+ case 0x002b: player_node->setAttributeEffective(MATK, value
+ + ATTR_BONUS(MATK));
+ player_node->setAttributeBase(MATK, value); break;
+ case 0x002c: value += player_node->getAttributeBase(MATK);
+ player_node->setAttributeEffective(MATK, value); break;
+
+ case 0x002d: player_node->setAttributeEffective(DEF, value
+ + ATTR_BONUS(DEF));
+ player_node->setAttributeBase(DEF, value); break;
+ case 0x002e: value += player_node->getAttributeBase(DEF);
+ player_node->setAttributeEffective(DEF, value); break;
+
+ case 0x002f: player_node->setAttributeEffective(MDEF, value
+ + ATTR_BONUS(MDEF));
+ player_node->setAttributeBase(MDEF, value); break;
+ case 0x0030: value += player_node->getAttributeBase(MDEF);
+ player_node->setAttributeEffective(MDEF, value); break;
+
+ case 0x0031: player_node->setAttributeBase(HIT, value);
+ player_node->setAttributeEffective(HIT, value); break;
+
+ case 0x0032: player_node->setAttributeEffective(FLEE, value
+ + ATTR_BONUS(FLEE));
+ player_node->setAttributeBase(FLEE, value); break;
+ case 0x0033: value += player_node->getAttributeBase(FLEE);
+ player_node->setAttributeEffective(FLEE, value); break;
+
+ case 0x0034: player_node->setAttributeBase(CRIT, value);
+ player_node->setAttributeEffective(CRIT, value); break;
+
case 0x0035: player_node->mAttackSpeed = value; break;
case 0x0037: player_node->mJobLevel = value; break;
case 500: player_node->setGMLevel(value); break;
@@ -302,26 +333,13 @@ void PlayerHandler::handleMessage(MessageIn &msg)
int type = msg.readInt32();
int base = msg.readInt32();
int bonus = msg.readInt32();
- int total = base + bonus;
- switch (type) {
- case 0x000d: player_node->mAttr[LocalPlayer::STR] = total;
- break;
- case 0x000e: player_node->mAttr[LocalPlayer::AGI] = total;
- break;
- case 0x000f: player_node->mAttr[LocalPlayer::VIT] = total;
- break;
- case 0x0010: player_node->mAttr[LocalPlayer::INT] = total;
- break;
- case 0x0011: player_node->mAttr[LocalPlayer::DEX] = total;
- break;
- case 0x0012: player_node->mAttr[LocalPlayer::LUK] = total;
- break;
- }
+ player_node->setAttributeBase(type, base);
+ player_node->setAttributeEffective(type, base + bonus);
}
break;
- case SMSG_PLAYER_STAT_UPDATE_4:
+ case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
{
int type = msg.readInt16();
int fail = msg.readInt8();
@@ -330,72 +348,104 @@ void PlayerHandler::handleMessage(MessageIn &msg)
if (fail != 1)
break;
- switch (type) {
- case 0x000d: player_node->mAttr[LocalPlayer::STR] = value;
- break;
- case 0x000e: player_node->mAttr[LocalPlayer::AGI] = value;
- break;
- case 0x000f: player_node->mAttr[LocalPlayer::VIT] = value;
- break;
- case 0x0010: player_node->mAttr[LocalPlayer::INT] = value;
- break;
- case 0x0011: player_node->mAttr[LocalPlayer::DEX] = value;
- break;
- case 0x0012: player_node->mAttr[LocalPlayer::LUK] = value;
- break;
- }
+ int bonus = ATTR_BONUS(type);
+
+ player_node->setAttributeBase(type, value);
+ player_node->setAttributeEffective(type, value + bonus);
}
break;
// Updates stats and status points
case SMSG_PLAYER_STAT_UPDATE_5:
player_node->setCharacterPoints(msg.readInt16());
- player_node->mAttr[LocalPlayer::STR] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
- player_node->mAttr[LocalPlayer::AGI] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
- player_node->mAttr[LocalPlayer::VIT] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
- player_node->mAttr[LocalPlayer::INT] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
- player_node->mAttr[LocalPlayer::DEX] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
- player_node->mAttr[LocalPlayer::LUK] = msg.readInt8();
- player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
- player_node->ATK = msg.readInt16(); // ATK
- player_node->ATK_BONUS = msg.readInt16(); // ATK bonus
- player_node->MATK = msg.readInt16(); // MATK max
- player_node->MATK_BONUS = msg.readInt16(); // MATK min
- player_node->DEF = msg.readInt16(); // DEF
- player_node->DEF_BONUS = msg.readInt16(); // DEF bonus
- player_node->MDEF = msg.readInt16(); // MDEF
- player_node->MDEF_BONUS = msg.readInt16(); // MDEF bonus
- player_node->HIT = msg.readInt16(); // HIT
- player_node->FLEE = msg.readInt16(); // FLEE
- player_node->FLEE_BONUS = msg.readInt16(); // FLEE bonus
- msg.readInt16(); // critical
- msg.readInt16(); // unknown
+
+ {
+ int val = msg.readInt8();
+ player_node->setAttributeEffective(STR, val + ATTR_BONUS(STR));
+ player_node->setAttributeBase(STR, val);
+ player_node->setAttributeBase(STR, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(AGI, val + ATTR_BONUS(AGI));
+ player_node->setAttributeBase(AGI, val);
+ player_node->setAttributeBase(AGI_U, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(VIT, val + ATTR_BONUS(VIT));
+ player_node->setAttributeBase(VIT, val);
+ player_node->setAttributeBase(VIT_U, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(INT, val + ATTR_BONUS(INT));
+ player_node->setAttributeBase(INT, val);
+ player_node->setAttributeBase(INT_U, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(DEX, val + ATTR_BONUS(DEX));
+ player_node->setAttributeBase(DEX, val);
+ player_node->setAttributeBase(DEX_U, msg.readInt8());
+
+ val = msg.readInt8();
+ player_node->setAttributeEffective(LUK, val + ATTR_BONUS(LUK));
+ player_node->setAttributeBase(LUK, val);
+ player_node->setAttributeBase(LUK_U, msg.readInt8());
+
+ val = msg.readInt16(); // ATK
+ player_node->setAttributeBase(ATK, val);
+ val += msg.readInt16(); // ATK bonus
+ player_node->setAttributeEffective(ATK, val);
+
+ val = msg.readInt16(); // MATK
+ player_node->setAttributeBase(MATK, val);
+ val += msg.readInt16(); // MATK bonus
+ player_node->setAttributeEffective(MATK, val);
+
+ val = msg.readInt16(); // DEF
+ player_node->setAttributeBase(DEF, val);
+ val += msg.readInt16(); // DEF bonus
+ player_node->setAttributeEffective(DEF, val);
+
+ val = msg.readInt16(); // MDEF
+ player_node->setAttributeBase(MDEF, val);
+ val += msg.readInt16(); // MDEF bonus
+ player_node->setAttributeEffective(MDEF, val);
+
+ val = msg.readInt16(); // HIT
+ player_node->setAttributeBase(ATK, val);
+ player_node->setAttributeEffective(ATK, val);
+
+ val = msg.readInt16(); // FLEE
+ player_node->setAttributeBase(FLEE, val);
+ val += msg.readInt16(); // FLEE bonus
+ player_node->setAttributeEffective(FLEE, val);
+
+ val = msg.readInt16();
+ player_node->setAttributeBase(CRIT, val);
+ player_node->setAttributeEffective(CRIT, val);
+ }
+
+ msg.readInt16(); // manner
break;
case SMSG_PLAYER_STAT_UPDATE_6:
switch (msg.readInt16()) {
case 0x0020:
- player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
+ player_node->setAttributeBase(STR_U, msg.readInt8());
break;
case 0x0021:
- player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
+ player_node->setAttributeBase(AGI_U, msg.readInt8());
break;
case 0x0022:
- player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
+ player_node->setAttributeBase(VIT_U, msg.readInt8());
break;
case 0x0023:
- player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
+ player_node->setAttributeBase(INT_U, msg.readInt8());
break;
case 0x0024:
- player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
+ player_node->setAttributeBase(DEX_U, msg.readInt8());
break;
case 0x0025:
- player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
+ player_node->setAttributeBase(LUK_U, msg.readInt8());
break;
}
break;
@@ -433,35 +483,12 @@ void PlayerHandler::emote(int emoteId)
void PlayerHandler::increaseAttribute(size_t attr)
{
- MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
-
- switch (attr)
+ if (attr >= STR && attr <= LUK)
{
- case LocalPlayer::STR:
- outMsg.writeInt16(0x000d);
- break;
-
- case LocalPlayer::AGI:
- outMsg.writeInt16(0x000e);
- break;
-
- case LocalPlayer::VIT:
- outMsg.writeInt16(0x000f);
- break;
-
- case LocalPlayer::INT:
- outMsg.writeInt16(0x0010);
- break;
-
- case LocalPlayer::DEX:
- outMsg.writeInt16(0x0011);
- break;
-
- case LocalPlayer::LUK:
- outMsg.writeInt16(0x0012);
- break;
+ MessageOut outMsg(CMSG_STAT_UPDATE_REQUEST);
+ outMsg.writeInt16(STR);
+ outMsg.writeInt8(1);
}
- outMsg.writeInt8(1);
}
void PlayerHandler::decreaseAttribute(size_t attr)
diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h
index fcb96f22..268c8c67 100644
--- a/src/net/ea/protocol.h
+++ b/src/net/ea/protocol.h
@@ -22,6 +22,30 @@
#ifndef EA_PROTOCOL_H
#define EA_PROTOCOL_H
+enum {
+ STR = 0xd,
+ AGI,
+ VIT,
+ INT,
+ DEX,
+ LUK,
+
+ STR_U,
+ AGI_U,
+ VIT_U,
+ INT_U,
+ DEX_U,
+ LUK_U,
+
+ ATK,
+ DEF,
+ MATK,
+ MDEF,
+ HIT,
+ FLEE,
+ CRIT
+};
+
static const int INVENTORY_OFFSET = 2;
static const int STORAGE_OFFSET = 1;
diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp
index 10b2c0f3..c04df973 100644
--- a/src/net/tmwserv/generalhandler.cpp
+++ b/src/net/tmwserv/generalhandler.cpp
@@ -22,6 +22,7 @@
#include "gui/inventorywindow.h"
#include "gui/partywindow.h"
#include "gui/skilldialog.h"
+#include "gui/statuswindow.h"
#include "net/tmwserv/generalhandler.h"
@@ -148,6 +149,13 @@ void GeneralHandler::guiWindowsLoaded()
inventoryWindow->setSplitAllowed(true);
partyWindow->clearPartyName();
skillDialog->loadSkills("tmw-skills.xml");
+
+ /*statusWindow->addAttribute(16, _("Strength"), true);
+ statusWindow->addAttribute(17, _("Agility"), true);
+ statusWindow->addAttribute(18, _("Dexterity"), true);
+ statusWindow->addAttribute(19, _("Vitality"), true);
+ statusWindow->addAttribute(20, _("Intelligence"), true);
+ statusWindow->addAttribute(21, _("Willpower"), true);*/
}
void GeneralHandler::guiWindowsUnloaded()