[Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic. (#1954)

* test

* complete

* Update effects.cpp

* Update spells.cpp

* Update effects.cpp

* [Spells] Support for bards using Disciplines while casting or /melody.

Support for spell field 'cast not standing' not allow casting from divine aura

* [Spells] Support for bards using Disciplines while casting or /melody.

DA bypass logic for spells with field 'cast_not_standing'

* updates

* stun and mez bypass

* Update spdat.cpp

* Update spdat.cpp

* Update spells.cpp

* clean

* requirement messages

* update

* pct

* save work

* Reform code 1_22_22

* updated

* update id to pointer

* Update spells.cpp

* rework 2

* update 1_23_22

* Update spells.cpp

* updates

* msg string works

* fix disc timers not be set

* more optimization

* update 1_23_22 PM

moved stop casting out
charm and harmony moved in

* update 1_25_22

rework of functions

* updates 1_26_22

* remove old checks

* gm override added for some

* update bard AA casting checks

* updates

* addbuff exception for bard

* debugs

* charm working

* update

* moved skill check here

* cast from item while singing

* lets not attack mounts

* instant cast items click

* aug clicks working

* aug tests

Bug? Cast time not display on aug clicks for bards

* aug recast from items semi ok

* added item timer function

* unified setting item recast timer

* clean up time

* update

* bard AA cast updates

* debugs removed

* debugs removed

* clean up

* clean up

* better placement of bindsight and numhits fix

* move and rename function

* Update spells.cpp

* add logs

* delete old DoCastingChecks

* Removed old bard pulse functions

* remove AEBardPulse and GroupPulse

* removed Raid::GroupBardPulse

* Pulse Restriction: Divine Aura

* Pulse Restrictions : Fear behavior

* Update spells.cpp

* Update spells.cpp

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

bots...

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

added recommended isvalidspell check

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

merged

* [Spells] Major update to Bard song pulsing, Bard item clicks while singing, and spell casting restriction logic.

removed defines since we have them as constants
This commit is contained in:
KayenEQ 2022-02-07 07:48:52 -05:00 committed by GitHub
parent a5d8a64792
commit a208801d1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1930 additions and 900 deletions

View File

@ -1462,6 +1462,23 @@ bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect)
//Allowing anything not confirmed to be restricted / allowed to receive modifiers, as to not inhbit anyone making custom bard songs.
}
bool IsPulsingBardSong(int32 spell_id)
{
if (!IsValidSpell(spell_id)) {
return false;
}
if (spells[spell_id].buff_duration == 0xFFFF ||
spells[spell_id].recast_time> 0 ||
spells[spell_id].mana > 0 ||
IsEffectInSpell(spell_id, SE_TemporaryPets) ||
IsEffectInSpell(spell_id, SE_Familiar)) {
return false;
}
return true;
}
int GetSpellStatValue(uint32 spell_id, const char* stat_identifier, uint8 slot)
{
if (!IsValidSpell(spell_id))

View File

@ -179,8 +179,6 @@
#define SPELLGROUP_FURIOUS_RAMPAGE 38106
#define SPELLGROUP_SHROUD_OF_PRAYER 41050
#define EFFECT_COUNT 12
#define MAX_SPELL_TRIGGER 12 // One for each slot(only 6 for AA since AA use 2)
#define MAX_RESISTABLE_EFFECTS 12 // Number of effects that are typcially checked agianst resists.
@ -193,6 +191,12 @@
#define MAX_APPEARANCE_EFFECTS 20 //Up to 20 Appearance Effects can be saved to a mobs appearance effect array, these will be sent to other clients when they enter a zone (This is arbitrary)
#define MAX_CAST_ON_SKILL_USE 36 //Actual amount is MAX/3
//instrument item id's used as song components
#define INSTRUMENT_HAND_DRUM 13000
#define INSTRUMENT_WOODEN_FLUTE 13001
#define INSTRUMENT_LUTE 13011
#define INSTRUMENT_HORN 13012
const int Z_AGGRO=10;
@ -1536,9 +1540,9 @@ int GetViralMinSpreadTime(int32 spell_id);
int GetViralMaxSpreadTime(int32 spell_id);
int GetViralSpreadRange(int32 spell_id);
bool IsInstrumentModAppliedToSpellEffect(int32 spell_id, int effect);
bool IsPulsingBardSong(int32 spell_id);
uint32 GetProcLimitTimer(int32 spell_id, int proc_type);
bool IgnoreCastingRestriction(int32 spell_id);
int CalcPetHp(int levelb, int classb, int STA = 75);
int GetSpellEffectDescNum(uint16 spell_id);
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);

