mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Mant more cmangos Cata commits applied
Commit:
This commit is contained in:
parent
6db0ba8ae9
commit
8cac2f42db
51 changed files with 964 additions and 270 deletions
|
|
@ -64,9 +64,20 @@ typedef ACE_SHLIB_HANDLE MANGOS_LIBRARY_HANDLE;
|
|||
# define MANGOS_EXPORT __declspec(dllexport)
|
||||
# define MANGOS_IMPORT __cdecl
|
||||
#else // PLATFORM != PLATFORM_WINDOWS
|
||||
# include <dlfcn.h>
|
||||
typedef void* MANGOS_LIBRARY_HANDLE;
|
||||
# define MANGOS_LOAD_LIBRARY(libname) dlopen(libname, RTLD_LAZY)
|
||||
# define MANGOS_CLOSE_LIBRARY(hlib) dlclose(hlib)
|
||||
# define MANGOS_GET_PROC_ADDR(hlib, name) dlsym(hlib, name)
|
||||
# define MANGOS_EXPORT export
|
||||
# if defined(__APPLE_CC__) && defined(BIG_ENDIAN)
|
||||
# if (defined(__ppc__) || defined(__powerpc__))
|
||||
# if PLATFORM == PLATFORM_APPLE
|
||||
# define MANGOS_SCRIPT_SUFFIX ".dylib"
|
||||
# else
|
||||
# define MANGOS_SCRIPT_SUFFIX ".so"
|
||||
# endif
|
||||
# define MANGOS_SCRIPT_PREFIX "lib"
|
||||
# if defined(__APPLE_CC__) && defined(BIG_ENDIAN) // TODO:: more work to do with byte order. Have to be rechecked after boost integration.
|
||||
# if (defined (__ppc__) || defined (__powerpc__))
|
||||
# define MANGOS_IMPORT __attribute__ ((longcall))
|
||||
# else
|
||||
# define MANGOS_IMPORT
|
||||
|
|
|
|||
|
|
@ -326,14 +326,7 @@ void BattleGround::Update(uint32 diff)
|
|||
}
|
||||
else if (m_PrematureCountDownTimer < diff)
|
||||
{
|
||||
// time's up!
|
||||
Team winner = TEAM_NONE;
|
||||
if (GetPlayersCountByTeam(ALLIANCE) >= GetMinPlayersPerTeam())
|
||||
winner = ALLIANCE;
|
||||
else if (GetPlayersCountByTeam(HORDE) >= GetMinPlayersPerTeam())
|
||||
winner = HORDE;
|
||||
|
||||
EndBattleGround(winner);
|
||||
EndBattleGround(GetPrematureWinner());
|
||||
m_PrematureCountDown = false;
|
||||
}
|
||||
else if (!sBattleGroundMgr.isTesting())
|
||||
|
|
@ -1483,6 +1476,19 @@ void BattleGround::DoorOpen(ObjectGuid guid)
|
|||
sLog.outError("BattleGround: Door %s not found! - doors will be closed.", guid.GetString().c_str());
|
||||
}
|
||||
|
||||
Team BattleGround::GetPrematureWinner()
|
||||
{
|
||||
uint32 hordePlayers = GetPlayersCountByTeam(HORDE);
|
||||
uint32 alliancePlayers = GetPlayersCountByTeam(ALLIANCE);
|
||||
|
||||
if (hordePlayers > alliancePlayers)
|
||||
return HORDE;
|
||||
if (alliancePlayers > hordePlayers)
|
||||
return ALLIANCE;
|
||||
|
||||
return TEAM_NONE;
|
||||
}
|
||||
|
||||
void BattleGround::OnObjectDBLoad(Creature* creature)
|
||||
{
|
||||
const BattleGroundEventIdx eventId = sBattleGroundMgr.GetCreatureEventIndex(creature->GetGUIDLow());
|
||||
|
|
|
|||
|
|
@ -550,6 +550,8 @@ class BattleGround
|
|||
void DoorOpen(ObjectGuid guid);
|
||||
void DoorClose(ObjectGuid guid);
|
||||
|
||||
virtual Team GetPrematureWinner();
|
||||
|
||||
virtual bool HandlePlayerUnderMap(Player* /*plr*/) { return false; }
|
||||
|
||||
// since arenas can be AvA or Hvh, we have to get the "temporary" team of a player
|
||||
|
|
|
|||
|
|
@ -543,3 +543,18 @@ bool BattleGroundAB::IsAllNodesControlledByTeam(Team team) const
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
Team BattleGroundAB::GetPrematureWinner()
|
||||
{
|
||||
int32 hordeScore = m_TeamScores[TEAM_INDEX_HORDE];
|
||||
int32 allianceScore = m_TeamScores[TEAM_INDEX_ALLIANCE];
|
||||
|
||||
if (hordeScore > allianceScore)
|
||||
return HORDE;
|
||||
if (allianceScore > hordeScore)
|
||||
return ALLIANCE;
|
||||
|
||||
// If the values are equal, fall back to number of players on each team
|
||||
return BattleGround::GetPrematureWinner();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,6 +189,8 @@ class BattleGroundAB : public BattleGround
|
|||
/* achievement req. */
|
||||
bool IsAllNodesControlledByTeam(Team team) const override;
|
||||
bool IsTeamScores500Disadvantage(Team team) const { return m_TeamScores500Disadvantage[GetTeamIndexByTeamId(team)]; }
|
||||
|
||||
virtual Team GetPrematureWinner() override;
|
||||
private:
|
||||
/* Gameobject spawning/despawning */
|
||||
void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay);
|
||||
|
|
|
|||
|
|
@ -823,3 +823,17 @@ void BattleGroundAV::Reset()
|
|||
|
||||
InitNode(BG_AV_NODES_SNOWFALL_GRAVE, BG_AV_TEAM_NEUTRAL, false); // give snowfall neutral owner
|
||||
}
|
||||
|
||||
Team BattleGroundAV::GetPrematureWinner()
|
||||
{
|
||||
int32 hordeScore = m_TeamScores[TEAM_INDEX_HORDE];
|
||||
int32 allianceScore = m_TeamScores[TEAM_INDEX_ALLIANCE];
|
||||
|
||||
if (hordeScore > allianceScore)
|
||||
return HORDE;
|
||||
if (allianceScore > hordeScore)
|
||||
return ALLIANCE;
|
||||
|
||||
// If the values are equal, fall back to number of players on each team
|
||||
return BattleGround::GetPrematureWinner();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -359,6 +359,8 @@ class BattleGroundAV : public BattleGround
|
|||
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* plr) override;
|
||||
|
||||
static BattleGroundAVTeamIndex GetAVTeamIndexByTeamId(Team team) { return BattleGroundAVTeamIndex(GetTeamIndexByTeamId(team)); }
|
||||
|
||||
virtual Team GetPrematureWinner() override;
|
||||
private:
|
||||
/* Nodes occupying */
|
||||
void EventPlayerAssaultsPoint(Player* player, BG_AV_Nodes node);
|
||||
|
|
|
|||
|
|
@ -401,18 +401,6 @@ void BattleGroundEY::HandleKillPlayer(Player* player, Player* killer)
|
|||
|
||||
void BattleGroundEY::EventPlayerDroppedFlag(Player* source)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
{
|
||||
// if not running, do not cast things at the dropper player, neither send unnecessary messages
|
||||
// just take off the aura
|
||||
if (IsFlagPickedUp() && GetFlagCarrierGuid() == source->GetObjectGuid())
|
||||
{
|
||||
ClearFlagCarrier();
|
||||
source->RemoveAurasDueToSpell(EY_NETHERSTORM_FLAG_SPELL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsFlagPickedUp())
|
||||
return;
|
||||
|
||||
|
|
@ -421,6 +409,13 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player* source)
|
|||
|
||||
ClearFlagCarrier();
|
||||
source->RemoveAurasDueToSpell(EY_NETHERSTORM_FLAG_SPELL);
|
||||
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
{
|
||||
// do not cast auras or send messages after match has ended
|
||||
return;
|
||||
}
|
||||
|
||||
m_flagState = EY_FLAG_STATE_ON_GROUND;
|
||||
m_flagRespawnTimer = EY_FLAG_RESPAWN_TIME;
|
||||
source->CastSpell(source, SPELL_RECENTLY_DROPPED_FLAG, true);
|
||||
|
|
@ -429,12 +424,12 @@ void BattleGroundEY::EventPlayerDroppedFlag(Player* source)
|
|||
if (source->GetTeam() == ALLIANCE)
|
||||
{
|
||||
UpdateWorldState(WORLD_STATE_EY_NETHERSTORM_FLAG_STATE_ALLIANCE, 1);
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL);
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWorldState(WORLD_STATE_EY_NETHERSTORM_FLAG_STATE_HORDE, 1);
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL);
|
||||
SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -625,3 +620,17 @@ bool BattleGroundEY::IsAllNodesControlledByTeam(Team team) const
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
Team BattleGroundEY::GetPrematureWinner()
|
||||
{
|
||||
int32 hordeScore = m_TeamScores[TEAM_INDEX_HORDE];
|
||||
int32 allianceScore = m_TeamScores[TEAM_INDEX_ALLIANCE];
|
||||
|
||||
if (hordeScore > allianceScore)
|
||||
return HORDE;
|
||||
if (allianceScore > hordeScore)
|
||||
return ALLIANCE;
|
||||
|
||||
// If the values are equal, fall back to number of players on each team
|
||||
return BattleGround::GetPrematureWinner();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,6 +284,8 @@ class BattleGroundEY : public BattleGround
|
|||
/* achievement req. */
|
||||
bool IsAllNodesControlledByTeam(Team team) const override;
|
||||
|
||||
virtual Team GetPrematureWinner() override;
|
||||
|
||||
private:
|
||||
// process capture events
|
||||
void ProcessCaptureEvent(GameObject* go, uint32 towerId, Team team, uint32 newWorldState, uint32 message);
|
||||
|
|
|
|||
|
|
@ -652,3 +652,17 @@ void BattleGroundWS::FillInitialWorldStates(WorldPacket& data, uint32& count)
|
|||
FillInitialWorldState(data, count, BG_WS_TIME_ENABLED, WORLD_STATE_ADD);
|
||||
FillInitialWorldState(data, count, BG_WS_TIME_REMAINING, GetRemainingTimeInMinutes());
|
||||
}
|
||||
|
||||
Team BattleGroundWS::GetPrematureWinner()
|
||||
{
|
||||
int32 hordeScore = m_TeamScores[TEAM_INDEX_HORDE];
|
||||
int32 allianceScore = m_TeamScores[TEAM_INDEX_ALLIANCE];
|
||||
|
||||
if (hordeScore > allianceScore)
|
||||
return HORDE;
|
||||
if (allianceScore > hordeScore)
|
||||
return ALLIANCE;
|
||||
|
||||
// If the values are equal, fall back to number of players on each team
|
||||
return BattleGround::GetPrematureWinner();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ class BattleGroundWS : public BattleGround
|
|||
void ClearDroppedFlagGuid(Team team) { m_DroppedFlagGuid[GetTeamIndexByTeamId(team)].Clear();}
|
||||
ObjectGuid const& GetDroppedFlagGuid(Team team) const { return m_DroppedFlagGuid[GetTeamIndexByTeamId(team)];}
|
||||
virtual void FillInitialWorldStates(WorldPacket& data, uint32& count) override;
|
||||
|
||||
virtual Team GetPrematureWinner() override;
|
||||
|
||||
private:
|
||||
ObjectGuid m_flagCarrierAlliance;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
|
||||
#include "MoveMap.h" // for mmap manager
|
||||
#include "PathFinder.h" // for mmap commands
|
||||
#include "movement/MoveSplineInit.h"
|
||||
|
||||
static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
|
||||
{
|
||||
|
|
@ -2919,24 +2920,21 @@ inline void UnsummonVisualWaypoints(Player const* player, ObjectGuid ownerGuid)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a waypoint to a creature.
|
||||
/** Add a waypoint to a creature
|
||||
* .wp add [dbGuid] [pathId] [source]
|
||||
*
|
||||
* The user can either select an npc or provide its GUID.
|
||||
* The user can either select an npc or provide its dbGuid.
|
||||
* Also the user can specify pathId and source if wanted.
|
||||
*
|
||||
* The user can even select a visual waypoint - then the new waypoint
|
||||
* is placed *after* the selected one - this makes insertion of new
|
||||
* waypoints possible.
|
||||
*
|
||||
* eg:
|
||||
* .wp add 12345
|
||||
* -> adds a waypoint to the npc with the GUID 12345
|
||||
* .wp add [pathId] [source]
|
||||
* -> adds a waypoint to the currently selected creature, to path pathId in source-storage
|
||||
*
|
||||
* .wp add
|
||||
* -> adds a waypoint to the currently selected creature
|
||||
*
|
||||
*
|
||||
* @param args if the user did not provide a GUID, it is NULL
|
||||
* .wp add guid [pathId] [source]
|
||||
* -> if no npc is selected, expect the creature provided with guid argument
|
||||
*
|
||||
* @return true - command did succeed, false - something went wrong
|
||||
*/
|
||||
|
|
@ -3079,27 +3077,42 @@ bool ChatHandler::HandleWpAddCommand(char* args)
|
|||
PSendSysMessage(LANG_WAYPOINT_ADDED, wpPointId, wpOwner->GetGuidStr().c_str(), wpPathId, WaypointManager::GetOriginString(wpDestination).c_str());
|
||||
|
||||
return true;
|
||||
} // HandleWpAddCommand
|
||||
} // HandleWpAddCommand
|
||||
|
||||
/**
|
||||
* .wp modify emote | spell | text | del | move | add
|
||||
* .wp modify waittime | scriptid | orientation | del | move [dbGuid, id] [value]
|
||||
*
|
||||
* add -> add a WP after the selected visual waypoint
|
||||
* User must select a visual waypoint and then issue ".wp modify add"
|
||||
*
|
||||
* emote <emoteID>
|
||||
* waittime <Delay>
|
||||
* User has selected a visual waypoint before.
|
||||
* <emoteID> is added to this waypoint. Everytime the
|
||||
* NPC comes to this waypoint, the emote is called.
|
||||
* Delay <Delay> is added to this waypoint. Everytime the
|
||||
* NPC comes to this waypoint, it will wait Delay millieseconds.
|
||||
*
|
||||
* emote <GUID> <WPNUM> <emoteID>
|
||||
* waittime <DBGuid> <WPNUM> <Delay>
|
||||
* User has not selected visual waypoint before.
|
||||
* For the waypoint <WPNUM> for the NPC with <GUID>
|
||||
* an emote <emoteID> is added.
|
||||
* Everytime the NPC comes to this waypoint, the emote is called.
|
||||
* For the waypoint <WPNUM> for the NPC with <DBGuid>
|
||||
* an delay Delay is added to this waypoint
|
||||
* Everytime the NPC comes to this waypoint, it will wait Delay millieseconds.
|
||||
*
|
||||
* scriptid <scriptId>
|
||||
* User has selected a visual waypoint before.
|
||||
* <scriptId> is added to this waypoint. Everytime the
|
||||
* NPC comes to this waypoint, the DBScript scriptId is executed.
|
||||
*
|
||||
* info <GUID> <WPNUM> -> User did not select a visual waypoint and
|
||||
* scriptid <DBGuid> <WPNUM> <scriptId>
|
||||
* User has not selected visual waypoint before.
|
||||
* For the waypoint <WPNUM> for the NPC with <DBGuid>
|
||||
* an emote <scriptId> is added.
|
||||
* Everytime the NPC comes to this waypoint, the DBScript scriptId is executed.
|
||||
*
|
||||
* orientation [DBGuid, WpNum] <Orientation>
|
||||
* Set the orientation of the selected waypoint or waypoint given with DbGuid/ WpId
|
||||
* to the value of <Orientation>.
|
||||
*
|
||||
* del [DBGuid, WpId]
|
||||
* Remove the selected waypoint or waypoint given with DbGuid/ WpId.
|
||||
*
|
||||
* move [DBGuid, WpId]
|
||||
* Move the selected waypoint or waypoint given with DbGuid/ WpId to player's current positiion.
|
||||
*/
|
||||
bool ChatHandler::HandleWpModifyCommand(char* args)
|
||||
{
|
||||
|
|
@ -3303,29 +3316,19 @@ bool ChatHandler::HandleWpModifyCommand(char* args)
|
|||
}
|
||||
|
||||
/**
|
||||
* .wp show info | on | off
|
||||
* .wp show info | on | off | first | last [dbGuid] [pathId [wpOrigin] ]
|
||||
*
|
||||
* info -> User has selected a visual waypoint before
|
||||
*
|
||||
* info <GUID> <WPNUM> -> User did not select a visual waypoint and
|
||||
* provided the GUID of the NPC and the number of
|
||||
* the waypoint.
|
||||
*
|
||||
* on -> User has selected an NPC; all visual waypoints for this
|
||||
* NPC are added to the world
|
||||
*
|
||||
* on <GUID> -> User did not select an NPC - instead the GUID of the
|
||||
* on <dbGuid> -> User did not select an NPC - instead the dbGuid of the
|
||||
* NPC is provided. All visual waypoints for this NPC
|
||||
* are added from the world.
|
||||
*
|
||||
* off -> User has selected an NPC; all visual waypoints for this
|
||||
* NPC are removed from the world.
|
||||
*
|
||||
* on <GUID> -> User did not select an NPC - instead the GUID of the
|
||||
* NPC is provided. All visual waypoints for this NPC
|
||||
* are removed from the world.
|
||||
*
|
||||
*
|
||||
*/
|
||||
bool ChatHandler::HandleWpShowCommand(char* args)
|
||||
{
|
||||
|
|
@ -5071,20 +5074,53 @@ bool ChatHandler::HandleMmapPathCommand(char* args)
|
|||
char* para = strtok(args, " ");
|
||||
|
||||
bool useStraightPath = false;
|
||||
if (para && strcmp(para, "true") == 0)
|
||||
useStraightPath = true;
|
||||
bool followPath = false;
|
||||
bool unitToPlayer = false;
|
||||
if (para)
|
||||
{
|
||||
if (strcmp(para, "go") == 0)
|
||||
{
|
||||
followPath = true;
|
||||
para = strtok(nullptr, " ");
|
||||
if (para && strcmp(para, "straight") == 0)
|
||||
useStraightPath = true;
|
||||
}
|
||||
else if (strcmp(para, "straight") == 0)
|
||||
useStraightPath = true;
|
||||
else if (strcmp(para, "to_me") == 0)
|
||||
unitToPlayer = true;
|
||||
else
|
||||
{
|
||||
PSendSysMessage("Use '.mmap path go' to move on target.");
|
||||
PSendSysMessage("Use '.mmap path straight' to generate straight path.");
|
||||
PSendSysMessage("Use '.mmap path to_me' to generate path from the target to you.");
|
||||
}
|
||||
}
|
||||
|
||||
Unit* destinationUnit;
|
||||
Unit* originUnit;
|
||||
if (unitToPlayer)
|
||||
{
|
||||
destinationUnit = player;
|
||||
originUnit = target;
|
||||
}
|
||||
else
|
||||
{
|
||||
destinationUnit = target;
|
||||
originUnit = player;
|
||||
}
|
||||
|
||||
// unit locations
|
||||
float x, y, z;
|
||||
player->GetPosition(x, y, z);
|
||||
destinationUnit->GetPosition(x, y, z);
|
||||
|
||||
// path
|
||||
PathFinder path(target);
|
||||
PathFinder path(originUnit);
|
||||
path.setUseStrightPath(useStraightPath);
|
||||
path.calculate(x, y, z);
|
||||
|
||||
PointsArray pointPath = path.getPath();
|
||||
PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName());
|
||||
PSendSysMessage("%s's path to %s:", originUnit->GetName(), destinationUnit->GetName());
|
||||
PSendSysMessage("Building %s", useStraightPath ? "StraightPath" : "SmoothPath");
|
||||
PSendSysMessage("length " SIZEFMTD " type %u", pointPath.size(), path.getPathType());
|
||||
|
||||
|
|
@ -5099,13 +5135,15 @@ bool ChatHandler::HandleMmapPathCommand(char* args)
|
|||
if (!player->isGameMaster())
|
||||
PSendSysMessage("Enable GM mode to see the path points.");
|
||||
|
||||
// this entry visible only to GM's with "gm on"
|
||||
static const uint32 WAYPOINT_NPC_ENTRY = 1;
|
||||
Creature* wp = NULL;
|
||||
for (uint32 i = 0; i < pointPath.size(); ++i)
|
||||
player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
|
||||
|
||||
if (followPath)
|
||||
{
|
||||
wp = player->SummonCreature(WAYPOINT_NPC_ENTRY, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
|
||||
// TODO: make creature not sink/fall
|
||||
Movement::MoveSplineInit init(*player);
|
||||
init.MovebyPath(pointPath);
|
||||
init.SetWalk(false);
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -2302,7 +2302,7 @@ bool ChatHandler::HandleLearnAllCommand(char* /*args*/)
|
|||
int loop = 0;
|
||||
while (strcmp(allSpellList[loop], "0"))
|
||||
{
|
||||
uint32 spell = atol((char*)allSpellList[loop++]);
|
||||
uint32 spell = std::stoul((char*)allSpellList[loop++]);
|
||||
|
||||
if (m_session->GetPlayer()->HasSpell(spell))
|
||||
continue;
|
||||
|
|
@ -2345,7 +2345,7 @@ bool ChatHandler::HandleLearnAllGMCommand(char* /*args*/)
|
|||
uint16 gmSpellIter = 0;
|
||||
while (strcmp(gmSpellList[gmSpellIter], "0"))
|
||||
{
|
||||
uint32 spell = atol((char*)gmSpellList[gmSpellIter++]);
|
||||
uint32 spell = std::stoul((char*)gmSpellList[gmSpellIter++]);
|
||||
|
||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
|
||||
if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ bool ChatHandler::HandleDebugGetLootRecipientCommand(char* /*args*/)
|
|||
|
||||
bool ChatHandler::HandleDebugSendQuestInvalidMsgCommand(char* args)
|
||||
{
|
||||
uint32 msg = atol(args);
|
||||
uint32 msg = std::stoul(args);
|
||||
m_session->GetPlayer()->SendCanTakeQuestResponse(msg);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ PathFinder::PathFinder(const Unit* owner) :
|
|||
DEBUG_FILTER_LOG(LOG_FILTER_PATHFINDING, "++ PathFinder::PathInfo for %u \n", m_sourceUnit->GetGUIDLow());
|
||||
|
||||
uint32 mapId = m_sourceUnit->GetMapId();
|
||||
if (MMAP::MMapFactory::IsPathfindingEnabled(mapId))
|
||||
if (MMAP::MMapFactory::IsPathfindingEnabled(mapId, owner))
|
||||
{
|
||||
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
|
||||
m_navMesh = mmap->GetNavMesh(mapId);
|
||||
|
|
|
|||
|
|
@ -1810,17 +1810,26 @@ void Creature::SetLootStatus(CreatureLootStatus status)
|
|||
}
|
||||
}
|
||||
|
||||
// return true if this creature is tapped by the player or by a member of his group.
|
||||
bool Creature::IsTappedBy(Player const* player) const
|
||||
// simple tap system return true if player or his group tapped the creature
|
||||
// TODO:: this is semi correct. For group situation need more work but its not a big issue
|
||||
bool Creature::IsTappedBy(Player* plr) const
|
||||
{
|
||||
if (player == GetOriginalLootRecipient())
|
||||
return true;
|
||||
if (Player* recipient = GetLootRecipient())
|
||||
{
|
||||
if (recipient == plr)
|
||||
return true;
|
||||
|
||||
Group const* playerGroup = player->GetGroup();
|
||||
if (!playerGroup || playerGroup != GetGroupLootRecipient()) // if we dont have a group we arent the recipient
|
||||
return false; // if creature doesnt have group bound it means it was solo killed by someone else
|
||||
|
||||
return true;
|
||||
if (Group* grp = recipient->GetGroup())
|
||||
{
|
||||
if (Group* plrGroup = plr->GetGroup())
|
||||
{
|
||||
if (plrGroup == grp)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
SpellEntry const* Creature::ReachWithSpellAttack(Unit* pVictim)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ enum CreatureFlagsExtra
|
|||
CREATURE_EXTRA_FLAG_MMAP_FORCE_DISABLE = 0x00004000, // creature is forced to NOT use MMaps
|
||||
CREATURE_EXTRA_FLAG_WALK_IN_WATER = 0x00008000, // creature is forced to walk in water even it can swim
|
||||
CREATURE_EXTRA_FLAG_HAVE_NO_SWIM_ANIMATION = 0x00010000, // we have to not set "swim" animation or creature will have "no animation"
|
||||
CREATURE_EXTRA_FLAG_NO_MELEE = 0x00020000, // creature can't melee
|
||||
};
|
||||
|
||||
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
|
||||
|
|
@ -561,7 +562,7 @@ class Creature : public Unit
|
|||
bool IsImmuneToSpell(SpellEntry const* spellInfo, bool castOnSelf) override;
|
||||
bool IsImmuneToSpellEffect(SpellEntry const* spellInfo, SpellEffectIndex index, bool castOnSelf) const override;
|
||||
void SetLootStatus(CreatureLootStatus status);
|
||||
bool IsTappedBy(Player const* player) const;
|
||||
bool IsTappedBy(Player* plr) const;
|
||||
|
||||
bool IsElite() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -79,6 +79,10 @@ GameObject::GameObject() : WorldObject(),
|
|||
m_groupLootTimer = 0;
|
||||
m_groupLootId = 0;
|
||||
m_lootGroupRecipientId = 0;
|
||||
|
||||
m_isInUse = false;
|
||||
m_reStockTimer = 0;
|
||||
m_despawnTimer = 0;
|
||||
}
|
||||
|
||||
GameObject::~GameObject()
|
||||
|
|
@ -1951,6 +1955,7 @@ void GameObject::SetLootRecipient(Unit* pUnit)
|
|||
{
|
||||
m_lootRecipientGuid.Clear();
|
||||
m_lootGroupRecipientId = 0;
|
||||
ForceValuesUpdateAtIndex(UNIT_DYNAMIC_FLAGS); // needed to be sure tapping status is updated
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1964,6 +1969,8 @@ void GameObject::SetLootRecipient(Unit* pUnit)
|
|||
// set group for group existed case including if player will leave group at loot time
|
||||
if (Group* group = player->GetGroup())
|
||||
{ m_lootGroupRecipientId = group->GetId(); }
|
||||
|
||||
ForceValuesUpdateAtIndex(UNIT_DYNAMIC_FLAGS); // needed to be sure tapping status is updated
|
||||
}
|
||||
|
||||
float GameObject::GetObjectBoundingRadius() const
|
||||
|
|
@ -2402,6 +2409,15 @@ float GameObject::GetInteractionDistance()
|
|||
}
|
||||
}
|
||||
|
||||
void GameObject::SetInUse(bool use)
|
||||
{
|
||||
m_isInUse = use;
|
||||
if (use)
|
||||
SetGoState(GO_STATE_ACTIVE);
|
||||
else
|
||||
SetGoState(GO_STATE_READY);
|
||||
}
|
||||
|
||||
uint32 GameObject::GetScriptId()
|
||||
{
|
||||
return sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, -int32(GetGUIDLow())) ? sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, -int32(GetGUIDLow())) : sScriptMgr.GetBoundScriptId(SCRIPTED_GAMEOBJECT, GetEntry());
|
||||
|
|
|
|||
|
|
@ -749,6 +749,8 @@ class GameObject : public WorldObject
|
|||
|
||||
void AddUniqueUse(Player* player);
|
||||
void AddUse() { ++m_useTimes; }
|
||||
bool IsInUse() const { return m_isInUse; }
|
||||
void SetInUse(bool use);
|
||||
|
||||
uint32 GetUseCount() const { return m_useTimes; }
|
||||
uint32 GetUniqueUseCount() const { return m_UniqueUsers.size(); }
|
||||
|
|
|
|||
|
|
@ -800,7 +800,7 @@ bool Object::LoadValues(const char* data)
|
|||
int index;
|
||||
for (iter = tokens.begin(), index = 0; index < m_valuesCount; ++iter, ++index)
|
||||
{
|
||||
m_uint32Values[index] = atol((*iter).c_str());
|
||||
m_uint32Values[index] = std::stoul((*iter).c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1119,6 +1119,16 @@ void Object::MarkForClientUpdate()
|
|||
}
|
||||
}
|
||||
|
||||
void Object::ForceValuesUpdateAtIndex(uint32 index)
|
||||
{
|
||||
m_changedValues[index] = true;
|
||||
if (m_inWorld && !m_objectUpdated)
|
||||
{
|
||||
AddToClientUpdateList();
|
||||
m_objectUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
WorldObject::WorldObject() :
|
||||
#ifdef ENABLE_ELUNA
|
||||
elunaEvents(NULL),
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ class Object
|
|||
void SetGuidValue(uint16 index, ObjectGuid const& value) { SetUInt64Value(index, value.GetRawValue()); }
|
||||
void SetStatFloatValue(uint16 index, float value);
|
||||
void SetStatInt32Value(uint16 index, int32 value);
|
||||
void ForceValuesUpdateAtIndex(uint32 index);
|
||||
|
||||
void ApplyModUInt32Value(uint16 index, int32 val, bool apply);
|
||||
void ApplyModInt32Value(uint16 index, int32 val, bool apply);
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ void PlayerTaxi::LoadTaxiMask(const char* data)
|
|||
(index < TaxiMaskSize) && (iter != tokens.end()); ++iter, ++index)
|
||||
{
|
||||
// load and set bits only for existing taxi nodes
|
||||
m_taximask[index] = sTaxiNodesMask[index] & uint8(atol((*iter).c_str()));
|
||||
m_taximask[index] = sTaxiNodesMask[index] & uint8(std::stoul((*iter).c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +218,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, Team
|
|||
|
||||
for (Tokens::iterator iter = tokens.begin(); iter != tokens.end(); ++iter)
|
||||
{
|
||||
uint32 node = uint32(atol(iter->c_str()));
|
||||
uint32 node = std::stoul(iter->c_str());
|
||||
AddTaxiDestination(node);
|
||||
}
|
||||
|
||||
|
|
@ -2358,23 +2358,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, uint32 gameo
|
|||
{
|
||||
if (uint32(go->GetGoType()) == gameobject_type || gameobject_type == MAX_GAMEOBJECT_TYPE)
|
||||
{
|
||||
float maxdist;
|
||||
switch (go->GetGoType())
|
||||
{
|
||||
// TODO: find out how the client calculates the maximal usage distance to spellless working
|
||||
// gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
|
||||
case GAMEOBJECT_TYPE_GUILD_BANK:
|
||||
case GAMEOBJECT_TYPE_MAILBOX:
|
||||
maxdist = 10.0f;
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_FISHINGHOLE:
|
||||
maxdist = 20.0f + CONTACT_DISTANCE; // max spell range
|
||||
break;
|
||||
default:
|
||||
maxdist = INTERACTION_DISTANCE;
|
||||
break;
|
||||
}
|
||||
|
||||
float maxdist = go->GetInteractionDistance();
|
||||
if (go->IsWithinDistInMap(this, maxdist) && go->isSpawned())
|
||||
return go;
|
||||
|
||||
|
|
@ -5543,6 +5527,10 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
|
|||
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
|
||||
return false;
|
||||
|
||||
SkillStatusData& skillStatus = itr->second;
|
||||
if (skillStatus.uState == SKILL_DELETED)
|
||||
return false;
|
||||
|
||||
uint16 field = itr->second.pos / 2;
|
||||
uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
|
||||
|
||||
|
|
@ -15349,7 +15337,7 @@ void Player::_LoadIntoDataField(const char* data, uint32 startOffset, uint32 cou
|
|||
uint32 index;
|
||||
for (iter = tokens.begin(), index = 0; index < count; ++iter, ++index)
|
||||
{
|
||||
m_uint32Values[startOffset + index] = atol((*iter).c_str());
|
||||
m_uint32Values[startOffset + index] = std::stoul((*iter).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2076,36 +2076,40 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
|||
// This seems to reduce the victims time until next attack if your attack was parried
|
||||
if (damageInfo->TargetState == VICTIMSTATE_PARRY)
|
||||
{
|
||||
// Get attack timers
|
||||
float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
|
||||
float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
|
||||
// Reduce attack time
|
||||
if (pVictim->haveOffhandWeapon() && offtime < basetime)
|
||||
if (pVictim->GetTypeId() != TYPEID_UNIT ||
|
||||
!(((Creature*)pVictim)->GetCreatureInfo()->ExtraFlags & CREATURE_EXTRA_FLAG_NO_PARRY_HASTEN))
|
||||
{
|
||||
float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20f;
|
||||
float percent60 = 3.0f * percent20;
|
||||
if (offtime > percent20 && offtime <= percent60)
|
||||
// Get attack timers
|
||||
float offtime = float(pVictim->getAttackTimer(OFF_ATTACK));
|
||||
float basetime = float(pVictim->getAttackTimer(BASE_ATTACK));
|
||||
// Reduce attack time
|
||||
if (pVictim->haveOffhandWeapon() && offtime < basetime)
|
||||
{
|
||||
pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
|
||||
float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20f;
|
||||
float percent60 = 3.0f * percent20;
|
||||
if (offtime > percent20 && offtime <= percent60)
|
||||
{
|
||||
pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20));
|
||||
}
|
||||
else if (offtime > percent60)
|
||||
{
|
||||
offtime -= 2.0f * percent20;
|
||||
pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
|
||||
}
|
||||
}
|
||||
else if (offtime > percent60)
|
||||
else
|
||||
{
|
||||
offtime -= 2.0f * percent20;
|
||||
pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20f;
|
||||
float percent60 = 3.0f * percent20;
|
||||
if (basetime > percent20 && basetime <= percent60)
|
||||
{
|
||||
pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
|
||||
}
|
||||
else if (basetime > percent60)
|
||||
{
|
||||
basetime -= 2.0f * percent20;
|
||||
pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
|
||||
float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20f;
|
||||
float percent60 = 3.0f * percent20;
|
||||
if (basetime > percent20 && basetime <= percent60)
|
||||
{
|
||||
pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20));
|
||||
}
|
||||
else if (basetime > percent60)
|
||||
{
|
||||
basetime -= 2.0f * percent20;
|
||||
pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10736,9 +10740,9 @@ void CharmInfo::LoadPetActionBar(const std::string& data)
|
|||
for (iter = tokens.begin(), index = ACTION_BAR_INDEX_START; index < ACTION_BAR_INDEX_END; ++iter, ++index)
|
||||
{
|
||||
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
|
||||
uint8 type = (uint8)atol((*iter).c_str());
|
||||
uint8 type = (uint8)std::stoul((*iter).c_str());
|
||||
++iter;
|
||||
uint32 action = atol((*iter).c_str());
|
||||
uint32 action = std::stoul((*iter).c_str());
|
||||
|
||||
PetActionBar[index].SetActionAndType(action, ActiveStates(type));
|
||||
|
||||
|
|
|
|||
|
|
@ -791,6 +791,7 @@ class MovementInfo
|
|||
void ChangeOrientation(float o) { pos.o = o; }
|
||||
void ChangePosition(float x, float y, float z, float o) { pos.x = x; pos.y = y; pos.z = z; pos.o = o; }
|
||||
void UpdateTime(uint32 _time) { time = _time; }
|
||||
uint32 GetTime(){ return time; }
|
||||
|
||||
struct JumpInfo
|
||||
{
|
||||
|
|
|
|||
|
|
@ -465,11 +465,12 @@ enum TotemCategoryType
|
|||
// SummonProperties.dbc, col 1 == Group (m_control)
|
||||
enum SummonPropGroup
|
||||
{
|
||||
SUMMON_PROP_GROUP_WILD = 0,
|
||||
SUMMON_PROP_GROUP_FRIENDLY = 1,
|
||||
SUMMON_PROP_GROUP_PETS = 2,
|
||||
SUMMON_PROP_GROUP_CONTROLLABLE = 3,
|
||||
SUMMON_PROP_GROUP_VEHICLE = 4
|
||||
SUMMON_PROP_GROUP_WILD = 0,
|
||||
SUMMON_PROP_GROUP_FRIENDLY = 1,
|
||||
SUMMON_PROP_GROUP_PETS = 2,
|
||||
SUMMON_PROP_GROUP_CONTROLLABLE = 3,
|
||||
SUMMON_PROP_GROUP_VEHICLE = 4,
|
||||
SUMMON_PROP_GROUP_UNCONTROLLABLE_VEHICLE = 5
|
||||
};
|
||||
|
||||
// SummonProperties.dbc, col 2 == FactionId (m_faction)
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
|
|||
m_muteTime(mute_time), _player(NULL), m_Socket(sock), _security(sec), _accountId(id), m_expansion(expansion), _logoutTime(0),
|
||||
m_inQueue(false), m_playerLoading(false), m_playerLogout(false), m_playerRecentlyLogout(false), m_playerSave(false),
|
||||
m_sessionDbcLocale(sWorld.GetAvailableDbcLocale(locale)), m_sessionDbLocaleIndex(sObjectMgr.GetIndexForLocale(locale)),
|
||||
m_latency(0), m_tutorialState(TUTORIALDATA_UNCHANGED)
|
||||
m_latency(0), m_clientTimeDelay(0), m_tutorialState(TUTORIALDATA_UNCHANGED)
|
||||
{
|
||||
if (sock)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -462,6 +462,7 @@ class WorldSession
|
|||
m_latency = latency;
|
||||
}
|
||||
void SetClientTimeDelay(uint32 delay) { m_clientTimeDelay = delay; }
|
||||
void ResetClientTimeDelay() { m_clientTimeDelay = 0; }
|
||||
uint32 getDialogStatus(Player* pPlayer, Object* questgiver, uint32 defstatus);
|
||||
|
||||
public: // opcodes handlers
|
||||
|
|
@ -1015,10 +1016,10 @@ class WorldSession
|
|||
LocaleConstant m_sessionDbcLocale;
|
||||
int m_sessionDbLocaleIndex;
|
||||
uint32 m_latency;
|
||||
uint32 m_clientTimeDelay;
|
||||
AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
|
||||
uint32 m_Tutorials[8];
|
||||
TutorialDataState m_tutorialState;
|
||||
uint32 m_clientTimeDelay;
|
||||
AddonsList m_addonsList;
|
||||
ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1051,17 +1051,18 @@ int WorldSocket::HandlePing(WorldPacket& recvPacket)
|
|||
|
||||
// critical section
|
||||
{
|
||||
ACE_GUARD_RETURN(LockType, Guard, m_SessionLock, -1);
|
||||
|
||||
if (m_Session)
|
||||
{
|
||||
m_Session->SetLatency(latency);
|
||||
m_Session->ResetClientTimeDelay();
|
||||
}
|
||||
else
|
||||
{
|
||||
sLog.outError("WorldSocket::HandlePing: peer sent CMSG_PING, "
|
||||
"but is not authenticated or got recently kicked,"
|
||||
" address = %s",
|
||||
GetRemoteAddress().c_str());
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ GridMap::GridMap()
|
|||
m_gridGetHeight = &GridMap::getHeightFromFlat;
|
||||
m_V9 = NULL;
|
||||
m_V8 = NULL;
|
||||
memset(m_holes, 0, sizeof(m_holes));
|
||||
|
||||
// Liquid data
|
||||
m_liquidType = 0;
|
||||
|
|
@ -205,6 +206,16 @@ bool GridMap::loadHeightData(FILE* in, uint32 offset, uint32 /*size*/)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GridMap::loadHolesData(FILE* in, uint32 offset, uint32 size)
|
||||
{
|
||||
if (fseek(in, offset, SEEK_SET) != 0)
|
||||
return false;
|
||||
|
||||
if (fread(&m_holes, sizeof(m_holes), 1, in) != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GridMap::loadGridMapLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
|
||||
{
|
||||
GridMapLiquidHeader header;
|
||||
|
|
@ -255,10 +266,22 @@ float GridMap::getHeightFromFlat(float /*x*/, float /*y*/) const
|
|||
return m_gridHeight;
|
||||
}
|
||||
|
||||
bool GridMap::isHole(int row, int col) const
|
||||
{
|
||||
int cellRow = row / 8; // 8 squares per cell
|
||||
int cellCol = col / 8;
|
||||
int holeRow = row % 8 / 2;
|
||||
int holeCol = (col - (cellCol * 8)) / 2;
|
||||
|
||||
uint16 hole = m_holes[cellRow][cellCol];
|
||||
|
||||
return (hole & holetab_h[holeCol] & holetab_v[holeRow]) != 0;
|
||||
}
|
||||
|
||||
float GridMap::getHeightFromFloat(float x, float y) const
|
||||
{
|
||||
if (!m_V8 || !m_V9)
|
||||
return m_gridHeight;
|
||||
return INVALID_HEIGHT_VALUE;
|
||||
|
||||
x = MAP_RESOLUTION * (32 - x / SIZE_OF_GRIDS);
|
||||
y = MAP_RESOLUTION * (32 - y / SIZE_OF_GRIDS);
|
||||
|
|
@ -270,6 +293,9 @@ float GridMap::getHeightFromFloat(float x, float y) const
|
|||
x_int &= (MAP_RESOLUTION - 1);
|
||||
y_int &= (MAP_RESOLUTION - 1);
|
||||
|
||||
if (isHole(x_int, y_int))
|
||||
return INVALID_HEIGHT_VALUE;
|
||||
|
||||
// Height stored as: h5 - its v8 grid, h1-h4 - its v9 grid
|
||||
// +--------------> X
|
||||
// | h1-------h2 Coordinates is:
|
||||
|
|
|
|||
|
|
@ -126,7 +126,8 @@ struct GridMapLiquidData
|
|||
class GridMap
|
||||
{
|
||||
private:
|
||||
|
||||
|
||||
uint16 m_holes[16][16];
|
||||
uint32 m_flags;
|
||||
|
||||
// Area data
|
||||
|
|
@ -163,6 +164,8 @@ class GridMap
|
|||
bool loadAreaData(FILE* in, uint32 offset, uint32 size);
|
||||
bool loadHeightData(FILE* in, uint32 offset, uint32 size);
|
||||
bool loadGridMapLiquidData(FILE* in, uint32 offset, uint32 size);
|
||||
bool loadHolesData(FILE* in, uint32 offset, uint32 size);
|
||||
bool isHole(int row, int col) const;
|
||||
|
||||
// Get height functions and pointers
|
||||
typedef float(GridMap::*pGetHeightPtr)(float x, float y) const;
|
||||
|
|
|
|||
|
|
@ -84,8 +84,6 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recv_data)
|
|||
DEBUG_LOG("WORLD: Received opcode CMSG_WHO");
|
||||
// recv_data.hexlike();
|
||||
|
||||
uint32 clientcount = 0;
|
||||
|
||||
uint32 level_min, level_max, racemask, classmask, zones_count, str_count;
|
||||
uint32 zoneids[10]; // 10 is client limit
|
||||
std::string player_name, guild_name;
|
||||
|
|
@ -149,9 +147,12 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recv_data)
|
|||
bool allowTwoSideWhoList = sWorld.getConfig(CONFIG_BOOL_ALLOW_TWO_SIDE_WHO_LIST);
|
||||
AccountTypes gmLevelInWhoList = (AccountTypes)sWorld.getConfig(CONFIG_UINT32_GM_LEVEL_IN_WHO_LIST);
|
||||
|
||||
uint32 matchcount = 0;
|
||||
uint32 displaycount = 0;
|
||||
|
||||
WorldPacket data(SMSG_WHO, 50); // guess size
|
||||
data << uint32(clientcount); // clientcount place holder, listed count
|
||||
data << uint32(clientcount); // clientcount place holder, online count
|
||||
data << uint32(matchcount); // clientcount place holder, listed count
|
||||
data << uint32(displaycount); // clientcount place holder, online count
|
||||
|
||||
// TODO: Guard Player map
|
||||
HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers();
|
||||
|
|
@ -250,6 +251,8 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recv_data)
|
|||
if (!s_show)
|
||||
continue;
|
||||
|
||||
++displaycount;
|
||||
|
||||
data << pname; // player name
|
||||
data << gname; // guild name
|
||||
data << uint32(lvl); // player level
|
||||
|
|
@ -257,15 +260,13 @@ void WorldSession::HandleWhoOpcode(WorldPacket& recv_data)
|
|||
data << uint32(race); // player race
|
||||
data << uint8(gender); // player gender
|
||||
data << uint32(pzoneid); // player zone id
|
||||
|
||||
// 50 is maximum player count sent to client
|
||||
if ((++clientcount) == 50)
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 count = m.size();
|
||||
data.put(0, clientcount); // insert right count, listed count
|
||||
data.put(4, count > 50 ? count : clientcount); // insert right count, online count
|
||||
if (sWorld.getConfig(CONFIG_UINT32_MAX_WHOLIST_RETURNS) && matchcount > sWorld.getConfig(CONFIG_UINT32_MAX_WHOLIST_RETURNS))
|
||||
matchcount = sWorld.getConfig(CONFIG_UINT32_MAX_WHOLIST_RETURNS);
|
||||
|
||||
data.put(0, displaycount); // insert right count, count displayed
|
||||
data.put(4, matchcount); // insert right count, count of matches
|
||||
|
||||
SendPacket(&data);
|
||||
DEBUG_LOG("WORLD: Send SMSG_WHO Message");
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "GridMap.h"
|
||||
#include "Log.h"
|
||||
#include "World.h"
|
||||
#include "Creature.h"
|
||||
|
||||
#include "MoveMap.h"
|
||||
#include "MoveMapSharedDefines.h"
|
||||
|
|
@ -65,10 +66,30 @@ namespace MMAP
|
|||
delete[] mapList;
|
||||
}
|
||||
|
||||
bool MMapFactory::IsPathfindingEnabled(uint32 mapId)
|
||||
bool MMapFactory::IsPathfindingEnabled(uint32 mapId, const Unit* unit = nullptr)
|
||||
{
|
||||
return sWorld.getConfig(CONFIG_BOOL_MMAP_ENABLED)
|
||||
&& g_mmapDisabledIds->find(mapId) == g_mmapDisabledIds->end();
|
||||
if (!sWorld.getConfig(CONFIG_BOOL_MMAP_ENABLED))
|
||||
return false;
|
||||
|
||||
if (unit)
|
||||
{
|
||||
// always use mmaps for players
|
||||
if (unit->GetTypeId() == TYPEID_PLAYER)
|
||||
return true;
|
||||
|
||||
if (IsPathfindingForceDisabled(unit))
|
||||
return false;
|
||||
|
||||
if (IsPathfindingForceEnabled(unit))
|
||||
return true;
|
||||
|
||||
// always use mmaps for pets of players (can still be disabled by extra-flag for pet creature)
|
||||
if (unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->IsPet() && unit->GetOwner() &&
|
||||
unit->GetOwner()->GetTypeId() == TYPEID_PLAYER)
|
||||
return true;
|
||||
}
|
||||
|
||||
return g_mmapDisabledIds->find(mapId) == g_mmapDisabledIds->end();
|
||||
}
|
||||
|
||||
void MMapFactory::clear()
|
||||
|
|
@ -80,6 +101,34 @@ namespace MMAP
|
|||
g_MMapManager = NULL;
|
||||
}
|
||||
|
||||
bool MMapFactory::IsPathfindingForceEnabled(const Unit* unit)
|
||||
{
|
||||
if (const Creature* pCreature = dynamic_cast<const Creature*>(unit))
|
||||
{
|
||||
if (const CreatureInfo* pInfo = pCreature->GetCreatureInfo())
|
||||
{
|
||||
if (pInfo->ExtraFlags & CREATURE_EXTRA_FLAG_MMAP_FORCE_ENABLE)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MMapFactory::IsPathfindingForceDisabled(const Unit* unit)
|
||||
{
|
||||
if (const Creature* pCreature = dynamic_cast<const Creature*>(unit))
|
||||
{
|
||||
if (const CreatureInfo* pInfo = pCreature->GetCreatureInfo())
|
||||
{
|
||||
if (pInfo->ExtraFlags & CREATURE_EXTRA_FLAG_MMAP_FORCE_DISABLE)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ######################## MMapManager ########################
|
||||
MMapManager::~MMapManager()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include "../../dep/recastnavigation/Detour/Include/DetourNavMesh.h"
|
||||
#include "../../dep/recastnavigation/Detour/Include/DetourNavMeshQuery.h"
|
||||
|
||||
class Unit;
|
||||
|
||||
// memory management
|
||||
inline void* dtCustomAlloc(int size, dtAllocHint /*hint*/)
|
||||
{
|
||||
|
|
@ -107,7 +109,9 @@ namespace MMAP
|
|||
static MMapManager* createOrGetMMapManager();
|
||||
static void clear();
|
||||
static void preventPathfindingOnMaps(const char* ignoreMapIds);
|
||||
static bool IsPathfindingEnabled(uint32 mapId);
|
||||
static bool IsPathfindingEnabled(uint32 mapId, const Unit* unit);
|
||||
static bool IsPathfindingForceEnabled(const Unit* unit);
|
||||
static bool IsPathfindingForceDisabled(const Unit* unit);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "MapPersistentStateMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
||||
#define MOVEMENT_PACKET_TIME_DELAY 0
|
||||
|
||||
void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
DEBUG_LOG("WORLD: got MSG_MOVE_WORLDPORT_ACK.");
|
||||
|
|
@ -595,7 +597,9 @@ bool WorldSession::VerifyMovementInfo(MovementInfo const& movementInfo, ObjectGu
|
|||
|
||||
void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo)
|
||||
{
|
||||
movementInfo.UpdateTime(WorldTimer::getMSTime());
|
||||
if (m_clientTimeDelay == 0)
|
||||
m_clientTimeDelay = WorldTimer::getMSTime() - movementInfo.GetTime();
|
||||
movementInfo.UpdateTime(movementInfo.GetTime() + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY);
|
||||
|
||||
Unit* mover = _player->GetMover();
|
||||
|
||||
|
|
|
|||
|
|
@ -702,7 +702,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_SEND_AI_EVENT_AROUND: // 35
|
||||
case SCRIPT_COMMAND_SEND_AI_EVENT: // 35
|
||||
{
|
||||
if (tmp.sendAIEvent.eventType >= MAXIMAL_AI_EVENT_EVENTAI)
|
||||
{
|
||||
|
|
@ -717,7 +717,7 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
{
|
||||
if (tmp.moveDynamic.maxDist < tmp.moveDynamic.minDist)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid min-dist (datalong2 = %u) less than max-dist (datalon = %u) in SCRIPT_COMMAND_MOVE_DYNAMIC for script id %u", tablename, tmp.moveDynamic.minDist, tmp.moveDynamic.maxDist, tmp.id);
|
||||
sLog.outErrorDb("Table `%s` has invalid min-dist (datalong2 = %u) less than max-dist (datalong = %u) in SCRIPT_COMMAND_MOVE_DYNAMIC for script id %u", tablename, tmp.moveDynamic.minDist, tmp.moveDynamic.maxDist, tmp.id);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
@ -736,7 +736,36 @@ void ScriptMgr::LoadScripts(ScriptMapMapName& scripts, const char* tablename)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_CHANGE_ENTRY: // 39
|
||||
case SCRIPT_COMMAND_SET_FLY: // 39
|
||||
case SCRIPT_COMMAND_DESPAWN_GO: // 40
|
||||
case SCRIPT_COMMAND_RESPAWN: // 41
|
||||
break;
|
||||
case SCRIPT_COMMAND_SET_EQUIPMENT_SLOTS: // 42
|
||||
{
|
||||
if (tmp.textId[0] < 0 || tmp.textId[1] < 0 || tmp.textId[2] < 0)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid equipment slot (dataint = %u, dataint2 = %u, dataint3 = %u) in SCRIPT_COMMAND_SET_EQUIPMENT_SLOTS for script id %u", tablename, tmp.textId[0], tmp.textId[1], tmp.textId[2], tmp.id);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_RESET_GO: // 43
|
||||
break;
|
||||
case SCRIPT_COMMAND_UPDATE_TEMPLATE: // 44
|
||||
{
|
||||
if (!sCreatureStorage.LookupEntry<CreatureInfo>(tmp.updateTemplate.newTemplate))
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` uses nonexistent creature entry %u in SCRIPT_COMMAND_UPDATE_TEMPLATE for script id %u.", tablename, tmp.updateTemplate.newTemplate, tmp.id);
|
||||
continue;
|
||||
}
|
||||
if (tmp.updateTemplate.newFactionTeam != 0 && tmp.updateTemplate.newFactionTeam != 1)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` uses nonexistent faction team %u in SCRIPT_COMMAND_UPDATE_TEMPLATE for script id %u.", tablename, tmp.updateTemplate.newFactionTeam, tmp.id);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_CHANGE_ENTRY: // 45
|
||||
{
|
||||
if (tmp.changeEntry.creatureEntry && !ObjectMgr::GetCreatureTemplate(tmp.changeEntry.creatureEntry))
|
||||
{
|
||||
|
|
@ -1048,15 +1077,24 @@ bool ScriptAction::GetScriptProcessTargets(WorldObject* pOrigSource, WorldObject
|
|||
|
||||
if (m_script->IsCreatureBuddy())
|
||||
{
|
||||
Creature* pCreatureBuddy = NULL;
|
||||
Creature* pCreatureBuddy = nullptr;
|
||||
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSearcher, m_script->buddyEntry, true, false, m_script->searchRadiusOrGuid, true);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreatureBuddy, u_check);
|
||||
if (m_script->data_flags & SCRIPT_FLAG_BUDDY_IS_DESPAWNED)
|
||||
{
|
||||
MaNGOS::AllCreaturesOfEntryInRangeCheck u_check(pSearcher, m_script->buddyEntry, m_script->searchRadiusOrGuid);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::AllCreaturesOfEntryInRangeCheck> searcher(pCreatureBuddy, u_check);
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadiusOrGuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*pSearcher, m_script->buddyEntry, true, false, m_script->searchRadiusOrGuid, true);
|
||||
MaNGOS::CreatureLastSearcher<MaNGOS::NearestCreatureEntryWithLiveStateInObjectRangeCheck> searcher(pCreatureBuddy, u_check);
|
||||
|
||||
if (m_script->data_flags & SCRIPT_FLAG_BUDDY_IS_PET)
|
||||
{ Cell::VisitWorldObjects(pSearcher, searcher, m_script->searchRadiusOrGuid); }
|
||||
else // Normal Creature
|
||||
{ Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadiusOrGuid); }
|
||||
if (m_script->data_flags & SCRIPT_FLAG_BUDDY_IS_PET)
|
||||
Cell::VisitWorldObjects(pSearcher, searcher, m_script->searchRadiusOrGuid);
|
||||
else // Normal Creature
|
||||
Cell::VisitGridObjects(pSearcher, searcher, m_script->searchRadiusOrGuid);
|
||||
}
|
||||
|
||||
pBuddy = pCreatureBuddy;
|
||||
|
||||
|
|
@ -1894,55 +1932,80 @@ bool ScriptAction::HandleScriptStep()
|
|||
}
|
||||
return terminateResult;
|
||||
}
|
||||
case SCRIPT_COMMAND_SEND_AI_EVENT_AROUND: // 35
|
||||
case SCRIPT_COMMAND_SEND_AI_EVENT: // 35
|
||||
{
|
||||
if (LogIfNotCreature(pSource))
|
||||
return false;
|
||||
if (LogIfNotUnit(pTarget))
|
||||
break;
|
||||
|
||||
((Creature*)pSource)->AI()->SendAIEventAround(AIEventType(m_script->sendAIEvent.eventType), (Unit*)pTarget, 0, float(m_script->sendAIEvent.radius));
|
||||
// if radius is provided send AI event around
|
||||
if (m_script->sendAIEvent.radius)
|
||||
((Creature*)pSource)->AI()->SendAIEventAround(AIEventType(m_script->sendAIEvent.eventType), (Unit*)pTarget, 0, float(m_script->sendAIEvent.radius));
|
||||
// else if no radius and target is creature send AI event to target
|
||||
else if (pTarget->GetTypeId() == TYPEID_UNIT)
|
||||
((Creature*)pSource)->AI()->SendAIEvent(AIEventType(m_script->sendAIEvent.eventType), nullptr, (Creature*)pTarget);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_TURN_TO: // 36
|
||||
case SCRIPT_COMMAND_TURN_TO: // 36
|
||||
{
|
||||
if (LogIfNotUnit(pSource))
|
||||
{ break; }
|
||||
if (LogIfNotCreature(pSource))
|
||||
return false;
|
||||
Creature* pCSource = static_cast<Creature*>(pSource);
|
||||
if (!pTarget)
|
||||
{
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command _SET_FACING (%u): No target found.", m_table, m_script->id, m_script->command);
|
||||
return false;
|
||||
}
|
||||
if (m_script->turnTo.targetId)
|
||||
{
|
||||
float x, y, z, o;
|
||||
if (pCSource->GetMotionMaster()->empty() || !pCSource->GetMotionMaster()->top()->GetResetPosition(*pCSource, x, y, z, o))
|
||||
pCSource->GetRespawnCoord(x, y, z, &o);
|
||||
pCSource->SetFacingTo(o);
|
||||
|
||||
((Unit*)pSource)->SetFacingTo(pSource->GetAngle(pTarget));
|
||||
if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL && !pCSource->IsInCombat())
|
||||
pCSource->SetTargetGuid(ObjectGuid());
|
||||
}
|
||||
else
|
||||
{
|
||||
pCSource->SetFacingToObject(pTarget);
|
||||
if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL && !LogIfNotUnit(pTarget) && !pCSource->IsInCombat())
|
||||
pCSource->SetTargetGuid(pTarget->GetObjectGuid());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_MOVE_DYNAMIC: // 37
|
||||
{
|
||||
//if (LogIfNotCreature(pSource))
|
||||
// return false;
|
||||
//if (LogIfNotUnit(pTarget))
|
||||
// return false;
|
||||
if (LogIfNotCreature(pSource))
|
||||
return false;
|
||||
if (LogIfNotUnit(pTarget))
|
||||
return false;
|
||||
|
||||
//float x, y, z;
|
||||
//if (m_script->moveDynamic.maxDist == 0) // Move to pTarget
|
||||
//{
|
||||
// if (pTarget == pSource)
|
||||
// {
|
||||
// sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, _MOVE_DYNAMIC called with maxDist == 0, but resultingSource == resultingTarget (== %s)", m_table, m_script->id, pSource->GetGuidStr().c_str());
|
||||
// break;
|
||||
// }
|
||||
// pTarget->GetContactPoint(pSource, x, y, z);
|
||||
//}
|
||||
//else // Calculate position
|
||||
//{
|
||||
// float orientation;
|
||||
// if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL)
|
||||
// orientation = pSource->GetOrientation() + m_script->o + 2 * M_PI_F;
|
||||
// else
|
||||
// orientation = m_script->o;
|
||||
float x, y, z;
|
||||
if (m_script->moveDynamic.maxDist == 0) // Move to pTarget
|
||||
{
|
||||
if (pTarget == pSource)
|
||||
{
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, _MOVE_DYNAMIC called with maxDist == 0, but resultingSource == resultingTarget (== %s)", m_table, m_script->id, pSource->GetGuidStr().c_str());
|
||||
break;
|
||||
}
|
||||
pTarget->GetContactPoint(pSource, x, y, z);
|
||||
}
|
||||
else // Calculate position
|
||||
{
|
||||
float orientation;
|
||||
if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL)
|
||||
orientation = pSource->GetOrientation() + m_script->o + 2 * M_PI_F;
|
||||
else
|
||||
orientation = m_script->o;
|
||||
|
||||
// pSource->GetRandomPoint(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), m_script->moveDynamic.maxDist, x, y, z,
|
||||
// m_script->moveDynamic.minDist, (orientation == 0.0f ? NULL : &orientation));
|
||||
// z = std::max(z, pTarget->GetPositionZ());
|
||||
// pSource->UpdateAllowedPositionZ(x, y, z);
|
||||
//}
|
||||
//((Creature*)pSource)->GetMotionMaster()->MovePoint(1, x, y, z);
|
||||
pSource->GetRandomPoint(pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), m_script->moveDynamic.maxDist, x, y, z,
|
||||
m_script->moveDynamic.minDist, (orientation == 0.0f ? nullptr : &orientation));
|
||||
z = std::max(z, pTarget->GetPositionZ());
|
||||
pSource->UpdateAllowedPositionZ(x, y, z);
|
||||
}
|
||||
((Creature*)pSource)->GetMotionMaster()->MovePoint(1, x, y, z);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_SEND_MAIL: // 38
|
||||
|
|
@ -1962,7 +2025,98 @@ bool ScriptAction::HandleScriptStep()
|
|||
MailDraft(m_script->sendMail.mailTemplateId).SendMailTo(static_cast<Player*>(pTarget), sender, MAIL_CHECK_MASK_HAS_BODY, deliverDelay);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_CHANGE_ENTRY: // 39
|
||||
case SCRIPT_COMMAND_SET_FLY: // 39
|
||||
{
|
||||
if (LogIfNotCreature(pSource))
|
||||
break;
|
||||
|
||||
// enable / disable the fly anim flag
|
||||
if (m_script->data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL)
|
||||
{
|
||||
if (m_script->fly.fly)
|
||||
pSource->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_FLY_ANIM);
|
||||
else
|
||||
pSource->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_FLY_ANIM);
|
||||
}
|
||||
|
||||
((Creature*)pSource)->SetLevitate(!!m_script->fly.fly);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_DESPAWN_GO: // 40
|
||||
{
|
||||
if (LogIfNotGameObject(pTarget))
|
||||
break;
|
||||
|
||||
// ToDo: Change this to pGo->ForcedDespawn() when function is implemented!
|
||||
((GameObject*)pTarget)->SetLootState(GO_JUST_DEACTIVATED);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_RESPAWN: // 41
|
||||
{
|
||||
if (LogIfNotCreature(pTarget))
|
||||
break;
|
||||
|
||||
((Creature*)pTarget)->Respawn();
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_SET_EQUIPMENT_SLOTS: // 42
|
||||
{
|
||||
if (LogIfNotCreature(pSource))
|
||||
return false;
|
||||
|
||||
Creature* pCSource = static_cast<Creature*>(pSource);
|
||||
// reset default
|
||||
if (m_script->setEquipment.resetDefault)
|
||||
{
|
||||
pCSource->LoadEquipment(pCSource->GetCreatureInfo()->EquipmentTemplateId, true);
|
||||
break;
|
||||
}
|
||||
|
||||
// main hand
|
||||
if (m_script->textId[0] >= 0)
|
||||
pCSource->SetVirtualItem(VIRTUAL_ITEM_SLOT_0, m_script->textId[0]);
|
||||
|
||||
// off hand
|
||||
if (m_script->textId[1] >= 0)
|
||||
pCSource->SetVirtualItem(VIRTUAL_ITEM_SLOT_1, m_script->textId[1]);
|
||||
|
||||
// ranged
|
||||
if (m_script->textId[2] >= 0)
|
||||
pCSource->SetVirtualItem(VIRTUAL_ITEM_SLOT_2, m_script->textId[2]);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_RESET_GO: // 43
|
||||
{
|
||||
if (LogIfNotGameObject(pTarget))
|
||||
break;
|
||||
|
||||
GameObject* pGoTarget = static_cast<GameObject*>(pTarget);
|
||||
switch (pGoTarget->GetGoType())
|
||||
{
|
||||
case GAMEOBJECT_TYPE_DOOR:
|
||||
case GAMEOBJECT_TYPE_BUTTON:
|
||||
pGoTarget->ResetDoorOrButton();
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u failed for gameobject(buddyEntry: %u). Gameobject is not a door or button", m_table, m_script->id, m_script->command, m_script->buddyEntry);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_UPDATE_TEMPLATE: // 44
|
||||
{
|
||||
if (LogIfNotCreature(pSource))
|
||||
return false;
|
||||
|
||||
Creature* pCSource = static_cast<Creature*>(pSource);
|
||||
|
||||
if (pCSource->GetEntry() != m_script->updateTemplate.newTemplate)
|
||||
pCSource->UpdateEntry(m_script->updateTemplate.newTemplate, m_script->updateTemplate.newFactionTeam ? HORDE : ALLIANCE);
|
||||
else
|
||||
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u failed. Source already has specified creature entry.", m_table, m_script->id, m_script->command);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_CHANGE_ENTRY: // 45
|
||||
{
|
||||
if (LogIfNotCreature(pSource))
|
||||
{ break; }
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ enum DBScriptCommand // resSource, resTar
|
|||
SCRIPT_COMMAND_XP_USER = 33, // source or target with Player, datalong = bool (0=off, 1=on)
|
||||
SCRIPT_COMMAND_TERMINATE_COND = 34, // datalong = condition_id, datalong2 = if != 0 then quest_id of quest that will be failed for player's group if the script is terminated
|
||||
// data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL terminate when condition is false ELSE terminate when condition is true
|
||||
SCRIPT_COMMAND_SEND_AI_EVENT_AROUND = 35, // resSource = Creature, resTarget = Unit
|
||||
SCRIPT_COMMAND_SEND_AI_EVENT = 35, // resSource = Creature, resTarget = Unit
|
||||
// datalong = AIEventType
|
||||
// datalong2 = radius
|
||||
SCRIPT_COMMAND_TURN_TO = 36, // resSource = Unit, resTarget = Unit/none
|
||||
|
|
@ -145,8 +145,20 @@ enum DBScriptCommand // resSource, resTar
|
|||
SCRIPT_COMMAND_SEND_MAIL = 38, // resSource WorldObject, can be NULL, resTarget Player
|
||||
// datalong: Send mailTemplateId from resSource (if provided) to player resTarget
|
||||
// datalong2: AlternativeSenderEntry. Use as sender-Entry
|
||||
SCRIPT_COMMAND_SET_FLY = 39, // resSource = Creature
|
||||
// datalong = bool 0=off, 1=on
|
||||
// data_flags & SCRIPT_FLAG_COMMAND_ADDITIONAL set/unset byte flag UNIT_BYTE1_FLAG_FLY_ANIM
|
||||
// dataint1: Delay (>= 0) in Seconds
|
||||
SCRIPT_COMMAND_CHANGE_ENTRY = 39, // resSource = Creature, datalong=creature entry
|
||||
SCRIPT_COMMAND_DESPAWN_GO = 40, // resTarget = GameObject
|
||||
SCRIPT_COMMAND_RESPAWN = 41, // resSource = Creature. Requires SCRIPT_FLAG_BUDDY_IS_DESPAWNED to find dead or despawned targets
|
||||
SCRIPT_COMMAND_SET_EQUIPMENT_SLOTS = 42, // resSource = Creature
|
||||
// datalong = resetDefault: bool 0=false, 1=true
|
||||
// dataint = main hand slot; dataint2 = off hand slot; dataint3 = ranged slot
|
||||
SCRIPT_COMMAND_RESET_GO = 43, // resTarget = GameObject
|
||||
SCRIPT_COMMAND_UPDATE_TEMPLATE = 44, // resSource = Creature
|
||||
// datalong = new Creature entry
|
||||
// datalong2 = Alliance(0) Horde(1), other values throw error
|
||||
SCRIPT_COMMAND_CHANGE_ENTRY = 45, // resSource = Creature, datalong=creature entry
|
||||
// dataint1 = entry
|
||||
};
|
||||
|
||||
|
|
@ -161,8 +173,9 @@ enum ScriptInfoDataFlags
|
|||
SCRIPT_FLAG_COMMAND_ADDITIONAL = 0x08, // command dependend
|
||||
SCRIPT_FLAG_BUDDY_BY_GUID = 0x10, // take the buddy by guid
|
||||
SCRIPT_FLAG_BUDDY_IS_PET = 0x20, // buddy is a pet
|
||||
SCRIPT_FLAG_BUDDY_IS_DESPAWNED = 0X40, // buddy is dead or despawned
|
||||
};
|
||||
#define MAX_SCRIPT_FLAG_VALID (2 * SCRIPT_FLAG_BUDDY_IS_PET - 1)
|
||||
#define MAX_SCRIPT_FLAG_VALID (2 * SCRIPT_FLAG_BUDDY_IS_DESPAWNED - 1)
|
||||
|
||||
struct ScriptInfo
|
||||
{
|
||||
|
|
@ -371,7 +384,7 @@ struct ScriptInfo
|
|||
uint32 failQuest; // datalong2
|
||||
} terminateCond;
|
||||
|
||||
struct // SCRIPT_COMMAND_SEND_AI_EVENT_AROUND (35)
|
||||
struct // SCRIPT_COMMAND_SEND_AI_EVENT (35)
|
||||
{
|
||||
uint32 eventType; // datalong
|
||||
uint32 radius; // datalong2
|
||||
|
|
@ -395,7 +408,30 @@ struct ScriptInfo
|
|||
uint32 altSender; // datalong2;
|
||||
} sendMail;
|
||||
|
||||
struct // SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL (23)
|
||||
struct // SCRIPT_COMMAND_SET_FLY (39)
|
||||
{
|
||||
uint32 fly; // datalong
|
||||
uint32 empty; // datalong2
|
||||
} fly;
|
||||
|
||||
// datalong unsed // SCRIPT_COMMAND_DESPAWN_GO (40)
|
||||
// datalong unsed // SCRIPT_COMMAND_RESPAWN (41)
|
||||
|
||||
struct // SCRIPT_COMMAND_SET_EQUIPMENT_SLOTS (42)
|
||||
{
|
||||
uint32 resetDefault; // datalong
|
||||
uint32 empty; // datalong2
|
||||
} setEquipment;
|
||||
|
||||
// datalong unsed // SCRIPT_COMMAND_RESET_GO (43)
|
||||
|
||||
struct // SCRIPT_COMMAND_UPDATE_TEMPLATE (44)
|
||||
{
|
||||
uint32 newTemplate; // datalong
|
||||
uint32 newFactionTeam; // datalong2
|
||||
} updateTemplate;
|
||||
|
||||
struct // SCRIPT_COMMAND_MORPH_TO_ENTRY_OR_MODEL (45)
|
||||
{
|
||||
uint32 creatureEntry; // datalong
|
||||
uint32 empty1; // datalong2
|
||||
|
|
@ -443,6 +479,8 @@ struct ScriptInfo
|
|||
case SCRIPT_COMMAND_CLOSE_DOOR:
|
||||
case SCRIPT_COMMAND_ACTIVATE_OBJECT:
|
||||
case SCRIPT_COMMAND_GO_LOCK_STATE:
|
||||
case SCRIPT_COMMAND_DESPAWN_GO:
|
||||
case SCRIPT_COMMAND_RESET_GO:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
|
|
@ -464,6 +502,7 @@ struct ScriptInfo
|
|||
case SCRIPT_COMMAND_TERMINATE_COND:
|
||||
case SCRIPT_COMMAND_TURN_TO:
|
||||
case SCRIPT_COMMAND_MOVE_DYNAMIC:
|
||||
case SCRIPT_COMMAND_SET_FLY:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -6154,24 +6154,29 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
case SPELL_EFFECT_LEAP:
|
||||
case SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER:
|
||||
{
|
||||
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(spellEffect->GetRadiusIndex()));
|
||||
float fx = m_caster->GetPositionX() + dis * cos(m_caster->GetOrientation());
|
||||
float fy = m_caster->GetPositionY() + dis * sin(m_caster->GetOrientation());
|
||||
// teleport a bit above terrain level to avoid falling below it
|
||||
float fz = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), fx, fy, m_caster->GetPositionZ());
|
||||
if (fz <= INVALID_HEIGHT) // note: this also will prevent use effect in instances without vmaps height enabled
|
||||
return SPELL_FAILED_TRY_AGAIN;
|
||||
if (!m_caster || m_caster->IsTaxiFlying())
|
||||
return SPELL_FAILED_NOT_ON_TAXI;
|
||||
|
||||
float caster_pos_z = m_caster->GetPositionZ();
|
||||
// Control the caster to not climb or drop when +-fz > 8
|
||||
if (!(fz <= caster_pos_z + 8 && fz >= caster_pos_z - 8))
|
||||
return SPELL_FAILED_TRY_AGAIN;
|
||||
// Blink has leap first and then removing of auras with root effect
|
||||
// need further research with this
|
||||
SpellEffectEntry const* spellEffect = m_spellInfo->GetSpellEffect(SpellEffectIndex(i));
|
||||
if (!spellEffect)
|
||||
break;
|
||||
|
||||
if (spellEffect->Effect != SPELL_EFFECT_LEAP)
|
||||
{
|
||||
if (m_caster->hasUnitState(UNIT_STAT_ROOT))
|
||||
return SPELL_FAILED_ROOTED;
|
||||
}
|
||||
|
||||
// not allow use this effect at battleground until battleground start
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// not allow use this effect at battleground until battleground start
|
||||
if (BattleGround const* bg = ((Player*)m_caster)->GetBattleGround())
|
||||
if (bg->GetStatus() != STATUS_IN_PROGRESS)
|
||||
return SPELL_FAILED_TRY_AGAIN;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF:
|
||||
|
|
|
|||
|
|
@ -2976,7 +2976,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
|||
{
|
||||
//AreaTableEntry const* area = GetAreaEntryByAreaID(target->GetAreaId());
|
||||
|
||||
//// Dalaran restricted flight zone (recheck before apply unmount)
|
||||
//// Dalaran restricstruct boss_freyted flight zone (recheck before apply unmount)
|
||||
//if (area && target->GetTypeId() == TYPEID_PLAYER && (area->flags & AREA_FLAG_CANNOT_FLY) &&
|
||||
// ((Player*)target)->IsFreeFlying() && !((Player*)target)->isGameMaster())
|
||||
//{
|
||||
|
|
|
|||
|
|
@ -5384,14 +5384,13 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect)
|
|||
if (summon_prop->Group == SUMMON_PROP_GROUP_PETS && prop_id != 1562)
|
||||
{
|
||||
DoSummonPet(effect);
|
||||
return;
|
||||
}
|
||||
|
||||
// Expected Amount: TODO - there are quite some exceptions (like totems, engineering dragonlings..)
|
||||
uint32 amount = damage > 0 ? damage : 1;
|
||||
|
||||
// basepoints of SUMMON_PROP_GROUP_VEHICLE is often a spellId, set amount to 1
|
||||
if (summon_prop->Group == SUMMON_PROP_GROUP_VEHICLE)
|
||||
if (summon_prop->Group == SUMMON_PROP_GROUP_VEHICLE || summon_prop->Group == SUMMON_PROP_GROUP_UNCONTROLLABLE_VEHICLE || summon_prop->Group == SUMMON_PROP_GROUP_CONTROLLABLE)
|
||||
amount = 1;
|
||||
|
||||
// Get casting object
|
||||
|
|
@ -5552,6 +5551,7 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect)
|
|||
break;
|
||||
}
|
||||
case SUMMON_PROP_GROUP_VEHICLE:
|
||||
case SUMMON_PROP_GROUP_UNCONTROLLABLE_VEHICLE:
|
||||
{
|
||||
summonResult = DoSummonVehicle(summonPositions, summon_prop, effect, level);
|
||||
break;
|
||||
|
|
@ -5750,17 +5750,30 @@ bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntr
|
|||
if (m_duration > 0)
|
||||
spawnCreature->SetDuration(m_duration);
|
||||
|
||||
CreatureInfo const* cInfo = spawnCreature->GetCreatureInfo();
|
||||
|
||||
// spawnCreature->SetName(""); // generated by client
|
||||
spawnCreature->SetOwnerGuid(m_caster->GetObjectGuid());
|
||||
spawnCreature->SetPowerType(POWER_MANA);
|
||||
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, spawnCreature->GetCreatureInfo()->NpcFlags);
|
||||
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS, cInfo->UnitFlags);
|
||||
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, cInfo->NpcFlags);
|
||||
spawnCreature->setFaction(m_caster->getFaction());
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
|
||||
spawnCreature->SetCreatorGuid(m_caster->GetObjectGuid());
|
||||
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
|
||||
spawnCreature->InitStatsForLevel(level, m_caster);
|
||||
spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false);
|
||||
spawnCreature->InitStatsForLevel(level);
|
||||
|
||||
if (CharmInfo* charmInfo = spawnCreature->GetCharmInfo())
|
||||
{
|
||||
charmInfo->SetPetNumber(pet_number, false);
|
||||
|
||||
if (spawnCreature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE))
|
||||
charmInfo->SetReactState(REACT_PASSIVE);
|
||||
else if ((cInfo->ExtraFlags & CREATURE_EXTRA_FLAG_NO_MELEE) || petType == PROTECTOR_PET)
|
||||
charmInfo->SetReactState(REACT_DEFENSIVE);
|
||||
else
|
||||
charmInfo->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
m_caster->AddGuardian(spawnCreature);
|
||||
}
|
||||
|
|
@ -10721,24 +10734,159 @@ void Spell::EffectBlock(SpellEffectEntry const* /*effect*/)
|
|||
|
||||
void Spell::EffectLeapForward(SpellEffectEntry const* effect)
|
||||
{
|
||||
if (unitTarget->IsTaxiFlying())
|
||||
return;
|
||||
float dist = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->rangeIndex));
|
||||
const float IN_OR_UNDER_LIQUID_RANGE = 0.8f; // range to make player under liquid or on liquid surface from liquid level
|
||||
|
||||
if (m_spellInfo->rangeIndex == SPELL_RANGE_IDX_SELF_ONLY)
|
||||
G3D::Vector3 prevPos, nextPos;
|
||||
float orientation = unitTarget->GetOrientation();
|
||||
|
||||
prevPos.x = unitTarget->GetPositionX();
|
||||
prevPos.y = unitTarget->GetPositionY();
|
||||
prevPos.z = unitTarget->GetPositionZ();
|
||||
|
||||
float groundZ = prevPos.z;
|
||||
|
||||
// falling case
|
||||
if (!unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), prevPos.x, prevPos.y, groundZ, 3.0f) && unitTarget->m_movementInfo.HasMovementFlag(MOVEFLAG_FALLING))
|
||||
{
|
||||
float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex()));
|
||||
nextPos.x = prevPos.x + dist * cos(orientation);
|
||||
nextPos.y = prevPos.y + dist * sin(orientation);
|
||||
nextPos.z = prevPos.z - 2.0f; // little hack to avoid the impression to go up when teleporting instead of continue to fall. This value may need some tweak
|
||||
|
||||
// before caster
|
||||
float fx, fy, fz;
|
||||
unitTarget->GetClosePoint(fx, fy, fz, unitTarget->GetObjectBoundingRadius(), dis);
|
||||
float ox, oy, oz;
|
||||
unitTarget->GetPosition(ox, oy, oz);
|
||||
//
|
||||
GridMapLiquidData liquidData;
|
||||
if (unitTarget->GetMap()->GetTerrain()->IsInWater(nextPos.x, nextPos.y, nextPos.z, &liquidData))
|
||||
{
|
||||
if (fabs(nextPos.z - liquidData.level) < 10.0f)
|
||||
nextPos.z = liquidData.level - IN_OR_UNDER_LIQUID_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// fix z to ground if near of it
|
||||
unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), nextPos.x, nextPos.y, nextPos.z, 10.0f);
|
||||
}
|
||||
|
||||
if (unitTarget->GetMap()->GetHitPosition(ox, oy, oz + 0.5f, fx, fy, fz, unitTarget->GetPhaseMask(), -0.5f))
|
||||
unitTarget->UpdateAllowedPositionZ(fx, fy, fz);
|
||||
// check any obstacle and fix coords
|
||||
unitTarget->GetMap()->GetHitPosition(prevPos.x, prevPos.y, prevPos.z + 0.5f, nextPos.x, nextPos.y, nextPos.z, unitTarget->GetPhaseMask(), -0.5f);
|
||||
|
||||
unitTarget->NearTeleportTo(fx, fy, fz, unitTarget->GetOrientation(), unitTarget == m_caster);
|
||||
// teleport
|
||||
unitTarget->NearTeleportTo(nextPos.x, nextPos.y, nextPos.z, orientation, unitTarget == m_caster);
|
||||
|
||||
//sLog.outString("Falling BLINK!");
|
||||
return;
|
||||
}
|
||||
|
||||
// fix origin position if player was jumping and near of the ground but not in ground
|
||||
if (fabs(prevPos.z - groundZ) > 0.5f)
|
||||
prevPos.z = groundZ;
|
||||
|
||||
//check if in liquid
|
||||
bool isPrevInLiquid = unitTarget->GetMap()->GetTerrain()->IsInWater(prevPos.x, prevPos.y, prevPos.z);
|
||||
|
||||
const float step = 2.0f; // step length before next check slope/edge/water
|
||||
const float maxSlope = 50.0f; // 50(degree) max seem best value for walkable slope
|
||||
const float MAX_SLOPE_IN_RADIAN = maxSlope / 180.0f * M_PI_F;
|
||||
float nextZPointEstimation = 1.0f;
|
||||
float destx = prevPos.x + dist * cos(orientation);
|
||||
float desty = prevPos.y + dist * sin(orientation);
|
||||
const uint32 numChecks = ceil(fabs(dist / step));
|
||||
const float DELTA_X = (destx - prevPos.x) / numChecks;
|
||||
const float DELTA_Y = (desty - prevPos.y) / numChecks;
|
||||
|
||||
for (uint32 i = 1; i < numChecks + 1; ++i)
|
||||
{
|
||||
// compute next point average position
|
||||
nextPos.x = prevPos.x + DELTA_X;
|
||||
nextPos.y = prevPos.y + DELTA_Y;
|
||||
nextPos.z = prevPos.z + nextZPointEstimation;
|
||||
|
||||
bool isInLiquid = false;
|
||||
bool isInLiquidTested = false;
|
||||
bool isOnGround = false;
|
||||
GridMapLiquidData liquidData;
|
||||
|
||||
// try fix height for next position
|
||||
if (!unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), nextPos.x, nextPos.y, nextPos.z))
|
||||
{
|
||||
// we cant so test if we are on water
|
||||
if (!unitTarget->GetMap()->GetTerrain()->IsInWater(nextPos.x, nextPos.y, nextPos.z, &liquidData))
|
||||
{
|
||||
// not in water and cannot get correct height, maybe flying?
|
||||
//sLog.outString("Can't get height of point %u, point value %s", i, nextPos.toString().c_str());
|
||||
nextPos = prevPos;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
isInLiquid = true;
|
||||
isInLiquidTested = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
isOnGround = true; // player is on ground
|
||||
|
||||
if (isInLiquid || (!isInLiquidTested && unitTarget->GetMap()->GetTerrain()->IsInWater(nextPos.x, nextPos.y, nextPos.z, &liquidData)))
|
||||
{
|
||||
if (!isPrevInLiquid && fabs(liquidData.level - prevPos.z) > 2.0f)
|
||||
{
|
||||
// on edge of water with difference a bit to high to continue
|
||||
//sLog.outString("Ground vs liquid edge detected!");
|
||||
nextPos = prevPos;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((liquidData.level - IN_OR_UNDER_LIQUID_RANGE) > nextPos.z)
|
||||
nextPos.z = prevPos.z; // we are under water so next z equal prev z
|
||||
else
|
||||
nextPos.z = liquidData.level - IN_OR_UNDER_LIQUID_RANGE; // we are on water surface, so next z equal liquid level
|
||||
|
||||
isInLiquid = true;
|
||||
|
||||
float ground = nextPos.z;
|
||||
if (unitTarget->GetMap()->GetHeightInRange(unitTarget->GetPhaseMask(), nextPos.x, nextPos.y, ground))
|
||||
{
|
||||
if (nextPos.z < ground)
|
||||
{
|
||||
nextPos.z = ground;
|
||||
isOnGround = true; // player is on ground of the water
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unitTarget->SummonCreature(VISUAL_WAYPOINT, nextPos.x, nextPos.y, nextPos.z, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
|
||||
float hitZ = nextPos.z + 1.5f;
|
||||
if (unitTarget->GetMap()->GetHitPosition(prevPos.x, prevPos.y, prevPos.z + 1.5f, nextPos.x, nextPos.y, hitZ, unitTarget->GetPhaseMask(), -1.0f))
|
||||
{
|
||||
//sLog.outString("Blink collision detected!");
|
||||
nextPos = prevPos;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isOnGround)
|
||||
{
|
||||
// project vector to get only positive value
|
||||
float ac = fabs(prevPos.z - nextPos.z);
|
||||
|
||||
// compute slope (in radian)
|
||||
float slope = atan(ac / step);
|
||||
|
||||
// check slope value
|
||||
if (slope > MAX_SLOPE_IN_RADIAN)
|
||||
{
|
||||
//sLog.outString("bad slope detected! %4.2f max %4.2f, ac(%4.2f)", slope * 180 / M_PI_F, maxSlope, ac);
|
||||
nextPos = prevPos;
|
||||
break;
|
||||
}
|
||||
//sLog.outString("slope is ok! %4.2f max %4.2f, ac(%4.2f)", slope * 180 / M_PI_F, maxSlope, ac);
|
||||
}
|
||||
|
||||
//sLog.outString("point %u is ok, coords %s", i, nextPos.toString().c_str());
|
||||
nextZPointEstimation = (nextPos.z - prevPos.z) / 2.0f;
|
||||
isPrevInLiquid = isInLiquid;
|
||||
prevPos = nextPos;
|
||||
}
|
||||
|
||||
unitTarget->NearTeleportTo(nextPos.x, nextPos.y, nextPos.z, orientation, unitTarget == m_caster);
|
||||
}
|
||||
|
||||
void Spell::EffectLeapBack(SpellEffectEntry const* effect)
|
||||
|
|
@ -10922,11 +11070,18 @@ void Spell::EffectPlayerPull(SpellEffectEntry const* effect)
|
|||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
float dist = unitTarget->GetDistance2d(m_caster);
|
||||
if (damage && dist > damage)
|
||||
dist = float(damage);
|
||||
float x, y, z;
|
||||
m_caster->GetPosition(x, y, z);
|
||||
|
||||
unitTarget->KnockBackFrom(m_caster, -dist, float(effect->EffectMiscValue) / 10);
|
||||
// move back a bit
|
||||
x = x - (0.6 * cos(m_caster->GetOrientation() + M_PI_F));
|
||||
y = y - (0.6 * sin(m_caster->GetOrientation() + M_PI_F));
|
||||
|
||||
// Try to normalize Z coord because GetContactPoint do nothing with Z axis
|
||||
unitTarget->UpdateAllowedPositionZ(x, y, z);
|
||||
|
||||
float speed = m_spellInfo->speed ? m_spellInfo->speed : 27.0f;
|
||||
unitTarget->GetMotionMaster()->MoveJump(x, y, z, speed, 2.5f);
|
||||
}
|
||||
|
||||
void Spell::EffectDispelMechanic(SpellEffectEntry const* effect)
|
||||
|
|
|
|||
|
|
@ -293,10 +293,13 @@ void WorldSession::HandleGameObjectUseOpcode(WorldPacket& recv_data)
|
|||
if (!_player->IsSelfMover())
|
||||
return;
|
||||
|
||||
GameObject* obj = GetPlayer()->GetMap()->GetGameObject(guid);
|
||||
GameObject* obj = _player->GetMap()->GetGameObject(guid);
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
if (!obj->IsWithinDistInMap(_player, obj->GetInteractionDistance()))
|
||||
return;
|
||||
|
||||
// Additional check preventing exploits (ie loot despawned chests)
|
||||
if (!obj->isSpawned())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -635,6 +635,6 @@ void WaypointManager::CheckTextsExistance(std::set<int32>& ids)
|
|||
{
|
||||
for (WaypointPath::const_iterator pItr = pmItr->second.begin(); pItr != pmItr->second.end(); ++pItr)
|
||||
if (pItr->second.behavior)
|
||||
CheckWPText(false, pmItr->first, pItr->first, pItr->second.behavior, ids);
|
||||
CheckWPText(true, pmItr->first, pItr->first, pItr->second.behavior, ids);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ class WaypointManager
|
|||
|
||||
WaypointPath* GetDefaultPath(uint32 entry, uint32 lowGuid, WaypointPathOrigin* wpOrigin = NULL)
|
||||
{
|
||||
WaypointPath* path = NULL;
|
||||
WaypointPath* path = GetPath(lowGuid);
|
||||
path = GetPath(lowGuid);
|
||||
if (path && wpOrigin)
|
||||
*wpOrigin = PATH_FROM_GUID;
|
||||
|
|
|
|||
|
|
@ -531,6 +531,7 @@ void World::LoadConfigSettings(bool reload)
|
|||
setConfig(CONFIG_BOOL_ADDON_CHANNEL, "AddonChannel", true);
|
||||
setConfig(CONFIG_BOOL_CLEAN_CHARACTER_DB, "CleanCharacterDB", true);
|
||||
setConfig(CONFIG_BOOL_GRID_UNLOAD, "GridUnload", true);
|
||||
setConfig(CONFIG_UINT32_MAX_WHOLIST_RETURNS, "MaxWhoListReturns", 49);
|
||||
|
||||
std::string forceLoadGridOnMaps = sConfig.GetStringDefault("LoadAllGridsOnMaps", "");
|
||||
if (!forceLoadGridOnMaps.empty())
|
||||
|
|
|
|||
|
|
@ -220,6 +220,8 @@ enum eConfigUInt32Values
|
|||
CONFIG_UINT32_MIN_LEVEL_FOR_RAID,
|
||||
CONFIG_UINT32_CREATURE_RESPAWN_AGGRO_DELAY,
|
||||
CONFIG_UINT32_RANDOM_BG_RESET_HOUR,
|
||||
CONFIG_UINT32_MAX_WHOLIST_RETURNS,
|
||||
CONFIG_UINT32_VALUE_COUNT,
|
||||
// Warden
|
||||
CONFIG_UINT32_WARDEN_CLIENT_RESPONSE_DELAY,
|
||||
CONFIG_UINT32_WARDEN_CLIENT_CHECK_HOLDOFF,
|
||||
|
|
@ -227,8 +229,7 @@ enum eConfigUInt32Values
|
|||
CONFIG_UINT32_WARDEN_CLIENT_BAN_DURATION,
|
||||
CONFIG_UINT32_WARDEN_NUM_MEM_CHECKS,
|
||||
CONFIG_UINT32_WARDEN_NUM_OTHER_CHECKS,
|
||||
CONFIG_UINT32_WARDEN_DB_LOGLEVEL,
|
||||
CONFIG_UINT32_VALUE_COUNT
|
||||
CONFIG_UINT32_WARDEN_DB_LOGLEVEL
|
||||
};
|
||||
|
||||
/// Configuration elements
|
||||
|
|
|
|||
|
|
@ -43,11 +43,14 @@ enum
|
|||
SPELL_MAGMASHACKLES = 19496,
|
||||
SPELL_ERUPTION_TRIGGER = 20482, // target script, dispel and permanent immune to banish anywhere on map
|
||||
SPELL_ENRAGE_TRIGGER = 19515, // target script, effect dummy anywhere on map
|
||||
SPELL_ENRAGE = 19516,
|
||||
|
||||
// Add spells
|
||||
SPELL_THRASH = 8876,
|
||||
SPELL_IMMOLATE = 15733,
|
||||
SPELL_ERUPTION = 19497,
|
||||
SPELL_MASSIVE_ERUPTION = 20483, // TODO possible on death
|
||||
SPELL_IMMOLATE = 20294,
|
||||
SPELL_SEPARATION_ANXIETY_BOSSGARR = 23492, // Used if separated too far from Garr
|
||||
};
|
||||
|
||||
struct boss_garr : public CreatureScript
|
||||
|
|
@ -184,6 +187,10 @@ struct mob_firesworn : public CreatureScript
|
|||
mob_fireswornAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
DoCastSpellIfCan(m_creature, SPELL_IMMOLATE, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
|
@ -199,6 +206,12 @@ struct mob_firesworn : public CreatureScript
|
|||
m_bExploding = false;
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
DoCastSpellIfCan(m_creature, SPELL_IMMOLATE, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*pDealer*/, uint32& uiDamage) override
|
||||
{
|
||||
if (!m_bExploding && m_creature->HealthBelowPctDamaged(10, uiDamage))
|
||||
|
|
|
|||
|
|
@ -43,9 +43,11 @@ enum
|
|||
SPELL_EARTHQUAKE = 19798,
|
||||
SPELL_ENRAGE = 19953,
|
||||
SPELL_GOLEMAGG_TRUST = 20553,
|
||||
SPELL_DOUBLE_ATTACK = 18943,
|
||||
|
||||
// Core Rager
|
||||
EMOTE_LOW_HP = -1409002,
|
||||
SPELL_THRASH = 12787,
|
||||
SPELL_MANGLE = 19820
|
||||
};
|
||||
|
||||
|
|
@ -60,6 +62,7 @@ struct boss_golemagg : public CreatureScript
|
|||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
#if defined (WOTLK) || defined (CATA)
|
||||
DoCastSpellIfCan(m_creature, SPELL_MAGMA_SPLASH, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -185,6 +188,9 @@ struct mob_core_rager : public CreatureScript
|
|||
mob_core_ragerAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
Reset();
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
|
@ -208,6 +214,11 @@ struct mob_core_rager : public CreatureScript
|
|||
}
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ enum
|
|||
EMOTE_INSECT_SWARM = -1533154,
|
||||
EMOTE_CORPSE_SCARABS = -1533155,
|
||||
|
||||
SPELL_DOUBLE_ATTACK = 18943,
|
||||
SPELL_IMPALE = 28783, // May be wrong spell id. Causes more dmg than I expect
|
||||
SPELL_IMPALE_H = 56090,
|
||||
SPELL_LOCUSTSWARM = 28785, // This is a self buff that triggers the dmg debuff
|
||||
|
|
@ -82,6 +83,9 @@ struct boss_anubrekhan : public CreatureScript
|
|||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
m_introDialogue.InitializeDialogueHelper(m_pInstance);
|
||||
m_bHasTaunted = false;
|
||||
Reset();
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
|
@ -135,6 +139,8 @@ struct boss_anubrekhan : public CreatureScript
|
|||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_ANUB_REKHAN, FAIL);
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* pWho) override
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ enum
|
|||
EMOTE_ZOMBIE = -1533119,
|
||||
EMOTE_BOSS_GENERIC_ENRAGED = -1000006,
|
||||
EMOTE_DECIMATE = -1533152,
|
||||
|
||||
|
||||
SPELL_DOUBLE_ATTACK = 19818,
|
||||
SPELL_MORTALWOUND = 54378, // old vanilla spell was 25646,
|
||||
SPELL_DECIMATE = 28374,
|
||||
SPELL_DECIMATE_H = 54426,
|
||||
|
|
@ -66,6 +67,9 @@ struct boss_gluth : public CreatureScript
|
|||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
|
@ -118,6 +122,8 @@ struct boss_gluth : public CreatureScript
|
|||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_GLUTH, FAIL);
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ enum
|
|||
EMOTE_SPRAY = -1533148,
|
||||
EMOTE_BOSS_GENERIC_FRENZY = -1000005,
|
||||
|
||||
SPELL_DOUBLE_ATTACK = 19818,
|
||||
|
||||
SPELL_WEBWRAP = 28622,
|
||||
SPELL_WEBWRAP_2 = 28673, // purpose unknown
|
||||
|
||||
|
|
@ -166,6 +168,9 @@ struct boss_maexxna : public CreatureScript
|
|||
{
|
||||
m_pInstance = (ScriptedInstance*)pCreature->GetInstanceData();
|
||||
m_bIsRegularMode = pCreature->GetMap()->IsRegularDifficulty();
|
||||
Reset();
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
|
@ -204,6 +209,8 @@ struct boss_maexxna : public CreatureScript
|
|||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_MAEXXNA, FAIL);
|
||||
|
||||
DoCastSpellIfCan(m_creature, SPELL_DOUBLE_ATTACK, CAST_TRIGGERED | CAST_AURA_NOT_PRESENT);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned) override
|
||||
|
|
|
|||
|
|
@ -211,6 +211,7 @@ struct boss_freya : public CreatureScript
|
|||
|
||||
uint32 m_uiEpilogueTimer;
|
||||
uint32 m_uiBerserkTimer;
|
||||
uint32 m_uiDrainEldersTimer;
|
||||
|
||||
uint32 m_uiAlliesNatureTimer;
|
||||
uint8 m_uiAlliesWaveCount;
|
||||
|
|
@ -244,6 +245,7 @@ struct boss_freya : public CreatureScript
|
|||
m_uiUnstableEnergyTimer = 0;
|
||||
m_uiIronRootsTimer = 0;
|
||||
m_uiGroundTremorTimer = 0;
|
||||
m_uiDrainEldersTimer = 0;
|
||||
|
||||
// make the spawn spells random
|
||||
std::random_shuffle(spawnSpellsVector.begin(), spawnSpellsVector.end());
|
||||
|
|
@ -292,17 +294,26 @@ struct boss_freya : public CreatureScript
|
|||
if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_BRIGHTLEAF))
|
||||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->AI()->EnterEvadeMode();
|
||||
pElder->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_IRONBRACH))
|
||||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->AI()->EnterEvadeMode();
|
||||
pElder->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_STONEBARK))
|
||||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->AI()->EnterEvadeMode();
|
||||
pElder->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -468,7 +479,7 @@ struct boss_freya : public CreatureScript
|
|||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_BRIGHTLEAF_ESSENCE_CHANNEL : SPELL_BRIGHTLEAF_ESSENCE_CHANNEL_H, true);
|
||||
pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_BRIGHTLEAF_ESSENCE_CHANNEL : SPELL_BRIGHTLEAF_ESSENCE_CHANNEL_H, false, NULL, NULL, m_creature->GetObjectGuid());
|
||||
pElder->CastSpell(pElder, SPELL_FULL_HEAL, true);
|
||||
|
||||
m_uiUnstableEnergyTimer = 25000;
|
||||
|
|
@ -479,7 +490,7 @@ struct boss_freya : public CreatureScript
|
|||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_IRONBRANCH_ESSENCE_CHANNEL : SPELL_IRONBRANCH_ESSENCE_CHANNEL_H, true);
|
||||
pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_IRONBRANCH_ESSENCE_CHANNEL : SPELL_IRONBRANCH_ESSENCE_CHANNEL_H, false, NULL, NULL, m_creature->GetObjectGuid());
|
||||
pElder->CastSpell(pElder, SPELL_FULL_HEAL, true);
|
||||
|
||||
m_uiIronRootsTimer = 60000;
|
||||
|
|
@ -490,7 +501,7 @@ struct boss_freya : public CreatureScript
|
|||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_STONEBARK_ESSEMCE_CHANNEL : SPELL_STONEBARK_ESSEMCE_CHANNEL_H, true);
|
||||
pElder->CastSpell(pElder, m_bIsRegularMode ? SPELL_STONEBARK_ESSEMCE_CHANNEL : SPELL_STONEBARK_ESSEMCE_CHANNEL_H, false, NULL, NULL, m_creature->GetObjectGuid());
|
||||
pElder->CastSpell(pElder, SPELL_FULL_HEAL, true);
|
||||
|
||||
m_uiGroundTremorTimer = 10000;
|
||||
|
|
@ -507,6 +518,38 @@ struct boss_freya : public CreatureScript
|
|||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
}
|
||||
|
||||
// Function that will drain elders after aggro
|
||||
void DoDrainElders()
|
||||
{
|
||||
if (!m_pInstance)
|
||||
return;
|
||||
|
||||
if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_BRIGHTLEAF))
|
||||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->CastSpell(pElder, SPELL_DRAINED_OF_POWER, true);
|
||||
pElder->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_IRONBRACH))
|
||||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->CastSpell(pElder, SPELL_DRAINED_OF_POWER, true);
|
||||
pElder->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
if (Creature* pElder = m_pInstance->GetSingleCreatureFromStorage(NPC_ELDER_STONEBARK))
|
||||
{
|
||||
if (pElder->IsAlive())
|
||||
{
|
||||
pElder->CastSpell(pElder, SPELL_DRAINED_OF_POWER, true);
|
||||
pElder->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff) override
|
||||
{
|
||||
if (m_uiEpilogueTimer)
|
||||
|
|
@ -540,6 +583,18 @@ struct boss_freya : public CreatureScript
|
|||
m_uiBerserkTimer -= uiDiff;
|
||||
}
|
||||
|
||||
// Drain elders after hard mode aggro
|
||||
if (m_uiDrainEldersTimer)
|
||||
{
|
||||
if (m_uiDrainEldersTimer <= uiDiff)
|
||||
{
|
||||
DoDrainElders();
|
||||
m_uiDrainEldersTimer = 0;
|
||||
}
|
||||
else
|
||||
m_uiDrainEldersTimer -= uiDiff;
|
||||
}
|
||||
|
||||
if (m_uiThreeAlliesTimer)
|
||||
{
|
||||
if (m_uiThreeAlliesTimer <= uiDiff)
|
||||
|
|
|
|||
|
|
@ -44,9 +44,8 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
|
|||
data=NULL;
|
||||
}
|
||||
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f)
|
||||
{ return false; }
|
||||
FILE * f = fopen(filename, "rb");
|
||||
if(!f)return false;
|
||||
|
||||
if(fread(&header, 4, 1, f) != 1) // Signature
|
||||
{
|
||||
|
|
@ -59,10 +58,10 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
|
|||
if(header != 0x32424457)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
return false; //'WDB2'
|
||||
}
|
||||
|
||||
if (fread(&recordCount, 4, 1, f) != 1) // Number of records
|
||||
if(fread(&recordCount,4,1,f)!=1) // Number of records
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
|
|
@ -70,7 +69,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
|
|||
|
||||
EndianConvert(recordCount);
|
||||
|
||||
if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
|
||||
if(fread(&fieldCount,4,1,f)!=1) // Number of fields
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
|
|
@ -78,7 +77,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
|
|||
|
||||
EndianConvert(fieldCount);
|
||||
|
||||
if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
|
||||
if(fread(&recordSize,4,1,f)!=1) // Size of a record
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
|
|
@ -86,7 +85,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
|
|||
|
||||
EndianConvert(recordSize);
|
||||
|
||||
if (fread(&stringSize, 4, 1, f) != 1) // String size
|
||||
if(fread(&stringSize,4,1,f)!=1) // String size
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
|
|
@ -153,19 +152,19 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
|
|||
|
||||
fieldsOffset = new uint32[fieldCount];
|
||||
fieldsOffset[0] = 0;
|
||||
for (uint32 i = 1; i < fieldCount; ++i)
|
||||
for(uint32 i = 1; i < fieldCount; i++)
|
||||
{
|
||||
fieldsOffset[i] = fieldsOffset[i - 1];
|
||||
if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') // byte fields
|
||||
{ fieldsOffset[i] += 1; }
|
||||
fieldsOffset[i] += 1;
|
||||
else // 4 byte fields (int32/float/strings)
|
||||
{ fieldsOffset[i] += 4; }
|
||||
fieldsOffset[i] += 4;
|
||||
}
|
||||
|
||||
data = new unsigned char[recordSize * recordCount + stringSize];
|
||||
stringTable = data + recordSize * recordCount;
|
||||
data = new unsigned char[recordSize*recordCount+stringSize];
|
||||
stringTable = data + recordSize*recordCount;
|
||||
|
||||
if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
|
||||
if(fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue