bool SkillManager::surrenderSkill(const String& skillName, CreatureObject* creature, bool notifyClient) { Skill* skill = skillMap.get(skillName.hashCode()); if (skill == NULL) return false; Locker locker(creature); SkillList* skillList = creature->getSkillList(); if(skillName == "force_title_jedi_novice" && getForceSensitiveSkillCount(creature, true) > 0) { return false; } if(skillName.beginsWith("force_sensitive_") && getForceSensitiveSkillCount(creature, false) <= 24 && creature->hasSkill("force_title_jedi_rank_01")) return false; for (int i = 0; i < skillList->size(); ++i) { Skill* checkSkill = skillList->get(i); if (checkSkill->isRequiredSkillOf(skill)) return false; } if(creature->hasSkill("force_title_jedi_rank_03") && skillName.contains("force_discipline_") && !knightPrereqsMet(creature, skillName)) { return false; } //If they have already surrendered the skill, then return true. if (!creature->hasSkill(skill->getSkillName())) return true; creature->removeSkill(skill, notifyClient); //Remove skill modifiers VectorMap<String, int>* skillModifiers = skill->getSkillModifiers(); ManagedReference<PlayerObject*> ghost = creature->getPlayerObject(); for (int i = 0; i < skillModifiers->size(); ++i) { VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i); creature->removeSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient); } if (ghost != NULL) { //Give the player the used skill points back. ghost->addSkillPoints(skill->getSkillPointsRequired()); //Remove abilities but only if the creature doesn't still have a skill that grants the //ability. Some abilities are granted by multiple skills. For example Dazzle for dancers //and musicians. Vector<String>* skillAbilities = skill->getAbilities(); if (skillAbilities->size() > 0) { SortedVector<String> abilitiesLost; for (int i = 0; i < skillAbilities->size(); i++) { abilitiesLost.put(skillAbilities->get(i)); } for (int i = 0; i < skillList->size(); i++) { Skill* remainingSkill = skillList->get(i); Vector<String>* remainingAbilities = remainingSkill->getAbilities(); for(int j = 0; j < remainingAbilities->size(); j++) { if (abilitiesLost.contains(remainingAbilities->get(j))) { abilitiesLost.drop(remainingAbilities->get(j)); if (abilitiesLost.size() == 0) { break; } } } } if (abilitiesLost.size() > 0) { removeAbilities(ghost, abilitiesLost, notifyClient); } } //Remove draft schematic groups Vector<String>* schematicsGranted = skill->getSchematicsGranted(); SchematicMap::instance()->removeSchematics(ghost, *schematicsGranted, notifyClient); //Update maximum experience. updateXpLimits(ghost); /// Update Force Power Max ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true); SkillList* list = creature->getSkillList(); int totalSkillPointsWasted = 250; for (int i = 0; i < list->size(); ++i) { Skill* skill = list->get(i); totalSkillPointsWasted -= skill->getSkillPointsRequired(); } if (ghost->getSkillPoints() != totalSkillPointsWasted) { creature->error("skill points mismatch calculated: " + String::valueOf(totalSkillPointsWasted) + " found: " + String::valueOf(ghost->getSkillPoints())); ghost->setSkillPoints(totalSkillPointsWasted); } ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager(); if (playerManager != NULL) { creature->setLevel(playerManager->calculatePlayerLevel(creature)); } } /// Update client with new values for things like Terrain Negotiation CreatureObjectDeltaMessage4* msg4 = new CreatureObjectDeltaMessage4(creature); msg4->updateAccelerationMultiplierBase(); msg4->updateAccelerationMultiplierMod(); msg4->updateSpeedMultiplierBase(); msg4->updateSpeedMultiplierMod(); msg4->updateRunSpeed(); msg4->updateTerrainNegotiation(); msg4->close(); creature->sendMessage(msg4); SkillModManager::instance()->verifySkillBoxSkillMods(creature); return true; }
bool SkillManager::awardSkill(const String& skillName, CreatureObject* creature, bool notifyClient, bool awardRequiredSkills, bool noXpRequired) { Skill* skill = skillMap.get(skillName.hashCode()); if (skill == NULL) return false; Locker locker(creature); //Check for required skills. Vector<String>* requiredSkills = skill->getSkillsRequired(); for (int i = 0; i < requiredSkills->size(); ++i) { String requiredSkillName = requiredSkills->get(i); Skill* requiredSkill = skillMap.get(requiredSkillName.hashCode()); if (requiredSkill == NULL) continue; if (awardRequiredSkills) awardSkill(requiredSkillName, creature, notifyClient, awardRequiredSkills, noXpRequired); if (!creature->hasSkill(requiredSkillName)) return false; } if (!canLearnSkill(skillName, creature, noXpRequired)) { return false; } //If they already have the skill, then return true. if (creature->hasSkill(skill->getSkillName())) return true; ManagedReference<PlayerObject*> ghost = creature->getPlayerObject(); if (ghost != NULL) { //Withdraw skill points. ghost->addSkillPoints(-skill->getSkillPointsRequired()); //Witdraw experience. if (!noXpRequired) { ghost->addExperience(skill->getXpType(), -skill->getXpCost(), true); } creature->addSkill(skill, notifyClient); //Add skill modifiers VectorMap<String, int>* skillModifiers = skill->getSkillModifiers(); for (int i = 0; i < skillModifiers->size(); ++i) { VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i); creature->addSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient); } //Add abilities Vector<String>* abilityNames = skill->getAbilities(); addAbilities(ghost, *abilityNames, notifyClient); if (skill->isGodOnly()) { for (int i = 0; i < abilityNames->size(); ++i) { String ability = abilityNames->get(i); StringIdChatParameter params; params.setTU(ability); params.setStringId("ui", "skill_command_acquired_prose"); creature->sendSystemMessage(params); } } //Add draft schematic groups Vector<String>* schematicsGranted = skill->getSchematicsGranted(); SchematicMap::instance()->addSchematics(ghost, *schematicsGranted, notifyClient); //Update maximum experience. updateXpLimits(ghost); // Update Force Power Max. ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true); if (skillName.contains("master")) { ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager(); if (playerManager != NULL) { const Badge* badge = BadgeList::instance()->get(skillName); if (badge == NULL && skillName == "crafting_shipwright_master") { badge = BadgeList::instance()->get("crafting_shipwright"); } if (badge != NULL) { playerManager->awardBadge(ghost, badge); } } } SkillList* list = creature->getSkillList(); int totalSkillPointsWasted = 250; for (int i = 0; i < list->size(); ++i) { Skill* skill = list->get(i); totalSkillPointsWasted -= skill->getSkillPointsRequired(); } if (ghost->getSkillPoints() != totalSkillPointsWasted) { creature->error("skill points mismatch calculated: " + String::valueOf(totalSkillPointsWasted) + " found: " + String::valueOf(ghost->getSkillPoints())); ghost->setSkillPoints(totalSkillPointsWasted); } ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager(); if (playerManager != NULL) { creature->setLevel(playerManager->calculatePlayerLevel(creature)); } } /// Update client with new values for things like Terrain Negotiation CreatureObjectDeltaMessage4* msg4 = new CreatureObjectDeltaMessage4(creature); msg4->updateAccelerationMultiplierBase(); msg4->updateAccelerationMultiplierMod(); msg4->updateSpeedMultiplierBase(); msg4->updateSpeedMultiplierMod(); msg4->updateRunSpeed(); msg4->updateTerrainNegotiation(); msg4->close(); creature->sendMessage(msg4); SkillModManager::instance()->verifySkillBoxSkillMods(creature); return true; }