Code:
/*
* Friend Porter
* Copyright (C) 2008 Spidey <http://www.aspiredev.org/>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "StdAfx.h"
#include "Setup.h"
// This determines the cost of the port in copper
#define FRIENDCOST 100000
// The ID of the item used
#define FRIENDPORTID 61000
#define FP_ERR(s)\
Plr->BroadcastMessage(s);\
Plr->Gossip_Complete();\
return;
class SCRIPT_DECL FriendGrab : public GossipScript
{
public:
void GossipHello(Object * pObject, Player* Plr, bool AutoSend);
void GossipSelectOption(Object * pObject, Player* Plr, uint32 Id, uint32 IntId, const char * Code);
void GossipEnd(Object * pObject, Player* Plr);
void Destroy()
{
delete this;
}
};
void FriendGrab::GossipHello(Object * pObject, Player* Plr, bool AutoSend)
{
if(Plr->GetUInt32Value(PLAYER_FIELD_COINAGE) < FRIENDCOST)
{
Plr->BroadcastMessage("You don't have enough gold to teleport to another player.");
return;
}
GossipMenu *Menu;
objmgr.CreateGossipMenuForPlayer(&Menu, pObject->GetGUID(), 1, Plr);
Menu->AddItem(1, "Teleport to friend", 1, 1);
//Note:
// When menus have only one item, the one item gets auto-picked;
// The text "Teleport to friend" will not show up ingame unless you add at least one other item.
// Instead, the item will automatically pop the code request window.
if(AutoSend)
Menu->SendTo(Plr);
}
void FriendGrab::GossipSelectOption(Object* pObject, Player* Plr, uint32 Id, uint32 IntId, const char * Code)
{
switch(IntId)
{
case 0:
{
GossipHello(pObject, Plr, true);
}break;
case 1:
{
if(!Code)
return;
if(Plr->GetUInt32Value(PLAYER_FIELD_COINAGE) < FRIENDCOST)
return;
Player * pTarget = objmgr.GetPlayer(Code, false);
if(!pTarget)
FP_ERR("Player does not exist or is offline.");
if(pTarget->GetSession()->HasGMPermissions())
FP_ERR("Player does not exist or is offline."); //As to not expose GMs
if(Plr->CombatStatus.IsInCombat())
FP_ERR("You cannot teleport while in combat.");
if(Plr->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_FREE_FOR_ALL_PVP))
FP_ERR("You can't port while in a PvP zone.");
if(pTarget->GetTeam() != Plr->GetTeam())
FP_ERR("Player is from the opposing faction.");
if(pTarget->CombatStatus.IsInCombat())
FP_ERR("Your friend is in combat, you cannot teleport to him now.");
if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_FREE_FOR_ALL_PVP))
FP_ERR("You can't port to a player in a PvP zone.");
uint32 pMap = pTarget->GetMapId();
if(pMap != 0 && pMap != 1 && pMap != 530) //Assume that all other maps are instances
FP_ERR("Cannot port to a player inside an instance");
//if we reached so far, the player can port
Plr->SetUInt32Value(PLAYER_FIELD_COINAGE, Plr->GetUInt32Value(PLAYER_FIELD_COINAGE)-FRIENDCOST);
float pX = pTarget->GetPositionX();
float pY = pTarget->GetPositionY();
float pZ = pTarget->GetPositionZ();
float pO = pTarget->GetOrientation();
Plr->Gossip_Complete();
pTarget->BroadcastMessage("%s is porting to your location.", Plr->GetName());
Plr->EventTeleport(pMap, pX, pY, pZ);
Plr->SetOrientation(pO);
}break;
}
};
void FriendGrab::GossipEnd(Object * pObject, Player* Plr)
{
GossipScript::GossipEnd(pObject, Plr);
}
void SetupFriendPorter(ScriptMgr * mgr)
{
GossipScript * gs = (GossipScript*) new FriendGrab();
mgr->register_item_gossip_script(FRIENDPORTID, gs);
}