summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Sehmisch <tmw@crushnet.org>2008-01-07 22:07:10 +0000
committerPhilipp Sehmisch <tmw@crushnet.org>2008-01-07 22:07:10 +0000
commitc1d99cc23ca3108c74ad897c9a3485701aae1220 (patch)
tree013ad38134d92df7b4f3d55c9b36b6c047b68d70
parentab00efb5c42b32a497fd56103dff7cc97b309ca8 (diff)
downloadmanaserv-c1d99cc23ca3108c74ad897c9a3485701aae1220.tar.gz
manaserv-c1d99cc23ca3108c74ad897c9a3485701aae1220.tar.bz2
manaserv-c1d99cc23ca3108c74ad897c9a3485701aae1220.tar.xz
manaserv-c1d99cc23ca3108c74ad897c9a3485701aae1220.zip
Implemented some of the game mechanics we decided to use. The clients now only receive attribute change messages when the attribute actually changed. Left the HP mechanics as they are for now (although I consider them flawed).
-rw-r--r--ChangeLog11
-rw-r--r--src/defines.h6
-rw-r--r--src/game-server/being.cpp33
-rw-r--r--src/game-server/character.cpp58
-rw-r--r--src/game-server/inventory.cpp5
-rw-r--r--src/game-server/itemmanager.cpp3
-rw-r--r--src/game-server/monster.cpp13
-rw-r--r--src/serialize/characterdata.hpp1
8 files changed, 80 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 14852935..e57fe9b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-01-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/defines.h, src/game-server/being.cpp,
+ src/game-server/being.hpp, src/game-server/character.cpp,
+ src/game-server/inventory.cpp, src/game-server/itemmanager.cpp,
+ src/game-server/monster.cpp, src/serialize/characterdata.hpp:
+ Implemented some of the game mechanics we decided to use.
+ * src/game-server/character.cpp:
+ The clients now only receive attribute change messages
+ when the attribute actually changed.
+
2007-12-18 Philipp Sehmisch <tmw@crushnet.org>
* src/account-server/dalstorage.cpp,
diff --git a/src/defines.h b/src/defines.h
index bc3e8a3f..a22a739d 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -357,13 +357,15 @@ enum
enum
{
BASE_ATTR_BEGIN = 0,
- BASE_ATTR_PHY_ATK = BASE_ATTR_BEGIN,
+ BASE_ATTR_PHY_ATK_MIN = BASE_ATTR_BEGIN,
+ BASE_ATTR_PHY_ATK_DELTA,
/**< Physical attack power. */
BASE_ATTR_MAG_ATK, /**< Magical attack power. */
BASE_ATTR_PHY_RES, /**< Resistance to physical damage. */
BASE_ATTR_MAG_RES, /**< Resistance to magical damage. */
BASE_ATTR_EVADE, /**< Ability to avoid hits. */
- BASE_ATTR_HP, /**< Remaining Hit Points. */
+ BASE_ATTR_HIT, /**< Ability to hit stuff. */
+ BASE_ATTR_HP, /**< Hit Points (Base value: maximum, Modded value: current) */
BASE_ATTR_END,
BASE_ATTR_NB = BASE_ATTR_END - BASE_ATTR_BEGIN,
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index 7c09d97e..c969daf5 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -53,33 +53,12 @@ int Being::damage(Object *, Damage const &damage)
HPloss += rand() / (RAND_MAX / (damage.delta + 1));
}
- /* Damage can either be avoided, or applied, or critical (applied twice).
- This is decided by comparing CTH and Evade. If they are equal, the
- probabilities are 10%, 80%, 10%. Otherwise, the bigger the CTH, the
- higher the chance to do a critical, up to 50%; and the bigger the Evade,
- the higher the chance to do evade the hit, up to 50% again. */
-
- int avoidChance = 10, criticalChance = 10;
- int diff = damage.cth - getModifiedAttribute(BASE_ATTR_EVADE);
- if (diff > 0)
- {
- // CTH - Evade >= 200 => 50% critical
- criticalChance += diff * diff / 1000;
- if (criticalChance > 50) criticalChance = 50;
- }
- else if (diff < 0)
+ int hitThrow = rand()%(damage.cth + 1);
+ int evadeThrow = rand()%(getModifiedAttribute(BASE_ATTR_EVADE) + 1);
+ if (evadeThrow > hitThrow)
{
- // Evade - CTH >= 200 => 50% avoid
- avoidChance += diff * diff / 10000;
- if (avoidChance > 50) avoidChance = 50;
+ HPloss = 0;
}
- int chance = rand() / (RAND_MAX / 100);
- if (chance <= avoidChance)
- {
- mHitsTaken.push_back(0);
- return 0;
- }
- if (chance >= 100 - criticalChance) HPloss *= 2;
/* Elemental modifier at 100 means normal damage. At 0, it means immune.
And at 200, it means vulnerable (double damage). */
@@ -99,7 +78,9 @@ int Being::damage(Object *, Damage const &damage)
default:
break;
}
- HPloss = HPloss * mod1 / (100 + mod2);
+ HPloss = HPloss * (mod1 / 100) - mod2;
+
+ if (HPloss < 0) HPloss = 0;
mHitsTaken.push_back(HPloss);
LOG_DEBUG("Being " << getPublicID() << " got hit.");
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index b9bb061b..04f3d52b 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -42,7 +42,7 @@
Character::Character(MessageIn &msg):
Being(OBJECT_CHARACTER, 65535),
mClient(NULL), mTransactionHandler(NULL), mDatabaseID(-1),
- mGender(0), mHairStyle(0), mHairColor(0), mLevel(0),
+ mGender(0), mHairStyle(0), mHairColor(0), mLevel(1),
mTransaction(TRANS_NONE)
{
Attribute attr = { 0, 0 };
@@ -69,20 +69,19 @@ void Character::perform()
int type = ic ? ic->getModifiers().getValue(MOD_WEAPON_TYPE) : WPNTYPE_NONE;
Damage damage;
- damage.base = getModifiedAttribute(BASE_ATTR_PHY_ATK) / 10;
+ damage.base = getModifiedAttribute(BASE_ATTR_PHY_ATK_MIN);
+ damage.delta = getModifiedAttribute(BASE_ATTR_PHY_ATK_DELTA);
damage.type = DAMAGE_PHYSICAL;
+ damage.cth = getModifiedAttribute(BASE_ATTR_HIT)
+ + getModifiedAttribute(CHAR_SKILL_WEAPON_BEGIN + type);
if (type)
{
ItemModifiers const &mods = ic->getModifiers();
- damage.delta = mods.getValue(MOD_WEAPON_DAMAGE);
- damage.cth = getModifiedAttribute(CHAR_SKILL_WEAPON_BEGIN + type);
damage.element = mods.getValue(MOD_ELEMENT_TYPE);
}
else
{
// No-weapon fighting.
- damage.delta = 1;
- damage.cth = getModifiedAttribute(CHAR_SKILL_WEAPON_NONE);
damage.element = ELEMENT_NEUTRAL;
}
performAttack(damage);
@@ -179,17 +178,46 @@ void Character::modifiedAttribute(int attr)
{
if (attr >= CHAR_ATTR_BEGIN && attr < CHAR_ATTR_END)
{
- /* FIXME: The following formulas are for testing purpose only. They
- should be replaced by a real system once designed. */
- setAttribute(BASE_ATTR_HP, getModifiedAttribute(CHAR_ATTR_VITALITY));
- setAttribute(BASE_ATTR_PHY_ATK, getModifiedAttribute(CHAR_ATTR_STRENGTH));
- setAttribute(BASE_ATTR_PHY_RES, getModifiedAttribute(CHAR_ATTR_VITALITY));
- setAttribute(BASE_ATTR_MAG_RES, getModifiedAttribute(CHAR_ATTR_WILLPOWER));
- setAttribute(BASE_ATTR_EVADE, getModifiedAttribute(CHAR_ATTR_DEXTERITY));
- // We have just modified the computed attributes. Mark them as such.
for (int i = BASE_ATTR_BEGIN; i < BASE_ATTR_END; ++i)
{
- flagAttribute(i);
+ int newValue = getAttribute(i);
+
+ if (i == BASE_ATTR_HP){
+ newValue = (getModifiedAttribute(CHAR_ATTR_VITALITY) + 10)
+ * (mLevel + 10);
+ }
+ else if (i == BASE_ATTR_HIT) {
+ newValue = getModifiedAttribute(CHAR_ATTR_DEXTERITY)
+ /* + skill in class of currently equipped weapon */;
+ }
+ else if (i == BASE_ATTR_EVADE) {
+ newValue = getModifiedAttribute(CHAR_ATTR_AGILITY);
+ /* TODO: multiply with 10 / (10 * equip_weight)*/
+ }
+ else if (i == BASE_ATTR_PHY_RES) {
+ newValue = getModifiedAttribute(CHAR_ATTR_VITALITY);
+ /* equip defence is through equip modifiers */
+ }
+ else if (i == BASE_ATTR_PHY_ATK_MIN) {
+ newValue = getModifiedAttribute(CHAR_ATTR_STRENGTH);
+ /* weapon attack is applied through equip modifiers */
+ }
+ else if (i == BASE_ATTR_PHY_ATK_DELTA) {
+ newValue = 0 /* + skill in class of currently equipped weapon */;
+ /* weapon attack is applied through equip modifiers */
+ }
+ else if (i == BASE_ATTR_MAG_RES) {
+ newValue = getModifiedAttribute(CHAR_ATTR_WILLPOWER);
+ }
+ else if (i == BASE_ATTR_MAG_ATK) {
+ newValue = getModifiedAttribute(CHAR_ATTR_WILLPOWER);
+ }
+
+ if (newValue != getAttribute(i))
+ {
+ setAttribute(i, newValue);
+ flagAttribute(i);
+ }
}
}
flagAttribute(attr);
diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp
index c2dc8ba9..31f3b17b 100644
--- a/src/game-server/inventory.cpp
+++ b/src/game-server/inventory.cpp
@@ -596,7 +596,7 @@ int Inventory::move(int slot1, int slot2, int amount)
mPoss->inventory.insert(mPoss->inventory.end(), it);
}
InventoryItem it = { id, nb };
- mPoss->inventory.insert(mPoss->inventory.end(), it);
+ mPoss->inventory.insert(mPoss->inventory.end(), it);
return amount;
}
@@ -682,6 +682,9 @@ void Inventory::changeEquipment(int slot, int itemId)
msg.writeShort(itemId);
mPoss->equipment[slot] = itemId;
mChangedLook = true;
+
+ //mark evade as modified because it depends on equipment weight
+ mClient->modifiedAttribute(BASE_ATTR_EVADE);
}
void Inventory::equip(int slot)
diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp
index 02eee7d5..57486177 100644
--- a/src/game-server/itemmanager.cpp
+++ b/src/game-server/itemmanager.cpp
@@ -112,9 +112,10 @@ void ItemManager::reload()
ItemModifiers modifiers;
modifiers.setValue(MOD_WEAPON_TYPE, XML::getProperty(node, "weapon_type", 0));
modifiers.setValue(MOD_WEAPON_RANGE, XML::getProperty(node, "range", 0));
- modifiers.setValue(MOD_WEAPON_DAMAGE, XML::getProperty(node, "attack", 0));
modifiers.setValue(MOD_ELEMENT_TYPE, XML::getProperty(node, "element", 0));
modifiers.setValue(MOD_LIFETIME, XML::getProperty(node, "lifetime", 0) * 10);
+ modifiers.setAttributeValue(BASE_ATTR_PHY_ATK_MIN, XML::getProperty(node, "attack-min", 0));
+ modifiers.setAttributeValue(BASE_ATTR_PHY_ATK_DELTA, XML::getProperty(node, "attack-delta", 0));
modifiers.setAttributeValue(BASE_ATTR_HP, XML::getProperty(node, "hp", 0));
modifiers.setAttributeValue(BASE_ATTR_PHY_RES, XML::getProperty(node, "defense", 0));
modifiers.setAttributeValue(CHAR_ATTR_STRENGTH, XML::getProperty(node, "strength", 0));
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index 1d4bc280..b65ee3de 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -70,8 +70,11 @@ Monster::Monster(MonsterClass *specy):
// Some bogus stats for testing.
setSpeed(300);
setSize(8);
- setAttribute(BASE_ATTR_HP, 10);
- setAttribute(BASE_ATTR_PHY_ATK, 10);
+ setAttribute(BASE_ATTR_HP, 100);
+ setAttribute(BASE_ATTR_PHY_ATK_MIN, 20);
+ setAttribute(BASE_ATTR_PHY_ATK_DELTA, 2);
+ setAttribute(BASE_ATTR_HIT, 10);
+ setAttribute(BASE_ATTR_EVADE, 10);
// Set positions relative to target from which the monster can attack
mAttackPositions.push_back(AttackPosition(+32, 0, DIRECTION_LEFT));
@@ -99,9 +102,9 @@ void Monster::perform()
// Hard-coded values for now.
Damage damage;
- damage.base = getModifiedAttribute(BASE_ATTR_PHY_ATK) / 10;
- damage.delta = 2;
- damage.cth = 50;
+ damage.base = getModifiedAttribute(BASE_ATTR_PHY_ATK_MIN);
+ damage.delta = getModifiedAttribute(BASE_ATTR_PHY_ATK_DELTA);
+ damage.cth = getModifiedAttribute(BASE_ATTR_HIT);
damage.element = ELEMENT_NEUTRAL;
damage.type = DAMAGE_PHYSICAL;
performAttack(damage);
diff --git a/src/serialize/characterdata.hpp b/src/serialize/characterdata.hpp
index 7d3a7fc1..c9969b63 100644
--- a/src/serialize/characterdata.hpp
+++ b/src/serialize/characterdata.hpp
@@ -74,6 +74,7 @@ void deserializeCharacterData(T &data, MessageIn &msg)
for (int i = CHAR_ATTR_BEGIN; i < CHAR_ATTR_END; ++i)
{
data.setAttribute(i, msg.readByte());
+ data.modifiedAttribute(i);
}
data.setMapId(msg.readShort());