View File

@ -1311,8 +1311,11 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
TogglePassiveAlternativeAdvancement(*rank, ability->id);
}
else {
// Bards can cast instant cast AAs while they are casting another song
if (spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
// Bards can cast instant cast AAs while they are casting or channeling item cast.
if (GetClass() == BARD && IsCasting() && spells[rank->spell].cast_time == 0) {
if (!DoCastingChecksOnCaster(rank->spell)) {
return;
}
if (!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQ::spells::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].resist_difficulty, false)) {
return;
}

View File

@ -660,6 +660,9 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
if (target->GetSpecialAbility(IMMUNE_DAMAGE_NPC) && IsNPC())
return false;
if (target->IsHorse())
return false;
// can't damage own pet (applies to everthing)
Mob *target_owner = target->GetOwner();
Mob *our_owner = GetOwner();

View File

@ -436,7 +436,6 @@ Json::Value ApiGetMobListDetail(EQ::Net::WebsocketServerConnection *connection,
row["cwp"] = mob->GetCWP();
row["cwpp"] = mob->GetCWPP();
row["divine_aura"] = mob->DivineAura();
row["do_casting_checks"] = mob->DoCastingChecks();
row["dont_buff_me_before"] = mob->DontBuffMeBefore();
row["dont_cure_me_before"] = mob->DontCureMeBefore();
row["dont_dot_me_before"] = mob->DontDotMeBefore();

View File

@ -7349,7 +7349,7 @@ void Bot::GenerateSpecialAttacks() {
bool Bot::DoFinishedSpellAETarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
if(GetClass() == BARD) {
if(!ApplyNextBardPulse(bardsong, this, bardsong_slot))
if(!ApplyBardPulse(bardsong, this, bardsong_slot))
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
stopLogic = true;

View File

@ -1491,7 +1491,10 @@ public:
void LeaveRaidXTargets(Raid *r);
bool GroupFollow(Client* inviter);
inline bool GetRunMode() const { return runmode; }
void SendItemRecastTimer(uint32 recast_type, uint32 recast_delay = 0);
void SendItemRecastTimer(int32 recast_type, uint32 recast_delay = 0);
void SetItemRecastTimer(int32 spell_id, uint32 inventory_slot);
bool HasItemRecastTimer(int32 spell_id, uint32 inventory_slot);
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQ::versions::maskRoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
inline void SetAggroMeterLock(int in) { m_aggrometer.set_lock_id(in); }

View File

@ -4053,7 +4053,6 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
{
EQ::ItemInstance* p_inst = (EQ::ItemInstance*)inst;
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot);
if (i == 0) {
CastSpell(item->Click.Effect, castspell->target_id, slot, item->CastTime, 0, 0, castspell->inventoryslot);
}
@ -8791,6 +8790,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
}
spell_id = item->Click.Effect;
bool is_casting_bard_song = false;
if
(
@ -8812,10 +8812,20 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
)
)
{
SendSpellBarEnable(spell_id);
return;
/*
Bards on live can click items while casting spell gems, it stops that song cast and replaces it with item click cast.
Can not click while casting other items.
*/
if (GetClass() == BARD && IsCasting() && casting_spell_slot < CastingSlot::MaxGems)
{
is_casting_bard_song = true;
}
else
{
SendSpellBarEnable(spell_id);
return;
}
}
// Modern clients don't require pet targeted for item clicks that are ST_Pet
if (spell_id > 0 && (spells[spell_id].target_type == ST_Pet || spells[spell_id].target_type == ST_SummonedPet))
target_id = GetPetID();
@ -8903,11 +8913,16 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
{
return;
}
if (i == 0) {
if (!IsCastWhileInvis(item->Click.Effect))
if (!IsCastWhileInvis(item->Click.Effect)) {
CommonBreakInvisible(); // client can't do this for us :(
CastSpell(item->Click.Effect, target_id, CastingSlot::Item, item->CastTime, 0, 0, slot_id);
}
if (GetClass() == BARD){
DoBardCastingFromItemClick(is_casting_bard_song, item->CastTime, item->Click.Effect, target_id, CastingSlot::Item, slot_id, item->RecastType, item->RecastDelay);
}
else {
CastSpell(item->Click.Effect, target_id, CastingSlot::Item, item->CastTime, 0, 0, slot_id);
}
}
}
else
@ -8944,9 +8959,15 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
}
if (i == 0) {
if (!IsCastWhileInvis(augitem->Click.Effect))
if (!IsCastWhileInvis(augitem->Click.Effect)) {
CommonBreakInvisible(); // client can't do this for us :(
CastSpell(augitem->Click.Effect, target_id, CastingSlot::Item, augitem->CastTime, 0, 0, slot_id);
}
if (GetClass() == BARD) {
DoBardCastingFromItemClick(is_casting_bard_song, augitem->CastTime, augitem->Click.Effect, target_id, CastingSlot::Item, slot_id, augitem->RecastType, augitem->RecastDelay);
}
else {
CastSpell(augitem->Click.Effect, target_id, CastingSlot::Item, augitem->CastTime, 0, 0, slot_id);
}
}
}
else
@ -9552,16 +9573,20 @@ void Client::Handle_OP_ManaChange(const EQApplicationPacket *app)
{
if (app->size == 0) {
// i think thats the sign to stop the songs
if (IsBardSong(casting_spell_id) || bardsong != 0)
InterruptSpell(SONG_ENDS, 0x121);
else
if (IsBardSong(casting_spell_id) || HasActiveSong()) {
InterruptSpell(SONG_ENDS, 0x121); //Live doesn't send song end message anymore (~Kayen 1/26/22)
}
else {
InterruptSpell(INTERRUPT_SPELL, 0x121);
}
return;
}
else // I don't think the client sends proper manachanges
{ // with a length, just the 0 len ones for stopping songs
//ManaChange_Struct* p = (ManaChange_Struct*)app->pBuffer;
/*
I don't think the client sends proper manachanges
with a length, just the 0 len ones for stopping songs
ManaChange_Struct* p = (ManaChange_Struct*)app->pBuffer;
*/
else{
printf("OP_ManaChange from client:\n");
DumpPacket(app);
}

View File

@ -238,9 +238,9 @@ bool Client::Process() {
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
}
else {
if (!ApplyNextBardPulse(bardsong, song_target, bardsong_slot))
if (!ApplyBardPulse(bardsong, song_target, bardsong_slot)) {
InterruptSpell(SONG_ENDS_ABRUPTLY, 0x121, bardsong);
//SpellFinished(bardsong, bardsong_target, bardsong_slot, spells[bardsong].mana);
}
}
}

View File

@ -821,22 +821,24 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
instant_recast = false;
if (GetClass() == BARD && IsCasting() && spells[spell_id].cast_time == 0) {
if (DoCastingChecks(spell_id, target)) {
SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline, 0, -1, spells[spell_id].resist_difficulty, false, -1, (uint32)DiscTimer, reduced_recast);
if (DoCastingChecksOnCaster(spell_id)) {
if (SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline, 0, -1, spells[spell_id].resist_difficulty, false, -1, (uint32)DiscTimer, reduced_recast, false)) {
SendDisciplineTimer(spells[spell_id].timer_id, reduced_recast);
}
}
}
else {
CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast);
if (CastSpell(spell_id, target, EQ::spells::CastingSlot::Discipline, -1, -1, 0, -1, (uint32)DiscTimer, reduced_recast)) {
SendDisciplineTimer(spells[spell_id].timer_id, reduced_recast);
}
}
SendDisciplineTimer(spells[spell_id].timer_id, reduced_recast);
}
}
if (instant_recast) {
if (GetClass() == BARD && IsCasting() && spells[spell_id].cast_time == 0) {
if (DoCastingChecks(spell_id, target)) {
SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline);
if (DoCastingChecksOnCaster(spell_id)) {
SpellFinished(spell_id, entity_list.GetMob(target), EQ::spells::CastingSlot::Discipline, 0, -1, spells[spell_id].resist_difficulty, false, -1, 0xFFFFFFFF, 0, false);
}
}
else {
@ -1194,90 +1196,6 @@ void EntityList::MassGroupBuff(
}
}
/**
* Causes caster to hit every mob within dist range of center with a bard pulse of spell_id
* NPC spells will only affect other NPCs with compatible faction
*
* @param caster
* @param center
* @param spell_id
* @param affect_caster
*/
void EntityList::AEBardPulse(
Mob *caster,
Mob *center,
uint16 spell_id,
bool affect_caster)
{
Mob *current_mob = nullptr;
float distance = caster->GetAOERange(spell_id);
float distance_squared = distance * distance;
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
bool is_npc = caster->IsNPC();
for (auto &it : entity_list.GetCloseMobList(caster, distance)) {
current_mob = it.second;
/**
* Skip self
*/
if (current_mob == center) {
continue;
}
if (current_mob == caster && !affect_caster) {
continue;
}
if (DistanceSquared(center->GetPosition(), current_mob->GetPosition()) > distance_squared) { //make sure they are in range
continue;
}
/**
* check npc->npc casting
*/
if (is_npc && current_mob->IsNPC()) {
FACTION_VALUE faction = current_mob->GetReverseFactionCon(caster);
if (is_detrimental_spell) {
//affect mobs that are on our hate list, or
//which have bad faction with us
if (!(caster->CheckAggro(current_mob) || faction == FACTION_THREATENINGLY || faction == FACTION_SCOWLS)) {
continue;
}
}
else {
//only affect mobs we would assist.
if (!(faction <= FACTION_AMIABLY)) {
continue;
}
}
}
/**
* LOS
*/
if (is_detrimental_spell) {
if (!center->CheckLosFN(current_mob)) {
continue;
}
}
else { // check to stop casting beneficial ae buffs (to wit: bard songs) on enemies...
// See notes in AESpell() above for more info.
if (caster->IsAttackAllowed(current_mob, true)) {
continue;
}
if (caster->CheckAggro(current_mob)) {
continue;
}
}
current_mob->BardPulse(spell_id, caster);
}
if (caster->IsClient()) {
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
}
}
/**
* Rampage - Normal and Duration rampages
* NPCs handle it differently in Mob::Rampage

View File

@ -422,7 +422,6 @@ public:
int *max_targets = nullptr
);
void MassGroupBuff(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
void AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool affect_caster = true);
//trap stuff
Mob* GetTrapTrigger(Trap* trap);

View File

@ -847,42 +847,6 @@ void Group::CastGroupSpell(Mob* caster, uint16 spell_id) {
disbandcheck = true;
}
// does the caster + group
void Group::GroupBardPulse(Mob* caster, uint16 spell_id) {
uint32 z;
float range, distance;
if(!caster)
return;
castspell = true;
range = caster->GetAOERange(spell_id);
float range2 = range*range;
for(z=0; z < MAX_GROUP_MEMBERS; z++) {
if(members[z] == caster) {
caster->BardPulse(spell_id, caster);
#ifdef GROUP_BUFF_PETS
if(caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed())
caster->BardPulse(spell_id, caster->GetPet());
#endif
}
else if(members[z] != nullptr)
{
distance = DistanceSquared(caster->GetPosition(), members[z]->GetPosition());
if(distance <= range2) {
members[z]->BardPulse(spell_id, caster);
#ifdef GROUP_BUFF_PETS
if(members[z]->GetPet() && members[z]->HasPetAffinity() && !members[z]->GetPet()->IsCharmed())
members[z]->GetPet()->BardPulse(spell_id, caster);
#endif
} else
LogSpells("Group bard pulse: [{}] is out of range [{}] at distance [{}] from [{}]", members[z]->GetName(), range, distance, caster->GetName());
}
}
}
bool Group::IsGroupMember(Mob* client)
{
bool Result = false;

View File

@ -71,7 +71,6 @@ public:
bool IsGroup() { return true; }
void SendGroupJoinOOZ(Mob* NewMember);
void CastGroupSpell(Mob* caster,uint16 spellid);
void GroupBardPulse(Mob* caster,uint16 spellid);
void SplitExp(uint32 exp, Mob* other);
void GroupMessage(Mob* sender,uint8 language,uint8 lang_skill,const char* message);
void GroupMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0);

View File

@ -4465,14 +4465,15 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id)
}
//Used for effects that should occur after the completion of the spell
void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
void Mob::ApplyHealthTransferDamage(Mob *caster, Mob *target, uint16 spell_id)
{
if (!IsValidSpell(spell_id))
return;
/*Apply damage from Lifeburn type effects on caster at end of spell cast.
This allows for the AE spells to function without repeatedly killing caster
Damage or heal portion can be found as regular single use spell effect
/*
Apply damage from Lifeburn type effects on caster at end of spell cast.
This allows for the AE spells to function without repeatedly killing caster
Damage or heal portion can be found as regular single use spell effect
*/
if (IsEffectInSpell(spell_id, SE_Health_Transfer)){
for (int i = 0; i < EFFECT_COUNT; i++) {
@ -4481,10 +4482,12 @@ void Mob::TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id)
int new_hp = GetMaxHP();
new_hp -= GetMaxHP() * spells[spell_id].base_value[i] / 1000;
if (new_hp > 0)
if (new_hp > 0) {
SetHP(new_hp);
else
}
else {
Kill();
}
}
}
}

View File

@ -285,11 +285,6 @@ public:
void SetInvisible(uint8 state);
void SetMobTextureProfile(uint8 material_slot, uint16 texture, uint32 color = 0, uint32 hero_forge_model = 0);
//Song
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
bool ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, EQ::spells::CastingSlot slot);
void BardPulse(uint16 spell_id, Mob *caster);
//Spell
void SendSpellEffect(uint32 effect_id, uint32 duration, uint32 finish_delay, bool zone_wide,
uint32 unk020, bool perm_effect = false, Client *c = nullptr, uint32 caster_id = 0, uint32 target_id = 0);
@ -331,13 +326,16 @@ public:
void CastedSpellFinished(uint16 spell_id, uint32 target_id, EQ::spells::CastingSlot slot, uint16 mana_used,
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0);
bool SpellFinished(uint16 spell_id, Mob *target, EQ::spells::CastingSlot slot = EQ::spells::CastingSlot::Item, uint16 mana_used = 0,
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0);
uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, bool from_casted_spell = false);
void SendBeginCast(uint16 spell_id, uint32 casttime);
virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar, int reflect_effectiveness = 0,
bool use_resist_adjust = false, int16 resist_adjust = 0, bool isproc = false, int level_override = -1, int32 duration_override = 0);
virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100, int level_override = -1, int reflect_effectiveness = 0, int32 duration_override = 0);
virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center,
CastAction_type &CastAction, EQ::spells::CastingSlot slot, bool isproc = false);
bool DoCastingChecksOnCaster(int32 spell_id);
bool DoCastingChecksZoneRestrictions(bool check_on_casting, int32 spell_id);
bool DoCastingChecksOnTarget(bool check_on_casting, int32 spell_id, Mob* spell_target);
virtual bool CheckFizzle(uint16 spell_id);
virtual bool CheckSpellLevelRestriction(uint16 spell_id);
virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster);
@ -345,9 +343,9 @@ public:
void InterruptSpell(uint16 spellid = SPELL_UNKNOWN);
void InterruptSpell(uint16, uint16, uint16 spellid = SPELL_UNKNOWN);
void StopCasting();
void StopCastSpell(int32 spell_id, bool send_spellbar_enable);
inline bool IsCasting() const { return((casting_spell_id != 0)); }
uint16 CastingSpellID() const { return casting_spell_id; }
bool DoCastingChecks(int32 spell_id = SPELL_UNKNOWN, uint16 target_id = 0);
bool TryDispel(uint8 caster_level, uint8 buff_level, int level_modifier);
bool TrySpellProjectile(Mob* spell_target, uint16 spell_id, float speed = 1.5f);
void ResourceTap(int32 damage, uint16 spell_id);
@ -355,10 +353,19 @@ public:
void CalcDestFromHeading(float heading, float distance, float MaxZDiff, float StartX, float StartY, float &dX, float &dY, float &dZ);
void BeamDirectional(uint16 spell_id, int16 resist_adjust);
void ConeDirectional(uint16 spell_id, int16 resist_adjust);
void TryOnSpellFinished(Mob *caster, Mob *target, uint16 spell_id);
void ApplyHealthTransferDamage(Mob *caster, Mob *target, uint16 spell_id);
void ApplySpellEffectIllusion(int32 spell_id, Mob* caster, int buffslot, int base, int limit, int max);
void ApplyIllusionToCorpse(int32 spell_id, Corpse* new_corpse);
void SendIllusionWearChange(Client* c);
//Bard
bool ApplyBardPulse(int32 spell_id, Mob *spell_target, EQ::spells::CastingSlot slot);
bool IsActiveBardSong(int32 spell_id);
bool HasActiveSong() const { return(bardsong != 0); }
void ZeroBardPulseVars();
void DoBardCastingFromItemClick(bool is_casting_bard_song, uint32 cast_time, int32 spell_id, uint16 target_id, EQ::spells::CastingSlot slot, uint32 item_slot,
uint32 recast_type , uint32 recast_delay);
bool UseBardSpellLogic(uint16 spell_id = 0xffff, int slot = -1);
//Buff
void BuffProcess();
@ -847,6 +854,7 @@ public:
int32 GetExtraSpellAmt(uint16 spell_id, int32 extra_spell_amt, int32 base_spell_dmg);
void MeleeLifeTap(int32 damage);
bool PassCastRestriction(int value);
void SendCastRestrictionMessage(int requirement_id, bool is_target_requirement = true, bool is_discipline = false);
bool ImprovedTaunt();
bool TryRootFadeByDamage(int buffslot, Mob* attacker);
float GetSlowMitigation() const { return slow_mitigation; }
@ -1126,7 +1134,6 @@ public:
void InstillDoubt(Mob *who);
int16 GetResist(uint8 type) const;
bool HasActiveSong() const { return(bardsong != 0); }
bool Charmed() const { return typeofpet == petCharmed; }
static uint32 GetLevelHP(uint8 tlevel);
uint32 GetZoneID() const; //for perl
@ -1735,7 +1742,6 @@ protected:
MobMovementManager *mMovementManager;
private:
void _StopSong(); //this is not what you think it is
Mob* target;

View File

@ -827,42 +827,6 @@ void Raid::SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uin
}
}
void Raid::GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid){
uint32 z;
float range, distance;
if(!caster)
return;
range = caster->GetAOERange(spellid);
float range2 = range*range;
for(z=0; z < MAX_RAID_MEMBERS; z++) {
if(members[z].member == caster) {
caster->BardPulse(spellid, caster);
#ifdef GROUP_BUFF_PETS
if(caster->GetPet() && caster->HasPetAffinity() && !caster->GetPet()->IsCharmed())
caster->BardPulse(spellid, caster->GetPet());
#endif
}
else if(members[z].member != nullptr)
{
if(members[z].GroupNumber == gid){
distance = DistanceSquared(caster->GetPosition(), members[z].member->GetPosition());
if(distance <= range2) {
members[z].member->BardPulse(spellid, caster);
#ifdef GROUP_BUFF_PETS
if(members[z].member->GetPet() && members[z].member->HasPetAffinity() && !members[z].member->GetPet()->IsCharmed())
members[z].member->GetPet()->BardPulse(spellid, caster);
#endif
} else
LogSpells("Group bard pulse: [{}] is out of range [{}] at distance [{}] from [{}]", members[z].member->GetName(), range, distance, caster->GetName());
}
}
}
}
void Raid::TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading, uint32 gid)
{
for(int i = 0; i < MAX_RAID_MEMBERS; i++)

View File

@ -160,7 +160,6 @@ public:
void BalanceMana(int32 penalty, uint32 gid, float range = 0, Mob* caster = nullptr, int32 limit = 0);
void HealGroup(uint32 heal_amt, Mob* caster, uint32 gid, float range = 0);
void SplitMoney(uint32 gid, uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = nullptr);
void GroupBardPulse(Mob* caster, uint16 spellid, uint32 gid);
void TeleportGroup(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading, uint32 gid);
void TeleportRaid(Mob* sender, uint32 zoneID, uint16 instance_id, float x, float y, float z, float heading);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff