void Monster::updateTargetList() { auto friendIterator = friendList.begin(); while (friendIterator != friendList.end()) { Creature* creature = *friendIterator; if (creature->getHealth() <= 0 || !canSee(creature->getPosition())) { creature->decrementReferenceCounter(); friendIterator = friendList.erase(friendIterator); } else { ++friendIterator; } } auto targetIterator = targetList.begin(); while (targetIterator != targetList.end()) { Creature* creature = *targetIterator; if (creature->getHealth() <= 0 || !canSee(creature->getPosition())) { creature->decrementReferenceCounter(); targetIterator = targetList.erase(targetIterator); } else { ++targetIterator; } } SpectatorHashSet spectators; g_game.map.getSpectators(spectators, position, true); spectators.erase(this); for (Creature* spectator : spectators) { if (canSee(spectator->getPosition())) { onCreatureFound(spectator); } } }
void Creature::onGainExperience(uint64_t gainExp, Creature* target) { if (gainExp == 0 || !master) { return; } gainExp /= 2; master->onGainExperience(gainExp, target); SpectatorHashSet spectators; g_game.map.getSpectators(spectators, position, false, true); if (spectators.empty()) { return; } TextMessage message(MESSAGE_EXPERIENCE_OTHERS, ucfirst(getNameDescription()) + " gained " + std::to_string(gainExp) + (gainExp != 1 ? " experience points." : " experience point.")); message.position = position; message.primary.color = TEXTCOLOR_WHITE_EXP; message.primary.value = gainExp; for (Creature* spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } }
bool ConditionRegeneration::executeCondition(Creature* creature, int32_t interval) { internalHealthTicks += interval; internalManaTicks += interval; if (creature->getZone() == ZONE_PROTECTION) { return ConditionGeneric::executeCondition(creature, interval); } if (internalHealthTicks >= healthTicks) { internalHealthTicks = 0; int32_t realHealthGain = creature->getHealth(); creature->changeHealth(healthGain); realHealthGain = creature->getHealth() - realHealthGain; if (isBuff && realHealthGain > 0) { Player* player = creature->getPlayer(); if (player) { std::string healString = std::to_string(realHealthGain) + (realHealthGain != 1 ? " hitpoints." : " hitpoint."); TextMessage message(MESSAGE_HEALED, "You were healed for " + healString); message.position = player->getPosition(); message.primary.value = realHealthGain; message.primary.color = TEXTCOLOR_MAYABLUE; player->sendTextMessage(message); SpectatorHashSet spectators; g_game.map.getSpectators(spectators, player->getPosition(), false, true); spectators.erase(player); if (!spectators.empty()) { message.type = MESSAGE_HEALED_OTHERS; message.text = player->getName() + " was healed for " + healString; for (Creature* spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } } } } } if (internalManaTicks >= manaTicks) { internalManaTicks = 0; if (Player* player = creature->getPlayer()) { int32_t realManaGain = player->getMana(); player->changeMana(manaGain); realManaGain = player->getMana() - realManaGain; if (isBuff && realManaGain > 0) { std::string manaGainString = std::to_string(realManaGain); TextMessage message(MESSAGE_HEALED, "You gained " + manaGainString + " mana."); message.position = player->getPosition(); message.primary.value = realManaGain; message.primary.color = TEXTCOLOR_MAYABLUE; player->sendTextMessage(message); SpectatorHashSet spectators; g_game.map.getSpectators(spectators, player->getPosition(), false, true); spectators.erase(player); if (!spectators.empty()) { message.type = MESSAGE_HEALED_OTHERS; message.text = player->getName() + " gained " + manaGainString + " mana."; for (Creature* spectator : spectators) { spectator->getPlayer()->sendTextMessage(message); } } } } } return ConditionGeneric::executeCondition(creature, interval); }
void Tile::removeThing(Thing* thing, uint32_t count) { Creature* creature = thing->getCreature(); if (creature) { CreatureVector* creatures = getCreatures(); if (creatures) { auto it = std::find(creatures->begin(), creatures->end(), thing); if (it != creatures->end()) { g_game.map.clearSpectatorCache(); creatures->erase(it); } } return; } Item* item = thing->getItem(); if (!item) { return; } int32_t index = getThingIndex(item); if (index == -1) { return; } if (item == ground) { ground->setParent(nullptr); ground = nullptr; SpectatorHashSet spectators; g_game.map.getSpectators(spectators, getPosition(), true); onRemoveTileItem(spectators, std::vector<int32_t>(spectators.size(), 0), item); return; } TileItemVector* items = getItemList(); if (!items) { return; } const ItemType& itemType = Item::items[item->getID()]; if (itemType.alwaysOnTop) { auto it = std::find(items->getBeginTopItem(), items->getEndTopItem(), item); if (it == items->getEndTopItem()) { return; } std::vector<int32_t> oldStackPosVector; SpectatorHashSet spectators; g_game.map.getSpectators(spectators, getPosition(), true); for (Creature* spectator : spectators) { if (Player* tmpPlayer = spectator->getPlayer()) { oldStackPosVector.push_back(getStackposOfItem(tmpPlayer, item)); } } item->setParent(nullptr); items->erase(it); onRemoveTileItem(spectators, oldStackPosVector, item); } else { auto it = std::find(items->getBeginDownItem(), items->getEndDownItem(), item); if (it == items->getEndDownItem()) { return; } if (itemType.stackable && count != item->getItemCount()) { uint8_t newCount = static_cast<uint8_t>(std::max<int32_t>(0, static_cast<int32_t>(item->getItemCount() - count))); item->setItemCount(newCount); onUpdateTileItem(item, itemType, item, itemType); } else { std::vector<int32_t> oldStackPosVector; SpectatorHashSet spectators; g_game.map.getSpectators(spectators, getPosition(), true); for (Creature* spectator : spectators) { if (Player* tmpPlayer = spectator->getPlayer()) { oldStackPosVector.push_back(getStackposOfItem(tmpPlayer, item)); } } item->setParent(nullptr); items->erase(it); items->addDownItemCount(-1); onRemoveTileItem(spectators, oldStackPosVector, item); } } }