[svn] * svn:eol-style native set on all files that need it
--HG-- branch : trunk
This commit is contained in:
+157
-157
@@ -1,157 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "AggressorAI.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "VMapFactory.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
int
|
||||
AggressorAI::Permissible(const Creature *creature)
|
||||
{
|
||||
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
|
||||
if( !creature->isCivilian() && !creature->IsNeutralToAll() )
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
// Ignore Z for flying creatures
|
||||
if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
||||
return;
|
||||
|
||||
if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
|
||||
( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
|
||||
u->isInAccessablePlaceFor(&i_creature) )
|
||||
{
|
||||
float attackRadius = i_creature.GetAttackDistance(u);
|
||||
if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) )
|
||||
{
|
||||
AttackStart(u);
|
||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AggressorAI::EnterEvadeMode()
|
||||
{
|
||||
if( !i_creature.isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
|
||||
if( !victim )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( !victim->isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim->HasStealthAura() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim->isInFlight() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow());
|
||||
//i_state = STATE_LOOK_AT_VICTIM;
|
||||
//i_tracker.Reset(TIME_INTERVAL_LOOK);
|
||||
}
|
||||
|
||||
if(!i_creature.isCharmed())
|
||||
{
|
||||
i_creature.RemoveAllAuras();
|
||||
|
||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
i_creature.DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.SetLootRecipient(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
||||
return;
|
||||
|
||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AggressorAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::AttackStart(Unit *u)
|
||||
{
|
||||
if( !u )
|
||||
return;
|
||||
|
||||
if(i_creature.Attack(u,true))
|
||||
{
|
||||
i_creature.SetInCombatWith(u);
|
||||
u->SetInCombatWith(&i_creature);
|
||||
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
||||
i_victimGuid = u->GetGUID();
|
||||
|
||||
i_creature.GetMotionMaster()->MoveChase(u);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "AggressorAI.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "VMapFactory.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
int
|
||||
AggressorAI::Permissible(const Creature *creature)
|
||||
{
|
||||
// have some hostile factions, it will be selected by IsHostileTo check at MoveInLineOfSight
|
||||
if( !creature->isCivilian() && !creature->IsNeutralToAll() )
|
||||
return PERMIT_BASE_PROACTIVE;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
// Ignore Z for flying creatures
|
||||
if( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
||||
return;
|
||||
|
||||
if( !i_creature.getVictim() && !i_creature.hasUnitState(UNIT_STAT_STUNNED) && u->isTargetableForAttack() &&
|
||||
( i_creature.IsHostileTo( u ) /*|| u->getVictim() && i_creature.IsFriendlyTo( u->getVictim() )*/ ) &&
|
||||
u->isInAccessablePlaceFor(&i_creature) )
|
||||
{
|
||||
float attackRadius = i_creature.GetAttackDistance(u);
|
||||
if(i_creature.IsWithinDistInMap(u, attackRadius) && i_creature.IsWithinLOSInMap(u) )
|
||||
{
|
||||
AttackStart(u);
|
||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AggressorAI::EnterEvadeMode()
|
||||
{
|
||||
if( !i_creature.isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
|
||||
if( !victim )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( !victim->isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his victim is dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim->HasStealthAura() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his victim is stealth [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim->isInFlight() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking cuz his victim is fly away [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking due to target out run him [guid=%u]", i_creature.GetGUIDLow());
|
||||
//i_state = STATE_LOOK_AT_VICTIM;
|
||||
//i_tracker.Reset(TIME_INTERVAL_LOOK);
|
||||
}
|
||||
|
||||
if(!i_creature.isCharmed())
|
||||
{
|
||||
i_creature.RemoveAllAuras();
|
||||
|
||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
i_creature.DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.SetLootRecipient(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
||||
return;
|
||||
|
||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AggressorAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_MONSTER)
|
||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
||||
}
|
||||
|
||||
void
|
||||
AggressorAI::AttackStart(Unit *u)
|
||||
{
|
||||
if( !u )
|
||||
return;
|
||||
|
||||
if(i_creature.Attack(u,true))
|
||||
{
|
||||
i_creature.SetInCombatWith(u);
|
||||
u->SetInCombatWith(&i_creature);
|
||||
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
||||
i_victimGuid = u->GetGUID();
|
||||
|
||||
i_creature.GetMotionMaster()->MoveChase(u);
|
||||
}
|
||||
}
|
||||
|
||||
+463
-463
@@ -1,463 +1,463 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "WorldSession.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Log.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Language.h"
|
||||
|
||||
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 8);
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
sLog.outDebug("Inspect Arena stats " I64FMTD, guid);
|
||||
|
||||
if(Player *plr = objmgr.GetPlayer(guid))
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ARENA_SLOT; i++)
|
||||
{
|
||||
if(uint32 a_id = plr->GetArenaTeamId(i))
|
||||
{
|
||||
if(ArenaTeam *at = objmgr.GetArenaTeamById(a_id))
|
||||
at->InspectStats(this, plr->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" );
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!arenateam) // arena team not found
|
||||
return;
|
||||
|
||||
arenateam->Query(this);
|
||||
arenateam->Stats(this);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" );
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!arenateam)
|
||||
return;
|
||||
|
||||
arenateam->Roster(this);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
std::string Invitedname;
|
||||
|
||||
Player * player = NULL;
|
||||
|
||||
recv_data >> ArenaTeamId >> Invitedname;
|
||||
|
||||
if(!Invitedname.empty())
|
||||
{
|
||||
if(!normalizePlayerName(Invitedname))
|
||||
return;
|
||||
|
||||
player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
|
||||
}
|
||||
|
||||
if(!player)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
//SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
// can't find related opcode
|
||||
SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!arenateam)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM);
|
||||
return;
|
||||
}
|
||||
|
||||
// OK result but not send invite
|
||||
if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
|
||||
return;
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if(player->GetArenaTeamId(arenateam->GetSlot()))
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if(player->GetArenaTeamIdInvited())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if(arenateam->GetMembersSize() >= arenateam->GetType() * 2)
|
||||
{
|
||||
// should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL
|
||||
// SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL);
|
||||
SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str());
|
||||
|
||||
player->SetArenaTeamIdInvited(arenateam->GetId());
|
||||
|
||||
WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10));
|
||||
data << GetPlayer()->GetName();
|
||||
data << arenateam->GetName();
|
||||
player->GetSession()->SendPacket(&data);
|
||||
|
||||
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_ACCEPT"); // empty opcode
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
|
||||
if(!at)
|
||||
{
|
||||
// arena team not exist
|
||||
return;
|
||||
}
|
||||
|
||||
if(_player->GetArenaTeamId(at->GetSlot()))
|
||||
{
|
||||
// already in arena team that size
|
||||
return;
|
||||
}
|
||||
|
||||
// not let enemies sign petition
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
|
||||
return;
|
||||
|
||||
if(!at->AddMember(_player->GetGUID()))
|
||||
return;
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), "");
|
||||
at->BroadcastPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamInviteDeclineOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_DECLINE"); // empty opcode
|
||||
|
||||
_player->SetArenaTeamIdInvited(0); // no more invited
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// send command result
|
||||
return;
|
||||
}
|
||||
if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
|
||||
{
|
||||
// check for correctness
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
|
||||
return;
|
||||
}
|
||||
// arena team has only one member (=captain)
|
||||
if(_player->GetGUID() == at->GetCaptain())
|
||||
{
|
||||
at->Disband(this);
|
||||
delete at;
|
||||
return;
|
||||
}
|
||||
|
||||
at->DelMember(_player->GetGUID());
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), "");
|
||||
at->BroadcastPacket(&data);
|
||||
|
||||
//SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// arena team not found
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
at->Disband(this);
|
||||
delete at;
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1);
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
std::string name;
|
||||
|
||||
recv_data >> ArenaTeamId;
|
||||
recv_data >> name;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// arena team not found
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 guid = objmgr.GetPlayerGUIDByName(name);
|
||||
if(!guid)
|
||||
{
|
||||
// player guid not found
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() == guid)
|
||||
{
|
||||
// unsure
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() == guid)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
|
||||
return;
|
||||
}
|
||||
|
||||
at->DelMember(guid);
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName());
|
||||
at->BroadcastPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1);
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
std::string name;
|
||||
|
||||
recv_data >> ArenaTeamId;
|
||||
recv_data >> name;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// arena team not found
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 guid = objmgr.GetPlayerGUIDByName(name);
|
||||
if(!guid)
|
||||
{
|
||||
// player guid not found
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() == guid)
|
||||
{
|
||||
// target player already captain
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
at->SetCaptain(guid);
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName());
|
||||
at->BroadcastPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendArenaTeamCommandResult(uint32 unk1, std::string str1, std::string str2, uint32 unk3)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+str1.length()+1+str2.length()+1+4);
|
||||
data << unk1;
|
||||
data << str1;
|
||||
data << str2;
|
||||
data << unk3;
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, std::string str1, std::string str2, std::string str3)
|
||||
{
|
||||
data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1);
|
||||
*data << eventid;
|
||||
*data << str_count;
|
||||
switch(str_count)
|
||||
{
|
||||
case 1:
|
||||
*data << str1;
|
||||
break;
|
||||
case 2:
|
||||
*data << str1;
|
||||
*data << str2;
|
||||
break;
|
||||
case 3:
|
||||
*data << str1;
|
||||
*data << str2;
|
||||
*data << str3;
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Unhandled str_count %u in SendArenaTeamEvent()", str_count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
|
||||
uint32 unk = 0;
|
||||
data << uint32(unk); // unk(0)
|
||||
if(!unk)
|
||||
data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
/*
|
||||
+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
|
||||
|
||||
+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
|
||||
+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
|
||||
+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
|
||||
ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
|
||||
|
||||
+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
|
||||
+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
|
||||
+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
|
||||
+ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
|
||||
+ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
|
||||
+ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
|
||||
+ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
|
||||
+ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
|
||||
+ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
|
||||
+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
|
||||
|
||||
+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
|
||||
+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
|
||||
|
||||
+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
|
||||
|
||||
+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
|
||||
+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
|
||||
|
||||
+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
|
||||
|
||||
+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
|
||||
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
|
||||
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
|
||||
|
||||
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "WorldSession.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Log.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "ArenaTeam.h"
|
||||
#include "World.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "Language.h"
|
||||
|
||||
void WorldSession::HandleInspectArenaStatsOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("MSG_INSPECT_ARENA_TEAMS");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 8);
|
||||
|
||||
uint64 guid;
|
||||
recv_data >> guid;
|
||||
sLog.outDebug("Inspect Arena stats " I64FMTD, guid);
|
||||
|
||||
if(Player *plr = objmgr.GetPlayer(guid))
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ARENA_SLOT; i++)
|
||||
{
|
||||
if(uint32 a_id = plr->GetArenaTeamId(i))
|
||||
{
|
||||
if(ArenaTeam *at = objmgr.GetArenaTeamById(a_id))
|
||||
at->InspectStats(this, plr->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamQueryOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_QUERY" );
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!arenateam) // arena team not found
|
||||
return;
|
||||
|
||||
arenateam->Query(this);
|
||||
arenateam->Stats(this);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug( "WORLD: Received CMSG_ARENA_TEAM_ROSTER" );
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!arenateam)
|
||||
return;
|
||||
|
||||
arenateam->Roster(this);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamAddMemberOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_ADD_MEMBER");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
std::string Invitedname;
|
||||
|
||||
Player * player = NULL;
|
||||
|
||||
recv_data >> ArenaTeamId >> Invitedname;
|
||||
|
||||
if(!Invitedname.empty())
|
||||
{
|
||||
if(!normalizePlayerName(Invitedname))
|
||||
return;
|
||||
|
||||
player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str());
|
||||
}
|
||||
|
||||
if(!player)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", Invitedname, ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if(player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
|
||||
{
|
||||
//SendArenaTeamCommandResult(ARENA_TEAM_INVITE_SS,"",Invitedname,ARENA_TEAM_PLAYER_NOT_FOUND_S);
|
||||
// can't find related opcode
|
||||
SendNotification(LANG_HIS_ARENA_LEVEL_REQ_ERROR, player->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaTeam *arenateam = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!arenateam)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM);
|
||||
return;
|
||||
}
|
||||
|
||||
// OK result but not send invite
|
||||
if(player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
|
||||
return;
|
||||
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_NOT_ALLIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if(player->GetArenaTeamId(arenateam->GetSlot()))
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_IN_ARENA_TEAM_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if(player->GetArenaTeamIdInvited())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, player->GetName(), "", ERR_ALREADY_INVITED_TO_ARENA_TEAM_S);
|
||||
return;
|
||||
}
|
||||
|
||||
if(arenateam->GetMembersSize() >= arenateam->GetType() * 2)
|
||||
{
|
||||
// should send an "arena team is full" or the likes message, I just don't know the proper values so... ERR_INTERNAL
|
||||
// SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", "", ERR_ARENA_TEAM_INTERNAL);
|
||||
SendNotification(LANG_YOUR_ARENA_TEAM_FULL, player->GetName());
|
||||
return;
|
||||
}
|
||||
|
||||
sLog.outDebug("Player %s Invited %s to Join his ArenaTeam", GetPlayer()->GetName(), Invitedname.c_str());
|
||||
|
||||
player->SetArenaTeamIdInvited(arenateam->GetId());
|
||||
|
||||
WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10));
|
||||
data << GetPlayer()->GetName();
|
||||
data << arenateam->GetName();
|
||||
player->GetSession()->SendPacket(&data);
|
||||
|
||||
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_INVITE");
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_ACCEPT"); // empty opcode
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(_player->GetArenaTeamIdInvited());
|
||||
if(!at)
|
||||
{
|
||||
// arena team not exist
|
||||
return;
|
||||
}
|
||||
|
||||
if(_player->GetArenaTeamId(at->GetSlot()))
|
||||
{
|
||||
// already in arena team that size
|
||||
return;
|
||||
}
|
||||
|
||||
// not let enemies sign petition
|
||||
if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && _player->GetTeam() != objmgr.GetPlayerTeamByGUID(at->GetCaptain()))
|
||||
return;
|
||||
|
||||
if(!at->AddMember(_player->GetGUID()))
|
||||
return;
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_JOIN_SS, 2, _player->GetName(), at->GetName(), "");
|
||||
at->BroadcastPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamInviteDeclineOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_INVITE_DECLINE"); // empty opcode
|
||||
|
||||
_player->SetArenaTeamIdInvited(0); // no more invited
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamLeaveOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_LEAVE");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// send command result
|
||||
return;
|
||||
}
|
||||
if(_player->GetGUID() == at->GetCaptain() && at->GetMembersSize() > 1)
|
||||
{
|
||||
// check for correctness
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
|
||||
return;
|
||||
}
|
||||
// arena team has only one member (=captain)
|
||||
if(_player->GetGUID() == at->GetCaptain())
|
||||
{
|
||||
at->Disband(this);
|
||||
delete at;
|
||||
return;
|
||||
}
|
||||
|
||||
at->DelMember(_player->GetGUID());
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEAVE_SS, 2, _player->GetName(), at->GetName(), "");
|
||||
at->BroadcastPacket(&data);
|
||||
|
||||
//SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, at->GetName(), "", 0);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamDisbandOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_DISBAND");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4);
|
||||
|
||||
uint32 ArenaTeamId; // arena team id
|
||||
recv_data >> ArenaTeamId;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// arena team not found
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
at->Disband(this);
|
||||
delete at;
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamRemoveFromTeamOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_REMOVE_FROM_TEAM");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1);
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
std::string name;
|
||||
|
||||
recv_data >> ArenaTeamId;
|
||||
recv_data >> name;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// arena team not found
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 guid = objmgr.GetPlayerGUIDByName(name);
|
||||
if(!guid)
|
||||
{
|
||||
// player guid not found
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() == guid)
|
||||
{
|
||||
// unsure
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() == guid)
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_LEADER_LEAVE_S);
|
||||
return;
|
||||
}
|
||||
|
||||
at->DelMember(guid);
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_REMOVE_SSS, 3, name, at->GetName(), _player->GetName());
|
||||
at->BroadcastPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::HandleArenaTeamPromoteToCaptainOpcode(WorldPacket & recv_data)
|
||||
{
|
||||
sLog.outDebug("CMSG_ARENA_TEAM_PROMOTE_TO_CAPTAIN");
|
||||
//recv_data.hexlike();
|
||||
|
||||
CHECK_PACKET_SIZE(recv_data, 4+1);
|
||||
|
||||
uint32 ArenaTeamId;
|
||||
std::string name;
|
||||
|
||||
recv_data >> ArenaTeamId;
|
||||
recv_data >> name;
|
||||
|
||||
ArenaTeam *at = objmgr.GetArenaTeamById(ArenaTeamId);
|
||||
if(!at)
|
||||
{
|
||||
// arena team not found
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 guid = objmgr.GetPlayerGUIDByName(name);
|
||||
if(!guid)
|
||||
{
|
||||
// player guid not found
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() == guid)
|
||||
{
|
||||
// target player already captain
|
||||
return;
|
||||
}
|
||||
|
||||
if(at->GetCaptain() != _player->GetGUID())
|
||||
{
|
||||
SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
at->SetCaptain(guid);
|
||||
|
||||
// event
|
||||
WorldPacket data;
|
||||
BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_LEADER_CHANGED_SSS, 3, _player->GetName(), name, at->GetName());
|
||||
at->BroadcastPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::SendArenaTeamCommandResult(uint32 unk1, std::string str1, std::string str2, uint32 unk3)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+str1.length()+1+str2.length()+1+4);
|
||||
data << unk1;
|
||||
data << str1;
|
||||
data << str2;
|
||||
data << unk3;
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
void WorldSession::BuildArenaTeamEventPacket(WorldPacket *data, uint8 eventid, uint8 str_count, std::string str1, std::string str2, std::string str3)
|
||||
{
|
||||
data->Initialize(SMSG_ARENA_TEAM_EVENT, 1+1+1);
|
||||
*data << eventid;
|
||||
*data << str_count;
|
||||
switch(str_count)
|
||||
{
|
||||
case 1:
|
||||
*data << str1;
|
||||
break;
|
||||
case 2:
|
||||
*data << str1;
|
||||
*data << str2;
|
||||
break;
|
||||
case 3:
|
||||
*data << str1;
|
||||
*data << str2;
|
||||
*data << str3;
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Unhandled str_count %u in SendArenaTeamEvent()", str_count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
|
||||
{
|
||||
WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
|
||||
uint32 unk = 0;
|
||||
data << uint32(unk); // unk(0)
|
||||
if(!unk)
|
||||
data << uint8(type); // team type (2=2v2,3=3v3,5=5v5), can be used for custom types...
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
/*
|
||||
+ERR_ARENA_NO_TEAM_II "You are not in a %dv%d arena team"
|
||||
|
||||
+ERR_ARENA_TEAM_CREATE_S "%s created. To disband, use /teamdisband [2v2, 3v3, 5v5]."
|
||||
+ERR_ARENA_TEAM_INVITE_SS "You have invited %s to join %s"
|
||||
+ERR_ARENA_TEAM_QUIT_S "You are no longer a member of %s"
|
||||
ERR_ARENA_TEAM_FOUNDER_S "Congratulations, you are a founding member of %s! To leave, use /teamquit [2v2, 3v3, 5v5]."
|
||||
|
||||
+ERR_ARENA_TEAM_INTERNAL "Internal arena team error"
|
||||
+ERR_ALREADY_IN_ARENA_TEAM "You are already in an arena team of that size"
|
||||
+ERR_ALREADY_IN_ARENA_TEAM_S "%s is already in an arena team of that size"
|
||||
+ERR_INVITED_TO_ARENA_TEAM "You have already been invited into an arena team"
|
||||
+ERR_ALREADY_INVITED_TO_ARENA_TEAM_S "%s has already been invited to an arena team"
|
||||
+ERR_ARENA_TEAM_NAME_INVALID "That name contains invalid characters, please enter a new name"
|
||||
+ERR_ARENA_TEAM_NAME_EXISTS_S "There is already an arena team named \"%s\""
|
||||
+ERR_ARENA_TEAM_LEADER_LEAVE_S "You must promote a new team captain using /teamcaptain before leaving the team"
|
||||
+ERR_ARENA_TEAM_PERMISSIONS "You don't have permission to do that"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM "You are not in an arena team of that size"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_IN_TEAM_SS "%s is not in %s"
|
||||
+ERR_ARENA_TEAM_PLAYER_NOT_FOUND_S "\"%s\" not found"
|
||||
+ERR_ARENA_TEAM_NOT_ALLIED "You cannot invite players from the opposing alliance"
|
||||
|
||||
+ERR_ARENA_TEAM_JOIN_SS "%s has joined %s"
|
||||
+ERR_ARENA_TEAM_YOU_JOIN_S "You have joined %s. To leave, use /teamquit [2v2, 3v3, 5v5]."
|
||||
|
||||
+ERR_ARENA_TEAM_LEAVE_SS "%s has left %s"
|
||||
|
||||
+ERR_ARENA_TEAM_LEADER_IS_SS "%s is the captain of %s"
|
||||
+ERR_ARENA_TEAM_LEADER_CHANGED_SSS "%s has made %s the new captain of %s"
|
||||
|
||||
+ERR_ARENA_TEAM_REMOVE_SSS "%s has been kicked out of %s by %s"
|
||||
|
||||
+ERR_ARENA_TEAM_DISBANDED_S "%s has disbanded %s"
|
||||
|
||||
ERR_ARENA_TEAM_TARGET_TOO_LOW_S "%s is not high enough level to join your team"
|
||||
|
||||
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S "%s is full"
|
||||
|
||||
ERR_ARENA_TEAM_LEVEL_TOO_LOW_I "You must be level %d to form an arena team"
|
||||
*/
|
||||
|
||||
+952
-952
File diff suppressed because it is too large
Load Diff
+1124
-1124
File diff suppressed because it is too large
Load Diff
+1084
-1084
File diff suppressed because it is too large
Load Diff
+411
-411
@@ -1,411 +1,411 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_CHAT_H
|
||||
#define MANGOSSERVER_CHAT_H
|
||||
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class ChatHandler;
|
||||
class WorldSession;
|
||||
class Creature;
|
||||
class Player;
|
||||
class Unit;
|
||||
struct GameTele;
|
||||
|
||||
class ChatCommand
|
||||
{
|
||||
public:
|
||||
const char * Name;
|
||||
uint32 SecurityLevel; // function pointer required correct align (use uint32)
|
||||
bool (ChatHandler::*Handler)(const char* args);
|
||||
std::string Help;
|
||||
ChatCommand * ChildCommands;
|
||||
};
|
||||
|
||||
class ChatHandler
|
||||
{
|
||||
public:
|
||||
explicit ChatHandler(WorldSession* session) : m_session(session) {}
|
||||
explicit ChatHandler(Player* player) : m_session(player->GetSession()) {}
|
||||
~ChatHandler() {}
|
||||
|
||||
static void FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker);
|
||||
|
||||
void FillMessageData( WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message)
|
||||
{
|
||||
FillMessageData( data, m_session, type, language, NULL, target_guid, message, NULL);
|
||||
}
|
||||
|
||||
void FillSystemMessageData( WorldPacket *data, const char* message )
|
||||
{
|
||||
FillMessageData( data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message );
|
||||
}
|
||||
|
||||
static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
|
||||
|
||||
const char *GetMangosString(int32 entry);
|
||||
|
||||
void SendSysMessage( const char *str);
|
||||
void SendSysMessage( int32 entry);
|
||||
void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3);
|
||||
void PSendSysMessage( int32 entry, ... );
|
||||
|
||||
int ParseCommands(const char* text);
|
||||
|
||||
protected:
|
||||
bool hasStringAbbr(const char* name, const char* part);
|
||||
void SendGlobalSysMessage(const char *str);
|
||||
|
||||
bool ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcommand);
|
||||
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
|
||||
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
|
||||
|
||||
ChatCommand* getCommandTable();
|
||||
|
||||
bool HandleHelpCommand(const char* args);
|
||||
bool HandleCommandsCommand(const char* args);
|
||||
bool HandleAcctCommand(const char* args);
|
||||
bool HandleStartCommand(const char* args);
|
||||
bool HandleInfoCommand(const char* args);
|
||||
bool HandleDismountCommand(const char* args);
|
||||
bool HandleSaveCommand(const char* args);
|
||||
bool HandleGMListCommand(const char* args);
|
||||
|
||||
bool HandleNamegoCommand(const char* args);
|
||||
bool HandleGonameCommand(const char* args);
|
||||
bool HandleGroupgoCommand(const char* args);
|
||||
bool HandleRecallCommand(const char* args);
|
||||
bool HandleAnnounceCommand(const char* args);
|
||||
bool HandleNotifyCommand(const char* args);
|
||||
bool HandleGMmodeCommand(const char* args);
|
||||
bool HandleGMChatCommand(const char* args);
|
||||
bool HandleVisibleCommand(const char* args);
|
||||
bool HandleGPSCommand(const char* args);
|
||||
bool HandleTaxiCheatCommand(const char* args);
|
||||
bool HandleWhispersCommand(const char* args);
|
||||
bool HandleSayCommand(const char* args);
|
||||
bool HandleNpcWhisperCommand(const char* args);
|
||||
bool HandleYellCommand(const char* args);
|
||||
bool HandlePlayEmoteCommand(const char* args);
|
||||
bool HandleSendMailCommand(const char* args);
|
||||
bool HandleNameTeleCommand(const char* args);
|
||||
bool HandleGroupTeleCommand(const char* args);
|
||||
bool HandleDrunkCommand(const char* args);
|
||||
|
||||
bool HandleEventActiveListCommand(const char* args);
|
||||
bool HandleEventStartCommand(const char* args);
|
||||
bool HandleEventStopCommand(const char* args);
|
||||
bool HandleEventInfoCommand(const char* args);
|
||||
|
||||
bool HandleModifyKnownTitlesCommand(const char* args);
|
||||
bool HandleModifyHPCommand(const char* args);
|
||||
bool HandleModifyManaCommand(const char* args);
|
||||
bool HandleModifyRageCommand(const char* args);
|
||||
bool HandleModifyEnergyCommand(const char* args);
|
||||
bool HandleModifyMoneyCommand(const char* args);
|
||||
bool HandleModifyASpeedCommand(const char* args);
|
||||
bool HandleModifySpeedCommand(const char* args);
|
||||
bool HandleModifyBWalkCommand(const char* args);
|
||||
bool HandleModifyFlyCommand(const char* args);
|
||||
bool HandleModifySwimCommand(const char* args);
|
||||
bool HandleModifyScaleCommand(const char* args);
|
||||
bool HandleModifyMountCommand(const char* args);
|
||||
bool HandleModifyBitCommand(const char* args);
|
||||
bool HandleModifyFactionCommand(const char* args);
|
||||
bool HandleModifySpellCommand(const char* args);
|
||||
bool HandleModifyTalentCommand (const char* args);
|
||||
bool HandleModifyHonorCommand (const char* args);
|
||||
bool HandleModifyRepCommand(const char* args);
|
||||
bool HandleModifyArenaCommand(const char* args);
|
||||
|
||||
bool HandleReloadCommand(const char* args);
|
||||
bool HandleReloadAllCommand(const char* args);
|
||||
bool HandleReloadAllAreaCommand(const char* args);
|
||||
bool HandleReloadAllItemCommand(const char* args);
|
||||
bool HandleReloadAllLootCommand(const char* args);
|
||||
bool HandleReloadAllNpcCommand(const char* args);
|
||||
bool HandleReloadAllQuestCommand(const char* args);
|
||||
bool HandleReloadAllScriptsCommand(const char* args);
|
||||
bool HandleReloadAllSpellCommand(const char* args);
|
||||
|
||||
bool HandleReloadConfigCommand(const char* args);
|
||||
|
||||
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
||||
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
|
||||
bool HandleReloadEventScriptsCommand(const char* args);
|
||||
bool HandleReloadCommandCommand(const char* args);
|
||||
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadGameGraveyardZoneCommand(const char* args);
|
||||
bool HandleReloadGameObjectScriptsCommand(const char* args);
|
||||
bool HandleReloadGameTeleCommand(const char* args);
|
||||
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesCreatureCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesDisenchantCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesFishingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesItemCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesQuestMailCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
|
||||
bool HandleReloadMangosStringCommand(const char* args);
|
||||
bool HandleReloadNpcGossipCommand(const char* args);
|
||||
bool HandleReloadNpcTrainerCommand(const char* args);
|
||||
bool HandleReloadNpcVendorCommand(const char* args);
|
||||
bool HandleReloadQuestAreaTriggersCommand(const char* args);
|
||||
bool HandleReloadQuestEndScriptsCommand(const char* args);
|
||||
bool HandleReloadQuestStartScriptsCommand(const char* args);
|
||||
bool HandleReloadQuestTemplateCommand(const char* args);
|
||||
bool HandleReloadReservedNameCommand(const char*);
|
||||
bool HandleReloadSkillDiscoveryTemplateCommand(const char* args);
|
||||
bool HandleReloadSkillExtraItemTemplateCommand(const char* args);
|
||||
bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
|
||||
bool HandleReloadSpellAffectCommand(const char* args);
|
||||
bool HandleReloadSpellChainCommand(const char* args);
|
||||
bool HandleReloadSpellElixirCommand(const char* args);
|
||||
bool HandleReloadSpellLearnSpellCommand(const char* args);
|
||||
bool HandleReloadSpellProcEventCommand(const char* args);
|
||||
bool HandleReloadSpellScriptTargetCommand(const char* args);
|
||||
bool HandleReloadSpellScriptsCommand(const char* args);
|
||||
bool HandleReloadSpellTargetPositionCommand(const char* args);
|
||||
bool HandleReloadSpellThreatsCommand(const char* args);
|
||||
bool HandleReloadSpellPetAurasCommand(const char* args);
|
||||
bool HandleReloadPageTextsCommand(const char* args);
|
||||
bool HandleReloadItemEnchantementsCommand(const char* args);
|
||||
|
||||
bool HandleInstanceListBindsCommand(const char* args);
|
||||
bool HandleInstanceUnbindCommand(const char* args);
|
||||
bool HandleInstanceStatsCommand(const char* args);
|
||||
bool HandleInstanceSaveDataCommand(const char * args);
|
||||
|
||||
bool HandleAddHonorCommand(const char* args);
|
||||
bool HandleHonorAddKillCommand(const char* args);
|
||||
bool HandleUpdateHonorFieldsCommand(const char* args);
|
||||
|
||||
bool HandleLoadScriptsCommand(const char* args);
|
||||
bool HandleSendQuestPartyMsgCommand(const char* args);
|
||||
bool HandleSendQuestInvalidMsgCommand(const char* args);
|
||||
|
||||
bool HandleDebugInArcCommand(const char* args);
|
||||
bool HandleDebugSpellFailCommand(const char* args);
|
||||
|
||||
bool HandleGUIDCommand(const char* args);
|
||||
bool HandleNameCommand(const char* args);
|
||||
bool HandleSubNameCommand(const char* args);
|
||||
bool HandleItemMoveCommand(const char* args);
|
||||
bool HandleDelCreatureCommand(const char* args);
|
||||
bool HandleDeMorphCommand(const char* args);
|
||||
bool HandleAddVendorItemCommand(const char* args);
|
||||
bool HandleDelVendorItemCommand(const char* args);
|
||||
bool HandleAddMoveCommand(const char* args);
|
||||
bool HandleSetMoveTypeCommand(const char* args);
|
||||
bool HandleChangeLevelCommand(const char* args);
|
||||
bool HandleSetPoiCommand(const char* args);
|
||||
bool HandleEquipErrorCommand(const char* args);
|
||||
bool HandleNPCFlagCommand(const char* args);
|
||||
bool HandleSetModelCommand(const char* args);
|
||||
bool HandleFactionIdCommand(const char* args);
|
||||
bool HandleAddSpwCommand(const char* args);
|
||||
bool HandleSpawnDistCommand(const char* args);
|
||||
bool HandleSpawnTimeCommand(const char* args);
|
||||
bool HandleGoCreatureCommand(const char* args);
|
||||
bool HandleGoObjectCommand(const char* args);
|
||||
bool HandleGoTriggerCommand(const char* args);
|
||||
bool HandleGoGraveyardCommand(const char* args);
|
||||
bool HandleTargetObjectCommand(const char* args);
|
||||
bool HandleDelObjectCommand(const char* args);
|
||||
bool HandleMoveCreatureCommand(const char* args);
|
||||
bool HandleMoveObjectCommand(const char* args);
|
||||
bool HandleTurnObjectCommand(const char* args);
|
||||
bool HandlePInfoCommand(const char* args);
|
||||
bool HandlePLimitCommand(const char* args);
|
||||
bool HandleMuteCommand(const char* args);
|
||||
bool HandleUnmuteCommand(const char* args);
|
||||
bool HandleMovegensCommand(const char* args);
|
||||
|
||||
bool HandleBanCommand(const char* args);
|
||||
bool HandleUnBanCommand(const char* args);
|
||||
bool HandleBanInfoCommand(const char* args);
|
||||
bool HandleBanListCommand(const char* args);
|
||||
bool HandleIdleRestartCommand(const char* args);
|
||||
bool HandleIdleShutDownCommand(const char* args);
|
||||
bool HandleShutDownCommand(const char* args);
|
||||
bool HandleRestartCommand(const char* args);
|
||||
bool HandleSecurityCommand(const char* args);
|
||||
bool HandleGoXYCommand(const char* args);
|
||||
bool HandleGoXYZCommand(const char* args);
|
||||
bool HandleGoZoneXYCommand(const char* args);
|
||||
bool HandleGoGridCommand(const char* args);
|
||||
bool HandleAddWeaponCommand(const char* args);
|
||||
bool HandleAllowMovementCommand(const char* args);
|
||||
bool HandleGoCommand(const char* args);
|
||||
|
||||
bool HandleLearnCommand(const char* args);
|
||||
bool HandleLearnAllCommand(const char* args);
|
||||
bool HandleLearnAllGMCommand(const char* args);
|
||||
bool HandleLearnAllCraftsCommand(const char* args);
|
||||
bool HandleLearnAllRecipesCommand(const char* args);
|
||||
bool HandleLearnAllDefaultCommand(const char* args);
|
||||
bool HandleLearnAllLangCommand(const char* args);
|
||||
bool HandleLearnAllMyClassCommand(const char* args);
|
||||
bool HandleLearnAllMySpellsCommand(const char* args);
|
||||
bool HandleLearnAllMyTalentsCommand(const char* args);
|
||||
|
||||
bool HandleLookupAreaCommand(const char* args);
|
||||
bool HandleLookupCreatureCommand(const char* args);
|
||||
bool HandleLookupEventCommand(const char* args);
|
||||
bool HandleLookupFactionCommand(const char * args);
|
||||
bool HandleLookupItemCommand(const char * args);
|
||||
bool HandleLookupItemSetCommand(const char * args);
|
||||
bool HandleLookupObjectCommand(const char* args);
|
||||
bool HandleLookupPlayerIpCommand(const char* args);
|
||||
bool HandleLookupPlayerAccountCommand(const char* args);
|
||||
bool HandleLookupPlayerEmailCommand(const char* args);
|
||||
bool HandleLookupQuestCommand(const char* args);
|
||||
bool HandleLookupSkillCommand(const char* args);
|
||||
bool HandleLookupSpellCommand(const char* args);
|
||||
bool HandleLookupTeleCommand(const char * args);
|
||||
|
||||
bool HandleCooldownCommand(const char* args);
|
||||
bool HandleUnLearnCommand(const char* args);
|
||||
bool HandleGetDistanceCommand(const char* args);
|
||||
bool HandleGameObjectCommand(const char* args);
|
||||
bool HandleAnimCommand(const char* args);
|
||||
bool HandlePlaySoundCommand(const char* args);
|
||||
bool HandleStandStateCommand(const char* args);
|
||||
bool HandleDieCommand(const char* args);
|
||||
bool HandleDamageCommand(const char *args);
|
||||
bool HandleReviveCommand(const char* args);
|
||||
bool HandleMorphCommand(const char* args);
|
||||
bool HandleAuraCommand(const char* args);
|
||||
bool HandleUnAuraCommand(const char* args);
|
||||
bool HandleLinkGraveCommand(const char* args);
|
||||
bool HandleNearGraveCommand(const char* args);
|
||||
bool HandleSpawnTransportCommand(const char* args);
|
||||
bool HandleExploreCheatCommand(const char* args);
|
||||
bool HandleTextEmoteCommand(const char* args);
|
||||
bool HandleNpcInfoCommand(const char* args);
|
||||
bool HandleHoverCommand(const char* args);
|
||||
bool HandleLevelUpCommand(const char* args);
|
||||
bool HandleShowAreaCommand(const char* args);
|
||||
bool HandleHideAreaCommand(const char* args);
|
||||
bool HandleAddItemCommand(const char* args);
|
||||
bool HandleAddItemSetCommand(const char* args);
|
||||
|
||||
bool HandleGuildCreateCommand(const char* args);
|
||||
bool HandleGuildInviteCommand(const char* args);
|
||||
bool HandleGuildUninviteCommand(const char* args);
|
||||
bool HandleGuildRankCommand(const char* args);
|
||||
bool HandleGuildDeleteCommand(const char* args);
|
||||
bool HandleUpdate(const char* args);
|
||||
bool HandleBankCommand(const char* args);
|
||||
bool HandleChangeWeather(const char* args);
|
||||
bool HandleKickPlayerCommand(const char * args);
|
||||
bool HandleTeleCommand(const char * args);
|
||||
bool HandleAddTeleCommand(const char * args);
|
||||
bool HandleDelTeleCommand(const char * args);
|
||||
bool HandleListAurasCommand(const char * args);
|
||||
|
||||
bool HandleResetHonorCommand(const char * args);
|
||||
bool HandleResetLevelCommand(const char * args);
|
||||
bool HandleResetSpellsCommand(const char * args);
|
||||
|
||||
bool HandleResetStatsCommand(const char * args);
|
||||
bool HandleResetTalentsCommand(const char * args);
|
||||
|
||||
bool HandleResetAllCommand(const char * args);
|
||||
bool HandleTicketCommand(const char* args);
|
||||
bool HandleDelTicketCommand(const char* args);
|
||||
bool HandleMaxSkillCommand(const char* args);
|
||||
bool HandleSetSkillCommand(const char* args);
|
||||
bool HandleListCreatureCommand(const char* args);
|
||||
bool HandleListItemCommand(const char* args);
|
||||
bool HandleListObjectCommand(const char* args);
|
||||
bool HandleNearObjectCommand(const char* args);
|
||||
bool HandlePasswordCommand(const char* args);
|
||||
bool HandleLockAccountCommand(const char* args);
|
||||
bool HandleRespawnCommand(const char* args);
|
||||
bool HandleWpAddCommand(const char* args);
|
||||
bool HandleWpModifyCommand(const char* args);
|
||||
bool HandleWpShowCommand(const char* args);
|
||||
bool HandleWpExportCommand(const char* args);
|
||||
bool HandleWpImportCommand(const char* args);
|
||||
bool HandleFlyModeCommand(const char* args);
|
||||
bool HandleSendOpcodeCommand(const char* args);
|
||||
bool HandleSellErrorCommand(const char* args);
|
||||
bool HandleBuyErrorCommand(const char* args);
|
||||
bool HandleUpdateWorldStateCommand(const char* args);
|
||||
bool HandlePlaySound2Command(const char* args);
|
||||
bool HandleSendChannelNotifyCommand(const char* args);
|
||||
bool HandleSendChatMsgCommand(const char* args);
|
||||
bool HandleRenameCommand(const char * args);
|
||||
bool HandleLoadPDumpCommand(const char *args);
|
||||
bool HandleWritePDumpCommand(const char *args);
|
||||
bool HandleChangeEntryCommand(const char *args);
|
||||
bool HandleCastCommand(const char *args);
|
||||
bool HandleCastBackCommand(const char *args);
|
||||
bool HandleCastDistCommand(const char *args);
|
||||
bool HandleCastSelfCommand(const char *args);
|
||||
bool HandleCastTargetCommand(const char *args);
|
||||
bool HandleComeToMeCommand(const char *args);
|
||||
bool HandleCombatStopCommand(const char *args);
|
||||
bool HandleFlushArenaPointsCommand(const char *args);
|
||||
|
||||
//! Development Commands
|
||||
bool HandleSetValue(const char* args);
|
||||
bool HandleGetValue(const char* args);
|
||||
bool HandleSet32Bit(const char* args);
|
||||
bool HandleMod32Value(const char* args);
|
||||
bool HandleAddQuest(const char * args);
|
||||
bool HandleRemoveQuest(const char * args);
|
||||
bool HandleCompleteQuest(const char * args);
|
||||
bool HandleSaveAllCommand(const char* args);
|
||||
bool HandleGetItemState(const char * args);
|
||||
bool HandleGetLootRecipient(const char * args);
|
||||
bool HandleDebugArenaCommand(const char * args);
|
||||
|
||||
Player* getSelectedPlayer();
|
||||
Creature* getSelectedCreature();
|
||||
Unit* getSelectedUnit();
|
||||
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
|
||||
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
|
||||
uint32 extractSpellIdFromLink(char* text);
|
||||
GameTele const* extractGameTeleFromLink(char* text);
|
||||
|
||||
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
|
||||
|
||||
WorldSession * m_session;
|
||||
|
||||
// Utility methods for commands
|
||||
void ShowTicket(uint64 guid, char const* text, char const* time);
|
||||
uint32 GetTicketIDByNum(uint32 num);
|
||||
bool LookupPlayerSearchCommand(QueryResult* result, int32 limit);
|
||||
|
||||
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
|
||||
private:
|
||||
// common global flag
|
||||
static bool load_command_table;
|
||||
bool sentErrorMessage;
|
||||
};
|
||||
#endif
|
||||
|
||||
char const *fmtstring( char const *format, ... );
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_CHAT_H
|
||||
#define MANGOSSERVER_CHAT_H
|
||||
|
||||
#include "SharedDefines.h"
|
||||
|
||||
class ChatHandler;
|
||||
class WorldSession;
|
||||
class Creature;
|
||||
class Player;
|
||||
class Unit;
|
||||
struct GameTele;
|
||||
|
||||
class ChatCommand
|
||||
{
|
||||
public:
|
||||
const char * Name;
|
||||
uint32 SecurityLevel; // function pointer required correct align (use uint32)
|
||||
bool (ChatHandler::*Handler)(const char* args);
|
||||
std::string Help;
|
||||
ChatCommand * ChildCommands;
|
||||
};
|
||||
|
||||
class ChatHandler
|
||||
{
|
||||
public:
|
||||
explicit ChatHandler(WorldSession* session) : m_session(session) {}
|
||||
explicit ChatHandler(Player* player) : m_session(player->GetSession()) {}
|
||||
~ChatHandler() {}
|
||||
|
||||
static void FillMessageData( WorldPacket *data, WorldSession* session, uint8 type, uint32 language, const char *channelName, uint64 target_guid, const char *message, Unit *speaker);
|
||||
|
||||
void FillMessageData( WorldPacket *data, uint8 type, uint32 language, uint64 target_guid, const char* message)
|
||||
{
|
||||
FillMessageData( data, m_session, type, language, NULL, target_guid, message, NULL);
|
||||
}
|
||||
|
||||
void FillSystemMessageData( WorldPacket *data, const char* message )
|
||||
{
|
||||
FillMessageData( data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, 0, message );
|
||||
}
|
||||
|
||||
static char* LineFromMessage(char*& pos) { char* start = strtok(pos,"\n"); pos = NULL; return start; }
|
||||
|
||||
const char *GetMangosString(int32 entry);
|
||||
|
||||
void SendSysMessage( const char *str);
|
||||
void SendSysMessage( int32 entry);
|
||||
void PSendSysMessage( const char *format, ...) ATTR_PRINTF(2,3);
|
||||
void PSendSysMessage( int32 entry, ... );
|
||||
|
||||
int ParseCommands(const char* text);
|
||||
|
||||
protected:
|
||||
bool hasStringAbbr(const char* name, const char* part);
|
||||
void SendGlobalSysMessage(const char *str);
|
||||
|
||||
bool ExecuteCommandInTable(ChatCommand *table, const char* text, std::string fullcommand);
|
||||
bool ShowHelpForCommand(ChatCommand *table, const char* cmd);
|
||||
bool ShowHelpForSubCommands(ChatCommand *table, char const* cmd, char const* subcmd);
|
||||
|
||||
ChatCommand* getCommandTable();
|
||||
|
||||
bool HandleHelpCommand(const char* args);
|
||||
bool HandleCommandsCommand(const char* args);
|
||||
bool HandleAcctCommand(const char* args);
|
||||
bool HandleStartCommand(const char* args);
|
||||
bool HandleInfoCommand(const char* args);
|
||||
bool HandleDismountCommand(const char* args);
|
||||
bool HandleSaveCommand(const char* args);
|
||||
bool HandleGMListCommand(const char* args);
|
||||
|
||||
bool HandleNamegoCommand(const char* args);
|
||||
bool HandleGonameCommand(const char* args);
|
||||
bool HandleGroupgoCommand(const char* args);
|
||||
bool HandleRecallCommand(const char* args);
|
||||
bool HandleAnnounceCommand(const char* args);
|
||||
bool HandleNotifyCommand(const char* args);
|
||||
bool HandleGMmodeCommand(const char* args);
|
||||
bool HandleGMChatCommand(const char* args);
|
||||
bool HandleVisibleCommand(const char* args);
|
||||
bool HandleGPSCommand(const char* args);
|
||||
bool HandleTaxiCheatCommand(const char* args);
|
||||
bool HandleWhispersCommand(const char* args);
|
||||
bool HandleSayCommand(const char* args);
|
||||
bool HandleNpcWhisperCommand(const char* args);
|
||||
bool HandleYellCommand(const char* args);
|
||||
bool HandlePlayEmoteCommand(const char* args);
|
||||
bool HandleSendMailCommand(const char* args);
|
||||
bool HandleNameTeleCommand(const char* args);
|
||||
bool HandleGroupTeleCommand(const char* args);
|
||||
bool HandleDrunkCommand(const char* args);
|
||||
|
||||
bool HandleEventActiveListCommand(const char* args);
|
||||
bool HandleEventStartCommand(const char* args);
|
||||
bool HandleEventStopCommand(const char* args);
|
||||
bool HandleEventInfoCommand(const char* args);
|
||||
|
||||
bool HandleModifyKnownTitlesCommand(const char* args);
|
||||
bool HandleModifyHPCommand(const char* args);
|
||||
bool HandleModifyManaCommand(const char* args);
|
||||
bool HandleModifyRageCommand(const char* args);
|
||||
bool HandleModifyEnergyCommand(const char* args);
|
||||
bool HandleModifyMoneyCommand(const char* args);
|
||||
bool HandleModifyASpeedCommand(const char* args);
|
||||
bool HandleModifySpeedCommand(const char* args);
|
||||
bool HandleModifyBWalkCommand(const char* args);
|
||||
bool HandleModifyFlyCommand(const char* args);
|
||||
bool HandleModifySwimCommand(const char* args);
|
||||
bool HandleModifyScaleCommand(const char* args);
|
||||
bool HandleModifyMountCommand(const char* args);
|
||||
bool HandleModifyBitCommand(const char* args);
|
||||
bool HandleModifyFactionCommand(const char* args);
|
||||
bool HandleModifySpellCommand(const char* args);
|
||||
bool HandleModifyTalentCommand (const char* args);
|
||||
bool HandleModifyHonorCommand (const char* args);
|
||||
bool HandleModifyRepCommand(const char* args);
|
||||
bool HandleModifyArenaCommand(const char* args);
|
||||
|
||||
bool HandleReloadCommand(const char* args);
|
||||
bool HandleReloadAllCommand(const char* args);
|
||||
bool HandleReloadAllAreaCommand(const char* args);
|
||||
bool HandleReloadAllItemCommand(const char* args);
|
||||
bool HandleReloadAllLootCommand(const char* args);
|
||||
bool HandleReloadAllNpcCommand(const char* args);
|
||||
bool HandleReloadAllQuestCommand(const char* args);
|
||||
bool HandleReloadAllScriptsCommand(const char* args);
|
||||
bool HandleReloadAllSpellCommand(const char* args);
|
||||
|
||||
bool HandleReloadConfigCommand(const char* args);
|
||||
|
||||
bool HandleReloadAreaTriggerTavernCommand(const char* args);
|
||||
bool HandleReloadAreaTriggerTeleportCommand(const char* args);
|
||||
bool HandleReloadEventScriptsCommand(const char* args);
|
||||
bool HandleReloadCommandCommand(const char* args);
|
||||
bool HandleReloadCreatureQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadCreatureQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadGameGraveyardZoneCommand(const char* args);
|
||||
bool HandleReloadGameObjectScriptsCommand(const char* args);
|
||||
bool HandleReloadGameTeleCommand(const char* args);
|
||||
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesCreatureCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesDisenchantCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesFishingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesGameobjectCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesItemCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesProspectingCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesReferenceCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesQuestMailCommand(const char* args);
|
||||
bool HandleReloadLootTemplatesSkinningCommand(const char* args);
|
||||
bool HandleReloadMangosStringCommand(const char* args);
|
||||
bool HandleReloadNpcGossipCommand(const char* args);
|
||||
bool HandleReloadNpcTrainerCommand(const char* args);
|
||||
bool HandleReloadNpcVendorCommand(const char* args);
|
||||
bool HandleReloadQuestAreaTriggersCommand(const char* args);
|
||||
bool HandleReloadQuestEndScriptsCommand(const char* args);
|
||||
bool HandleReloadQuestStartScriptsCommand(const char* args);
|
||||
bool HandleReloadQuestTemplateCommand(const char* args);
|
||||
bool HandleReloadReservedNameCommand(const char*);
|
||||
bool HandleReloadSkillDiscoveryTemplateCommand(const char* args);
|
||||
bool HandleReloadSkillExtraItemTemplateCommand(const char* args);
|
||||
bool HandleReloadSkillFishingBaseLevelCommand(const char* args);
|
||||
bool HandleReloadSpellAffectCommand(const char* args);
|
||||
bool HandleReloadSpellChainCommand(const char* args);
|
||||
bool HandleReloadSpellElixirCommand(const char* args);
|
||||
bool HandleReloadSpellLearnSpellCommand(const char* args);
|
||||
bool HandleReloadSpellProcEventCommand(const char* args);
|
||||
bool HandleReloadSpellScriptTargetCommand(const char* args);
|
||||
bool HandleReloadSpellScriptsCommand(const char* args);
|
||||
bool HandleReloadSpellTargetPositionCommand(const char* args);
|
||||
bool HandleReloadSpellThreatsCommand(const char* args);
|
||||
bool HandleReloadSpellPetAurasCommand(const char* args);
|
||||
bool HandleReloadPageTextsCommand(const char* args);
|
||||
bool HandleReloadItemEnchantementsCommand(const char* args);
|
||||
|
||||
bool HandleInstanceListBindsCommand(const char* args);
|
||||
bool HandleInstanceUnbindCommand(const char* args);
|
||||
bool HandleInstanceStatsCommand(const char* args);
|
||||
bool HandleInstanceSaveDataCommand(const char * args);
|
||||
|
||||
bool HandleAddHonorCommand(const char* args);
|
||||
bool HandleHonorAddKillCommand(const char* args);
|
||||
bool HandleUpdateHonorFieldsCommand(const char* args);
|
||||
|
||||
bool HandleLoadScriptsCommand(const char* args);
|
||||
bool HandleSendQuestPartyMsgCommand(const char* args);
|
||||
bool HandleSendQuestInvalidMsgCommand(const char* args);
|
||||
|
||||
bool HandleDebugInArcCommand(const char* args);
|
||||
bool HandleDebugSpellFailCommand(const char* args);
|
||||
|
||||
bool HandleGUIDCommand(const char* args);
|
||||
bool HandleNameCommand(const char* args);
|
||||
bool HandleSubNameCommand(const char* args);
|
||||
bool HandleItemMoveCommand(const char* args);
|
||||
bool HandleDelCreatureCommand(const char* args);
|
||||
bool HandleDeMorphCommand(const char* args);
|
||||
bool HandleAddVendorItemCommand(const char* args);
|
||||
bool HandleDelVendorItemCommand(const char* args);
|
||||
bool HandleAddMoveCommand(const char* args);
|
||||
bool HandleSetMoveTypeCommand(const char* args);
|
||||
bool HandleChangeLevelCommand(const char* args);
|
||||
bool HandleSetPoiCommand(const char* args);
|
||||
bool HandleEquipErrorCommand(const char* args);
|
||||
bool HandleNPCFlagCommand(const char* args);
|
||||
bool HandleSetModelCommand(const char* args);
|
||||
bool HandleFactionIdCommand(const char* args);
|
||||
bool HandleAddSpwCommand(const char* args);
|
||||
bool HandleSpawnDistCommand(const char* args);
|
||||
bool HandleSpawnTimeCommand(const char* args);
|
||||
bool HandleGoCreatureCommand(const char* args);
|
||||
bool HandleGoObjectCommand(const char* args);
|
||||
bool HandleGoTriggerCommand(const char* args);
|
||||
bool HandleGoGraveyardCommand(const char* args);
|
||||
bool HandleTargetObjectCommand(const char* args);
|
||||
bool HandleDelObjectCommand(const char* args);
|
||||
bool HandleMoveCreatureCommand(const char* args);
|
||||
bool HandleMoveObjectCommand(const char* args);
|
||||
bool HandleTurnObjectCommand(const char* args);
|
||||
bool HandlePInfoCommand(const char* args);
|
||||
bool HandlePLimitCommand(const char* args);
|
||||
bool HandleMuteCommand(const char* args);
|
||||
bool HandleUnmuteCommand(const char* args);
|
||||
bool HandleMovegensCommand(const char* args);
|
||||
|
||||
bool HandleBanCommand(const char* args);
|
||||
bool HandleUnBanCommand(const char* args);
|
||||
bool HandleBanInfoCommand(const char* args);
|
||||
bool HandleBanListCommand(const char* args);
|
||||
bool HandleIdleRestartCommand(const char* args);
|
||||
bool HandleIdleShutDownCommand(const char* args);
|
||||
bool HandleShutDownCommand(const char* args);
|
||||
bool HandleRestartCommand(const char* args);
|
||||
bool HandleSecurityCommand(const char* args);
|
||||
bool HandleGoXYCommand(const char* args);
|
||||
bool HandleGoXYZCommand(const char* args);
|
||||
bool HandleGoZoneXYCommand(const char* args);
|
||||
bool HandleGoGridCommand(const char* args);
|
||||
bool HandleAddWeaponCommand(const char* args);
|
||||
bool HandleAllowMovementCommand(const char* args);
|
||||
bool HandleGoCommand(const char* args);
|
||||
|
||||
bool HandleLearnCommand(const char* args);
|
||||
bool HandleLearnAllCommand(const char* args);
|
||||
bool HandleLearnAllGMCommand(const char* args);
|
||||
bool HandleLearnAllCraftsCommand(const char* args);
|
||||
bool HandleLearnAllRecipesCommand(const char* args);
|
||||
bool HandleLearnAllDefaultCommand(const char* args);
|
||||
bool HandleLearnAllLangCommand(const char* args);
|
||||
bool HandleLearnAllMyClassCommand(const char* args);
|
||||
bool HandleLearnAllMySpellsCommand(const char* args);
|
||||
bool HandleLearnAllMyTalentsCommand(const char* args);
|
||||
|
||||
bool HandleLookupAreaCommand(const char* args);
|
||||
bool HandleLookupCreatureCommand(const char* args);
|
||||
bool HandleLookupEventCommand(const char* args);
|
||||
bool HandleLookupFactionCommand(const char * args);
|
||||
bool HandleLookupItemCommand(const char * args);
|
||||
bool HandleLookupItemSetCommand(const char * args);
|
||||
bool HandleLookupObjectCommand(const char* args);
|
||||
bool HandleLookupPlayerIpCommand(const char* args);
|
||||
bool HandleLookupPlayerAccountCommand(const char* args);
|
||||
bool HandleLookupPlayerEmailCommand(const char* args);
|
||||
bool HandleLookupQuestCommand(const char* args);
|
||||
bool HandleLookupSkillCommand(const char* args);
|
||||
bool HandleLookupSpellCommand(const char* args);
|
||||
bool HandleLookupTeleCommand(const char * args);
|
||||
|
||||
bool HandleCooldownCommand(const char* args);
|
||||
bool HandleUnLearnCommand(const char* args);
|
||||
bool HandleGetDistanceCommand(const char* args);
|
||||
bool HandleGameObjectCommand(const char* args);
|
||||
bool HandleAnimCommand(const char* args);
|
||||
bool HandlePlaySoundCommand(const char* args);
|
||||
bool HandleStandStateCommand(const char* args);
|
||||
bool HandleDieCommand(const char* args);
|
||||
bool HandleDamageCommand(const char *args);
|
||||
bool HandleReviveCommand(const char* args);
|
||||
bool HandleMorphCommand(const char* args);
|
||||
bool HandleAuraCommand(const char* args);
|
||||
bool HandleUnAuraCommand(const char* args);
|
||||
bool HandleLinkGraveCommand(const char* args);
|
||||
bool HandleNearGraveCommand(const char* args);
|
||||
bool HandleSpawnTransportCommand(const char* args);
|
||||
bool HandleExploreCheatCommand(const char* args);
|
||||
bool HandleTextEmoteCommand(const char* args);
|
||||
bool HandleNpcInfoCommand(const char* args);
|
||||
bool HandleHoverCommand(const char* args);
|
||||
bool HandleLevelUpCommand(const char* args);
|
||||
bool HandleShowAreaCommand(const char* args);
|
||||
bool HandleHideAreaCommand(const char* args);
|
||||
bool HandleAddItemCommand(const char* args);
|
||||
bool HandleAddItemSetCommand(const char* args);
|
||||
|
||||
bool HandleGuildCreateCommand(const char* args);
|
||||
bool HandleGuildInviteCommand(const char* args);
|
||||
bool HandleGuildUninviteCommand(const char* args);
|
||||
bool HandleGuildRankCommand(const char* args);
|
||||
bool HandleGuildDeleteCommand(const char* args);
|
||||
bool HandleUpdate(const char* args);
|
||||
bool HandleBankCommand(const char* args);
|
||||
bool HandleChangeWeather(const char* args);
|
||||
bool HandleKickPlayerCommand(const char * args);
|
||||
bool HandleTeleCommand(const char * args);
|
||||
bool HandleAddTeleCommand(const char * args);
|
||||
bool HandleDelTeleCommand(const char * args);
|
||||
bool HandleListAurasCommand(const char * args);
|
||||
|
||||
bool HandleResetHonorCommand(const char * args);
|
||||
bool HandleResetLevelCommand(const char * args);
|
||||
bool HandleResetSpellsCommand(const char * args);
|
||||
|
||||
bool HandleResetStatsCommand(const char * args);
|
||||
bool HandleResetTalentsCommand(const char * args);
|
||||
|
||||
bool HandleResetAllCommand(const char * args);
|
||||
bool HandleTicketCommand(const char* args);
|
||||
bool HandleDelTicketCommand(const char* args);
|
||||
bool HandleMaxSkillCommand(const char* args);
|
||||
bool HandleSetSkillCommand(const char* args);
|
||||
bool HandleListCreatureCommand(const char* args);
|
||||
bool HandleListItemCommand(const char* args);
|
||||
bool HandleListObjectCommand(const char* args);
|
||||
bool HandleNearObjectCommand(const char* args);
|
||||
bool HandlePasswordCommand(const char* args);
|
||||
bool HandleLockAccountCommand(const char* args);
|
||||
bool HandleRespawnCommand(const char* args);
|
||||
bool HandleWpAddCommand(const char* args);
|
||||
bool HandleWpModifyCommand(const char* args);
|
||||
bool HandleWpShowCommand(const char* args);
|
||||
bool HandleWpExportCommand(const char* args);
|
||||
bool HandleWpImportCommand(const char* args);
|
||||
bool HandleFlyModeCommand(const char* args);
|
||||
bool HandleSendOpcodeCommand(const char* args);
|
||||
bool HandleSellErrorCommand(const char* args);
|
||||
bool HandleBuyErrorCommand(const char* args);
|
||||
bool HandleUpdateWorldStateCommand(const char* args);
|
||||
bool HandlePlaySound2Command(const char* args);
|
||||
bool HandleSendChannelNotifyCommand(const char* args);
|
||||
bool HandleSendChatMsgCommand(const char* args);
|
||||
bool HandleRenameCommand(const char * args);
|
||||
bool HandleLoadPDumpCommand(const char *args);
|
||||
bool HandleWritePDumpCommand(const char *args);
|
||||
bool HandleChangeEntryCommand(const char *args);
|
||||
bool HandleCastCommand(const char *args);
|
||||
bool HandleCastBackCommand(const char *args);
|
||||
bool HandleCastDistCommand(const char *args);
|
||||
bool HandleCastSelfCommand(const char *args);
|
||||
bool HandleCastTargetCommand(const char *args);
|
||||
bool HandleComeToMeCommand(const char *args);
|
||||
bool HandleCombatStopCommand(const char *args);
|
||||
bool HandleFlushArenaPointsCommand(const char *args);
|
||||
|
||||
//! Development Commands
|
||||
bool HandleSetValue(const char* args);
|
||||
bool HandleGetValue(const char* args);
|
||||
bool HandleSet32Bit(const char* args);
|
||||
bool HandleMod32Value(const char* args);
|
||||
bool HandleAddQuest(const char * args);
|
||||
bool HandleRemoveQuest(const char * args);
|
||||
bool HandleCompleteQuest(const char * args);
|
||||
bool HandleSaveAllCommand(const char* args);
|
||||
bool HandleGetItemState(const char * args);
|
||||
bool HandleGetLootRecipient(const char * args);
|
||||
bool HandleDebugArenaCommand(const char * args);
|
||||
|
||||
Player* getSelectedPlayer();
|
||||
Creature* getSelectedCreature();
|
||||
Unit* getSelectedUnit();
|
||||
char* extractKeyFromLink(char* text, char const* linkType, char** something1 = NULL);
|
||||
char* extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = NULL);
|
||||
uint32 extractSpellIdFromLink(char* text);
|
||||
GameTele const* extractGameTeleFromLink(char* text);
|
||||
|
||||
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid,uint32 entry);
|
||||
|
||||
WorldSession * m_session;
|
||||
|
||||
// Utility methods for commands
|
||||
void ShowTicket(uint64 guid, char const* text, char const* time);
|
||||
uint32 GetTicketIDByNum(uint32 num);
|
||||
bool LookupPlayerSearchCommand(QueryResult* result, int32 limit);
|
||||
|
||||
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
|
||||
private:
|
||||
// common global flag
|
||||
static bool load_command_table;
|
||||
bool sentErrorMessage;
|
||||
};
|
||||
#endif
|
||||
|
||||
char const *fmtstring( char const *format, ... );
|
||||
|
||||
+583
-583
File diff suppressed because it is too large
Load Diff
@@ -1,155 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
const float wander_distance=11;
|
||||
float x,y,z;
|
||||
x = unit.GetPositionX();
|
||||
y = unit.GetPositionY();
|
||||
z = unit.GetPositionZ();
|
||||
uint32 mapid=unit.GetMapId();
|
||||
|
||||
Map const* map = MapManager::Instance().GetBaseMap(mapid);
|
||||
|
||||
i_nextMove = 1;
|
||||
|
||||
bool is_water_ok, is_land_ok;
|
||||
_InitSpecific(unit, is_water_ok, is_land_ok);
|
||||
|
||||
for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx)
|
||||
{
|
||||
const float wanderX=wander_distance*rand_norm() - wander_distance/2;
|
||||
const float wanderY=wander_distance*rand_norm() - wander_distance/2;
|
||||
|
||||
i_waypoints[idx][0] = x + wanderX;
|
||||
i_waypoints[idx][1] = y + wanderY;
|
||||
|
||||
// prevent invalid coordinates generation
|
||||
MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
|
||||
MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);
|
||||
|
||||
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
||||
// if generated wrong path just ignore
|
||||
if( is_water && !is_water_ok || !is_water && !is_land_ok )
|
||||
{
|
||||
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
|
||||
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
|
||||
}
|
||||
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
||||
i_waypoints[idx][2] = z;
|
||||
}
|
||||
|
||||
unit.StopMoving();
|
||||
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
unit.addUnitState(UNIT_STAT_CONFUSED);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
|
||||
{
|
||||
is_water_ok = creature.canSwim();
|
||||
is_land_ok = creature.canWalk();
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
|
||||
{
|
||||
is_water_ok = true;
|
||||
is_land_ok = true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Reset(T &unit)
|
||||
{
|
||||
i_nextMove = 1;
|
||||
i_nextMoveTime.Reset(0);
|
||||
i_destinationHolder.ResetUpdate();
|
||||
unit.StopMoving();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if(!&unit)
|
||||
return true;
|
||||
|
||||
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
|
||||
return true;
|
||||
|
||||
if( i_nextMoveTime.Passed() )
|
||||
{
|
||||
// currently moving, update location
|
||||
Traveller<T> traveller(unit);
|
||||
if( i_destinationHolder.UpdateTraveller(traveller, diff, false))
|
||||
{
|
||||
if( i_destinationHolder.HasArrived())
|
||||
{
|
||||
// arrived, stop and wait a bit
|
||||
unit.StopMoving();
|
||||
|
||||
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
|
||||
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// waiting for next move
|
||||
i_nextMoveTime.Update(diff);
|
||||
if( i_nextMoveTime.Passed() )
|
||||
{
|
||||
// start moving
|
||||
assert( i_nextMove <= MAX_CONF_WAYPOINTS );
|
||||
const float x = i_waypoints[i_nextMove][0];
|
||||
const float y = i_waypoints[i_nextMove][1];
|
||||
const float z = i_waypoints[i_nextMove][2];
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Finalize(T &unit)
|
||||
{
|
||||
unit.clearUnitState(UNIT_STAT_CONFUSED);
|
||||
}
|
||||
|
||||
template void ConfusedMovementGenerator<Player>::Initialize(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature);
|
||||
template void ConfusedMovementGenerator<Player>::Finalize(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Finalize(Creature &creature);
|
||||
template void ConfusedMovementGenerator<Player>::Reset(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Reset(Creature &creature);
|
||||
template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
|
||||
template bool ConfusedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
const float wander_distance=11;
|
||||
float x,y,z;
|
||||
x = unit.GetPositionX();
|
||||
y = unit.GetPositionY();
|
||||
z = unit.GetPositionZ();
|
||||
uint32 mapid=unit.GetMapId();
|
||||
|
||||
Map const* map = MapManager::Instance().GetBaseMap(mapid);
|
||||
|
||||
i_nextMove = 1;
|
||||
|
||||
bool is_water_ok, is_land_ok;
|
||||
_InitSpecific(unit, is_water_ok, is_land_ok);
|
||||
|
||||
for(unsigned int idx=0; idx < MAX_CONF_WAYPOINTS+1; ++idx)
|
||||
{
|
||||
const float wanderX=wander_distance*rand_norm() - wander_distance/2;
|
||||
const float wanderY=wander_distance*rand_norm() - wander_distance/2;
|
||||
|
||||
i_waypoints[idx][0] = x + wanderX;
|
||||
i_waypoints[idx][1] = y + wanderY;
|
||||
|
||||
// prevent invalid coordinates generation
|
||||
MaNGOS::NormalizeMapCoord(i_waypoints[idx][0]);
|
||||
MaNGOS::NormalizeMapCoord(i_waypoints[idx][1]);
|
||||
|
||||
bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
||||
// if generated wrong path just ignore
|
||||
if( is_water && !is_water_ok || !is_water && !is_land_ok )
|
||||
{
|
||||
i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x;
|
||||
i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
|
||||
}
|
||||
unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z);
|
||||
i_waypoints[idx][2] = z;
|
||||
}
|
||||
|
||||
unit.StopMoving();
|
||||
unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
unit.addUnitState(UNIT_STAT_CONFUSED);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
ConfusedMovementGenerator<Creature>::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok)
|
||||
{
|
||||
is_water_ok = creature.canSwim();
|
||||
is_land_ok = creature.canWalk();
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
ConfusedMovementGenerator<Player>::_InitSpecific(Player &, bool &is_water_ok, bool &is_land_ok)
|
||||
{
|
||||
is_water_ok = true;
|
||||
is_land_ok = true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Reset(T &unit)
|
||||
{
|
||||
i_nextMove = 1;
|
||||
i_nextMoveTime.Reset(0);
|
||||
i_destinationHolder.ResetUpdate();
|
||||
unit.StopMoving();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
ConfusedMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if(!&unit)
|
||||
return true;
|
||||
|
||||
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
|
||||
return true;
|
||||
|
||||
if( i_nextMoveTime.Passed() )
|
||||
{
|
||||
// currently moving, update location
|
||||
Traveller<T> traveller(unit);
|
||||
if( i_destinationHolder.UpdateTraveller(traveller, diff, false))
|
||||
{
|
||||
if( i_destinationHolder.HasArrived())
|
||||
{
|
||||
// arrived, stop and wait a bit
|
||||
unit.StopMoving();
|
||||
|
||||
i_nextMove = urand(1,MAX_CONF_WAYPOINTS);
|
||||
i_nextMoveTime.Reset(urand(0, 1500-1)); // TODO: check the minimum reset time, should be probably higher
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// waiting for next move
|
||||
i_nextMoveTime.Update(diff);
|
||||
if( i_nextMoveTime.Passed() )
|
||||
{
|
||||
// start moving
|
||||
assert( i_nextMove <= MAX_CONF_WAYPOINTS );
|
||||
const float x = i_waypoints[i_nextMove][0];
|
||||
const float y = i_waypoints[i_nextMove][1];
|
||||
const float z = i_waypoints[i_nextMove][2];
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
ConfusedMovementGenerator<T>::Finalize(T &unit)
|
||||
{
|
||||
unit.clearUnitState(UNIT_STAT_CONFUSED);
|
||||
}
|
||||
|
||||
template void ConfusedMovementGenerator<Player>::Initialize(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Initialize(Creature &creature);
|
||||
template void ConfusedMovementGenerator<Player>::Finalize(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Finalize(Creature &creature);
|
||||
template void ConfusedMovementGenerator<Player>::Reset(Player &player);
|
||||
template void ConfusedMovementGenerator<Creature>::Reset(Creature &creature);
|
||||
template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
|
||||
template bool ConfusedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
|
||||
|
||||
+2066
-2066
File diff suppressed because it is too large
Load Diff
+617
-617
File diff suppressed because it is too large
Load Diff
+118
-118
@@ -1,118 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "NullCreatureAI.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "ScriptCalls.h"
|
||||
#include "Pet.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(CreatureAIRegistry);
|
||||
INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry);
|
||||
|
||||
namespace FactorySelector
|
||||
{
|
||||
CreatureAI* selectAI(Creature *creature)
|
||||
{
|
||||
// Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
|
||||
if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
|
||||
if(CreatureAI* scriptedAI = Script->GetAI(creature))
|
||||
return scriptedAI;
|
||||
|
||||
CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());
|
||||
assert( creature->GetCreatureInfo() != NULL );
|
||||
CreatureInfo const *cinfo=creature->GetCreatureInfo();
|
||||
|
||||
const CreatureAICreator *ai_factory = NULL;
|
||||
|
||||
std::string ainame=cinfo->AIName;
|
||||
|
||||
// select by script name
|
||||
if( !ainame.empty())
|
||||
ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );
|
||||
|
||||
// select by NPC flags
|
||||
if(!ai_factory)
|
||||
{
|
||||
if( creature->isGuard() )
|
||||
ai_factory = ai_registry.GetRegistryItem("GuardAI");
|
||||
else if(creature->isPet() || creature->isCharmed())
|
||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||
else if(creature->isTotem())
|
||||
ai_factory = ai_registry.GetRegistryItem("TotemAI");
|
||||
}
|
||||
|
||||
// select by permit check
|
||||
if(!ai_factory)
|
||||
{
|
||||
int best_val = -1;
|
||||
typedef CreatureAIRegistry::RegistryMapType RMT;
|
||||
RMT const &l = ai_registry.GetRegisteredItems();
|
||||
for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const CreatureAICreator *factory = iter->second;
|
||||
const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
|
||||
assert( p != NULL );
|
||||
int val = p->Permit(creature);
|
||||
if( val > best_val )
|
||||
{
|
||||
best_val = val;
|
||||
ai_factory = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// select NullCreatureAI if not another cases
|
||||
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
||||
|
||||
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
|
||||
return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) );
|
||||
}
|
||||
|
||||
MovementGenerator* selectMovementGenerator(Creature *creature)
|
||||
{
|
||||
MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance());
|
||||
assert( creature->GetCreatureInfo() != NULL );
|
||||
const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType());
|
||||
|
||||
/* if( mv_factory == NULL )
|
||||
{
|
||||
int best_val = -1;
|
||||
std::vector<std::string> l;
|
||||
mv_registry.GetRegisteredItems(l);
|
||||
for( std::vector<std::string>::iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str());
|
||||
const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory);
|
||||
assert( p != NULL );
|
||||
int val = p->Permit(creature);
|
||||
if( val > best_val )
|
||||
{
|
||||
best_val = val;
|
||||
mv_factory = p;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return ( mv_factory == NULL ? NULL : mv_factory->Create(creature) );
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "NullCreatureAI.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "ScriptCalls.h"
|
||||
#include "Pet.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(CreatureAIRegistry);
|
||||
INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry);
|
||||
|
||||
namespace FactorySelector
|
||||
{
|
||||
CreatureAI* selectAI(Creature *creature)
|
||||
{
|
||||
// Allow scripting AI for normal creatures and not controlled pets (guardians and mini-pets)
|
||||
if((!creature->isPet() || !((Pet*)creature)->isControlled()) && !creature->isCharmed())
|
||||
if(CreatureAI* scriptedAI = Script->GetAI(creature))
|
||||
return scriptedAI;
|
||||
|
||||
CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance());
|
||||
assert( creature->GetCreatureInfo() != NULL );
|
||||
CreatureInfo const *cinfo=creature->GetCreatureInfo();
|
||||
|
||||
const CreatureAICreator *ai_factory = NULL;
|
||||
|
||||
std::string ainame=cinfo->AIName;
|
||||
|
||||
// select by script name
|
||||
if( !ainame.empty())
|
||||
ai_factory = ai_registry.GetRegistryItem( ainame.c_str() );
|
||||
|
||||
// select by NPC flags
|
||||
if(!ai_factory)
|
||||
{
|
||||
if( creature->isGuard() )
|
||||
ai_factory = ai_registry.GetRegistryItem("GuardAI");
|
||||
else if(creature->isPet() || creature->isCharmed())
|
||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||
else if(creature->isTotem())
|
||||
ai_factory = ai_registry.GetRegistryItem("TotemAI");
|
||||
}
|
||||
|
||||
// select by permit check
|
||||
if(!ai_factory)
|
||||
{
|
||||
int best_val = -1;
|
||||
typedef CreatureAIRegistry::RegistryMapType RMT;
|
||||
RMT const &l = ai_registry.GetRegisteredItems();
|
||||
for( RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const CreatureAICreator *factory = iter->second;
|
||||
const SelectableAI *p = dynamic_cast<const SelectableAI *>(factory);
|
||||
assert( p != NULL );
|
||||
int val = p->Permit(creature);
|
||||
if( val > best_val )
|
||||
{
|
||||
best_val = val;
|
||||
ai_factory = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// select NullCreatureAI if not another cases
|
||||
ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key();
|
||||
|
||||
DEBUG_LOG("Creature %u used AI is %s.", creature->GetGUIDLow(), ainame.c_str() );
|
||||
return ( ai_factory == NULL ? new NullCreatureAI : ai_factory->Create(creature) );
|
||||
}
|
||||
|
||||
MovementGenerator* selectMovementGenerator(Creature *creature)
|
||||
{
|
||||
MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance());
|
||||
assert( creature->GetCreatureInfo() != NULL );
|
||||
const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem( creature->GetDefaultMovementType());
|
||||
|
||||
/* if( mv_factory == NULL )
|
||||
{
|
||||
int best_val = -1;
|
||||
std::vector<std::string> l;
|
||||
mv_registry.GetRegisteredItems(l);
|
||||
for( std::vector<std::string>::iterator iter = l.begin(); iter != l.end(); ++iter)
|
||||
{
|
||||
const MovementGeneratorCreator *factory = mv_registry.GetRegistryItem((*iter).c_str());
|
||||
const SelectableMovement *p = dynamic_cast<const SelectableMovement *>(factory);
|
||||
assert( p != NULL );
|
||||
int val = p->Permit(creature);
|
||||
if( val > best_val )
|
||||
{
|
||||
best_val = val;
|
||||
mv_factory = p;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return ( mv_factory == NULL ? NULL : mv_factory->Create(creature) );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,379 +1,379 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "ObjectAccessor.h"
|
||||
|
||||
#define MIN_QUIET_DISTANCE 28.0f
|
||||
#define MAX_QUIET_DISTANCE 43.0f
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
{
|
||||
if( !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
|
||||
return;
|
||||
|
||||
if(!_setMoveData(owner))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if(!_getPoint(owner, x, y, z))
|
||||
return;
|
||||
|
||||
owner.addUnitState(UNIT_STAT_FLEEING);
|
||||
Traveller<T> traveller(owner);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
|
||||
{
|
||||
if(!&owner)
|
||||
return false;
|
||||
|
||||
x = owner.GetPositionX();
|
||||
y = owner.GetPositionY();
|
||||
z = owner.GetPositionZ();
|
||||
|
||||
float temp_x, temp_y, angle;
|
||||
const Map * _map = MapManager::Instance().GetBaseMap(owner.GetMapId());
|
||||
//primitive path-finding
|
||||
for(uint8 i = 0; i < 18; i++)
|
||||
{
|
||||
if(i_only_forward && i > 2)
|
||||
break;
|
||||
|
||||
float distance = 5.0f;
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
angle = i_cur_angle;
|
||||
break;
|
||||
case 1:
|
||||
angle = i_cur_angle;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 2:
|
||||
angle = i_cur_angle;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 3:
|
||||
angle = i_cur_angle + M_PI/4.0f;
|
||||
break;
|
||||
case 4:
|
||||
angle = i_cur_angle - M_PI/4.0f;
|
||||
break;
|
||||
case 5:
|
||||
angle = i_cur_angle + M_PI/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 6:
|
||||
angle = i_cur_angle - M_PI/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 7:
|
||||
angle = i_cur_angle + M_PI/2.0f;
|
||||
break;
|
||||
case 8:
|
||||
angle = i_cur_angle - M_PI/2.0f;
|
||||
break;
|
||||
case 9:
|
||||
angle = i_cur_angle + M_PI/2.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 10:
|
||||
angle = i_cur_angle - M_PI/2.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 11:
|
||||
angle = i_cur_angle + M_PI/4.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 12:
|
||||
angle = i_cur_angle - M_PI/4.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 13:
|
||||
angle = i_cur_angle + M_PI/2.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 14:
|
||||
angle = i_cur_angle - M_PI/2.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 15:
|
||||
angle = i_cur_angle + M_PI*3/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 16:
|
||||
angle = i_cur_angle - M_PI*3/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 17:
|
||||
angle = i_cur_angle + M_PI;
|
||||
distance /= 2;
|
||||
break;
|
||||
}
|
||||
temp_x = x + distance * cos(angle);
|
||||
temp_y = y + distance * sin(angle);
|
||||
MaNGOS::NormalizeMapCoord(temp_x);
|
||||
MaNGOS::NormalizeMapCoord(temp_y);
|
||||
if( owner.IsWithinLOS(temp_x,temp_y,z))
|
||||
{
|
||||
bool is_water_now = _map->IsInWater(x,y,z);
|
||||
|
||||
if(is_water_now && _map->IsInWater(temp_x,temp_y,z))
|
||||
{
|
||||
x = temp_x;
|
||||
y = temp_y;
|
||||
return true;
|
||||
}
|
||||
float new_z = _map->GetHeight(temp_x,temp_y,z,true);
|
||||
|
||||
if(new_z <= INVALID_HEIGHT)
|
||||
continue;
|
||||
|
||||
bool is_water_next = _map->IsInWater(temp_x,temp_y,new_z);
|
||||
|
||||
if((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
|
||||
continue;
|
||||
|
||||
if( !(new_z - z) || distance / fabs(new_z - z) > 1.0f)
|
||||
{
|
||||
float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+M_PI/2),temp_y + 1.0f*sin(angle+M_PI/2),z,true);
|
||||
float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-M_PI/2),temp_y + 1.0f*sin(angle-M_PI/2),z,true);
|
||||
if(fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
|
||||
{
|
||||
x = temp_x;
|
||||
y = temp_y;
|
||||
z = new_z;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i_to_distance_from_caster = 0.0f;
|
||||
i_nextCheckTime.Reset( urand(500,1000) );
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
FleeingMovementGenerator<T>::_setMoveData(T &owner)
|
||||
{
|
||||
float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z);
|
||||
|
||||
if(i_to_distance_from_caster > 0.0f)
|
||||
{
|
||||
if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) ||
|
||||
// if we reach lower distance
|
||||
(i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) ||
|
||||
// if we can't be close
|
||||
(i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) ||
|
||||
// if we reach bigger distance
|
||||
(cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far
|
||||
(i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) )
|
||||
// if we leave 'quiet zone'
|
||||
{
|
||||
// we are very far or too close, stopping
|
||||
i_to_distance_from_caster = 0.0f;
|
||||
i_nextCheckTime.Reset( urand(500,1000) );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// now we are running, continue
|
||||
i_last_distance_from_caster = cur_dist_xyz;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
float cur_dist;
|
||||
float angle_to_caster;
|
||||
|
||||
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
|
||||
|
||||
if(fright)
|
||||
{
|
||||
cur_dist = fright->GetDistance(&owner);
|
||||
if(cur_dist < cur_dist_xyz)
|
||||
{
|
||||
i_caster_x = fright->GetPositionX();
|
||||
i_caster_y = fright->GetPositionY();
|
||||
i_caster_z = fright->GetPositionZ();
|
||||
angle_to_caster = fright->GetAngle(&owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_dist = cur_dist_xyz;
|
||||
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_dist = cur_dist_xyz;
|
||||
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
|
||||
}
|
||||
|
||||
// if we too close may use 'path-finding' else just stop
|
||||
i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3;
|
||||
|
||||
//get angle and 'distance from caster' to run
|
||||
float angle;
|
||||
|
||||
if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time
|
||||
{
|
||||
angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3;
|
||||
i_to_distance_from_caster = MIN_QUIET_DISTANCE;
|
||||
i_only_forward = true;
|
||||
}
|
||||
else if(cur_dist < MIN_QUIET_DISTANCE)
|
||||
{
|
||||
angle = M_PI/6 + rand_norm()*M_PI*2/3;
|
||||
i_to_distance_from_caster = cur_dist*2/3 + rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3);
|
||||
}
|
||||
else if(cur_dist > MAX_QUIET_DISTANCE)
|
||||
{
|
||||
angle = rand_norm()*M_PI/3 + M_PI*2/3;
|
||||
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = rand_norm()*M_PI;
|
||||
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
|
||||
}
|
||||
|
||||
int8 sign = rand_norm() > 0.5f ? 1 : -1;
|
||||
i_cur_angle = sign*angle + angle_to_caster;
|
||||
|
||||
// current distance
|
||||
i_last_distance_from_caster = cur_dist;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::Initialize(T &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
|
||||
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
|
||||
if(!fright)
|
||||
return;
|
||||
|
||||
_Init(owner);
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
i_caster_x = fright->GetPositionX();
|
||||
i_caster_y = fright->GetPositionY();
|
||||
i_caster_z = fright->GetPositionZ();
|
||||
i_only_forward = true;
|
||||
i_cur_angle = 0.0f;
|
||||
i_last_distance_from_caster = 0.0f;
|
||||
i_to_distance_from_caster = 0.0f;
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
FleeingMovementGenerator<Creature>::_Init(Creature &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
is_water_ok = owner.canSwim();
|
||||
is_land_ok = owner.canWalk();
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
FleeingMovementGenerator<Player>::_Init(Player &)
|
||||
{
|
||||
is_water_ok = true;
|
||||
is_land_ok = true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::Finalize(T &owner)
|
||||
{
|
||||
owner.clearUnitState(UNIT_STAT_FLEEING);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::Reset(T &owner)
|
||||
{
|
||||
Initialize(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
{
|
||||
if( !&owner || !owner.isAlive() )
|
||||
return false;
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
i_nextCheckTime.Update(time_diff);
|
||||
|
||||
if( (owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination() )
|
||||
{
|
||||
_setTargetLocation(owner);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
|
||||
{
|
||||
i_destinationHolder.ResetUpdate(50);
|
||||
if(i_nextCheckTime.Passed() && i_destinationHolder.HasArrived())
|
||||
{
|
||||
_setTargetLocation(owner);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template void FleeingMovementGenerator<Player>::Initialize(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::Initialize(Creature &);
|
||||
template bool FleeingMovementGenerator<Player>::_setMoveData(Player &);
|
||||
template bool FleeingMovementGenerator<Creature>::_setMoveData(Creature &);
|
||||
template bool FleeingMovementGenerator<Player>::_getPoint(Player &, float &, float &, float &);
|
||||
template bool FleeingMovementGenerator<Creature>::_getPoint(Creature &, float &, float &, float &);
|
||||
template void FleeingMovementGenerator<Player>::_setTargetLocation(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::_setTargetLocation(Creature &);
|
||||
template void FleeingMovementGenerator<Player>::Finalize(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::Finalize(Creature &);
|
||||
template void FleeingMovementGenerator<Player>::Reset(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::Reset(Creature &);
|
||||
template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
|
||||
template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "ObjectAccessor.h"
|
||||
|
||||
#define MIN_QUIET_DISTANCE 28.0f
|
||||
#define MAX_QUIET_DISTANCE 43.0f
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
{
|
||||
if( !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
|
||||
return;
|
||||
|
||||
if(!_setMoveData(owner))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if(!_getPoint(owner, x, y, z))
|
||||
return;
|
||||
|
||||
owner.addUnitState(UNIT_STAT_FLEEING);
|
||||
Traveller<T> traveller(owner);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
|
||||
{
|
||||
if(!&owner)
|
||||
return false;
|
||||
|
||||
x = owner.GetPositionX();
|
||||
y = owner.GetPositionY();
|
||||
z = owner.GetPositionZ();
|
||||
|
||||
float temp_x, temp_y, angle;
|
||||
const Map * _map = MapManager::Instance().GetBaseMap(owner.GetMapId());
|
||||
//primitive path-finding
|
||||
for(uint8 i = 0; i < 18; i++)
|
||||
{
|
||||
if(i_only_forward && i > 2)
|
||||
break;
|
||||
|
||||
float distance = 5.0f;
|
||||
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
angle = i_cur_angle;
|
||||
break;
|
||||
case 1:
|
||||
angle = i_cur_angle;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 2:
|
||||
angle = i_cur_angle;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 3:
|
||||
angle = i_cur_angle + M_PI/4.0f;
|
||||
break;
|
||||
case 4:
|
||||
angle = i_cur_angle - M_PI/4.0f;
|
||||
break;
|
||||
case 5:
|
||||
angle = i_cur_angle + M_PI/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 6:
|
||||
angle = i_cur_angle - M_PI/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 7:
|
||||
angle = i_cur_angle + M_PI/2.0f;
|
||||
break;
|
||||
case 8:
|
||||
angle = i_cur_angle - M_PI/2.0f;
|
||||
break;
|
||||
case 9:
|
||||
angle = i_cur_angle + M_PI/2.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 10:
|
||||
angle = i_cur_angle - M_PI/2.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 11:
|
||||
angle = i_cur_angle + M_PI/4.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 12:
|
||||
angle = i_cur_angle - M_PI/4.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 13:
|
||||
angle = i_cur_angle + M_PI/2.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 14:
|
||||
angle = i_cur_angle - M_PI/2.0f;
|
||||
distance /= 4;
|
||||
break;
|
||||
case 15:
|
||||
angle = i_cur_angle + M_PI*3/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 16:
|
||||
angle = i_cur_angle - M_PI*3/4.0f;
|
||||
distance /= 2;
|
||||
break;
|
||||
case 17:
|
||||
angle = i_cur_angle + M_PI;
|
||||
distance /= 2;
|
||||
break;
|
||||
}
|
||||
temp_x = x + distance * cos(angle);
|
||||
temp_y = y + distance * sin(angle);
|
||||
MaNGOS::NormalizeMapCoord(temp_x);
|
||||
MaNGOS::NormalizeMapCoord(temp_y);
|
||||
if( owner.IsWithinLOS(temp_x,temp_y,z))
|
||||
{
|
||||
bool is_water_now = _map->IsInWater(x,y,z);
|
||||
|
||||
if(is_water_now && _map->IsInWater(temp_x,temp_y,z))
|
||||
{
|
||||
x = temp_x;
|
||||
y = temp_y;
|
||||
return true;
|
||||
}
|
||||
float new_z = _map->GetHeight(temp_x,temp_y,z,true);
|
||||
|
||||
if(new_z <= INVALID_HEIGHT)
|
||||
continue;
|
||||
|
||||
bool is_water_next = _map->IsInWater(temp_x,temp_y,new_z);
|
||||
|
||||
if((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
|
||||
continue;
|
||||
|
||||
if( !(new_z - z) || distance / fabs(new_z - z) > 1.0f)
|
||||
{
|
||||
float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+M_PI/2),temp_y + 1.0f*sin(angle+M_PI/2),z,true);
|
||||
float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-M_PI/2),temp_y + 1.0f*sin(angle-M_PI/2),z,true);
|
||||
if(fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
|
||||
{
|
||||
x = temp_x;
|
||||
y = temp_y;
|
||||
z = new_z;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i_to_distance_from_caster = 0.0f;
|
||||
i_nextCheckTime.Reset( urand(500,1000) );
|
||||
return false;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
FleeingMovementGenerator<T>::_setMoveData(T &owner)
|
||||
{
|
||||
float cur_dist_xyz = owner.GetDistance(i_caster_x, i_caster_y, i_caster_z);
|
||||
|
||||
if(i_to_distance_from_caster > 0.0f)
|
||||
{
|
||||
if((i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz < i_to_distance_from_caster) ||
|
||||
// if we reach lower distance
|
||||
(i_last_distance_from_caster > i_to_distance_from_caster && cur_dist_xyz > i_last_distance_from_caster) ||
|
||||
// if we can't be close
|
||||
(i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) ||
|
||||
// if we reach bigger distance
|
||||
(cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far
|
||||
(i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) )
|
||||
// if we leave 'quiet zone'
|
||||
{
|
||||
// we are very far or too close, stopping
|
||||
i_to_distance_from_caster = 0.0f;
|
||||
i_nextCheckTime.Reset( urand(500,1000) );
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// now we are running, continue
|
||||
i_last_distance_from_caster = cur_dist_xyz;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
float cur_dist;
|
||||
float angle_to_caster;
|
||||
|
||||
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
|
||||
|
||||
if(fright)
|
||||
{
|
||||
cur_dist = fright->GetDistance(&owner);
|
||||
if(cur_dist < cur_dist_xyz)
|
||||
{
|
||||
i_caster_x = fright->GetPositionX();
|
||||
i_caster_y = fright->GetPositionY();
|
||||
i_caster_z = fright->GetPositionZ();
|
||||
angle_to_caster = fright->GetAngle(&owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_dist = cur_dist_xyz;
|
||||
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_dist = cur_dist_xyz;
|
||||
angle_to_caster = owner.GetAngle(i_caster_x, i_caster_y) + M_PI;
|
||||
}
|
||||
|
||||
// if we too close may use 'path-finding' else just stop
|
||||
i_only_forward = cur_dist >= MIN_QUIET_DISTANCE/3;
|
||||
|
||||
//get angle and 'distance from caster' to run
|
||||
float angle;
|
||||
|
||||
if(i_cur_angle == 0.0f && i_last_distance_from_caster == 0.0f) //just started, first time
|
||||
{
|
||||
angle = rand_norm()*(1.0f - cur_dist/MIN_QUIET_DISTANCE) * M_PI/3 + rand_norm()*M_PI*2/3;
|
||||
i_to_distance_from_caster = MIN_QUIET_DISTANCE;
|
||||
i_only_forward = true;
|
||||
}
|
||||
else if(cur_dist < MIN_QUIET_DISTANCE)
|
||||
{
|
||||
angle = M_PI/6 + rand_norm()*M_PI*2/3;
|
||||
i_to_distance_from_caster = cur_dist*2/3 + rand_norm()*(MIN_QUIET_DISTANCE - cur_dist*2/3);
|
||||
}
|
||||
else if(cur_dist > MAX_QUIET_DISTANCE)
|
||||
{
|
||||
angle = rand_norm()*M_PI/3 + M_PI*2/3;
|
||||
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = rand_norm()*M_PI;
|
||||
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
|
||||
}
|
||||
|
||||
int8 sign = rand_norm() > 0.5f ? 1 : -1;
|
||||
i_cur_angle = sign*angle + angle_to_caster;
|
||||
|
||||
// current distance
|
||||
i_last_distance_from_caster = cur_dist;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::Initialize(T &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
|
||||
Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
|
||||
if(!fright)
|
||||
return;
|
||||
|
||||
_Init(owner);
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
i_caster_x = fright->GetPositionX();
|
||||
i_caster_y = fright->GetPositionY();
|
||||
i_caster_z = fright->GetPositionZ();
|
||||
i_only_forward = true;
|
||||
i_cur_angle = 0.0f;
|
||||
i_last_distance_from_caster = 0.0f;
|
||||
i_to_distance_from_caster = 0.0f;
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
FleeingMovementGenerator<Creature>::_Init(Creature &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
owner.SetUInt64Value(UNIT_FIELD_TARGET, 0);
|
||||
is_water_ok = owner.canSwim();
|
||||
is_land_ok = owner.canWalk();
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
FleeingMovementGenerator<Player>::_Init(Player &)
|
||||
{
|
||||
is_water_ok = true;
|
||||
is_land_ok = true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::Finalize(T &owner)
|
||||
{
|
||||
owner.clearUnitState(UNIT_STAT_FLEEING);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
FleeingMovementGenerator<T>::Reset(T &owner)
|
||||
{
|
||||
Initialize(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
FleeingMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
{
|
||||
if( !&owner || !owner.isAlive() )
|
||||
return false;
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
i_nextCheckTime.Update(time_diff);
|
||||
|
||||
if( (owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination() )
|
||||
{
|
||||
_setTargetLocation(owner);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
|
||||
{
|
||||
i_destinationHolder.ResetUpdate(50);
|
||||
if(i_nextCheckTime.Passed() && i_destinationHolder.HasArrived())
|
||||
{
|
||||
_setTargetLocation(owner);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template void FleeingMovementGenerator<Player>::Initialize(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::Initialize(Creature &);
|
||||
template bool FleeingMovementGenerator<Player>::_setMoveData(Player &);
|
||||
template bool FleeingMovementGenerator<Creature>::_setMoveData(Creature &);
|
||||
template bool FleeingMovementGenerator<Player>::_getPoint(Player &, float &, float &, float &);
|
||||
template bool FleeingMovementGenerator<Creature>::_getPoint(Creature &, float &, float &, float &);
|
||||
template void FleeingMovementGenerator<Player>::_setTargetLocation(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::_setTargetLocation(Creature &);
|
||||
template void FleeingMovementGenerator<Player>::Finalize(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::Finalize(Creature &);
|
||||
template void FleeingMovementGenerator<Player>::Reset(Player &);
|
||||
template void FleeingMovementGenerator<Creature>::Reset(Creature &);
|
||||
template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
|
||||
template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
|
||||
|
||||
+1247
-1247
File diff suppressed because it is too large
Load Diff
+592
-592
File diff suppressed because it is too large
Load Diff
+762
-762
File diff suppressed because it is too large
Load Diff
+206
-206
@@ -1,206 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_GOSSIP_H
|
||||
#define MANGOSSERVER_GOSSIP_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "QuestDef.h"
|
||||
#include "NPCHandler.h"
|
||||
|
||||
class WorldSession;
|
||||
|
||||
#define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough
|
||||
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
|
||||
|
||||
//POI defines
|
||||
enum Poi_Icon
|
||||
{
|
||||
ICON_POI_0 = 0, // Grey ?
|
||||
ICON_POI_1 = 1, // Red ?
|
||||
ICON_POI_2 = 2, // Blue ?
|
||||
ICON_POI_BWTOMB = 3, // Blue and White Tomb Stone
|
||||
ICON_POI_HOUSE = 4, // House
|
||||
ICON_POI_TOWER = 5, // Tower
|
||||
ICON_POI_REDFLAG = 6, // Red Flag with Yellow !
|
||||
ICON_POI_TOMB = 7, // Tomb Stone
|
||||
ICON_POI_BWTOWER = 8, // Blue and White Tower
|
||||
ICON_POI_REDTOWER = 9, // Red Tower
|
||||
ICON_POI_BLUETOWER = 10, // Blue Tower
|
||||
ICON_POI_RWTOWER = 11, // Red and White Tower
|
||||
ICON_POI_REDTOMB = 12, // Red Tomb Stone
|
||||
ICON_POI_RWTOMB = 13, // Red and White Tomb Stone
|
||||
ICON_POI_BLUETOMB = 14, // Blue Tomb Stone
|
||||
ICON_POI_NOTHING = 15, // NOTHING
|
||||
ICON_POI_16 = 16, // Red ?
|
||||
ICON_POI_17 = 17, // Grey ?
|
||||
ICON_POI_18 = 18, // Blue ?
|
||||
ICON_POI_19 = 19, // Red and White ?
|
||||
ICON_POI_20 = 20, // Red ?
|
||||
ICON_POI_GREYLOGS = 21, // Grey Wood Logs
|
||||
ICON_POI_BWLOGS = 22, // Blue and White Wood Logs
|
||||
ICON_POI_BLUELOGS = 23, // Blue Wood Logs
|
||||
ICON_POI_RWLOGS = 24, // Red and White Wood Logs
|
||||
ICON_POI_REDLOGS = 25, // Red Wood Logs
|
||||
ICON_POI_26 = 26, // Grey ?
|
||||
ICON_POI_27 = 27, // Blue and White ?
|
||||
ICON_POI_28 = 28, // Blue ?
|
||||
ICON_POI_29 = 29, // Red and White ?
|
||||
ICON_POI_30 = 30, // Red ?
|
||||
ICON_POI_GREYHOUSE = 31, // Grey House
|
||||
ICON_POI_BWHOUSE = 32, // Blue and White House
|
||||
ICON_POI_BLUEHOUSE = 33, // Blue House
|
||||
ICON_POI_RWHOUSE = 34, // Red and White House
|
||||
ICON_POI_REDHOUSE = 35, // Red House
|
||||
ICON_POI_GREYHORSE = 36, // Grey Horse
|
||||
ICON_POI_BWHORSE = 37, // Blue and White Horse
|
||||
ICON_POI_BLUEHORSE = 38, // Blue Horse
|
||||
ICON_POI_RWHORSE = 39, // Red and White Horse
|
||||
ICON_POI_REDHORSE = 40 // Red Horse
|
||||
};
|
||||
|
||||
struct GossipMenuItem
|
||||
{
|
||||
uint8 m_gIcon;
|
||||
bool m_gCoded;
|
||||
std::string m_gMessage;
|
||||
uint32 m_gSender;
|
||||
uint32 m_gAction;
|
||||
std::string m_gBoxMessage;
|
||||
uint32 m_gBoxMoney;
|
||||
};
|
||||
|
||||
typedef std::vector<GossipMenuItem> GossipMenuItemList;
|
||||
|
||||
struct QuestMenuItem
|
||||
{
|
||||
uint32 m_qId;
|
||||
uint8 m_qIcon;
|
||||
};
|
||||
|
||||
typedef std::vector<QuestMenuItem> QuestMenuItemList;
|
||||
|
||||
class MANGOS_DLL_SPEC GossipMenu
|
||||
{
|
||||
public:
|
||||
GossipMenu();
|
||||
~GossipMenu();
|
||||
|
||||
void AddMenuItem(uint8 Icon, std::string Message, bool Coded = false);
|
||||
void AddMenuItem(uint8 Icon, std::string Message, uint32 dtSender, uint32 dtAction, std::string BoxMessage, uint32 BoxMoney, bool Coded = false);
|
||||
|
||||
// for using from scripts, don't must be inlined
|
||||
void AddMenuItem(uint8 Icon, char const* Message, bool Coded = false);
|
||||
void AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded = false);
|
||||
|
||||
unsigned int MenuItemCount() const
|
||||
{
|
||||
return m_gItems.size();
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return m_gItems.empty();
|
||||
}
|
||||
|
||||
GossipMenuItem const& GetItem( unsigned int Id )
|
||||
{
|
||||
return m_gItems[ Id ];
|
||||
}
|
||||
|
||||
uint32 MenuItemSender( unsigned int ItemId );
|
||||
uint32 MenuItemAction( unsigned int ItemId );
|
||||
bool MenuItemCoded( unsigned int ItemId );
|
||||
|
||||
void ClearMenu();
|
||||
|
||||
protected:
|
||||
GossipMenuItemList m_gItems;
|
||||
};
|
||||
|
||||
class QuestMenu
|
||||
{
|
||||
public:
|
||||
QuestMenu();
|
||||
~QuestMenu();
|
||||
|
||||
void AddMenuItem( uint32 QuestId, uint8 Icon);
|
||||
void ClearMenu();
|
||||
|
||||
uint8 MenuItemCount() const
|
||||
{
|
||||
return m_qItems.size();
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return m_qItems.empty();
|
||||
}
|
||||
|
||||
bool HasItem( uint32 questid );
|
||||
|
||||
QuestMenuItem const& GetItem( uint16 Id )
|
||||
{
|
||||
return m_qItems[ Id ];
|
||||
}
|
||||
|
||||
protected:
|
||||
QuestMenuItemList m_qItems;
|
||||
};
|
||||
|
||||
class MANGOS_DLL_SPEC PlayerMenu
|
||||
{
|
||||
private:
|
||||
GossipMenu mGossipMenu;
|
||||
QuestMenu mQuestMenu;
|
||||
WorldSession* pSession;
|
||||
|
||||
public:
|
||||
PlayerMenu( WorldSession *Session );
|
||||
~PlayerMenu();
|
||||
|
||||
GossipMenu& GetGossipMenu() { return mGossipMenu; }
|
||||
QuestMenu& GetQuestMenu() { return mQuestMenu; }
|
||||
|
||||
bool Empty() const { return mGossipMenu.Empty() && mQuestMenu.Empty(); }
|
||||
|
||||
void ClearMenus();
|
||||
uint32 GossipOptionSender( unsigned int Selection );
|
||||
uint32 GossipOptionAction( unsigned int Selection );
|
||||
bool GossipOptionCoded( unsigned int Selection );
|
||||
|
||||
void SendGossipMenu( uint32 TitleTextId, uint64 npcGUID );
|
||||
void CloseGossip();
|
||||
void SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, const char * locName );
|
||||
void SendTalking( uint32 textID );
|
||||
void SendTalking( char const * title, char const * text );
|
||||
|
||||
/*********************************************************/
|
||||
/*** QUEST SYSTEM ***/
|
||||
/*********************************************************/
|
||||
void SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID );
|
||||
|
||||
void SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint64 npcGUID );
|
||||
|
||||
void SendQuestQueryResponse ( Quest const *pQuest );
|
||||
void SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept);
|
||||
|
||||
void SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext );
|
||||
void SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel );
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_GOSSIP_H
|
||||
#define MANGOSSERVER_GOSSIP_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "QuestDef.h"
|
||||
#include "NPCHandler.h"
|
||||
|
||||
class WorldSession;
|
||||
|
||||
#define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough
|
||||
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
|
||||
|
||||
//POI defines
|
||||
enum Poi_Icon
|
||||
{
|
||||
ICON_POI_0 = 0, // Grey ?
|
||||
ICON_POI_1 = 1, // Red ?
|
||||
ICON_POI_2 = 2, // Blue ?
|
||||
ICON_POI_BWTOMB = 3, // Blue and White Tomb Stone
|
||||
ICON_POI_HOUSE = 4, // House
|
||||
ICON_POI_TOWER = 5, // Tower
|
||||
ICON_POI_REDFLAG = 6, // Red Flag with Yellow !
|
||||
ICON_POI_TOMB = 7, // Tomb Stone
|
||||
ICON_POI_BWTOWER = 8, // Blue and White Tower
|
||||
ICON_POI_REDTOWER = 9, // Red Tower
|
||||
ICON_POI_BLUETOWER = 10, // Blue Tower
|
||||
ICON_POI_RWTOWER = 11, // Red and White Tower
|
||||
ICON_POI_REDTOMB = 12, // Red Tomb Stone
|
||||
ICON_POI_RWTOMB = 13, // Red and White Tomb Stone
|
||||
ICON_POI_BLUETOMB = 14, // Blue Tomb Stone
|
||||
ICON_POI_NOTHING = 15, // NOTHING
|
||||
ICON_POI_16 = 16, // Red ?
|
||||
ICON_POI_17 = 17, // Grey ?
|
||||
ICON_POI_18 = 18, // Blue ?
|
||||
ICON_POI_19 = 19, // Red and White ?
|
||||
ICON_POI_20 = 20, // Red ?
|
||||
ICON_POI_GREYLOGS = 21, // Grey Wood Logs
|
||||
ICON_POI_BWLOGS = 22, // Blue and White Wood Logs
|
||||
ICON_POI_BLUELOGS = 23, // Blue Wood Logs
|
||||
ICON_POI_RWLOGS = 24, // Red and White Wood Logs
|
||||
ICON_POI_REDLOGS = 25, // Red Wood Logs
|
||||
ICON_POI_26 = 26, // Grey ?
|
||||
ICON_POI_27 = 27, // Blue and White ?
|
||||
ICON_POI_28 = 28, // Blue ?
|
||||
ICON_POI_29 = 29, // Red and White ?
|
||||
ICON_POI_30 = 30, // Red ?
|
||||
ICON_POI_GREYHOUSE = 31, // Grey House
|
||||
ICON_POI_BWHOUSE = 32, // Blue and White House
|
||||
ICON_POI_BLUEHOUSE = 33, // Blue House
|
||||
ICON_POI_RWHOUSE = 34, // Red and White House
|
||||
ICON_POI_REDHOUSE = 35, // Red House
|
||||
ICON_POI_GREYHORSE = 36, // Grey Horse
|
||||
ICON_POI_BWHORSE = 37, // Blue and White Horse
|
||||
ICON_POI_BLUEHORSE = 38, // Blue Horse
|
||||
ICON_POI_RWHORSE = 39, // Red and White Horse
|
||||
ICON_POI_REDHORSE = 40 // Red Horse
|
||||
};
|
||||
|
||||
struct GossipMenuItem
|
||||
{
|
||||
uint8 m_gIcon;
|
||||
bool m_gCoded;
|
||||
std::string m_gMessage;
|
||||
uint32 m_gSender;
|
||||
uint32 m_gAction;
|
||||
std::string m_gBoxMessage;
|
||||
uint32 m_gBoxMoney;
|
||||
};
|
||||
|
||||
typedef std::vector<GossipMenuItem> GossipMenuItemList;
|
||||
|
||||
struct QuestMenuItem
|
||||
{
|
||||
uint32 m_qId;
|
||||
uint8 m_qIcon;
|
||||
};
|
||||
|
||||
typedef std::vector<QuestMenuItem> QuestMenuItemList;
|
||||
|
||||
class MANGOS_DLL_SPEC GossipMenu
|
||||
{
|
||||
public:
|
||||
GossipMenu();
|
||||
~GossipMenu();
|
||||
|
||||
void AddMenuItem(uint8 Icon, std::string Message, bool Coded = false);
|
||||
void AddMenuItem(uint8 Icon, std::string Message, uint32 dtSender, uint32 dtAction, std::string BoxMessage, uint32 BoxMoney, bool Coded = false);
|
||||
|
||||
// for using from scripts, don't must be inlined
|
||||
void AddMenuItem(uint8 Icon, char const* Message, bool Coded = false);
|
||||
void AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded = false);
|
||||
|
||||
unsigned int MenuItemCount() const
|
||||
{
|
||||
return m_gItems.size();
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return m_gItems.empty();
|
||||
}
|
||||
|
||||
GossipMenuItem const& GetItem( unsigned int Id )
|
||||
{
|
||||
return m_gItems[ Id ];
|
||||
}
|
||||
|
||||
uint32 MenuItemSender( unsigned int ItemId );
|
||||
uint32 MenuItemAction( unsigned int ItemId );
|
||||
bool MenuItemCoded( unsigned int ItemId );
|
||||
|
||||
void ClearMenu();
|
||||
|
||||
protected:
|
||||
GossipMenuItemList m_gItems;
|
||||
};
|
||||
|
||||
class QuestMenu
|
||||
{
|
||||
public:
|
||||
QuestMenu();
|
||||
~QuestMenu();
|
||||
|
||||
void AddMenuItem( uint32 QuestId, uint8 Icon);
|
||||
void ClearMenu();
|
||||
|
||||
uint8 MenuItemCount() const
|
||||
{
|
||||
return m_qItems.size();
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return m_qItems.empty();
|
||||
}
|
||||
|
||||
bool HasItem( uint32 questid );
|
||||
|
||||
QuestMenuItem const& GetItem( uint16 Id )
|
||||
{
|
||||
return m_qItems[ Id ];
|
||||
}
|
||||
|
||||
protected:
|
||||
QuestMenuItemList m_qItems;
|
||||
};
|
||||
|
||||
class MANGOS_DLL_SPEC PlayerMenu
|
||||
{
|
||||
private:
|
||||
GossipMenu mGossipMenu;
|
||||
QuestMenu mQuestMenu;
|
||||
WorldSession* pSession;
|
||||
|
||||
public:
|
||||
PlayerMenu( WorldSession *Session );
|
||||
~PlayerMenu();
|
||||
|
||||
GossipMenu& GetGossipMenu() { return mGossipMenu; }
|
||||
QuestMenu& GetQuestMenu() { return mQuestMenu; }
|
||||
|
||||
bool Empty() const { return mGossipMenu.Empty() && mQuestMenu.Empty(); }
|
||||
|
||||
void ClearMenus();
|
||||
uint32 GossipOptionSender( unsigned int Selection );
|
||||
uint32 GossipOptionAction( unsigned int Selection );
|
||||
bool GossipOptionCoded( unsigned int Selection );
|
||||
|
||||
void SendGossipMenu( uint32 TitleTextId, uint64 npcGUID );
|
||||
void CloseGossip();
|
||||
void SendPointOfInterest( float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, const char * locName );
|
||||
void SendTalking( uint32 textID );
|
||||
void SendTalking( char const * title, char const * text );
|
||||
|
||||
/*********************************************************/
|
||||
/*** QUEST SYSTEM ***/
|
||||
/*********************************************************/
|
||||
void SendQuestGiverStatus( uint8 questStatus, uint64 npcGUID );
|
||||
|
||||
void SendQuestGiverQuestList( QEmote eEmote, std::string Title, uint64 npcGUID );
|
||||
|
||||
void SendQuestQueryResponse ( Quest const *pQuest );
|
||||
void SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID, bool ActivateAccept);
|
||||
|
||||
void SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext );
|
||||
void SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel );
|
||||
};
|
||||
#endif
|
||||
|
||||
+941
-941
File diff suppressed because it is too large
Load Diff
+1454
-1454
File diff suppressed because it is too large
Load Diff
+154
-154
@@ -1,154 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "GuardAI.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "World.h"
|
||||
|
||||
int GuardAI::Permissible(const Creature *creature)
|
||||
{
|
||||
if( creature->isGuard())
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
GuardAI::GuardAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
||||
{
|
||||
}
|
||||
|
||||
void GuardAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
// Ignore Z for flying creatures
|
||||
if ( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
||||
return;
|
||||
|
||||
if( !i_creature.getVictim() && u->isTargetableForAttack() &&
|
||||
( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) &&
|
||||
u->isInAccessablePlaceFor(&i_creature))
|
||||
{
|
||||
float attackRadius = i_creature.GetAttackDistance(u);
|
||||
if(i_creature.IsWithinDistInMap(u,attackRadius))
|
||||
{
|
||||
//Need add code to let guard support player
|
||||
AttackStart(u);
|
||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuardAI::EnterEvadeMode()
|
||||
{
|
||||
if( !i_creature.isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
i_creature.StopMoving();
|
||||
i_creature.GetMotionMaster()->MoveIdle();
|
||||
|
||||
i_state = STATE_NORMAL;
|
||||
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
|
||||
if( !victim )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( !victim ->isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim ->HasStealthAura() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim ->isInFlight() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
|
||||
i_creature.RemoveAllAuras();
|
||||
i_creature.DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_state = STATE_NORMAL;
|
||||
|
||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
void GuardAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
||||
return;
|
||||
|
||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GuardAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
||||
}
|
||||
|
||||
void GuardAI::AttackStart(Unit *u)
|
||||
{
|
||||
if( !u )
|
||||
return;
|
||||
|
||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
||||
if(i_creature.Attack(u,true))
|
||||
{
|
||||
i_creature.SetInCombatWith(u);
|
||||
u->SetInCombatWith(&i_creature);
|
||||
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
i_victimGuid = u->GetGUID();
|
||||
i_creature.GetMotionMaster()->MoveChase(u);
|
||||
}
|
||||
}
|
||||
|
||||
void GuardAI::JustDied(Unit *killer)
|
||||
{
|
||||
if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
i_creature.SendZoneUnderAttackMessage(pkiller);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "GuardAI.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "World.h"
|
||||
|
||||
int GuardAI::Permissible(const Creature *creature)
|
||||
{
|
||||
if( creature->isGuard())
|
||||
return PERMIT_BASE_SPECIAL;
|
||||
|
||||
return PERMIT_BASE_NO;
|
||||
}
|
||||
|
||||
GuardAI::GuardAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)
|
||||
{
|
||||
}
|
||||
|
||||
void GuardAI::MoveInLineOfSight(Unit *u)
|
||||
{
|
||||
// Ignore Z for flying creatures
|
||||
if ( !i_creature.canFly() && i_creature.GetDistanceZ(u) > CREATURE_Z_ATTACK_RANGE )
|
||||
return;
|
||||
|
||||
if( !i_creature.getVictim() && u->isTargetableForAttack() &&
|
||||
( u->IsHostileToPlayers() || i_creature.IsHostileTo(u) /*|| u->getVictim() && i_creature.IsFriendlyTo(u->getVictim())*/ ) &&
|
||||
u->isInAccessablePlaceFor(&i_creature))
|
||||
{
|
||||
float attackRadius = i_creature.GetAttackDistance(u);
|
||||
if(i_creature.IsWithinDistInMap(u,attackRadius))
|
||||
{
|
||||
//Need add code to let guard support player
|
||||
AttackStart(u);
|
||||
u->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GuardAI::EnterEvadeMode()
|
||||
{
|
||||
if( !i_creature.isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because he's dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
i_creature.StopMoving();
|
||||
i_creature.GetMotionMaster()->MoveIdle();
|
||||
|
||||
i_state = STATE_NORMAL;
|
||||
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_creature.DeleteThreatList();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = ObjectAccessor::GetUnit(i_creature, i_victimGuid );
|
||||
|
||||
if( !victim )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is non exist [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( !victim ->isAlive() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is dead [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim ->HasStealthAura() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is using stealth [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else if( victim ->isInFlight() )
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim is flying away [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature stopped attacking because victim outran him [guid=%u]", i_creature.GetGUIDLow());
|
||||
}
|
||||
|
||||
i_creature.RemoveAllAuras();
|
||||
i_creature.DeleteThreatList();
|
||||
i_victimGuid = 0;
|
||||
i_creature.CombatStop();
|
||||
i_state = STATE_NORMAL;
|
||||
|
||||
// Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
|
||||
if( i_creature.GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
i_creature.GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
void GuardAI::UpdateAI(const uint32 /*diff*/)
|
||||
{
|
||||
// update i_victimGuid if i_creature.getVictim() !=0 and changed
|
||||
if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())
|
||||
return;
|
||||
|
||||
i_victimGuid = i_creature.getVictim()->GetGUID();
|
||||
|
||||
if( i_creature.isAttackReady() )
|
||||
{
|
||||
if( i_creature.IsWithinDistInMap(i_creature.getVictim(), ATTACK_DISTANCE))
|
||||
{
|
||||
i_creature.AttackerStateUpdate(i_creature.getVictim());
|
||||
i_creature.resetAttackTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GuardAI::IsVisible(Unit *pl) const
|
||||
{
|
||||
return i_creature.GetDistance(pl) < sWorld.getConfig(CONFIG_SIGHT_GUARDER)
|
||||
&& pl->isVisibleForOrDetect(&i_creature,true);
|
||||
}
|
||||
|
||||
void GuardAI::AttackStart(Unit *u)
|
||||
{
|
||||
if( !u )
|
||||
return;
|
||||
|
||||
// DEBUG_LOG("Creature %s tagged a victim to kill [guid=%u]", i_creature.GetName(), u->GetGUIDLow());
|
||||
if(i_creature.Attack(u,true))
|
||||
{
|
||||
i_creature.SetInCombatWith(u);
|
||||
u->SetInCombatWith(&i_creature);
|
||||
|
||||
i_creature.AddThreat(u, 0.0f);
|
||||
i_victimGuid = u->GetGUID();
|
||||
i_creature.GetMotionMaster()->MoveChase(u);
|
||||
}
|
||||
}
|
||||
|
||||
void GuardAI::JustDied(Unit *killer)
|
||||
{
|
||||
if(Player* pkiller = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
i_creature.SendZoneUnderAttackMessage(pkiller);
|
||||
}
|
||||
|
||||
|
||||
+1963
-1963
File diff suppressed because it is too large
Load Diff
+437
-437
@@ -1,437 +1,437 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_GUILD_H
|
||||
#define MANGOSSERVER_GUILD_H
|
||||
|
||||
#define WITHDRAW_MONEY_UNLIMITED 0xFFFFFFFF
|
||||
#define WITHDRAW_SLOT_UNLIMITED 0xFFFFFFFF
|
||||
|
||||
#include "Item.h"
|
||||
|
||||
class Item;
|
||||
|
||||
enum GuildDefaultRanks
|
||||
{
|
||||
GR_GUILDMASTER = 0,
|
||||
GR_OFFICER = 1,
|
||||
//GR_VETERAN = 2, -- not used anywhere and possible incorrect in modified rank list
|
||||
//GR_MEMBER = 3,
|
||||
//GR_INITIATE = 4, -- use Guild::GetLowestRank() instead for lowest rank
|
||||
};
|
||||
|
||||
enum GuildRankRights
|
||||
{
|
||||
GR_RIGHT_EMPTY = 0x00000040,
|
||||
GR_RIGHT_GCHATLISTEN = 0x00000041,
|
||||
GR_RIGHT_GCHATSPEAK = 0x00000042,
|
||||
GR_RIGHT_OFFCHATLISTEN = 0x00000044,
|
||||
GR_RIGHT_OFFCHATSPEAK = 0x00000048,
|
||||
GR_RIGHT_PROMOTE = 0x000000C0,
|
||||
GR_RIGHT_DEMOTE = 0x00000140,
|
||||
GR_RIGHT_INVITE = 0x00000050,
|
||||
GR_RIGHT_REMOVE = 0x00000060,
|
||||
GR_RIGHT_SETMOTD = 0x00001040,
|
||||
GR_RIGHT_EPNOTE = 0x00002040,
|
||||
GR_RIGHT_VIEWOFFNOTE = 0x00004040,
|
||||
GR_RIGHT_EOFFNOTE = 0x00008040,
|
||||
GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040,
|
||||
GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity
|
||||
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
|
||||
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
|
||||
GR_RIGHT_ALL = 0x000FF1FF
|
||||
};
|
||||
|
||||
enum Typecommand
|
||||
{
|
||||
GUILD_CREATE_S = 0x00,
|
||||
GUILD_INVITE_S = 0x01,
|
||||
GUILD_QUIT_S = 0x03,
|
||||
GUILD_FOUNDER_S = 0x0E,
|
||||
GUILD_UNK1 = 0x10,
|
||||
GUILD_BANK_S = 0x15,
|
||||
GUILD_UNK3 = 0x16
|
||||
};
|
||||
|
||||
enum CommandErrors
|
||||
{
|
||||
GUILD_PLAYER_NO_MORE_IN_GUILD = 0x00,
|
||||
GUILD_INTERNAL = 0x01,
|
||||
GUILD_ALREADY_IN_GUILD = 0x02,
|
||||
ALREADY_IN_GUILD = 0x03,
|
||||
INVITED_TO_GUILD = 0x04,
|
||||
ALREADY_INVITED_TO_GUILD = 0x05,
|
||||
GUILD_NAME_INVALID = 0x06,
|
||||
GUILD_NAME_EXISTS = 0x07,
|
||||
GUILD_LEADER_LEAVE = 0x08,
|
||||
GUILD_PERMISSIONS = 0x08,
|
||||
GUILD_PLAYER_NOT_IN_GUILD = 0x09,
|
||||
GUILD_PLAYER_NOT_IN_GUILD_S = 0x0A,
|
||||
GUILD_PLAYER_NOT_FOUND = 0x0B,
|
||||
GUILD_NOT_ALLIED = 0x0C,
|
||||
GUILD_RANK_TOO_HIGH_S = 0x0D,
|
||||
GUILD_ALREADY_LOWEST_RANK_S = 0x0E,
|
||||
GUILD_TEMP_ERROR = 0x11,
|
||||
GUILD_RANK_IN_USE = 0x12,
|
||||
GUILD_IGNORE = 0x13,
|
||||
GUILD_ERR_UNK1 = 0x17,
|
||||
GUILD_WITHDRAW_TOO_MUCH = 0x18,
|
||||
GUILD_BANK_NO_MONEY = 0x19,
|
||||
GUILD_BANK_TAB_IS_FULL = 0x1B,
|
||||
GUILD_BANK_ITEM_NOT_FOUND = 0x1C
|
||||
};
|
||||
|
||||
enum GuildEvents
|
||||
{
|
||||
GE_PROMOTION = 0x00,
|
||||
GE_DEMOTION = 0x01,
|
||||
GE_MOTD = 0x02,
|
||||
GE_JOINED = 0x03,
|
||||
GE_LEFT = 0x04,
|
||||
GE_REMOVED = 0x05,
|
||||
GE_LEADER_IS = 0x06,
|
||||
GE_LEADER_CHANGED = 0x07,
|
||||
GE_DISBANDED = 0x08,
|
||||
GE_TABARDCHANGE = 0x09,
|
||||
GE_UNK1 = 0x0A, // string, string
|
||||
GE_UNK2 = 0x0B,
|
||||
GE_SIGNED_ON = 0x0C,
|
||||
GE_SIGNED_OFF = 0x0D,
|
||||
GE_UNK3 = 0x0E,
|
||||
GE_BANKTAB_PURCHASED= 0x0F,
|
||||
GE_UNK5 = 0x10,
|
||||
GE_UNK6 = 0x11, // string 0000000000002710 is 1 gold
|
||||
GE_UNK7 = 0x12
|
||||
};
|
||||
|
||||
enum PetitionTurns
|
||||
{
|
||||
PETITION_TURN_OK = 0,
|
||||
PETITION_TURN_ALREADY_IN_GUILD = 2,
|
||||
PETITION_TURN_NEED_MORE_SIGNATURES = 4,
|
||||
};
|
||||
|
||||
enum PetitionSigns
|
||||
{
|
||||
PETITION_SIGN_OK = 0,
|
||||
PETITION_SIGN_ALREADY_SIGNED = 1,
|
||||
PETITION_SIGN_ALREADY_IN_GUILD = 2,
|
||||
PETITION_SIGN_CANT_SIGN_OWN = 3,
|
||||
PETITION_SIGN_NOT_SERVER = 4,
|
||||
};
|
||||
|
||||
enum GuildBankRights
|
||||
{
|
||||
GUILD_BANK_RIGHT_VIEW_TAB = 0x01,
|
||||
GUILD_BANK_RIGHT_PUT_ITEM = 0x02,
|
||||
GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04,
|
||||
|
||||
GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM,
|
||||
GUILD_BANK_RIGHT_FULL = 0xFF,
|
||||
};
|
||||
|
||||
enum GuildBankLogEntries
|
||||
{
|
||||
GUILD_BANK_LOG_DEPOSIT_ITEM = 1,
|
||||
GUILD_BANK_LOG_WITHDRAW_ITEM = 2,
|
||||
GUILD_BANK_LOG_MOVE_ITEM = 3,
|
||||
GUILD_BANK_LOG_DEPOSIT_MONEY = 4,
|
||||
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
|
||||
GUILD_BANK_LOG_REPAIR_MONEY = 6,
|
||||
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
|
||||
};
|
||||
|
||||
enum GuildEventLogEntryTypes
|
||||
{
|
||||
GUILD_EVENT_LOG_INVITE_PLAYER = 1,
|
||||
GUILD_EVENT_LOG_JOIN_GUILD = 2,
|
||||
GUILD_EVENT_LOG_PROMOTE_PLAYER = 3,
|
||||
GUILD_EVENT_LOG_DEMOTE_PLAYER = 4,
|
||||
GUILD_EVENT_LOG_UNINVITE_PLAYER = 5,
|
||||
GUILD_EVENT_LOG_LEAVE_GUILD = 6,
|
||||
};
|
||||
|
||||
struct GuildEventlogEntry
|
||||
{
|
||||
uint32 LogGuid;
|
||||
uint8 EventType;
|
||||
uint32 PlayerGuid1;
|
||||
uint32 PlayerGuid2;
|
||||
uint8 NewRank;
|
||||
uint64 TimeStamp;
|
||||
};
|
||||
|
||||
enum GuildEmblem
|
||||
{
|
||||
ERR_GUILDEMBLEM_SUCCESS = 0,
|
||||
ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1,
|
||||
ERR_GUILDEMBLEM_NOGUILD = 2,
|
||||
ERR_GUILDEMBLEM_NOTGUILDMASTER = 3,
|
||||
ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4,
|
||||
ERR_GUILDEMBLEM_INVALIDVENDOR = 5
|
||||
};
|
||||
|
||||
struct GuildBankEvent
|
||||
{
|
||||
uint32 LogGuid;
|
||||
uint8 LogEntry;
|
||||
uint8 TabId;
|
||||
uint32 PlayerGuid;
|
||||
uint32 ItemOrMoney;
|
||||
uint8 ItemStackCount;
|
||||
uint8 DestTabId;
|
||||
uint64 TimeStamp;
|
||||
|
||||
const bool isMoneyEvent()
|
||||
{
|
||||
return LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
|
||||
LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
|
||||
LogEntry == GUILD_BANK_LOG_REPAIR_MONEY;
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildBankTab
|
||||
{
|
||||
Item* Slots[GUILD_BANK_MAX_SLOTS];
|
||||
std::string Name;
|
||||
std::string Icon;
|
||||
std::string Text;
|
||||
};
|
||||
|
||||
struct GuildItemPosCount
|
||||
{
|
||||
GuildItemPosCount(uint8 _slot, uint8 _count) : slot(_slot), count(_count) {}
|
||||
|
||||
bool isContainedIn(std::vector<GuildItemPosCount> const& vec) const;
|
||||
|
||||
uint8 slot;
|
||||
uint8 count;
|
||||
};
|
||||
typedef std::vector<GuildItemPosCount> GuildItemPosCountVec;
|
||||
|
||||
struct MemberSlot
|
||||
{
|
||||
uint64 logout_time;
|
||||
std::string name;
|
||||
std::string Pnote;
|
||||
std::string OFFnote;
|
||||
uint32 RankId;
|
||||
uint32 zoneId;
|
||||
uint8 level;
|
||||
uint8 Class;
|
||||
uint32 BankResetTimeMoney;
|
||||
uint32 BankRemMoney;
|
||||
uint32 BankResetTimeTab[GUILD_BANK_MAX_TABS];
|
||||
uint32 BankRemSlotsTab[GUILD_BANK_MAX_TABS];
|
||||
};
|
||||
|
||||
struct RankInfo
|
||||
{
|
||||
RankInfo(std::string _name, uint32 _rights, uint32 _money) : name(_name), rights(_rights), BankMoneyPerDay(_money)
|
||||
{
|
||||
for(uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i)
|
||||
{
|
||||
TabRight[i] = 0;
|
||||
TabSlotPerDay[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string name;
|
||||
uint32 rights;
|
||||
uint32 BankMoneyPerDay;
|
||||
uint32 TabRight[GUILD_BANK_MAX_TABS];
|
||||
uint32 TabSlotPerDay[GUILD_BANK_MAX_TABS];
|
||||
};
|
||||
|
||||
class Guild
|
||||
{
|
||||
public:
|
||||
Guild();
|
||||
~Guild();
|
||||
|
||||
bool create(uint64 lGuid, std::string gname);
|
||||
void Disband();
|
||||
|
||||
typedef std::map<uint32, MemberSlot> MemberList;
|
||||
typedef std::vector<RankInfo> RankList;
|
||||
|
||||
uint32 GetId(){ return Id; }
|
||||
const uint64& GetLeader(){ return leaderGuid; }
|
||||
std::string GetName(){ return name; }
|
||||
std::string GetMOTD(){ return MOTD; }
|
||||
std::string GetGINFO(){ return GINFO; }
|
||||
|
||||
uint32 GetCreatedYear(){ return CreatedYear; }
|
||||
uint32 GetCreatedMonth(){ return CreatedMonth; }
|
||||
uint32 GetCreatedDay(){ return CreatedDay; }
|
||||
|
||||
uint32 GetEmblemStyle(){ return EmblemStyle; }
|
||||
uint32 GetEmblemColor(){ return EmblemColor; }
|
||||
uint32 GetBorderStyle(){ return BorderStyle; }
|
||||
uint32 GetBorderColor(){ return BorderColor; }
|
||||
uint32 GetBackgroundColor(){ return BackgroundColor; }
|
||||
|
||||
void SetLeader(uint64 guid);
|
||||
bool AddMember(uint64 plGuid, uint32 plRank);
|
||||
void ChangeRank(uint64 guid, uint32 newRank);
|
||||
void DelMember(uint64 guid, bool isDisbanding=false);
|
||||
uint32 GetLowestRank() const { return GetNrRanks()-1; }
|
||||
|
||||
void SetMOTD(std::string motd);
|
||||
void SetGINFO(std::string ginfo);
|
||||
void SetPNOTE(uint64 guid,std::string pnote);
|
||||
void SetOFFNOTE(uint64 guid,std::string offnote);
|
||||
void SetEmblem(uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor, uint32 backgroundColor);
|
||||
|
||||
uint32 GetMemberSize() const { return members.size(); }
|
||||
|
||||
bool LoadGuildFromDB(uint32 GuildId);
|
||||
bool LoadRanksFromDB(uint32 GuildId);
|
||||
bool LoadMembersFromDB(uint32 GuildId);
|
||||
|
||||
bool FillPlayerData(uint64 guid, MemberSlot* memslot);
|
||||
void LoadPlayerStatsByGuid(uint64 guid);
|
||||
|
||||
void BroadcastToGuild(WorldSession *session, std::string msg, uint32 language = LANG_UNIVERSAL);
|
||||
void BroadcastToOfficers(WorldSession *session, std::string msg, uint32 language = LANG_UNIVERSAL);
|
||||
void BroadcastPacketToRank(WorldPacket *packet, uint32 rankId);
|
||||
void BroadcastPacket(WorldPacket *packet);
|
||||
|
||||
void CreateRank(std::string name,uint32 rights);
|
||||
void DelRank();
|
||||
std::string GetRankName(uint32 rankId);
|
||||
uint32 GetRankRights(uint32 rankId);
|
||||
uint32 GetNrRanks() const { return m_ranks.size(); }
|
||||
|
||||
void SetRankName(uint32 rankId, std::string name);
|
||||
void SetRankRights(uint32 rankId, uint32 rights);
|
||||
bool HasRankRight(uint32 rankId, uint32 right)
|
||||
{
|
||||
return ((GetRankRights(rankId) & right) != GR_RIGHT_EMPTY) ? true : false;
|
||||
}
|
||||
|
||||
void Roster(WorldSession *session);
|
||||
void Query(WorldSession *session);
|
||||
|
||||
void UpdateLogoutTime(uint64 guid);
|
||||
// Guild eventlog
|
||||
void LoadGuildEventLogFromDB();
|
||||
void UnloadGuildEventlog();
|
||||
void DisplayGuildEventlog(WorldSession *session);
|
||||
void LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank);
|
||||
void RenumGuildEventlog();
|
||||
|
||||
// ** Guild bank **
|
||||
// Content & item deposit/withdraw
|
||||
void DisplayGuildBankContent(WorldSession *session, uint8 TabId);
|
||||
void DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2 = -1);
|
||||
void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots);
|
||||
void DisplayGuildBankMoneyUpdate();
|
||||
|
||||
Item* GetItem(uint8 TabId, uint8 SlotId);
|
||||
uint8 CanStoreItem( uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32 count, Item *pItem, bool swap = false) const;
|
||||
Item* StoreItem( uint8 tab, GuildItemPosCountVec const& pos, Item *pItem );
|
||||
void RemoveItem(uint8 tab, uint8 slot );
|
||||
|
||||
// Tabs
|
||||
void DisplayGuildBankTabsInfo(WorldSession *session);
|
||||
void CreateNewBankTab();
|
||||
void SetGuildBankTabText(uint8 TabId, std::string text);
|
||||
void SendGuildBankTabText(WorldSession *session, uint8 TabId);
|
||||
void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon);
|
||||
void CreateBankRightForTab(uint32 rankid, uint8 TabId);
|
||||
const GuildBankTab *GetBankTab(uint8 index) { if(index >= m_TabListMap.size()) return NULL; return m_TabListMap[index]; }
|
||||
const uint8 GetPurchasedTabs() const { return purchased_tabs; }
|
||||
uint32 GetBankRights(uint32 rankId, uint8 TabId) const;
|
||||
bool IsMemberHaveRights(uint32 LowGuid, uint8 TabId,uint32 rights) const;
|
||||
bool CanMemberViewTab(uint32 LowGuid, uint8 TabId) const;
|
||||
// Load/unload
|
||||
void LoadGuildBankFromDB();
|
||||
void UnloadGuildBank();
|
||||
void IncOnlineMemberCount() { ++m_onlinemembers; }
|
||||
// Money deposit/withdraw
|
||||
void SendMoneyInfo(WorldSession *session, uint32 LowGuid);
|
||||
bool MemberMoneyWithdraw(uint32 amount, uint32 LowGuid);
|
||||
uint64 GetGuildBankMoney() { return guildbank_money; }
|
||||
void SetBankMoney(int64 money);
|
||||
// per days
|
||||
bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid);
|
||||
uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId);
|
||||
uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid);
|
||||
void SetBankMoneyPerDay(uint32 rankId, uint32 money);
|
||||
void SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 SlotPerDay, bool db);
|
||||
uint32 GetBankMoneyPerDay(uint32 rankId);
|
||||
uint32 GetBankSlotPerDay(uint32 rankId, uint8 TabId);
|
||||
// rights per day
|
||||
void LoadBankRightsFromDB(uint32 GuildId);
|
||||
// logs
|
||||
void LoadGuildBankEventLogFromDB();
|
||||
void UnloadGuildBankEventLog();
|
||||
void DisplayGuildBankLogs(WorldSession *session, uint8 TabId);
|
||||
void LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount=0, uint8 DestTabId=0);
|
||||
void RenumBankLogs();
|
||||
bool AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry );
|
||||
|
||||
protected:
|
||||
void AddRank(std::string name,uint32 rights,uint32 money);
|
||||
|
||||
uint32 Id;
|
||||
std::string name;
|
||||
uint64 leaderGuid;
|
||||
std::string MOTD;
|
||||
std::string GINFO;
|
||||
uint32 CreatedYear;
|
||||
uint32 CreatedMonth;
|
||||
uint32 CreatedDay;
|
||||
|
||||
uint32 EmblemStyle;
|
||||
uint32 EmblemColor;
|
||||
uint32 BorderStyle;
|
||||
uint32 BorderColor;
|
||||
uint32 BackgroundColor;
|
||||
|
||||
RankList m_ranks;
|
||||
|
||||
MemberList members;
|
||||
|
||||
typedef std::vector<GuildBankTab*> TabListMap;
|
||||
TabListMap m_TabListMap;
|
||||
|
||||
/** These are actually ordered lists. The first element is the oldest entry.*/
|
||||
typedef std::list<GuildEventlogEntry*> GuildEventlog;
|
||||
typedef std::list<GuildBankEvent*> GuildBankEventLog;
|
||||
GuildEventlog m_GuildEventlog;
|
||||
GuildBankEventLog m_GuildBankEventLog_Money;
|
||||
GuildBankEventLog m_GuildBankEventLog_Item[GUILD_BANK_MAX_TABS];
|
||||
|
||||
bool m_bankloaded;
|
||||
bool m_eventlogloaded;
|
||||
uint32 m_onlinemembers;
|
||||
uint64 guildbank_money;
|
||||
uint8 purchased_tabs;
|
||||
|
||||
uint32 LogMaxGuid;
|
||||
uint32 GuildEventlogMaxGuid;
|
||||
private:
|
||||
// internal common parts for CanStore/StoreItem functions
|
||||
void AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *tab, int32 slot );
|
||||
uint8 _CanStoreItem_InSpecificSlot( uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32& count, bool swap, Item *pSrcItem ) const;
|
||||
uint8 _CanStoreItem_InTab( uint8 tab, GuildItemPosCountVec& dest, uint32& count, bool merge, Item *pSrcItem, uint8 skip_slot ) const;
|
||||
Item* _StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone );
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_GUILD_H
|
||||
#define MANGOSSERVER_GUILD_H
|
||||
|
||||
#define WITHDRAW_MONEY_UNLIMITED 0xFFFFFFFF
|
||||
#define WITHDRAW_SLOT_UNLIMITED 0xFFFFFFFF
|
||||
|
||||
#include "Item.h"
|
||||
|
||||
class Item;
|
||||
|
||||
enum GuildDefaultRanks
|
||||
{
|
||||
GR_GUILDMASTER = 0,
|
||||
GR_OFFICER = 1,
|
||||
//GR_VETERAN = 2, -- not used anywhere and possible incorrect in modified rank list
|
||||
//GR_MEMBER = 3,
|
||||
//GR_INITIATE = 4, -- use Guild::GetLowestRank() instead for lowest rank
|
||||
};
|
||||
|
||||
enum GuildRankRights
|
||||
{
|
||||
GR_RIGHT_EMPTY = 0x00000040,
|
||||
GR_RIGHT_GCHATLISTEN = 0x00000041,
|
||||
GR_RIGHT_GCHATSPEAK = 0x00000042,
|
||||
GR_RIGHT_OFFCHATLISTEN = 0x00000044,
|
||||
GR_RIGHT_OFFCHATSPEAK = 0x00000048,
|
||||
GR_RIGHT_PROMOTE = 0x000000C0,
|
||||
GR_RIGHT_DEMOTE = 0x00000140,
|
||||
GR_RIGHT_INVITE = 0x00000050,
|
||||
GR_RIGHT_REMOVE = 0x00000060,
|
||||
GR_RIGHT_SETMOTD = 0x00001040,
|
||||
GR_RIGHT_EPNOTE = 0x00002040,
|
||||
GR_RIGHT_VIEWOFFNOTE = 0x00004040,
|
||||
GR_RIGHT_EOFFNOTE = 0x00008040,
|
||||
GR_RIGHT_MODIFY_GUILD_INFO = 0x00010040,
|
||||
GR_RIGHT_REPAIR_FROM_GUILD = 0x00020000, // unused in 2.4.x?, Remove money withdraw capacity
|
||||
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
|
||||
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
|
||||
GR_RIGHT_ALL = 0x000FF1FF
|
||||
};
|
||||
|
||||
enum Typecommand
|
||||
{
|
||||
GUILD_CREATE_S = 0x00,
|
||||
GUILD_INVITE_S = 0x01,
|
||||
GUILD_QUIT_S = 0x03,
|
||||
GUILD_FOUNDER_S = 0x0E,
|
||||
GUILD_UNK1 = 0x10,
|
||||
GUILD_BANK_S = 0x15,
|
||||
GUILD_UNK3 = 0x16
|
||||
};
|
||||
|
||||
enum CommandErrors
|
||||
{
|
||||
GUILD_PLAYER_NO_MORE_IN_GUILD = 0x00,
|
||||
GUILD_INTERNAL = 0x01,
|
||||
GUILD_ALREADY_IN_GUILD = 0x02,
|
||||
ALREADY_IN_GUILD = 0x03,
|
||||
INVITED_TO_GUILD = 0x04,
|
||||
ALREADY_INVITED_TO_GUILD = 0x05,
|
||||
GUILD_NAME_INVALID = 0x06,
|
||||
GUILD_NAME_EXISTS = 0x07,
|
||||
GUILD_LEADER_LEAVE = 0x08,
|
||||
GUILD_PERMISSIONS = 0x08,
|
||||
GUILD_PLAYER_NOT_IN_GUILD = 0x09,
|
||||
GUILD_PLAYER_NOT_IN_GUILD_S = 0x0A,
|
||||
GUILD_PLAYER_NOT_FOUND = 0x0B,
|
||||
GUILD_NOT_ALLIED = 0x0C,
|
||||
GUILD_RANK_TOO_HIGH_S = 0x0D,
|
||||
GUILD_ALREADY_LOWEST_RANK_S = 0x0E,
|
||||
GUILD_TEMP_ERROR = 0x11,
|
||||
GUILD_RANK_IN_USE = 0x12,
|
||||
GUILD_IGNORE = 0x13,
|
||||
GUILD_ERR_UNK1 = 0x17,
|
||||
GUILD_WITHDRAW_TOO_MUCH = 0x18,
|
||||
GUILD_BANK_NO_MONEY = 0x19,
|
||||
GUILD_BANK_TAB_IS_FULL = 0x1B,
|
||||
GUILD_BANK_ITEM_NOT_FOUND = 0x1C
|
||||
};
|
||||
|
||||
enum GuildEvents
|
||||
{
|
||||
GE_PROMOTION = 0x00,
|
||||
GE_DEMOTION = 0x01,
|
||||
GE_MOTD = 0x02,
|
||||
GE_JOINED = 0x03,
|
||||
GE_LEFT = 0x04,
|
||||
GE_REMOVED = 0x05,
|
||||
GE_LEADER_IS = 0x06,
|
||||
GE_LEADER_CHANGED = 0x07,
|
||||
GE_DISBANDED = 0x08,
|
||||
GE_TABARDCHANGE = 0x09,
|
||||
GE_UNK1 = 0x0A, // string, string
|
||||
GE_UNK2 = 0x0B,
|
||||
GE_SIGNED_ON = 0x0C,
|
||||
GE_SIGNED_OFF = 0x0D,
|
||||
GE_UNK3 = 0x0E,
|
||||
GE_BANKTAB_PURCHASED= 0x0F,
|
||||
GE_UNK5 = 0x10,
|
||||
GE_UNK6 = 0x11, // string 0000000000002710 is 1 gold
|
||||
GE_UNK7 = 0x12
|
||||
};
|
||||
|
||||
enum PetitionTurns
|
||||
{
|
||||
PETITION_TURN_OK = 0,
|
||||
PETITION_TURN_ALREADY_IN_GUILD = 2,
|
||||
PETITION_TURN_NEED_MORE_SIGNATURES = 4,
|
||||
};
|
||||
|
||||
enum PetitionSigns
|
||||
{
|
||||
PETITION_SIGN_OK = 0,
|
||||
PETITION_SIGN_ALREADY_SIGNED = 1,
|
||||
PETITION_SIGN_ALREADY_IN_GUILD = 2,
|
||||
PETITION_SIGN_CANT_SIGN_OWN = 3,
|
||||
PETITION_SIGN_NOT_SERVER = 4,
|
||||
};
|
||||
|
||||
enum GuildBankRights
|
||||
{
|
||||
GUILD_BANK_RIGHT_VIEW_TAB = 0x01,
|
||||
GUILD_BANK_RIGHT_PUT_ITEM = 0x02,
|
||||
GUILD_BANK_RIGHT_UPDATE_TEXT = 0x04,
|
||||
|
||||
GUILD_BANK_RIGHT_DEPOSIT_ITEM = GUILD_BANK_RIGHT_VIEW_TAB | GUILD_BANK_RIGHT_PUT_ITEM,
|
||||
GUILD_BANK_RIGHT_FULL = 0xFF,
|
||||
};
|
||||
|
||||
enum GuildBankLogEntries
|
||||
{
|
||||
GUILD_BANK_LOG_DEPOSIT_ITEM = 1,
|
||||
GUILD_BANK_LOG_WITHDRAW_ITEM = 2,
|
||||
GUILD_BANK_LOG_MOVE_ITEM = 3,
|
||||
GUILD_BANK_LOG_DEPOSIT_MONEY = 4,
|
||||
GUILD_BANK_LOG_WITHDRAW_MONEY = 5,
|
||||
GUILD_BANK_LOG_REPAIR_MONEY = 6,
|
||||
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
|
||||
};
|
||||
|
||||
enum GuildEventLogEntryTypes
|
||||
{
|
||||
GUILD_EVENT_LOG_INVITE_PLAYER = 1,
|
||||
GUILD_EVENT_LOG_JOIN_GUILD = 2,
|
||||
GUILD_EVENT_LOG_PROMOTE_PLAYER = 3,
|
||||
GUILD_EVENT_LOG_DEMOTE_PLAYER = 4,
|
||||
GUILD_EVENT_LOG_UNINVITE_PLAYER = 5,
|
||||
GUILD_EVENT_LOG_LEAVE_GUILD = 6,
|
||||
};
|
||||
|
||||
struct GuildEventlogEntry
|
||||
{
|
||||
uint32 LogGuid;
|
||||
uint8 EventType;
|
||||
uint32 PlayerGuid1;
|
||||
uint32 PlayerGuid2;
|
||||
uint8 NewRank;
|
||||
uint64 TimeStamp;
|
||||
};
|
||||
|
||||
enum GuildEmblem
|
||||
{
|
||||
ERR_GUILDEMBLEM_SUCCESS = 0,
|
||||
ERR_GUILDEMBLEM_INVALID_TABARD_COLORS = 1,
|
||||
ERR_GUILDEMBLEM_NOGUILD = 2,
|
||||
ERR_GUILDEMBLEM_NOTGUILDMASTER = 3,
|
||||
ERR_GUILDEMBLEM_NOTENOUGHMONEY = 4,
|
||||
ERR_GUILDEMBLEM_INVALIDVENDOR = 5
|
||||
};
|
||||
|
||||
struct GuildBankEvent
|
||||
{
|
||||
uint32 LogGuid;
|
||||
uint8 LogEntry;
|
||||
uint8 TabId;
|
||||
uint32 PlayerGuid;
|
||||
uint32 ItemOrMoney;
|
||||
uint8 ItemStackCount;
|
||||
uint8 DestTabId;
|
||||
uint64 TimeStamp;
|
||||
|
||||
const bool isMoneyEvent()
|
||||
{
|
||||
return LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||
|
||||
LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY ||
|
||||
LogEntry == GUILD_BANK_LOG_REPAIR_MONEY;
|
||||
}
|
||||
};
|
||||
|
||||
struct GuildBankTab
|
||||
{
|
||||
Item* Slots[GUILD_BANK_MAX_SLOTS];
|
||||
std::string Name;
|
||||
std::string Icon;
|
||||
std::string Text;
|
||||
};
|
||||
|
||||
struct GuildItemPosCount
|
||||
{
|
||||
GuildItemPosCount(uint8 _slot, uint8 _count) : slot(_slot), count(_count) {}
|
||||
|
||||
bool isContainedIn(std::vector<GuildItemPosCount> const& vec) const;
|
||||
|
||||
uint8 slot;
|
||||
uint8 count;
|
||||
};
|
||||
typedef std::vector<GuildItemPosCount> GuildItemPosCountVec;
|
||||
|
||||
struct MemberSlot
|
||||
{
|
||||
uint64 logout_time;
|
||||
std::string name;
|
||||
std::string Pnote;
|
||||
std::string OFFnote;
|
||||
uint32 RankId;
|
||||
uint32 zoneId;
|
||||
uint8 level;
|
||||
uint8 Class;
|
||||
uint32 BankResetTimeMoney;
|
||||
uint32 BankRemMoney;
|
||||
uint32 BankResetTimeTab[GUILD_BANK_MAX_TABS];
|
||||
uint32 BankRemSlotsTab[GUILD_BANK_MAX_TABS];
|
||||
};
|
||||
|
||||
struct RankInfo
|
||||
{
|
||||
RankInfo(std::string _name, uint32 _rights, uint32 _money) : name(_name), rights(_rights), BankMoneyPerDay(_money)
|
||||
{
|
||||
for(uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i)
|
||||
{
|
||||
TabRight[i] = 0;
|
||||
TabSlotPerDay[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string name;
|
||||
uint32 rights;
|
||||
uint32 BankMoneyPerDay;
|
||||
uint32 TabRight[GUILD_BANK_MAX_TABS];
|
||||
uint32 TabSlotPerDay[GUILD_BANK_MAX_TABS];
|
||||
};
|
||||
|
||||
class Guild
|
||||
{
|
||||
public:
|
||||
Guild();
|
||||
~Guild();
|
||||
|
||||
bool create(uint64 lGuid, std::string gname);
|
||||
void Disband();
|
||||
|
||||
typedef std::map<uint32, MemberSlot> MemberList;
|
||||
typedef std::vector<RankInfo> RankList;
|
||||
|
||||
uint32 GetId(){ return Id; }
|
||||
const uint64& GetLeader(){ return leaderGuid; }
|
||||
std::string GetName(){ return name; }
|
||||
std::string GetMOTD(){ return MOTD; }
|
||||
std::string GetGINFO(){ return GINFO; }
|
||||
|
||||
uint32 GetCreatedYear(){ return CreatedYear; }
|
||||
uint32 GetCreatedMonth(){ return CreatedMonth; }
|
||||
uint32 GetCreatedDay(){ return CreatedDay; }
|
||||
|
||||
uint32 GetEmblemStyle(){ return EmblemStyle; }
|
||||
uint32 GetEmblemColor(){ return EmblemColor; }
|
||||
uint32 GetBorderStyle(){ return BorderStyle; }
|
||||
uint32 GetBorderColor(){ return BorderColor; }
|
||||
uint32 GetBackgroundColor(){ return BackgroundColor; }
|
||||
|
||||
void SetLeader(uint64 guid);
|
||||
bool AddMember(uint64 plGuid, uint32 plRank);
|
||||
void ChangeRank(uint64 guid, uint32 newRank);
|
||||
void DelMember(uint64 guid, bool isDisbanding=false);
|
||||
uint32 GetLowestRank() const { return GetNrRanks()-1; }
|
||||
|
||||
void SetMOTD(std::string motd);
|
||||
void SetGINFO(std::string ginfo);
|
||||
void SetPNOTE(uint64 guid,std::string pnote);
|
||||
void SetOFFNOTE(uint64 guid,std::string offnote);
|
||||
void SetEmblem(uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor, uint32 backgroundColor);
|
||||
|
||||
uint32 GetMemberSize() const { return members.size(); }
|
||||
|
||||
bool LoadGuildFromDB(uint32 GuildId);
|
||||
bool LoadRanksFromDB(uint32 GuildId);
|
||||
bool LoadMembersFromDB(uint32 GuildId);
|
||||
|
||||
bool FillPlayerData(uint64 guid, MemberSlot* memslot);
|
||||
void LoadPlayerStatsByGuid(uint64 guid);
|
||||
|
||||
void BroadcastToGuild(WorldSession *session, std::string msg, uint32 language = LANG_UNIVERSAL);
|
||||
void BroadcastToOfficers(WorldSession *session, std::string msg, uint32 language = LANG_UNIVERSAL);
|
||||
void BroadcastPacketToRank(WorldPacket *packet, uint32 rankId);
|
||||
void BroadcastPacket(WorldPacket *packet);
|
||||
|
||||
void CreateRank(std::string name,uint32 rights);
|
||||
void DelRank();
|
||||
std::string GetRankName(uint32 rankId);
|
||||
uint32 GetRankRights(uint32 rankId);
|
||||
uint32 GetNrRanks() const { return m_ranks.size(); }
|
||||
|
||||
void SetRankName(uint32 rankId, std::string name);
|
||||
void SetRankRights(uint32 rankId, uint32 rights);
|
||||
bool HasRankRight(uint32 rankId, uint32 right)
|
||||
{
|
||||
return ((GetRankRights(rankId) & right) != GR_RIGHT_EMPTY) ? true : false;
|
||||
}
|
||||
|
||||
void Roster(WorldSession *session);
|
||||
void Query(WorldSession *session);
|
||||
|
||||
void UpdateLogoutTime(uint64 guid);
|
||||
// Guild eventlog
|
||||
void LoadGuildEventLogFromDB();
|
||||
void UnloadGuildEventlog();
|
||||
void DisplayGuildEventlog(WorldSession *session);
|
||||
void LogGuildEvent(uint8 EventType, uint32 PlayerGuid1, uint32 PlayerGuid2, uint8 NewRank);
|
||||
void RenumGuildEventlog();
|
||||
|
||||
// ** Guild bank **
|
||||
// Content & item deposit/withdraw
|
||||
void DisplayGuildBankContent(WorldSession *session, uint8 TabId);
|
||||
void DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2 = -1);
|
||||
void DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec const& slots);
|
||||
void DisplayGuildBankMoneyUpdate();
|
||||
|
||||
Item* GetItem(uint8 TabId, uint8 SlotId);
|
||||
uint8 CanStoreItem( uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32 count, Item *pItem, bool swap = false) const;
|
||||
Item* StoreItem( uint8 tab, GuildItemPosCountVec const& pos, Item *pItem );
|
||||
void RemoveItem(uint8 tab, uint8 slot );
|
||||
|
||||
// Tabs
|
||||
void DisplayGuildBankTabsInfo(WorldSession *session);
|
||||
void CreateNewBankTab();
|
||||
void SetGuildBankTabText(uint8 TabId, std::string text);
|
||||
void SendGuildBankTabText(WorldSession *session, uint8 TabId);
|
||||
void SetGuildBankTabInfo(uint8 TabId, std::string name, std::string icon);
|
||||
void CreateBankRightForTab(uint32 rankid, uint8 TabId);
|
||||
const GuildBankTab *GetBankTab(uint8 index) { if(index >= m_TabListMap.size()) return NULL; return m_TabListMap[index]; }
|
||||
const uint8 GetPurchasedTabs() const { return purchased_tabs; }
|
||||
uint32 GetBankRights(uint32 rankId, uint8 TabId) const;
|
||||
bool IsMemberHaveRights(uint32 LowGuid, uint8 TabId,uint32 rights) const;
|
||||
bool CanMemberViewTab(uint32 LowGuid, uint8 TabId) const;
|
||||
// Load/unload
|
||||
void LoadGuildBankFromDB();
|
||||
void UnloadGuildBank();
|
||||
void IncOnlineMemberCount() { ++m_onlinemembers; }
|
||||
// Money deposit/withdraw
|
||||
void SendMoneyInfo(WorldSession *session, uint32 LowGuid);
|
||||
bool MemberMoneyWithdraw(uint32 amount, uint32 LowGuid);
|
||||
uint64 GetGuildBankMoney() { return guildbank_money; }
|
||||
void SetBankMoney(int64 money);
|
||||
// per days
|
||||
bool MemberItemWithdraw(uint8 TabId, uint32 LowGuid);
|
||||
uint32 GetMemberSlotWithdrawRem(uint32 LowGuid, uint8 TabId);
|
||||
uint32 GetMemberMoneyWithdrawRem(uint32 LowGuid);
|
||||
void SetBankMoneyPerDay(uint32 rankId, uint32 money);
|
||||
void SetBankRightsAndSlots(uint32 rankId, uint8 TabId, uint32 right, uint32 SlotPerDay, bool db);
|
||||
uint32 GetBankMoneyPerDay(uint32 rankId);
|
||||
uint32 GetBankSlotPerDay(uint32 rankId, uint8 TabId);
|
||||
// rights per day
|
||||
void LoadBankRightsFromDB(uint32 GuildId);
|
||||
// logs
|
||||
void LoadGuildBankEventLogFromDB();
|
||||
void UnloadGuildBankEventLog();
|
||||
void DisplayGuildBankLogs(WorldSession *session, uint8 TabId);
|
||||
void LogBankEvent(uint8 LogEntry, uint8 TabId, uint32 PlayerGuidLow, uint32 ItemOrMoney, uint8 ItemStackCount=0, uint8 DestTabId=0);
|
||||
void RenumBankLogs();
|
||||
bool AddGBankItemToDB(uint32 GuildId, uint32 BankTab , uint32 BankTabSlot , uint32 GUIDLow, uint32 Entry );
|
||||
|
||||
protected:
|
||||
void AddRank(std::string name,uint32 rights,uint32 money);
|
||||
|
||||
uint32 Id;
|
||||
std::string name;
|
||||
uint64 leaderGuid;
|
||||
std::string MOTD;
|
||||
std::string GINFO;
|
||||
uint32 CreatedYear;
|
||||
uint32 CreatedMonth;
|
||||
uint32 CreatedDay;
|
||||
|
||||
uint32 EmblemStyle;
|
||||
uint32 EmblemColor;
|
||||
uint32 BorderStyle;
|
||||
uint32 BorderColor;
|
||||
uint32 BackgroundColor;
|
||||
|
||||
RankList m_ranks;
|
||||
|
||||
MemberList members;
|
||||
|
||||
typedef std::vector<GuildBankTab*> TabListMap;
|
||||
TabListMap m_TabListMap;
|
||||
|
||||
/** These are actually ordered lists. The first element is the oldest entry.*/
|
||||
typedef std::list<GuildEventlogEntry*> GuildEventlog;
|
||||
typedef std::list<GuildBankEvent*> GuildBankEventLog;
|
||||
GuildEventlog m_GuildEventlog;
|
||||
GuildBankEventLog m_GuildBankEventLog_Money;
|
||||
GuildBankEventLog m_GuildBankEventLog_Item[GUILD_BANK_MAX_TABS];
|
||||
|
||||
bool m_bankloaded;
|
||||
bool m_eventlogloaded;
|
||||
uint32 m_onlinemembers;
|
||||
uint64 guildbank_money;
|
||||
uint8 purchased_tabs;
|
||||
|
||||
uint32 LogMaxGuid;
|
||||
uint32 GuildEventlogMaxGuid;
|
||||
private:
|
||||
// internal common parts for CanStore/StoreItem functions
|
||||
void AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *tab, int32 slot );
|
||||
uint8 _CanStoreItem_InSpecificSlot( uint8 tab, uint8 slot, GuildItemPosCountVec& dest, uint32& count, bool swap, Item *pSrcItem ) const;
|
||||
uint8 _CanStoreItem_InTab( uint8 tab, GuildItemPosCountVec& dest, uint32& count, bool merge, Item *pSrcItem, uint8 skip_slot ) const;
|
||||
Item* _StoreItem( uint8 tab, uint8 slot, Item *pItem, uint32 count, bool clone );
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,86 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "HomeMovementGenerator.h"
|
||||
#include "Creature.h"
|
||||
#include "Traveller.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
void
|
||||
HomeMovementGenerator<Creature>::Initialize(Creature & owner)
|
||||
{
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
void
|
||||
HomeMovementGenerator<Creature>::Reset(Creature &)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
|
||||
{
|
||||
if( !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
owner.GetRespawnCoord(x, y, z);
|
||||
|
||||
CreatureTraveller traveller(owner);
|
||||
|
||||
uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
modifyTravelTime(travel_time);
|
||||
owner.clearUnitState(UNIT_STAT_ALL_STATE);
|
||||
}
|
||||
|
||||
bool
|
||||
HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff)
|
||||
{
|
||||
CreatureTraveller traveller( owner);
|
||||
i_destinationHolder.UpdateTraveller(traveller, time_diff, false);
|
||||
|
||||
if (time_diff > i_travel_timer)
|
||||
{
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
|
||||
// restore orientation of not moving creature at returning to home
|
||||
if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE)
|
||||
{
|
||||
if(CreatureData const* data = objmgr.GetCreatureData(owner.GetDBTableGUIDLow()))
|
||||
{
|
||||
owner.SetOrientation(data->orientation);
|
||||
WorldPacket packet;
|
||||
owner.BuildHeartBeatMsg(&packet);
|
||||
owner.SendMessageToSet(&packet, false);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
i_travel_timer -= time_diff;
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "HomeMovementGenerator.h"
|
||||
#include "Creature.h"
|
||||
#include "Traveller.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
void
|
||||
HomeMovementGenerator<Creature>::Initialize(Creature & owner)
|
||||
{
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
void
|
||||
HomeMovementGenerator<Creature>::Reset(Creature &)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
|
||||
{
|
||||
if( !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
owner.GetRespawnCoord(x, y, z);
|
||||
|
||||
CreatureTraveller traveller(owner);
|
||||
|
||||
uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
modifyTravelTime(travel_time);
|
||||
owner.clearUnitState(UNIT_STAT_ALL_STATE);
|
||||
}
|
||||
|
||||
bool
|
||||
HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32& time_diff)
|
||||
{
|
||||
CreatureTraveller traveller( owner);
|
||||
i_destinationHolder.UpdateTraveller(traveller, time_diff, false);
|
||||
|
||||
if (time_diff > i_travel_timer)
|
||||
{
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
|
||||
// restore orientation of not moving creature at returning to home
|
||||
if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE)
|
||||
{
|
||||
if(CreatureData const* data = objmgr.GetCreatureData(owner.GetDBTableGUIDLow()))
|
||||
{
|
||||
owner.SetOrientation(data->orientation);
|
||||
WorldPacket packet;
|
||||
owner.BuildHeartBeatMsg(&packet);
|
||||
owner.SendMessageToSet(&packet, false);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
i_travel_timer -= time_diff;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+1211
-1211
File diff suppressed because it is too large
Load Diff
+663
-663
File diff suppressed because it is too large
Load Diff
+2479
-2479
File diff suppressed because it is too large
Load Diff
+4009
-4009
File diff suppressed because it is too large
Load Diff
+5466
-5466
File diff suppressed because it is too large
Load Diff
+1766
-1766
File diff suppressed because it is too large
Load Diff
+342
-342
@@ -1,342 +1,342 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "MotionMaster.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "Creature.h"
|
||||
#include "Traveller.h"
|
||||
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
#include "HomeMovementGenerator.h"
|
||||
#include "IdleMovementGenerator.h"
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
inline bool isStatic(MovementGenerator *mv)
|
||||
{
|
||||
return (mv == &si_idleMovement);
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::Initialize()
|
||||
{
|
||||
// clear ALL movement generators (including default)
|
||||
while(!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
|
||||
// set new default movement generator
|
||||
if(i_owner->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
|
||||
push( movement == NULL ? &si_idleMovement : movement );
|
||||
top()->Initialize(*i_owner);
|
||||
}
|
||||
else
|
||||
push(&si_idleMovement);
|
||||
}
|
||||
|
||||
MotionMaster::~MotionMaster()
|
||||
{
|
||||
// clear ALL movement generators (including default)
|
||||
while(!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::UpdateMotion(const uint32 &diff)
|
||||
{
|
||||
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
|
||||
return;
|
||||
assert( !empty() );
|
||||
if (!top()->Update(*i_owner, diff))
|
||||
MovementExpired();
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::Clear(bool reset)
|
||||
{
|
||||
while( !empty() && size() > 1 )
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
assert( !empty() );
|
||||
top()->Reset(*i_owner);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MovementExpired(bool reset)
|
||||
{
|
||||
if( empty() || size() == 1 )
|
||||
return;
|
||||
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
|
||||
if( !isStatic(curr) )
|
||||
delete curr;
|
||||
|
||||
assert( !empty() );
|
||||
while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
{
|
||||
// Should check if target is still valid? If not valid it will crash.
|
||||
curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
delete curr;
|
||||
}
|
||||
if( empty() )
|
||||
Initialize();
|
||||
if (reset) top()->Reset(*i_owner);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveIdle()
|
||||
{
|
||||
if( empty() || !isStatic( top() ) )
|
||||
push( &si_idleMovement );
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveTargetedHome()
|
||||
{
|
||||
if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
|
||||
return;
|
||||
|
||||
Clear(false);
|
||||
|
||||
if(i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID())
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
|
||||
Mutate(new HomeMovementGenerator<Creature>());
|
||||
}
|
||||
else if(i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID())
|
||||
{
|
||||
sLog.outError("Pet or controlled creature (Entry: %u GUID: %u) attempt targeted home",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow() );
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveConfused()
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) move confused", i_owner->GetGUIDLow() );
|
||||
Mutate(new ConfusedMovementGenerator<Player>());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) move confused",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow() );
|
||||
Mutate(new ConfusedMovementGenerator<Creature>());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveChase(Unit* target, float dist, float angle)
|
||||
{
|
||||
// ignore movement request if target not exist
|
||||
if(!target)
|
||||
return;
|
||||
|
||||
i_owner->clearUnitState(UNIT_STAT_FOLLOW);
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) chase to %s (GUID: %u)",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(),
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// ignore movement request if target not exist
|
||||
if(!target)
|
||||
return;
|
||||
|
||||
i_owner->addUnitState(UNIT_STAT_FOLLOW);
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(),
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MovePoint(uint32 id, float x, float y, float z)
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), id, x, y, z );
|
||||
Mutate(new PointMovementGenerator<Player>(id,x,y,z));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(), id, x, y, z );
|
||||
Mutate(new PointMovementGenerator<Creature>(id,x,y,z));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveFleeing(Unit* enemy)
|
||||
{
|
||||
if(!enemy)
|
||||
return;
|
||||
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) flee from %s (GUID: %u)", i_owner->GetGUIDLow(),
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
|
||||
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(),
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
|
||||
Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) taxi to (Path %u node %u)", i_owner->GetGUIDLow(), path, pathnode);
|
||||
FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(path,pathnode);
|
||||
Mutate(mgen);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(), path, pathnode );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveDistract(uint32 timer)
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) distracted (timer: %u)", i_owner->GetGUIDLow(), timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) (timer: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(), timer);
|
||||
}
|
||||
|
||||
DistractMovementGenerator* mgen = new DistractMovementGenerator(timer);
|
||||
Mutate(mgen);
|
||||
}
|
||||
|
||||
void MotionMaster::Mutate(MovementGenerator *m)
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
switch(top()->GetMovementGeneratorType())
|
||||
{
|
||||
// HomeMovement is not that important, delete it if meanwhile a new comes
|
||||
case HOME_MOTION_TYPE:
|
||||
// DistractMovement interrupted by any other movement
|
||||
case DISTRACT_MOTION_TYPE:
|
||||
MovementExpired(false);
|
||||
}
|
||||
}
|
||||
m->Initialize(*i_owner);
|
||||
push(m);
|
||||
}
|
||||
|
||||
void MotionMaster::propagateSpeedChange()
|
||||
{
|
||||
Impl::container_type::iterator it = Impl::c.begin();
|
||||
for ( ;it != end(); ++it)
|
||||
{
|
||||
(*it)->unitSpeedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
|
||||
{
|
||||
if(empty())
|
||||
return IDLE_MOTION_TYPE;
|
||||
|
||||
return top()->GetMovementGeneratorType();
|
||||
}
|
||||
|
||||
bool MotionMaster::GetDestination(float &x, float &y, float &z)
|
||||
{
|
||||
if(empty())
|
||||
return false;
|
||||
|
||||
return top()->GetDestination(x,y,z);
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "MotionMaster.h"
|
||||
#include "CreatureAISelector.h"
|
||||
#include "Creature.h"
|
||||
#include "Traveller.h"
|
||||
|
||||
#include "ConfusedMovementGenerator.h"
|
||||
#include "FleeingMovementGenerator.h"
|
||||
#include "HomeMovementGenerator.h"
|
||||
#include "IdleMovementGenerator.h"
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "WaypointMovementGenerator.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
inline bool isStatic(MovementGenerator *mv)
|
||||
{
|
||||
return (mv == &si_idleMovement);
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::Initialize()
|
||||
{
|
||||
// clear ALL movement generators (including default)
|
||||
while(!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
|
||||
// set new default movement generator
|
||||
if(i_owner->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
MovementGenerator* movement = FactorySelector::selectMovementGenerator((Creature*)i_owner);
|
||||
push( movement == NULL ? &si_idleMovement : movement );
|
||||
top()->Initialize(*i_owner);
|
||||
}
|
||||
else
|
||||
push(&si_idleMovement);
|
||||
}
|
||||
|
||||
MotionMaster::~MotionMaster()
|
||||
{
|
||||
// clear ALL movement generators (including default)
|
||||
while(!empty())
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::UpdateMotion(const uint32 &diff)
|
||||
{
|
||||
if( i_owner->hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED) )
|
||||
return;
|
||||
assert( !empty() );
|
||||
if (!top()->Update(*i_owner, diff))
|
||||
MovementExpired();
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::Clear(bool reset)
|
||||
{
|
||||
while( !empty() && size() > 1 )
|
||||
{
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
if( !isStatic( curr ) )
|
||||
delete curr;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
assert( !empty() );
|
||||
top()->Reset(*i_owner);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MovementExpired(bool reset)
|
||||
{
|
||||
if( empty() || size() == 1 )
|
||||
return;
|
||||
|
||||
MovementGenerator *curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
|
||||
if( !isStatic(curr) )
|
||||
delete curr;
|
||||
|
||||
assert( !empty() );
|
||||
while( !empty() && top()->GetMovementGeneratorType() == TARGETED_MOTION_TYPE )
|
||||
{
|
||||
// Should check if target is still valid? If not valid it will crash.
|
||||
curr = top();
|
||||
curr->Finalize(*i_owner);
|
||||
pop();
|
||||
delete curr;
|
||||
}
|
||||
if( empty() )
|
||||
Initialize();
|
||||
if (reset) top()->Reset(*i_owner);
|
||||
}
|
||||
|
||||
void MotionMaster::MoveIdle()
|
||||
{
|
||||
if( empty() || !isStatic( top() ) )
|
||||
push( &si_idleMovement );
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveTargetedHome()
|
||||
{
|
||||
if(i_owner->hasUnitState(UNIT_STAT_FLEEING))
|
||||
return;
|
||||
|
||||
Clear(false);
|
||||
|
||||
if(i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID())
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
|
||||
Mutate(new HomeMovementGenerator<Creature>());
|
||||
}
|
||||
else if(i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID())
|
||||
{
|
||||
sLog.outError("Pet or controlled creature (Entry: %u GUID: %u) attempt targeted home",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow() );
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveConfused()
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) move confused", i_owner->GetGUIDLow() );
|
||||
Mutate(new ConfusedMovementGenerator<Player>());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) move confused",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow() );
|
||||
Mutate(new ConfusedMovementGenerator<Creature>());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveChase(Unit* target, float dist, float angle)
|
||||
{
|
||||
// ignore movement request if target not exist
|
||||
if(!target)
|
||||
return;
|
||||
|
||||
i_owner->clearUnitState(UNIT_STAT_FOLLOW);
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) chase to %s (GUID: %u)",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(),
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveFollow(Unit* target, float dist, float angle)
|
||||
{
|
||||
Clear();
|
||||
|
||||
// ignore movement request if target not exist
|
||||
if(!target)
|
||||
return;
|
||||
|
||||
i_owner->addUnitState(UNIT_STAT_FOLLOW);
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? i_owner->GetGUIDLow() : ((Creature*)i_owner)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Player>(*target,dist,angle));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(),
|
||||
target->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
target->GetTypeId()==TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
|
||||
Mutate(new TargetedMovementGenerator<Creature>(*target,dist,angle));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MovePoint(uint32 id, float x, float y, float z)
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), id, x, y, z );
|
||||
Mutate(new PointMovementGenerator<Player>(id,x,y,z));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(), id, x, y, z );
|
||||
Mutate(new PointMovementGenerator<Creature>(id,x,y,z));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveFleeing(Unit* enemy)
|
||||
{
|
||||
if(!enemy)
|
||||
return;
|
||||
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) flee from %s (GUID: %u)", i_owner->GetGUIDLow(),
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
|
||||
Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(),
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? "player" : "creature",
|
||||
enemy->GetTypeId()==TYPEID_PLAYER ? enemy->GetGUIDLow() : ((Creature*)enemy)->GetDBTableGUIDLow() );
|
||||
Mutate(new FleeingMovementGenerator<Creature>(enemy->GetGUID()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) taxi to (Path %u node %u)", i_owner->GetGUIDLow(), path, pathnode);
|
||||
FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(path,pathnode);
|
||||
Mutate(mgen);
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(), path, pathnode );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MotionMaster::MoveDistract(uint32 timer)
|
||||
{
|
||||
if(i_owner->GetTypeId()==TYPEID_PLAYER)
|
||||
{
|
||||
DEBUG_LOG("Player (GUID: %u) distracted (timer: %u)", i_owner->GetGUIDLow(), timer);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG("Creature (Entry: %u GUID: %u) (timer: %u)",
|
||||
i_owner->GetEntry(), i_owner->GetGUIDLow(), timer);
|
||||
}
|
||||
|
||||
DistractMovementGenerator* mgen = new DistractMovementGenerator(timer);
|
||||
Mutate(mgen);
|
||||
}
|
||||
|
||||
void MotionMaster::Mutate(MovementGenerator *m)
|
||||
{
|
||||
if (!empty())
|
||||
{
|
||||
switch(top()->GetMovementGeneratorType())
|
||||
{
|
||||
// HomeMovement is not that important, delete it if meanwhile a new comes
|
||||
case HOME_MOTION_TYPE:
|
||||
// DistractMovement interrupted by any other movement
|
||||
case DISTRACT_MOTION_TYPE:
|
||||
MovementExpired(false);
|
||||
}
|
||||
}
|
||||
m->Initialize(*i_owner);
|
||||
push(m);
|
||||
}
|
||||
|
||||
void MotionMaster::propagateSpeedChange()
|
||||
{
|
||||
Impl::container_type::iterator it = Impl::c.begin();
|
||||
for ( ;it != end(); ++it)
|
||||
{
|
||||
(*it)->unitSpeedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
MovementGeneratorType MotionMaster::GetCurrentMovementGeneratorType() const
|
||||
{
|
||||
if(empty())
|
||||
return IDLE_MOTION_TYPE;
|
||||
|
||||
return top()->GetMovementGeneratorType();
|
||||
}
|
||||
|
||||
bool MotionMaster::GetDestination(float &x, float &y, float &z)
|
||||
{
|
||||
if(empty())
|
||||
return false;
|
||||
|
||||
return top()->GetDestination(x,y,z);
|
||||
}
|
||||
|
||||
+826
-826
File diff suppressed because it is too large
Load Diff
+1447
-1447
File diff suppressed because it is too large
Load Diff
+6997
-6997
File diff suppressed because it is too large
Load Diff
+865
-865
File diff suppressed because it is too large
Load Diff
+1750
-1750
File diff suppressed because it is too large
Load Diff
+649
-649
File diff suppressed because it is too large
Load Diff
+936
-936
File diff suppressed because it is too large
Load Diff
+18297
-18297
File diff suppressed because it is too large
Load Diff
+2336
-2336
File diff suppressed because it is too large
Load Diff
@@ -1,76 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
|
||||
//----- Point Movement Generator
|
||||
template<class T>
|
||||
void PointMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
unit.StopMoving();
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
|
||||
|
||||
if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly())
|
||||
unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if(!&unit)
|
||||
return false;
|
||||
|
||||
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(unit);
|
||||
|
||||
i_destinationHolder.UpdateTraveller(traveller, diff, false);
|
||||
|
||||
if(i_destinationHolder.HasArrived())
|
||||
{
|
||||
unit.StopMoving();
|
||||
MovementInform(unit);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void PointMovementGenerator<T>::MovementInform(T &unit)
|
||||
{
|
||||
}
|
||||
|
||||
template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit)
|
||||
{
|
||||
unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
|
||||
}
|
||||
|
||||
template void PointMovementGenerator<Player>::Initialize(Player&);
|
||||
template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &diff);
|
||||
template void PointMovementGenerator<Player>::MovementInform(Player&);
|
||||
|
||||
template void PointMovementGenerator<Creature>::Initialize(Creature&);
|
||||
template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &diff);
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "PointMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
|
||||
//----- Point Movement Generator
|
||||
template<class T>
|
||||
void PointMovementGenerator<T>::Initialize(T &unit)
|
||||
{
|
||||
unit.StopMoving();
|
||||
Traveller<T> traveller(unit);
|
||||
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z);
|
||||
|
||||
if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly())
|
||||
unit.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
|
||||
{
|
||||
if(!&unit)
|
||||
return false;
|
||||
|
||||
if(unit.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(unit);
|
||||
|
||||
i_destinationHolder.UpdateTraveller(traveller, diff, false);
|
||||
|
||||
if(i_destinationHolder.HasArrived())
|
||||
{
|
||||
unit.StopMoving();
|
||||
MovementInform(unit);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void PointMovementGenerator<T>::MovementInform(T &unit)
|
||||
{
|
||||
}
|
||||
|
||||
template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit)
|
||||
{
|
||||
unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
|
||||
}
|
||||
|
||||
template void PointMovementGenerator<Player>::Initialize(Player&);
|
||||
template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &diff);
|
||||
template void PointMovementGenerator<Player>::MovementInform(Player&);
|
||||
|
||||
template void PointMovementGenerator<Creature>::Initialize(Creature&);
|
||||
template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &diff);
|
||||
|
||||
+200
-200
@@ -1,200 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "QuestDef.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
|
||||
Quest::Quest(Field * questRecord)
|
||||
{
|
||||
QuestId = questRecord[0].GetUInt32();
|
||||
QuestMethod = questRecord[1].GetUInt32();
|
||||
ZoneOrSort = questRecord[2].GetInt32();
|
||||
SkillOrClass = questRecord[3].GetInt32();
|
||||
MinLevel = questRecord[4].GetUInt32();
|
||||
QuestLevel = questRecord[5].GetUInt32();
|
||||
Type = questRecord[6].GetUInt32();
|
||||
RequiredRaces = questRecord[7].GetUInt32();
|
||||
RequiredSkillValue = questRecord[8].GetUInt32();
|
||||
RepObjectiveFaction = questRecord[9].GetUInt32();
|
||||
RepObjectiveValue = questRecord[10].GetInt32();
|
||||
RequiredMinRepFaction = questRecord[11].GetUInt32();
|
||||
RequiredMinRepValue = questRecord[12].GetInt32();
|
||||
RequiredMaxRepFaction = questRecord[13].GetUInt32();
|
||||
RequiredMaxRepValue = questRecord[14].GetInt32();
|
||||
SuggestedPlayers = questRecord[15].GetUInt32();
|
||||
LimitTime = questRecord[16].GetUInt32();
|
||||
QuestFlags = questRecord[17].GetUInt16();
|
||||
uint32 SpecialFlags = questRecord[18].GetUInt16();
|
||||
CharTitleId = questRecord[19].GetUInt32();
|
||||
PrevQuestId = questRecord[20].GetInt32();
|
||||
NextQuestId = questRecord[21].GetInt32();
|
||||
ExclusiveGroup = questRecord[22].GetInt32();
|
||||
NextQuestInChain = questRecord[23].GetUInt32();
|
||||
SrcItemId = questRecord[24].GetUInt32();
|
||||
SrcItemCount = questRecord[25].GetUInt32();
|
||||
SrcSpell = questRecord[26].GetUInt32();
|
||||
Title = questRecord[27].GetCppString();
|
||||
Details = questRecord[28].GetCppString();
|
||||
Objectives = questRecord[29].GetCppString();
|
||||
OfferRewardText = questRecord[30].GetCppString();
|
||||
RequestItemsText = questRecord[31].GetCppString();
|
||||
EndText = questRecord[32].GetCppString();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ObjectiveText[i] = questRecord[33+i].GetCppString();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemId[i] = questRecord[37+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemCount[i] = questRecord[41+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceId[i] = questRecord[45+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceCount[i] = questRecord[49+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceRef[i] = questRecord[53+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqSpell[i] = questRecord[65+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
|
||||
RewChoiceItemId[i] = questRecord[69+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
|
||||
RewChoiceItemCount[i] = questRecord[75+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
RewItemId[i] = questRecord[81+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
RewItemCount[i] = questRecord[85+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepFaction[i] = questRecord[89+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepValue[i] = questRecord[94+i].GetInt32();
|
||||
|
||||
RewOrReqMoney = questRecord[99].GetInt32();
|
||||
RewMoneyMaxLevel = questRecord[100].GetUInt32();
|
||||
RewSpell = questRecord[101].GetUInt32();
|
||||
RewSpellCast = questRecord[102].GetUInt32();
|
||||
RewMailTemplateId = questRecord[103].GetUInt32();
|
||||
RewMailDelaySecs = questRecord[104].GetUInt32();
|
||||
PointMapId = questRecord[105].GetUInt32();
|
||||
PointX = questRecord[106].GetFloat();
|
||||
PointY = questRecord[107].GetFloat();
|
||||
PointOpt = questRecord[108].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
DetailsEmote[i] = questRecord[109+i].GetUInt32();
|
||||
|
||||
IncompleteEmote = questRecord[113].GetUInt32();
|
||||
CompleteEmote = questRecord[114].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
OfferRewardEmote[i] = questRecord[115+i].GetInt32();
|
||||
|
||||
QuestStartScript = questRecord[119].GetUInt32();
|
||||
QuestCompleteScript = questRecord[120].GetUInt32();
|
||||
|
||||
QuestFlags |= SpecialFlags << 16;
|
||||
|
||||
m_reqitemscount = 0;
|
||||
m_reqCreatureOrGOcount = 0;
|
||||
m_rewitemscount = 0;
|
||||
m_rewchoiceitemscount = 0;
|
||||
|
||||
for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
|
||||
{
|
||||
if ( ReqItemId[i] )
|
||||
++m_reqitemscount;
|
||||
if ( ReqCreatureOrGOId[i] )
|
||||
++m_reqCreatureOrGOcount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARDS_COUNT; i++)
|
||||
{
|
||||
if ( RewItemId[i] )
|
||||
++m_rewitemscount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
|
||||
{
|
||||
if (RewChoiceItemId[i])
|
||||
++m_rewchoiceitemscount;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Quest::XPValue( Player *pPlayer ) const
|
||||
{
|
||||
if( pPlayer )
|
||||
{
|
||||
if( RewMoneyMaxLevel > 0 )
|
||||
{
|
||||
uint32 pLevel = pPlayer->getLevel();
|
||||
uint32 qLevel = QuestLevel;
|
||||
float fullxp = 0;
|
||||
if (qLevel >= 65)
|
||||
fullxp = RewMoneyMaxLevel / 6.0f;
|
||||
else if (qLevel == 64)
|
||||
fullxp = RewMoneyMaxLevel / 4.8f;
|
||||
else if (qLevel == 63)
|
||||
fullxp = RewMoneyMaxLevel / 3.6f;
|
||||
else if (qLevel == 62)
|
||||
fullxp = RewMoneyMaxLevel / 2.4f;
|
||||
else if (qLevel == 61)
|
||||
fullxp = RewMoneyMaxLevel / 1.2f;
|
||||
else if (qLevel > 0 && qLevel <= 60)
|
||||
fullxp = RewMoneyMaxLevel / 0.6f;
|
||||
|
||||
if( pLevel <= qLevel + 5 )
|
||||
return (uint32)fullxp;
|
||||
else if( pLevel == qLevel + 6 )
|
||||
return (uint32)(fullxp * 0.8f);
|
||||
else if( pLevel == qLevel + 7 )
|
||||
return (uint32)(fullxp * 0.6f);
|
||||
else if( pLevel == qLevel + 8 )
|
||||
return (uint32)(fullxp * 0.4f);
|
||||
else if( pLevel == qLevel + 9 )
|
||||
return (uint32)(fullxp * 0.2f);
|
||||
else
|
||||
return (uint32)(fullxp * 0.1f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Quest::GetRewOrReqMoney() const
|
||||
{
|
||||
if(RewOrReqMoney <=0)
|
||||
return RewOrReqMoney;
|
||||
|
||||
return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY));
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "QuestDef.h"
|
||||
#include "Player.h"
|
||||
#include "World.h"
|
||||
|
||||
Quest::Quest(Field * questRecord)
|
||||
{
|
||||
QuestId = questRecord[0].GetUInt32();
|
||||
QuestMethod = questRecord[1].GetUInt32();
|
||||
ZoneOrSort = questRecord[2].GetInt32();
|
||||
SkillOrClass = questRecord[3].GetInt32();
|
||||
MinLevel = questRecord[4].GetUInt32();
|
||||
QuestLevel = questRecord[5].GetUInt32();
|
||||
Type = questRecord[6].GetUInt32();
|
||||
RequiredRaces = questRecord[7].GetUInt32();
|
||||
RequiredSkillValue = questRecord[8].GetUInt32();
|
||||
RepObjectiveFaction = questRecord[9].GetUInt32();
|
||||
RepObjectiveValue = questRecord[10].GetInt32();
|
||||
RequiredMinRepFaction = questRecord[11].GetUInt32();
|
||||
RequiredMinRepValue = questRecord[12].GetInt32();
|
||||
RequiredMaxRepFaction = questRecord[13].GetUInt32();
|
||||
RequiredMaxRepValue = questRecord[14].GetInt32();
|
||||
SuggestedPlayers = questRecord[15].GetUInt32();
|
||||
LimitTime = questRecord[16].GetUInt32();
|
||||
QuestFlags = questRecord[17].GetUInt16();
|
||||
uint32 SpecialFlags = questRecord[18].GetUInt16();
|
||||
CharTitleId = questRecord[19].GetUInt32();
|
||||
PrevQuestId = questRecord[20].GetInt32();
|
||||
NextQuestId = questRecord[21].GetInt32();
|
||||
ExclusiveGroup = questRecord[22].GetInt32();
|
||||
NextQuestInChain = questRecord[23].GetUInt32();
|
||||
SrcItemId = questRecord[24].GetUInt32();
|
||||
SrcItemCount = questRecord[25].GetUInt32();
|
||||
SrcSpell = questRecord[26].GetUInt32();
|
||||
Title = questRecord[27].GetCppString();
|
||||
Details = questRecord[28].GetCppString();
|
||||
Objectives = questRecord[29].GetCppString();
|
||||
OfferRewardText = questRecord[30].GetCppString();
|
||||
RequestItemsText = questRecord[31].GetCppString();
|
||||
EndText = questRecord[32].GetCppString();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ObjectiveText[i] = questRecord[33+i].GetCppString();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemId[i] = questRecord[37+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqItemCount[i] = questRecord[41+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceId[i] = questRecord[45+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceCount[i] = questRecord[49+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
|
||||
ReqSourceRef[i] = questRecord[53+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
|
||||
ReqSpell[i] = questRecord[65+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
|
||||
RewChoiceItemId[i] = questRecord[69+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
|
||||
RewChoiceItemCount[i] = questRecord[75+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
RewItemId[i] = questRecord[81+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
|
||||
RewItemCount[i] = questRecord[85+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepFaction[i] = questRecord[89+i].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
|
||||
RewRepValue[i] = questRecord[94+i].GetInt32();
|
||||
|
||||
RewOrReqMoney = questRecord[99].GetInt32();
|
||||
RewMoneyMaxLevel = questRecord[100].GetUInt32();
|
||||
RewSpell = questRecord[101].GetUInt32();
|
||||
RewSpellCast = questRecord[102].GetUInt32();
|
||||
RewMailTemplateId = questRecord[103].GetUInt32();
|
||||
RewMailDelaySecs = questRecord[104].GetUInt32();
|
||||
PointMapId = questRecord[105].GetUInt32();
|
||||
PointX = questRecord[106].GetFloat();
|
||||
PointY = questRecord[107].GetFloat();
|
||||
PointOpt = questRecord[108].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
DetailsEmote[i] = questRecord[109+i].GetUInt32();
|
||||
|
||||
IncompleteEmote = questRecord[113].GetUInt32();
|
||||
CompleteEmote = questRecord[114].GetUInt32();
|
||||
|
||||
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
|
||||
OfferRewardEmote[i] = questRecord[115+i].GetInt32();
|
||||
|
||||
QuestStartScript = questRecord[119].GetUInt32();
|
||||
QuestCompleteScript = questRecord[120].GetUInt32();
|
||||
|
||||
QuestFlags |= SpecialFlags << 16;
|
||||
|
||||
m_reqitemscount = 0;
|
||||
m_reqCreatureOrGOcount = 0;
|
||||
m_rewitemscount = 0;
|
||||
m_rewchoiceitemscount = 0;
|
||||
|
||||
for (int i=0; i < QUEST_OBJECTIVES_COUNT; i++)
|
||||
{
|
||||
if ( ReqItemId[i] )
|
||||
++m_reqitemscount;
|
||||
if ( ReqCreatureOrGOId[i] )
|
||||
++m_reqCreatureOrGOcount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARDS_COUNT; i++)
|
||||
{
|
||||
if ( RewItemId[i] )
|
||||
++m_rewitemscount;
|
||||
}
|
||||
|
||||
for (int i=0; i < QUEST_REWARD_CHOICES_COUNT; i++)
|
||||
{
|
||||
if (RewChoiceItemId[i])
|
||||
++m_rewchoiceitemscount;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Quest::XPValue( Player *pPlayer ) const
|
||||
{
|
||||
if( pPlayer )
|
||||
{
|
||||
if( RewMoneyMaxLevel > 0 )
|
||||
{
|
||||
uint32 pLevel = pPlayer->getLevel();
|
||||
uint32 qLevel = QuestLevel;
|
||||
float fullxp = 0;
|
||||
if (qLevel >= 65)
|
||||
fullxp = RewMoneyMaxLevel / 6.0f;
|
||||
else if (qLevel == 64)
|
||||
fullxp = RewMoneyMaxLevel / 4.8f;
|
||||
else if (qLevel == 63)
|
||||
fullxp = RewMoneyMaxLevel / 3.6f;
|
||||
else if (qLevel == 62)
|
||||
fullxp = RewMoneyMaxLevel / 2.4f;
|
||||
else if (qLevel == 61)
|
||||
fullxp = RewMoneyMaxLevel / 1.2f;
|
||||
else if (qLevel > 0 && qLevel <= 60)
|
||||
fullxp = RewMoneyMaxLevel / 0.6f;
|
||||
|
||||
if( pLevel <= qLevel + 5 )
|
||||
return (uint32)fullxp;
|
||||
else if( pLevel == qLevel + 6 )
|
||||
return (uint32)(fullxp * 0.8f);
|
||||
else if( pLevel == qLevel + 7 )
|
||||
return (uint32)(fullxp * 0.6f);
|
||||
else if( pLevel == qLevel + 8 )
|
||||
return (uint32)(fullxp * 0.4f);
|
||||
else if( pLevel == qLevel + 9 )
|
||||
return (uint32)(fullxp * 0.2f);
|
||||
else
|
||||
return (uint32)(fullxp * 0.1f);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Quest::GetRewOrReqMoney() const
|
||||
{
|
||||
if(RewOrReqMoney <=0)
|
||||
return RewOrReqMoney;
|
||||
|
||||
return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY));
|
||||
}
|
||||
|
||||
+332
-332
@@ -1,332 +1,332 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_QUEST_H
|
||||
#define MANGOSSERVER_QUEST_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Player;
|
||||
|
||||
class ObjectMgr;
|
||||
|
||||
#define MAX_QUEST_LOG_SIZE 25
|
||||
|
||||
#define QUEST_OBJECTIVES_COUNT 4
|
||||
#define QUEST_SOURCE_ITEM_IDS_COUNT 4
|
||||
#define QUEST_REWARD_CHOICES_COUNT 6
|
||||
#define QUEST_REWARDS_COUNT 4
|
||||
#define QUEST_DEPLINK_COUNT 10
|
||||
#define QUEST_REPUTATIONS_COUNT 5
|
||||
#define QUEST_EMOTE_COUNT 4
|
||||
|
||||
enum QuestFailedReasons
|
||||
{
|
||||
INVALIDREASON_DONT_HAVE_REQ = 0,
|
||||
INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest.
|
||||
INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race.
|
||||
INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest.
|
||||
INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time.
|
||||
INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest
|
||||
INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account.
|
||||
INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest
|
||||
INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage.
|
||||
INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest.
|
||||
INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today
|
||||
INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time
|
||||
};
|
||||
|
||||
enum QuestShareMessages
|
||||
{
|
||||
QUEST_PARTY_MSG_SHARING_QUEST = 0,
|
||||
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
|
||||
QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
|
||||
QUEST_PARTY_MSG_REFUSE_QUEST = 3,
|
||||
QUEST_PARTY_MSG_TOO_FAR = 4,
|
||||
QUEST_PARTY_MSG_BUSY = 5,
|
||||
QUEST_PARTY_MSG_LOG_FULL = 6,
|
||||
QUEST_PARTY_MSG_HAVE_QUEST = 7,
|
||||
QUEST_PARTY_MSG_FINISH_QUEST = 8,
|
||||
};
|
||||
|
||||
enum __QuestTradeSkill
|
||||
{
|
||||
QUEST_TRSKILL_NONE = 0,
|
||||
QUEST_TRSKILL_ALCHEMY = 1,
|
||||
QUEST_TRSKILL_BLACKSMITHING = 2,
|
||||
QUEST_TRSKILL_COOKING = 3,
|
||||
QUEST_TRSKILL_ENCHANTING = 4,
|
||||
QUEST_TRSKILL_ENGINEERING = 5,
|
||||
QUEST_TRSKILL_FIRSTAID = 6,
|
||||
QUEST_TRSKILL_HERBALISM = 7,
|
||||
QUEST_TRSKILL_LEATHERWORKING = 8,
|
||||
QUEST_TRSKILL_POISONS = 9,
|
||||
QUEST_TRSKILL_TAILORING = 10,
|
||||
QUEST_TRSKILL_MINING = 11,
|
||||
QUEST_TRSKILL_FISHING = 12,
|
||||
QUEST_TRSKILL_SKINNING = 13,
|
||||
QUEST_TRSKILL_JEWELCRAFTING = 14,
|
||||
};
|
||||
|
||||
enum QuestStatus
|
||||
{
|
||||
QUEST_STATUS_NONE = 0,
|
||||
QUEST_STATUS_COMPLETE = 1,
|
||||
QUEST_STATUS_UNAVAILABLE = 2,
|
||||
QUEST_STATUS_INCOMPLETE = 3,
|
||||
QUEST_STATUS_AVAILABLE = 4,
|
||||
MAX_QUEST_STATUS
|
||||
};
|
||||
|
||||
enum __QuestGiverStatus
|
||||
{
|
||||
DIALOG_STATUS_NONE = 0,
|
||||
DIALOG_STATUS_UNAVAILABLE = 1,
|
||||
DIALOG_STATUS_CHAT = 2,
|
||||
DIALOG_STATUS_INCOMPLETE = 3,
|
||||
DIALOG_STATUS_REWARD_REP = 4,
|
||||
DIALOG_STATUS_AVAILABLE_REP = 5,
|
||||
DIALOG_STATUS_AVAILABLE = 6,
|
||||
DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap
|
||||
DIALOG_STATUS_REWARD = 8 // yellow dot on minimap
|
||||
};
|
||||
|
||||
enum __QuestFlags
|
||||
{
|
||||
// Flags used at server and sended to client
|
||||
QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently
|
||||
QUEST_FLAGS_PARTY_ACCEPT = 2, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
|
||||
QUEST_FLAGS_EXPLORATION = 4, // Not used currently
|
||||
QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest()
|
||||
//QUEST_FLAGS_NONE2 = 16, // Not used currently
|
||||
QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content
|
||||
QUEST_FLAGS_RAID = 64, // Not used currently
|
||||
QUEST_FLAGS_TBC = 128, // Not used currently: Available if TBC expension enabled only
|
||||
QUEST_FLAGS_UNK2 = 256, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs
|
||||
QUEST_FLAGS_HIDDEN_REWARDS = 512, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
|
||||
QUEST_FLAGS_AUTO_REWARDED = 1024, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
|
||||
QUEST_FLAGS_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests
|
||||
QUEST_FLAGS_DAILY = 4096, // Used to know quest is Daily one
|
||||
|
||||
// Mangos flags for set SpecialFlags in DB if required but used only at server
|
||||
QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB
|
||||
QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if reequired area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL)
|
||||
QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
|
||||
|
||||
// Mangos flags for internal use only
|
||||
QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // Internal flag computed only
|
||||
QUEST_MANGOS_FLAGS_SPEAKTO = 0x080000, // Internal flag computed only
|
||||
QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x100000, // Internal flag computed only
|
||||
QUEST_MANGOS_FLAGS_TIMED = 0x200000, // Internal flag computed only
|
||||
};
|
||||
|
||||
struct QuestLocale
|
||||
{
|
||||
QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); }
|
||||
|
||||
std::vector<std::string> Title;
|
||||
std::vector<std::string> Details;
|
||||
std::vector<std::string> Objectives;
|
||||
std::vector<std::string> OfferRewardText;
|
||||
std::vector<std::string> RequestItemsText;
|
||||
std::vector<std::string> EndText;
|
||||
std::vector< std::vector<std::string> > ObjectiveText;
|
||||
};
|
||||
|
||||
// This Quest class provides a convenient way to access a few pretotaled (cached) quest details,
|
||||
// all base quest information, and any utility functions such as generating the amount of
|
||||
// xp to give
|
||||
class Quest
|
||||
{
|
||||
friend class ObjectMgr;
|
||||
public:
|
||||
Quest(Field * questRecord);
|
||||
uint32 XPValue( Player *pPlayer ) const;
|
||||
|
||||
bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; }
|
||||
void SetFlag( uint32 flag ) { QuestFlags |= flag; }
|
||||
|
||||
// table data accessors:
|
||||
uint32 GetQuestId() const { return QuestId; }
|
||||
uint32 GetQuestMethod() const { return QuestMethod; }
|
||||
int32 GetZoneOrSort() const { return ZoneOrSort; }
|
||||
int32 GetSkillOrClass() const { return SkillOrClass; }
|
||||
uint32 GetMinLevel() const { return MinLevel; }
|
||||
uint32 GetQuestLevel() const { return QuestLevel; }
|
||||
uint32 GetType() const { return Type; }
|
||||
uint32 GetRequiredRaces() const { return RequiredRaces; }
|
||||
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
|
||||
uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; }
|
||||
int32 GetRepObjectiveValue() const { return RepObjectiveValue; }
|
||||
uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }
|
||||
int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }
|
||||
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
|
||||
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
|
||||
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
|
||||
uint32 GetLimitTime() const { return LimitTime; }
|
||||
int32 GetPrevQuestId() const { return PrevQuestId; }
|
||||
int32 GetNextQuestId() const { return NextQuestId; }
|
||||
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
|
||||
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
|
||||
uint32 GetCharTitleId() const { return CharTitleId; }
|
||||
uint32 GetSrcItemId() const { return SrcItemId; }
|
||||
uint32 GetSrcItemCount() const { return SrcItemCount; }
|
||||
uint32 GetSrcSpell() const { return SrcSpell; }
|
||||
std::string GetTitle() const { return Title; }
|
||||
std::string GetDetails() const { return Details; }
|
||||
std::string GetObjectives() const { return Objectives; }
|
||||
std::string GetOfferRewardText() const { return OfferRewardText; }
|
||||
std::string GetRequestItemsText() const { return RequestItemsText; }
|
||||
std::string GetEndText() const { return EndText; }
|
||||
int32 GetRewOrReqMoney() const;
|
||||
uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; }
|
||||
// use in XP calculation at client
|
||||
uint32 GetRewSpell() const { return RewSpell; }
|
||||
uint32 GetRewSpellCast() const { return RewSpellCast; }
|
||||
uint32 GetRewMailTemplateId() const { return RewMailTemplateId; }
|
||||
uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; }
|
||||
uint32 GetPointMapId() const { return PointMapId; }
|
||||
float GetPointX() const { return PointX; }
|
||||
float GetPointY() const { return PointY; }
|
||||
uint32 GetPointOpt() const { return PointOpt; }
|
||||
uint32 GetIncompleteEmote() const { return IncompleteEmote; }
|
||||
uint32 GetCompleteEmote() const { return CompleteEmote; }
|
||||
uint32 GetQuestStartScript() const { return QuestStartScript; }
|
||||
uint32 GetQuestCompleteScript() const { return QuestCompleteScript; }
|
||||
bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; }
|
||||
bool IsAutoComplete() const { return QuestMethod ? false : true; }
|
||||
uint32 GetFlags() const { return QuestFlags; }
|
||||
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
|
||||
|
||||
// multiple values
|
||||
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemId[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
|
||||
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSpell[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewItemId[QUEST_REWARDS_COUNT];
|
||||
uint32 RewItemCount[QUEST_REWARDS_COUNT];
|
||||
uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT];
|
||||
int32 RewRepValue[QUEST_REPUTATIONS_COUNT];
|
||||
uint32 DetailsEmote[QUEST_EMOTE_COUNT];
|
||||
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
|
||||
|
||||
uint32 GetReqItemsCount() const { return m_reqitemscount; }
|
||||
uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; }
|
||||
uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; }
|
||||
uint32 GetRewItemsCount() const { return m_rewitemscount; }
|
||||
|
||||
typedef std::vector<int32> PrevQuests;
|
||||
PrevQuests prevQuests;
|
||||
typedef std::vector<uint32> PrevChainQuests;
|
||||
PrevChainQuests prevChainQuests;
|
||||
|
||||
// cached data
|
||||
private:
|
||||
uint32 m_reqitemscount;
|
||||
uint32 m_reqCreatureOrGOcount;
|
||||
uint32 m_rewchoiceitemscount;
|
||||
uint32 m_rewitemscount;
|
||||
|
||||
// table data
|
||||
protected:
|
||||
uint32 QuestId;
|
||||
uint32 QuestMethod;
|
||||
int32 ZoneOrSort;
|
||||
int32 SkillOrClass;
|
||||
uint32 MinLevel;
|
||||
uint32 QuestLevel;
|
||||
uint32 Type;
|
||||
uint32 RequiredRaces;
|
||||
uint32 RequiredSkillValue;
|
||||
uint32 RepObjectiveFaction;
|
||||
int32 RepObjectiveValue;
|
||||
uint32 RequiredMinRepFaction;
|
||||
int32 RequiredMinRepValue;
|
||||
uint32 RequiredMaxRepFaction;
|
||||
int32 RequiredMaxRepValue;
|
||||
uint32 SuggestedPlayers;
|
||||
uint32 LimitTime;
|
||||
uint32 QuestFlags;
|
||||
uint32 CharTitleId;
|
||||
int32 PrevQuestId;
|
||||
int32 NextQuestId;
|
||||
int32 ExclusiveGroup;
|
||||
uint32 NextQuestInChain;
|
||||
uint32 SrcItemId;
|
||||
uint32 SrcItemCount;
|
||||
uint32 SrcSpell;
|
||||
std::string Title;
|
||||
std::string Details;
|
||||
std::string Objectives;
|
||||
std::string OfferRewardText;
|
||||
std::string RequestItemsText;
|
||||
std::string EndText;
|
||||
int32 RewOrReqMoney;
|
||||
uint32 RewMoneyMaxLevel;
|
||||
uint32 RewSpell;
|
||||
uint32 RewSpellCast;
|
||||
uint32 RewMailTemplateId;
|
||||
uint32 RewMailDelaySecs;
|
||||
uint32 PointMapId;
|
||||
float PointX;
|
||||
float PointY;
|
||||
uint32 PointOpt;
|
||||
uint32 IncompleteEmote;
|
||||
uint32 CompleteEmote;
|
||||
uint32 QuestStartScript;
|
||||
uint32 QuestCompleteScript;
|
||||
};
|
||||
|
||||
enum QuestUpdateState
|
||||
{
|
||||
QUEST_UNCHANGED = 0,
|
||||
QUEST_CHANGED = 1,
|
||||
QUEST_NEW = 2
|
||||
};
|
||||
|
||||
struct QuestStatusData
|
||||
{
|
||||
QuestStatusData()
|
||||
: m_status(QUEST_STATUS_NONE),m_rewarded(false),
|
||||
m_explored(false), m_timer(0), uState(QUEST_NEW)
|
||||
{
|
||||
memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
|
||||
memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
|
||||
}
|
||||
|
||||
QuestStatus m_status;
|
||||
bool m_rewarded;
|
||||
bool m_explored;
|
||||
uint32 m_timer;
|
||||
QuestUpdateState uState;
|
||||
|
||||
uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
};
|
||||
#endif
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MANGOSSERVER_QUEST_H
|
||||
#define MANGOSSERVER_QUEST_H
|
||||
|
||||
#include "Platform/Define.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Player;
|
||||
|
||||
class ObjectMgr;
|
||||
|
||||
#define MAX_QUEST_LOG_SIZE 25
|
||||
|
||||
#define QUEST_OBJECTIVES_COUNT 4
|
||||
#define QUEST_SOURCE_ITEM_IDS_COUNT 4
|
||||
#define QUEST_REWARD_CHOICES_COUNT 6
|
||||
#define QUEST_REWARDS_COUNT 4
|
||||
#define QUEST_DEPLINK_COUNT 10
|
||||
#define QUEST_REPUTATIONS_COUNT 5
|
||||
#define QUEST_EMOTE_COUNT 4
|
||||
|
||||
enum QuestFailedReasons
|
||||
{
|
||||
INVALIDREASON_DONT_HAVE_REQ = 0,
|
||||
INVALIDREASON_QUEST_FAILED_LOW_LEVEL = 1, //You are not high enough level for that quest.
|
||||
INVALIDREASON_QUEST_FAILED_WRONG_RACE = 6, //That quest is not available to your race.
|
||||
INVALIDREASON_QUEST_ALREADY_DONE = 7, //You have completed that quest.
|
||||
INVALIDREASON_QUEST_ONLY_ONE_TIMED = 12, //You can only be on one timed quest at a time.
|
||||
INVALIDREASON_QUEST_ALREADY_ON = 13, //You are already on that quest
|
||||
INVALIDREASON_QUEST_FAILED_EXPANSION = 16, //This quest requires an expansion enabled account.
|
||||
INVALIDREASON_QUEST_ALREADY_ON2 = 18, //You are already on that quest
|
||||
INVALIDREASON_QUEST_FAILED_MISSING_ITEMS = 21, //You don't have the required items with you. Check storage.
|
||||
INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23, //You don't have enough money for that quest.
|
||||
INVALIDREASON_DAILY_QUESTS_REMAINING = 26, //You have already completed 10 daily quests today
|
||||
INVALIDREASON_QUEST_FAILED_CAIS = 27, //You cannot complete quests once you have reached tired time
|
||||
};
|
||||
|
||||
enum QuestShareMessages
|
||||
{
|
||||
QUEST_PARTY_MSG_SHARING_QUEST = 0,
|
||||
QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1,
|
||||
QUEST_PARTY_MSG_ACCEPT_QUEST = 2,
|
||||
QUEST_PARTY_MSG_REFUSE_QUEST = 3,
|
||||
QUEST_PARTY_MSG_TOO_FAR = 4,
|
||||
QUEST_PARTY_MSG_BUSY = 5,
|
||||
QUEST_PARTY_MSG_LOG_FULL = 6,
|
||||
QUEST_PARTY_MSG_HAVE_QUEST = 7,
|
||||
QUEST_PARTY_MSG_FINISH_QUEST = 8,
|
||||
};
|
||||
|
||||
enum __QuestTradeSkill
|
||||
{
|
||||
QUEST_TRSKILL_NONE = 0,
|
||||
QUEST_TRSKILL_ALCHEMY = 1,
|
||||
QUEST_TRSKILL_BLACKSMITHING = 2,
|
||||
QUEST_TRSKILL_COOKING = 3,
|
||||
QUEST_TRSKILL_ENCHANTING = 4,
|
||||
QUEST_TRSKILL_ENGINEERING = 5,
|
||||
QUEST_TRSKILL_FIRSTAID = 6,
|
||||
QUEST_TRSKILL_HERBALISM = 7,
|
||||
QUEST_TRSKILL_LEATHERWORKING = 8,
|
||||
QUEST_TRSKILL_POISONS = 9,
|
||||
QUEST_TRSKILL_TAILORING = 10,
|
||||
QUEST_TRSKILL_MINING = 11,
|
||||
QUEST_TRSKILL_FISHING = 12,
|
||||
QUEST_TRSKILL_SKINNING = 13,
|
||||
QUEST_TRSKILL_JEWELCRAFTING = 14,
|
||||
};
|
||||
|
||||
enum QuestStatus
|
||||
{
|
||||
QUEST_STATUS_NONE = 0,
|
||||
QUEST_STATUS_COMPLETE = 1,
|
||||
QUEST_STATUS_UNAVAILABLE = 2,
|
||||
QUEST_STATUS_INCOMPLETE = 3,
|
||||
QUEST_STATUS_AVAILABLE = 4,
|
||||
MAX_QUEST_STATUS
|
||||
};
|
||||
|
||||
enum __QuestGiverStatus
|
||||
{
|
||||
DIALOG_STATUS_NONE = 0,
|
||||
DIALOG_STATUS_UNAVAILABLE = 1,
|
||||
DIALOG_STATUS_CHAT = 2,
|
||||
DIALOG_STATUS_INCOMPLETE = 3,
|
||||
DIALOG_STATUS_REWARD_REP = 4,
|
||||
DIALOG_STATUS_AVAILABLE_REP = 5,
|
||||
DIALOG_STATUS_AVAILABLE = 6,
|
||||
DIALOG_STATUS_REWARD2 = 7, // not yellow dot on minimap
|
||||
DIALOG_STATUS_REWARD = 8 // yellow dot on minimap
|
||||
};
|
||||
|
||||
enum __QuestFlags
|
||||
{
|
||||
// Flags used at server and sended to client
|
||||
QUEST_FLAGS_STAY_ALIVE = 1, // Not used currently
|
||||
QUEST_FLAGS_PARTY_ACCEPT = 2, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
|
||||
QUEST_FLAGS_EXPLORATION = 4, // Not used currently
|
||||
QUEST_FLAGS_SHARABLE = 8, // Can be shared: Player::CanShareQuest()
|
||||
//QUEST_FLAGS_NONE2 = 16, // Not used currently
|
||||
QUEST_FLAGS_EPIC = 32, // Not used currently: Unsure of content
|
||||
QUEST_FLAGS_RAID = 64, // Not used currently
|
||||
QUEST_FLAGS_TBC = 128, // Not used currently: Available if TBC expension enabled only
|
||||
QUEST_FLAGS_UNK2 = 256, // Not used currently: _DELIVER_MORE Quest needs more than normal _q-item_ drops from mobs
|
||||
QUEST_FLAGS_HIDDEN_REWARDS = 512, // Items and money rewarded only sent in SMSG_QUESTGIVER_OFFER_REWARD (not in SMSG_QUESTGIVER_QUEST_DETAILS or in client quest log(SMSG_QUEST_QUERY_RESPONSE))
|
||||
QUEST_FLAGS_AUTO_REWARDED = 1024, // These quests are automatically rewarded on quest complete and they will never appear in quest log client side.
|
||||
QUEST_FLAGS_TBC_RACES = 2048, // Not used currently: Bloodelf/draenei starting zone quests
|
||||
QUEST_FLAGS_DAILY = 4096, // Used to know quest is Daily one
|
||||
|
||||
// Mangos flags for set SpecialFlags in DB if required but used only at server
|
||||
QUEST_MANGOS_FLAGS_REPEATABLE = 0x010000, // Set by 1 in SpecialFlags from DB
|
||||
QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT = 0x020000, // Set by 2 in SpecialFlags from DB (if reequired area explore, spell SPELL_EFFECT_QUEST_COMPLETE casting, table `*_script` command SCRIPT_COMMAND_QUEST_EXPLORED use, set from script DLL)
|
||||
QUEST_MANGOS_FLAGS_DB_ALLOWED = 0xFFFF | QUEST_MANGOS_FLAGS_REPEATABLE | QUEST_MANGOS_FLAGS_EXPLORATION_OR_EVENT,
|
||||
|
||||
// Mangos flags for internal use only
|
||||
QUEST_MANGOS_FLAGS_DELIVER = 0x040000, // Internal flag computed only
|
||||
QUEST_MANGOS_FLAGS_SPEAKTO = 0x080000, // Internal flag computed only
|
||||
QUEST_MANGOS_FLAGS_KILL_OR_CAST = 0x100000, // Internal flag computed only
|
||||
QUEST_MANGOS_FLAGS_TIMED = 0x200000, // Internal flag computed only
|
||||
};
|
||||
|
||||
struct QuestLocale
|
||||
{
|
||||
QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); }
|
||||
|
||||
std::vector<std::string> Title;
|
||||
std::vector<std::string> Details;
|
||||
std::vector<std::string> Objectives;
|
||||
std::vector<std::string> OfferRewardText;
|
||||
std::vector<std::string> RequestItemsText;
|
||||
std::vector<std::string> EndText;
|
||||
std::vector< std::vector<std::string> > ObjectiveText;
|
||||
};
|
||||
|
||||
// This Quest class provides a convenient way to access a few pretotaled (cached) quest details,
|
||||
// all base quest information, and any utility functions such as generating the amount of
|
||||
// xp to give
|
||||
class Quest
|
||||
{
|
||||
friend class ObjectMgr;
|
||||
public:
|
||||
Quest(Field * questRecord);
|
||||
uint32 XPValue( Player *pPlayer ) const;
|
||||
|
||||
bool HasFlag( uint32 flag ) const { return ( QuestFlags & flag ) != 0; }
|
||||
void SetFlag( uint32 flag ) { QuestFlags |= flag; }
|
||||
|
||||
// table data accessors:
|
||||
uint32 GetQuestId() const { return QuestId; }
|
||||
uint32 GetQuestMethod() const { return QuestMethod; }
|
||||
int32 GetZoneOrSort() const { return ZoneOrSort; }
|
||||
int32 GetSkillOrClass() const { return SkillOrClass; }
|
||||
uint32 GetMinLevel() const { return MinLevel; }
|
||||
uint32 GetQuestLevel() const { return QuestLevel; }
|
||||
uint32 GetType() const { return Type; }
|
||||
uint32 GetRequiredRaces() const { return RequiredRaces; }
|
||||
uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
|
||||
uint32 GetRepObjectiveFaction() const { return RepObjectiveFaction; }
|
||||
int32 GetRepObjectiveValue() const { return RepObjectiveValue; }
|
||||
uint32 GetRequiredMinRepFaction() const { return RequiredMinRepFaction; }
|
||||
int32 GetRequiredMinRepValue() const { return RequiredMinRepValue; }
|
||||
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
|
||||
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
|
||||
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
|
||||
uint32 GetLimitTime() const { return LimitTime; }
|
||||
int32 GetPrevQuestId() const { return PrevQuestId; }
|
||||
int32 GetNextQuestId() const { return NextQuestId; }
|
||||
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
|
||||
uint32 GetNextQuestInChain() const { return NextQuestInChain; }
|
||||
uint32 GetCharTitleId() const { return CharTitleId; }
|
||||
uint32 GetSrcItemId() const { return SrcItemId; }
|
||||
uint32 GetSrcItemCount() const { return SrcItemCount; }
|
||||
uint32 GetSrcSpell() const { return SrcSpell; }
|
||||
std::string GetTitle() const { return Title; }
|
||||
std::string GetDetails() const { return Details; }
|
||||
std::string GetObjectives() const { return Objectives; }
|
||||
std::string GetOfferRewardText() const { return OfferRewardText; }
|
||||
std::string GetRequestItemsText() const { return RequestItemsText; }
|
||||
std::string GetEndText() const { return EndText; }
|
||||
int32 GetRewOrReqMoney() const;
|
||||
uint32 GetRewMoneyMaxLevel() const { return RewMoneyMaxLevel; }
|
||||
// use in XP calculation at client
|
||||
uint32 GetRewSpell() const { return RewSpell; }
|
||||
uint32 GetRewSpellCast() const { return RewSpellCast; }
|
||||
uint32 GetRewMailTemplateId() const { return RewMailTemplateId; }
|
||||
uint32 GetRewMailDelaySecs() const { return RewMailDelaySecs; }
|
||||
uint32 GetPointMapId() const { return PointMapId; }
|
||||
float GetPointX() const { return PointX; }
|
||||
float GetPointY() const { return PointY; }
|
||||
uint32 GetPointOpt() const { return PointOpt; }
|
||||
uint32 GetIncompleteEmote() const { return IncompleteEmote; }
|
||||
uint32 GetCompleteEmote() const { return CompleteEmote; }
|
||||
uint32 GetQuestStartScript() const { return QuestStartScript; }
|
||||
uint32 GetQuestCompleteScript() const { return QuestCompleteScript; }
|
||||
bool IsRepeatable() const { return QuestFlags & QUEST_MANGOS_FLAGS_REPEATABLE; }
|
||||
bool IsAutoComplete() const { return QuestMethod ? false : true; }
|
||||
uint32 GetFlags() const { return QuestFlags; }
|
||||
bool IsDaily() const { return QuestFlags & QUEST_FLAGS_DAILY; }
|
||||
|
||||
// multiple values
|
||||
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemId[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqItemCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSourceId[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceCount[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
uint32 ReqSourceRef[QUEST_SOURCE_ITEM_IDS_COUNT];
|
||||
int32 ReqCreatureOrGOId[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
|
||||
uint32 ReqCreatureOrGOCount[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 ReqSpell[QUEST_OBJECTIVES_COUNT];
|
||||
uint32 RewChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewChoiceItemCount[QUEST_REWARD_CHOICES_COUNT];
|
||||
uint32 RewItemId[QUEST_REWARDS_COUNT];
|
||||
uint32 RewItemCount[QUEST_REWARDS_COUNT];
|
||||
uint32 RewRepFaction[QUEST_REPUTATIONS_COUNT];
|
||||
int32 RewRepValue[QUEST_REPUTATIONS_COUNT];
|
||||
uint32 DetailsEmote[QUEST_EMOTE_COUNT];
|
||||
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
|
||||
|
||||
uint32 GetReqItemsCount() const { return m_reqitemscount; }
|
||||
uint32 GetReqCreatureOrGOcount() const { return m_reqCreatureOrGOcount; }
|
||||
uint32 GetRewChoiceItemsCount() const { return m_rewchoiceitemscount; }
|
||||
uint32 GetRewItemsCount() const { return m_rewitemscount; }
|
||||
|
||||
typedef std::vector<int32> PrevQuests;
|
||||
PrevQuests prevQuests;
|
||||
typedef std::vector<uint32> PrevChainQuests;
|
||||
PrevChainQuests prevChainQuests;
|
||||
|
||||
// cached data
|
||||
private:
|
||||
uint32 m_reqitemscount;
|
||||
uint32 m_reqCreatureOrGOcount;
|
||||
uint32 m_rewchoiceitemscount;
|
||||
uint32 m_rewitemscount;
|
||||
|
||||
// table data
|
||||
protected:
|
||||
uint32 QuestId;
|
||||
uint32 QuestMethod;
|
||||
int32 ZoneOrSort;
|
||||
int32 SkillOrClass;
|
||||
uint32 MinLevel;
|
||||
uint32 QuestLevel;
|
||||
uint32 Type;
|
||||
uint32 RequiredRaces;
|
||||
uint32 RequiredSkillValue;
|
||||
uint32 RepObjectiveFaction;
|
||||
int32 RepObjectiveValue;
|
||||
uint32 RequiredMinRepFaction;
|
||||
int32 RequiredMinRepValue;
|
||||
uint32 RequiredMaxRepFaction;
|
||||
int32 RequiredMaxRepValue;
|
||||
uint32 SuggestedPlayers;
|
||||
uint32 LimitTime;
|
||||
uint32 QuestFlags;
|
||||
uint32 CharTitleId;
|
||||
int32 PrevQuestId;
|
||||
int32 NextQuestId;
|
||||
int32 ExclusiveGroup;
|
||||
uint32 NextQuestInChain;
|
||||
uint32 SrcItemId;
|
||||
uint32 SrcItemCount;
|
||||
uint32 SrcSpell;
|
||||
std::string Title;
|
||||
std::string Details;
|
||||
std::string Objectives;
|
||||
std::string OfferRewardText;
|
||||
std::string RequestItemsText;
|
||||
std::string EndText;
|
||||
int32 RewOrReqMoney;
|
||||
uint32 RewMoneyMaxLevel;
|
||||
uint32 RewSpell;
|
||||
uint32 RewSpellCast;
|
||||
uint32 RewMailTemplateId;
|
||||
uint32 RewMailDelaySecs;
|
||||
uint32 PointMapId;
|
||||
float PointX;
|
||||
float PointY;
|
||||
uint32 PointOpt;
|
||||
uint32 IncompleteEmote;
|
||||
uint32 CompleteEmote;
|
||||
uint32 QuestStartScript;
|
||||
uint32 QuestCompleteScript;
|
||||
};
|
||||
|
||||
enum QuestUpdateState
|
||||
{
|
||||
QUEST_UNCHANGED = 0,
|
||||
QUEST_CHANGED = 1,
|
||||
QUEST_NEW = 2
|
||||
};
|
||||
|
||||
struct QuestStatusData
|
||||
{
|
||||
QuestStatusData()
|
||||
: m_status(QUEST_STATUS_NONE),m_rewarded(false),
|
||||
m_explored(false), m_timer(0), uState(QUEST_NEW)
|
||||
{
|
||||
memset(m_itemcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
|
||||
memset(m_creatureOrGOcount, 0, QUEST_OBJECTIVES_COUNT * sizeof(uint32));
|
||||
}
|
||||
|
||||
QuestStatus m_status;
|
||||
bool m_rewarded;
|
||||
bool m_explored;
|
||||
uint32 m_timer;
|
||||
QuestUpdateState uState;
|
||||
|
||||
uint32 m_itemcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
uint32 m_creatureOrGOcount[ QUEST_OBJECTIVES_COUNT ];
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "Map.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
|
||||
{
|
||||
float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist;
|
||||
|
||||
creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);
|
||||
|
||||
z = creature.GetPositionZ();
|
||||
uint32 mapid=creature.GetMapId();
|
||||
Map const* map = MapManager::Instance().GetBaseMap(mapid);
|
||||
|
||||
// For 2D/3D system selection
|
||||
bool is_land_ok = creature.canWalk();
|
||||
bool is_water_ok = creature.canSwim();
|
||||
bool is_air_ok = creature.canFly();
|
||||
|
||||
const float angle = rand_norm()*(M_PI*2);
|
||||
const float range = rand_norm()*wander_distance;
|
||||
const float distanceX = range * cos(angle);
|
||||
const float distanceY = range * sin(angle);
|
||||
|
||||
nx = X + distanceX;
|
||||
ny = Y + distanceY;
|
||||
|
||||
// prevent invalid coordinates generation
|
||||
MaNGOS::NormalizeMapCoord(nx);
|
||||
MaNGOS::NormalizeMapCoord(ny);
|
||||
|
||||
dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y);
|
||||
|
||||
if (is_air_ok) // 3D system above ground and above water (flying mode)
|
||||
{
|
||||
const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change
|
||||
nz = Z + distanceZ;
|
||||
float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.
|
||||
float wz = map->GetWaterLevel(nx, ny);
|
||||
if (tz >= nz || wz >= nz)
|
||||
return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
|
||||
}
|
||||
//else if (is_water_ok) // 3D system under water and above ground (swimming mode)
|
||||
else // 2D only
|
||||
{
|
||||
dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
|
||||
// The fastest way to get an accurate result 90% of the time.
|
||||
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
|
||||
nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check
|
||||
if (fabs(nz-Z)>dist)
|
||||
{
|
||||
nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above
|
||||
if (fabs(nz-Z)>dist)
|
||||
{
|
||||
nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher
|
||||
if (fabs(nz-Z)>dist)
|
||||
return; // let's forget this bad coords where a z cannot be find and retry at next tick
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Traveller<Creature> traveller(creature);
|
||||
creature.SetOrientation(creature.GetAngle(nx,ny));
|
||||
i_destinationHolder.SetDestination(traveller, nx, ny, nz);
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
if (is_air_ok)
|
||||
{
|
||||
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
//else if (is_water_ok) // Swimming mode to be done with more than this check
|
||||
else
|
||||
{
|
||||
i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
|
||||
{
|
||||
if(!creature.isAlive())
|
||||
return;
|
||||
|
||||
if (creature.canFly())
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Reset(Creature &creature)
|
||||
{
|
||||
Initialize(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
|
||||
{
|
||||
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
|
||||
{
|
||||
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
return true;
|
||||
}
|
||||
|
||||
i_nextMoveTime.Update(diff);
|
||||
|
||||
if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
CreatureTraveller traveller(creature);
|
||||
|
||||
if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
|
||||
{
|
||||
if(i_nextMoveTime.Passed())
|
||||
{
|
||||
if (creature.canFly())
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
|
||||
{
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "RandomMovementGenerator.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "Map.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
|
||||
{
|
||||
float X,Y,Z,z,nx,ny,nz,wander_distance,ori,dist;
|
||||
|
||||
creature.GetRespawnCoord(X, Y, Z, &ori, &wander_distance);
|
||||
|
||||
z = creature.GetPositionZ();
|
||||
uint32 mapid=creature.GetMapId();
|
||||
Map const* map = MapManager::Instance().GetBaseMap(mapid);
|
||||
|
||||
// For 2D/3D system selection
|
||||
bool is_land_ok = creature.canWalk();
|
||||
bool is_water_ok = creature.canSwim();
|
||||
bool is_air_ok = creature.canFly();
|
||||
|
||||
const float angle = rand_norm()*(M_PI*2);
|
||||
const float range = rand_norm()*wander_distance;
|
||||
const float distanceX = range * cos(angle);
|
||||
const float distanceY = range * sin(angle);
|
||||
|
||||
nx = X + distanceX;
|
||||
ny = Y + distanceY;
|
||||
|
||||
// prevent invalid coordinates generation
|
||||
MaNGOS::NormalizeMapCoord(nx);
|
||||
MaNGOS::NormalizeMapCoord(ny);
|
||||
|
||||
dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y);
|
||||
|
||||
if (is_air_ok) // 3D system above ground and above water (flying mode)
|
||||
{
|
||||
const float distanceZ = rand_norm() * sqrtf(dist)/2; // Limit height change
|
||||
nz = Z + distanceZ;
|
||||
float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.
|
||||
float wz = map->GetWaterLevel(nx, ny);
|
||||
if (tz >= nz || wz >= nz)
|
||||
return; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
|
||||
}
|
||||
//else if (is_water_ok) // 3D system under water and above ground (swimming mode)
|
||||
else // 2D only
|
||||
{
|
||||
dist = dist>=100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
|
||||
// The fastest way to get an accurate result 90% of the time.
|
||||
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
|
||||
nz = map->GetHeight(nx,ny,Z+dist-2.0f,false); // Map check
|
||||
if (fabs(nz-Z)>dist)
|
||||
{
|
||||
nz = map->GetHeight(nx,ny,Z-2.0f,true); // Vmap Horizontal or above
|
||||
if (fabs(nz-Z)>dist)
|
||||
{
|
||||
nz = map->GetHeight(nx,ny,Z+dist-2.0f,true); // Vmap Higher
|
||||
if (fabs(nz-Z)>dist)
|
||||
return; // let's forget this bad coords where a z cannot be find and retry at next tick
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Traveller<Creature> traveller(creature);
|
||||
creature.SetOrientation(creature.GetAngle(nx,ny));
|
||||
i_destinationHolder.SetDestination(traveller, nx, ny, nz);
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
if (is_air_ok)
|
||||
{
|
||||
i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
//else if (is_water_ok) // Swimming mode to be done with more than this check
|
||||
else
|
||||
{
|
||||
i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime()));
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_WALK_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Initialize(Creature &creature)
|
||||
{
|
||||
if(!creature.isAlive())
|
||||
return;
|
||||
|
||||
if (creature.canFly())
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE );
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
void
|
||||
RandomMovementGenerator<Creature>::Reset(Creature &creature)
|
||||
{
|
||||
Initialize(creature);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
|
||||
{
|
||||
if(creature.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
|
||||
{
|
||||
i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
return true;
|
||||
}
|
||||
|
||||
i_nextMoveTime.Update(diff);
|
||||
|
||||
if(i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
|
||||
creature.clearUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
if(!i_destinationHolder.HasArrived() && creature.IsStopped())
|
||||
creature.addUnitState(UNIT_STAT_ROAMING);
|
||||
|
||||
CreatureTraveller traveller(creature);
|
||||
|
||||
if( i_destinationHolder.UpdateTraveller(traveller, diff, false, true) )
|
||||
{
|
||||
if(i_nextMoveTime.Passed())
|
||||
{
|
||||
if (creature.canFly())
|
||||
creature.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
else
|
||||
creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MOVEMENTFLAG_WALK_MODE : MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
else if(creature.isPet() && creature.GetOwner() && creature.GetDistance(creature.GetOwner()) > PET_FOLLOW_DIST+2.5f)
|
||||
{
|
||||
creature.SetUnitMovementFlags(MOVEMENTFLAG_NONE);
|
||||
_setRandomLocation(creature);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+311
-311
@@ -1,311 +1,311 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "SocialMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "Util.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( SocialMgr );
|
||||
|
||||
PlayerSocial::PlayerSocial()
|
||||
{
|
||||
m_playerGUID = 0;
|
||||
}
|
||||
|
||||
PlayerSocial::~PlayerSocial()
|
||||
{
|
||||
m_playerSocialMap.clear();
|
||||
}
|
||||
|
||||
bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore)
|
||||
{
|
||||
// client limit
|
||||
if(m_playerSocialMap.size() >= 50)
|
||||
return false;
|
||||
|
||||
uint32 flag = SOCIAL_FLAG_FRIEND;
|
||||
if(ignore)
|
||||
flag = SOCIAL_FLAG_IGNORED;
|
||||
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr != m_playerSocialMap.end())
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags | %u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
|
||||
m_playerSocialMap[friend_guid].Flags |= flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("INSERT INTO character_social (guid, friend, flags) VALUES ('%u', '%u', '%u')", GetPlayerGUID(), friend_guid, flag);
|
||||
FriendInfo fi;
|
||||
fi.Flags |= flag;
|
||||
m_playerSocialMap[friend_guid] = fi;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlayerSocial::RemoveFromSocialList(uint32 friend_guid, bool ignore)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr == m_playerSocialMap.end()) // not exist
|
||||
return;
|
||||
|
||||
uint32 flag = SOCIAL_FLAG_FRIEND;
|
||||
if(ignore)
|
||||
flag = SOCIAL_FLAG_IGNORED;
|
||||
|
||||
itr->second.Flags &= ~flag;
|
||||
if(itr->second.Flags == 0)
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u'", GetPlayerGUID(), friend_guid);
|
||||
m_playerSocialMap.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags & ~%u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSocial::SetFriendNote(uint32 friend_guid, std::string note)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr == m_playerSocialMap.end()) // not exist
|
||||
return;
|
||||
|
||||
utf8truncate(note,48); // DB and client size limitation
|
||||
|
||||
CharacterDatabase.escape_string(note);
|
||||
CharacterDatabase.PExecute("UPDATE character_social SET note = '%s' WHERE guid = '%u' AND friend = '%u'", note.c_str(), GetPlayerGUID(), friend_guid);
|
||||
m_playerSocialMap[friend_guid].Note = note;
|
||||
}
|
||||
|
||||
void PlayerSocial::SendSocialList()
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(GetPlayerGUID());
|
||||
if(!plr)
|
||||
return;
|
||||
|
||||
uint32 size = m_playerSocialMap.size();
|
||||
|
||||
WorldPacket data(SMSG_CONTACT_LIST, (4+4+size*25)); // just can guess size
|
||||
data << uint32(7); // unk flag (0x1, 0x2, 0x4), 0x7 if it include ignore list
|
||||
data << uint32(size); // friends count
|
||||
|
||||
for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
|
||||
{
|
||||
sSocialMgr.GetFriendInfo(plr, itr->first, itr->second);
|
||||
|
||||
data << uint64(itr->first); // player guid
|
||||
data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?)
|
||||
data << itr->second.Note; // string note
|
||||
if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
|
||||
{
|
||||
data << uint8(itr->second.Status); // online/offline/etc?
|
||||
if(itr->second.Status) // if online
|
||||
{
|
||||
data << uint32(itr->second.Area); // player area
|
||||
data << uint32(itr->second.Level); // player level
|
||||
data << uint32(itr->second.Class); // player class
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
sLog.outDebug("WORLD: Sent SMSG_CONTACT_LIST");
|
||||
}
|
||||
|
||||
bool PlayerSocial::HasFriend(uint32 friend_guid)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr != m_playerSocialMap.end())
|
||||
return itr->second.Flags & SOCIAL_FLAG_FRIEND;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerSocial::HasIgnore(uint32 ignore_guid)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(ignore_guid);
|
||||
if(itr != m_playerSocialMap.end())
|
||||
return itr->second.Flags & SOCIAL_FLAG_IGNORED;
|
||||
return false;
|
||||
}
|
||||
|
||||
SocialMgr::SocialMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SocialMgr::~SocialMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SocialMgr::RemovePlayerSocial(uint32 guid)
|
||||
{
|
||||
SocialMap::iterator itr = m_socialMap.find(guid);
|
||||
if(itr != m_socialMap.end())
|
||||
m_socialMap.erase(itr);
|
||||
}
|
||||
|
||||
void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
|
||||
{
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
Player *pFriend = ObjectAccessor::FindPlayer(friendGUID);
|
||||
|
||||
uint32 team = player->GetTeam();
|
||||
uint32 security = player->GetSession()->GetSecurity();
|
||||
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
|
||||
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER;
|
||||
|
||||
PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
|
||||
if(itr != player->GetSocial()->m_playerSocialMap.end())
|
||||
friendInfo.Note = itr->second.Note;
|
||||
|
||||
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
|
||||
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
|
||||
if( pFriend && pFriend->GetName() &&
|
||||
( security > SEC_PLAYER ||
|
||||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
|
||||
( pFriend->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && pFriend->IsVisibleGloballyFor(player) )))
|
||||
{
|
||||
friendInfo.Status = FRIEND_STATUS_ONLINE;
|
||||
if(pFriend->isAFK())
|
||||
friendInfo.Status = FRIEND_STATUS_AFK;
|
||||
if(pFriend->isDND())
|
||||
friendInfo.Status = FRIEND_STATUS_DND;
|
||||
friendInfo.Area = pFriend->GetZoneId();
|
||||
friendInfo.Level = pFriend->getLevel();
|
||||
friendInfo.Class = pFriend->getClass();
|
||||
}
|
||||
else
|
||||
{
|
||||
friendInfo.Status = FRIEND_STATUS_OFFLINE;
|
||||
friendInfo.Area = 0;
|
||||
friendInfo.Level = 0;
|
||||
friendInfo.Class = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SocialMgr::MakeFriendStatusPacket(FriendsResult result, uint32 guid, WorldPacket *data)
|
||||
{
|
||||
data->Initialize(SMSG_FRIEND_STATUS, 5);
|
||||
*data << uint8(result);
|
||||
*data << uint64(guid);
|
||||
}
|
||||
|
||||
void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast)
|
||||
{
|
||||
FriendInfo fi;
|
||||
|
||||
WorldPacket data;
|
||||
MakeFriendStatusPacket(result, friend_guid, &data);
|
||||
GetFriendInfo(player, friend_guid, fi);
|
||||
switch(result)
|
||||
{
|
||||
case FRIEND_ADDED_OFFLINE:
|
||||
case FRIEND_ADDED_ONLINE:
|
||||
data << fi.Note;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case FRIEND_ADDED_ONLINE:
|
||||
case FRIEND_ONLINE:
|
||||
data << uint8(fi.Status);
|
||||
data << uint32(fi.Area);
|
||||
data << uint32(fi.Level);
|
||||
data << uint32(fi.Class);
|
||||
break;
|
||||
}
|
||||
|
||||
if(broadcast)
|
||||
BroadcastToFriendListers(player, &data);
|
||||
else
|
||||
player->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet)
|
||||
{
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
uint32 team = player->GetTeam();
|
||||
uint32 security = player->GetSession()->GetSecurity();
|
||||
uint32 guid = player->GetGUIDLow();
|
||||
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST);
|
||||
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
|
||||
|
||||
for(SocialMap::iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
|
||||
{
|
||||
PlayerSocialMap::iterator itr2 = itr->second.m_playerSocialMap.find(guid);
|
||||
if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
|
||||
{
|
||||
Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
|
||||
|
||||
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
|
||||
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
|
||||
if( pFriend && pFriend->IsInWorld() &&
|
||||
( pFriend->GetSession()->GetSecurity() > SEC_PLAYER ||
|
||||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
|
||||
(security == SEC_PLAYER || gmInWhoList && player->IsVisibleGloballyFor(pFriend) )))
|
||||
{
|
||||
pFriend->GetSession()->SendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerSocial *SocialMgr::LoadFromDB(QueryResult *result, uint32 guid)
|
||||
{
|
||||
PlayerSocial *social = &m_socialMap[guid];
|
||||
social->SetPlayerGUID(guid);
|
||||
|
||||
if(!result)
|
||||
return social;
|
||||
|
||||
uint32 friend_guid = 0;
|
||||
uint32 flags = 0;
|
||||
std::string note = "";
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
friend_guid = fields[0].GetUInt32();
|
||||
flags = fields[1].GetUInt32();
|
||||
note = fields[2].GetCppString();
|
||||
|
||||
social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note);
|
||||
|
||||
// client limit
|
||||
if(social->m_playerSocialMap.size() >= 50)
|
||||
break;
|
||||
}
|
||||
while( result->NextRow() );
|
||||
delete result;
|
||||
return social;
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "SocialMgr.h"
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
#include "Opcodes.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "World.h"
|
||||
#include "Util.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( SocialMgr );
|
||||
|
||||
PlayerSocial::PlayerSocial()
|
||||
{
|
||||
m_playerGUID = 0;
|
||||
}
|
||||
|
||||
PlayerSocial::~PlayerSocial()
|
||||
{
|
||||
m_playerSocialMap.clear();
|
||||
}
|
||||
|
||||
bool PlayerSocial::AddToSocialList(uint32 friend_guid, bool ignore)
|
||||
{
|
||||
// client limit
|
||||
if(m_playerSocialMap.size() >= 50)
|
||||
return false;
|
||||
|
||||
uint32 flag = SOCIAL_FLAG_FRIEND;
|
||||
if(ignore)
|
||||
flag = SOCIAL_FLAG_IGNORED;
|
||||
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr != m_playerSocialMap.end())
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags | %u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
|
||||
m_playerSocialMap[friend_guid].Flags |= flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("INSERT INTO character_social (guid, friend, flags) VALUES ('%u', '%u', '%u')", GetPlayerGUID(), friend_guid, flag);
|
||||
FriendInfo fi;
|
||||
fi.Flags |= flag;
|
||||
m_playerSocialMap[friend_guid] = fi;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlayerSocial::RemoveFromSocialList(uint32 friend_guid, bool ignore)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr == m_playerSocialMap.end()) // not exist
|
||||
return;
|
||||
|
||||
uint32 flag = SOCIAL_FLAG_FRIEND;
|
||||
if(ignore)
|
||||
flag = SOCIAL_FLAG_IGNORED;
|
||||
|
||||
itr->second.Flags &= ~flag;
|
||||
if(itr->second.Flags == 0)
|
||||
{
|
||||
CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' AND friend = '%u'", GetPlayerGUID(), friend_guid);
|
||||
m_playerSocialMap.erase(itr);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterDatabase.PExecute("UPDATE character_social SET flags = (flags & ~%u) WHERE guid = '%u' AND friend = '%u'", flag, GetPlayerGUID(), friend_guid);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerSocial::SetFriendNote(uint32 friend_guid, std::string note)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr == m_playerSocialMap.end()) // not exist
|
||||
return;
|
||||
|
||||
utf8truncate(note,48); // DB and client size limitation
|
||||
|
||||
CharacterDatabase.escape_string(note);
|
||||
CharacterDatabase.PExecute("UPDATE character_social SET note = '%s' WHERE guid = '%u' AND friend = '%u'", note.c_str(), GetPlayerGUID(), friend_guid);
|
||||
m_playerSocialMap[friend_guid].Note = note;
|
||||
}
|
||||
|
||||
void PlayerSocial::SendSocialList()
|
||||
{
|
||||
Player *plr = objmgr.GetPlayer(GetPlayerGUID());
|
||||
if(!plr)
|
||||
return;
|
||||
|
||||
uint32 size = m_playerSocialMap.size();
|
||||
|
||||
WorldPacket data(SMSG_CONTACT_LIST, (4+4+size*25)); // just can guess size
|
||||
data << uint32(7); // unk flag (0x1, 0x2, 0x4), 0x7 if it include ignore list
|
||||
data << uint32(size); // friends count
|
||||
|
||||
for(PlayerSocialMap::iterator itr = m_playerSocialMap.begin(); itr != m_playerSocialMap.end(); ++itr)
|
||||
{
|
||||
sSocialMgr.GetFriendInfo(plr, itr->first, itr->second);
|
||||
|
||||
data << uint64(itr->first); // player guid
|
||||
data << uint32(itr->second.Flags); // player flag (0x1-friend?, 0x2-ignored?, 0x4-muted?)
|
||||
data << itr->second.Note; // string note
|
||||
if(itr->second.Flags & SOCIAL_FLAG_FRIEND) // if IsFriend()
|
||||
{
|
||||
data << uint8(itr->second.Status); // online/offline/etc?
|
||||
if(itr->second.Status) // if online
|
||||
{
|
||||
data << uint32(itr->second.Area); // player area
|
||||
data << uint32(itr->second.Level); // player level
|
||||
data << uint32(itr->second.Class); // player class
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plr->GetSession()->SendPacket(&data);
|
||||
sLog.outDebug("WORLD: Sent SMSG_CONTACT_LIST");
|
||||
}
|
||||
|
||||
bool PlayerSocial::HasFriend(uint32 friend_guid)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(friend_guid);
|
||||
if(itr != m_playerSocialMap.end())
|
||||
return itr->second.Flags & SOCIAL_FLAG_FRIEND;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PlayerSocial::HasIgnore(uint32 ignore_guid)
|
||||
{
|
||||
PlayerSocialMap::iterator itr = m_playerSocialMap.find(ignore_guid);
|
||||
if(itr != m_playerSocialMap.end())
|
||||
return itr->second.Flags & SOCIAL_FLAG_IGNORED;
|
||||
return false;
|
||||
}
|
||||
|
||||
SocialMgr::SocialMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SocialMgr::~SocialMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SocialMgr::RemovePlayerSocial(uint32 guid)
|
||||
{
|
||||
SocialMap::iterator itr = m_socialMap.find(guid);
|
||||
if(itr != m_socialMap.end())
|
||||
m_socialMap.erase(itr);
|
||||
}
|
||||
|
||||
void SocialMgr::GetFriendInfo(Player *player, uint32 friendGUID, FriendInfo &friendInfo)
|
||||
{
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
Player *pFriend = ObjectAccessor::FindPlayer(friendGUID);
|
||||
|
||||
uint32 team = player->GetTeam();
|
||||
uint32 security = player->GetSession()->GetSecurity();
|
||||
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
|
||||
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST) || security > SEC_PLAYER;
|
||||
|
||||
PlayerSocialMap::iterator itr = player->GetSocial()->m_playerSocialMap.find(friendGUID);
|
||||
if(itr != player->GetSocial()->m_playerSocialMap.end())
|
||||
friendInfo.Note = itr->second.Note;
|
||||
|
||||
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
|
||||
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
|
||||
if( pFriend && pFriend->GetName() &&
|
||||
( security > SEC_PLAYER ||
|
||||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
|
||||
( pFriend->GetSession()->GetSecurity() == SEC_PLAYER || gmInWhoList && pFriend->IsVisibleGloballyFor(player) )))
|
||||
{
|
||||
friendInfo.Status = FRIEND_STATUS_ONLINE;
|
||||
if(pFriend->isAFK())
|
||||
friendInfo.Status = FRIEND_STATUS_AFK;
|
||||
if(pFriend->isDND())
|
||||
friendInfo.Status = FRIEND_STATUS_DND;
|
||||
friendInfo.Area = pFriend->GetZoneId();
|
||||
friendInfo.Level = pFriend->getLevel();
|
||||
friendInfo.Class = pFriend->getClass();
|
||||
}
|
||||
else
|
||||
{
|
||||
friendInfo.Status = FRIEND_STATUS_OFFLINE;
|
||||
friendInfo.Area = 0;
|
||||
friendInfo.Level = 0;
|
||||
friendInfo.Class = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SocialMgr::MakeFriendStatusPacket(FriendsResult result, uint32 guid, WorldPacket *data)
|
||||
{
|
||||
data->Initialize(SMSG_FRIEND_STATUS, 5);
|
||||
*data << uint8(result);
|
||||
*data << uint64(guid);
|
||||
}
|
||||
|
||||
void SocialMgr::SendFriendStatus(Player *player, FriendsResult result, uint32 friend_guid, std::string name, bool broadcast)
|
||||
{
|
||||
FriendInfo fi;
|
||||
|
||||
WorldPacket data;
|
||||
MakeFriendStatusPacket(result, friend_guid, &data);
|
||||
GetFriendInfo(player, friend_guid, fi);
|
||||
switch(result)
|
||||
{
|
||||
case FRIEND_ADDED_OFFLINE:
|
||||
case FRIEND_ADDED_ONLINE:
|
||||
data << fi.Note;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(result)
|
||||
{
|
||||
case FRIEND_ADDED_ONLINE:
|
||||
case FRIEND_ONLINE:
|
||||
data << uint8(fi.Status);
|
||||
data << uint32(fi.Area);
|
||||
data << uint32(fi.Level);
|
||||
data << uint32(fi.Class);
|
||||
break;
|
||||
}
|
||||
|
||||
if(broadcast)
|
||||
BroadcastToFriendListers(player, &data);
|
||||
else
|
||||
player->GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet)
|
||||
{
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
uint32 team = player->GetTeam();
|
||||
uint32 security = player->GetSession()->GetSecurity();
|
||||
uint32 guid = player->GetGUIDLow();
|
||||
bool gmInWhoList = sWorld.getConfig(CONFIG_GM_IN_WHO_LIST);
|
||||
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_WHO_LIST);
|
||||
|
||||
for(SocialMap::iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr)
|
||||
{
|
||||
PlayerSocialMap::iterator itr2 = itr->second.m_playerSocialMap.find(guid);
|
||||
if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
|
||||
{
|
||||
Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
|
||||
|
||||
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
|
||||
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
|
||||
if( pFriend && pFriend->IsInWorld() &&
|
||||
( pFriend->GetSession()->GetSecurity() > SEC_PLAYER ||
|
||||
( pFriend->GetTeam() == team || allowTwoSideWhoList ) &&
|
||||
(security == SEC_PLAYER || gmInWhoList && player->IsVisibleGloballyFor(pFriend) )))
|
||||
{
|
||||
pFriend->GetSession()->SendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlayerSocial *SocialMgr::LoadFromDB(QueryResult *result, uint32 guid)
|
||||
{
|
||||
PlayerSocial *social = &m_socialMap[guid];
|
||||
social->SetPlayerGUID(guid);
|
||||
|
||||
if(!result)
|
||||
return social;
|
||||
|
||||
uint32 friend_guid = 0;
|
||||
uint32 flags = 0;
|
||||
std::string note = "";
|
||||
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
|
||||
friend_guid = fields[0].GetUInt32();
|
||||
flags = fields[1].GetUInt32();
|
||||
note = fields[2].GetCppString();
|
||||
|
||||
social->m_playerSocialMap[friend_guid] = FriendInfo(flags, note);
|
||||
|
||||
// client limit
|
||||
if(social->m_playerSocialMap.size() >= 50)
|
||||
break;
|
||||
}
|
||||
while( result->NextRow() );
|
||||
delete result;
|
||||
return social;
|
||||
}
|
||||
|
||||
+5089
-5089
File diff suppressed because it is too large
Load Diff
+696
-696
File diff suppressed because it is too large
Load Diff
+6360
-6360
File diff suppressed because it is too large
Load Diff
+6187
-6187
File diff suppressed because it is too large
Load Diff
+965
-965
File diff suppressed because it is too large
Load Diff
@@ -1,211 +1,211 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "World.h"
|
||||
|
||||
#define SMALL_ALPHA 0.05f
|
||||
|
||||
#include <cmath>
|
||||
/*
|
||||
struct StackCleaner
|
||||
{
|
||||
Creature &i_creature;
|
||||
StackCleaner(Creature &creature) : i_creature(creature) {}
|
||||
void Done(void) { i_creature.StopMoving(); }
|
||||
~StackCleaner()
|
||||
{
|
||||
i_creature->Clear();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
{
|
||||
if( !i_target.isValid() || !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
|
||||
return;
|
||||
|
||||
// prevent redundant micro-movement for pets, other followers.
|
||||
if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if(!i_offset)
|
||||
{
|
||||
// to nearest contact position
|
||||
i_target->GetContactPoint( &owner, x, y, z );
|
||||
}
|
||||
else
|
||||
{
|
||||
// to at i_offset distance from target and i_angle from target facing
|
||||
i_target->GetClosePoint(x,y,z,owner.GetObjectSize(),i_offset,i_angle);
|
||||
}
|
||||
|
||||
/*
|
||||
We MUST not check the distance difference and avoid setting the new location for smaller distances.
|
||||
By that we risk having far too many GetContactPoint() calls freezing the whole system.
|
||||
In TargetedMovementGenerator<T>::Update() we check the distance to the target and at
|
||||
some range we calculate a new position. The calculation takes some processor cycles due to vmaps.
|
||||
If the distance to the target it too large to ignore,
|
||||
but the distance to the new contact point is short enough to be ignored,
|
||||
we will calculate a new contact point each update loop, but will never move to it.
|
||||
The system will freeze.
|
||||
ralf
|
||||
|
||||
//We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
|
||||
float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
|
||||
if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
|
||||
return;
|
||||
*/
|
||||
Traveller<T> traveller(owner);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Initialize(T &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Finalize(T &owner)
|
||||
{
|
||||
owner.clearUnitState(UNIT_STAT_CHASE);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Reset(T &owner)
|
||||
{
|
||||
Initialize(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
{
|
||||
if(!i_target.isValid())
|
||||
return false;
|
||||
|
||||
if( !&owner || !owner.isAlive())
|
||||
return true;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
|
||||
return true;
|
||||
|
||||
// prevent movement while casting spells with cast time or channel time
|
||||
if ( owner.IsNonMeleeSpellCasted(false, false, true))
|
||||
{
|
||||
if (!owner.IsStopped())
|
||||
owner.StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
// prevent crash after creature killed pet
|
||||
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
if( !i_destinationHolder.HasDestination() )
|
||||
_setTargetLocation(owner);
|
||||
if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
|
||||
{
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
|
||||
i_destinationHolder.StartTravel(traveller);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
|
||||
{
|
||||
// put targeted movement generators on a higher priority
|
||||
if (owner.GetObjectSize())
|
||||
i_destinationHolder.ResetUpdate(50);
|
||||
|
||||
float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
|
||||
|
||||
//More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
|
||||
// try to counter precision differences
|
||||
if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
|
||||
{
|
||||
owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
|
||||
_setTargetLocation(owner); //Calculate New Dest and Send data To Player
|
||||
}
|
||||
// Update the Angle of the target only for Map::, no need to send packet for player
|
||||
else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) )
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
|
||||
{
|
||||
i_recalculateTravel = false;
|
||||
//Angle update will take place into owner.StopMoving()
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
owner.StopMoving();
|
||||
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
|
||||
owner.Attack(i_target.getTarget(),true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Unit*
|
||||
TargetedMovementGenerator<T>::GetTarget() const
|
||||
{
|
||||
return i_target.getTarget();
|
||||
}
|
||||
|
||||
template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
|
||||
template void TargetedMovementGenerator<Player>::Initialize(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
|
||||
template void TargetedMovementGenerator<Player>::Finalize(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::Finalize(Creature &);
|
||||
template void TargetedMovementGenerator<Player>::Reset(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::Reset(Creature &);
|
||||
template bool TargetedMovementGenerator<Player>::Update(Player &, const uint32 &);
|
||||
template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32 &);
|
||||
template Unit* TargetedMovementGenerator<Player>::GetTarget() const;
|
||||
template Unit* TargetedMovementGenerator<Creature>::GetTarget() const;
|
||||
/*
|
||||
* Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
|
||||
*
|
||||
* 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 2 of the License, or
|
||||
* (at your option) 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "Errors.h"
|
||||
#include "Creature.h"
|
||||
#include "MapManager.h"
|
||||
#include "DestinationHolderImp.h"
|
||||
#include "World.h"
|
||||
|
||||
#define SMALL_ALPHA 0.05f
|
||||
|
||||
#include <cmath>
|
||||
/*
|
||||
struct StackCleaner
|
||||
{
|
||||
Creature &i_creature;
|
||||
StackCleaner(Creature &creature) : i_creature(creature) {}
|
||||
void Done(void) { i_creature.StopMoving(); }
|
||||
~StackCleaner()
|
||||
{
|
||||
i_creature->Clear();
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
|
||||
{
|
||||
if( !i_target.isValid() || !&owner )
|
||||
return;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED) )
|
||||
return;
|
||||
|
||||
// prevent redundant micro-movement for pets, other followers.
|
||||
if(i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
|
||||
return;
|
||||
|
||||
float x, y, z;
|
||||
if(!i_offset)
|
||||
{
|
||||
// to nearest contact position
|
||||
i_target->GetContactPoint( &owner, x, y, z );
|
||||
}
|
||||
else
|
||||
{
|
||||
// to at i_offset distance from target and i_angle from target facing
|
||||
i_target->GetClosePoint(x,y,z,owner.GetObjectSize(),i_offset,i_angle);
|
||||
}
|
||||
|
||||
/*
|
||||
We MUST not check the distance difference and avoid setting the new location for smaller distances.
|
||||
By that we risk having far too many GetContactPoint() calls freezing the whole system.
|
||||
In TargetedMovementGenerator<T>::Update() we check the distance to the target and at
|
||||
some range we calculate a new position. The calculation takes some processor cycles due to vmaps.
|
||||
If the distance to the target it too large to ignore,
|
||||
but the distance to the new contact point is short enough to be ignored,
|
||||
we will calculate a new contact point each update loop, but will never move to it.
|
||||
The system will freeze.
|
||||
ralf
|
||||
|
||||
//We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
|
||||
float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
|
||||
if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
|
||||
return;
|
||||
*/
|
||||
Traveller<T> traveller(owner);
|
||||
i_destinationHolder.SetDestination(traveller, x, y, z);
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Initialize(T &owner)
|
||||
{
|
||||
if(!&owner)
|
||||
return;
|
||||
owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);
|
||||
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
|
||||
_setTargetLocation(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Finalize(T &owner)
|
||||
{
|
||||
owner.clearUnitState(UNIT_STAT_CHASE);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TargetedMovementGenerator<T>::Reset(T &owner)
|
||||
{
|
||||
Initialize(owner);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
TargetedMovementGenerator<T>::Update(T &owner, const uint32 & time_diff)
|
||||
{
|
||||
if(!i_target.isValid())
|
||||
return false;
|
||||
|
||||
if( !&owner || !owner.isAlive())
|
||||
return true;
|
||||
|
||||
if( owner.hasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED) )
|
||||
return true;
|
||||
|
||||
// prevent movement while casting spells with cast time or channel time
|
||||
if ( owner.IsNonMeleeSpellCasted(false, false, true))
|
||||
{
|
||||
if (!owner.IsStopped())
|
||||
owner.StopMoving();
|
||||
return true;
|
||||
}
|
||||
|
||||
// prevent crash after creature killed pet
|
||||
if (!owner.hasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
|
||||
return true;
|
||||
|
||||
Traveller<T> traveller(owner);
|
||||
|
||||
if( !i_destinationHolder.HasDestination() )
|
||||
_setTargetLocation(owner);
|
||||
if( owner.IsStopped() && !i_destinationHolder.HasArrived() )
|
||||
{
|
||||
owner.addUnitState(UNIT_STAT_CHASE);
|
||||
if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly())
|
||||
owner.AddUnitMovementFlag(MOVEMENTFLAG_FLYING2);
|
||||
|
||||
i_destinationHolder.StartTravel(traveller);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (i_destinationHolder.UpdateTraveller(traveller, time_diff, false))
|
||||
{
|
||||
// put targeted movement generators on a higher priority
|
||||
if (owner.GetObjectSize())
|
||||
i_destinationHolder.ResetUpdate(50);
|
||||
|
||||
float dist = i_target->GetObjectSize() + owner.GetObjectSize() + sWorld.getRate(RATE_TARGET_POS_RECALCULATION_RANGE);
|
||||
|
||||
//More distance let have better performance, less distance let have more sensitive reaction at target move.
|
||||
|
||||
// try to counter precision differences
|
||||
if( i_destinationHolder.GetDistance2dFromDestSq(*i_target.getTarget()) >= dist * dist)
|
||||
{
|
||||
owner.SetInFront(i_target.getTarget()); // Set new Angle For Map::
|
||||
_setTargetLocation(owner); //Calculate New Dest and Send data To Player
|
||||
}
|
||||
// Update the Angle of the target only for Map::, no need to send packet for player
|
||||
else if ( !i_angle && !owner.HasInArc( 0.01f, i_target.getTarget() ) )
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
if(( owner.IsStopped() && !i_destinationHolder.HasArrived() ) || i_recalculateTravel )
|
||||
{
|
||||
i_recalculateTravel = false;
|
||||
//Angle update will take place into owner.StopMoving()
|
||||
owner.SetInFront(i_target.getTarget());
|
||||
|
||||
owner.StopMoving();
|
||||
if(owner.canReachWithAttack(i_target.getTarget()) && !owner.hasUnitState(UNIT_STAT_FOLLOW))
|
||||
owner.Attack(i_target.getTarget(),true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Unit*
|
||||
TargetedMovementGenerator<T>::GetTarget() const
|
||||
{
|
||||
return i_target.getTarget();
|
||||
}
|
||||
|
||||
template void TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
|
||||
template void TargetedMovementGenerator<Player>::Initialize(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
|
||||
template void TargetedMovementGenerator<Player>::Finalize(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::Finalize(Creature &);
|
||||
template void TargetedMovementGenerator<Player>::Reset(Player &);
|
||||
template void TargetedMovementGenerator<Creature>::Reset(Creature &);
|
||||
template bool TargetedMovementGenerator<Player>::Update(Player &, const uint32 &);
|
||||
template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32 &);
|
||||
template Unit* TargetedMovementGenerator<Player>::GetTarget() const;
|
||||
template Unit* TargetedMovementGenerator<Creature>::GetTarget() const;
|
||||
|
||||
+634
-634
File diff suppressed because it is too large
Load Diff
+10828
-10828
File diff suppressed because it is too large
Load Diff
+1337
-1337
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2595
-2595
File diff suppressed because it is too large
Load Diff
+568
-568
File diff suppressed because it is too large
Load Diff
+511
-511
File diff suppressed because it is too large
Load Diff
+643
-643
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user