mirror of
https://bitbucket.org/projectswg/cucore.git
synced 2026-01-16 23:04:20 -05:00
Added support for mark >1 expertise abilities
This commit is contained in:
50
serverdata/player/expertise_abilities.sdb
Normal file
50
serverdata/player/expertise_abilities.sdb
Normal 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
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user