Merge commit 'c61fac843b86f584f913dd21c256a626668df756' into 4.3.4
Conflicts: sql/base/dev/world_database.sql sql/updates/world/2015_03_22_00_world.sql sql/updates/world/2015_03_23_00_world.sql sql/updates/world/2015_03_23_01_world.sql sql/updates/world/2015_03_23_02_world.sql sql/updates/world/2015_03_23_03_world.sql sql/updates/world/2015_03_23_07_world.sql sql/updates/world/2015_03_24_00_world.sql sql/updates/world/2015_03_25_00_world.sql sql/updates/world/2015_03_25_01_world.sql sql/updates/world/2015_03_26_00_world.sql sql/updates/world/2015_03_26_01_world.sql sql/updates/world/2015_03_26_02_world.sql sql/updates/world/2015_03_28_00_world.sql sql/updates/world/2015_03_28_01_world.sql
This commit is contained in:
commit
963150dc8e
17 files changed
+827
-50
No files matched your search
@@ -2925,7 +2925,7 @@ CREATE TABLE `quest_template` (
|
||||
`RewardSpell` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`RewardSpellCast` int(11) NOT NULL DEFAULT '0',
|
||||
`RewardHonor` int(11) NOT NULL DEFAULT '0',
|
||||
`RewardHonorMultiplier` float NOT NULL DEFAULT '1',
|
||||
`RewardHonorMultiplier` float NOT NULL DEFAULT '0',
|
||||
`RewardMailTemplateId` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
`RewardMailDelay` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`SourceItemId` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||
|
||||
@@ -227,13 +227,16 @@ Updates.ArchivedRedundancy = 0
|
||||
Updates.AllowRehash = 1
|
||||
|
||||
#
|
||||
# Updates.CleanDeadRef
|
||||
# Description: Cleans dead/ orphaned references that occure if a update was deleted or renamed and edited.
|
||||
# Updates.CleanDeadRefMaxCount
|
||||
# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step.
|
||||
# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value.
|
||||
# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision).
|
||||
# Disable this if you want to know if the database is in a possible "dirty state".
|
||||
# Default: 1 - (Enabled)
|
||||
# Default: 3 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
# -1 - (Enabled - unlimited)
|
||||
|
||||
Updates.CleanDeadRef = 1
|
||||
Updates.CleanDeadRefMaxCount = 3
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
@@ -16446,6 +16446,8 @@ void Player::AreaExploredOrEventHappens(uint32 questId)
|
||||
{
|
||||
q_status.Explored = true;
|
||||
m_QuestStatusSave[questId] = QUEST_DEFAULT_SAVE_TYPE;
|
||||
SetQuestSlotState(log_slot, QUEST_STATE_COMPLETE);
|
||||
SendQuestComplete(questId);
|
||||
}
|
||||
}
|
||||
if (CanCompleteQuest(questId))
|
||||
@@ -23216,7 +23218,7 @@ void Player::UpdateTriggerVisibility()
|
||||
WorldPacket packet;
|
||||
for (auto itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
|
||||
{
|
||||
if (itr->IsCreature())
|
||||
if (itr->IsCreatureOrVehicle())
|
||||
{
|
||||
Creature* creature = GetMap()->GetCreature(*itr);
|
||||
// Update fields of triggers, transformed units or unselectable units (values dependent on GM state)
|
||||
|
||||
@@ -3825,8 +3825,6 @@ void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, Play
|
||||
}
|
||||
}
|
||||
|
||||
int32 const ReputationMgr::Reputation_Cap;
|
||||
|
||||
void ObjectMgr::LoadQuests()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
|
||||
const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
|
||||
|
||||
const int32 ReputationMgr::Reputation_Cap = 42999;
|
||||
const int32 ReputationMgr::Reputation_Bottom = -42000;
|
||||
|
||||
ReputationRank ReputationMgr::ReputationToRank(int32 standing)
|
||||
{
|
||||
int32 limit = Reputation_Cap + 1;
|
||||
|
||||
@@ -72,8 +72,8 @@ class ReputationMgr
|
||||
void LoadFromDB(PreparedQueryResult result);
|
||||
public: // statics
|
||||
static const int32 PointsInRank[MAX_REPUTATION_RANK];
|
||||
static const int32 Reputation_Cap = 42999;
|
||||
static const int32 Reputation_Bottom = -42000;
|
||||
static const int32 Reputation_Cap;
|
||||
static const int32 Reputation_Bottom;
|
||||
|
||||
static ReputationRank ReputationToRank(int32 standing);
|
||||
public: // accessors
|
||||
|
||||
@@ -46,13 +46,12 @@ WorldSocketMgr::WorldSocketMgr() : BaseSocketMgr(), _socketSendBufferSize(-1), m
|
||||
{
|
||||
}
|
||||
|
||||
int const boost::asio::socket_base::max_connections;
|
||||
|
||||
bool WorldSocketMgr::StartNetwork(boost::asio::io_service& service, std::string const& bindIp, uint16 port)
|
||||
{
|
||||
_tcpNoDelay = sConfigMgr->GetBoolDefault("Network.TcpNodelay", true);
|
||||
|
||||
TC_LOG_DEBUG("misc", "Max allowed socket connections %d", boost::asio::socket_base::max_connections);
|
||||
int const max_connections = boost::asio::socket_base::max_connections;
|
||||
TC_LOG_DEBUG("misc", "Max allowed socket connections %d", max_connections);
|
||||
|
||||
// -1 means use default
|
||||
_socketSendBufferSize = sConfigMgr->GetIntDefault("Network.OutKBuff", -1);
|
||||
|
||||
@@ -27,10 +27,13 @@ EndScriptData */
|
||||
npc_webbed_creature
|
||||
EndContentData */
|
||||
|
||||
#include "Player.h"
|
||||
#include "Group.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*######
|
||||
## npc_webbed_creature
|
||||
@@ -88,7 +91,723 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## Quest 9759: Ending Their World
|
||||
######*/
|
||||
|
||||
enum EndingTheirWorldMisc
|
||||
{
|
||||
SAY_SIRONAS_1 = 0,
|
||||
|
||||
SAY_LEGOSO_1 = 0,
|
||||
SAY_LEGOSO_2 = 1,
|
||||
SAY_LEGOSO_3 = 2,
|
||||
SAY_LEGOSO_4 = 3,
|
||||
SAY_LEGOSO_5 = 4,
|
||||
SAY_LEGOSO_6 = 5,
|
||||
SAY_LEGOSO_7 = 6,
|
||||
SAY_LEGOSO_8 = 7,
|
||||
SAY_LEGOSO_9 = 8,
|
||||
SAY_LEGOSO_10 = 9,
|
||||
SAY_LEGOSO_11 = 10,
|
||||
SAY_LEGOSO_12 = 11,
|
||||
SAY_LEGOSO_13 = 12,
|
||||
SAY_LEGOSO_14 = 13,
|
||||
SAY_LEGOSO_15 = 14,
|
||||
SAY_LEGOSO_16 = 15,
|
||||
SAY_LEGOSO_17 = 16,
|
||||
SAY_LEGOSO_18 = 17,
|
||||
SAY_LEGOSO_19 = 18,
|
||||
SAY_LEGOSO_20 = 19,
|
||||
SAY_LEGOSO_21 = 20,
|
||||
|
||||
SPELL_BLOODMYST_TESLA = 31611,
|
||||
SPELL_SIRONAS_CHANNELING = 31612,
|
||||
|
||||
SPELL_UPPERCUT = 10966,
|
||||
SPELL_IMMOLATE = 12742,
|
||||
SPELL_CURSE_OF_BLOOD = 8282,
|
||||
|
||||
SPELL_FROST_SHOCK = 8056,
|
||||
SPELL_HEALING_SURGE = 8004,
|
||||
SPELL_SEARING_TOTEM = 38116,
|
||||
SPELL_STRENGTH_OF_EARTH_TOTEM = 31633,
|
||||
|
||||
NPC_SIRONAS = 17678,
|
||||
NPC_BLOODMYST_TESLA_COIL = 17979,
|
||||
NPC_LEGOSO = 17982,
|
||||
|
||||
GO_DRAENEI_EXPLOSIVES_1 = 182088,
|
||||
GO_DRAENEI_EXPLOSIVES_2 = 182091,
|
||||
GO_FIRE_EXPLOSION = 182071,
|
||||
|
||||
ACTION_SIRONAS_CHANNEL_START = 1,
|
||||
ACTION_SIRONAS_CHANNEL_STOP = 2,
|
||||
|
||||
ACTION_LEGOSO_SIRONAS_KILLED = 1,
|
||||
|
||||
EVENT_UPPERCUT = 1,
|
||||
EVENT_IMMOLATE = 2,
|
||||
EVENT_CURSE_OF_BLOOD = 3,
|
||||
|
||||
EVENT_FROST_SHOCK = 1,
|
||||
EVENT_HEALING_SURGE = 2,
|
||||
EVENT_SEARING_TOTEM = 3,
|
||||
EVENT_STRENGTH_OF_EARTH_TOTEM = 4,
|
||||
|
||||
WP_START = 1,
|
||||
WP_EXPLOSIVES_FIRST_POINT = 21,
|
||||
WP_EXPLOSIVES_FIRST_PLANT = 22,
|
||||
WP_EXPLOSIVES_FIRST_RUNOFF = 23,
|
||||
WP_EXPLOSIVES_FIRST_DETONATE = 24,
|
||||
WP_DEBUG_1 = 25,
|
||||
WP_DEBUG_2 = 26,
|
||||
WP_SIRONAS_HILL = 33,
|
||||
WP_EXPLOSIVES_SECOND_BATTLEROAR = 35,
|
||||
WP_EXPLOSIVES_SECOND_PLANT = 39,
|
||||
WP_EXPLOSIVES_SECOND_DETONATE = 40,
|
||||
|
||||
PHASE_NONE = 0,
|
||||
PHASE_CONTINUE = -1,
|
||||
PHASE_WP_26 = 1,
|
||||
PHASE_WP_22 = 2,
|
||||
PHASE_PLANT_FIRST_KNEEL = 3,
|
||||
PHASE_PLANT_FIRST_STAND = 4,
|
||||
PHASE_PLANT_FIRST_WORK = 5,
|
||||
PHASE_PLANT_FIRST_FINISH = 6,
|
||||
PHASE_PLANT_FIRST_TIMER_1 = 7,
|
||||
PHASE_PLANT_FIRST_TIMER_2 = 8,
|
||||
PHASE_PLANT_FIRST_TIMER_3 = 9,
|
||||
PHASE_PLANT_FIRST_DETONATE = 10,
|
||||
PHASE_PLANT_FIRST_SPEECH = 11,
|
||||
PHASE_PLANT_FIRST_ROTATE = 12,
|
||||
PHASE_PLANT_FIRST_POINT = 13,
|
||||
PHASE_FEEL_SIRONAS_1 = 14,
|
||||
PHASE_FEEL_SIRONAS_2 = 15,
|
||||
PHASE_MEET_SIRONAS_ROAR = 16,
|
||||
PHASE_MEET_SIRONAS_TURN = 17,
|
||||
PHASE_MEET_SIRONAS_SPEECH = 18,
|
||||
PHASE_PLANT_SECOND_KNEEL = 19,
|
||||
PHASE_PLANT_SECOND_SPEECH = 20,
|
||||
PHASE_PLANT_SECOND_STAND = 21,
|
||||
PHASE_PLANT_SECOND_FINISH = 22,
|
||||
PHASE_PLANT_SECOND_WAIT = 23,
|
||||
PHASE_PLANT_SECOND_TIMER_1 = 24,
|
||||
PHASE_PLANT_SECOND_TIMER_2 = 25,
|
||||
PHASE_PLANT_SECOND_TIMER_3 = 26,
|
||||
PHASE_PLANT_SECOND_DETONATE = 27,
|
||||
PHASE_FIGHT_SIRONAS_STOP = 28,
|
||||
PHASE_FIGHT_SIRONAS_SPEECH_1 = 29,
|
||||
PHASE_FIGHT_SIRONAS_SPEECH_2 = 30,
|
||||
PHASE_FIGHT_SIRONAS_START = 31,
|
||||
PHASE_SIRONAS_SLAIN_SPEECH_1 = 32,
|
||||
PHASE_SIRONAS_SLAIN_EMOTE_1 = 33,
|
||||
PHASE_SIRONAS_SLAIN_EMOTE_2 = 34,
|
||||
PHASE_SIRONAS_SLAIN_SPEECH_2 = 35,
|
||||
|
||||
DATA_EVENT_STARTER_GUID = 0,
|
||||
|
||||
MAX_EXPLOSIVES = 5,
|
||||
|
||||
QUEST_ENDING_THEIR_WORLD = 9759
|
||||
};
|
||||
|
||||
Position const ExplosivesPos[2][MAX_EXPLOSIVES] =
|
||||
{
|
||||
{
|
||||
{ -1954.946f, -10654.714f, 110.448f },
|
||||
{ -1956.331f, -10654.494f, 110.869f },
|
||||
{ -1955.906f, -10656.221f, 110.791f },
|
||||
{ -1957.294f, -10656.000f, 111.219f },
|
||||
{ -1954.462f, -10656.451f, 110.404f }
|
||||
},
|
||||
{
|
||||
{ -1915.137f, -10583.651f, 178.365f },
|
||||
{ -1914.006f, -10582.964f, 178.471f },
|
||||
{ -1912.717f, -10582.398f, 178.658f },
|
||||
{ -1915.056f, -10582.251f, 178.162f },
|
||||
{ -1913.883f, -10581.778f, 178.346f }
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_sironas
|
||||
######*/
|
||||
|
||||
class npc_sironas : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_sironas() : CreatureScript("npc_sironas") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_sironasAI(creature);
|
||||
}
|
||||
|
||||
struct npc_sironasAI : public ScriptedAI
|
||||
{
|
||||
npc_sironasAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_events.Reset();
|
||||
me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_UPPERCUT, 15 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_IMMOLATE, 10 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, 5 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
me->SetObjectScale(1.0f);
|
||||
_events.Reset();
|
||||
if (Creature* legoso = me->FindNearestCreature(NPC_LEGOSO, SIZE_OF_GRIDS))
|
||||
{
|
||||
Group* group = me->GetLootRecipientGroup();
|
||||
|
||||
if (killer->GetGUID() == legoso->GetGUID() ||
|
||||
(group && group->IsMember(killer->GetGUID())) ||
|
||||
killer->GetGUIDLow() == legoso->AI()->GetData(DATA_EVENT_STARTER_GUID))
|
||||
legoso->AI()->DoAction(ACTION_LEGOSO_SIRONAS_KILLED);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_UPPERCUT:
|
||||
DoCastVictim(SPELL_UPPERCUT);
|
||||
_events.ScheduleEvent(EVENT_UPPERCUT, urand(10, 12) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_IMMOLATE:
|
||||
DoCastVictim(SPELL_IMMOLATE);
|
||||
_events.ScheduleEvent(EVENT_IMMOLATE, urand(15, 20) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_CURSE_OF_BLOOD:
|
||||
DoCastVictim(SPELL_CURSE_OF_BLOOD);
|
||||
_events.ScheduleEvent(EVENT_CURSE_OF_BLOOD, urand(20, 25) * IN_MILLISECONDS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case ACTION_SIRONAS_CHANNEL_START:
|
||||
{
|
||||
DoCast(me, SPELL_SIRONAS_CHANNELING);
|
||||
std::list<Creature*> BeamList;
|
||||
_beamGuidList.clear();
|
||||
me->GetCreatureListWithEntryInGrid(BeamList, NPC_BLOODMYST_TESLA_COIL, SIZE_OF_GRIDS);
|
||||
for (std::list<Creature*>::iterator itr = BeamList.begin(); itr != BeamList.end(); ++itr)
|
||||
{
|
||||
_beamGuidList.push_back((*itr)->GetGUID());
|
||||
(*itr)->CastSpell(*itr, SPELL_BLOODMYST_TESLA);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ACTION_SIRONAS_CHANNEL_STOP:
|
||||
{
|
||||
me->InterruptNonMeleeSpells(true, SPELL_SIRONAS_CHANNELING);
|
||||
std::list<Creature*> creatureList;
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_BLOODMYST_TESLA_COIL, 500.0f);
|
||||
if (!creatureList.empty())
|
||||
for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
|
||||
(*itr)->InterruptNonMeleeSpells(true, SPELL_BLOODMYST_TESLA);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GuidList _beamGuidList;
|
||||
EventMap _events;
|
||||
};
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_demolitionist_legoso
|
||||
######*/
|
||||
|
||||
class npc_demolitionist_legoso : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_demolitionist_legoso() : CreatureScript("npc_demolitionist_legoso") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_demolitionist_legosoAI(creature);
|
||||
}
|
||||
|
||||
struct npc_demolitionist_legosoAI : public npc_escortAI
|
||||
{
|
||||
npc_demolitionist_legosoAI(Creature* creature) : npc_escortAI(creature) { }
|
||||
|
||||
void sQuestAccept(Player* player, Quest const* quest) override
|
||||
{
|
||||
if (quest->GetQuestId() == QUEST_ENDING_THEIR_WORLD)
|
||||
{
|
||||
SetData(DATA_EVENT_STARTER_GUID, player->GetGUIDLow());
|
||||
Start(true, true, player->GetGUID(), quest);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 id) const override
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case DATA_EVENT_STARTER_GUID:
|
||||
return _eventStarterGuidLow;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 data, uint32 value) override
|
||||
{
|
||||
switch (data)
|
||||
{
|
||||
case DATA_EVENT_STARTER_GUID:
|
||||
_eventStarterGuidLow = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_phase = PHASE_NONE;
|
||||
_moveTimer = 0;
|
||||
_eventStarterGuidLow = 0;
|
||||
me->SetCanDualWield(true);
|
||||
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_FROST_SHOCK, 1 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_HEALING_SURGE, 5 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_SEARING_TOTEM, 15 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_STRENGTH_OF_EARTH_TOTEM, 20 * IN_MILLISECONDS);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (UpdateVictim())
|
||||
{
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FROST_SHOCK:
|
||||
DoCastVictim(SPELL_FROST_SHOCK);
|
||||
_events.DelayEvents(1 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_FROST_SHOCK, urand(10, 15) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_SEARING_TOTEM:
|
||||
DoCast(me, SPELL_SEARING_TOTEM);
|
||||
_events.DelayEvents(1 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_SEARING_TOTEM, urand(110, 130) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_STRENGTH_OF_EARTH_TOTEM:
|
||||
DoCast(me, SPELL_STRENGTH_OF_EARTH_TOTEM);
|
||||
_events.DelayEvents(1 * IN_MILLISECONDS);
|
||||
_events.ScheduleEvent(EVENT_STRENGTH_OF_EARTH_TOTEM, urand(110, 130) * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_HEALING_SURGE:
|
||||
{
|
||||
Unit* target = NULL;
|
||||
if (me->GetHealthPct() < 85)
|
||||
target = me;
|
||||
else if (Player* player = GetPlayerForEscort())
|
||||
if (player->GetHealthPct() < 85)
|
||||
target = player;
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_HEALING_SURGE);
|
||||
_events.ScheduleEvent(EVENT_HEALING_SURGE, 10 * IN_MILLISECONDS);
|
||||
}
|
||||
else
|
||||
_events.ScheduleEvent(EVENT_HEALING_SURGE, 2 * IN_MILLISECONDS);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
if (HasEscortState(STATE_ESCORT_NONE))
|
||||
return;
|
||||
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
if (_phase)
|
||||
{
|
||||
if (_moveTimer <= diff)
|
||||
{
|
||||
switch (_phase)
|
||||
{
|
||||
case PHASE_WP_26: //debug skip path to point 26, buggy path calculation
|
||||
me->GetMotionMaster()->MovePoint(WP_DEBUG_2, -2021.77f, -10648.8f, 129.903f, false);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_CONTINUE: // continue escort
|
||||
SetEscortPaused(false);
|
||||
_moveTimer = 0 * IN_MILLISECONDS;
|
||||
_phase = PHASE_NONE;
|
||||
break;
|
||||
case PHASE_WP_22: //debug skip path to point 22, buggy path calculation
|
||||
me->GetMotionMaster()->MovePoint(WP_EXPLOSIVES_FIRST_PLANT, -1958.026f, -10660.465f, 111.547f, false);
|
||||
Talk(SAY_LEGOSO_3);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_KNEEL;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_KNEEL: // plant first explosives stage 1 kneel
|
||||
me->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
_moveTimer = 10 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_STAND;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_STAND: // plant first explosives stage 1 stand
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
_moveTimer = 0.5* IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_WORK;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_WORK: // plant first explosives stage 2 work
|
||||
Talk(SAY_LEGOSO_4);
|
||||
_moveTimer = 17.5 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_FINISH;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_FINISH: // plant first explosives finish
|
||||
_explosivesGuids.clear();
|
||||
for (uint8 i = 0; i != MAX_EXPLOSIVES; ++i)
|
||||
{
|
||||
if (GameObject* explosive = me->SummonGameObject(GO_DRAENEI_EXPLOSIVES_1, ExplosivesPos[0][i].m_positionX, ExplosivesPos[0][i].m_positionY, ExplosivesPos[0][i].m_positionZ, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
||||
_explosivesGuids.push_back(explosive->GetGUID());
|
||||
}
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_NONE); // reset anim state
|
||||
// force runoff movement so he will not screw up next waypoint
|
||||
me->GetMotionMaster()->MovePoint(WP_EXPLOSIVES_FIRST_RUNOFF, -1955.6f, -10669.8f, 110.65f, false);
|
||||
Talk(SAY_LEGOSO_5);
|
||||
_moveTimer = 1.5 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_TIMER_1: // first explosives detonate timer 1
|
||||
Talk(SAY_LEGOSO_6);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_TIMER_2;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_TIMER_2: // first explosives detonate timer 2
|
||||
Talk(SAY_LEGOSO_7);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_TIMER_3;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_TIMER_3: // first explosives detonate timer 3
|
||||
Talk(SAY_LEGOSO_8);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_DETONATE;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_DETONATE: // first explosives detonate finish
|
||||
for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr)
|
||||
{
|
||||
if (GameObject* explosive = sObjectAccessor->GetGameObject(*me, *itr))
|
||||
me->RemoveGameObject(explosive, true);
|
||||
}
|
||||
_explosivesGuids.clear();
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_SPEECH;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_SPEECH: // after detonation 1 speech
|
||||
Talk(SAY_LEGOSO_9);
|
||||
_moveTimer = 4 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_ROTATE;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_ROTATE: // after detonation 1 rotate to next point
|
||||
me->SetFacingTo(2.272f);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_POINT;
|
||||
break;
|
||||
case PHASE_PLANT_FIRST_POINT: // after detonation 1 send point anim and go on to next point
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_FEEL_SIRONAS_1: // legoso exclamation before sironas 1.1
|
||||
Talk(SAY_LEGOSO_10);
|
||||
_moveTimer = 4 * IN_MILLISECONDS;
|
||||
_phase = PHASE_FEEL_SIRONAS_2;
|
||||
break;
|
||||
case PHASE_FEEL_SIRONAS_2: // legoso exclamation before sironas 1.2
|
||||
Talk(SAY_LEGOSO_11);
|
||||
_moveTimer = 4 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_MEET_SIRONAS_ROAR: // legoso exclamation before sironas 2.1
|
||||
Talk(SAY_LEGOSO_12);
|
||||
_moveTimer = 4 * IN_MILLISECONDS;
|
||||
_phase = PHASE_MEET_SIRONAS_TURN;
|
||||
break;
|
||||
case PHASE_MEET_SIRONAS_TURN: // legoso exclamation before sironas 2.2
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
me->SetFacingToObject(player);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_MEET_SIRONAS_SPEECH;
|
||||
break;
|
||||
case PHASE_MEET_SIRONAS_SPEECH: // legoso exclamation before sironas 2.3
|
||||
Talk(SAY_LEGOSO_13);
|
||||
_moveTimer = 7 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_KNEEL: // plant second explosives stage 1 kneel
|
||||
me->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
_moveTimer = 11 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_SPEECH;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_SPEECH: // plant second explosives stage 2 kneel
|
||||
Talk(SAY_LEGOSO_14);
|
||||
_moveTimer = 13 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_STAND;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_STAND: // plant second explosives finish
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_FINISH;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_FINISH: // plant second explosives finish - create explosives
|
||||
_explosivesGuids.clear();
|
||||
for (uint8 i = 0; i != MAX_EXPLOSIVES; ++i)
|
||||
{
|
||||
if (GameObject* explosive = me->SummonGameObject(GO_DRAENEI_EXPLOSIVES_2, ExplosivesPos[1][i].m_positionX, ExplosivesPos[1][i].m_positionY, ExplosivesPos[1][i].m_positionZ, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
|
||||
_explosivesGuids.push_back(explosive->GetGUID());
|
||||
}
|
||||
Talk(SAY_LEGOSO_15);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_WAIT;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_WAIT: // plant second explosives finish - proceed to next point
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_TIMER_1: // second explosives detonate timer 1
|
||||
Talk(SAY_LEGOSO_16);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_TIMER_2;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_TIMER_2: // second explosives detonate timer 2
|
||||
Talk(SAY_LEGOSO_17);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_TIMER_3;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_TIMER_3: // second explosives detonate timer 3
|
||||
Talk(SAY_LEGOSO_18);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_DETONATE;
|
||||
break;
|
||||
case PHASE_PLANT_SECOND_DETONATE: // second explosives detonate finish
|
||||
for (GuidList::iterator itr = _explosivesGuids.begin(); itr != _explosivesGuids.end(); ++itr)
|
||||
{
|
||||
if (GameObject* explosive = sObjectAccessor->GetGameObject(*me, *itr))
|
||||
me->RemoveGameObject(explosive, true);
|
||||
}
|
||||
_explosivesGuids.clear();
|
||||
if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS))
|
||||
{
|
||||
sironas->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetFacingToObject(sironas);
|
||||
}
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_FIGHT_SIRONAS_STOP;
|
||||
break;
|
||||
case PHASE_FIGHT_SIRONAS_STOP: // sironas channel stop
|
||||
if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS))
|
||||
sironas->AI()->DoAction(ACTION_SIRONAS_CHANNEL_STOP);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_FIGHT_SIRONAS_SPEECH_1;
|
||||
break;
|
||||
case PHASE_FIGHT_SIRONAS_SPEECH_1: // sironas exclamation before aggro
|
||||
if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS))
|
||||
sironas->AI()->Talk(SAY_SIRONAS_1);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_FIGHT_SIRONAS_SPEECH_2;
|
||||
break;
|
||||
case PHASE_FIGHT_SIRONAS_SPEECH_2: // legoso exclamation before aggro
|
||||
if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS))
|
||||
sironas->SetObjectScale(3.0f);
|
||||
Talk(SAY_LEGOSO_19);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_FIGHT_SIRONAS_START;
|
||||
break;
|
||||
case PHASE_FIGHT_SIRONAS_START: // legoso exclamation at aggro
|
||||
if (Creature* sironas = me->FindNearestCreature(NPC_SIRONAS, SIZE_OF_GRIDS))
|
||||
{
|
||||
Unit* target = GetPlayerForEscort();
|
||||
if (!target)
|
||||
target = me;
|
||||
|
||||
target->AddThreat(sironas, 0.001f);
|
||||
sironas->Attack(target, true);
|
||||
sironas->GetMotionMaster()->MoveChase(target);
|
||||
}
|
||||
_moveTimer = 10 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case PHASE_SIRONAS_SLAIN_SPEECH_1: // legoso exclamation after battle - stage 1.1
|
||||
Talk(SAY_LEGOSO_20);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_SIRONAS_SLAIN_EMOTE_1;
|
||||
break;
|
||||
case PHASE_SIRONAS_SLAIN_EMOTE_1: // legoso exclamation after battle - stage 1.2
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_SIRONAS_SLAIN_EMOTE_2;
|
||||
break;
|
||||
case PHASE_SIRONAS_SLAIN_EMOTE_2: // legoso exclamation after battle - stage 1.3
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
player->GroupEventHappens(QUEST_ENDING_THEIR_WORLD, me);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
_moveTimer = 5 * IN_MILLISECONDS;
|
||||
_phase = PHASE_SIRONAS_SLAIN_SPEECH_2;
|
||||
break;
|
||||
case PHASE_SIRONAS_SLAIN_SPEECH_2: // legoso exclamation after battle - stage 2
|
||||
Talk(SAY_LEGOSO_21);
|
||||
_moveTimer = 30 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!me->IsInCombat())
|
||||
_moveTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId) override
|
||||
{
|
||||
Player* player = GetPlayerForEscort();
|
||||
if (!player)
|
||||
return;
|
||||
|
||||
switch (waypointId)
|
||||
{
|
||||
case WP_START:
|
||||
SetEscortPaused(true);
|
||||
me->SetFacingToObject(player);
|
||||
Talk(SAY_LEGOSO_1);
|
||||
_moveTimer = 2.5 * IN_MILLISECONDS;
|
||||
_phase = PHASE_CONTINUE;
|
||||
break;
|
||||
case WP_EXPLOSIVES_FIRST_POINT:
|
||||
SetEscortPaused(true);
|
||||
Talk(SAY_LEGOSO_2);
|
||||
_moveTimer = 8 * IN_MILLISECONDS;
|
||||
_phase = PHASE_WP_22;
|
||||
break;
|
||||
case WP_EXPLOSIVES_FIRST_PLANT:
|
||||
me->SetFacingTo(1.46f);
|
||||
break;
|
||||
case WP_EXPLOSIVES_FIRST_DETONATE:
|
||||
SetEscortPaused(true);
|
||||
me->SetFacingTo(1.05f);
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_FIRST_TIMER_1;
|
||||
break;
|
||||
case WP_DEBUG_1:
|
||||
SetEscortPaused(true);
|
||||
_moveTimer = 0.5 * IN_MILLISECONDS;
|
||||
_phase = PHASE_WP_26;
|
||||
break;
|
||||
case WP_SIRONAS_HILL:
|
||||
{
|
||||
SetEscortPaused(true);
|
||||
|
||||
//Find Sironas and make it respawn if needed
|
||||
Creature* sironas = NULL;
|
||||
Trinity::AllCreaturesOfEntryInRange check(me, NPC_SIRONAS, SIZE_OF_GRIDS);
|
||||
Trinity::CreatureSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, sironas, check);
|
||||
me->VisitNearbyObject(SIZE_OF_GRIDS, searcher);
|
||||
|
||||
if (sironas)
|
||||
{
|
||||
if (!sironas->IsAlive())
|
||||
sironas->Respawn(true);
|
||||
|
||||
sironas->AI()->DoAction(ACTION_SIRONAS_CHANNEL_START);
|
||||
me->SetFacingToObject(sironas);
|
||||
}
|
||||
_moveTimer = 1 * IN_MILLISECONDS;
|
||||
_phase = PHASE_FEEL_SIRONAS_1;
|
||||
break;
|
||||
}
|
||||
case WP_EXPLOSIVES_SECOND_BATTLEROAR:
|
||||
SetEscortPaused(true);
|
||||
_moveTimer = 0.2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_MEET_SIRONAS_ROAR;
|
||||
break;
|
||||
case WP_EXPLOSIVES_SECOND_PLANT:
|
||||
SetEscortPaused(true);
|
||||
_moveTimer = 0.5 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_KNEEL;
|
||||
break;
|
||||
case WP_EXPLOSIVES_SECOND_DETONATE:
|
||||
SetEscortPaused(true);
|
||||
me->SetFacingTo(5.7f);
|
||||
_moveTimer = 2 * IN_MILLISECONDS;
|
||||
_phase = PHASE_PLANT_SECOND_TIMER_1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case ACTION_LEGOSO_SIRONAS_KILLED:
|
||||
_phase = PHASE_SIRONAS_SLAIN_SPEECH_1;
|
||||
_moveTimer = 5 * IN_MILLISECONDS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int8 _phase;
|
||||
uint32 _moveTimer;
|
||||
uint32 _eventStarterGuidLow;
|
||||
GuidList _explosivesGuids;
|
||||
EventMap _events;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_bloodmyst_isle()
|
||||
{
|
||||
new npc_webbed_creature();
|
||||
new npc_sironas();
|
||||
new npc_demolitionist_legoso();
|
||||
}
|
||||
@@ -3617,6 +3617,43 @@ class spell_gen_eject_all_passengers : public SpellScriptLoader
|
||||
}
|
||||
};
|
||||
|
||||
class spell_gen_eject_passenger : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_gen_eject_passenger() : SpellScriptLoader("spell_gen_eject_passenger") { }
|
||||
|
||||
class spell_gen_eject_passenger_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gen_eject_passenger_SpellScript);
|
||||
|
||||
bool Validate(SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Effects[EFFECT_0].CalcValue() < 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EjectPassenger(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Vehicle* vehicle = GetHitUnit()->GetVehicleKit())
|
||||
{
|
||||
if (Unit* passenger = vehicle->GetPassenger(GetEffectValue() - 1))
|
||||
passenger->ExitVehicle();
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_gen_eject_passenger_SpellScript::EjectPassenger, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const override
|
||||
{
|
||||
return new spell_gen_eject_passenger_SpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
enum GMFreeze
|
||||
{
|
||||
SPELL_GM_FREEZE = 9454
|
||||
@@ -4111,6 +4148,7 @@ void AddSC_generic_spell_scripts()
|
||||
new spell_gen_wg_water();
|
||||
new spell_gen_whisper_gulch_yogg_saron_whisper();
|
||||
new spell_gen_eject_all_passengers();
|
||||
new spell_gen_eject_passenger();
|
||||
new spell_gen_gm_freeze();
|
||||
new spell_gen_stand();
|
||||
new spell_gen_mixology_bonus();
|
||||
|
||||
@@ -79,7 +79,7 @@ uint32 MySQLConnection::Open()
|
||||
if (!mysqlInit)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Could not initialize Mysql connection to database `%s`", m_connectionInfo.database.c_str());
|
||||
return false;
|
||||
return CR_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
int port;
|
||||
@@ -491,8 +491,18 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
|
||||
m_reconnecting = true;
|
||||
uint64 oldThreadId = mysql_thread_id(GetHandle());
|
||||
mysql_close(GetHandle());
|
||||
if (this->Open()) // Don't remove 'this' pointer unless you want to skip loading all prepared statements....
|
||||
|
||||
uint32 const lErrno = Open();
|
||||
if (!lErrno)
|
||||
{
|
||||
// Don't remove 'this' pointer unless you want to skip loading all prepared statements...
|
||||
if (!this->PrepareStatements())
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Could not re-prepare statements!");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
TC_LOG_INFO("sql.sql", "Connection to the MySQL server is active.");
|
||||
if (oldThreadId != mysql_thread_id(GetHandle()))
|
||||
TC_LOG_INFO("sql.sql", "Successfully reconnected to %s @%s:%s (%s).",
|
||||
@@ -503,7 +513,7 @@ bool MySQLConnection::_HandleMySQLErrno(uint32 errNo)
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32 lErrno = mysql_errno(GetHandle()); // It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
|
||||
// It's possible this attempted reconnect throws 2006 at us. To prevent crazy recursive calls, sleep here.
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3)); // Sleep 3 seconds
|
||||
return _HandleMySQLErrno(lErrno); // Call self (recursive)
|
||||
}
|
||||
|
||||
@@ -80,26 +80,13 @@ void Appender::write(LogMessage* message)
|
||||
std::ostringstream ss;
|
||||
|
||||
if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
|
||||
ss << message->getTimeStr();
|
||||
ss << message->getTimeStr() << ' ';
|
||||
|
||||
if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL)
|
||||
{
|
||||
if (ss.rdbuf()->in_avail() == 0)
|
||||
ss << ' ';
|
||||
|
||||
ss << Trinity::StringFormat("%-5s", Appender::getLogLevelString(message->level));
|
||||
}
|
||||
ss << Trinity::StringFormat("%-5s ", Appender::getLogLevelString(message->level));
|
||||
|
||||
if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)
|
||||
{
|
||||
if (ss.rdbuf()->in_avail() == 0)
|
||||
ss << ' ';
|
||||
|
||||
ss << '[' << message->type << ']';
|
||||
}
|
||||
|
||||
if (ss.rdbuf()->in_avail() == 0)
|
||||
ss << ' ';
|
||||
ss << '[' << message->type << "] ";
|
||||
|
||||
message->prefix = std::move(ss.str());
|
||||
_write(message);
|
||||
|
||||
@@ -62,6 +62,9 @@ struct LogMessage
|
||||
: level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL))
|
||||
{ }
|
||||
|
||||
LogMessage(LogMessage const& /*other*/) = delete;
|
||||
LogMessage& operator=(LogMessage const& /*other*/) = delete;
|
||||
|
||||
static std::string getTimeStr(time_t time);
|
||||
std::string getTimeStr();
|
||||
|
||||
|
||||
@@ -75,9 +75,7 @@ class Log
|
||||
|
||||
std::unique_ptr<LogMessage> msg(new LogMessage(LOG_LEVEL_INFO, "commands.gm", std::move(Trinity::StringFormat(fmt, args...))));
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << account;
|
||||
msg->param1 = ss.str();
|
||||
msg->param1 = std::to_string(account);
|
||||
|
||||
write(std::move(msg));
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ bool DBUpdater<T>::Update(DatabaseWorkerPool<T>& pool)
|
||||
sConfigMgr->GetBoolDefault("Updates.Redundancy", true),
|
||||
sConfigMgr->GetBoolDefault("Updates.AllowRehash", true),
|
||||
sConfigMgr->GetBoolDefault("Updates.ArchivedRedundancy", false),
|
||||
sConfigMgr->GetBoolDefault("Updates.CleanDeadRef", true));
|
||||
sConfigMgr->GetIntDefault("Updates.CleanDeadRefMaxCount", 3));
|
||||
|
||||
if (!count)
|
||||
TC_LOG_INFO("sql.updates", ">> %s database is up-to-date!", DBUpdater<T>::GetTableName().c_str());
|
||||
|
||||
@@ -101,7 +101,7 @@ UpdateFetcher::DirectoryStorage UpdateFetcher::ReceiveIncludedDirectories() cons
|
||||
|
||||
if (!is_directory(p))
|
||||
{
|
||||
TC_LOG_ERROR("sql.updates", "DBUpdater: Given update include directory \"%s\" isn't existing, skipped!", p.generic_string().c_str());
|
||||
TC_LOG_WARN("sql.updates", "DBUpdater: Given update include directory \"%s\" isn't existing, skipped!", p.generic_string().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ UpdateFetcher::SQLUpdate UpdateFetcher::ReadSQLUpdate(boost::filesystem::path co
|
||||
return update;
|
||||
}
|
||||
|
||||
uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, bool const cleanDeadReferences) const
|
||||
uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash, bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const
|
||||
{
|
||||
LocaleFileStorage const available = GetFileList();
|
||||
AppliedFileStorage applied = ReceiveAppliedFiles();
|
||||
@@ -291,14 +291,28 @@ uint32 UpdateFetcher::Update(bool const redundancyChecks, bool const allowRehash
|
||||
++importedUpdates;
|
||||
}
|
||||
|
||||
for (auto const& entry : applied)
|
||||
// Cleanup up orphaned entries if enabled
|
||||
if (!applied.empty())
|
||||
{
|
||||
TC_LOG_WARN("sql.updates", ">> File \'%s\' was applied to the database but is missing in" \
|
||||
" your update directory now!%s", entry.first.c_str(), cleanDeadReferences ? " Deleting orphaned entry..." : "");
|
||||
}
|
||||
bool const doCleanup = (cleanDeadReferencesMaxCount < 0) || (applied.size() <= static_cast<size_t>(cleanDeadReferencesMaxCount));
|
||||
|
||||
if (cleanDeadReferences)
|
||||
CleanUp(applied);
|
||||
for (auto const& entry : applied)
|
||||
{
|
||||
TC_LOG_WARN("sql.updates", ">> File \'%s\' was applied to the database but is missing in" \
|
||||
" your update directory now!", entry.first.c_str());
|
||||
|
||||
if (doCleanup)
|
||||
TC_LOG_INFO("sql.updates", "Deleting orphaned entry \'%s\'...", entry.first.c_str());
|
||||
}
|
||||
|
||||
if (doCleanup)
|
||||
CleanUp(applied);
|
||||
else
|
||||
{
|
||||
TC_LOG_ERROR("sql.updates", "Cleanup is disabled! There are " SZFMTD " dirty files that were applied to your database " \
|
||||
"but are now missing in your source directory!", applied.size());
|
||||
}
|
||||
}
|
||||
|
||||
return importedUpdates;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
std::function<QueryResult(std::string const&)> const& retrieve);
|
||||
|
||||
uint32 Update(bool const redundancyChecks, bool const allowRehash,
|
||||
bool const archivedRedundancy, bool const cleanDeadReferences) const;
|
||||
bool const archivedRedundancy, int32 const cleanDeadReferencesMaxCount) const;
|
||||
|
||||
private:
|
||||
enum UpdateMode
|
||||
|
||||
@@ -1169,13 +1169,16 @@ Updates.ArchivedRedundancy = 0
|
||||
Updates.AllowRehash = 1
|
||||
|
||||
#
|
||||
# Updates.CleanDeadRef
|
||||
# Description: Cleans dead/ orphaned references that occure if a update was deleted or renamed and edited.
|
||||
# Updates.CleanDeadRefMaxCount
|
||||
# Description: Cleans dead/ orphaned references that occur if an update was removed or renamed and edited in one step.
|
||||
# It only starts the clean up if the count of the missing updates is below or equal the Updates.CleanDeadRefMaxCount value.
|
||||
# This way prevents erasing of the update history due to wrong source directory state (maybe wrong branch or bad revision).
|
||||
# Disable this if you want to know if the database is in a possible "dirty state".
|
||||
# Default: 1 - (Enabled)
|
||||
# Default: 3 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
# -1 - (Enabled - unlimited)
|
||||
|
||||
Updates.CleanDeadRef = 1
|
||||
Updates.CleanDeadRefMaxCount = 3
|
||||
|
||||
#
|
||||
###################################################################################################
|
||||
|
||||
Reference in new issue
Block a user