Added support for mark >1 expertise abilities

This commit is contained in:
Mads Boddum
2016-10-28 16:28:34 +02:00
parent c0677c1472
commit a89f47d306
2 changed files with 130 additions and 10 deletions

View File

@@ -0,0 +1,50 @@
skill chains
TEXT PRIMARY KEY TEXT
expertise_bh_armor_duelist_1 bh_armor_duelist_2;bh_armor_duelist_3;bh_armor_duelist_4;bh_armor_duelist_5
expertise_bh_intimidate_1 bh_intimidate_2;bh_intimidate_3;bh_intimidate_4;bh_intimidate_5;bh_intimidate_6
expertise_bh_sniper_1 bh_sniper_2;bh_sniper_3;bh_sniper_4;bh_sniper_5;bh_sniper_6
expertise_bh_stun_1 bh_stun_2;bh_stun_3;bh_stun_4;bh_stun_5
expertise_bh_surprise_1 bh_dm_crit_3;bh_dm_crit_4;bh_dm_crit_5;bh_dm_crit_6;bh_dm_crit_7;bh_dm_crit_8
expertise_bh_taunt_1 bh_taunt_2;bh_taunt_3;bh_taunt_4;bh_taunt_5;bh_taunt_6
expertise_co_focus_beam_1 co_hw_dm_2;co_hw_dm_3;co_hw_dm_4;co_hw_dm_5;co_hw_dm_6
expertise_co_lethal_beam_1 co_hw_dm_crit_2;co_hw_dm_crit_3;co_hw_dm_crit_4;co_hw_dm_crit_5;co_hw_dm_crit_6
expertise_en_heal_1 en_heal_2;en_heal_3;en_heal_4
expertise_en_project_will_1 en_project_will_1;en_project_will_2;en_project_will_3;en_project_will_4;en_project_will_5;en_project_will_6
expertise_en_spiral_kick_1 en_spiral_kick_1;en_spiral_kick_2;en_spiral_kick_3;en_spiral_kick_4
expertise_en_strike_1 en_strike_1;en_strike_2;en_strike_3;en_strike_4;en_strike_5;en_strike_6
expertise_en_sweeping_pirouette_1 en_sweeping_pirouette_1;en_sweeping_pirouette_2;en_sweeping_pirouette_3;en_sweeping_pirouette_4;en_sweeping_pirouette_5
expertise_en_thrill_1 en_thrill_1;en_thrill_2
expertise_en_void_dance_1 en_void_dance_2;en_void_dance_3
expertise_fs_general_force_shockwave_1 fs_dm_cc_crit_2;fs_dm_cc_crit_3;fs_dm_cc_crit_4;fs_dm_cc_crit_5
expertise_fs_path_dark_lightning_1 fs_ae_dm_cc_2;fs_ae_dm_cc_3;fs_ae_dm_cc_4;fs_ae_dm_cc_5;fs_ae_dm_cc_6
expertise_fs_path_flurry fs_flurry_2;fs_flurry_3;fs_flurry_4;fs_flurry_5;fs_flurry_6;fs_flurry_7
expertise_fs_path_force_choke_1 fs_dm_cc_2;fs_dm_cc_3;fs_dm_cc_4;fs_dm_cc_5;fs_dm_cc_6
expertise_fs_path_force_drain_1 fs_drain_2;fs_drain_3;fs_drain_4;fs_drain_5
expertise_fs_path_maelstrom_1 fs_maelstrom_2;fs_maelstrom_3;fs_maelstrom_4;fs_maelstrom_5
expertise_me_bacta_bomb_1 me_bacta_bomb_2;me_bacta_bomb_3;me_bacta_bomb_4;me_bacta_bomb_5
expertise_me_bacta_grenade_1 me_bacta_grenade_2;me_bacta_grenade_3;me_bacta_grenade_4;me_bacta_grenade_5
expertise_me_burst_1 me_burst_2;me_burst_3;me_burst_4;me_burst_5
expertise_me_cranial_smash_1 me_cranial_smash_2;me_cranial_smash_3;me_cranial_smash_4;me_cranial_smash_5
expertise_me_enhance_agility_1 me_enhance_agility_2;me_enhance_agility_3
expertise_me_enhance_precision_1 me_enhance_precision_2;me_enhance_precision_3
expertise_me_enhance_strength_1 me_enhance_strength_2;me_enhance_strength_3
expertise_me_enhancement_specialist_1 me_enhance_action_2;me_enhance_action_3|me_buff_health_2;me_buff_health_3
expertise_of_advanced_paint_1 of_deb_def_4;of_deb_def_5;of_deb_def_6;of_deb_def_7;of_deb_def_8
expertise_of_advanced_tactics_1 of_buff_def_4;of_buff_def_5;of_buff_def_6;of_buff_def_7;of_buff_def_8;of_buff_def_9
expertise_of_decapitate_1 of_decapitate_2;of_decapitate_3;of_decapitate_4;of_decapitate_5;of_decapitate_6
expertise_of_focus_fire_1 of_focus_fire_2;of_focus_fire_3;of_focus_fire_4;of_focus_fire_5;of_focus_fire_6
expertise_of_inspiration_1 of_inspiration_2;of_inspiration_3;of_inspiration_4;of_inspiration_5;of_inspiration_6
expertise_of_leg_strike_1 of_leg_strike_2;of_leg_strike_3;of_leg_strike_4;of_leg_strike_5;of_leg_strike_6;of_leg_strike_7
expertise_of_medical_sup_1 of_medical_sup_2;of_medical_sup_3;of_medical_sup_4;of_medical_sup_5;of_medical_sup_6
expertise_of_reinforcements_1 of_reinforcements_2;of_reinforcements_3;of_reinforcements_4;of_reinforcements_5
expertise_of_vortex_1 of_vortex_2;of_vortex_3;of_vortex_4;of_vortex_5
expertise_sm_general_bad_odds_1 sm_bad_odds_2;sm_bad_odds_3;sm_bad_odds_4;sm_bad_odds_5
expertise_sm_general_narrow_escape_1 sm_narrow_escape_2;sm_narrow_escape_3;sm_narrow_escape_4
expertise_sm_general_spot_a_sucker_1 sm_spot_a_sucker_2;sm_spot_a_sucker_3;sm_spot_a_sucker_4
expertise_sm_path_pistol_whip_1 sm_pistol_whip_2;sm_pistol_whip_3;sm_pistol_whip_4
expertise_sm_path_shoot_first_1 sm_shoot_first_2;sm_shoot_first_3;sm_shoot_first_4;sm_shoot_first_5
expertise_sp_cloaked_attacks_1 sp_stealth_melee_1;sp_stealth_melee_2;sp_stealth_melee_3;sp_stealth_melee_4;sp_stealth_melee_5;sp_stealth_melee_6|sp_stealth_melee_1;sp_stealth_ranged_2;sp_stealth_ranged_3;sp_stealth_ranged_4;sp_stealth_ranged_5;sp_stealth_ranged_6
expertise_sp_cloaked_recovery_1 sp_cloaked_recovery_1;sp_cloaked_recovery_2;sp_cloaked_recovery_3;sp_cloaked_recovery_4
expertise_sp_hidden_daggers_1 sp_hd_melee_1;sp_hd_melee_2;sp_hd_melee_3;sp_hd_melee_4;sp_hd_melee_5;sp_hd_melee_6|sp_hd_ranged_1;sp_hd_ranged_2;sp_hd_ranged_3;sp_hd_ranged_4;sp_hd_ranged_5;sp_hd_ranged_6
expertise_sp_improved_arachnids_web_1 sp_improved_cc_dot_2;sp_improved_cc_dot_3;sp_improved_cc_dot_4
expertise_sp_improved_spys_fang_1 sp_dot_1;sp_dot_2;sp_dot_3;sp_dot_4;sp_dot_5

