diff options
author | David Athay <ko2fan@gmail.com> | 2009-05-18 18:42:33 +0100 |
---|---|---|
committer | David Athay <ko2fan@gmail.com> | 2009-05-18 18:42:33 +0100 |
commit | c3c5ff134ac2e31560b421d125b35a9a73a25e5c (patch) | |
tree | deeff273aa8f93f89ee9d4eba59cc1b6fdca1d4b /src | |
parent | 9bf793b93df88fb38c2f29d5ec7643d11899ef2f (diff) | |
download | manaserv-c3c5ff134ac2e31560b421d125b35a9a73a25e5c.tar.gz manaserv-c3c5ff134ac2e31560b421d125b35a9a73a25e5c.tar.bz2 manaserv-c3c5ff134ac2e31560b421d125b35a9a73a25e5c.tar.xz manaserv-c3c5ff134ac2e31560b421d125b35a9a73a25e5c.zip |
Added target combat
Diffstat (limited to 'src')
-rw-r--r-- | src/game-server/being.cpp | 139 | ||||
-rw-r--r-- | src/game-server/being.hpp | 15 | ||||
-rw-r--r-- | src/game-server/character.cpp | 9 | ||||
-rw-r--r-- | src/game-server/gamehandler.cpp | 10 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 2 |
5 files changed, 41 insertions, 134 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index a1991551..b43b789a 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -33,6 +33,7 @@ Being::Being(ThingType type): Actor(type), mAction(STAND), + mTarget(NULL), mSpeed(0), mDirection(0), mHpRegenTimer(0) @@ -105,6 +106,9 @@ void Being::died() // dead beings stay where they are clearDestination(); + // reset target + mTarget = NULL; + for (Listeners::iterator i = mListeners.begin(), i_end = mListeners.end(); i != i_end;) { @@ -218,138 +222,19 @@ int Being::directionToAngle(int direction) } } -void Being::performAttack(const Damage &damage, const AttackZone *attackZone) +void Being::performAttack(const Damage &damage) { - Point ppos = getPosition(); - const int attackAngle = directionToAngle(getDirection()); - - std::list<Being *> victims; - LOG_DEBUG("Direction:"<<getDirection()<< - " range:"<<attackZone->range<< - " angle:"<<attackZone->angle); - - Point attPos, attSize, defPos, defSize; - if (attackZone->shape == ATTZONESHAPE_RECT) - { - if (getDirection() == DIRECTION_UP) - { - attPos.x = ppos.x - attackZone->angle; - attPos.y = ppos.y - attackZone->range; - attSize.x = attackZone->angle * 2; - attSize.y = attackZone->range; - } - if (getDirection() == DIRECTION_DOWN) - { - attPos.x = ppos.x - attackZone->angle; - attPos.y = ppos.y; - attSize.x = attackZone->angle * 2; - attSize.y = attackZone->range; - } - if (getDirection() == DIRECTION_RIGHT) - { - attPos.x = ppos.x; - attPos.y = ppos.y - attackZone->angle; - attSize.x = attackZone->range; - attSize.y = attackZone->angle * 2; - } - if (getDirection() == DIRECTION_LEFT) - { - attPos.x = ppos.x - attackZone->range; - attPos.y = ppos.y - attackZone->angle; - attSize.x = attackZone->range; - attSize.y = attackZone->angle * 2; - } - /* debug effect to see when and where the server pictures the attack - should - * be moved to the client side when the attack detection works statisfactory. - */ - Effects::show(26, getMap(), Point(attPos.x + attSize.x / 2, attPos.y + attSize.y / 2)); - } + " Target:"<<mTarget->getName()); - for (BeingIterator - i(getMap()->getAroundActorIterator(this, attackZone->range)); i; ++i) - { - Being *b = *i; - - if (b == this) - continue; + if (!mTarget || mTarget == this || mTarget->getAction() == Being::DEAD || !mTarget->canFight()) + return; - 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); - - const Point &opos = b->getPosition(); - - switch (attackZone->shape) - { - case ATTZONESHAPE_CONE: - if (Collision::diskWithCircleSector( - opos, b->getSize(), - ppos, attackZone->range, - attackZone->angle / 2, attackAngle) - ) - { - victims.push_back(b); - } - break; - case ATTZONESHAPE_RECT: - 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(b); - } - break; - default: - break; - } - } + if (getMap()->getPvP() == PVP_NONE && mTarget->getType() == OBJECT_CHARACTER && + getType() == OBJECT_CHARACTER) + return; - if (attackZone->multiTarget) - { - // damage everyone - for (std::list<Being *>::iterator i = victims.begin(); - i != victims.end(); - i++) - { - (*i)->damage(this, damage); - } - } - else - { - // find the closest and damage this one - Being* closestVictim = NULL; - int closestDistance = INT_MAX; - for (std::list<Being *>::iterator i = victims.begin(); - i != victims.end(); - i++) - { - Point opos = (*i)->getPosition(); - int distance = abs(opos.x - ppos.x) + abs(opos.y - ppos.y); - /* not using pythagoras here is a) faster and b) results in more natural - target selection because targets closer to the center line of the - attack angle are prioritized - */ - if (distance < closestDistance) - { - closestVictim = (*i); - closestDistance = distance; - } - } - if (closestVictim) closestVictim->damage(this, damage); - } + mTarget->damage(this, damage); } void Being::setAction(Action action) diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp index 92957096..96af1092 100644 --- a/src/game-server/being.hpp +++ b/src/game-server/being.hpp @@ -205,7 +205,7 @@ class Being : public Actor /** * Performs an attack. */ - void performAttack(const Damage &, const AttackZone *attackZone); + void performAttack(const Damage &); /** * Sets the current action. @@ -278,10 +278,23 @@ class Being : public Actor */ static int directionToAngle(int direction); + /** + * Get Target + */ + Being* getTarget() const + { return mTarget; } + + /** + * Set Target + */ + void setTarget(Being *target) + { mTarget = target; } + protected: static const int TICKS_PER_HP_REGENERATION = 100; Action mAction; std::vector< Attribute > mAttributes; + Being *mTarget; private: Being(const Being &rhs); diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index f9a9b588..e17abc2b 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -116,7 +116,7 @@ void Character::update() void Character::perform() { - if (mAction != ATTACK || mActionTime > 0) return; + if (mAction != ATTACK || mActionTime > 0 || mTarget == NULL) return; mActionTime = 1000; mAction = STAND; @@ -141,13 +141,13 @@ void Character::perform() // weapon fighting const ItemModifiers &mods = ic->getModifiers(); damage.element = mods.getValue(MOD_ELEMENT_TYPE); - performAttack(damage, ic->getAttackZone()); + performAttack(damage); } else { // No-weapon fighting. damage.element = ELEMENT_NEUTRAL; - performAttack(damage, &UNARMED_ATTACK_ZONE); + performAttack(damage); } } @@ -170,6 +170,9 @@ void Character::respawn() setAction(STAND); mAttributes[BASE_ATTR_HP].mod = -mAttributes[BASE_ATTR_HP].base + 1; modifiedAttribute(BASE_ATTR_HP); + + // reset target + mTarget = NULL; } void Character::useSpecial(int id) diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp index d4b13e74..68af5314 100644 --- a/src/game-server/gamehandler.cpp +++ b/src/game-server/gamehandler.cpp @@ -354,8 +354,14 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message) { LOG_DEBUG("Character " << computer.character->getPublicID() << " attacks"); - computer.character->setDirection(message.readByte()); - computer.character->setAction(Being::ATTACK); + int id = message.readShort(); + Actor *o = findActorNear(computer.character, id); + if (o && o->getType() != OBJECT_NPC) + { + Being *being = static_cast<Being*>(o); + computer.character->setTarget(being); + computer.character->setAction(Being::ATTACK); + } } break; case PGMSG_USE_SPECIAL: diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 9c5fb044..eaab71f2 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -123,7 +123,7 @@ void Monster::perform() damage.cth = getModifiedAttribute(BASE_ATTR_HIT); damage.element = mCurrentAttack->element; damage.type = mCurrentAttack->type; - performAttack(damage, &mCurrentAttack->attackZone); + performAttack(damage); } if (!mAttackTime) { |