Пример #1
0
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature || (isSummon() && attackedCreature == this))
		return;

	bool updateLook = true, outOfRange = true;
	resetTicks = interval;
	attackTicks += interval;

	const Position& myPos = getPosition();
	const Position& targetPos = attackedCreature->getPosition();
	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::clog << "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;
}
Пример #2
0
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature)
		return;

	bool updateLook = true;
	resetTicks = (interval != 0);
	attackTicks += interval;

	const Position& myPos = getPosition();
	for(SpellList::iterator it = _type->spellAttackList.begin(); it != _type->spellAttackList.end(); ++it)
	{
		if(!attackedCreature || !attackedCreature->isAlive())
			break;

		const Position& targetPos = attackedCreature->getPosition();
		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 = server.configManager().getDouble(ConfigManager::RATE_MONSTER_DEFENSE);
				else //attack
					multiplier = server.configManager().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;
			}
		}

		if(!inRange && it->isMelee) //melee swing out of reach
			extraMeleeAttack = true;
	}

	if(updateLook)
		updateLookDirection();

	if(resetTicks)
		attackTicks = 0;
}
Пример #3
0
void Actor::doAttacking(uint32_t interval)
{
  if(!attackedCreature || (isSummon() && attackedCreature == this)){
    return;
  }

  // TODO: seems "outOfRange" is being unused. Why?
  //bool outOfRange = true;
  bool updateLook = true;

  resetTicks = interval != 0;
  attackTicks += interval;

  const Position& myPos = getPosition();
  const Position& targetPos = attackedCreature->getPosition();

  for(SpellList::const_iterator it = cType.spellAttackList().begin(), spell_list_end = cType.spellAttackList().end(); it != spell_list_end; ++it){
    bool inRange = false;
    if(canUseSpell(myPos, targetPos, *it, interval, inRange)){
      if(it->chance >= (uint32_t)random_range(1, 100)){
        if(updateLook){
          updateLookDirection();
          updateLook = false;
        }

        g_game.onActorCastSpell(this, attackedCreature, (*it).name);
        /*
        if(it->isMelee){
          extraMeleeAttack = false;
        }
        */
      }
    }
    /*
    if(inRange){
      outOfRange = false;
    }
    */
    /*
    else if(it->isMelee){
      //melee swing out of reach
      extraMeleeAttack = true;
    }
    */
  }

  if(updateLook){
    updateLookDirection();
  }

  if(resetTicks){
    attackTicks = 0;
  }
}
Пример #4
0
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature || (isSummon() && attackedCreature == this))
		return;

	bool updateLook = true;

	resetTicks = interval != 0;
	attackTicks += interval;

	const Position& myPos = getPosition();
	const Position& targetPos = attackedCreature->getPosition();

	for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it)
	{
		bool inRange = false;
		if(canUseSpell(myPos, targetPos, *it, interval, inRange))
		{
			if(it->chance >= (uint32_t)random_range(1, 100))
			{
				if(updateLook)
				{
					updateLookDirection();
					updateLook = false;
				}

				minCombatValue = it->minCombatValue;
				maxCombatValue = it->maxCombatValue;
				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 && it->isMelee)
		{
			//melee swing out of reach
			extraMeleeAttack = true;
		}
	}

	if(updateLook)
		updateLookDirection();

	if(resetTicks)
		attackTicks = 0;
}
Пример #5
0
void Monster::doAttacking(uint32_t interval)
{
	if (!attackedCreature || (isSummon() && attackedCreature == this)) {
		return;
	}

	bool updateLook = true;
	bool resetTicks = interval != 0;
	attackTicks += interval;

	const Position& myPos = getPosition();
	const Position& targetPos = attackedCreature->getPosition();

	for (const spellBlock_t& spellBlock : mType->info.attackSpells) {
		bool inRange = false;

		if (canUseSpell(myPos, targetPos, spellBlock, interval, inRange, resetTicks)) {
			if (spellBlock.chance >= static_cast<uint32_t>(uniform_random(1, 100))) {
				if (updateLook) {
					updateLookDirection();
					updateLook = false;
				}

				minCombatValue = spellBlock.minCombatValue;
				maxCombatValue = spellBlock.maxCombatValue;
				spellBlock.spell->castSpell(this, attackedCreature);

				if (spellBlock.isMelee) {
					extraMeleeAttack = false;
				}
			}
		}

		if (!inRange && spellBlock.isMelee) {
			//melee swing out of reach
			extraMeleeAttack = true;
		}
	}

	if (updateLook) {
		updateLookDirection();
	}

	if (resetTicks) {
		attackTicks = 0;
	}
}
Пример #6
0
bool GameState::isSpellAllowed(int attId, int defId) const
{
    if (!canUseSpell(attId)) return false;

    const auto &att = getUnit(attId);
    const auto &def = getUnit(defId);
    if (!def.isAlive()) return false;

    const Spell *spell = att.type->spell;

    // Healing spells can't target units at full health.
    if (spell->damage < 0 && def.hpLeft == def.type->hp) {
        return false;
    }

    return (spell->target == SpellTarget::ENEMY && att.isEnemy(def)) ||
        (spell->target == SpellTarget::FRIEND && !att.isEnemy(def));
}
Пример #7
0
std::vector<Action> GameState::getPossibleActions() const
{
    const auto &unit = getActiveUnit();
    assert(unit.isAlive());

    auto reachableHexes = getReachableHexes(unit);
    std::vector<Action> actions;

    if (canUseRangedAttack(unit.entityId)) {
        for (auto e : getAllEnemies(unit.entityId)) {
            actions.push_back(makeAttack(unit.entityId, e, unit.aHex));
        }
    }
    else if (canUseSpell(unit.entityId)) {
        for (const auto &target : units_) {
            if (!target.isAlive()) continue;
            auto possible = makeAttack(unit.entityId, target.entityId,
                                       unit.aHex);
            if (possible.type == ActionType::NONE) continue;
            actions.push_back(std::move(possible));
        }
    }
    else if (canUseMeleeAttack(unit.entityId)) {
        for (auto aHex : reachableHexes) {
            for (auto e : getAdjEnemies(unit.entityId, aHex)) {
                actions.push_back(makeAttack(unit.entityId, e, aHex));
            }
        }
    }

    actions.emplace_back(makeSkip(unit.entityId));

    for (auto aHex : reachableHexes) {
        if (aHex != unit.aHex) {
            actions.emplace_back(makeMove(unit.entityId, aHex));
        }
    }

    return actions;
}
Пример #8
0
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;
}
void Monster::doAttacking(uint32_t interval)
{
	if(!attackedCreature || (isSummon() && attackedCreature == this)){
		return;
	}

	bool updateLook = true;
	bool outOfRange = true;

	resetTicks = interval != 0;
	attackTicks += interval;

	for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it){
		bool inRange = false;

		/* updates positions and check if there is still an attackedCreature
		   as it all may be changed at the previous spell (if the spell teleports attacked creature) */
		if(!attackedCreature){
			break;
		}
		const Position& myPos = getPosition();
		const Position& targetPos = attackedCreature->getPosition();

		if(canUseSpell(myPos, targetPos, *it, interval, inRange)){
			if(it->chance >= (uint32_t)random_range(1, 100)){
				if(updateLook){
					updateLookDirection();
					updateLook = false;
				}

				minCombatValue = it->minCombatValue;
				maxCombatValue = it->maxCombatValue;
				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;
	}
}