📄 pvp.cpp.svn-base
字号:
#include "StdAfx.h"
#define FORTRESS_PREPARATION 32727
#define FORTRESS_WORLD_STATE_A_PLAYER_COUNT 2544
#define FORTRESS_WORLD_STATE_H_PLAYER_COUNT 2545
#define GREEN_TEAM 0
#define GOLD_TEAM 1
FORTRESS::FORTRESS(MapMgr * mgr, uint32 id, uint32 lgroup, uint32 t, uint32 players_per_side) : CBattleground(mgr, id, lgroup, t)
{
m_started = false;
m_playerCountPerTeam = players_per_side;
switch(t)
{
case BATTLEGROUND_FORTRESS_5V5:
m_FORTRESSteamtype=2;
break;
case BATTLEGROUND_FORTRESS_3V3:
m_FORTRESSteamtype=1;
break;
case BATTLEGROUND_FORTRESS_2V2:
m_FORTRESSteamtype=0;
break;
default:
m_FORTRESSteamtype=0;
break;
}
rated_match=false;
}
FORTRESS::~FORTRESS()
{
}
void FORTRESS::OSUPddPlayer(Player * plr)
{
if( !m_started )
{
/* cast FORTRESS readyness buff */
if(plr->isDead())
plr->ResurrectPlayer();
plr->SetUInt32Value(UNIT_FIELD_HEALTH, plr->GetUInt32Value(UNIT_FIELD_MAXHEALTH));
plr->SetUInt32Value(UNIT_FIELD_POWER1, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER1));
plr->SetUInt32Value(UNIT_FIELD_POWER4, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER4));
sEventMgr.AddEvent(plr, &Player::FullHPMP, EVENT_PLAYER_UPDATE, 500, 1, 0);
sEventMgr.AddEvent(plr, &Player::ResetAllCooldowns, EVENT_PLAYER_UPDATE, 500, 1, 0);
}
plr->m_deathVision = true;
// remove all buffs (exclude talents, include flasks)
for(uint32 x=0;x<MAX_AURAS;x++)
{
if(plr->m_auras[x])
{
if(plr->m_auras[x] && !plr->m_auras[x]->GetSpellProto()->DurationIndex && plr->m_auras[x]->GetSpellProto()->Flags4 & CAN_PERSIST_AND_CASTED_WHILE_DEAD)
continue;
else
{
plr->m_auras[x]->Remove();
}
}
}
plr->GetItemInterface()->RemoveAllConjured();
plr->ResetAllCooldowns();
if( !m_started )
plr->CastSpell(plr, FORTRESS_PREPARATION, true);
UpdatePlayerCounts();
/* Add the green/gold team flag */
Aura * aura = new Aura(dbcSpell.LookupEntry(32725-plr->m_bgTeam), -1, plr, plr);
plr->AddAura(aura);
/* Set FFA PvP Flag */
if(!plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_FREE_FOR_ALL_PVP))
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_FREE_FOR_ALL_PVP);
/* update FORTRESS team stats */
if(rated_match && plr->m_FORTRESSTeams[m_FORTRESSteamtype] != NULL)
{
FORTRESSTeam * t = plr->m_FORTRESSTeams[m_FORTRESSteamtype];
FORTRESSTeamMember * tp = t->GetMember(plr->m_playerInfo);
if(doneteams.find(t) == doneteams.end())
{
t->m_stat_gamesplayedseason++;
t->m_stat_gamesplayedweek++;
doneteams.insert(t);
}
if(tp != NULL)
{
tp->Played_ThisWeek++;
tp->Played_ThisSeason++;
}
t->SaveToDB();
}
}
void FORTRESS::OnRemovePlayer(Player * plr)
{
/* remove FORTRESS readyness buff */
plr->m_deathVision = false;
plr->RemoveAura(FORTRESS_PREPARATION);
UpdatePlayerCounts();
plr->RemoveAura(32725-plr->m_bgTeam);
if(plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_FREE_FOR_ALL_PVP))
plr->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_FREE_FOR_ALL_PVP);
}
void FORTRESS::HookOnPlayerKill(Player * plr, Unit * pVictim)
{
plr->m_bgScore.KillingBlows++;
UpdatePlayerCounts();
}
void FORTRESS::HookOnHK(Player * plr)
{
plr->m_bgScore.HonorableKills++;
}
void FORTRESS::HookOnPlayerDeath(Player * plr)
{
}
void FORTRESS::OnCreate()
{
GameObject * obj;
switch(m_mapMgr->GetMapId())
{
/* loraedeon */
case 572: {
obj = SpawnGameObject(185917, 572, 1278.647705f, 1730.556641f, 31.605574f, 1.684245f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.746058f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, 0.665881f);
m_gates.insert(obj);
obj = SpawnGameObject(185918, 572, 1293.560791f, 1601.937988f, 31.605574f, -1.457349f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, -0.665881f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, 0.746058f);
m_gates.insert(obj);
}break;
/* blades edge FORTRESS */
case 562: {
obj = SpawnGameObject(183972, 562, 6177.707520f, 227.348145f, 3.604374f, -2.260201f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.90445f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, -0.426569f);
obj->PushToWorld(m_mapMgr);
obj = SpawnGameObject(183973, 562, 6189.546387f, 241.709854f, 3.101481f, 0.881392f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.426569f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, 0.904455f);
m_gates.insert(obj);
obj = SpawnGameObject(183970, 562, 6299.115723f, 296.549438f, 3.308032f, 0.881392f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.426569f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, 0.904455f);
obj->PushToWorld(m_mapMgr);
obj = SpawnGameObject(183971, 562, 6287.276855f, 282.187714f, 3.810925f, -2.260201f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.904455f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, -0.426569f);
m_gates.insert(obj);
}break;
/* SUPgrand FORTRESS */
case 559: {
obj = SpawnGameObject(183979, 559, 4090.064453f, 2858.437744f, 10.236313f, 0.492805f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.243916f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, 0.969796f);
obj->PushToWorld(m_mapMgr);
obj = SpawnGameObject(183980, 559, 4081.178955f, 2874.970459f, 12.391714f, 0.492805f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.243916f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, 0.969796f);
m_gates.insert(obj);
obj = SpawnGameObject(183977, 559, 4023.709473f, 2981.776611f, 10.701169f, -2.648788f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.969796f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, -0.243916f);
obj->PushToWorld(m_mapMgr);
obj = SpawnGameObject(183978, 559, 4031.854248f, 2966.833496f, 12.646200f, -2.648788f, 32, 1375, 1.0f);
obj->SetUInt32Value(GAMEOBJECT_STATE, 1);
obj->SetFloatValue(GAMEOBJECT_ROTATION_02, 0.969796f);
obj->SetFloatValue(GAMEOBJECT_ROTATION_03, -0.243916f);
m_gates.insert(obj);
}break;
}
/* push gates into world */
for(set<GameObject*>::iterator itr = m_gates.begin(); itr != m_gates.end(); ++itr)
(*itr)->PushToWorld(m_mapMgr);
SetWorldState(0x08D4 ,0x0000);
SetWorldState(0x08D8 ,0x0000);
SetWorldState(0x08D7 ,0x0000);
SetWorldState(0x08D6 ,0x0000);
SetWorldState(0x08D5 ,0x0000);
SetWorldState(0x08D3 ,0x0000);
SetWorldState(0x09F1 ,0x0000);
SetWorldState(0x09F0 ,0x0000);
SetWorldState(0x0C0D ,0x017B);
SetWorldState(0x09F3 ,0x0001);
}
void FORTRESS::OnStart()
{
/* remove FORTRESS readyness buff */
for(uint32 i = 0; i < 2; ++i) {
for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr) {
(*itr)->RemoveAura(FORTRESS_PREPARATION);
}
}
/* open gates */
for(set<GameObject*>::iterator itr = m_gates.begin(); itr != m_gates.end(); ++itr)
{
(*itr)->SetUInt32Value(GAMEOBJECT_FLAGS, 64);
(*itr)->SetUInt32Value(GAMEOBJECT_STATE, 0);
}
m_started = true;
/* Incase all players left */
UpdatePlayerCounts();
}
void FORTRESS::UpdatePlayerCounts()
{
if(m_ended)
return;
uint32 players[2] = {0,0};
for(uint32 i = 0; i < 2; ++i) {
for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr) {
if((*itr)->isAlive())
players[i]++;
}
}
SetWorldState(FORTRESS_WORLD_STATE_A_PLAYER_COUNT, players[0]);
SetWorldState(FORTRESS_WORLD_STATE_H_PLAYER_COUNT, players[1]);
if(!m_started)
return;
if(players[1] == 0)
m_winningteam = 0;
else if(players[0] == 0)
m_winningteam = 1;
else
return;
Finish();
}
void FORTRESS::Finish()
{
m_ended = true;
m_nextPvPUpdateTime = 0;
UpdatePvPData();
PlaySoundToAll(m_winningteam ? SOUND_EUROPEANSWINS : SOUND_CHINESEWINS);
sEventMgr.RemoveEvents(this, EVENT_BATTLEGROUND_CLOSE);
sEventMgr.AddEvent(((CBattleground*)this), &CBattleground::Close, EVENT_BATTLEGROUND_CLOSE, 120000, 1,0);
/* update FORTRESS team stats */
doneteams.clear();
if(rated_match)
{
uint32 averageRating[2] = {0,0};
for(uint32 i = 0; i < 2; ++i) {
uint32 teamCount = 0;
for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
{
Player * plr = *itr;
if(plr->m_FORTRESSTeams[m_FORTRESSteamtype] != NULL)
{
FORTRESSTeam * t = plr->m_FORTRESSTeams[m_FORTRESSteamtype];
if(doneteams.find(t) == doneteams.end())
{
averageRating[i] += t->m_stat_rating;
teamCount++;
doneteams.insert(t);
}
}
}
if(teamCount)
averageRating[i] /= teamCount;
}
doneteams.clear();
for (uint32 i = 0; i < 2; ++i) {
uint32 j = i ? 0 : 1; // opposing side
bool outcome;
outcome = (i == m_winningteam);
// ---- Elo Rating System ----
// Expected Chance to Win for Team A vs Team B
// 1
// -------------------------------------------
// (PB - PA)/400
// 1 + 10
double power = (int)(averageRating[j] - averageRating[i]) / 400.0f;
double divisor = pow(((double)(10.0)), power);
divisor += 1.0;
double winChance = 1.0 / divisor;
for(set<Player*>::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
{
Player * plr = *itr;
if(plr->m_FORTRESSTeams[m_FORTRESSteamtype] != NULL)
{
FORTRESSTeam * t = plr->m_FORTRESSTeams[m_FORTRESSteamtype];
FORTRESSTeamMember * tp = t->GetMember(plr->m_playerInfo);
if(doneteams.find(t) == doneteams.end())
{
if (outcome)
{
t->m_stat_gameswonseason++;
t->m_stat_gameswonweek++;
}
// New Rating Calculation via Elo
// New Rating = Old Rating + K * (outcome - Expected Win Chance)
// outcome = 1 for a win and 0 for a loss (0.5 for a draw ... but we cant have that)
// K is the maximum possible change
// Through investigation, K was estimated to be 32 (same as chess)
double multiplier = (outcome ? 1.0 : 0.0) - winChance;
double deltaRating = 32.0 * multiplier;
if ( deltaRating < 0 && (-1.0 * deltaRating) > t->m_stat_rating )
t->m_stat_rating = 0;
else
t->m_stat_rating += long2int32(deltaRating);
objmgr.UpdateFORTRESSTeamRankings();
doneteams.insert(t);
}
if(tp != NULL && outcome)
{
tp->Won_ThisWeek++;
tp->Won_ThisSeason++;
}
t->SaveToDB();
}
}
}
}
for(int i = 0; i < 2; i++)
{
bool victorious = (i == m_winningteam);
set<Player*>::iterator itr = m_players[i].begin();
for(; itr != m_players[i].end(); itr++)
{
Player * plr = (Player *)(*itr);
sHookInterface.OnFORTRESSFinish(plr, plr->m_FORTRESSTeams[m_FORTRESSteamtype], victorious, rated_match);
}
}
}
LocationVector FORTRESS::GetStartingCoords(uint32 Team)
{
// 559, 562, 572
/*
A start
H start
Repop
572 1295.322388 1585.953369 31.605387
572 1277.105103 1743.956177 31.603209
572 1286.112061 1668.334961 39.289127
562 6184.806641 236.643463 5.037095
562 6292.032227 287.570343 5.003577
562 6241.171875 261.067322 0.891833
559 4085.861328 2866.750488 12.417445
559 4027.004883 2976.964844 11.600499
559 4057.042725 2918.686523 13.051933
*/
switch(m_mapMgr->GetMapId())
{
/* */
case 572:
{
if(Team)
return LocationVector(1277.105103f, 1743.956177f, 31.603209f);
else
return LocationVector(1295.322388f, 1585.953369f, 31.605387f);
}break;
/* FORTRESS */
case 562:
{
if(Team)
return LocationVector(6292.032227f, 287.570343f, 5.003577f);
else
return LocationVector(6184.806641f, 236.643463f, 5.037095f);
}break;
/* FORTRESS */
case 559:
{
if(Team)
return LocationVector(4027.004883f, 2976.964844f, 11.600499f);
else
return LocationVector(4085.861328f, 2866.750488f, 12.417445f);
}break;
}
return LocationVector(0,0,0,0);
}
bool FORTRESS::HookHandleRepop(Player * plr)
{
// 559, 562, 572
/*
A start
H start
Repop
572 1295.322388 1585.953369 31.605387
572 1277.105103 1743.956177 31.603209
572 1286.112061 1668.334961 39.289127
562 6184.806641 236.643463 5.037095
562 6292.032227 287.570343 5.003577
562 6241.171875 261.067322 0.891833
559 4085.861328 2866.750488 12.417445
559 4027.004883 2976.964844 11.600499
559 4057.042725 2918.686523 13.051933
*/
LocationVector dest(0,0,0,0);
switch(m_mapMgr->GetMapId())
{
/* */
case 572: {
dest.ChangeCoords(1286.112061f, 1668.334961f, 39.289127f);
}break;
/* FORTRESS */
case 562: {
dest.ChangeCoords(6241.171875f, 261.067322f, 0.891833f);
}break;
/* FORTRESS */
case 559: {
dest.ChangeCoords(4057.042725f, 2918.686523f, 13.051933f);
}break;
}
plr->SafeTeleport(m_mapMgr->GetMapId(), m_mapMgr->GetInstanceID(), dest);
return true;
}
void FORTRESS::HookOnTRIGGER(Player * plr, uint32 id)
{
}
void Player::FullHPMP()
{
if(isDead())
ResurrectPlayer();
SetUInt32Value(UNIT_FIELD_HEALTH, GetUInt32Value(UNIT_FIELD_MAXHEALTH));
SetUInt32Value(UNIT_FIELD_POWER1, GetUInt32Value(UNIT_FIELD_MAXPOWER1));
SetUInt32Value(UNIT_FIELD_POWER4, GetUInt32Value(UNIT_FIELD_MAXPOWER4));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -