mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-30 00:53:46 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -597,15 +597,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
|
||||
if (caster && caster != me) // Areatrigger cast
|
||||
{
|
||||
caster->CastSpell(target->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
|
||||
caster->CastSpell(target->ToUnit(), e.action.cast.spell, (e.action.cast.castFlags & SMARTCAST_TRIGGERED));
|
||||
}
|
||||
else if (me && (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell)))
|
||||
else if (me && (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell)))
|
||||
{
|
||||
if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
// Xinef: flag usable only if caster has max dist set
|
||||
if ((e.action.cast.flags & SMARTCAST_COMBAT_MOVE) && GetCasterMaxDist() > 0.0f && me->GetMaxPower(GetCasterPowerType()) > 0)
|
||||
if ((e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE) && GetCasterMaxDist() > 0.0f && me->GetMaxPower(GetCasterPowerType()) > 0)
|
||||
{
|
||||
// Xinef: check mana case only and operate movement accordingly, LoS and range is checked in targetet movement generator
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell);
|
||||
@@ -623,12 +623,45 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
}
|
||||
|
||||
me->CastSpell(target->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
|
||||
me->CastSpell(target->ToUnit(), e.action.cast.spell, (e.action.cast.castFlags & SMARTCAST_TRIGGERED));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_SELF_CAST:
|
||||
{
|
||||
if (targets.empty())
|
||||
break;
|
||||
|
||||
if (e.action.cast.targetsLimit)
|
||||
Acore::Containers::RandomResize(targets, e.action.cast.targetsLimit);
|
||||
|
||||
TriggerCastFlags triggerFlags = TRIGGERED_NONE;
|
||||
if (e.action.cast.castFlags & SMARTCAST_TRIGGERED)
|
||||
{
|
||||
if (e.action.cast.triggerFlags)
|
||||
triggerFlags = TriggerCastFlags(e.action.cast.triggerFlags);
|
||||
else
|
||||
triggerFlags = TRIGGERED_FULL_MASK;
|
||||
}
|
||||
|
||||
for (WorldObject* target : targets)
|
||||
{
|
||||
Unit* uTarget = target->ToUnit();
|
||||
if (!uTarget)
|
||||
continue;
|
||||
|
||||
if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !uTarget->HasAura(e.action.cast.spell))
|
||||
{
|
||||
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
uTarget->InterruptNonMeleeSpells(false);
|
||||
|
||||
uTarget->CastSpell(uTarget, e.action.cast.spell, triggerFlags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_INVOKER_CAST:
|
||||
{
|
||||
Unit* tempLastInvoker = GetLastInvoker(unit); // xinef: can be used for area triggers cast
|
||||
@@ -638,7 +671,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (targets.empty())
|
||||
break;
|
||||
|
||||
if (e.action.cast.targetsLimit > 0 && targets.size() > e.action.cast.targetsLimit)
|
||||
if (e.action.cast.targetsLimit)
|
||||
Acore::Containers::RandomResize(targets, e.action.cast.targetsLimit);
|
||||
|
||||
for (WorldObject* target : targets)
|
||||
@@ -646,12 +679,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (!IsUnit(target))
|
||||
continue;
|
||||
|
||||
if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell))
|
||||
if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell))
|
||||
{
|
||||
if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
|
||||
tempLastInvoker->InterruptNonMeleeSpells(false);
|
||||
|
||||
tempLastInvoker->CastSpell(target->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED));
|
||||
tempLastInvoker->CastSpell(target->ToUnit(), e.action.cast.spell, (e.action.cast.castFlags & SMARTCAST_TRIGGERED));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4143,7 +4176,7 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff)
|
||||
// delay spell cast event if another spell is being casted
|
||||
if (e.GetActionType() == SMART_ACTION_CAST)
|
||||
{
|
||||
if (!(e.action.cast.flags & (SMARTCAST_INTERRUPT_PREVIOUS | SMARTCAST_TRIGGERED)))
|
||||
if (!(e.action.cast.castFlags & (SMARTCAST_INTERRUPT_PREVIOUS | SMARTCAST_TRIGGERED)))
|
||||
{
|
||||
if (me && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
@@ -4402,7 +4435,7 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTrigger const* at)
|
||||
}
|
||||
|
||||
// Xinef: if smartcast combat move flag is present
|
||||
if (i->GetActionType() == SMART_ACTION_CAST && (i->action.cast.flags & SMARTCAST_COMBAT_MOVE))
|
||||
if (i->GetActionType() == SMART_ACTION_CAST && (i->action.cast.castFlags & SMARTCAST_COMBAT_MOVE))
|
||||
{
|
||||
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i->action.cast.spell))
|
||||
{
|
||||
|
||||
@@ -409,7 +409,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
|
||||
case SMART_TARGET_INVOKER_PARTY:
|
||||
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && e.GetEventType() != SMART_EVENT_LINK && !EventHasInvoker(e.event.type))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has invoker target, but action does not provide any invoker!", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has invoker target, but event does not provide any invoker!", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -620,7 +620,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
case SMART_ACTION_THREAT_SINGLE_PCT: return sizeof(SmartAction::threatPCT);
|
||||
case SMART_ACTION_THREAT_ALL_PCT: return sizeof(SmartAction::threatPCT);
|
||||
case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: return sizeof(SmartAction::quest);
|
||||
//case SMART_ACTION_RESERVED_16: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_RESERVED_16: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_SET_EMOTE_STATE: return sizeof(SmartAction::emote);
|
||||
case SMART_ACTION_SET_UNIT_FLAG: return sizeof(SmartAction::unitFlag);
|
||||
case SMART_ACTION_REMOVE_UNIT_FLAG: return sizeof(SmartAction::unitFlag);
|
||||
@@ -690,6 +690,7 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
case SMART_ACTION_ADD_NPC_FLAG: return sizeof(SmartAction::flag);
|
||||
case SMART_ACTION_REMOVE_NPC_FLAG: return sizeof(SmartAction::flag);
|
||||
case SMART_ACTION_SIMPLE_TALK: return sizeof(SmartAction::simpleTalk);
|
||||
case SMART_ACTION_SELF_CAST: return sizeof(SmartAction::cast);
|
||||
case SMART_ACTION_INVOKER_CAST: return sizeof(SmartAction::cast);
|
||||
case SMART_ACTION_CROSS_CAST: return sizeof(SmartAction::crossCast);
|
||||
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: return sizeof(SmartAction::randTimedActionList);
|
||||
@@ -733,22 +734,21 @@ bool SmartAIMgr::CheckUnusedActionParams(SmartScriptHolder const& e)
|
||||
case SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT: return sizeof(SmartAction::randomTimedEvent);
|
||||
case SMART_ACTION_REMOVE_ALL_GAMEOBJECTS: return NO_PARAMS;
|
||||
// case SMART_ACTION_PAUSE_MOVEMENT: return sizeof(SmartAction::pauseMovement);
|
||||
//case SMART_ACTION_PLAY_ANIMKIT: return sizeof(SmartAction::raw);
|
||||
//case SMART_ACTION_SCENE_PLAY: return sizeof(SmartAction::raw);
|
||||
//case SMART_ACTION_SCENE_CANCEL: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_PLAY_ANIMKIT: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_SCENE_PLAY: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_SCENE_CANCEL: return sizeof(SmartAction::raw);
|
||||
// case SMART_ACTION_SPAWN_SPAWNGROUP: return sizeof(SmartAction::groupSpawn);
|
||||
// case SMART_ACTION_DESPAWN_SPAWNGROUP: return sizeof(SmartAction::groupSpawn);
|
||||
// case SMART_ACTION_RESPAWN_BY_SPAWNID: return sizeof(SmartAction::respawnData);
|
||||
// case SMART_ACTION_INVOKER_CAST: return sizeof(SmartAction::cast);
|
||||
case SMART_ACTION_PLAY_CINEMATIC: return sizeof(SmartAction::cinematic);
|
||||
case SMART_ACTION_SET_MOVEMENT_SPEED: return sizeof(SmartAction::movementSpeed);
|
||||
//case SMART_ACTION_PLAY_SPELL_VISUAL_KIT: return sizeof(SmartAction::raw);
|
||||
// case SMART_ACTION_PLAY_SPELL_VISUAL_KIT: return sizeof(SmartAction::raw);
|
||||
// case SMART_ACTION_OVERRIDE_LIGHT: return sizeof(SmartAction::overrideLight);
|
||||
// case SMART_ACTION_OVERRIDE_WEATHER: return sizeof(SmartAction::overrideWeather);
|
||||
//case SMART_ACTION_SET_AI_ANIM_KIT: return sizeof(SmartAction::raw);
|
||||
// case SMART_ACTION_SET_AI_ANIM_KIT: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_SET_HOVER: return sizeof(SmartAction::setHover);
|
||||
case SMART_ACTION_SET_HEALTH_PCT: return sizeof(SmartAction::setHealthPct);
|
||||
//case SMART_ACTION_CREATE_CONVERSATION: return sizeof(SmartAction::raw);
|
||||
// case SMART_ACTION_CREATE_CONVERSATION: return sizeof(SmartAction::raw);
|
||||
case SMART_ACTION_MOVE_TO_POS_TARGET: return sizeof(SmartAction::moveToPos);
|
||||
case SMART_ACTION_EXIT_VEHICLE: return NO_PARAMS;
|
||||
case SMART_ACTION_SET_UNIT_MOVEMENT_FLAGS: return sizeof(SmartAction::movementFlag);
|
||||
@@ -1438,11 +1438,14 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SMART_ACTION_CAST:
|
||||
case SMART_ACTION_INVOKER_CAST:
|
||||
if (!IsSpellValid(e, e.action.cast.spell))
|
||||
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && e.GetEventType() != SMART_EVENT_LINK && !EventHasInvoker(e.event.type))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} has invoker cast action, but event does not provide any invoker!", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SMART_ACTION_CAST:
|
||||
case SMART_ACTION_CROSS_CAST:
|
||||
if (!IsSpellValid(e, e.action.crossCast.spell))
|
||||
return false;
|
||||
|
||||
@@ -607,7 +607,7 @@ enum SMART_ACTION
|
||||
SMART_ACTION_ADD_NPC_FLAG = 82, // Flags
|
||||
SMART_ACTION_REMOVE_NPC_FLAG = 83, // Flags
|
||||
SMART_ACTION_SIMPLE_TALK = 84, // groupID, can be used to make players say groupID, Text_over event is not triggered, whisper can not be used (Target units will say the text)
|
||||
SMART_ACTION_INVOKER_CAST = 85, // spellID, castFlags, if avaliable, last used invoker will cast spellId with castFlags on targets
|
||||
SMART_ACTION_SELF_CAST = 85, // spellID, castFlags
|
||||
SMART_ACTION_CROSS_CAST = 86, // spellID, castFlags, CasterTargetType, CasterTarget param1, CasterTarget param2, CasterTarget param3, ( + the origonal target fields as Destination target), CasterTargets will cast spellID on all Targets (use with caution if targeting multiple * multiple units)
|
||||
SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST = 87, // script9 ids 1-9
|
||||
SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST = 88, // script9 id min, max
|
||||
@@ -656,8 +656,8 @@ enum SMART_ACTION
|
||||
SMART_ACTION_SPAWN_SPAWNGROUP = 131, /// @todo: NOT SUPPORTED YET
|
||||
SMART_ACTION_DESPAWN_SPAWNGROUP = 132, /// @todo: NOT SUPPORTED YET
|
||||
SMART_ACTION_RESPAWN_BY_SPAWNID = 133, /// @todo: NOT SUPPORTED YET
|
||||
// SMART_ACTION_INVOKER_CAST = 134, /// @todo: solve name conflicts
|
||||
SMART_ACTION_PLAY_CINEMATIC = 135, // entry
|
||||
SMART_ACTION_INVOKER_CAST = 134, // spellID, castFlags
|
||||
SMART_ACTION_PLAY_CINEMATIC = 135, // entry, cinematic
|
||||
SMART_ACTION_SET_MOVEMENT_SPEED = 136, // movementType, speedInteger, speedFraction
|
||||
|
||||
SMART_ACTION_SET_HEALTH_PCT = 142, // percent
|
||||
@@ -801,7 +801,8 @@ struct SmartAction
|
||||
struct
|
||||
{
|
||||
uint32 spell;
|
||||
uint32 flags;
|
||||
uint32 castFlags;
|
||||
uint32 triggerFlags;
|
||||
uint32 targetsLimit;
|
||||
} cast;
|
||||
|
||||
|
||||
@@ -4575,6 +4575,8 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo
|
||||
// only way correctly remove all auras from list
|
||||
//if (removedAuras != m_removedAurasCount) new aura may be added
|
||||
i = m_appliedAuras.begin();
|
||||
|
||||
sScriptMgr->OnAuraRemove(this, aurApp, removeMode);
|
||||
}
|
||||
|
||||
void Unit::_UnapplyAura(AuraApplication* aurApp, AuraRemoveMode removeMode)
|
||||
@@ -4718,8 +4720,6 @@ void Unit::RemoveAura(AuraApplicationMap::iterator& i, AuraRemoveMode mode)
|
||||
// Remove aura - for Area and Target auras
|
||||
if (aura->GetOwner() == this)
|
||||
aura->Remove(mode);
|
||||
|
||||
sScriptMgr->OnAuraRemove(this, aurApp, mode);
|
||||
}
|
||||
|
||||
void Unit::RemoveAura(uint32 spellId, ObjectGuid caster, uint8 reqEffMask, AuraRemoveMode removeMode)
|
||||
|
||||
@@ -422,6 +422,12 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
|
||||
AuctionEntry* auction = auctionHouse->GetAuction(auctionId);
|
||||
Player* player = GetPlayer();
|
||||
|
||||
if (!sScriptMgr->CanPlaceAuctionBid(player, auction))
|
||||
{
|
||||
SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_RESTRICTED_ACCOUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!auction || auction->owner == player->GetGUID())
|
||||
{
|
||||
//you cannot bid your own auction:
|
||||
|
||||
@@ -614,6 +614,21 @@ void ScriptMgr::OnQuestRewardItem(Player* player, Item* item, uint32 count)
|
||||
});
|
||||
}
|
||||
|
||||
bool ScriptMgr::CanPlaceAuctionBid(Player* player, AuctionEntry* auction)
|
||||
{
|
||||
auto ret = IsValidBoolScript<PlayerScript>([&](PlayerScript *script)
|
||||
{
|
||||
return !script->CanPlaceAuctionBid(player, auction);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScriptMgr::OnGroupRollRewardItem(Player* player, Item* item, uint32 count, RollVote voteType, Roll* roll)
|
||||
{
|
||||
ExecuteScript<PlayerScript>([&](PlayerScript* script)
|
||||
|
||||
@@ -1192,6 +1192,9 @@ public:
|
||||
// After receiving item as a quest reward
|
||||
virtual void OnQuestRewardItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/) { }
|
||||
|
||||
// When placing a bid or buying out an auction
|
||||
[[nodiscard]] virtual bool CanPlaceAuctionBid(Player* /*player*/, AuctionEntry* /*auction*/) { return true; }
|
||||
|
||||
// After receiving item as a group roll reward
|
||||
virtual void OnGroupRollRewardItem(Player* /*player*/, Item* /*item*/, uint32 /*count*/, RollVote /*voteType*/, Roll* /*roll*/) { }
|
||||
|
||||
@@ -2331,6 +2334,7 @@ public: /* PlayerScript */
|
||||
void OnStoreNewItem(Player* player, Item* item, uint32 count);
|
||||
void OnCreateItem(Player* player, Item* item, uint32 count);
|
||||
void OnQuestRewardItem(Player* player, Item* item, uint32 count);
|
||||
bool CanPlaceAuctionBid(Player* player, AuctionEntry* auction);
|
||||
void OnGroupRollRewardItem(Player* player, Item* item, uint32 count, RollVote voteType, Roll* roll);
|
||||
bool OnBeforeOpenItem(Player* player, Item* item);
|
||||
bool OnBeforePlayerQuestComplete(Player* player, uint32 quest_id);
|
||||
|
||||
Reference in New Issue
Block a user