summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--src/game-server/monster.cpp26
-rw-r--r--src/game-server/monster.hpp33
-rw-r--r--src/game-server/monstermanager.cpp22
4 files changed, 70 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index ee6e3284..58853f4e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-02-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/game-server/monster.cpp, src/game-server/monster.hpp,
+ src/game-server/monstermanager.cpp: Parts of monster behavior are now
+ read from monsters.xml. Warnings during monster parsing now include
+ the name of the monster.
+
2008-02-07 Bjørn Lindeijer <bjorn@lindeijer.nl>
* src/scripting/lua.cpp: Fail gracefully on invalid monster IDs, don't
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index efbd02c4..4cad2311 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -74,8 +74,6 @@ Monster::Monster(MonsterClass *specy):
// Some bogus stats for testing.
// TODO: Get all this stuff from the monster database.
- mAgressive = false;
- mAgressionRange = 10;
mAttackPreDelay = 10;
mAttackAftDelay = 10;
mAttackRange = 32;
@@ -177,7 +175,7 @@ void Monster::update()
{
targetPriority = angerIterator->second;
}
- else if (mAgressive)
+ else if (mSpecy->isAggressive())
{
targetPriority = 1;
}
@@ -231,10 +229,14 @@ void Monster::update()
mCountDown--;
if (mCountDown <= 0)
{
- Point randomPos(rand() % 160 - 80 + getPosition().x,
- rand() % 160 - 80 + getPosition().y);
- setDestination(randomPos);
- mCountDown = 10 + rand() % 10;
+ unsigned range = mSpecy->getStrollRange();
+ if (range)
+ {
+ Point randomPos(rand() % (range * 2) - range + getPosition().x,
+ rand() % (range * 2) - range + getPosition().y);
+ setDestination(randomPos);
+ mCountDown = 10 + rand() % 10;
+ }
}
}
}
@@ -243,25 +245,27 @@ int Monster::calculatePositionPriority(Point position, int targetPriority)
{
Point thisPos = getPosition();
+ unsigned range = mSpecy->getTrackRange();
+
// Check if we already are on this position
if (thisPos.x / 32 == position.x / 32 &&
thisPos.y / 32 == position.y / 32)
{
- return targetPriority *= mAgressionRange;
+ return targetPriority *= range;
}
std::list<PATH_NODE> path;
path = getMap()->getMap()->findPath(thisPos.x / 32, thisPos.y / 32,
position.x / 32, position.y / 32,
- mAgressionRange);
+ range);
- if (path.empty() || path.size() >= mAgressionRange)
+ if (path.empty() || path.size() >= range)
{
return 0;
}
else
{
- return targetPriority * (mAgressionRange - path.size());
+ return targetPriority * (range - path.size());
}
}
diff --git a/src/game-server/monster.hpp b/src/game-server/monster.hpp
index f5c7c18f..3b96c619 100644
--- a/src/game-server/monster.hpp
+++ b/src/game-server/monster.hpp
@@ -49,7 +49,14 @@ typedef std::vector< MonsterDrop > MonsterDrops;
class MonsterClass
{
public:
- MonsterClass(int id): mID(id), mAttributes(BASE_ATTR_NB, 0), mExp(-1) {}
+ MonsterClass(int id):
+ mID(id),
+ mAttributes(BASE_ATTR_NB, 0),
+ mExp(-1),
+ mAggressive(false),
+ mTrackRange(1),
+ mStrollRange(0)
+ {}
/**
* Gets monster type.
@@ -87,9 +94,26 @@ class MonsterClass
int getExp() const
{ return mExp; }
+ void setAggressive(bool aggressive)
+ { mAggressive = aggressive; }
+
+ bool isAggressive() const
+ { return mAggressive; }
+
+ void setTrackRange(int range)
+ { mTrackRange = range; }
+
+ unsigned getTrackRange() const
+ { return mTrackRange; }
+
+ void setStrollRange(int range)
+ { mStrollRange = range; }
+
+ unsigned getStrollRange() const
+ { return mStrollRange; }
+
/**
* Randomly selects a monster drop (may return NULL).
- * TODO: pass some luck modifier as an argument.
*/
ItemClass *getRandomDrop() const;
@@ -98,6 +122,9 @@ class MonsterClass
MonsterDrops mDrops; /**< Items the monster drops when dying. */
std::vector<int> mAttributes; /**< Base attributes of the monster*/
int mExp; /**< Exp reward for killing the monster */
+ bool mAggressive; /**< Does the monster attack without being provoked? */
+ unsigned mTrackRange; /**< Distance the monster tracks enemies in */
+ unsigned mStrollRange; /**< Distance the monster strolls around in when not fighting */
};
/**
@@ -187,8 +214,6 @@ class Monster : public Being
int mAttackAftDelay; /**< time it takes to perform an attack */
int mAttackRange; /**< range of the monsters attacks in pixel */
int mAttackAngle; /**< angle of the monsters attacks in degree */
- bool mAgressive; /**< Does the monster attack without being provoked? */
- unsigned mAgressionRange; /**< Distance the monster tracks enemies in */
std::list<AttackPosition> mAttackPositions; /**< set positions relative to target from which the monster can attack */
friend struct MonsterTargetEventDispatch;
diff --git a/src/game-server/monstermanager.cpp b/src/game-server/monstermanager.cpp
index f613969d..c4bddfa3 100644
--- a/src/game-server/monstermanager.cpp
+++ b/src/game-server/monstermanager.cpp
@@ -83,10 +83,11 @@ void MonsterManager::reload()
}
int id = XML::getProperty(node, "id", 0);
+ std::string name = XML::getProperty(node, "name", "unnamed");
if (id == 0)
{
- LOG_WARN("Monster Manager: There is a monster without ID in "
+ LOG_WARN("Monster Manager: There is a monster ("<<name<<") without ID in "
<< monsterReferenceFile << "! It has been ignored.");
continue;
}
@@ -105,6 +106,7 @@ void MonsterManager::reload()
MonsterDrops drops;
bool attributesSet = false;
+ bool behaviorSet = false;
for (xmlNodePtr subnode = node->xmlChildrenNode; subnode != NULL;
subnode = subnode->next)
@@ -159,16 +161,30 @@ void MonsterManager::reload()
xmlChar *exp = subnode->xmlChildrenNode->content;
monster->setExp(atoi((const char*)exp));
}
+ else if (xmlStrEqual(subnode->name, BAD_CAST "behavior"))
+ {
+ behaviorSet = true;
+ if (XML::getProperty(subnode, "aggressive", "") == "true")
+ {
+ monster->setAggressive(true);
+ }
+ monster->setTrackRange(XML::getProperty(subnode, "track-range", 1));
+ monster->setStrollRange(XML::getProperty(subnode, "stroll-range", 0) * 32);
+ }
}
monster->setDrops(drops);
if (!attributesSet) LOG_WARN(monsterReferenceFile
<<": No attributes defined for monster #"
- <<id);
+ <<id<<" ("<<name<<")");
+ if (!behaviorSet) LOG_WARN(monsterReferenceFile
+ <<": No behavior defined for monster #"
+ <<id<<" ("<<name<<")");
if (monster->getExp() == -1)
{
LOG_WARN(monsterReferenceFile
- <<": No experience defined for monster #"<<id);
+ <<": No experience defined for monster #"
+ <<id<<" ("<<name<<")");
monster->setExp(0);
}
++nbMonsters;