Skip to content

Instantly share code, notes, and snippets.

@qyh214
Forked from irancore/PhasedDuelingwithcmd.cpp
Created September 4, 2019 04:13
Show Gist options
  • Save qyh214/ca5da29e6694e9848cdc792d893f2678 to your computer and use it in GitHub Desktop.
Save qyh214/ca5da29e6694e9848cdc792d893f2678 to your computer and use it in GitHub Desktop.
Last rev trinitycore (PhasedDueling&Command Duel watching)
/*
Original Script was done by Teiby from emu-devstore
Last Update and added cmd watching by irancore.ir
*/
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "Battleground.h"
#include "CellImpl.h"
#include "CreatureTextMgr.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
#include "GroupMgr.h"
#include "Log.h"
#include "Map.h"
#include "MapManager.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "WorldSession.h"
#include "WorldStatePackets.h"
#include "Config.h"
#include "Object.h"
#include "Unit.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "SpellAuraEffects.h"
#include <G3D/g3dmath.h>
#include "Transport.h"
#include "Unit.h"
#include "UpdateFieldFlags.h"
#include "Vehicle.h"
#include "VMapFactory.h"
#include "World.h"
#include "rbac.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
#include "SpellHistory.h"
#include "SpellMgr.h"
#include "Chat.h"
#include "Pet.h"
#include <G3D/Vector3.h>
class PhasedDueling : public PlayerScript
{
public:
PhasedDueling() : PlayerScript("PhasedDueling") {}
void OnDuelStart(Player* firstplayer, Player* secondplayer) override
{
if (sConfigMgr->GetBoolDefault("PhasedDueling.Enable", true))
{
Map* map = firstplayer->GetMap();
if (map->IsDungeon())
return;
// Duel flag is used as duel center point
GameObject* go = map->GetGameObject(ObjectGuid(firstplayer->GetUInt64Value(PLAYER_DUEL_ARBITER)));
if (!go)
return;
// Get players from 100 yard radius ( duel radius is 40-50 yd )
std::list<Player*> playerList;
Trinity::AnyPlayerInObjectRangeCheck checker(go, 100.0f);
Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(go, playerList, checker);
Cell::VisitWorldObjects(go, searcher, 100.0f);
// insert players' phases to used phases, ignore GMs
uint32 usedPhases = 0;
if (!playerList.empty())
for (std::list<Player*>::const_iterator it = playerList.begin(); it != playerList.end(); ++it)
if (!(*it)->IsGameMaster())
usedPhases |= (*it)->GetPhaseMask();
// loop all unique phases
for (uint32 phase = 2; phase <= ULONG_MAX / 2; phase *= 2)
{
// If phase in use, skip
if (usedPhases & phase)
continue;
// Phase players & pets, dont update visibility yet
firstplayer->SetPhaseMask(phase, false);
secondplayer->SetPhaseMask(phase, false);
// Phase duel flag
go->SetPhaseMask(phase, true);
// Update visibility here so pets will be phased and wont despawn
firstplayer->UpdateObjectVisibility();
secondplayer->UpdateObjectVisibility();
return;
}
// Couldnt find free unique phase
firstplayer->GetSession()->SendNotification("There are no free phases");
secondplayer->GetSession()->SendNotification("There are no free phases");
}
}
// Restore phases
void OnDuelEnd(Player* firstplayer, Player* secondplayer, DuelCompleteType type) override
{
if (sConfigMgr->GetBoolDefault("PhasedDueling.Enable", true))
{
// Phase players, dont update visibility yet
firstplayer->SetPhaseMask(GetNormalPhase(firstplayer), false);
secondplayer->SetPhaseMask(GetNormalPhase(secondplayer), false);
// Update visibility here so pets will be phased and wont despawn
firstplayer->UpdateObjectVisibility();
secondplayer->UpdateObjectVisibility();
}
}
// Attempt in storing the player phase with spell phases included.
uint32 GetNormalPhase(Player* player) const
{
if (player->IsGameMaster())
return uint32(PHASEMASK_ANYWHERE);
// GetPhaseMaskForSpawn copypaste
uint32 phase = PHASEMASK_NORMAL;
Player::AuraEffectList const& phases = player->GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
phase = phases.front()->GetMiscValue();
if (uint32 n_phase = phase & ~PHASEMASK_NORMAL)
return n_phase;
return PHASEMASK_NORMAL;
}
};
class Duel_watching : public CommandScript
{
public:
Duel_watching() : CommandScript("Duel_watching") { }
static bool HandleDuelViewCommand(ChatHandler* handler, char const* args)
{
Player* target;
ObjectGuid target_guid;
std::string target_name;
if (!handler->extractPlayerTarget((char*)args, &target, &target_guid, &target_name))
return false;
Player* _player = handler->GetSession()->GetPlayer();
if (target == _player || target_guid == _player->GetGUID())
{
handler->PSendSysMessage(LANG_CANT_TELEPORT_SELF);
handler->SetSentErrorMessage(true);
return false;
}
if (target)
{
// check online security
if (handler->HasLowerSecurity(target, ObjectGuid::Empty))
return false;
std::string chrNameLink = handler->playerLink(target_name);
if (!target->duel)
{
handler->PSendSysMessage("Target is not dueling.");
handler->SetSentErrorMessage(true);
return false;
}
if (target->GetPhaseMask() == _player->GetPhaseMask())
{
handler->PSendSysMessage("You are in the same phase.");
handler->SetSentErrorMessage(true);
return false;
}
Map* cMap_target = target->GetMap();
if(cMap_target != _player->GetMap())
{
handler->PSendSysMessage("Must be in the same map.");
handler->SetSentErrorMessage(true);
return false;
}
if (cMap_target->IsBattlegroundOrArena() || cMap_target->IsDungeon() || cMap_target->IsRaid())
{
handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str());
handler->SetSentErrorMessage(true);
return false;
}
// stop flight if need
if (_player->IsInFlight())
_player->FinishTaxiFlight();
// save only in non-flight case
else
_player->SaveRecallPosition();
// to point to see at target with same orientation
float x, y, z;
target->GetContactPoint(_player, x, y, z);
_player->SetFaction(35);
_player->CombatStop();
if (_player->IsNonMeleeSpellCast(true))
_player->InterruptNonMeleeSpells(true);
//if player class = hunter || warlock remove pet if alive
if ((_player->GetClass() == CLASS_HUNTER) || (_player->GetClass() == CLASS_WARLOCK))
{
if (Pet* pet = _player->GetPet())
{
pet->SavePetToDB(PET_SAVE_AS_CURRENT);
// not let dismiss dead pet
if (pet && pet->IsAlive())
_player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT);
}
}
_player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
_player->TeleportTo(target->GetMapId(), x, y, z, _player->GetRelativeAngle(target));
_player->SetPhaseMask(target->GetPhaseMask(), true);
_player->SaveToDB();
}
return true;
}
static bool HandleDuelLeaveCommand(ChatHandler* handler, char const* /*args*/)
{
Player* _player = handler->GetSession()->GetPlayer();
_player->SetFactionForRace(_player->GetRace());
_player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
_player->SetPhaseMask(1, true);
_player->SaveToDB();
return true;
}
std::vector<ChatCommand> GetCommands() const override
{
static std::vector<ChatCommand> DuelSubCommandsTable =
{
{ "view", rbac::RBAC_PERM_COMMAND_SAVE, true, &HandleDuelViewCommand, ""},
{ "leave", rbac::RBAC_PERM_COMMAND_SAVE, true, &HandleDuelLeaveCommand, ""},
};
static std::vector<ChatCommand> DuelCommandTable =
{
{ "duel", rbac::RBAC_PERM_COMMAND_SAVE, false,NULL,"", DuelSubCommandsTable },
};
return DuelCommandTable;
}
};
void AddSC_PhasedDueling()
{
new PhasedDueling();
new Duel_watching();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment