mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 06:21:28 +00:00
Merge branch 'aa' of github.com:EQEmu/Server into aa
This commit is contained in:
commit
51caa3c577
@ -544,7 +544,7 @@ typedef enum {
|
||||
//#define SE_SummonCorpseZone 388 // *not implemented - summons a corpse from any zone(nec AA)
|
||||
#define SE_FcTimerRefresh 389 // implemented - Refresh spell icons
|
||||
//#define SE_FcTimerLockout 390 // *not implemented - Sets recast timers to specific value, focus limited.
|
||||
#define SE_MeleeVulnerability 391 // implemented [Live SPA has this as LimitManaMax however that is clearly not the effect used]
|
||||
#define SE_LimitManaMax 391 // implemented
|
||||
#define SE_FcHealAmt 392 // implemented - Adds or removes healing from spells
|
||||
#define SE_FcHealPctIncoming 393 // implemented - HealRate with focus restrictions.
|
||||
#define SE_FcHealAmtIncoming 394 // implemented - Adds/Removes amount of healing on target by X value with foucs restrictions.
|
||||
|
||||
43
zone/aa.cpp
43
zone/aa.cpp
@ -828,7 +828,7 @@ void Client::SendAlternateAdvancementRank(int aa_id, int level) {
|
||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int size = sizeof(AARankInfo_Struct) + (sizeof(AARankEffect_Struct) * rank->effects.size()) + (sizeof(AARankPrereq_Struct) * rank->prereqs.size());
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, size);
|
||||
AARankInfo_Struct *aai = (AARankInfo_Struct*)outapp->pBuffer;
|
||||
@ -996,7 +996,7 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) {
|
||||
if(!CanPurchaseAlternateAdvancementRank(rank, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(rank->base_ability->charges > 0) {
|
||||
uint32 charges = 0;
|
||||
GetAA(rank_id, &charges);
|
||||
@ -1004,7 +1004,7 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) {
|
||||
if(charges > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SetAA(rank_id, rank->current_value, rank->base_ability->charges);
|
||||
} else {
|
||||
SetAA(rank_id, rank->current_value, 0);
|
||||
@ -1022,10 +1022,10 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) {
|
||||
SendAlternateAdvancementStats();
|
||||
|
||||
if(rank->prev) {
|
||||
Message_StringID(15, AA_IMPROVE,
|
||||
std::to_string(rank->title_sid).c_str(),
|
||||
std::to_string(rank->prev->current_value).c_str(),
|
||||
std::to_string(rank->cost).c_str(),
|
||||
Message_StringID(15, AA_IMPROVE,
|
||||
std::to_string(rank->title_sid).c_str(),
|
||||
std::to_string(rank->prev->current_value).c_str(),
|
||||
std::to_string(rank->cost).c_str(),
|
||||
std::to_string(AA_POINTS).c_str());
|
||||
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
@ -1034,9 +1034,9 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) {
|
||||
QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc);
|
||||
}
|
||||
} else {
|
||||
Message_StringID(15, AA_GAIN_ABILITY,
|
||||
std::to_string(rank->title_sid).c_str(),
|
||||
std::to_string(rank->cost).c_str(),
|
||||
Message_StringID(15, AA_GAIN_ABILITY,
|
||||
std::to_string(rank->title_sid).c_str(),
|
||||
std::to_string(rank->cost).c_str(),
|
||||
std::to_string(AA_POINTS).c_str());
|
||||
/* QS: Player_Log_AA_Purchases */
|
||||
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||
@ -1125,7 +1125,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
||||
if(!IsValidSpell(rank->spell)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
||||
return;
|
||||
}
|
||||
@ -1448,7 +1448,7 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price)
|
||||
|
||||
if(!ability)
|
||||
return false;
|
||||
|
||||
|
||||
if(!CanUseAlternateAdvancementRank(rank)) {
|
||||
return false;
|
||||
}
|
||||
@ -1474,7 +1474,7 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price)
|
||||
}
|
||||
|
||||
//if expendable only let us purchase if we have no charges already
|
||||
//not quite sure on how this functions client side atm
|
||||
//not quite sure on how this functions client side atm
|
||||
//I intend to look into it later to make sure the behavior is right
|
||||
if(ability->charges > 0 && current_charges > 0) {
|
||||
return false;
|
||||
@ -1568,7 +1568,7 @@ void Zone::LoadAlternateAdvancement() {
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std::unique_ptr<AA::Ability>> &abilities,
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks)
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> &ranks)
|
||||
{
|
||||
Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Abilities...");
|
||||
abilities.clear();
|
||||
@ -1730,3 +1730,18 @@ void Mob::GrantAlternateAdvancementAbility(int aa_id, int points) {
|
||||
c->CalcBonuses();
|
||||
}
|
||||
}
|
||||
|
||||
bool Mob::CheckAATimer(int timer)
|
||||
{
|
||||
if (timer >= aaTimerMax)
|
||||
return false;
|
||||
if (aa_timers[timer].Enabled()) {
|
||||
if (aa_timers[timer].Check(false)) {
|
||||
aa_timers[timer].Disable();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5056,3 +5056,39 @@ void NPC::SetAttackTimer()
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
|
||||
if (CanThisClassDoubleAttack()) {
|
||||
CheckIncreaseSkill(SkillDoubleAttack, target, -10);
|
||||
if (CheckDoubleAttack())
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
if (hand == MainPrimary && GetLevel() >= 60 &&
|
||||
(GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER) &&
|
||||
CheckDoubleAttack(true))
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
if (hand == MainPrimary) {
|
||||
auto flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||
if (flurrychance && zone->random.Roll(flurrychance)) {
|
||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
|
||||
auto extraattackchance = aabonuses.ExtraAttackChance + spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance;
|
||||
if (extraattackchance) {
|
||||
auto wpn = GetInv().GetItem(MainPrimary);
|
||||
if (wpn && (wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
||||
wpn->GetItem()->ItemType == ItemType2HSlash ||
|
||||
wpn->GetItem()->ItemType == ItemType2HPiercing))
|
||||
if (zone->random.Roll(extraattackchance))
|
||||
Attack(target, hand, false, false, IsFromSpell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1333,10 +1333,6 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
newbon->PetMeleeMitigation += base1;
|
||||
break;
|
||||
|
||||
case SE_MeleeVulnerability:
|
||||
newbon->MeleeVulnerability += base1;
|
||||
break;
|
||||
|
||||
case SE_FactionModPct: {
|
||||
if ((base1 < 0) && (newbon->FactionModPct > base1))
|
||||
newbon->FactionModPct = base1;
|
||||
@ -3008,10 +3004,6 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
new_bonus->PetMeleeMitigation += effect_value;
|
||||
break;
|
||||
|
||||
case SE_MeleeVulnerability:
|
||||
new_bonus->MeleeVulnerability += effect_value;
|
||||
break;
|
||||
|
||||
case SE_Sanctuary:
|
||||
new_bonus->Sanctuary = true;
|
||||
break;
|
||||
@ -4588,12 +4580,6 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
aabonuses.FactionModPct = effect_value;
|
||||
break;
|
||||
|
||||
case SE_MeleeVulnerability:
|
||||
spellbonuses.MeleeVulnerability = effect_value;
|
||||
itembonuses.MeleeVulnerability = effect_value;
|
||||
aabonuses.MeleeVulnerability = effect_value;
|
||||
break;
|
||||
|
||||
case SE_IllusionPersistence:
|
||||
spellbonuses.IllusionPersistence = false;
|
||||
itembonuses.IllusionPersistence = false;
|
||||
|
||||
@ -226,6 +226,7 @@ public:
|
||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
virtual void SetAttackTimer();
|
||||
float GetQuiverHaste();
|
||||
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||
|
||||
void AI_Init();
|
||||
void AI_Start(uint32 iMoveDelay = 0);
|
||||
@ -774,7 +775,7 @@ public:
|
||||
void AddAAPoints(uint32 points) { m_pp.aapoints += points; SendAlternateAdvancementStats(); }
|
||||
int GetAAPoints() { return m_pp.aapoints; }
|
||||
int GetSpentAA() { return m_pp.aapoints_spent; }
|
||||
|
||||
|
||||
//old AA methods that we still use
|
||||
void ResetAA();
|
||||
void RefundAA();
|
||||
|
||||
@ -391,74 +391,12 @@ bool Client::Process() {
|
||||
}
|
||||
else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP
|
||||
{
|
||||
//old aa
|
||||
//if(CheckAAEffect(aaEffectRampage))
|
||||
//{
|
||||
// entity_list.AEAttack(this, 30);
|
||||
//} else {
|
||||
Attack(auto_attack_target, MainPrimary); // Kaiyodo - added attacking hand to arguments
|
||||
//}
|
||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||
TryWeaponProc(wpn, auto_attack_target, MainPrimary);
|
||||
|
||||
bool tripleAttackSuccess = false;
|
||||
if( auto_attack_target && CanThisClassDoubleAttack() ) {
|
||||
|
||||
CheckIncreaseSkill(SkillDoubleAttack, auto_attack_target, -10);
|
||||
if(CheckDoubleAttack()) {
|
||||
//should we allow rampage on double attack?
|
||||
//if(CheckAAEffect(aaEffectRampage)) {
|
||||
// entity_list.AEAttack(this, 30);
|
||||
//} else {
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
//}
|
||||
}
|
||||
|
||||
//triple attack: rangers, monks, warriors, berserkers over level 60
|
||||
if((((GetClass() == MONK || GetClass() == WARRIOR || GetClass() == RANGER || GetClass() == BERSERKER)
|
||||
&& GetLevel() >= 60) || GetSpecialAbility(SPECATK_TRIPLE))
|
||||
&& CheckDoubleAttack(true))
|
||||
{
|
||||
tripleAttackSuccess = true;
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
|
||||
//quad attack, does this belong here??
|
||||
if(GetSpecialAbility(SPECATK_QUAD) && CheckDoubleAttack(true))
|
||||
{
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
|
||||
int16 flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance;
|
||||
|
||||
if (auto_attack_target && flurrychance)
|
||||
{
|
||||
if(zone->random.Int(0, 99) < flurrychance)
|
||||
{
|
||||
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
|
||||
int16 ExtraAttackChanceBonus = spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance;
|
||||
|
||||
if (auto_attack_target && ExtraAttackChanceBonus) {
|
||||
ItemInst *wpn = GetInv().GetItem(MainPrimary);
|
||||
if(wpn){
|
||||
if(wpn->GetItem()->ItemType == ItemType2HSlash ||
|
||||
wpn->GetItem()->ItemType == ItemType2HBlunt ||
|
||||
wpn->GetItem()->ItemType == ItemType2HPiercing )
|
||||
{
|
||||
if(zone->random.Int(0, 99) < ExtraAttackChanceBonus)
|
||||
{
|
||||
Attack(auto_attack_target, MainPrimary, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DoAttackRounds(auto_attack_target, MainPrimary);
|
||||
if (CheckAATimer(aaTimerRampage))
|
||||
entity_list.AEAttack(this, 30);
|
||||
}
|
||||
}
|
||||
|
||||
@ -499,23 +437,11 @@ bool Client::Process() {
|
||||
|
||||
float random = zone->random.Real(0, 1);
|
||||
CheckIncreaseSkill(SkillDualWield, auto_attack_target, -10);
|
||||
if (random < DualWieldProbability){ // Max 78% of DW
|
||||
//if(CheckAAEffect(aaEffectRampage)) {
|
||||
// entity_list.AEAttack(this, 30, MainSecondary);
|
||||
//} else {
|
||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
||||
//}
|
||||
if (random < DualWieldProbability) { // Max 78% of DW
|
||||
ItemInst *wpn = GetInv().GetItem(MainSecondary);
|
||||
TryWeaponProc(wpn, auto_attack_target, MainSecondary);
|
||||
|
||||
if( CanThisClassDoubleAttack() && CheckDoubleAttack()) {
|
||||
//if(CheckAAEffect(aaEffectRampage)) {
|
||||
// entity_list.AEAttack(this, 30, MainSecondary);
|
||||
//} else {
|
||||
// if(auto_attack_target && auto_attack_target->GetHP() > -10)
|
||||
Attack(auto_attack_target, MainSecondary); // Single attack with offhand
|
||||
//}
|
||||
}
|
||||
DoAttackRounds(auto_attack_target, MainSecondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,7 +400,6 @@ struct StatBonuses {
|
||||
int32 Metabolism; // Food/drink consumption rates.
|
||||
bool Sanctuary; // Sanctuary effect, lowers place on hate list until cast on others.
|
||||
int32 FactionModPct; // Modifies amount of faction gained.
|
||||
int32 MeleeVulnerability; // Weakness/mitigation to melee damage
|
||||
bool LimitToSkill[HIGHEST_SKILL+2]; // Determines if we need to search for a skill proc.
|
||||
uint32 SkillProc[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs.
|
||||
uint32 SkillProcSuccess[MAX_SKILL_PROCS]; // Max number of spells containing skill_procs_success.
|
||||
|
||||
@ -421,12 +421,6 @@ int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||
int tic_inc = 0;
|
||||
tic_inc = GetFocusEffect(focusSpellDurByTic, spell_id);
|
||||
|
||||
// unsure on the exact details, but bard songs that don't cost mana at some point get an extra tick, 60 for now
|
||||
// a level 53 bard reported getting 2 tics
|
||||
// bard DOTs do get this extra tick, but beneficial long bard songs don't? (invul, crescendo)
|
||||
if ((IsShortDurationBuff(spell_id) || IsDetrimentalSpell(spell_id)) && IsBardSong(spell_id) &&
|
||||
spells[spell_id].mana == 0 && GetClass() == BARD && GetLevel() > 60)
|
||||
tic_inc++;
|
||||
float focused = ((duration * increase) / 100.0f) + tic_inc;
|
||||
int ifocused = static_cast<int>(focused);
|
||||
|
||||
@ -878,7 +872,7 @@ void EntityList::AEBardPulse(Mob *caster, Mob *center, uint16 spell_id, bool aff
|
||||
caster->CastToClient()->CheckSongSkillIncrease(spell_id);
|
||||
}
|
||||
|
||||
//Dook- Rampage and stuff for clients.
|
||||
// Rampage and stuff for clients. Normal and Duration rampages
|
||||
//NPCs handle it differently in Mob::Rampage
|
||||
void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool IsFromSpell) {
|
||||
//Dook- Will need tweaking, currently no pets or players or horses
|
||||
@ -896,7 +890,10 @@ void EntityList::AEAttack(Mob *attacker, float dist, int Hand, int count, bool I
|
||||
&& curmob->GetRace() != 216 && curmob->GetRace() != 472 /* dont attack horses */
|
||||
&& (DistanceSquared(curmob->GetPosition(), attacker->GetPosition()) <= dist2)
|
||||
) {
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
if (!attacker->IsClient() || attacker->GetClass() == MONK || attacker->GetClass() == RANGER)
|
||||
attacker->Attack(curmob, Hand, false, false, IsFromSpell);
|
||||
else
|
||||
attacker->CastToClient()->DoAttackRounds(curmob, Hand, IsFromSpell);
|
||||
hit++;
|
||||
if (count != 0 && hit >= count)
|
||||
return;
|
||||
|
||||
@ -3769,11 +3769,8 @@ int16 Mob::GetSkillDmgTaken(const SkillUseTypes skill_used)
|
||||
skilldmg_mod += itembonuses.SkillDmgTaken[HIGHEST_SKILL+1] + spellbonuses.SkillDmgTaken[HIGHEST_SKILL+1] +
|
||||
itembonuses.SkillDmgTaken[skill_used] + spellbonuses.SkillDmgTaken[skill_used];
|
||||
|
||||
|
||||
skilldmg_mod += SkillDmgTaken_Mod[skill_used] + SkillDmgTaken_Mod[HIGHEST_SKILL+1];
|
||||
|
||||
skilldmg_mod += spellbonuses.MeleeVulnerability + itembonuses.MeleeVulnerability + aabonuses.MeleeVulnerability;
|
||||
|
||||
if(skilldmg_mod < -100)
|
||||
skilldmg_mod = -100;
|
||||
|
||||
|
||||
@ -971,6 +971,7 @@ public:
|
||||
void CalcAABonuses(StatBonuses* newbon);
|
||||
void ApplyAABonuses(const AA::Rank &rank, StatBonuses* newbon);
|
||||
void GrantAlternateAdvancementAbility(int aa_id, int points);
|
||||
bool CheckAATimer(int timer);
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic);
|
||||
|
||||
@ -638,42 +638,23 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
snprintf(effect_desc, _EDLEN, "Group Fear Immunity");
|
||||
#endif
|
||||
//Added client messages to give some indication this effect is active.
|
||||
uint32 group_id_caster = 0;
|
||||
uint32 time = spell.base[i]*10;
|
||||
if(caster->IsClient())
|
||||
{
|
||||
if(caster->IsGrouped())
|
||||
{
|
||||
group_id_caster = GetGroup()->GetID();
|
||||
}
|
||||
else if(caster->IsRaidGrouped())
|
||||
{
|
||||
group_id_caster = (GetRaid()->GetGroup(CastToClient()) == 0xFFFF) ? 0 : (GetRaid()->GetGroup(CastToClient()) + 1);
|
||||
// Is there a message generated? Too disgusted by raids.
|
||||
uint32 time = spell.base[i] * 10 * 1000;
|
||||
if (caster->IsClient()) {
|
||||
if (caster->IsGrouped()) {
|
||||
auto group = caster->GetGroup();
|
||||
for (int i = 0; i < 6; ++i)
|
||||
if (group->members[i])
|
||||
group->members[i]->aa_timers[aaTimerWarcry].Start(time);
|
||||
} else if (caster->IsRaidGrouped()) {
|
||||
auto raid = caster->GetRaid();
|
||||
uint32 gid = raid->GetGroup(caster->CastToClient());
|
||||
if (gid < 12)
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; ++i)
|
||||
if (raid->members[i].member && raid->members[i].GroupNumber == gid)
|
||||
raid->members[i].member->aa_timers[aaTimerWarcry].Start(time);
|
||||
}
|
||||
}
|
||||
//old aa
|
||||
//if(group_id_caster){
|
||||
// Group *g = entity_list.GetGroupByID(group_id_caster);
|
||||
// uint32 time = spell.base[i]*10;
|
||||
// if(g){
|
||||
// for(int gi=0; gi < 6; gi++){
|
||||
// if(g->members[gi] && g->members[gi]->IsClient())
|
||||
// {
|
||||
// g->members[gi]->CastToClient()->EnableAAEffect(aaEffectWarcry , time);
|
||||
// if (g->members[gi]->GetID() != caster->GetID())
|
||||
// g->members[gi]->Message(13, "You hear the war cry.");
|
||||
// else
|
||||
// Message(13, "You let loose a fierce war cry.");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//else{
|
||||
// CastToClient()->EnableAAEffect(aaEffectWarcry , time);
|
||||
// Message(13, "You let loose a fierce war cry.");
|
||||
//}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2238,9 +2219,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
#ifdef SPELL_EFFECT_SPAM
|
||||
snprintf(effect_desc, _EDLEN, "Duration Rampage");
|
||||
#endif
|
||||
//if (caster && caster->IsClient()) { // will tidy this up later so that NPCs can duration ramp from spells too
|
||||
// CastToClient()->DurationRampage(effect_value*12);
|
||||
//}
|
||||
aa_timers[aaTimerRampage].Start(effect_value * 10 * 1000); // Live bug, was suppose to be 1 second per value
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2969,7 +2948,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
case SE_FcIncreaseNumHits:
|
||||
case SE_CastonFocusEffect:
|
||||
case SE_FcHealAmtIncoming:
|
||||
case SE_MeleeVulnerability:
|
||||
case SE_LimitManaMax:
|
||||
case SE_DoubleRangedAttack:
|
||||
case SE_ShieldEquipHateMod:
|
||||
case SE_ShieldEquipDmgMod:
|
||||
@ -3377,7 +3356,7 @@ void Mob::BuffProcess()
|
||||
{
|
||||
--buffs[buffs_i].ticsremaining;
|
||||
|
||||
if ((buffs[buffs_i].ticsremaining == 0 && !IsShortDurationBuff(buffs[buffs_i].spellid)) || buffs[buffs_i].ticsremaining < 0) {
|
||||
if ((buffs[buffs_i].ticsremaining == 0 && !(IsShortDurationBuff(buffs[buffs_i].spellid) || IsBardSong(buffs[buffs_i].spellid))) || buffs[buffs_i].ticsremaining < 0) {
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Buff %d in slot %d has expired. Fading.", buffs[buffs_i].spellid, buffs_i);
|
||||
BuffFadeBySlot(buffs_i);
|
||||
}
|
||||
@ -4322,6 +4301,11 @@ int16 Client::CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id)
|
||||
LimitFailure = true;
|
||||
break;
|
||||
|
||||
case SE_LimitManaMax:
|
||||
if (spell.mana > base1)
|
||||
LimitFailure = true;
|
||||
break;
|
||||
|
||||
case SE_LimitTarget:
|
||||
if (base1 < 0) {
|
||||
if (-base1 == spell.targettype) // Exclude
|
||||
@ -4740,6 +4724,11 @@ int16 Mob::CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, boo
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SE_LimitManaMax:
|
||||
if (spell.mana > focus_spell.base[i])
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case SE_LimitTarget:
|
||||
if (focus_spell.base[i] < 0) {
|
||||
if (-focus_spell.base[i] == spell.targettype) // Exclude
|
||||
@ -5199,11 +5188,8 @@ uint16 Client::GetSympatheticFocusEffect(focusType type, uint16 spell_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int16 Client::GetFocusEffect(focusType type, uint16 spell_id) {
|
||||
|
||||
if (IsBardSong(spell_id) && type != focusFcBaseEffects)
|
||||
return 0;
|
||||
|
||||
int16 Client::GetFocusEffect(focusType type, uint16 spell_id)
|
||||
{
|
||||
int16 realTotal = 0;
|
||||
int16 realTotal2 = 0;
|
||||
int16 realTotal3 = 0;
|
||||
|
||||
@ -2280,7 +2280,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
|
||||
if(rank && rank->base_ability) {
|
||||
ExpendAlternateAdvancementCharge(rank->base_ability->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(spell_id == casting_spell_id && casting_spell_timer != 0xFFFFFFFF)
|
||||
{
|
||||
//aa new todo: aa expendable charges here
|
||||
@ -4124,13 +4124,13 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//else if (IsClient() && CastToClient()->CheckAAEffect(aaEffectWarcry)) //old aa
|
||||
//{
|
||||
// Message(13, "Your are immune to fear.");
|
||||
// Log.Out(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!");
|
||||
// caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
||||
// return true;
|
||||
//}
|
||||
else if (CheckAATimer(aaTimerWarcry))
|
||||
{
|
||||
Message(13, "Your are immune to fear.");
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!");
|
||||
caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(IsCharmSpell(spell_id))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user