summaryrefslogtreecommitdiff
path: root/src/game-server
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 /src/game-server
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).
Diffstat (limited to 'src/game-server')
-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
5 files changed, 64 insertions, 48 deletions
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);