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; }
bool Monster::getCombatValues(int32_t& min, int32_t& max) { if(!minCombatValue && !maxCombatValue) return 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); min = (int32_t)(minCombatValue * multiplier); max = (int32_t)(maxCombatValue * multiplier); return true; }
Monster::Monster(MonsterType* _mType): Creature() { isIdle = true; nick = _mType->name; name = _mType->realName; isMasterInRange = false; teleportToMaster = false; mType = _mType; spawn = NULL; raid = NULL; defaultOutfit = mType->outfit; currentOutfit = mType->outfit; double multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_HEALTH); health = (int32_t)(mType->health * multiplier); healthMax = (int32_t)(mType->healthMax * multiplier); baseSpeed = mType->baseSpeed; internalLight.level = mType->lightLevel; internalLight.color = mType->lightColor; setSkull(mType->skull); setShield(mType->partyShield); hideName = mType->hideName, hideHealth = mType->hideHealth; minCombatValue = 0; maxCombatValue = 0; targetTicks = 0; targetChangeTicks = 0; targetChangeCooldown = 0; attackTicks = 0; defenseTicks = 0; yellTicks = 0; extraMeleeAttack = false; //setStorage(510, mType->name); // register creature events for(StringVec::iterator it = mType->scriptList.begin(); it != mType->scriptList.end(); ++it) { if(!registerCreatureEvent(*it)) std::cout << "[Warning - Monster::Monster] Unknown event name - " << *it << std::endl; } #ifdef __ENABLE_SERVER_DIAGNOSTIC__ monsterCount++; #endif }
void Creature::onGainSharedExperience(double& gainExp, Creature* target, bool multiplied) { if(gainExp <= 0) return; if(master) { gainExp = gainExp / 2; master->onGainSharedExperience(gainExp, target, multiplied); } else if(!multiplied) gainExp *= g_config.getDouble(ConfigManager::RATE_EXPERIENCE); int16_t color = g_config.getNumber(ConfigManager::EXPERIENCE_COLOR); if(color < 0) color = random_range(0, 255); std::stringstream ss; ss << (uint64_t)gainExp; g_game.addAnimatedText(getPosition(), (uint8_t)color, ss.str()); }
bool Party::canUseSharedExperience(const Player* player, uint32_t highestLevel/* = 0*/) const { if(!highestLevel) { highestLevel = getLeader()->getLevel(); for(PlayerVector::const_iterator it = memberList.begin(); it != memberList.end(); ++it) { if((*it)->getLevel() > highestLevel) highestLevel = (*it)->getLevel(); } } if(player->getLevel() < (uint32_t)std::ceil((double)highestLevel * g_config.getDouble( ConfigManager::PARTY_DIFFERENCE)) || !Position::areInRange(Position( g_config.getNumber(ConfigManager::PARTY_RADIUS_X), g_config.getNumber( ConfigManager::PARTY_RADIUS_Y), g_config.getNumber(ConfigManager::PARTY_RADIUS_Z)), getLeader()->getPosition(), player->getPosition())) return false; CountMap::const_iterator it = pointMap.find(player->getID()); return it != pointMap.end() && (OTSYS_TIME() - it->second.ticks) <= g_config.getNumber( ConfigManager::EXPERIENCE_SHARE_ACTIVITY); }
uint16_t Monsters::getLootRandom() { return (uint16_t)std::ceil((double)random_range(0, MAX_LOOTCHANCE) / g_config.getDouble(ConfigManager::RATE_LOOT)); }
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; }