From afaa9ee6c995dbad567477dac038816fd8fe4fae Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 11 Jun 2015 23:08:17 -0700 Subject: [PATCH] Expendable aa work --- zone/aa.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++----- zone/bot.cpp | 9 ++++---- zone/bot.h | 5 +++-- zone/mob.cpp | 1 + zone/mob.h | 8 +++++-- zone/spells.cpp | 15 +++++++++---- 6 files changed, 77 insertions(+), 17 deletions(-) diff --git a/zone/aa.cpp b/zone/aa.cpp index 368eda225..20009d281 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -1276,7 +1276,8 @@ Mob *AA_SwarmPetInfo::GetOwner() //New AA void Client::SendAlternateAdvancementTable() { for(auto &aa : zone->aa_abilities) { - auto ranks = GetAA(aa.second->first_rank_id); + uint32 charges = 0; + auto ranks = GetAA(aa.second->first_rank_id, &charges); if(ranks) { if(aa.second->GetMaxLevel() == ranks) { SendAlternateAdvancementRank(aa.first, ranks); @@ -1446,7 +1447,12 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) { } if(rank->base_ability->charges > 0) { - SetAA(rank_id, rank->current_value, rank->base_ability->charges); + uint32 charges = 0; + GetAA(rank_id, &charges); + + if(charges == 0) { + SetAA(rank_id, rank->current_value, rank->base_ability->charges); + } } else { SetAA(rank_id, rank->current_value, 0); @@ -1570,11 +1576,21 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { return; } - //make sure it's activateable type - if(!(ability->type == 3 || ability->type == 4)) { + //make sure it is not a passive + if(rank->effects.size() > 0) { return; } + //if expendable make sure we have charges + if(ability->charges > 0) { + uint32 charges = 0; + GetAA(rank_id, &charges); + + if(charges < 0) { + return; + } + } + //check cooldown if(!p_timers.Expired(&database, rank->spell_type + pTimerAAStart)) { uint32 aaremain = p_timers.GetRemainingTime(rank->spell_type + pTimerAAStart); @@ -1609,8 +1625,9 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { p_timers.Clear(&database, rank->spell_type + pTimerAAStart); return; } + ExpendAlternateAdvancementCharge(ability->id); } else { - if(!CastSpell(rank->spell, target_id, USE_ITEM_SPELL_SLOT, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, 1)) { + if(!CastSpell(rank->spell, target_id, USE_ITEM_SPELL_SLOT, -1, -1, 0, -1, rank->spell_type + pTimerAAStart, cooldown, 1, nullptr, ability->id)) { //Reset on failed cast SendAlternateAdvancementTimer(rank->spell_type, 0, -1); Message_StringID(15, ABILITY_FAILED); @@ -1655,6 +1672,35 @@ int Mob::GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in) { return 0; } +void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) { + for(auto &iter : aa_ranks) { + AA::Ability *ability = zone->GetAlternateAdvancementAbility(iter.first); + if(ability && aa_id == ability->id) { + if(iter.second.second > 0) { + iter.second.second -= 1; + + if(iter.second.second == 0) { + aa_ranks.erase(iter.first); + if(IsClient()) { + AA::Rank *r = ability->GetRankByPointsSpent(iter.second.first); + if(r) { + CastToClient()->GetEPP().expended_aa += r->cost; + } + } + } + + if(IsClient()) { + Client *c = CastToClient(); + c->SaveAA(); + c->SendAlternateAdvancementPoints(); + } + } + + return; + } + } +} + bool ZoneDatabase::LoadAlternateAdvancement(Client *c) { c->ClearAAs(); std::string query = StringFormat( diff --git a/zone/bot.cpp b/zone/bot.cpp index c6c0f6e7f..1d8c16f57 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -9078,7 +9078,8 @@ void Bot::DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster) { Mob::DoBuffTic(buff, slot, caster); } -bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust) { +bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, + uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust, uint32 aa_id) { bool Result = false; if(zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) { @@ -9143,7 +9144,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_t bardsong_timer.Disable(); } - Result = DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot); + Result = DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, aa_id); } return Result; @@ -9305,7 +9306,7 @@ bool Bot::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce return Result; } -bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot) { +bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, uint32 aa_id) { bool Result = false; if(GetClass() == BARD) { @@ -9313,7 +9314,7 @@ bool Bot::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast cast_time = 0; } - Result = Mob::DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot); + Result = Mob::DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, aa_id); if(oSpellWillFinish) { const SPDat_Spell_Struct &spell = spells[spell_id]; diff --git a/zone/bot.h b/zone/bot.h index 1f1262ffc..4a88c5f18 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -314,11 +314,12 @@ public: virtual float GetAOERange(uint16 spell_id); virtual bool SpellEffect(Mob* caster, uint16 spell_id, float partial = 100); virtual void DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster = nullptr); - virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr); + virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, + uint32 item_slot = 0xFFFFFFFF, int16 *resist_adjust = nullptr, uint32 aa_id = 0); virtual bool SpellOnTarget(uint16 spell_id, Mob* spelltar); virtual bool IsImmuneToSpell(uint16 spell_id, Mob *caster); virtual bool DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_center, CastAction_type &CastAction); - virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF); + virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0); // Bot Action Command Methods bool MesmerizeTarget(Mob* target); diff --git a/zone/mob.cpp b/zone/mob.cpp index b107565bc..645b42325 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -309,6 +309,7 @@ Mob::Mob(const char* in_name, casting_spell_timer_duration = 0; casting_spell_type = 0; casting_spell_inventory_slot = 0; + casting_spell_aa_id = 0; target = 0; ActiveProjectileATK = false; diff --git a/zone/mob.h b/zone/mob.h index 08c6cd482..ed5d68c2c 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -222,10 +222,12 @@ public: virtual void SpellProcess(); virtual bool CastSpell(uint16 spell_id, uint16 target_id, uint16 slot = USE_ITEM_SPELL_SLOT, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, - uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 *resist_adjust = nullptr); + uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 *resist_adjust = nullptr, + uint32 aa_id = 0); virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot = 10, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, - uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 resist_adjust = 0); + uint32 timer = 0xFFFFFFFF, uint32 timer_duration = 0, uint32 type = 0, int16 resist_adjust = 0, + uint32 aa_id = 0); void CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, uint16 mana_used, uint32 inventory_slot = 0xFFFFFFFF, int16 resist_adjust = 0); bool SpellFinished(uint16 spell_id, Mob *target, uint16 slot = 10, uint16 mana_used = 0, @@ -963,6 +965,7 @@ public: bool CanUseAlternateAdvancementRank(AA::Rank *rank); bool CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price); int GetAlternateAdvancementCooldownReduction(AA::Rank *rank_in); + void ExpendAlternateAdvancementCharge(uint32 aa_id); protected: void CommonDamage(Mob* other, int32 &damage, const uint16 spell_id, const SkillUseTypes attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic); @@ -1152,6 +1155,7 @@ protected: uint32 casting_spell_timer_duration; uint32 casting_spell_type; int16 casting_spell_resist_adjust; + uint32 casting_spell_aa_id; bool casting_spell_checks; uint16 bardsong; uint8 bardsong_slot; diff --git a/zone/spells.cpp b/zone/spells.cpp index 4ef1337a7..ea4d1068b 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -146,7 +146,8 @@ void NPC::SpellProcess() // to allow procs to work bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, - uint32 timer, uint32 timer_duration, uint32 type, int16 *resist_adjust) + uint32 timer, uint32 timer_duration, uint32 type, int16 *resist_adjust, + uint32 aa_id) { Log.Out(Logs::Detail, Logs::Spells, "CastSpell called for spell %s (%d) on entity %d, slot %d, time %d, mana %d, from item slot %d", (IsValidSpell(spell_id))?spells[spell_id].name:"UNKNOWN SPELL", spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot); @@ -318,11 +319,11 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, if(resist_adjust) { - return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, *resist_adjust)); + return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, *resist_adjust, aa_id)); } else { - return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, spells[spell_id].ResistDiff)); + return(DoCastSpell(spell_id, target_id, slot, cast_time, mana_cost, oSpellWillFinish, item_slot, timer, timer_duration, type, spells[spell_id].ResistDiff, aa_id)); } } @@ -337,7 +338,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, uint16 slot, bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, int32 cast_time, int32 mana_cost, uint32* oSpellWillFinish, uint32 item_slot, uint32 timer, uint32 timer_duration, uint32 type, - int16 resist_adjust) + int16 resist_adjust, uint32 aa_id) { Mob* pMob = nullptr; int32 orgcasttime; @@ -361,6 +362,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot, casting_spell_timer = timer; casting_spell_timer_duration = timer_duration; } + casting_spell_aa_id = aa_id; casting_spell_type = type; SaveSpellLoc(); @@ -786,6 +788,7 @@ void Mob::ZeroCastingVars() casting_spell_type = 0; casting_spell_resist_adjust = 0; casting_spell_checks = false; + casting_spell_aa_id = 0; delaytimer = false; } @@ -2297,6 +2300,10 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16 Log.Out(Logs::Detail, Logs::Spells, "Spell %d: Setting long reuse timer to %d s (orig %d)", spell_id, recast, spells[spell_id].recast_time); CastToClient()->GetPTimers().Start(pTimerSpellStart + spell_id, recast); } + + if(casting_spell_aa_id) { + ExpendAlternateAdvancementCharge(casting_spell_aa_id); + } } if(IsClient() && ((slot == USE_ITEM_SPELL_SLOT) || (slot == POTION_BELT_SPELL_SLOT) || (slot == TARGET_RING_SPELL_SLOT)))