Merge branch 'master' into Playerbot

# Conflicts:
#	src/server/game/World/IWorld.h
#	src/server/game/World/World.cpp
#	src/server/game/World/World.h
#	src/server/scripts/Commands/cs_server.cpp
This commit is contained in:
郑佩茹
2022-05-02 16:39:21 -06:00
99 changed files with 839 additions and 5304 deletions

View File

@@ -334,11 +334,12 @@ void Minion::InitStats(uint32 duration)
SetReactState(REACT_PASSIVE);
Unit* owner = GetOwner();
SetCreatorGUID(owner->GetGUID());
SetFaction(owner->GetFaction());
owner->SetMinion(this, true);
if (Unit* owner = GetOwner())
{
SetCreatorGUID(owner->GetGUID());
SetFaction(owner->GetFaction());
owner->SetMinion(this, true);
}
}
void Minion::RemoveFromWorld()

View File

@@ -11035,6 +11035,11 @@ void Player::LeaveBattleground(Battleground* bg)
// xinef: reset corpse reclaim time
m_deathExpireTime = GameTime::GetGameTime().count();
// Remove all dots
RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
// pussywizard: clear movement, because after porting player will move to arena cords
GetMotionMaster()->MovementExpired();
StopMoving();

View File

@@ -1952,7 +1952,7 @@ inline LiquidData const GridMap::GetLiquidData(float x, float y, float z, float
float ground_level = getHeight(x, y);
// Check water level and ground level
if (liquid_level >= ground_level && z >= ground_level - 2)
if (liquid_level >= ground_level && z >= ground_level)
{
// All ok in water -> store data
liquidData.Entry = entry;

View File

@@ -608,6 +608,19 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id,
}
}
void MotionMaster::MoveCharge(PathGenerator const& path, float speed /*= SPEED_CHARGE*/)
{
G3D::Vector3 dest = path.GetActualEndPosition();
MoveCharge(dest.x, dest.y, dest.z, speed, EVENT_CHARGE_PREPATH);
// Charge movement is not started when using EVENT_CHARGE_PREPATH
Movement::MoveSplineInit init(_owner);
init.MovebyPath(path.GetPath());
init.SetVelocity(speed);
init.Launch();
}
void MotionMaster::MoveSeekAssistance(float x, float y, float z)
{
// Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE

View File

@@ -219,6 +219,7 @@ public:
void MoveTakeoff(uint32 id, float x, float y, float z, float speed = 0.0f); // pussywizard: added for easy calling by passing 3 floats x, y, z
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE, const Movement::PointsArray* path = nullptr, bool generatePath = false, float orientation = 0.0f, ObjectGuid targetGUID = ObjectGuid::Empty);
void MoveCharge(PathGenerator const& path, float speed = SPEED_CHARGE);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
void MoveJumpTo(float angle, float speedXY, float speedZ);
void MoveJump(Position const& pos, float speedXY, float speedZ, uint32 id = 0)

View File

