Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-03-25 10:48:58 -06:00
committed by GitHub
10 changed files with 499 additions and 185 deletions

View File

@@ -0,0 +1,90 @@
-- DB update 2022_03_23_03 -> 2022_03_25_00
DROP PROCEDURE IF EXISTS `updateDb`;
DELIMITER //
CREATE PROCEDURE updateDb ()
proc:BEGIN DECLARE OK VARCHAR(100) DEFAULT 'FALSE';
SELECT COUNT(*) INTO @COLEXISTS
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'version_db_world' AND COLUMN_NAME = '2022_03_23_03';
IF @COLEXISTS = 0 THEN LEAVE proc; END IF;
START TRANSACTION;
ALTER TABLE version_db_world CHANGE COLUMN 2022_03_23_03 2022_03_25_00 bit;
SELECT sql_rev INTO OK FROM version_db_world WHERE sql_rev = '1643290179356130100'; IF OK <> 'FALSE' THEN LEAVE proc; END IF;
--
-- START UPDATING QUERIES
--
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1643290179356130100');
-- npc kneel
DELETE FROM `creature_addon` WHERE (`guid` IN (102453, 102454, 102455, 102457, 102458, 102459, 102462, 102463, 102464, 102466));
INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `visibilityDistanceType`, `auras`) VALUES
(102453, 0, 0, 8, 257, 0, 0, NULL),
(102454, 0, 0, 8, 257, 0, 0, NULL),
(102455, 0, 0, 8, 257, 0, 0, NULL),
(102457, 0, 0, 8, 257, 0, 0, NULL),
(102458, 0, 0, 8, 257, 0, 0, NULL),
(102459, 0, 0, 8, 257, 0, 0, NULL),
(102462, 0, 0, 8, 257, 0, 0, NULL),
(102463, 0, 0, 8, 257, 0, 0, NULL),
(102464, 0, 0, 8, 257, 0, 0, NULL),
(102466, 0, 0, 8, 257, 0, 0, NULL);
-- npc Wounded Skirmisher
DELETE FROM `creature` WHERE (`guid` IN (102453, 102454, 102455, 102456, 102457, 102458, 102459, 102460, 102461, 102462, 102463, 102464, 102466, 102467, 102469));
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES
(102453, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4229.39, -2981.89, 283.151, 1.61792, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102454, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4134.07, -2897.23, 279.272, 5.12241, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102455, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4123.8, -2835.11, 284.196, 0.610865, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102456, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4000.98, -2847.93, 273.325, 6.03884, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102457, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4185.56, -2961.08, 283.319, 0.903392, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102458, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4017.75, -2835.31, 279.277, 1.47867, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102459, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4073.33, -2906.89, 278.332, 6.10865, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102460, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4085.95, -2846.31, 286.589, 2.94961, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102461, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4071.18, -2886.01, 281.6, 5.8294, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102462, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4074.98, -2940.5, 276.138, 4.22481, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102463, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4139.99, -3020.99, 285.459, 5.82814, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102464, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4166.57, -2964.73, 283.2, 2.63745, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102466, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4204.05, -3048.94, 280.839, 4.65053, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102467, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4057.32, -2822.2, 288.962, 3.4383, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0),
(102469, 27463, 0, 0, 571, 0, 0, 1, 1, 1, 4183.3, -2934.44, 283.114, 5.63741, 300, 0, 0, 9940, 0, 0, 0, 0, 0, '', 0);
-- npc Skirmisher Corpse
DELETE FROM `creature` WHERE `guid`=91749;
INSERT INTO `creature` (`guid`, `id1`, `id2`, `id3`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES
(91749, 27457, 0, 0, 571, 0, 0, 1, 1, 1, 4137.9, -3008.35, 285.667, 5.54491, 300, 0, 0, 4399, 0, 0, 0, 0, 0, '', 0);
DELETE FROM `waypoint_data` WHERE `id`=274630;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(274630, 1, 4153.06, -2928.47, 282.58, 0, 0, 1, 0, 100, 0),
(274630, 2, 4184.53, -2909.76, 280.17, 0, 0, 1, 0, 100, 0);
DELETE FROM `waypoint_data` WHERE `id`=274631;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(274631, 1, 4138.41, -2950.63, 282.92, 0, 0, 1, 0, 100, 0),
(274631, 2, 4153.06, -2928.47, 282.58, 0, 0, 1, 0, 100, 0),
(274631, 3, 4184.53, -2909.76, 280.17, 0, 0, 1, 0, 100, 0);
DELETE FROM `waypoint_data` WHERE `id`=274632;
INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
(274632, 1, 4184.53, -2909.76, 280.17, 0, 0, 1, 0, 100, 0);
/* implementing both conditions */
DELETE FROM `spell_script_names` WHERE `spell_id`=48812 AND `ScriptName`='spell_renew_skirmisher';
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(48812, 'spell_renew_skirmisher');
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=17 AND `SourceGroup`=0 AND `SourceEntry`=48812;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`,`SourceGroup`,`SourceEntry`,`SourceId`,`ElseGroup`,`ConditionTypeOrReference`,`ConditionTarget`,`ConditionValue1`,`ConditionValue2`,`ConditionValue3`,`NegativeCondition`,`ErrorType`,`ErrorTextId`,`ScriptName`,`Comment`) VALUES
(17,0,48812,0,0,31,1,3,27463,0,0,0,0,"","Heals a wounded skirmisher at Blue Sky Logging Ground.");
--
-- END UPDATING QUERIES
--
UPDATE version_db_world SET date = '2022_03_25_00' WHERE sql_rev = '1643290179356130100';
COMMIT;
END //
DELIMITER ;
CALL updateDb();
DROP PROCEDURE IF EXISTS `updateDb`;

View File

@@ -21,6 +21,7 @@
#include "Common.h"
#include "Creature.h"
#include "UnitAI.h"
#include "EventMap.h"
class WorldObject;
class Unit;
@@ -67,6 +68,8 @@ class CreatureAI : public UnitAI
protected:
Creature* const me;
EventMap events;
bool UpdateVictim();
bool UpdateVictimWithGaze();

View File

@@ -20,6 +20,7 @@
#include "DBCFileLoader.h"
#include "DBCfmt.h"
#include "Errors.h"
#include "LFGMgr.h"
#include "Log.h"
#include "SharedDefines.h"
#include "SpellMgr.h"
@@ -529,7 +530,7 @@ void LoadDBCStores(const std::string& dataPath)
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price);
sTaxiPathSetBySource[entry->from][entry->to] = entry;
// Calculate path nodes count
uint32 pathCount = sTaxiPathStore.GetNumRows();
@@ -578,7 +579,7 @@ void LoadDBCStores(const std::string& dataPath)
for (TaxiPathSetForSource::const_iterator dest_i = src_i->second.begin(); dest_i != src_i->second.end(); ++dest_i)
{
// not spell path
if (dest_i->second.price || spellPaths.find(dest_i->second.ID) == spellPaths.end())
if (dest_i->second->price || spellPaths.find(dest_i->second->ID) == spellPaths.end())
{
ok = true;
break;
@@ -871,6 +872,19 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty)
return nullptr;
}
LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale)
{
for (LFGDungeonEntry const* dungeon : sLFGDungeonStore)
{
if (dungeon->type == lfg::LFG_TYPE_ZONE && zoneName.find(dungeon->name[locale]) != std::string::npos)
{
return dungeon;
}
}
return nullptr;
}
uint32 GetDefaultMapLight(uint32 mapId)
{
for (int32 i = sLightStore.GetNumRows(); i >= 0; --i)

View File

@@ -66,6 +66,8 @@ CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, ui
CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType, uint8 gender, uint8 type, uint8 color);
LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
LFGDungeonEntry const* GetZoneLFGDungeonEntry(std::string const& zoneName, LocaleConstant locale);
uint32 GetDefaultMapLight(uint32 mapId);
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;

View File

@@ -69,6 +69,7 @@ namespace lfg
LFG_TYPE_NONE = 0,
LFG_TYPE_DUNGEON = 1,
LFG_TYPE_RAID = 2,
LFG_TYPE_ZONE = 4,
LFG_TYPE_HEROIC = 5,
LFG_TYPE_RANDOM = 6
};

View File

@@ -6435,8 +6435,8 @@ void ObjectMgr::GetTaxiPath(uint32 source, uint32 destination, uint32& path, uin
return;
}
cost = dest_i->second.price;
path = dest_i->second.ID;
cost = dest_i->second->price;
path = dest_i->second->ID;
}
uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, TeamId teamId, bool allowed_alt_team /* = false */)

View File

@@ -33,6 +33,7 @@
#include "InstanceSaveMgr.h"
#include "Language.h"
#include "Log.h"
#include "MapMgr.h"
#include "Metric.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
@@ -2168,33 +2169,97 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
if (factionChangeInfo->FactionChange)
{
// Delete all Flypaths
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
stmt->SetData(0, lowGuid);
trans->Append(stmt);
if (level > 7)
{
// Update Taxi path
// this doesn't seem to be 100% blizzlike... but it can't really be helped.
std::ostringstream taximaskstream;
uint32 numFullTaximasks = level / 7;
// Delete all Flypaths
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXI_PATH);
stmt->SetData(0, lowGuid);
trans->Append(stmt);
if (numFullTaximasks > 11)
numFullTaximasks = 11;
// Update Taxi path
TaxiMask newTaxiMask;
memset(newTaxiMask, 0, sizeof(newTaxiMask));
TaxiMask const& factionMask = newTeam == TEAM_HORDE ? sHordeTaxiNodesMask : sAllianceTaxiNodesMask;
for (uint8 i = 0; i < numFullTaximasks; ++i)
for (auto const& itr : sTaxiPathSetBySource)
{
uint8 deathKnightExtraNode = (playerClass == CLASS_DEATH_KNIGHT) ? sDeathKnightTaxiNodesMask[i] : 0;
taximaskstream << uint32(factionMask[i] | deathKnightExtraNode) << ' ';
auto FillTaxiMask = [&](uint8 field, uint32 mask)
{
if (playerClass == CLASS_DEATH_KNIGHT)
{
newTaxiMask[field] |= uint32(mask | (sDeathKnightTaxiNodesMask[field] & mask));
}
else
{
newTaxiMask[field] |= mask;
}
};
uint32 nodeId = itr.first;
uint8 field = (uint8)((nodeId - 1) / 32);
uint32 submask = 1 << ((nodeId - 1) % 32);
if ((factionMask[field] & submask) == 0)
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathSetForSource const& taxiPaths = itr.second;
if (taxiPaths.empty())
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathEntry const* taxiPath = taxiPaths.begin()->second;
if (!taxiPath)
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathNodeList const& taxiNodePaths = sTaxiPathNodesByPath[taxiPath->ID];
if (taxiNodePaths.empty())
{
FillTaxiMask(field, 0);
continue;
}
TaxiPathNodeEntry const* pathNode = taxiNodePaths.front();
if (!pathNode)
{
FillTaxiMask(field, 0);
continue;
}
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(sMapMgr->GetZoneId(PHASEMASK_NORMAL, pathNode->mapid, pathNode->x, pathNode->y, pathNode->z));
if (!zone)
{
FillTaxiMask(field, 0);
continue;
}
LFGDungeonEntry const* lfgDungeon = GetZoneLFGDungeonEntry(zone->area_name[GetSessionDbLocaleIndex()], GetSessionDbLocaleIndex());
if (!lfgDungeon)
{
FillTaxiMask(field, 0);
continue;
}
// Get level from LFGDungeonEntry because the one from AreaTableEntry is not valid
// If area level is too big, do not add new taxi
if (lfgDungeon->minlevel > level)
{
FillTaxiMask(field, 0);
continue;
}
FillTaxiMask(field, submask);
}
uint32 numEmptyTaximasks = 11 - numFullTaximasks;
for (uint8 i = 0; i < numEmptyTaximasks; ++i)
taximaskstream << "0 ";
taximaskstream << '0';
std::ostringstream taximaskstream;
for (uint8 i = 0; i < TaxiMaskSize; ++i)
taximaskstream << uint32(newTaxiMask[i]) << ' ';
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_TAXIMASK);
stmt->SetData(0, taximaskstream.str());

View File

@@ -111,6 +111,10 @@ public:
break;
case EVENT_LAUNCH:
{
if (Player* player = me->GetCharmerOrOwnerPlayerOrPlayerItself())
{
player->AddAura(SPELL_EYE_OF_ACHERUS_VISUAL, player);
}
me->SetSpeed(MOVE_FLIGHT, 5.0f, true);
const Position EYE_DESTINATION_1 = { me->GetPositionX() - 40.0f, me->GetPositionY(), me->GetPositionZ() + 10.0f, 0.0f };
@@ -118,6 +122,10 @@ public:
me->GetMotionMaster()->MovePoint(EYE_POINT_DESTINATION_1, EYE_DESTINATION_1);
me->GetMotionMaster()->MovePoint(EYE_POINT_DESTINATION_2, EYE_DESTINATION_2);
if (Player* player = me->GetCharmerOrOwnerPlayerOrPlayerItself())
{
player->RemoveAura(SPELL_EYE_OF_ACHERUS_VISUAL);
}
break;
}
case EVENT_REGAIN_CONTROL:

View File

@@ -25,37 +25,37 @@
#include "SpellInfo.h"
#include "SpellScript.h"
// Theirs
// Theirs
/*######
## Quest 12027: Mr. Floppy's Perilous Adventure
######*/
/*######
## Quest 12027: Mr. Floppy's Perilous Adventure
######*/
enum Floppy
{
// Creature
NPC_MRFLOPPY = 26589,
NPC_HUNGRY_WORG = 26586,
NPC_RAVENOUS_WORG = 26590, // RWORG
NPC_EMILY = 26588,
NPC_MRFLOPPY = 26589,
NPC_HUNGRY_WORG = 26586,
NPC_RAVENOUS_WORG = 26590, // RWORG
NPC_EMILY = 26588,
// Quest
QUEST_PERILOUS_ADVENTURE = 12027,
QUEST_PERILOUS_ADVENTURE = 12027,
// Spell
SPELL_MRFLOPPY = 47184, // vehicle aura
SPELL_MRFLOPPY = 47184, // vehicle aura
// Text
SAY_WORGHAGGRO1 = 0, // Um... I think one of those wolves is back...
SAY_WORGHAGGRO2 = 1, // He's going for Mr. Floppy!
SAY_WORGRAGGRO3 = 2, // Oh, no! Look, it's another wolf, and it's a biiiiiig one!
SAY_WORGRAGGRO4 = 3, // He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta!
SAY_RANDOMAGGRO = 4, // There's a big meanie attacking Mr. Floppy! Help!
SAY_VICTORY1 = 5, // Let's get out of here before more wolves find us!
SAY_VICTORY2 = 6, // Don't go toward the light, Mr. Floppy!
SAY_VICTORY3 = 7, // Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy!
SAY_VICTORY4 = 8, // I think I see the camp! We're almost home, Mr. Floppy! Let's go!
TEXT_EMOTE_WP1 = 9, // Mr. Floppy revives
TEXT_EMOTE_AGGRO = 10, // The Ravenous Worg chomps down on Mr. Floppy
SAY_QUEST_ACCEPT = 11, // Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves!
SAY_QUEST_COMPLETE = 12 // Thank you for helping me get back to the camp. Go tell Walter that I'm safe now!
SAY_WORGHAGGRO1 = 0, // Um... I think one of those wolves is back...
SAY_WORGHAGGRO2 = 1, // He's going for Mr. Floppy!
SAY_WORGRAGGRO3 = 2, // Oh, no! Look, it's another wolf, and it's a biiiiiig one!
SAY_WORGRAGGRO4 = 3, // He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta!
SAY_RANDOMAGGRO = 4, // There's a big meanie attacking Mr. Floppy! Help!
SAY_VICTORY1 = 5, // Let's get out of here before more wolves find us!
SAY_VICTORY2 = 6, // Don't go toward the light, Mr. Floppy!
SAY_VICTORY3 = 7, // Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy!
SAY_VICTORY4 = 8, // I think I see the camp! We're almost home, Mr. Floppy! Let's go!
TEXT_EMOTE_WP1 = 9, // Mr. Floppy revives
TEXT_EMOTE_AGGRO = 10, // The Ravenous Worg chomps down on Mr. Floppy
SAY_QUEST_ACCEPT = 11, // Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves!
SAY_QUEST_COMPLETE = 12 // Thank you for helping me get back to the camp. Go tell Walter that I'm safe now!
};
// emily
@@ -84,102 +84,102 @@ public:
switch (waypointId)
{
case 9:
if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f))
_mrfloppyGUID = Mrfloppy->GetGUID();
break;
case 10:
if (ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
Talk(SAY_WORGHAGGRO1);
if (Creature* worg = me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX() + 5, me->GetPositionY() + 2, me->GetPositionZ() + 1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000))
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
worg->SetReactState(REACT_AGGRESSIVE);
worg->GetAI()->AttackStart(Mrfloppy);
}
}
break;
case 11:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
break;
case 17:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
Talk(SAY_WORGRAGGRO3);
if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX() + 10, me->GetPositionY() + 8, me->GetPositionZ() + 2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000))
{
RWORG->SetReactState(REACT_PASSIVE);
RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
_RavenousworgGUID = RWORG->GetGUID();
}
break;
case 18:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
me->AddAura(SPELL_MRFLOPPY, Mrfloppy);
}
break;
case 19:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Mrfloppy->HasAura(SPELL_MRFLOPPY))
case 9:
if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f))
_mrfloppyGUID = Mrfloppy->GetGUID();
break;
case 10:
if (ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
Talk(SAY_WORGHAGGRO1);
if (Creature* worg = me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX() + 5, me->GetPositionY() + 2, me->GetPositionZ() + 1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000))
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
Mrfloppy->EnterVehicle(RWORG);
worg->SetReactState(REACT_AGGRESSIVE);
worg->GetAI()->AttackStart(Mrfloppy);
}
}
break;
case 20:
}
break;
case 11:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
break;
case 17:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
Talk(SAY_WORGRAGGRO3);
if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX() + 10, me->GetPositionY() + 8, me->GetPositionZ() + 2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000))
{
RWORG->SetReactState(REACT_PASSIVE);
RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
RWORG->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
_RavenousworgGUID = RWORG->GetGUID();
}
break;
case 18:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
RWORG->HandleEmoteCommand(34);
break;
case 21:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
me->AddAura(SPELL_MRFLOPPY, Mrfloppy);
}
break;
case 19:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Mrfloppy->HasAura(SPELL_MRFLOPPY))
{
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
{
Unit::Kill(RWORG, Mrfloppy);
Mrfloppy->ExitVehicle();
RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
RWORG->AI()->AttackStart(player);
Talk(SAY_VICTORY2);
}
Mrfloppy->EnterVehicle(RWORG);
}
break;
case 22:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
}
break;
case 20:
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
RWORG->HandleEmoteCommand(34);
break;
case 21:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Creature* RWORG = ObjectAccessor::GetCreature(*me, _RavenousworgGUID))
{
if (Mrfloppy->isDead())
{
me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
Mrfloppy->setDeathState(ALIVE);
Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
Talk(SAY_VICTORY3);
}
Unit::Kill(RWORG, Mrfloppy);
Mrfloppy->ExitVehicle();
RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
RWORG->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
RWORG->AI()->AttackStart(player);
Talk(SAY_VICTORY2);
}
break;
case 24:
if (player)
}
break;
case 22:
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
{
if (Mrfloppy->isDead())
{
player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me);
Talk(SAY_QUEST_COMPLETE, player);
me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
Mrfloppy->setDeathState(ALIVE);
Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
Talk(SAY_VICTORY3);
}
me->SetWalk(false);
break;
case 25:
Talk(SAY_VICTORY4);
break;
case 27:
me->DisappearAndDie();
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->DisappearAndDie();
break;
}
break;
case 24:
if (player)
{
player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me);
Talk(SAY_QUEST_COMPLETE, player);
}
me->SetWalk(false);
break;
case 25:
Talk(SAY_VICTORY4);
break;
case 27:
me->DisappearAndDie();
if (Creature* Mrfloppy = ObjectAccessor::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->DisappearAndDie();
break;
}
}
@@ -506,66 +506,204 @@ enum Skirmisher
{
// Quest
QUEST_OVERWHELMED = 12288,
// Spell
SPELL_RENEW_SKIRMISHER = 48812,
SPELL_KILL_CREDIT = 48813,
SPELL_CLEAVE = 15496,
SPELL_HAMSTRING = 9080,
SPELL_MORTAL_STRIKE = 32736,
// Text
SAY_RANDOM = 0
SAY_RANDOM = 0,
// EVENT
EVENT_WOUNDED_MOVE = 1,
EVENT_CLEAVE = 2,
EVENT_HAMSTRING = 3,
EVENT_MORTAL_STRIKE = 4,
// Waypoints
WOUNDED_MOVE_1 = 274630,
WOUNDED_MOVE_2 = 274631,
WOUNDED_MOVE_3 = 274632
};
class npc_wounded_skirmisher : public CreatureScript
struct npc_wounded_skirmisher : public CreatureAI
{
public:
npc_wounded_skirmisher() : CreatureScript("npc_wounded_skirmisher") { }
struct npc_wounded_skirmisherAI : public ScriptedAI
npc_wounded_skirmisher(Creature* creature) : CreatureAI(creature)
{
npc_wounded_skirmisherAI(Creature* creature) : ScriptedAI(creature) { }
Initialize();
}
void Reset() override
{
_despawnTimer = 5000;
_playerGUID.Clear();
}
void Initialize()
{
me->SetReactState(REACT_DEFENSIVE);
}
void MovementInform(uint32, uint32 id) override
{
if (id == 1)
me->DespawnOrUnsummon(_despawnTimer);
}
void Reset() override
{
Initialize();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
void EnterCombat(Unit* /*who*/) override
{
events.ScheduleEvent(EVENT_CLEAVE, urand(1000, 7000));
events.ScheduleEvent(EVENT_HAMSTRING, urand(5000, 12000));
events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(5000, 10000));
}
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
Player* playerCaster = caster->ToPlayer();
if (!playerCaster)
return;
if (spell->Id == SPELL_RENEW_SKIRMISHER && playerCaster->GetQuestStatus(QUEST_OVERWHELMED) == QUEST_STATUS_INCOMPLETE)
{
if (spell->Id == SPELL_RENEW_SKIRMISHER && caster->GetTypeId() == TYPEID_PLAYER
&& caster->ToPlayer()->GetQuestStatus(QUEST_OVERWHELMED) == QUEST_STATUS_INCOMPLETE)
me->SetFacingToObject(caster);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
Talk(SAY_RANDOM, caster);
DoCast(caster, SPELL_KILL_CREDIT);
if (!me->IsStandState())
{
DoCast(caster, SPELL_KILL_CREDIT);
Talk(SAY_RANDOM, caster);
if (me->IsStandState())
me->GetMotionMaster()->MovePoint(1, me->GetPositionX() + 7, me->GetPositionY() + 7, me->GetPositionZ());
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
me->DespawnOrUnsummon(_despawnTimer);
}
me->SetStandState(UNIT_STAND_STATE_STAND);
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
events.ScheduleEvent(EVENT_WOUNDED_MOVE, 3000);
}
}
}
void UpdateAI(uint32 /*diff*/) override
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
private:
ObjectGuid _playerGUID;
uint32 _despawnTimer;
};
CreatureAI* GetAI(Creature* creature) const override
void UpdateAI(uint32 diff) override
{
return new npc_wounded_skirmisherAI(creature);
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_WOUNDED_MOVE:
if (me->GetPositionY() == -2835.11f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(20000);
}
if (me->GetPositionY() == -2981.89f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false);
me->DespawnOrUnsummon(18000);
}
if (me->GetPositionY() == -2934.44f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false);
me->DespawnOrUnsummon(9000);
}
if (me->GetPositionY() == -3020.99f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(22000);
}
if (me->GetPositionY() == -2964.73f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_2, false);
me->DespawnOrUnsummon(15000);
}
if (me->GetPositionY() == -2940.50f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(20000);
}
if (me->GetPositionY() == -2847.93f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(30000);
}
if (me->GetPositionY() == -2835.31f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(27000);
}
if (me->GetPositionY() == -2822.20f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(25000);
}
if (me->GetPositionY() == -2846.31f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_1, false);
me->DespawnOrUnsummon(21000);
}
if (me->GetPositionY() == -2897.23f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false);
me->DespawnOrUnsummon(15000);
}
if (me->GetPositionY() == -2886.01f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false);
me->DespawnOrUnsummon(25000);
}
if (me->GetPositionY() == -2906.89f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_3, false);
me->DespawnOrUnsummon(25000);
}
if (me->GetPositionY() == -3048.94f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_2, false);
me->DespawnOrUnsummon(30000);
}
if (me->GetPositionY() == -2961.08f)
{
me->GetMotionMaster()->MovePath(WOUNDED_MOVE_2, false);
me->DespawnOrUnsummon(25000);
}
break;
case EVENT_CLEAVE:
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
events.RepeatEvent(urand(7000, 15000));
break;
case EVENT_HAMSTRING:
me->CastSpell(me->GetVictim(), SPELL_HAMSTRING, false);
events.RepeatEvent(urand(9000, 15000));
break;
case EVENT_MORTAL_STRIKE:
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
events.RepeatEvent(urand(10000, 15000));
break;
}
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
enum renewskirmisher
{
NPC_WOUNDED_SKIRMISHER = 27463
};
class spell_renew_skirmisher : public SpellScript
{
public:
PrepareSpellScript(spell_renew_skirmisher);
SpellCastResult CheckRequirement()
{
if (Unit* caster = GetCaster())
if (Creature* wounded = caster->FindNearestCreature(NPC_WOUNDED_SKIRMISHER, 5.0f))
if (!wounded->IsInCombat())
return SPELL_CAST_OK;
return SPELL_FAILED_CASTER_AURASTATE;
}
void Register() override
{
OnCheckCast += SpellCheckCastFn(spell_renew_skirmisher::CheckRequirement);
}
};
@@ -1163,7 +1301,8 @@ void AddSC_grizzly_hills()
new npc_outhouse_bunny();
new npc_tallhorn_stag();
new npc_amberpine_woodsman();
new npc_wounded_skirmisher();
RegisterCreatureAI(npc_wounded_skirmisher);
RegisterSpellScript(spell_renew_skirmisher);
new npc_venture_co_straggler();
new npc_lake_frog();
new spell_shredder_delivery();

View File

@@ -2195,15 +2195,7 @@ struct TalentSpellPos
typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap;
struct TaxiPathBySourceAndDestination
{
TaxiPathBySourceAndDestination() = default;
TaxiPathBySourceAndDestination(uint32 _id, uint32 _price) : ID(_id), price(_price) {}
uint32 ID{0};
uint32 price{0};
};
typedef std::map<uint32, TaxiPathBySourceAndDestination> TaxiPathSetForSource;
typedef std::map<uint32, TaxiPathEntry const*> TaxiPathSetForSource;
typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource;
typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList;