void Monster::onThink(uint32_t interval) { Creature::onThink(interval); if(despawn()){ g_game.removeCreature(this, true); setIdle(true); } else{ updateIdleStatus(); if(!isIdle && !semiIdle){ addEventWalk(); if(isSummon()){ if(!attackedCreature){ if(getMaster() && getMaster()->getAttackedCreature()){ ///This happens if the monster is summoned during combat selectTarget(getMaster()->getAttackedCreature()); } else if(getMaster() != followCreature){ //Our master has not ordered us to attack anything, lets follow him around instead. setFollowCreature(getMaster()); } } else if(attackedCreature == this){ setFollowCreature(NULL); } else if(followCreature != attackedCreature){ //This happens just after a master orders an attack, so lets follow it aswell. setFollowCreature(attackedCreature); } } else if(!targetList.empty()){ if(!followCreature || !hasFollowPath){ searchTarget(); } else if(isFleeing()){ if(attackedCreature && !canUseAttack(getPosition(), attackedCreature)){ searchTarget(TARGETSEARCH_ATTACKRANGE); } } } onThinkTarget(interval); onThinkYell(interval); onThinkDefense(interval); } } }
void DefendBehavior::doMove() { vector<otank_t> otherTanks; connection->get_othertanks(&otherTanks); vector<tank_t> myTanks; connection->get_mytanks(&myTanks); tank_t me = myTanks[tankNumber]; // Check if the currentTarget needs to be changed selectTarget(&otherTanks, me); if(currentTarget == NULL) { return; } // Aim and fire Point targetLocation = currentTarget->getCurrentPoint(); double distanceToEnemy = SearchTools::distance(me.pos[0], me.pos[1], targetLocation.x, targetLocation.y); double timeForShotToHit = distanceToEnemy / SHOTSPEED; Point futureLocation = currentTarget->getTargetPoint(timeForShotToHit); double targetAngle = atan2((futureLocation.y - me.pos[1]) , (futureLocation.x - me.pos[0])); double angularVelocity = pdController.calculateAngularVelocity(me.angle, targetAngle); connection->speed(tankNumber, 0); connection->angvel(tankNumber, angularVelocity * 4);// / abs(angularVelocity)); bool safeToFire = true; for(int i = 0; i < myTanks.size();i++) { if (i == tankNumber) continue; double friendAngle = atan2((myTanks[i].pos[1] - me.pos[1]), (myTanks[i].pos[0] - me.pos[0])); if (abs(differenceBetweenTwoAngles(me.angle, friendAngle)) < .01 && SearchTools::distance(myTanks[i].pos[0], myTanks[i].pos[1], me.pos[0], me.pos[1]) < 400) { safeToFire = false; } } if(abs(differenceBetweenTwoAngles(me.angle, targetAngle)) < .01 && safeToFire) { connection->shoot(tankNumber); } }
bool Monster::challengeCreature(Creature* creature) { if(isSummon()) return false; else { bool result = selectTarget(creature); if(result) { targetChangeCooldown = 8000; targetChangeTicks = 0; } return result; } return false; }
bool Actor::challengeCreature(Creature* creature) { if(isPlayerSummon()){ return false; } else{ bool result = selectTarget(creature); if(result){ targetChangeCooldown = 8000; targetChangeTicks = 0; } return result; } return false; }
void UnitFiring::autoFire() { mTargetAquired = selectTarget(); if (!mTargetAquired) mAimReset = true; if (mTargetAquired) { mTargetPosition = predictTargetPosition( const_cast<Unit*>(mTargetUnit)); aim(); if (isAimed()) { fire(); } } else if (mAimReset) { resetAim(); } else { freezeAim(); } theApp->displayUnitReload(this, getRemainingReloadTime()); }
void Piece::markPosition(int diagId, int diagonal, map<int,int>* values, vector<Object*> board){ if (diagId < 0 || diagId >= BOARD_SIZE) return; if (board[diagId] != NULL) { if (diagId % (int)sqrt(BOARD_SIZE) == 0 || diagId % (int)sqrt(BOARD_SIZE) == (int)sqrt(BOARD_SIZE) - 1) return; if (diagId / (int)sqrt(BOARD_SIZE) == 0 || diagId / (int)sqrt(BOARD_SIZE) == (int)sqrt(BOARD_SIZE) - 1) return; selectTarget(diagId,diagonal,values,board); } else values->insert(pair<int,int>(diagId,-1)); }
void ComponentAIBomber::deleteObject(GameObject* targetObject) { if(targetObject->getTag() == GameObject::MAIN_PLAYER) { std::list<GameObject*>::iterator it; if(!players.empty()) { for (it=players.begin(); it!=players.end(); ++it) { if( *it == targetObject) { players.erase(it); break; } } } } else { std::list<GameObject*>::iterator it; for (it=onVisionList.begin(); it!=onVisionList.end(); ++it) { if( *it == targetObject) { //Es el primero if(*it == onVisionList.front() && shooting) { messageStopAIM(); shooting = false; } onVisionList.erase(it); target = NULL; watching = false; selectTarget(); break; } } } }
bool GameScreen::select(sf::Vector2i s) { if(m_selectedPiece != NULL_SQUARE) //if a piece is selected { if(m_selectedTarget != NULL_SQUARE) //if an enemy piece is selected { if(!m_highlighter.isHighlighted(s)) //square isn't selectable unselect(); else //square is selectable { bool res = m_game.displace(toSquare(m_selectedPiece), toSquare(s), toSquare(m_selectedTarget), false); unselect(); return res; } } else //no enemy piece selected { if(!m_highlighter.isHighlighted(s)) //square isn't selectable unselect(); else //square is selectable { PiecePtr p = m_game[toSquare(s)]; if (p == nullptr) //no piece here { bool res = m_game.move(toSquare(m_selectedPiece), toSquare(s), false); unselect(); return res; } else selectTarget(s); } } } else //no piece is selected { PiecePtr p = m_game[toSquare(s)]; if (p != nullptr && p->getColor() == m_game.getActivePlayer()) //there is a piece and it can be selected selectPiece(s); } return false; }
void ComponentAIBomber::addObject(GameObject* gameObject) { if(gameObject->getTag() != GameObject::MAIN_PLAYER) { onVisionList.push_back(gameObject); if(onVisionList.size() > 1) { onVisionList.sort(GameObject::selectPrefEnemy); } if(onVisionList.front() == gameObject) { selectTarget(); } } else { players.push_back(gameObject); } }
void Monster::onCreatureMove(const Creature* creature, const Tile* newTile, const Position& newPos, const Tile* oldTile, const Position& oldPos, bool teleport) { Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport); if(creature == this) { if(isSummon()) isMasterInRange = canSee(getMaster()->getPosition()); updateTargetList(); updateIdleStatus(); } else { bool canSeeNewPos = canSee(newPos); bool canSeeOldPos = canSee(oldPos); if(canSeeNewPos && !canSeeOldPos) onCreatureEnter(const_cast<Creature*>(creature)); else if(!canSeeNewPos && canSeeOldPos) onCreatureLeave(const_cast<Creature*>(creature)); if(canSeeNewPos && isSummon() && getMaster() == creature) isMasterInRange = true; //Turn the summon on again updateIdleStatus(); if(!followCreature && !isSummon()) { //we have no target lets try pick this one if(isOpponent(creature)) selectTarget(const_cast<Creature*>(creature)); } } }
TextureOgl::TextureOgl( const Description &description ) : _description( description ), _texelDescription( selectTexelDescription(description.format) ), _target( selectTarget(description.layout) ) { validateDescription(); ScopeTextureBinding scopeTextureBinding( _target, _texture ); const unsigned int levelsMaximum = getMipLevelsMaximum( _description ); const unsigned int levels = _description.mipLevels == CompleteMipMap ? levelsMaximum : _description.mipLevels; storm_assert( levels <= levelsMaximum ); if( _description.mipLevels == CompleteMipMap ) _description.mipLevels = levels; switch( _description.layout ) { case Layout::Separate1d: ::glTexStorage1D( _target, levels, _texelDescription.internalFormat, description.width ); checkResult( "::glTexStorage1D" ); break; case Layout::Separate2d: case Layout::CubeMap: ::glTexStorage2D( _target, levels, _texelDescription.internalFormat, description.width, description.height ); checkResult( "::glTexStorage2D" ); break; case Layout::Separate3d: ::glTexStorage3D( _target, levels, _texelDescription.internalFormat, description.width, description.height, description.depth ); checkResult( "::glTexStorage3D" ); break; case Layout::Layered1d: ::glTexStorage2D( _target, levels, _texelDescription.internalFormat, description.width, description.layers ); checkResult( "::glTexStorage2D" ); break; case Layout::Layered2d: ::glTexStorage3D( _target, levels, _texelDescription.internalFormat, description.width, description.height, description.layers ); checkResult( "::glTexStorage3D" ); break; case Layout::Separate2dMsaa: ::glTexStorage2DMultisample( _target, description.texelSamples, _texelDescription.internalFormat, description.width, description.height, GL_TRUE ); checkResult( "::glTexStorage2DMultisample" ); break; case Layout::Layered2dMsaa: ::glTexStorage3DMultisample( _target, description.texelSamples, _texelDescription.internalFormat, description.width, description.height, description.layers, GL_TRUE ); checkResult( "::glTexStorage3DMultisample" ); break; default: throwNotImplemented(); } }
void doPlayer(void) { self = player; rechargeBoostECM(); if (game.currentMission->challengeData.isChallenge) { applyRestrictions(); } if (player->alive == ALIVE_ALIVE && player->systemPower > 0) { handleKeyboard(); handleMouse(); handleSuspicionLevel(); if (!player->target || player->target->health <= 0 || player->target->systemPower <= 0 || targetOutOfRange()) { selectTarget(); } } player->angle = ((int)player->angle) % 360; if (player->health <= 0 && battle.status == MS_IN_PROGRESS) { if (game.currentMission->challengeData.isChallenge) { if (!game.currentMission->challengeData.allowPlayerDeath) { updateDeathStats(); failMission(); } } else if (!battle.isEpic) { updateDeathStats(); failMission(); } else if (player->health == -FPS) { updateDeathStats(); updateCondition("PLAYER", TT_DESTROY); if (battle.status == MS_IN_PROGRESS) { initPlayerSelect(); } } } if (battle.status == MS_IN_PROGRESS) { selectMissionTarget(); } if (dev.playerUnlimitedMissiles) { player->missiles = 999; } /* really only used in challenge mode */ if (player->systemPower <= 0 && battle.status == MS_IN_PROGRESS) { if (game.currentMission->challengeData.isChallenge) { addHudMessage(colors.red, _("Challenge Failed!")); failMission(); } } if (battle.boostTimer == (int)BOOST_FINISHED_TIME) { deactivateBoost(); } }
static void handleKeyboard(void) { if (battle.status == MS_IN_PROGRESS) { if (isControl(CONTROL_BOOST) && player->speed > 0) { if (battle.boostTimer == BOOST_RECHARGE_TIME) { playSound(SND_BOOST); activateBoost(); } else { playSound(SND_GUI_DENIED); } clearControl(CONTROL_BOOST); } if (isControl(CONTROL_TARGET)) { selectTarget(); clearControl(CONTROL_TARGET); } if (isControl(CONTROL_ECM)) { if (battle.ecmTimer == ECM_RECHARGE_TIME) { playSound(SND_ECM); activateECM(); } else { playSound(SND_GUI_DENIED); } clearControl(CONTROL_ECM); } if (isControl(CONTROL_BRAKE)) { applyFighterBrakes(); } if (isControl(CONTROL_GUNS)) { switchGuns(); clearControl(CONTROL_GUNS); } if (isControl(CONTROL_RADAR)) { cycleRadarZoom(); clearControl(CONTROL_RADAR); } if (isControl(CONTROL_MISSILE)) { preFireMissile(); clearControl(CONTROL_MISSILE); } } else { applyFighterBrakes(); } }
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/) { #ifdef __DEBUG__ std::clog << "Searching target... " << std::endl; #endif std::list<Creature*> resultList; const Position& myPos = getPosition(); for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it) { if(followCreature != (*it) && isTarget(*it) && (searchType == TARGETSEARCH_RANDOM || canUseAttack(myPos, *it))) resultList.push_back(*it); } switch(searchType) { case TARGETSEARCH_NEAREST: { Creature* target = NULL; int32_t range = -1; for(CreatureList::iterator it = resultList.begin(); it != resultList.end(); ++it) { int32_t tmp = std::max(std::abs(myPos.x - (*it)->getPosition().x), std::abs(myPos.y - (*it)->getPosition().y)); if(range >= 0 && tmp >= range) continue; target = *it; range = tmp; } if(target && selectTarget(target)) return target; break; } default: { if(!resultList.empty()) { CreatureList::iterator it = resultList.begin(); std::advance(it, random_range(0, resultList.size() - 1)); #ifdef __DEBUG__ std::clog << "Selecting target " << (*it)->getName() << std::endl; #endif return selectTarget(*it); } if(searchType == TARGETSEARCH_ATTACKRANGE) return false; break; } } //lets just pick the first target in the list for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it) { if(followCreature == (*it) || !selectTarget(*it)) continue; #ifdef __DEBUG__ std::clog << "Selecting target " << (*it)->getName() << std::endl; #endif return true; } return false; }
void Monster::onCreatureMove(Creature* creature, const Tile* newTile, const Position& newPos, const Tile* oldTile, const Position& oldPos, bool teleport) { Creature::onCreatureMove(creature, newTile, newPos, oldTile, oldPos, teleport); if (mType->info.creatureMoveEvent != -1) { // onCreatureMove(self, creature, oldPosition, newPosition) LuaScriptInterface* scriptInterface = mType->info.scriptInterface; if (!scriptInterface->reserveScriptEnv()) { std::cout << "[Error - Monster::onCreatureMove] Call stack overflow" << std::endl; return; } ScriptEnvironment* env = scriptInterface->getScriptEnv(); env->setScriptId(mType->info.creatureMoveEvent, scriptInterface); lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.creatureMoveEvent); LuaScriptInterface::pushUserdata<Monster>(L, this); LuaScriptInterface::setMetatable(L, -1, "Monster"); LuaScriptInterface::pushUserdata<Creature>(L, creature); LuaScriptInterface::setCreatureMetatable(L, -1, creature); LuaScriptInterface::pushPosition(L, oldPos); LuaScriptInterface::pushPosition(L, newPos); if (scriptInterface->callFunction(4)) { return; } } if (creature == this) { if (isSummon()) { isMasterInRange = canSee(getMaster()->getPosition()); } updateTargetList(); updateIdleStatus(); } else { bool canSeeNewPos = canSee(newPos); bool canSeeOldPos = canSee(oldPos); if (canSeeNewPos && !canSeeOldPos) { onCreatureEnter(creature); } else if (!canSeeNewPos && canSeeOldPos) { onCreatureLeave(creature); } if (canSeeNewPos && isSummon() && getMaster() == creature) { isMasterInRange = true; //Follow master again } updateIdleStatus(); if (!isSummon()) { if (followCreature) { const Position& followPosition = followCreature->getPosition(); const Position& position = getPosition(); int32_t offset_x = Position::getDistanceX(followPosition, position); int32_t offset_y = Position::getDistanceY(followPosition, position); if ((offset_x > 1 || offset_y > 1) && mType->info.changeTargetChance > 0) { Direction dir = getDirectionTo(position, followPosition); const Position& checkPosition = getNextPosition(dir, position); Tile* tile = g_game.map.getTile(checkPosition); if (tile) { Creature* topCreature = tile->getTopCreature(); if (topCreature && followCreature != topCreature && isOpponent(topCreature)) { selectTarget(topCreature); } } } } else if (isOpponent(creature)) { //we have no target lets try pick this one selectTarget(creature); } } } }
void Robot::planAction(void) { ownTime_ms_delta_t hurryUp = 1000*60*11; // If it's time to abandon everything else and get current targets to the goal static ownTime_ms_delta_t explRollStartTime = 0; static ownTime_ms_delta_t hidasprkl = 0; if (!manual.enabled) { if(statistics.taskStartTime == 0) statistics.taskStartTime = ownTime_get_ms(); SLAM::RobotLocation p = slam.getCurrentMapData().getRobotLocation(); std::cout << "PLANNER: ROBOT LOCATION " << p.x << " " << p.y << " " << p.theta << std::endl; switch (taskState) { case START: // roll around to discover empty areas if (!motionControl.rollStart(p)) taskState = EXPLORE; break; case EXPLORE: // seek unexplored areas until targets visible if (ownTime_get_ms_since(hidasprkl) >= 5000) { hidasprkl = ownTime_get_ms(); updateTargets(); } if (targets.size()) { if (motionControl.running()) motionControl.stop(); taskState = GO_TO_TARGET; selectTarget(); navigateTarget(); } else { if (!motionControl.iterate(p) && explRollStartTime == 0) { explRollStartTime = ownTime_get_ms(); motionControl.setCtrl(0, 1.0 / 10 * M_PI); } else if (explRollStartTime != 0 && ownTime_get_ms_since(explRollStartTime) > 3000) { motionControl.setCtrl(0, 0); SLAM::Location to(navigation.farthest()); explRollStartTime = 0; std::cout << "PLANNER: explore to farthest " << to.x << " " << to.y << std::endl; navigation.solveTo(to); navigate(); //explore(); } } break; case GO_TO_TARGET: // Move near the nearest target to open the hatch if (motionControl.routeLeft() < HATCH_OPEN_DISTANCE) { if (approachStarted < 1) { approachStarted = ownTime_get_ms(); break; } camera.rotateNear(); if(ownTime_get_ms_since(approachStarted) < 1000) { if (motionControl.running()) { motionControl.stop(); } break; } servoControl.setHatch(false); navigateTarget(); approachStarted = 0; taskState = APPROACH_PICK_UP; } motionControl.iterate(p); break; case APPROACH_PICK_UP: // Move on close to target if (!motionControl.iterate(p)) { float clear = navigation.wallClearance(p); float walk = clear < PICKUPWALK ? clear : PICKUPWALK; navigation.solveTo(SLAM::Location(p.x + cos(p.theta) * walk, p.y + sin(p.theta) * walk)); navigate(); taskState = PICK_UP; } break; case GO_RETURN_TO_GOAL: // Try to find a route to the goal -- if cannot, explore more ownSleep_ms(1000); updateTargets(); if (navigation.solveTo(SLAM::Location(0, 0))) { navigate(); taskState = RETURN_TO_GOAL; } else { taskState = EXPLORE; } break; case RETURN_TO_GOAL: // Going to goal if (!motionControl.iterate(p)) { float clear = navigation.wallClearance(p); float walk = clear < GOALWALK ? clear : GOALWALK; navigation.solveTo(SLAM::Location(p.x + cos(p.theta) * walk, p.y + sin(p.theta) * walk)); navigate(); camera.rotateFar(); taskState = GOAL_WALKHAX; } break; case GOAL_WALKHAX: // in goal, drive a bit forwards to be able to drop targets correctly if (!motionControl.iterate(p)) { taskState = RELEASE_TARGETS; servoControl.setHatch(false); } break; case PICK_UP: // when target is near, drive a bit forwards to be sure if (!motionControl.iterate(p)) { servoControl.setHatch(true); camera.rotateFar(); numberOfPickUps++; speak("Pallo " + lexical_cast(numberOfPickUps)); if(numberOfPickUps >= 10) { taskState = GO_RETURN_TO_GOAL; } else { if (targets.empty()) { taskState = EXPLORE; } else { selectTarget(); navigateTarget(); taskState = GO_TO_TARGET; } taskState = EXPLORE; } } break; case RELEASE_TARGETS: // eggs hatching, get back servoControl.setHatch(false); if (!motionControl.backFromGoal(p)) { taskState = RETURN_TO_GOAL_AGAIN; navigation.solveTo(SLAM::Location(0, 0)); navigate(); } break; case RETURN_TO_GOAL_AGAIN: // Going to goal another time to get last balls rolling if (!motionControl.iterate(p)) { float clear = navigation.wallClearance(p); float walk = clear < GOALWALK_AGAIN ? clear : GOALWALK_AGAIN; navigation.solveTo(SLAM::Location(p.x + cos(p.theta) * walk, p.y + sin(p.theta) * walk)); navigate(); camera.rotateFar(); taskState = GOAL_WALKHAX_AGAIN; } break; case GOAL_WALKHAX_AGAIN: // in goal, drive a bit forwards to be able to drop targets correctly if (!motionControl.iterate(p)) { taskState = RELEASE_TARGETS_AGAIN; } break; case RELEASE_TARGETS_AGAIN: // they see me rollin', they hatin' if (!motionControl.backFromGoal(p)) { taskState = END_STATE; } break; case END_STATE: // world domination succeeded camera.rotateNear(); speak("Hurraa"); manual.enabled = true; break; case BACK_OFF: // bumpers hit. exit to exploring when bumpers not hitting anymore std::cout << "PLANNER: DYNDYNDYY" << std::endl; motionControl.backOff(); break; default: throw std::runtime_error("Bad task state number"); break; } float timeSince = ownTime_get_ms_since(statistics.taskStartTime); if (timeSince >= hurryUp && ( taskState == START || taskState == EXPLORE || taskState == GO_TO_TARGET || taskState == APPROACH_PICK_UP || taskState == PICK_UP )) { taskState = GO_RETURN_TO_GOAL; speak("Hop hop hop"); } std::cout << "PLANNER: CURRENT TASK: " << taskdescr[taskState] << ", time elapsed " << (timeSince / 1000) << std::endl; } }
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/) { #ifdef __DEBUG__ std::cout << "Searching target... " << std::endl; #endif std::list<Creature*> resultList; const Position& myPos = getPosition(); for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it) { if(followCreature != (*it) && isTarget(*it)) { if(searchType == TARGETSEARCH_RANDOM || canUseAttack(myPos, *it)) resultList.push_back(*it); } } switch(searchType) { case TARGETSEARCH_NEAREAST: { Creature* target = NULL; int32_t minRange = -1; for(std::list<Creature*>::iterator it = resultList.begin(); it != resultList.end(); ++it) { const Position& pos = (*it)->getPosition(); if(minRange == -1 || std::max(std::abs(myPos.x - pos.x), std::abs(myPos.y - pos.y)) < minRange) { target = *it; minRange = std::max(std::abs(myPos.x - pos.x), std::abs(myPos.y - pos.y)); } } if(target && selectTarget(target)) return true; break; } case TARGETSEARCH_DEFAULT: case TARGETSEARCH_ATTACKRANGE: case TARGETSEARCH_RANDOM: default: { if(!resultList.empty()) { uint32_t index = random_range(0, resultList.size() - 1); CreatureList::iterator it = resultList.begin(); std::advance(it, index); #ifdef __DEBUG__ std::cout << "Selecting target " << (*it)->getName() << std::endl; #endif return selectTarget(*it); } if(searchType == TARGETSEARCH_ATTACKRANGE) return false; break; } } //lets just pick the first target in the list for(CreatureList::iterator it = targetList.begin(); it != targetList.end(); ++it) { if(followCreature != (*it) && selectTarget(*it)) { #ifdef __DEBUG__ std::cout << "Selecting target " << (*it)->getName() << std::endl; #endif return true; } } return false; }
bool Monster::searchTarget(TargetSearchType_t searchType /*= TARGETSEARCH_DEFAULT*/) { std::list<Creature*> resultList; const Position& myPos = getPosition(); for (Creature* creature : targetList) { if (followCreature != creature && isTarget(creature)) { if (searchType == TARGETSEARCH_RANDOM || canUseAttack(myPos, creature)) { resultList.push_back(creature); } } } switch (searchType) { case TARGETSEARCH_NEAREST: { Creature* target = nullptr; if (!resultList.empty()) { auto it = resultList.begin(); target = *it; if (++it != resultList.end()) { const Position& targetPosition = target->getPosition(); int32_t minRange = Position::getDistanceX(myPos, targetPosition) + Position::getDistanceY(myPos, targetPosition); do { const Position& pos = (*it)->getPosition(); int32_t distance = Position::getDistanceX(myPos, pos) + Position::getDistanceY(myPos, pos); if (distance < minRange) { target = *it; minRange = distance; } } while (++it != resultList.end()); } } else { int32_t minRange = std::numeric_limits<int32_t>::max(); for (Creature* creature : targetList) { if (!isTarget(creature)) { continue; } const Position& pos = creature->getPosition(); int32_t distance = Position::getDistanceX(myPos, pos) + Position::getDistanceY(myPos, pos); if (distance < minRange) { target = creature; minRange = distance; } } } if (target && selectTarget(target)) { return true; } break; } case TARGETSEARCH_DEFAULT: case TARGETSEARCH_ATTACKRANGE: case TARGETSEARCH_RANDOM: default: { if (!resultList.empty()) { auto it = resultList.begin(); std::advance(it, uniform_random(0, resultList.size() - 1)); return selectTarget(*it); } if (searchType == TARGETSEARCH_ATTACKRANGE) { return false; } break; } } //lets just pick the first target in the list for (Creature* target : targetList) { if (followCreature != target && selectTarget(target)) { return true; } } return false; }
void Monster::onThink(uint32_t interval) { Creature::onThink(interval); if (mType->info.thinkEvent != -1) { // onThink(self, interval) LuaScriptInterface* scriptInterface = mType->info.scriptInterface; if (!scriptInterface->reserveScriptEnv()) { std::cout << "[Error - Monster::onThink] Call stack overflow" << std::endl; return; } ScriptEnvironment* env = scriptInterface->getScriptEnv(); env->setScriptId(mType->info.thinkEvent, scriptInterface); lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.thinkEvent); LuaScriptInterface::pushUserdata<Monster>(L, this); LuaScriptInterface::setMetatable(L, -1, "Monster"); lua_pushnumber(L, interval); if (scriptInterface->callFunction(2)) { return; } } if (!isInSpawnRange(position)) { g_game.internalTeleport(this, masterPos); setIdle(true); } else { updateIdleStatus(); if (!isIdle) { addEventWalk(); if (isSummon()) { if (!attackedCreature) { if (getMaster() && getMaster()->getAttackedCreature()) { //This happens if the monster is summoned during combat selectTarget(getMaster()->getAttackedCreature()); } else if (getMaster() != followCreature) { //Our master has not ordered us to attack anything, lets follow him around instead. setFollowCreature(getMaster()); } } else if (attackedCreature == this) { setFollowCreature(nullptr); } else if (followCreature != attackedCreature) { //This happens just after a master orders an attack, so lets follow it aswell. setFollowCreature(attackedCreature); } } else if (!targetList.empty()) { if (!followCreature || !hasFollowPath) { searchTarget(); } else if (isFleeing()) { if (attackedCreature && !canUseAttack(getPosition(), attackedCreature)) { searchTarget(TARGETSEARCH_ATTACKRANGE); } } } onThinkTarget(interval); onThinkYell(interval); onThinkDefense(interval); } } }
void Monster::doAttacking(uint32_t interval) { if(!attackedCreature || (isSummon() && attackedCreature == this)) return; // aqui const Position& myPos = getPosition(); const Position& targetPos = attackedCreature->getPosition(); FindPathParams fpp; fpp.fullPathSearch = true; fpp.maxSearchDist = -1; fpp.minTargetDist = 0; fpp.maxTargetDist = 1; std::string valueString; std::list<Direction> dirList; if(attackedCreature->getPlayer()){ if(Creature* summon = attackedCreature->pushBackSummonOne()) selectTarget(summon); } /* if(!g_game.getPathToEx(this, targetPos, dirList, fpp) && attackedCreature->isSummon()){ selectTarget(attackedCreature->getMaster()); std::string strValue; int32_t value; if(getStorage(8085, strValue)) { value = atoi(strValue.c_str()); } if(value == 0) g_game.addAnimatedText(getPosition(), 215, "GRRR!"); setStorage(8085, "2"); } if(attackedCreature->getPlayer()){ if(Creature* summon = attackedCreature->pushBackSummonOne()){ if(g_game.getPathToEx(this, summon->getPosition(), dirList, fpp)){ selectTarget(summon); std::string strValue, playerStor; int32_t value, value2; if(getStorage(8085, strValue)) { value = atoi(strValue.c_str()); } if(value == 2) g_game.addAnimatedText(getPosition(), 215, "Hmpf"); setStorage(8085, "0"); } }else setStorage(8085, "1"); } */ bool updateLook = true, outOfRange = true; resetTicks = interval; attackTicks += interval; for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it) { if(it->isMelee && isFleeing()) continue; bool inRange = false; if(canUseSpell(myPos, targetPos, *it, interval, inRange)) { if(it->chance >= (uint32_t)random_range(1, 100)) { if(updateLook) { updateLookDirection(); updateLook = false; } double multiplier; if(maxCombatValue > 0) //defense multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_DEFENSE); else //attack multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_ATTACK); minCombatValue = (int32_t)(it->minCombatValue * multiplier); maxCombatValue = (int32_t)(it->maxCombatValue * multiplier); it->spell->castSpell(this, attackedCreature); if(it->isMelee) extraMeleeAttack = false; #ifdef __DEBUG__ static uint64_t prevTicks = OTSYS_TIME(); std::cout << "doAttacking ticks: " << OTSYS_TIME() - prevTicks << std::endl; prevTicks = OTSYS_TIME(); #endif } } if(inRange) outOfRange = false; else if(it->isMelee) //melee swing out of reach extraMeleeAttack = true; } if(updateLook) updateLookDirection(); if(resetTicks) attackTicks = 0; }