Example #1
0
 MoveInfo getAttackMove(Creature* other, bool chase) {
   int distance = 10000;
   CHECK(other);
   if (other->getAttributes().isInvincible())
     return NoMove;
   Debug() << creature->getName().bare() << " enemy " << other->getName().bare();
   Vec2 enemyDir = creature->getPosition().getDir(other->getPosition());
   distance = enemyDir.length8();
   if (creature->getAttributes().isHumanoid() && !creature->getWeapon()) {
     if (Item* weapon = getBestWeapon())
       if (auto action = creature->equip(weapon))
         return {3.0 / (2.0 + distance), action.prepend([=](Creature* creature) {
           creature->setInCombat();
           other->setInCombat();
       })};
   }
   if (distance == 1)
     if (MoveInfo move = tryEffect(EffectId::AIR_BLAST, 1))
       return move;
   if (distance <= 5)
     for (EffectType effect : {
         EffectType(EffectId::LASTING, LastingEffect::INVISIBLE),
         EffectType(EffectId::LASTING, LastingEffect::STR_BONUS),
         EffectType(EffectId::LASTING, LastingEffect::DEX_BONUS),
         EffectType(EffectId::LASTING, LastingEffect::SPEED),
         EffectType(EffectId::DECEPTION),
         EffectType(EffectId::SUMMON, CreatureId::SPIRIT)})
       if (MoveInfo move = tryEffect(effect, 1))
         return move;
   if (distance > 1) {
     if (distance < 10) {
       if (MoveInfo move = getFireMove(enemyDir))
         return move;
       if (MoveInfo move = getThrowMove(enemyDir))
         return move;
     }
     if (chase && !other->getAttributes().dontChase() && !isChaseFrozen(other)) {
       lastSeen = none;
       if (auto action = creature->moveTowards(other->getPosition()))
         return {max(0., 1.0 - double(distance) / 10), action.prepend([=](Creature* creature) {
           creature->setInCombat();
           other->setInCombat();
           lastSeen = {other->getPosition(), creature->getGlobalTime(), LastSeen::ATTACK, other->getUniqueId()};
           if (!chaseFreeze.count(other) || other->getGlobalTime() > chaseFreeze.at(other).second)
             chaseFreeze[other] = make_pair(other->getGlobalTime() + 20, other->getGlobalTime() + 70);
         })};
     }
   }
   if (distance == 1)
     if (auto action = creature->attack(other, getAttackParams(other)))
       return {1.0, action.prepend([=](Creature* creature) {
           creature->setInCombat();
           other->setInCombat();
       })};
   return NoMove;
 }
Example #2
0
 MoveInfo getAttackMove(const Creature* other, bool chase) {
   int radius = 4;
   int distance = 10000;
   CHECK(other);
   if (other->isInvincible())
     return NoMove;
   Debug() << creature->getName() << " enemy " << other->getName();
   Vec2 enemyDir = (other->getPosition() - creature->getPosition());
   distance = enemyDir.length8();
   if (creature->isHumanoid() && !creature->getEquipment().getItem(EquipmentSlot::WEAPON)) {
     Item* weapon = getBestWeapon();
     if (weapon != nullptr && creature->canEquip(weapon, nullptr))
       return {3.0 / (2.0 + distance), [this, weapon, other]() {
         EventListener::addCombatEvent(creature);
         EventListener::addCombatEvent(other);
         creature->globalMessage(creature->getTheName() + " draws " + weapon->getAName());
         creature->equip(weapon);
       }};
   }
   if (distance <= 5)
     for (EffectType effect : {EffectType::INVISIBLE, EffectType::STR_BONUS, EffectType::DEX_BONUS,
         EffectType::SPEED, EffectType::SUMMON_SPIRIT})
       if (MoveInfo move = tryToApplyItem(effect, 1))
         return move;
   if (distance > 1) {
     if (MoveInfo move = getFireMove(enemyDir))
       return move;
     if (MoveInfo move = getThrowMove(enemyDir))
       return move;
     if (chase && other->getTribe() != Tribes::get(TribeId::WILDLIFE)) {
       Optional<Vec2> move = creature->getMoveTowards(creature->getPosition() + enemyDir);
       lastSeen = Nothing();
       if (move)
         return {max(0., 1.0 - double(distance) / 10), [this, enemyDir, move, other]() {
           EventListener::addCombatEvent(creature);
           EventListener::addCombatEvent(other);
           lastSeen = {creature->getPosition() + enemyDir, creature->getTime(), creature->getLevel(),
               LastSeen::ATTACK, other};
           creature->move(*move);
         }};
     }
   }
   if (distance == 1) {
     if (creature->canAttack(other))
       return {1.0, [this, other]() {
         EventListener::addCombatEvent(creature);
         EventListener::addCombatEvent(other);
         creature->attack(other);
       }};
   }
   return NoMove;
 }
Example #3
0
 MoveInfo getPanicMove(Creature* other, double weight) {
   if (auto teleMove = tryEffect(EffectId::TELEPORT, 1))
     return teleMove.withValue(weight);
   if (other->getPosition().dist8(creature->getPosition()) > 3)
     if (auto move = getFireMove(creature->getPosition().getDir(other->getPosition())))
       return move.withValue(weight);
   if (auto action = creature->moveAway(other->getPosition(), chase))
     return {weight, action.prepend([=](Creature* creature) {
       creature->setInCombat();
       other->setInCombat();
       lastSeen = {creature->getPosition(), creature->getGlobalTime(), LastSeen::PANIC, other->getUniqueId()};
     })};
   else
     return NoMove;
 }
Example #4
0
 MoveInfo getPanicMove(const Creature* other, double weight) {
   if (auto teleMove = tryToApplyItem(EffectType::TELEPORT, 1))
     return {weight, teleMove.move};
   if (other->getPosition().dist8(creature->getPosition()) > 3)
     if (auto move = getFireMove(other->getPosition() - creature->getPosition()))
       return {weight, move.move};
   if (auto move = creature->getMoveAway(other->getPosition(), chase))
     return {weight, [this, move, other] () {
       EventListener::addCombatEvent(creature);
       EventListener::addCombatEvent(other);
       lastSeen = {creature->getPosition(), creature->getTime(), creature->getLevel(), LastSeen::PANIC, other};
       creature->move(*move);
     }};
   else
     return NoMove;
 }