@@ -117,7 +117,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* unit, uint32 /*diff*/)
unit->AddUnitState(UNIT_STATE_ROAMING_MOVE);
if (i_recalculateSpeed && !unit->movespline->Finalized())
if (id != EVENT_CHARGE_PREPATH && i_recalculateSpeed && !unit->movespline->Finalized())
{
i_recalculateSpeed = false;
Movement::MoveSplineInit init(unit);

View File

@@ -446,11 +446,10 @@ bool FollowMovementGenerator<T>::DoUpdate(T* owner, uint32 time_diff)
else
i_path->Clear();
float distance = _range - target->GetCombatReach();
target->MovePositionToFirstCollision(targetPosition, owner->GetCombatReach() + _range, target->ToAbsoluteAngle(_angle.RelativeAngle) - target->GetOrientation());
float relAngle = _angle.RelativeAngle;
float x, y, z;
target->GetNearPoint(owner, x, y, z, owner->GetCombatReach(), distance, target->ToAbsoluteAngle(relAngle), 0.f, &targetPosition);
targetPosition.GetPosition(x, y, z);
if (owner->IsHovering())
owner->UpdateAllowedPositionZ(x, y, z);

View File

@@ -646,7 +646,6 @@ Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags,
m_glyphIndex = 0;
m_preCastSpell = 0;
m_spellAura = nullptr;
m_pathFinder = nullptr; // pussywizard
_scriptsLoaded = false;
//Auto Shot & Shoot (wand)
@@ -701,7 +700,6 @@ Spell::~Spell()
}
delete m_spellValue;
delete m_pathFinder; // pussywizard
CheckEffectExecuteData();
}
@@ -6001,40 +5999,28 @@ SpellCastResult Spell::CheckCast(bool strict)
{
Unit* target = m_targets.GetUnitTarget();
if (!target)
return SPELL_FAILED_BAD_TARGETS;
return SPELL_FAILED_DONT_REPORT;
Position pos;
target->GetChargeContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
// first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
return SPELL_FAILED_LINE_OF_SIGHT;
if (m_caster->GetMapId() == 618) // pussywizard: 618 Ring of Valor
pos.m_positionZ = std::max(pos.m_positionZ, 28.28f);
float objSize = target->GetCombatReach();
float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
float maxdist = m_caster->GetMeleeRange(target);
if (!target->IsInDist(&pos, maxdist))
m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
m_preGeneratedPath->SetPathLengthLimit(range);
// first try with raycast, if it fails fall back to normal path
bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
return SPELL_FAILED_NOPATH;
else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
return SPELL_FAILED_NOPATH;
else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
return SPELL_FAILED_NOPATH;
if (m_caster->GetMapId() == 618) // pussywizard: 618 Ring of Valor
{
if (!((target->GetPositionZ() > 32.0f) ^ (m_caster->GetPositionZ() > 32.0f)))
break;
return SPELL_FAILED_NOPATH;
}
else if (m_caster->GetMapId() == 572) // pussywizard: 572 Ruins of Lordaeron
{
if (pos.GetPositionX() < 1275.0f || m_caster->GetPositionX() < 1275.0f) // special case (acid)
break; // can't force path because the way is around and the path is too long
}
if (m_caster->GetTransport() != target->GetTransport())
return SPELL_FAILED_NOPATH;
if (m_caster->GetTransport())
break;
m_pathFinder = new PathGenerator(m_caster);
m_pathFinder->CalculatePath(pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.15f, false);
G3D::Vector3 endPos = m_pathFinder->GetEndPosition(); // also check distance between target and the point calculated by mmaps
if (m_pathFinder->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE) || target->GetExactDistSq(endPos.x, endPos.y, endPos.z) > maxdist * maxdist || m_pathFinder->getPathLength() > (40.0f + (m_caster->HasAura(58097) ? 5.0f : 0.0f)))
return SPELL_FAILED_NOPATH;
m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
}
if (Player* player = m_caster->ToPlayer())
player->SetCanTeleport(true);

View File

@@ -544,8 +544,6 @@ public:
UsedSpellMods m_appliedMods;
PathGenerator* m_pathFinder; // pussywizard: for precomputing path for charge
int32 GetCastTime() const { return m_casttime; }
bool IsAutoRepeat() const { return m_autoRepeat; }
void SetAutoRepeat(bool rep) { m_autoRepeat = rep; }
@@ -770,6 +768,7 @@ public:
bool m_skipCheck;
uint8 m_auraScaleMask;
std::unique_ptr<PathGenerator> m_preGeneratedPath;
// xinef:
bool _spellTargetsSelected;

View File

