From 250c1b1becc72585e121dd0c181c9cb1f260bd25 Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Fri, 22 Feb 2008 23:05:04 +0000 Subject: Improved monster AI by making monster only use attacks which have a chance to hit the target and also use them when the optimal combat distance hasn't been reached yet. --- src/game-server/monster.cpp | 46 +++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index 525b3c73..81cf29c2 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -23,6 +23,7 @@ #include "game-server/monster.hpp" #include "game-server/character.hpp" +#include "game-server/collisiondetection.hpp" #include "game-server/item.hpp" #include "game-server/mapcomposite.hpp" #include "game-server/state.hpp" @@ -209,28 +210,45 @@ void Monster::update() } } - // Check if an attack position has been found + // Check if an enemy has been found if (bestAttackTarget) { - // Check if we are there - if (bestAttackPosition == getPosition()) - { - // We are there - let's beat the crap out of the target - setDirection(bestAttackDirection); - MonsterAttacks allAttacks = mSpecy->getAttacks(); + //check which attacks have a chance to hit the target + MonsterAttacks allAttacks = mSpecy->getAttacks(); + MonsterAttacks workingAttacks; //TODO: maybe another container than vector is better - reevaluate when implementing priority - if (!allAttacks.empty()) + for (MonsterAttacks::iterator i = allAttacks.begin(); + i != allAttacks.end(); + i++) + { + int attackAngle = 0; + switch (bestAttackDirection) + { + case DIRECTION_UP: attackAngle = 90; break; + case DIRECTION_DOWN: attackAngle = 270; break; + case DIRECTION_LEFT: attackAngle = 180; break; + case DIRECTION_RIGHT:attackAngle = 0; break; + default: break; + } + if (Collision::diskWithCircleSector( + bestAttackTarget->getPosition(), bestAttackTarget->getSize(), + getPosition(), (*i)->range, (*i)->angle, attackAngle)) { - mCurrentAttack = allAttacks.at(rand()%allAttacks.size()); //TODO: this ignores priority -> fix it - mAttackTime = mCurrentAttack->preDelay + mCurrentAttack->aftDelay; - setAction(ATTACK); - raiseUpdateFlags(UPDATEFLAG_ATTACK); + workingAttacks.push_back((*i)); } } + if (workingAttacks.empty()) + { //when no attack can hit move closer to attack position + setDestination(bestAttackPosition); + } else { - // We aren't there yet - let's move - setDestination(bestAttackPosition); + setDestination(getPosition()); + setDirection(bestAttackDirection); + mCurrentAttack = workingAttacks.at(rand()%workingAttacks.size()); //TODO: this ignores priority -> fix it + mAttackTime = mCurrentAttack->preDelay + mCurrentAttack->aftDelay; + setAction(ATTACK); + raiseUpdateFlags(UPDATEFLAG_ATTACK); } } else -- cgit v1.2.3-60-g2f50