void CheckSpellLevels(CCharEntity* PChar) { uint8 level = 0; if (PChar->GetMJob() == JOB_BLU) { level = PChar->GetMLevel(); } else if (PChar->GetSJob() == JOB_BLU) { level = PChar->GetSLevel(); } if (level != 0) { for (int slot = 0; slot < 20; slot++) { if (PChar->m_SetBlueSpells[slot] != 0) { CBlueSpell* PSpell = (CBlueSpell*)spell::GetSpell(PChar->m_SetBlueSpells[slot] + 0x200); if (PSpell && level < PSpell->getJob(JOB_BLU)) { SetBlueSpell(PChar, PSpell, slot, false); } } } } }
void ValidateBlueSpells(CCharEntity* PChar) { CheckSpellLevels(PChar); uint8 maxSetPoints = GetTotalBlueMagicPoints(PChar); uint8 currentPoints = 0; for (int slot = 0; slot < 20; slot++) { if (PChar->m_SetBlueSpells[slot] != 0) { CBlueSpell* PSpell = (CBlueSpell*)spell::GetSpell(PChar->m_SetBlueSpells[slot] + 0x200); if (currentPoints + PSpell->getSetPoints() > maxSetPoints) { SetBlueSpell(PChar, PSpell, slot, false); } else { currentPoints += PSpell->getSetPoints(); } } } CompactSpells(PChar); uint8 maxSlots = GetTotalSlots(PChar); for (int slot = maxSlots; slot < 20; slot++) { if (PChar->m_SetBlueSpells[slot] != 0) { SetBlueSpell(PChar, (CBlueSpell*)spell::GetSpell(PChar->m_SetBlueSpells[slot] + 0x200), slot, false); } } SaveSetSpells(PChar); PChar->status = STATUS_UPDATE; charutils::BuildingCharTraitsTable(PChar); PChar->pushPacket(new CCharJobExtraPacket(PChar, true)); PChar->pushPacket(new CCharJobExtraPacket(PChar, false)); PChar->pushPacket(new CCharStatsPacket(PChar)); charutils::CalculateStats(PChar); PChar->UpdateHealth(); PChar->pushPacket(new CCharHealthPacket(PChar)); }
void ValidateBlueSpells(CCharEntity* PChar) { CheckSpellLevels(PChar); uint8 maxSetPoints = GetTotalBlueMagicPoints(PChar); uint8 currentPoints = 0; for (int slot = 0; slot < 20; slot++) { if (PChar->m_SetBlueSpells[slot] != 0) { CBlueSpell* PSpell = (CBlueSpell*)spell::GetSpell(static_cast<SpellID>(PChar->m_SetBlueSpells[slot] + 0x200)); if (currentPoints + PSpell->getSetPoints() > maxSetPoints) { SetBlueSpell(PChar, PSpell, slot, false); } else { currentPoints += PSpell->getSetPoints(); } } } CompactSpells(PChar); uint8 maxSlots = GetTotalSlots(PChar); for (int slot = maxSlots; slot < 20; slot++) { if (PChar->m_SetBlueSpells[slot] != 0) { SetBlueSpell(PChar, (CBlueSpell*)spell::GetSpell(static_cast<SpellID>(PChar->m_SetBlueSpells[slot] + 0x200)), slot, false); } } SaveSetSpells(PChar); }
bool HasEnoughSetPoints(CCharEntity* PChar, CBlueSpell* PSpellToAdd, uint8 slotToPut) { uint8 setpoints = 0; for (int slot = 0; slot < 20; slot++) { if (slot != slotToPut && PChar->m_SetBlueSpells[slot] != 0) { CBlueSpell* setSpell = (CBlueSpell*)spell::GetSpell(PChar->m_SetBlueSpells[slot] + 0x200); if (setSpell) { setpoints += setSpell->getSetPoints(); } } } if (setpoints + PSpellToAdd->getSetPoints() <= GetTotalBlueMagicPoints(PChar)) { return true; } else { return false; } }
void CalculateTraits(CCharEntity* PChar) { TraitList_t* PTraitsList = traits::GetTraits(JOB_BLU); std::map<uint8, uint8> points; for (int slot = 0; slot < 20; slot++) { if (PChar->m_SetBlueSpells[slot] != 0) { CBlueSpell* PSpell = (CBlueSpell*)spell::GetSpell(PChar->m_SetBlueSpells[slot] + 0x200); if (PSpell) { uint8 category = PSpell->getTraitCategory(); uint8 weight = PSpell->getTraitWeight(); std::map<uint8, uint8>::iterator iter = points.find(category); if (iter != points.end()) { iter->second += iter->second + weight; } else { points.insert(std::make_pair(category, weight)); } } } } for (std::map<uint8, uint8>::iterator iter = points.begin(); iter != points.end(); iter++) { uint8 category = iter->first; uint8 totalWeight = iter->second; for (uint8 i = 0; i < PTraitsList->size(); ++i) { if (PTraitsList->at(i)->getLevel() == 0) { CBlueTrait* PTrait = (CBlueTrait*)PTraitsList->at(i); if (PTrait && PTrait->getCategory() == category) { bool add = true; for (uint8 j = 0; j < PChar->TraitList.size(); ++j) { CTrait* PExistingTrait = PChar->TraitList.at(j); if (PExistingTrait->getID() == PTrait->getID()) { if (PExistingTrait->getLevel() == 0 && ((CBlueTrait*)PExistingTrait)->getCategory() == PTrait->getCategory()) { add = false; break; } if (PExistingTrait->getRank() < PTrait->getRank()) { PChar->delModifier(PExistingTrait->getMod(), PExistingTrait->getValue()); charutils::delTrait(PChar, PExistingTrait->getID()); PChar->TraitList.erase(PChar->TraitList.begin()+j); break; } else if (PExistingTrait->getRank() > PTrait->getRank()) { add = false; break; } else { if (PExistingTrait->getMod() == PTrait->getMod()) { add = false; break; } } } } if (totalWeight >= PTrait->getPoints() && add) { charutils::addTrait(PChar, PTrait->getID()); PChar->TraitList.push_back(PTrait); PChar->addModifier(PTrait->getMod(), PTrait->getValue()); break; } } } } } }
bool CAutomatonController::TryTPMove() { if (PAutomaton->health.tp >= 1000) { const auto& FamilySkills = battleutils::GetMobSkillList(PAutomaton->m_Family); std::vector<CMobSkill*> validSkills; //load the skills that the automaton has access to with it's skill SKILLTYPE skilltype = SKILL_AME; if (PAutomaton->getFrame() == FRAME_SHARPSHOT) skilltype = SKILL_ARA; for (auto skillid : FamilySkills) { auto PSkill = battleutils::GetMobSkill(skillid); if (PSkill && PAutomaton->GetSkill(skilltype) > PSkill->getParam() && PSkill->getParam() != -1 && distance(PAutomaton->loc.p, PTarget->loc.p) < PSkill->getRadius()) { validSkills.push_back(PSkill); } } int16 currentSkill = -1; CMobSkill* PWSkill = nullptr; int8 currentManeuvers = -1; bool attemptChain = (PAutomaton->getMod(Mod::AUTO_TP_EFFICIENCY) != 0); if (attemptChain) { CStatusEffect* PSCEffect = PTarget->StatusEffectContainer->GetStatusEffect(EFFECT_SKILLCHAIN, 0); if (PSCEffect) { std::list<SKILLCHAIN_ELEMENT> resonanceProperties; if (PSCEffect->GetTier() == 0) { if (PSCEffect->GetStartTime() + 3s < m_Tick) { if (PSCEffect->GetPower()) { CWeaponSkill* PWeaponSkill = battleutils::GetWeaponSkill(PSCEffect->GetPower()); resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PWeaponSkill->getPrimarySkillchain()); resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PWeaponSkill->getSecondarySkillchain()); resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PWeaponSkill->getTertiarySkillchain()); } else { CBlueSpell* oldSpell = (CBlueSpell*)spell::GetSpell(static_cast<SpellID>(PSCEffect->GetSubPower())); resonanceProperties.push_back((SKILLCHAIN_ELEMENT)oldSpell->getPrimarySkillchain()); resonanceProperties.push_back((SKILLCHAIN_ELEMENT)oldSpell->getSecondarySkillchain()); } } } else { resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PSCEffect->GetPower()); } for (auto PSkill : validSkills) { if (PSkill->getParam() > currentSkill) { std::list<SKILLCHAIN_ELEMENT> skillProperties; skillProperties.push_back((SKILLCHAIN_ELEMENT)PSkill->getPrimarySkillchain()); skillProperties.push_back((SKILLCHAIN_ELEMENT)PSkill->getSecondarySkillchain()); skillProperties.push_back((SKILLCHAIN_ELEMENT)PSkill->getTertiarySkillchain()); if (battleutils::FormSkillchain(resonanceProperties, skillProperties) != SC_NONE) { currentManeuvers = 1; currentSkill = PSkill->getParam(); PWSkill = PSkill; } } } } } if (!attemptChain || (currentManeuvers == -1 && PAutomaton->PMaster && PAutomaton->PMaster->health.tp < PAutomaton->getMod(Mod::AUTO_TP_EFFICIENCY))) { for (auto PSkill : validSkills) { int8 maneuvers = luautils::OnMobAutomatonSkillCheck(PTarget, PAutomaton, PSkill); if (maneuvers > -1 && (maneuvers > currentManeuvers || (maneuvers == currentManeuvers && PSkill->getParam() > currentSkill))) { currentManeuvers = maneuvers; currentSkill = PSkill->getParam(); PWSkill = PSkill; } } } // No WS was chosen (waiting on master's TP to skillchain probably) if (currentManeuvers == -1) return false; if (PWSkill) return MobSkill(PTarget->targid, PWSkill->getID()); } return false; }