Ejemplo n.º 1
0
DeathList Creature::getKillers()
{
	DeathList list;
	CountMap::const_iterator it;

	Creature* lhc = NULL;
	if((lhc = g_game.getCreatureByID(lastHitCreature)))
	{
		int32_t damage = 0;
		if((it = damageMap.find(lastHitCreature)) != damageMap.end())
			damage = it->second.total;

		list.push_back(DeathEntry(lhc, damage));
	}
	else
		list.push_back(DeathEntry(getCombatName(lastDamageSource), 0));

	int32_t requiredTime = g_config.getNumber(ConfigManager::DEATHLIST_REQUIRED_TIME);
	int64_t now = OTSYS_TIME();

	CountBlock_t cb;
	for(it = damageMap.begin(); it != damageMap.end(); ++it)
	{
		cb = it->second;
		if((now - cb.ticks) > requiredTime)
			continue;

		Creature* mdc = g_game.getCreatureByID(it->first);
		if(!mdc || mdc == lhc || (lhc && (mdc->getMaster() == lhc || lhc->getMaster() == mdc)))
			continue;

		bool deny = false;
		for(DeathList::iterator fit = list.begin(); fit != list.end(); ++fit)
		{
			if(fit->isNameKill())
				continue;

			Creature* tmp = fit->getKillerCreature();
			if(!(mdc->getName() == tmp->getName() && mdc->getMaster() == tmp->getMaster()) &&
				(!mdc->getMaster() || (mdc->getMaster() != tmp && mdc->getMaster() != tmp->getMaster()))
				&& (mdc->getSummonCount() <= 0 || tmp->getMaster() != mdc))
				continue;

			deny = true;
			break;
		}

		if(!deny)
			list.push_back(DeathEntry(mdc, cb.total));
	}

	if(list.size() > 1)
		std::sort(list.begin() + 1, list.end(), DeathLessThan());

	return list;
}
Ejemplo n.º 2
0
DeathList Creature::getKillers(int32_t assist_count /*= 1*/)
{
	DeathList list;
	Creature* lhc = g_game.getCreatureByID(lastHitCreature);
	if(lhc){
		list.push_back(DeathEntry(lhc, 0, Combat::isUnjustKill(lhc, this))); // Final Hit killer
	}
	else{
		list.push_back(DeathEntry(combatTypeToString(lastDamageSource), 0));
	}

	if(assist_count == 0){
		return list;
	}
	else if(assist_count == 1){
		// Optimized case for last hit + one killer
		Creature* mdc = NULL;
		int32_t mostDamage = 0;
		int64_t now = OTSYS_TIME();

		for(CountMap::const_iterator it = damageMap.begin(); it != damageMap.end(); ++it){
			const CountBlock_t& cb = it->second;
			if(cb.total > mostDamage && (now - cb.ticks <= g_game.getInFightTicks())){
				Creature* tmpDamageCreature = g_game.getCreatureByID(it->first);
				if(tmpDamageCreature){
					mdc = tmpDamageCreature;
					mostDamage = cb.total;
				}
			}
		}

		if(mdc && mdc != lhc){
			if(lhc && (mdc->getMaster() == lhc || lhc->getMaster() == mdc || (lhc->getMaster() && lhc->getMaster() == mdc->getMaster()))){
				return list;
			}
			else{
				list.push_back(DeathEntry(mdc, mostDamage, Combat::isUnjustKill(mdc, this)));
			}
		}
	}
	else{
		int64_t now = OTSYS_TIME();

		// Add all (recent) damagers to the list
		for(CountMap::const_iterator it = damageMap.begin(); it != damageMap.end(); ++it){
			const CountBlock_t& cb = it->second;
			if(now - cb.ticks <= g_game.getInFightTicks()){
				Creature* mdc = g_game.getCreatureByID(it->first);
				// Player who made last hit is not included in assist list
				if(mdc && mdc != lhc){
					// Check if master is last hit creature, or if our summon is last hit creature
					if(lhc && (mdc->getMaster() == lhc || lhc->getMaster() == mdc)){
						continue;
					}

					// Check if master has already been added to the list
					if(mdc->getMaster()){
						bool cont = false;
						for(DeathList::iterator finder = list.begin(); finder != list.end(); ++finder){
							if(finder->isCreatureKill()){
								Creature* c = finder->getKillerCreature();
								if(mdc->getMaster() == c || mdc->getMaster() == c->getMaster()){
									cont = true;
									break;
								}
							}
						}
						if(cont){
							continue;
						}
					}

					// Check if our summon has already been added to the list
					if(mdc->getSummonCount() > 0){
						bool cont = false;
						for(DeathList::iterator finder = list.begin(); finder != list.end(); ++finder){
							if(finder->isCreatureKill()){
								Creature* c = finder->getKillerCreature();
								if(c->getMaster() == mdc){
									cont = true;
									break;
								}
							}
						}
						if(cont){
							continue;
						}
					}

					list.push_back(DeathEntry(mdc, cb.total, Combat::isUnjustKill(mdc, this)));
				}
			}
		}
		// Sort them by damage, first is always final hit killer
		if(list.size() > 1){
			std::sort(list.begin() + 1, list.end(), DeathLessThan());
		}
	}

	if(list.size() > (uint32_t)assist_count + 1){
		// Shrink list to assist_count
		list.resize(assist_count + 1, DeathEntry("", -1));
	}

	return list;
}