View File

@@ -30,10 +30,17 @@ package services.experience;
import intents.experience.GrantSkillIntent;
import intents.experience.LevelChangedIntent;
import intents.network.GalacticPacketIntent;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import network.packets.Packet;
import network.packets.swg.zone.ExpertiseRequestMessage;
import resources.Location;
import resources.client_info.ClientFactory;
import resources.client_info.visitors.DatatableData;
import resources.control.Intent;
@@ -42,6 +49,8 @@ import resources.objects.creature.CreatureObject;
import resources.objects.player.PlayerObject;
import resources.player.Player;
import resources.server_info.Log;
import resources.server_info.RelationalDatabase;
import resources.server_info.RelationalServerFactory;
/**
*
@@ -49,13 +58,17 @@ import resources.server_info.Log;
*/
public final class ExpertiseService extends Service {
private static final String EXPERTISE_ABILITIES_QUERY = "SELECT * FROM expertise_abilities";
private final Map<String, Integer> expertiseSkills; // Expertise skill to tree ID
private final Map<Integer, Map<String, Expertise>> trees; // Tree ID to tree
private final Map<String, Collection<String[]>> expertiseAbilities; // Expertise skill to abilities
private final Map<Integer, Integer> pointsForLevel; // Level to points available
public ExpertiseService() {
trees = new HashMap<>();
expertiseSkills = new HashMap<>();
expertiseAbilities = new HashMap<>();
pointsForLevel = new HashMap<>();
registerForIntent(GalacticPacketIntent.TYPE);
@@ -75,7 +88,7 @@ public final class ExpertiseService extends Service {
public boolean initialize() {
loadTrees();
loadPointsForLevel();
return super.initialize() && loadExpertise();
return super.initialize() && loadExpertise() && loadAbilities();
}
private void loadTrees() {
@@ -122,6 +135,40 @@ public final class ExpertiseService extends Service {
return true;
}
private boolean loadAbilities() {
Log.i(this, "Loading expertise abilities...");
long startTime = System.nanoTime();
int abilityCount = 0;
try (RelationalDatabase abilityDatabase = RelationalServerFactory.getServerData("player/expertise_abilities.db", "expertise_abilities")) {
try (ResultSet set = abilityDatabase.executeQuery(EXPERTISE_ABILITIES_QUERY)) {
while (set.next()) {
String skill = set.getString("skill");
String[] chains = set.getString("chains").split("\\|");
Collection<String[]> abilityChains = new ArrayList<>();
for (int i = 0; i < chains.length; i++) {
String chain = chains[i];
String[] abilities = chain.split(";");
abilityChains.add(abilities);
abilityCount += abilities.length;
}
expertiseAbilities.put(skill, abilityChains);
}
} catch (SQLException e) {
Log.e(this, e);
return false;
}
}
Log.i(this, "Finished loading %d expertise abilities in %fms", abilityCount, (System.nanoTime() - startTime) / 1E6);
return true;
}
private void loadPointsForLevel() {
DatatableData playerLevelTable = (DatatableData) ClientFactory.getInfoFromFile("datatables/player/player_level.iff", false);
int points = 0;
@@ -169,7 +216,6 @@ public final class ExpertiseService extends Service {
continue;
}
// TODO below actually works, but the GrantSkillIntent from the previous iteration hasn't necessarily been processed yet! This can cause the check below to fail
int requiredTreePoints = (expertise.getTier() - 1) * 4;
if (requiredTreePoints > getPointsInTree(tree, creatureObject)) {
@@ -181,6 +227,8 @@ public final class ExpertiseService extends Service {
intent.broadcast();
while(!intent.isComplete()); // Block until the GrantSkillIntent has been processed
}
checkExtraAbilities(creatureObject);
}
private void handleLevelChangedIntent(LevelChangedIntent i) {
@@ -192,23 +240,45 @@ public final class ExpertiseService extends Service {
creatureObject.addSkill("expertise");
}
grantExtraAbilities(creatureObject);
checkExtraAbilities(creatureObject);
}
private void handleGrantSkillIntent(GrantSkillIntent i) {
if (i.getIntentType() != GrantSkillIntent.IntentType.GIVEN) {
if (i.getIntentType() == GrantSkillIntent.IntentType.GIVEN) {
return;
}
grantExtraAbilities(i.getTarget());
// Let's check if this is an expertise skill that gives them additional commands
checkExtraAbilities(i.getTarget());
}
private void grantExtraAbilities(CreatureObject creatureObject) {
// based on their level, they may have unlocked new marks of the abilities given by this expertise skill
// TODO We need to grant ability commands if they have the correct skill. Algorithm if possible, SDB otherwise
private void checkExtraAbilities(CreatureObject creatureObject) {
creatureObject.getSkills().stream()
.filter(expertiseAbilities::containsKey) // We only want to check skills that give additional abilities
.forEach(expertise -> grantExtraAbilities(creatureObject, expertise));
}
private boolean isQualified(CreatureObject creatureObject, int abilityIndex) {
int baseRequirement = 18;
int levelDifference = 12; // Amount of levels between each ability
int level = creatureObject.getLevel();
int requiredLevel = baseRequirement + abilityIndex * levelDifference;
// Loop over expertise skills
// For each expertise skill, check if this level unlocks ability marks
// TODO what if requiredLevel goes above the maximum level possible for a player?
System.out.println("required level: " + requiredLevel);
return level >= requiredLevel;
}
private void grantExtraAbilities(CreatureObject creatureObject, String expertise) {
expertiseAbilities.get(expertise).forEach(chain -> {
for (int abilityIndex = 1; abilityIndex <= chain.length; abilityIndex++) {
String ability = chain[abilityIndex - 1];
if (isQualified(creatureObject, abilityIndex) && !creatureObject.hasAbility(ability)) {
creatureObject.addAbility(ability);
}
}
});
}
private String formatProfession(String profession) {