mirror of
https://bitbucket.org/projectswg/holocore.git
synced 2026-01-16 23:04:20 -05:00
Added expertise and skill loaders
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,8 +1,10 @@
|
||||
.settings
|
||||
scripts/
|
||||
|
||||
# IDE-based
|
||||
Holocore.iml
|
||||
out
|
||||
classes/
|
||||
.idea
|
||||
.classpath
|
||||
.project
|
||||
@@ -10,6 +12,7 @@ out
|
||||
# Gradle
|
||||
build
|
||||
.gradle
|
||||
gradle.properties
|
||||
|
||||
# Holocore
|
||||
/clientdata/
|
||||
|
||||
Submodule pswgcommon updated: 9f0e9fd4fa...c2c2bf76c1
1091
serverdata/expertise/expertise.sdb
Normal file
1091
serverdata/expertise/expertise.sdb
Normal file
File diff suppressed because it is too large
Load Diff
33
serverdata/expertise/expertise_trees.sdb
Normal file
33
serverdata/expertise/expertise_trees.sdb
Normal file
@@ -0,0 +1,33 @@
|
||||
expertise_tree_id expertise_tree_string_id ui_background_id
|
||||
INTEGER STRING STRING
|
||||
1 expertise_tree_bh_general left
|
||||
2 expertise_tree_bh_path left_bounty_hunter
|
||||
3 expertise_tree_bh_warfare
|
||||
4 expertise_tree_fs_general left
|
||||
5 expertise_tree_fs_path left_jedi
|
||||
6 expertise_tree_fs_warfare
|
||||
7 expertise_tree_sm_general left
|
||||
8 expertise_tree_sm_path left_smuggler
|
||||
9 expertise_tree_sm_warfare
|
||||
10 expertise_tree_of_general left
|
||||
11 expertise_tree_of_path left_officer
|
||||
12 expertise_tree_of_warfare
|
||||
13 expertise_tree_co_path left_commando
|
||||
14 expertise_tree_co_general left
|
||||
15 expertise_tree_co_warfare
|
||||
16 expertise_tree_me_general left
|
||||
17 expertise_tree_me_path left_medic
|
||||
18 expertise_tree_me_warfare
|
||||
19 expertise_tree_sp_general left
|
||||
20 expertise_tree_sp_path left_spy
|
||||
21 expertise_tree_sp_warfare
|
||||
22 expertise_tree_en_general left
|
||||
23 expertise_tree_en_path left_entertainer
|
||||
24 expertise_tree_en_warfare
|
||||
25 expertise_tree_trader_domestic left_trader
|
||||
26 expertise_tree_trader_structure left_trader
|
||||
27 expertise_tree_trader_munition left_trader
|
||||
28 expertise_tree_trader_engineer left_trader
|
||||
29 expertise_tree_trader_general left
|
||||
30 expertise_tree_beastmaster left_beastmaster
|
||||
99 expertise_tree_test
|
||||
92
serverdata/player/player_level.sdb
Normal file
92
serverdata/player/player_level.sdb
Normal file
@@ -0,0 +1,92 @@
|
||||
level xp_required xp_type xp_multiplier health_granted expertise_points
|
||||
INTEGER INTEGER STRING INTEGER INTEGER INTEGER
|
||||
1 0 combat_meleespecialize_unarmed 1 0 0
|
||||
2 500 combat_meleespecialize_onehand 1 50 0
|
||||
3 1700 combat_meleespecialize_twohand 1 75 0
|
||||
4 3800 combat_meleespecialize_polearm 1 100 0
|
||||
5 6900 combat_rangedspecialize_rifle 1 125 0
|
||||
6 11000 combat_rangedspecialize_pistol 1 150 0
|
||||
7 16200 combat_rangedspecialize_carbine 1 175 0
|
||||
8 22600 combat_rangedspecialize_heavy 1 200 0
|
||||
9 30300 bountyhunter 35 225 0
|
||||
10 39400 jedi_general 1 250 5
|
||||
11 50000 crafting_medicine_general 1 275 0
|
||||
12 62200 combat_general 1 300 6
|
||||
13 76000 medical 1 325 0
|
||||
14 91500 creaturehandler 1 350 7
|
||||
15 108800 trapping 1 375 0
|
||||
16 128000 scout 1 390 8
|
||||
17 149200 entertainer 1 405 0
|
||||
18 172500 crafting 1 420 9
|
||||
19 198000 0 435 0
|
||||
20 225800 0 450 10
|
||||
21 256000 0 465 0
|
||||
22 288700 0 480 11
|
||||
23 324000 0 495 0
|
||||
24 362000 0 510 12
|
||||
25 402800 0 525 0
|
||||
26 446500 0 540 13
|
||||
27 493200 0 555 0
|
||||
28 543000 0 570 14
|
||||
29 596000 0 585 0
|
||||
30 652300 0 600 15
|
||||
31 712100 0 615 0
|
||||
32 775500 0 630 16
|
||||
33 842600 0 645 0
|
||||
34 913600 0 660 17
|
||||
35 988600 0 675 0
|
||||
36 1067800 0 690 18
|
||||
37 1151300 0 705 0
|
||||
38 1239300 0 720 19
|
||||
39 1331900 0 735 0
|
||||
40 1429300 0 750 20
|
||||
41 1531600 0 765 0
|
||||
42 1639000 0 780 21
|
||||
43 1751700 0 795 0
|
||||
44 1869900 0 810 22
|
||||
45 1993800 0 825 0
|
||||
46 2123600 0 840 23
|
||||
47 2259500 0 855 0
|
||||
48 2401700 0 870 24
|
||||
49 2550400 0 885 0
|
||||
50 2705800 0 900 25
|
||||
51 2868100 0 915 0
|
||||
52 3037600 0 930 26
|
||||
53 3214500 0 945 0
|
||||
54 3399000 0 960 27
|
||||
55 3591400 0 1000 0
|
||||
56 3792000 0 1040 28
|
||||
57 4001000 0 1080 0
|
||||
58 4218700 0 1120 29
|
||||
59 4445400 0 1160 0
|
||||
60 4681400 0 1200 30
|
||||
61 4927000 0 1240 0
|
||||
62 5182500 0 1280 31
|
||||
63 5448300 0 1320 0
|
||||
64 5724700 0 1360 32
|
||||
65 6012100 0 1400 0
|
||||
66 6310800 0 1440 33
|
||||
67 6621200 0 1480 0
|
||||
68 6943700 0 1520 34
|
||||
69 7278700 0 1560 0
|
||||
70 7626600 0 1600 35
|
||||
71 7987800 0 1640 0
|
||||
72 8362800 0 1680 36
|
||||
73 8752000 0 1720 0
|
||||
74 9155900 0 1760 37
|
||||
75 9575000 0 1800 0
|
||||
76 10009800 0 1840 38
|
||||
77 10460800 0 1880 0
|
||||
78 10928500 0 1920 39
|
||||
79 11413500 0 1960 0
|
||||
80 11916400 0 2000 40
|
||||
81 12437700 0 2000 0
|
||||
82 12978100 0 2000 41
|
||||
83 13538200 0 2000 0
|
||||
84 14118600 0 2000 42
|
||||
85 14720000 0 2000 0
|
||||
86 15343100 0 2000 43
|
||||
87 15988600 0 2000 0
|
||||
88 16657200 0 2000 44
|
||||
89 17349700 0 2000 0
|
||||
90 18066900 0 2000 45
|
||||
2793
serverdata/skill/skills.sdb
Normal file
2793
serverdata/skill/skills.sdb
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.intents.gameplay.player.experience.expertise;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.ExpertiseLoader.ExpertiseInfo;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
import me.joshlarson.jlcommon.control.Intent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class RequestExpertiseIntent extends Intent {
|
||||
|
||||
private final @NotNull CreatureObject creature;
|
||||
private final @NotNull List<@NotNull ExpertiseInfo> expertise;
|
||||
|
||||
public RequestExpertiseIntent(@NotNull CreatureObject creature, @NotNull List<@NotNull ExpertiseInfo> expertise) {
|
||||
this.creature = creature;
|
||||
this.expertise = Collections.unmodifiableList(expertise);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CreatureObject getCreature() {
|
||||
return creature;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<@NotNull ExpertiseInfo> getExpertise() {
|
||||
return expertise;
|
||||
}
|
||||
|
||||
public static void broadcast(@NotNull CreatureObject creature, @NotNull List<@NotNull ExpertiseInfo> expertise) {
|
||||
new RequestExpertiseIntent(creature, expertise).broadcast();
|
||||
}
|
||||
|
||||
public static void broadcast(@NotNull CreatureObject creature, @NotNull ExpertiseInfo expertise) {
|
||||
new RequestExpertiseIntent(creature, List.of(expertise)).broadcast();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,13 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
enum CachedLoader {
|
||||
// Player
|
||||
BUFFS (BuffLoader::new),
|
||||
EXPERTISE (ExpertiseLoader::new),
|
||||
EXPERTISE_TREES (ExpertiseTreeLoader::new),
|
||||
SKILLS (SkillLoader::new),
|
||||
PLAYER_LEVELS (PlayerLevelLoader::new),
|
||||
// Other
|
||||
BUILDING_CELLS (BuildingCellLoader::new),
|
||||
NPC_LOADER (NpcLoader::new),
|
||||
NPC_COMBAT_PROFILES (NpcCombatProfileLoader::new),
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class CollectionLoader extends DataLoader {
|
||||
|
||||
CollectionLoader() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/collection/collection.sdb"))) {
|
||||
while (set.next()) {
|
||||
CollectionInfo collection = new CollectionInfo(set);
|
||||
// TODO: Store information
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CollectionInfo {
|
||||
|
||||
private final String bookName;
|
||||
private final String pageName;
|
||||
private final String collectionName;
|
||||
private final String slotName;
|
||||
private final int beginSlotId;
|
||||
private final int endSlotId;
|
||||
private final int maxSlotValue;
|
||||
private final String category1;
|
||||
private final String category2;
|
||||
private final String category3;
|
||||
private final String category4;
|
||||
private final String category5;
|
||||
private final String category6;
|
||||
private final String category7;
|
||||
private final String category8;
|
||||
private final String category9;
|
||||
private final String category10;
|
||||
private final String category11;
|
||||
private final String prereqSlotName1;
|
||||
private final String prereqSlotName2;
|
||||
private final String prereqSlotName3;
|
||||
private final String prereqSlotName4;
|
||||
private final String prereqSlotName5;
|
||||
private final String icon;
|
||||
private final String music;
|
||||
private final String showIfNotYetEarned;
|
||||
private final boolean hidden;
|
||||
private final boolean title;
|
||||
private final String alternateTitle1;
|
||||
private final String alternateTitle2;
|
||||
private final String alternateTitle3;
|
||||
private final String alternateTitle4;
|
||||
private final String alternateTitle5;
|
||||
private final boolean noReward;
|
||||
private final boolean trackServerFirst;
|
||||
|
||||
public CollectionInfo(SdbResultSet set) {
|
||||
this.bookName = set.getText("book_name");
|
||||
this.pageName = set.getText("page_name");
|
||||
this.collectionName = set.getText("collection_name");
|
||||
this.slotName = set.getText("slot_name");
|
||||
this.beginSlotId = (int) set.getInt("begin_slot_id");
|
||||
this.endSlotId = (int) set.getInt("end_slot_id");
|
||||
this.maxSlotValue = (int) set.getInt("max_slot_value");
|
||||
this.category1 = set.getText("category1");
|
||||
this.category2 = set.getText("category2");
|
||||
this.category3 = set.getText("category3");
|
||||
this.category4 = set.getText("category4");
|
||||
this.category5 = set.getText("category5");
|
||||
this.category6 = set.getText("category6");
|
||||
this.category7 = set.getText("category7");
|
||||
this.category8 = set.getText("category8");
|
||||
this.category9 = set.getText("category9");
|
||||
this.category10 = set.getText("category10");
|
||||
this.category11 = set.getText("category11");
|
||||
this.prereqSlotName1 = set.getText("prereq_slot_name1");
|
||||
this.prereqSlotName2 = set.getText("prereq_slot_name2");
|
||||
this.prereqSlotName3 = set.getText("prereq_slot_name3");
|
||||
this.prereqSlotName4 = set.getText("prereq_slot_name4");
|
||||
this.prereqSlotName5 = set.getText("prereq_slot_name5");
|
||||
this.icon = set.getText("icon");
|
||||
this.music = set.getText("music");
|
||||
this.showIfNotYetEarned = set.getText("show_if_not_yet_earned");
|
||||
this.hidden = set.getBoolean("hidden");
|
||||
this.title = set.getBoolean("title");
|
||||
this.alternateTitle1 = set.getText("alternate_title1");
|
||||
this.alternateTitle2 = set.getText("alternate_title2");
|
||||
this.alternateTitle3 = set.getText("alternate_title3");
|
||||
this.alternateTitle4 = set.getText("alternate_title4");
|
||||
this.alternateTitle5 = set.getText("alternate_title5");
|
||||
this.noReward = set.getBoolean("no_reward");
|
||||
this.trackServerFirst = set.getBoolean("track_server_first");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,22 @@ public abstract class DataLoader {
|
||||
return (BuffLoader) CachedLoader.BUFFS.load();
|
||||
}
|
||||
|
||||
public static ExpertiseLoader expertise() {
|
||||
return (ExpertiseLoader) CachedLoader.EXPERTISE.load();
|
||||
}
|
||||
|
||||
public static ExpertiseTreeLoader expertiseTrees() {
|
||||
return (ExpertiseTreeLoader) CachedLoader.EXPERTISE_TREES.load();
|
||||
}
|
||||
|
||||
public static SkillLoader skills() {
|
||||
return (SkillLoader) CachedLoader.SKILLS.load();
|
||||
}
|
||||
|
||||
public static PlayerLevelLoader playerLevels() {
|
||||
return (PlayerLevelLoader) CachedLoader.PLAYER_LEVELS.load();
|
||||
}
|
||||
|
||||
public static BuildoutLoader buildouts() {
|
||||
return BuildoutLoader.load(List.of());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.ExpertiseTreeLoader.ExpertiseTreeInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public final class ExpertiseLoader extends DataLoader {
|
||||
|
||||
private final Map<String, ExpertiseInfo> expertiseByName;
|
||||
private final Map<ExpertiseTreeInfo, List<ExpertiseInfo>> expertiseByTree;
|
||||
|
||||
ExpertiseLoader() {
|
||||
this.expertiseByName = new HashMap<>();
|
||||
this.expertiseByTree = new HashMap<>();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ExpertiseInfo getByName(String name) {
|
||||
return expertiseByName.get(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ExpertiseInfo> getPeerExpertise(@NotNull ExpertiseInfo expertise) {
|
||||
Collection<ExpertiseInfo> ret = expertiseByTree.get(expertise.getTree());
|
||||
return ret == null ? List.of() : Collections.unmodifiableCollection(ret);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ExpertiseInfo> getExpertiseByTree(ExpertiseTreeInfo tree) {
|
||||
Collection<ExpertiseInfo> ret = expertiseByTree.get(tree);
|
||||
return ret == null ? List.of() : Collections.unmodifiableCollection(ret);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ExpertiseInfo> getAllExpertise() {
|
||||
return Collections.unmodifiableCollection(expertiseByName.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
ExpertiseTreeLoader trees = DataLoader.expertiseTrees();
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/expertise/expertise.sdb"))) {
|
||||
while (set.next()) {
|
||||
ExpertiseInfo expertise = new ExpertiseInfo(set, trees);
|
||||
expertiseByName.put(expertise.getName(), expertise);
|
||||
expertiseByTree.computeIfAbsent(expertise.getTree(), t -> new ArrayList<>()).add(expertise);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExpertiseInfo {
|
||||
|
||||
private final String name;
|
||||
private final ExpertiseTreeInfo tree;
|
||||
private final int tier;
|
||||
private final int grid;
|
||||
private final int rank;
|
||||
private final int requiredLevel;
|
||||
private final String requiredFaction;
|
||||
private final String requiredProfession;
|
||||
|
||||
public ExpertiseInfo(SdbResultSet set, ExpertiseTreeLoader trees) {
|
||||
this.name = set.getText("name");
|
||||
this.tree = trees.getTreeFromId((int) set.getInt("tree"));
|
||||
this.tier = (int) set.getInt("tier");
|
||||
this.grid = (int) set.getInt("grid");
|
||||
this.rank = (int) set.getInt("rank");
|
||||
this.requiredLevel = (int) set.getInt("prereq_level");
|
||||
this.requiredFaction = set.getText("prereq_faction");
|
||||
this.requiredProfession = formatProfession(set.getText("req_prof"));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public ExpertiseTreeInfo getTree() {
|
||||
return tree;
|
||||
}
|
||||
|
||||
public int getTier() {
|
||||
return tier;
|
||||
}
|
||||
|
||||
public int getGrid() {
|
||||
return grid;
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
return rank;
|
||||
}
|
||||
|
||||
public int getRequiredLevel() {
|
||||
return requiredLevel;
|
||||
}
|
||||
|
||||
public String getRequiredFaction() {
|
||||
return requiredFaction;
|
||||
}
|
||||
|
||||
public String getRequiredProfession() {
|
||||
return requiredProfession;
|
||||
}
|
||||
|
||||
private static String formatProfession(String profession) {
|
||||
switch (profession) {
|
||||
case "trader_dom": return "trader_0a";
|
||||
case "trader_struct": return "trader_0b";
|
||||
case "trader_mun": return "trader_0c";
|
||||
case "trader_eng": return "trader_0d";
|
||||
default: return profession + "_1a";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class ExpertiseTreeLoader extends DataLoader {
|
||||
|
||||
private final Map<Integer, ExpertiseTreeInfo> trees;
|
||||
|
||||
ExpertiseTreeLoader() {
|
||||
this.trees = new HashMap<>();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ExpertiseTreeInfo getTreeFromId(int id) {
|
||||
return trees.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/expertise/expertise_trees.sdb"))) {
|
||||
while (set.next()) {
|
||||
ExpertiseTreeInfo treeInfo = new ExpertiseTreeInfo(set);
|
||||
trees.put(treeInfo.getId(), treeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExpertiseTreeInfo {
|
||||
|
||||
private final int id;
|
||||
private final String stringId;
|
||||
private final String uiBackgroundId;
|
||||
|
||||
public ExpertiseTreeInfo(SdbResultSet set) {
|
||||
this.id = (int) set.getInt("expertise_tree_id");
|
||||
this.stringId = set.getText("expertise_tree_string_id");
|
||||
this.uiBackgroundId = set.getText("ui_background_id");
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getStringId() {
|
||||
return stringId;
|
||||
}
|
||||
|
||||
public String getUiBackgroundId() {
|
||||
return uiBackgroundId;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class PlanetMapLoader extends DataLoader {
|
||||
|
||||
PlanetMapLoader() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/player/planet_map_cat.sdb"))) {
|
||||
while (set.next()) {
|
||||
PlanetMapInfo mapInfo = new PlanetMapInfo(set);
|
||||
// TODO: Store information
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlanetMapInfo {
|
||||
|
||||
private final String name;
|
||||
private final int index;
|
||||
private final boolean category;
|
||||
private final boolean subcategory;
|
||||
private final boolean canBeActive;
|
||||
private final String faction;
|
||||
private final boolean factionVisibleOnly;
|
||||
|
||||
public PlanetMapInfo(SdbResultSet set) {
|
||||
this.name = set.getText("name");
|
||||
this.index = (int) set.getInt("index");
|
||||
this.category = set.getBoolean("iscategory");
|
||||
this.subcategory = set.getBoolean("issubcategory");
|
||||
this.canBeActive = set.getBoolean("can_be_active");
|
||||
this.faction = set.getText("faction");
|
||||
this.factionVisibleOnly = set.getBoolean("faction_visible_only");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class PlayerLevelLoader extends DataLoader {
|
||||
|
||||
private final Map<Integer, PlayerLevelInfo> levels;
|
||||
|
||||
PlayerLevelLoader() {
|
||||
this.levels = new HashMap<>();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PlayerLevelInfo getFromLevel(int level) {
|
||||
return levels.get(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/player/player_level.sdb"))) {
|
||||
while (set.next()) {
|
||||
PlayerLevelInfo levelInfo = new PlayerLevelInfo(set);
|
||||
levels.put(levelInfo.getLevel(), levelInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlayerLevelInfo {
|
||||
|
||||
private final int level;
|
||||
private final int xpRequired;
|
||||
private final String xpType;
|
||||
private final int xpMultiplier;
|
||||
private final int healthGranted;
|
||||
private final int expertisePoints;
|
||||
|
||||
public PlayerLevelInfo(SdbResultSet set) {
|
||||
this.level = (int) set.getInt("level");
|
||||
this.xpRequired = (int) set.getInt("xp_required");
|
||||
this.xpType = set.getText("xp_type");
|
||||
this.xpMultiplier = (int) set.getInt("xp_multiplier");
|
||||
this.healthGranted = (int) set.getInt("health_granted");
|
||||
this.expertisePoints = (int) set.getInt("expertise_points");
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public int getXpRequired() {
|
||||
return xpRequired;
|
||||
}
|
||||
|
||||
public String getXpType() {
|
||||
return xpType;
|
||||
}
|
||||
|
||||
public int getXpMultiplier() {
|
||||
return xpMultiplier;
|
||||
}
|
||||
|
||||
public int getHealthGranted() {
|
||||
return healthGranted;
|
||||
}
|
||||
|
||||
public int getExpertisePoints() {
|
||||
return expertisePoints;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class PlayerRoleLoader extends DataLoader {
|
||||
|
||||
PlayerRoleLoader() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/player/role.sdb"))) {
|
||||
while (set.next()) {
|
||||
RoleInfo role = new RoleInfo(set);
|
||||
// TODO: Store information
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RoleInfo {
|
||||
|
||||
private final int index;
|
||||
private final String roleIcon;
|
||||
private final String qualifyingSkill;
|
||||
|
||||
public RoleInfo(SdbResultSet set) {
|
||||
this.index = (int) set.getInt("index");
|
||||
this.roleIcon = set.getText("role_icon");
|
||||
this.qualifyingSkill = set.getText("qualifying_skill");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class RoadmapRewardLoader extends DataLoader {
|
||||
|
||||
RoadmapRewardLoader() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/roadmap/item_rewards.sdb"))) {
|
||||
while (set.next()) {
|
||||
RoadmapRewardInfo rewardInfo = new RoadmapRewardInfo(set);
|
||||
// TODO: Store information
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RoadmapRewardInfo {
|
||||
|
||||
private final String roadmapTemplateName;
|
||||
private final String roadmapSkillName;
|
||||
private final String appearanceName;
|
||||
private final String stringId;
|
||||
private final String itemDefault;
|
||||
private final String itemWookiee;
|
||||
private final String itemIthorian;
|
||||
|
||||
public RoadmapRewardInfo(SdbResultSet set) {
|
||||
this.roadmapTemplateName = set.getText("roadmap_template_name");
|
||||
this.roadmapSkillName = set.getText("roadmap_skill_name");
|
||||
this.appearanceName = set.getText("appearance_name");
|
||||
this.stringId = set.getText("string_id");
|
||||
this.itemDefault = set.getText("item_default");
|
||||
this.itemWookiee = set.getText("item_wookiee");
|
||||
this.itemIthorian = set.getText("item_ithorian");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class SkillLoader extends DataLoader {
|
||||
|
||||
private final Map<String, SkillInfo> skillsByName;
|
||||
|
||||
SkillLoader() {
|
||||
this.skillsByName = new HashMap<>();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SkillInfo getSkillByName(String name) {
|
||||
return skillsByName.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/skill/skills.sdb"))) {
|
||||
while (set.next()) {
|
||||
SkillInfo skills = new SkillInfo(set);
|
||||
skillsByName.put(skills.getName(), skills);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ClassWithTooManyFields")
|
||||
public static class SkillInfo {
|
||||
|
||||
private final String name;
|
||||
private final String parent;
|
||||
private final String graphType;
|
||||
private final boolean godOnly;
|
||||
private final boolean title;
|
||||
private final boolean profession;
|
||||
private final boolean hidden;
|
||||
private final int moneyRequired;
|
||||
private final int pointsRequired;
|
||||
private final int skillsRequiredCount;
|
||||
private final String [] skillsRequired;
|
||||
private final String [] preclusionSkills;
|
||||
private final String xpType;
|
||||
private final int xpCost;
|
||||
private final int xpCap;
|
||||
private final String [] missionsRequired;
|
||||
private final int apprenticeshipsRequired;
|
||||
private final String [] statsRequired;
|
||||
private final String [] speciesRequired;
|
||||
private final String jediStateRequired;
|
||||
private final String skillAbility;
|
||||
private final String [] commands;
|
||||
private final Map<String, Integer> skillMods;
|
||||
private final String [] schematicsGranted;
|
||||
private final String [] schematicsRevoked;
|
||||
private final boolean searchable;
|
||||
private final int ender;
|
||||
|
||||
public SkillInfo(SdbResultSet set) {
|
||||
this.name = set.getText("name");
|
||||
this.parent = set.getText("parent");
|
||||
this.graphType = set.getText("graph_type");
|
||||
this.godOnly = set.getBoolean("god_only");
|
||||
this.title = set.getBoolean("is_title");
|
||||
this.profession = set.getBoolean("is_profession");
|
||||
this.hidden = set.getBoolean("is_hidden");
|
||||
this.moneyRequired = (int) set.getInt("money_required");
|
||||
this.pointsRequired = (int) set.getInt("points_required");
|
||||
this.skillsRequiredCount = (int) set.getInt("skills_required_count");
|
||||
this.skillsRequired = splitCsv(set.getText("skills_required"));
|
||||
this.preclusionSkills = splitCsv(set.getText("preclusion_skills"));
|
||||
this.xpType = set.getText("xp_type");
|
||||
this.xpCost = (int) set.getInt("xp_cost");
|
||||
this.xpCap = (int) set.getInt("xp_cap");
|
||||
this.missionsRequired = splitCsv(set.getText("missions_required"));
|
||||
this.apprenticeshipsRequired = (int) set.getInt("apprenticeships_required");
|
||||
this.statsRequired = splitCsv(set.getText("stats_required"));
|
||||
this.speciesRequired = splitCsv(set.getText("species_required"));
|
||||
this.jediStateRequired = set.getText("jedi_state_required");
|
||||
this.skillAbility = set.getText("skill_ability");
|
||||
this.commands = splitCsv(set.getText("commands"));
|
||||
this.skillMods = createSkillModMap(splitCsv(set.getText("skill_mods")));
|
||||
this.schematicsGranted = splitCsv(set.getText("schematics_granted"));
|
||||
this.schematicsRevoked = splitCsv(set.getText("schematics_revoked"));
|
||||
this.searchable = set.getBoolean("searchable");
|
||||
this.ender = (int) set.getInt("ender");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getGraphType() {
|
||||
return graphType;
|
||||
}
|
||||
|
||||
public boolean isGodOnly() {
|
||||
return godOnly;
|
||||
}
|
||||
|
||||
public boolean isTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public boolean isProfession() {
|
||||
return profession;
|
||||
}
|
||||
|
||||
public boolean isHidden() {
|
||||
return hidden;
|
||||
}
|
||||
|
||||
public int getMoneyRequired() {
|
||||
return moneyRequired;
|
||||
}
|
||||
|
||||
public int getPointsRequired() {
|
||||
return pointsRequired;
|
||||
}
|
||||
|
||||
public int getSkillsRequiredCount() {
|
||||
return skillsRequiredCount;
|
||||
}
|
||||
|
||||
public String[] getSkillsRequired() {
|
||||
return skillsRequired.clone();
|
||||
}
|
||||
|
||||
public String[] getPreclusionSkills() {
|
||||
return preclusionSkills.clone();
|
||||
}
|
||||
|
||||
public String getXpType() {
|
||||
return xpType;
|
||||
}
|
||||
|
||||
public int getXpCost() {
|
||||
return xpCost;
|
||||
}
|
||||
|
||||
public int getXpCap() {
|
||||
return xpCap;
|
||||
}
|
||||
|
||||
public String[] getMissionsRequired() {
|
||||
return missionsRequired.clone();
|
||||
}
|
||||
|
||||
public int getApprenticeshipsRequired() {
|
||||
return apprenticeshipsRequired;
|
||||
}
|
||||
|
||||
public String[] getStatsRequired() {
|
||||
return statsRequired.clone();
|
||||
}
|
||||
|
||||
public String[] getSpeciesRequired() {
|
||||
return speciesRequired.clone();
|
||||
}
|
||||
|
||||
public String getJediStateRequired() {
|
||||
return jediStateRequired;
|
||||
}
|
||||
|
||||
public String getSkillAbility() {
|
||||
return skillAbility;
|
||||
}
|
||||
|
||||
public String[] getCommands() {
|
||||
return commands.clone();
|
||||
}
|
||||
|
||||
public Map<String, Integer> getSkillMods() {
|
||||
return Collections.unmodifiableMap(skillMods);
|
||||
}
|
||||
|
||||
public String[] getSchematicsGranted() {
|
||||
return schematicsGranted.clone();
|
||||
}
|
||||
|
||||
public String[] getSchematicsRevoked() {
|
||||
return schematicsRevoked.clone();
|
||||
}
|
||||
|
||||
public boolean isSearchable() {
|
||||
return searchable;
|
||||
}
|
||||
|
||||
public int getEnder() {
|
||||
return ender;
|
||||
}
|
||||
|
||||
private static String [] splitCsv(String str) {
|
||||
if (str.isEmpty())
|
||||
return new String[0];
|
||||
else if (str.indexOf(',') == -1)
|
||||
return new String[]{str};
|
||||
return str.split(",");
|
||||
}
|
||||
|
||||
private static Map<String, Integer> createSkillModMap(String [] elements) {
|
||||
Map<String, Integer> skillMods = new HashMap<>();
|
||||
for (String element : elements) {
|
||||
String [] split = element.split("=", 2);
|
||||
if (split.length < 2)
|
||||
continue;
|
||||
skillMods.put(split[0], Integer.valueOf(split[1]));
|
||||
}
|
||||
return skillMods;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class SkillTemplateLoader extends DataLoader {
|
||||
|
||||
SkillTemplateLoader() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/skill/skill_template.sdb"))) {
|
||||
while (set.next()) {
|
||||
SkillTemplateInfo skillTemplate = new SkillTemplateInfo(set);
|
||||
// TODO: Store information
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SkillTemplateInfo {
|
||||
|
||||
private final String templateName;
|
||||
private final String startingTemplateName;
|
||||
private final String strClassName;
|
||||
private final int userInterfacePriority;
|
||||
private final String template;
|
||||
private final boolean levelBased;
|
||||
private final String expertiseTrees;
|
||||
private final int respecAllowed;
|
||||
|
||||
public SkillTemplateInfo(SdbResultSet set) {
|
||||
this.templateName = set.getText("template_name");
|
||||
this.startingTemplateName = set.getText("starting_template_name");
|
||||
this.strClassName = set.getText("str_class_name");
|
||||
this.userInterfacePriority = (int) set.getInt("user_interface_priority");
|
||||
this.template = set.getText("template");
|
||||
this.levelBased = set.getBoolean("level_based");
|
||||
this.expertiseTrees = set.getText("expertise_trees");
|
||||
this.respecAllowed = (int) set.getInt("respec_allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,14 +28,16 @@ package com.projectswg.holocore.services.gameplay.player.experience;
|
||||
|
||||
import com.projectswg.common.data.info.RelationalDatabase;
|
||||
import com.projectswg.common.data.info.RelationalServerFactory;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.DatatableData;
|
||||
import com.projectswg.common.network.packets.SWGPacket;
|
||||
import com.projectswg.common.network.packets.swg.zone.ExpertiseRequestMessage;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.LevelChangedIntent;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.expertise.RequestExpertiseIntent;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.skills.GrantSkillIntent;
|
||||
import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.ExpertiseLoader.ExpertiseInfo;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.PlayerLevelLoader.PlayerLevelInfo;
|
||||
import com.projectswg.holocore.resources.support.global.zone.sui.SuiButtons;
|
||||
import com.projectswg.holocore.resources.support.global.zone.sui.SuiMessageBox;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
@@ -47,75 +49,25 @@ import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Mads
|
||||
*/
|
||||
public class ExperienceExpertiseService 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
|
||||
private final Map<String, Collection<String[]>> expertiseAbilities; // Expertise skill to abilities
|
||||
|
||||
public ExperienceExpertiseService() {
|
||||
trees = new HashMap<>();
|
||||
expertiseSkills = new HashMap<>();
|
||||
expertiseAbilities = new HashMap<>();
|
||||
pointsForLevel = new HashMap<>();
|
||||
this.expertiseAbilities = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
loadTrees();
|
||||
loadPointsForLevel();
|
||||
return super.initialize() && loadExpertise() && loadAbilities();
|
||||
}
|
||||
|
||||
private void loadTrees() {
|
||||
long startTime = StandardLog.onStartLoad("expertise trees");
|
||||
DatatableData expertiseTable = (DatatableData) ClientFactory.getInfoFromFile("datatables/expertise/expertise_trees.iff");
|
||||
int rowCount = expertiseTable.getRowCount();
|
||||
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
int treeId = (int) expertiseTable.getCell(i, 0);
|
||||
trees.put(treeId, new HashMap<>());
|
||||
}
|
||||
StandardLog.onEndLoad(rowCount, "expertise trees", startTime);
|
||||
}
|
||||
|
||||
private boolean loadExpertise() {
|
||||
long startTime = StandardLog.onStartLoad("expertise skills");
|
||||
DatatableData expertiseTable = (DatatableData) ClientFactory.getInfoFromFile("datatables/expertise/expertise.iff");
|
||||
int rowCount = expertiseTable.getRowCount();
|
||||
|
||||
for (int i = 0; i < rowCount; i++) {
|
||||
String skillName = (String) expertiseTable.getCell(i, 0);
|
||||
int treeId = (int) expertiseTable.getCell(i, 1);
|
||||
|
||||
Map<String, Expertise> expertise = trees.get(treeId);
|
||||
|
||||
if (expertise == null) {
|
||||
Log.e("Expertise %s refers to unknown tree with ID %d", skillName, treeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
expertiseSkills.put(skillName, treeId);
|
||||
|
||||
String requiredProfession = formatProfession((String) expertiseTable.getCell(i, 7));
|
||||
int tier = (int) expertiseTable.getCell(i, 2);
|
||||
|
||||
expertise.put(skillName, new Expertise(requiredProfession, tier));
|
||||
}
|
||||
StandardLog.onEndLoad(rowCount, "expertise skills", startTime);
|
||||
return true;
|
||||
return loadAbilities();
|
||||
}
|
||||
|
||||
private boolean loadAbilities() {
|
||||
@@ -148,18 +100,6 @@ public class ExperienceExpertiseService extends Service {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void loadPointsForLevel() {
|
||||
DatatableData playerLevelTable = (DatatableData) ClientFactory.getInfoFromFile("datatables/player/player_level.iff");
|
||||
int points = 0;
|
||||
|
||||
for (int i = 0; i < playerLevelTable.getRowCount(); i++) {
|
||||
int level = (int) playerLevelTable.getCell(i, 0);
|
||||
|
||||
points += (int) playerLevelTable.getCell(i, 5);
|
||||
pointsForLevel.put(level, points);
|
||||
}
|
||||
}
|
||||
|
||||
@IntentHandler
|
||||
private void handleInboundPacketIntent(InboundPacketIntent gpi) {
|
||||
SWGPacket packet = gpi.getPacket();
|
||||
@@ -168,43 +108,51 @@ public class ExperienceExpertiseService extends Service {
|
||||
return;
|
||||
}
|
||||
|
||||
ExpertiseRequestMessage expertiseRequestMessage = (ExpertiseRequestMessage) packet;
|
||||
CreatureObject creatureObject = gpi.getPlayer().getCreatureObject();
|
||||
String[] requestedSkills = expertiseRequestMessage.getRequestedSkills();
|
||||
|
||||
for (String requestedSkill : requestedSkills) {
|
||||
if (creatureObject == null)
|
||||
return;
|
||||
|
||||
ExpertiseRequestMessage request = (ExpertiseRequestMessage) packet;
|
||||
RequestExpertiseIntent.broadcast(creatureObject, Arrays.stream(request.getRequestedSkills())
|
||||
.map(DataLoader.expertise()::getByName)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@IntentHandler
|
||||
private void handleRequestExpertiseIntent(RequestExpertiseIntent rei) {
|
||||
CreatureObject creatureObject = rei.getCreature();
|
||||
checkExtraAbilities(creatureObject);
|
||||
|
||||
int index = -1;
|
||||
for (ExpertiseInfo expertise : rei.getExpertise()) {
|
||||
index++;
|
||||
if (getAvailablePoints(creatureObject) < 1) {
|
||||
Log.i("%s attempted to spend more expertise points than available to them", creatureObject);
|
||||
StandardLog.onPlayerError(this, creatureObject, "attempted to spend more expertise points than available to them");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// TODO do anything with clearAllExpertisesFirst?
|
||||
Integer treeId = expertiseSkills.get(requestedSkill);
|
||||
|
||||
if (treeId == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PlayerObject playerObject = creatureObject.getPlayerObject();
|
||||
String profession = playerObject.getProfession();
|
||||
Map<String, Expertise> tree = trees.get(treeId);
|
||||
Expertise expertise = tree.get(requestedSkill);
|
||||
|
||||
|
||||
if (!expertise.getRequiredProfession().equals(profession)) {
|
||||
Log.i("%s attempted to train expertise skill %s as the wrong profession", creatureObject, requestedSkill);
|
||||
continue;
|
||||
}
|
||||
|
||||
int requiredTreePoints = (expertise.getTier() - 1) * 4;
|
||||
|
||||
if (requiredTreePoints > getPointsInTree(tree, creatureObject)) {
|
||||
Log.i("%s attempted to train expertise skill %s without having unlocked the tier of the tree", creatureObject, requestedSkill);
|
||||
StandardLog.onPlayerError(this, creatureObject, "attempted to train expertise skill %s as the wrong profession", expertise.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
Intent intent = new GrantSkillIntent(GrantSkillIntent.IntentType.GRANT, requestedSkill, creatureObject, false);
|
||||
intent.broadcast();
|
||||
while (!intent.isComplete()); // Block until the GrantSkillIntent has been processed
|
||||
int requiredTreePoints = (expertise.getTier() - 1) * 4;
|
||||
if (requiredTreePoints > getPointsInTree(expertise, creatureObject)) {
|
||||
StandardLog.onPlayerError(this, creatureObject, "attempted to train expertise skill %s without having unlocked the tier of the tree", expertise.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
// After the grant is processed, try adding the next expertise
|
||||
Intent grant = new GrantSkillIntent(GrantSkillIntent.IntentType.GRANT, expertise.getName(), creatureObject, false);
|
||||
Intent recursive = new RequestExpertiseIntent(rei.getCreature(), rei.getExpertise().subList(index+1, rei.getExpertise().size()));
|
||||
recursive.broadcastAfterIntent(grant);
|
||||
grant.broadcast();
|
||||
break;
|
||||
}
|
||||
|
||||
checkExtraAbilities(creatureObject);
|
||||
@@ -216,14 +164,14 @@ public class ExperienceExpertiseService extends Service {
|
||||
CreatureObject creatureObject = lci.getCreatureObject();
|
||||
PlayerObject playerObject = creatureObject.getPlayerObject();
|
||||
short oldLevel = lci.getPreviousLevel();
|
||||
|
||||
|
||||
if (oldLevel < 10 && newLevel >= 10) {
|
||||
SuiMessageBox window = new SuiMessageBox(SuiButtons.OK, "@expertise_d:sui_expertise_introduction_title", "@expertise_d:sui_expertise_introduction_body");
|
||||
SuiMessageBox window = new SuiMessageBox(SuiButtons.OK, "@expertise_d:sui_expertise_introduction_title", "@expertise_d:sui_expertise_introduction_body");
|
||||
window.display(playerObject.getOwner());
|
||||
// If we don't add the expertise root skill, the creature can't learn child skills
|
||||
creatureObject.addSkill("expertise");
|
||||
}
|
||||
|
||||
|
||||
checkExtraAbilities(creatureObject);
|
||||
}
|
||||
|
||||
@@ -238,22 +186,21 @@ public class ExperienceExpertiseService extends Service {
|
||||
}
|
||||
|
||||
private void checkExtraAbilities(CreatureObject creatureObject) {
|
||||
creatureObject.getSkills().stream()
|
||||
.filter(expertiseAbilities::containsKey) // We only want to check skills that give additional abilities
|
||||
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 levelDifference = 12; // Amount of levels between each ability
|
||||
int level = creatureObject.getLevel();
|
||||
|
||||
|
||||
// All first rank abilities have a required level of 10
|
||||
// The required level logic is required for ranks 2+
|
||||
if (abilityIndex == 0) {
|
||||
return level >= 10;
|
||||
}
|
||||
|
||||
|
||||
// Otherwise, perform the check as usual
|
||||
int requiredLevel = baseRequirement + abilityIndex * levelDifference;
|
||||
|
||||
@@ -273,55 +220,19 @@ public class ExperienceExpertiseService extends Service {
|
||||
});
|
||||
}
|
||||
|
||||
private String formatProfession(String profession) {
|
||||
switch (profession) {
|
||||
case "trader_dom": return "trader_0a";
|
||||
case "trader_struct": return "trader_0b";
|
||||
case "trader_mun": return "trader_0c";
|
||||
case "trader_eng": return "trader_0d";
|
||||
default: return profession + "_1a";
|
||||
}
|
||||
}
|
||||
|
||||
private int getAvailablePoints(CreatureObject creatureObject) {
|
||||
int levelPoints = pointsForLevel.get((int) creatureObject.getLevel());
|
||||
int spentPoints = (int) creatureObject.getSkills().stream()
|
||||
.filter(skill -> skill.startsWith("expertise_"))
|
||||
.count();
|
||||
PlayerLevelInfo levelInfo = DataLoader.playerLevels().getFromLevel(creatureObject.getLevel());
|
||||
int spentPoints = (int) creatureObject.getSkills().stream().filter(skill -> skill.startsWith("expertise_")).count();
|
||||
|
||||
return levelPoints - spentPoints;
|
||||
Objects.requireNonNull(levelInfo, "No player level defined for " + creatureObject.getLevel());
|
||||
return levelInfo.getExpertisePoints() - spentPoints;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tree
|
||||
* @param creatureObject
|
||||
* @return the amount of expertise points invested in a given expertise tree
|
||||
*/
|
||||
private long getPointsInTree(Map<String, Expertise> tree, CreatureObject creatureObject) {
|
||||
return tree.keySet().stream()
|
||||
.filter(creatureObject.getSkills()::contains)
|
||||
.count();
|
||||
}
|
||||
|
||||
private static class Expertise {
|
||||
|
||||
private final String requiredProfession;
|
||||
private final int tier;
|
||||
|
||||
public Expertise(String requiredProfession, int tier) {
|
||||
this.requiredProfession = requiredProfession;
|
||||
this.tier = tier;
|
||||
}
|
||||
|
||||
public String getRequiredProfession() {
|
||||
return requiredProfession;
|
||||
}
|
||||
|
||||
public int getTier() {
|
||||
return tier;
|
||||
}
|
||||
|
||||
private long getPointsInTree(ExpertiseInfo expertise, CreatureObject creatureObject) {
|
||||
return DataLoader.expertise().getPeerExpertise(expertise).stream().map(ExpertiseInfo::getName).filter(creatureObject.getSkills()::contains).count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,64 +1,19 @@
|
||||
package com.projectswg.holocore.services.gameplay.player.experience.skills;
|
||||
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.DatatableData;
|
||||
import com.projectswg.holocore.intents.gameplay.player.badge.SetTitleIntent;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.skills.GrantSkillIntent;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.skills.SkillModIntent;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.SkillLoader.SkillInfo;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
import me.joshlarson.jlcommon.control.IntentHandler;
|
||||
import me.joshlarson.jlcommon.control.Service;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SkillService extends Service {
|
||||
|
||||
private final Map<String, SkillData> skillDataMap;
|
||||
|
||||
public SkillService() {
|
||||
skillDataMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
DatatableData skillsTable = (DatatableData) ClientFactory.getInfoFromFile("datatables/skill/skills.iff");
|
||||
|
||||
for (int i = 0; i < skillsTable.getRowCount(); i++) {
|
||||
String skillName = (String) skillsTable.getCell(i, 0);
|
||||
String [] skillModsStrings = splitCsv((String) skillsTable.getCell(i, 22));
|
||||
Map<String, Integer> skillMods = new HashMap<>();
|
||||
for (String skillModString : skillModsStrings) {
|
||||
String [] values = skillModString.split("=", 2);
|
||||
skillMods.put(values[0], Integer.parseInt(values[1]));
|
||||
}
|
||||
|
||||
SkillData skillData = new SkillData(
|
||||
(boolean) skillsTable.getCell(i, 4), // Is title
|
||||
splitCsv((String) skillsTable.getCell(i, 10)), // required skills
|
||||
(String) skillsTable.getCell(i, 1), // parent skill
|
||||
(String) skillsTable.getCell(i, 12), // xp type
|
||||
(int) skillsTable.getCell(i, 13), // xp cost
|
||||
splitCsv((String) skillsTable.getCell(i, 21)), // commands
|
||||
skillMods,
|
||||
splitCsv((String) skillsTable.getCell(i, 23)) // schematics
|
||||
);
|
||||
|
||||
skillDataMap.put(skillName, skillData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void loadSkills() {
|
||||
}
|
||||
|
||||
private String [] splitCsv(String str) {
|
||||
if (str.isEmpty())
|
||||
return new String[0];
|
||||
else if (str.indexOf(',') == -1)
|
||||
return new String[]{str};
|
||||
return str.split(",");
|
||||
}
|
||||
|
||||
@IntentHandler
|
||||
@@ -69,14 +24,17 @@ public class SkillService extends Service {
|
||||
|
||||
String skillName = gsi.getSkillName();
|
||||
CreatureObject target = gsi.getTarget();
|
||||
SkillData skillData = skillDataMap.get(skillName);
|
||||
String parentSkillName = skillData.getParentSkill();
|
||||
SkillInfo skillData = DataLoader.skills().getSkillByName(skillName);
|
||||
if (skillData == null)
|
||||
return;
|
||||
|
||||
String parentSkillName = skillData.getParent();
|
||||
|
||||
if (gsi.isGrantRequiredSkills()) {
|
||||
grantParentSkills(skillData, parentSkillName, target);
|
||||
grantRequiredSkills(skillData, target);
|
||||
} else if (!target.hasSkill(parentSkillName) || !hasRequiredSkills(skillData, target)) {
|
||||
Log.i("%s lacks required skill %s before being granted skill %s", target, parentSkillName, skillName);
|
||||
StandardLog.onPlayerError(this, target, "lacks required skill %s before being granted skill %s", parentSkillName, skillName);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -87,13 +45,12 @@ public class SkillService extends Service {
|
||||
private void handleSetTitleIntent(SetTitleIntent sti) {
|
||||
String title = sti.getTitle();
|
||||
|
||||
if (!skillDataMap.containsKey(title)) {
|
||||
SkillInfo skillData = DataLoader.skills().getSkillByName(title);
|
||||
if (skillData == null) {
|
||||
// Might be a Collections title or someone playing tricks
|
||||
return;
|
||||
}
|
||||
|
||||
SkillData skillData = skillDataMap.get(title);
|
||||
|
||||
if (!skillData.isTitle()) {
|
||||
// There's a skill with this name, but it doesn't grant a title
|
||||
return;
|
||||
@@ -102,8 +59,8 @@ public class SkillService extends Service {
|
||||
sti.getRequester().setTitle(title);
|
||||
}
|
||||
|
||||
private boolean hasRequiredSkills(SkillData skillData, CreatureObject creatureObject) {
|
||||
String[] requiredSkills = skillData.getRequiredSkills();
|
||||
private boolean hasRequiredSkills(SkillInfo skillData, CreatureObject creatureObject) {
|
||||
String[] requiredSkills = skillData.getSkillsRequired();
|
||||
if (requiredSkills == null)
|
||||
return true;
|
||||
|
||||
@@ -114,25 +71,28 @@ public class SkillService extends Service {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void grantParentSkills(SkillData skillData, String parentSkill, CreatureObject target) {
|
||||
if (skillData == null || parentSkill.isEmpty() || target.hasSkill(parentSkill)) {
|
||||
private void grantParentSkills(SkillInfo skillData, String parentSkill, CreatureObject target) {
|
||||
if (skillData == null || parentSkill.isEmpty() || target.hasSkill(parentSkill))
|
||||
return;
|
||||
}
|
||||
|
||||
SkillInfo skillParent = DataLoader.skills().getSkillByName(parentSkill);
|
||||
if (skillParent == null)
|
||||
return;
|
||||
grantSkill(skillData, parentSkill, target);
|
||||
String grandParentSkill = skillData.getParentSkill();
|
||||
grantParentSkills(skillDataMap.get(grandParentSkill), grandParentSkill, target);
|
||||
|
||||
String grandParentSkill = skillData.getParent();
|
||||
grantParentSkills(skillParent, grandParentSkill, target);
|
||||
}
|
||||
|
||||
private void grantRequiredSkills(SkillData skillData, CreatureObject target) {
|
||||
String[] requiredSkills = skillData.getRequiredSkills();
|
||||
private void grantRequiredSkills(SkillInfo skillData, CreatureObject target) {
|
||||
String[] requiredSkills = skillData.getSkillsRequired();
|
||||
if (requiredSkills == null)
|
||||
return;
|
||||
|
||||
target.addSkill(requiredSkills);
|
||||
}
|
||||
|
||||
private void grantSkill(SkillData skillData, String skillName, CreatureObject target) {
|
||||
private void grantSkill(SkillInfo skillData, String skillName, CreatureObject target) {
|
||||
target.addSkill(skillName);
|
||||
target.addAbility(skillData.getCommands());
|
||||
|
||||
@@ -141,35 +101,4 @@ public class SkillService extends Service {
|
||||
new GrantSkillIntent(GrantSkillIntent.IntentType.GIVEN, skillName, target, false).broadcast();
|
||||
}
|
||||
|
||||
private static class SkillData {
|
||||
private boolean title;
|
||||
private String[] requiredSkills;
|
||||
private final String parentSkill;
|
||||
private final String xpType;
|
||||
private final int xpCost;
|
||||
private final String[] commands;
|
||||
private final Map<String, Integer> skillMods;
|
||||
private final String[] schematics;
|
||||
|
||||
public SkillData(boolean title, String[] requiredSkills, String parentSkill, String xpType, int xpCost, String[] commands, Map<String, Integer> skillMods, String[] schematics) {
|
||||
this.title = title;
|
||||
this.requiredSkills = requiredSkills;
|
||||
this.parentSkill = parentSkill;
|
||||
this.xpType = xpType;
|
||||
this.xpCost = xpCost;
|
||||
this.commands = commands;
|
||||
this.skillMods = skillMods;
|
||||
this.schematics = schematics;
|
||||
}
|
||||
|
||||
private boolean isTitle() { return title; }
|
||||
public String[] getRequiredSkills() { return requiredSkills; }
|
||||
public String getParentSkill() { return parentSkill; }
|
||||
public String getXpType() { return xpType; }
|
||||
public int getXpCost() { return xpCost; }
|
||||
public String[] getCommands() { return commands; }
|
||||
public Map<String, Integer> getSkillMods() { return skillMods; }
|
||||
public String[] getSchematics() { return schematics; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.services.gameplay.player.experience;
|
||||
|
||||
import com.projectswg.common.network.packets.swg.zone.ExpertiseRequestMessage;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.LevelChangedIntent;
|
||||
import com.projectswg.holocore.intents.support.global.network.InboundPacketIntent;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.ExpertiseLoader.ExpertiseInfo;
|
||||
import com.projectswg.holocore.resources.support.global.player.Player;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.player.PlayerObject;
|
||||
import com.projectswg.holocore.services.gameplay.player.experience.skills.SkillService;
|
||||
import com.projectswg.holocore.test.resources.GenericCreatureObject;
|
||||
import com.projectswg.holocore.test.runners.TestRunnerSynchronousIntents;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TestExperienceExpertiseService extends TestRunnerSynchronousIntents {
|
||||
|
||||
@Test
|
||||
public void testRequestExpertiseWrongProfession() {
|
||||
registerService(new ExperienceExpertiseService());
|
||||
registerService(new SkillService());
|
||||
|
||||
GenericCreatureObject creature = new GenericCreatureObject(1);
|
||||
PlayerObject player = creature.getPlayerObject();
|
||||
Player owner = creature.getOwner();
|
||||
|
||||
Assert.assertNotNull(player);
|
||||
Assert.assertNotNull(owner);
|
||||
|
||||
player.setProfession("medic_1a");
|
||||
// Nothing defined
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(new String[]{}, false)));
|
||||
Assert.assertEquals(Set.of(), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
|
||||
// No expertise yet
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(new String[]{"expertise_fs_general_enhanced_strength_1"}, false)));
|
||||
Assert.assertEquals(Set.of(), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
|
||||
// Wrong profession
|
||||
creature.setLevel(90);
|
||||
broadcastAndWait(new LevelChangedIntent(creature, (short) 1, (short) 90));
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(new String[]{"expertise_fs_general_enhanced_strength_1"}, false)));
|
||||
Assert.assertEquals(Set.of("expertise"), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestExpertise() {
|
||||
registerService(new ExperienceExpertiseService());
|
||||
registerService(new SkillService());
|
||||
|
||||
GenericCreatureObject creature = new GenericCreatureObject(1);
|
||||
PlayerObject player = creature.getPlayerObject();
|
||||
Player owner = creature.getOwner();
|
||||
|
||||
Assert.assertNotNull(player);
|
||||
Assert.assertNotNull(owner);
|
||||
|
||||
player.setProfession("force_sensitive_1a");
|
||||
// Nothing defined
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(new String[]{}, false)));
|
||||
Assert.assertEquals(Set.of(), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
|
||||
// No expertise yet
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(new String[]{"expertise_fs_general_enhanced_strength_1"}, false)));
|
||||
Assert.assertEquals(Set.of(), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
|
||||
// Haven't unlocked tier
|
||||
creature.setLevel(10);
|
||||
broadcastAndWait(new LevelChangedIntent(creature, (short) 1, (short) 10));
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(new String[]{"expertise_fs_general_improved_force_throw_1"}, false)));
|
||||
Assert.assertEquals(Set.of("expertise"), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
|
||||
// Success
|
||||
creature.setLevel(90);
|
||||
broadcastAndWait(new LevelChangedIntent(creature, (short) 10, (short) 90));
|
||||
String [] expertiseRequest = new String[]{
|
||||
"expertise",
|
||||
"expertise_fs_general_enhanced_strength_1",
|
||||
"expertise_fs_general_enhanced_strength_2",
|
||||
"expertise_fs_general_enhanced_constitution_1",
|
||||
"expertise_fs_general_enhanced_constitution_2",
|
||||
"expertise_fs_general_improved_force_throw_1"
|
||||
};
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(expertiseRequest, false)));
|
||||
Assert.assertEquals(Set.of(expertiseRequest), creature.getSkills());
|
||||
Assert.assertEquals(Set.of(), creature.getAbilityNames());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFullTree() {
|
||||
registerService(new ExperienceExpertiseService());
|
||||
registerService(new SkillService());
|
||||
|
||||
for (String profession : new String[]{"bounty_hunter_1a", "commando_1a", "entertainer_1a", "force_sensitive_1a", "medic_1a", "officer_1a", "smuggler_1a", "spy_1a", "trader_1a", "trader_1b", "trader_1c", "trader_1d"}) {
|
||||
GenericCreatureObject creature = new GenericCreatureObject(1, profession);
|
||||
PlayerObject player = creature.getPlayerObject();
|
||||
Player owner = creature.getOwner();
|
||||
|
||||
Assert.assertNotNull(player);
|
||||
Assert.assertNotNull(owner);
|
||||
|
||||
player.setProfession(profession);
|
||||
creature.setLevel(90);
|
||||
broadcastAndWait(new LevelChangedIntent(creature, (short) 1, (short) 90));
|
||||
|
||||
List<ExpertiseInfo> sortedExpertise = DataLoader.expertise().getAllExpertise().stream()
|
||||
.filter(e -> e.getRequiredProfession().equals(profession))
|
||||
.filter(e -> e.getTree().getUiBackgroundId().equals("left"))
|
||||
.sorted(Comparator.comparingInt(ExpertiseInfo::getTier).thenComparing(ExpertiseInfo::getGrid).thenComparing(ExpertiseInfo::getRank))
|
||||
.collect(Collectors.toList());
|
||||
List<String> expectedExpertise = new ArrayList<>(); // the list we verify with
|
||||
List<String> requestExpertise = new ArrayList<>(); // the list sent to the service
|
||||
int usedPoints = 0;
|
||||
|
||||
expectedExpertise.add("expertise");
|
||||
for (ExpertiseInfo expertise : sortedExpertise) {
|
||||
expectedExpertise.add(expertise.getName());
|
||||
requestExpertise.add(expertise.getName());
|
||||
usedPoints++;
|
||||
if (usedPoints >= 45)
|
||||
break;
|
||||
}
|
||||
|
||||
broadcastAndWait(new InboundPacketIntent(owner, new ExpertiseRequestMessage(requestExpertise.toArray(String[]::new), false)));
|
||||
Assert.assertEquals("Failed on: " + profession, new HashSet<>(expectedExpertise), creature.getSkills());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user