void OnPVPKill(Player * killer, Player * victim)
	{
		if (killer->GetGUID() == victim->GetGUID())
			return;
		if (isInArena(killer) || isInArena(victim))
			return;
		
		int32 kKillstreak = GetKillstreak(killer);
		int32 vKillstreak = GetKillstreak(victim);

		if (vKillstreak >= 25)
			killer->SetArenaPoints(killer->GetArenaPoints() + 50);

		if (kKillstreak == -1)
			CharacterDatabase.PExecute("REPLACE INTO killstreak(guid, ks) VALUES ('%u', 1)", killer->GetGUID());
		else
		{
			CharacterDatabase.PExecute("UPDATE killstreak SET ks = (ks+1) WHERE guid = '%u'", killer->GetGUID());
			QueryResult ks = CharacterDatabase.PQuery("SELECT * FROM killstreak WHERE guid = '%u'", killer->GetGUID());
			Field * high_ks = ks->Fetch();
			if (kKillstreak > high_ks[2].GetInt32())
				CharacterDatabase.PExecute("UPDATE killstreak SET high_ks = ks WHERE guid = '%u'", killer->GetGUID());

		}

		if (vKillstreak > 0)
		{
			CharacterDatabase.PExecute("UPDATE killstreak SET ks = 0 WHERE guid = '%u'", victim->GetGUID());
			// Only send a server message if their streak is 5 or more
			if (vKillstreak >= 5)
				alertServer(killer, victim, vKillstreak, 0);
		}

		switch(kKillstreak)
		{
			case 5:
				alertServer(killer, victim, kKillstreak, 1);
				killer->AddItem(6657, 5);
				break;
			case 10:
				alertServer(killer, victim, kKillstreak, 1);
				killer->AddItem(20558, 1);
				break;
			case 15:
				alertServer(killer, victim, kKillstreak, 1);
				killer->AddItem(8529, 15);
				break;
			case 20:
				alertServer(killer, victim, kKillstreak, 1);
				killer->AddItem(20558, 2);
				break;
			case 25:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 30:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 3);
				break;
			case 35:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 40:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 4);
				break;
			case 45:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 50:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 5);
				break;
			case 55:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 60:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 6);
				break;
			case 65:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 70:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 7);
				break;
			case 75:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 80:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 8);
				break;
			case 85:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 90:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 9);
				break;
			case 95:
				alertServer(killer, victim, kKillstreak, 2);
				break;
			case 100:
				alertServer(killer, victim, kKillstreak, 2);
				killer->AddItem(20558, 10);
				break;
		}
	}
