bool DamageOverTimeList::healState(CreatureObject* victim, uint64 dotType, float reduction, bool sendMsg) { Locker locker(&guard); if (!hasDot()) return reduction; Vector<DamageOverTime*> timeVec; for (int i = 0; i < size(); i++) { Vector<DamageOverTime>* vector = &elementAt(i).getValue(); for (int j = 0; j < vector->size(); j++) { DamageOverTime* dot = &vector->elementAt(j); if (dot->getType() == dotType && !dot->isPast()) timeVec.add(dot); } } bool expired = true; float reductionLeft = reduction; for (int i = 0; i < timeVec.size(); i++) { DamageOverTime* dot = timeVec.elementAt(i); if (!dot->isPast()) { reductionLeft = dot->reduceTick(reductionLeft); // reduceTick() *should* be guaranteed to return a non-negative value, // but since this is a float, we want to make sure if (reductionLeft <= 0.f) { // we ran out of juice in our cure, so don't expire the dotType, // ie, maintain the state with a reduced damage per tick expired = false; break; } } } if (expired) { locker.release(); victim->clearState(dotType); return true; } if (sendMsg) sendDecreaseMessage(victim, dotType); return false; }
void DamageOverTimeList::clear(CreatureObject* creature) { Locker locker(&guard); dot = false; for (int i = 0; i < size(); ++i) { uint64 type = elementAt(i).getKey(); Vector<DamageOverTime>* vector = &elementAt(i).getValue(); for (int j = 0; j < vector->size(); ++j) { DamageOverTime* dot = &vector->elementAt(j); creature->clearState(dot->getType()); } } removeAll(); }
bool DamageOverTimeList::hasDot(uint64 dotType) { Locker locker(&guard); bool hasDot = false; for (int i = 0; i < size(); ++i) { uint64 type = elementAt(i).getKey(); Vector<DamageOverTime>* vector = &elementAt(i).getValue(); for (int j = 0; j < vector->size(); ++j) { DamageOverTime* dot = &vector->elementAt(j); if (dot->getType() == dotType) hasDot = true; } } return hasDot; }
int DamageOverTimeList::getStrength(uint8 pool, uint64 dotType) { Locker locker(&guard); Vector<DamageOverTime>* vector; int strength = 0; for(int i = 0; i < size(); i++) { vector = &elementAt(i).getValue(); for(int j = 0; j < vector->size(); j++) { DamageOverTime* currentDot = &vector->elementAt(j); if(currentDot->getType() == dotType && (currentDot->getAttribute() == pool || pool == 0xFF)) { if (!currentDot->isPast()) { strength+=currentDot->getStrength(); } } } } return strength; }
uint64 DamageOverTimeList::activateDots(CreatureObject* victim) { uint64 states = 0; uint64 statesBefore = 0; Locker guardLocker(&guard); for (int i = size() - 1; i >= 0 ; --i) { Vector<DamageOverTime>* vector = &elementAt(i).getValue(); for (int j = vector->size() - 1; j >= 0 ; --j) { DamageOverTime* dot = &vector->elementAt(j); statesBefore |= dot->getType(); if (dot->nextTickPast()) { //guard.unlock(); try { dot->applyDot(victim); } catch (...) { //guard.wlock(); throw; } //guard.wlock(); } Time nTime = dot->getNextTick(); if (nextTick.isPast() || (!dot->isPast() && (nTime.compareTo(nextTick) > 0))) nextTick = nTime; if (!dot->isPast()) { states |= dot->getType(); } else { if (vector->size() == 1) { vector->remove(j); remove(i); } else { vector->remove(j); } } } } int statesRemoved = states ^ statesBefore; if( statesRemoved & CreatureState::BLEEDING ) victim->clearState(CreatureState::BLEEDING); if( statesRemoved & CreatureState::POISONED ) victim->clearState(CreatureState::POISONED); if( statesRemoved & CreatureState::DISEASED ) victim->clearState(CreatureState::DISEASED); if( statesRemoved & CreatureState::ONFIRE ) victim->clearState(CreatureState::ONFIRE); if (nextTick.isPast()) { dot = false; removeAll(); states = 0; } return states; }