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; }
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; }
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; } }
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; }
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; } }
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)); }
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; }
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; } }