/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "StdAfx.h" void WorldSession::HandleSetVisibleRankOpcode(WorldPacket& recv_data) { CHECK_PACKET_SIZE(recv_data, 4); uint32 ChosenRank; recv_data >> ChosenRank; if(ChosenRank == 0xFFFFFFFF) _player->SetUInt32Value(PLAYER_CHOSEN_TITLE, 0); else _player->SetUInt32Value(PLAYER_CHOSEN_TITLE, ChosenRank); } void HonorHandler::AddHonorPointsToPlayer(Player *pPlayer, uint32 uAmount) { pPlayer->m_honorPoints += uAmount; pPlayer->m_honorToday += uAmount; pPlayer->HandleProc(PROC_ON_GAIN_EXPIERIENCE, pPlayer, NULL); pPlayer->m_procCounter = 0; RecalculateHonorFields(pPlayer); } time_t HonorHandler::GetNextUpdateTime() { time_t ct = time(NULL); struct tm * tp = localtime(&ct); tm now_time = *tp; now_time.tm_hour = now_time.tm_min = now_time.tm_sec = 0; return mktime(&now_time); } void HonorHandler::PerformStartupTasks() { Log.Notice("HonorHandler", "Starting Honor System..."); Log.Notice("HonorHandler", "Checking for out of date players and moving their kill values..."); uint32 next_update = GetNextUpdateTime(); uint32 now_update = time(NULL); CharacterDatabase.WaitExecute("UPDATE characters SET lastDailyReset = %u, killsYesterday = killsToday, honorYesterday = honorToday, killsToday = 0, honorToday = 0 WHERE lastDailyReset < %u", now_update, next_update); } int32 HonorHandler::CalculateHonorPointsForKill(Player *pPlayer, Unit* pVictim) { // this sucks.. ;p if(!pVictim) { int pts = rand() % 100 + 100; return pts; } if(pVictim->HasActiveAura(2479)) // How dishonorable, you fiend! return 0; if(pVictim != pPlayer && pVictim->GetTypeId() == TYPEID_PLAYER) { uint32 k_level = pPlayer->GetUInt32Value(UNIT_FIELD_LEVEL); uint32 v_level = pVictim->GetUInt32Value(UNIT_FIELD_LEVEL); int k_honor = pPlayer->m_honorPoints; // or whatever function is :P int v_honor = static_cast(pVictim)->m_honorPoints; //uint32 total_kills = pPlayer->m_killsToday; uint32 k_grey = 0; if (k_level > 5 && k_level < 40) { k_grey = k_level - (uint32)(5 + floor(float(float(k_level) / 10.0f))); } else { k_grey = k_level - (uint32)(1 + floor(float(float(k_level) / 5.0f))); } float tmp = (float)(k_level - k_grey); if(tmp == 0.0f) tmp = 1.0f; if(k_honor == 0) k_honor = 1; float diff_level = ((float)(v_level-k_grey)) / ((float)(k_level - k_grey)); if(diff_level > 2) diff_level = 2.0; if(diff_level < 0) diff_level = 0.0; float diff_honor = ((float)v_honor) / ((float)k_honor); if(diff_honor > 3) diff_honor = 3.0; if(diff_honor < 0) diff_honor = 0.0; float honor_points = diff_level * (150 + diff_honor*60); honor_points *= ((float)k_level) / 70.0; honor_points *= World::getSingleton().getRate(RATE_HONOR); return float2int32(honor_points); } return 0; } void HonorHandler::OnPlayerKilledUnit(Player *pPlayer, Unit* pVictim) { if(pVictim && (!pVictim->IsPlayer() || static_cast(pVictim)->m_honorless)) return; if(pVictim && pVictim->IsPlayer() && static_cast(pVictim)->GetTeam() == pPlayer->GetTeam()) return; // Calculate points int32 Points = CalculateHonorPointsForKill(pPlayer, pVictim); if(Points > 0) { if(pPlayer->GetGroup()) { Group *pGroup = pPlayer->GetGroup(); Player *gPlayer = NULL; int32 GroupPoints; pGroup->Lock(); GroupPoints = (Points / (pGroup->MemberCount() ? pGroup->MemberCount() : 1)); GroupMembersSet::iterator gitr; for(uint32 k = 0; k < pGroup->GetSubGroupCount(); k++) { for(gitr = pGroup->GetSubGroup(k)->GetGroupMembersBegin(); gitr != pGroup->GetSubGroup(k)->GetGroupMembersEnd(); ++gitr) { gPlayer = gitr->player; if(gPlayer && (gPlayer == pPlayer || gPlayer->isInRange(pPlayer,100.0f))) // visible range { gPlayer->m_killsToday++; gPlayer->m_killsLifetime++; if(gPlayer->m_bg) gPlayer->m_bg->HookOnHK(gPlayer); AddHonorPointsToPlayer(gPlayer, GroupPoints); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = GroupPoints * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast(pVictim)->GetPVPRank()); gPlayer->GetSession()->SendPacket(&data); } } } } pGroup->Unlock(); } else { pPlayer->m_killsToday++; pPlayer->m_killsLifetime++; AddHonorPointsToPlayer(pPlayer, Points); if(pPlayer->m_bg) pPlayer->m_bg->HookOnHK(pPlayer); if(pVictim) { // Send PVP credit WorldPacket data(SMSG_PVP_CREDIT, 12); uint32 pvppoints = Points * 10; data << pvppoints << pVictim->GetGUID() << uint32(static_cast(pVictim)->GetPVPRank()); pPlayer->GetSession()->SendPacket(&data); } } } } void HonorHandler::RecalculateHonorFields(Player *pPlayer) { // Why are we multiplying by 10.. ho well pPlayer->SetUInt32Value(PLAYER_FIELD_KILLS, pPlayer->m_killsToday); pPlayer->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, pPlayer->m_honorToday); pPlayer->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, pPlayer->m_killsYesterday | ( (pPlayer->m_honorYesterday * 10) << 16)); pPlayer->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, pPlayer->m_killsLifetime); // if(pPlayer->m_honorPoints < 0) // return; pPlayer->SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, pPlayer->m_honorPoints); } void HonorHandler::DailyFieldMove(Player *pPlayer) { // Move fields pPlayer->m_honorYesterday = pPlayer->m_honorToday; pPlayer->m_killsYesterday = pPlayer->m_killsToday; pPlayer->m_killsToday = 0; pPlayer->m_honorToday = 0; // update fields RecalculateHonorFields(pPlayer); pPlayer->LastHonorResetTime(time(NULL)); pPlayer->SaveHonorFields(); } bool ChatHandler::HandleAddKillCommand(const char* args, WorldSession* m_session) { uint32 KillAmount = args ? atol(args) : 1; Player *plr = getSelectedChar(m_session, true); if(plr == 0) return true; BlueSystemMessage(m_session, "Adding %u kills to player %s.", KillAmount, plr->GetName()); GreenSystemMessage(plr->GetSession(), "You have had %u honor kills added to your character.", KillAmount); for(uint32 i = 0; i < KillAmount; ++i) HonorHandler::OnPlayerKilledUnit(plr, 0); return true; } bool ChatHandler::HandleAddHonorCommand(const char* args, WorldSession* m_session) { uint32 HonorAmount = args ? atol(args) : 1; Player *plr = getSelectedChar(m_session, true); if(plr == 0) return true; BlueSystemMessage(m_session, "Adding %u honor to player %s.", HonorAmount, plr->GetName()); GreenSystemMessage(plr->GetSession(), "You have had %u honor points added to your character.", HonorAmount); HonorHandler::AddHonorPointsToPlayer(plr, HonorAmount); return true; } bool ChatHandler::HandlePVPCreditCommand(const char* args, WorldSession* m_session) { uint32 Rank, Points; if(sscanf(args, "%u %u", (unsigned int*)&Rank, (unsigned int*)&Points) != 2) { RedSystemMessage(m_session, "Command must be in format ."); return true; } Points *= 10; uint64 Guid = m_session->GetPlayer()->GetSelection(); if(Guid == 0) { RedSystemMessage(m_session, "A selection of a unit or player is required."); return true; } BlueSystemMessage(m_session, "Building packet with Rank %u, Points %u, GUID "I64FMT".", Rank, Points, Guid); WorldPacket data(SMSG_PVP_CREDIT, 12); data << Points << Guid << Rank; m_session->SendPacket(&data); return true; } bool ChatHandler::HandleGlobalHonorDailyMaintenanceCommand(const char* args, WorldSession* m_session) { return false; } bool ChatHandler::HandleNextDayCommand(const char* args, WorldSession* m_session) { Player * plr = getSelectedChar(m_session); if(plr == 0) return true; BlueSystemMessage(m_session, "Moving honor fields to tomorrow for player %s.", plr->GetName()); GreenSystemMessage(m_session, "%s moved your honor fields to tomorrow.", m_session->GetPlayer()->GetName()); HonorHandler::DailyFieldMove(plr); return true; }