Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
-- DB update 2022_09_19_08 -> 2022_09_21_00
|
||||||
|
--
|
||||||
|
UPDATE `creature_template` SET `flags_extra`=`flags_extra`|0x02000000 WHERE `entry` IN (14825, 14882, 14883);
|
||||||
|
UPDATE `creature_formations` SET `groupAI`=515 WHERE `LeaderGUID`=49359 AND `memberGUID` IN (49359,49361,49362,49389);
|
||||||
|
UPDATE `creature_formations` SET `groupAI`=515 WHERE `LeaderGUID`=49651 AND `memberGUID` IN (49651,49652,49653,49654);
|
||||||
|
|
||||||
|
DELETE FROM `creature_formations` WHERE `LeaderGUID` IN (49363,49383,49387,49397,49373) AND `memberGUID` IN (49363,49364,49365,49366,49367,49368,49369,49370,49371,49372,49373,49374,49375,49376,49377,49378,49379,49380,49381,49382,49383,49384,49385,49386,49387,49388,49390,49391,49392,49393,49394,49395,49396,49397,49398,49399,49400);
|
||||||
|
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`, `point_1`, `point_2`) VALUES
|
||||||
|
(49363, 49363, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49370, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49364, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49368, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49372, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49371, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49367, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49365, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49366, 0, 0, 3, 0, 0),
|
||||||
|
(49363, 49369, 0, 0, 3, 0, 0),
|
||||||
|
|
||||||
|
(49383, 49383, 0, 0, 3, 0, 0),
|
||||||
|
(49383, 49384, 0, 0, 3, 0, 0),
|
||||||
|
(49383, 49385, 0, 0, 3, 0, 0),
|
||||||
|
(49383, 49386, 0, 0, 3, 0, 0),
|
||||||
|
|
||||||
|
(49387, 49387, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49393, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49388, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49392, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49390, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49396, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49391, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49395, 0, 0, 3, 0, 0),
|
||||||
|
(49387, 49394, 0, 0, 3, 0, 0),
|
||||||
|
|
||||||
|
(49397, 49397, 0, 0, 3, 0, 0),
|
||||||
|
(49397, 49398, 0, 0, 3, 0, 0),
|
||||||
|
(49397, 49399, 0, 0, 3, 0, 0),
|
||||||
|
(49397, 49400, 0, 0, 3, 0, 0),
|
||||||
|
|
||||||
|
(49373, 49373, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49381, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49382, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49380, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49379, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49375, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49378, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49376, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49377, 0, 0, 3, 0, 0),
|
||||||
|
(49373, 49374, 0, 0, 3, 0, 0);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DB update 2022_09_21_00 -> 2022_09_21_01
|
||||||
|
--
|
||||||
|
UPDATE `creature_formations` SET `groupAI` = 515 WHERE `leaderGUID` = 87648 AND `memberGUID` IN (87649, 87650, 87651);
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- DB update 2022_09_21_01 -> 2022_09_21_02
|
||||||
|
UPDATE `quest_offer_reward` SET `RewardText`='Hmmm, Narm sent you to me, did he?$b$bWell then, Narm could always be trusted, so that must mean you\'re ready to take part of the next sapta--the sapta of fire.$b$bI see it in your eyes already, the burning, the desire. You\'ve tasted power, and now you\'re ready for more of it. Patience, $N. Remember what earth taught you. Power and destruction will come easily, but you must still know when to stay your hand.' WHERE `ID`=2984;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- DB update 2022_09_21_02 -> 2022_09_21_03
|
||||||
|
--
|
||||||
|
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_item_freeze_rookery_egg';
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
|
||||||
|
(15748, 'spell_item_freeze_rookery_egg'), -- item
|
||||||
|
(16028, 'spell_item_freeze_rookery_egg'); -- quest
|
||||||
@@ -868,6 +868,14 @@ StartHeroicPlayerLevel = 55
|
|||||||
|
|
||||||
StartPlayerMoney = 0
|
StartPlayerMoney = 0
|
||||||
|
|
||||||
|
#
|
||||||
|
# StartHeroicPlayerMoney
|
||||||
|
# Description: Amount of money (in Copper) that heroic class characters have after creation.
|
||||||
|
# Default: 2000
|
||||||
|
# 2000 - (20 Silver)
|
||||||
|
|
||||||
|
StartHeroicPlayerMoney = 2000
|
||||||
|
|
||||||
#
|
#
|
||||||
# MaxHonorPoints
|
# MaxHonorPoints
|
||||||
# Description: Maximum honor points a character can have.
|
# Description: Maximum honor points a character can have.
|
||||||
@@ -2156,6 +2164,14 @@ Visibility.Notify.Period.InBGArenas = 1000
|
|||||||
|
|
||||||
Visibility.ObjectSparkles = 1
|
Visibility.ObjectSparkles = 1
|
||||||
|
|
||||||
|
#
|
||||||
|
# Visibility.ObjectQuestMarkers
|
||||||
|
# Description: Show quest icons above game objects in the same way as creature quest givers.
|
||||||
|
# Default: 1 - (Show quest markers, post patch 2.3 behavior)
|
||||||
|
# 0 - (Hide quest markers, pre patch 2.3 behavior)
|
||||||
|
|
||||||
|
Visibility.ObjectQuestMarkers = 1
|
||||||
|
|
||||||
#
|
#
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -3428,15 +3428,19 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
|
|||||||
if (!me || !me->IsEngaged() || !me->GetVictim())
|
if (!me || !me->IsEngaged() || !me->GetVictim())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max))
|
if (me->IsInRange(me->GetVictim(), (float)e.event.rangeRepeat.minRange, (float)e.event.rangeRepeat.maxRange))
|
||||||
ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim());
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (!e.event.minMaxRepeat.controller)
|
if (e.event.rangeRepeat.onlyFireOnRepeat == 2)
|
||||||
RecalcTimer(e, 500, 500); // xinef: make it predictable "Malcrom: This seems to be done to standardize min, max start rather than using the range values for the timer."
|
{
|
||||||
|
e.event.rangeRepeat.onlyFireOnRepeat = 1;
|
||||||
|
RecalcTimer(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); // Malcrom: if param5 value is greater than 0 first action will not happen until after repeat timer fires.
|
ProcessTimedAction(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax, me->GetVictim());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
RecalcTimer(e, 500, 500); // make it predictable
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SMART_EVENT_VICTIM_CASTING:
|
case SMART_EVENT_VICTIM_CASTING:
|
||||||
@@ -4000,6 +4004,13 @@ void SmartScript::InitTimer(SmartScriptHolder& e)
|
|||||||
switch (e.GetEventType())
|
switch (e.GetEventType())
|
||||||
{
|
{
|
||||||
//set only events which have initial timers
|
//set only events which have initial timers
|
||||||
|
case SMART_EVENT_RANGE:
|
||||||
|
// If onlyFireOnRepeat is true set to 2 before entering combat. Will be set back to 1 after entering combat to ignore initial firing.
|
||||||
|
if (e.event.rangeRepeat.onlyFireOnRepeat == 1)
|
||||||
|
e.event.rangeRepeat.onlyFireOnRepeat = 2;
|
||||||
|
// make it predictable
|
||||||
|
RecalcTimer(e, 500, 500);
|
||||||
|
break;
|
||||||
case SMART_EVENT_NEAR_PLAYERS:
|
case SMART_EVENT_NEAR_PLAYERS:
|
||||||
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
case SMART_EVENT_NEAR_PLAYERS_NEGATION:
|
||||||
RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer);
|
RecalcTimer(e, e.event.nearPlayer.firstTimer, e.event.nearPlayer.firstTimer);
|
||||||
@@ -4291,10 +4302,10 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTrigger const* at)
|
|||||||
InitTimer((*i));//calculate timers for first time use
|
InitTimer((*i));//calculate timers for first time use
|
||||||
if (i->GetEventType() == SMART_EVENT_RANGE && i->GetActionType() == SMART_ACTION_ALLOW_COMBAT_MOVEMENT)
|
if (i->GetEventType() == SMART_EVENT_RANGE && i->GetActionType() == SMART_ACTION_ALLOW_COMBAT_MOVEMENT)
|
||||||
{
|
{
|
||||||
if (i->action.combatMove.move == 1 && i->event.minMaxRepeat.min > minEnableDist)
|
if (i->action.combatMove.move == 1 && i->event.rangeRepeat.minRange > minEnableDist)
|
||||||
minEnableDist = i->event.minMaxRepeat.min;
|
minEnableDist = i->event.rangeRepeat.minRange;
|
||||||
else if (i->action.combatMove.move == 0 && (i->event.minMaxRepeat.max < maxDisableDist || maxDisableDist == 0))
|
else if (i->action.combatMove.move == 0 && (i->event.rangeRepeat.maxRange < maxDisableDist || maxDisableDist == 0))
|
||||||
maxDisableDist = i->event.minMaxRepeat.max;
|
maxDisableDist = i->event.rangeRepeat.maxRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Xinef: if smartcast combat move flag is present
|
// Xinef: if smartcast combat move flag is present
|
||||||
|
|||||||
@@ -260,7 +260,6 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
|||||||
case SMART_EVENT_TARGET_HEALTH_PCT:
|
case SMART_EVENT_TARGET_HEALTH_PCT:
|
||||||
case SMART_EVENT_MANA_PCT:
|
case SMART_EVENT_MANA_PCT:
|
||||||
case SMART_EVENT_TARGET_MANA_PCT:
|
case SMART_EVENT_TARGET_MANA_PCT:
|
||||||
case SMART_EVENT_RANGE:
|
|
||||||
case SMART_EVENT_FRIENDLY_HEALTH:
|
case SMART_EVENT_FRIENDLY_HEALTH:
|
||||||
case SMART_EVENT_FRIENDLY_HEALTH_PCT:
|
case SMART_EVENT_FRIENDLY_HEALTH_PCT:
|
||||||
case SMART_EVENT_FRIENDLY_MISSING_BUFF:
|
case SMART_EVENT_FRIENDLY_MISSING_BUFF:
|
||||||
@@ -269,6 +268,13 @@ void SmartAIMgr::LoadSmartAIFromDB()
|
|||||||
if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0)
|
if (temp.event.minMaxRepeat.repeatMin == 0 && temp.event.minMaxRepeat.repeatMax == 0)
|
||||||
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
||||||
break;
|
break;
|
||||||
|
case SMART_EVENT_RANGE:
|
||||||
|
if (temp.event.rangeRepeat.repeatMin == 0 && temp.event.rangeRepeat.repeatMax == 0)
|
||||||
|
temp.event.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE;
|
||||||
|
// Will only work properly if value is 0 or 1
|
||||||
|
if (temp.event.rangeRepeat.onlyFireOnRepeat > 1)
|
||||||
|
temp.event.rangeRepeat.onlyFireOnRepeat = 1;
|
||||||
|
break;
|
||||||
case SMART_EVENT_VICTIM_CASTING:
|
case SMART_EVENT_VICTIM_CASTING:
|
||||||
case SMART_EVENT_IS_BEHIND_TARGET:
|
case SMART_EVENT_IS_BEHIND_TARGET:
|
||||||
if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0)
|
if (temp.event.minMaxRepeat.min == 0 && temp.event.minMaxRepeat.max == 0)
|
||||||
@@ -472,7 +478,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e)
|
|||||||
case SMART_EVENT_DEATH: return NO_PARAMS;
|
case SMART_EVENT_DEATH: return NO_PARAMS;
|
||||||
case SMART_EVENT_EVADE: return NO_PARAMS;
|
case SMART_EVENT_EVADE: return NO_PARAMS;
|
||||||
case SMART_EVENT_SPELLHIT: return sizeof(SmartEvent::spellHit);
|
case SMART_EVENT_SPELLHIT: return sizeof(SmartEvent::spellHit);
|
||||||
case SMART_EVENT_RANGE: return sizeof(SmartEvent::minMaxRepeat);
|
case SMART_EVENT_RANGE: return sizeof(SmartEvent::rangeRepeat);
|
||||||
case SMART_EVENT_OOC_LOS: return sizeof(SmartEvent::los);
|
case SMART_EVENT_OOC_LOS: return sizeof(SmartEvent::los);
|
||||||
case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn);
|
case SMART_EVENT_RESPAWN: return sizeof(SmartEvent::respawn);
|
||||||
case SMART_EVENT_TARGET_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat);
|
case SMART_EVENT_TARGET_HEALTH_PCT: return sizeof(SmartEvent::minMaxRepeat);
|
||||||
@@ -911,7 +917,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||||||
case SMART_EVENT_MANA_PCT:
|
case SMART_EVENT_MANA_PCT:
|
||||||
case SMART_EVENT_TARGET_HEALTH_PCT:
|
case SMART_EVENT_TARGET_HEALTH_PCT:
|
||||||
case SMART_EVENT_TARGET_MANA_PCT:
|
case SMART_EVENT_TARGET_MANA_PCT:
|
||||||
case SMART_EVENT_RANGE:
|
|
||||||
case SMART_EVENT_DAMAGED:
|
case SMART_EVENT_DAMAGED:
|
||||||
case SMART_EVENT_DAMAGED_TARGET:
|
case SMART_EVENT_DAMAGED_TARGET:
|
||||||
case SMART_EVENT_RECEIVE_HEAL:
|
case SMART_EVENT_RECEIVE_HEAL:
|
||||||
@@ -921,6 +926,13 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
|||||||
if (!IsMinMaxValid(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax))
|
if (!IsMinMaxValid(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
case SMART_EVENT_RANGE:
|
||||||
|
if (!IsMinMaxValid(e, e.event.rangeRepeat.minRange, e.event.rangeRepeat.maxRange))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!IsMinMaxValid(e, e.event.rangeRepeat.repeatMin, e.event.rangeRepeat.repeatMax))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
case SMART_EVENT_SPELLHIT:
|
case SMART_EVENT_SPELLHIT:
|
||||||
case SMART_EVENT_SPELLHIT_TARGET:
|
case SMART_EVENT_SPELLHIT_TARGET:
|
||||||
if (e.event.spellHit.spell)
|
if (e.event.spellHit.spell)
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ enum SMART_EVENT
|
|||||||
SMART_EVENT_DEATH = 6, // NONE
|
SMART_EVENT_DEATH = 6, // NONE
|
||||||
SMART_EVENT_EVADE = 7, // NONE
|
SMART_EVENT_EVADE = 7, // NONE
|
||||||
SMART_EVENT_SPELLHIT = 8, // SpellID, School, CooldownMin, CooldownMax
|
SMART_EVENT_SPELLHIT = 8, // SpellID, School, CooldownMin, CooldownMax
|
||||||
SMART_EVENT_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
|
SMART_EVENT_RANGE = 9, // minRange, maxRange, repeatMin, repeatMax, onlyFireOnRepeat
|
||||||
SMART_EVENT_OOC_LOS = 10, // HostilityMode, MaxRnage, CooldownMin, CooldownMax, PlayerOnly
|
SMART_EVENT_OOC_LOS = 10, // HostilityMode, MaxRnage, CooldownMin, CooldownMax, PlayerOnly
|
||||||
SMART_EVENT_RESPAWN = 11, // type, MapId, ZoneId
|
SMART_EVENT_RESPAWN = 11, // type, MapId, ZoneId
|
||||||
SMART_EVENT_TARGET_HEALTH_PCT = 12, // HPMin%, HPMax%, RepeatMin, RepeatMax
|
SMART_EVENT_TARGET_HEALTH_PCT = 12, // HPMin%, HPMax%, RepeatMin, RepeatMax
|
||||||
@@ -221,9 +221,17 @@ struct SmartEvent
|
|||||||
uint32 max;
|
uint32 max;
|
||||||
uint32 repeatMin;
|
uint32 repeatMin;
|
||||||
uint32 repeatMax;
|
uint32 repeatMax;
|
||||||
uint32 controller;
|
|
||||||
} minMaxRepeat;
|
} minMaxRepeat;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 minRange;
|
||||||
|
uint32 maxRange;
|
||||||
|
uint32 repeatMin;
|
||||||
|
uint32 repeatMax;
|
||||||
|
uint32 onlyFireOnRepeat;
|
||||||
|
} rangeRepeat;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint32 cooldownMin;
|
uint32 cooldownMin;
|
||||||
|
|||||||
@@ -2089,8 +2089,14 @@ void GameObject::CastSpell(Unit* target, uint32 spellId)
|
|||||||
if (owner->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED))
|
if (owner->HasUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED))
|
||||||
trigger->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
|
trigger->SetUnitFlag(UNIT_FLAG_PLAYER_CONTROLLED);
|
||||||
if (owner->IsFFAPvP())
|
if (owner->IsFFAPvP())
|
||||||
trigger->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(trigger, true);
|
||||||
|
trigger->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
// xinef: Remove Immunity flags
|
// xinef: Remove Immunity flags
|
||||||
trigger->SetImmuneToNPC(false);
|
trigger->SetImmuneToNPC(false);
|
||||||
// xinef: set proper orientation, fixes cast against stealthed targets
|
// xinef: set proper orientation, fixes cast against stealthed targets
|
||||||
|
|||||||
@@ -569,7 +569,9 @@ bool Player::Create(ObjectGuid::LowType guidlow, CharacterCreateInfo* createInfo
|
|||||||
|
|
||||||
InitRunes();
|
InitRunes();
|
||||||
|
|
||||||
SetUInt32Value(PLAYER_FIELD_COINAGE, sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY));
|
SetUInt32Value(PLAYER_FIELD_COINAGE, getClass() != CLASS_DEATH_KNIGHT
|
||||||
|
? sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY)
|
||||||
|
: sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_MONEY));
|
||||||
SetHonorPoints(sWorld->getIntConfig(CONFIG_START_HONOR_POINTS));
|
SetHonorPoints(sWorld->getIntConfig(CONFIG_START_HONOR_POINTS));
|
||||||
SetArenaPoints(sWorld->getIntConfig(CONFIG_START_ARENA_POINTS));
|
SetArenaPoints(sWorld->getIntConfig(CONFIG_START_ARENA_POINTS));
|
||||||
|
|
||||||
@@ -2177,8 +2179,11 @@ void Player::SetGameMaster(bool on)
|
|||||||
pet->SetFaction(FACTION_FRIENDLY);
|
pet->SetFaction(FACTION_FRIENDLY);
|
||||||
pet->getHostileRefMgr().setOnlineOfflineState(false);
|
pet->getHostileRefMgr().setOnlineOfflineState(false);
|
||||||
}
|
}
|
||||||
|
if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, false);
|
||||||
|
}
|
||||||
ResetContestedPvP();
|
ResetContestedPvP();
|
||||||
|
|
||||||
getHostileRefMgr().setOnlineOfflineState(false);
|
getHostileRefMgr().setOnlineOfflineState(false);
|
||||||
@@ -2210,8 +2215,13 @@ void Player::SetGameMaster(bool on)
|
|||||||
|
|
||||||
// restore FFA PvP Server state
|
// restore FFA PvP Server state
|
||||||
if (sWorld->IsFFAPvPRealm())
|
if (sWorld->IsFFAPvPRealm())
|
||||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
// restore FFA PvP area state, remove not allowed for GM mounts
|
// restore FFA PvP area state, remove not allowed for GM mounts
|
||||||
UpdateArea(m_areaUpdateId);
|
UpdateArea(m_areaUpdateId);
|
||||||
|
|
||||||
@@ -2654,8 +2664,12 @@ void Player::InitStatsForLevel(bool reapplyMods)
|
|||||||
RemovePlayerFlag(PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_ALLOW_ONLY_ABILITY);
|
RemovePlayerFlag(PLAYER_FLAGS_AFK | PLAYER_FLAGS_DND | PLAYER_FLAGS_GM | PLAYER_FLAGS_GHOST | PLAYER_ALLOW_ONLY_ABILITY);
|
||||||
|
|
||||||
RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes
|
RemoveStandFlags(UNIT_STAND_FLAGS_ALL); // one form stealth modified bytes
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY);
|
if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, false);
|
||||||
|
|
||||||
|
}
|
||||||
// restore if need some important flags
|
// restore if need some important flags
|
||||||
SetUInt32Value(PLAYER_FIELD_BYTES2, 0); // flags empty by default
|
SetUInt32Value(PLAYER_FIELD_BYTES2, 0); // flags empty by default
|
||||||
|
|
||||||
@@ -15001,7 +15015,11 @@ void Player::SetIsSpectator(bool on)
|
|||||||
AddUnitState(UNIT_STATE_ISOLATED);
|
AddUnitState(UNIT_STATE_ISOLATED);
|
||||||
//SetFaction(1100);
|
//SetFaction(1100);
|
||||||
SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, false);
|
||||||
|
}
|
||||||
ResetContestedPvP();
|
ResetContestedPvP();
|
||||||
SetDisplayId(23691);
|
SetDisplayId(23691);
|
||||||
}
|
}
|
||||||
@@ -15021,7 +15039,14 @@ void Player::SetIsSpectator(bool on)
|
|||||||
// restore FFA PvP Server state
|
// restore FFA PvP Server state
|
||||||
// Xinef: it will be removed if necessery in UpdateArea called in WorldPortOpcode
|
// Xinef: it will be removed if necessery in UpdateArea called in WorldPortOpcode
|
||||||
if (sWorld->IsFFAPvPRealm())
|
if (sWorld->IsFFAPvPRealm())
|
||||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
if (!HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -396,8 +396,11 @@ void Player::UpdateFFAPvPFlag(time_t currTime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pvpInfo.FFAPvPEndTimer = time_t(0);
|
pvpInfo.FFAPvPEndTimer = time_t(0);
|
||||||
|
if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, false);
|
||||||
|
}
|
||||||
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
for (ControlSet::iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||||
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
|
||||||
|
|||||||
@@ -982,42 +982,56 @@ void Player::UpdateWeaponSkill(Unit* victim, WeaponAttackType attType, Item* ite
|
|||||||
|
|
||||||
void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, Item* item /*= nullptr*/)
|
void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence, Item* item /*= nullptr*/)
|
||||||
{
|
{
|
||||||
uint8 plevel = getLevel(); // if defense than victim == attacker
|
uint8 playerLevel = getLevel();
|
||||||
uint8 greylevel = Acore::XP::GetGrayLevel(plevel);
|
uint16 currentSkillValue = defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType);
|
||||||
uint8 moblevel = victim->getLevelForTarget(this);
|
uint16 currentSkillMax = 5 * playerLevel;
|
||||||
|
int32 skillDiff = currentSkillMax - currentSkillValue;
|
||||||
|
|
||||||
|
// Max skill reached for level.
|
||||||
|
// Can in some cases be less than 0: having max skill and then .level -1 as example.
|
||||||
|
if (skillDiff <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 greylevel = Acore::XP::GetGrayLevel(playerLevel);
|
||||||
|
uint8 moblevel = defence ? victim->getLevelForTarget(this) : victim->getLevel(); // if defense than victim == attacker
|
||||||
/*if (moblevel < greylevel)
|
/*if (moblevel < greylevel)
|
||||||
return;*/
|
return;*/
|
||||||
// Patch 3.0.8 (2009-01-20): You can no longer skill up weapons on mobs that are immune to damage.
|
// Patch 3.0.8 (2009-01-20): You can no longer skill up weapons on mobs that are immune to damage.
|
||||||
|
|
||||||
if (moblevel > plevel + 5)
|
if (moblevel > playerLevel + 5)
|
||||||
moblevel = plevel + 5;
|
{
|
||||||
|
moblevel = playerLevel + 5;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 lvldif = moblevel - greylevel;
|
int16 lvldif = moblevel - greylevel;
|
||||||
if (lvldif < 3)
|
if (lvldif < 3)
|
||||||
|
{
|
||||||
lvldif = 3;
|
lvldif = 3;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 skilldif = 5 * plevel - (defence ? GetBaseDefenseSkillValue()
|
float chance = float(3 * lvldif * skillDiff) / playerLevel;
|
||||||
: GetBaseWeaponSkillValue(attType));
|
|
||||||
if (skilldif <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float chance = float(3 * lvldif * skilldif) / plevel;
|
|
||||||
if (!defence)
|
if (!defence)
|
||||||
if (getClass() == CLASS_WARRIOR || getClass() == CLASS_ROGUE)
|
{
|
||||||
chance += chance * 0.02f * GetStat(STAT_INTELLECT);
|
chance += chance * 0.02f * GetStat(STAT_INTELLECT);
|
||||||
|
}
|
||||||
|
|
||||||
chance =
|
chance = chance < 1.0f ? 1.0f : chance; // minimum chance to increase skill is 1%
|
||||||
chance < 1.0f ? 1.0f : chance; // minimum chance to increase skill is 1%
|
|
||||||
|
LOG_DEBUG("entities.player", "Player::UpdateCombatSkills(defence:{}, playerLevel:{}, moblevel:{}) -> ({}/{}) chance to increase skill is {}\%", defence, playerLevel, moblevel, currentSkillValue, currentSkillMax, chance);
|
||||||
|
|
||||||
if (roll_chance_f(chance))
|
if (roll_chance_f(chance))
|
||||||
{
|
{
|
||||||
if (defence)
|
if (defence)
|
||||||
|
{
|
||||||
UpdateDefense();
|
UpdateDefense();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
UpdateWeaponSkill(victim, attType, item);
|
UpdateWeaponSkill(victim, attType, item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UpdateSkillsForLevel()
|
void Player::UpdateSkillsForLevel()
|
||||||
@@ -1403,6 +1417,7 @@ void Player::UpdateFFAPvPState(bool reset /*= true*/)
|
|||||||
{
|
{
|
||||||
if (!IsFFAPvP())
|
if (!IsFFAPvP())
|
||||||
{
|
{
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, true);
|
||||||
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
for (ControlSet::iterator itr = m_Controlled.begin();
|
for (ControlSet::iterator itr = m_Controlled.begin();
|
||||||
itr != m_Controlled.end(); ++itr)
|
itr != m_Controlled.end(); ++itr)
|
||||||
@@ -1421,8 +1436,11 @@ void Player::UpdateFFAPvPState(bool reset /*= true*/)
|
|||||||
!pvpInfo.EndTimer)
|
!pvpInfo.EndTimer)
|
||||||
{
|
{
|
||||||
pvpInfo.FFAPvPEndTimer = time_t(0);
|
pvpInfo.FFAPvPEndTimer = time_t(0);
|
||||||
|
if (HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(this, false);
|
||||||
|
}
|
||||||
for (ControlSet::iterator itr = m_Controlled.begin();
|
for (ControlSet::iterator itr = m_Controlled.begin();
|
||||||
itr != m_Controlled.end(); ++itr)
|
itr != m_Controlled.end(); ++itr)
|
||||||
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1,
|
(*itr)->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1,
|
||||||
|
|||||||
@@ -15759,21 +15759,18 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
|
|||||||
|
|
||||||
// Update skills here for players
|
// Update skills here for players
|
||||||
// only when you are not fighting other players or their pets/totems (pvp)
|
// only when you are not fighting other players or their pets/totems (pvp)
|
||||||
if (GetTypeId() == TYPEID_PLAYER &&
|
if (IsPlayer() && !target->IsCharmedOwnedByPlayerOrPlayer())
|
||||||
target->GetTypeId() != TYPEID_PLAYER &&
|
|
||||||
!(target->IsTotem() && target->ToTotem()->GetOwner()->IsPlayer()) &&
|
|
||||||
!target->IsPet()
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// On melee based hit/miss/resist/parry/dodge need to update skill (for victim and attacker)
|
// On melee based hit/miss/resist/parry/dodge need to update skill (for victim and attacker)
|
||||||
if (procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_MISS | PROC_EX_RESIST | PROC_EX_PARRY | PROC_EX_DODGE))
|
if (procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_MISS | PROC_EX_RESIST | PROC_EX_PARRY | PROC_EX_DODGE))
|
||||||
{
|
{
|
||||||
if (target->GetTypeId() != TYPEID_PLAYER)
|
ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr);
|
||||||
ToPlayer()->UpdateCombatSkills(target, attType, isVictim, procSpell ? procSpell->m_weaponItem : nullptr);
|
|
||||||
}
|
}
|
||||||
// Update defence if player is victim and we block
|
// Update defence if player is victim and we block - TODO: confirm that blocked attacks only have a chance to increase defence skill
|
||||||
else if (isVictim && procExtra & (PROC_EX_BLOCK))
|
else if (isVictim && procExtra & (PROC_EX_BLOCK))
|
||||||
|
{
|
||||||
ToPlayer()->UpdateCombatSkills(target, attType, true);
|
ToPlayer()->UpdateCombatSkills(target, attType, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// If exist crit/parry/dodge/block need update aura state (for victim and attacker)
|
// If exist crit/parry/dodge/block need update aura state (for victim and attacker)
|
||||||
if (procExtra & (PROC_EX_CRITICAL_HIT | PROC_EX_PARRY | PROC_EX_DODGE | PROC_EX_BLOCK))
|
if (procExtra & (PROC_EX_CRITICAL_HIT | PROC_EX_PARRY | PROC_EX_DODGE | PROC_EX_BLOCK))
|
||||||
|
|||||||
@@ -109,8 +109,10 @@ void Vehicle::Uninstall()
|
|||||||
LOG_DEBUG("vehicles", "Vehicle::Uninstall {}", _me->GetGUID().ToString());
|
LOG_DEBUG("vehicles", "Vehicle::Uninstall {}", _me->GetGUID().ToString());
|
||||||
RemoveAllPassengers();
|
RemoveAllPassengers();
|
||||||
|
|
||||||
if (GetBase()->GetTypeId() == TYPEID_UNIT)
|
if (_me && _me->GetTypeId() == TYPEID_UNIT)
|
||||||
|
{
|
||||||
sScriptMgr->OnUninstall(this);
|
sScriptMgr->OnUninstall(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vehicle::Reset(bool evading /*= false*/)
|
void Vehicle::Reset(bool evading /*= false*/)
|
||||||
|
|||||||
@@ -422,7 +422,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket& recvData)
|
|||||||
|
|
||||||
std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
|
std::function<void(PreparedQueryResult)> finalizeCharacterCreation = [this, createInfo](PreparedQueryResult result)
|
||||||
{
|
{
|
||||||
if (!sScriptMgr->CanAccountCreateCharacter(createInfo, GetAccountId()))
|
if (!sScriptMgr->CanAccountCreateCharacter(GetAccountId(), createInfo->Race, createInfo->Class))
|
||||||
{
|
{
|
||||||
SendCharCreate(CHAR_CREATE_DISABLED);
|
SendCharCreate(CHAR_CREATE_DISABLED);
|
||||||
return;
|
return;
|
||||||
@@ -948,7 +948,11 @@ void WorldSession::HandlePlayerLoginFromDB(LoginQueryHolder const& holder)
|
|||||||
|
|
||||||
// Set FFA PvP for non GM in non-rest mode
|
// Set FFA PvP for non GM in non-rest mode
|
||||||
if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
|
if (sWorld->IsFFAPvPRealm() && !pCurrChar->IsGameMaster() && !pCurrChar->HasPlayerFlag(PLAYER_FLAGS_RESTING))
|
||||||
pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
if (!pCurrChar->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(pCurrChar,true);
|
||||||
|
pCurrChar->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
}
|
||||||
|
|
||||||
if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP))
|
if (pCurrChar->HasPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
|
|||||||
|
|
||||||
if (loot)
|
if (loot)
|
||||||
{
|
{
|
||||||
|
sScriptMgr->OnBeforeLootMoney(player, loot);
|
||||||
loot->NotifyMoneyRemoved();
|
loot->NotifyMoneyRemoved();
|
||||||
if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
|
if (shareMoney && player->GetGroup()) //item, pickpocket and players can be looted only single player
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -772,8 +772,14 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data)
|
|||||||
player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry);
|
player->SetRestFlag(REST_FLAG_IN_TAVERN, atEntry->entry);
|
||||||
|
|
||||||
if (sWorld->IsFFAPvPRealm())
|
if (sWorld->IsFFAPvPRealm())
|
||||||
player->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
{
|
||||||
|
if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
|
||||||
|
{
|
||||||
|
player->RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
|
||||||
|
sScriptMgr->OnFfaPvpStateUpdate(player, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,10 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
|
|||||||
case TYPEID_GAMEOBJECT:
|
case TYPEID_GAMEOBJECT:
|
||||||
{
|
{
|
||||||
LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject {}", guid.ToString());
|
LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject {}", guid.ToString());
|
||||||
questStatus = _player->GetQuestDialogStatus(questGiver);
|
if (sWorld->getBoolConfig(CONFIG_OBJECT_QUEST_MARKERS))
|
||||||
|
{
|
||||||
|
questStatus = _player->GetQuestDialogStatus(questGiver);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -82,11 +82,11 @@ void ScriptMgr::OnFailedPasswordChange(uint32 accountId)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptMgr::CanAccountCreateCharacter(std::shared_ptr<CharacterCreateInfo> createInfo, uint32 accountId)
|
bool ScriptMgr::CanAccountCreateCharacter(uint32 accountId, uint8 charRace, uint8 charClass)
|
||||||
{
|
{
|
||||||
auto ret = IsValidBoolScript<AccountScript>([&](AccountScript* script)
|
auto ret = IsValidBoolScript<AccountScript>([&](AccountScript* script)
|
||||||
{
|
{
|
||||||
return !script->CanAccountCreateCharacter(createInfo, accountId);
|
return !script->CanAccountCreateCharacter(accountId, charRace, charClass);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ret && *ret)
|
if (ret && *ret)
|
||||||
|
|||||||
@@ -170,6 +170,15 @@ CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature)
|
|||||||
return tempScript ? tempScript->GetAI(creature) : nullptr;
|
return tempScript ? tempScript->GetAI(creature) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Fires whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed on the player
|
||||||
|
void ScriptMgr::OnFfaPvpStateUpdate(Creature* creature, bool InPvp)
|
||||||
|
{
|
||||||
|
ExecuteScript<AllCreatureScript>([&](AllCreatureScript* script)
|
||||||
|
{
|
||||||
|
script->OnFfaPvpStateUpdate(creature, InPvp);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff)
|
void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff)
|
||||||
{
|
{
|
||||||
ASSERT(creature);
|
ASSERT(creature);
|
||||||
|
|||||||
@@ -146,6 +146,14 @@ void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptMgr::OnBeforeLootMoney(Player* player, Loot* loot)
|
||||||
|
{
|
||||||
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
|
{
|
||||||
|
script->OnBeforeLootMoney(player, loot);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim)
|
void ScriptMgr::OnGivePlayerXP(Player* player, uint32& amount, Unit* victim)
|
||||||
{
|
{
|
||||||
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
@@ -1263,6 +1271,7 @@ void ScriptMgr::OnGetArenaTeamId(Player* player, uint8 slot, uint32& result)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Signifies that IsFfaPvp has been called.
|
||||||
void ScriptMgr::OnIsFFAPvP(Player* player, bool& result)
|
void ScriptMgr::OnIsFFAPvP(Player* player, bool& result)
|
||||||
{
|
{
|
||||||
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
@@ -1270,6 +1279,14 @@ void ScriptMgr::OnIsFFAPvP(Player* player, bool& result)
|
|||||||
script->OnIsFFAPvP(player, result);
|
script->OnIsFFAPvP(player, result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//Fires whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed
|
||||||
|
void ScriptMgr::OnFfaPvpStateUpdate(Player* player, bool result)
|
||||||
|
{
|
||||||
|
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||||
|
{
|
||||||
|
script->OnFfaPvpStateUpdate(player, result);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptMgr::OnIsPvP(Player* player, bool& result)
|
void ScriptMgr::OnIsPvP(Player* player, bool& result)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -620,6 +620,9 @@ public:
|
|||||||
|
|
||||||
// Called when a CreatureAI object is needed for the creature.
|
// Called when a CreatureAI object is needed for the creature.
|
||||||
[[nodiscard]] virtual CreatureAI* GetCreatureAI(Creature* /*creature*/) const { return nullptr; }
|
[[nodiscard]] virtual CreatureAI* GetCreatureAI(Creature* /*creature*/) const { return nullptr; }
|
||||||
|
|
||||||
|
//Called Whenever the UNIT_BYTE2_FLAG_FFA_PVP Bit is set on the creature
|
||||||
|
virtual void OnFfaPvpStateUpdate(Creature* /*creature*/, bool /*InPvp*/) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class AllItemScript : public ScriptObject
|
class AllItemScript : public ScriptObject
|
||||||
@@ -744,6 +747,10 @@ public:
|
|||||||
|
|
||||||
// Called when a CreatureAI object is needed for the creature.
|
// Called when a CreatureAI object is needed for the creature.
|
||||||
virtual CreatureAI* GetAI(Creature* /*creature*/) const { return nullptr; }
|
virtual CreatureAI* GetAI(Creature* /*creature*/) const { return nullptr; }
|
||||||
|
|
||||||
|
//Called whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed on the player
|
||||||
|
virtual void OnFfaPvpStateUpdate(Creature* /*player*/, bool /*result*/) { }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
|
class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
|
||||||
@@ -1023,6 +1030,9 @@ public:
|
|||||||
// Called when a player's money is modified (before the modification is done)
|
// Called when a player's money is modified (before the modification is done)
|
||||||
virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { }
|
virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { }
|
||||||
|
|
||||||
|
// Called before looted money is added to a player
|
||||||
|
virtual void OnBeforeLootMoney(Player* /*player*/, Loot* /*loot*/) {}
|
||||||
|
|
||||||
// Called when a player gains XP (before anything is given)
|
// Called when a player gains XP (before anything is given)
|
||||||
virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { }
|
virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { }
|
||||||
|
|
||||||
@@ -1306,6 +1316,9 @@ public:
|
|||||||
|
|
||||||
virtual void OnIsFFAPvP(Player* /*player*/, bool& /*result*/) { }
|
virtual void OnIsFFAPvP(Player* /*player*/, bool& /*result*/) { }
|
||||||
|
|
||||||
|
//Fires whenever the UNIT_BYTE2_FLAG_FFA_PVP bit is Changed on the player
|
||||||
|
virtual void OnFfaPvpStateUpdate(Player* /*player*/, bool /*result*/) { }
|
||||||
|
|
||||||
virtual void OnIsPvP(Player* /*player*/, bool& /*result*/) { }
|
virtual void OnIsPvP(Player* /*player*/, bool& /*result*/) { }
|
||||||
|
|
||||||
virtual void OnGetMaxSkillValueForLevel(Player* /*player*/, uint16& /*result*/) { }
|
virtual void OnGetMaxSkillValueForLevel(Player* /*player*/, uint16& /*result*/) { }
|
||||||
@@ -1463,7 +1476,7 @@ public:
|
|||||||
virtual void OnFailedPasswordChange(uint32 /*accountId*/) { }
|
virtual void OnFailedPasswordChange(uint32 /*accountId*/) { }
|
||||||
|
|
||||||
// Called when creating a character on the Account
|
// Called when creating a character on the Account
|
||||||
[[nodiscard]] virtual bool CanAccountCreateCharacter(std::shared_ptr<CharacterCreateInfo> /*createInfo*/, uint32 /*accountId*/) { return true;}
|
[[nodiscard]] virtual bool CanAccountCreateCharacter(uint32 /*accountId*/, uint8 /*charRace*/, uint8 /*charClass*/) { return true;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class GuildScript : public ScriptObject
|
class GuildScript : public ScriptObject
|
||||||
@@ -2164,6 +2177,7 @@ public: /* CreatureScript */
|
|||||||
void OnCreatureUpdate(Creature* creature, uint32 diff);
|
void OnCreatureUpdate(Creature* creature, uint32 diff);
|
||||||
void OnCreatureAddWorld(Creature* creature);
|
void OnCreatureAddWorld(Creature* creature);
|
||||||
void OnCreatureRemoveWorld(Creature* creature);
|
void OnCreatureRemoveWorld(Creature* creature);
|
||||||
|
void OnFfaPvpStateUpdate(Creature* creature, bool InPvp);
|
||||||
|
|
||||||
public: /* GameObjectScript */
|
public: /* GameObjectScript */
|
||||||
bool OnGossipHello(Player* player, GameObject* go);
|
bool OnGossipHello(Player* player, GameObject* go);
|
||||||
@@ -2249,6 +2263,7 @@ public: /* PlayerScript */
|
|||||||
void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints);
|
void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints);
|
||||||
void OnPlayerTalentsReset(Player* player, bool noCost);
|
void OnPlayerTalentsReset(Player* player, bool noCost);
|
||||||
void OnPlayerMoneyChanged(Player* player, int32& amount);
|
void OnPlayerMoneyChanged(Player* player, int32& amount);
|
||||||
|
void OnBeforeLootMoney(Player* player, Loot* loot);
|
||||||
void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim);
|
void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim);
|
||||||
bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
|
bool OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
|
||||||
void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased);
|
void OnPlayerReputationRankChange(Player* player, uint32 factionID, ReputationRank newRank, ReputationRank oldRank, bool increased);
|
||||||
@@ -2361,6 +2376,7 @@ public: /* PlayerScript */
|
|||||||
bool NotAvoidSatisfy(Player* player, DungeonProgressionRequirements const* ar, uint32 target_map, bool report);
|
bool NotAvoidSatisfy(Player* player, DungeonProgressionRequirements const* ar, uint32 target_map, bool report);
|
||||||
bool NotVisibleGloballyFor(Player* player, Player const* u);
|
bool NotVisibleGloballyFor(Player* player, Player const* u);
|
||||||
void OnGetArenaPersonalRating(Player* player, uint8 slot, uint32& result);
|
void OnGetArenaPersonalRating(Player* player, uint8 slot, uint32& result);
|
||||||
|
void OnFfaPvpStateUpdate(Player* player, bool result);
|
||||||
void OnGetArenaTeamId(Player* player, uint8 slot, uint32& result);
|
void OnGetArenaTeamId(Player* player, uint8 slot, uint32& result);
|
||||||
void OnIsFFAPvP(Player* player, bool& result);
|
void OnIsFFAPvP(Player* player, bool& result);
|
||||||
void OnIsPvP(Player* player, bool& result);
|
void OnIsPvP(Player* player, bool& result);
|
||||||
@@ -2401,7 +2417,7 @@ public: /* AccountScript */
|
|||||||
void OnFailedEmailChange(uint32 accountId);
|
void OnFailedEmailChange(uint32 accountId);
|
||||||
void OnPasswordChange(uint32 accountId);
|
void OnPasswordChange(uint32 accountId);
|
||||||
void OnFailedPasswordChange(uint32 accountId);
|
void OnFailedPasswordChange(uint32 accountId);
|
||||||
bool CanAccountCreateCharacter(std::shared_ptr<CharacterCreateInfo> createInfo, uint32 accountId);
|
bool CanAccountCreateCharacter(uint32 accountId, uint8 charRace, uint8 charClass);
|
||||||
|
|
||||||
public: /* GuildScript */
|
public: /* GuildScript */
|
||||||
void OnGuildAddMember(Guild* guild, Player* player, uint8& plRank);
|
void OnGuildAddMember(Guild* guild, Player* player, uint8& plRank);
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ enum WorldBoolConfigs
|
|||||||
CONFIG_LEAVE_GROUP_ON_LOGOUT,
|
CONFIG_LEAVE_GROUP_ON_LOGOUT,
|
||||||
CONFIG_VMAP_BLIZZLIKE_PVP_LOS,
|
CONFIG_VMAP_BLIZZLIKE_PVP_LOS,
|
||||||
CONFIG_OBJECT_SPARKLES,
|
CONFIG_OBJECT_SPARKLES,
|
||||||
|
CONFIG_OBJECT_QUEST_MARKERS,
|
||||||
BOOL_CONFIG_VALUE_COUNT
|
BOOL_CONFIG_VALUE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -231,6 +232,7 @@ enum WorldIntConfigs
|
|||||||
CONFIG_START_PLAYER_LEVEL,
|
CONFIG_START_PLAYER_LEVEL,
|
||||||
CONFIG_START_HEROIC_PLAYER_LEVEL,
|
CONFIG_START_HEROIC_PLAYER_LEVEL,
|
||||||
CONFIG_START_PLAYER_MONEY,
|
CONFIG_START_PLAYER_MONEY,
|
||||||
|
CONFIG_START_HEROIC_PLAYER_MONEY,
|
||||||
CONFIG_MAX_HONOR_POINTS,
|
CONFIG_MAX_HONOR_POINTS,
|
||||||
CONFIG_MAX_HONOR_POINTS_MONEY_PER_POINT,
|
CONFIG_MAX_HONOR_POINTS_MONEY_PER_POINT,
|
||||||
CONFIG_START_HONOR_POINTS,
|
CONFIG_START_HONOR_POINTS,
|
||||||
|
|||||||
@@ -849,6 +849,13 @@ void World::LoadConfigSettings(bool reload)
|
|||||||
m_int_configs[CONFIG_START_PLAYER_MONEY] = 0;
|
m_int_configs[CONFIG_START_PLAYER_MONEY] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY] = sConfigMgr->GetOption<int32>("StartHeroicPlayerMoney", 2000);
|
||||||
|
if (int32(m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY]) < 0 || int32(m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY]) > MAX_MONEY_AMOUNT)
|
||||||
|
{
|
||||||
|
LOG_ERROR("server.loading", "StartHeroicPlayerMoney ({}) must be in range 0..{}. Set to {}.", m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY], MAX_MONEY_AMOUNT, 2000);
|
||||||
|
m_int_configs[CONFIG_START_HEROIC_PLAYER_MONEY] = 2000;
|
||||||
|
}
|
||||||
|
|
||||||
m_int_configs[CONFIG_MAX_HONOR_POINTS] = sConfigMgr->GetOption<int32>("MaxHonorPoints", 75000);
|
m_int_configs[CONFIG_MAX_HONOR_POINTS] = sConfigMgr->GetOption<int32>("MaxHonorPoints", 75000);
|
||||||
if (int32(m_int_configs[CONFIG_MAX_HONOR_POINTS]) < 0)
|
if (int32(m_int_configs[CONFIG_MAX_HONOR_POINTS]) < 0)
|
||||||
{
|
{
|
||||||
@@ -944,6 +951,8 @@ void World::LoadConfigSettings(bool reload)
|
|||||||
|
|
||||||
m_bool_configs[CONFIG_OBJECT_SPARKLES] = sConfigMgr->GetOption<bool>("Visibility.ObjectSparkles", true);
|
m_bool_configs[CONFIG_OBJECT_SPARKLES] = sConfigMgr->GetOption<bool>("Visibility.ObjectSparkles", true);
|
||||||
|
|
||||||
|
m_bool_configs[CONFIG_OBJECT_QUEST_MARKERS] = sConfigMgr->GetOption<bool>("Visibility.ObjectQuestMarkers", true);
|
||||||
|
|
||||||
m_int_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfigMgr->GetOption<int32>("MailDeliveryDelay", HOUR);
|
m_int_configs[CONFIG_MAIL_DELIVERY_DELAY] = sConfigMgr->GetOption<int32>("MailDeliveryDelay", HOUR);
|
||||||
|
|
||||||
m_int_configs[CONFIG_UPTIME_UPDATE] = sConfigMgr->GetOption<int32>("UpdateUptimeInterval", 10);
|
m_int_configs[CONFIG_UPTIME_UPDATE] = sConfigMgr->GetOption<int32>("UpdateUptimeInterval", 10);
|
||||||
|
|||||||
@@ -655,13 +655,12 @@ class spell_hun_readiness : public SpellScript
|
|||||||
|
|
||||||
SpellCooldowns& cooldowns = caster->GetSpellCooldownMap();
|
SpellCooldowns& cooldowns = caster->GetSpellCooldownMap();
|
||||||
|
|
||||||
SpellCooldowns::iterator itr, next;
|
std::set<std::pair<uint32, bool>> spellsToRemove;
|
||||||
for (itr = cooldowns.begin(); itr != cooldowns.end(); itr = next)
|
std::set<uint32> categoriesToRemove;
|
||||||
{
|
|
||||||
next = itr;
|
|
||||||
++next;
|
|
||||||
|
|
||||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
|
for (const auto& [spellId, cooldown] : cooldowns)
|
||||||
|
{
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||||
if (spellInfo
|
if (spellInfo
|
||||||
&& spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER
|
&& spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER
|
||||||
&& spellInfo->Id != SPELL_HUNTER_READINESS
|
&& spellInfo->Id != SPELL_HUNTER_READINESS
|
||||||
@@ -669,12 +668,18 @@ class spell_hun_readiness : public SpellScript
|
|||||||
&& spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU)
|
&& spellInfo->Id != SPELL_DRAENEI_GIFT_OF_THE_NAARU)
|
||||||
{
|
{
|
||||||
if (spellInfo->RecoveryTime > 0)
|
if (spellInfo->RecoveryTime > 0)
|
||||||
caster->RemoveSpellCooldown(spellInfo->Id, itr->second.needSendToClient);
|
spellsToRemove.insert(std::make_pair(spellInfo->Id, cooldown.needSendToClient));
|
||||||
|
|
||||||
if (spellInfo->CategoryRecoveryTime > 0)
|
if (spellInfo->CategoryRecoveryTime > 0)
|
||||||
caster->RemoveCategoryCooldown(spellInfo->GetCategory());
|
categoriesToRemove.insert(spellInfo->GetCategory());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we can't remove spell cooldowns while iterating.
|
||||||
|
for (const auto& [spellId, sendToClient] : spellsToRemove)
|
||||||
|
caster->RemoveSpellCooldown(spellId, sendToClient);
|
||||||
|
for (const auto& category : categoriesToRemove)
|
||||||
|
caster->RemoveCategoryCooldown(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Register() override
|
void Register() override
|
||||||
|
|||||||
@@ -3702,6 +3702,29 @@ class spell_item_snowman : public SpellScript
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://www.wowhead.com/wotlk/spell=16028 Freeze Rookery Egg - Prototype
|
||||||
|
// https://www.wowhead.com/wotlk/spell=15748 Freeze Rookery Egg
|
||||||
|
class spell_item_freeze_rookery_egg : public SpellScript
|
||||||
|
{
|
||||||
|
PrepareSpellScript(spell_item_freeze_rookery_egg);
|
||||||
|
|
||||||
|
void HandleOpenObject(SpellEffIndex effIndex)
|
||||||
|
{
|
||||||
|
PreventHitDefaultEffect(effIndex);
|
||||||
|
|
||||||
|
if (GameObject* rookery = GetHitGObj())
|
||||||
|
{
|
||||||
|
if (rookery->getLootState() == GO_READY)
|
||||||
|
rookery->UseDoorOrButton(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectHitTarget += SpellEffectFn(spell_item_freeze_rookery_egg::HandleOpenObject, EFFECT_0, SPELL_EFFECT_OPEN_LOCK);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void AddSC_item_spell_scripts()
|
void AddSC_item_spell_scripts()
|
||||||
{
|
{
|
||||||
RegisterSpellScript(spell_item_massive_seaforium_charge);
|
RegisterSpellScript(spell_item_massive_seaforium_charge);
|
||||||
@@ -3816,4 +3839,5 @@ void AddSC_item_spell_scripts()
|
|||||||
RegisterSpellScript(spell_item_wraith_scythe_drain_life);
|
RegisterSpellScript(spell_item_wraith_scythe_drain_life);
|
||||||
RegisterSpellScript(spell_item_mirrens_drinking_hat);
|
RegisterSpellScript(spell_item_mirrens_drinking_hat);
|
||||||
RegisterSpellScript(spell_item_snowman);
|
RegisterSpellScript(spell_item_snowman);
|
||||||
|
RegisterSpellScript(spell_item_freeze_rookery_egg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,9 +104,10 @@ char* DBCDatabaseLoader::Load(uint32& records, char**& indexTable)
|
|||||||
break;
|
break;
|
||||||
case FT_SORT:
|
case FT_SORT:
|
||||||
case FT_NA:
|
case FT_NA:
|
||||||
|
case FT_NA_BYTE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(false, "Unsupported data type '%c' in table '{}'", *dbcFormat, _sqlTableName);
|
ASSERT(false, "Unsupported data type '{}' in table '{}'", *dbcFormat, _sqlTableName);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user