summaryrefslogtreecommitdiff
path: root/src/game-server/being.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2009-04-23 21:00:16 +0200
committerBjørn Lindeijer <bjorn@lindeijer.nl>2009-04-26 17:18:21 +0200
commite726c34606f85347e70a0deb6b180db03b6d0c25 (patch)
treee78e5ba07dd9484abed035cc3e63744101bbef57 /src/game-server/being.cpp
parenta3f72002fa02cd4c525f101c5f240a22d4480119 (diff)
downloadmanaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.tar.gz
manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.tar.bz2
manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.tar.xz
manaserv-e726c34606f85347e70a0deb6b180db03b6d0c25.zip
Merged MovingObject into the Being class
Also renamed Object to Actor, to make it sound a little less generic. Cleans up a bit the rather big hierarchy of different object types we have.
Diffstat (limited to 'src/game-server/being.cpp')
-rw-r--r--src/game-server/being.cpp150
1 files changed, 118 insertions, 32 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index ace30861..7319bcbe 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -30,9 +30,11 @@
#include "game-server/effect.hpp"
#include "utils/logger.h"
-Being::Being(int type, int id):
- MovingObject(type, id),
+Being::Being(ThingType type):
+ Actor(type),
mAction(STAND),
+ mSpeed(0),
+ mDirection(0),
mHpRegenTimer(0)
{
Attribute attr = { 0, 0 };
@@ -44,9 +46,10 @@ Being::Being(int type, int id):
}
}
-int Being::damage(Object *, Damage const &damage)
+int Being::damage(Actor *, Damage const &damage)
{
- if (mAction == DEAD) return 0;
+ if (mAction == DEAD)
+ return 0;
int HPloss = damage.base;
if (damage.delta)
@@ -94,7 +97,8 @@ int Being::damage(Object *, Damage const &damage)
void Being::died()
{
- if (mAction == DEAD) return;
+ if (mAction == DEAD)
+ return;
LOG_DEBUG("Being " << getPublicID() << " died.");
setAction(DEAD);
@@ -110,9 +114,92 @@ void Being::died()
}
}
+void Being::setDestination(const Point &dst)
+{
+ mDst = dst;
+ raiseUpdateFlags(UPDATEFLAG_NEW_DESTINATION);
+ mPath.clear();
+}
+
void Being::move()
{
- MovingObject::move();
+ mOld = getPosition();
+
+ if (mActionTime > 100)
+ {
+ // Current move has not yet ended
+ mActionTime -= 100;
+ return;
+ }
+
+ int tileSX = mOld.x / 32, tileSY = mOld.y / 32;
+ int tileDX = mDst.x / 32, tileDY = mDst.y / 32;
+ if (tileSX == tileDX && tileSY == tileDY)
+ {
+ // Moving while staying on the same tile is free
+ setPosition(mDst);
+ mActionTime = 0;
+ return;
+ }
+
+ Map *map = getMap()->getMap();
+
+ /* If no path exists, the for-loop won't be entered. Else a path for the
+ * current destination has already been calculated.
+ * The tiles in this path have to be checked for walkability,
+ * in case there have been changes. The 'getWalk' method of the Map
+ * class has been used, because that seems to be the most logical
+ * place extra functionality will be added.
+ */
+ for (std::list<PATH_NODE>::iterator pathIterator = mPath.begin();
+ pathIterator != mPath.end(); pathIterator++)
+ {
+ if (!map->getWalk(pathIterator->x, pathIterator->y, getWalkMask()))
+ {
+ mPath.clear();
+ break;
+ }
+ }
+
+ if (mPath.empty())
+ {
+ // No path exists: the walkability of cached path has changed, the
+ // destination has changed, or a path was never set.
+ mPath = map->findPath(tileSX, tileSY, tileDX, tileDY, getWalkMask());
+ }
+
+ if (mPath.empty())
+ {
+ // no path was found
+ mDst = mOld;
+ mActionTime = 0;
+ return;
+ }
+
+ PATH_NODE prev(tileSX, tileSY);
+ Point pos;
+ do
+ {
+ PATH_NODE next = mPath.front();
+ mPath.pop_front();
+ // 362 / 256 is square root of 2, used for walking diagonally
+ mActionTime += (prev.x != next.x && prev.y != next.y)
+ ? mSpeed * 362 / 256 : mSpeed;
+ if (mPath.empty())
+ {
+ // skip last tile center
+ pos = mDst;
+ break;
+ }
+ // position the actor in the middle of the tile for pathfinding purposes
+ pos.x = next.x * 32 + 16;
+ pos.y = next.y * 32 + 16;
+ }
+ while (mActionTime < 100);
+ setPosition(pos);
+
+ mActionTime = mActionTime > 100 ? mActionTime - 100 : 0;
+
if (mAction == WALK || mAction == STAND)
{
mAction = (mActionTime) ? WALK : STAND;
@@ -179,51 +266,50 @@ void Being::performAttack(Damage const &damage, AttackZone const *attackZone)
Effects::show(26, getMap(), Point(attPos.x + attSize.x / 2, attPos.y + attSize.y / 2));
}
- for (MovingObjectIterator
- i(getMap()->getAroundObjectIterator(this, attackZone->range)); i; ++i)
+ for (BeingIterator
+ i(getMap()->getAroundActorIterator(this, attackZone->range)); i; ++i)
{
- MovingObject *o = *i;
- Point opos = o->getPosition();
+ Being *b = *i;
- if (o == this) continue;
+ if (b == this)
+ continue;
- int type = o->getType();
- if (type != OBJECT_CHARACTER && type != OBJECT_MONSTER) continue;
+ const ThingType type = b->getType();
+ if (type != OBJECT_CHARACTER && type != OBJECT_MONSTER)
+ continue;
if (getMap()->getPvP() == PVP_NONE &&
type == OBJECT_CHARACTER &&
getType() == OBJECT_CHARACTER)
continue;
- LOG_DEBUG("Attack Zone:"<<
- attPos.x<<":"<<attPos.y<<
- " "<<
- attSize.x<<"x"<<attSize.y);
- LOG_DEBUG("Defender Zone:"<<
- defPos.x<<":"<<defPos.y<<
- " "<<
- defSize.x<<"x"<<defSize.y);
+ LOG_DEBUG("Attack Zone:" << attPos.x << ":" << attPos.y <<
+ " " << attSize.x << "x" << attSize.y);
+ LOG_DEBUG("Defender Zone:" << defPos.x << ":" << defPos.y <<
+ " " << defSize.x << "x" << defSize.y);
+
+ const Point &opos = b->getPosition();
switch (attackZone->shape)
{
case ATTZONESHAPE_CONE:
if (Collision::diskWithCircleSector(
- opos, o->getSize(),
+ opos, b->getSize(),
ppos, attackZone->range,
attackZone->angle / 2, attackAngle)
)
{
- victims.push_back(static_cast< Being * >(o));
+ victims.push_back(b);
}
break;
case ATTZONESHAPE_RECT:
- defPos.x = opos.x - o->getSize();
- defPos.y = opos.y - o->getSize();
- defSize.x = o->getSize() * 2;
- defSize.y = o->getSize() * 2;
+ defPos.x = opos.x - b->getSize();
+ defPos.y = opos.y - b->getSize();
+ defSize.x = b->getSize() * 2;
+ defSize.y = b->getSize() * 2;
if (Collision::rectWithRect(attPos, attSize, defPos, defSize))
{
- victims.push_back(static_cast< Being * >(o));
+ victims.push_back(b);
}
break;
default:
@@ -319,18 +405,18 @@ void Being::update()
int newHP = oldHP;
int maxHP = getAttribute(BASE_ATTR_HP);
- // regenerate HP
+ // Regenerate HP
if (mAction != DEAD && ++mHpRegenTimer >= TICKS_PER_HP_REGENERATION)
{
mHpRegenTimer = 0;
newHP += getModifiedAttribute(BASE_ATTR_HP_REGEN);
}
- //cap HP at maximum
+ // Cap HP at maximum
if (newHP > maxHP)
{
newHP = maxHP;
}
- //only update HP when it actually changed to avoid network noise
+ // Only update HP when it actually changed to avoid network noise
if (newHP != oldHP)
{
applyModifier(BASE_ATTR_HP, newHP - oldHP);
@@ -352,7 +438,7 @@ void Being::update()
++i;
}
- //check if being died
+ // Check if being died
if (getModifiedAttribute(BASE_ATTR_HP) <= 0 && mAction != DEAD)
{
died();