Ejemplo n.º 1
0
 virtual MoveInfo getMove() override {
   const Creature* other = getClosestEnemy();
   if (other != nullptr) {
     double myDamage = creature->getAttr(AttrType::DAMAGE);
     Item* weapon = getBestWeapon();
     if (!creature->getWeapon() && weapon)
       myDamage += weapon->getModifier(AttrType::DAMAGE);
     double powerRatio = courage * myDamage / other->getAttr(AttrType::DAMAGE);
     bool significantEnemy = myDamage < 5 * other->getAttr(AttrType::DAMAGE);
     double weight = 1. - creature->getHealth() * 0.9;
     if (powerRatio < maxPowerRatio)
       weight += 2 - powerRatio * 2;
     weight = min(1.0, max(0.0, weight));
     if (creature->isAffected(Creature::PANIC))
       weight = 1;
     if (other->isAffected(Creature::SLEEP) || other->isStationary())
       weight = 0;
     Debug() << creature->getName() << " panic weight " << weight;
     if (weight >= 0.5) {
       double dist = creature->getPosition().dist8(other->getPosition());
       if (dist < 7) {
         if (dist == 1)
           EventListener::addSurrenderEvent(creature, other);
         if (MoveInfo move = getPanicMove(other, weight))
           return move;
         else
           return getAttackMove(other, significantEnemy && chase);
       }
       return NoMove;
     } else
       return getAttackMove(other, significantEnemy && chase);
   } else
     return getLastSeenMove();
 }
Ejemplo n.º 2
0
 virtual double itemValue(const Item* item) override {
   if (contains<EffectType>({
         EffectType(EffectId::LASTING, LastingEffect::INVISIBLE),
         EffectType(EffectId::LASTING, LastingEffect::SLOWED),
         EffectType(EffectId::LASTING, LastingEffect::BLIND),
         EffectType(EffectId::LASTING, LastingEffect::SLEEP),
         EffectType(EffectId::LASTING, LastingEffect::POISON),
         EffectType(EffectId::LASTING, LastingEffect::POISON_RESISTANT),
         EffectId::CURE_POISON,
         EffectId::TELEPORT,
         EffectType(EffectId::LASTING, LastingEffect::STR_BONUS),
         EffectType(EffectId::LASTING, LastingEffect::DEX_BONUS)},
         item->getEffectType()))
     return 1;
   if (item->getClass() == ItemClass::AMMO && creature->getAttributes().getSkills().getValue(SkillId::ARCHERY) > 0)
     return 0.1;
   if (!creature->isEquipmentAppropriate(item))
     return 0;
   if (item->getModifier(ModifierType::THROWN_DAMAGE) > 0)
     return (double)item->getModifier(ModifierType::THROWN_DAMAGE) / 50;
   int damage = item->getModifier(ModifierType::DAMAGE);
   Item* best = getBestWeapon();
   if (best && best != item && best->getModifier(ModifierType::DAMAGE) >= damage)
       return 0;
   return (double)damage / 50;
 }
Ejemplo n.º 3
0
void CHLDMBot :: handleWeapons ()
{
	//
	// Handle attacking at this point
	//
	if ( m_pEnemy && !hasSomeConditions(CONDITION_ENEMY_DEAD) && 
		hasSomeConditions(CONDITION_SEE_CUR_ENEMY) && wantToShoot() && 
		isVisible(m_pEnemy) && isEnemy(m_pEnemy) )
	{
		CBotWeapon *pWeapon;

		pWeapon = getBestWeapon(m_pEnemy,true,true,(m_pEnemy==m_NearestBreakable)&&!rcbot_melee_only.GetBool());

		if ( m_bWantToChangeWeapon && (pWeapon != NULL) && (pWeapon != getCurrentWeapon()) && pWeapon->getWeaponIndex() )
		{
			//selectWeaponSlot(pWeapon->getWeaponInfo()->getSlot());
			selectWeapon(pWeapon->getWeaponIndex());
		}

		setLookAtTask((LOOK_ENEMY));

		///battack = true;

		if ( !handleAttack ( pWeapon, m_pEnemy ) )
		{
			m_pEnemy = NULL;
			m_pOldEnemy = NULL;
			wantToShoot(false);
		}
	}
}
Ejemplo n.º 4
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;
 }
Ejemplo n.º 5
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;
 }
Ejemplo n.º 6
0
 virtual double itemValue(const Item* item) {
   if (contains({EffectType::INVISIBLE, EffectType::SLOW, EffectType::BLINDNESS, EffectType::SLEEP,
           EffectType::POISON, EffectType::TELEPORT, EffectType::STR_BONUS, EffectType::DEX_BONUS},
         item->getEffectType()))
     return 1;
   if (item->getType() == ItemType::AMMO && creature->hasSkill(Skill::archery))
     return 0.1;
   if (item->getType() != ItemType::WEAPON || !creature->hasSkillToUseWeapon(item))
     return 0;
   if (item->getModifier(AttrType::THROWN_DAMAGE) > 0)
     return (double)item->getModifier(AttrType::THROWN_DAMAGE) / 50;
   int damage = item->getModifier(AttrType::DAMAGE);
   Item* best = getBestWeapon();
   if (best && best != item && best->getModifier(AttrType::DAMAGE) >= damage)
       return 0;
   return (double)damage / 50;
 }