@@ -2728,6 +2728,8 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
dynObj->SetDuration(duration);
dynObj->SetCasterViewpoint();
m_caster->ToPlayer()->UpdateVisibilityForPlayer();
}
void Spell::EffectUntrainTalents(SpellEffIndex /*effIndex*/)
@@ -4868,10 +4870,12 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
targetGUID = unitTarget->GetGUID();
}
if (m_pathFinder)
float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
// Spell is not using explicit target - no generated path
if (!m_preGeneratedPath)
{
m_caster->GetMotionMaster()->MoveCharge(m_pathFinder->GetEndPosition().x, m_pathFinder->GetEndPosition().y, m_pathFinder->GetEndPosition().z,
42.0f, EVENT_CHARGE, &m_pathFinder->GetPath(), false, 0.f, targetGUID);
Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster));
m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed);
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
@@ -4880,10 +4884,7 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
}
else
{
Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetObjectSize(), unitTarget->GetRelativeAngle(m_caster));
m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + Z_OFFSET_FIND_HEIGHT, SPEED_CHARGE, EVENT_CHARGE,
nullptr, false, 0.f, targetGUID);
m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed);
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{

View File

@@ -583,11 +583,7 @@ public:
virtual void UpdateRealmCharCount(uint32 accid) = 0;
[[nodiscard]] virtual LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const = 0;
virtual void LoadDBVersion() = 0;
virtual void LoadDBRevision() = 0;
[[nodiscard]] virtual char const* GetDBVersion() const = 0;
[[nodiscard]] virtual char const* GetWorldDBRevision() const = 0;
[[nodiscard]] virtual char const* GetCharacterDBRevision() const = 0;
[[nodiscard]] virtual char const* GetAuthDBRevision() const = 0;
#ifdef MOD_PLAYERBOTS
[[nodiscard]] virtual char const* GetPlayerbotsDBRevision() const = 0;
#endif

View File

@@ -3274,49 +3274,6 @@ void World::LoadDBVersion()
m_DBVersion = "Unknown world database.";
}
void World::LoadDBRevision()
{
QueryResult resultWorld = WorldDatabase.Query("SELECT date FROM version_db_world ORDER BY date DESC LIMIT 1");
QueryResult resultCharacter = CharacterDatabase.Query("SELECT date FROM version_db_characters ORDER BY date DESC LIMIT 1");
QueryResult resultAuth = LoginDatabase.Query("SELECT date FROM version_db_auth ORDER BY date DESC LIMIT 1");
if (resultWorld)
{
Field* fields = resultWorld->Fetch();
m_WorldDBRevision = fields[0].Get<std::string>();
}
if (resultCharacter)
{
Field* fields = resultCharacter->Fetch();
m_CharacterDBRevision = fields[0].Get<std::string>();
}
if (resultAuth)
{
Field* fields = resultAuth->Fetch();
m_AuthDBRevision = fields[0].Get<std::string>();
}
if (m_WorldDBRevision.empty())
{
m_WorldDBRevision = "Unkown World Database Revision";
}
if (m_CharacterDBRevision.empty())
{
m_CharacterDBRevision = "Unkown Character Database Revision";
}
if (m_AuthDBRevision.empty())
{
m_AuthDBRevision = "Unkown Auth Database Revision";
}
#ifdef MOD_PLAYERBOTS
sScriptMgr->OnDatabaseGetDBRevision(m_PlayerbotsDBRevision);
#endif
}
void World::UpdateAreaDependentAuras()
{
SessionMap::const_iterator itr;

View File

@@ -339,11 +339,7 @@ public:
// used World DB version
void LoadDBVersion() override;
void LoadDBRevision() override;
[[nodiscard]] char const* GetDBVersion() const override { return m_DBVersion.c_str(); }
[[nodiscard]] char const* GetWorldDBRevision() const override { return m_WorldDBRevision.c_str(); }
[[nodiscard]] char const* GetCharacterDBRevision() const override { return m_CharacterDBRevision.c_str(); }
[[nodiscard]] char const* GetAuthDBRevision() const override { return m_AuthDBRevision.c_str(); }
#ifdef MOD_PLAYERBOTS
[[nodiscard]] char const* GetPlayerbotsDBRevision() const { return m_PlayerbotsDBRevision.c_str(); }
#endif
@@ -445,9 +441,6 @@ private:
// used versions
std::string m_DBVersion;
std::string m_WorldDBRevision;
std::string m_CharacterDBRevision;
std::string m_AuthDBRevision;
#ifdef MOD_PLAYERBOTS
std::string m_PlayerbotsDBRevision;
#endif