Пример #1
0
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;
}