Beispiel #2
0
void CUser::Regene(uint8 regene_type, uint32 magicid /*= 0*/)
{
	ASSERT(GetMap() != nullptr);

	_OBJECT_EVENT* pEvent = nullptr;
	_HOME_INFO* pHomeInfo = nullptr;
	float x = 0.0f, z = 0.0f;

	if (!isDead())
		return;

	if (regene_type != 1 && regene_type != 2)
		regene_type = 1;

	if (regene_type == 2) 
	{
		magicid = 490041;	// The Stone of Ressurection magic ID

		// Is our level high enough to be able to resurrect using this skill?
		if (GetLevel() <= 5
			// Do we have enough resurrection stones?
				|| !RobItem(379006000, 3 * GetLevel()))
				return;
	}

	// If we're in a home zone, we'll want the coordinates from there. Otherwise, assume our own home zone.
	pHomeInfo = g_pMain->m_HomeArray.GetData(GetZoneID() <= ZONE_ELMORAD ? GetZoneID() : GetNation());
	if (pHomeInfo == nullptr)
		return;

	UserInOut(INOUT_OUT);

	pEvent = GetMap()->GetObjectEvent(m_sBind);	

	// If we're not using a spell to resurrect.
	if (magicid == 0) 
	{
		// Resurrect at a bind/respawn point
		if (pEvent != nullptr && pEvent->byLife == 1)
		{
			SetPosition(pEvent->fPosX + x, 0.0f, pEvent->fPosZ + z);
		}
		// Are we trying to respawn in a home zone?
		else if (GetZoneID() <= ZONE_ELMORAD) 
		{
			// Use the proper respawn area for our nation, as the opposite nation can
			// enter this zone at a war's invasion stage.
			if (GetNation() == KARUS) 
			{
				x = (float)(pHomeInfo->KarusZoneX + myrand(0, pHomeInfo->KarusZoneLX));
				z = (float)(pHomeInfo->KarusZoneZ + myrand(0, pHomeInfo->KarusZoneLZ));			
			}
			else 
			{
				x = (float)(pHomeInfo->ElmoZoneX + myrand(0, pHomeInfo->ElmoZoneLX));
				z = (float)(pHomeInfo->ElmoZoneZ + myrand(0, pHomeInfo->ElmoZoneLZ));
			}		
		}
		else
		{
			// If we're in a war zone (aside from snow wars, which apparently use different coords), use BattleZone coordinates.
			if (GetZoneID() != ZONE_SNOW_BATTLE 
				&& GetZoneID() == (ZONE_BATTLE_BASE + g_pMain->m_byBattleZone))
			{
				x = (float)(pHomeInfo->BattleZoneX + myrand(0, pHomeInfo->BattleZoneLX));
				z = (float)(pHomeInfo->BattleZoneZ + myrand(0, pHomeInfo->BattleZoneLZ));
			}
			// If we died in the Moradon arena, we need to spawn near the Arena.
			else if (GetZoneID() == ZONE_MORADON && isInArena())
			{
				x = (float)(MINI_ARENA_RESPAWN_X + myrand(-MINI_ARENA_RESPAWN_RADIUS, MINI_ARENA_RESPAWN_RADIUS));
				z = (float)(MINI_ARENA_RESPAWN_Z + myrand(-MINI_ARENA_RESPAWN_RADIUS, MINI_ARENA_RESPAWN_RADIUS));
			}
			// For all else, just grab the start position (/town coordinates) from the START_POSITION table.
			else
			{
				short sx, sz;
				GetStartPosition(sx, sz);

				x = sx;
				z = sz;
			}
		}

		SetPosition(x, 0.0f, z);

		m_bResHpType = USER_STANDING;	
		m_bRegeneType = REGENE_NORMAL;
	}
	else // we're respawning using a resurrect skill.
	{
		_MAGIC_TYPE5 * pType = g_pMain->m_Magictype5Array.GetData(magicid);     
		if (pType == nullptr)
			return;

		MSpChange(-m_iMaxMp); // reset us to 0 MP. 

		if (m_sWhoKilledMe == -1) 
			ExpChange((m_iLostExp * pType->bExpRecover) / 100); // Restore 

		m_bResHpType = USER_STANDING;
		m_bRegeneType = REGENE_MAGIC;
	}

	Packet result(WIZ_REGENE);
	result << GetSPosX() << GetSPosZ() << GetSPosY();
	Send(&result);

	HpChange(GetMaxHealth());

	m_tLastRegeneTime = UNIXTIME;
	m_sWhoKilledMe = -1;
	m_iLostExp = 0;

	if (magicid == 0)
		BlinkStart();

	if (!isBlinking())
	{
		result.Initialize(AG_USER_REGENE);
		result << GetSocketID() << m_sHp;
		Send_AIServer(&result);
	}

	SetRegion(GetNewRegionX(), GetNewRegionZ());

	UserInOut(INOUT_RESPAWN);		

	g_pMain->RegionUserInOutForMe(this);
	g_pMain->RegionNpcInfoForMe(this);

	InitializeStealth();
	SendUserStatusUpdate(USER_STATUS_DOT, USER_STATUS_CURE);
	SendUserStatusUpdate(USER_STATUS_POISON, USER_STATUS_CURE);

	if (isInArena())
		SendUserStatusUpdate(USER_STATUS_SPEED, USER_STATUS_CURE);

	RecastSavedMagic();

	// If we actually respawned (i.e. we weren't resurrected by a skill)...
	if (magicid == 0)
	{
		// In PVP zones (not war zones), we must kick out players if they no longer
		// have any national points.
		if (GetMap()->isNationPVPZone() 
			&& GetMap()->isWarZone()
			&& GetLoyalty() == 0)
			KickOutZoneUser(false);
	}
}