📄 monsterai.cpp
字号:
//////////////////////////////////////////////////////////////////////////////// Filename : MonsterAI.cpp// Written By : excel96// Description : //////////////////////////////////////////////////////////////////////////////#include "MonsterAI.h"#include "Zone.h"#include "Slayer.h"#include "Vampire.h"#include "Monster.h"#include "MonsterInfo.h"#include "EffectManager.h"#include "SkillInfo.h"#include "skill/SkillHandlerManager.h"#include "Directive.h"#include "ZoneUtil.h"#include "Tile.h"#include "MonsterManager.h"#include "MasterLairManager.h"#include "VariableManager.h"#include "Effect.h"#include "Profile.h"#define ABS(X) ((X)>=0)?X:-X//#define __PROFILE_MONSTER__#ifdef __PROFILE_MONSTER__ #define __BEGIN_PROFILE_MONSTER(name) beginProfileEx(name); #define __END_PROFILE_MONSTER(name) endProfileEx(name);#else #define __BEGIN_PROFILE_MONSTER(name) ((void)0); #define __END_PROFILE_MONSTER(name) ((void)0);#endifTPOINT getSafeTile(Zone* pZone, ZoneCoord_t x, ZoneCoord_t y){ TPOINT ptAcid; ptAcid = findSuitablePositionForEffect( pZone, x, y, Effect::EFFECT_CLASS_ACID_SWAMP ); /* TPOINT ptBloody; ptBloody = findSuitablePositionForEffect( pZone, x, y, Effect::EFFECT_CLASS_BLOODY_WALL ); */ return ptAcid;}int getStrongValue(Creature* pCreature){ HP_t currentHP = 0; HP_t maxHP = 0; int strongValue = 0; if (pCreature->isSlayer()) { Slayer* pSlayer = dynamic_cast<Slayer*>(pCreature); currentHP = pSlayer->getHP(ATTR_CURRENT); maxHP = pSlayer->getHP(ATTR_MAX); strongValue = pSlayer->getSTR() + pSlayer->getDEX() + pSlayer->getINT() + pSlayer->getProtection() + pSlayer->getDefense(); } else if (pCreature->isVampire()) { Vampire* pVampire = dynamic_cast<Vampire*>(pCreature); currentHP = pVampire->getHP(ATTR_CURRENT); maxHP = pVampire->getHP(ATTR_MAX); strongValue = pVampire->getSTR() + pVampire->getDEX() + pVampire->getINT() + pVampire->getProtection() + pVampire->getDefense(); } else if (pCreature->isOusters()) { Ousters* pOusters = dynamic_cast<Ousters*>(pCreature); currentHP = pOusters->getHP(ATTR_CURRENT); maxHP = pOusters->getHP(ATTR_MAX); strongValue = pOusters->getSTR() + pOusters->getDEX() + pOusters->getINT() + pOusters->getProtection() + pOusters->getDefense(); } else if (pCreature->isMonster()) { Monster* pMonster = dynamic_cast<Monster*>(pCreature); currentHP = pMonster->getHP(ATTR_CURRENT); maxHP = pMonster->getHP(ATTR_MAX); strongValue = pMonster->getSTR() + pMonster->getDEX() + pMonster->getINT() + pMonster->getProtection() + pMonster->getDefense(); } else return 0; // pCreature HP啊 120捞惑 if (currentHP>=120) { strongValue += 200; } // HP percentage啊 60% 捞惑捞扼搁 if (currentHP*100 >= maxHP*60) { strongValue += 200; } return strongValue;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TPOINT randPos(int ox, int oy, int threshold, Zone* pZone) throw(){ int tx = ox + (rand()%(threshold*2)) - threshold; int ty = oy + (rand()%(threshold*2)) - threshold; if (tx < 0) tx = 0; else if (tx >= pZone->getWidth()) tx = pZone->getWidth() - 1; if (ty < 0) ty = 0; else if (ty >= pZone->getHeight()) ty = pZone->getHeight() - 1; TPOINT pt; pt.x = tx; pt.y = ty; return pt;}//////////////////////////////////////////////////////////////////////////////// 积己磊/家戈磊//////////////////////////////////////////////////////////////////////////////MonsterAI::MonsterAI(Monster* pMonster, uint type) throw(){ __BEGIN_TRY Assert(pMonster != NULL); // by sigi m_pBody = pMonster; m_AIType = type; m_Panic = 5; m_PanicMax = 5; m_Courage = 20; m_CourageMax = 20; m_bDamaged = false; m_LastAction = LAST_ACTION_NONE; m_MoveRule = MOVE_RULE_NORMAL; m_BlockedDir = DIR_NONE; m_WallCount = 0; m_pDirectiveSet = g_pDirectiveSetManager->getDirectiveSet(type); m_pCondChecker[DIRECTIVE_COND_ENEMY_RANGE_MELEE] = checkEnemyRangeMelee; m_pCondChecker[DIRECTIVE_COND_ENEMY_RANGE_MISSILE] = checkEnemyRangeMissile; m_pCondChecker[DIRECTIVE_COND_ENEMY_RANGE_CLOSE] = checkEnemyRangeClose; m_pCondChecker[DIRECTIVE_COND_ENEMY_RANGE_OUT_OF_SIGHT] = checkEnemyRangeOutOfSight; m_pCondChecker[DIRECTIVE_COND_ENEMY_DYING] = checkEnemyDying; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_BLOOD_DRAINED] = checkEnemyNotBloodDrained; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_GREEN_POISONED] = checkEnemyNotGreenPoisoned; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_YELLOW_POISONED] = checkEnemyNotYellowPoisoned; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_DARKBLUE_POISONED] = checkEnemyNotDarkbluePoisoned; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_GREEN_STALKERED] = checkEnemyNotGreenStalkered; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_PARALYZED] = checkEnemyNotParalyzed; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_DOOMED] = checkEnemyNotDoomed; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_BLINDED] = checkEnemyNotBlinded; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_IN_DARKNESS] = checkEnemyNotInDarkness; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_SEDUCTION] = checkEnemyNotSeduction; m_pCondChecker[DIRECTIVE_COND_IM_OK] = checkImOK; m_pCondChecker[DIRECTIVE_COND_IM_DYING] = checkImDying; m_pCondChecker[DIRECTIVE_COND_IM_DAMAGED] = checkImDamaged; m_pCondChecker[DIRECTIVE_COND_IM_HIDING] = checkImHiding; m_pCondChecker[DIRECTIVE_COND_IM_WOLF] = checkImWolf; m_pCondChecker[DIRECTIVE_COND_IM_BAT] = checkImBat; m_pCondChecker[DIRECTIVE_COND_IM_INVISIBLE] = checkImInvisible; m_pCondChecker[DIRECTIVE_COND_IM_WALKING_WALL] = checkImWalkingWall; m_pCondChecker[DIRECTIVE_COND_TIMING_BLOOD_DRAIN] = checkTimingBloodDrain; m_pCondChecker[DIRECTIVE_COND_MASTER_SUMMON_TIMING] = checkMasterSummonTiming; m_pCondChecker[DIRECTIVE_COND_MASTER_NOT_READY] = checkMasterNotReady; m_pCondChecker[DIRECTIVE_COND_IM_IN_BAD_POSITION] = checkImInBadPosition; m_pCondChecker[DIRECTIVE_COND_FIND_WEAK_ENEMY] = checkFindWeakEnemy; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_DEATH] = checkEnemyNotDeath; m_pCondChecker[DIRECTIVE_COND_ENEMY_NOT_HALLUCINATION] = checkEnemyNotHallucination; m_pCondChecker[DIRECTIVE_COND_TIMING_MASTER_BLOOD_DRAIN] = checkTimingMasterBloodDrain; m_pCondChecker[DIRECTIVE_COND_TIMING_DUPLICATE_SELF] = checkTimingDuplicateSelf; m_pCondChecker[DIRECTIVE_COND_ENEMY_RANGE_IN_MISSILE] = checkEnemyRangeInMissile; m_pCondChecker[DIRECTIVE_COND_POSSIBLE_SUMMON_MONSTERS] = checkPossibleSummonMonsters; m_pCondChecker[DIRECTIVE_COND_ENEMY_TILE_NOT_ACID_SWAMP] = checkEnemyTileNotAcidSwamp; m_pCondChecker[DIRECTIVE_COND_ENEMY_ON_AIR] = checkEnemyOnAir; m_pCondChecker[DIRECTIVE_COND_ENEMY_ON_SAFE_ZONE] = checkEnemyOnSafeZone; __END_CATCH}MonsterAI::~MonsterAI() throw(){ __BEGIN_TRY __END_CATCH}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void MonsterAI::addDirective(Directive* pDirective) throw(){ __BEGIN_TRY m_pDirectiveSet->addDirective(pDirective); __END_CATCH}//////////////////////////////////////////////////////////////////////////////// 炼扒 窃荐//////////////////////////////////////////////////////////////////////////////bool MonsterAI::checkCondition(int condition, Creature* pEnemy) throw(){ __BEGIN_TRY Assert(0 <= condition && condition < DIRECTIVE_COND_MAX);// cout << m_pBody->toString() << " check condition " << condition << " to" << pEnemy->toString() << endl; return m_pCondChecker[condition](m_pBody, pEnemy); __END_CATCH}bool MonsterAI::checkDirective(Directive* pDirective, Creature* pEnemy) throw(){ __BEGIN_TRY if (pDirective == NULL) return false; // 牧叼记 府胶飘甫 掘绢郴绊... list<int>& conditionList = pDirective->getConditions(); bool rValue = true; // 炼扒 吝俊 窍唱扼档 父练窍瘤 臼绰 巴捞 乐促搁, // false甫 府畔茄促. list<int>::iterator itr = conditionList.begin(); for (; itr != conditionList.end(); itr++) { if (checkCondition(*itr, pEnemy) == false) { rValue = false; break; } } return rValue; __END_CATCH}//////////////////////////////////////////////////////////////////////////////// 焊烹狼 框流烙//////////////////////////////////////////////////////////////////////////////bool MonsterAI::moveNormal(ZoneCoord_t ex, ZoneCoord_t ey, ZoneCoord_t& nx, ZoneCoord_t& ny, Dir_t& ndir) throw(){ //Zone* pZone = m_pBody->getZone(); Dir_t bestDir = DIR_NONE; Dir_t curDir = m_pBody->getDir(); //////////////////////////////////////////////////////////// // 格利瘤痢栏肺 氢窍绰 弥急狼 规氢阑 茫绰促. //////////////////////////////////////////////////////////// if (m_pBody->getX() < ex) { if (m_pBody->getY() < ey) bestDir = RIGHTDOWN; else if (m_pBody->getY() > ey) bestDir = RIGHTUP; else bestDir = RIGHT;// m_pBody->getY() == ey } else if (m_pBody->getX() > ex) { if (m_pBody->getY() < ey) bestDir = LEFTDOWN; else if (m_pBody->getY() > ey) bestDir = LEFTUP; else bestDir = LEFT;// m_pBody->getY() == ey } else { if (m_pBody->getY() < ey) bestDir = DOWN; // m_pBody->getX() == ex else if (m_pBody->getY() > ey) bestDir = UP; else bestDir = DIR_NONE; // m_pBody->getY() == ey } //////////////////////////////////////////////////////////// // search surrounding tiles //////////////////////////////////////////////////////////// int diffLevel = 0; // 规氢苞 规氢 荤捞狼 瞒捞甫 唱鸥辰促. diffLevel == 1 俊辑, diff == 0 捞扁 困秦辑 // 0 栏肺 檬扁拳秦具 茄促. 弊犯瘤 臼栏搁, garbage 蔼栏肺 牢秦 坷幅啊 唱霸 等促. int diff = 0; // 促澜 规氢捞 惯斑登菌绰啊? bool found = false; // 快急 bestDir 何磐 眉农秦夯促. unsigned type 捞 登绢辑绰 救等促. ndir = bestDir; // 促澜 谅钎 nx = m_pBody->getX() + dirMoveMask[ndir].x; ny = m_pBody->getY() + dirMoveMask[ndir].y; bool bBlocked[DIR_MAX] = { false, }; const Dir_t DIR_MAX_1 = DIR_MAX - 1; // bestDir 规氢捞 阜囚 乐促搁, previous Dir 规氢阑 扁霖栏肺 +- 窍搁辑 眉农茄促. // 捞锭 粮狼 版拌甫 逞绢辑绰瘤 眉农甫 秦具 茄促. bool bCanMove = m_pBody->canMove(nx,ny); // 付胶磐牢 版快俊绰 官蹿俊 救 亮篮霸 绝绢具 茄促. - -; by sigi. 2002.9.12 /* if (bCanMove && m_pBody->isMaster()) { Tile& tile = m_pBody->getZone()->getTile(nx, ny); if (tile.hasEffect()) { if (tile.getEffect(Effect::EFFECT_CLASS_ACID_SWAMP)!=NULL && tile.getEffect(Effect::EFFECT_CLASS_GROUND_ATTACK)!=NULL) { } else bCanMove = false; } } */ if (!bCanMove) { bBlocked[ndir] = true; // best direction捞 寒捞扼搁 促澜何磐 寒鸥扁甫 茄促. // 冠零唱 hide吝捞 酒聪绢具 茄促. if (!m_pBody->isBlockedByCreature(nx,ny) && !m_pBody->isFlag(Effect::EFFECT_CLASS_TRANSFORM_TO_BAT) && !m_pBody->isFlag(Effect::EFFECT_CLASS_HIDE)) { setMoveRule( MOVE_RULE_RIGHTWALL ); // 咯扁搏 喊 狼固绝促. m_BlockedDir = bestDir; // 捞锅 畔俊绰 弊成 哎 规氢阑 搬沥窍搁 等促. } while (true) { // 弥檬老 版快, diffLevel == 1 捞 等促. 捞绰 m_pBody->getDir() 规氢阑 眉农窍扼绰 舵捞促. diffLevel ++; // 利例茄 规氢阑 茫疽芭唱, 歹捞惑 茫阑 荐 绝促搁 场辰促. if (found || diffLevel > 8) break; //////////////////////////////////////////////////////////// // diffLevel 阑 2 肺 唱传 蔼捞 鞍促绰 舵篮, 辑肺 措莫登绰 // 规氢捞扼绰 舵捞促. 弊 吝 娄荐甫 父唱搁 弥檬肺 diff 甫 // 拌魂秦辑 茄率 规氢阑 眉农窍哥, 圈荐甫 父唱搁 捞傈 风橇俊辑 // 馆措祈 规氢捞 眉农登菌促绰 舵捞骨肺, 拌魂等 diff 狼 // 澜荐甫 荤侩秦辑 促弗祈 规氢阑 眉农窍搁 登摆促. //////////////////////////////////////////////////////////// if ((diffLevel & 0x00000001) == 0) // % 2 牢单.. 官插寸.. せせ by sigi { //diff = (int)(diffLevel >> 1) * (bSelectLeft ? 1 : -1); diff = diffLevel >> 1; Dir_t dir1 = (m_pBody->getDir() + diff) & DIR_MAX_1; Dir_t dir2 = (m_pBody->getDir() + DIR_MAX - diff) & DIR_MAX_1; // bestDir俊 啊鳖款 率阑 刚历 急琶秦焊磊. if ((abs(ndir+DIR_MAX-dir1) & DIR_MAX_1) < (abs(ndir+DIR_MAX-dir2) & DIR_MAX_1)) { ndir = dir1; } else { diff = -diff; ndir = dir2; } } else ndir = m_pBody->getDir() + DIR_MAX - diff; //////////////////////////////////////////////////////////// // ndir 捞 overflow, underflow 且 版快 蔼阑 焊沥秦拎具 茄促. // overflow : -1 -> 7 , -2 -> 6 , -3 -> 5 , ... // underflow : 8 -> 0 , 9 -> 1 , 10 -> 2 , ... //////////////////////////////////////////////////////////// //if (ndir >= DIR_MAX) // overflow //{ // ndir = Directions(DIR_MAX - ndir); //} //else if (ndir < 0) // underflow //{ // ndir = Directions(DIR_MAX + ndir); //} ndir &= DIR_MAX_1; // 促澜 谅钎甫 备茄促. nx = m_pBody->getX() + dirMoveMask[ndir].x; ny = m_pBody->getY() + dirMoveMask[ndir].y; // 促澜 规氢捞 厚菌栏搁, 风橇甫 狐廉唱哎 荐 乐促. // 捞锭 粮狼 版拌甫 逞绢辑绰瘤 眉农甫 秦具 茄促. if (m_pBody->canMove(nx,ny)) { // 付胶磐牢 版快俊绰 官蹿俊 救 亮篮霸 绝绢具 茄促. - -; by sigi. 2002.9.12 /* if (m_pBody->isMaster()) { Tile& tile = m_pBody->getZone()->getTile(nx, ny); if (tile.hasEffect()) { if (tile.getEffect(Effect::EFFECT_CLASS_ACID_SWAMP)!=NULL && tile.getEffect(Effect::EFFECT_CLASS_GROUND_ATTACK)!=NULL) { found = true; } } } else */ { found = true; } } bBlocked[ndir] = true; }//while } else found = true; // 谅荐/快荐甫 犬角洒 搬沥秦霖促. if (found && m_MoveRule!=MOVE_RULE_NORMAL) { bool leftWall = bBlocked[(ndir+2) & DIR_MAX_1]; bool rightWall = bBlocked[(ndir+DIR_MAX-2) & DIR_MAX_1]; // 笛 促 阜躯栏搁 规氢俊 蝶扼辑.. 荤官荤官 if (leftWall && rightWall) { if (ndir>curDir && ndir<curDir+4 || curDir>4 && (ndir>curDir || ndir<curDir-4)) { setMoveRule( MOVE_RULE_RIGHTWALL ); //cout << "set RightWall : " << (int)curDir << " to " << (int)ndir << " - " << (int)m_BlockedDir << " - " << m_pBody->getName() << endl; } else { setMoveRule( MOVE_RULE_LEFTWALL ); //cout << "set LeftWall : " << (int)curDir << " to " << (int)ndir << " - " << (int)m_BlockedDir << " - " << m_pBody->getName() << endl; } } // 谅荐过 利侩 else if (leftWall) { setMoveRule( MOVE_RULE_LEFTWALL ); //cout << "set LeftWall : " << (int)curDir << " to " << (int)ndir << " - " << (int)m_BlockedDir << " - " << m_pBody->getName() << endl; } // 快荐过 利侩 else if (rightWall) { setMoveRule( MOVE_RULE_RIGHTWALL ); //cout << "set RightWall : " << (int)curDir << " to " << (int)ndir << " - " << (int)m_BlockedDir << " - " << m_pBody->getName() << endl; } // 寒捞 绝促搁 寒鸥扁 救茄促. else { setMoveRule( MOVE_RULE_NORMAL ); } } else { setMoveRule( MOVE_RULE_NORMAL ); } return found;}//////////////////////////////////////////////////////////////////////////////// 寒鸥绊 捞悼窍扁//////////////////////////////////////////////////////////////////////////////bool MonsterAI::moveWall(ZoneCoord_t ex, ZoneCoord_t ey, ZoneCoord_t& nx, ZoneCoord_t& ny, Dir_t& ndir, bool bLeft) throw(){ //Zone* pZone = m_pBody->getZone(); //cout << "MoveWall[" << (bLeft? "Left" : "Right") << "] : " << m_pBody->getName() << endl; //////////////////////////////////////////////////////////// // search surrounding tiles //////////////////////////////////////////////////////////// // 快急 格钎 规氢栏肺 啊杭妨绊 茄促. ndir = m_BlockedDir; // 促澜 谅钎 nx = m_pBody->getX() + dirMoveMask[ndir].x; ny = m_pBody->getY() + dirMoveMask[ndir].y; m_WallCount++; // 格钎茄 规氢栏肺 哎 荐 乐绰 版快 bool bCanMove = m_pBody->canMove(nx,ny); // 付胶磐牢 版快俊绰 官蹿俊 救 亮篮霸 绝绢具 茄促. - -; by sigi. 2002.9.12 /* if (bCanMove && m_pBody->isMaster()) { Tile& tile = m_pBody->getZone()->getTile(nx, ny); if (tile.hasEffect()) { if (tile.getEffect(Effect::EFFECT_CLASS_ACID_SWAMP)!=NULL && tile.getEffect(Effect::EFFECT_CLASS_GROUND_ATTACK)!=NULL) { } else bCanMove = false; } } */ if (bCanMove) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -